Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c87
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c32
-rw-r--r--source/blender/editors/animation/anim_deps.c17
-rw-r--r--source/blender/editors/animation/anim_draw.c6
-rw-r--r--source/blender/editors/animation/anim_filter.c16
-rw-r--r--source/blender/editors/animation/anim_markers.c4
-rw-r--r--source/blender/editors/animation/anim_motion_paths.c2
-rw-r--r--source/blender/editors/animation/anim_ops.c84
-rw-r--r--source/blender/editors/animation/drivers.c10
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c2
-rw-r--r--source/blender/editors/animation/keyframes_edit.c10
-rw-r--r--source/blender/editors/animation/keyframes_general.c14
-rw-r--r--source/blender/editors/animation/keyframing.c74
-rw-r--r--source/blender/editors/animation/keyingsets.c2
-rw-r--r--source/blender/editors/animation/time_scrub_ui.c2
-rw-r--r--source/blender/editors/armature/armature_add.c44
-rw-r--r--source/blender/editors/armature/armature_edit.c20
-rw-r--r--source/blender/editors/armature/armature_intern.h8
-rw-r--r--source/blender/editors/armature/armature_naming.c4
-rw-r--r--source/blender/editors/armature/armature_relations.c12
-rw-r--r--source/blender/editors/armature/armature_select.c2
-rw-r--r--source/blender/editors/armature/armature_skinning.c6
-rw-r--r--source/blender/editors/armature/armature_utils.c43
-rw-r--r--source/blender/editors/armature/editarmature_undo.c2
-rw-r--r--source/blender/editors/armature/pose_edit.c22
-rw-r--r--source/blender/editors/armature/pose_lib.c8
-rw-r--r--source/blender/editors/armature/pose_select.c6
-rw-r--r--source/blender/editors/armature/pose_slide.c994
-rw-r--r--source/blender/editors/armature/pose_transform.c45
-rw-r--r--source/blender/editors/armature/pose_utils.c28
-rw-r--r--source/blender/editors/curve/editcurve.c14
-rw-r--r--source/blender/editors/curve/editcurve_add.c2
-rw-r--r--source/blender/editors/curve/editcurve_paint.c26
-rw-r--r--source/blender/editors/curve/editcurve_query.c4
-rw-r--r--source/blender/editors/curve/editcurve_select.c211
-rw-r--r--source/blender/editors/curve/editcurve_undo.c6
-rw-r--r--source/blender/editors/curve/editfont.c5
-rw-r--r--source/blender/editors/curve/editfont_undo.c4
-rw-r--r--source/blender/editors/geometry/geometry_attributes.c31
-rw-r--r--source/blender/editors/gizmo_library/gizmo_draw_utils.c2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_library_presets.c2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_library_utils.c6
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c4
-rw-r--r--source/blender/editors/gpencil/CMakeLists.txt1
-rw-r--r--source/blender/editors/gpencil/annotate_draw.c10
-rw-r--r--source/blender/editors/gpencil/annotate_paint.c50
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c2
-rw-r--r--source/blender/editors/gpencil/editaction_gpencil.c10
-rw-r--r--source/blender/editors/gpencil/gpencil_add_monkey.c82
-rw-r--r--source/blender/editors/gpencil/gpencil_add_stroke.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_armature.c10
-rw-r--r--source/blender/editors/gpencil/gpencil_bake_animation.c453
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c10
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c86
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c206
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c20
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h56
-rw-r--r--source/blender/editors/gpencil/gpencil_mesh.c28
-rw-r--r--source/blender/editors/gpencil/gpencil_ops.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c92
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c37
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c12
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c16
-rw-r--r--source/blender/editors/gpencil/gpencil_trace_utils.c5
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c60
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_ops.c14
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_paint.c6
-rw-r--r--source/blender/editors/gpencil/gpencil_weight_paint.c12
-rw-r--r--source/blender/editors/include/ED_anim_api.h6
-rw-r--r--source/blender/editors/include/ED_curve.h8
-rw-r--r--source/blender/editors/include/ED_datafiles.h176
-rw-r--r--source/blender/editors/include/ED_fileselect.h12
-rw-r--r--source/blender/editors/include/ED_gizmo_library.h2
-rw-r--r--source/blender/editors/include/ED_gpencil.h23
-rw-r--r--source/blender/editors/include/ED_info.h4
-rw-r--r--source/blender/editors/include/ED_keyframes_edit.h2
-rw-r--r--source/blender/editors/include/ED_keyframing.h6
-rw-r--r--source/blender/editors/include/ED_mask.h2
-rw-r--r--source/blender/editors/include/ED_mesh.h33
-rw-r--r--source/blender/editors/include/ED_node.h9
-rw-r--r--source/blender/editors/include/ED_object.h17
-rw-r--r--source/blender/editors/include/ED_particle.h7
-rw-r--r--source/blender/editors/include/ED_screen.h4
-rw-r--r--source/blender/editors/include/ED_sequencer.h2
-rw-r--r--source/blender/editors/include/ED_spreadsheet.h26
-rw-r--r--source/blender/editors/include/ED_undo.h2
-rw-r--r--source/blender/editors/include/ED_uvedit.h1
-rw-r--r--source/blender/editors/include/ED_view3d.h66
-rw-r--r--source/blender/editors/include/UI_icons.h4
-rw-r--r--source/blender/editors/include/UI_interface.h115
-rw-r--r--source/blender/editors/include/UI_view2d.h79
-rw-r--r--source/blender/editors/interface/CMakeLists.txt3
-rw-r--r--source/blender/editors/interface/interface.c153
-rw-r--r--source/blender/editors/interface/interface_align.c3
-rw-r--r--source/blender/editors/interface/interface_context_menu.c7
-rw-r--r--source/blender/editors/interface/interface_draw.c14
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c11
-rw-r--r--source/blender/editors/interface/interface_eyedropper_color.c100
-rw-r--r--source/blender/editors/interface/interface_eyedropper_gpencil_color.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c461
-rw-r--r--source/blender/editors/interface/interface_icons.c12
-rw-r--r--source/blender/editors/interface/interface_intern.h43
-rw-r--r--source/blender/editors/interface/interface_layout.c91
-rw-r--r--source/blender/editors/interface/interface_ops.c8
-rw-r--r--source/blender/editors/interface/interface_panel.c9
-rw-r--r--source/blender/editors/interface/interface_query.c8
-rw-r--r--source/blender/editors/interface/interface_region_color_picker.c2
-rw-r--r--source/blender/editors/interface/interface_region_menu_popup.c9
-rw-r--r--source/blender/editors/interface/interface_region_popover.c2
-rw-r--r--source/blender/editors/interface/interface_region_popup.c4
-rw-r--r--source/blender/editors/interface/interface_region_search.c36
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c16
-rw-r--r--source/blender/editors/interface/interface_style.c2
-rw-r--r--source/blender/editors/interface/interface_template_search_menu.c2
-rw-r--r--source/blender/editors/interface/interface_templates.c42
-rw-r--r--source/blender/editors/interface/interface_undo.c2
-rw-r--r--source/blender/editors/interface/interface_utils.c4
-rw-r--r--source/blender/editors/interface/interface_widgets.c187
-rw-r--r--source/blender/editors/interface/view2d.c29
-rw-r--r--source/blender/editors/interface/view2d_draw.c2
-rw-r--r--source/blender/editors/interface/view2d_edge_pan.c345
-rw-r--r--source/blender/editors/interface/view2d_gizmo_navigate.c2
-rw-r--r--source/blender/editors/interface/view2d_ops.c180
-rw-r--r--source/blender/editors/io/io_alembic.c36
-rw-r--r--source/blender/editors/lattice/editlattice_select.c35
-rw-r--r--source/blender/editors/lattice/editlattice_undo.c2
-rw-r--r--source/blender/editors/mask/mask_add.c10
-rw-r--r--source/blender/editors/mask/mask_draw.c2
-rw-r--r--source/blender/editors/mask/mask_editaction.c12
-rw-r--r--source/blender/editors/mask/mask_ops.c6
-rw-r--r--source/blender/editors/mask/mask_query.c2
-rw-r--r--source/blender/editors/mask/mask_select.c1
-rw-r--r--source/blender/editors/mask/mask_shapekey.c4
-rw-r--r--source/blender/editors/mesh/editface.c4
-rw-r--r--source/blender/editors/mesh/editmesh_add.c7
-rw-r--r--source/blender/editors/mesh/editmesh_add_gizmo.c7
-rw-r--r--source/blender/editors/mesh/editmesh_automerge.c14
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c24
-rw-r--r--source/blender/editors/mesh/editmesh_bisect.c19
-rw-r--r--source/blender/editors/mesh/editmesh_extrude.c68
-rw-r--r--source/blender/editors/mesh/editmesh_extrude_screw.c7
-rw-r--r--source/blender/editors/mesh/editmesh_extrude_spin.c7
-rw-r--r--source/blender/editors/mesh/editmesh_inset.c20
-rw-r--r--source/blender/editors/mesh/editmesh_intersect.c24
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c35
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c5
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c11
-rw-r--r--source/blender/editors/mesh/editmesh_mask_extract.c8
-rw-r--r--source/blender/editors/mesh/editmesh_path.c22
-rw-r--r--source/blender/editors/mesh/editmesh_polybuild.c42
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c33
-rw-r--r--source/blender/editors/mesh/editmesh_rip_edge.c7
-rw-r--r--source/blender/editors/mesh/editmesh_select.c44
-rw-r--r--source/blender/editors/mesh/editmesh_select_similar.c50
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c570
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c119
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c280
-rw-r--r--source/blender/editors/mesh/mesh_data.c12
-rw-r--r--source/blender/editors/mesh/mesh_intern.h8
-rw-r--r--source/blender/editors/mesh/mesh_mirror.c5
-rw-r--r--source/blender/editors/mesh/meshtools.c35
-rw-r--r--source/blender/editors/metaball/editmball_undo.c2
-rw-r--r--source/blender/editors/object/CMakeLists.txt2
-rw-r--r--source/blender/editors/object/object_add.c237
-rw-r--r--source/blender/editors/object/object_bake.c2
-rw-r--r--source/blender/editors/object/object_bake_api.c6
-rw-r--r--source/blender/editors/object/object_constraint.c21
-rw-r--r--source/blender/editors/object/object_data_transfer.c26
-rw-r--r--source/blender/editors/object/object_data_transform.c8
-rw-r--r--source/blender/editors/object/object_edit.c18
-rw-r--r--source/blender/editors/object/object_hook.c17
-rw-r--r--source/blender/editors/object/object_intern.h1
-rw-r--r--source/blender/editors/object/object_modes.c25
-rw-r--r--source/blender/editors/object/object_modifier.c9
-rw-r--r--source/blender/editors/object/object_ops.c3
-rw-r--r--source/blender/editors/object/object_relations.c70
-rw-r--r--source/blender/editors/object/object_remesh.c15
-rw-r--r--source/blender/editors/object/object_select.c32
-rw-r--r--source/blender/editors/object/object_shader_fx.c133
-rw-r--r--source/blender/editors/object/object_transform.c517
-rw-r--r--source/blender/editors/object/object_vgroup.c222
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c2
-rw-r--r--source/blender/editors/physics/particle_edit.c120
-rw-r--r--source/blender/editors/physics/particle_object.c5
-rw-r--r--source/blender/editors/physics/physics_fluid.c6
-rw-r--r--source/blender/editors/physics/physics_intern.h2
-rw-r--r--source/blender/editors/render/render_internal.c8
-rw-r--r--source/blender/editors/render/render_opengl.c10
-rw-r--r--source/blender/editors/render/render_preview.c26
-rw-r--r--source/blender/editors/render/render_shading.c14
-rw-r--r--source/blender/editors/render/render_update.c2
-rw-r--r--source/blender/editors/render/render_view.c9
-rw-r--r--source/blender/editors/scene/scene_edit.c2
-rw-r--r--source/blender/editors/screen/area.c24
-rw-r--r--source/blender/editors/screen/area_query.c2
-rw-r--r--source/blender/editors/screen/glutil.c4
-rw-r--r--source/blender/editors/screen/screen_context.c6
-rw-r--r--source/blender/editors/screen/screen_draw.c2
-rw-r--r--source/blender/editors/screen/screen_edit.c50
-rw-r--r--source/blender/editors/screen/screen_ops.c110
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c108
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h2
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c9
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c10
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c34
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_color_ops.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c28
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c22
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c19
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_automasking.c6
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h8
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c16
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c20
-rw-r--r--source/blender/editors/space_action/action_data.c6
-rw-r--r--source/blender/editors/space_action/action_draw.c4
-rw-r--r--source/blender/editors/space_action/action_edit.c14
-rw-r--r--source/blender/editors/space_action/action_select.c30
-rw-r--r--source/blender/editors/space_action/space_action.c4
-rw-r--r--source/blender/editors/space_buttons/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c26
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c2
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c8
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c6
-rw-r--r--source/blender/editors/space_clip/clip_editor.c2
-rw-r--r--source/blender/editors/space_clip/clip_ops.c8
-rw-r--r--source/blender/editors/space_clip/clip_utils.c2
-rw-r--r--source/blender/editors/space_clip/space_clip.c2
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c138
-rw-r--r--source/blender/editors/space_console/console_ops.c8
-rw-r--r--source/blender/editors/space_console/space_console.c2
-rw-r--r--source/blender/editors/space_file/file_draw.c122
-rw-r--r--source/blender/editors/space_file/file_intern.h13
-rw-r--r--source/blender/editors/space_file/file_ops.c128
-rw-r--r--source/blender/editors/space_file/file_panels.c4
-rw-r--r--source/blender/editors/space_file/filelist.c235
-rw-r--r--source/blender/editors/space_file/filelist.h12
-rw-r--r--source/blender/editors/space_file/filesel.c110
-rw-r--r--source/blender/editors/space_file/space_file.c43
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c4
-rw-r--r--source/blender/editors/space_graph/graph_draw.c6
-rw-r--r--source/blender/editors/space_graph/graph_edit.c8
-rw-r--r--source/blender/editors/space_graph/graph_select.c241
-rw-r--r--source/blender/editors/space_graph/graph_slider_ops.c6
-rw-r--r--source/blender/editors/space_graph/graph_view.c6
-rw-r--r--source/blender/editors/space_graph/space_graph.c8
-rw-r--r--source/blender/editors/space_image/image_buttons.c7
-rw-r--r--source/blender/editors/space_image/image_edit.c4
-rw-r--r--source/blender/editors/space_image/image_ops.c32
-rw-r--r--source/blender/editors/space_image/image_undo.c9
-rw-r--r--source/blender/editors/space_info/info_draw.c4
-rw-r--r--source/blender/editors/space_info/info_ops.c9
-rw-r--r--source/blender/editors/space_info/info_report.c6
-rw-r--r--source/blender/editors/space_info/info_stats.c287
-rw-r--r--source/blender/editors/space_info/textview.c2
-rw-r--r--source/blender/editors/space_nla/nla_channels.c14
-rw-r--r--source/blender/editors/space_nla/nla_draw.c8
-rw-r--r--source/blender/editors/space_nla/nla_edit.c25
-rw-r--r--source/blender/editors/space_nla/nla_ops.c16
-rw-r--r--source/blender/editors/space_nla/nla_select.c6
-rw-r--r--source/blender/editors/space_node/CMakeLists.txt36
-rw-r--r--source/blender/editors/space_node/drawnode.cc (renamed from source/blender/editors/space_node/drawnode.c)964
-rw-r--r--source/blender/editors/space_node/node_add.cc (renamed from source/blender/editors/space_node/node_add.c)72
-rw-r--r--source/blender/editors/space_node/node_buttons.c223
-rw-r--r--source/blender/editors/space_node/node_draw.cc323
-rw-r--r--source/blender/editors/space_node/node_edit.cc (renamed from source/blender/editors/space_node/node_edit.c)384
-rw-r--r--source/blender/editors/space_node/node_geometry_attribute_search.cc94
-rw-r--r--source/blender/editors/space_node/node_gizmo.c7
-rw-r--r--source/blender/editors/space_node/node_group.cc (renamed from source/blender/editors/space_node/node_group.c)80
-rw-r--r--source/blender/editors/space_node/node_intern.h13
-rw-r--r--source/blender/editors/space_node/node_ops.c3
-rw-r--r--source/blender/editors/space_node/node_relationships.cc (renamed from source/blender/editors/space_node/node_relationships.c)371
-rw-r--r--source/blender/editors/space_node/node_select.cc (renamed from source/blender/editors/space_node/node_select.c)166
-rw-r--r--source/blender/editors/space_node/node_templates.cc (renamed from source/blender/editors/space_node/node_templates.c)113
-rw-r--r--source/blender/editors/space_node/node_toolbar.cc (renamed from source/blender/editors/space_node/node_toolbar.c)0
-rw-r--r--source/blender/editors/space_node/node_view.cc (renamed from source/blender/editors/space_node/node_view.c)68
-rw-r--r--source/blender/editors/space_node/space_node.c10
-rw-r--r--source/blender/editors/space_outliner/outliner_context.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_dragdrop.c13
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c21
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c12
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h2
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c9
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c20
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c45
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c3
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display.hh2
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_libraries.cc4
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_override_library.cc34
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_view_layer.cc65
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_id.cc2
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_overrides.cc4
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_overrides.hh1
-rw-r--r--source/blender/editors/space_script/space_script.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c7
-rw-r--r--source/blender/editors/space_sequencer/sequencer_buttons.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c82
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c140
-rw-r--r--source/blender/editors/space_sequencer/sequencer_proxy.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_scopes.c10
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c43
-rw-r--r--source/blender/editors/space_spreadsheet/CMakeLists.txt14
-rw-r--r--source/blender/editors/space_spreadsheet/space_spreadsheet.cc245
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh2
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_column.cc13
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_column.hh3
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_column_values.hh23
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_context.cc305
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_data_source.hh9
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc168
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh3
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc287
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.hh64
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.cc112
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.hh68
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_intern.hh13
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_layout.cc2
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_ops.cc128
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc366
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_row_filter.hh35
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc347
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.hh21
-rw-r--r--source/blender/editors/space_statusbar/space_statusbar.c2
-rw-r--r--source/blender/editors/space_text/text_draw.c2
-rw-r--r--source/blender/editors/space_text/text_format_pov.c4
-rw-r--r--source/blender/editors/space_text/text_format_py.c2
-rw-r--r--source/blender/editors/space_text/text_ops.c10
-rw-r--r--source/blender/editors/space_text/text_undo.c2
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_view3d/drawobject.c6
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c38
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c115
-rw-r--r--source/blender/editors/space_view3d/view3d_camera_control.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c134
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c66
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_armature.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_camera.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_light.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_ruler.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h6
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c510
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_fly.c (renamed from source/blender/editors/space_view3d/view3d_fly.c)22
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_walk.c (renamed from source/blender/editors/space_view3d/view3d_walk.c)96
-rw-r--r--source/blender/editors/space_view3d/view3d_placement.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c30
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c378
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c74
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c43
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c15
-rw-r--r--source/blender/editors/transform/CMakeLists.txt1
-rw-r--r--source/blender/editors/transform/transform.c186
-rw-r--r--source/blender/editors/transform/transform.h43
-rw-r--r--source/blender/editors/transform/transform_constraints.c91
-rw-r--r--source/blender/editors/transform/transform_constraints.h4
-rw-r--r--source/blender/editors/transform/transform_convert.c11
-rw-r--r--source/blender/editors/transform/transform_convert.h5
-rw-r--r--source/blender/editors/transform/transform_convert_action.c17
-rw-r--r--source/blender/editors/transform/transform_convert_armature.c17
-rw-r--r--source/blender/editors/transform/transform_convert_curve.c10
-rw-r--r--source/blender/editors/transform/transform_convert_gpencil.c8
-rw-r--r--source/blender/editors/transform/transform_convert_graph.c6
-rw-r--r--source/blender/editors/transform/transform_convert_lattice.c2
-rw-r--r--source/blender/editors/transform/transform_convert_mask.c2
-rw-r--r--source/blender/editors/transform/transform_convert_mball.c2
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c529
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_edge.c8
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_skin.c5
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_uv.c3
-rw-r--r--source/blender/editors/transform/transform_convert_node.c66
-rw-r--r--source/blender/editors/transform/transform_convert_object.c4
-rw-r--r--source/blender/editors/transform/transform_convert_particle.c2
-rw-r--r--source/blender/editors/transform/transform_convert_sequencer.c581
-rw-r--r--source/blender/editors/transform/transform_data.h6
-rw-r--r--source/blender/editors/transform/transform_generics.c11
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c2
-rw-r--r--source/blender/editors/transform/transform_gizmo_extrude_3d.c2
-rw-r--r--source/blender/editors/transform/transform_input.c11
-rw-r--r--source/blender/editors/transform/transform_mode.c184
-rw-r--r--source/blender/editors/transform/transform_mode.h26
-rw-r--r--source/blender/editors/transform/transform_mode_bend.c236
-rw-r--r--source/blender/editors/transform/transform_mode_edge_bevelweight.c70
-rw-r--r--source/blender/editors/transform/transform_mode_edge_crease.c76
-rw-r--r--source/blender/editors/transform/transform_mode_edge_rotate_normal.c2
-rw-r--r--source/blender/editors/transform/transform_mode_edge_seq_slide.c33
-rw-r--r--source/blender/editors/transform/transform_mode_edge_slide.c30
-rw-r--r--source/blender/editors/transform/transform_mode_maskshrinkfatten.c2
-rw-r--r--source/blender/editors/transform/transform_mode_push_pull.c118
-rw-r--r--source/blender/editors/transform/transform_mode_resize.c56
-rw-r--r--source/blender/editors/transform/transform_mode_rotate.c221
-rw-r--r--source/blender/editors/transform/transform_mode_shear.c136
-rw-r--r--source/blender/editors/transform/transform_mode_shrink_fatten.c78
-rw-r--r--source/blender/editors/transform/transform_mode_skin_resize.c98
-rw-r--r--source/blender/editors/transform/transform_mode_timetranslate.c4
-rw-r--r--source/blender/editors/transform/transform_mode_tosphere.c136
-rw-r--r--source/blender/editors/transform/transform_mode_trackball.c106
-rw-r--r--source/blender/editors/transform/transform_mode_translate.c447
-rw-r--r--source/blender/editors/transform/transform_mode_vert_slide.c10
-rw-r--r--source/blender/editors/transform/transform_ops.c7
-rw-r--r--source/blender/editors/transform/transform_orientations.c4
-rw-r--r--source/blender/editors/transform/transform_snap.c293
-rw-r--r--source/blender/editors/transform/transform_snap.h14
-rw-r--r--source/blender/editors/transform/transform_snap_object.c16
-rw-r--r--source/blender/editors/transform/transform_snap_sequencer.c275
-rw-r--r--source/blender/editors/undo/ed_undo.c18
-rw-r--r--source/blender/editors/undo/memfile_undo.c14
-rw-r--r--source/blender/editors/util/ed_transverts.c6
-rw-r--r--source/blender/editors/util/ed_util.c7
-rw-r--r--source/blender/editors/util/ed_util_imbuf.c4
-rw-r--r--source/blender/editors/util/select_utils.c4
-rw-r--r--source/blender/editors/uvedit/uvedit_islands.c1
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c34
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c30
-rw-r--r--source/blender/editors/uvedit/uvedit_path.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_rip.c4
-rw-r--r--source/blender/editors/uvedit/uvedit_select.c7
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c22
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c10
425 files changed, 15039 insertions, 7646 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 6dd1fe75163..87688ee343c 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -502,7 +502,7 @@ static bool acf_summary_setting_valid(bAnimContext *UNUSED(ac),
return (setting == ACHANNEL_SETTING_EXPAND);
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_summary_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -595,7 +595,7 @@ static bool acf_scene_setting_valid(bAnimContext *ac,
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_scene_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -766,7 +766,7 @@ static bool acf_object_setting_valid(bAnimContext *ac,
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_object_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -949,7 +949,7 @@ static bool acf_group_setting_valid(bAnimContext *ac,
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_group_setting_flag(bAnimContext *ac, eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
@@ -1086,7 +1086,7 @@ static bool acf_fcurve_setting_valid(bAnimContext *ac,
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -1212,7 +1212,7 @@ static bool acf_nla_controls_setting_valid(bAnimContext *UNUSED(ac),
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_nla_controls_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -1330,7 +1330,7 @@ static bool acf_fillactd_setting_valid(bAnimContext *UNUSED(ac),
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -1425,7 +1425,7 @@ static bool acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac),
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -1489,7 +1489,7 @@ static int acf_dsmat_icon(bAnimListElem *UNUSED(ale))
return ICON_MATERIAL_DATA;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -1568,7 +1568,7 @@ static int acf_dslight_icon(bAnimListElem *UNUSED(ale))
return ICON_LIGHT_DATA;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dslight_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -1656,7 +1656,7 @@ static short acf_dstex_offset(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(al
return 14; /* XXX: simply include this in indention instead? */
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -1736,7 +1736,7 @@ static int acf_dscachefile_icon(bAnimListElem *ale)
return ICON_FILE;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dscachefile_setting_flag(bAnimContext *ac, eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
@@ -1818,7 +1818,7 @@ static int acf_dscam_icon(bAnimListElem *UNUSED(ale))
return ICON_CAMERA_DATA;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -1911,7 +1911,7 @@ static int acf_dscur_icon(bAnimListElem *ale)
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -2009,7 +2009,7 @@ static bool acf_dsskey_setting_valid(bAnimContext *ac,
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -2088,7 +2088,7 @@ static int acf_dswor_icon(bAnimListElem *UNUSED(ale))
return ICON_WORLD_DATA;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -2167,7 +2167,7 @@ static int acf_dspart_icon(bAnimListElem *UNUSED(ale))
return ICON_PARTICLE_DATA;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -2246,7 +2246,7 @@ static int acf_dsmball_icon(bAnimListElem *UNUSED(ale))
return ICON_META_DATA;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -2327,7 +2327,7 @@ static int acf_dsarm_icon(bAnimListElem *UNUSED(ale))
return ICON_ARMATURE_DATA;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -2417,7 +2417,7 @@ static short acf_dsntree_offset(bAnimContext *ac, bAnimListElem *ale)
return offset;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -2498,7 +2498,7 @@ static int acf_dslinestyle_icon(bAnimListElem *UNUSED(ale))
return ICON_LINE_DATA;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -2579,7 +2579,7 @@ static int acf_dsmesh_icon(bAnimListElem *UNUSED(ale))
return ICON_MESH_DATA;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -2659,7 +2659,7 @@ static int acf_dslat_icon(bAnimListElem *UNUSED(ale))
return ICON_LATTICE_DATA;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -2739,7 +2739,7 @@ static int acf_dsspk_icon(bAnimListElem *UNUSED(ale))
return ICON_SPEAKER;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -2818,7 +2818,7 @@ static int acf_dshair_icon(bAnimListElem *UNUSED(ale))
return ICON_HAIR_DATA;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dshair_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -2897,7 +2897,7 @@ static int acf_dspointcloud_icon(bAnimListElem *UNUSED(ale))
return ICON_POINTCLOUD_DATA;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dspointcloud_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -2978,7 +2978,7 @@ static int acf_dsvolume_icon(bAnimListElem *UNUSED(ale))
return ICON_VOLUME_DATA;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dsvolume_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -3137,7 +3137,7 @@ static int acf_dsgpencil_icon(bAnimListElem *UNUSED(ale))
return ICON_GREASEPENCIL;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dsgpencil_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -3218,7 +3218,7 @@ static int acf_dsmclip_icon(bAnimListElem *UNUSED(ale))
return ICON_SEQUENCE;
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_dsmclip_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -3343,7 +3343,7 @@ static bool acf_shapekey_setting_valid(bAnimContext *UNUSED(ac),
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -3437,7 +3437,7 @@ static bool acf_gpd_setting_valid(bAnimContext *UNUSED(ac),
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
@@ -3530,7 +3530,7 @@ static bool acf_gpl_setting_valid(bAnimContext *UNUSED(ac),
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
/* clear extra return data first */
@@ -3616,7 +3616,7 @@ static bool acf_mask_setting_valid(bAnimContext *UNUSED(ac),
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_mask_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -3713,7 +3713,7 @@ static bool acf_masklay_setting_valid(bAnimContext *UNUSED(ac),
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -3849,7 +3849,7 @@ static bool acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac),
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_nlatrack_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -4025,7 +4025,7 @@ static bool acf_nlaaction_setting_valid(bAnimContext *UNUSED(ac),
/* conditionally supported */
case ACHANNEL_SETTING_PINNED: /* pinned - map/unmap */
if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
- /* this should only appear in tweakmode */
+ /* This should only appear in tweak-mode. */
return true;
}
else {
@@ -4038,7 +4038,7 @@ static bool acf_nlaaction_setting_valid(bAnimContext *UNUSED(ac),
}
}
-/* get the appropriate flag(s) for the setting when it is valid */
+/* Get the appropriate flag(s) for the setting when it is valid. */
static int acf_nlaaction_setting_flag(bAnimContext *UNUSED(ac),
eAnimChannel_Settings setting,
bool *neg)
@@ -4415,7 +4415,7 @@ void ANIM_channel_draw(
/* set blending again, as may not be set in previous step */
GPU_blend(GPU_BLEND_ALPHA);
- /* step 1) draw backdrop ........................................... */
+ /* step 1) draw backdrop ........................................... */
if (acf->draw_backdrop) {
acf->draw_backdrop(ac, ale, yminc, ymaxc);
}
@@ -4674,7 +4674,7 @@ static void achannel_setting_flush_widget_cb(bContext *C, void *ale_npoin, void
DEG_id_tag_update(ale_setting->id, ID_RECALC_ANIMATION);
}
if (ale_setting->adt && ale_setting->adt->action) {
- /* Action is it's own datablock, so has to be tagged specifically. */
+ /* Action is its own datablock, so has to be tagged specifically. */
DEG_id_tag_update(&ale_setting->adt->action->id, ID_RECALC_ANIMATION);
}
@@ -5096,7 +5096,7 @@ static void draw_setting_widget(bAnimContext *ac,
/* set call to send relevant notifiers and/or perform type-specific updates */
if (but) {
switch (setting) {
- /* settings needing flushing up/down hierarchy */
+ /* Settings needing flushing up/down hierarchy. */
case ACHANNEL_SETTING_VISIBLE: /* Graph Editor - 'visibility' toggles */
case ACHANNEL_SETTING_PROTECT: /* General - protection flags */
case ACHANNEL_SETTING_MUTE: /* General - muting flags */
@@ -5176,7 +5176,7 @@ void ANIM_channel_draw_widgets(const bContext *C,
}
/* step 3) draw special toggles .................................
- * - in Graph Editor, checkboxes for visibility in curves area
+ * - in Graph Editor, check-boxes for visibility in curves area
* - in NLA Editor, glowing dots for solo/not solo...
* - in Grease Pencil mode, color swatches for layer color
*/
@@ -5184,12 +5184,12 @@ void ANIM_channel_draw_widgets(const bContext *C,
if ((ac->spacetype == SPACE_GRAPH) &&
(acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE) ||
acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE))) {
- /* pin toggle */
+ /* Pin toggle. */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE)) {
draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_ALWAYS_VISIBLE);
offset += ICON_WIDTH;
}
- /* visibility toggle */
+ /* Visibility toggle. */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
/* For F-curves, add the extra space for the color bands. */
if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
@@ -5462,7 +5462,6 @@ void ANIM_channel_draw_widgets(const bContext *C,
prop = RNA_struct_find_property(&ptr, "use_mask_layer");
gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop);
if (RNA_path_resolve_property(&id_ptr, gp_rna_path, &ptr, &prop)) {
- icon = ICON_LAYER_ACTIVE;
if (gpl->flag & GP_LAYER_USE_MASK) {
icon = ICON_MOD_MASK;
}
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 64082b08da9..8f8c1c067d4 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -747,7 +747,7 @@ static bool animedit_poll_channels_active(bContext *C)
return 1;
}
-/* poll callback for Animation Editor channels list region + not in NLA-tweakmode for NLA */
+/* Poll callback for Animation Editor channels list region + not in NLA-tweak-mode for NLA. */
static bool animedit_poll_channels_nla_tweakmode_off(bContext *C)
{
ScrArea *area = CTX_wm_area(C);
@@ -763,7 +763,7 @@ static bool animedit_poll_channels_nla_tweakmode_off(bContext *C)
return 0;
}
- /* NLA TweakMode test */
+ /* NLA tweak-mode test. */
if (area->spacetype == SPACE_NLA) {
if ((scene == NULL) || (scene->flag & SCE_NLA_EDIT_ON)) {
return 0;
@@ -1283,6 +1283,9 @@ static void split_groups_action_temp(bAction *act, bActionGroup *tgrp)
else {
group_fcurves_last->next->prev = group_fcurves_first->prev;
}
+
+ /* Clear links pointing outside the per-group list. */
+ group_fcurves_first->prev = group_fcurves_last->next = NULL;
}
/* Initialize memory for temp-group */
@@ -1337,22 +1340,12 @@ static void join_groups_action_temp(bAction *act)
if (agrp->flag & AGRP_TEMP) {
LISTBASE_FOREACH (FCurve *, fcu, &agrp->channels) {
fcu->grp = NULL;
- if (fcu == agrp->channels.last) {
- break;
- }
}
BLI_remlink(&act->groups, agrp);
break;
}
}
-
- /* BLI_movelisttolist() doesn't touch first->prev and last->next pointers in its "dst" list.
- * Ensure that after the reshuffling the list is properly terminated. */
- FCurve *act_fcurves_first = act->curves.first;
- act_fcurves_first->prev = NULL;
- FCurve *act_fcurves_last = act->curves.last;
- act_fcurves_last->next = NULL;
}
/* Change the order of anim-channels within action
@@ -1683,7 +1676,7 @@ static void animchannels_group_channels(bAnimContext *ac,
agrp = action_groups_add_new(act, name);
BLI_assert(agrp != NULL);
- /* transfer selected F-Curves across to new group */
+ /* Transfer selected F-Curves across to new group. */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->data;
bActionGroup *grp = fcu->grp;
@@ -1724,7 +1717,7 @@ static int animchannels_group_exec(bContext *C, wmOperator *op)
bAnimListElem *ale;
int filter;
- /* handle each animdata block separately, so that the regrouping doesn't flow into blocks */
+ /* Handle each animdata block separately, so that the regrouping doesn't flow into blocks. */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA |
ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
@@ -2432,6 +2425,7 @@ static int animchannels_clean_empty_exec(bContext *C, wmOperator *UNUSED(op))
/* send notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_REMOVED, NULL);
return OPERATOR_FINISHED;
}
@@ -3441,12 +3435,14 @@ static void ANIM_OT_channels_click(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
/* properties */
- /* NOTE: don't save settings, otherwise, can end up with some weird behavior (sticky extend) */
- prop = RNA_def_boolean(ot->srna, "extend", false, "Extend Select", ""); /* SHIFTKEY */
+ /* NOTE: don't save settings, otherwise, can end up with some weird behavior (sticky extend)
+ *
+ * Key-map: Enable with `Shift`. */
+ prop = RNA_def_boolean(ot->srna, "extend", false, "Extend Select", "");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(
- ot->srna, "children_only", false, "Select Children Only", ""); /* CTRLKEY|SHIFTKEY */
+ /* Key-map: Enable with `Ctrl-Shift`. */
+ prop = RNA_def_boolean(ot->srna, "children_only", false, "Select Children Only", "");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c
index 17251587d3b..42fdb714127 100644
--- a/source/blender/editors/animation/anim_deps.c
+++ b/source/blender/editors/animation/anim_deps.c
@@ -93,9 +93,9 @@ void ANIM_list_elem_update(Main *bmain, Scene *scene, bAnimListElem *ale)
fcu = (ale->datatype == ALE_FCURVE) ? ale->key_data : NULL;
if (fcu && fcu->rna_path) {
- /* if we have an fcurve, call the update for the property we
+ /* If we have an fcurve, call the update for the property we
* are editing, this is then expected to do the proper redraws
- * and depsgraph updates */
+ * and depsgraph updates. */
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
@@ -109,8 +109,8 @@ void ANIM_list_elem_update(Main *bmain, Scene *scene, bAnimListElem *ale)
/* in other case we do standard depsgraph update, ideally
* we'd be calling property update functions here too ... */
DEG_id_tag_update(id,
- ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY |
- ID_RECALC_ANIMATION); /* XXX or do we want something more restrictive? */
+ /* XXX: or do we want something more restrictive? */
+ ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
}
}
@@ -119,11 +119,10 @@ void ANIM_list_elem_update(Main *bmain, Scene *scene, bAnimListElem *ale)
void ANIM_id_update(Main *bmain, ID *id)
{
if (id) {
- DEG_id_tag_update_ex(
- bmain,
- id,
- ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY |
- ID_RECALC_ANIMATION); /* XXX or do we want something more restrictive? */
+ DEG_id_tag_update_ex(bmain,
+ id,
+ /* XXX: or do we want something more restrictive? */
+ ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
}
}
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index aca332ff0fe..2fcd59a1bbe 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -89,7 +89,7 @@ void ANIM_draw_cfra(const bContext *C, View2D *v2d, short flag)
/* *************************************************** */
/* PREVIEW RANGE 'CURTAINS' */
-/* Note: 'Preview Range' tools are defined in anim_ops.c */
+/* NOTE: 'Preview Range' tools are defined in `anim_ops.c`. */
/* Draw preview range 'curtains' for highlighting where the animation data is */
void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width)
@@ -168,7 +168,7 @@ void ANIM_draw_framerange(Scene *scene, View2D *v2d)
}
/* *************************************************** */
-/* NLA-MAPPING UTILITIES (required for drawing and also editing keyframes) */
+/* NLA-MAPPING UTILITIES (required for drawing and also editing keyframes). */
/**
* Obtain the AnimData block providing NLA-mapping for the given channel (if applicable).
@@ -413,7 +413,7 @@ static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, flo
else {
/* Calculate min/max using full fcurve evaluation.
* [slower than bezier forward differencing but evaluates Back/Elastic interpolation
- * as well].*/
+ * 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;
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index a03f19d0111..b2d387ea898 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -32,7 +32,7 @@
* are being edited. Likewise, the NLA Editor also uses this for its channel list and in
* its operators.
*
- * Note: much of the original system this was based on was built before the creation of the RNA
+ * NOTE: much of the original system this was based on was built before the creation of the RNA
* system. In future, it would be interesting to replace some parts of this code with RNA queries,
* however, RNA does not eliminate some of the boiler-plate reduction benefits presented by this
* system, so if any such work does occur, it should only be used for the internals used here...
@@ -131,7 +131,7 @@ static void animedit_get_yscale_factor(bAnimContext *ac)
/* ----------- Private Stuff - Action Editor ------------- */
/* Get shapekey data being edited (for Action Editor -> ShapeKey mode) */
-/* Note: there's a similar function in key.c (BKE_key_from_object) */
+/* NOTE: there's a similar function in key.c #BKE_key_from_object. */
static Key *actedit_get_shapekeys(bAnimContext *ac)
{
ViewLayer *view_layer = ac->view_layer;
@@ -222,9 +222,9 @@ static bool actedit_get_context(bAnimContext *ac, SpaceAction *saction)
ac->mode = saction->mode;
return true;
- case SACTCONT_MASK: /* Mask */ /* XXX review how this mode is handled... */
+ case SACTCONT_MASK: /* Mask */ /* XXX: review how this mode is handled. */
{
- /* TODO, other methods to get the mask */
+ /* TODO: other methods to get the mask. */
#if 0
Sequence *seq = SEQ_select_active_get(ac->scene);
MovieClip *clip = ac->scene->clip;
@@ -454,7 +454,7 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
* keep expander channels with no sub-data out, as those cases should get
* dealt with by the recursive detection idiom in place.
*
- * Implementation Note:
+ * Implementation NOTE:
* YES the _doSubChannels variable is NOT read anywhere. BUT, this is NOT an excuse
* to go steamrolling the logic into a single-line expression as from experience,
* those are notoriously difficult to read + debug when extending later on. The code
@@ -1217,7 +1217,7 @@ static bool skip_fcurve_with_name(
*
* \return true if F-Curve has errors/is disabled
*/
-static bool fcurve_has_errors(FCurve *fcu)
+static bool fcurve_has_errors(const FCurve *fcu)
{
/* F-Curve disabled - path eval error */
if (fcu->flag & FCURVE_DISABLED) {
@@ -1226,7 +1226,7 @@ static bool fcurve_has_errors(FCurve *fcu)
/* driver? */
if (fcu->driver) {
- ChannelDriver *driver = fcu->driver;
+ const ChannelDriver *driver = fcu->driver;
DriverVar *dvar;
/* error flag on driver usually means that there is an error
@@ -3132,7 +3132,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_m
/* check selection and object type filters */
if ((ads->filterflag & ADS_FILTER_ONLYSEL) &&
- !((base->flag & BASE_SELECTED) /*|| (base == sce->basact)*/)) {
+ !((base->flag & BASE_SELECTED) /*|| (base == sce->basact) */)) {
/* only selected should be shown */
return false;
}
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 7adddf8f4ae..9d998326b4d 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -687,7 +687,7 @@ static int ed_marker_add_exec(bContext *C, wmOperator *UNUSED(op))
marker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
marker->flag = SELECT;
marker->frame = frame;
- BLI_snprintf(marker->name, sizeof(marker->name), "F_%02d", frame); /* XXX - temp code only */
+ BLI_snprintf(marker->name, sizeof(marker->name), "F_%02d", frame); /* XXX: temp code only. */
BLI_addtail(markers, marker);
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
@@ -897,7 +897,7 @@ static int ed_marker_move_invoke(bContext *C, wmOperator *op, const wmEvent *eve
return OPERATOR_CANCELLED;
}
-/* note, init has to be called successfully */
+/* NOTE: init has to be called successfully. */
static void ed_marker_move_apply(bContext *C, wmOperator *op)
{
#ifdef DURIAN_CAMERA_SWITCH
diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c
index aac2465d43a..51a897600e1 100644
--- a/source/blender/editors/animation/anim_motion_paths.c
+++ b/source/blender/editors/animation/anim_motion_paths.c
@@ -355,7 +355,7 @@ static void motionpath_free_free_tree_data(ListBase *targets)
/* Perform baking of the given object's and/or its bones' transforms to motion paths
* - scene: current scene
- * - ob: object whose flagged motionpaths should get calculated
+ * - ob: object whose flagged motion-paths should get calculated
* - recalc: whether we need to
*/
/* TODO: include reports pointer? */
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index 72d9bff545a..6f3277397c5 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -51,8 +51,10 @@
#include "DEG_depsgraph.h"
+#include "SEQ_iterator.h"
#include "SEQ_sequencer.h"
#include "SEQ_time.h"
+#include "SEQ_transform.h"
#include "anim_intern.h"
@@ -81,6 +83,49 @@ static bool change_frame_poll(bContext *C)
return false;
}
+static int seq_snap_threshold_get_frame_distance(bContext *C)
+{
+ const int snap_distance = SEQ_tool_settings_snap_distance_get(CTX_data_scene(C));
+ const ARegion *region = CTX_wm_region(C);
+ return round_fl_to_int(UI_view2d_region_to_view_x(&region->v2d, snap_distance) -
+ UI_view2d_region_to_view_x(&region->v2d, 0));
+}
+
+static void seq_frame_snap_update_best(const int position,
+ const int timeline_frame,
+ int *r_best_frame,
+ int *r_best_distance)
+{
+ if (abs(position - timeline_frame) < *r_best_distance) {
+ *r_best_distance = abs(position - timeline_frame);
+ *r_best_frame = position;
+ }
+}
+
+static int seq_frame_apply_snap(bContext *C, Scene *scene, const int timeline_frame)
+{
+
+ ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene, false));
+ SeqCollection *strips = SEQ_query_all_strips(seqbase);
+
+ int best_frame = 0;
+ int best_distance = MAXFRAME;
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, strips) {
+ seq_frame_snap_update_best(
+ SEQ_transform_get_left_handle_frame(seq), timeline_frame, &best_frame, &best_distance);
+ seq_frame_snap_update_best(
+ SEQ_transform_get_right_handle_frame(seq), timeline_frame, &best_frame, &best_distance);
+ }
+ SEQ_collection_free(strips);
+
+ if (best_distance < seq_snap_threshold_get_frame_distance(C)) {
+ return best_frame;
+ }
+
+ return timeline_frame;
+}
+
/* Set the new frame number */
static void change_frame_apply(bContext *C, wmOperator *op)
{
@@ -90,7 +135,7 @@ static void change_frame_apply(bContext *C, wmOperator *op)
if (do_snap) {
if (CTX_wm_space_seq(C)) {
- frame = SEQ_time_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false);
+ frame = seq_frame_apply_snap(C, scene, frame);
}
else {
frame = BKE_scene_frame_snap_by_seconds(scene, 1.0, frame);
@@ -181,6 +226,18 @@ static void change_frame_seq_preview_end(bContext *C)
}
}
+static bool use_sequencer_snapping(bContext *C)
+{
+ if (!CTX_wm_space_seq(C)) {
+ return false;
+ }
+
+ Scene *scene = CTX_data_scene(C);
+ short snap_flag = SEQ_tool_settings_snap_flag_get(scene);
+ return (scene->toolsettings->snap_flag & SCE_SNAP_SEQ) &&
+ (snap_flag & SEQ_SNAP_CURRENT_FRAME_TO_STRIPS);
+}
+
/* Modal Operator init */
static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
@@ -190,6 +247,10 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event
*/
RNA_float_set(op->ptr, "frame", frame_from_event(C, event));
+ if (use_sequencer_snapping(C)) {
+ RNA_boolean_set(op->ptr, "snap", true);
+ }
+
change_frame_seq_preview_begin(C, event);
change_frame_apply(C, op);
@@ -231,11 +292,22 @@ static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
case EVT_LEFTCTRLKEY:
case EVT_RIGHTCTRLKEY:
- if (event->val == KM_RELEASE) {
- RNA_boolean_set(op->ptr, "snap", false);
+ /* Use Ctrl key to invert snapping in sequencer. */
+ if (use_sequencer_snapping(C)) {
+ if (event->val == KM_RELEASE) {
+ RNA_boolean_set(op->ptr, "snap", true);
+ }
+ else if (event->val == KM_PRESS) {
+ RNA_boolean_set(op->ptr, "snap", false);
+ }
}
- else if (event->val == KM_PRESS) {
- RNA_boolean_set(op->ptr, "snap", true);
+ else {
+ if (event->val == KM_RELEASE) {
+ RNA_boolean_set(op->ptr, "snap", false);
+ }
+ else if (event->val == KM_PRESS) {
+ RNA_boolean_set(op->ptr, "snap", true);
+ }
}
break;
}
@@ -465,7 +537,7 @@ static void ANIM_OT_previewrange_set(wmOperatorType *ot)
/* rna */
/* used to define frame range.
*
- * note: border Y values are not used,
+ * NOTE: border Y values are not used,
* but are needed by box_select gesture operator stuff */
WM_operator_properties_border(ot);
}
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 43d5efe9ea9..bfaa76b3bf9 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -80,7 +80,7 @@ FCurve *verify_driver_fcurve(ID *id,
/* init animdata if none available yet */
adt = BKE_animdata_from_id(id);
if (adt == NULL && creation_mode != DRIVER_FCURVE_LOOKUP_ONLY) {
- adt = BKE_animdata_add_id(id);
+ adt = BKE_animdata_ensure_id(id);
}
if (adt == NULL) {
/* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
@@ -568,7 +568,7 @@ bool ANIM_remove_driver(ReportList *UNUSED(reports),
FCurve *fcu_iter = adt->drivers.first;
while ((fcu = BKE_fcurve_iter_step(fcu_iter, rna_path)) != NULL) {
- /* store the next fcurve for looping */
+ /* Store the next fcurve for looping. */
fcu_iter = fcu->next;
/* remove F-Curve from driver stack, then free it */
@@ -581,7 +581,7 @@ bool ANIM_remove_driver(ReportList *UNUSED(reports),
}
else {
/* find the matching driver and remove it only
- * Note: here is one of the places where we don't want new F-Curve + Driver added!
+ * NOTE: here is one of the places where we don't want new F-Curve + Driver added!
* so 'add' var must be 0
*/
fcu = verify_driver_fcurve(id, rna_path, array_index, DRIVER_FCURVE_LOOKUP_ONLY);
@@ -1253,7 +1253,7 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op)
}
}
- /* since we're just copying, we don't really need to do anything else...*/
+ /* Since we're just copying, we don't really need to do anything else. */
return (changed) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -1303,7 +1303,7 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op)
}
}
- /* since we're just copying, we don't really need to do anything else...*/
+ /* Since we're just copying, we don't really need to do anything else. */
return (changed) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index 653bd72b364..31552330071 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -246,7 +246,7 @@ static PanelType *fmodifier_subpanel_register(ARegionType *region_type,
#define B_REDR 1
#define B_FMODIFIER_REDRAW 20
-/* callback to remove the given modifier */
+/* Callback to remove the given modifier. */
typedef struct FModifierDeleteContext {
ID *owner_id;
ListBase *modifiers;
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 636f0d3cbea..0923d490110 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -251,7 +251,7 @@ static short ob_keyframes_loop(KeyframeEditData *ked,
ANIM_animdata_freelist(&anim_data);
- /* return return code - defaults to zero if nothing happened */
+ /* Return the return code (defaults to zero if nothing happened). */
return ret;
}
@@ -300,7 +300,7 @@ static short scene_keyframes_loop(KeyframeEditData *ked,
ANIM_animdata_freelist(&anim_data);
- /* return return code - defaults to zero if nothing happened */
+ /* Return the return code (defaults to zero if nothing happened). */
return ret;
}
@@ -1024,7 +1024,7 @@ static short mirror_bezier_value(KeyframeEditData *ked, BezTriple *bezt)
return 0;
}
-/* Note: for markers and 'value', the values to use must be supplied as the first float value */
+/* NOTE: for markers and 'value', the values to use must be supplied as the first float value. */
/* calchandles_fcurve */
KeyframeEditFunc ANIM_editkeyframes_mirror(short mode)
{
@@ -1109,7 +1109,7 @@ static short set_bezier_auto_clamped(KeyframeEditData *UNUSED(ked), BezTriple *b
return 0;
}
-/* Sets the selected bezier handles to type 'vector' */
+/* Sets the selected bezier handles to type 'vector'. */
static short set_bezier_vector(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
/* If the key is selected, always apply to both handles. */
@@ -1164,7 +1164,7 @@ static short set_bezier_align(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
return 0;
}
-/* Sets selected bezier handles to type 'free' */
+/* Sets selected bezier handles to type 'free'. */
static short set_bezier_free(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
/* If the key is selected, always apply to both handles. */
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index 87291974e08..eb91afa5c84 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -193,7 +193,7 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo
BezTriple *lastb;
int totCount, i;
- /* check if any points */
+ /* Check if any points. */
if ((fcu == NULL) || (fcu->bezt == NULL) || (fcu->totvert == 0) ||
(!cleardefault && fcu->totvert == 1)) {
return;
@@ -408,7 +408,7 @@ bool decimate_fcurve(bAnimListElem *ale, float remove_ratio, float error_sq_max)
{
FCurve *fcu = (FCurve *)ale->key_data;
- /* Check if the curve actually has any points */
+ /* Check if the curve actually has any points. */
if (fcu == NULL || fcu->bezt == NULL || fcu->totvert == 0) {
return true;
}
@@ -588,7 +588,7 @@ typedef struct TempFrameValCache {
float frame, val;
} TempFrameValCache;
-/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
+/* Evaluates the curves between each selected keyframe on each frame, and keys the value. */
void sample_fcurve(FCurve *fcu)
{
BezTriple *bezt, *start = NULL, *end = NULL;
@@ -600,7 +600,7 @@ void sample_fcurve(FCurve *fcu)
return;
}
- /* find selected keyframes... once pair has been found, add keyframes */
+ /* Find selected keyframes... once pair has been found, add keyframes. */
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
/* check if selected, and which end this is */
if (BEZT_ISSEL_ANY(bezt)) {
@@ -693,7 +693,7 @@ typedef struct tAnimCopybufItem {
int totvert; /* number of keyframes stored for this channel */
BezTriple *bezt; /* keyframes in buffer */
- short id_type; /* Result of GS(id->name)*/
+ short id_type; /* Result of `GS(id->name)`. */
bool is_bone; /* special flag for armature bones */
} tAnimCopybufItem;
@@ -913,7 +913,7 @@ static tAnimCopybufItem *pastebuf_match_path_property(Main *bmain,
if (aci->rna_path && fcu->rna_path) {
/* find the property of the fcurve and compare against the end of the tAnimCopybufItem
* more involved since it needs to do path lookups.
- * This is not 100% reliable since the user could be editing the curves on a path that wont
+ * This is not 100% reliable since the user could be editing the curves on a path that won't
* resolve, or a bone could be renamed after copying for eg. but in normal copy & paste
* this should work out ok.
*/
@@ -932,7 +932,7 @@ static tAnimCopybufItem *pastebuf_match_path_property(Main *bmain,
int len_id = strlen(identifier);
int len_path = strlen(fcu->rna_path);
if (len_id <= len_path) {
- /* note, paths which end with "] will fail with this test - Animated ID Props */
+ /* NOTE: paths which end with "] will fail with this test - Animated ID Props. */
if (STREQ(identifier, fcu->rna_path + (len_path - len_id))) {
if ((from_single) || (aci->array_index == fcu->array_index)) {
break;
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index f229d48b4eb..0a499232ba9 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -85,6 +85,8 @@ static KeyingSet *keyingset_get_from_op_with_error(wmOperator *op,
PropertyRNA *prop,
Scene *scene);
+static int delete_key_using_keying_set(bContext *C, wmOperator *op, KeyingSet *ks);
+
/* ************************************************** */
/* Keyframing Setting Wrangling */
@@ -140,7 +142,7 @@ bAction *ED_id_action_ensure(Main *bmain, ID *id)
/* init animdata if none available yet */
adt = BKE_animdata_from_id(id);
if (adt == NULL) {
- adt = BKE_animdata_add_id(id);
+ adt = BKE_animdata_ensure_id(id);
}
if (adt == NULL) {
/* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
@@ -952,7 +954,7 @@ static bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
case CONSTRAINT_TYPE_KINEMATIC:
return true;
- /* single-transform constraints */
+ /* Single-transform constraints. */
case CONSTRAINT_TYPE_TRACKTO:
if (searchtype == VISUALKEY_ROT) {
return true;
@@ -1672,7 +1674,7 @@ int delete_keyframe(Main *bmain,
}
/* get F-Curve
- * Note: here is one of the places where we don't want new Action + F-Curve added!
+ * NOTE: here is one of the places where we don't want new Action + F-Curve added!
* so 'add' var must be 0
*/
if (act == NULL) {
@@ -1779,7 +1781,7 @@ static int clear_keyframe(Main *bmain,
}
/* get F-Curve
- * Note: here is one of the places where we don't want new Action + F-Curve added!
+ * NOTE: here is one of the places where we don't want new Action + F-Curve added!
* so 'add' var must be 0
*/
if (act == NULL) {
@@ -2079,42 +2081,19 @@ void ANIM_OT_keyframe_insert_menu(wmOperatorType *ot)
static int delete_key_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- float cfra = (float)CFRA; /* XXX for now, don't bother about all the yucky offset crap */
- int num_channels;
-
KeyingSet *ks = keyingset_get_from_op_with_error(op, op->type->prop, scene);
if (ks == NULL) {
return OPERATOR_CANCELLED;
}
- const int prop_type = RNA_property_type(op->type->prop);
- if (prop_type == PROP_ENUM) {
- int type = RNA_property_enum_get(op->ptr, op->type->prop);
- ks = ANIM_keyingset_get_from_enum_type(scene, type);
- if (ks == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No active Keying Set");
- return OPERATOR_CANCELLED;
- }
- }
- else if (prop_type == PROP_STRING) {
- char type_id[MAX_ID_NAME - 2];
- RNA_property_string_get(op->ptr, op->type->prop, type_id);
- ks = ANIM_keyingset_get_from_idname(scene, type_id);
-
- if (ks == NULL) {
- BKE_reportf(op->reports, RPT_ERROR, "Active Keying Set '%s' not found", type_id);
- return OPERATOR_CANCELLED;
- }
- }
- else {
- BLI_assert(0);
- }
+ return delete_key_using_keying_set(C, op, ks);
+}
- /* report failure */
- if (ks == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No active Keying Set");
- return OPERATOR_CANCELLED;
- }
+static int delete_key_using_keying_set(bContext *C, wmOperator *op, KeyingSet *ks)
+{
+ Scene *scene = CTX_data_scene(C);
+ float cfra = (float)CFRA; /* XXX for now, don't bother about all the yucky offset crap */
+ int num_channels;
/* try to delete keyframes for the channels specified by KeyingSet */
num_channels = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_DELETE, cfra);
@@ -2130,7 +2109,8 @@ static int delete_key_exec(bContext *C, wmOperator *op)
if (num_channels > 0) {
/* if the appropriate properties have been set, make a note that we've inserted something */
- if (RNA_boolean_get(op->ptr, "confirm_success")) {
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "confirm_success");
+ if (prop != NULL && RNA_property_boolean_get(op->ptr, prop)) {
BKE_reportf(op->reports,
RPT_INFO,
"Successfully removed %d keyframes for keying set '%s'",
@@ -2244,7 +2224,7 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
MEM_freeN(bone_name);
- /* delete if bone is selected*/
+ /* Delete if bone is selected. */
if ((pchan) && (pchan->bone)) {
if (pchan->bone->flag & BONE_SELECTED) {
can_delete = true;
@@ -2301,7 +2281,7 @@ void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int delete_key_v3d_exec(bContext *C, wmOperator *op)
+static int delete_key_v3d_without_keying_set(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
float cfra = (float)CFRA;
@@ -2408,6 +2388,18 @@ static int delete_key_v3d_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static int delete_key_v3d_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ KeyingSet *ks = ANIM_scene_get_active_keyingset(scene);
+
+ if (ks == NULL) {
+ return delete_key_v3d_without_keying_set(C, op);
+ }
+
+ return delete_key_using_keying_set(C, op, ks);
+}
+
void ANIM_OT_keyframe_delete_v3d(wmOperatorType *ot)
{
/* identifiers */
@@ -2810,14 +2802,14 @@ bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
/* --------------- API/Per-Datablock Handling ------------------- */
/* Checks if some F-Curve has a keyframe for a given frame */
-bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter)
+bool fcurve_frame_has_keyframe(const FCurve *fcu, float frame, short filter)
{
/* quick sanity check */
if (ELEM(NULL, fcu, fcu->bezt)) {
return false;
}
- /* we either include all regardless of muting, or only non-muted */
+ /* We either include all regardless of muting, or only non-muted. */
if ((filter & ANIMFILTER_KEYS_MUTED) || (fcu->flag & FCURVE_MUTED) == 0) {
bool replace;
int i = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, frame, fcu->totvert, &replace);
@@ -2931,7 +2923,7 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter)
}
/* 2. test for time */
- /* TODO... yet to be implemented (this feature may evolve before then anyway) */
+ /* TODO: yet to be implemented (this feature may evolve before then anyway). */
}
/* try materials */
@@ -3101,7 +3093,7 @@ bool ED_autokeyframe_property(
ToolSettings *ts = scene->toolsettings;
const eInsertKeyFlags flag = ANIM_get_keyframing_flags(scene, true);
- /* Note: We use rnaindex instead of fcu->array_index,
+ /* NOTE: We use rnaindex instead of fcu->array_index,
* because a button may control all items of an array at once.
* E.g., color wheels (see T42567). */
BLI_assert((fcu->array_index == rnaindex) || (rnaindex == -1));
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index fda7b600c1c..0206aabd359 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -529,7 +529,7 @@ void ANIM_OT_keying_set_active_set(wmOperatorType *ot)
/* Keying Set Type Info declarations */
static ListBase keyingset_type_infos = {NULL, NULL};
-/* Built-In Keying Sets (referencing type infos)*/
+/* Built-In Keying Sets (referencing type information). */
ListBase builtin_keyingsets = {NULL, NULL};
/* --------------- */
diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c
index 034378399b9..6af033f3cf2 100644
--- a/source/blender/editors/animation/time_scrub_ui.c
+++ b/source/blender/editors/animation/time_scrub_ui.c
@@ -109,7 +109,7 @@ static void draw_current_frame(const Scene *scene,
if (draw_line) {
/* Draw vertical line to from the bottom of the current frame box to the bottom of the screen.
*/
- const float subframe_x = UI_view2d_view_to_region_x(v2d, BKE_scene_frame_get(scene));
+ const float subframe_x = UI_view2d_view_to_region_x(v2d, BKE_scene_ctime_get(scene));
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index 3902f6613a1..45bf18fe1bb 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -89,15 +89,14 @@ EditBone *ED_armature_ebone_add(bArmature *arm, const char *name)
bone->roll1 = 0.0f;
bone->roll2 = 0.0f;
bone->curve_in_x = 0.0f;
- bone->curve_in_y = 0.0f;
+ bone->curve_in_z = 0.0f;
bone->curve_out_x = 0.0f;
- bone->curve_out_y = 0.0f;
+ bone->curve_out_z = 0.0f;
bone->ease1 = 1.0f;
bone->ease2 = 1.0f;
- bone->scale_in_x = 1.0f;
- bone->scale_in_y = 1.0f;
- bone->scale_out_x = 1.0f;
- bone->scale_out_y = 1.0f;
+
+ copy_v3_fl(bone->scale_in, 1.0f);
+ copy_v3_fl(bone->scale_out, 1.0f);
return bone;
}
@@ -226,7 +225,7 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
static int armature_click_extrude_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- /* TODO most of this code is copied from set3dcursor_invoke,
+ /* TODO: most of this code is copied from set3dcursor_invoke,
* it would be better to reuse code in set3dcursor_invoke */
/* temporarily change 3d cursor position */
@@ -439,17 +438,15 @@ static void updateDuplicateSubtarget(EditBone *dup_bone,
}
}
-static void updateDuplicateActionConstraintSettings(EditBone *dup_bone,
- EditBone *orig_bone,
- Object *ob,
- bConstraint *curcon)
+static void updateDuplicateActionConstraintSettings(
+ EditBone *dup_bone, EditBone *orig_bone, Object *ob, bPoseChannel *pchan, bConstraint *curcon)
{
bActionConstraint *act_con = (bActionConstraint *)curcon->data;
bAction *act = (bAction *)act_con->act;
float mat[4][4];
- bConstraintOb cob = {.depsgraph = NULL, .scene = NULL, .ob = ob, .pchan = NULL};
+ bConstraintOb cob = {.depsgraph = NULL, .scene = NULL, .ob = ob, .pchan = pchan};
BKE_constraint_custom_object_space_get(cob.space_obj_world_matrix, curcon);
unit_m4(mat);
@@ -833,7 +830,7 @@ static void updateDuplicateConstraintSettings(EditBone *dup_bone, EditBone *orig
for (curcon = conlist->first; curcon; curcon = curcon->next) {
switch (curcon->type) {
case CONSTRAINT_TYPE_ACTION:
- updateDuplicateActionConstraintSettings(dup_bone, orig_bone, ob, curcon);
+ updateDuplicateActionConstraintSettings(dup_bone, orig_bone, ob, pchan, curcon);
break;
case CONSTRAINT_TYPE_KINEMATIC:
updateDuplicateKinematicConstraintSettings(curcon);
@@ -1265,6 +1262,10 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op)
ebone->bbone_prev_type = ebone_iter->bbone_prev_type;
ebone->bbone_next_type = ebone_iter->bbone_next_type;
+ ebone->bbone_flag = ebone_iter->bbone_flag;
+ ebone->bbone_prev_flag = ebone_iter->bbone_prev_flag;
+ ebone->bbone_next_flag = ebone_iter->bbone_next_flag;
+
/* Lets try to fix any constraint subtargets that might
* have been duplicated
*/
@@ -1464,15 +1465,14 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
newbone->roll1 = ebone->roll1;
newbone->roll2 = ebone->roll2;
newbone->curve_in_x = ebone->curve_in_x;
- newbone->curve_in_y = ebone->curve_in_y;
+ newbone->curve_in_z = ebone->curve_in_z;
newbone->curve_out_x = ebone->curve_out_x;
- newbone->curve_out_y = ebone->curve_out_y;
+ newbone->curve_out_z = ebone->curve_out_z;
newbone->ease1 = ebone->ease1;
newbone->ease2 = ebone->ease2;
- newbone->scale_in_x = ebone->scale_in_x;
- newbone->scale_in_y = ebone->scale_in_y;
- newbone->scale_out_x = ebone->scale_out_x;
- newbone->scale_out_y = ebone->scale_out_y;
+
+ copy_v3_v3(newbone->scale_in, ebone->scale_in);
+ copy_v3_v3(newbone->scale_out, ebone->scale_out);
BLI_strncpy(newbone->name, ebone->name, sizeof(newbone->name));
@@ -1556,7 +1556,7 @@ void ARMATURE_OT_extrude(wmOperatorType *ot)
/* ********************** Bone Add *************************************/
-/*op makes a new bone and returns it with its tip selected */
+/* Op makes a new bone and returns it with its tip selected. */
static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op)
{
@@ -1601,7 +1601,7 @@ static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op)
ED_armature_edit_refresh_layer_used(obedit->data);
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
DEG_id_tag_update(&obedit->id, ID_RECALC_SELECT);
ED_outliner_select_sync_from_edit_bone_tag(C);
@@ -1692,7 +1692,7 @@ static int armature_subdivide_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
DEG_id_tag_update(&obedit->id, ID_RECALC_SELECT);
ED_outliner_select_sync_from_edit_bone_tag(C);
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index 912aafbd6e3..ea6c71fd33f 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -228,7 +228,7 @@ float ED_armature_ebone_roll_to_vector(const EditBone *bone,
return roll;
}
-/* note, ranges arithmetic is used below */
+/* NOTE: ranges arithmetic is used below. */
typedef enum eCalcRollTypes {
/* pos */
CALC_ROLL_POS_X = 0,
@@ -449,7 +449,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
}
if (changed) {
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
DEG_id_tag_update(&arm->id, ID_RECALC_SELECT);
}
@@ -519,7 +519,7 @@ static int armature_roll_clear_exec(bContext *C, wmOperator *op)
}
if (changed) {
- /* Note, notifier might evolve. */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
DEG_id_tag_update(&arm->id, ID_RECALC_SELECT);
}
@@ -577,7 +577,7 @@ static void chains_find_tips(ListBase *edbo, ListBase *list)
EditBone *curBone, *ebo;
LinkData *ld;
- /* note: this is potentially very slow ... there's got to be a better way */
+ /* NOTE: this is potentially very slow ... there's got to be a better way. */
for (curBone = edbo->first; curBone; curBone = curBone->next) {
short stop = 0;
@@ -1000,7 +1000,7 @@ static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
armature_clear_swap_done_flags(arm);
armature_tag_unselect(arm);
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
DEG_id_tag_update(&arm->id, ID_RECALC_SELECT);
}
@@ -1030,7 +1030,7 @@ void ARMATURE_OT_switch_direction(wmOperatorType *ot)
/** \name Align Operator
* \{ */
-/* helper to fix a ebone position if its parent has moved due to alignment*/
+/* Helper to fix a ebone position if its parent has moved due to alignment. */
static void fix_connected_bone(EditBone *ebone)
{
float diff[3];
@@ -1073,9 +1073,9 @@ static void bone_align_to_bone(ListBase *edbo, EditBone *selbone, EditBone *actb
add_v3_v3v3(selbone->tail, selbone->head, actboneaxis);
selbone->roll = actbone->roll;
- /* if the bone being aligned has connected descendants they must be moved
+ /* If the bone being aligned has connected descendants they must be moved
* according to their parent new position, otherwise they would be left
- * in an inconsistent state: connected but away from the parent*/
+ * in an inconsistent state: connected but away from the parent. */
fix_editbone_connected_children(edbo, selbone);
}
@@ -1107,7 +1107,7 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op)
}
}
- /* if there is only 1 selected bone, we assume that that is the active bone,
+ /* if there is only 1 selected bone, we assume that it is the active bone,
* since a user will need to have clicked on a bone (thus selecting it) to make it active
*/
num_selected_bones = CTX_DATA_COUNT(C, selected_editable_bones);
@@ -1151,7 +1151,7 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op)
op->reports, RPT_INFO, "%d bones aligned to bone '%s'", num_selected_bones, actbone->name);
}
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
DEG_id_tag_update(&arm->id, ID_RECALC_SELECT);
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index 4fff2ae03b0..d429e51061b 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -161,11 +161,11 @@ typedef struct tPChanFCurveLink {
/** old bbone values (to be restored along with the transform properties) */
float roll1, roll2;
/** (NOTE: we haven't renamed these this time, as their names are already long enough) */
- float curve_in_x, curve_in_y;
- float curve_out_x, curve_out_y;
+ float curve_in_x, curve_in_z;
+ float curve_out_x, curve_out_z;
float ease1, ease2;
- float scale_in_x, scale_in_y;
- float scale_out_x, scale_out_y;
+ float scale_in[3];
+ float scale_out[3];
/** copy of custom properties at start of operator (to be restored before each modal step) */
struct IDProperty *oldprops;
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index 70154695dcd..35bd30377c8 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -69,7 +69,7 @@
/** \name Unique Bone Name Utility (Edit Mode)
* \{ */
-/* note: there's a ed_armature_bone_unique_name() too! */
+/* NOTE: there's a ed_armature_bone_unique_name() too! */
static bool editbone_unique_check(void *arg, const char *name)
{
struct {
@@ -589,7 +589,7 @@ static int armature_autoside_names_exec(bContext *C, wmOperator *op)
/* Since we renamed stuff... */
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- /* Note, notifier might evolve. */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
}
MEM_freeN(objects);
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index 66ca38ce218..32fd1c9ad41 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -457,7 +457,7 @@ static void separated_armature_fix_links(Main *bmain, Object *origArm, Object *n
bConstraint *con;
ListBase *opchans, *npchans;
- /* get reference to list of bones in original and new armatures */
+ /* Get reference to list of bones in original and new armatures. */
opchans = &origArm->pose->chanbase;
npchans = &newArm->pose->chanbase;
@@ -576,7 +576,7 @@ static void separate_armature_bones(Main *bmain, Object *ob, const bool is_selec
/* check if bone needs to be removed */
if (is_select == (EBONE_VISIBLE(arm, curbone) && (curbone->flag & BONE_SELECTED))) {
- /* clear the bone->parent var of any bone that had this as its parent */
+ /* Clear the bone->parent var of any bone that had this as its parent. */
LISTBASE_FOREACH (EditBone *, ebo, arm->edbo) {
if (ebo->parent == curbone) {
ebo->parent = NULL;
@@ -703,7 +703,7 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
ok = true;
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob_old);
}
MEM_freeN(bases);
@@ -838,7 +838,7 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
}
}
- /* If there is only 1 selected bone, we assume that that is the active bone,
+ /* If there is only 1 selected bone, we assume that it is the active bone,
* since a user will need to have clicked on a bone (thus selecting it) to make it active. */
bool is_active_only_selected = false;
if (actbone->flag & BONE_SELECTED) {
@@ -893,7 +893,7 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
}
}
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
DEG_id_tag_update(&ob->id, ID_RECALC_SELECT);
@@ -1004,7 +1004,7 @@ static int armature_parent_clear_exec(bContext *C, wmOperator *op)
ED_armature_edit_sync_selection(arm->edbo);
- /* Note, notifier might evolve. */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
}
MEM_freeN(objects);
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index 65f30c3729f..bd799c00373 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -1426,7 +1426,7 @@ static void armature_select_more_less(Object *ob, bool more)
bArmature *arm = (bArmature *)ob->data;
EditBone *ebone;
- /* XXX, eventually we shouldn't need this - campbell */
+ /* XXX(campbell): eventually we shouldn't need this. */
ED_armature_edit_sync_selection(arm->edbo);
/* count bones & store selection state */
diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c
index f86ec545712..ec5c665402b 100644
--- a/source/blender/editors/armature/armature_skinning.c
+++ b/source/blender/editors/armature/armature_skinning.c
@@ -478,7 +478,7 @@ void ED_object_vgroup_calc_from_armature(ReportList *reports,
bArmature *arm = par->data;
if (mode == ARM_GROUPS_NAME) {
- const int defbase_tot = BLI_listbase_count(&ob->defbase);
+ const int defbase_tot = BKE_object_defgroup_count(ob);
int defbase_add;
/* Traverse the bone list, trying to create empty vertex
* groups corresponding to the bone.
@@ -486,8 +486,8 @@ void ED_object_vgroup_calc_from_armature(ReportList *reports,
defbase_add = bone_looper(ob, arm->bonebase.first, NULL, vgroup_add_unique_bone_cb);
if (defbase_add) {
- /* its possible there are DWeight's outside the range of the current
- * objects deform groups, in this case the new groups wont be empty T33889. */
+ /* It's possible there are DWeights outside the range of the current
+ * object's deform groups. In this case the new groups won't be empty T33889. */
ED_vgroup_data_clamp_range(ob->data, defbase_tot);
}
}
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index 3d1d8d0d1f1..874f1b49451 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -391,7 +391,7 @@ void armature_tag_unselect(bArmature *arm)
void ED_armature_ebone_transform_mirror_update(bArmature *arm, EditBone *ebo, bool check_select)
{
- /* TODO When this function is called by property updates,
+ /* TODO: When this function is called by property updates,
* canceling the value change will not restore mirrored bone correctly. */
/* Currently check_select==true when this function is called from a transform operator,
@@ -414,9 +414,8 @@ void ED_armature_ebone_transform_mirror_update(bArmature *arm, EditBone *ebo, bo
eboflip->tail[2] = ebo->tail[2];
eboflip->rad_tail = ebo->rad_tail;
eboflip->curve_out_x = -ebo->curve_out_x;
- eboflip->curve_out_y = ebo->curve_out_y;
- eboflip->scale_out_x = ebo->scale_out_x;
- eboflip->scale_out_y = ebo->scale_out_y;
+ eboflip->curve_out_z = ebo->curve_out_z;
+ copy_v3_v3(eboflip->scale_out, ebo->scale_out);
eboflip->ease2 = ebo->ease2;
eboflip->roll2 = -ebo->roll2;
@@ -438,9 +437,8 @@ void ED_armature_ebone_transform_mirror_update(bArmature *arm, EditBone *ebo, bo
eboflip->rad_head = ebo->rad_head;
eboflip->curve_in_x = -ebo->curve_in_x;
- eboflip->curve_in_y = ebo->curve_in_y;
- eboflip->scale_in_x = ebo->scale_in_x;
- eboflip->scale_in_y = ebo->scale_in_y;
+ eboflip->curve_in_z = ebo->curve_in_z;
+ copy_v3_v3(eboflip->scale_in, ebo->scale_in);
eboflip->ease1 = ebo->ease1;
eboflip->roll1 = -ebo->roll1;
@@ -542,19 +540,22 @@ static EditBone *make_boneList_recursive(ListBase *edbo,
eBone->roll1 = curBone->roll1;
eBone->roll2 = curBone->roll2;
eBone->curve_in_x = curBone->curve_in_x;
- eBone->curve_in_y = curBone->curve_in_y;
+ eBone->curve_in_z = curBone->curve_in_z;
eBone->curve_out_x = curBone->curve_out_x;
- eBone->curve_out_y = curBone->curve_out_y;
+ eBone->curve_out_z = curBone->curve_out_z;
eBone->ease1 = curBone->ease1;
eBone->ease2 = curBone->ease2;
- eBone->scale_in_x = curBone->scale_in_x;
- eBone->scale_in_y = curBone->scale_in_y;
- eBone->scale_out_x = curBone->scale_out_x;
- eBone->scale_out_y = curBone->scale_out_y;
+
+ copy_v3_v3(eBone->scale_in, curBone->scale_in);
+ copy_v3_v3(eBone->scale_out, curBone->scale_out);
eBone->bbone_prev_type = curBone->bbone_prev_type;
eBone->bbone_next_type = curBone->bbone_next_type;
+ eBone->bbone_flag = curBone->bbone_flag;
+ eBone->bbone_prev_flag = curBone->bbone_prev_flag;
+ eBone->bbone_next_flag = curBone->bbone_next_flag;
+
if (curBone->prop) {
eBone->prop = IDP_CopyProperty(curBone->prop);
}
@@ -757,19 +758,21 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm)
newBone->roll1 = eBone->roll1;
newBone->roll2 = eBone->roll2;
newBone->curve_in_x = eBone->curve_in_x;
- newBone->curve_in_y = eBone->curve_in_y;
+ newBone->curve_in_z = eBone->curve_in_z;
newBone->curve_out_x = eBone->curve_out_x;
- newBone->curve_out_y = eBone->curve_out_y;
+ newBone->curve_out_z = eBone->curve_out_z;
newBone->ease1 = eBone->ease1;
newBone->ease2 = eBone->ease2;
- newBone->scale_in_x = eBone->scale_in_x;
- newBone->scale_in_y = eBone->scale_in_y;
- newBone->scale_out_x = eBone->scale_out_x;
- newBone->scale_out_y = eBone->scale_out_y;
+ copy_v3_v3(newBone->scale_in, eBone->scale_in);
+ copy_v3_v3(newBone->scale_out, eBone->scale_out);
newBone->bbone_prev_type = eBone->bbone_prev_type;
newBone->bbone_next_type = eBone->bbone_next_type;
+ newBone->bbone_flag = eBone->bbone_flag;
+ newBone->bbone_prev_flag = eBone->bbone_prev_flag;
+ newBone->bbone_next_flag = eBone->bbone_next_flag;
+
if (eBone->prop) {
newBone->prop = IDP_CopyProperty(eBone->prop);
}
@@ -844,7 +847,7 @@ void ED_armature_to_edit(bArmature *arm)
}
/* *************************************************************** */
-/* Used by Undo for Armature EditMode*/
+/* Used by Undo for Armature EditMode. */
/* free's bones and their properties */
diff --git a/source/blender/editors/armature/editarmature_undo.c b/source/blender/editors/armature/editarmature_undo.c
index 725945f8edc..832e75b2a8b 100644
--- a/source/blender/editors/armature/editarmature_undo.c
+++ b/source/blender/editors/armature/editarmature_undo.c
@@ -206,7 +206,7 @@ static void armature_undosys_step_decode(struct bContext *C,
}
undoarm_to_editarm(&elem->data, arm);
arm->needs_flush_to_id = 1;
- DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(&arm->id, ID_RECALC_GEOMETRY);
}
/* The first element is always active */
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index f5daa427149..20d7baa39ed 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -224,7 +224,7 @@ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, ePosePathC
#endif
/* For a single frame update it's faster to re-use existing dependency graph and avoid overhead
- * of building all the relations and so on for a temporary one. */
+ * of building all the relations and so on for a temporary one. */
if (range == POSE_PATH_CALC_RANGE_CURRENT_FRAME) {
/* NOTE: Dependency graph will be evaluated at all the frames, but we first need to access some
* nested pointers, like animation data. */
@@ -318,7 +318,7 @@ static int pose_calculate_paths_exec(bContext *C, wmOperator *op)
TIMEIT_START(recalc_pose_paths);
#endif
- /* calculate the bones that now have motionpaths... */
+ /* Calculate the bones that now have motionpaths. */
/* TODO: only make for the selected bones? */
ED_pose_recalculate_paths(C, scene, ob, POSE_PATH_CALC_RANGE_FULL);
@@ -396,7 +396,7 @@ static int pose_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
- /* calculate the bones that now have motionpaths... */
+ /* Calculate the bones that now have motion-paths. */
/* TODO: only make for the selected bones? */
ED_pose_recalculate_paths(C, scene, ob, POSE_PATH_CALC_RANGE_FULL);
@@ -455,7 +455,7 @@ static void ED_pose_clear_paths(Object *ob, bool only_selected)
DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
}
-/* operator callback - wrapper for the backend function */
+/* Operator callback - wrapper for the back-end function. */
static int pose_clear_paths_exec(bContext *C, wmOperator *op)
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
@@ -567,7 +567,7 @@ static int pose_flip_names_exec(bContext *C, wmOperator *op)
/* since we renamed stuff... */
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
}
FOREACH_OBJECT_IN_MODE_END;
@@ -618,7 +618,7 @@ static int pose_autoside_names_exec(bContext *C, wmOperator *op)
/* since we renamed stuff... */
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
ob_prev = ob;
}
@@ -663,7 +663,7 @@ static int pose_bone_rotmode_exec(bContext *C, wmOperator *op)
const int mode = RNA_enum_get(op->ptr, "type");
Object *prev_ob = NULL;
- /* set rotation mode of selected bones */
+ /* Set rotation mode of selected bones. */
CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, selected_pose_bones, Object *, ob) {
/* use API Method for conversions... */
BKE_rotMode_change_values(
@@ -760,7 +760,7 @@ static int pose_armature_layers_showall_exec(bContext *C, wmOperator *op)
RNA_boolean_set_array(&ptr, "layers", layers);
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
@@ -833,7 +833,7 @@ static int armature_layers_exec(bContext *C, wmOperator *op)
RNA_id_pointer_create((ID *)arm, &ptr);
RNA_boolean_set_array(&ptr, "layers", layers);
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
@@ -919,7 +919,7 @@ static int pose_bone_layers_exec(bContext *C, wmOperator *op)
RNA_boolean_set_array(&ptr, "layers", layers);
if (prev_ob != ob) {
- /* Note, notifier might evolve. */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
DEG_id_tag_update((ID *)ob->data, ID_RECALC_COPY_ON_WRITE);
prev_ob = ob;
@@ -998,7 +998,7 @@ static int armature_bone_layers_exec(bContext *C, wmOperator *op)
ED_armature_edit_refresh_layer_used(ob->data);
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index 21fcbf8886b..df3550d5db6 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -516,7 +516,7 @@ static int poselib_add_exec(bContext *C, wmOperator *op)
/* use Keying Set to determine what to store for the pose */
- /* this includes custom props :)*/
+ /* This includes custom props :). */
ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_WHOLE_CHARACTER_SELECTED_ID);
ANIM_apply_keyingset(C, NULL, act, ks, MODIFYKEY_MODE_INSERT, (float)frame);
@@ -863,7 +863,7 @@ typedef struct tPoseLib_PreviewData {
/** active area. */
ScrArea *area;
- /** RNA-Pointer to Object 'ob' .*/
+ /** RNA-Pointer to Object 'ob'. */
PointerRNA rna_ptr;
/** object to work on. */
Object *ob;
@@ -1100,7 +1100,7 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, tPoseLib_PreviewData
/* start tagging/keying */
for (agrp = act->groups.first; agrp; agrp = agrp->next) {
- /* only for selected bones unless there aren't any selected, in which case all are included */
+ /* Only for selected bones unless there aren't any selected, in which case all are included. */
pchan = BKE_pose_channel_find_name(pose, agrp->name);
if (pchan) {
@@ -1462,7 +1462,7 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con
pld->state = PL_PREVIEW_CONFIRM;
break;
- /* toggle between original pose and poselib pose*/
+ /* Toggle between original pose and poselib pose. */
case EVT_TABKEY:
pld->flag |= PL_PREVIEW_SHOWORIGINAL;
pld->redraw = PL_PREVIEW_REDRAWALL;
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 8fc06a5f962..c39fcb790dd 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -69,7 +69,7 @@
/* ***************** Pose Select Utilities ********************* */
-/* Note: SEL_TOGGLE is assumed to have already been handled! */
+/* NOTE: SEL_TOGGLE is assumed to have already been handled! */
static void pose_do_bone_select(bPoseChannel *pchan, const int select_mode)
{
/* select pchan only if selectable, but deselect works always */
@@ -161,9 +161,9 @@ void ED_armature_pose_select_pick_bone(ViewLayer *view_layer,
/* Since we do unified select, we don't shift+select a bone if the
* armature object was not active yet.
- * Note, special exception for armature mode so we can do multi-select
+ * NOTE(campbell): special exception for armature mode so we can do multi-select
* we could check for multi-select explicitly but think its fine to
- * always give predictable behavior in weight paint mode - campbell */
+ * always give predictable behavior in weight paint mode. */
if ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) == 0)) {
/* When we are entering into posemode via toggle-select,
* from another active object - always select the bone. */
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index f7b54b79601..1a1685e4a01 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -19,6 +19,28 @@
/** \file
* \ingroup edarmature
+ *
+ * Pose 'Sliding' Tools
+ * ====================
+ *
+ * - Push & Relax, Breakdowner
+
+ * These tools provide the animator with various capabilities
+ * for interactively controlling the spacing of poses, but also
+ * for 'pushing' and/or 'relaxing' extremes as they see fit.
+ *
+ * - Propagate
+
+ * This tool copies elements of the selected pose to successive
+ * keyframes, allowing the animator to go back and modify the poses
+ * for some "static" pose controls, without having to repeatedly
+ * doing a "next paste" dance.
+ *
+ * - Pose Sculpting (TODO)
+
+ * This is yet to be implemented, but the idea here is to use
+ * sculpting techniques to make it easier to pose rigs by allowing
+ * rigs to be manipulated using a familiar paint-based interface.
*/
#include "MEM_guardedalloc.h"
@@ -75,35 +97,48 @@
#define OVERSHOOT_RANGE_DELTA 0.2f
/* **************************************************** */
-/* == POSE 'SLIDING' TOOLS ==
- *
- * A) Push & Relax, Breakdowner
- * These tools provide the animator with various capabilities
- * for interactively controlling the spacing of poses, but also
- * for 'pushing' and/or 'relaxing' extremes as they see fit.
- *
- * B) Propagate
- * This tool copies elements of the selected pose to successive
- * keyframes, allowing the animator to go back and modify the poses
- * for some "static" pose controls, without having to repeatedly
- * doing a "next paste" dance.
- *
- * C) Pose Sculpting
- * This is yet to be implemented, but the idea here is to use
- * sculpting techniques to make it easier to pose rigs by allowing
- * rigs to be manipulated using a familiar paint-based interface.
- */
-/* **************************************************** */
/* A) Push & Relax, Breakdowner */
-/* Temporary data shared between these operators */
+/** Axis Locks. */
+typedef enum ePoseSlide_AxisLock {
+ PS_LOCK_X = (1 << 0),
+ PS_LOCK_Y = (1 << 1),
+ PS_LOCK_Z = (1 << 2),
+} ePoseSlide_AxisLock;
+
+/** Pose Sliding Modes. */
+typedef enum ePoseSlide_Modes {
+ /** Exaggerate the pose. */
+ POSESLIDE_PUSH = 0,
+ /** soften the pose. */
+ POSESLIDE_RELAX,
+ /** Slide between the endpoint poses, finding a 'soft' spot. */
+ POSESLIDE_BREAKDOWN,
+ POSESLIDE_PUSH_REST,
+ POSESLIDE_RELAX_REST,
+} ePoseSlide_Modes;
+
+/** Transforms/Channels to Affect. */
+typedef enum ePoseSlide_Channels {
+ PS_TFM_ALL = 0, /* All transforms and properties */
+
+ PS_TFM_LOC, /* Loc/Rot/Scale */
+ PS_TFM_ROT,
+ PS_TFM_SIZE,
+
+ PS_TFM_BBONE_SHAPE, /* Bendy Bones */
+
+ PS_TFM_PROPS, /* Custom Properties */
+} ePoseSlide_Channels;
+
+/** Temporary data shared between these operators. */
typedef struct tPoseSlideOp {
/** current scene */
Scene *scene;
/** area that we're operating in (needed for modal()) */
ScrArea *area;
- /** region that we're operating in (needed for modal()) */
- ARegion *region;
+ /** Header of the region used for drawing the slider. */
+ ARegion *region_header;
/** len of the PoseSlideObject array. */
uint objects_len;
@@ -120,76 +155,57 @@ typedef struct tPoseSlideOp {
/** frame after current frame (blend-to) - global time */
int nextFrame;
- /** sliding mode (ePoseSlide_Modes) */
- short mode;
+ /** Sliding Mode. */
+ ePoseSlide_Modes mode;
/** unused for now, but can later get used for storing runtime settings.... */
short flag;
/* Store overlay settings when invoking the operator. Bones will be temporarily hidden. */
int overlay_flag;
- /** which transforms/channels are affected (ePoseSlide_Channels) */
- short channels;
- /** axis-limits for transforms (ePoseSlide_AxisLock) */
- short axislock;
+ /** Which transforms/channels are affected. */
+ ePoseSlide_Channels channels;
+ /** Axis-limits for transforms. */
+ ePoseSlide_AxisLock axislock;
- /* Allow overshoot or clamp between 0% and 100%. */
+ /** Allow overshoot or clamp between 0% and 100%. */
bool overshoot;
- /* Reduces percentage delta from mouse movement. */
+ /** Reduces factor delta from mouse movement. */
bool precision;
- /* Move percentage in 10% steps. */
+ /** Move factor in 10% steps. */
bool increments;
- /* Draw callback handler. */
+ /** Draw callback handler. */
void *draw_handle;
- /* Accumulative, unclamped and unrounded percentage. */
- float raw_percentage;
+ /** Accumulative, unclamped and unrounded factor. */
+ float raw_factor;
- /* 0-1 value for determining the influence of whatever is relevant. */
- float percentage;
+ /** 0-1 value for determining the influence of whatever is relevant. */
+ float factor;
- /* Last cursor position in screen space used for mouse movement delta calculation. */
+ /** Last cursor position in screen space used for mouse movement delta calculation. */
int last_cursor_x;
- /* Numeric input. */
+ /** Numeric input. */
NumInput num;
struct tPoseSlideObject *ob_data_array;
} tPoseSlideOp;
typedef struct tPoseSlideObject {
- Object *ob; /* active object that Pose Info comes from */
- float prevFrameF; /* prevFrame, but in local action time (for F-Curve lookups to work) */
- float nextFrameF; /* nextFrame, but in local action time (for F-Curve lookups to work) */
+ /** Active object that Pose Info comes from. */
+ Object *ob;
+ /** `prevFrame`, but in local action time (for F-Curve look-ups to work). */
+ float prevFrameF;
+ /** `nextFrame`, but in local action time (for F-Curve look-ups to work). */
+ float nextFrameF;
bool valid;
} tPoseSlideObject;
-/* Pose Sliding Modes */
-typedef enum ePoseSlide_Modes {
- POSESLIDE_PUSH = 0, /* exaggerate the pose... */
- POSESLIDE_RELAX, /* soften the pose... */
- POSESLIDE_BREAKDOWN, /* slide between the endpoint poses, finding a 'soft' spot */
- POSESLIDE_PUSH_REST,
- POSESLIDE_RELAX_REST,
-} ePoseSlide_Modes;
-
-/* Transforms/Channels to Affect */
-typedef enum ePoseSlide_Channels {
- PS_TFM_ALL = 0, /* All transforms and properties */
-
- PS_TFM_LOC, /* Loc/Rot/Scale */
- PS_TFM_ROT,
- PS_TFM_SIZE,
-
- PS_TFM_BBONE_SHAPE, /* Bendy Bones */
-
- PS_TFM_PROPS, /* Custom Properties */
-} ePoseSlide_Channels;
-
-/* Property enum for ePoseSlide_Channels */
+/** Property enum for #ePoseSlide_Channels. */
static const EnumPropertyItem prop_channels_types[] = {
{PS_TFM_ALL,
"ALL",
@@ -204,13 +220,6 @@ static const EnumPropertyItem prop_channels_types[] = {
{0, NULL, 0, NULL, NULL},
};
-/* Axis Locks */
-typedef enum ePoseSlide_AxisLock {
- PS_LOCK_X = (1 << 0),
- PS_LOCK_Y = (1 << 1),
- PS_LOCK_Z = (1 << 2),
-} ePoseSlide_AxisLock;
-
/* Property enum for ePoseSlide_AxisLock */
static const EnumPropertyItem prop_axis_lock_types[] = {
{0, "FREE", 0, "Free", "All axes are affected"},
@@ -248,22 +257,22 @@ static void draw_overshoot_triangle(const uint8_t color[4],
immUnbindProgram();
}
-static void draw_ticks(const float start_percentage,
- const float end_percentage,
- const struct vec2f line_start,
+static void draw_ticks(const float start_factor,
+ const float end_factor,
+ const float line_start[2],
const float base_tick_height,
const float line_width,
const uint8_t color_overshoot[4],
const uint8_t color_line[4])
{
- /* Use percentage represented as 0-100 int to avoid floating point precision problems. */
+ /* Use factor represented as 0-100 int to avoid floating point precision problems. */
const int tick_increment = 10;
- /* Round initial_tick_percentage up to the next tick_increment. */
- int tick_percentage = ceil((start_percentage * 100) / tick_increment) * tick_increment;
- float tick_height = base_tick_height;
+ /* Round initial_tick_factor up to the next tick_increment. */
+ int tick_percentage = ceil((start_factor * 100) / tick_increment) * tick_increment;
- while (tick_percentage <= (int)(end_percentage * 100)) {
+ while (tick_percentage <= (int)(end_factor * 100)) {
+ float tick_height;
/* Different ticks have different heights. Multiples of 100% are the tallest, 50% is a bit
* smaller and the rest is the minimum size. */
if (tick_percentage % 100 == 0) {
@@ -276,12 +285,14 @@ static void draw_ticks(const float start_percentage,
tick_height = base_tick_height * 0.5;
}
- const float x = line_start.x +
- (((float)tick_percentage / 100) - start_percentage) * SLIDE_PIXEL_DISTANCE;
- const struct rctf tick_rect = {.xmin = x - (line_width / 2),
- .xmax = x + (line_width / 2),
- .ymin = line_start.y - (tick_height / 2),
- .ymax = line_start.y + (tick_height / 2)};
+ const float x = line_start[0] +
+ (((float)tick_percentage / 100) - start_factor) * SLIDE_PIXEL_DISTANCE;
+ const rctf tick_rect = {
+ .xmin = x - (line_width / 2),
+ .xmax = x + (line_width / 2),
+ .ymin = line_start[1] - (tick_height / 2),
+ .ymax = line_start[1] + (tick_height / 2),
+ };
if (tick_percentage < 0 || tick_percentage > 100) {
UI_draw_roundbox_3ub_alpha(&tick_rect, true, 1, color_overshoot, 255);
@@ -293,73 +304,83 @@ static void draw_ticks(const float start_percentage,
}
}
-static void draw_main_line(const struct rctf main_line_rect,
- const float percentage,
+static void draw_main_line(const rctf *main_line_rect,
+ const float factor,
const bool overshoot,
const uint8_t color_overshoot[4],
const uint8_t color_line[4])
{
if (overshoot) {
/* In overshoot mode, draw the 0-100% range differently to provide a visual reference. */
- const float line_zero_percent = main_line_rect.xmin -
- ((percentage - 0.5f - OVERSHOOT_RANGE_DELTA) *
+ const float line_zero_percent = main_line_rect->xmin -
+ ((factor - 0.5f - OVERSHOOT_RANGE_DELTA) *
SLIDE_PIXEL_DISTANCE);
const float clamped_line_zero_percent = clamp_f(
- line_zero_percent, main_line_rect.xmin, main_line_rect.xmax);
+ line_zero_percent, main_line_rect->xmin, main_line_rect->xmax);
const float clamped_line_hundred_percent = clamp_f(
- line_zero_percent + SLIDE_PIXEL_DISTANCE, main_line_rect.xmin, main_line_rect.xmax);
-
- const struct rctf left_overshoot_line_rect = {.xmin = main_line_rect.xmin,
- .xmax = clamped_line_zero_percent,
- .ymin = main_line_rect.ymin,
- .ymax = main_line_rect.ymax};
- const struct rctf right_overshoot_line_rect = {.xmin = clamped_line_hundred_percent,
- .xmax = main_line_rect.xmax,
- .ymin = main_line_rect.ymin,
- .ymax = main_line_rect.ymax};
+ line_zero_percent + SLIDE_PIXEL_DISTANCE, main_line_rect->xmin, main_line_rect->xmax);
+
+ const rctf left_overshoot_line_rect = {
+ .xmin = main_line_rect->xmin,
+ .xmax = clamped_line_zero_percent,
+ .ymin = main_line_rect->ymin,
+ .ymax = main_line_rect->ymax,
+ };
+ const rctf right_overshoot_line_rect = {
+ .xmin = clamped_line_hundred_percent,
+ .xmax = main_line_rect->xmax,
+ .ymin = main_line_rect->ymin,
+ .ymax = main_line_rect->ymax,
+ };
UI_draw_roundbox_3ub_alpha(&left_overshoot_line_rect, true, 0, color_overshoot, 255);
UI_draw_roundbox_3ub_alpha(&right_overshoot_line_rect, true, 0, color_overshoot, 255);
- const struct rctf non_overshoot_line_rect = {.xmin = clamped_line_zero_percent,
- .xmax = clamped_line_hundred_percent,
- .ymin = main_line_rect.ymin,
- .ymax = main_line_rect.ymax};
+ const rctf non_overshoot_line_rect = {
+ .xmin = clamped_line_zero_percent,
+ .xmax = clamped_line_hundred_percent,
+ .ymin = main_line_rect->ymin,
+ .ymax = main_line_rect->ymax,
+ };
UI_draw_roundbox_3ub_alpha(&non_overshoot_line_rect, true, 0, color_line, 255);
}
else {
- UI_draw_roundbox_3ub_alpha(&main_line_rect, true, 0, color_line, 255);
+ UI_draw_roundbox_3ub_alpha(main_line_rect, true, 0, color_line, 255);
}
}
static void draw_backdrop(const int fontid,
- const struct rctf main_line_rect,
+ const rctf *main_line_rect,
const float color_bg[4],
const short region_y_size,
const float base_tick_height)
{
float string_pixel_size[2];
- const char *percentage_placeholder = "000%%";
+ const char *percentage_string_placeholder = "000%%";
BLF_width_and_height(fontid,
- percentage_placeholder,
- sizeof(percentage_placeholder),
+ percentage_string_placeholder,
+ sizeof(percentage_string_placeholder),
&string_pixel_size[0],
&string_pixel_size[1]);
- const struct vec2f pad = {.x = (region_y_size - base_tick_height) / 2, .y = 2.0f * U.pixelsize};
- const struct rctf backdrop_rect = {.xmin = main_line_rect.xmin - string_pixel_size[0] - pad.x,
- .xmax = main_line_rect.xmax + pad.x,
- .ymin = pad.y,
- .ymax = region_y_size - pad.y};
+ const float pad[2] = {(region_y_size - base_tick_height) / 2, 2.0f * U.pixelsize};
+ const rctf backdrop_rect = {
+ .xmin = main_line_rect->xmin - string_pixel_size[0] - pad[0],
+ .xmax = main_line_rect->xmax + pad[0],
+ .ymin = pad[1],
+ .ymax = region_y_size - pad[1],
+ };
UI_draw_roundbox_aa(&backdrop_rect, true, 4.0f, color_bg);
}
-/* Draw an on screen Slider for a Pose Slide Operator. */
+/**
+ * Draw an on screen Slider for a Pose Slide Operator.
+ */
static void pose_slide_draw_2d_slider(const struct bContext *UNUSED(C), ARegion *region, void *arg)
{
tPoseSlideOp *pso = arg;
/* Only draw in region from which the Operator was started. */
- if (region != pso->region) {
+ if (region != pso->region_header) {
return;
}
@@ -392,28 +413,30 @@ static void pose_slide_draw_2d_slider(const struct bContext *UNUSED(C), ARegion
const float base_tick_height = 12.0 * U.pixelsize;
const float line_y = region->winy / 2;
- struct rctf main_line_rect = {.xmin = (region->winx / 2) - (SLIDE_PIXEL_DISTANCE / 2),
- .xmax = (region->winx / 2) + (SLIDE_PIXEL_DISTANCE / 2),
- .ymin = line_y - line_width / 2,
- .ymax = line_y + line_width / 2};
- float line_start_percentage = 0;
- int handle_pos_x = main_line_rect.xmin + SLIDE_PIXEL_DISTANCE * pso->percentage;
+ rctf main_line_rect = {
+ .xmin = (region->winx / 2) - (SLIDE_PIXEL_DISTANCE / 2),
+ .xmax = (region->winx / 2) + (SLIDE_PIXEL_DISTANCE / 2),
+ .ymin = line_y - line_width / 2,
+ .ymax = line_y + line_width / 2,
+ };
+ float line_start_factor = 0;
+ int handle_pos_x = main_line_rect.xmin + SLIDE_PIXEL_DISTANCE * pso->factor;
if (pso->overshoot) {
main_line_rect.xmin = main_line_rect.xmin - SLIDE_PIXEL_DISTANCE * OVERSHOOT_RANGE_DELTA;
main_line_rect.xmax = main_line_rect.xmax + SLIDE_PIXEL_DISTANCE * OVERSHOOT_RANGE_DELTA;
- line_start_percentage = pso->percentage - 0.5f - OVERSHOOT_RANGE_DELTA;
+ line_start_factor = pso->factor - 0.5f - OVERSHOOT_RANGE_DELTA;
handle_pos_x = region->winx / 2;
}
- draw_backdrop(fontid, main_line_rect, color_bg, pso->region->winy, base_tick_height);
+ draw_backdrop(fontid, &main_line_rect, color_bg, pso->region_header->winy, base_tick_height);
- draw_main_line(main_line_rect, pso->percentage, pso->overshoot, color_overshoot, color_line);
+ draw_main_line(&main_line_rect, pso->factor, pso->overshoot, color_overshoot, color_line);
- const float percentage_range = pso->overshoot ? 1 + OVERSHOOT_RANGE_DELTA * 2 : 1;
- const struct vec2f line_start_position = {.x = main_line_rect.xmin, .y = line_y};
- draw_ticks(line_start_percentage,
- line_start_percentage + percentage_range,
+ const float factor_range = pso->overshoot ? 1 + OVERSHOOT_RANGE_DELTA * 2 : 1;
+ const float line_start_position[2] = {main_line_rect.xmin, line_y};
+ draw_ticks(line_start_factor,
+ line_start_factor + factor_range,
line_start_position,
base_tick_height,
line_width,
@@ -421,70 +444,72 @@ static void pose_slide_draw_2d_slider(const struct bContext *UNUSED(C), ARegion
color_line);
/* Draw triangles at the ends of the line in overshoot mode to indicate direction of 0-100%
- * range.*/
+ * range. */
if (pso->overshoot) {
- if (pso->percentage > 1 + OVERSHOOT_RANGE_DELTA + 0.5) {
+ if (pso->factor > 1 + OVERSHOOT_RANGE_DELTA + 0.5) {
draw_overshoot_triangle(color_line, false, main_line_rect.xmin, line_y);
}
- if (pso->percentage < 0 - OVERSHOOT_RANGE_DELTA - 0.5) {
+ if (pso->factor < 0 - OVERSHOOT_RANGE_DELTA - 0.5) {
draw_overshoot_triangle(color_line, true, main_line_rect.xmax, line_y);
}
}
char percentage_string[256];
- /* Draw handle indicating current percentage. */
- const struct rctf handle_rect = {.xmin = handle_pos_x - (line_width),
- .xmax = handle_pos_x + (line_width),
- .ymin = line_y - (base_tick_height / 2),
- .ymax = line_y + (base_tick_height / 2)};
+ /* Draw handle indicating current factor. */
+ const rctf handle_rect = {
+ .xmin = handle_pos_x - (line_width),
+ .xmax = handle_pos_x + (line_width),
+ .ymin = line_y - (base_tick_height / 2),
+ .ymax = line_y + (base_tick_height / 2),
+ };
UI_draw_roundbox_3ub_alpha(&handle_rect, true, 1, color_handle, 255);
- BLI_snprintf(percentage_string, sizeof(percentage_string), "%.0f%%", pso->percentage * 100);
+ BLI_snprintf(percentage_string, sizeof(percentage_string), "%.0f%%", pso->factor * 100);
/* Draw percentage string. */
- float percentage_pixel_size[2];
+ float percentage_string_pixel_size[2];
BLF_width_and_height(fontid,
percentage_string,
sizeof(percentage_string),
- &percentage_pixel_size[0],
- &percentage_pixel_size[1]);
+ &percentage_string_pixel_size[0],
+ &percentage_string_pixel_size[1]);
BLF_position(fontid,
- main_line_rect.xmin - 24.0 * U.pixelsize - percentage_pixel_size[0] / 2,
- (region->winy / 2) - percentage_pixel_size[1] / 2,
+ main_line_rect.xmin - 24.0 * U.pixelsize - percentage_string_pixel_size[0] / 2,
+ (region->winy / 2) - percentage_string_pixel_size[1] / 2,
0.0f);
BLF_draw(fontid, percentage_string, sizeof(percentage_string));
}
-/* operator init */
+/** Operator custom-data initialization. */
static int pose_slide_init(bContext *C, wmOperator *op, ePoseSlide_Modes mode)
{
tPoseSlideOp *pso;
- /* init slide-op data */
+ /* Init slide-op data. */
pso = op->customdata = MEM_callocN(sizeof(tPoseSlideOp), "tPoseSlideOp");
- /* get info from context */
+ /* Get info from context. */
pso->scene = CTX_data_scene(C);
- pso->area = CTX_wm_area(C); /* only really needed when doing modal() */
- pso->region = CTX_wm_region(C); /* only really needed when doing modal() */
+ pso->area = CTX_wm_area(C); /* Only really needed when doing modal(). */
+ pso->region_header = CTX_wm_region(C); /* Only really needed when doing modal(). */
pso->cframe = pso->scene->r.cfra;
pso->mode = mode;
- /* set range info from property values - these may get overridden for the invoke() */
- pso->percentage = RNA_float_get(op->ptr, "percentage");
- pso->raw_percentage = pso->percentage;
+ /* Set range info from property values - these may get overridden for the invoke(). */
+ pso->factor = RNA_float_get(op->ptr, "factor");
+ pso->raw_factor = pso->factor;
pso->prevFrame = RNA_int_get(op->ptr, "prev_frame");
pso->nextFrame = RNA_int_get(op->ptr, "next_frame");
- /* get the set of properties/axes that can be operated on */
+ /* Get the set of properties/axes that can be operated on. */
pso->channels = RNA_enum_get(op->ptr, "channels");
pso->axislock = RNA_enum_get(op->ptr, "axis_lock");
- /* for each Pose-Channel which gets affected, get the F-Curves for that channel
- * and set the relevant transform flags... */
+ /* For each Pose-Channel which gets affected, get the F-Curves for that channel
+ * and set the relevant transform flags. */
poseAnim_mapping_get(C, &pso->pfLinks);
Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(
@@ -504,43 +529,44 @@ static int pose_slide_init(bContext *C, wmOperator *op, ePoseSlide_Modes mode)
ob_data->ob = ob_iter;
ob_data->valid = true;
- /* apply NLA mapping corrections so the frame lookups work */
+ /* Apply NLA mapping corrections so the frame look-ups work. */
ob_data->prevFrameF = BKE_nla_tweakedit_remap(
ob_data->ob->adt, pso->prevFrame, NLATIME_CONVERT_UNMAP);
ob_data->nextFrameF = BKE_nla_tweakedit_remap(
ob_data->ob->adt, pso->nextFrame, NLATIME_CONVERT_UNMAP);
- /* set depsgraph flags */
- /* make sure the lock is set OK, unlock can be accidentally saved? */
+ /* Set depsgraph flags. */
+ /* Make sure the lock is set OK, unlock can be accidentally saved? */
ob_data->ob->pose->flag |= POSE_LOCKED;
ob_data->ob->pose->flag &= ~POSE_DO_UNLOCK;
}
MEM_freeN(objects);
- /* do basic initialize of RB-BST used for finding keyframes, but leave the filling of it up
- * to the caller of this (usually only invoke() will do it, to make things more efficient).
- */
+ /* Do basic initialize of RB-BST used for finding keyframes, but leave the filling of it up
+ * to the caller of this (usually only invoke() will do it, to make things more efficient). */
BLI_dlrbTree_init(&pso->keys);
/* Initialize numeric input. */
initNumInput(&pso->num);
- pso->num.idx_max = 0; /* one axis */
+ pso->num.idx_max = 0; /* One axis. */
pso->num.val_flag[0] |= NUM_NO_NEGATIVE;
- pso->num.unit_type[0] = B_UNIT_NONE; /* percentages don't have any units... */
+ pso->num.unit_type[0] = B_UNIT_NONE; /* Percentages don't have any units. */
/* Register UI drawing callback. */
ARegion *region_header = BKE_area_find_region_type(pso->area, RGN_TYPE_HEADER);
if (region_header != NULL) {
- pso->region = region_header;
+ pso->region_header = region_header;
pso->draw_handle = ED_region_draw_cb_activate(
region_header->type, pose_slide_draw_2d_slider, pso, REGION_DRAW_POST_PIXEL);
}
- /* return status is whether we've got all the data we were requested to get */
+ /* Return status is whether we've got all the data we were requested to get. */
return 1;
}
-/* exiting the operator - free data */
+/**
+ * Exiting the operator (free data).
+ */
static void pose_slide_exit(wmOperator *op)
{
tPoseSlideOp *pso = op->customdata;
@@ -550,34 +576,33 @@ static void pose_slide_exit(wmOperator *op)
v3d->overlay.flag = pso->overlay_flag;
/* Remove UI drawing callback. */
- ED_region_draw_cb_exit(pso->region->type, pso->draw_handle);
-
- /* if data exists, clear its data and exit */
- if (pso) {
- /* free the temp pchan links and their data */
- poseAnim_mapping_free(&pso->pfLinks);
+ ED_region_draw_cb_exit(pso->region_header->type, pso->draw_handle);
- /* free RB-BST for keyframes (if it contained data) */
- BLI_dlrbTree_free(&pso->keys);
+ /* Free the temp pchan links and their data. */
+ poseAnim_mapping_free(&pso->pfLinks);
- if (pso->ob_data_array != NULL) {
- MEM_freeN(pso->ob_data_array);
- }
+ /* Free RB-BST for keyframes (if it contained data). */
+ BLI_dlrbTree_free(&pso->keys);
- /* free data itself */
- MEM_freeN(pso);
+ if (pso->ob_data_array != NULL) {
+ MEM_freeN(pso->ob_data_array);
}
- /* cleanup */
+ /* Free data itself. */
+ MEM_freeN(pso);
+
+ /* Cleanup. */
op->customdata = NULL;
}
/* ------------------------------------ */
-/* helper for apply() / reset() - refresh the data */
+/**
+ * Helper for apply() / reset() - refresh the data.
+ */
static void pose_slide_refresh(bContext *C, tPoseSlideOp *pso)
{
- /* wrapper around the generic version, allowing us to add some custom stuff later still */
+ /* Wrapper around the generic version, allowing us to add some custom stuff later still. */
for (uint ob_index = 0; ob_index < pso->objects_len; ob_index++) {
tPoseSlideObject *ob_data = &pso->ob_data_array[ob_index];
if (ob_data->valid) {
@@ -609,7 +634,9 @@ static bool pose_frame_range_from_object_get(tPoseSlideOp *pso,
return false;
}
-/* helper for apply() - perform sliding for some value */
+/**
+ * Helper for apply() - perform sliding for some value.
+ */
static void pose_slide_apply_val(tPoseSlideOp *pso, FCurve *fcu, Object *ob, float *val)
{
float prevFrameF, nextFrameF;
@@ -619,17 +646,17 @@ static void pose_slide_apply_val(tPoseSlideOp *pso, FCurve *fcu, Object *ob, flo
pose_frame_range_from_object_get(pso, ob, &prevFrameF, &nextFrameF);
- /* get keyframe values for endpoint poses to blend with */
- /* previous/start */
+ /* Get keyframe values for endpoint poses to blend with. */
+ /* Previous/start. */
sVal = evaluate_fcurve(fcu, prevFrameF);
- /* next/end */
+ /* Next/end. */
eVal = evaluate_fcurve(fcu, nextFrameF);
- /* calculate the relative weights of the endpoints */
+ /* Calculate the relative weights of the endpoints. */
if (pso->mode == POSESLIDE_BREAKDOWN) {
- /* get weights from the percentage control */
- w1 = pso->percentage; /* this must come second */
- w2 = 1.0f - w1; /* this must come first */
+ /* Get weights from the factor control. */
+ w1 = pso->factor; /* This must come second. */
+ w2 = 1.0f - w1; /* This must come first. */
}
else {
/* - these weights are derived from the relative distance of these
@@ -652,30 +679,37 @@ static void pose_slide_apply_val(tPoseSlideOp *pso, FCurve *fcu, Object *ob, flo
* the value the current frame is closer to.
*/
switch (pso->mode) {
- case POSESLIDE_PUSH: /* make the current pose more pronounced */
+ case POSESLIDE_PUSH: /* Make the current pose more pronounced. */
{
/* Slide the pose away from the breakdown pose in the timeline */
- (*val) -= ((sVal * w2) + (eVal * w1) - (*val)) * pso->percentage;
+ (*val) -= ((sVal * w2) + (eVal * w1) - (*val)) * pso->factor;
break;
}
- case POSESLIDE_RELAX: /* make the current pose more like its surrounding ones */
+ case POSESLIDE_RELAX: /* Make the current pose more like its surrounding ones. */
{
/* Slide the pose towards the breakdown pose in the timeline */
- (*val) += ((sVal * w2) + (eVal * w1) - (*val)) * pso->percentage;
+ (*val) += ((sVal * w2) + (eVal * w1) - (*val)) * pso->factor;
break;
}
- case POSESLIDE_BREAKDOWN: /* make the current pose slide around between the endpoints */
+ case POSESLIDE_BREAKDOWN: /* Make the current pose slide around between the endpoints. */
{
/* Perform simple linear interpolation -
- * coefficient for start must come from pso->percentage. */
+ * coefficient for start must come from pso->factor. */
/* TODO: make this use some kind of spline interpolation instead? */
(*val) = ((sVal * w2) + (eVal * w1));
break;
}
+ /* Those are handled in pose_slide_rest_pose_apply. */
+ case POSESLIDE_PUSH_REST:
+ case POSESLIDE_RELAX_REST: {
+ break;
+ }
}
}
-/* helper for apply() - perform sliding for some 3-element vector */
+/**
+ * Helper for apply() - perform sliding for some 3-element vector.
+ */
static void pose_slide_apply_vec3(tPoseSlideOp *pso,
tPChanFCurveLink *pfl,
float vec[3],
@@ -684,30 +718,32 @@ static void pose_slide_apply_vec3(tPoseSlideOp *pso,
LinkData *ld = NULL;
char *path = NULL;
- /* get the path to use... */
+ /* Get the path to use. */
path = BLI_sprintfN("%s.%s", pfl->pchan_path, propName);
- /* using this path, find each matching F-Curve for the variables we're interested in */
+ /* Using this path, find each matching F-Curve for the variables we're interested in. */
while ((ld = poseAnim_mapping_getNextFCurve(&pfl->fcurves, ld, path))) {
FCurve *fcu = (FCurve *)ld->data;
const int idx = fcu->array_index;
const int lock = pso->axislock;
- /* check if this F-Curve is ok given the current axis locks */
+ /* Check if this F-Curve is ok given the current axis locks. */
BLI_assert(fcu->array_index < 3);
if ((lock == 0) || ((lock & PS_LOCK_X) && (idx == 0)) || ((lock & PS_LOCK_Y) && (idx == 1)) ||
((lock & PS_LOCK_Z) && (idx == 2))) {
- /* just work on these channels one by one... there's no interaction between values */
+ /* Just work on these channels one by one... there's no interaction between values. */
pose_slide_apply_val(pso, fcu, pfl->ob, &vec[fcu->array_index]);
}
}
- /* free the temp path we got */
+ /* Free the temp path we got. */
MEM_freeN(path);
}
-/* helper for apply() - perform sliding for custom properties or bbone properties */
+/**
+ * Helper for apply() - perform sliding for custom properties or bbone properties.
+ */
static void pose_slide_apply_props(tPoseSlideOp *pso,
tPChanFCurveLink *pfl,
const char prop_prefix[])
@@ -716,7 +752,7 @@ static void pose_slide_apply_props(tPoseSlideOp *pso,
LinkData *ld;
int len = strlen(pfl->pchan_path);
- /* setup pointer RNA for resolving paths */
+ /* Setup pointer RNA for resolving paths. */
RNA_pointer_create(NULL, &RNA_PoseBone, pfl->pchan, &ptr);
/* - custom properties are just denoted using ["..."][etc.] after the end of the base path,
@@ -732,22 +768,21 @@ static void pose_slide_apply_props(tPoseSlideOp *pso,
continue;
}
- /* do we have a match?
- * - bPtr is the RNA Path with the standard part chopped off
- * - pPtr is the chunk of the path which is left over
+ /* Do we have a match?
+ * - bPtr is the RNA Path with the standard part chopped off.
+ * - pPtr is the chunk of the path which is left over.
*/
bPtr = strstr(fcu->rna_path, pfl->pchan_path) + len;
pPtr = strstr(bPtr, prop_prefix);
if (pPtr) {
- /* use RNA to try and get a handle on this property, then, assuming that it is just
- * numerical, try and grab the value as a float for temp editing before setting back
- */
+ /* Use RNA to try and get a handle on this property, then, assuming that it is just
+ * numerical, try and grab the value as a float for temp editing before setting back. */
PropertyRNA *prop = RNA_struct_find_property(&ptr, pPtr);
if (prop) {
switch (RNA_property_type(prop)) {
- /* continuous values that can be smoothly interpolated... */
+ /* Continuous values that can be smoothly interpolated. */
case PROP_FLOAT: {
float tval = RNA_property_float_get(&ptr, prop);
pose_slide_apply_val(pso, fcu, pfl->ob, &tval);
@@ -761,7 +796,7 @@ static void pose_slide_apply_props(tPoseSlideOp *pso,
break;
}
- /* values which can only take discrete values */
+ /* Values which can only take discrete values. */
case PROP_BOOLEAN: {
float tval = (float)RNA_property_boolean_get(&ptr, prop);
pose_slide_apply_val(pso, fcu, pfl->ob, &tval);
@@ -770,14 +805,13 @@ static void pose_slide_apply_props(tPoseSlideOp *pso,
break;
}
case PROP_ENUM: {
- /* don't handle this case - these don't usually represent interchangeable
- * set of values which should be interpolated between
- */
+ /* Don't handle this case - these don't usually represent interchangeable
+ * set of values which should be interpolated between. */
break;
}
default:
- /* cannot handle */
+ /* Cannot handle. */
// printf("Cannot Pose Slide non-numerical property\n");
break;
}
@@ -786,7 +820,9 @@ static void pose_slide_apply_props(tPoseSlideOp *pso,
}
}
-/* helper for apply() - perform sliding for quaternion rotations (using quat blending) */
+/**
+ * Helper for apply() - perform sliding for quaternion rotations (using quat blending).
+ */
static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
{
FCurve *fcu_w = NULL, *fcu_x = NULL, *fcu_y = NULL, *fcu_z = NULL;
@@ -797,21 +833,21 @@ static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
float prevFrameF, nextFrameF;
if (!pose_frame_range_from_object_get(pso, pfl->ob, &prevFrameF, &nextFrameF)) {
- BLI_assert(!"Invalid pfl data");
+ BLI_assert_msg(0, "Invalid pfl data");
return;
}
- /* get the path to use - this should be quaternion rotations only (needs care) */
+ /* Get the path to use - this should be quaternion rotations only (needs care). */
path = BLI_sprintfN("%s.%s", pfl->pchan_path, "rotation_quaternion");
- /* get the current frame number */
+ /* Get the current frame number. */
cframe = (float)pso->cframe;
- /* using this path, find each matching F-Curve for the variables we're interested in */
+ /* Using this path, find each matching F-Curve for the variables we're interested in. */
while ((ld = poseAnim_mapping_getNextFCurve(&pfl->fcurves, ld, path))) {
FCurve *fcu = (FCurve *)ld->data;
- /* assign this F-Curve to one of the relevant pointers... */
+ /* Assign this F-Curve to one of the relevant pointers. */
switch (fcu->array_index) {
case 3: /* z */
fcu_z = fcu;
@@ -828,14 +864,14 @@ static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
}
}
- /* only if all channels exist, proceed */
+ /* Only if all channels exist, proceed. */
if (fcu_w && fcu_x && fcu_y && fcu_z) {
float quat_final[4];
- /* perform blending */
+ /* Perform blending. */
if (pso->mode == POSESLIDE_BREAKDOWN) {
/* Just perform the interpolation between quat_prev and
- * quat_next using pso->percentage as a guide. */
+ * quat_next using pso->factor as a guide. */
float quat_prev[4];
float quat_next[4];
@@ -852,7 +888,7 @@ static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
normalize_qt(quat_prev);
normalize_qt(quat_next);
- interp_qt_qtqt(quat_final, quat_prev, quat_next, pso->percentage);
+ interp_qt_qtqt(quat_final, quat_prev, quat_next, pso->factor);
}
else {
/* POSESLIDE_PUSH and POSESLIDE_RELAX. */
@@ -870,11 +906,11 @@ static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
normalize_qt(quat_curr);
if (pso->mode == POSESLIDE_PUSH) {
- interp_qt_qtqt(quat_final, quat_breakdown, quat_curr, 1.0f + pso->percentage);
+ interp_qt_qtqt(quat_final, quat_breakdown, quat_curr, 1.0f + pso->factor);
}
else {
BLI_assert(pso->mode == POSESLIDE_RELAX);
- interp_qt_qtqt(quat_final, quat_curr, quat_breakdown, pso->percentage);
+ interp_qt_qtqt(quat_final, quat_curr, quat_breakdown, pso->factor);
}
}
@@ -882,7 +918,7 @@ static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
quat_to_compatible_quat(pchan->quat, quat_final, pchan->quat);
}
- /* free the path now */
+ /* Free the path now. */
MEM_freeN(path);
}
@@ -895,11 +931,11 @@ static void pose_slide_rest_pose_apply_vec3(tPoseSlideOp *pso, float vec[3], flo
((lock & PS_LOCK_Z) && (idx == 2))) {
float diff_val = default_value - vec[idx];
if (pso->mode == POSESLIDE_RELAX_REST) {
- vec[idx] += pso->percentage * diff_val;
+ vec[idx] += pso->factor * diff_val;
}
else {
/* Push */
- vec[idx] -= pso->percentage * diff_val;
+ vec[idx] -= pso->factor * diff_val;
}
}
}
@@ -917,80 +953,84 @@ static void pose_slide_rest_pose_apply_other_rot(tPoseSlideOp *pso, float vec[4]
for (int idx = 0; idx < 4; idx++) {
float diff_val = default_values[idx] - vec[idx];
if (pso->mode == POSESLIDE_RELAX_REST) {
- vec[idx] += pso->percentage * diff_val;
+ vec[idx] += pso->factor * diff_val;
}
else {
/* Push */
- vec[idx] -= pso->percentage * diff_val;
+ vec[idx] -= pso->factor * diff_val;
}
}
}
-/* apply() - perform the pose sliding between the current pose and the rest pose */
+/**
+ * apply() - perform the pose sliding between the current pose and the rest pose.
+ */
static void pose_slide_rest_pose_apply(bContext *C, tPoseSlideOp *pso)
{
tPChanFCurveLink *pfl;
- /* for each link, handle each set of transforms */
+ /* For each link, handle each set of transforms. */
for (pfl = pso->pfLinks.first; pfl; pfl = pfl->next) {
- /* valid transforms for each PoseChannel should have been noted already
- * - sliding the pose should be a straightforward exercise for location+rotation,
+ /* Valid transforms for each #bPoseChannel should have been noted already.
+ * - Sliding the pose should be a straightforward exercise for location+rotation,
* but rotations get more complicated since we may want to use quaternion blending
- * for quaternions instead...
+ * for quaternions instead.
*/
bPoseChannel *pchan = pfl->pchan;
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_LOC) && (pchan->flag & POSE_LOC)) {
- /* calculate these for the 'location' vector, and use location curves */
+ /* Calculate these for the 'location' vector, and use location curves. */
pose_slide_rest_pose_apply_vec3(pso, pchan->loc, 0.0f);
}
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_SIZE) && (pchan->flag & POSE_SIZE)) {
- /* calculate these for the 'scale' vector, and use scale curves */
+ /* Calculate these for the 'scale' vector, and use scale curves. */
pose_slide_rest_pose_apply_vec3(pso, pchan->size, 1.0f);
}
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_ROT) && (pchan->flag & POSE_ROT)) {
- /* everything depends on the rotation mode */
+ /* Everything depends on the rotation mode. */
if (pchan->rotmode > 0) {
- /* eulers - so calculate these for the 'eul' vector, and use euler_rotation curves */
+ /* Eulers - so calculate these for the 'eul' vector, and use euler_rotation curves. */
pose_slide_rest_pose_apply_vec3(pso, pchan->eul, 0.0f);
}
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
pose_slide_rest_pose_apply_other_rot(pso, pchan->quat, false);
}
else {
- /* quaternions - use quaternion blending */
+ /* Quaternions - use quaternion blending. */
pose_slide_rest_pose_apply_other_rot(pso, pchan->quat, true);
}
}
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_BBONE_SHAPE) && (pchan->flag & POSE_BBONE_SHAPE)) {
- /* bbone properties - they all start a "bbone_" prefix */
- /* TODO Not implemented */
+ /* Bbone properties - they all start a "bbone_" prefix. */
+ /* TODO: Not implemented. */
// pose_slide_apply_props(pso, pfl, "bbone_");
}
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_PROPS) && (pfl->oldprops)) {
/* Not strictly a transform, but custom properties contribute
* to the pose produced in many rigs (e.g. the facial rigs used in Sintel). */
- /* TODO Not implemented */
+ /* TODO: Not implemented. */
// pose_slide_apply_props(pso, pfl, "[\"");
}
}
- /* depsgraph updates + redraws */
+ /* Depsgraph updates + redraws. */
pose_slide_refresh(C, pso);
}
-/* apply() - perform the pose sliding based on weighting various poses */
+/**
+ * apply() - perform the pose sliding based on weighting various poses.
+ */
static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
{
tPChanFCurveLink *pfl;
/* Sanitize the frame ranges. */
if (pso->prevFrame == pso->nextFrame) {
- /* move out one step either side */
+ /* Move out one step either side. */
pso->prevFrame--;
pso->nextFrame++;
@@ -1001,7 +1041,7 @@ static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
continue;
}
- /* apply NLA mapping corrections so the frame lookups work */
+ /* Apply NLA mapping corrections so the frame look-ups work. */
ob_data->prevFrameF = BKE_nla_tweakedit_remap(
ob_data->ob->adt, pso->prevFrame, NLATIME_CONVERT_UNMAP);
ob_data->nextFrameF = BKE_nla_tweakedit_remap(
@@ -1009,9 +1049,9 @@ static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
}
}
- /* for each link, handle each set of transforms */
+ /* For each link, handle each set of transforms. */
for (pfl = pso->pfLinks.first; pfl; pfl = pfl->next) {
- /* valid transforms for each PoseChannel should have been noted already
+ /* Valid transforms for each #bPoseChannel should have been noted already
* - sliding the pose should be a straightforward exercise for location+rotation,
* but rotations get more complicated since we may want to use quaternion blending
* for quaternions instead...
@@ -1019,32 +1059,32 @@ static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
bPoseChannel *pchan = pfl->pchan;
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_LOC) && (pchan->flag & POSE_LOC)) {
- /* calculate these for the 'location' vector, and use location curves */
+ /* Calculate these for the 'location' vector, and use location curves. */
pose_slide_apply_vec3(pso, pfl, pchan->loc, "location");
}
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_SIZE) && (pchan->flag & POSE_SIZE)) {
- /* calculate these for the 'scale' vector, and use scale curves */
+ /* Calculate these for the 'scale' vector, and use scale curves. */
pose_slide_apply_vec3(pso, pfl, pchan->size, "scale");
}
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_ROT) && (pchan->flag & POSE_ROT)) {
- /* everything depends on the rotation mode */
+ /* Everything depends on the rotation mode. */
if (pchan->rotmode > 0) {
- /* eulers - so calculate these for the 'eul' vector, and use euler_rotation curves */
+ /* Eulers - so calculate these for the 'eul' vector, and use euler_rotation curves. */
pose_slide_apply_vec3(pso, pfl, pchan->eul, "rotation_euler");
}
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
/* TODO: need to figure out how to do this! */
}
else {
- /* quaternions - use quaternion blending */
+ /* Quaternions - use quaternion blending. */
pose_slide_apply_quat(pso, pfl);
}
}
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_BBONE_SHAPE) && (pchan->flag & POSE_BBONE_SHAPE)) {
- /* bbone properties - they all start a "bbone_" prefix */
+ /* Bbone properties - they all start a "bbone_" prefix. */
pose_slide_apply_props(pso, pfl, "bbone_");
}
@@ -1055,28 +1095,35 @@ static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
}
}
- /* depsgraph updates + redraws */
+ /* Depsgraph updates + redraws. */
pose_slide_refresh(C, pso);
}
-/* perform auto-key-framing after changes were made + confirmed */
+/**
+ * Perform auto-key-framing after changes were made + confirmed.
+ */
static void pose_slide_autoKeyframe(bContext *C, tPoseSlideOp *pso)
{
- /* wrapper around the generic call */
+ /* Wrapper around the generic call. */
poseAnim_mapping_autoKeyframe(C, pso->scene, &pso->pfLinks, (float)pso->cframe);
}
-/* reset changes made to current pose */
+/**
+ * Reset changes made to current pose.
+ */
static void pose_slide_reset(tPoseSlideOp *pso)
{
- /* wrapper around the generic call, so that custom stuff can be added later */
+ /* Wrapper around the generic call, so that custom stuff can be added later. */
poseAnim_mapping_reset(&pso->pfLinks);
}
/* ------------------------------------ */
-/* Draw percentage indicator in workspace footer. */
-/* TODO: Include hints about locks here... */
+/**
+ * Draw percentage indicator in status-bar.
+ *
+ * TODO: Include hints about locks here.
+ */
static void pose_slide_draw_status(bContext *C, tPoseSlideOp *pso)
{
char status_str[UI_MAX_DRAW_STR];
@@ -1100,25 +1147,25 @@ static void pose_slide_draw_status(bContext *C, tPoseSlideOp *pso)
break;
default:
- /* unknown */
+ /* Unknown. */
strcpy(mode_str, TIP_("Sliding-Tool"));
break;
}
switch (pso->axislock) {
case PS_LOCK_X:
- BLI_strncpy(axis_str, TIP_("[X]/Y/Z axis only (X to clear)"), sizeof(axis_str));
+ STRNCPY(axis_str, TIP_("[X]/Y/Z axis only (X to clear)"));
break;
case PS_LOCK_Y:
- BLI_strncpy(axis_str, TIP_("X/[Y]/Z axis only (Y to clear)"), sizeof(axis_str));
+ STRNCPY(axis_str, TIP_("X/[Y]/Z axis only (Y to clear)"));
break;
case PS_LOCK_Z:
- BLI_strncpy(axis_str, TIP_("X/Y/[Z] axis only (Z to clear)"), sizeof(axis_str));
+ STRNCPY(axis_str, TIP_("X/Y/[Z] axis only (Z to clear)"));
break;
default:
if (ELEM(pso->channels, PS_TFM_LOC, PS_TFM_ROT, PS_TFM_SIZE)) {
- BLI_strncpy(axis_str, TIP_("X/Y/Z = Axis Constraint"), sizeof(axis_str));
+ STRNCPY(axis_str, TIP_("X/Y/Z = Axis Constraint"));
}
else {
axis_str[0] = '\0';
@@ -1146,43 +1193,38 @@ static void pose_slide_draw_status(bContext *C, tPoseSlideOp *pso)
axis_str);
break;
case PS_TFM_BBONE_SHAPE:
- BLI_strncpy(limits_str,
- TIP_("G/R/S/[B]/C - Bendy Bone properties only (B to clear) | %s"),
- sizeof(limits_str));
+ STRNCPY(limits_str, TIP_("G/R/S/[B]/C - Bendy Bone properties only (B to clear) | %s"));
break;
case PS_TFM_PROPS:
- BLI_strncpy(limits_str,
- TIP_("G/R/S/B/[C] - Custom Properties only (C to clear) | %s"),
- sizeof(limits_str));
+ STRNCPY(limits_str, TIP_("G/R/S/B/[C] - Custom Properties only (C to clear) | %s"));
break;
default:
- BLI_strncpy(
- limits_str, TIP_("G/R/S/B/C - Limit to Transform/Property Set"), sizeof(limits_str));
+ STRNCPY(limits_str, TIP_("G/R/S/B/C - Limit to Transform/Property Set"));
break;
}
if (pso->overshoot) {
- BLI_strncpy(overshoot_str, TIP_("[E] - Disable overshoot"), sizeof(overshoot_str));
+ STRNCPY(overshoot_str, TIP_("[E] - Disable overshoot"));
}
else {
- BLI_strncpy(overshoot_str, TIP_("E - Enable overshoot"), sizeof(overshoot_str));
+ STRNCPY(overshoot_str, TIP_("[E] - Enable overshoot"));
}
if (pso->precision) {
- BLI_strncpy(precision_str, TIP_("[Shift] - Precision active"), sizeof(precision_str));
+ STRNCPY(precision_str, TIP_("[Shift] - Precision active"));
}
else {
- BLI_strncpy(precision_str, TIP_("Shift - Hold for precision"), sizeof(precision_str));
+ STRNCPY(precision_str, TIP_("Shift - Hold for precision"));
}
if (pso->increments) {
- BLI_strncpy(increments_str, TIP_("[Ctrl] - Increments active"), sizeof(increments_str));
+ STRNCPY(increments_str, TIP_("[Ctrl] - Increments active"));
}
else {
- BLI_strncpy(increments_str, TIP_("Ctrl - Hold for 10% increments"), sizeof(increments_str));
+ STRNCPY(increments_str, TIP_("Ctrl - Hold for 10% increments"));
}
- BLI_strncpy(bone_vis_str, TIP_("[H] - Toggle bone visibility"), sizeof(increments_str));
+ STRNCPY(bone_vis_str, TIP_("[H] - Toggle bone visibility"));
if (hasNumInput(&pso->num)) {
Scene *scene = pso->scene;
@@ -1208,57 +1250,59 @@ static void pose_slide_draw_status(bContext *C, tPoseSlideOp *pso)
ED_area_status_text(pso->area, "");
}
-/* common code for invoke() methods */
+/**
+ * Common code for invoke() methods.
+ */
static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *pso)
{
tPChanFCurveLink *pfl;
wmWindow *win = CTX_wm_window(C);
- /* for each link, add all its keyframes to the search tree */
+ /* For each link, add all its keyframes to the search tree. */
for (pfl = pso->pfLinks.first; pfl; pfl = pfl->next) {
LinkData *ld;
- /* do this for each F-Curve */
+ /* Do this for each F-Curve. */
for (ld = pfl->fcurves.first; ld; ld = ld->next) {
FCurve *fcu = (FCurve *)ld->data;
fcurve_to_keylist(pfl->ob->adt, fcu, &pso->keys, 0);
}
}
- /* cancel if no keyframes found... */
+ /* Cancel if no keyframes found. */
if (pso->keys.root) {
ActKeyColumn *ak;
float cframe = (float)pso->cframe;
- /* firstly, check if the current frame is a keyframe... */
+ /* Firstly, check if the current frame is a keyframe. */
ak = (ActKeyColumn *)BLI_dlrbTree_search_exact(&pso->keys, compare_ak_cfraPtr, &cframe);
if (ak == NULL) {
- /* current frame is not a keyframe, so search */
+ /* Current frame is not a keyframe, so search. */
ActKeyColumn *pk = (ActKeyColumn *)BLI_dlrbTree_search_prev(
&pso->keys, compare_ak_cfraPtr, &cframe);
ActKeyColumn *nk = (ActKeyColumn *)BLI_dlrbTree_search_next(
&pso->keys, compare_ak_cfraPtr, &cframe);
- /* new set the frames */
- /* prev frame */
+ /* New set the frames. */
+ /* Prev frame. */
pso->prevFrame = (pk) ? (pk->cfra) : (pso->cframe - 1);
RNA_int_set(op->ptr, "prev_frame", pso->prevFrame);
- /* next frame */
+ /* Next frame. */
pso->nextFrame = (nk) ? (nk->cfra) : (pso->cframe + 1);
RNA_int_set(op->ptr, "next_frame", pso->nextFrame);
}
else {
- /* current frame itself is a keyframe, so just take keyframes on either side */
- /* prev frame */
+ /* Current frame itself is a keyframe, so just take keyframes on either side. */
+ /* Prev frame. */
pso->prevFrame = (ak->prev) ? (ak->prev->cfra) : (pso->cframe - 1);
RNA_int_set(op->ptr, "prev_frame", pso->prevFrame);
- /* next frame */
+ /* Next frame. */
pso->nextFrame = (ak->next) ? (ak->next->cfra) : (pso->cframe + 1);
RNA_int_set(op->ptr, "next_frame", pso->nextFrame);
}
- /* apply NLA mapping corrections so the frame lookups work */
+ /* Apply NLA mapping corrections so the frame look-ups work. */
for (uint ob_index = 0; ob_index < pso->objects_len; ob_index++) {
tPoseSlideObject *ob_data = &pso->ob_data_array[ob_index];
if (ob_data->valid) {
@@ -1275,8 +1319,8 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p
return OPERATOR_CANCELLED;
}
- /* initial apply for operator... */
- /* TODO: need to calculate percentage for initial round too... */
+ /* Initial apply for operator. */
+ /* TODO: need to calculate factor for initial round too. */
if (!ELEM(pso->mode, POSESLIDE_PUSH_REST, POSESLIDE_RELAX_REST)) {
pose_slide_apply(C, pso);
}
@@ -1284,16 +1328,16 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p
pose_slide_rest_pose_apply(C, pso);
}
- /* depsgraph updates + redraws */
+ /* Depsgraph updates + redraws. */
pose_slide_refresh(C, pso);
- /* set cursor to indicate modal */
+ /* Set cursor to indicate modal. */
WM_cursor_modal_set(win, WM_CURSOR_EW_SCROLL);
- /* header print */
+ /* Header print. */
pose_slide_draw_status(C, pso);
- /* add a modal handler for this operator */
+ /* Add a modal handler for this operator. */
WM_event_add_modal_handler(C, op);
/* Hide Bone Overlay. */
@@ -1304,31 +1348,32 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p
return OPERATOR_RUNNING_MODAL;
}
-/* Calculate percentage based on mouse movement, clamp or round to increments if
- * enabled by the user. Store the new percentage value.
+/**
+ * Calculate factor based on mouse movement, clamp or round to increments if
+ * enabled by the user. Store the new factor value.
*/
-static void pose_slide_mouse_update_percentage(tPoseSlideOp *pso,
- wmOperator *op,
- const wmEvent *event)
+static void pose_slide_mouse_update_factor(tPoseSlideOp *pso, wmOperator *op, const wmEvent *event)
{
- const float percentage_delta = (event->x - pso->last_cursor_x) / ((float)(SLIDE_PIXEL_DISTANCE));
- /* Reduced percentage delta in precision mode (shift held). */
- pso->raw_percentage += pso->precision ? (percentage_delta / 8) : percentage_delta;
- pso->percentage = pso->raw_percentage;
+ const float factor_delta = (event->x - pso->last_cursor_x) / ((float)(SLIDE_PIXEL_DISTANCE));
+ /* Reduced factor delta in precision mode (shift held). */
+ pso->raw_factor += pso->precision ? (factor_delta / 8) : factor_delta;
+ pso->factor = pso->raw_factor;
pso->last_cursor_x = event->x;
if (!pso->overshoot) {
- pso->percentage = clamp_f(pso->percentage, 0, 1);
+ pso->factor = clamp_f(pso->factor, 0, 1);
}
if (pso->increments) {
- pso->percentage = round(pso->percentage * 10) / 10;
+ pso->factor = round(pso->factor * 10) / 10;
}
- RNA_float_set(op->ptr, "percentage", pso->percentage);
+ RNA_float_set(op->ptr, "factor", pso->factor);
}
-/* handle an event to toggle channels mode */
+/**
+ * Handle an event to toggle channels mode.
+ */
static void pose_slide_toggle_channels_mode(wmOperator *op,
tPoseSlideOp *pso,
ePoseSlide_Channels channel)
@@ -1349,7 +1394,9 @@ static void pose_slide_toggle_channels_mode(wmOperator *op,
RNA_enum_set(op->ptr, "axis_lock", pso->axislock);
}
-/* handle an event to toggle axis locks - returns whether any change in state is needed */
+/**
+ * Handle an event to toggle axis locks - returns whether any change in state is needed.
+ */
static bool pose_slide_toggle_axis_locks(wmOperator *op,
tPoseSlideOp *pso,
ePoseSlide_AxisLock axis)
@@ -1376,7 +1423,9 @@ static bool pose_slide_toggle_axis_locks(wmOperator *op,
return true;
}
-/* common code for modal() */
+/**
+ * Operator `modal()` callback.
+ */
static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseSlideOp *pso = op->customdata;
@@ -1386,11 +1435,11 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
const bool has_numinput = hasNumInput(&pso->num);
switch (event->type) {
- case LEFTMOUSE: /* confirm */
+ case LEFTMOUSE: /* Confirm. */
case EVT_RETKEY:
case EVT_PADENTER: {
if (event->val == KM_PRESS) {
- /* return to normal cursor and header status */
+ /* Return to normal cursor and header status. */
ED_workspace_status_text(C, NULL);
ED_area_status_text(pso->area, NULL);
WM_cursor_modal_restore(win);
@@ -1398,48 +1447,48 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* Depsgraph updates + redraws. Redraw needed to remove UI. */
pose_slide_refresh(C, pso);
- /* insert keyframes as required... */
+ /* Insert keyframes as required. */
pose_slide_autoKeyframe(C, pso);
pose_slide_exit(op);
- /* done! */
+ /* Done! */
return OPERATOR_FINISHED;
}
break;
}
- case EVT_ESCKEY: /* cancel */
+ case EVT_ESCKEY: /* Cancel. */
case RIGHTMOUSE: {
if (event->val == KM_PRESS) {
- /* return to normal cursor and header status */
+ /* Return to normal cursor and header status. */
ED_workspace_status_text(C, NULL);
ED_area_status_text(pso->area, NULL);
WM_cursor_modal_restore(win);
- /* reset transforms back to original state */
+ /* Reset transforms back to original state. */
pose_slide_reset(pso);
- /* Depsgraph updates + redraws.*/
+ /* Depsgraph updates + redraws. */
pose_slide_refresh(C, pso);
- /* clean up temp data */
+ /* Clean up temp data. */
pose_slide_exit(op);
- /* canceled! */
+ /* Canceled! */
return OPERATOR_CANCELLED;
}
break;
}
- /* Percentage Change... */
- case MOUSEMOVE: /* calculate new position */
+ /* Factor Change... */
+ case MOUSEMOVE: /* Calculate new position. */
{
- /* only handle mousemove if not doing numinput */
+ /* Only handle mouse-move if not doing numinput. */
if (has_numinput == false) {
- /* update percentage based on position of mouse */
- pose_slide_mouse_update_percentage(pso, op, event);
+ /* Update factor based on position of mouse. */
+ pose_slide_mouse_update_factor(pso, op, event);
- /* update pose to reflect the new values (see below) */
+ /* Update pose to reflect the new values (see below). */
do_pose_update = true;
}
break;
@@ -1451,12 +1500,12 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* Grab percentage from numeric input, and store this new value for redo
* NOTE: users see ints, while internally we use a 0-1 float
*/
- value = pso->percentage * 100.0f;
+ value = pso->factor * 100.0f;
applyNumInput(&pso->num, &value);
- pso->percentage = value / 100.0f;
- CLAMP(pso->percentage, 0.0f, 1.0f);
- RNA_float_set(op->ptr, "percentage", pso->percentage);
+ pso->factor = value / 100.0f;
+ CLAMP(pso->factor, 0.0f, 1.0f);
+ RNA_float_set(op->ptr, "factor", pso->factor);
/* Update pose to reflect the new values (see below) */
do_pose_update = true;
@@ -1464,7 +1513,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (event->val == KM_PRESS) {
switch (event->type) {
- /* Transform Channel Limits */
+ /* Transform Channel Limits. */
/* XXX: Replace these hard-coded hotkeys with a modal-map that can be customized. */
case EVT_GKEY: /* Location */
{
@@ -1571,8 +1620,8 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else {
- /* unhandled event - maybe it was some view manipulation? */
- /* allow to pass through */
+ /* Unhandled event - maybe it was some view manipulation? */
+ /* Allow to pass through. */
return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH;
}
}
@@ -1581,15 +1630,13 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* Perform pose updates - in response to some user action
* (e.g. pressing a key or moving the mouse). */
if (do_pose_update) {
- pose_slide_mouse_update_percentage(pso, op, event);
-
- /* update percentage indicator in header */
+ /* Update percentage indicator in header. */
pose_slide_draw_status(C, pso);
- /* reset transforms (to avoid accumulation errors) */
+ /* Reset transforms (to avoid accumulation errors). */
pose_slide_reset(pso);
- /* apply... */
+ /* Apply. */
if (!ELEM(pso->mode, POSESLIDE_PUSH_REST, POSESLIDE_RELAX_REST)) {
pose_slide_apply(C, pso);
}
@@ -1598,21 +1645,25 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
- /* still running... */
+ /* Still running. */
return OPERATOR_RUNNING_MODAL;
}
-/* common code for cancel() */
+/**
+ * Common code for cancel()
+ */
static void pose_slide_cancel(bContext *UNUSED(C), wmOperator *op)
{
- /* cleanup and done */
+ /* Cleanup and done. */
pose_slide_exit(op);
}
-/* common code for exec() methods */
+/**
+ * Common code for exec() methods.
+ */
static int pose_slide_exec_common(bContext *C, wmOperator *op, tPoseSlideOp *pso)
{
- /* settings should have been set up ok for applying, so just apply! */
+ /* Settings should have been set up ok for applying, so just apply! */
if (!ELEM(pso->mode, POSESLIDE_PUSH_REST, POSESLIDE_RELAX_REST)) {
pose_slide_apply(C, pso);
}
@@ -1620,10 +1671,10 @@ static int pose_slide_exec_common(bContext *C, wmOperator *op, tPoseSlideOp *pso
pose_slide_rest_pose_apply(C, pso);
}
- /* insert keyframes if needed */
+ /* Insert keyframes if needed. */
pose_slide_autoKeyframe(C, pso);
- /* cleanup and done */
+ /* Cleanup and done. */
pose_slide_exit(op);
return OPERATOR_FINISHED;
@@ -1637,11 +1688,11 @@ static void pose_slide_opdef_properties(wmOperatorType *ot)
PropertyRNA *prop;
prop = RNA_def_float_factor(ot->srna,
- "percentage",
+ "factor",
0.5f,
0.0f,
1.0f,
- "Percentage",
+ "Factor",
"Weighting factor for which keyframe is favored more",
0.0,
1.0);
@@ -1687,12 +1738,14 @@ static void pose_slide_opdef_properties(wmOperatorType *ot)
/* ------------------------------------ */
-/* invoke() - for 'push from breakdown' mode */
+/**
+ * Operator `invoke()` callback for 'push from breakdown' mode.
+ */
static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseSlideOp *pso;
- /* initialize data */
+ /* Initialize data. */
if (pose_slide_init(C, op, POSESLIDE_PUSH) == 0) {
pose_slide_exit(op);
return OPERATOR_CANCELLED;
@@ -1702,19 +1755,21 @@ static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *ev
pso->last_cursor_x = event->x;
- /* Initialize percentage so that it won't pop on first mouse move. */
- pose_slide_mouse_update_percentage(pso, op, event);
+ /* Initialize factor so that it won't pop on first mouse move. */
+ pose_slide_mouse_update_factor(pso, op, event);
- /* do common setup work */
+ /* Do common setup work. */
return pose_slide_invoke_common(C, op, pso);
}
-/* exec() - for push */
+/**
+ * Operator `exec()` callback - for push.
+ */
static int pose_slide_push_exec(bContext *C, wmOperator *op)
{
tPoseSlideOp *pso;
- /* initialize data (from RNA-props) */
+ /* Initialize data (from RNA-props). */
if (pose_slide_init(C, op, POSESLIDE_PUSH) == 0) {
pose_slide_exit(op);
return OPERATOR_CANCELLED;
@@ -1722,7 +1777,7 @@ static int pose_slide_push_exec(bContext *C, wmOperator *op)
pso = op->customdata;
- /* do common exec work */
+ /* Do common exec work. */
return pose_slide_exec_common(C, op, pso);
}
@@ -1749,12 +1804,14 @@ void POSE_OT_push(wmOperatorType *ot)
/* ........................ */
-/* invoke() - for 'relax to breakdown' mode */
+/**
+ * Invoke callback - for 'relax to breakdown' mode.
+ */
static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseSlideOp *pso;
- /* initialize data */
+ /* Initialize data. */
if (pose_slide_init(C, op, POSESLIDE_RELAX) == 0) {
pose_slide_exit(op);
return OPERATOR_CANCELLED;
@@ -1764,19 +1821,21 @@ static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *e
pso->last_cursor_x = event->x;
- /* Initialize percentage so that it won't pop on first mouse move. */
- pose_slide_mouse_update_percentage(pso, op, event);
+ /* Initialize factor so that it won't pop on first mouse move. */
+ pose_slide_mouse_update_factor(pso, op, event);
- /* do common setup work */
+ /* Do common setup work. */
return pose_slide_invoke_common(C, op, pso);
}
-/* exec() - for relax */
+/**
+ * Operator exec() - for relax.
+ */
static int pose_slide_relax_exec(bContext *C, wmOperator *op)
{
tPoseSlideOp *pso;
- /* initialize data (from RNA-props) */
+ /* Initialize data (from RNA-props). */
if (pose_slide_init(C, op, POSESLIDE_RELAX) == 0) {
pose_slide_exit(op);
return OPERATOR_CANCELLED;
@@ -1784,7 +1843,7 @@ static int pose_slide_relax_exec(bContext *C, wmOperator *op)
pso = op->customdata;
- /* do common exec work */
+ /* Do common exec work. */
return pose_slide_exec_common(C, op, pso);
}
@@ -1810,12 +1869,14 @@ void POSE_OT_relax(wmOperatorType *ot)
}
/* ........................ */
-/* invoke() - for 'push from rest pose' mode */
+/**
+ * Operator `invoke()` - for 'push from rest pose' mode.
+ */
static int pose_slide_push_rest_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseSlideOp *pso;
- /* initialize data */
+ /* Initialize data. */
if (pose_slide_init(C, op, POSESLIDE_PUSH_REST) == 0) {
pose_slide_exit(op);
return OPERATOR_CANCELLED;
@@ -1825,19 +1886,21 @@ static int pose_slide_push_rest_invoke(bContext *C, wmOperator *op, const wmEven
pso->last_cursor_x = event->x;
- /* Initialize percentage so that it won't pop on first mouse move. */
- pose_slide_mouse_update_percentage(pso, op, event);
+ /* Initialize factor so that it won't pop on first mouse move. */
+ pose_slide_mouse_update_factor(pso, op, event);
/* do common setup work */
return pose_slide_invoke_common(C, op, pso);
}
-/* exec() - for push */
+/**
+ * Operator `exec()` - for push.
+ */
static int pose_slide_push_rest_exec(bContext *C, wmOperator *op)
{
tPoseSlideOp *pso;
- /* initialize data (from RNA-props) */
+ /* Initialize data (from RNA-props). */
if (pose_slide_init(C, op, POSESLIDE_PUSH_REST) == 0) {
pose_slide_exit(op);
return OPERATOR_CANCELLED;
@@ -1845,7 +1908,7 @@ static int pose_slide_push_rest_exec(bContext *C, wmOperator *op)
pso = op->customdata;
- /* do common exec work */
+ /* Do common exec work. */
return pose_slide_exec_common(C, op, pso);
}
@@ -1872,12 +1935,14 @@ void POSE_OT_push_rest(wmOperatorType *ot)
/* ........................ */
-/* invoke() - for 'relax' mode */
+/**
+ * Operator `invoke()` - for 'relax' mode.
+ */
static int pose_slide_relax_rest_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseSlideOp *pso;
- /* initialize data */
+ /* Initialize data. */
if (pose_slide_init(C, op, POSESLIDE_RELAX_REST) == 0) {
pose_slide_exit(op);
return OPERATOR_CANCELLED;
@@ -1887,19 +1952,21 @@ static int pose_slide_relax_rest_invoke(bContext *C, wmOperator *op, const wmEve
pso->last_cursor_x = event->x;
- /* Initialize percentage so that it won't pop on first mouse move. */
- pose_slide_mouse_update_percentage(pso, op, event);
+ /* Initialize factor so that it won't pop on first mouse move. */
+ pose_slide_mouse_update_factor(pso, op, event);
- /* do common setup work */
+ /* Do common setup work. */
return pose_slide_invoke_common(C, op, pso);
}
-/* exec() - for relax */
+/**
+ * Operator `exec()` - for relax.
+ */
static int pose_slide_relax_rest_exec(bContext *C, wmOperator *op)
{
tPoseSlideOp *pso;
- /* initialize data (from RNA-props) */
+ /* Initialize data (from RNA-props). */
if (pose_slide_init(C, op, POSESLIDE_RELAX_REST) == 0) {
pose_slide_exit(op);
return OPERATOR_CANCELLED;
@@ -1907,7 +1974,7 @@ static int pose_slide_relax_rest_exec(bContext *C, wmOperator *op)
pso = op->customdata;
- /* do common exec work */
+ /* Do common exec work. */
return pose_slide_exec_common(C, op, pso);
}
@@ -1934,12 +2001,14 @@ void POSE_OT_relax_rest(wmOperatorType *ot)
/* ........................ */
-/* invoke() - for 'breakdown' mode */
+/**
+ * Operator `invoke()` - for 'breakdown' mode.
+ */
static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseSlideOp *pso;
- /* initialize data */
+ /* Initialize data. */
if (pose_slide_init(C, op, POSESLIDE_BREAKDOWN) == 0) {
pose_slide_exit(op);
return OPERATOR_CANCELLED;
@@ -1949,19 +2018,21 @@ static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEven
pso->last_cursor_x = event->x;
- /* Initialize percentage so that it won't pop on first mouse move. */
- pose_slide_mouse_update_percentage(pso, op, event);
+ /* Initialize factor so that it won't pop on first mouse move. */
+ pose_slide_mouse_update_factor(pso, op, event);
- /* do common setup work */
+ /* Do common setup work. */
return pose_slide_invoke_common(C, op, pso);
}
-/* exec() - for breakdown */
+/**
+ * Operator exec() - for breakdown.
+ */
static int pose_slide_breakdown_exec(bContext *C, wmOperator *op)
{
tPoseSlideOp *pso;
- /* initialize data (from RNA-props) */
+ /* Initialize data (from RNA-props). */
if (pose_slide_init(C, op, POSESLIDE_BREAKDOWN) == 0) {
pose_slide_exit(op);
return OPERATOR_CANCELLED;
@@ -1969,7 +2040,7 @@ static int pose_slide_breakdown_exec(bContext *C, wmOperator *op)
pso = op->customdata;
- /* do common exec work */
+ /* Do common exec work. */
return pose_slide_exec_common(C, op, pso);
}
@@ -1999,36 +2070,39 @@ void POSE_OT_breakdown(wmOperatorType *ot)
/* "termination conditions" - i.e. when we stop */
typedef enum ePosePropagate_Termination {
- /* stop after the current hold ends */
+ /** Stop after the current hold ends. */
POSE_PROPAGATE_SMART_HOLDS = 0,
- /* only do on the last keyframe */
+ /** Only do on the last keyframe. */
POSE_PROPAGATE_LAST_KEY,
- /* stop after the next keyframe */
+ /** Stop after the next keyframe. */
POSE_PROPAGATE_NEXT_KEY,
- /* stop after the specified frame */
+ /** Stop after the specified frame. */
POSE_PROPAGATE_BEFORE_FRAME,
- /* stop when we run out of keyframes */
+ /** Stop when we run out of keyframes. */
POSE_PROPAGATE_BEFORE_END,
- /* only do on keyframes that are selected */
+ /** Only do on keyframes that are selected. */
POSE_PROPAGATE_SELECTED_KEYS,
- /* only do on the frames where markers are selected */
+ /** Only do on the frames where markers are selected. */
POSE_PROPAGATE_SELECTED_MARKERS,
} ePosePropagate_Termination;
-/* Termination data needed for some modes -
- * assumes only one of these entries will be needed at a time. */
+/**
+ * Termination data needed for some modes -
+ * assumes only one of these entries will be needed at a time.
+ */
typedef union tPosePropagate_ModeData {
- /* smart holds + before frame: frame number to stop on */
+ /** Smart holds + before frame: frame number to stop on. */
float end_frame;
- /* selected markers: listbase for CfraElem's marking these frames */
+ /** Selected markers: listbase for CfraElem's marking these frames. */
ListBase sel_markers;
} tPosePropagate_ModeData;
/* --------------------------------- */
-/* get frame on which the "hold" for the bone ends
+/**
+ * Get frame on which the "hold" for the bone ends.
* XXX: this may not really work that well if a bone moves on some channels and not others
* if this happens to be a major issue, scrap this, and just make this happen
* independently per F-Curve
@@ -2042,7 +2116,7 @@ static float pose_propagate_get_boneHoldEndFrame(tPChanFCurveLink *pfl, float st
LinkData *ld;
float endFrame = startFrame;
- /* set up optimized data-structures for searching for relevant keyframes + holds */
+ /* Set up optimized data-structures for searching for relevant keyframes + holds. */
BLI_dlrbTree_init(&keys);
for (ld = pfl->fcurves.first; ld; ld = ld->next) {
@@ -2050,7 +2124,7 @@ static float pose_propagate_get_boneHoldEndFrame(tPChanFCurveLink *pfl, float st
fcurve_to_keylist(adt, fcu, &keys, 0);
}
- /* find the long keyframe (i.e. hold), and hence obtain the endFrame value
+ /* Find the long keyframe (i.e. hold), and hence obtain the endFrame value
* - the best case would be one that starts on the frame itself
*/
ActKeyColumn *ab = (ActKeyColumn *)BLI_dlrbTree_search_exact(
@@ -2064,67 +2138,68 @@ static float pose_propagate_get_boneHoldEndFrame(tPChanFCurveLink *pfl, float st
* otherwise forget it, as we'd be overwriting some valid data.
*/
if (ab == NULL) {
- /* we've got case 1, so try the one after */
+ /* We've got case 1, so try the one after. */
ab = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &startFrame);
if ((actkeyblock_get_valid_hold(ab) & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) {
- /* try the block before this frame then as last resort */
+ /* Try the block before this frame then as last resort. */
ab = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &startFrame);
}
}
- /* whatever happens, stop searching now... */
+ /* Whatever happens, stop searching now.... */
if ((actkeyblock_get_valid_hold(ab) & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) {
- /* restrict range to just the frame itself
- * i.e. everything is in motion, so no holds to safely overwrite
- */
+ /* Restrict range to just the frame itself
+ * i.e. everything is in motion, so no holds to safely overwrite. */
ab = NULL;
}
- /* check if we can go any further than we've already gone */
+ /* Check if we can go any further than we've already gone. */
if (ab) {
- /* go to next if it is also valid and meets "extension" criteria */
+ /* Go to next if it is also valid and meets "extension" criteria. */
while (ab->next) {
ActKeyColumn *abn = ab->next;
- /* must be valid */
+ /* Must be valid. */
if ((actkeyblock_get_valid_hold(abn) & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) {
break;
}
- /* should have the same number of curves */
+ /* Should have the same number of curves. */
if (ab->totblock != abn->totblock) {
break;
}
- /* we can extend the bounds to the end of this "next" block now */
+ /* We can extend the bounds to the end of this "next" block now. */
ab = abn;
}
- /* end frame can now take the value of the end of the block */
+ /* End frame can now take the value of the end of the block. */
endFrame = ab->next->cfra;
}
- /* free temp memory */
+ /* Free temp memory. */
BLI_dlrbTree_free(&keys);
- /* return the end frame we've found */
+ /* Return the end frame we've found. */
return endFrame;
}
-/* get reference value from F-Curve using RNA */
+/**
+ * Get reference value from F-Curve using RNA.
+ */
static bool pose_propagate_get_refVal(Object *ob, FCurve *fcu, float *value)
{
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
bool found = false;
- /* base pointer is always the object -> id_ptr */
+ /* Base pointer is always the `object -> id_ptr`. */
RNA_id_pointer_create(&ob->id, &id_ptr);
- /* resolve the property... */
+ /* Resolve the property. */
if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
if (RNA_property_array_check(prop)) {
- /* array */
+ /* Array. */
if (fcu->array_index < RNA_property_array_length(&ptr, prop)) {
found = true;
switch (RNA_property_type(prop)) {
@@ -2144,7 +2219,7 @@ static bool pose_propagate_get_refVal(Object *ob, FCurve *fcu, float *value)
}
}
else {
- /* not an array */
+ /* Not an array. */
found = true;
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
@@ -2169,7 +2244,9 @@ static bool pose_propagate_get_refVal(Object *ob, FCurve *fcu, float *value)
return found;
}
-/* propagate just works along each F-Curve in turn */
+/**
+ * Propagate just works along each F-Curve in turn.
+ */
static void pose_propagate_fcurve(
wmOperator *op, Object *ob, FCurve *fcu, float startFrame, tPosePropagate_ModeData modeData)
{
@@ -2178,31 +2255,31 @@ static void pose_propagate_fcurve(
BezTriple *bezt;
float refVal = 0.0f;
bool keyExists;
- int i, match;
+ int i;
bool first = true;
- /* skip if no keyframes to edit */
+ /* Skip if no keyframes to edit. */
if ((fcu->bezt == NULL) || (fcu->totvert < 2)) {
return;
}
- /* find the reference value from bones directly, which means that the user
+ /* Find the reference value from bones directly, which means that the user
* doesn't need to firstly keyframe the pose (though this doesn't mean that
- * they can't either)
- */
+ * they can't either). */
if (!pose_propagate_get_refVal(ob, fcu, &refVal)) {
return;
}
- /* find the first keyframe to start propagating from
+ /* Find the first keyframe to start propagating from:
* - if there's a keyframe on the current frame, we probably want to save this value there too
- * since it may be as of yet unkeyed
+ * since it may be as of yet un-keyed
* - if starting before the starting frame, don't touch the key, as it may have had some valid
* values
* - if only doing selected keyframes, start from the first one
*/
if (mode != POSE_PROPAGATE_SELECTED_KEYS) {
- match = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, startFrame, fcu->totvert, &keyExists);
+ const int match = BKE_fcurve_bezt_binarysearch_index(
+ fcu->bezt, startFrame, fcu->totvert, &keyExists);
if (fcu->bezt[match].vec[1][0] < startFrame) {
i = match + 1;
@@ -2212,58 +2289,58 @@ static void pose_propagate_fcurve(
}
}
else {
- /* selected - start from first keyframe */
+ /* Selected - start from first keyframe. */
i = 0;
}
for (bezt = &fcu->bezt[i]; i < fcu->totvert; i++, bezt++) {
- /* additional termination conditions based on the operator 'mode' property go here... */
+ /* Additional termination conditions based on the operator 'mode' property go here. */
if (ELEM(mode, POSE_PROPAGATE_BEFORE_FRAME, POSE_PROPAGATE_SMART_HOLDS)) {
- /* stop if keyframe is outside the accepted range */
+ /* Stop if keyframe is outside the accepted range. */
if (bezt->vec[1][0] > modeData.end_frame) {
break;
}
}
else if (mode == POSE_PROPAGATE_NEXT_KEY) {
- /* stop after the first keyframe has been processed */
+ /* Stop after the first keyframe has been processed. */
if (first == false) {
break;
}
}
else if (mode == POSE_PROPAGATE_LAST_KEY) {
- /* only affect this frame if it will be the last one */
+ /* Only affect this frame if it will be the last one. */
if (i != (fcu->totvert - 1)) {
continue;
}
}
else if (mode == POSE_PROPAGATE_SELECTED_MARKERS) {
- /* only allow if there's a marker on this frame */
+ /* Only allow if there's a marker on this frame. */
CfraElem *ce = NULL;
- /* stop on matching marker if there is one */
+ /* Stop on matching marker if there is one. */
for (ce = modeData.sel_markers.first; ce; ce = ce->next) {
if (ce->cfra == round_fl_to_int(bezt->vec[1][0])) {
break;
}
}
- /* skip this keyframe if no marker */
+ /* Skip this keyframe if no marker. */
if (ce == NULL) {
continue;
}
}
else if (mode == POSE_PROPAGATE_SELECTED_KEYS) {
- /* only allow if this keyframe is already selected - skip otherwise */
+ /* Only allow if this keyframe is already selected - skip otherwise. */
if (BEZT_ISSEL_ANY(bezt) == 0) {
continue;
}
}
- /* just flatten handles, since values will now be the same either side... */
+ /* Just flatten handles, since values will now be the same either side. */
/* TODO: perhaps a fade-out modulation of the value is required here (optional once again)? */
bezt->vec[0][1] = bezt->vec[1][1] = bezt->vec[2][1] = refVal;
- /* select keyframe to indicate that it's been changed */
+ /* Select keyframe to indicate that it's been changed. */
bezt->f2 |= SELECT;
first = false;
}
@@ -2283,7 +2360,7 @@ static int pose_propagate_exec(bContext *C, wmOperator *op)
tPosePropagate_ModeData modeData;
const int mode = RNA_enum_get(op->ptr, "mode");
- /* isolate F-Curves related to the selected bones */
+ /* Isolate F-Curves related to the selected bones. */
poseAnim_mapping_get(C, &pflinks);
if (BLI_listbase_is_empty(&pflinks)) {
@@ -2294,42 +2371,41 @@ static int pose_propagate_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* mode-specific data preprocessing (requiring no access to curves) */
+ /* Mode-specific data preprocessing (requiring no access to curves). */
if (mode == POSE_PROPAGATE_SELECTED_MARKERS) {
- /* get a list of selected markers */
+ /* Get a list of selected markers. */
ED_markers_make_cfra_list(&scene->markers, &modeData.sel_markers, SELECT);
}
else {
- /* assume everything else wants endFrame */
+ /* Assume everything else wants endFrame. */
modeData.end_frame = RNA_float_get(op->ptr, "end_frame");
}
- /* for each bone, perform the copying required */
+ /* For each bone, perform the copying required. */
for (pfl = pflinks.first; pfl; pfl = pfl->next) {
LinkData *ld;
- /* mode-specific data preprocessing (requiring access to all curves) */
+ /* Mode-specific data preprocessing (requiring access to all curves). */
if (mode == POSE_PROPAGATE_SMART_HOLDS) {
- /* we store in endFrame the end frame of the "long keyframe" (i.e. a held value) starting
- * from the keyframe that occurs after the current frame
- */
+ /* We store in endFrame the end frame of the "long keyframe" (i.e. a held value) starting
+ * from the keyframe that occurs after the current frame. */
modeData.end_frame = pose_propagate_get_boneHoldEndFrame(pfl, (float)CFRA);
}
- /* go through propagating pose to keyframes, curve by curve */
+ /* Go through propagating pose to keyframes, curve by curve. */
for (ld = pfl->fcurves.first; ld; ld = ld->next) {
pose_propagate_fcurve(op, pfl->ob, (FCurve *)ld->data, (float)CFRA, modeData);
}
}
- /* free temp data */
+ /* Free temp data. */
poseAnim_mapping_free(&pflinks);
if (mode == POSE_PROPAGATE_SELECTED_MARKERS) {
BLI_freelistN(&modeData.sel_markers);
}
- /* updates + notifiers */
+ /* Updates + notifiers. */
FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
poseAnim_mapping_refresh(C, scene, ob);
}
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index 43ab20eb71c..1118e84ef4f 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -144,26 +144,25 @@ static void applyarmature_transfer_properties(EditBone *curbone,
if (pchan->bone->segments > 1) {
/* Combine rest/pose values. */
curbone->curve_in_x += pchan_eval->curve_in_x;
- curbone->curve_in_y += pchan_eval->curve_in_y;
+ curbone->curve_in_z += pchan_eval->curve_in_z;
curbone->curve_out_x += pchan_eval->curve_out_x;
- curbone->curve_out_y += pchan_eval->curve_out_y;
+ curbone->curve_out_z += pchan_eval->curve_out_z;
curbone->roll1 += pchan_eval->roll1;
curbone->roll2 += pchan_eval->roll2;
curbone->ease1 += pchan_eval->ease1;
curbone->ease2 += pchan_eval->ease2;
- curbone->scale_in_x *= pchan_eval->scale_in_x;
- curbone->scale_in_y *= pchan_eval->scale_in_y;
- curbone->scale_out_x *= pchan_eval->scale_out_x;
- curbone->scale_out_y *= pchan_eval->scale_out_y;
+ mul_v3_v3(curbone->scale_in, pchan_eval->scale_in);
+ mul_v3_v3(curbone->scale_out, pchan_eval->scale_out);
/* Reset pose values. */
pchan->curve_in_x = pchan->curve_out_x = 0.0f;
- pchan->curve_in_y = pchan->curve_out_y = 0.0f;
+ pchan->curve_in_z = pchan->curve_out_z = 0.0f;
pchan->roll1 = pchan->roll2 = 0.0f;
pchan->ease1 = pchan->ease2 = 0.0f;
- pchan->scale_in_x = pchan->scale_in_y = 1.0f;
- pchan->scale_out_x = pchan->scale_out_y = 1.0f;
+
+ copy_v3_fl(pchan->scale_in, 1.0f);
+ copy_v3_fl(pchan->scale_out, 1.0f);
}
/* Clear transform values for pchan. */
@@ -458,7 +457,7 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
/* For the affected bones, reset specific constraints that are now known to be invalid. */
applyarmature_reset_constraints(pose, use_selected);
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
@@ -558,7 +557,7 @@ static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op))
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
}
@@ -699,18 +698,17 @@ static bPoseChannel *pose_bone_do_paste(Object *ob,
/* B-Bone posing options should also be included... */
pchan->curve_in_x = chan->curve_in_x;
- pchan->curve_in_y = chan->curve_in_y;
+ pchan->curve_in_z = chan->curve_in_z;
pchan->curve_out_x = chan->curve_out_x;
- pchan->curve_out_y = chan->curve_out_y;
+ pchan->curve_out_z = chan->curve_out_z;
pchan->roll1 = chan->roll1;
pchan->roll2 = chan->roll2;
pchan->ease1 = chan->ease1;
pchan->ease2 = chan->ease2;
- pchan->scale_in_x = chan->scale_in_x;
- pchan->scale_in_y = chan->scale_in_y;
- pchan->scale_out_x = chan->scale_out_x;
- pchan->scale_out_y = chan->scale_out_y;
+
+ copy_v3_v3(pchan->scale_in, chan->scale_in);
+ copy_v3_v3(pchan->scale_out, chan->scale_out);
/* paste flipped pose? */
if (flip) {
@@ -972,8 +970,9 @@ static void pchan_clear_scale(bPoseChannel *pchan)
pchan->ease1 = 0.0f;
pchan->ease2 = 0.0f;
- pchan->scale_in_x = pchan->scale_in_y = 1.0f;
- pchan->scale_out_x = pchan->scale_out_y = 1.0f;
+
+ copy_v3_fl(pchan->scale_in, 1.0f);
+ copy_v3_fl(pchan->scale_out, 1.0f);
}
/* Clear the scale. When X-mirror is enabled,
* also clear the scale of the mirrored pose channel. */
@@ -1136,9 +1135,9 @@ static void pchan_clear_rot(bPoseChannel *pchan)
pchan->roll2 = 0.0f;
pchan->curve_in_x = 0.0f;
- pchan->curve_in_y = 0.0f;
+ pchan->curve_in_z = 0.0f;
pchan->curve_out_x = 0.0f;
- pchan->curve_out_y = 0.0f;
+ pchan->curve_out_z = 0.0f;
}
/* Clear the rotation. When X-mirror is enabled,
* also clear the rotation of the mirrored pose channel. */
@@ -1229,7 +1228,7 @@ static int pose_clear_transform_generic_exec(bContext *C,
DEG_id_tag_update(&ob_iter->id, ID_RECALC_GEOMETRY);
- /* note, notifier might evolve */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob_iter);
}
}
@@ -1384,7 +1383,7 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
BKE_animsys_evaluate_animdata(
&workob.id, workob.adt, &anim_eval_context, ADT_RECALC_ANIM, false);
- /* copy back values, but on selected bones only */
+ /* Copy back values, but on selected bones only. */
for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
pose_bone_do_paste(ob, pchan, only_select, 0);
}
diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c
index 75348c2b196..500b9663a6c 100644
--- a/source/blender/editors/armature/pose_utils.c
+++ b/source/blender/editors/armature/pose_utils.c
@@ -116,15 +116,14 @@ static void fcurves_to_pchan_links_get(ListBase *pfLinks,
pfl->roll1 = pchan->roll1;
pfl->roll2 = pchan->roll2;
pfl->curve_in_x = pchan->curve_in_x;
- pfl->curve_in_y = pchan->curve_in_y;
+ pfl->curve_in_z = pchan->curve_in_z;
pfl->curve_out_x = pchan->curve_out_x;
- pfl->curve_out_y = pchan->curve_out_y;
+ pfl->curve_out_z = pchan->curve_out_z;
pfl->ease1 = pchan->ease1;
pfl->ease2 = pchan->ease2;
- pfl->scale_in_x = pchan->scale_in_x;
- pfl->scale_in_y = pchan->scale_in_y;
- pfl->scale_out_x = pchan->scale_out_x;
- pfl->scale_out_y = pchan->scale_out_y;
+
+ copy_v3_v3(pfl->scale_in, pchan->scale_in);
+ copy_v3_v3(pfl->scale_out, pchan->scale_out);
/* make copy of custom properties */
if (pchan->prop && (transFlags & ACT_TRANS_PROP)) {
@@ -145,7 +144,9 @@ Object *poseAnim_object_get(Object *ob_)
return NULL;
}
-/* get sets of F-Curves providing transforms for the bones in the Pose */
+/**
+ * Get sets of F-Curves providing transforms for the bones in the Pose.
+ */
void poseAnim_mapping_get(bContext *C, ListBase *pfLinks)
{
/* for each Pose-Channel which gets affected, get the F-Curves for that channel
@@ -191,7 +192,7 @@ void poseAnim_mapping_get(bContext *C, ListBase *pfLinks)
}
}
-/* free F-Curve <-> PoseChannel links */
+/* Free F-Curve <-> PoseChannel links. */
void poseAnim_mapping_free(ListBase *pfLinks)
{
tPChanFCurveLink *pfl, *pfln = NULL;
@@ -251,15 +252,14 @@ void poseAnim_mapping_reset(ListBase *pfLinks)
pchan->roll1 = pfl->roll1;
pchan->roll2 = pfl->roll2;
pchan->curve_in_x = pfl->curve_in_x;
- pchan->curve_in_y = pfl->curve_in_y;
+ pchan->curve_in_z = pfl->curve_in_z;
pchan->curve_out_x = pfl->curve_out_x;
- pchan->curve_out_y = pfl->curve_out_y;
+ pchan->curve_out_z = pfl->curve_out_z;
pchan->ease1 = pfl->ease1;
pchan->ease2 = pfl->ease2;
- pchan->scale_in_x = pfl->scale_in_x;
- pchan->scale_in_y = pfl->scale_in_y;
- pchan->scale_out_x = pfl->scale_out_x;
- pchan->scale_out_y = pfl->scale_out_y;
+
+ copy_v3_v3(pchan->scale_in, pfl->scale_in);
+ copy_v3_v3(pchan->scale_out, pfl->scale_out);
/* just overwrite values of properties from the stored copies (there should be some) */
if (pfl->oldprops) {
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 535ccaa06fd..e7d97ce343c 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1929,7 +1929,7 @@ static void ed_curve_delete_selected(Object *obedit, View3D *v3d)
}
/* Never allow the order to exceed the number of points
- * - note, this is ok but changes unselected nurbs, disable for now */
+ * NOTE: this is ok but changes unselected nurbs, disable for now. */
#if 0
if ((nu != NULL) && (nu->type == CU_NURBS)) {
clamp_nurb_order_u(nu);
@@ -1988,7 +1988,7 @@ static void ed_curve_delete_selected(Object *obedit, View3D *v3d)
nu->bp = bp1;
/* Never allow the order to exceed the number of points
- * - note, this is ok but changes unselected nurbs, disable for now */
+ * NOTE: this is ok but changes unselected nurbs, disable for now. */
#if 0
if (nu->type == CU_NURBS) {
clamp_nurb_order_u(nu);
@@ -3747,8 +3747,8 @@ static void subdividenurb(Object *obedit, View3D *v3d, int number_cuts)
}
if (sel) { /* U ! */
- /* Inserting U points is sort of 'default' Flat curves only get */
- /* U points inserted in them. */
+ /* Inserting U points is sort of 'default' Flat curves only get
+ * U points inserted in them. */
bpn = bpnew = MEM_mallocN((sel + nu->pntsu) * nu->pntsv * sizeof(BPoint),
"subdivideNurb4");
bp = nu->bp;
@@ -3786,7 +3786,7 @@ static void subdividenurb(Object *obedit, View3D *v3d, int number_cuts)
MEM_freeN(usel);
MEM_freeN(vsel);
- } /* End of 'if (nu->type == CU_NURBS)' */
+ } /* End of `if (nu->type == CU_NURBS)`. */
}
}
@@ -6646,7 +6646,7 @@ void CURVE_OT_dissolve_verts(wmOperatorType *ot)
static bool nurb_bezt_flag_any(const Nurb *nu, const char flag_test)
{
- BezTriple *bezt = nu->bezt;
+ const BezTriple *bezt;
int i;
for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
@@ -6877,7 +6877,7 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op)
LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
Nurb *newnu = BKE_nurb_duplicate(nu);
- if (ob_active->totcol) { /* TODO, merge material lists */
+ if (ob_active->totcol) { /* TODO: merge material lists. */
CLAMP(newnu->mat_nr, 0, ob_active->totcol - 1);
}
else {
diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c
index 065763764c1..2be55accd3a 100644
--- a/source/blender/editors/curve/editcurve_add.c
+++ b/source/blender/editors/curve/editcurve_add.c
@@ -485,7 +485,7 @@ Nurb *ED_curve_add_nurbs_primitive(
break;
default: /* should never happen */
- BLI_assert(!"invalid nurbs type");
+ BLI_assert_msg(0, "invalid nurbs type");
return NULL;
}
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 8842274e017..26906b0ddcd 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -128,6 +128,7 @@ struct CurveDrawData {
} prev;
ViewContext vc;
+ ViewDepths *depths;
enum {
CURVE_DRAW_IDLE = 0,
CURVE_DRAW_PAINTING = 1,
@@ -188,7 +189,6 @@ static bool stroke_elem_project(const struct CurveDrawData *cdd,
float r_normal_world[3])
{
ARegion *region = cdd->vc.region;
- RegionView3D *rv3d = cdd->vc.rv3d;
bool is_location_world_set = false;
@@ -204,13 +204,13 @@ static bool stroke_elem_project(const struct CurveDrawData *cdd,
}
}
else {
- const ViewDepths *depths = rv3d->depths;
+ const ViewDepths *depths = cdd->depths;
if (depths && ((uint)mval_i[0] < depths->w) && ((uint)mval_i[1] < depths->h)) {
float depth_fl = 1.0f;
ED_view3d_depth_read_cached(depths, mval_i, 0, &depth_fl);
const double depth = (double)depth_fl;
if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
- if (ED_view3d_depth_unproject(region, mval_i, depth, r_location_world)) {
+ if (ED_view3d_depth_unproject_v3(region, mval_i, depth, r_location_world)) {
is_location_world_set = true;
if (r_normal_world) {
zero_v3(r_normal_world);
@@ -219,7 +219,7 @@ static bool stroke_elem_project(const struct CurveDrawData *cdd,
if (surface_offset != 0.0f) {
const float offset = cdd->project.use_surface_offset_absolute ? 1.0f : radius;
float normal[3];
- if (ED_view3d_depth_read_cached_normal(&cdd->vc, mval_i, normal)) {
+ if (ED_view3d_depth_read_cached_normal(region, depths, mval_i, normal)) {
madd_v3_v3fl(r_location_world, normal, offset * surface_offset);
if (r_normal_world) {
copy_v3_v3(r_normal_world, normal);
@@ -387,7 +387,6 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C),
GPU_matrix_translate_3f(selem->location_local[0] - location_prev[0],
selem->location_local[1] - location_prev[1],
selem->location_local[2] - location_prev[2]);
- location_prev = selem->location_local;
const float radius = stroke_elem_radius(cdd, selem);
@@ -529,7 +528,7 @@ static void curve_draw_event_add_first(wmOperator *op, const wmEvent *event)
if (ELEM(cps->surface_plane,
CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW,
CURVE_PAINT_SURFACE_PLANE_NORMAL_SURFACE)) {
- if (ED_view3d_depth_read_cached_normal(&cdd->vc, event->mval, normal)) {
+ if (ED_view3d_depth_read_cached_normal(cdd->vc.region, cdd->depths, event->mval, normal)) {
if (cps->surface_plane == CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW) {
float cross_a[3], cross_b[3];
cross_v3_v3v3(cross_a, rv3d->viewinv[2], normal);
@@ -623,6 +622,9 @@ static void curve_draw_exit(wmOperator *op)
BLI_mempool_destroy(cdd->stroke_elem_pool);
}
+ if (cdd->depths) {
+ ED_view3d_depths_free(cdd->depths);
+ }
MEM_freeN(cdd);
op->customdata = NULL;
}
@@ -696,7 +698,7 @@ static void curve_draw_exec_precalc(wmOperator *op)
}
if ((cps->radius_taper_start != 0.0f) || (cps->radius_taper_end != 0.0f)) {
- /* note, we could try to de-duplicate the length calculations above */
+ /* NOTE: we could try to de-duplicate the length calculations above. */
const int stroke_len = BLI_mempool_len(cdd->stroke_elem_pool);
BLI_mempool_iter iter;
@@ -1085,10 +1087,14 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* needed or else the draw matrix can be incorrect */
view3d_operator_needs_opengl(C);
- ED_view3d_depth_override(
- cdd->vc.depsgraph, cdd->vc.region, cdd->vc.v3d, NULL, V3D_DEPTH_NO_GPENCIL, true);
+ ED_view3d_depth_override(cdd->vc.depsgraph,
+ cdd->vc.region,
+ cdd->vc.v3d,
+ NULL,
+ V3D_DEPTH_NO_GPENCIL,
+ &cdd->depths);
- if (cdd->vc.rv3d->depths != NULL) {
+ if (cdd->depths != NULL) {
cdd->project.use_depth = true;
}
else {
diff --git a/source/blender/editors/curve/editcurve_query.c b/source/blender/editors/curve/editcurve_query.c
index 56392aab5bf..a8fd3ea2803 100644
--- a/source/blender/editors/curve/editcurve_query.c
+++ b/source/blender/editors/curve/editcurve_query.c
@@ -168,8 +168,8 @@ bool ED_curve_pick_vert(ViewContext *vc,
void ED_curve_nurb_vert_selected_find(
Curve *cu, View3D *v3d, Nurb **r_nu, BezTriple **r_bezt, BPoint **r_bp)
{
- /* in nu and (bezt or bp) selected are written if there's 1 sel. */
- /* if more points selected in 1 spline: return only nu, bezt and bp are 0 */
+ /* In nu and (bezt or bp) selected are written if there's 1 sel. */
+ /* If more points selected in 1 spline: return only nu, bezt and bp are 0. */
ListBase *editnurb = &cu->editnurb->nurbs;
BezTriple *bezt1;
BPoint *bp1;
diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c
index 90cefef38ee..721aa7afecc 100644
--- a/source/blender/editors/curve/editcurve_select.c
+++ b/source/blender/editors/curve/editcurve_select.c
@@ -56,6 +56,10 @@
#include "DEG_depsgraph.h"
+/* -------------------------------------------------------------------- */
+/** \name Utilities
+ * \{ */
+
/* returns 1 in case (de)selection was successful */
bool select_beztriple(BezTriple *bezt, bool selstatus, uint8_t flag, eVisible_Types hidden)
{
@@ -107,10 +111,10 @@ static bool swap_selection_bpoint(BPoint *bp)
return select_bpoint(bp, SELECT, SELECT, VISIBLE);
}
-bool ED_curve_nurb_select_check(View3D *v3d, Nurb *nu)
+bool ED_curve_nurb_select_check(const View3D *v3d, const Nurb *nu)
{
if (nu->type == CU_BEZIER) {
- BezTriple *bezt;
+ const BezTriple *bezt;
int i;
for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
@@ -120,7 +124,7 @@ bool ED_curve_nurb_select_check(View3D *v3d, Nurb *nu)
}
}
else {
- BPoint *bp;
+ const BPoint *bp;
int i;
for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
@@ -132,12 +136,12 @@ bool ED_curve_nurb_select_check(View3D *v3d, Nurb *nu)
return false;
}
-int ED_curve_nurb_select_count(View3D *v3d, Nurb *nu)
+int ED_curve_nurb_select_count(const View3D *v3d, const Nurb *nu)
{
int sel = 0;
if (nu->type == CU_BEZIER) {
- BezTriple *bezt;
+ const BezTriple *bezt;
int i;
for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) {
@@ -147,7 +151,7 @@ int ED_curve_nurb_select_count(View3D *v3d, Nurb *nu)
}
}
else {
- BPoint *bp;
+ const BPoint *bp;
int i;
for (i = nu->pntsu * nu->pntsv, bp = nu->bp; i--; bp++) {
@@ -223,7 +227,7 @@ bool ED_curve_nurb_deselect_all(const Nurb *nu)
return changed;
}
-int ED_curve_select_count(View3D *v3d, struct EditNurb *editnurb)
+int ED_curve_select_count(const View3D *v3d, const EditNurb *editnurb)
{
int sel = 0;
Nurb *nu;
@@ -235,9 +239,9 @@ int ED_curve_select_count(View3D *v3d, struct EditNurb *editnurb)
return sel;
}
-bool ED_curve_select_check(View3D *v3d, struct EditNurb *editnurb)
+bool ED_curve_select_check(const View3D *v3d, const EditNurb *editnurb)
{
- LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
+ LISTBASE_FOREACH (const Nurb *, nu, &editnurb->nurbs) {
if (ED_curve_nurb_select_check(v3d, nu)) {
return true;
}
@@ -398,12 +402,18 @@ static void select_adjacent_cp(ListBase *editnurb,
}
}
-/**************** select start/end operators **************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Start/End Operators
+ * \{ */
-/* (de)selects first or last of visible part of each Nurb depending on selFirst
- * selFirst: defines the end of which to select
- * doswap: defines if selection state of each first/last control point is swapped
- * selstatus: selection status in case doswap is false
+/**
+ * (De)selects first or last of visible part of each #Nurb depending on `selfirst`.
+ *
+ * \param selfirst: defines the end of which to select.
+ * \param doswap: defines if selection state of each first/last control point is swapped.
+ * \param selstatus: selection status in case `doswap` is false.
*/
static void selectend_nurb(Object *obedit, eEndPoint_Types selfirst, bool doswap, bool selstatus)
{
@@ -543,6 +553,12 @@ void CURVE_OT_de_select_last(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select All Operator
+ * \{ */
+
static int de_select_all_exec(bContext *C, wmOperator *op)
{
int action = RNA_enum_get(op->ptr, "action");
@@ -612,7 +628,11 @@ void CURVE_OT_select_all(wmOperatorType *ot)
WM_operator_properties_select_all(ot);
}
-/***************** select linked operator ******************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Linked Operator
+ * \{ */
static int select_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -668,7 +688,11 @@ void CURVE_OT_select_linked(wmOperatorType *ot)
/* properties */
}
-/***************** select linked pick operator ******************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Linked Pick Operator
+ * \{ */
static int select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
@@ -740,7 +764,11 @@ void CURVE_OT_select_linked_pick(wmOperatorType *ot)
"Deselect linked control points rather than selecting them");
}
-/***************** select row operator **********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Row Operator
+ * \{ */
static int select_row_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -802,7 +830,11 @@ void CURVE_OT_select_row(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/***************** select next operator **********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Next Operator
+ * \{ */
static int select_next_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -839,7 +871,11 @@ void CURVE_OT_select_next(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/***************** select previous operator **********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Previous Operator
+ * \{ */
static int select_previous_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -876,7 +912,11 @@ void CURVE_OT_select_previous(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/***************** select more operator **********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select More Operator
+ * \{ */
static void curve_select_more(Object *obedit)
{
@@ -885,10 +925,10 @@ static void curve_select_more(Object *obedit)
int a;
short sel = 0;
- /* note that NURBS surface is a special case because we mimic */
- /* the behavior of "select more" of mesh tools. */
- /* The algorithm is designed to work in planar cases so it */
- /* may not be optimal always (example: end of NURBS sphere) */
+ /* NOTE: NURBS surface is a special case because we mimic
+ * the behavior of "select more" of mesh tools.
+ * The algorithm is designed to work in planar cases so it
+ * may not be optimal always (example: end of NURBS sphere). */
if (obedit->type == OB_SURF) {
LISTBASE_FOREACH (Nurb *, nu, editnurb) {
BLI_bitmap *selbpoints;
@@ -984,7 +1024,11 @@ void CURVE_OT_select_more(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/******************** select less operator *****************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Less Operator
+ * \{ */
/* basic method: deselect if control point doesn't have all neighbors selected */
static void curve_select_less(Object *obedit)
@@ -1198,46 +1242,11 @@ void CURVE_OT_select_less(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/********************** select random *********************/
-
-static void curve_select_random(ListBase *editnurb, float randfac, int seed, bool select)
-{
- BezTriple *bezt;
- BPoint *bp;
- int a;
-
- RNG *rng = BLI_rng_new_srandom(seed);
-
- LISTBASE_FOREACH (Nurb *, nu, editnurb) {
- if (nu->type == CU_BEZIER) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- if (!bezt->hide) {
- if (BLI_rng_get_float(rng) < randfac) {
- select_beztriple(bezt, select, SELECT, VISIBLE);
- }
- }
- bezt++;
- }
- }
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
-
- while (a--) {
- if (!bp->hide) {
- if (BLI_rng_get_float(rng) < randfac) {
- select_bpoint(bp, select, SELECT, VISIBLE);
- }
- }
- bp++;
- }
- }
- }
+/** \} */
- BLI_rng_free(rng);
-}
+/* -------------------------------------------------------------------- */
+/** \name Select Random Operator
+ * \{ */
static int curve_select_random_exec(bContext *C, wmOperator *op)
{
@@ -1260,9 +1269,71 @@ static int curve_select_random_exec(bContext *C, wmOperator *op)
seed_iter += BLI_ghashutil_strhash_p(obedit->id.name);
}
- curve_select_random(editnurb, randfac, seed_iter, select);
- BKE_curve_nurb_vert_active_validate(obedit->data);
+ int totvert = 0;
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
+ if (nu->type == CU_BEZIER) {
+ int a = nu->pntsu;
+ BezTriple *bezt = nu->bezt;
+ while (a--) {
+ if (!bezt->hide) {
+ totvert++;
+ }
+ bezt++;
+ }
+ }
+ else {
+ int a = nu->pntsu * nu->pntsv;
+ BPoint *bp = nu->bp;
+ while (a--) {
+ if (!bp->hide) {
+ totvert++;
+ }
+ bp++;
+ }
+ }
+ }
+
+ BLI_bitmap *verts_selection_mask = BLI_BITMAP_NEW(totvert, __func__);
+ const int count_select = totvert * randfac;
+ for (int i = 0; i < count_select; i++) {
+ BLI_BITMAP_SET(verts_selection_mask, i, true);
+ }
+ BLI_bitmap_randomize(verts_selection_mask, totvert, seed_iter);
+
+ int bit_index = 0;
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
+ if (nu->type == CU_BEZIER) {
+ int a = nu->pntsu;
+ BezTriple *bezt = nu->bezt;
+
+ while (a--) {
+ if (!bezt->hide) {
+ if (BLI_BITMAP_TEST(verts_selection_mask, bit_index)) {
+ select_beztriple(bezt, select, SELECT, VISIBLE);
+ }
+ bit_index++;
+ }
+ bezt++;
+ }
+ }
+ else {
+ int a = nu->pntsu * nu->pntsv;
+ BPoint *bp = nu->bp;
+ while (a--) {
+ if (!bp->hide) {
+ if (BLI_BITMAP_TEST(verts_selection_mask, bit_index)) {
+ select_bpoint(bp, select, SELECT, VISIBLE);
+ }
+ bit_index++;
+ }
+ bp++;
+ }
+ }
+ }
+
+ MEM_freeN(verts_selection_mask);
+ BKE_curve_nurb_vert_active_validate(obedit->data);
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
@@ -1289,7 +1360,11 @@ void CURVE_OT_select_random(wmOperatorType *ot)
WM_operator_properties_select_random(ot);
}
-/********************* every nth number of point *******************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Every Nth Number of Point Operator
+ * \{ */
static void select_nth_bezt(Nurb *nu, BezTriple *bezt, const struct CheckerIntervalParams *params)
{
@@ -1421,6 +1496,8 @@ void CURVE_OT_select_nth(wmOperatorType *ot)
WM_operator_properties_checker_interval(ot, false);
}
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Select Similar Operator
* \{ */
diff --git a/source/blender/editors/curve/editcurve_undo.c b/source/blender/editors/curve/editcurve_undo.c
index b07c3c85f4a..210411c6eb5 100644
--- a/source/blender/editors/curve/editcurve_undo.c
+++ b/source/blender/editors/curve/editcurve_undo.c
@@ -97,7 +97,7 @@ static void undocurve_to_editcurve(Main *bmain, UndoCurve *ucu, Curve *cu, short
BKE_fcurves_copy(&ad->drivers, &ucu->drivers);
}
- /* copy */
+ /* Copy. */
for (nu = undobase->first; nu; nu = nu->next) {
newnu = BKE_nurb_duplicate(nu);
@@ -139,7 +139,7 @@ static void undocurve_from_editcurve(UndoCurve *ucu, Curve *cu, const short shap
BKE_fcurves_copy(&ucu->drivers, &ad->drivers);
}
- /* copy */
+ /* Copy. */
for (nu = nubase->first; nu; nu = nu->next) {
newnu = BKE_nurb_duplicate(nu);
@@ -267,7 +267,7 @@ static void curve_undosys_step_decode(struct bContext *C,
}
undocurve_to_editcurve(bmain, &elem->data, obedit->data, &obedit->shapenr);
cu->editnurb->needs_flush_to_id = 1;
- DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(&cu->id, ID_RECALC_GEOMETRY);
}
/* The first element is always active */
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 80771df3572..e43e4194c51 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -656,7 +656,7 @@ static void txt_add_object(bContext *C,
obedit = BKE_object_add(bmain, view_layer, OB_FONT, NULL);
base = view_layer->basact;
- /* seems to assume view align ? TODO - look into this, could be an operator option */
+ /* seems to assume view align ? TODO: look into this, could be an operator option. */
ED_object_base_init_transform_on_add(base->object, NULL, rot);
BKE_object_where_is_calc(depsgraph, scene, obedit);
@@ -1573,7 +1573,8 @@ static int delete_exec(bContext *C, wmOperator *op)
else if (*sel >= range[1]) {
*sel -= len_remove;
}
- else if (*sel < range[1]) {
+ else {
+ BLI_assert(*sel < range[1]);
/* pass */
*sel = range[0];
}
diff --git a/source/blender/editors/curve/editfont_undo.c b/source/blender/editors/curve/editfont_undo.c
index a305a997d50..6eaf8971eb0 100644
--- a/source/blender/editors/curve/editfont_undo.c
+++ b/source/blender/editors/curve/editfont_undo.c
@@ -341,7 +341,7 @@ static Object *editfont_object_from_context(bContext *C)
typedef struct FontUndoStep {
UndoStep step;
- /* note: will split out into list for multi-object-editmode. */
+ /* NOTE: will split out into list for multi-object-editmode. */
UndoRefID_Object obedit_ref;
UndoFont data;
} FontUndoStep;
@@ -379,7 +379,7 @@ static void font_undosys_step_decode(struct bContext *C,
Curve *cu = obedit->data;
undofont_to_editfont(&us->data, cu);
- DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(&cu->id, ID_RECALC_GEOMETRY);
ED_undo_object_set_active_or_warn(
CTX_data_scene(C), CTX_data_view_layer(C), obedit, us_p->name, &LOG);
diff --git a/source/blender/editors/geometry/geometry_attributes.c b/source/blender/editors/geometry/geometry_attributes.c
index 12f6bb90677..9b034d82a51 100644
--- a/source/blender/editors/geometry/geometry_attributes.c
+++ b/source/blender/editors/geometry/geometry_attributes.c
@@ -52,12 +52,16 @@ static const EnumPropertyItem *geometry_attribute_domain_itemf(bContext *C,
PropertyRNA *UNUSED(prop),
bool *r_free)
{
+ if (C == NULL) {
+ return DummyRNA_NULL_items;
+ }
+
Object *ob = ED_object_context(C);
- if (ob != NULL) {
- return rna_enum_attribute_domain_itemf(ob->data, r_free);
+ if (ob == NULL) {
+ return DummyRNA_NULL_items;
}
- return DummyRNA_NULL_items;
+ return rna_enum_attribute_domain_itemf(ob->data, r_free);
}
static int geometry_attribute_add_exec(bContext *C, wmOperator *op)
@@ -105,14 +109,6 @@ void GEOMETRY_OT_attribute_add(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_enum(ot->srna,
- "data_type",
- rna_enum_attribute_type_items,
- CD_PROP_FLOAT,
- "Data Type",
- "Type of data stored in attribute");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
- prop = RNA_def_enum(ot->srna,
"domain",
rna_enum_attribute_domain_items,
ATTR_DOMAIN_POINT,
@@ -120,6 +116,14 @@ void GEOMETRY_OT_attribute_add(wmOperatorType *ot)
"Type of element that attribute is stored on");
RNA_def_enum_funcs(prop, geometry_attribute_domain_itemf);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_enum(ot->srna,
+ "data_type",
+ rna_enum_attribute_type_items,
+ CD_PROP_FLOAT,
+ "Data Type",
+ "Type of data stored in attribute");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
static int geometry_attribute_remove_exec(bContext *C, wmOperator *op)
@@ -136,6 +140,11 @@ static int geometry_attribute_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ int *active_index = BKE_id_attributes_active_index_p(id);
+ if (*active_index > 0) {
+ *active_index -= 1;
+ }
+
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
diff --git a/source/blender/editors/gizmo_library/gizmo_draw_utils.c b/source/blender/editors/gizmo_library/gizmo_draw_utils.c
index 2896aa25930..2ec287a62e9 100644
--- a/source/blender/editors/gizmo_library/gizmo_draw_utils.c
+++ b/source/blender/editors/gizmo_library/gizmo_draw_utils.c
@@ -51,7 +51,7 @@ void wm_gizmo_geometryinfo_draw(const GizmoGeomInfo *info,
const bool UNUSED(select),
const float color[4])
{
- /* TODO store the Batches inside the GizmoGeomInfo and updated it when geom changes
+ /* TODO: store the Batches inside the GizmoGeomInfo and updated it when geom changes
* So we don't need to re-created and discard it every time */
GPUVertBuf *vbo;
diff --git a/source/blender/editors/gizmo_library/gizmo_library_presets.c b/source/blender/editors/gizmo_library/gizmo_library_presets.c
index 4e56ceb9fd4..f842c20b74f 100644
--- a/source/blender/editors/gizmo_library/gizmo_library_presets.c
+++ b/source/blender/editors/gizmo_library/gizmo_library_presets.c
@@ -41,7 +41,7 @@
#include "ED_gizmo_library.h" /* own include */
#include "gizmo_library_intern.h" /* own include */
-/* TODO, this is to be used by RNA. might move to ED_gizmo_library */
+/* TODO: this is to be used by RNA. might move to ED_gizmo_library. */
/**
* Given a single axis, orient the matrix to a different direction.
diff --git a/source/blender/editors/gizmo_library/gizmo_library_utils.c b/source/blender/editors/gizmo_library/gizmo_library_utils.c
index 847f3e3916c..7d0ae5afb9b 100644
--- a/source/blender/editors/gizmo_library/gizmo_library_utils.c
+++ b/source/blender/editors/gizmo_library/gizmo_library_utils.c
@@ -118,10 +118,10 @@ void gizmo_property_data_update(wmGizmo *gz,
const bool inverted)
{
if (gz_prop->custom_func.value_get_fn != NULL) {
- /* pass */
+ /* Pass. */
}
else if (gz_prop->prop != NULL) {
- /* pass */
+ /* Pass. */
}
else {
data->offset = 0.0f;
@@ -237,7 +237,7 @@ bool gizmo_window_project_3d(
if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) {
View3D *v3d = CTX_wm_view3d(C);
ARegion *region = CTX_wm_region(C);
- /* Note: we might want a custom reference point passed in,
+ /* NOTE: we might want a custom reference point passed in,
* instead of the gizmo center. */
ED_view3d_win_to_3d(v3d, region, mat[3], mval, r_co);
invert_m4(mat);
diff --git a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
index d99ce25451c..f286d3930e2 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
@@ -82,7 +82,7 @@ static void button2d_geom_draw_backdrop(const wmGizmo *gz,
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- /* TODO, other draw styles */
+ /* TODO: other draw styles. */
if (color[3] == 1.0 && fill_alpha == 1.0 && select == false) {
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(color);
diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
index deb89319f4f..6fd06b47656 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
@@ -774,7 +774,7 @@ static int gizmo_cage2d_get_cursor(wmGizmo *gz)
case ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y:
return WM_CURSOR_Y_MOVE;
- /* TODO diagonal cursor */
+ /* TODO: diagonal cursor. */
case ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y:
case ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y:
return WM_CURSOR_NSEW_SCROLL;
diff --git a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c
index b2d3a2e1576..31ab5eca974 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c
@@ -319,9 +319,9 @@ bool ED_gizmotypes_snap_3d_invert_snap_get(struct wmGizmo *gz)
#endif
}
-bool ED_gizmotypes_snap_3d_is_enabled(wmGizmo *gz)
+bool ED_gizmotypes_snap_3d_is_enabled(const wmGizmo *gz)
{
- SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
+ const SnapGizmo3D *snap_gizmo = (const SnapGizmo3D *)gz;
return snap_gizmo->is_enabled;
}
diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt
index f7ab72a8a43..bff7310e9f7 100644
--- a/source/blender/editors/gpencil/CMakeLists.txt
+++ b/source/blender/editors/gpencil/CMakeLists.txt
@@ -41,6 +41,7 @@ set(SRC
gpencil_add_monkey.c
gpencil_add_stroke.c
gpencil_armature.c
+ gpencil_bake_animation.c
gpencil_convert.c
gpencil_data.c
gpencil_edit.c
diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c
index fe1c5efc747..196fb88ea55 100644
--- a/source/blender/editors/gpencil/annotate_draw.c
+++ b/source/blender/editors/gpencil/annotate_draw.c
@@ -348,7 +348,7 @@ static void annotation_draw_stroke_3d(
/* If there was a significant pressure change, stop the curve,
* change the thickness of the stroke, and continue drawing again
* (since line-width cannot change in middle of GL_LINE_STRIP)
- * Note: we want more visible levels of pressures when thickness is bigger.
+ * NOTE: we want more visible levels of pressures when thickness is bigger.
*/
if (fabsf(pt->pressure - curpressure) > 0.2f / (float)thickness) {
/* if the pressure changes before get at least 2 vertices,
@@ -760,15 +760,15 @@ static void annotation_draw_data_all(Scene *scene,
int winy,
int cfra,
int dflag,
- const char spacetype)
+ const eSpace_Type space_type)
{
bGPdata *gpd_source = NULL;
if (scene) {
- if (spacetype == SPACE_VIEW3D) {
+ if (space_type == SPACE_VIEW3D) {
gpd_source = (scene->gpd ? scene->gpd : NULL);
}
- else if (spacetype == SPACE_CLIP && scene->clip) {
+ else if (space_type == SPACE_CLIP && scene->clip) {
/* currently drawing only gpencil data from either clip or track,
* but not both - XXX fix logic behind */
gpd_source = (scene->clip->gpd ? scene->clip->gpd : NULL);
@@ -901,7 +901,7 @@ void ED_annotation_draw_view2d(const bContext *C, bool onlyv2d)
}
/* draw annotations sketches to specified 3d-view assuming that matrices are already set
- * correctly Note: this gets called twice - first time with only3d=true to draw 3d-strokes,
+ * correctly NOTE: this gets called twice - first time with only3d=true to draw 3d-strokes,
* second time with only3d=false for screen-aligned strokes */
void ED_annotation_draw_view3d(
Scene *scene, struct Depsgraph *depsgraph, View3D *v3d, ARegion *region, bool only3d)
diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c
index c155587e95a..4b0c5ccd285 100644
--- a/source/blender/editors/gpencil/annotate_paint.c
+++ b/source/blender/editors/gpencil/annotate_paint.c
@@ -667,7 +667,7 @@ static short annotation_stroke_addpoint(tGPsdata *p,
(ts->annotate_v3d_align & GP_PROJECT_DEPTH_STROKE) ?
V3D_DEPTH_GPENCIL_ONLY :
V3D_DEPTH_NO_GPENCIL,
- false);
+ NULL);
}
/* convert screen-coordinates to appropriate coordinates (and store them) */
@@ -708,7 +708,7 @@ static void annotation_stroke_arrow_init_conv_point(bGPDspoint *pt, const float
static void annotation_stroke_arrow_init_point(
tGPsdata *p, tGPspoint *ptc, bGPDspoint *pt, const float co[8], const int co_idx)
{
- /* Note: provided co_idx should be always pair number as it's [x1, y1, x2, y2, x3, y3]. */
+ /* NOTE: provided co_idx should be always pair number as it's [x1, y1, x2, y2, x3, y3]. */
const float real_co[2] = {co[co_idx], co[co_idx + 1]};
copy_v2_v2(&ptc->x, real_co);
annotation_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
@@ -908,7 +908,7 @@ static void annotation_stroke_newfrombuffer(tGPsdata *p)
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
pt->time = ptc->time;
- /** Create arrow strokes. **/
+ /** Create arrow strokes. */
/* End arrow stroke. */
if ((runtime.sbuffer_sflag & GP_STROKE_USE_ARROW_END) &&
(runtime.arrow_end_style != GP_STROKE_ARROWSTYLE_NONE)) {
@@ -1079,17 +1079,6 @@ static void annotation_free_stroke(bGPDframe *gpf, bGPDstroke *gps)
BLI_freelinkN(&gpf->strokes, gps);
}
-/**
- * Which which point is in front (result should only be used for comparison).
- */
-static float view3d_point_depth(const RegionView3D *rv3d, const float co[3])
-{
- if (rv3d->is_persp) {
- return ED_view3d_calc_zfac(rv3d, co, NULL);
- }
- return -dot_v3v3(rv3d->viewinv[2], co);
-}
-
/* only erase stroke points that are visible (3d view) */
static bool annotation_stroke_eraser_is_occluded(tGPsdata *p,
const bGPDspoint *pt,
@@ -1102,8 +1091,8 @@ static bool annotation_stroke_eraser_is_occluded(tGPsdata *p,
float mval_3d[3];
if (ED_view3d_autodist_simple(p->region, mval_i, mval_3d, 0, NULL)) {
- const float depth_mval = view3d_point_depth(rv3d, mval_3d);
- const float depth_pt = view3d_point_depth(rv3d, &pt->x);
+ const float depth_mval = ED_view3d_calc_depth_for_comparison(rv3d, mval_3d);
+ const float depth_pt = ED_view3d_calc_depth_for_comparison(rv3d, &pt->x);
if (depth_pt > depth_mval) {
return true;
@@ -1152,7 +1141,7 @@ static void annotation_stroke_eraser_dostroke(tGPsdata *p,
/* Clear Tags
*
- * Note: It's better this way, as we are sure that
+ * NOTE: It's better this way, as we are sure that
* we don't miss anything, though things will be
* slightly slower as a result
*/
@@ -1183,7 +1172,7 @@ static void annotation_stroke_eraser_dostroke(tGPsdata *p,
((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
/* 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
+ * - this assumes that line-width is irrelevant.
*/
if (gpencil_stroke_inside_circle(mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
if ((annotation_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) ||
@@ -1226,7 +1215,7 @@ static void annotation_stroke_doeraser(tGPsdata *p)
if (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH) {
View3D *v3d = p->area->spacedata.first;
view3d_region_operator_needs_opengl(p->win, p->region);
- ED_view3d_depth_override(p->depsgraph, p->region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, false);
+ ED_view3d_depth_override(p->depsgraph, p->region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, NULL);
}
}
@@ -1706,7 +1695,7 @@ static void annotation_paint_strokeend(tGPsdata *p)
(ts->annotate_v3d_align & GP_PROJECT_DEPTH_STROKE) ?
V3D_DEPTH_GPENCIL_ONLY :
V3D_DEPTH_NO_GPENCIL,
- false);
+ NULL);
}
/* check if doing eraser or not */
@@ -2489,18 +2478,15 @@ static int annotation_draw_modal(bContext *C, wmOperator *op, const wmEvent *eve
/* default exit state - pass through to support MMB view nav, etc. */
int estate = OPERATOR_PASS_THROUGH;
- /* if (event->type == NDOF_MOTION)
- * return OPERATOR_PASS_THROUGH;
- * -------------------------------
- * [mce] Not quite what I was looking
- * for, but a good start! GP continues to
- * draw on the screen while the 3D mouse
- * moves the viewpoint. Problem is that
- * the stroke is converted to 3D only after
- * it is finished. This approach should work
- * better in tools that immediately apply
- * in 3D space.
- */
+ /* NOTE(mike erwin): Not quite what I was looking for, but a good start!
+ * grease-pencil continues to draw on the screen while the 3D mouse moves the viewpoint.
+ * Problem is that the stroke is converted to 3D only after it is finished.
+ * This approach should work better in tools that immediately apply in 3D space. */
+#if 0
+ if (event->type == NDOF_MOTION) {
+ return OPERATOR_PASS_THROUGH;
+ }
+#endif
if (p->status == GP_STATUS_IDLING) {
ARegion *region = CTX_wm_region(C);
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 751f8333aaa..2160aaf705f 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -323,7 +323,7 @@ static void gpencil_draw_strokes(tGPDdraw *tgpw)
MaterialGPencilStyle *gp_style = (ma) ? ma->gp_style : NULL;
if ((gp_style == NULL) || (gp_style->flag & GP_MATERIAL_HIDE) ||
- /* if onion and ghost flag do not draw*/
+ /* If onion and ghost flag do not draw. */
(tgpw->onion && (gp_style->flag & GP_MATERIAL_HIDE_ONIONSKIN))) {
continue;
}
diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c
index 166111c582c..fbdb7c8e520 100644
--- a/source/blender/editors/gpencil/editaction_gpencil.c
+++ b/source/blender/editors/gpencil/editaction_gpencil.c
@@ -107,7 +107,7 @@ void ED_gpencil_layer_make_cfra_list(bGPDlayer *gpl, ListBase *elems, bool onlys
/* Selection Tools */
/* check if one of the frames in this layer is selected */
-bool ED_gpencil_layer_frame_select_check(bGPDlayer *gpl)
+bool ED_gpencil_layer_frame_select_check(const bGPDlayer *gpl)
{
/* error checking */
if (gpl == NULL) {
@@ -115,7 +115,7 @@ bool ED_gpencil_layer_frame_select_check(bGPDlayer *gpl)
}
/* stop at the first one found */
- LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (const bGPDframe *, gpf, &gpl->frames) {
if (gpf->flag & GP_FRAME_SELECT) {
return true;
}
@@ -268,7 +268,7 @@ void ED_gpencil_layer_frames_duplicate(bGPDlayer *gpl)
return;
}
- /* duplicate selected frames */
+ /* Duplicate selected frames. */
LISTBASE_FOREACH_MUTABLE (bGPDframe *, gpf, &gpl->frames) {
/* duplicate this frame */
@@ -421,7 +421,7 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode)
return false;
}
- /* check if single channel in buffer (disregard names if so) */
+ /* Check if single channel in buffer (disregard names if so). */
if (gpencil_anim_copybuf.first == gpencil_anim_copybuf.last) {
no_name = true;
}
@@ -513,7 +513,7 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode)
static bool gpencil_frame_snap_nearest(bGPDframe *UNUSED(gpf), Scene *UNUSED(scene))
{
-#if 0 /* note: gpf->framenum is already an int! */
+#if 0 /* NOTE: gpf->framenum is already an int! */
if (gpf->flag & GP_FRAME_SELECT) {
gpf->framenum = (int)(floor(gpf->framenum + 0.5));
}
diff --git a/source/blender/editors/gpencil/gpencil_add_monkey.c b/source/blender/editors/gpencil/gpencil_add_monkey.c
index d8734c4ae6b..8d60ef3ed12 100644
--- a/source/blender/editors/gpencil/gpencil_add_monkey.c
+++ b/source/blender/editors/gpencil/gpencil_add_monkey.c
@@ -39,6 +39,32 @@
#include "ED_gpencil.h"
+/**
+ * Populate stroke with point data from data buffers.
+ * \param gps: Grease pencil stroke
+ * \param array: Flat array of point data values. Each entry has #GP_PRIM_DATABUF_SIZE values.
+ * \param totpoints: Total of points
+ * \param mat: 4x4 transform matrix to transform points into the right coordinate space.
+ */
+void ED_gpencil_stroke_init_data(bGPDstroke *gps,
+ const float *array,
+ const int totpoints,
+ const float mat[4][4])
+{
+ for (int i = 0; i < totpoints; i++) {
+ bGPDspoint *pt = &gps->points[i];
+ const int x = GP_PRIM_DATABUF_SIZE * i;
+
+ pt->x = array[x];
+ pt->y = array[x + 1];
+ pt->z = array[x + 2];
+ mul_m4_v3(mat, &pt->x);
+
+ pt->pressure = array[x + 3];
+ pt->strength = array[x + 4];
+ }
+}
+
/* Definition of the most important info from a color */
typedef struct ColorTemplate {
const char *name;
@@ -847,115 +873,115 @@ void ED_gpencil_create_monkey(bContext *C, Object *ob, float mat[4][4])
/* generate strokes */
gps = BKE_gpencil_stroke_add(frameFills, color_Skin, 270, 75, false);
- BKE_gpencil_stroke_add_points(gps, data0, 270, mat);
+ ED_gpencil_stroke_init_data(gps, data0, 270, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameFills, color_Skin_Shadow, 33, 60, false);
- BKE_gpencil_stroke_add_points(gps, data1, 33, mat);
+ ED_gpencil_stroke_init_data(gps, data1, 33, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameFills, color_Skin_Shadow, 18, 60, false);
- BKE_gpencil_stroke_add_points(gps, data2, 18, mat);
+ ED_gpencil_stroke_init_data(gps, data2, 18, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameFills, color_Skin_Light, 64, 60, false);
- BKE_gpencil_stroke_add_points(gps, data3, 64, mat);
+ ED_gpencil_stroke_init_data(gps, data3, 64, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameFills, color_Skin_Light, 33, 60, false);
- BKE_gpencil_stroke_add_points(gps, data4, 33, mat);
+ ED_gpencil_stroke_init_data(gps, data4, 33, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameFills, color_Skin_Light, 64, 60, false);
- BKE_gpencil_stroke_add_points(gps, data5, 64, mat);
+ ED_gpencil_stroke_init_data(gps, data5, 64, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameFills, color_Skin_Light, 33, 60, false);
- BKE_gpencil_stroke_add_points(gps, data6, 33, mat);
+ ED_gpencil_stroke_init_data(gps, data6, 33, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameFills, color_Skin_Light, 18, 40, false);
- BKE_gpencil_stroke_add_points(gps, data7, 18, mat);
+ ED_gpencil_stroke_init_data(gps, data7, 18, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameFills, color_Eyes, 49, 60, false);
- BKE_gpencil_stroke_add_points(gps, data8, 49, mat);
+ ED_gpencil_stroke_init_data(gps, data8, 49, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameFills, color_Skin_Shadow, 33, 60, false);
- BKE_gpencil_stroke_add_points(gps, data9, 33, mat);
+ ED_gpencil_stroke_init_data(gps, data9, 33, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameFills, color_Eyes, 49, 60, false);
- BKE_gpencil_stroke_add_points(gps, data10, 49, mat);
+ ED_gpencil_stroke_init_data(gps, data10, 49, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameFills, color_Skin_Shadow, 18, 40, false);
- BKE_gpencil_stroke_add_points(gps, data11, 18, mat);
+ ED_gpencil_stroke_init_data(gps, data11, 18, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameFills, color_Skin_Shadow, 18, 40, false);
- BKE_gpencil_stroke_add_points(gps, data12, 18, mat);
+ ED_gpencil_stroke_init_data(gps, data12, 18, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Black, 33, 60, false);
- BKE_gpencil_stroke_add_points(gps, data13, 33, mat);
+ ED_gpencil_stroke_init_data(gps, data13, 33, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Black, 33, 60, false);
- BKE_gpencil_stroke_add_points(gps, data14, 33, mat);
+ ED_gpencil_stroke_init_data(gps, data14, 33, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Black, 65, 60, false);
- BKE_gpencil_stroke_add_points(gps, data15, 65, mat);
+ ED_gpencil_stroke_init_data(gps, data15, 65, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Black, 34, 60, false);
- BKE_gpencil_stroke_add_points(gps, data16, 34, mat);
+ ED_gpencil_stroke_init_data(gps, data16, 34, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Black, 33, 60, false);
- BKE_gpencil_stroke_add_points(gps, data17, 33, mat);
+ ED_gpencil_stroke_init_data(gps, data17, 33, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Black, 33, 40, false);
- BKE_gpencil_stroke_add_points(gps, data18, 33, mat);
+ ED_gpencil_stroke_init_data(gps, data18, 33, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Black, 34, 40, false);
- BKE_gpencil_stroke_add_points(gps, data19, 34, mat);
+ ED_gpencil_stroke_init_data(gps, data19, 34, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Black, 33, 60, false);
- BKE_gpencil_stroke_add_points(gps, data20, 33, mat);
+ ED_gpencil_stroke_init_data(gps, data20, 33, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Black, 64, 60, false);
- BKE_gpencil_stroke_add_points(gps, data21, 64, mat);
+ ED_gpencil_stroke_init_data(gps, data21, 64, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Pupils, 26, 60, false);
- BKE_gpencil_stroke_add_points(gps, data22, 26, mat);
+ ED_gpencil_stroke_init_data(gps, data22, 26, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Pupils, 26, 60, false);
- BKE_gpencil_stroke_add_points(gps, data23, 26, mat);
+ ED_gpencil_stroke_init_data(gps, data23, 26, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Black, 33, 60, false);
- BKE_gpencil_stroke_add_points(gps, data24, 33, mat);
+ ED_gpencil_stroke_init_data(gps, data24, 33, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Black, 18, 40, false);
- BKE_gpencil_stroke_add_points(gps, data25, 18, mat);
+ ED_gpencil_stroke_init_data(gps, data25, 18, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Black, 18, 40, false);
- BKE_gpencil_stroke_add_points(gps, data26, 18, mat);
+ ED_gpencil_stroke_init_data(gps, data26, 18, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
gps = BKE_gpencil_stroke_add(frameLines, color_Black, 33, 60, false);
- BKE_gpencil_stroke_add_points(gps, data27, 33, mat);
+ ED_gpencil_stroke_init_data(gps, data27, 33, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
/* update depsgraph */
diff --git a/source/blender/editors/gpencil/gpencil_add_stroke.c b/source/blender/editors/gpencil/gpencil_add_stroke.c
index e95496b51ee..73c4e64dd9a 100644
--- a/source/blender/editors/gpencil/gpencil_add_stroke.c
+++ b/source/blender/editors/gpencil/gpencil_add_stroke.c
@@ -235,7 +235,7 @@ void ED_gpencil_create_stroke(bContext *C, Object *ob, float mat[4][4])
/* generate stroke */
gps = BKE_gpencil_stroke_add(frame_lines, color_black, 175, 75, false);
- BKE_gpencil_stroke_add_points(gps, data0, 175, mat);
+ ED_gpencil_stroke_init_data(gps, data0, 175, mat);
BKE_gpencil_stroke_geometry_update(gpd, gps);
/* update depsgraph */
diff --git a/source/blender/editors/gpencil/gpencil_armature.c b/source/blender/editors/gpencil/gpencil_armature.c
index 3271096c433..c800851bb08 100644
--- a/source/blender/editors/gpencil/gpencil_armature.c
+++ b/source/blender/editors/gpencil/gpencil_armature.c
@@ -384,7 +384,7 @@ static void gpencil_add_verts_to_dgroups(
/* loop groups and assign weight */
for (j = 0; j < numbones; j++) {
- int def_nr = BLI_findindex(&ob->defbase, dgrouplist[j]);
+ int def_nr = BLI_findindex(&gpd->vertex_group_names, dgrouplist[j]);
if (def_nr < 0) {
continue;
}
@@ -425,7 +425,7 @@ static void gpencil_add_verts_to_dgroups(
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -454,7 +454,7 @@ static void gpencil_object_vgroup_calc_from_armature(const bContext *C,
bArmature *arm = ob_arm->data;
/* always create groups */
- const int defbase_tot = BLI_listbase_count(&ob->defbase);
+ const int defbase_tot = BKE_object_defgroup_count(ob);
int defbase_add;
/* Traverse the bone list, trying to create empty vertex
* groups corresponding to the bone.
@@ -462,8 +462,8 @@ static void gpencil_object_vgroup_calc_from_armature(const bContext *C,
defbase_add = gpencil_bone_looper(ob, arm->bonebase.first, NULL, vgroup_add_unique_bone_cb);
if (defbase_add) {
- /* its possible there are DWeight's outside the range of the current
- * objects deform groups, in this case the new groups wont be empty */
+ /* It's possible there are DWeights outside the range of the current
+ * object's deform groups. In this case the new groups won't be empty */
ED_vgroup_data_clamp_range(ob->data, defbase_tot);
}
diff --git a/source/blender/editors/gpencil/gpencil_bake_animation.c b/source/blender/editors/gpencil/gpencil_bake_animation.c
new file mode 100644
index 00000000000..2d299230124
--- /dev/null
+++ b/source/blender/editors/gpencil/gpencil_bake_animation.c
@@ -0,0 +1,453 @@
+/*
+ * 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) 2021 Blender Foundation
+ * This is a new part of Blender
+ */
+
+/** \file
+ * \ingroup edgpencil
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
+#include "BLI_math.h"
+
+#include "DNA_anim_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_material_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+
+#include "BKE_anim_data.h"
+#include "BKE_context.h"
+#include "BKE_duplilist.h"
+#include "BKE_gpencil.h"
+#include "BKE_gpencil_geom.h"
+#include "BKE_gpencil_modifier.h"
+#include "BKE_layer.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
+#include "BKE_object.h"
+#include "BKE_report.h"
+#include "BKE_scene.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "ED_gpencil.h"
+#include "ED_transform_snap_object_context.h"
+
+#include "gpencil_intern.h"
+
+const EnumPropertyItem rna_gpencil_reproject_type_items[] = {
+ {GP_REPROJECT_KEEP, "KEEP", 0, "No Reproject", ""},
+ {GP_REPROJECT_FRONT, "FRONT", 0, "Front", "Reproject the strokes using the X-Z plane"},
+ {GP_REPROJECT_SIDE, "SIDE", 0, "Side", "Reproject the strokes using the Y-Z plane"},
+ {GP_REPROJECT_TOP, "TOP", 0, "Top", "Reproject the strokes using the X-Y plane"},
+ {GP_REPROJECT_VIEW,
+ "VIEW",
+ 0,
+ "View",
+ "Reproject the strokes to end up on the same plane, as if drawn from the current "
+ "viewpoint "
+ "using 'Cursor' Stroke Placement"},
+ {GP_REPROJECT_CURSOR,
+ "CURSOR",
+ 0,
+ "Cursor",
+ "Reproject the strokes using the orientation of 3D cursor"},
+ {0, NULL, 0, NULL, NULL},
+};
+
+/* Check frame_end is always > start frame! */
+static void gpencil_bake_set_frame_end(struct Main *UNUSED(main),
+ struct Scene *UNUSED(scene),
+ struct PointerRNA *ptr)
+{
+ int frame_start = RNA_int_get(ptr, "frame_start");
+ int frame_end = RNA_int_get(ptr, "frame_end");
+
+ if (frame_end <= frame_start) {
+ RNA_int_set(ptr, "frame_end", frame_start + 1);
+ }
+}
+
+/* Extract mesh animation to Grease Pencil. */
+static bool gpencil_bake_grease_pencil_animation_poll(bContext *C)
+{
+ Object *obact = CTX_data_active_object(C);
+ if (CTX_data_mode_enum(C) != CTX_MODE_OBJECT) {
+ return false;
+ }
+
+ /* Check if grease pencil or empty for dupli groups. */
+ if ((obact == NULL) || ((obact->type != OB_GPENCIL) && (obact->type != OB_EMPTY))) {
+ return false;
+ }
+
+ /* Only if the current view is 3D View. */
+ ScrArea *area = CTX_wm_area(C);
+ return (area && area->spacetype);
+}
+
+typedef struct GpBakeOb {
+ struct GpBakeOb *next, *prev;
+ Object *ob;
+} GpBakeOb;
+
+/* Get list of keyframes used by selected objects. */
+static void animdata_keyframe_list_get(ListBase *ob_list,
+ const bool only_selected,
+ GHash *r_keyframes)
+{
+ /* Loop all objects to get the list of keyframes used. */
+ LISTBASE_FOREACH (GpBakeOb *, elem, ob_list) {
+ Object *ob = elem->ob;
+ AnimData *adt = BKE_animdata_from_id(&ob->id);
+ if ((adt == NULL) || (adt->action == NULL)) {
+ continue;
+ }
+ LISTBASE_FOREACH (FCurve *, fcurve, &adt->action->curves) {
+ int i;
+ BezTriple *bezt;
+ for (i = 0, bezt = fcurve->bezt; i < fcurve->totvert; i++, bezt++) {
+ /* Keyframe number is x value of point. */
+ if ((bezt->f2 & SELECT) || (!only_selected)) {
+ /* Insert only one key for each keyframe number. */
+ int key = (int)bezt->vec[1][0];
+ if (!BLI_ghash_haskey(r_keyframes, POINTER_FROM_INT(key))) {
+ BLI_ghash_insert(r_keyframes, POINTER_FROM_INT(key), POINTER_FROM_INT(key));
+ }
+ }
+ }
+ }
+ }
+}
+
+static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *list)
+{
+ GpBakeOb *elem = NULL;
+ ListBase *lb;
+ DupliObject *dob;
+ lb = object_duplilist(depsgraph, scene, ob);
+ for (dob = lb->first; dob; dob = dob->next) {
+ if (dob->ob->type != OB_GPENCIL) {
+ continue;
+ }
+
+ elem = MEM_callocN(sizeof(GpBakeOb), __func__);
+ elem->ob = dob->ob;
+ BLI_addtail(list, elem);
+ }
+
+ free_object_duplilist(lb);
+}
+
+static void gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene, ListBase *list)
+{
+ GpBakeOb *elem = NULL;
+
+ /* Add active object. In some files this could not be in selected array. */
+ Object *obact = CTX_data_active_object(C);
+
+ if (obact->type == OB_GPENCIL) {
+ elem = MEM_callocN(sizeof(GpBakeOb), __func__);
+ elem->ob = obact;
+ BLI_addtail(list, elem);
+ }
+ /* Add duplilist. */
+ else if (obact->type == OB_EMPTY) {
+ gpencil_bake_duplilist(depsgraph, scene, obact, list);
+ }
+
+ /* Add other selected objects. */
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
+ if (ob == obact) {
+ continue;
+ }
+ /* Add selected objects. */
+ if (ob->type == OB_GPENCIL) {
+ elem = MEM_callocN(sizeof(GpBakeOb), __func__);
+ elem->ob = ob;
+ BLI_addtail(list, elem);
+ }
+
+ /* Add duplilist. */
+ if (ob->type == OB_EMPTY) {
+ gpencil_bake_duplilist(depsgraph, scene, ob, list);
+ }
+ }
+ CTX_DATA_END;
+}
+
+static void gpencil_bake_free_ob_list(ListBase *list)
+{
+ LISTBASE_FOREACH_MUTABLE (GpBakeOb *, elem, list) {
+ MEM_SAFE_FREE(elem);
+ }
+}
+
+static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ ARegion *region = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ ListBase ob_selected_list = {NULL, NULL};
+ gpencil_bake_ob_list(C, depsgraph, scene, &ob_selected_list);
+
+ /* Grab all relevant settings. */
+ const int step = RNA_int_get(op->ptr, "step");
+
+ const int frame_start = (scene->r.sfra > RNA_int_get(op->ptr, "frame_start")) ?
+ scene->r.sfra :
+ RNA_int_get(op->ptr, "frame_start");
+
+ const int frame_end = (scene->r.efra < RNA_int_get(op->ptr, "frame_end")) ?
+ scene->r.efra :
+ RNA_int_get(op->ptr, "frame_end");
+
+ const bool only_selected = RNA_boolean_get(op->ptr, "only_selected");
+ const int frame_offset = RNA_int_get(op->ptr, "frame_target") - frame_start;
+ const int project_type = RNA_enum_get(op->ptr, "project_type");
+
+ /* Create a new grease pencil object. */
+ Object *ob_gpencil = NULL;
+ ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
+ ob_gpencil = ED_gpencil_add_object(C, scene->cursor.location, local_view_bits);
+ float invmat[4][4];
+ invert_m4_m4(invmat, ob_gpencil->obmat);
+
+ bGPdata *gpd_dst = (bGPdata *)ob_gpencil->data;
+ gpd_dst->draw_mode = GP_DRAWMODE_2D;
+
+ /* Set cursor to indicate working. */
+ WM_cursor_wait(true);
+
+ GP_SpaceConversion gsc = {NULL};
+ SnapObjectContext *sctx = NULL;
+ if (project_type != GP_REPROJECT_KEEP) {
+ /* Init space conversion stuff. */
+ gpencil_point_conversion_init(C, &gsc);
+ /* Move the grease pencil object to conversion data. */
+ gsc.ob = ob_gpencil;
+
+ /* Init snap context for geometry projection. */
+ sctx = ED_transform_snap_object_context_create_view3d(scene, 0, region, CTX_wm_view3d(C));
+ }
+
+ /* Loop all frame range. */
+ int oldframe = (int)DEG_get_ctime(depsgraph);
+ int key = -1;
+
+ /* Get list of keyframes. */
+ GHash *keyframe_list = BLI_ghash_int_new(__func__);
+ if (only_selected) {
+ animdata_keyframe_list_get(&ob_selected_list, only_selected, keyframe_list);
+ }
+
+ for (int i = frame_start; i < frame_end + 1; i++) {
+ key++;
+ /* Jump if not step limit but include last frame always. */
+ if ((key % step != 0) && (i != frame_end)) {
+ continue;
+ }
+
+ /* Check if frame is in the list of frames to be exported. */
+ if ((only_selected) && (!BLI_ghash_haskey(keyframe_list, POINTER_FROM_INT(i)))) {
+ continue;
+ }
+
+ /* Move scene to new frame. */
+ CFRA = i;
+ BKE_scene_graph_update_for_newframe(depsgraph);
+
+ /* Loop all objects in the list. */
+ LISTBASE_FOREACH (GpBakeOb *, elem, &ob_selected_list) {
+ Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, elem->ob);
+ bGPdata *gpd_src = ob_eval->data;
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl_src, &gpd_src->layers) {
+ /* Create destination layer. */
+ char *layer_name;
+ layer_name = BLI_sprintfN("%s_%s", elem->ob->id.name + 2, gpl_src->info);
+ bGPDlayer *gpl_dst = BKE_gpencil_layer_named_get(gpd_dst, layer_name);
+ if (gpl_dst == NULL) {
+ gpl_dst = BKE_gpencil_layer_addnew(gpd_dst, layer_name, true, false);
+ }
+ MEM_freeN(layer_name);
+
+ /* Layer Transform matrix. */
+ float matrix[4][4];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, elem->ob, gpl_src, matrix);
+
+ /* Apply time modifier. */
+ int remap_cfra = BKE_gpencil_time_modifier_cfra(
+ depsgraph, scene, elem->ob, gpl_src, CFRA, false);
+ /* Duplicate frame. */
+ bGPDframe *gpf_src = BKE_gpencil_layer_frame_get(
+ gpl_src, remap_cfra, GP_GETFRAME_USE_PREV);
+ if (gpf_src == NULL) {
+ continue;
+ }
+ bGPDframe *gpf_dst = BKE_gpencil_frame_duplicate(gpf_src, true);
+ gpf_dst->framenum = CFRA + frame_offset;
+ gpf_dst->flag &= ~GP_FRAME_SELECT;
+ BLI_addtail(&gpl_dst->frames, gpf_dst);
+
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf_dst->strokes) {
+ /* Create material of the stroke. */
+ Material *ma_src = BKE_object_material_get(elem->ob, gps->mat_nr + 1);
+ bool found = false;
+ for (int index = 0; index < ob_gpencil->totcol; index++) {
+ Material *ma_dst = BKE_object_material_get(ob_gpencil, index + 1);
+ if (ma_src == ma_dst) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ BKE_object_material_slot_add(bmain, ob_gpencil);
+ BKE_object_material_assign(
+ bmain, ob_gpencil, ma_src, ob_gpencil->totcol, BKE_MAT_ASSIGN_USERPREF);
+ }
+
+ /* Set new material index. */
+ gps->mat_nr = BKE_gpencil_object_material_index_get(ob_gpencil, ma_src);
+
+ /* Update point location to new object space. */
+ for (int j = 0; j < gps->totpoints; j++) {
+ bGPDspoint *pt = &gps->points[j];
+ mul_m4_v3(matrix, &pt->x);
+ mul_m4_v3(invmat, &pt->x);
+ }
+
+ /* Reproject stroke. */
+ if (project_type != GP_REPROJECT_KEEP) {
+ ED_gpencil_stroke_reproject(
+ depsgraph, &gsc, sctx, gpl_dst, gpf_dst, gps, project_type, false);
+ }
+ else {
+ BKE_gpencil_stroke_geometry_update(gpd_dst, gps);
+ }
+ }
+ }
+ }
+ }
+ /* Return scene frame state and DB to original state. */
+ CFRA = oldframe;
+ BKE_scene_graph_update_for_newframe(depsgraph);
+
+ /* Free memory. */
+ gpencil_bake_free_ob_list(&ob_selected_list);
+ if (sctx != NULL) {
+ ED_transform_snap_object_context_destroy(sctx);
+ }
+ /* Free temp hash table. */
+ if (keyframe_list != NULL) {
+ BLI_ghash_free(keyframe_list, NULL, NULL);
+ }
+
+ /* Notifiers. */
+ DEG_relations_tag_update(bmain);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ DEG_id_tag_update(&gpd_dst->id, ID_RECALC_COPY_ON_WRITE);
+ WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+
+ /* Reset cursor. */
+ WM_cursor_wait(false);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+static int gpencil_bake_grease_pencil_animation_invoke(bContext *C,
+ wmOperator *op,
+ const wmEvent *UNUSED(event))
+{
+ PropertyRNA *prop;
+ Scene *scene = CTX_data_scene(C);
+
+ prop = RNA_struct_find_property(op->ptr, "frame_start");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ const int frame_start = RNA_property_int_get(op->ptr, prop);
+ if (frame_start < scene->r.sfra) {
+ RNA_property_int_set(op->ptr, prop, scene->r.sfra);
+ }
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "frame_end");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ const int frame_end = RNA_property_int_get(op->ptr, prop);
+ if (frame_end > scene->r.efra) {
+ RNA_property_int_set(op->ptr, prop, scene->r.efra);
+ }
+ }
+
+ /* Show popup dialog to allow editing. */
+ return WM_operator_props_dialog_popup(C, op, 250);
+}
+
+void GPENCIL_OT_bake_grease_pencil_animation(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Bake Object Transform to Grease Pencil";
+ ot->idname = "GPENCIL_OT_bake_grease_pencil_animation";
+ ot->description = "Bake grease pencil object transform to grease pencil keyframes";
+
+ /* callbacks */
+ ot->invoke = gpencil_bake_grease_pencil_animation_invoke;
+ ot->exec = gpencil_bake_grease_pencil_animation_exec;
+ ot->poll = gpencil_bake_grease_pencil_animation_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ prop = RNA_def_int(
+ ot->srna, "frame_start", 1, 1, 100000, "Start Frame", "The start frame", 1, 100000);
+
+ prop = RNA_def_int(
+ ot->srna, "frame_end", 250, 1, 100000, "End Frame", "The end frame of animation", 1, 100000);
+ RNA_def_property_update_runtime(prop, gpencil_bake_set_frame_end);
+
+ prop = RNA_def_int(ot->srna, "step", 1, 1, 100, "Step", "Step between generated frames", 1, 100);
+
+ RNA_def_boolean(
+ ot->srna, "only_selected", 0, "Only Selected Keyframes", "Convert only selected keyframes");
+ RNA_def_int(
+ ot->srna, "frame_target", 1, 1, 100000, "Target Frame", "Destination frame", 1, 100000);
+
+ RNA_def_enum(ot->srna,
+ "project_type",
+ rna_gpencil_reproject_type_items,
+ GP_REPROJECT_KEEP,
+ "Projection Type",
+ "");
+}
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index 8ab413e907c..ee3536c2f3f 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -168,7 +168,7 @@ static void gpencil_strokepoint_convertcoords(bContext *C,
ARegion *region = CTX_wm_region(C);
/* TODO(sergey): This function might be called from a loop, but no tagging is happening in it,
* so it's not that expensive to ensure evaluated depsgraph here. However, ideally all the
- * parameters are to wrapped into a context style struct and queried from Context once.*/
+ * parameters are to wrapped into a context style struct and queried from Context once. */
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Object *obact = CTX_data_active_object(C);
bGPDspoint mypt, *pt;
@@ -219,7 +219,7 @@ typedef struct tGpTimingData {
int frame_range; /* Number of frames evaluated for path animation */
int start_frame, end_frame;
bool realtime; /* Will overwrite end_frame in case of Original or CustomGap timing... */
- float gap_duration, gap_randomness; /* To be used with CustomGap mode*/
+ float gap_duration, gap_randomness; /* To be used with CustomGap mode. */
int seed;
/* Data set from points, used to compute final timing FCurve */
@@ -230,7 +230,7 @@ typedef struct tGpTimingData {
float tot_dist;
/* Times */
- float *times; /* Note: Gap times will be negative! */
+ float *times; /* NOTE: Gap times will be negative! */
float tot_time, gap_tot_time;
double inittime;
@@ -1409,7 +1409,7 @@ static void gpencil_layer_to_curve(bContext *C,
gtd);
break;
default:
- BLI_assert(!"invalid mode");
+ BLI_assert_msg(0, "invalid mode");
break;
}
prev_gps = gps;
@@ -1806,7 +1806,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
0,
100);
- /* Note: Internal use, this one will always be hidden by UI code... */
+ /* NOTE: Internal use, this one will always be hidden by UI code... */
prop = RNA_def_boolean(
ot->srna,
"use_timing_data",
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index d9a807d17ab..b1e57079d28 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -828,7 +828,7 @@ static int gpencil_frame_clean_loose_exec(bContext *C, wmOperator *op)
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -871,20 +871,20 @@ void GPENCIL_OT_frame_clean_loose(wmOperatorType *ot)
}
/* ********************* Clean Duplicated Frames ************************** */
-static bool gpencil_frame_is_equal(bGPDframe *gpf_a, bGPDframe *gpf_b)
+static bool gpencil_frame_is_equal(const bGPDframe *gpf_a, const bGPDframe *gpf_b)
{
if ((gpf_a == NULL) || (gpf_b == NULL)) {
return false;
}
/* If the number of strokes is different, cannot be equal. */
- int totstrokes_a = BLI_listbase_count(&gpf_a->strokes);
- int totstrokes_b = BLI_listbase_count(&gpf_b->strokes);
+ const int totstrokes_a = BLI_listbase_count(&gpf_a->strokes);
+ const int totstrokes_b = BLI_listbase_count(&gpf_b->strokes);
if ((totstrokes_a == 0) || (totstrokes_b == 0) || (totstrokes_a != totstrokes_b)) {
return false;
}
/* Loop all strokes and check. */
- bGPDstroke *gps_a = gpf_a->strokes.first;
- bGPDstroke *gps_b = gpf_b->strokes.first;
+ const bGPDstroke *gps_a = gpf_a->strokes.first;
+ const bGPDstroke *gps_b = gpf_b->strokes.first;
for (int i = 0; i < totstrokes_a; i++) {
/* If the number of points is different, cannot be equal. */
if (gps_a->totpoints != gps_b->totpoints) {
@@ -924,8 +924,8 @@ static bool gpencil_frame_is_equal(bGPDframe *gpf_a, bGPDframe *gpf_b)
/* Loop points and check if equals or not. */
for (int p = 0; p < gps_a->totpoints; p++) {
- bGPDspoint *pt_a = &gps_a->points[p];
- bGPDspoint *pt_b = &gps_b->points[p];
+ const bGPDspoint *pt_a = &gps_a->points[p];
+ const bGPDspoint *pt_b = &gps_b->points[p];
if (!equals_v3v3(&pt_a->x, &pt_b->x)) {
return false;
}
@@ -1572,7 +1572,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
continue;
}
bool gpf_lock = false;
- /* some stroke is already at front*/
+ /* Some stroke is already at front. */
if (ELEM(direction, GP_STROKE_MOVE_TOP, GP_STROKE_MOVE_UP)) {
if (gps == gpf->strokes.last) {
gpf_lock = true;
@@ -1664,7 +1664,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
BLI_freelistN(&selected);
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -1772,7 +1772,7 @@ static int gpencil_stroke_change_color_exec(bContext *C, wmOperator *op)
}
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -2165,7 +2165,9 @@ static bool gpencil_vertex_group_poll(bContext *C)
Object *ob = CTX_data_active_object(C);
if ((ob) && (ob->type == OB_GPENCIL)) {
- if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) && ob->defbase.first) {
+ const bGPdata *gpd = (const bGPdata *)ob->data;
+ if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) &&
+ !BLI_listbase_is_empty(&gpd->vertex_group_names)) {
if (ELEM(ob->mode, OB_MODE_EDIT_GPENCIL, OB_MODE_SCULPT_GPENCIL)) {
return true;
}
@@ -2180,7 +2182,9 @@ static bool gpencil_vertex_group_weight_poll(bContext *C)
Object *ob = CTX_data_active_object(C);
if ((ob) && (ob->type == OB_GPENCIL)) {
- if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) && ob->defbase.first) {
+ const bGPdata *gpd = (const bGPdata *)ob->data;
+ if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) &&
+ !BLI_listbase_is_empty(&gpd->vertex_group_names)) {
if (ob->mode == OB_MODE_WEIGHT_GPENCIL) {
return true;
}
@@ -2333,6 +2337,7 @@ static int gpencil_vertex_group_invert_exec(bContext *C, wmOperator *op)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
+ bGPdata *gpd = ob->data;
/* sanity checks */
if (ELEM(NULL, ts, ob, ob->data)) {
@@ -2340,8 +2345,9 @@ static int gpencil_vertex_group_invert_exec(bContext *C, wmOperator *op)
}
MDeformVert *dvert;
- const int def_nr = ob->actdef - 1;
- bDeformGroup *defgroup = BLI_findlink(&ob->defbase, def_nr);
+ const int def_nr = gpd->vertex_group_active_index - 1;
+
+ bDeformGroup *defgroup = BLI_findlink(&gpd->vertex_group_names, def_nr);
if (defgroup == NULL) {
return OPERATOR_CANCELLED;
}
@@ -2373,7 +2379,6 @@ static int gpencil_vertex_group_invert_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* notifiers */
- bGPdata *gpd = ob->data;
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
@@ -2403,14 +2408,15 @@ static int gpencil_vertex_group_smooth_exec(bContext *C, wmOperator *op)
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
+ bGPdata *gpd = ob->data;
/* sanity checks */
if (ELEM(NULL, ts, ob, ob->data)) {
return OPERATOR_CANCELLED;
}
- const int def_nr = ob->actdef - 1;
- bDeformGroup *defgroup = BLI_findlink(&ob->defbase, def_nr);
+ const int def_nr = gpd->vertex_group_active_index - 1;
+ bDeformGroup *defgroup = BLI_findlink(&gpd->vertex_group_names, def_nr);
if (defgroup == NULL) {
return OPERATOR_CANCELLED;
}
@@ -2470,7 +2476,6 @@ static int gpencil_vertex_group_smooth_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* notifiers */
- bGPdata *gpd = ob->data;
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
@@ -2500,6 +2505,7 @@ static int gpencil_vertex_group_normalize_exec(bContext *C, wmOperator *op)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
+ bGPdata *gpd = ob->data;
/* sanity checks */
if (ELEM(NULL, ts, ob, ob->data)) {
@@ -2508,8 +2514,8 @@ static int gpencil_vertex_group_normalize_exec(bContext *C, wmOperator *op)
MDeformVert *dvert = NULL;
MDeformWeight *dw = NULL;
- const int def_nr = ob->actdef - 1;
- bDeformGroup *defgroup = BLI_findlink(&ob->defbase, def_nr);
+ const int def_nr = gpd->vertex_group_active_index - 1;
+ bDeformGroup *defgroup = BLI_findlink(&gpd->vertex_group_names, def_nr);
if (defgroup == NULL) {
return OPERATOR_CANCELLED;
}
@@ -2548,7 +2554,6 @@ static int gpencil_vertex_group_normalize_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* notifiers */
- bGPdata *gpd = ob->data;
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
@@ -2576,6 +2581,7 @@ static int gpencil_vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
bool lock_active = RNA_boolean_get(op->ptr, "lock_active");
+ bGPdata *gpd = ob->data;
/* sanity checks */
if (ELEM(NULL, ts, ob, ob->data)) {
@@ -2585,8 +2591,8 @@ static int gpencil_vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
bDeformGroup *defgroup = NULL;
MDeformVert *dvert = NULL;
MDeformWeight *dw = NULL;
- const int def_nr = ob->actdef - 1;
- const int defbase_tot = BLI_listbase_count(&ob->defbase);
+ const int def_nr = gpd->vertex_group_active_index - 1;
+ const int defbase_tot = BLI_listbase_count(&gpd->vertex_group_names);
if (defbase_tot == 0) {
return OPERATOR_CANCELLED;
}
@@ -2603,7 +2609,7 @@ static int gpencil_vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
for (int i = 0; i < gps->totpoints; i++) {
dvert = &gps->dvert[i];
for (int v = 0; v < defbase_tot; v++) {
- defgroup = BLI_findlink(&ob->defbase, v);
+ defgroup = BLI_findlink(&gpd->vertex_group_names, v);
/* skip NULL or locked groups */
if ((defgroup == NULL) || (defgroup->flag & DG_LOCK_WEIGHT)) {
continue;
@@ -2629,7 +2635,7 @@ static int gpencil_vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
dvert = &gps->dvert[i];
for (int v = 0; v < defbase_tot; v++) {
- defgroup = BLI_findlink(&ob->defbase, v);
+ defgroup = BLI_findlink(&gpd->vertex_group_names, v);
/* skip NULL or locked groups */
if ((defgroup == NULL) || (defgroup->flag & DG_LOCK_WEIGHT)) {
continue;
@@ -2653,7 +2659,6 @@ static int gpencil_vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* notifiers */
- bGPdata *gpd = ob->data;
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
@@ -2718,9 +2723,8 @@ static void gpencil_joined_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data)
fcu->rna_path = BKE_animsys_fix_rna_path_rename(
id, fcu->rna_path, "layers", old_name, new_name, 0, 0, false);
- /* we don't want to apply a second remapping on this F-Curve now,
- * so stop trying to fix names names
- */
+ /* We don't want to apply a second remapping on this F-Curve now,
+ * so stop trying to fix names. */
break;
}
}
@@ -2770,7 +2774,6 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Object *ob_active = CTX_data_active_object(C);
- bGPdata *gpd_dst = NULL;
bool ok = false;
/* Ensure we're in right mode and that the active object is correct */
@@ -2808,7 +2811,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- gpd_dst = ob_active->data;
+ bGPdata *gpd_dst = ob_active->data;
Object *ob_dst = ob_active;
/* loop and join all data */
@@ -2829,11 +2832,11 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
/* copy vertex groups to the base one's */
int old_idx = 0;
- LISTBASE_FOREACH (bDeformGroup *, dg, &ob_iter->defbase) {
+ LISTBASE_FOREACH (bDeformGroup *, dg, &gpd_src->vertex_group_names) {
bDeformGroup *vgroup = MEM_dupallocN(dg);
- int idx = BLI_listbase_count(&ob_active->defbase);
+ int idx = BLI_listbase_count(&gpd_dst->vertex_group_names);
BKE_object_defgroup_unique_name(vgroup, ob_active);
- BLI_addtail(&ob_active->defbase, vgroup);
+ BLI_addtail(&gpd_dst->vertex_group_names, vgroup);
/* update vertex groups in strokes in original data */
LISTBASE_FOREACH (bGPDlayer *, gpl_src, &gpd->layers) {
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl_src->frames) {
@@ -2853,8 +2856,9 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
}
old_idx++;
}
- if (ob_active->defbase.first && ob_active->actdef == 0) {
- ob_active->actdef = 1;
+ if (!BLI_listbase_is_empty(&gpd_dst->vertex_group_names) &&
+ gpd_dst->vertex_group_active_index == 0) {
+ gpd_dst->vertex_group_active_index = 1;
}
/* add missing materials reading source materials and checking in destination object */
@@ -2865,7 +2869,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
BKE_gpencil_object_material_ensure(bmain, ob_dst, tmp_ma);
}
- /* duplicate bGPDlayers */
+ /* Duplicate #bGPDlayers. */
tJoinGPencil_AdtFixData afd = {0};
afd.src_gpd = gpd_src;
afd.tar_gpd = gpd_dst;
@@ -3356,7 +3360,7 @@ static int gpencil_material_unlock_all_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
- /* make all layers editable again*/
+ /* Make all layers editable again. */
MaterialGPencilStyle *gp_style = NULL;
for (short i = 0; i < *totcol; i++) {
@@ -3410,7 +3414,7 @@ static int gpencil_material_select_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* read all strokes and select*/
+ /* Read all strokes and select. */
CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
@@ -3452,7 +3456,7 @@ static int gpencil_material_select_exec(bContext *C, wmOperator *op)
}
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index e65afa1abff..8d1f841da6c 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -863,7 +863,7 @@ static void gpencil_duplicate_points(bGPdata *gpd,
start_idx = i;
}
}
- else {
+ if ((start_idx != -1) || (start_idx == gps->totpoints - 1)) {
size_t len = 0;
/* is this the end of current island yet?
@@ -2779,7 +2779,7 @@ void GPENCIL_OT_dissolve(wmOperatorType *ot)
/* Poll callback for snap operators */
/* NOTE: For now, we only allow these in the 3D view, as other editors do not
- * define a cursor or gridstep which can be used
+ * define a cursor or grid-step which can be used.
*/
static bool gpencil_snap_poll(bContext *C)
{
@@ -3285,7 +3285,7 @@ static int gpencil_stroke_cyclical_set_exec(bContext *C, wmOperator *op)
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -3443,7 +3443,7 @@ void GPENCIL_OT_stroke_caps_set(wmOperatorType *ot)
{GP_STROKE_CAPS_TOGGLE_BOTH, "TOGGLE", 0, "Both", ""},
{GP_STROKE_CAPS_TOGGLE_START, "START", 0, "Start", ""},
{GP_STROKE_CAPS_TOGGLE_END, "END", 0, "End", ""},
- {GP_STROKE_CAPS_TOGGLE_DEFAULT, "TOGGLE", 0, "Default", "Set as default rounded"},
+ {GP_STROKE_CAPS_TOGGLE_DEFAULT, "DEFAULT", 0, "Default", "Set as default rounded"},
{0, NULL, 0, NULL, NULL},
};
@@ -3555,7 +3555,7 @@ static int gpencil_stroke_join_exec(bContext *C, wmOperator *op)
BLI_assert(ELEM(type, GP_STROKE_JOIN, GP_STROKE_JOINCOPY));
int tot_strokes = 0;
- /** Alloc memory */
+ /** Alloc memory. */
tJoinStrokes *strokes_list = MEM_malloc_arrayN(sizeof(tJoinStrokes), max_join_strokes, __func__);
tJoinStrokes *elem = NULL;
/* Read all selected strokes to create a list. */
@@ -4478,7 +4478,7 @@ static int gpencil_stroke_trim_exec(bContext *C, wmOperator *op)
}
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -4618,6 +4618,9 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
/* add layer if not created before */
if (gpl_dst == NULL) {
gpl_dst = BKE_gpencil_layer_addnew(gpd_dst, gpl->info, false, false);
+ BKE_gpencil_layer_copy_settings(gpl, gpl_dst);
+ /* Copy masks. */
+ BKE_gpencil_layer_mask_copy(gpl, gpl_dst);
}
/* add frame if not created before */
@@ -4678,7 +4681,7 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -4736,6 +4739,9 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
}
ob_dst->actcol = actcol;
+ /* Remove any invalid Mask relationship. */
+ BKE_gpencil_layer_mask_cleanup_all_layers(gpd_dst);
+
DEG_id_tag_update(&gpd_src->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
DEG_id_tag_update(&gpd_dst->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
@@ -4854,7 +4860,7 @@ static int gpencil_stroke_split_exec(bContext *C, wmOperator *op)
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -5081,7 +5087,7 @@ static int gpencil_cutter_lasso_select(bContext *C,
BKE_gpencil_stroke_select_index_reset(gps);
}
}
- /* if not multiedit, exit loop. */
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -5145,7 +5151,7 @@ static int gpencil_cutter_lasso_select(bContext *C,
}
}
}
- /* if not multiedit, exit loop. */
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -5164,7 +5170,7 @@ static int gpencil_cutter_lasso_select(bContext *C,
gpencil_cutter_dissolve(gpd, gpl, gps, flat_caps);
}
}
- /* if not multiedit, exit loop. */
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -5347,3 +5353,181 @@ void GPENCIL_OT_stroke_merge_by_distance(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Stroke Normalize Operator
+ * \{ */
+
+typedef enum eGP_NormalizeMode {
+ GP_NORMALIZE_THICKNESS = 0,
+ GP_NORMALIZE_OPACITY,
+} eGP_NormalizeMode;
+
+static bool gpencil_stroke_normalize_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+ if ((ob == NULL) || (ob->type != OB_GPENCIL)) {
+ return false;
+ }
+ bGPdata *gpd = (bGPdata *)ob->data;
+ if (gpd == NULL) {
+ return false;
+ }
+
+ bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
+
+ return ((gpl != NULL) && (ob->mode == OB_MODE_EDIT_GPENCIL));
+}
+
+static void gpencil_stroke_normalize_ui(bContext *UNUSED(C), wmOperator *op)
+{
+ uiLayout *layout = op->layout;
+ uiLayout *row;
+
+ const eGP_NormalizeMode mode = RNA_enum_get(op->ptr, "mode");
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+ row = uiLayoutRow(layout, true);
+ uiItemR(row, op->ptr, "mode", 0, NULL, ICON_NONE);
+
+ if (mode == GP_NORMALIZE_THICKNESS) {
+ row = uiLayoutRow(layout, true);
+ uiItemR(row, op->ptr, "value", 0, NULL, ICON_NONE);
+ }
+ else if (mode == GP_NORMALIZE_OPACITY) {
+ row = uiLayoutRow(layout, true);
+ uiItemR(row, op->ptr, "factor", 0, NULL, ICON_NONE);
+ }
+}
+
+static int gpencil_stroke_normalize_exec(bContext *C, wmOperator *op)
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+
+ /* Sanity checks. */
+ if (ELEM(NULL, gpd)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ const eGP_NormalizeMode mode = RNA_enum_get(op->ptr, "mode");
+ const int value = RNA_int_get(op->ptr, "value");
+ const float factor = RNA_float_get(op->ptr, "factor");
+
+ /* Go through each editable + selected stroke. */
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd);
+
+ CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
+
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+
+ if (gpf == NULL) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+
+ /* Skip strokes that are invalid for current view. */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
+
+ bool selected = (is_curve_edit) ? gps->editcurve->flag |= GP_CURVE_SELECT :
+ (gps->flag & GP_STROKE_SELECT);
+ if (!selected) {
+ continue;
+ }
+
+ float stroke_thickness_inv = 1.0f / max_ii(gps->thickness, 1);
+ /* Fill opacity need to be managed before. */
+ if (mode == GP_NORMALIZE_OPACITY) {
+ gps->fill_opacity_fac = factor;
+ CLAMP(gps->fill_opacity_fac, 0.0f, 1.0f);
+ }
+
+ /* Loop all Polyline points. */
+ if (!is_curve_edit) {
+ for (int i = 0; i < gps->totpoints; i++) {
+ bGPDspoint *pt = &gps->points[i];
+ if (mode == GP_NORMALIZE_THICKNESS) {
+ pt->pressure = max_ff((float)value * stroke_thickness_inv, 0.0f);
+ }
+ else if (mode == GP_NORMALIZE_OPACITY) {
+ pt->strength = factor;
+ CLAMP(pt->strength, 0.0f, 1.0f);
+ }
+ }
+ }
+ else {
+ /* Loop all Bezier points. */
+ for (int i = 0; i < gps->editcurve->tot_curve_points; i++) {
+ bGPDcurve_point *gpc_pt = &gps->editcurve->curve_points[i];
+ if (mode == GP_NORMALIZE_THICKNESS) {
+ gpc_pt->pressure = max_ff((float)value * stroke_thickness_inv, 0.0f);
+ }
+ else if (mode == GP_NORMALIZE_OPACITY) {
+ gpc_pt->strength = factor;
+ CLAMP(gpc_pt->strength, 0.0f, 1.0f);
+ }
+ }
+
+ gps->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
+ BKE_gpencil_stroke_geometry_update(gpd, gps);
+ }
+ }
+ /* If not multi-edit, exit loop. */
+ if (!is_multiedit) {
+ break;
+ }
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ /* notifiers */
+ DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_stroke_normalize(wmOperatorType *ot)
+{
+ static const EnumPropertyItem prop_gpencil_normalize_modes[] = {
+ {GP_NORMALIZE_THICKNESS,
+ "THICKNESS",
+ 0,
+ "Thickness",
+ "Normalizes the stroke thickness by making all points use the same thickness value"},
+ {GP_NORMALIZE_OPACITY,
+ "OPACITY",
+ 0,
+ "Opacity",
+ "Normalizes the stroke opacity by making all points use the same opacity value"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ /* identifiers */
+ ot->name = "Normalize Stroke";
+ ot->idname = "GPENCIL_OT_stroke_normalize";
+ ot->description = "Normalize stroke attributes";
+
+ /* api callbacks */
+ ot->exec = gpencil_stroke_normalize_exec;
+ ot->poll = gpencil_stroke_normalize_poll;
+ ot->ui = gpencil_stroke_normalize_ui;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* props */
+ ot->prop = RNA_def_enum(
+ ot->srna, "mode", prop_gpencil_normalize_modes, 0, "Mode", "Attribute to be normalized");
+ RNA_def_float(ot->srna, "factor", 1.0f, 0.0f, 1.0f, "Factor", "", 0.0f, 1.0f);
+ RNA_def_int(ot->srna, "value", 10, 0, 1000, "Value", "Value", 0, 1000);
+}
+
+/** \} */
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index f74e211dd65..67e1bd5294b 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -125,7 +125,7 @@ typedef struct tGPDfill {
struct bGPDframe *gpf;
/** Temp mouse position stroke. */
struct bGPDstroke *gps_mouse;
- /** Pointer to report messages. */
+ /** Pointer to report messages. */
struct ReportList *reports;
/** flags */
short flag;
@@ -810,7 +810,7 @@ static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index
}
}
else {
- /* edge of image*/
+ /* Edge of image. */
t_a = true;
}
/* pixels on bottom */
@@ -822,7 +822,7 @@ static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index
}
}
else {
- /* edge of image*/
+ /* Edge of image. */
t_b = true;
}
}
@@ -846,7 +846,7 @@ static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index
}
}
else {
- t_a = true; /* edge of image*/
+ t_a = true; /* Edge of image. */
}
/* pixels to left */
pt = index + extreme;
@@ -1373,7 +1373,7 @@ static void gpencil_get_depth_array(tGPDfill *tgpf)
/* need to restore the original projection settings before packing up */
view3d_region_operator_needs_opengl(tgpf->win, tgpf->region);
ED_view3d_depth_override(
- tgpf->depsgraph, tgpf->region, tgpf->v3d, NULL, V3D_DEPTH_NO_GPENCIL, false);
+ tgpf->depsgraph, tgpf->region, tgpf->v3d, NULL, V3D_DEPTH_NO_GPENCIL, NULL);
/* Since strokes are so fine, when using their depth we need a margin
* otherwise they might get missed. */
@@ -1522,8 +1522,8 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
pt = gps->points;
point2D = (tGPspoint *)tgpf->sbuffer;
- const int def_nr = tgpf->ob->actdef - 1;
- const bool have_weight = (bool)BLI_findlink(&tgpf->ob->defbase, def_nr);
+ const int def_nr = tgpf->gpd->vertex_group_active_index - 1;
+ const bool have_weight = (bool)BLI_findlink(&tgpf->gpd->vertex_group_names, def_nr);
if ((ts->gpencil_flags & GP_TOOL_FLAG_CREATE_WEIGHTS) && (have_weight)) {
BKE_gpencil_dvert_ensure(gps);
@@ -1625,7 +1625,7 @@ static void gpencil_draw_boundary_lines(const bContext *UNUSED(C), tGPDfill *tgp
static void gpencil_fill_draw_3d(const bContext *C, ARegion *UNUSED(region), void *arg)
{
tGPDfill *tgpf = (tGPDfill *)arg;
- /* draw only in the region that originated operator. This is required for multiwindow */
+ /* Draw only in the region that originated operator. This is required for multi-window. */
ARegion *region = CTX_wm_region(C);
if (region != tgpf->region) {
return;
@@ -1869,7 +1869,7 @@ static int gpencil_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
DEG_id_tag_update(&tgpf->gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
- /* add a modal handler for this operator*/
+ /* Add a modal handler for this operator. */
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
@@ -2123,7 +2123,7 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
gpencil_stroke_convertcoords_tpoint(
tgpf->scene, tgpf->region, tgpf->ob, &point2D, NULL, &pt->x);
- /* Hash of selected frames.*/
+ /* Hash of selected frames. */
GHash *frame_list = BLI_ghash_int_new_ex(__func__, 64);
/* If not multiframe and there is no frame in CFRA for the active layer, create
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 9f48c81c8f1..d1a1e417d9e 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -444,6 +444,7 @@ void GPENCIL_OT_frame_clean_duplicate(struct wmOperatorType *ot);
void GPENCIL_OT_convert(struct wmOperatorType *ot);
void GPENCIL_OT_bake_mesh_animation(struct wmOperatorType *ot);
+void GPENCIL_OT_bake_grease_pencil_animation(struct wmOperatorType *ot);
void GPENCIL_OT_image_to_grease_pencil(struct wmOperatorType *ot);
void GPENCIL_OT_trace_image(struct wmOperatorType *ot);
@@ -487,6 +488,7 @@ void GPENCIL_OT_stroke_trim(struct wmOperatorType *ot);
void GPENCIL_OT_stroke_merge_by_distance(struct wmOperatorType *ot);
void GPENCIL_OT_stroke_merge_material(struct wmOperatorType *ot);
void GPENCIL_OT_stroke_reset_vertex_color(struct wmOperatorType *ot);
+void GPENCIL_OT_stroke_normalize(struct wmOperatorType *ot);
void GPENCIL_OT_material_to_vertex_color(struct wmOperatorType *ot);
void GPENCIL_OT_extract_palette_vertex(struct wmOperatorType *ot);
@@ -547,51 +549,6 @@ void GPENCIL_OT_convert_old_files(struct wmOperatorType *ot);
void GPENCIL_OT_generate_weights(struct wmOperatorType *ot);
/* ****************************************************** */
-/* FILTERED ACTION DATA - TYPES ---> XXX DEPRECATED OLD ANIM SYSTEM CODE! */
-
-/* XXX - TODO: replace this with the modern bAnimListElem... */
-/* This struct defines a structure used for quick access */
-typedef struct bActListElem {
- struct bActListElem *next, *prev;
-
- void *data; /* source data this elem represents */
- int type; /* one of the ACTTYPE_* values */
- int flag; /* copy of elem's flags for quick access */
- int index; /* copy of adrcode where applicable */
-
- void *key_data; /* motion data - ipo or ipo-curve */
- short datatype; /* type of motion data to expect */
-
- struct bActionGroup *grp; /* action group that owns the channel */
-
- void *owner; /* will either be an action channel or fake IPO-channel (for keys) */
- short ownertype; /* type of owner */
-} bActListElem;
-
-/* ****************************************************** */
-/* FILTER ACTION DATA - METHODS/TYPES */
-
-/* filtering flags - under what circumstances should a channel be added */
-typedef enum ACTFILTER_FLAGS {
- ACTFILTER_VISIBLE = (1 << 0), /* should channels be visible */
- ACTFILTER_SEL = (1 << 1), /* should channels be selected */
- ACTFILTER_FOREDIT = (1 << 2), /* does editable status matter */
- ACTFILTER_CHANNELS = (1 << 3), /* do we only care that it is a channel */
- ACTFILTER_IPOKEYS = (1 << 4), /* only channels referencing IPO's */
- ACTFILTER_ONLYICU = (1 << 5), /* only reference ipo-curves */
- ACTFILTER_FORDRAWING = (1 << 6), /* make list for interface drawing */
- ACTFILTER_ACTGROUPED = (1 << 7), /* belongs to the active group */
-} ACTFILTER_FLAGS;
-
-/* Action Editor - Main Data types */
-typedef enum ACTCONT_TYPES {
- ACTCONT_NONE = 0,
- ACTCONT_ACTION,
- ACTCONT_SHAPEKEY,
- ACTCONT_GPENCIL,
-} ACTCONT_TYPES;
-
-/* ****************************************************** */
/* Stroke Iteration Utilities */
struct GP_EditableStrokes_Iter {
@@ -635,7 +592,7 @@ struct GP_EditableStrokes_Iter {
if (ED_gpencil_stroke_material_editable(obact_, gpl, gps) == false) { \
continue; \
} \
- /* ... Do Stuff With Strokes ... */
+ /* ... Do Stuff With Strokes ... */
#define GP_EDITABLE_STROKES_END(gpstroke_iter) \
} \
@@ -685,7 +642,7 @@ struct GP_EditableStrokes_Iter {
if (gps->editcurve == NULL) \
continue; \
bGPDcurve *gpc = gps->editcurve; \
- /* ... Do Stuff With Strokes ... */
+ /* ... Do Stuff With Strokes ... */
#define GP_EDITABLE_CURVES_END(gpstroke_iter) \
} \
@@ -736,7 +693,7 @@ struct GP_EditableStrokes_Iter {
if (ED_gpencil_stroke_material_editable(obact_, gpl, gps) == false) { \
continue; \
} \
- /* ... Do Stuff With Strokes ... */
+ /* ... Do Stuff With Strokes ... */
#define GP_EVALUATED_STROKES_END(gpstroke_iter) \
} \
@@ -750,4 +707,7 @@ struct GP_EditableStrokes_Iter {
} \
(void)0
+/* Reused items for bake operators. */
+extern const EnumPropertyItem rna_gpencil_reproject_type_items[];
+
/* ****************************************************** */
diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c
index b7ed77801c0..1882285a230 100644
--- a/source/blender/editors/gpencil/gpencil_mesh.c
+++ b/source/blender/editors/gpencil/gpencil_mesh.c
@@ -159,7 +159,7 @@ static bool gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene
if (ob == obact) {
continue;
}
- /* Add selected meshes.*/
+ /* Add selected meshes. */
if (ob->type == OB_MESH) {
elem = MEM_callocN(sizeof(GpBakeOb), __func__);
elem->ob = ob;
@@ -402,25 +402,6 @@ static int gpencil_bake_mesh_animation_invoke(bContext *C,
void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
{
- static const EnumPropertyItem reproject_type[] = {
- {GP_REPROJECT_KEEP, "KEEP", 0, "No Reproject", ""},
- {GP_REPROJECT_FRONT, "FRONT", 0, "Front", "Reproject the strokes using the X-Z plane"},
- {GP_REPROJECT_SIDE, "SIDE", 0, "Side", "Reproject the strokes using the Y-Z plane"},
- {GP_REPROJECT_TOP, "TOP", 0, "Top", "Reproject the strokes using the X-Y plane"},
- {GP_REPROJECT_VIEW,
- "VIEW",
- 0,
- "View",
- "Reproject the strokes to end up on the same plane, as if drawn from the current viewpoint "
- "using 'Cursor' Stroke Placement"},
- {GP_REPROJECT_CURSOR,
- "CURSOR",
- 0,
- "Cursor",
- "Reproject the strokes using the orientation of 3D cursor"},
- {0, NULL, 0, NULL, NULL},
- };
-
static const EnumPropertyItem target_object_modes[] = {
{GP_TARGET_OB_NEW, "NEW", 0, "New Object", ""},
{GP_TARGET_OB_SELECTED, "SELECTED", 0, "Selected Object", ""},
@@ -491,5 +472,10 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
RNA_def_int(
ot->srna, "frame_target", 1, 1, 100000, "Target Frame", "Destination frame", 1, 100000);
- RNA_def_enum(ot->srna, "project_type", reproject_type, GP_REPROJECT_VIEW, "Projection Type", "");
+ RNA_def_enum(ot->srna,
+ "project_type",
+ rna_gpencil_reproject_type_items,
+ GP_REPROJECT_VIEW,
+ "Projection Type",
+ "");
}
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 698d784c3b0..35640cf3b66 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -622,6 +622,7 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_convert);
WM_operatortype_append(GPENCIL_OT_bake_mesh_animation);
+ WM_operatortype_append(GPENCIL_OT_bake_grease_pencil_animation);
WM_operatortype_append(GPENCIL_OT_image_to_grease_pencil);
#ifdef WITH_POTRACE
@@ -648,6 +649,7 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_stroke_merge_by_distance);
WM_operatortype_append(GPENCIL_OT_stroke_merge_material);
WM_operatortype_append(GPENCIL_OT_stroke_reset_vertex_color);
+ WM_operatortype_append(GPENCIL_OT_stroke_normalize);
WM_operatortype_append(GPENCIL_OT_material_to_vertex_color);
WM_operatortype_append(GPENCIL_OT_extract_palette_vertex);
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 30d85b09974..d6f6dbb2b10 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -938,8 +938,8 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
Depsgraph *depsgraph = p->depsgraph;
Object *obact = (Object *)p->ownerPtr.data;
RegionView3D *rv3d = p->region->regiondata;
- const int def_nr = obact->actdef - 1;
- const bool have_weight = (bool)BLI_findlink(&obact->defbase, def_nr);
+ const int def_nr = gpd->vertex_group_active_index - 1;
+ const bool have_weight = (bool)BLI_findlink(&gpd->vertex_group_names, def_nr);
const char align_flag = ts->gpencil_v3d_align;
const bool is_depth = (bool)(align_flag & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE));
const bool is_lock_axis_view = (bool)(ts->gp_sculpt.lock_axis == 0);
@@ -1319,20 +1319,9 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
/* --- 'Eraser' for 'Paint' Tool ------ */
-/**
- * Which which point is in front (result should only be used for comparison).
- */
-static float view3d_point_depth(const RegionView3D *rv3d, const float co[3])
-{
- if (rv3d->is_persp) {
- return ED_view3d_calc_zfac(rv3d, co, NULL);
- }
- return -dot_v3v3(rv3d->viewinv[2], co);
-}
-
/* only erase stroke points that are visible */
static bool gpencil_stroke_eraser_is_occluded(
- tGPsdata *p, bGPDlayer *gpl, const bGPDspoint *pt, const int x, const int y)
+ tGPsdata *p, bGPDlayer *gpl, bGPDspoint *pt, const int x, const int y)
{
Object *obact = (Object *)p->ownerPtr.data;
Brush *brush = p->brush;
@@ -1359,12 +1348,16 @@ static bool gpencil_stroke_eraser_is_occluded(
BKE_gpencil_layer_transform_matrix_get(p->depsgraph, obact, gpl, diff_mat);
if (ED_view3d_autodist_simple(p->region, mval_i, mval_3d, 0, NULL)) {
- const float depth_mval = view3d_point_depth(rv3d, mval_3d);
+ const float depth_mval = ED_view3d_calc_depth_for_comparison(rv3d, mval_3d);
mul_v3_m4v3(fpt, diff_mat, &pt->x);
- const float depth_pt = view3d_point_depth(rv3d, fpt);
+ const float depth_pt = ED_view3d_calc_depth_for_comparison(rv3d, fpt);
+ /* Checked occlusion flag. */
+ pt->flag |= GP_SPOINT_TEMP_TAG;
if (depth_pt > depth_mval) {
+ /* Is occluded. */
+ pt->flag |= GP_SPOINT_TEMP_TAG2;
return true;
}
}
@@ -1429,7 +1422,7 @@ static void gpencil_stroke_soft_refine(bGPDstroke *gps)
bGPDspoint *pt2 = NULL;
int i;
- /* check if enough points*/
+ /* Check if enough points. */
if (gps->totpoints < 3) {
return;
}
@@ -1533,13 +1526,17 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
/* Clear Tags
*
- * Note: It's better this way, as we are sure that
+ * NOTE: It's better this way, as we are sure that
* we don't miss anything, though things will be
* slightly slower as a result
*/
for (i = 0; i < gps->totpoints; i++) {
bGPDspoint *pt = &gps->points[i];
pt->flag &= ~GP_SPOINT_TAG;
+ /* Occlusion already checked. */
+ pt->flag &= ~GP_SPOINT_TEMP_TAG;
+ /* Point is occluded. */
+ pt->flag &= ~GP_SPOINT_TEMP_TAG2;
}
/* First Pass: Loop over the points in the stroke
@@ -1582,12 +1579,26 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
/* 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
+ * - this assumes that line-width is irrelevant.
*/
if (gpencil_stroke_inside_circle(mval, radius, pc0[0], pc0[1], pc2[0], pc2[1])) {
- if ((gpencil_stroke_eraser_is_occluded(p, gpl, pt0, pc0[0], pc0[1]) == false) ||
- (gpencil_stroke_eraser_is_occluded(p, gpl, pt1, pc1[0], pc1[1]) == false) ||
- (gpencil_stroke_eraser_is_occluded(p, gpl, pt2, pc2[0], pc2[1]) == false)) {
+
+ bool is_occluded_pt0, is_occluded_pt1, is_occluded_pt2 = true;
+ is_occluded_pt0 = (pt0 && ((pt0->flag & GP_SPOINT_TEMP_TAG) != 0)) ?
+ ((pt0->flag & GP_SPOINT_TEMP_TAG2) != 0) :
+ gpencil_stroke_eraser_is_occluded(p, gpl, pt0, pc0[0], pc0[1]);
+ if (is_occluded_pt0) {
+ is_occluded_pt1 = ((pt1->flag & GP_SPOINT_TEMP_TAG) != 0) ?
+ ((pt1->flag & GP_SPOINT_TEMP_TAG2) != 0) :
+ gpencil_stroke_eraser_is_occluded(p, gpl, pt1, pc1[0], pc1[1]);
+ if (is_occluded_pt1) {
+ is_occluded_pt2 = ((pt2->flag & GP_SPOINT_TEMP_TAG) != 0) ?
+ ((pt2->flag & GP_SPOINT_TEMP_TAG2) != 0) :
+ gpencil_stroke_eraser_is_occluded(p, gpl, pt2, pc2[0], pc2[1]);
+ }
+ }
+
+ if (!is_occluded_pt0 || !is_occluded_pt1 || !is_occluded_pt2) {
/* Point is affected: */
/* Adjust thickness
* - Influence of eraser falls off with distance from the middle of the eraser
@@ -1722,7 +1733,7 @@ static void gpencil_stroke_doeraser(tGPsdata *p)
if ((gp_settings != NULL) && (gp_settings->flag & GP_BRUSH_OCCLUDE_ERASER)) {
View3D *v3d = p->area->spacedata.first;
view3d_region_operator_needs_opengl(p->win, p->region);
- ED_view3d_depth_override(p->depsgraph, p->region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, false);
+ ED_view3d_depth_override(p->depsgraph, p->region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, NULL);
}
}
@@ -1770,7 +1781,7 @@ static void gpencil_stroke_doeraser(tGPsdata *p)
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -2163,7 +2174,7 @@ static void gpencil_paint_initstroke(tGPsdata *p,
/* Add a new frame if needed (and based off the active frame,
* as we need some existing strokes to erase)
*
- * Note: We don't add a new frame if there's nothing there now, so
+ * NOTE: We don't add a new frame if there's nothing there now, so
* -> If there are no frames at all, don't add one
* -> If there are no strokes in that frame, don't add a new empty frame
*/
@@ -2312,7 +2323,7 @@ static void gpencil_paint_strokeend(tGPsdata *p)
(ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ?
V3D_DEPTH_GPENCIL_ONLY :
V3D_DEPTH_NO_GPENCIL,
- false);
+ NULL);
}
/* check if doing eraser or not */
@@ -3156,7 +3167,7 @@ static void gpencil_guide_event_handling(bContext *C,
guide->type = GP_GUIDE_CIRCULAR;
}
}
- /* Change line angle */
+ /* Change line angle. */
else if (ELEM(event->type, EVT_JKEY, EVT_KKEY) && (event->val == KM_RELEASE)) {
add_notifier = true;
float angle = guide->angle;
@@ -3265,7 +3276,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
gpencil_guide_event_handling(C, op, event, p);
}
- if (ob && (ob->type == OB_GPENCIL) && ((p->gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0)) {
+ if ((ob->type == OB_GPENCIL) && ((p->gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0)) {
/* FIXME: use the mode switching operator, this misses notifiers, messages. */
/* Just set paintmode flag... */
p->gpd->flag |= GP_DATA_STROKE_PAINTMODE;
@@ -3438,7 +3449,7 @@ static void gpencil_add_arc_points(tGPsdata *p, const float mval[2], int segment
interp_v4_v4v4(
pt->vert_color, pt_before->vert_color, pt_prev->vert_color, stepcolor * (i + 1));
- /* Apply angle of stroke to brush size to interpolated points but slightly attenuated.. */
+ /* Apply angle of stroke to brush size to interpolated points but slightly attenuated. */
if (brush_settings->draw_angle_factor != 0.0f) {
gpencil_brush_angle_segment(p, pt_step, pt);
CLAMP(pt->pressure, pt_prev->pressure * 0.5f, 1.0f);
@@ -3591,18 +3602,15 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* default exit state - pass through to support MMB view nav, etc. */
int estate = OPERATOR_PASS_THROUGH;
- /* if (event->type == NDOF_MOTION)
- * return OPERATOR_PASS_THROUGH;
- * -------------------------------
- * [mce] Not quite what I was looking
- * for, but a good start! GP continues to
- * draw on the screen while the 3D mouse
- * moves the viewpoint. Problem is that
- * the stroke is converted to 3D only after
- * it is finished. This approach should work
- * better in tools that immediately apply
- * in 3D space.
- */
+ /* NOTE(mike erwin): Not quite what I was looking for, but a good start!
+ * grease-pencil continues to draw on the screen while the 3D mouse moves the viewpoint.
+ * Problem is that the stroke is converted to 3D only after it is finished.
+ * This approach should work better in tools that immediately apply in 3D space. */
+#if 0
+ if (event->type == NDOF_MOTION) {
+ return OPERATOR_PASS_THROUGH;
+ }
+#endif
if (p->status == GP_STATUS_IDLING) {
ARegion *region = CTX_wm_region(C);
@@ -3749,7 +3757,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else if (p->region) {
- /* Perform bounds check using */
+ /* Perform bounds check using. */
const rcti *region_rect = ED_region_visible_rect(p->region);
in_bounds = BLI_rcti_isect_pt_v(region_rect, event->mval);
}
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 1b0a40b1be1..78eaab01b1a 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -792,7 +792,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
(ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ?
V3D_DEPTH_GPENCIL_ONLY :
V3D_DEPTH_NO_GPENCIL,
- false);
+ NULL);
depth_arr = MEM_mallocN(sizeof(float) * gps->totpoints, "depth_points");
tGPspoint *ptc = &points2D[0];
@@ -1315,8 +1315,9 @@ static void gpencil_primitive_interaction_end(bContext *C,
Brush *brush = tgpi->brush;
BrushGpencilSettings *brush_settings = brush->gpencil_settings;
- const int def_nr = tgpi->ob->actdef - 1;
- const bool have_weight = (bool)BLI_findlink(&tgpi->ob->defbase, def_nr);
+ const int def_nr = tgpi->gpd->vertex_group_active_index - 1;
+ const ListBase *defbase = BKE_object_defgroup_list(tgpi->ob);
+ const bool have_weight = (bool)BLI_findlink(defbase, def_nr);
/* return to normal cursor and header status */
ED_workspace_status_text(C, NULL);
@@ -1536,24 +1537,22 @@ static void gpencil_primitive_strength(tGPDprimitive *tgpi, bool reset)
Brush *brush = tgpi->brush;
BrushGpencilSettings *brush_settings = brush->gpencil_settings;
- if (brush) {
- if (reset) {
- brush_settings->draw_strength = tgpi->brush_strength;
- tgpi->brush_strength = 0.0f;
- }
- else {
- if (tgpi->brush_strength == 0.0f) {
- tgpi->brush_strength = brush_settings->draw_strength;
- }
- float move[2];
- sub_v2_v2v2(move, tgpi->mval, tgpi->mvalo);
- float adjust = (move[1] > 0.0f) ? 0.01f : -0.01f;
- brush_settings->draw_strength += adjust * fabsf(len_manhattan_v2(move));
+ if (reset) {
+ brush_settings->draw_strength = tgpi->brush_strength;
+ tgpi->brush_strength = 0.0f;
+ }
+ else {
+ if (tgpi->brush_strength == 0.0f) {
+ tgpi->brush_strength = brush_settings->draw_strength;
}
-
- /* limit low limit because below 0.2f the stroke is invisible */
- CLAMP(brush_settings->draw_strength, 0.2f, 1.0f);
+ float move[2];
+ sub_v2_v2v2(move, tgpi->mval, tgpi->mvalo);
+ float adjust = (move[1] > 0.0f) ? 0.01f : -0.01f;
+ brush_settings->draw_strength += adjust * fabsf(len_manhattan_v2(move));
}
+
+ /* limit low limit because below 0.2f the stroke is invisible */
+ CLAMP(brush_settings->draw_strength, 0.2f, 1.0f);
}
/* brush size */
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index 2b8800e5136..462462cf341 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -1096,7 +1096,7 @@ static void gpencil_brush_clone_adjust(tGP_BrushEditData *gso)
}
}
-/* Entrypoint for applying "clone" brush */
+/* Entry-point for applying "clone" brush. */
static bool gpencil_sculpt_brush_apply_clone(bContext *C, tGP_BrushEditData *gso)
{
/* Which "mode" are we operating in? */
@@ -1177,8 +1177,8 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op)
gso->object = ob;
if (ob) {
invert_m4_m4(gso->inv_mat, ob->obmat);
- gso->vrgroup = ob->actdef - 1;
- if (!BLI_findlink(&ob->defbase, gso->vrgroup)) {
+ gso->vrgroup = gso->gpd->vertex_group_active_index - 1;
+ if (!BLI_findlink(&gso->gpd->vertex_group_names, gso->vrgroup)) {
gso->vrgroup = -1;
}
/* Check if some modifier can transform the stroke. */
@@ -1381,7 +1381,7 @@ static float gpencil_sculpt_rotation_eval_get(tGP_BrushEditData *gso,
return 0.0f;
}
- GP_SpaceConversion *gsc = &gso->gsc;
+ const GP_SpaceConversion *gsc = &gso->gsc;
bGPDstroke *gps_orig = (gps_eval->runtime.gps_orig) ? gps_eval->runtime.gps_orig : gps_eval;
bGPDspoint *pt_orig = &gps_orig->points[pt_eval->runtime.idx_orig];
bGPDspoint *pt_prev_eval = NULL;
@@ -1500,7 +1500,7 @@ static bool gpencil_sculpt_brush_do_stroke(tGP_BrushEditData *gso,
((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
/* Check if point segment of stroke had anything to do with
* brush region (either within stroke painted, or on its lines)
- * - this assumes that linewidth is irrelevant
+ * - this assumes that line-width is irrelevant.
*/
if (gpencil_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
/* Apply operation to these points */
@@ -2020,7 +2020,7 @@ static int gpencil_sculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent
/* The operator can be in 2 states: Painting and Idling */
if (gso->is_painting) {
- /* Painting */
+ /* Painting. */
switch (event->type) {
/* Mouse Move = Apply somewhere else */
case MOUSEMOVE:
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index e1776988186..69734fa1ba8 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -689,7 +689,7 @@ static int gpencil_select_grouped_exec(bContext *C, wmOperator *op)
break;
default:
- BLI_assert(!"unhandled select grouped gpencil mode");
+ BLI_assert_msg(0, "unhandled select grouped gpencil mode");
break;
}
@@ -1276,7 +1276,7 @@ static bool gpencil_stroke_do_circle_sel(bGPdata *gpd,
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
bGPDspoint pt_temp;
- gpencil_point_to_parent_space(pt_active, diff_mat, &pt_temp);
+ gpencil_point_to_parent_space(pt, diff_mat, &pt_temp);
gpencil_point_to_xy(gsc, gps, &pt_temp, &x0, &y0);
/* do boundbox check first */
@@ -1374,7 +1374,7 @@ static bool gpencil_do_curve_circle_sel(bContext *C,
const bool handles_visible = (v3d->overlay.handle_display != CURVE_HANDLE_NONE) &&
(!only_selected || BEZT_ISSEL_ANY(bezt));
- /* if the handles are not visible only check ctrl point (vec[1])*/
+ /* If the handles are not visible only check control point (vec[1]). */
int from = (!handles_visible) ? 1 : 0;
int to = (!handles_visible) ? 2 : 3;
@@ -1719,7 +1719,7 @@ static bool gpencil_generic_curve_select(bContext *C,
}
}
}
- /* if the handles are not visible only check ctrl point (vec[1])*/
+ /* If the handles are not visible only check ctrl point (vec[1]). */
else {
const bool is_select = bezt->f2;
bool is_inside = is_inside_fn(region, gps_iter.diff_mat, bezt->vec[1], user_data);
@@ -1847,7 +1847,7 @@ static bool gpencil_generic_stroke_select(bContext *C,
bGPDspoint *pt;
int i;
bool hit = false;
- for (i = 0, pt = gps_active->points; i < gps_active->totpoints; i++, pt++) {
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
bGPDspoint *pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
/* convert point coords to screenspace */
@@ -1889,7 +1889,7 @@ static bool gpencil_generic_stroke_select(bContext *C,
mval[0] = (box.xmax + box.xmin) / 2;
mval[1] = (box.ymax + box.ymin) / 2;
- whole = ED_gpencil_stroke_point_is_inside(gps_active, &gsc, mval, gpstroke_iter.diff_mat);
+ whole = ED_gpencil_stroke_point_is_inside(gps, &gsc, mval, gpstroke_iter.diff_mat);
}
/* if stroke mode expand selection. */
@@ -2153,7 +2153,7 @@ static void gpencil_select_curve_point(bContext *C,
const bool handles_visible = (v3d->overlay.handle_display != CURVE_HANDLE_NONE) &&
(!only_selected || BEZT_ISSEL_ANY(bezt));
- /* if the handles are not visible only check ctrl point (vec[1])*/
+ /* If the handles are not visible only check control point (vec[1]). */
int from = (!handles_visible) ? 1 : 0;
int to = (!handles_visible) ? 2 : 3;
@@ -2252,7 +2252,7 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
int i;
/* firstly, check for hit-point */
- for (i = 0, pt = gps_active->points; i < gps_active->totpoints; i++, pt++) {
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
int xy[2];
bGPDspoint pt2;
diff --git a/source/blender/editors/gpencil/gpencil_trace_utils.c b/source/blender/editors/gpencil/gpencil_trace_utils.c
index 482f7015720..970afc3ff6b 100644
--- a/source/blender/editors/gpencil/gpencil_trace_utils.c
+++ b/source/blender/editors/gpencil/gpencil_trace_utils.c
@@ -250,7 +250,7 @@ void ED_gpencil_trace_data_to_strokes(Main *bmain,
const int32_t thickness)
{
#define MAX_LENGTH 100.0f
- /* Find materials and create them if not found. */
+ /* Find materials and create them if not found. */
int32_t mat_fill_idx = BKE_gpencil_material_find_index_by_name_prefix(ob, "Stroke");
int32_t mat_mask_idx = BKE_gpencil_material_find_index_by_name_prefix(ob, "Holdout");
@@ -281,7 +281,6 @@ void ED_gpencil_trace_data_to_strokes(Main *bmain,
mat_mask_idx = ob->totcol - 1;
}
- potrace_path_t *path = st->plist;
int n, *tag;
potrace_dpoint_t(*c)[3];
@@ -289,7 +288,7 @@ void ED_gpencil_trace_data_to_strokes(Main *bmain,
* good results using the Potrace data. */
const float scalef = 0.008f * scale;
/* Draw each curve. */
- path = st->plist;
+ potrace_path_t *path = st->plist;
while (path != NULL) {
n = path->curve.n;
tag = path->curve.tag;
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 04764587ebe..ba3d3b584d7 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -565,7 +565,7 @@ bool ED_gpencil_layer_has_selected_stroke(const bGPDlayer *gpl, const bool is_mu
return true;
}
}
- /* If not multiedit, exit loop. */
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -680,7 +680,7 @@ void gpencil_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
view3d_operator_needs_opengl(C);
view3d_region_operator_needs_opengl(win, region);
- ED_view3d_depth_override(depsgraph, region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, false);
+ ED_view3d_depth_override(depsgraph, region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, NULL);
/* for camera view set the subrect */
if (rv3d->persp == RV3D_CAMOB) {
@@ -1227,7 +1227,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
float xy[2];
/* 3D to Screen-space */
- /* Note: We can't use gpencil_point_to_xy() here because that uses ints for the screen-space
+ /* NOTE: We can't use gpencil_point_to_xy() here because that uses ints for the screen-space
* coordinates, resulting in lost precision, which in turn causes stair-stepping
* artifacts in the final points. */
@@ -1276,6 +1276,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
}
else {
/* Geometry - Snap to surfaces of visible geometry */
+ float ray_start[3];
float ray_normal[3];
/* magic value for initial depth copied from the default
* value of Python's Scene.ray_cast function
@@ -1284,14 +1285,17 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
float location[3] = {0.0f, 0.0f, 0.0f};
float normal[3] = {0.0f, 0.0f, 0.0f};
- ED_view3d_win_to_vector(region, xy, &ray_normal[0]);
BLI_assert(gps->flag & GP_STROKE_3DSPACE);
+ BLI_assert(gsc->area && gsc->area->spacetype == SPACE_VIEW3D);
+ const View3D *v3d = gsc->area->spacedata.first;
+ ED_view3d_win_to_ray_clipped(
+ depsgraph, region, v3d, xy, &ray_start[0], &ray_normal[0], true);
if (ED_transform_snap_object_project_ray(sctx,
depsgraph,
&(const struct SnapObjectParams){
.snap_select = SNAP_ALL,
},
- &pt2.x,
+ &ray_start[0],
&ray_normal[0],
&depth,
&location[0],
@@ -1596,8 +1600,8 @@ void ED_gpencil_vgroup_assign(bContext *C, Object *ob, float weight)
{
bGPdata *gpd = (bGPdata *)ob->data;
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
- const int def_nr = ob->actdef - 1;
- if (!BLI_findlink(&ob->defbase, def_nr)) {
+ const int def_nr = gpd->vertex_group_active_index - 1;
+ if (!BLI_findlink(&gpd->vertex_group_names, def_nr)) {
return;
}
@@ -1636,7 +1640,7 @@ void ED_gpencil_vgroup_assign(bContext *C, Object *ob, float weight)
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -1650,8 +1654,8 @@ void ED_gpencil_vgroup_remove(bContext *C, Object *ob)
{
bGPdata *gpd = (bGPdata *)ob->data;
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
- const int def_nr = ob->actdef - 1;
- if (!BLI_findlink(&ob->defbase, def_nr)) {
+ const int def_nr = gpd->vertex_group_active_index - 1;
+ if (!BLI_findlink(&gpd->vertex_group_names, def_nr)) {
return;
}
@@ -1689,7 +1693,7 @@ void ED_gpencil_vgroup_remove(bContext *C, Object *ob)
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -1703,8 +1707,8 @@ void ED_gpencil_vgroup_select(bContext *C, Object *ob)
{
bGPdata *gpd = (bGPdata *)ob->data;
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
- const int def_nr = ob->actdef - 1;
- if (!BLI_findlink(&ob->defbase, def_nr)) {
+ const int def_nr = gpd->vertex_group_active_index - 1;
+ if (!BLI_findlink(&gpd->vertex_group_names, def_nr)) {
return;
}
@@ -1744,7 +1748,7 @@ void ED_gpencil_vgroup_select(bContext *C, Object *ob)
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -1758,8 +1762,8 @@ void ED_gpencil_vgroup_deselect(bContext *C, Object *ob)
{
bGPdata *gpd = (bGPdata *)ob->data;
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
- const int def_nr = ob->actdef - 1;
- if (!BLI_findlink(&ob->defbase, def_nr)) {
+ const int def_nr = gpd->vertex_group_active_index - 1;
+ if (!BLI_findlink(&gpd->vertex_group_names, def_nr)) {
return;
}
@@ -1794,7 +1798,7 @@ void ED_gpencil_vgroup_deselect(bContext *C, Object *ob)
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -2211,7 +2215,7 @@ void ED_gpencil_tpoint_to_point(ARegion *region,
void ED_gpencil_update_color_uv(Main *bmain, Material *mat)
{
Material *gps_ma = NULL;
- /* read all strokes */
+ /* Read all strokes. */
for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
if (ob->type == OB_GPENCIL) {
bGPdata *gpd = ob->data;
@@ -2474,7 +2478,7 @@ int ED_gpencil_select_stroke_segment(bGPdata *gpd,
return 0;
}
- /* convert all gps points to 2d and save in a hash to avoid recalculation */
+ /* Convert all gps points to 2d and save in a hash to avoid recalculation. */
int direction = 0;
float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * gps->totpoints,
"GP Stroke temp 2d points");
@@ -3102,8 +3106,8 @@ void ED_gpencil_sbuffer_vertex_color_set(Depsgraph *depsgraph,
}
/* Get the bigger 2D bound box points. */
-void ED_gpencil_projected_2d_bound_box(GP_SpaceConversion *gsc,
- bGPDstroke *gps,
+void ED_gpencil_projected_2d_bound_box(const GP_SpaceConversion *gsc,
+ const bGPDstroke *gps,
const float diff_mat[4][4],
float r_min[2],
float r_max[2])
@@ -3136,7 +3140,7 @@ void ED_gpencil_projected_2d_bound_box(GP_SpaceConversion *gsc,
}
/* Check if the stroke collides with brush. */
-bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc,
+bool ED_gpencil_stroke_check_collision(const GP_SpaceConversion *gsc,
bGPDstroke *gps,
const float mouse[2],
const int radius,
@@ -3171,9 +3175,9 @@ bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc,
* \param diff_mat: View matrix.
* \return True if the point is inside.
*/
-bool ED_gpencil_stroke_point_is_inside(bGPDstroke *gps,
- GP_SpaceConversion *gsc,
- int mouse[2],
+bool ED_gpencil_stroke_point_is_inside(const bGPDstroke *gps,
+ const GP_SpaceConversion *gsc,
+ const int mouse[2],
const float diff_mat[4][4])
{
bool hit = false;
@@ -3186,7 +3190,7 @@ bool ED_gpencil_stroke_point_is_inside(bGPDstroke *gps,
mcoords = MEM_mallocN(sizeof(int[2]) * len, __func__);
/* Convert stroke to 2D array of points. */
- bGPDspoint *pt;
+ const bGPDspoint *pt;
int i;
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
bGPDspoint pt2;
@@ -3210,7 +3214,7 @@ bool ED_gpencil_stroke_point_is_inside(bGPDstroke *gps,
}
bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
- GP_SpaceConversion *gsc,
+ const GP_SpaceConversion *gsc,
bGPDlayer *gpl,
bGPDframe *gpf,
bGPDstroke *gps,
@@ -3298,7 +3302,7 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
return gps_rtn;
}
-/* Join two stroke using a contact point index and trimming the rest. */
+/* Join two stroke using a contact point index and trimming the rest. */
bGPDstroke *ED_gpencil_stroke_join_and_trim(
bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *gps_dst, const int pt_index)
{
diff --git a/source/blender/editors/gpencil/gpencil_vertex_ops.c b/source/blender/editors/gpencil/gpencil_vertex_ops.c
index bf46fa2544f..402bccce2f7 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_ops.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_ops.c
@@ -99,7 +99,7 @@ static bool is_any_stroke_selected(bContext *C, const bool is_multiedit, const b
}
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -204,7 +204,7 @@ static int gpencil_vertexpaint_brightness_contrast_exec(bContext *C, wmOperator
}
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -325,7 +325,7 @@ static int gpencil_vertexpaint_hsv_exec(bContext *C, wmOperator *op)
}
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -419,7 +419,7 @@ static int gpencil_vertexpaint_invert_exec(bContext *C, wmOperator *op)
}
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -510,7 +510,7 @@ static int gpencil_vertexpaint_levels_exec(bContext *C, wmOperator *op)
}
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -605,7 +605,7 @@ static int gpencil_vertexpaint_set_exec(bContext *C, wmOperator *op)
}
}
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
@@ -1113,7 +1113,7 @@ static int gpencil_stroke_reset_vertex_color_exec(bContext *C, wmOperator *op)
changed = true;
}
- /* if not multiedit, exit loop*/
+ /* If not multi-edit, exit loop. */
if (!is_multiedit) {
break;
}
diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c
index a05cc3c4dbd..16605b6c634 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_paint.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c
@@ -910,7 +910,7 @@ static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
/* Check if point segment of stroke had anything to do with
* brush region (either within stroke painted, or on its lines)
- * - this assumes that linewidth is irrelevant
+ * - this assumes that line-width is irrelevant.
*/
if (gpencil_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
@@ -1107,7 +1107,7 @@ static bool gpencil_vertexpaint_brush_do_frame(bContext *C,
break;
}
}
- /* Clear the selected array, but keep the memory allocation.*/
+ /* Clear the selected array, but keep the memory allocation. */
gso->pbuffer = gpencil_select_buffer_ensure(
gso->pbuffer, &gso->pbuffer_size, &gso->pbuffer_used, true);
@@ -1335,7 +1335,7 @@ static int gpencil_vertexpaint_brush_modal(bContext *C, wmOperator *op, const wm
/* The operator can be in 2 states: Painting and Idling */
if (gso->is_painting) {
- /* Painting */
+ /* Painting. */
switch (event->type) {
/* Mouse Move = Apply somewhere else */
case MOUSEMOVE:
diff --git a/source/blender/editors/gpencil/gpencil_weight_paint.c b/source/blender/editors/gpencil/gpencil_weight_paint.c
index a3e5ece5862..d14322e12b5 100644
--- a/source/blender/editors/gpencil/gpencil_weight_paint.c
+++ b/source/blender/editors/gpencil/gpencil_weight_paint.c
@@ -252,7 +252,7 @@ static bool brush_draw_apply(tGP_BrushWeightpaintData *gso,
}
}
else {
- bDeformGroup *defgroup = BLI_findlink(&gso->object->defbase, gso->vrgroup);
+ bDeformGroup *defgroup = BLI_findlink(&gso->gpd->vertex_group_names, gso->vrgroup);
if (defgroup->flag & DG_LOCK_WEIGHT) {
return false;
}
@@ -308,8 +308,8 @@ static bool gpencil_weightpaint_brush_init(bContext *C, wmOperator *op)
gso->scene = scene;
gso->object = ob;
if (ob) {
- gso->vrgroup = ob->actdef - 1;
- if (!BLI_findlink(&ob->defbase, gso->vrgroup)) {
+ gso->vrgroup = gso->gpd->vertex_group_active_index - 1;
+ if (!BLI_findlink(&gso->gpd->vertex_group_names, gso->vrgroup)) {
gso->vrgroup = -1;
}
}
@@ -448,7 +448,7 @@ static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) {
/* Check if point segment of stroke had anything to do with
* brush region (either within stroke painted, or on its lines)
- * - this assumes that linewidth is irrelevant
+ * - this assumes that line-width is irrelevant.
*/
if (gpencil_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
@@ -555,7 +555,7 @@ static bool gpencil_weightpaint_brush_do_frame(bContext *C,
break;
}
}
- /* Clear the selected array, but keep the memory allocation.*/
+ /* Clear the selected array, but keep the memory allocation. */
gso->pbuffer = gpencil_select_buffer_ensure(
gso->pbuffer, &gso->pbuffer_size, &gso->pbuffer_used, true);
@@ -774,7 +774,7 @@ static int gpencil_weightpaint_brush_modal(bContext *C, wmOperator *op, const wm
/* The operator can be in 2 states: Painting and Idling */
if (gso->is_painting) {
- /* Painting */
+ /* Painting. */
switch (event->type) {
/* Mouse Move = Apply somewhere else */
case MOUSEMOVE:
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 4b440aa7367..5cf2a9c9dd0 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -177,9 +177,9 @@ typedef struct bAnimListElem {
* action's ID. But if this is a f-curve which is a driver, then the owner
* is set to, for example, object.
*
- * Note, that this is different from id above. The id above will be set to
- * an object if the f-curve is coming from action associated with that
- * object. */
+ * NOTE: this is different from id above. The id above will be set to
+ * an object if the f-curve is coming from action associated with that object.
+ */
struct ID *fcurve_owner_id;
/**
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index 8015a665970..44c5897d3a3 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -60,21 +60,21 @@ bool ED_curve_editnurb_select_pick(
struct Nurb *ED_curve_add_nurbs_primitive(
struct bContext *C, struct Object *obedit, float mat[4][4], int type, int newob);
-bool ED_curve_nurb_select_check(struct View3D *v3d, struct Nurb *nu);
-int ED_curve_nurb_select_count(struct View3D *v3d, struct Nurb *nu);
+bool ED_curve_nurb_select_check(const struct View3D *v3d, const struct Nurb *nu);
+int ED_curve_nurb_select_count(const struct View3D *v3d, const struct Nurb *nu);
bool ED_curve_nurb_select_all(const struct Nurb *nu);
bool ED_curve_nurb_deselect_all(const struct Nurb *nu);
int ED_curve_join_objects_exec(struct bContext *C, struct wmOperator *op);
/* editcurve_select.c */
-bool ED_curve_select_check(struct View3D *v3d, struct EditNurb *editnurb);
+bool ED_curve_select_check(const struct View3D *v3d, const struct EditNurb *editnurb);
bool ED_curve_deselect_all(struct EditNurb *editnurb);
bool ED_curve_deselect_all_multi_ex(struct Base **bases, int bases_len);
bool ED_curve_deselect_all_multi(struct bContext *C);
bool ED_curve_select_all(struct EditNurb *editnurb);
bool ED_curve_select_swap(struct EditNurb *editnurb, bool hide_handles);
-int ED_curve_select_count(struct View3D *v3d, struct EditNurb *editnurb);
+int ED_curve_select_count(const struct View3D *v3d, const struct EditNurb *editnurb);
/* editcurve_undo.c */
void ED_curve_undosys_type(struct UndoType *ut);
diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h
index 40b0a8d96b1..59e0e014933 100644
--- a/source/blender/editors/include/ED_datafiles.h
+++ b/source/blender/editors/include/ED_datafiles.h
@@ -30,275 +30,275 @@ extern "C" {
/* Datafiles embedded in Blender */
extern int datatoc_startup_blend_size;
-extern char datatoc_startup_blend[];
+extern const char datatoc_startup_blend[];
extern int datatoc_preview_blend_size;
-extern char datatoc_preview_blend[];
+extern const char datatoc_preview_blend[];
extern int datatoc_preview_grease_pencil_blend_size;
-extern char datatoc_preview_grease_pencil_blend[];
+extern const char datatoc_preview_grease_pencil_blend[];
extern int datatoc_blender_icons16_png_size;
-extern char datatoc_blender_icons16_png[];
+extern const char datatoc_blender_icons16_png[];
extern int datatoc_blender_icons32_png_size;
-extern char datatoc_blender_icons32_png[];
+extern const char datatoc_blender_icons32_png[];
extern int datatoc_prvicons_png_size;
-extern char datatoc_prvicons_png[];
+extern const char datatoc_prvicons_png[];
extern int datatoc_alert_icons_png_size;
-extern char datatoc_alert_icons_png[];
+extern const char datatoc_alert_icons_png[];
extern int datatoc_blender_logo_png_size;
-extern char datatoc_blender_logo_png[];
+extern const char datatoc_blender_logo_png[];
extern int datatoc_splash_png_size;
-extern char datatoc_splash_png[];
+extern const char datatoc_splash_png[];
extern int datatoc_bfont_pfb_size;
-extern char datatoc_bfont_pfb[];
+extern const char datatoc_bfont_pfb[];
/* Brush icon datafiles */
/* TODO: this could be simplified by putting all
* the brush icons in one file */
extern int datatoc_add_png_size;
-extern char datatoc_add_png[];
+extern const char datatoc_add_png[];
extern int datatoc_blob_png_size;
-extern char datatoc_blob_png[];
+extern const char datatoc_blob_png[];
extern int datatoc_blur_png_size;
-extern char datatoc_blur_png[];
+extern const char datatoc_blur_png[];
extern int datatoc_clay_png_size;
-extern char datatoc_clay_png[];
+extern const char datatoc_clay_png[];
extern int datatoc_claystrips_png_size;
-extern char datatoc_claystrips_png[];
+extern const char datatoc_claystrips_png[];
extern int datatoc_clone_png_size;
-extern char datatoc_clone_png[];
+extern const char datatoc_clone_png[];
extern int datatoc_crease_png_size;
-extern char datatoc_crease_png[];
+extern const char datatoc_crease_png[];
extern int datatoc_darken_png_size;
-extern char datatoc_darken_png[];
+extern const char datatoc_darken_png[];
extern int datatoc_draw_png_size;
-extern char datatoc_draw_png[];
+extern const char datatoc_draw_png[];
extern int datatoc_fill_png_size;
-extern char datatoc_fill_png[];
+extern const char datatoc_fill_png[];
extern int datatoc_flatten_png_size;
-extern char datatoc_flatten_png[];
+extern const char datatoc_flatten_png[];
extern int datatoc_grab_png_size;
-extern char datatoc_grab_png[];
+extern const char datatoc_grab_png[];
extern int datatoc_inflate_png_size;
-extern char datatoc_inflate_png[];
+extern const char datatoc_inflate_png[];
extern int datatoc_layer_png_size;
-extern char datatoc_layer_png[];
+extern const char datatoc_layer_png[];
extern int datatoc_lighten_png_size;
-extern char datatoc_lighten_png[];
+extern const char datatoc_lighten_png[];
extern int datatoc_mask_png_size;
-extern char datatoc_mask_png[];
+extern const char datatoc_mask_png[];
extern int datatoc_mix_png_size;
-extern char datatoc_mix_png[];
+extern const char datatoc_mix_png[];
extern int datatoc_multiply_png_size;
-extern char datatoc_multiply_png[];
+extern const char datatoc_multiply_png[];
extern int datatoc_nudge_png_size;
-extern char datatoc_nudge_png[];
+extern const char datatoc_nudge_png[];
extern int datatoc_pinch_png_size;
-extern char datatoc_pinch_png[];
+extern const char datatoc_pinch_png[];
extern int datatoc_scrape_png_size;
-extern char datatoc_scrape_png[];
+extern const char datatoc_scrape_png[];
extern int datatoc_smear_png_size;
-extern char datatoc_smear_png[];
+extern const char datatoc_smear_png[];
extern int datatoc_smooth_png_size;
-extern char datatoc_smooth_png[];
+extern const char datatoc_smooth_png[];
extern int datatoc_snake_hook_png_size;
-extern char datatoc_snake_hook_png[];
+extern const char datatoc_snake_hook_png[];
extern int datatoc_soften_png_size;
-extern char datatoc_soften_png[];
+extern const char datatoc_soften_png[];
extern int datatoc_subtract_png_size;
-extern char datatoc_subtract_png[];
+extern const char datatoc_subtract_png[];
extern int datatoc_texdraw_png_size;
-extern char datatoc_texdraw_png[];
+extern const char datatoc_texdraw_png[];
extern int datatoc_texfill_png_size;
-extern char datatoc_texfill_png[];
+extern const char datatoc_texfill_png[];
extern int datatoc_texmask_png_size;
-extern char datatoc_texmask_png[];
+extern const char datatoc_texmask_png[];
extern int datatoc_thumb_png_size;
-extern char datatoc_thumb_png[];
+extern const char datatoc_thumb_png[];
extern int datatoc_twist_png_size;
-extern char datatoc_twist_png[];
+extern const char datatoc_twist_png[];
extern int datatoc_vertexdraw_png_size;
-extern char datatoc_vertexdraw_png[];
+extern const char datatoc_vertexdraw_png[];
/* Matcap files */
extern int datatoc_mc01_jpg_size;
-extern char datatoc_mc01_jpg[];
+extern const char datatoc_mc01_jpg[];
extern int datatoc_mc02_jpg_size;
-extern char datatoc_mc02_jpg[];
+extern const char datatoc_mc02_jpg[];
extern int datatoc_mc03_jpg_size;
-extern char datatoc_mc03_jpg[];
+extern const char datatoc_mc03_jpg[];
extern int datatoc_mc04_jpg_size;
-extern char datatoc_mc04_jpg[];
+extern const char datatoc_mc04_jpg[];
extern int datatoc_mc05_jpg_size;
-extern char datatoc_mc05_jpg[];
+extern const char datatoc_mc05_jpg[];
extern int datatoc_mc06_jpg_size;
-extern char datatoc_mc06_jpg[];
+extern const char datatoc_mc06_jpg[];
extern int datatoc_mc07_jpg_size;
-extern char datatoc_mc07_jpg[];
+extern const char datatoc_mc07_jpg[];
extern int datatoc_mc08_jpg_size;
-extern char datatoc_mc08_jpg[];
+extern const char datatoc_mc08_jpg[];
extern int datatoc_mc09_jpg_size;
-extern char datatoc_mc09_jpg[];
+extern const char datatoc_mc09_jpg[];
extern int datatoc_mc10_jpg_size;
-extern char datatoc_mc10_jpg[];
+extern const char datatoc_mc10_jpg[];
extern int datatoc_mc11_jpg_size;
-extern char datatoc_mc11_jpg[];
+extern const char datatoc_mc11_jpg[];
extern int datatoc_mc12_jpg_size;
-extern char datatoc_mc12_jpg[];
+extern const char datatoc_mc12_jpg[];
extern int datatoc_mc13_jpg_size;
-extern char datatoc_mc13_jpg[];
+extern const char datatoc_mc13_jpg[];
extern int datatoc_mc14_jpg_size;
-extern char datatoc_mc14_jpg[];
+extern const char datatoc_mc14_jpg[];
extern int datatoc_mc15_jpg_size;
-extern char datatoc_mc15_jpg[];
+extern const char datatoc_mc15_jpg[];
extern int datatoc_mc16_jpg_size;
-extern char datatoc_mc16_jpg[];
+extern const char datatoc_mc16_jpg[];
extern int datatoc_mc17_jpg_size;
-extern char datatoc_mc17_jpg[];
+extern const char datatoc_mc17_jpg[];
extern int datatoc_mc18_jpg_size;
-extern char datatoc_mc18_jpg[];
+extern const char datatoc_mc18_jpg[];
extern int datatoc_mc19_jpg_size;
-extern char datatoc_mc19_jpg[];
+extern const char datatoc_mc19_jpg[];
extern int datatoc_mc20_jpg_size;
-extern char datatoc_mc20_jpg[];
+extern const char datatoc_mc20_jpg[];
extern int datatoc_mc21_jpg_size;
-extern char datatoc_mc21_jpg[];
+extern const char datatoc_mc21_jpg[];
extern int datatoc_mc22_jpg_size;
-extern char datatoc_mc22_jpg[];
+extern const char datatoc_mc22_jpg[];
extern int datatoc_mc23_jpg_size;
-extern char datatoc_mc23_jpg[];
+extern const char datatoc_mc23_jpg[];
extern int datatoc_mc24_jpg_size;
-extern char datatoc_mc24_jpg[];
+extern const char datatoc_mc24_jpg[];
/* grease pencil sculpt brushes files */
extern int datatoc_gp_brush_smooth_png_size;
-extern char datatoc_gp_brush_smooth_png[];
+extern const char datatoc_gp_brush_smooth_png[];
extern int datatoc_gp_brush_thickness_png_size;
-extern char datatoc_gp_brush_thickness_png[];
+extern const char datatoc_gp_brush_thickness_png[];
extern int datatoc_gp_brush_strength_png_size;
-extern char datatoc_gp_brush_strength_png[];
+extern const char datatoc_gp_brush_strength_png[];
extern int datatoc_gp_brush_grab_png_size;
-extern char datatoc_gp_brush_grab_png[];
+extern const char datatoc_gp_brush_grab_png[];
extern int datatoc_gp_brush_push_png_size;
-extern char datatoc_gp_brush_push_png[];
+extern const char datatoc_gp_brush_push_png[];
extern int datatoc_gp_brush_twist_png_size;
-extern char datatoc_gp_brush_twist_png[];
+extern const char datatoc_gp_brush_twist_png[];
extern int datatoc_gp_brush_pinch_png_size;
-extern char datatoc_gp_brush_pinch_png[];
+extern const char datatoc_gp_brush_pinch_png[];
extern int datatoc_gp_brush_randomize_png_size;
-extern char datatoc_gp_brush_randomize_png[];
+extern const char datatoc_gp_brush_randomize_png[];
extern int datatoc_gp_brush_clone_png_size;
-extern char datatoc_gp_brush_clone_png[];
+extern const char datatoc_gp_brush_clone_png[];
extern int datatoc_gp_brush_weight_png_size;
-extern char datatoc_gp_brush_weight_png[];
+extern const char datatoc_gp_brush_weight_png[];
extern int datatoc_gp_brush_pencil_png_size;
-extern char datatoc_gp_brush_pencil_png[];
+extern const char datatoc_gp_brush_pencil_png[];
extern int datatoc_gp_brush_pen_png_size;
-extern char datatoc_gp_brush_pen_png[];
+extern const char datatoc_gp_brush_pen_png[];
extern int datatoc_gp_brush_ink_png_size;
-extern char datatoc_gp_brush_ink_png[];
+extern const char datatoc_gp_brush_ink_png[];
extern int datatoc_gp_brush_inknoise_png_size;
-extern char datatoc_gp_brush_inknoise_png[];
+extern const char datatoc_gp_brush_inknoise_png[];
extern int datatoc_gp_brush_block_png_size;
-extern char datatoc_gp_brush_block_png[];
+extern const char datatoc_gp_brush_block_png[];
extern int datatoc_gp_brush_marker_png_size;
-extern char datatoc_gp_brush_marker_png[];
+extern const char datatoc_gp_brush_marker_png[];
extern int datatoc_gp_brush_fill_png_size;
-extern char datatoc_gp_brush_fill_png[];
+extern const char datatoc_gp_brush_fill_png[];
extern int datatoc_gp_brush_airbrush_png_size;
-extern char datatoc_gp_brush_airbrush_png[];
+extern const char datatoc_gp_brush_airbrush_png[];
extern int datatoc_gp_brush_chisel_png_size;
-extern char datatoc_gp_brush_chisel_png[];
+extern const char datatoc_gp_brush_chisel_png[];
extern int datatoc_gp_brush_erase_soft_png_size;
-extern char datatoc_gp_brush_erase_soft_png[];
+extern const char datatoc_gp_brush_erase_soft_png[];
extern int datatoc_gp_brush_erase_hard_png_size;
-extern char datatoc_gp_brush_erase_hard_png[];
+extern const char datatoc_gp_brush_erase_hard_png[];
extern int datatoc_gp_brush_erase_stroke_png_size;
-extern char datatoc_gp_brush_erase_stroke_png[];
+extern const char datatoc_gp_brush_erase_stroke_png[];
#ifdef __cplusplus
}
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index 8118e3c6c69..e57e2316d93 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -66,7 +66,7 @@ typedef struct FileAttributeColumn {
} FileAttributeColumn;
typedef struct FileLayout {
- /* view settings - XXX - move into own struct */
+ /* view settings - XXX: move into own struct. */
int offset_top;
/* Height of the header for the different FileAttributeColumn's. */
int attribute_column_header_h;
@@ -136,13 +136,9 @@ void ED_fileselect_layout_tilepos(FileLayout *layout, int tile, int *x, int *y);
void ED_operatormacros_file(void);
-void ED_fileselect_clear(struct wmWindowManager *wm,
- struct Scene *owner_scene,
- struct SpaceFile *sfile);
+void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile);
-void ED_fileselect_exit(struct wmWindowManager *wm,
- struct Scene *owner_scene,
- struct SpaceFile *sfile);
+void ED_fileselect_exit(struct wmWindowManager *wm, struct SpaceFile *sfile);
bool ED_fileselect_is_asset_browser(const struct SpaceFile *sfile);
struct ID *ED_fileselect_active_asset_get(const struct SpaceFile *sfile);
@@ -166,7 +162,7 @@ int ED_file_icon(const struct FileDirEntry *file);
void ED_file_read_bookmarks(void);
-void ED_file_change_dir_ex(struct bContext *C, struct bScreen *screen, struct ScrArea *area);
+void ED_file_change_dir_ex(struct bContext *C, struct ScrArea *area);
void ED_file_change_dir(struct bContext *C);
void ED_file_path_button(struct bScreen *screen,
diff --git a/source/blender/editors/include/ED_gizmo_library.h b/source/blender/editors/include/ED_gizmo_library.h
index 571519e52f7..357d5e10fa7 100644
--- a/source/blender/editors/include/ED_gizmo_library.h
+++ b/source/blender/editors/include/ED_gizmo_library.h
@@ -275,7 +275,7 @@ void ED_gizmotypes_snap_3d_flag_clear(struct wmGizmo *gz, eSnapGizmo flag);
bool ED_gizmotypes_snap_3d_flag_test(struct wmGizmo *gz, eSnapGizmo flag);
bool ED_gizmotypes_snap_3d_invert_snap_get(struct wmGizmo *gz);
-bool ED_gizmotypes_snap_3d_is_enabled(struct wmGizmo *gz);
+bool ED_gizmotypes_snap_3d_is_enabled(const struct wmGizmo *gz);
short ED_gizmotypes_snap_3d_update(struct wmGizmo *gz,
struct Depsgraph *depsgraph,
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index bad080e1609..8a8d91a570c 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -189,7 +189,7 @@ bool ED_gpencil_layer_frames_looper(struct bGPDlayer *gpl,
bool (*gpf_cb)(struct bGPDframe *, struct Scene *));
void ED_gpencil_layer_make_cfra_list(struct bGPDlayer *gpl, ListBase *elems, bool onlysel);
-bool ED_gpencil_layer_frame_select_check(struct bGPDlayer *gpl);
+bool ED_gpencil_layer_frame_select_check(const struct bGPDlayer *gpl);
void ED_gpencil_layer_frame_select_set(struct bGPDlayer *gpl, short mode);
void ED_gpencil_layer_frames_select_box(struct bGPDlayer *gpl,
float min,
@@ -251,6 +251,13 @@ void ED_gpencil_brush_draw_eraser(struct Brush *brush, int x, int y);
/* ----------- Add Primitive Utilities -------------- */
+/* Number of values defining each point in the built-in data buffers for primitives. */
+#define GP_PRIM_DATABUF_SIZE 5
+void ED_gpencil_stroke_init_data(struct bGPDstroke *gps,
+ const float *array,
+ const int totpoints,
+ const float mat[4][4]);
+
void ED_gpencil_create_blank(struct bContext *C, struct Object *ob, float mat[4][4]);
void ED_gpencil_create_monkey(struct bContext *C, struct Object *ob, float mat[4][4]);
void ED_gpencil_create_stroke(struct bContext *C, struct Object *ob, float mat[4][4]);
@@ -364,23 +371,23 @@ void ED_gpencil_init_random_settings(struct Brush *brush,
const int mval[2],
struct GpRandomSettings *random_settings);
-bool ED_gpencil_stroke_check_collision(struct GP_SpaceConversion *gsc,
+bool ED_gpencil_stroke_check_collision(const struct GP_SpaceConversion *gsc,
struct bGPDstroke *gps,
const float mouse[2],
const int radius,
const float diff_mat[4][4]);
-bool ED_gpencil_stroke_point_is_inside(struct bGPDstroke *gps,
- struct GP_SpaceConversion *gsc,
- int mouse[2],
+bool ED_gpencil_stroke_point_is_inside(const struct bGPDstroke *gps,
+ const struct GP_SpaceConversion *gsc,
+ const int mouse[2],
const float diff_mat[4][4]);
-void ED_gpencil_projected_2d_bound_box(struct GP_SpaceConversion *gsc,
- struct bGPDstroke *gps,
+void ED_gpencil_projected_2d_bound_box(const struct GP_SpaceConversion *gsc,
+ const struct bGPDstroke *gps,
const float diff_mat[4][4],
float r_min[2],
float r_max[2]);
struct bGPDstroke *ED_gpencil_stroke_nearest_to_ends(struct bContext *C,
- struct GP_SpaceConversion *gsc,
+ const struct GP_SpaceConversion *gsc,
struct bGPDlayer *gpl,
struct bGPDframe *gpf,
struct bGPDstroke *gps,
diff --git a/source/blender/editors/include/ED_info.h b/source/blender/editors/include/ED_info.h
index 9ac6b6c1085..dde26c072d0 100644
--- a/source/blender/editors/include/ED_info.h
+++ b/source/blender/editors/include/ED_info.h
@@ -27,9 +27,10 @@ extern "C" {
#endif
struct Main;
+struct wmWindowManager;
/* info_stats.c */
-void ED_info_stats_clear(struct ViewLayer *view_layer);
+void ED_info_stats_clear(struct wmWindowManager *wm, struct ViewLayer *view_layer);
const char *ED_info_statusbar_string(struct Main *bmain,
struct Scene *scene,
struct ViewLayer *view_layer);
@@ -41,6 +42,7 @@ const char *ED_info_statistics_string(struct Main *bmain,
void ED_info_draw_stats(struct Main *bmain,
struct Scene *scene,
struct ViewLayer *view_layer,
+ struct View3D *v3d_local,
int x,
int *y,
int height);
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index cf90a21f799..e29ff3ed890 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -160,7 +160,7 @@ typedef struct KeyframeEditData {
/* generic properties/data access */
/** temp list for storing custom list of data to check */
ListBase list;
- /** pointer to current scene - many tools need access to cfra/etc. */
+ /** pointer to current scene - many tools need access to cfra/etc. */
struct Scene *scene;
/** pointer to custom data - usually 'Object' but also 'rectf', but could be other types too */
void *data;
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index 179c9d5b30d..673f629d6ef 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -434,7 +434,7 @@ void ANIM_copy_as_driver(struct ID *target_id, const char *target_path, const ch
/* check if auto-keyframing is enabled (per scene takes precedence) */
#define IS_AUTOKEY_ON(scene) \
((scene) ? ((scene)->toolsettings->autokey_mode & AUTOKEY_ON) : (U.autokey_mode & AUTOKEY_ON))
-/* check the mode for auto-keyframing (per scene takes precedence) */
+/* Check the mode for auto-keyframing (per scene takes precedence). */
#define IS_AUTOKEY_MODE(scene, mode) \
((scene) ? ((scene)->toolsettings->autokey_mode == AUTOKEY_MODE_##mode) : \
(U.autokey_mode == AUTOKEY_MODE_##mode))
@@ -452,7 +452,7 @@ bool autokeyframe_cfra_can_key(const struct Scene *scene, struct ID *id);
/* Lesser Keyframe Checking API call:
* - Used for the buttons to check for keyframes...
*/
-bool fcurve_frame_has_keyframe(struct FCurve *fcu, float frame, short filter);
+bool fcurve_frame_has_keyframe(const struct FCurve *fcu, float frame, short filter);
/* Lesser Keyframe Checking API call:
* - Returns whether the current value of a given property differs from the interpolated value.
@@ -468,7 +468,7 @@ bool fcurve_is_changed(struct PointerRNA ptr,
* Checks whether a keyframe exists for the given ID-block one the given frame.
* - It is recommended to call this method over the other keyframe-checkers directly,
* in case some detail of the implementation changes...
- * - frame: the value of this is quite often result of #BKE_scene_frame_get()
+ * - frame: the value of this is quite often result of #BKE_scene_ctime_get()
*/
bool id_frame_has_keyframe(struct ID *id, float frame, short filter);
diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h
index 247911bdc55..c2fdbc160de 100644
--- a/source/blender/editors/include/ED_mask.h
+++ b/source/blender/editors/include/ED_mask.h
@@ -100,7 +100,7 @@ bool ED_masklayer_frames_looper(struct MaskLayer *mask_layer,
struct Scene *));
void ED_masklayer_make_cfra_list(struct MaskLayer *mask_layer, ListBase *elems, bool onlysel);
-bool ED_masklayer_frame_select_check(struct MaskLayer *mask_layer);
+bool ED_masklayer_frame_select_check(const struct MaskLayer *mask_layer);
void ED_masklayer_frame_select_set(struct MaskLayer *mask_layer, short mode);
void ED_masklayer_frames_select_box(struct MaskLayer *mask_layer,
float min,
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index b8e9f6e8871..2b73194afb2 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -27,6 +27,8 @@
extern "C" {
#endif
+#include "BLI_compiler_attrs.h"
+
struct ARegion;
struct BMBVHTree;
struct BMEdge;
@@ -36,6 +38,7 @@ struct BMFace;
struct BMLoop;
struct BMVert;
struct BMesh;
+struct BMeshNormalsUpdate_Params;
struct Base;
struct Depsgraph;
struct ID;
@@ -76,19 +79,21 @@ struct BMFace *EDBM_verts_mirror_get_face(struct BMEditMesh *em, struct BMFace *
void EDBM_verts_mirror_cache_clear(struct BMEditMesh *em, struct BMVert *v);
void EDBM_verts_mirror_cache_end(struct BMEditMesh *em);
+void EDBM_mesh_normals_update_ex(struct BMEditMesh *em,
+ const struct BMeshNormalsUpdate_Params *params);
void EDBM_mesh_normals_update(struct BMEditMesh *em);
void EDBM_mesh_clear(struct BMEditMesh *em);
void EDBM_selectmode_to_scene(struct bContext *C);
void EDBM_mesh_make(struct Object *ob, const int select_mode, const bool add_key_index);
-void EDBM_mesh_free(struct BMEditMesh *em);
+void EDBM_mesh_free_data(struct BMEditMesh *em);
void EDBM_mesh_load_ex(struct Main *bmain, struct Object *ob, bool free_data);
void EDBM_mesh_load(struct Main *bmain, struct Object *ob);
/* flushes based on the current select mode. if in vertex select mode,
* verts select/deselect edges and faces, if in edge select mode,
* edges select/deselect faces and vertices, and in face select mode faces select/deselect
- * edges and vertices.*/
+ * edges and vertices. */
void EDBM_select_more(struct BMEditMesh *em, const bool use_face_step);
void EDBM_select_less(struct BMEditMesh *em, const bool use_face_step);
@@ -103,7 +108,14 @@ bool EDBM_vert_color_check(struct BMEditMesh *em);
bool EDBM_mesh_hide(struct BMEditMesh *em, bool swap);
bool EDBM_mesh_reveal(struct BMEditMesh *em, bool select);
-void EDBM_update_generic(struct Mesh *me, const bool do_tessellation, const bool is_destructive);
+struct EDBMUpdate_Params {
+ uint calc_looptri : 1;
+ uint calc_normals : 1;
+ uint is_destructive : 1;
+};
+
+void EDBM_update(struct Mesh *me, const struct EDBMUpdate_Params *params);
+void EDBM_update_extern(struct Mesh *me, const bool do_tessellation, const bool is_destructive);
struct UvElementMap *BM_uv_element_map_create(struct BMesh *bm,
const struct Scene *scene,
@@ -445,12 +457,14 @@ typedef struct BMBackup {
struct BMesh *bmcopy;
} BMBackup;
-/* save a copy of the bmesh for restoring later */
struct BMBackup EDBM_redo_state_store(struct BMEditMesh *em);
/* restore a bmesh from backup */
-void EDBM_redo_state_restore(struct BMBackup, struct BMEditMesh *em, int recalctess);
-/* delete the backup, optionally flushing it to an editmesh */
-void EDBM_redo_state_free(struct BMBackup *, struct BMEditMesh *em, int recalctess);
+void EDBM_redo_state_restore(struct BMBackup *backup, struct BMEditMesh *em, bool recalc_looptri)
+ ATTR_NONNULL(1, 2);
+void EDBM_redo_state_restore_and_free(struct BMBackup *backup,
+ struct BMEditMesh *em,
+ bool recalc_looptri) ATTR_NONNULL(1, 2);
+void EDBM_redo_state_free(struct BMBackup *backup) ATTR_NONNULL(1);
/* *** meshtools.c *** */
int ED_mesh_join_objects_exec(struct bContext *C, struct wmOperator *op);
@@ -471,9 +485,8 @@ int ED_mesh_mirror_spatial_table_lookup(struct Object *ob,
void ED_mesh_mirror_topo_table_begin(struct Object *ob, struct Mesh *me_eval);
void ED_mesh_mirror_topo_table_end(struct Object *ob);
-/* retrieves mirrored cache vert, or NULL if there isn't one.
- * note: calling this without ensuring the mirror cache state
- * is bad.*/
+/* Retrieves mirrored cache vert, or NULL if there isn't one.
+ * NOTE: calling this without ensuring the mirror cache state is bad. */
int mesh_get_x_mirror_vert(struct Object *ob,
struct Mesh *me_eval,
int index,
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index 67a50b83bd6..058d4fa91a3 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -40,6 +40,7 @@ struct bNodeSocketType;
struct bNodeTree;
struct bNodeTreeType;
struct bNodeType;
+struct SpaceNode;
typedef enum {
NODE_TOP = 1,
@@ -49,6 +50,11 @@ typedef enum {
} NodeBorder;
#define NODE_GRID_STEPS 5
+#define NODE_EDGE_PAN_INSIDE_PAD 2
+#define NODE_EDGE_PAN_OUTSIDE_PAD 0 /* Disable clamping for node panning, use whole screen. */
+#define NODE_EDGE_PAN_SPEED_RAMP 1
+#define NODE_EDGE_PAN_MAX_SPEED 40 /* In UI units per second, slower than default. */
+#define NODE_EDGE_PAN_DELAY 1.0f
/* space_node.c */
@@ -105,10 +111,11 @@ bool ED_node_is_geometry(struct SpaceNode *snode);
void ED_node_shader_default(const struct bContext *C, struct ID *id);
void ED_node_composit_default(const struct bContext *C, struct Scene *scene);
void ED_node_texture_default(const struct bContext *C, struct Tex *tex);
-bool ED_node_select_check(ListBase *lb);
+bool ED_node_select_check(const ListBase *lb);
void ED_node_select_all(ListBase *lb, int action);
void ED_node_post_apply_transform(struct bContext *C, struct bNodeTree *ntree);
void ED_node_set_active(struct Main *bmain,
+ struct SpaceNode *snode,
struct bNodeTree *ntree,
struct bNode *node,
bool *r_active_texture_changed);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 6f88ab4253a..888dcd9d428 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -62,7 +62,8 @@ struct Object *ED_object_active_context(const struct bContext *C);
void ED_collection_hide_menu_draw(const struct bContext *C, struct uiLayout *layout);
Object **ED_object_array_in_mode_or_selected(struct bContext *C,
- bool (*filter_fn)(struct Object *ob, void *user_data),
+ bool (*filter_fn)(const struct Object *ob,
+ void *user_data),
void *filter_user_data,
uint *r_objects_len);
@@ -295,12 +296,12 @@ void ED_object_add_mesh_props(struct wmOperatorType *ot);
bool ED_object_add_generic_get_opts(struct bContext *C,
struct wmOperator *op,
const char view_align_axis,
- float loc[3],
- float rot[3],
- float scale[3],
- bool *enter_editmode,
- unsigned short *local_view_bits,
- bool *is_view_aligned);
+ float r_loc[3],
+ float r_rot[3],
+ float r_scale[3],
+ bool *r_enter_editmode,
+ unsigned short *r_local_view_bits,
+ bool *r_is_view_aligned);
struct Object *ED_object_add_type_with_obdata(struct bContext *C,
const int type,
@@ -387,7 +388,7 @@ void ED_object_mode_generic_exit(struct Main *bmain,
struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob);
-bool ED_object_mode_generic_has_data(struct Depsgraph *depsgraph, struct Object *ob);
+bool ED_object_mode_generic_has_data(struct Depsgraph *depsgraph, const struct Object *ob);
void ED_object_posemode_set_for_weight_paint(struct bContext *C,
struct Main *bmain,
diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h
index e84298bd9c2..6d0172e724a 100644
--- a/source/blender/editors/include/ED_particle.h
+++ b/source/blender/editors/include/ED_particle.h
@@ -34,6 +34,7 @@ struct ParticleSystem;
struct Scene;
struct UndoType;
struct ViewLayer;
+struct wmGenericUserData;
struct bContext;
struct rcti;
@@ -68,7 +69,11 @@ void PE_update_object(struct Depsgraph *depsgraph,
bool PE_mouse_particles(
struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
bool PE_box_select(struct bContext *C, const struct rcti *rect, const int sel_op);
-bool PE_circle_select(struct bContext *C, const int sel_op, const int mval[2], float rad);
+bool PE_circle_select(struct bContext *C,
+ struct wmGenericUserData *wm_userdata,
+ const int sel_op,
+ const int mval[2],
+ float rad);
int PE_lasso_select(struct bContext *C,
const int mcoords[][2],
const int mcoords_len,
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index bdd7ec571dc..823050b46f7 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -215,7 +215,7 @@ void ED_screen_restore_temp_type(struct bContext *C, ScrArea *area);
ScrArea *ED_screen_full_newspace(struct bContext *C, ScrArea *area, int type);
void ED_screen_full_prevspace(struct bContext *C, ScrArea *area);
void ED_screen_full_restore(struct bContext *C, ScrArea *area);
-ScrArea *ED_screen_state_maximized_create(struct bContext *C);
+bScreen *ED_screen_state_maximized_create(struct bContext *C);
struct ScrArea *ED_screen_state_toggle(struct bContext *C,
struct wmWindow *win,
struct ScrArea *area,
@@ -317,6 +317,7 @@ bool ED_operator_animview_active(struct bContext *C);
bool ED_operator_outliner_active(struct bContext *C);
bool ED_operator_outliner_active_no_editobject(struct bContext *C);
bool ED_operator_file_active(struct bContext *C);
+bool ED_operator_spreadsheet_active(struct bContext *C);
bool ED_operator_action_active(struct bContext *C);
bool ED_operator_buttons_active(struct bContext *C);
bool ED_operator_node_active(struct bContext *C);
@@ -354,6 +355,7 @@ bool ED_operator_uvedit(struct bContext *C);
bool ED_operator_uvedit_space_image(struct bContext *C);
bool ED_operator_uvmap(struct bContext *C);
bool ED_operator_posemode_exclusive(struct bContext *C);
+bool ED_operator_object_active_local_editable_posemode_exclusive(struct bContext *C);
bool ED_operator_posemode_context(struct bContext *C);
bool ED_operator_posemode(struct bContext *C);
bool ED_operator_posemode_local(struct bContext *C);
diff --git a/source/blender/editors/include/ED_sequencer.h b/source/blender/editors/include/ED_sequencer.h
index 11eff2d583b..606b4c9cad0 100644
--- a/source/blender/editors/include/ED_sequencer.h
+++ b/source/blender/editors/include/ED_sequencer.h
@@ -42,6 +42,8 @@ bool ED_space_sequencer_maskedit_poll(struct bContext *C);
bool ED_space_sequencer_check_show_imbuf(struct SpaceSeq *sseq);
bool ED_space_sequencer_check_show_strip(struct SpaceSeq *sseq);
+bool ED_space_sequencer_has_playback_animation(const struct SpaceSeq *sseq,
+ const struct Scene *scene);
void ED_operatormacros_sequencer(void);
diff --git a/source/blender/editors/include/ED_spreadsheet.h b/source/blender/editors/include/ED_spreadsheet.h
index 3a07b1b9d4b..ff77135a51c 100644
--- a/source/blender/editors/include/ED_spreadsheet.h
+++ b/source/blender/editors/include/ED_spreadsheet.h
@@ -21,6 +21,9 @@ struct SpaceSpreadsheet;
struct SpaceNode;
struct ID;
struct bNode;
+struct Main;
+struct bContext;
+struct Object;
#ifdef __cplusplus
extern "C" {
@@ -29,14 +32,25 @@ extern "C" {
struct SpreadsheetContext *ED_spreadsheet_context_new(int type);
void ED_spreadsheet_context_free(struct SpreadsheetContext *context);
void ED_spreadsheet_context_path_clear(struct SpaceSpreadsheet *sspreadsheet);
-void ED_spreadsheet_context_path_update_tag(struct SpaceSpreadsheet *sspreadsheet);
-uint64_t ED_spreadsheet_context_path_hash(struct SpaceSpreadsheet *sspreadsheet);
+bool ED_spreadsheet_context_path_update_tag(struct SpaceSpreadsheet *sspreadsheet);
+uint64_t ED_spreadsheet_context_path_hash(const struct SpaceSpreadsheet *sspreadsheet);
-struct ID *ED_spreadsheet_get_current_id(struct SpaceSpreadsheet *sspreadsheet);
+struct ID *ED_spreadsheet_get_current_id(const struct SpaceSpreadsheet *sspreadsheet);
-void ED_spreadsheet_set_geometry_node_context(struct SpaceSpreadsheet *sspreadsheet,
- struct SpaceNode *snode,
- struct bNode *node);
+void ED_spreadsheet_context_path_set_geometry_node(struct SpaceSpreadsheet *sspreadsheet,
+ struct SpaceNode *snode,
+ struct bNode *node);
+void ED_spreadsheet_context_paths_set_geometry_node(struct Main *bmain,
+ struct SpaceNode *snode,
+ struct bNode *node);
+void ED_spreadsheet_context_path_set_evaluated_object(struct SpaceSpreadsheet *sspreadsheet,
+ struct Object *object);
+
+void ED_spreadsheet_context_path_guess(const struct bContext *C,
+ struct SpaceSpreadsheet *sspreadsheet);
+bool ED_spreadsheet_context_path_is_active(const struct bContext *C,
+ struct SpaceSpreadsheet *sspreadsheet);
+bool ED_spreadsheet_context_path_exists(struct Main *bmain, struct SpaceSpreadsheet *sspreadsheet);
#ifdef __cplusplus
}
diff --git a/source/blender/editors/include/ED_undo.h b/source/blender/editors/include/ED_undo.h
index ed1ec96a13f..059277e1466 100644
--- a/source/blender/editors/include/ED_undo.h
+++ b/source/blender/editors/include/ED_undo.h
@@ -53,7 +53,7 @@ void ED_OT_undo_redo(struct wmOperatorType *ot);
void ED_OT_undo_history(struct wmOperatorType *ot);
int ED_undo_operator_repeat(struct bContext *C, struct wmOperator *op);
-/* convenience since UI callbacks use this mostly*/
+/* Convenience since UI callbacks use this mostly. */
void ED_undo_operator_repeat_cb(struct bContext *C, void *arg_op, void *arg_unused);
void ED_undo_operator_repeat_cb_evt(struct bContext *C, void *arg_op, int arg_unused);
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index 4de97411059..ea3d921f2c5 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -42,6 +42,7 @@ struct SpaceImage;
struct ToolSettings;
struct ViewLayer;
struct bNode;
+struct bNodeTree;
struct wmKeyConfig;
/* uvedit_ops.c */
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 499f28beb60..2c958d282f9 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -90,8 +90,6 @@ typedef struct ViewDepths {
short x, y; /* only for temp use for sub-rects, added to region->winx/y */
float *depths;
double depth_range[2];
-
- bool damaged;
} ViewDepths;
/* Rotate 3D cursor on placement. */
@@ -154,19 +152,20 @@ void ED_view3d_depth_override(struct Depsgraph *depsgraph,
struct View3D *v3d,
struct Object *obact,
eV3DDepthOverrideMode mode,
- bool update_cache);
+ struct ViewDepths **r_depths);
+void ED_view3d_depths_free(ViewDepths *depths);
bool ED_view3d_depth_read_cached(const ViewDepths *vd,
const int mval[2],
int margin,
float *r_depth);
-bool ED_view3d_depth_read_cached_normal(const ViewContext *vc,
+bool ED_view3d_depth_read_cached_normal(const struct ARegion *region,
+ const ViewDepths *depths,
const int mval[2],
float r_normal[3]);
-bool ED_view3d_depth_unproject(const struct ARegion *region,
- const int mval[2],
- const double depth,
- float r_location_world[3]);
-void ED_view3d_depth_tag_update(struct RegionView3D *rv3d);
+bool ED_view3d_depth_unproject_v3(const struct ARegion *region,
+ const int mval[2],
+ const double depth,
+ float r_location_world[3]);
/* Projection */
#define IS_CLIPPED 12000
@@ -196,12 +195,38 @@ typedef enum {
V3D_PROJ_TEST_CLIP_NEAR = (1 << 2),
V3D_PROJ_TEST_CLIP_FAR = (1 << 3),
V3D_PROJ_TEST_CLIP_ZERO = (1 << 4),
+ /**
+ * Clip the contents of the data being iterated over.
+ * Currently this is only used to edges when projecting into screen space.
+ *
+ * Clamp the edge within the viewport limits defined by
+ * #V3D_PROJ_TEST_CLIP_WIN, #V3D_PROJ_TEST_CLIP_NEAR & #V3D_PROJ_TEST_CLIP_FAR.
+ * This resolves the problem of a visible edge having one of it's vertices
+ * behind the viewport. See: T32214.
+ *
+ * This is not default behavior as it may be important for the screen-space location
+ * of an edges vertex to represent that vertices location (instead of a location along the edge).
+ *
+ * \note Perspective views should enable #V3D_PROJ_TEST_CLIP_WIN along with
+ * #V3D_PROJ_TEST_CLIP_NEAR as the near-plane-clipped location of a point
+ * may become very large (even infinite) when projected into screen-space.
+ * Unless that point happens to coincide with the camera's point of view.
+ *
+ * Use #V3D_PROJ_TEST_CLIP_CONTENT_DEFAULT instead of #V3D_PROJ_TEST_CLIP_CONTENT,
+ * to avoid accidentally enabling near clipping without clipping by window bounds.
+ */
+ V3D_PROJ_TEST_CLIP_CONTENT = (1 << 5),
} eV3DProjTest;
#define V3D_PROJ_TEST_CLIP_DEFAULT \
(V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR)
#define V3D_PROJ_TEST_ALL \
- (V3D_PROJ_TEST_CLIP_DEFAULT | V3D_PROJ_TEST_CLIP_FAR | V3D_PROJ_TEST_CLIP_ZERO)
+ (V3D_PROJ_TEST_CLIP_DEFAULT | V3D_PROJ_TEST_CLIP_FAR | V3D_PROJ_TEST_CLIP_ZERO | \
+ V3D_PROJ_TEST_CLIP_CONTENT)
+
+#define V3D_PROJ_TEST_CLIP_CONTENT_DEFAULT \
+ (V3D_PROJ_TEST_CLIP_CONTENT | V3D_PROJ_TEST_CLIP_NEAR | V3D_PROJ_TEST_CLIP_FAR | \
+ V3D_PROJ_TEST_CLIP_WIN)
/* view3d_iterators.c */
@@ -341,6 +366,8 @@ float ED_view3d_pixel_size(const struct RegionView3D *rv3d, const float co[3]);
float ED_view3d_pixel_size_no_ui_scale(const struct RegionView3D *rv3d, const float co[3]);
float ED_view3d_calc_zfac(const struct RegionView3D *rv3d, const float co[3], bool *r_flip);
+float ED_view3d_calc_depth_for_comparison(const struct RegionView3D *rv3d, const float co[3]);
+
bool ED_view3d_clip_segment(const struct RegionView3D *rv3d, float ray_start[3], float ray_end[3]);
bool ED_view3d_win_to_ray_clipped(struct Depsgraph *depsgraph,
const struct ARegion *region,
@@ -404,14 +431,19 @@ bool ED_view3d_win_to_segment_clipped(struct Depsgraph *depsgraph,
float r_ray_end[3],
const bool do_clip);
void ED_view3d_ob_project_mat_get(const struct RegionView3D *v3d,
- struct Object *ob,
+ const struct Object *ob,
float r_pmat[4][4]);
void ED_view3d_ob_project_mat_get_from_obmat(const struct RegionView3D *rv3d,
const float obmat[4][4],
float r_pmat[4][4]);
-void ED_view3d_project(const struct ARegion *region, const float world[3], float r_region_co[3]);
-bool ED_view3d_unproject(
+void ED_view3d_project_v3(const struct ARegion *region,
+ const float world[3],
+ float r_region_co[3]);
+void ED_view3d_project_v2(const struct ARegion *region,
+ const float world[3],
+ float r_region_co[2]);
+bool ED_view3d_unproject_v3(
const struct ARegion *region, float regionx, float regiony, float regionz, float world[3]);
/* end */
@@ -454,7 +486,7 @@ bool ED_view3d_calc_render_border(const struct Scene *scene,
struct ARegion *region,
struct rcti *rect);
-void ED_view3d_clipping_calc_from_boundbox(float clip[6][4],
+void ED_view3d_clipping_calc_from_boundbox(float clip[4][4],
const struct BoundBox *clipbb,
const bool is_flip);
void ED_view3d_clipping_calc(struct BoundBox *bb,
@@ -573,8 +605,8 @@ bool ED_view3d_area_user_region(const struct ScrArea *area,
struct ARegion **r_region);
bool ED_operator_rv3d_user_region_poll(struct bContext *C);
-void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d);
-void ED_view3d_init_mats_rv3d_gl(struct Object *ob, struct RegionView3D *rv3d);
+void ED_view3d_init_mats_rv3d(const struct Object *ob, struct RegionView3D *rv3d);
+void ED_view3d_init_mats_rv3d_gl(const struct Object *ob, struct RegionView3D *rv3d);
#ifdef DEBUG
void ED_view3d_clear_mats_rv3d(struct RegionView3D *rv3d);
void ED_view3d_check_mats_rv3d(struct RegionView3D *rv3d);
@@ -690,7 +722,7 @@ float ED_view3d_grid_scale(const struct Scene *scene,
void ED_view3d_grid_steps(const struct Scene *scene,
struct View3D *v3d,
struct RegionView3D *rv3d,
- float *r_grid_steps);
+ float r_grid_steps[8]);
float ED_view3d_grid_view_scale(struct Scene *scene,
struct View3D *v3d,
struct ARegion *region,
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index f0a4b3c462e..7ccdc49d291 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -21,7 +21,7 @@
* \ingroup editorui
*/
-/* Note: this is included multiple times with different #defines for DEF_ICON. */
+/* NOTE: this is included multiple times with different #defines for DEF_ICON. */
/* Auto define more specific types for places that do not need the distinction. */
#ifndef DEF_ICON_SCENE
@@ -989,7 +989,7 @@ DEF_ICON_VECTOR(COLLECTION_COLOR_06)
DEF_ICON_VECTOR(COLLECTION_COLOR_07)
DEF_ICON_VECTOR(COLLECTION_COLOR_08)
-/* Events */
+/* Events. */
DEF_ICON_COLOR(EVENT_A)
DEF_ICON_COLOR(EVENT_B)
DEF_ICON_COLOR(EVENT_C)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 338b12f7985..802c175492f 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -58,6 +58,7 @@ struct bNodeTree;
struct bScreen;
struct rctf;
struct rcti;
+struct uiBlockInteraction_Handle;
struct uiButSearch;
struct uiFontStyle;
struct uiList;
@@ -129,12 +130,6 @@ enum {
UI_DIR_ALL = UI_DIR_UP | UI_DIR_DOWN | UI_DIR_LEFT | UI_DIR_RIGHT,
};
-#if 0
-/* uiBlock->autofill (not yet used) */
-# define UI_BLOCK_COLLUMNS 1
-# define UI_BLOCK_ROWS 2
-#endif
-
/** #uiBlock.flag (controls) */
enum {
UI_BLOCK_LOOP = 1 << 0,
@@ -251,7 +246,7 @@ enum {
#define UI_PANEL_BOX_STYLE_MARGIN (U.widget_unit * 0.2f)
/* but->drawflag - these flags should only affect how the button is drawn. */
-/* Note: currently, these flags _are not passed_ to the widget's state() or draw() functions
+/* NOTE: currently, these flags *are not passed* to the widget's state() or draw() functions
* (except for the 'align' ones)!
*/
enum {
@@ -290,18 +285,14 @@ enum {
/** Active right part of number button */
UI_BUT_ACTIVE_RIGHT = 1 << 22,
- /* (also used by search buttons to enforce shortcut display for their items). */
- /** Button has shortcut text. */
- UI_BUT_HAS_SHORTCUT = 1 << 23,
-
/** Reverse order of consecutive off/on icons */
- UI_BUT_ICON_REVERSE = 1 << 24,
+ UI_BUT_ICON_REVERSE = 1 << 23,
/** Value is animated, but the current value differs from the animated one. */
- UI_BUT_ANIMATED_CHANGED = 1 << 25,
+ UI_BUT_ANIMATED_CHANGED = 1 << 24,
/* Draw the checkbox buttons inverted. */
- UI_BUT_CHECKBOX_INVERT = 1 << 26,
+ UI_BUT_CHECKBOX_INVERT = 1 << 25,
};
/* scale fixed button widths by this to account for DPI */
@@ -322,8 +313,8 @@ typedef enum {
UI_BUT_POIN_SHORT = 64,
UI_BUT_POIN_INT = 96,
UI_BUT_POIN_FLOAT = 128,
- /* UI_BUT_POIN_FUNCTION = 192, */ /*UNUSED*/
- UI_BUT_POIN_BIT = 256, /* OR'd with a bit index*/
+ // UI_BUT_POIN_FUNCTION = 192, /* UNUSED */
+ UI_BUT_POIN_BIT = 256, /* OR'd with a bit index. */
} eButPointerType;
/* requires (but->poin != NULL) */
@@ -390,6 +381,7 @@ typedef enum {
/** Resize handle (resize uilist). */
UI_BTYPE_GRIP = 57 << 9,
UI_BTYPE_DECORATOR = 58 << 9,
+ UI_BTYPE_DATASETROW = 59 << 9,
} eButType;
#define BUTTYPE (63 << 9)
@@ -507,7 +499,6 @@ typedef void (*uiButSearchUpdateFn)(const struct bContext *C,
const char *str,
uiSearchItems *items,
const bool is_first);
-typedef void (*uiButSearchArgFreeFn)(void *arg);
typedef bool (*uiButSearchContextMenuFn)(struct bContext *C,
void *arg,
void *active,
@@ -520,10 +511,58 @@ typedef struct ARegion *(*uiButSearchTooltipFn)(struct bContext *C,
/* Must return allocated string. */
typedef char *(*uiButToolTipFunc)(struct bContext *C, void *argN, const char *tip);
-typedef int (*uiButPushedStateFunc)(struct bContext *C, void *arg);
+typedef int (*uiButPushedStateFunc)(struct uiBut *but, const void *arg);
typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
+/* -------------------------------------------------------------------- */
+/** \name Custom Interaction
+ *
+ * Sometimes it's useful to create data that remains available
+ * while the user interacts with a button.
+ *
+ * A common case is dragging a number button or slider
+ * however this could be used in other cases too.
+ * \{ */
+
+struct uiBlockInteraction_Params {
+ /**
+ * When true, this interaction is not modal
+ * (user clicking on a number button arrows or pasting a value for example).
+ */
+ bool is_click;
+ /**
+ * Array of unique event ID's (values from #uiBut.retval).
+ * There may be more than one for multi-button editing (see #UI_BUT_DRAG_MULTI).
+ */
+ int *unique_retval_ids;
+ uint unique_retval_ids_len;
+};
+
+/** Returns 'user_data', freed by #uiBlockInteractionEndFn. */
+typedef void *(*uiBlockInteractionBeginFn)(struct bContext *C,
+ const struct uiBlockInteraction_Params *params,
+ void *arg1);
+typedef void (*uiBlockInteractionEndFn)(struct bContext *C,
+ const struct uiBlockInteraction_Params *params,
+ void *arg1,
+ void *user_data);
+typedef void (*uiBlockInteractionUpdateFn)(struct bContext *C,
+ const struct uiBlockInteraction_Params *params,
+ void *arg1,
+ void *user_data);
+
+typedef struct uiBlockInteraction_CallbackData {
+ uiBlockInteractionBeginFn begin_fn;
+ uiBlockInteractionEndFn end_fn;
+ uiBlockInteractionUpdateFn update_fn;
+ void *arg1;
+} uiBlockInteraction_CallbackData;
+
+void UI_block_interaction_set(uiBlock *block, uiBlockInteraction_CallbackData *callbacks);
+
+/** \} */
+
/* Menu Callbacks */
typedef void (*uiMenuCreateFunc)(struct bContext *C, struct uiLayout *layout, void *arg1);
@@ -536,6 +575,8 @@ typedef void (*uiMenuHandleFunc)(struct bContext *C, void *arg, int event);
*/
typedef bool (*uiMenuStepFunc)(struct bContext *C, int direction, void *arg1);
+typedef void (*uiFreeArgFunc)(void *arg);
+
/* interface_query.c */
bool UI_but_has_tooltip_label(const uiBut *but);
bool UI_but_is_tool(const uiBut *but);
@@ -622,11 +663,11 @@ typedef void (*uiBlockCancelFunc)(struct bContext *C, void *arg1);
void UI_popup_block_invoke(struct bContext *C,
uiBlockCreateFunc func,
void *arg,
- void (*arg_free)(void *arg));
+ uiFreeArgFunc arg_free);
void UI_popup_block_invoke_ex(struct bContext *C,
uiBlockCreateFunc func,
void *arg,
- void (*arg_free)(void *arg),
+ uiFreeArgFunc arg_free,
bool can_refresh);
void UI_popup_block_ex(struct bContext *C,
uiBlockCreateFunc func,
@@ -671,7 +712,7 @@ enum {
UI_BLOCK_THEME_STYLE_POPUP = 1,
};
void UI_block_theme_style_set(uiBlock *block, char theme_style);
-char UI_block_emboss_get(uiBlock *block);
+eUIEmbossType UI_block_emboss_get(uiBlock *block);
void UI_block_emboss_set(uiBlock *block, eUIEmbossType emboss);
bool UI_block_is_search_only(const uiBlock *block);
void UI_block_set_search_only(uiBlock *block, bool search_only);
@@ -686,7 +727,7 @@ void UI_block_region_set(uiBlock *block, struct ARegion *region);
void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr);
void UI_block_lock_clear(uiBlock *block);
-/* automatic aligning, horiz or verical */
+/* Automatic aligning, horizontal or vertical. */
void UI_block_align_begin(uiBlock *block);
void UI_block_align_end(uiBlock *block);
@@ -723,6 +764,7 @@ void UI_but_drag_set_asset(uiBut *but,
const char *name,
const char *path,
int id_type,
+ int import_type, /* eFileAssetImportType */
int icon,
struct ImBuf *imb,
float scale);
@@ -1371,7 +1413,7 @@ typedef struct uiStringInfo {
char *strinfo;
} uiStringInfo;
-/* Note: Expects pointers to uiStringInfo structs as parameters.
+/* NOTE: Expects pointers to uiStringInfo structs as parameters.
* Will fill them with translated strings, when possible.
* Strings in uiStringInfo must be MEM_freeN'ed by caller. */
void UI_but_string_info_get(struct bContext *C, uiBut *but, ...) ATTR_SENTINEL(0);
@@ -1601,7 +1643,7 @@ void UI_but_func_search_set(uiBut *but,
uiButSearchUpdateFn search_update_fn,
void *arg,
const bool free_arg,
- uiButSearchArgFreeFn search_arg_free_fn,
+ uiFreeArgFunc search_arg_free_fn,
uiButHandleFunc search_exec_fn,
void *active);
void UI_but_func_search_set_context_menu(uiBut *but, uiButSearchContextMenuFn context_menu_fn);
@@ -1615,6 +1657,13 @@ int UI_searchbox_size_x(void);
/* check if a string is in an existing search box */
int UI_search_items_find_index(uiSearchItems *items, const char *name);
+void UI_but_hint_drawstr_set(uiBut *but, const char *string);
+void UI_but_datasetrow_indentation_set(uiBut *but, int indentation);
+void UI_but_datasetrow_component_set(uiBut *but, uint8_t geometry_component_type);
+void UI_but_datasetrow_domain_set(uiBut *but, uint8_t attribute_domain);
+uint8_t UI_but_datasetrow_component_get(uiBut *but);
+uint8_t UI_but_datasetrow_domain_get(uiBut *but);
+
void UI_but_node_link_set(uiBut *but, struct bNodeSocket *socket, const float draw_color[4]);
void UI_but_number_step_size_set(uiBut *but, float step_size);
@@ -1639,7 +1688,7 @@ void UI_but_func_drawextra_set(
void UI_but_func_menu_step_set(uiBut *but, uiMenuStepFunc func);
-void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *argN);
+void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *arg, uiFreeArgFunc free_arg);
void UI_but_tooltip_refresh(struct bContext *C, uiBut *but);
void UI_but_tooltip_timer_remove(struct bContext *C, uiBut *but);
@@ -1653,7 +1702,7 @@ void UI_but_focus_on_enter_event(struct wmWindow *win, uiBut *but);
void UI_but_func_hold_set(uiBut *but, uiButHandleHoldFunc func, void *argN);
-void UI_but_func_pushed_state_set(uiBut *but, uiButPushedStateFunc func, void *arg);
+void UI_but_func_pushed_state_set(uiBut *but, uiButPushedStateFunc func, const void *arg);
struct PointerRNA *UI_but_extra_operator_icon_add(uiBut *but,
const char *opname,
@@ -2420,12 +2469,20 @@ void uiItemPopoverPanelFromGroup(uiLayout *layout,
void uiItemMenuF(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg);
void uiItemMenuFN(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *argN);
-void uiItemMenuEnumO_ptr(uiLayout *layout,
+void uiItemMenuEnumFullO_ptr(uiLayout *layout,
+ struct bContext *C,
+ struct wmOperatorType *ot,
+ const char *propname,
+ const char *name,
+ int icon,
+ struct PointerRNA *r_opptr);
+void uiItemMenuEnumFullO(uiLayout *layout,
struct bContext *C,
- struct wmOperatorType *ot,
+ const char *opname,
const char *propname,
const char *name,
- int icon);
+ int icon,
+ struct PointerRNA *r_opptr);
void uiItemMenuEnumO(uiLayout *layout,
struct bContext *C,
const char *opname,
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index 64f881052a1..8191a9a9062 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -51,7 +51,7 @@ enum eView2D_CommonViewTypes {
V2D_COMMONVIEW_STANDARD,
/* listview (i.e. Outliner) */
V2D_COMMONVIEW_LIST,
- /* stackview (this is basically a list where new items are added at the top) */
+ /* Stack-view (this is basically a list where new items are added at the top). */
V2D_COMMONVIEW_STACK,
/* headers (this is basically the same as listview, but no y-panning) */
V2D_COMMONVIEW_HEADER,
@@ -105,8 +105,12 @@ struct ScrArea;
struct bContext;
struct bScreen;
struct rctf;
+struct rcti;
+struct wmEvent;
struct wmGizmoGroupType;
struct wmKeyConfig;
+struct wmOperator;
+struct wmOperatorType;
typedef struct View2DScrollers View2DScrollers;
@@ -284,9 +288,80 @@ void UI_view2d_smooth_view(struct bContext *C,
/* Gizmo Types */
/* view2d_gizmo_navigate.c */
-/* Caller passes in own idname. */
+/* Caller passes in own idname. */
void VIEW2D_GGT_navigate_impl(struct wmGizmoGroupType *gzgt, const char *idname);
+/* Edge pan */
+
+/**
+ * Custom-data for view panning operators.
+ */
+typedef struct View2DEdgePanData {
+ /** Screen where view pan was initiated. */
+ struct bScreen *screen;
+ /** Area where view pan was initiated. */
+ struct ScrArea *area;
+ /** Region where view pan was initiated. */
+ struct ARegion *region;
+ /** View2d we're operating in. */
+ struct View2D *v2d;
+
+ /** Inside distance in UI units from the edge of the region within which to start panning. */
+ float inside_pad;
+ /** Outside distance in UI units from the edge of the region at which to stop panning. */
+ float outside_pad;
+ /**
+ * Width of the zone in UI units where speed increases with distance from the edge.
+ * At the end of this zone max speed is reached.
+ */
+ float speed_ramp;
+ /** Maximum speed in UI units per second. */
+ float max_speed;
+ /** Delay in seconds before maximum speed is reached. */
+ float delay;
+
+ /** Amount to move view relative to zoom. */
+ float facx, facy;
+
+ /* Timers. */
+ double edge_pan_last_time;
+ double edge_pan_start_time_x, edge_pan_start_time_y;
+} View2DEdgePanData;
+
+bool UI_view2d_edge_pan_poll(struct bContext *C);
+
+void UI_view2d_edge_pan_init(struct bContext *C,
+ struct View2DEdgePanData *vpd,
+ float inside_pad,
+ float outside_pad,
+ float speed_ramp,
+ float max_speed,
+ float delay);
+
+void UI_view2d_edge_pan_reset(struct View2DEdgePanData *vpd);
+
+/* Apply transform to view (i.e. adjust 'cur' rect). */
+void UI_view2d_edge_pan_apply(struct bContext *C, struct View2DEdgePanData *vpd, int x, int y);
+
+/* Apply transform to view using mouse events. */
+void UI_view2d_edge_pan_apply_event(struct bContext *C,
+ struct View2DEdgePanData *vpd,
+ const struct wmEvent *event);
+
+void UI_view2d_edge_pan_operator_properties(struct wmOperatorType *ot);
+
+void UI_view2d_edge_pan_operator_properties_ex(struct wmOperatorType *ot,
+ float inside_pad,
+ float outside_pad,
+ float speed_ramp,
+ float max_speed,
+ float delay);
+
+/* Initialize panning data with operator settings. */
+void UI_view2d_edge_pan_operator_init(struct bContext *C,
+ struct View2DEdgePanData *vpd,
+ struct wmOperator *op);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index 421019bebb8..2cc3830042c 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -75,6 +75,7 @@ set(SRC
resources.c
view2d.c
view2d_draw.c
+ view2d_edge_pan.c
view2d_gizmo_navigate.c
view2d_ops.c
@@ -101,7 +102,7 @@ if(WITH_PYTHON)
add_definitions(-DWITH_PYTHON)
endif()
-if(WIN32)
+if(WIN32 OR APPLE)
if(WITH_INPUT_IME)
add_definitions(-DWITH_INPUT_IME)
endif()
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index a31efefd99c..32b86119753 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -476,7 +476,7 @@ void ui_block_bounds_calc(uiBlock *block)
static void ui_block_bounds_calc_centered(wmWindow *window, uiBlock *block)
{
- /* note: this is used for the splash where window bounds event has not been
+ /* NOTE: this is used for the splash where window bounds event has not been
* updated by ghost, get the window bounds from ghost directly */
const int xmax = WM_window_pixels_x(window);
@@ -587,7 +587,7 @@ void UI_block_bounds_set_normal(uiBlock *block, int addval)
block->bounds_type = UI_BLOCK_BOUNDS;
}
-/* used for pulldowns */
+/* Used for pull-downs. */
void UI_block_bounds_set_text(uiBlock *block, int addval)
{
block->bounds = addval;
@@ -811,7 +811,8 @@ static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but)
/* Move tooltip from new to old. */
SWAP(uiButToolTipFunc, oldbut->tip_func, but->tip_func);
- SWAP(void *, oldbut->tip_argN, but->tip_argN);
+ SWAP(void *, oldbut->tip_arg, but->tip_arg);
+ SWAP(uiFreeArgFunc, oldbut->tip_arg_free, but->tip_arg_free);
oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy);
oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy);
@@ -822,7 +823,7 @@ static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but)
if (oldbut->type == UI_BTYPE_SEARCH_MENU) {
uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but;
- SWAP(uiButSearchArgFreeFn, search_oldbut->arg_free_fn, search_but->arg_free_fn);
+ SWAP(uiFreeArgFunc, search_oldbut->arg_free_fn, search_but->arg_free_fn);
SWAP(void *, search_oldbut->arg, search_but->arg);
}
@@ -861,7 +862,7 @@ static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but)
SWAP(void *, but->dragpoin, oldbut->dragpoin);
}
- /* note: if layout hasn't been applied yet, it uses old button pointers... */
+ /* NOTE: if layout hasn't been applied yet, it uses old button pointers... */
}
/**
@@ -985,12 +986,12 @@ bool UI_but_active_only(const bContext *C, ARegion *region, uiBlock *block, uiBu
/**
* \warning This must run after other handlers have been added,
- * otherwise the handler wont be removed, see: T71112.
+ * otherwise the handler won't be removed, see: T71112.
*/
bool UI_block_active_only_flagged_buttons(const bContext *C, ARegion *region, uiBlock *block)
{
/* Running this command before end-block has run, means buttons that open menus
- * wont have those menus correctly positioned, see T83539. */
+ * won't have those menus correctly positioned, see T83539. */
BLI_assert(block->endblock);
bool done = false;
@@ -1160,7 +1161,6 @@ void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_str
MEM_freeN(butstr_orig);
but->str = but->strdata;
but->flag |= UI_BUT_HAS_SEP_CHAR;
- but->drawflag |= UI_BUT_HAS_SHORTCUT;
ui_but_update(but);
}
@@ -1199,7 +1199,7 @@ static bool ui_but_event_operator_string_from_menu(const bContext *C,
/* annoying, create a property */
const IDPropertyTemplate val = {0};
- IDProperty *prop_menu = IDP_New(IDP_GROUP, &val, __func__); /* dummy, name is unimportant */
+ IDProperty *prop_menu = IDP_New(IDP_GROUP, &val, __func__); /* Dummy, name is unimportant. */
IDP_AddToGroup(prop_menu, IDP_NewString(mt->idname, "name", sizeof(mt->idname)));
if (WM_key_event_operator_string(
@@ -1224,7 +1224,7 @@ static bool ui_but_event_operator_string_from_panel(const bContext *C,
/* annoying, create a property */
const IDPropertyTemplate val = {0};
- IDProperty *prop_panel = IDP_New(IDP_GROUP, &val, __func__); /* dummy, name is unimportant */
+ IDProperty *prop_panel = IDP_New(IDP_GROUP, &val, __func__); /* Dummy, name is unimportant. */
IDP_AddToGroup(prop_panel, IDP_NewString(pt->idname, "name", sizeof(pt->idname)));
IDP_AddToGroup(prop_panel,
IDP_New(IDP_INT,
@@ -1382,11 +1382,11 @@ static bool ui_but_event_property_operator_string(const bContext *C,
else {
/* special exceptions for common nested data in editors... */
if (RNA_struct_is_a(ptr->type, &RNA_DopeSheet)) {
- /* dopesheet filtering options... */
+ /* Dope-sheet filtering options. */
data_path = BLI_sprintfN("space_data.dopesheet.%s", RNA_property_identifier(prop));
}
else if (RNA_struct_is_a(ptr->type, &RNA_FileSelectParams)) {
- /* Filebrowser options... */
+ /* File-browser options. */
data_path = BLI_sprintfN("space_data.params.%s", RNA_property_identifier(prop));
}
}
@@ -1805,7 +1805,7 @@ void UI_block_update_from_old(const bContext *C, uiBlock *block)
static void ui_but_validate(const uiBut *but)
{
/* Number buttons must have a click-step,
- * assert instead of correcting the value to ensure the caller knows what they're doing. */
+ * assert instead of correcting the value to ensure the caller knows what they're doing. */
if (but->type == UI_BTYPE_NUM) {
uiButNumber *number_but = (uiButNumber *)but;
@@ -1945,8 +1945,8 @@ void ui_fontscale(short *points, float aspect)
if (aspect < 0.9f || aspect > 1.1f) {
float pointsf = *points;
- /* for some reason scaling fonts goes too fast compared to widget size */
- /* XXX not true anymore? (ton) */
+ /* For some reason scaling fonts goes too fast compared to widget size. */
+ /* XXX(ton): not true anymore? */
// aspect = sqrt(aspect);
pointsf /= aspect;
@@ -2106,6 +2106,9 @@ void UI_region_message_subscribe(ARegion *region, struct wmMsgBus *mbus)
int ui_but_is_pushed_ex(uiBut *but, double *value)
{
int is_push = 0;
+ if (but->pushed_state_func) {
+ return but->pushed_state_func(but, but->pushed_state_arg);
+ }
if (but->bit) {
const bool state = !ELEM(
@@ -2254,7 +2257,6 @@ void ui_but_v3_get(uiBut *but, float vec[3])
}
else if (but->pointype == UI_BUT_POIN_CHAR) {
const char *cp = (char *)but->poin;
-
vec[0] = ((float)cp[0]) / 255.0f;
vec[1] = ((float)cp[1]) / 255.0f;
vec[2] = ((float)cp[2]) / 255.0f;
@@ -3138,7 +3140,7 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
return true;
}
else if (str[0] == '#') {
- /* shortcut to create new driver expression (versus immediate Py-execution) */
+ /* Shortcut to create new driver expression (versus immediate Python-execution). */
return ui_but_anim_expression_create(but, str + 1);
}
else {
@@ -3207,27 +3209,25 @@ void ui_but_range_set_hard(uiBut *but)
const PropertyType type = RNA_property_type(but->rnaprop);
- /* clamp button range to something reasonable in case
- * we get -inf/inf from RNA properties */
if (type == PROP_INT) {
int imin, imax;
RNA_property_int_range(&but->rnapoin, but->rnaprop, &imin, &imax);
- but->hardmin = (imin == INT_MIN) ? -1e4 : imin;
- but->hardmax = (imin == INT_MAX) ? 1e4 : imax;
+ but->hardmin = imin;
+ but->hardmax = imax;
}
else if (type == PROP_FLOAT) {
float fmin, fmax;
RNA_property_float_range(&but->rnapoin, but->rnaprop, &fmin, &fmax);
- but->hardmin = (fmin == -FLT_MAX) ? (float)-1e4 : fmin;
- but->hardmax = (fmax == FLT_MAX) ? (float)1e4 : fmax;
+ but->hardmin = fmin;
+ but->hardmax = fmax;
}
}
-/* note: this could be split up into functions which handle arrays and not */
+/* NOTE: this could be split up into functions which handle arrays and not. */
void ui_but_range_set_soft(uiBut *but)
{
- /* ideally we would not limit this but practically, its more than
- * enough worst case is very long vectors wont use a smart soft-range
+ /* Ideally we would not limit this, but practically it's more than
+ * enough. Worst case is very long vectors won't use a smart soft-range,
* which isn't so bad. */
if (but->rnaprop) {
@@ -3246,8 +3246,8 @@ void ui_but_range_set_soft(uiBut *but)
RNA_property_int_ui_range(&but->rnapoin, but->rnaprop, &imin, &imax, &istep);
softmin = (imin == INT_MIN) ? -1e4 : imin;
softmax = (imin == INT_MAX) ? 1e4 : imax;
- /*step = istep;*/ /*UNUSED*/
- /*precision = 1;*/ /*UNUSED*/
+ // step = istep; /* UNUSED */
+ // precision = 1; /* UNUSED */
if (is_array) {
int value_range[2];
@@ -3266,8 +3266,8 @@ void ui_but_range_set_soft(uiBut *but)
RNA_property_float_ui_range(&but->rnapoin, but->rnaprop, &fmin, &fmax, &fstep, &fprecision);
softmin = (fmin == -FLT_MAX) ? (float)-1e4 : fmin;
softmax = (fmax == FLT_MAX) ? (float)1e4 : fmax;
- /*step = fstep;*/ /*UNUSED*/
- /*precision = fprecision;*/ /*UNUSED*/
+ // step = fstep; /* UNUSED */
+ // precision = fprecision; /* UNUSED */
/* Use shared min/max for array values, except for color alpha. */
if (is_array && !(subtype == PROP_COLOR && but->rnaindex == 3)) {
@@ -3359,8 +3359,8 @@ static void ui_but_free(const bContext *C, uiBut *but)
MEM_freeN(but->func_argN);
}
- if (but->tip_argN) {
- MEM_freeN(but->tip_argN);
+ if (but->tip_arg_free) {
+ but->tip_arg_free(but->tip_arg);
}
if (but->hold_argN) {
@@ -3542,7 +3542,7 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, eU
return block;
}
-char UI_block_emboss_get(uiBlock *block)
+eUIEmbossType UI_block_emboss_get(uiBlock *block)
{
return block->emboss;
}
@@ -3581,7 +3581,7 @@ static void ui_but_build_drawstr_float(uiBut *but, double value)
subtype = RNA_property_subtype(but->rnaprop);
}
- /* Change negative zero to regular zero, without altering anything else. */
+ /* Change negative zero to regular zero, without altering anything else. */
value += +0.0f;
if (value == (double)FLT_MAX) {
@@ -3906,6 +3906,10 @@ static void ui_but_alloc_info(const eButType type,
alloc_size = sizeof(uiButCurveProfile);
alloc_str = "uiButCurveProfile";
break;
+ case UI_BTYPE_DATASETROW:
+ alloc_size = sizeof(uiButDatasetRow);
+ alloc_str = "uiButDatasetRow";
+ break;
default:
alloc_size = sizeof(uiBut);
alloc_str = "uiBut";
@@ -4102,7 +4106,7 @@ static uiBut *ui_def_but(uiBlock *block,
UI_BTYPE_BLOCK,
UI_BTYPE_BUT_MENU,
UI_BTYPE_SEARCH_MENU,
- UI_BTYPE_PROGRESS_BAR,
+ UI_BTYPE_DATASETROW,
UI_BTYPE_POPOVER)) {
but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT);
}
@@ -4149,7 +4153,7 @@ static uiBut *ui_def_but(uiBlock *block,
}
#ifdef WITH_PYTHON
- /* if the 'UI_OT_editsource' is running, extract the source info from the button */
+ /* If the 'UI_OT_editsource' is running, extract the source info from the button. */
if (UI_editsource_enable_check()) {
UI_editsource_active_but_test(but);
}
@@ -4187,7 +4191,7 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu
uiPopupBlockHandle *handle = block->handle;
uiBut *but = (uiBut *)but_p;
- /* see comment in ui_item_enum_expand, re: uiname */
+ /* see comment in ui_item_enum_expand, re: `uiname`. */
const EnumPropertyItem *item_array;
UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
@@ -4242,7 +4246,7 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu
uiItemS(layout);
}
- /* note, item_array[...] is reversed on access */
+ /* NOTE: `item_array[...]` is reversed on access. */
/* create items */
uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
@@ -4545,7 +4549,7 @@ static uiBut *ui_def_but_rna(uiBlock *block,
else if (proptype == PROP_STRING) {
min = 0;
max = RNA_property_string_maxlength(prop);
- /* note, 'max' may be zero (code for dynamically resized array) */
+ /* NOTE: 'max' may be zero (code for dynamically resized array). */
}
}
@@ -4592,7 +4596,7 @@ static uiBut *ui_def_but_rna(uiBlock *block,
if (proptype == PROP_POINTER) {
/* If the button shows an ID, automatically set it as focused in context so operators can
- * access it.*/
+ * access it. */
const PointerRNA pptr = RNA_property_pointer_get(ptr, prop);
if (pptr.data && RNA_struct_is_ID(pptr.type)) {
but->context = CTX_store_add(&block->contexts, "id", &pptr);
@@ -6146,6 +6150,7 @@ void UI_but_drag_set_asset(uiBut *but,
const char *name,
const char *path,
int id_type,
+ int import_type,
int icon,
struct ImBuf *imb,
float scale)
@@ -6155,6 +6160,7 @@ void UI_but_drag_set_asset(uiBut *but,
BLI_strncpy(asset_drag->name, name, sizeof(asset_drag->name));
asset_drag->path = path;
asset_drag->id_type = id_type;
+ asset_drag->import_type = import_type;
but->dragtype = WM_DRAG_ASSET;
ui_def_but_icon(but, icon, 0); /* no flag UI_HAS_ICON, so icon doesn't draw in button */
@@ -6328,19 +6334,21 @@ void UI_but_func_menu_step_set(uiBut *but, uiMenuStepFunc func)
but->menu_step_func = func;
}
-void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *argN)
+void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *arg, uiFreeArgFunc free_arg)
{
but->tip_func = func;
- if (but->tip_argN) {
- MEM_freeN(but->tip_argN);
+ if (but->tip_arg_free) {
+ but->tip_arg_free(but->tip_arg);
}
- but->tip_argN = argN;
+ but->tip_arg = arg;
+ but->tip_arg_free = free_arg;
}
-void UI_but_func_pushed_state_set(uiBut *but, uiButPushedStateFunc func, void *arg)
+void UI_but_func_pushed_state_set(uiBut *but, uiButPushedStateFunc func, const void *arg)
{
but->pushed_state_func = func;
but->pushed_state_arg = arg;
+ ui_but_update(but);
}
uiBut *uiDefBlockBut(uiBlock *block,
@@ -6623,7 +6631,7 @@ void UI_but_func_search_set(uiBut *but,
uiButSearchUpdateFn search_update_fn,
void *arg,
const bool free_arg,
- uiButSearchArgFreeFn search_arg_free_fn,
+ uiFreeArgFunc search_arg_free_fn,
uiButHandleFunc search_exec_fn,
void *active)
{
@@ -6748,7 +6756,7 @@ static void operator_enum_search_update_fn(const struct bContext *C,
for (int i = 0; i < filtered_amount; i++) {
const EnumPropertyItem *item = filtered_items[i];
- /* note: need to give the index rather than the
+ /* NOTE: need to give the index rather than the
* identifier because the enum can be freed */
if (!UI_search_item_add(
items, item->name, POINTER_FROM_INT(item->value), item->icon, 0, 0)) {
@@ -6825,6 +6833,55 @@ uiBut *uiDefSearchButO_ptr(uiBlock *block,
return but;
}
+void UI_but_datasetrow_indentation_set(uiBut *but, int indentation)
+{
+ uiButDatasetRow *but_dataset = (uiButDatasetRow *)but;
+ BLI_assert(but->type == UI_BTYPE_DATASETROW);
+
+ but_dataset->indentation = indentation;
+ BLI_assert(indentation >= 0);
+}
+
+/**
+ * Adds a hint to the button which draws right aligned, grayed out and never clipped.
+ */
+void UI_but_hint_drawstr_set(uiBut *but, const char *string)
+{
+ ui_but_add_shortcut(but, string, false);
+}
+
+void UI_but_datasetrow_component_set(uiBut *but, uint8_t geometry_component_type)
+{
+ uiButDatasetRow *but_dataset_row = (uiButDatasetRow *)but;
+ BLI_assert(but->type == UI_BTYPE_DATASETROW);
+
+ but_dataset_row->geometry_component_type = geometry_component_type;
+}
+
+void UI_but_datasetrow_domain_set(uiBut *but, uint8_t attribute_domain)
+{
+ uiButDatasetRow *but_dataset_row = (uiButDatasetRow *)but;
+ BLI_assert(but->type == UI_BTYPE_DATASETROW);
+
+ but_dataset_row->attribute_domain = attribute_domain;
+}
+
+uint8_t UI_but_datasetrow_component_get(uiBut *but)
+{
+ uiButDatasetRow *but_dataset_row = (uiButDatasetRow *)but;
+ BLI_assert(but->type == UI_BTYPE_DATASETROW);
+
+ return but_dataset_row->geometry_component_type;
+}
+
+uint8_t UI_but_datasetrow_domain_get(uiBut *but)
+{
+ uiButDatasetRow *but_dataset_row = (uiButDatasetRow *)but;
+ BLI_assert(but->type == UI_BTYPE_DATASETROW);
+
+ return but_dataset_row->attribute_domain;
+}
+
void UI_but_node_link_set(uiBut *but, bNodeSocket *socket, const float draw_color[4])
{
but->flag |= UI_BUT_NODE_LINK;
@@ -6909,7 +6966,7 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...)
}
else if (type == BUT_GET_TIP) {
if (but->tip_func) {
- tmp = but->tip_func(C, but->tip_argN, but->tip);
+ tmp = but->tip_func(C, but->tip_arg, but->tip);
}
else if (but->tip && but->tip[0]) {
tmp = BLI_strdup(but->tip);
diff --git a/source/blender/editors/interface/interface_align.c b/source/blender/editors/interface/interface_align.c
index 1f9c736a5f3..dbfdfbf7950 100644
--- a/source/blender/editors/interface/interface_align.c
+++ b/source/blender/editors/interface/interface_align.c
@@ -590,7 +590,8 @@ static void ui_block_align_calc_but(uiBut *first, short nr)
/* rows == 0: 1 row, cols == 0: 1 column */
- /* note; how it uses 'flag' in loop below (either set it, or OR it) is confusing */
+ /* NOTE: manipulation of 'flag' in the loop below is confusing.
+ * In some cases it's assigned, other times OR is used. */
for (but = first, prev = NULL; but && but->alignnr == nr; prev = but, but = but->next) {
next = but->next;
if (next && next->alignnr != nr) {
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index b142e383df0..2a7611eabb1 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -417,7 +417,7 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
&um->items, drawstr, but->optype, but->opptr ? but->opptr->data : NULL, but->opcontext);
}
else if (but->rnaprop) {
- /* Note: 'member_id' may be a path. */
+ /* NOTE: 'member_id' may be a path. */
const char *member_id = WM_context_member_from_ptr(C, &but->rnapoin);
const char *data_path = RNA_path_from_ID_to_struct(&but->rnapoin);
const char *member_id_data_path = member_id;
@@ -425,7 +425,7 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
member_id_data_path = BLI_sprintfN("%s.%s", member_id, data_path);
}
const char *prop_id = RNA_property_identifier(but->rnaprop);
- /* Note, ignore 'drawstr', use property idname always. */
+ /* NOTE: ignore 'drawstr', use property idname always. */
ED_screen_user_menu_item_add_prop(&um->items, "", member_id_data_path, prop_id, but->rnaindex);
if (data_path) {
MEM_freeN((void *)data_path);
@@ -560,7 +560,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
const bool is_overridable = (override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE) != 0;
/* Set the (button_pointer, button_prop)
- * and pointer data for Python access to the hovered ui element. */
+ * and pointer data for Python access to the hovered UI element. */
uiLayoutSetContextFromBut(layout, but);
/* Keyframes */
@@ -1280,7 +1280,6 @@ void ui_popup_context_menu_for_panel(bContext *C, ARegion *region, Panel *panel)
uiBlock *block = uiLayoutGetBlock(layout);
uiBut *but = block->buttons.last;
but->flag |= UI_BUT_HAS_SEP_CHAR;
- but->drawflag |= UI_BUT_HAS_SHORTCUT;
}
}
UI_popup_menu_end(C, pup);
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 40cfcaea883..655fdda3069 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -69,8 +69,7 @@ static int roundboxtype = UI_CNR_ALL;
void UI_draw_roundbox_corner_set(int type)
{
/* Not sure the roundbox function is the best place to change this
- * if this is undone, it's not that big a deal, only makes curves edges
- * square for the */
+ * if this is undone, it's not that big a deal, only makes curves edges square. */
roundboxtype = type;
}
@@ -230,7 +229,7 @@ void ui_draw_but_TAB_outline(const rcti *rect,
{0.98, 0.805},
};
- /* mult */
+ /* Multiply. */
for (a = 0; a < 4; a++) {
mul_v2_fl(vec[a], rad);
}
@@ -593,7 +592,7 @@ static void waveform_draw_one(float *waveform, int nbr, const float col[3])
GPU_vertbuf_attr_fill(vbo, pos_id, waveform);
- /* TODO store the GPUBatch inside the scope */
+ /* TODO: store the #GPUBatch inside the scope. */
GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
GPU_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f);
@@ -2224,9 +2223,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
/* ****************************************************** */
-/* TODO: high quality UI drop shadows using GLSL shader and single draw call
- * would replace / modify the following 3 functions - merwin
- */
+/* TODO(merwin): high quality UI drop shadows using GLSL shader and single draw call
+ * would replace / modify the following 3 functions. */
static void ui_shadowbox(const rctf *rect, uint pos, uint color, float shadsize, uchar alpha)
{
@@ -2351,7 +2349,7 @@ void ui_draw_dropshadow(
true, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax - 10.0f + a, rad + a, color);
#endif
/* Compute final visibility to match old method result. */
- /* TODO we could just find a better fit function inside the shader instead of this. */
+ /* TODO: we could just find a better fit function inside the shader instead of this. */
visibility = visibility * (1.0f - calpha);
calpha += dalpha;
}
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index 178f663ff58..b52bfc81b7a 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -130,14 +130,19 @@ void eyedropper_draw_cursor_text_region(const struct bContext *C,
const char *name)
{
wmWindow *win = CTX_wm_window(C);
- const int x = win->eventstate->x - region->winrct.xmin;
- const int y = win->eventstate->y - region->winrct.ymin;
+ const int x = win->eventstate->x;
+ const int y = win->eventstate->y;
if ((name[0] == '\0') || (BLI_rcti_isect_pt(&region->winrct, x, y) == false)) {
return;
}
- eyedropper_draw_cursor_text_ex(x, y, name);
+ const int mval[2] = {
+ x - region->winrct.xmin,
+ y - region->winrct.ymin,
+ };
+
+ eyedropper_draw_cursor_text_ex(mval[0], mval[1], name);
}
/**
diff --git a/source/blender/editors/interface/interface_eyedropper_color.c b/source/blender/editors/interface/interface_eyedropper_color.c
index d5fb0e4e744..ba72cecc514 100644
--- a/source/blender/editors/interface/interface_eyedropper_color.c
+++ b/source/blender/editors/interface/interface_eyedropper_color.c
@@ -118,7 +118,8 @@ static bool eyedropper_init(bContext *C, wmOperator *op)
RNA_property_float_get_array(&eye->ptr, eye->prop, col);
if (eye->ptr.type == &RNA_CompositorNodeCryptomatteV2) {
eye->crypto_node = (bNode *)eye->ptr.data;
- eye->cryptomatte_session = ntreeCompositCryptomatteSession(eye->crypto_node);
+ eye->cryptomatte_session = ntreeCompositCryptomatteSession(CTX_data_scene(C),
+ eye->crypto_node);
eye->draw_handle_sample_text = WM_draw_cb_activate(CTX_wm_window(C), eyedropper_draw_cb, eye);
}
@@ -199,6 +200,57 @@ static bool eyedropper_cryptomatte_sample_renderlayer_fl(RenderLayer *render_lay
return false;
}
+static bool eyedropper_cryptomatte_sample_render_fl(const bNode *node,
+ const char *prefix,
+ const float fpos[2],
+ float r_col[3])
+{
+ bool success = false;
+ Scene *scene = (Scene *)node->id;
+ BLI_assert(GS(scene->id.name) == ID_SCE);
+ Render *re = RE_GetSceneRender(scene);
+
+ if (re) {
+ RenderResult *rr = RE_AcquireResultRead(re);
+ if (rr) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ RenderLayer *render_layer = RE_GetRenderLayer(rr, view_layer->name);
+ success = eyedropper_cryptomatte_sample_renderlayer_fl(render_layer, prefix, fpos, r_col);
+ if (success) {
+ break;
+ }
+ }
+ }
+ RE_ReleaseResult(re);
+ }
+ return success;
+}
+
+static bool eyedropper_cryptomatte_sample_image_fl(const bNode *node,
+ NodeCryptomatte *crypto,
+ const char *prefix,
+ const float fpos[2],
+ float r_col[3])
+{
+ bool success = false;
+ Image *image = (Image *)node->id;
+ BLI_assert((image == NULL) || (GS(image->id.name) == ID_IM));
+ ImageUser *iuser = &crypto->iuser;
+
+ if (image && image->type == IMA_TYPE_MULTILAYER) {
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, NULL);
+ if (image->rr) {
+ LISTBASE_FOREACH (RenderLayer *, render_layer, &image->rr->layers) {
+ success = eyedropper_cryptomatte_sample_renderlayer_fl(render_layer, prefix, fpos, r_col);
+ if (success) {
+ break;
+ }
+ }
+ }
+ BKE_image_release_ibuf(image, ibuf, NULL);
+ }
+ return success;
+}
static bool eyedropper_cryptomatte_sample_fl(
bContext *C, Eyedropper *eye, int mx, int my, float r_col[3])
@@ -255,53 +307,19 @@ static bool eyedropper_cryptomatte_sample_fl(
return false;
}
- bool success = false;
/* TODO(jbakker): Migrate this file to cc and use std::string as return param. */
char prefix[MAX_NAME + 1];
- ntreeCompositCryptomatteLayerPrefix(node, prefix, sizeof(prefix) - 1);
+ const Scene *scene = CTX_data_scene(C);
+ ntreeCompositCryptomatteLayerPrefix(scene, node, prefix, sizeof(prefix) - 1);
prefix[MAX_NAME] = '\0';
if (node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER) {
- Scene *scene = (Scene *)node->id;
- BLI_assert(GS(scene->id.name) == ID_SCE);
- Render *re = RE_GetSceneRender(scene);
-
- if (re) {
- RenderResult *rr = RE_AcquireResultRead(re);
- if (rr) {
- LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
- RenderLayer *render_layer = RE_GetRenderLayer(rr, view_layer->name);
- success = eyedropper_cryptomatte_sample_renderlayer_fl(
- render_layer, prefix, fpos, r_col);
- if (success) {
- break;
- }
- }
- }
- RE_ReleaseResult(re);
- }
+ return eyedropper_cryptomatte_sample_render_fl(node, prefix, fpos, r_col);
}
- else if (node->custom1 == CMP_CRYPTOMATTE_SRC_IMAGE) {
- Image *image = (Image *)node->id;
- BLI_assert(GS(image->id.name) == ID_IM);
- ImageUser *iuser = &crypto->iuser;
-
- if (image && image->type == IMA_TYPE_MULTILAYER) {
- ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, NULL);
- if (image->rr) {
- LISTBASE_FOREACH (RenderLayer *, render_layer, &image->rr->layers) {
- success = eyedropper_cryptomatte_sample_renderlayer_fl(
- render_layer, prefix, fpos, r_col);
- if (success) {
- break;
- }
- }
- }
- BKE_image_release_ibuf(image, ibuf, NULL);
- }
+ if (node->custom1 == CMP_CRYPTOMATTE_SRC_IMAGE) {
+ return eyedropper_cryptomatte_sample_image_fl(node, crypto, prefix, fpos, r_col);
}
-
- return success;
+ return false;
}
/**
diff --git a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c
index f2899fc0098..417807afff1 100644
--- a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c
+++ b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c
@@ -255,7 +255,7 @@ static void eyedropper_gpencil_color_set(bContext *C, const wmEvent *event, Eyed
copy_v3_v3(col_conv, eye->color);
}
- /* Add material or Palette color*/
+ /* Add material or Palette color. */
if (eye->mode == 0) {
eyedropper_add_material(C, col_conv, only_stroke, only_fill, both);
}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 282d470c7ea..3136ca64e0f 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -35,10 +35,12 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "BLI_array_utils.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_rect.h"
+#include "BLI_sort_utils.h"
#include "BLI_string.h"
#include "BLI_string_cursor_utf8.h"
#include "BLI_string_utf8.h"
@@ -170,6 +172,20 @@ static bool ui_but_find_select_in_enum__cmp(const uiBut *but_a, const uiBut *but
static void ui_textedit_string_set(uiBut *but, struct uiHandleButtonData *data, const char *str);
static void button_tooltip_timer_reset(bContext *C, uiBut *but);
+static void ui_block_interaction_begin_ensure(bContext *C,
+ uiBlock *block,
+ struct uiHandleButtonData *data,
+ const bool is_click);
+static struct uiBlockInteraction_Handle *ui_block_interaction_begin(struct bContext *C,
+ uiBlock *block,
+ const bool is_click);
+static void ui_block_interaction_end(struct bContext *C,
+ uiBlockInteraction_CallbackData *callbacks,
+ struct uiBlockInteraction_Handle *interaction);
+static void ui_block_interaction_update(struct bContext *C,
+ uiBlockInteraction_CallbackData *callbacks,
+ struct uiBlockInteraction_Handle *interaction);
+
#ifdef USE_KEYNAV_LIMIT
static void ui_mouse_motion_keynav_init(struct uiKeyNavLock *keynav, const wmEvent *event);
static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEvent *event);
@@ -225,6 +241,19 @@ typedef enum uiMenuScrollType {
MENU_SCROLL_BOTTOM,
} uiMenuScrollType;
+typedef struct uiBlockInteraction_Handle {
+ struct uiBlockInteraction_Params params;
+ void *user_data;
+ /**
+ * This is shared between #uiHandleButtonData and #uiAfterFunc,
+ * the last user runs the end callback and frees the data.
+ *
+ * This is needed as the order of freeing changes depending on
+ * accepting/canceling the operation.
+ */
+ int user_count;
+} uiBlockInteraction_Handle;
+
#ifdef USE_ALLSELECT
/* Unfortunately there's no good way handle more generally:
@@ -273,7 +302,7 @@ static void ui_selectcontext_apply(bContext *C,
/**
* how far to drag before we check for gesture direction (in pixels),
- * note: half the height of a button is about right... */
+ * NOTE: half the height of a button is about right... */
# define DRAG_MULTINUM_THRESHOLD_DRAG_X (UI_UNIT_Y / 4)
/**
@@ -430,6 +459,8 @@ typedef struct uiHandleButtonData {
uiSelectContextStore select_others;
#endif
+ struct uiBlockInteraction_Handle *custom_interaction_handle;
+
/* Text field undo. */
struct uiUndoStack_Text *undo_stack_text;
@@ -469,7 +500,10 @@ typedef struct uiAfterFunc {
PropertyRNA *rnaprop;
void *search_arg;
- uiButSearchArgFreeFn search_arg_free_fn;
+ uiFreeArgFunc search_arg_free_fn;
+
+ uiBlockInteraction_CallbackData custom_interaction_callbacks;
+ uiBlockInteraction_Handle *custom_interaction_handle;
bContextStore *context;
@@ -769,72 +803,95 @@ static bool ui_afterfunc_check(const uiBlock *block, const uiBut *but)
(block->handle && block->handle->popup_op));
}
+/**
+ * These functions are postponed and only executed after all other
+ * handling is done, i.e. menus are closed, in order to avoid conflicts
+ * with these functions removing the buttons we are working with.
+ */
static void ui_apply_but_func(bContext *C, uiBut *but)
{
uiBlock *block = but->block;
+ if (!ui_afterfunc_check(block, but)) {
+ return;
+ }
- /* these functions are postponed and only executed after all other
- * handling is done, i.e. menus are closed, in order to avoid conflicts
- * with these functions removing the buttons we are working with */
-
- if (ui_afterfunc_check(block, but)) {
- uiAfterFunc *after = ui_afterfunc_new();
+ uiAfterFunc *after = ui_afterfunc_new();
- if (but->func && ELEM(but, but->func_arg1, but->func_arg2)) {
- /* exception, this will crash due to removed button otherwise */
- but->func(C, but->func_arg1, but->func_arg2);
- }
- else {
- after->func = but->func;
- }
+ if (but->func && ELEM(but, but->func_arg1, but->func_arg2)) {
+ /* exception, this will crash due to removed button otherwise */
+ but->func(C, but->func_arg1, but->func_arg2);
+ }
+ else {
+ after->func = but->func;
+ }
- after->func_arg1 = but->func_arg1;
- after->func_arg2 = but->func_arg2;
+ after->func_arg1 = but->func_arg1;
+ after->func_arg2 = but->func_arg2;
- after->funcN = but->funcN;
- after->func_argN = (but->func_argN) ? MEM_dupallocN(but->func_argN) : NULL;
+ after->funcN = but->funcN;
+ after->func_argN = (but->func_argN) ? MEM_dupallocN(but->func_argN) : NULL;
- after->rename_func = but->rename_func;
- after->rename_arg1 = but->rename_arg1;
- after->rename_orig = but->rename_orig; /* needs free! */
+ after->rename_func = but->rename_func;
+ after->rename_arg1 = but->rename_arg1;
+ after->rename_orig = but->rename_orig; /* needs free! */
- after->handle_func = block->handle_func;
- after->handle_func_arg = block->handle_func_arg;
- after->retval = but->retval;
+ after->handle_func = block->handle_func;
+ after->handle_func_arg = block->handle_func_arg;
+ after->retval = but->retval;
- if (but->type == UI_BTYPE_BUT_MENU) {
- after->butm_func = block->butm_func;
- after->butm_func_arg = block->butm_func_arg;
- after->a2 = but->a2;
- }
+ if (but->type == UI_BTYPE_BUT_MENU) {
+ after->butm_func = block->butm_func;
+ after->butm_func_arg = block->butm_func_arg;
+ after->a2 = but->a2;
+ }
- if (block->handle) {
- after->popup_op = block->handle->popup_op;
- }
+ if (block->handle) {
+ after->popup_op = block->handle->popup_op;
+ }
- after->optype = but->optype;
- after->opcontext = but->opcontext;
- after->opptr = but->opptr;
+ after->optype = but->optype;
+ after->opcontext = but->opcontext;
+ after->opptr = but->opptr;
- after->rnapoin = but->rnapoin;
- after->rnaprop = but->rnaprop;
+ after->rnapoin = but->rnapoin;
+ after->rnaprop = but->rnaprop;
- if (but->type == UI_BTYPE_SEARCH_MENU) {
- uiButSearch *search_but = (uiButSearch *)but;
- after->search_arg_free_fn = search_but->arg_free_fn;
- after->search_arg = search_but->arg;
- search_but->arg_free_fn = NULL;
- search_but->arg = NULL;
- }
+ if (but->type == UI_BTYPE_SEARCH_MENU) {
+ uiButSearch *search_but = (uiButSearch *)but;
+ after->search_arg_free_fn = search_but->arg_free_fn;
+ after->search_arg = search_but->arg;
+ search_but->arg_free_fn = NULL;
+ search_but->arg = NULL;
+ }
- if (but->context) {
- after->context = CTX_store_copy(but->context);
+ if (but->active != NULL) {
+ uiHandleButtonData *data = but->active;
+ if (data->custom_interaction_handle != NULL) {
+ after->custom_interaction_callbacks = block->custom_interaction_callbacks;
+ after->custom_interaction_handle = data->custom_interaction_handle;
+
+ /* Ensure this callback runs once and last. */
+ uiAfterFunc *after_prev = after->prev;
+ if (after_prev &&
+ (after_prev->custom_interaction_handle == data->custom_interaction_handle)) {
+ after_prev->custom_interaction_handle = NULL;
+ memset(&after_prev->custom_interaction_callbacks,
+ 0x0,
+ sizeof(after_prev->custom_interaction_callbacks));
+ }
+ else {
+ after->custom_interaction_handle->user_count++;
+ }
}
+ }
- but->optype = NULL;
- but->opcontext = 0;
- but->opptr = NULL;
+ if (but->context) {
+ after->context = CTX_store_copy(but->context);
}
+
+ but->optype = NULL;
+ but->opcontext = 0;
+ but->opptr = NULL;
}
/* typically call ui_apply_but_undo(), ui_apply_but_autokey() */
@@ -997,6 +1054,18 @@ static void ui_apply_but_funcs_after(bContext *C)
after.search_arg_free_fn(after.search_arg);
}
+ if (after.custom_interaction_handle != NULL) {
+ after.custom_interaction_handle->user_count--;
+ BLI_assert(after.custom_interaction_handle->user_count >= 0);
+ if (after.custom_interaction_handle->user_count == 0) {
+ ui_block_interaction_update(
+ C, &after.custom_interaction_callbacks, after.custom_interaction_handle);
+ ui_block_interaction_end(
+ C, &after.custom_interaction_callbacks, after.custom_interaction_handle);
+ }
+ after.custom_interaction_handle = NULL;
+ }
+
ui_afterfunc_update_preferences_dirty(&after);
if (after.undostr[0]) {
@@ -1350,7 +1419,7 @@ static void ui_multibut_states_create(uiBut *but_active, uiHandleButtonData *dat
}
/* edit buttons proportionally to eachother
- * note: if we mix buttons which are proportional and others which are not,
+ * NOTE: if we mix buttons which are proportional and others which are not,
* this may work a bit strangely */
if ((but_active->rnaprop && (RNA_property_flag(but_active->rnaprop) & PROP_PROPORTIONAL)) ||
ELEM(but_active->unit_type, RNA_SUBTYPE_UNIT_VALUE(PROP_UNIT_LENGTH))) {
@@ -1461,12 +1530,9 @@ static bool ui_drag_toggle_but_is_supported(const uiBut *but)
/* Button pushed state to compare if other buttons match. Can be more
* then just true or false for toggle buttons with more than 2 states. */
-static int ui_drag_toggle_but_pushed_state(bContext *C, uiBut *but)
+static int ui_drag_toggle_but_pushed_state(uiBut *but)
{
if (but->rnapoin.data == NULL && but->poin == NULL && but->icon) {
- if (but->pushed_state_func) {
- return but->pushed_state_func(C, but->pushed_state_arg);
- }
/* Assume icon identifies a unique state, for buttons that
* work through functions callbacks and don't have an boolean
* value that indicates the state. */
@@ -1505,7 +1571,7 @@ static bool ui_drag_toggle_set_xy_xy(
ui_window_to_block_fl(region, block, &xy_b_block[0], &xy_b_block[1]);
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
- /* Note: ctrl is always true here because (at least for now)
+ /* NOTE: ctrl is always true here because (at least for now)
* we always want to consider text control in this case, even when not embossed. */
if (ui_but_is_interactive(but, true)) {
if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) {
@@ -1513,7 +1579,7 @@ static bool ui_drag_toggle_set_xy_xy(
/* execute the button */
if (ui_drag_toggle_but_is_supported(but)) {
/* is it pressed? */
- const int pushed_state_but = ui_drag_toggle_but_pushed_state(C, but);
+ const int pushed_state_but = ui_drag_toggle_but_pushed_state(but);
if (pushed_state_but != pushed_state) {
UI_but_execute(C, region, but);
if (do_check) {
@@ -1561,7 +1627,7 @@ static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const
};
/* check if this is a different button,
- * chances are high the button wont move about :) */
+ * chances are high the button won't move about :) */
if (len_manhattan_v2v2(drag_info->but_cent_start, but_cent_new) > 1.0f) {
if (fabsf(drag_info->but_cent_start[0] - but_cent_new[0]) <
fabsf(drag_info->but_cent_start[1] - but_cent_new[1])) {
@@ -1689,7 +1755,7 @@ static bool ui_selectcontext_begin(bContext *C, uiBut *but, uiSelectContextStore
break;
}
uiSelectContextElem *other = &selctx_data->elems[i];
- /* TODO,. de-duplicate copy_to_selected_button */
+ /* TODO: de-duplicate copy_to_selected_button. */
if (link->ptr.data != ptr.data) {
if (use_path_from_id) {
/* Path relative to ID. */
@@ -1939,11 +2005,11 @@ static bool ui_but_drag_init(bContext *C,
uiDragToggleHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
ARegion *region_prev;
- /* call here because regular mouse-up event wont run,
+ /* call here because regular mouse-up event won't run,
* typically 'button_activate_exit()' handles this */
ui_apply_but_autokey(C, but);
- drag_info->pushed_state = ui_drag_toggle_but_pushed_state(C, but);
+ drag_info->pushed_state = ui_drag_toggle_but_pushed_state(but);
drag_info->but_cent_start[0] = BLI_rctf_cent_x(&but->rect);
drag_info->but_cent_start[1] = BLI_rctf_cent_y(&but->rect);
copy_v2_v2_int(drag_info->xy_init, &event->x);
@@ -1990,7 +2056,7 @@ static bool ui_but_drag_init(bContext *C,
bool valid = false;
uiDragColorHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
- /* TODO support more button pointer types */
+ /* TODO: support more button pointer types. */
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
ui_but_v3_get(but, drag_info->color);
drag_info->gamma_corrected = true;
@@ -2187,6 +2253,9 @@ static void ui_apply_but(
case UI_BTYPE_LISTROW:
ui_apply_but_ROW(C, block, but, data);
break;
+ case UI_BTYPE_DATASETROW:
+ ui_apply_but_ROW(C, block, but, data);
+ break;
case UI_BTYPE_TAB:
ui_apply_but_TAB(C, but, data);
break;
@@ -2283,6 +2352,11 @@ static void ui_apply_but(
uiButCurveProfile *but_profile = (uiButCurveProfile *)but;
but_profile->edit_profile = editprofile;
}
+
+ if (data->custom_interaction_handle != NULL) {
+ ui_block_interaction_update(
+ C, &block->custom_interaction_callbacks, data->custom_interaction_handle);
+ }
}
/** \} */
@@ -2297,7 +2371,7 @@ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleB
ListBase *drags = event->customdata; /* drop event type has listbase customdata by default */
LISTBASE_FOREACH (wmDrag *, wmd, drags) {
- /* TODO asset dropping. */
+ /* TODO: asset dropping. */
if (wmd->type == WM_DRAG_ID) {
/* align these types with UI_but_active_drop_name */
if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
@@ -2346,16 +2420,16 @@ static int get_but_property_array_length(uiBut *but)
}
static void ui_but_set_float_array(
- bContext *C, uiBut *but, uiHandleButtonData *data, float *values, int array_length)
+ bContext *C, uiBut *but, uiHandleButtonData *data, const float *values, const int values_len)
{
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- for (int i = 0; i < array_length; i++) {
+ for (int i = 0; i < values_len; i++) {
RNA_property_float_set_index(&but->rnapoin, but->rnaprop, i, values[i]);
}
if (data) {
if (but->type == UI_BTYPE_UNITVEC) {
- BLI_assert(array_length == 3);
+ BLI_assert(values_len == 3);
copy_v3_v3(data->vec, values);
}
else {
@@ -2366,56 +2440,39 @@ static void ui_but_set_float_array(
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
-static void float_array_to_string(float *values,
- int array_length,
+static void float_array_to_string(const float *values,
+ const int values_len,
char *output,
int output_len_max)
{
- /* to avoid buffer overflow attacks; numbers are quite arbitrary */
- BLI_assert(output_len_max > 15);
- output_len_max -= 10;
-
- int current_index = 0;
- output[current_index] = '[';
- current_index++;
-
- for (int i = 0; i < array_length; i++) {
- int length = BLI_snprintf(
- output + current_index, output_len_max - current_index, "%f", values[i]);
- current_index += length;
-
- if (i < array_length - 1) {
- if (current_index < output_len_max) {
- output[current_index + 0] = ',';
- output[current_index + 1] = ' ';
- current_index += 2;
- }
- }
+ const int values_end = values_len - 1;
+ int ofs = 0;
+ output[ofs++] = '[';
+ for (int i = 0; i < values_len; i++) {
+ ofs += BLI_snprintf_rlen(
+ output + ofs, output_len_max - ofs, (i != values_end) ? "%f, " : "%f]", values[i]);
}
-
- output[current_index + 0] = ']';
- output[current_index + 1] = '\0';
}
static void ui_but_copy_numeric_array(uiBut *but, char *output, int output_len_max)
{
- const int array_length = get_but_property_array_length(but);
- float *values = alloca(array_length * sizeof(float));
+ const int values_len = get_but_property_array_length(but);
+ float *values = alloca(values_len * sizeof(float));
RNA_property_float_get_array(&but->rnapoin, but->rnaprop, values);
- float_array_to_string(values, array_length, output, output_len_max);
+ float_array_to_string(values, values_len, output, output_len_max);
}
-static bool parse_float_array(char *text, float *values, int expected_length)
+static bool parse_float_array(char *text, float *values, int values_len_expected)
{
/* can parse max 4 floats for now */
- BLI_assert(0 <= expected_length && expected_length <= 4);
+ BLI_assert(0 <= values_len_expected && values_len_expected <= 4);
float v[5];
- const int actual_length = sscanf(
+ const int values_len_actual = sscanf(
text, "[%f, %f, %f, %f, %f]", &v[0], &v[1], &v[2], &v[3], &v[4]);
- if (actual_length == expected_length) {
- memcpy(values, v, sizeof(float) * expected_length);
+ if (values_len_actual == values_len_expected) {
+ memcpy(values, v, sizeof(float) * values_len_expected);
return true;
}
return false;
@@ -2426,16 +2483,16 @@ static void ui_but_paste_numeric_array(bContext *C,
uiHandleButtonData *data,
char *buf_paste)
{
- const int array_length = get_but_property_array_length(but);
- if (array_length > 4) {
+ const int values_len = get_but_property_array_length(but);
+ if (values_len > 4) {
/* not supported for now */
return;
}
- float *values = alloca(sizeof(float) * array_length);
+ float *values = alloca(sizeof(float) * values_len);
- if (parse_float_array(buf_paste, values, array_length)) {
- ui_but_set_float_array(C, but, data, values, array_length);
+ if (parse_float_array(buf_paste, values, values_len)) {
+ ui_but_set_float_array(C, but, data, values, values_len);
}
else {
WM_report(RPT_ERROR, "Expected an array of numbers: [n, n, ...]");
@@ -2445,7 +2502,7 @@ static void ui_but_paste_numeric_array(bContext *C,
static void ui_but_copy_numeric_value(uiBut *but, char *output, int output_len_max)
{
/* Get many decimal places, then strip trailing zeros.
- * note: too high values start to give strange results */
+ * NOTE: too high values start to give strange results. */
ui_but_string_get_ex(but, output, output_len_max, UI_PRECISION_FLOAT_MAX, false, NULL);
BLI_str_rstrip_float_zero(output, '\0');
}
@@ -3085,7 +3142,7 @@ static bool ui_textedit_insert_buf(uiBut *but,
if ((len + step >= data->maxlen) && (data->maxlen - (len + 1) > 0)) {
if (UI_but_is_utf8(but)) {
- /* shorten 'step' to a utf8 aligned size that fits */
+ /* Shorten 'step' to a utf8 aligned size that fits. */
BLI_strnlen_utf8_ex(buf, data->maxlen - (len + 1), &step);
}
else {
@@ -3285,7 +3342,7 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in
}
#ifdef WITH_INPUT_IME
-/* enable ime, and set up uibut ime data */
+/* Enable IME, and setup #uiBut IME data. */
static void ui_textedit_ime_begin(wmWindow *win, uiBut *UNUSED(but))
{
/* XXX Is this really needed? */
@@ -3301,7 +3358,7 @@ static void ui_textedit_ime_begin(wmWindow *win, uiBut *UNUSED(but))
wm_window_IME_begin(win, x, y, 0, 0, true);
}
-/* disable ime, and clear uibut ime data */
+/* Disable IME, and clear #uiBut IME data. */
static void ui_textedit_ime_end(wmWindow *win, uiBut *UNUSED(but))
{
wm_window_IME_end(win);
@@ -3431,7 +3488,7 @@ static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data)
const int strip = BLI_utf8_invalid_strip(but->editstr, strlen(but->editstr));
/* not a file?, strip non utf-8 chars */
if (strip) {
- /* wont happen often so isn't that annoying to keep it here for a while */
+ /* won't happen often so isn't that annoying to keep it here for a while */
printf("%s: invalid utf8 - stripped chars %d\n", __func__, strip);
}
}
@@ -3923,7 +3980,6 @@ static void ui_numedit_begin_set_values(uiBut *but, uiHandleButtonData *data)
data->startvalue = ui_but_value_get(but);
data->origvalue = data->startvalue;
data->value = data->origvalue;
- but->editval = &data->value;
}
static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
@@ -3952,6 +4008,7 @@ static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
}
else {
ui_numedit_begin_set_values(but, data);
+ but->editval = &data->value;
float softmin = but->softmin;
float softmax = but->softmax;
@@ -4301,7 +4358,7 @@ static bool ui_do_but_extra_operator_icon(bContext *C,
button_tooltip_timer_reset(C, but);
ui_but_extra_operator_icon_apply(C, but, op_icon);
- /* Note: 'but', 'data' may now be freed, don't access. */
+ /* NOTE: 'but', 'data' may now be freed, don't access. */
return true;
}
@@ -4351,7 +4408,7 @@ static bool ui_do_but_ANY_drag_toggle(
}
}
else if (data->state == BUTTON_STATE_WAIT_DRAG) {
- /* note: the 'BUTTON_STATE_WAIT_DRAG' part of 'ui_do_but_EXIT' could be refactored into
+ /* NOTE: the 'BUTTON_STATE_WAIT_DRAG' part of 'ui_do_but_EXIT' could be refactored into
* its own function */
data->applied = false;
*r_retval = ui_do_but_EXIT(C, but, data, event);
@@ -4569,7 +4626,7 @@ static int ui_do_but_TEX(
if (ELEM(event->type, EVT_PADENTER, EVT_RETKEY) && (!UI_but_is_utf8(but))) {
/* pass - allow filesel, enter to execute */
}
- else if (but->emboss == UI_EMBOSS_NONE && !event->ctrl) {
+ else if (ELEM(but->emboss, UI_EMBOSS_NONE, UI_EMBOSS_NONE_OR_STATUS) && !event->ctrl) {
/* pass */
}
else {
@@ -4694,7 +4751,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
- /* first handle click on icondrag type button */
+ /* First handle click on icon-drag type button. */
if ((event->type == LEFTMOUSE) && (event->val == KM_PRESS) && but->dragpoin) {
if (ui_but_contains_point_px_icon(but, data->region, event)) {
@@ -4717,7 +4774,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con
if (ELEM(event->type, LEFTMOUSE, EVT_PADENTER, EVT_RETKEY) && event->val == KM_PRESS) {
int ret = WM_UI_HANDLER_BREAK;
- /* XXX (a bit ugly) Special case handling for filebrowser drag button */
+ /* XXX: (a bit ugly) Special case handling for file-browser drag button. */
if (but->dragpoin && but->imb && ui_but_contains_point_px_icon(but, data->region, event)) {
ret = WM_UI_HANDLER_CONTINUE;
}
@@ -4787,7 +4844,7 @@ static float ui_numedit_apply_snapf(
UnitSettings *unit = but->block->unit;
const int unit_type = UI_but_unit_type_get(but);
if ((unit_type == PROP_UNIT_ROTATION) && (unit->system_rotation != USER_UNIT_ROT_RADIANS)) {
- /* pass (degrees)*/
+ /* Pass (degrees). */
}
else {
softrange = 20.0f;
@@ -4869,6 +4926,8 @@ static bool ui_numedit_but_NUM(uiButNumber *number_but,
return changed;
}
+ ui_block_interaction_begin_ensure(but->block->evil_C, but->block, data, false);
+
if (ui_but_is_cursor_warp(but)) {
const float softmin = but->softmin;
const float softmax = but->softmax;
@@ -5379,6 +5438,8 @@ static bool ui_numedit_but_SLI(uiBut *but,
return changed;
}
+ ui_block_interaction_begin_ensure(but->block->evil_C, but->block, data, false);
+
const PropertyScaleType scale_type = ui_but_scale_type(but);
softmin = but->softmin;
@@ -5780,7 +5841,7 @@ static int ui_do_but_GRIP(
int retval = WM_UI_HANDLER_CONTINUE;
const bool horizontal = (BLI_rctf_size_x(&but->rect) < BLI_rctf_size_y(&but->rect));
- /* Note: Having to store org point in window space and recompute it to block "space" each time
+ /* NOTE: Having to store org point in window space and recompute it to block "space" each time
* is not ideal, but this is a way to hack around behavior of ui_window_to_block(), which
* returns different results when the block is inside a panel or not...
* See T37739.
@@ -5853,7 +5914,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
- /* first handle click on icondrag type button */
+ /* First handle click on icon-drag type button. */
if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) {
if (ui_but_contains_point_px_icon(but, data->region, event)) {
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
@@ -5900,7 +5961,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
* wouldn't lead to cancel changes made to this button, but changing state to EXIT also
* makes no button active for a while which leads to triggering operator when doing fast
* scrolling mouse wheel. using post activate stuff from button allows to make button be
- * active again after checking for all all that mouse leave and cancel stuff, so quick
+ * active again after checking for all that mouse leave and cancel stuff, so quick
* scroll wouldn't be an issue anymore. Same goes for scrolling wheel in another
* direction below (sergey).
*/
@@ -6038,7 +6099,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
uiButColor *color_but = (uiButColor *)but;
if (data->state == BUTTON_STATE_HIGHLIGHT) {
- /* first handle click on icondrag type button */
+ /* First handle click on icon-drag type button. */
if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) {
ui_palette_set_active(color_but);
if (ui_but_contains_point_px_icon(but, data->region, event)) {
@@ -6452,7 +6513,7 @@ static void ui_ndofedit_but_HSVCUBE(uiButHSVCube *hsv_but,
CLAMP(hsv[2], hsv_but->but.softmin, hsv_but->but.softmax);
break;
default:
- BLI_assert(!"invalid hsv type");
+ BLI_assert_msg(0, "invalid hsv type");
break;
}
@@ -6968,8 +7029,8 @@ static bool ui_numedit_but_CURVE(uiBlock *block,
CurveMapPoint *cmp = cuma->curve;
bool changed = false;
- /* evtx evty and drag coords are absolute mousecoords,
- * prevents errors when editing when layout changes */
+ /* evtx evty and drag coords are absolute mouse-coords,
+ * prevents errors when editing when layout changes. */
int mx = evtx;
int my = evty;
ui_window_to_block(data->region, block, &mx, &my);
@@ -7027,7 +7088,7 @@ static bool ui_numedit_but_CURVE(uiBlock *block,
changed = true;
#ifdef USE_CONT_MOUSE_CORRECT
- /* note: using 'cmp_last' is weak since there may be multiple points selected,
+ /* NOTE: using 'cmp_last' is weak since there may be multiple points selected,
* but in practice this isn't really an issue */
if (ui_but_is_cursor_warp(but)) {
/* OK but can go outside bounds */
@@ -7236,8 +7297,8 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block,
CurveProfilePoint *pts = profile->path;
bool changed = false;
- /* evtx evty and drag coords are absolute mousecoords,
- * prevents errors when editing when layout changes */
+ /* evtx evty and drag coords are absolute mouse-coords,
+ * prevents errors when editing when layout changes. */
int mx = evtx;
int my = evty;
ui_window_to_block(data->region, block, &mx, &my);
@@ -7298,7 +7359,7 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block,
data->draglasty = evty;
changed = true;
#ifdef USE_CONT_MOUSE_CORRECT
- /* note: using 'cmp_last' is weak since there may be multiple points selected,
+ /* NOTE: using 'cmp_last' is weak since there may be multiple points selected,
* but in practice this isn't really an issue */
if (ui_but_is_cursor_warp(but)) {
/* OK but can go outside bounds */
@@ -7844,6 +7905,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
case UI_BTYPE_CHECKBOX:
case UI_BTYPE_CHECKBOX_N:
case UI_BTYPE_ROW:
+ case UI_BTYPE_DATASETROW:
retval = ui_do_but_TOG(C, but, data, event);
break;
case UI_BTYPE_SCROLL:
@@ -8006,8 +8068,7 @@ static void ui_blocks_set_tooltips(ARegion *region, const bool enable)
return;
}
- /* we disabled buttons when when they were already shown, and
- * re-enable them on mouse move */
+ /* We disabled buttons when they were already shown, and re-enable them on mouse move. */
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
block->tooltipdisabled = !enable;
}
@@ -8233,8 +8294,8 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
data->hold_action_timer = NULL;
}
- /* add a blocking ui handler at the window handler for blocking, modal states
- * but not for popups, because we already have a window level handler*/
+ /* Add a blocking ui handler at the window handler for blocking, modal states
+ * but not for popups, because we already have a window level handler. */
if (!(but->block->handle && but->block->handle->popup)) {
if (button_modal_state(state)) {
if (!button_modal_state(data->state)) {
@@ -8256,6 +8317,16 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
but->flag &= ~UI_SELECT;
}
+ if (state == BUTTON_STATE_TEXT_EDITING) {
+ ui_block_interaction_begin_ensure(C, but->block, data, true);
+ }
+ else if (state == BUTTON_STATE_EXIT) {
+ if (data->state == BUTTON_STATE_NUM_EDITING) {
+ /* This happens on pasting values for example. */
+ ui_block_interaction_begin_ensure(C, but->block, data, true);
+ }
+ }
+
data->state = state;
if (state != BUTTON_STATE_EXIT) {
@@ -8484,6 +8555,21 @@ static void button_activate_exit(
ED_region_tag_redraw_no_rebuild(data->region);
ED_region_tag_refresh_ui(data->region);
+ if ((but->flag & UI_BUT_DRAG_MULTI) == 0) {
+ if (data->custom_interaction_handle != NULL) {
+ /* Should only set when the button is modal. */
+ BLI_assert(but->active != NULL);
+ data->custom_interaction_handle->user_count--;
+
+ BLI_assert(data->custom_interaction_handle->user_count >= 0);
+ if (data->custom_interaction_handle->user_count == 0) {
+ ui_block_interaction_end(
+ C, &but->block->custom_interaction_callbacks, data->custom_interaction_handle);
+ }
+ data->custom_interaction_handle = NULL;
+ }
+ }
+
/* clean up button */
if (but->active) {
MEM_freeN(but->active);
@@ -8631,9 +8717,9 @@ void UI_context_active_but_prop_handle(bContext *C)
{
uiBut *activebut = ui_context_rna_button_active(C);
if (activebut) {
- /* TODO, look into a better way to handle the button change
+ /* TODO(campbell): look into a better way to handle the button change
* currently this is mainly so reset defaults works for the
- * operator redo panel - campbell */
+ * operator redo panel. */
uiBlock *block = activebut->block;
if (block->handle_func) {
block->handle_func(C, block->handle_func_arg, activebut->retval);
@@ -8822,7 +8908,7 @@ void ui_but_execute_begin(struct bContext *UNUSED(C),
{
BLI_assert(region != NULL);
BLI_assert(BLI_findindex(&region->uiblocks, but->block) != -1);
- /* note: ideally we would not have to change 'but->active' however
+ /* NOTE: ideally we would not have to change 'but->active' however
* some functions we call don't use data (as they should be doing) */
uiHandleButtonData *data;
*active_back = but->active;
@@ -9191,7 +9277,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
*
* This is needed to make sure if a button was active,
* it stays active while the mouse is over it.
- * This avoids adding mousemoves, see: T33466. */
+ * This avoids adding mouse-moves, see: T33466. */
if (ELEM(state_orig, BUTTON_STATE_INIT, BUTTON_STATE_HIGHLIGHT, BUTTON_STATE_WAIT_DRAG)) {
if (ui_but_find_mouse_over(region, event) == but) {
button_activate_init(C, region, but, BUTTON_ACTIVATE_OVER);
@@ -9679,7 +9765,7 @@ static void ui_region_auto_open_clear(ARegion *region)
* This allows a menu to be open,
* but send key events to the parent if there's no active buttons.
*
- * Without this keyboard navigation from menu's wont work.
+ * Without this keyboard navigation from menus won't work.
*/
static bool ui_menu_pass_event_to_parent_if_nonactive(uiPopupBlockHandle *menu,
const uiBut *but,
@@ -10032,7 +10118,7 @@ static int ui_handle_menu_event(bContext *C,
}
if (!but) {
- /* wrap button or no active button*/
+ /* 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);
@@ -10272,7 +10358,7 @@ static int ui_handle_menu_event(bContext *C,
/* For buttons that use a hold function,
* exit when mouse-up outside the menu. */
if (block->flag & UI_BLOCK_POPUP_HOLD) {
- /* Note, we could check the cursor is over the parent button. */
+ /* NOTE: we could check the cursor is over the parent button. */
menu->menuretval = UI_RETURN_CANCEL;
retval = WM_UI_HANDLER_CONTINUE;
}
@@ -10376,7 +10462,7 @@ static int ui_handle_menu_event(bContext *C,
* anymore why it was there? but it meant enter didn't work
* for example when mouse was not over submenu */
if ((event->type == TIMER) ||
- (/*inside &&*/ (!menu->menuretval || (menu->menuretval & UI_RETURN_UPDATE)) &&
+ (/* inside && */ (!menu->menuretval || (menu->menuretval & UI_RETURN_UPDATE)) &&
retval == WM_UI_HANDLER_CONTINUE)) {
retval = ui_handle_menu_button(C, event, menu);
}
@@ -11331,3 +11417,100 @@ bool UI_but_active_drop_color(bContext *C)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name UI Block Interaction API
+ * \{ */
+
+void UI_block_interaction_set(uiBlock *block, uiBlockInteraction_CallbackData *callbacks)
+{
+ block->custom_interaction_callbacks = *callbacks;
+}
+
+static uiBlockInteraction_Handle *ui_block_interaction_begin(bContext *C,
+ uiBlock *block,
+ const bool is_click)
+{
+ BLI_assert(block->custom_interaction_callbacks.begin_fn != NULL);
+ uiBlockInteraction_Handle *interaction = MEM_callocN(sizeof(*interaction), __func__);
+
+ int unique_retval_ids_len = 0;
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
+ if (but->active || (but->flag & UI_BUT_DRAG_MULTI)) {
+ unique_retval_ids_len++;
+ }
+ }
+
+ int *unique_retval_ids = MEM_mallocN(sizeof(*unique_retval_ids) * unique_retval_ids_len,
+ __func__);
+ unique_retval_ids_len = 0;
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
+ if (but->active || (but->flag & UI_BUT_DRAG_MULTI)) {
+ unique_retval_ids[unique_retval_ids_len++] = but->retval;
+ }
+ }
+
+ if (unique_retval_ids_len > 1) {
+ qsort(unique_retval_ids, unique_retval_ids_len, sizeof(int), BLI_sortutil_cmp_int);
+ unique_retval_ids_len = BLI_array_deduplicate_ordered(unique_retval_ids,
+ unique_retval_ids_len);
+ unique_retval_ids = MEM_reallocN(unique_retval_ids,
+ sizeof(*unique_retval_ids) * unique_retval_ids_len);
+ }
+
+ interaction->params.is_click = is_click;
+ interaction->params.unique_retval_ids = unique_retval_ids;
+ interaction->params.unique_retval_ids_len = unique_retval_ids_len;
+
+ interaction->user_data = block->custom_interaction_callbacks.begin_fn(
+ C, &interaction->params, block->custom_interaction_callbacks.arg1);
+ return interaction;
+}
+
+static void ui_block_interaction_end(bContext *C,
+ uiBlockInteraction_CallbackData *callbacks,
+ uiBlockInteraction_Handle *interaction)
+{
+ BLI_assert(callbacks->end_fn != NULL);
+ callbacks->end_fn(C, &interaction->params, callbacks->arg1, interaction->user_data);
+ MEM_freeN(interaction->params.unique_retval_ids);
+ MEM_freeN(interaction);
+}
+
+static void ui_block_interaction_update(bContext *C,
+ uiBlockInteraction_CallbackData *callbacks,
+ uiBlockInteraction_Handle *interaction)
+{
+ BLI_assert(callbacks->update_fn != NULL);
+ callbacks->update_fn(C, &interaction->params, callbacks->arg1, interaction->user_data);
+}
+
+/**
+ * \note #ui_block_interaction_begin cannot be called when setting the button state
+ * (e.g. #BUTTON_STATE_NUM_EDITING) for the following reasons.
+ *
+ * - Other buttons may still be activated using #UI_BUT_DRAG_MULTI
+ * which is necessary before gathering all the #uiBut.retval values to initialize
+ * #uiBlockInteraction_Params.unique_retval_ids.
+ * - When clicking on a number button it's not known if the event is a click or a drag.
+ *
+ * Instead, it must be called immediately before the drag action begins.
+ */
+static void ui_block_interaction_begin_ensure(bContext *C,
+ uiBlock *block,
+ uiHandleButtonData *data,
+ const bool is_click)
+{
+ if (data->custom_interaction_handle) {
+ return;
+ }
+ if (block->custom_interaction_callbacks.begin_fn == NULL) {
+ return;
+ }
+
+ uiBlockInteraction_Handle *interaction = ui_block_interaction_begin(C, block, is_click);
+ interaction->user_count = 1;
+ data->custom_interaction_handle = interaction;
+}
+
+/** \} */
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 4defbed940e..2a505abe257 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1180,7 +1180,7 @@ static DrawInfo *icon_ensure_drawinfo(Icon *icon)
return di;
}
-/* note!, returns unscaled by DPI */
+/* NOTE:, returns unscaled by DPI. */
int UI_icon_get_width(int icon_id)
{
Icon *icon = BKE_icon_get(icon_id);
@@ -1500,7 +1500,7 @@ static void icon_draw_rect(float x,
/* sanity check */
if (w <= 0 || h <= 0 || w > 2000 || h > 2000) {
printf("%s: icons are %i x %i pixels?\n", __func__, w, h);
- BLI_assert(!"invalid icon size");
+ BLI_assert_msg(0, "invalid icon size");
return;
}
/* modulate color */
@@ -1519,7 +1519,7 @@ static void icon_draw_rect(float x,
draw_h = h;
draw_x += (w - draw_w) / 2;
}
- /* if the image is squared, the draw_ initialization values are good */
+ /* If the image is squared, the `draw_*` initialization values are good. */
/* first allocate imbuf for scaling and copy preview into it */
ima = IMB_allocImBuf(rw, rh, 32, IB_rect);
@@ -2294,7 +2294,7 @@ int UI_icon_from_idcode(const int idcode)
case ID_ME:
return ICON_MESH_DATA;
case ID_MSK:
- return ICON_MOD_MASK; /* TODO! this would need its own icon! */
+ return ICON_MOD_MASK; /* TODO: this would need its own icon! */
case ID_NT:
return ICON_NODETREE;
case ID_OB:
@@ -2302,9 +2302,9 @@ int UI_icon_from_idcode(const int idcode)
case ID_PA:
return ICON_PARTICLE_DATA;
case ID_PAL:
- return ICON_COLOR; /* TODO! this would need its own icon! */
+ return ICON_COLOR; /* TODO: this would need its own icon! */
case ID_PC:
- return ICON_CURVE_BEZCURVE; /* TODO! this would need its own icon! */
+ return ICON_CURVE_BEZCURVE; /* TODO: this would need its own icon! */
case ID_LP:
return ICON_OUTLINER_DATA_LIGHTPROBE;
case ID_SCE:
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 40a3f0d330f..40a9c67c630 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -137,19 +137,19 @@ extern const short ui_radial_dir_to_angle[8];
/** #PieMenuData.flags */
enum {
- /** pie menu item collision is detected at 90 degrees */
+ /** Pie menu item collision is detected at 90 degrees. */
UI_PIE_DEGREES_RANGE_LARGE = (1 << 0),
- /** use initial center of pie menu to calculate direction */
+ /** Use initial center of pie menu to calculate direction. */
UI_PIE_INITIAL_DIRECTION = (1 << 1),
- /** pie menu is drag style */
+ /** Pie menu is drag style. */
UI_PIE_DRAG_STYLE = (1 << 2),
- /** mouse not far enough from center position */
+ /** Mouse not far enough from center position. */
UI_PIE_INVALID_DIR = (1 << 3),
- /** pie menu changed to click style, click to confirm */
+ /** Pie menu changed to click style, click to confirm. */
UI_PIE_CLICK_STYLE = (1 << 4),
- /** pie animation finished, do not calculate any more motion */
+ /** Pie animation finished, do not calculate any more motion. */
UI_PIE_ANIMATION_FINISHED = (1 << 5),
- /** pie gesture selection has been done, now wait for mouse motion to end */
+ /** Pie gesture selection has been done, now wait for mouse motion to end. */
UI_PIE_GESTURE_END_WAIT = (1 << 6),
};
@@ -221,7 +221,8 @@ struct uiBut {
const char *tip;
uiButToolTipFunc tip_func;
- void *tip_argN;
+ void *tip_arg;
+ uiFreeArgFunc tip_arg_free;
/** info on why button is disabled, displayed in tooltip */
const char *disabled_info;
@@ -261,7 +262,7 @@ struct uiBut {
ListBase extra_op_icons; /** #uiButExtraOpIcon */
- /* Draggable data, type is WM_DRAG_... */
+ /* Drag-able data, type is WM_DRAG_... */
char dragtype;
short dragflag;
void *dragpoin;
@@ -279,7 +280,7 @@ struct uiBut {
float *editvec;
uiButPushedStateFunc pushed_state_func;
- void *pushed_state_arg;
+ const void *pushed_state_arg;
/* pointer back */
uiBlock *block;
@@ -316,7 +317,7 @@ typedef struct uiButSearch {
void *item_active;
void *arg;
- uiButSearchArgFreeFn arg_free_fn;
+ uiFreeArgFunc arg_free_fn;
uiButSearchContextMenuFn item_context_menu_fn;
uiButSearchTooltipFn item_tooltip_fn;
@@ -350,6 +351,15 @@ typedef struct uiButProgressbar {
float progress;
} uiButProgressbar;
+/** Derived struct for #UI_BTYPE_DATASETROW. */
+typedef struct uiButDatasetRow {
+ uiBut but;
+
+ uint8_t geometry_component_type;
+ uint8_t attribute_domain;
+ int indentation;
+} uiButDatasetRow;
+
/** Derived struct for #UI_BTYPE_HSVCUBE. */
typedef struct uiButHSVCube {
uiBut but;
@@ -501,6 +511,9 @@ struct uiBlock {
uiBlockHandleFunc handle_func;
void *handle_func_arg;
+ /** Custom interaction data. */
+ uiBlockInteraction_CallbackData custom_interaction_callbacks;
+
/** Custom extra event handling. */
int (*block_event_func)(const struct bContext *C, struct uiBlock *, const struct wmEvent *);
@@ -695,7 +708,7 @@ struct uiPopupBlockCreate {
uiBlockCreateFunc create_func;
uiBlockHandleCreateFunc handle_create_func;
void *arg;
- void (*arg_free)(void *arg);
+ uiFreeArgFunc arg_free;
int event_xy[2];
@@ -819,7 +832,7 @@ uiPopupBlockHandle *ui_popup_block_create(struct bContext *C,
uiBlockCreateFunc create_func,
uiBlockHandleCreateFunc handle_create_func,
void *arg,
- void (*arg_free)(void *arg));
+ uiFreeArgFunc arg_free);
uiPopupBlockHandle *ui_popup_menu_create(struct bContext *C,
struct ARegion *butregion,
uiBut *but,
@@ -934,9 +947,7 @@ extern void ui_but_execute_end(struct bContext *C,
void *active_back);
extern void ui_but_active_free(const struct bContext *C, uiBut *but);
extern int ui_but_menu_direction(uiBut *but);
-extern void ui_but_text_password_hide(char password_str[UI_MAX_DRAW_STR],
- uiBut *but,
- const bool restore);
+extern void ui_but_text_password_hide(char password_str[128], uiBut *but, const bool restore);
extern uiBut *ui_but_find_select_in_enum(uiBut *but, int direction);
bool ui_but_is_editing(const uiBut *but);
float ui_block_calc_pie_segment(struct uiBlock *block, const float event_xy[2]);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 8f2871ce18b..8b9539f1d33 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -169,7 +169,7 @@ struct uiLayout {
bool enabled;
bool redalert;
bool keepaspect;
- /** For layouts inside gridflow, they and their items shall never have a fixed maximal size. */
+ /** For layouts inside grid-flow, they and their items shall never have a fixed maximal size. */
bool variable_size;
char alignment;
eUIEmbossType emboss;
@@ -643,7 +643,7 @@ static void ui_item_array(uiLayout *layout,
NULL);
}
else {
- /* note, this block of code is a bit arbitrary and has just been made
+ /* NOTE: this block of code is a bit arbitrary and has just been made
* to work with common cases, but may need to be re-worked */
/* special case, boolean array in a menu, this could be used in a more generic way too */
@@ -662,7 +662,7 @@ static void ui_item_array(uiLayout *layout,
}
}
- /* show checkboxes for rna on a non-emboss block (menu for eg) */
+ /* Show check-boxes for rna on a non-emboss block (menu for eg). */
bool *boolarr = NULL;
if (type == PROP_BOOLEAN &&
ELEM(layout->root->block->emboss, UI_EMBOSS_NONE, UI_EMBOSS_PULLDOWN)) {
@@ -1191,7 +1191,7 @@ static uiBut *uiItemFullO_ptr_ex(uiLayout *layout,
const eUIEmbossType prev_emboss = layout->emboss;
if (flag & UI_ITEM_R_NO_BG) {
- layout->emboss = UI_EMBOSS_NONE;
+ layout->emboss = UI_EMBOSS_NONE_OR_STATUS;
}
/* create the button */
@@ -1411,7 +1411,7 @@ BLI_INLINE bool ui_layout_is_radial(const uiLayout *layout)
}
/**
- * Create ui items for enum items in \a item_array.
+ * Create UI items for enum items in \a item_array.
*
* A version of #uiItemsFullEnumO that takes pre-calculated item array.
*/
@@ -1818,7 +1818,7 @@ static void ui_item_rna_size(uiLayout *layout,
}
else if (type == PROP_BOOLEAN) {
if (icon == ICON_NONE) {
- /* Exception for checkboxes, they need a little less space to align nicely. */
+ /* Exception for check-boxes, they need a little less space to align nicely. */
is_checkbox_only = true;
}
icon = ICON_DOT;
@@ -1984,7 +1984,7 @@ void uiItemFullR(uiLayout *layout,
* a label to display in the first column, the heading is inserted there. Otherwise it's inserted
* as a new row before the first item. */
uiLayout *heading_layout = ui_layout_heading_find(layout);
- /* Although checkboxes use the split layout, they are an exception and should only place their
+ /* Although check-boxes use the split layout, they are an exception and should only place their
* label in the second column, to not make that almost empty.
*
* Keep using 'use_prop_sep' instead of disabling it entirely because
@@ -2062,7 +2062,7 @@ void uiItemFullR(uiLayout *layout,
/* Menus and pie-menus don't show checkbox without this. */
if ((layout->root->type == UI_LAYOUT_MENU) ||
- /* Use checkboxes only as a fallback in pie-menu's, when no icon is defined. */
+ /* Use check-boxes only as a fallback in pie-menu's, when no icon is defined. */
((layout->root->type == UI_LAYOUT_PIEMENU) && (icon == ICON_NONE))) {
const int prop_flag = RNA_property_flag(prop);
if (type == PROP_BOOLEAN) {
@@ -2122,7 +2122,7 @@ void uiItemFullR(uiLayout *layout,
const eUIEmbossType prev_emboss = layout->emboss;
if (no_bg) {
- layout->emboss = UI_EMBOSS_NONE;
+ layout->emboss = UI_EMBOSS_NONE_OR_STATUS;
}
uiBut *but = NULL;
@@ -2346,16 +2346,16 @@ void uiItemFullR(uiLayout *layout,
* In this case we want the ability not to have an icon.
*
* We could pass an argument not to set the icon to begin with however this is the one case
- * the functionality is needed. */
+ * the functionality is needed. */
if (but && no_icon) {
if ((icon == ICON_NONE) && (but->icon != ICON_NONE)) {
ui_def_but_icon_clear(but);
}
}
- /* Mark non-embossed textfields inside a listbox. */
+ /* Mark non-embossed text-fields inside a list-box. */
if (but && (block->flag & UI_BLOCK_LIST_ITEM) && (but->type == UI_BTYPE_TEXT) &&
- (but->emboss & UI_EMBOSS_NONE)) {
+ ELEM(but->emboss, UI_EMBOSS_NONE, UI_EMBOSS_NONE_OR_STATUS)) {
UI_but_flag_enable(but, UI_BUT_LIST_ITEM);
}
@@ -2831,7 +2831,7 @@ void ui_item_paneltype_func(bContext *C, uiLayout *layout, void *arg_pt)
PanelType *pt = (PanelType *)arg_pt;
UI_paneltype_draw(C, pt, layout);
- /* panels are created flipped (from event handling pov) */
+ /* Panels are created flipped (from event handling POV). */
layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
}
@@ -2860,7 +2860,7 @@ static uiBut *ui_item_menu(uiLayout *layout,
int w = ui_text_icon_width(layout, name, icon, 1);
const int h = UI_UNIT_Y;
- if (layout->root->type == UI_LAYOUT_HEADER) { /* ugly .. */
+ if (layout->root->type == UI_LAYOUT_HEADER) { /* Ugly! */
if (icon == ICON_NONE && force_menu) {
/* pass */
}
@@ -2893,7 +2893,7 @@ static uiBut *ui_item_menu(uiLayout *layout,
}
if (argN) {
- /* ugly .. */
+ /* ugly! */
if (arg != argN) {
but->poin = (char *)but;
}
@@ -3147,7 +3147,7 @@ static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon)
but->drawflag |= UI_BUT_TEXT_RIGHT;
}
- /* Mark as a label inside a listbox. */
+ /* Mark as a label inside a list-box. */
if (block->flag & UI_BLOCK_LIST_ITEM) {
but->flag |= UI_BUT_LIST_ITEM;
}
@@ -3381,10 +3381,13 @@ typedef struct MenuItemLevel {
static void menu_item_enum_opname_menu(bContext *UNUSED(C), uiLayout *layout, void *arg)
{
- MenuItemLevel *lvl = (MenuItemLevel *)(((uiBut *)arg)->func_argN);
+ uiBut *but = arg;
+ MenuItemLevel *lvl = but->func_argN;
+ /* Use the operator properties from the button owning the menu. */
+ IDProperty *op_props = but->opptr ? but->opptr->data : NULL;
uiLayoutSetOperatorContext(layout, lvl->opcontext);
- uiItemsEnumO(layout, lvl->opname, lvl->propname);
+ uiItemsFullEnumO(layout, lvl->opname, lvl->propname, op_props, lvl->opcontext, 0);
layout->root->block->flag |= UI_BLOCK_IS_FLIP;
@@ -3392,12 +3395,13 @@ static void menu_item_enum_opname_menu(bContext *UNUSED(C), uiLayout *layout, vo
UI_block_direction_set(layout->root->block, UI_DIR_DOWN);
}
-void uiItemMenuEnumO_ptr(uiLayout *layout,
- bContext *C,
- wmOperatorType *ot,
- const char *propname,
- const char *name,
- int icon)
+void uiItemMenuEnumFullO_ptr(uiLayout *layout,
+ bContext *C,
+ wmOperatorType *ot,
+ const char *propname,
+ const char *name,
+ int icon,
+ PointerRNA *r_opptr)
{
/* Caller must check */
BLI_assert(ot->srna != NULL);
@@ -3416,6 +3420,15 @@ void uiItemMenuEnumO_ptr(uiLayout *layout,
lvl->opcontext = layout->root->opcontext;
uiBut *but = ui_item_menu(layout, name, icon, menu_item_enum_opname_menu, NULL, lvl, NULL, true);
+ /* Use the menu button as owner for the operator properties, which will then be passed to the
+ * individual menu items. */
+ if (r_opptr) {
+ but->opptr = MEM_callocN(sizeof(PointerRNA), "uiButOpPtr");
+ WM_operator_properties_create_ptr(but->opptr, ot);
+ BLI_assert(but->opptr->data == NULL);
+ WM_operator_properties_alloc(&but->opptr, (IDProperty **)&but->opptr->data, ot->idname);
+ *r_opptr = *but->opptr;
+ }
/* add hotkey here, lower UI code can't detect it */
if ((layout->root->block->flag & UI_BLOCK_LOOP) && (ot->prop && ot->invoke)) {
@@ -3427,12 +3440,13 @@ void uiItemMenuEnumO_ptr(uiLayout *layout,
}
}
-void uiItemMenuEnumO(uiLayout *layout,
- bContext *C,
- const char *opname,
- const char *propname,
- const char *name,
- int icon)
+void uiItemMenuEnumFullO(uiLayout *layout,
+ bContext *C,
+ const char *opname,
+ const char *propname,
+ const char *name,
+ int icon,
+ PointerRNA *r_opptr)
{
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
@@ -3444,7 +3458,17 @@ void uiItemMenuEnumO(uiLayout *layout,
return;
}
- uiItemMenuEnumO_ptr(layout, C, ot, propname, name, icon);
+ uiItemMenuEnumFullO_ptr(layout, C, ot, propname, name, icon, r_opptr);
+}
+
+void uiItemMenuEnumO(uiLayout *layout,
+ bContext *C,
+ const char *opname,
+ const char *propname,
+ const char *name,
+ int icon)
+{
+ uiItemMenuEnumFullO(layout, C, opname, propname, name, icon, NULL);
}
static void menu_item_enum_rna_menu(bContext *UNUSED(C), uiLayout *layout, void *arg)
@@ -4042,12 +4066,11 @@ static void ui_litem_layout_column_flow(uiLayout *litem)
int emy = 0;
int miny = 0;
- int w = litem->w - (flow->totcol - 1) * style->columnspace;
emh = toth / flow->totcol;
/* create column per column */
col = 0;
- w = (litem->w - (flow->totcol - 1) * style->columnspace) / flow->totcol;
+ int w = (litem->w - (flow->totcol - 1) * style->columnspace) / flow->totcol;
LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, &itemw, &itemh);
@@ -4616,7 +4639,7 @@ static void ui_litem_init_from_parent(uiLayout *litem, uiLayout *layout, int ali
{
litem->root = layout->root;
litem->align = align;
- /* Children of gridflow layout shall never have "ideal big size" returned as estimated size. */
+ /* Children of grid-flow layout shall never have "ideal big size" returned as estimated size. */
litem->variable_size = layout->variable_size || layout->item.type == ITEM_LAYOUT_GRID_FLOW;
litem->active = true;
litem->enabled = true;
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 0cf3ad59903..4afe232e33e 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -803,7 +803,7 @@ bool UI_context_copy_to_selected_list(bContext *C,
}
else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
/* Special case when we do this for 'Sequence.lock'.
- * (if the sequence is locked, it wont be in "selected_editable_sequences"). */
+ * (if the sequence is locked, it won't be in "selected_editable_sequences"). */
const char *prop_id = RNA_property_identifier(prop);
if (STREQ(prop_id, "lock")) {
*r_lb = CTX_data_collection_get(C, "selected_sequences");
@@ -921,7 +921,7 @@ bool UI_context_copy_to_selected_list(bContext *C,
* to handle situations like T41062... */
if ((*r_path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Sequence)) != NULL) {
/* Special case when we do this for 'Sequence.lock'.
- * (if the sequence is locked, it wont be in "selected_editable_sequences"). */
+ * (if the sequence is locked, it won't be in "selected_editable_sequences"). */
const char *prop_id = RNA_property_identifier(prop);
if (STREQ(prop_id, "lock")) {
*r_lb = CTX_data_collection_get(C, "selected_sequences");
@@ -1215,7 +1215,7 @@ static void UI_OT_jump_to_target_button(wmOperatorType *ot)
/* ------------------------------------------------------------------------- */
/* EditSource Utility funcs and operator,
- * note, this includes utility functions and button matching checks */
+ * NOTE: this includes utility functions and button matching checks. */
typedef struct uiEditSourceStore {
uiBut but_orig;
@@ -1340,7 +1340,7 @@ static int editsource_text_edit(bContext *C,
txt_move_toline(text, line - 1, false);
/* naughty!, find text area to set, not good behavior
- * but since this is a dev tool lets allow it - campbell */
+ * but since this is a developer tool lets allow it - campbell */
ScrArea *area = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_TEXT, 0);
if (area) {
SpaceText *st = area->spacedata.first;
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 6505a7cd76a..38dc91fb57f 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -258,7 +258,7 @@ static Panel *panel_add_instanced(ARegion *region,
/* Make sure the panel is added to the end of the display-order as well. This is needed for
* loading existing files.
*
- * Note: We could use special behavior to place it after the panel that starts the list of
+ * NOTE: We could use special behavior to place it after the panel that starts the list of
* instanced panels, but that would add complexity that isn't needed for now. */
int max_sortorder = 0;
LISTBASE_FOREACH (Panel *, existing_panel, panels) {
@@ -674,7 +674,7 @@ static bool panel_type_context_poll(ARegion *region,
const PanelType *panel_type,
const char *context)
{
- if (UI_panel_category_is_visible(region)) {
+ if (!BLI_listbase_is_empty(&region->panels_category)) {
return STREQ(panel_type->category, UI_panel_category_active_get(region, false));
}
@@ -1188,7 +1188,6 @@ static void panel_draw_aligned_widgets(const uiStyle *style,
/* Draw text label. */
if (panel->drawname[0] != '\0') {
- /* + 0.001f to avoid flirting with float inaccuracy .*/
const rcti title_rect = {
.xmin = widget_rect.xmin + (panel->labelofs / aspect) + scaled_unit * 1.1f,
.xmax = widget_rect.xmax,
@@ -1893,7 +1892,7 @@ static void ui_do_animate(bContext *C, Panel *panel)
}
else {
if (UI_panel_is_dragging(panel)) {
- /* Note: doing this in #panel_activate_state would require
+ /* NOTE: doing this in #panel_activate_state would require
* removing `const` for context in many other places. */
reorder_instanced_panel_list(C, region, panel);
}
@@ -2564,7 +2563,7 @@ PointerRNA *UI_region_panel_custom_data_under_cursor(const bContext *C, const wm
/** \name Window Level Modal Panel Interaction
* \{ */
-/* Note, this is modal handler and should not swallow events for animation. */
+/* NOTE: this is modal handler and should not swallow events for animation. */
static int ui_handler_panel(bContext *C, const wmEvent *event, void *userdata)
{
Panel *panel = userdata;
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index aa10d092f5e..025c242d0fc 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -67,7 +67,8 @@ bool ui_but_is_toggle(const uiBut *but)
UI_BTYPE_TOGGLE_N,
UI_BTYPE_CHECKBOX,
UI_BTYPE_CHECKBOX_N,
- UI_BTYPE_ROW);
+ UI_BTYPE_ROW,
+ UI_BTYPE_DATASETROW);
}
/**
@@ -77,7 +78,7 @@ bool ui_but_is_toggle(const uiBut *but)
*/
bool ui_but_is_interactive(const uiBut *but, const bool labeledit)
{
- /* note, UI_BTYPE_LABEL is included for highlights, this allows drags */
+ /* NOTE: #UI_BTYPE_LABEL is included for highlights, this allows drags. */
if ((but->type == UI_BTYPE_LABEL) && but->dragpoin == NULL) {
return false;
}
@@ -90,7 +91,8 @@ bool ui_but_is_interactive(const uiBut *but, const bool labeledit)
if (but->flag & UI_SCROLLED) {
return false;
}
- if ((but->type == UI_BTYPE_TEXT) && (but->emboss == UI_EMBOSS_NONE) && !labeledit) {
+ if ((but->type == UI_BTYPE_TEXT) &&
+ (ELEM(but->emboss, UI_EMBOSS_NONE, UI_EMBOSS_NONE_OR_STATUS)) && !labeledit) {
return false;
}
if ((but->type == UI_BTYPE_LISTROW) && labeledit) {
diff --git a/source/blender/editors/interface/interface_region_color_picker.c b/source/blender/editors/interface/interface_region_color_picker.c
index e68705e4321..48952c4f121 100644
--- a/source/blender/editors/interface/interface_region_color_picker.c
+++ b/source/blender/editors/interface/interface_region_color_picker.c
@@ -624,7 +624,7 @@ static void ui_block_colorpicker(uiBlock *block,
bt->custom_data = cpicker;
}
- /* Note: don't disable UI_BUT_UNDO for RGBA values, since these don't add undo steps. */
+ /* NOTE: don't disable UI_BUT_UNDO for RGBA values, since these don't add undo steps. */
/* RGB values */
UI_block_align_begin(block);
diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.c
index 58a74a3473e..d3c1a97e957 100644
--- a/source/blender/editors/interface/interface_region_menu_popup.c
+++ b/source/blender/editors/interface/interface_region_menu_popup.c
@@ -403,7 +403,7 @@ uiPopupMenu *UI_popup_menu_begin_ex(bContext *C,
pup->layout = UI_block_layout(
pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, UI_MENU_PADDING, style);
- /* note, this intentionally differs from the menu & sub-menu default because many operators
+ /* NOTE: this intentionally differs from the menu & sub-menu default because many operators
* use popups like this to select one of their options -
* where having invoke doesn't make sense */
uiLayoutSetOperatorContext(pup->layout, WM_OP_EXEC_REGION_WIN);
@@ -591,7 +591,7 @@ int UI_popup_menu_invoke(bContext *C, const char *idname, ReportList *reports)
* \{ */
void UI_popup_block_invoke_ex(
- bContext *C, uiBlockCreateFunc func, void *arg, void (*arg_free)(void *arg), bool can_refresh)
+ bContext *C, uiBlockCreateFunc func, void *arg, uiFreeArgFunc arg_free, bool can_refresh)
{
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *handle;
@@ -608,10 +608,7 @@ void UI_popup_block_invoke_ex(
WM_event_add_mousemove(window);
}
-void UI_popup_block_invoke(bContext *C,
- uiBlockCreateFunc func,
- void *arg,
- void (*arg_free)(void *arg))
+void UI_popup_block_invoke(bContext *C, uiBlockCreateFunc func, void *arg, uiFreeArgFunc arg_free)
{
UI_popup_block_invoke_ex(C, func, arg, arg_free, true);
}
diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c
index a9f72233cb1..b8c4d8ddb09 100644
--- a/source/blender/editors/interface/interface_region_popover.c
+++ b/source/blender/editors/interface/interface_region_popover.c
@@ -420,7 +420,7 @@ void UI_popover_end(bContext *C, uiPopover *pup, wmKeyMap *keymap)
* For now close this style of popovers when accessed. */
UI_block_flag_disable(pup->block, UI_BLOCK_KEEP_OPEN);
- /* panels are created flipped (from event handling pov) */
+ /* Panels are created flipped (from event handling POV). */
pup->block->flag ^= UI_BLOCK_IS_FLIP;
}
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index 8135f5a203e..55a162c883a 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -341,7 +341,7 @@ static void ui_popup_block_position(wmWindow *window,
block->safety.ymax = block->rect.ymax + s1;
}
- /* exception for switched pulldowns... */
+ /* Exception for switched pull-downs. */
if (dir1 && (dir1 & block->direction) == 0) {
if (dir2 == UI_DIR_RIGHT) {
block->safety.xmax = block->rect.xmax + s2;
@@ -773,7 +773,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C,
uiBlockCreateFunc create_func,
uiBlockHandleCreateFunc handle_create_func,
void *arg,
- void (*arg_free)(void *arg))
+ uiFreeArgFunc arg_free)
{
wmWindow *window = CTX_wm_window(C);
uiBut *activebut = UI_context_active_but_get(C);
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index 987cde61f97..c35dbc5d7a6 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -95,7 +95,7 @@ typedef struct uiSearchboxData {
/** draw thumbnail previews, rather than list */
bool preview;
/** Use the #UI_SEP_CHAR char for splitting shortcuts (good for operators, bad for data). */
- bool use_sep;
+ bool use_shortcut_sep;
int prv_rows, prv_cols;
/**
* Show the active icon and text after the last instance of this string.
@@ -314,7 +314,7 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region)
data->items.name_prefix_offsets[data->active] :
0);
- const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
+ const char *name_sep = data->use_shortcut_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) + 1 : data->items.maxstrlen);
@@ -535,7 +535,7 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
/* Never include the prefix in the button. */
(data->items.name_prefix_offsets ? data->items.name_prefix_offsets[a] :
0);
- const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
+ const char *name_sep = data->use_shortcut_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) {
data->active = a;
break;
@@ -627,7 +627,7 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region)
char *name_sep_test = NULL;
uiMenuItemSeparatorType separator_type = UI_MENU_ITEM_SEPARATOR_NONE;
- if (data->use_sep) {
+ if (data->use_shortcut_sep) {
separator_type = UI_MENU_ITEM_SEPARATOR_SHORTCUT;
}
/* Only set for displaying additional hint (e.g. library name of a linked data-block). */
@@ -719,7 +719,10 @@ static void ui_searchbox_region_free_cb(ARegion *region)
region->regiondata = NULL;
}
-ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearch *search_but)
+static ARegion *ui_searchbox_create_generic_ex(bContext *C,
+ ARegion *butregion,
+ uiButSearch *search_but,
+ const bool use_shortcut_sep)
{
wmWindow *win = CTX_wm_window(C);
const uiStyle *style = UI_style_get();
@@ -759,12 +762,8 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearc
data->prv_cols = but->a2;
}
- /* Only show key shortcuts when needed (checking RNA prop pointer is useless here, a lot of
- * buttons are about data without having that pointer defined, let's rather try with optype!).
- * One can also enforce that behavior by setting
- * UI_BUT_HAS_SHORTCUT drawflag of search button. */
- if (but->optype != NULL || (but->drawflag & UI_BUT_HAS_SHORTCUT) != 0) {
- data->use_sep = true;
+ if (but->optype != NULL || use_shortcut_sep) {
+ data->use_shortcut_sep = true;
}
data->sep_string = search_but->item_sep_string;
@@ -888,6 +887,11 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearc
return region;
}
+ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearch *search_but)
+{
+ return ui_searchbox_create_generic_ex(C, butregion, search_but, false);
+}
+
/**
* Similar to Python's `str.title` except...
*
@@ -973,8 +977,8 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe
data->items.names[a],
0,
state,
- data->use_sep ? UI_MENU_ITEM_SEPARATOR_SHORTCUT :
- UI_MENU_ITEM_SEPARATOR_NONE,
+ data->use_shortcut_sep ? UI_MENU_ITEM_SEPARATOR_SHORTCUT :
+ UI_MENU_ITEM_SEPARATOR_NONE,
NULL);
}
}
@@ -996,8 +1000,7 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe
ARegion *ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiButSearch *search_but)
{
- UI_but_drawflag_enable(&search_but->but, UI_BUT_HAS_SHORTCUT);
- ARegion *region = ui_searchbox_create_generic(C, butregion, search_but);
+ ARegion *region = ui_searchbox_create_generic_ex(C, butregion, search_but, true);
region->type->draw = ui_searchbox_region_draw_cb__operator;
@@ -1016,8 +1019,7 @@ static void ui_searchbox_region_draw_cb__menu(const bContext *UNUSED(C), ARegion
ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiButSearch *search_but)
{
- UI_but_drawflag_enable(&search_but->but, UI_BUT_HAS_SHORTCUT);
- ARegion *region = ui_searchbox_create_generic(C, butregion, search_but);
+ ARegion *region = ui_searchbox_create_generic_ex(C, butregion, search_but, true);
if (false) {
region->type->draw = ui_searchbox_region_draw_cb__menu;
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index accfb78ab94..10bc3760b42 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -188,11 +188,11 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region
/* tone_fg = rgb_to_grayscale(main_color); */
/* mix the colors */
- rgb_tint(value_color, 0.0f, 0.0f, tone_bg, 0.2f); /* light gray */
- rgb_tint(active_color, 0.6f, 0.2f, tone_bg, 0.2f); /* light blue */
- rgb_tint(normal_color, 0.0f, 0.0f, tone_bg, 0.4f); /* gray */
- rgb_tint(python_color, 0.0f, 0.0f, tone_bg, 0.5f); /* dark gray */
- rgb_tint(alert_color, 0.0f, 0.8f, tone_bg, 0.1f); /* red */
+ rgb_tint(value_color, 0.0f, 0.0f, tone_bg, 0.2f); /* Light gray. */
+ rgb_tint(active_color, 0.6f, 0.2f, tone_bg, 0.2f); /* Light blue. */
+ rgb_tint(normal_color, 0.0f, 0.0f, tone_bg, 0.4f); /* Gray. */
+ rgb_tint(python_color, 0.0f, 0.0f, tone_bg, 0.5f); /* Dark gray. */
+ rgb_tint(alert_color, 0.0f, 0.8f, tone_bg, 0.1f); /* Red. */
/* draw text */
BLF_wordwrap(data->fstyle.uifont_id, data->wrap_width);
@@ -435,7 +435,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
}
}
else {
- /* Note, this is an exceptional case, we could even remove it
+ /* NOTE: this is an exceptional case, we could even remove it
* however there have been reports of tooltips failing, so keep it for now. */
expr_result = BLI_strdup(IFACE_("Internal error!"));
is_error = true;
@@ -492,7 +492,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
}
}
else {
- /* Note, this is an exceptional case, we could even remove it
+ /* NOTE: this is an exceptional case, we could even remove it
* however there have been reports of tooltips failing, so keep it for now. */
expr_result = BLI_strdup(TIP_("Internal error!"));
is_error = true;
@@ -574,7 +574,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
shortcut_toolbar,
ARRAY_SIZE(shortcut_toolbar))) {
/* Generate keymap in order to inspect it.
- * Note, we could make a utility to avoid the keymap generation part of this. */
+ * NOTE: we could make a utility to avoid the keymap generation part of this. */
const char *expr_imports[] = {
"bpy", "bl_keymap_utils", "bl_keymap_utils.keymap_from_toolbar", NULL};
const char *expr =
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index ad0c523a594..88ab6a377d0 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -245,7 +245,7 @@ void UI_fontstyle_draw_rotated(const uiFontStyle *fs,
/* ignore UI_STYLE, always aligned to top */
- /* rotate counter-clockwise for now (assumes left-to-right language)*/
+ /* Rotate counter-clockwise for now (assumes left-to-right language). */
xofs += height;
yofs = BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX) + 5;
angle = M_PI_2;
diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c
index 91ad6619889..f01dca7712c 100644
--- a/source/blender/editors/interface/interface_template_search_menu.c
+++ b/source/blender/editors/interface/interface_template_search_menu.c
@@ -873,7 +873,7 @@ static struct MenuSearch_Data *menu_items_from_ui_create(
/* Finally sort menu items.
*
- * Note: we might want to keep the in-menu order, for now sort all. */
+ * NOTE: we might want to keep the in-menu order, for now sort all. */
BLI_listbase_sort(&data->items, menu_item_sort_by_drawstr_full);
BLI_ghash_free(menu_parent_map, NULL, NULL);
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index e3df9704826..9c17486aea4 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -344,7 +344,7 @@ typedef struct TemplateID {
float scale;
} TemplateID;
-/* Search browse menu, assign */
+/* Search browse menu, assign. */
static void template_ID_set_property_exec_fn(bContext *C, void *arg_template, void *item)
{
TemplateID *template_ui = (TemplateID *)arg_template;
@@ -653,7 +653,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
/* Only remap that specific ID usage to overriding local data-block. */
ID *override_id = BKE_lib_override_library_create_from_id(bmain, id, false);
if (override_id != NULL) {
- BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_newptr_and_tag_clear(bmain);
if (GS(override_id->name) == ID_OB) {
Scene *scene = CTX_data_scene(C);
@@ -672,9 +672,9 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
}
else {
if (BKE_lib_id_make_local(bmain, id, false, 0)) {
- BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_newptr_and_tag_clear(bmain);
- /* reassign to get get proper updates/notifiers */
+ /* Reassign to get proper updates/notifiers. */
idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
undo_push_label = "Make Local";
}
@@ -687,8 +687,8 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
break;
case UI_ID_OVERRIDE:
if (id && ID_IS_OVERRIDE_LIBRARY(id)) {
- BKE_lib_override_library_free(&id->override_library, true);
- /* reassign to get get proper updates/notifiers */
+ BKE_lib_override_library_make_local(id);
+ /* Reassign to get proper updates/notifiers. */
idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
RNA_property_update(C, &template_ui->ptr, template_ui->prop);
@@ -877,7 +877,7 @@ static uiBut *template_id_def_new_but(uiBlock *block,
BLT_I18NCONTEXT_ID_POINTCLOUD,
BLT_I18NCONTEXT_ID_VOLUME,
BLT_I18NCONTEXT_ID_SIMULATION, );
- /* Note: BLT_I18N_MSGID_MULTI_CTXT takes a maximum number of parameters,
+ /* NOTE: BLT_I18N_MSGID_MULTI_CTXT takes a maximum number of parameters,
* check the definition to see if a new call must be added when the limit
* is exceeded. */
@@ -1078,7 +1078,7 @@ static void template_ID(const bContext *C,
char numstr[32];
short numstr_len;
- numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", ID_REAL_USERS(id));
+ numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", ID_REAL_USERS(id));
but = uiDefBut(
block,
@@ -2399,8 +2399,8 @@ static eAutoPropButsReturn template_operator_property_buts_draw_single(
op->type->ui((bContext *)C, op);
op->layout = NULL;
- /* UI_LAYOUT_OP_SHOW_EMPTY ignored. retun_info is ignored too. We could
- * allow ot.ui callback to return this, but not needed right now. */
+ /* #UI_LAYOUT_OP_SHOW_EMPTY ignored. retun_info is ignored too.
+ * We could allow #wmOperatorType.ui callback to return this, but not needed right now. */
}
else {
wmWindowManager *wm = CTX_wm_manager(C);
@@ -2556,7 +2556,7 @@ void uiTemplateOperatorPropertyButs(
wmWindowManager *wm = CTX_wm_manager(C);
/* If there are only checkbox items, don't use split layout by default. It looks weird if the
- * checkboxes only use half the width. */
+ * check-boxes only use half the width. */
if (ui_layout_operator_properties_only_booleans(C, wm, op, flag)) {
flag |= UI_TEMPLATE_OP_PROPS_NO_SPLIT_LAYOUT;
}
@@ -3050,7 +3050,7 @@ static void colorband_flip_cb(bContext *C, ColorBand *coba)
coba->data[a] = data_tmp[a];
}
- /* may as well flip the cur*/
+ /* May as well flip the `cur`. */
coba->cur = coba->tot - (coba->cur + 1);
ED_undo_push(C, "Flip Color Ramp");
@@ -4015,23 +4015,23 @@ static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
case UICURVE_FUNC_RESET_VIEW:
BKE_curvemapping_reset_view(cumap);
break;
- case UICURVE_FUNC_HANDLE_VECTOR: /* set vector */
+ case UICURVE_FUNC_HANDLE_VECTOR: /* Set vector. */
BKE_curvemap_handle_set(cuma, HD_VECT);
BKE_curvemapping_changed(cumap, false);
break;
- case UICURVE_FUNC_HANDLE_AUTO: /* set auto */
+ case UICURVE_FUNC_HANDLE_AUTO: /* Set auto. */
BKE_curvemap_handle_set(cuma, HD_AUTO);
BKE_curvemapping_changed(cumap, false);
break;
- case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* set auto-clamped */
+ case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* Set auto-clamped. */
BKE_curvemap_handle_set(cuma, HD_AUTO_ANIM);
BKE_curvemapping_changed(cumap, false);
break;
- case UICURVE_FUNC_EXTEND_HOZ: /* extend horiz */
+ case UICURVE_FUNC_EXTEND_HOZ: /* Extend horizontal. */
cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
BKE_curvemapping_changed(cumap, false);
break;
- case UICURVE_FUNC_EXTEND_EXP: /* extend extrapolate */
+ case UICURVE_FUNC_EXTEND_EXP: /* Extend extrapolate. */
cumap->flag |= CUMA_EXTEND_EXTRAPOLATE;
BKE_curvemapping_changed(cumap, false);
break;
@@ -5805,7 +5805,7 @@ static void uilist_filter_items_default(struct uiList *ui_list,
if (order_by_name) {
int new_idx;
- /* note: order_idx equals either to ui_list->items_len if no filtering done,
+ /* NOTE: order_idx equals either to ui_list->items_len if no filtering done,
* or to ui_list->items_shown if filter is enabled,
* or to (ui_list->items_len - ui_list->items_shown) if filtered items are excluded.
* This way, we only sort items we actually intend to draw!
@@ -5883,7 +5883,7 @@ static void uilist_prepare(uiList *ui_list,
}
/* If list length changes or list is tagged to check this,
- * and active is out of view, scroll to it .*/
+ * and active is out of view, scroll to it. */
if (ui_list->list_last_len != len || ui_list->flag & UILST_SCROLL_TO_ACTIVE_ITEM) {
if (activei_row < ui_list->list_scroll) {
ui_list->list_scroll = activei_row;
@@ -6205,7 +6205,7 @@ void uiTemplateList(uiLayout *layout,
0,
TIP_("Double click to rename"));
if ((dyntip_data = uilist_item_use_dynamic_tooltip(itemptr, item_dyntip_propname))) {
- UI_but_func_tooltip_set(but, uilist_item_tooltip_func, dyntip_data);
+ UI_but_func_tooltip_set(but, uilist_item_tooltip_func, dyntip_data, MEM_freeN);
}
sub = uiLayoutRow(overlap, false);
@@ -6762,7 +6762,7 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
NULL);
but_progress->progress = progress;
- UI_but_func_tooltip_set(&but_progress->but, progress_tooltip_func, tip_arg);
+ UI_but_func_tooltip_set(&but_progress->but, progress_tooltip_func, tip_arg, MEM_freeN);
}
if (!wm->is_interface_locked) {
diff --git a/source/blender/editors/interface/interface_undo.c b/source/blender/editors/interface/interface_undo.c
index 304d2254a81..40f196d9b45 100644
--- a/source/blender/editors/interface/interface_undo.c
+++ b/source/blender/editors/interface/interface_undo.c
@@ -107,7 +107,7 @@ void ui_textedit_undo_push(uiUndoStack_Text *stack, const char *text, int cursor
}
}
- /* Create the new state */
+ /* Create the new state. */
const int text_size = strlen(text) + 1;
stack->current = MEM_mallocN(sizeof(uiUndoStack_Text_State) + text_size, __func__);
stack->current->cursor_index = cursor_index;
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 6ad1de68a1f..7ea02226f02 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -701,7 +701,7 @@ int UI_calc_float_precision(int prec, double value)
/* Check on the number of decimal places need to display the number,
* this is so 0.00001 is not displayed as 0.00,
- * _but_, this is only for small values si 10.0001 will not get the same treatment.
+ * _but_, this is only for small values as 10.0001 will not get the same treatment.
*/
value = fabs(value);
if ((value < pow10_neg[prec]) && (value > (1.0 / max_pow))) {
@@ -932,7 +932,7 @@ void UI_butstore_update(uiBlock *block)
uiBut *but_new = ui_but_find_new(block, *bs_elem->but_p);
/* can be NULL if the buttons removed,
- * note: we could allow passing in a callback when buttons are removed
+ * NOTE: we could allow passing in a callback when buttons are removed
* so the caller can cleanup */
*bs_elem->but_p = but_new;
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index d2e6165a20f..8abff4ad0d8 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -113,6 +113,7 @@ typedef enum {
UI_WTYPE_LISTITEM,
UI_WTYPE_PROGRESSBAR,
UI_WTYPE_NODESOCKET,
+ UI_WTYPE_DATASETROW,
} uiWidgetTypeEnum;
/* Button state argument shares bits with 'uiBut.flag'.
@@ -236,7 +237,7 @@ typedef struct uiWidgetTrias {
#define WIDGET_SIZE_MAX (WIDGET_CURVE_RESOLU * 4)
typedef struct uiWidgetBase {
- /* TODO remove these completely */
+ /* TODO: remove these completely. */
int totvert, halfwayvert;
float outer_v[WIDGET_SIZE_MAX][2];
float inner_v[WIDGET_SIZE_MAX][2];
@@ -398,7 +399,7 @@ static struct {
GPUBatch *roundbox_widget;
GPUBatch *roundbox_shadow;
- /* TODO remove */
+ /* TODO: remove. */
GPUVertFormat format;
uint vflag_id;
} g_ui_batch_cache = {0};
@@ -522,7 +523,7 @@ void UI_draw_anti_tria(
float draw_color[4];
copy_v4_v4(draw_color, color);
- /* Note: This won't give back the original color. */
+ /* NOTE: This won't give back the original color. */
draw_color[3] *= 1.0f / WIDGET_AA_JITTER;
GPU_blend(GPU_BLEND_ALPHA);
@@ -767,7 +768,7 @@ static void round_box__edges(
BLI_rctf_rcti_copy(&wt->uniform_params.rect, rect);
BLI_rctf_init(&wt->uniform_params.recti, minxi, maxxi, minyi, maxyi);
- /* mult */
+ /* Multiply by radius. */
for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) {
veci[a][0] = radi * cornervec[a][0];
veci[a][1] = radi * cornervec[a][1];
@@ -1376,8 +1377,6 @@ static int ui_but_draw_menu_icon(const uiBut *but)
static void widget_draw_icon(
const uiBut *but, BIFIconID icon, float alpha, const rcti *rect, const uchar mono_color[4])
{
- float xs = 0.0f, ys = 0.0f;
-
if (but->flag & UI_BUT_ICON_PREVIEW) {
GPU_blend(GPU_BLEND_ALPHA);
widget_draw_preview(icon, alpha, rect);
@@ -1419,6 +1418,7 @@ static void widget_draw_icon(
if (icon && icon != ICON_BLANK1) {
const float ofs = 1.0f / aspect;
+ float xs, ys;
if (but->drawflag & UI_BUT_ICON_LEFT) {
/* special case - icon_only pie buttons */
@@ -1531,14 +1531,14 @@ static void ui_text_clip_right_ex(const uiFontStyle *fstyle,
int l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth - sep_strwidth, NULL);
if (l_end > 0) {
- /* At least one character, so clip and add the ellipsis. */
+ /* At least one character, so clip and add the ellipsis. */
memcpy(str + l_end, sep, sep_len + 1); /* +1 for trailing '\0'. */
if (r_final_len) {
*r_final_len = (size_t)(l_end) + sep_len;
}
}
else {
- /* Otherwise fit as much as we can without adding an ellipsis. */
+ /* Otherwise fit as much as we can without adding an ellipsis. */
l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth, NULL);
str[l_end] = '\0';
if (r_final_len) {
@@ -1640,7 +1640,7 @@ float UI_text_clip_middle_ex(const uiFontStyle *fstyle,
/* Corner case, the str already takes all available mem,
* and the ellipsis chars would actually add more chars.
* Better to just trim one or two letters to the right in this case...
- * Note: with a single-char ellipsis, this should never happen! But better be safe
+ * NOTE: with a single-char ellipsis, this should never happen! But better be safe
* here...
*/
ui_text_clip_right_ex(
@@ -1930,19 +1930,27 @@ static void widget_draw_text_ime_underline(const uiFontStyle *fstyle,
}
#endif /* WITH_INPUT_IME */
-static bool widget_draw_text_underline_calc_center_x(const char *UNUSED(str),
+struct UnderlineData {
+ size_t str_offset; /* The string offset of the underlined character. */
+ int width_px; /* The underline width in pixels. */
+ int r_offset_px[2]; /* Write the X,Y offset here. */
+};
+
+static bool widget_draw_text_underline_calc_position(const char *UNUSED(str),
const size_t str_step_ofs,
const rcti *glyph_step_bounds,
const int UNUSED(glyph_advance_x),
const rctf *glyph_bounds,
- const int glyph_bearing[2],
+ const int UNUSED(glyph_bearing[2]),
void *user_data)
{
- /* The index of the character to get, set to the x-position. */
- int *ul_data = user_data;
- if (ul_data[0] == (int)str_step_ofs) {
- ul_data[1] = glyph_step_bounds->xmin + glyph_bearing[0] +
- (BLI_rctf_size_x(glyph_bounds) / 2.0f);
+ struct UnderlineData *ul_data = user_data;
+ if (ul_data->str_offset == str_step_ofs) {
+ /* Full width of this glyph including both bearings. */
+ const float width = glyph_bounds->xmin + BLI_rctf_size_x(glyph_bounds) + glyph_bounds->xmin;
+ ul_data->r_offset_px[0] = glyph_step_bounds->xmin + ((width - ul_data->width_px) * 0.5f);
+ /* One line-width below the lower glyph bounds. */
+ ul_data->r_offset_px[1] = glyph_bounds->ymin - U.pixelsize;
/* Early exit. */
return false;
}
@@ -1997,14 +2005,15 @@ static void widget_draw_text(const uiFontStyle *fstyle,
drawstr_left_len = INT_MAX;
#ifdef WITH_INPUT_IME
- /* FIXME, IME is modifying 'const char *drawstr! */
+ /* FIXME: IME is modifying `const char *drawstr`! */
ime_data = ui_but_ime_data_get(but);
if (ime_data && ime_data->composite_len) {
/* insert composite string into cursor pos */
BLI_snprintf((char *)drawstr,
UI_MAX_DRAW_STR,
- "%s%s%s",
+ "%.*s%s%s",
+ but->pos,
but->editstr,
ime_data->str_composite,
but->editstr + but->pos);
@@ -2020,8 +2029,11 @@ static void widget_draw_text(const uiFontStyle *fstyle,
/* text button selection, cursor, composite underline */
if (but->editstr && but->pos != -1) {
int but_pos_ofs;
- /* Shape of the cursor for drawing. */
- rcti but_cursor_shape;
+
+#ifdef WITH_INPUT_IME
+ bool ime_reposition_window = false;
+ int ime_win_x, ime_win_y;
+#endif
/* text button selection */
if ((but->selend - but->selsta) > 0) {
@@ -2046,14 +2058,28 @@ static void widget_draw_text(const uiFontStyle *fstyle,
immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ rcti selection_shape;
+ selection_shape.xmin = rect->xmin + selsta_draw;
+ selection_shape.xmax = min_ii(rect->xmin + selwidth_draw, rect->xmax - 2);
+ selection_shape.ymin = rect->ymin + U.pixelsize;
+ selection_shape.ymax = rect->ymax - U.pixelsize;
immUniformColor4ubv(wcol->item);
immRecti(pos,
- rect->xmin + selsta_draw,
- rect->ymin + U.pixelsize,
- min_ii(rect->xmin + selwidth_draw, rect->xmax - 2),
- rect->ymax - U.pixelsize);
+ selection_shape.xmin,
+ selection_shape.ymin,
+ selection_shape.xmax,
+ selection_shape.ymax);
immUnbindProgram();
+
+#ifdef WITH_INPUT_IME
+ /* IME candidate window uses selection position. */
+ if (!ime_reposition_window) {
+ ime_reposition_window = true;
+ ime_win_x = selection_shape.xmin;
+ ime_win_y = selection_shape.ymin;
+ }
+#endif
}
}
@@ -2061,7 +2087,7 @@ static void widget_draw_text(const uiFontStyle *fstyle,
but_pos_ofs = but->pos;
#ifdef WITH_INPUT_IME
- /* if is ime compositing, move the cursor */
+ /* If is IME compositing, move the cursor. */
if (ime_data && ime_data->composite_len && ime_data->cursor_pos != -1) {
but_pos_ofs += ime_data->cursor_pos;
}
@@ -2086,6 +2112,8 @@ static void widget_draw_text(const uiFontStyle *fstyle,
immUniformThemeColor(TH_WIDGET_TEXT_CURSOR);
+ /* Shape of the cursor for drawing. */
+ rcti but_cursor_shape;
but_cursor_shape.xmin = (rect->xmin + t) - U.pixelsize;
but_cursor_shape.ymin = rect->ymin + U.pixelsize;
but_cursor_shape.xmax = (rect->xmin + t) + U.pixelsize;
@@ -2099,16 +2127,24 @@ static void widget_draw_text(const uiFontStyle *fstyle,
but_cursor_shape.ymax);
immUnbindProgram();
- }
#ifdef WITH_INPUT_IME
- if (ime_data && ime_data->composite_len) {
- /* ime cursor following */
- if (but->pos >= but->ofs) {
- ui_but_ime_reposition(but, but_cursor_shape.xmax + 5, but_cursor_shape.ymin + 3, false);
+ /* IME candidate window uses cursor position. */
+ if (!ime_reposition_window) {
+ ime_reposition_window = true;
+ ime_win_x = but_cursor_shape.xmax + 5;
+ ime_win_y = but_cursor_shape.ymin + 3;
}
+#endif
+ }
- /* composite underline */
+#ifdef WITH_INPUT_IME
+ /* IME cursor following. */
+ if (ime_reposition_window) {
+ ui_but_ime_reposition(but, ime_win_x, ime_win_y, false);
+ }
+ if (ime_data && ime_data->composite_len) {
+ /* Composite underline. */
widget_draw_text_ime_underline(fstyle, wcol, but, rect, ime_data, drawstr);
}
#endif
@@ -2123,14 +2159,15 @@ static void widget_draw_text(const uiFontStyle *fstyle,
transopts = ui_translate_buttons();
#endif
+ bool use_drawstr_right_as_hint = false;
+
/* cut string in 2 parts - only for menu entries */
- if ((but->drawflag & UI_BUT_HAS_SHORTCUT) && (but->editstr == NULL)) {
- if (but->flag & UI_BUT_HAS_SEP_CHAR) {
- drawstr_right = strrchr(drawstr, UI_SEP_CHAR);
- if (drawstr_right) {
- drawstr_left_len = (drawstr_right - drawstr);
- drawstr_right++;
- }
+ if (but->flag & UI_BUT_HAS_SEP_CHAR && (but->editstr == NULL)) {
+ drawstr_right = strrchr(drawstr, UI_SEP_CHAR);
+ if (drawstr_right) {
+ use_drawstr_right_as_hint = true;
+ drawstr_left_len = (drawstr_right - drawstr);
+ drawstr_right++;
}
}
@@ -2198,21 +2235,24 @@ static void widget_draw_text(const uiFontStyle *fstyle,
BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
}
- int ul_data[2] = {
- ul_index, /* Character index to test. */
- 0, /* Write the x-offset here. */
+ int ul_width = round_fl_to_int(BLF_width(fstyle->uifont_id, "_", 2));
+
+ struct UnderlineData ul_data = {
+ .str_offset = ul_index,
+ .width_px = ul_width,
};
+
BLF_boundbox_foreach_glyph(fstyle->uifont_id,
drawstr_ofs,
ul_index + 1,
- widget_draw_text_underline_calc_center_x,
- ul_data);
- ul_data[1] -= BLF_width(fstyle->uifont_id, "_", 2) / 2.0f;
-
- BLF_position(fstyle->uifont_id,
- rect->xmin + font_xofs + ul_data[1],
- rect->ymin + font_yofs,
- 0.0f);
+ widget_draw_text_underline_calc_position,
+ &ul_data);
+
+ const int pos_x = rect->xmin + font_xofs + ul_data.r_offset_px[0];
+ const int pos_y = rect->ymin + font_yofs + ul_data.r_offset_px[1];
+
+ /* Use text output because direct drawing doesn't always work. See T89246. */
+ BLF_position(fstyle->uifont_id, pos_x, pos_y, 0.0f);
BLF_color4ubv(fstyle->uifont_id, wcol->text);
BLF_draw(fstyle->uifont_id, "_", 2);
@@ -2228,7 +2268,7 @@ static void widget_draw_text(const uiFontStyle *fstyle,
if (drawstr_right) {
uchar col[4];
copy_v4_v4_uchar(col, wcol->text);
- if (but->drawflag & UI_BUT_HAS_SHORTCUT) {
+ if (use_drawstr_right_as_hint) {
col[3] *= 0.5f;
}
@@ -2480,7 +2520,7 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle,
ui_text_clip_middle(fstyle, but, rect);
}
- /* always draw text for textbutton cursor */
+ /* Always draw text for text-button cursor. */
widget_draw_text(fstyle, wcol, but, rect);
ui_but_text_password_hide(password_str, but, true);
@@ -3075,7 +3115,7 @@ void ui_draw_gradient(const rcti *rect,
copy_v3_v3(col1[3], col1[2]);
break;
default:
- BLI_assert(!"invalid 'type' argument");
+ BLI_assert_msg(0, "invalid 'type' argument");
hsv_to_rgb(1.0, 1.0, 1.0, &col1[2][0], &col1[2][1], &col1[2][2]);
copy_v3_v3(col1[0], col1[2]);
copy_v3_v3(col1[1], col1[2]);
@@ -3476,7 +3516,7 @@ static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
/**
* Draw menu buttons still with triangles when field is not embossed
*/
-static void widget_menubut_embossn(uiBut *UNUSED(but),
+static void widget_menubut_embossn(const uiBut *UNUSED(but),
uiWidgetColors *wcol,
rcti *rect,
int UNUSED(state),
@@ -3499,7 +3539,7 @@ static void widget_menubut_embossn(uiBut *UNUSED(but),
* Draw number buttons still with triangles when field is not embossed
*/
static void widget_numbut_embossn(
- uiBut *UNUSED(but), uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+ const uiBut *UNUSED(but), uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
widget_numbut_draw(wcol, rect, state, roundboxalign, true);
}
@@ -3679,10 +3719,28 @@ static void widget_progressbar(
/* "slider" bar color */
copy_v3_v3_uchar(wcol->inner, wcol->item);
widgetbase_draw(&wtb_bar, wcol);
+}
+
+static void widget_datasetrow(
+ uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign))
+{
+ uiButDatasetRow *but_componentrow = (uiButDatasetRow *)but;
+ uiWidgetBase wtb;
+ widget_init(&wtb);
+
+ /* no outline */
+ wtb.draw_outline = false;
+ const float rad = wcol->roundness * U.widget_unit;
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
+
+ if ((state & UI_ACTIVE) || (state & UI_SELECT)) {
+ widgetbase_draw(&wtb, wcol);
+ }
- /* raise text a bit */
- rect->xmin += (BLI_rcti_size_x(&rect_prog) / 2);
- rect->xmax += (BLI_rcti_size_x(&rect_prog) / 2);
+ BLI_rcti_resize(rect,
+ BLI_rcti_size_x(rect) - UI_UNIT_X * but_componentrow->indentation,
+ BLI_rcti_size_y(rect));
+ BLI_rcti_translate(rect, 0.5f * UI_UNIT_X * but_componentrow->indentation, 0);
}
static void widget_nodesocket(
@@ -4271,7 +4329,7 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
widget_init(&wtb);
if (but->block->drawextra) {
- /* note: drawextra can change rect +1 or -1, to match round errors of existing previews */
+ /* NOTE: drawextra can change rect +1 or -1, to match round errors of existing previews. */
but->block->drawextra(
C, but->poin, but->block->drawextra_arg1, but->block->drawextra_arg2, rect);
@@ -4457,6 +4515,10 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
wt.custom = widget_progressbar;
break;
+ case UI_WTYPE_DATASETROW:
+ wt.custom = widget_datasetrow;
+ break;
+
case UI_WTYPE_NODESOCKET:
wt.custom = widget_nodesocket;
break;
@@ -4780,6 +4842,11 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
fstyle = &style->widgetlabel;
break;
+ case UI_BTYPE_DATASETROW:
+ wt = widget_type(UI_WTYPE_DATASETROW);
+ fstyle = &style->widgetlabel;
+ break;
+
case UI_BTYPE_SCROLL:
wt = widget_type(UI_WTYPE_SCROLL);
break;
@@ -4912,7 +4979,7 @@ void ui_draw_menu_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect)
}
/**
- * Uses the widget base drawing and colors from from the box widget, but ensures an opaque
+ * Uses the widget base drawing and colors from the box widget, but ensures an opaque
* inner color.
*/
void ui_draw_box_opaque(rcti *rect, int roundboxalign)
@@ -5307,7 +5374,7 @@ void ui_draw_menu_item(const uiFontStyle *fstyle,
}
}
else {
- BLI_assert(!"Unknwon menu item separator type");
+ BLI_assert_msg(0, "Unknwon menu item separator type");
}
if (fstyle->kerning == 1) {
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index e4dad0f1a53..e9804840801 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -347,7 +347,7 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
v2d->keeptot = V2D_KEEPTOT_BOUNDS;
- /* note, scroll is being flipped in ED_region_panels() drawing */
+ /* NOTE: scroll is being flipped in #ED_region_panels() drawing. */
v2d->scroll |= (V2D_SCROLL_HORIZONTAL_HIDE | V2D_SCROLL_VERTICAL_HIDE);
if (do_init) {
@@ -535,7 +535,7 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, bool resize)
curRatio = height / width;
winRatio = winy / winx;
- /* both sizes change (area/region maximized) */
+ /* Both sizes change (area/region maximized). */
if (do_x == do_y) {
if (do_x && do_y) {
/* here is 1,1 case, so all others must be 0,0 */
@@ -717,7 +717,7 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, bool resize)
*
* So, resolution is to just shift view by the gap between the extremities.
* We favor moving the 'minimum' across, as that's origin for most things.
- * (XXX - in the past, max was favored... if there are bugs, swap!)
+ * (XXX: in the past, max was favored... if there are bugs, swap!)
*/
if ((cur->xmin < tot->xmin) && (cur->xmax > tot->xmax)) {
/* outside boundaries on both sides,
@@ -991,10 +991,11 @@ void UI_view2d_totRect_set_resize(View2D *v2d, int width, int height, bool resiz
if (ELEM(0, width, height)) {
if (G.debug & G_DEBUG) {
+ /* XXX: temp debug info. */
printf("Error: View2D totRect set exiting: v2d=%p width=%d height=%d\n",
(void *)v2d,
width,
- height); /* XXX temp debug info */
+ height);
}
return;
}
@@ -1058,7 +1059,7 @@ void UI_view2d_zoom_cache_reset(void)
/* While scaling we can accumulate fonts at many sizes (~20 or so).
* Not an issue with embedded font, but can use over 500Mb with i18n ones! See T38244. */
- /* Note: only some views draw text, we could check for this case to avoid cleaning cache. */
+ /* NOTE: only some views draw text, we could check for this case to avoid cleaning cache. */
BLF_cache_clear();
}
@@ -1157,7 +1158,7 @@ void UI_view2d_view_orthoSpecial(ARegion *region, View2D *v2d, const bool xaxis)
* correspondence with pixels for smooth UI drawing,
* but only applied where requested.
*/
- /* XXX temp (ton) */
+ /* XXX(ton): temp. */
xofs = 0.0f; // (v2d->flag & V2D_PIXELOFS_X) ? GLA_PIXEL_OFS : 0.0f;
yofs = 0.0f; // (v2d->flag & V2D_PIXELOFS_Y) ? GLA_PIXEL_OFS : 0.0f;
@@ -1737,15 +1738,15 @@ bool UI_view2d_view_to_region_clip(
void UI_view2d_view_to_region(
const View2D *v2d, float x, float y, int *r_region_x, int *r_region_y)
{
- /* step 1: express given coordinates as proportional values */
+ /* Step 1: express given coordinates as proportional values. */
x = (x - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
y = (y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
- /* step 2: convert proportional distances to screen coordinates */
+ /* Step 2: convert proportional distances to screen coordinates. */
x = v2d->mask.xmin + (x * BLI_rcti_size_x(&v2d->mask));
y = v2d->mask.ymin + (y * BLI_rcti_size_y(&v2d->mask));
- /* although we don't clamp to lie within region bounds, we must avoid exceeding size of ints */
+ /* Although we don't clamp to lie within region bounds, we must avoid exceeding size of ints. */
*r_region_x = clamp_float_to_int(x);
*r_region_y = clamp_float_to_int(y);
}
@@ -1768,13 +1769,13 @@ void UI_view2d_view_to_region_rcti(const View2D *v2d, const rctf *rect_src, rcti
const float mask_size[2] = {BLI_rcti_size_x(&v2d->mask), BLI_rcti_size_y(&v2d->mask)};
rctf rect_tmp;
- /* step 1: express given coordinates as proportional values */
+ /* Step 1: express given coordinates as proportional values. */
rect_tmp.xmin = (rect_src->xmin - v2d->cur.xmin) / cur_size[0];
rect_tmp.xmax = (rect_src->xmax - v2d->cur.xmin) / cur_size[0];
rect_tmp.ymin = (rect_src->ymin - v2d->cur.ymin) / cur_size[1];
rect_tmp.ymax = (rect_src->ymax - v2d->cur.ymin) / cur_size[1];
- /* step 2: convert proportional distances to screen coordinates */
+ /* Step 2: convert proportional distances to screen coordinates. */
rect_tmp.xmin = v2d->mask.xmin + (rect_tmp.xmin * mask_size[0]);
rect_tmp.xmax = v2d->mask.xmin + (rect_tmp.xmax * mask_size[0]);
rect_tmp.ymin = v2d->mask.ymin + (rect_tmp.ymin * mask_size[1]);
@@ -1799,7 +1800,7 @@ bool UI_view2d_view_to_region_rcti_clip(const View2D *v2d, const rctf *rect_src,
BLI_assert(rect_src->xmin <= rect_src->xmax && rect_src->ymin <= rect_src->ymax);
- /* step 1: express given coordinates as proportional values */
+ /* Step 1: express given coordinates as proportional values. */
rect_tmp.xmin = (rect_src->xmin - v2d->cur.xmin) / cur_size[0];
rect_tmp.xmax = (rect_src->xmax - v2d->cur.xmin) / cur_size[0];
rect_tmp.ymin = (rect_src->ymin - v2d->cur.ymin) / cur_size[1];
@@ -1807,7 +1808,7 @@ bool UI_view2d_view_to_region_rcti_clip(const View2D *v2d, const rctf *rect_src,
if (((rect_tmp.xmax < 0.0f) || (rect_tmp.xmin > 1.0f) || (rect_tmp.ymax < 0.0f) ||
(rect_tmp.ymin > 1.0f)) == 0) {
- /* step 2: convert proportional distances to screen coordinates */
+ /* Step 2: convert proportional distances to screen coordinates. */
rect_tmp.xmin = v2d->mask.xmin + (rect_tmp.xmin * mask_size[0]);
rect_tmp.xmax = v2d->mask.ymin + (rect_tmp.xmax * mask_size[0]);
rect_tmp.ymin = v2d->mask.ymin + (rect_tmp.ymin * mask_size[1]);
@@ -1843,7 +1844,7 @@ View2D *UI_view2d_fromcontext(const bContext *C)
return &(region->v2d);
}
-/* same as above, but it returns regionwindow. Utility for pulldowns or buttons */
+/* Same as above, but it returns region-window. Utility for pull-downs or buttons. */
View2D *UI_view2d_fromcontext_rwin(const bContext *C)
{
ScrArea *area = CTX_wm_area(C);
diff --git a/source/blender/editors/interface/view2d_draw.c b/source/blender/editors/interface/view2d_draw.c
index 5801b7cdbdb..f7ef8c06389 100644
--- a/source/blender/editors/interface/view2d_draw.c
+++ b/source/blender/editors/interface/view2d_draw.c
@@ -216,7 +216,7 @@ static void draw_parallel_lines(const ParallelLinesSet *lines,
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
immUniform2fv("viewportSize", &viewport[2]);
/* -1.0f offset here is because the line is too fat due to the builtin anti-aliasing.
- * TODO make a variant or a uniform to toggle it off. */
+ * TODO: make a variant or a uniform to toggle it off. */
immUniform1f("lineWidth", U.pixelsize - 1.0f);
}
else {
diff --git a/source/blender/editors/interface/view2d_edge_pan.c b/source/blender/editors/interface/view2d_edge_pan.c
new file mode 100644
index 00000000000..1d300c7b275
--- /dev/null
+++ b/source/blender/editors/interface/view2d_edge_pan.c
@@ -0,0 +1,345 @@
+/*
+ * 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) 2021 Blender Foundation
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup spnode
+ */
+
+#include "BKE_context.h"
+
+#include "BLI_math.h"
+#include "BLI_rect.h"
+
+#include "ED_screen.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "PIL_time.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_interface.h"
+#include "UI_view2d.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Edge Pan Operator Utilities
+ * \{ */
+
+bool UI_view2d_edge_pan_poll(bContext *C)
+{
+ ARegion *region = CTX_wm_region(C);
+
+ /* Check if there's a region in context to work with. */
+ if (region == NULL) {
+ return false;
+ }
+
+ View2D *v2d = &region->v2d;
+
+ /* Check that 2d-view can pan. */
+ if ((v2d->keepofs & V2D_LOCKOFS_X) && (v2d->keepofs & V2D_LOCKOFS_Y)) {
+ return false;
+ }
+
+ /* View can pan. */
+ return true;
+}
+
+void UI_view2d_edge_pan_init(bContext *C,
+ View2DEdgePanData *vpd,
+ float inside_pad,
+ float outside_pad,
+ float speed_ramp,
+ float max_speed,
+ float delay)
+{
+ if (!UI_view2d_edge_pan_poll(C)) {
+ return;
+ }
+
+ /* Set pointers to owners. */
+ vpd->screen = CTX_wm_screen(C);
+ vpd->area = CTX_wm_area(C);
+ vpd->region = CTX_wm_region(C);
+ vpd->v2d = &vpd->region->v2d;
+
+ BLI_assert(speed_ramp > 0.0f);
+ vpd->inside_pad = inside_pad;
+ vpd->outside_pad = outside_pad;
+ vpd->speed_ramp = speed_ramp;
+ vpd->max_speed = max_speed;
+ vpd->delay = delay;
+
+ /* Calculate translation factor, based on size of view. */
+ const float winx = (float)(BLI_rcti_size_x(&vpd->region->winrct) + 1);
+ const float winy = (float)(BLI_rcti_size_y(&vpd->region->winrct) + 1);
+ vpd->facx = (BLI_rctf_size_x(&vpd->v2d->cur)) / winx;
+ vpd->facy = (BLI_rctf_size_y(&vpd->v2d->cur)) / winy;
+
+ UI_view2d_edge_pan_reset(vpd);
+}
+
+void UI_view2d_edge_pan_reset(View2DEdgePanData *vpd)
+{
+ vpd->edge_pan_start_time_x = 0.0;
+ vpd->edge_pan_start_time_y = 0.0;
+ vpd->edge_pan_last_time = PIL_check_seconds_timer();
+}
+
+/**
+ * Reset the edge pan timers if the mouse isn't in the scroll zone and
+ * start the timers when the mouse enters a scroll zone.
+ */
+static void edge_pan_manage_delay_timers(View2DEdgePanData *vpd,
+ int pan_dir_x,
+ int pan_dir_y,
+ const double current_time)
+{
+ if (pan_dir_x == 0) {
+ vpd->edge_pan_start_time_x = 0.0;
+ }
+ else if (vpd->edge_pan_start_time_x == 0.0) {
+ vpd->edge_pan_start_time_x = current_time;
+ }
+ if (pan_dir_y == 0) {
+ vpd->edge_pan_start_time_y = 0.0;
+ }
+ else if (vpd->edge_pan_start_time_y == 0.0) {
+ vpd->edge_pan_start_time_y = current_time;
+ }
+}
+
+/**
+ * Used to calculate a "fade in" factor for edge panning to make the interaction feel smooth
+ * and more purposeful.
+ *
+ * \note Assumes a domain_min of 0.0f.
+ */
+static float smootherstep(const float domain_max, float x)
+{
+ x = clamp_f(x / domain_max, 0.0, 1.0);
+ return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
+}
+
+static float edge_pan_speed(View2DEdgePanData *vpd,
+ int event_loc,
+ bool x_dir,
+ const double current_time)
+{
+ ARegion *region = vpd->region;
+
+ /* Find the distance from the start of the drag zone. */
+ const int pad = vpd->inside_pad * U.widget_unit;
+ const int min = (x_dir ? region->winrct.xmin : region->winrct.ymin) + pad;
+ const int max = (x_dir ? region->winrct.xmax : region->winrct.ymax) - pad;
+ int distance = 0.0;
+ if (event_loc > max) {
+ distance = event_loc - max;
+ }
+ else if (event_loc < min) {
+ distance = min - event_loc;
+ }
+ else {
+ BLI_assert_msg(0, "Calculating speed outside of pan zones");
+ return 0.0f;
+ }
+ float distance_factor = distance / (vpd->speed_ramp * U.widget_unit);
+ CLAMP(distance_factor, 0.0f, 1.0f);
+
+ /* Apply a fade in to the speed based on a start time delay. */
+ const double start_time = x_dir ? vpd->edge_pan_start_time_x : vpd->edge_pan_start_time_y;
+ const float delay_factor = smootherstep(vpd->delay, (float)(current_time - start_time));
+
+ return distance_factor * delay_factor * vpd->max_speed * U.widget_unit * (float)U.dpi_fac;
+}
+
+static void edge_pan_apply_delta(bContext *C, View2DEdgePanData *vpd, float dx, float dy)
+{
+ View2D *v2d = vpd->v2d;
+ if (!v2d) {
+ return;
+ }
+
+ /* Calculate amount to move view by. */
+ dx *= vpd->facx;
+ dy *= vpd->facy;
+
+ /* Only move view on an axis if change is allowed. */
+ if ((v2d->keepofs & V2D_LOCKOFS_X) == 0) {
+ v2d->cur.xmin += dx;
+ v2d->cur.xmax += dx;
+ }
+ if ((v2d->keepofs & V2D_LOCKOFS_Y) == 0) {
+ v2d->cur.ymin += dy;
+ v2d->cur.ymax += dy;
+ }
+
+ /* Inform v2d about changes after this operation. */
+ UI_view2d_curRect_changed(C, v2d);
+
+ /* Don't rebuild full tree in outliner, since we're just changing our view. */
+ ED_region_tag_redraw_no_rebuild(vpd->region);
+
+ /* Request updates to be done. */
+ WM_event_add_mousemove(CTX_wm_window(C));
+
+ UI_view2d_sync(vpd->screen, vpd->area, v2d, V2D_LOCK_COPY);
+}
+
+void UI_view2d_edge_pan_apply(bContext *C, View2DEdgePanData *vpd, int x, int y)
+{
+ ARegion *region = vpd->region;
+
+ rcti inside_rect, outside_rect;
+ inside_rect = region->winrct;
+ outside_rect = region->winrct;
+ BLI_rcti_pad(&inside_rect, -vpd->inside_pad * U.widget_unit, -vpd->inside_pad * U.widget_unit);
+ BLI_rcti_pad(&outside_rect, vpd->outside_pad * U.widget_unit, vpd->outside_pad * U.widget_unit);
+
+ int pan_dir_x = 0;
+ int pan_dir_y = 0;
+ if ((vpd->outside_pad == 0) || BLI_rcti_isect_pt(&outside_rect, x, y)) {
+ /* Find whether the mouse is beyond X and Y edges. */
+ if (x > inside_rect.xmax) {
+ pan_dir_x = 1;
+ }
+ else if (x < inside_rect.xmin) {
+ pan_dir_x = -1;
+ }
+ if (y > inside_rect.ymax) {
+ pan_dir_y = 1;
+ }
+ else if (y < inside_rect.ymin) {
+ pan_dir_y = -1;
+ }
+ }
+
+ const double current_time = PIL_check_seconds_timer();
+ edge_pan_manage_delay_timers(vpd, pan_dir_x, pan_dir_y, current_time);
+
+ /* Calculate the delta since the last time the operator was called. */
+ const float dtime = (float)(current_time - vpd->edge_pan_last_time);
+ float dx = 0.0f, dy = 0.0f;
+ if (pan_dir_x != 0) {
+ const float speed = edge_pan_speed(vpd, x, true, current_time);
+ dx = dtime * speed * (float)pan_dir_x;
+ }
+ if (pan_dir_y != 0) {
+ const float speed = edge_pan_speed(vpd, y, false, current_time);
+ dy = dtime * speed * (float)pan_dir_y;
+ }
+ vpd->edge_pan_last_time = current_time;
+
+ /* Pan, clamping inside the regions total bounds. */
+ edge_pan_apply_delta(C, vpd, dx, dy);
+}
+
+void UI_view2d_edge_pan_apply_event(bContext *C, View2DEdgePanData *vpd, const wmEvent *event)
+{
+ /* Only mouse-move events matter here, ignore others. */
+ if (event->type != MOUSEMOVE) {
+ return;
+ }
+
+ UI_view2d_edge_pan_apply(C, vpd, event->x, event->y);
+}
+
+void UI_view2d_edge_pan_operator_properties(wmOperatorType *ot)
+{
+ /* Default values for edge panning operators. */
+ UI_view2d_edge_pan_operator_properties_ex(ot,
+ /*inside_pad*/ 1.0f,
+ /*outside_pad*/ 0.0f,
+ /*speed_ramp*/ 1.0f,
+ /*max_speed*/ 500.0f,
+ /*delay*/ 1.0f);
+}
+
+void UI_view2d_edge_pan_operator_properties_ex(struct wmOperatorType *ot,
+ float inside_pad,
+ float outside_pad,
+ float speed_ramp,
+ float max_speed,
+ float delay)
+{
+ RNA_def_float(
+ ot->srna,
+ "inside_padding",
+ inside_pad,
+ 0.0f,
+ 100.0f,
+ "Inside Padding",
+ "Inside distance in UI units from the edge of the region within which to start panning",
+ 0.0f,
+ 100.0f);
+ RNA_def_float(
+ ot->srna,
+ "outside_padding",
+ outside_pad,
+ 0.0f,
+ 100.0f,
+ "Outside Padding",
+ "Outside distance in UI units from the edge of the region at which to stop panning",
+ 0.0f,
+ 100.0f);
+ RNA_def_float(ot->srna,
+ "speed_ramp",
+ speed_ramp,
+ 0.0f,
+ 100.0f,
+ "Speed Ramp",
+ "Width of the zone in UI units where speed increases with distance from the edge",
+ 0.0f,
+ 100.0f);
+ RNA_def_float(ot->srna,
+ "max_speed",
+ max_speed,
+ 0.0f,
+ 10000.0f,
+ "Max Speed",
+ "Maximum speed in UI units per second",
+ 0.0f,
+ 10000.0f);
+ RNA_def_float(ot->srna,
+ "delay",
+ delay,
+ 0.0f,
+ 10.0f,
+ "Delay",
+ "Delay in seconds before maximum speed is reached",
+ 0.0f,
+ 10.0f);
+}
+
+void UI_view2d_edge_pan_operator_init(bContext *C, View2DEdgePanData *vpd, wmOperator *op)
+{
+ UI_view2d_edge_pan_init(C,
+ vpd,
+ RNA_float_get(op->ptr, "inside_padding"),
+ RNA_float_get(op->ptr, "outside_padding"),
+ RNA_float_get(op->ptr, "speed_ramp"),
+ RNA_float_get(op->ptr, "max_speed"),
+ RNA_float_get(op->ptr, "delay"));
+}
+
+/** \} */
diff --git a/source/blender/editors/interface/view2d_gizmo_navigate.c b/source/blender/editors/interface/view2d_gizmo_navigate.c
index 8d3f1beb947..30b4a7c097a 100644
--- a/source/blender/editors/interface/view2d_gizmo_navigate.c
+++ b/source/blender/editors/interface/view2d_gizmo_navigate.c
@@ -113,7 +113,7 @@ static struct NavigateGizmoInfo *navigate_params_from_space_type(short space_typ
case SPACE_CLIP:
return g_navigate_params_for_space_clip;
default:
- /* Used for sequencer. */
+ /* Used for sequencer. */
return g_navigate_params_for_view2d;
}
}
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 7453cd17868..1fd1b6c984d 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -187,7 +187,7 @@ static void view_pan_apply(bContext *C, wmOperator *op)
view_pan_apply_ex(C, vpd, RNA_int_get(op->ptr, "deltax"), RNA_int_get(op->ptr, "deltay"));
}
-/* cleanup temp customdata */
+/* Cleanup temp custom-data. */
static void view_pan_exit(wmOperator *op)
{
MEM_SAFE_FREE(op->customdata);
@@ -271,7 +271,7 @@ static int view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event)
view_pan_apply(C, op);
break;
}
- /* XXX - Mode switching isn't implemented. See comments in 36818.
+ /* XXX: Mode switching isn't implemented. See comments in 36818.
* switch to zoom */
#if 0
case LEFTMOUSE:
@@ -341,162 +341,37 @@ static void VIEW2D_OT_pan(wmOperatorType *ot)
* passes through.
* \{ */
-/** Distance from the edge of the region within which to start panning. */
-#define EDGE_PAN_REGION_PAD (U.widget_unit)
-/** Speed factor in pixels per second per pixel of distance from edge pan zone beginning. */
-#define EDGE_PAN_SPEED_PER_PIXEL (25.0f * (float)U.dpi_fac)
-/** Delay before drag panning in seconds. */
-#define EDGE_PAN_DELAY 1.0f
-
/* set up modal operator and relevant settings */
static int view_edge_pan_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- /* Set up customdata. */
- view_pan_init(C, op);
-
- v2dViewPanData *vpd = op->customdata;
-
- vpd->edge_pan_start_time_x = 0.0;
- vpd->edge_pan_start_time_y = 0.0;
- vpd->edge_pan_last_time = PIL_check_seconds_timer();
+ op->customdata = MEM_callocN(sizeof(View2DEdgePanData), "View2DEdgePanData");
+ View2DEdgePanData *vpd = op->customdata;
+ UI_view2d_edge_pan_operator_init(C, vpd, op);
WM_event_add_modal_handler(C, op);
return (OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH);
}
-/**
- * Reset the edge pan timers if the mouse isn't in the scroll zone and
- * start the timers when the mouse enters a scroll zone.
- */
-static void edge_pan_manage_delay_timers(v2dViewPanData *vpd,
- int pan_dir_x,
- int pan_dir_y,
- const double current_time)
-{
- if (pan_dir_x == 0) {
- vpd->edge_pan_start_time_x = 0.0;
- }
- else if (vpd->edge_pan_start_time_x == 0.0) {
- vpd->edge_pan_start_time_x = current_time;
- }
- if (pan_dir_y == 0) {
- vpd->edge_pan_start_time_y = 0.0;
- }
- else if (vpd->edge_pan_start_time_y == 0.0) {
- vpd->edge_pan_start_time_y = current_time;
- }
-}
-
-/**
- * Used to calculate a "fade in" factor for edge panning to make the interaction feel smooth
- * and more purposeful.
- *
- * \note Assumes a domain_min of 0.0f.
- */
-static float smootherstep(const float domain_max, float x)
-{
- x = clamp_f(x / domain_max, 0.0, 1.0);
- return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
-}
-
-static float edge_pan_speed(v2dViewPanData *vpd,
- int event_loc,
- bool x_dir,
- const double current_time)
-{
- ARegion *region = vpd->region;
-
- /* Find the distance from the start of the drag zone. */
- const int min = (x_dir ? region->winrct.xmin : region->winrct.ymin) + EDGE_PAN_REGION_PAD;
- const int max = (x_dir ? region->winrct.xmax : region->winrct.ymax) - EDGE_PAN_REGION_PAD;
- int distance = 0.0;
- if (event_loc > max) {
- distance = event_loc - max;
- }
- else if (event_loc < min) {
- distance = min - event_loc;
- }
- else {
- BLI_assert(!"Calculating speed outside of pan zones");
- return 0.0f;
- }
-
- /* Apply a fade in to the speed based on a start time delay. */
- const double start_time = x_dir ? vpd->edge_pan_start_time_x : vpd->edge_pan_start_time_y;
- const float delay_factor = smootherstep(EDGE_PAN_DELAY, (float)(current_time - start_time));
-
- return distance * EDGE_PAN_SPEED_PER_PIXEL * delay_factor;
-}
-
static int view_edge_pan_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- v2dViewPanData *vpd = op->customdata;
- ARegion *region = vpd->region;
+ View2DEdgePanData *vpd = op->customdata;
if (event->val == KM_RELEASE || event->type == EVT_ESCKEY) {
- view_pan_exit(op);
+ MEM_SAFE_FREE(op->customdata);
return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
}
- /* Only mousemove events matter here, ignore others. */
- if (event->type != MOUSEMOVE) {
- return OPERATOR_PASS_THROUGH;
- }
+
+ UI_view2d_edge_pan_apply_event(C, vpd, event);
/* This operator is supposed to run together with some drag action.
* On successful handling, always pass events on to other handlers. */
- const int success_retval = OPERATOR_PASS_THROUGH;
-
- const int outside_padding = RNA_int_get(op->ptr, "outside_padding") * UI_UNIT_X;
- rcti padding_rect;
- if (outside_padding != 0) {
- padding_rect = region->winrct;
- BLI_rcti_pad(&padding_rect, outside_padding, outside_padding);
- }
-
- int pan_dir_x = 0;
- int pan_dir_y = 0;
- if ((outside_padding == 0) || BLI_rcti_isect_pt(&padding_rect, event->x, event->y)) {
- /* Find whether the mouse is beyond X and Y edges. */
- if (event->x > region->winrct.xmax - EDGE_PAN_REGION_PAD) {
- pan_dir_x = 1;
- }
- else if (event->x < region->winrct.xmin + EDGE_PAN_REGION_PAD) {
- pan_dir_x = -1;
- }
- if (event->y > region->winrct.ymax - EDGE_PAN_REGION_PAD) {
- pan_dir_y = 1;
- }
- else if (event->y < region->winrct.ymin + EDGE_PAN_REGION_PAD) {
- pan_dir_y = -1;
- }
- }
-
- const double current_time = PIL_check_seconds_timer();
- edge_pan_manage_delay_timers(vpd, pan_dir_x, pan_dir_y, current_time);
-
- /* Calculate the delta since the last time the operator was called. */
- const float dtime = (float)(current_time - vpd->edge_pan_last_time);
- float dx = 0.0f, dy = 0.0f;
- if (pan_dir_x != 0) {
- const float speed = edge_pan_speed(vpd, event->x, true, current_time);
- dx = dtime * speed * (float)pan_dir_x;
- }
- if (pan_dir_y != 0) {
- const float speed = edge_pan_speed(vpd, event->y, false, current_time);
- dy = dtime * speed * (float)pan_dir_y;
- }
- vpd->edge_pan_last_time = current_time;
-
- /* Pan, clamping inside the regions's total bounds. */
- view_pan_apply_ex(C, vpd, dx, dy);
-
- return success_retval;
+ return OPERATOR_PASS_THROUGH;
}
static void view_edge_pan_cancel(bContext *UNUSED(C), wmOperator *op)
{
- view_pan_exit(op);
+ MEM_SAFE_FREE(op->customdata);
}
static void VIEW2D_OT_edge_pan(wmOperatorType *ot)
@@ -510,26 +385,13 @@ static void VIEW2D_OT_edge_pan(wmOperatorType *ot)
ot->invoke = view_edge_pan_invoke;
ot->modal = view_edge_pan_modal;
ot->cancel = view_edge_pan_cancel;
- ot->poll = view_pan_poll;
+ ot->poll = UI_view2d_edge_pan_poll;
/* operator is modal */
ot->flag = OPTYPE_INTERNAL;
- RNA_def_int(ot->srna,
- "outside_padding",
- 0,
- 0,
- 100,
- "Outside Padding",
- "Padding around the region in UI units within which panning is activated (0 to "
- "disable boundary)",
- 0,
- 100);
+ UI_view2d_edge_pan_operator_properties(ot);
}
-#undef EDGE_PAN_REGION_PAD
-#undef EDGE_PAN_SPEED_PER_PIXEL
-#undef EDGE_PAN_DELAY
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -757,7 +619,7 @@ typedef struct v2dViewZoomData {
} v2dViewZoomData;
/**
- * Clamp by convention rather then locking flags,
+ * Clamp by convention rather than locking flags,
* for ndof and +/- keys
*/
static void view_zoom_axis_lock_defaults(bContext *C, bool r_do_zoom_xy[2])
@@ -943,7 +805,7 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op)
/** \name View Zoom Operator (single step)
* \{ */
-/* cleanup temp customdata */
+/* Cleanup temp custom-data. */
static void view_zoomstep_exit(wmOperator *op)
{
UI_view2d_zoom_cache_reset();
@@ -1172,7 +1034,7 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
}
-/* cleanup temp customdata */
+/* Cleanup temp custom-data. */
static void view_zoomdrag_exit(bContext *C, wmOperator *op)
{
UI_view2d_zoom_cache_reset();
@@ -1665,7 +1527,7 @@ struct SmoothView2DStore {
/**
* function to get a factor out of a rectangle
*
- * note: this doesn't always work as well as it might because the target size
+ * NOTE: this doesn't always work as well as it might because the target size
* may not be reached because of clamping the desired rect, we _could_
* attempt to clamp the rect before working out the zoom factor but its
* not really worthwhile for the few cases this happens.
@@ -1883,7 +1745,7 @@ typedef struct v2dScrollerMove {
* This is a CUT DOWN VERSION of the 'real' version, which is defined in view2d.c,
* as we only need focus bubble info.
*
- * \warning: The start of this struct must not change,
+ * \warning The start of this struct must not change,
* so that it stays in sync with the 'real' version.
* For now, we don't need to have a separate (internal) header for structs like this...
*/
@@ -2052,7 +1914,7 @@ static void scroller_activate_init(bContext *C,
ED_region_tag_redraw_no_rebuild(region);
}
-/* cleanup temp customdata */
+/* Cleanup temp custom-data. */
static void scroller_activate_exit(bContext *C, wmOperator *op)
{
if (op->customdata) {
@@ -2194,7 +2056,7 @@ static int scroller_activate_modal(bContext *C, wmOperator *op, const wmEvent *e
return OPERATOR_FINISHED;
}
- /* otherwise, end the drag action */
+ /* Otherwise, end the drag action. */
if (vsm->lastx || vsm->lasty) {
scroller_activate_exit(C, op);
return OPERATOR_FINISHED;
@@ -2270,7 +2132,7 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, const wmEvent *
scroller_activate_exit(C, op);
/* can't catch this event for ourselves, so let it go to someone else? */
- /* XXX note: if handlers use mask rect to clip input, input will fail for this case */
+ /* XXX NOTE: if handlers use mask rect to clip input, input will fail for this case. */
return OPERATOR_PASS_THROUGH;
}
diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c
index 28838d677f0..12890552b1d 100644
--- a/source/blender/editors/io/io_alembic.c
+++ b/source/blender/editors/io/io_alembic.c
@@ -63,10 +63,26 @@
# include "WM_api.h"
# include "WM_types.h"
+# include "DEG_depsgraph.h"
+
# include "io_alembic.h"
# include "ABC_alembic.h"
+const EnumPropertyItem rna_enum_abc_export_evaluation_mode_items[] = {
+ {DAG_EVAL_RENDER,
+ "RENDER",
+ 0,
+ "Render",
+ "Use Render settings for object visibility, modifier settings, etc"},
+ {DAG_EVAL_VIEWPORT,
+ "VIEWPORT",
+ 0,
+ "Viewport",
+ "Use Viewport settings for object visibility, modifier settings, etc"},
+ {0, NULL, 0, NULL, NULL},
+};
+
static int wm_alembic_export_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!RNA_struct_property_is_set(op->ptr, "as_background_job")) {
@@ -126,7 +142,6 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op)
.curves_as_mesh = RNA_boolean_get(op->ptr, "curves_as_mesh"),
.flatten_hierarchy = RNA_boolean_get(op->ptr, "flatten"),
.visible_objects_only = RNA_boolean_get(op->ptr, "visible_objects_only"),
- .renderable_only = RNA_boolean_get(op->ptr, "renderable_only"),
.face_sets = RNA_boolean_get(op->ptr, "face_sets"),
.use_subdiv_schema = RNA_boolean_get(op->ptr, "subdiv_schema"),
.export_hair = RNA_boolean_get(op->ptr, "export_hair"),
@@ -137,6 +152,7 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op)
.triangulate = RNA_boolean_get(op->ptr, "triangulate"),
.quad_method = RNA_enum_get(op->ptr, "quad_method"),
.ngon_method = RNA_enum_get(op->ptr, "ngon_method"),
+ .evaluation_mode = RNA_enum_get(op->ptr, "evaluation_mode"),
.global_scale = RNA_float_get(op->ptr, "global_scale"),
};
@@ -194,9 +210,11 @@ static void ui_alembic_export_settings(uiLayout *layout, PointerRNA *imfptr)
sub = uiLayoutColumnWithHeading(col, true, IFACE_("Only"));
uiItemR(sub, imfptr, "selected", 0, IFACE_("Selected Objects"), ICON_NONE);
- uiItemR(sub, imfptr, "renderable_only", 0, IFACE_("Renderable Objects"), ICON_NONE);
uiItemR(sub, imfptr, "visible_objects_only", 0, IFACE_("Visible Objects"), ICON_NONE);
+ col = uiLayoutColumn(box, true);
+ uiItemR(col, imfptr, "evaluation_mode", 0, NULL, ICON_NONE);
+
/* Object Data */
box = uiLayoutBox(layout);
row = uiLayoutRow(box, false);
@@ -355,12 +373,6 @@ void WM_OT_alembic_export(wmOperatorType *ot)
ot->srna, "selected", 0, "Selected Objects Only", "Export only selected objects");
RNA_def_boolean(ot->srna,
- "renderable_only",
- 1,
- "Renderable Objects Only",
- "Export only objects marked renderable in the outliner");
-
- RNA_def_boolean(ot->srna,
"visible_objects_only",
0,
"Visible Objects Only",
@@ -468,6 +480,14 @@ void WM_OT_alembic_export(wmOperatorType *ot)
"This option is deprecated; EXECUTE this operator to run in the foreground, and INVOKE it "
"to run as a background job");
+ RNA_def_enum(ot->srna,
+ "evaluation_mode",
+ rna_enum_abc_export_evaluation_mode_items,
+ DAG_EVAL_RENDER,
+ "Use Settings for",
+ "Determines visibility of objects, modifier settings, and other areas where there "
+ "are different settings for viewport and rendering");
+
/* This dummy prop is used to check whether we need to init the start and
* end frame values to that of the scene's, otherwise they are reset at
* every change, draw update. */
diff --git a/source/blender/editors/lattice/editlattice_select.c b/source/blender/editors/lattice/editlattice_select.c
index cb3f9a89e62..e6f190f335b 100644
--- a/source/blender/editors/lattice/editlattice_select.c
+++ b/source/blender/editors/lattice/editlattice_select.c
@@ -108,9 +108,9 @@ bool ED_lattice_deselect_all_multi(struct bContext *C)
static int lattice_select_random_exec(bContext *C, wmOperator *op)
{
+ const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
- const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
@@ -119,29 +119,36 @@ static int lattice_select_random_exec(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt;
+ int seed_iter = seed;
- RNG *rng = BLI_rng_new_srandom(seed);
+ /* This gives a consistent result regardless of object order. */
+ if (ob_index) {
+ seed_iter += BLI_ghashutil_strhash_p(obedit->id.name);
+ }
- int tot;
- BPoint *bp;
+ int a = lt->pntsu * lt->pntsv * lt->pntsw;
+ int elem_map_len = 0;
+ BPoint **elem_map = MEM_mallocN(sizeof(*elem_map) * a, __func__);
+ BPoint *bp = lt->def;
- tot = lt->pntsu * lt->pntsv * lt->pntsw;
- bp = lt->def;
- while (tot--) {
+ while (a--) {
if (!bp->hide) {
- if (BLI_rng_get_float(rng) < randfac) {
- bpoint_select_set(bp, select);
- }
+ elem_map[elem_map_len++] = bp;
}
bp++;
}
+ BLI_array_randomize(elem_map, sizeof(*elem_map), elem_map_len, seed_iter);
+ const int count_select = elem_map_len * randfac;
+ for (int i = 0; i < count_select; i++) {
+ bpoint_select_set(elem_map[i], select);
+ }
+ MEM_freeN(elem_map);
+
if (select == false) {
lt->actbp = LT_ACTBP_NONE;
}
- BLI_rng_free(rng);
-
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
@@ -229,7 +236,7 @@ static int lattice_select_mirror_exec(bContext *C, wmOperator *op)
}
}
- /* TODO, only notify changes */
+ /* TODO: only notify changes. */
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
@@ -507,7 +514,7 @@ static int lattice_select_ungrouped_exec(bContext *C, wmOperator *op)
BPoint *bp;
int a, tot;
- if (BLI_listbase_is_empty(&obedit->defbase) || lt->dvert == NULL) {
+ if (BLI_listbase_is_empty(&lt->vertex_group_names) || lt->dvert == NULL) {
continue;
}
diff --git a/source/blender/editors/lattice/editlattice_undo.c b/source/blender/editors/lattice/editlattice_undo.c
index d92a81179cc..23eaf991fd3 100644
--- a/source/blender/editors/lattice/editlattice_undo.c
+++ b/source/blender/editors/lattice/editlattice_undo.c
@@ -240,7 +240,7 @@ static void lattice_undosys_step_decode(struct bContext *C,
}
undolatt_to_editlatt(&elem->data, lt->editlatt);
lt->editlatt->needs_flush_to_id = 1;
- DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(&lt->id, ID_RECALC_GEOMETRY);
}
/* The first element is always active */
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index 36edbbe31d6..880d27e1615 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -145,7 +145,7 @@ static void setup_vertex_point(Mask *mask,
/* parent */
reference_parent_point = close_point;
- /* note, we may want to copy other attributes later, radius? pressure? color? */
+ /* NOTE: we may want to copy other attributes later, radius? pressure? color? */
}
}
@@ -189,7 +189,7 @@ static void finSelectedSplinePoint(MaskLayer *mask_layer,
*point = NULL;
if (check_active) {
- /* TODO, having an active point but no active spline is possible, why? */
+ /* TODO: having an active point but no active spline is possible, why? */
if (mask_layer->act_spline && mask_layer->act_point &&
MASKPOINT_ISSEL_ANY(mask_layer->act_point)) {
*spline = mask_layer->act_spline;
@@ -277,7 +277,7 @@ static bool add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2
setup_vertex_point(mask, spline, new_point, co, u, ctime, NULL, true);
- /* TODO - we could pass the spline! */
+ /* TODO: we could pass the spline! */
BKE_mask_layer_shape_changed_add(mask_layer,
BKE_mask_layer_shape_spline_to_index(mask_layer, spline) +
point_index + 1,
@@ -479,7 +479,7 @@ static int add_vertex_handle_cyclic_at_point(bContext *C,
spline->flag |= MASK_SPLINE_CYCLIC;
- /* TODO, update keyframes in time. */
+ /* TODO: update keyframes in time. */
BKE_mask_calc_handle_point_auto(spline, active_point, false);
BKE_mask_calc_handle_point_auto(spline, other_point, false);
@@ -526,7 +526,7 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
float co[2];
RNA_float_get_array(op->ptr, "location", co);
- /* TODO, having an active point but no active spline is possible, why? */
+ /* TODO: having an active point but no active spline is possible, why? */
if (mask_layer && mask_layer->act_spline && mask_layer->act_point &&
MASKPOINT_ISSEL_ANY(mask_layer->act_point)) {
MaskSpline *spline = mask_layer->act_spline;
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index d3fa0e93597..de8ea8e21eb 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -211,7 +211,7 @@ static void draw_spline_points(const bContext *C,
undistort = sc->clip && (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT);
}
- /* TODO, add this to sequence editor */
+ /* TODO: add this to sequence editor. */
float handle_size = 2.0f * UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) * U.pixelsize;
mask_spline_color_get(mask_layer, spline, is_spline_sel, rgb_spline);
diff --git a/source/blender/editors/mask/mask_editaction.c b/source/blender/editors/mask/mask_editaction.c
index 1792f0e13bc..d9efbef4b42 100644
--- a/source/blender/editors/mask/mask_editaction.c
+++ b/source/blender/editors/mask/mask_editaction.c
@@ -109,7 +109,7 @@ void ED_masklayer_make_cfra_list(MaskLayer *mask_layer, ListBase *elems, bool on
/* Selection Tools */
/* check if one of the frames in this layer is selected */
-bool ED_masklayer_frame_select_check(MaskLayer *mask_layer)
+bool ED_masklayer_frame_select_check(const MaskLayer *mask_layer)
{
MaskLayerShape *mask_layer_shape;
@@ -283,25 +283,25 @@ void ED_masklayer_frames_duplicate(MaskLayer *mask_layer)
{
MaskLayerShape *mask_layer_shape, *gpfn;
- /* error checking */
+ /* Error checking. */
if (mask_layer == NULL) {
return;
}
- /* duplicate selected frames */
+ /* Duplicate selected frames. */
for (mask_layer_shape = mask_layer->splines_shapes.first; mask_layer_shape;
mask_layer_shape = gpfn) {
gpfn = mask_layer_shape->next;
- /* duplicate this frame */
+ /* Duplicate this frame. */
if (mask_layer_shape->flag & MASK_SHAPE_SELECT) {
MaskLayerShape *mask_shape_dupe;
- /* duplicate frame, and deselect self */
+ /* Duplicate frame, and deselect self. */
mask_shape_dupe = BKE_mask_layer_shape_duplicate(mask_layer_shape);
mask_layer_shape->flag &= ~MASK_SHAPE_SELECT;
- /* XXX - how to handle duplicate frames? */
+ /* XXX: how to handle duplicate frames? */
BLI_insertlinkafter(&mask_layer->splines_shapes, mask_layer_shape, mask_shape_dupe);
}
}
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 1a6ac8597ae..6fa7457ce14 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -83,7 +83,9 @@ Mask *ED_mask_new(bContext *C, const char *name)
return mask;
}
-/* Get ative layer. Will create mask/layer to be sure there's an active layer. */
+/**
+ * Get active layer. Will create mask/layer to be sure there's an active layer.
+ */
MaskLayer *ED_mask_layer_ensure(bContext *C, bool *r_added_mask)
{
Mask *mask = CTX_data_edit_mask(C);
@@ -388,7 +390,7 @@ static void select_sliding_point(Mask *mask,
point->bezt.f3 |= SELECT;
break;
default:
- BLI_assert(!"Unexpected situation in select_sliding_point()");
+ BLI_assert_msg(0, "Unexpected situation in select_sliding_point()");
}
mask_layer->act_spline = spline;
diff --git a/source/blender/editors/mask/mask_query.c b/source/blender/editors/mask/mask_query.c
index 401b6eac4f2..cd51026d20c 100644
--- a/source/blender/editors/mask/mask_query.c
+++ b/source/blender/editors/mask/mask_query.c
@@ -169,7 +169,7 @@ bool ED_mask_find_nearest_diff_point(const bContext *C,
}
if (r_u) {
- /* TODO(sergey): Projection fails in some weirdo cases.. */
+ /* 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);
}
diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c
index 5c369afc4cd..3bb05a27c54 100644
--- a/source/blender/editors/mask/mask_select.c
+++ b/source/blender/editors/mask/mask_select.c
@@ -92,7 +92,6 @@ bool ED_mask_select_check(const Mask *mask)
return false;
}
-/* 'sel' select */
void ED_mask_spline_select_set(MaskSpline *spline, const bool do_select)
{
if (do_select) {
diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c
index 81bf66da72c..a5a3489c143 100644
--- a/source/blender/editors/mask/mask_shapekey.c
+++ b/source/blender/editors/mask/mask_shapekey.c
@@ -173,7 +173,7 @@ static int mask_shape_key_feather_reset_exec(bContext *C, wmOperator *UNUSED(op)
MaskSplinePoint *point = &spline->points[i];
if (MASKPOINT_ISSEL_ANY(point)) {
- /* TODO - nicer access here */
+ /* TODO: nicer access here. */
shape_ele_dst->value[6] = shape_ele_src->value[6];
}
@@ -291,7 +291,7 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op)
BLI_addtail(&shapes_tmp, mask_layer_shape_tmp);
}
- /* re-key, note: cant modify the keys here since it messes uop */
+ /* re-key, NOTE: can't modify the keys here since it messes up. */
for (mask_layer_shape_tmp = shapes_tmp.first; mask_layer_shape_tmp;
mask_layer_shape_tmp = mask_layer_shape_tmp->next) {
BKE_mask_layer_evaluate(mask_layer, mask_layer_shape_tmp->frame, true);
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index b7ee50a9461..648008a4779 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -65,7 +65,7 @@ void paintface_flush_flags(struct bContext *C, Object *ob, short flag)
return;
}
- /* note, call #BKE_mesh_flush_hidden_from_verts_ex first when changing hidden flags */
+ /* NOTE: call #BKE_mesh_flush_hidden_from_verts_ex first when changing hidden flags. */
/* we could call this directly in all areas that change selection,
* since this could become slow for realtime updates (circle-select for eg) */
@@ -433,7 +433,7 @@ bool paintface_mouse_select(
/* image window redraw */
paintface_flush_flags(C, ob, SELECT);
- ED_region_tag_redraw(CTX_wm_region(C)); /* XXX - should redraw all 3D views */
+ ED_region_tag_redraw(CTX_wm_region(C)); /* XXX: should redraw all 3D views. */
return true;
}
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 18e231893d4..a64b90e15a3 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -95,7 +95,12 @@ static void make_prim_finish(bContext *C,
EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
/* only recalc editmode tessface if we are staying in editmode */
- EDBM_update_generic(obedit->data, !exit_editmode, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = !exit_editmode,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
/* userdef */
if (exit_editmode) {
diff --git a/source/blender/editors/mesh/editmesh_add_gizmo.c b/source/blender/editors/mesh/editmesh_add_gizmo.c
index e7a99ca9e08..9efcf0963b4 100644
--- a/source/blender/editors/mesh/editmesh_add_gizmo.c
+++ b/source/blender/editors/mesh/editmesh_add_gizmo.c
@@ -357,7 +357,12 @@ static int add_primitive_cube_gizmo_exec(bContext *C, wmOperator *op)
}
EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/editmesh_automerge.c b/source/blender/editors/mesh/editmesh_automerge.c
index 2bd5b9b26ca..35fff1f8f3a 100644
--- a/source/blender/editors/mesh/editmesh_automerge.c
+++ b/source/blender/editors/mesh/editmesh_automerge.c
@@ -76,7 +76,12 @@ void EDBM_automerge(Object *obedit, bool update, const char hflag, const float d
BMO_op_finish(bm, &weldop);
if ((totvert_prev != bm->totvert) && update) {
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
}
@@ -134,7 +139,12 @@ void EDBM_automerge_and_split(Object *obedit,
#endif
if (LIKELY(ok) && update) {
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
}
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index 43492cd57af..01736f2919a 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -279,7 +279,7 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
for (int i = 0; i < NUM_VALUE_KINDS; i++) {
opdata->shift_value[i] = -1.0f;
opdata->initial_length[i] = -1.0f;
- /* note: scale for OFFSET_VALUE will get overwritten in edbm_bevel_invoke */
+ /* NOTE: scale for #OFFSET_VALUE will get overwritten in #edbm_bevel_invoke. */
opdata->scale[i] = value_scale_per_inch[i] / pixels_per_inch;
initNumInput(&opdata->num_input[i]);
@@ -347,7 +347,7 @@ static bool edbm_bevel_calc(wmOperator *op)
/* revert to original mesh */
if (opdata->is_modal) {
- EDBM_redo_state_restore(opdata->ob_store[ob_index].mesh_backup, em, false);
+ EDBM_redo_state_restore(&opdata->ob_store[ob_index].mesh_backup, em, false);
}
const int material = CLAMPIS(material_init, -1, obedit->totcol - 1);
@@ -403,9 +403,12 @@ static bool edbm_bevel_calc(wmOperator *op)
continue;
}
- EDBM_mesh_normals_update(em);
-
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
changed = true;
}
return changed;
@@ -433,7 +436,7 @@ static void edbm_bevel_exit(bContext *C, wmOperator *op)
View3D *v3d = CTX_wm_view3d(C);
ARegion *region = CTX_wm_region(C);
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
- EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup, NULL, false);
+ EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup);
}
ED_region_draw_cb_exit(region->type, opdata->draw_handle_pixel);
if (v3d) {
@@ -453,8 +456,13 @@ static void edbm_bevel_cancel(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
Object *obedit = opdata->ob_store[ob_index].ob;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup, em, true);
- EDBM_update_generic(obedit->data, false, true);
+ EDBM_redo_state_restore_and_free(&opdata->ob_store[ob_index].mesh_backup, em, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
}
}
diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c
index ea35d5a9e26..3c8afe8e7db 100644
--- a/source/blender/editors/mesh/editmesh_bisect.c
+++ b/source/blender/editors/mesh/editmesh_bisect.c
@@ -67,7 +67,7 @@ typedef struct {
/* Aligned with objects array. */
struct {
- BMBackup mesh;
+ BMBackup mesh_backup;
bool is_valid;
bool is_dirty;
} * backup;
@@ -160,7 +160,7 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (em->bm->totedgesel != 0) {
opdata->backup[ob_index].is_valid = true;
- opdata->backup[ob_index].mesh = EDBM_redo_state_store(em);
+ opdata->backup[ob_index].mesh_backup = EDBM_redo_state_store(em);
}
}
@@ -184,7 +184,7 @@ static void edbm_bisect_exit(bContext *C, BisectData *opdata)
for (int ob_index = 0; ob_index < opdata->backup_len; ob_index++) {
if (opdata->backup[ob_index].is_valid) {
- EDBM_redo_state_free(&opdata->backup[ob_index].mesh, NULL, false);
+ EDBM_redo_state_free(&opdata->backup[ob_index].mesh_backup);
}
}
MEM_freeN(opdata->backup);
@@ -280,7 +280,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
/* -------------------------------------------------------------------- */
/* Modal support */
- /* Note: keep this isolated, exec can work without this */
+ /* NOTE: keep this isolated, exec can work without this. */
if (opdata != NULL) {
mesh_bisect_interactive_calc(C, op, plane_co, plane_no);
/* Write back to the props. */
@@ -301,7 +301,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
if (opdata != NULL) {
if (opdata->backup[ob_index].is_dirty) {
- EDBM_redo_state_restore(opdata->backup[ob_index].mesh, em, false);
+ EDBM_redo_state_restore(&opdata->backup[ob_index].mesh_backup, em, false);
opdata->backup[ob_index].is_dirty = false;
}
}
@@ -347,7 +347,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
BMOperator bmop_attr;
/* The fill normal sign is ignored as the face-winding is defined by surrounding faces.
- * The normal is passed so triangle fill wont have to calculate it. */
+ * The normal is passed so triangle fill won't have to calculate it. */
normalize_v3_v3(normal_fill, plane_no_local);
/* Fill */
@@ -383,7 +383,12 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
bm, bmop.slots_out, "geom_cut.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true);
if (EDBM_op_finish(em, &bmop, op, true)) {
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
EDBM_selectmode_flush(em);
ret = OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index d5ddb7fc2c4..907881a44f3 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -319,9 +319,12 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
em->bm, BMO_FLAG_DEFAULTS, "translate vec=%v verts=%hv", offset_local, BM_ELEM_SELECT);
}
- EDBM_mesh_normals_update(em);
-
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -448,11 +451,13 @@ static int edbm_extrude_region_exec(bContext *C, wmOperator *op)
continue;
}
/* This normally happens when pushing undo but modal operators
- * like this one don't push undo data until after modal mode is
- * done.*/
- EDBM_mesh_normals_update(em);
-
- EDBM_update_generic(obedit->data, true, true);
+ * like this one don't push undo data until after modal mode is done. */
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
return OPERATOR_FINISHED;
@@ -502,13 +507,15 @@ static int edbm_extrude_context_exec(bContext *C, wmOperator *op)
}
edbm_extrude_mesh(obedit, em, op);
- /* This normally happens when pushing undo but modal operators
- * like this one don't push undo data until after modal mode is
- * done.*/
- EDBM_mesh_normals_update(em);
-
- EDBM_update_generic(obedit->data, true, true);
+ /* This normally happens when pushing undo but modal operators
+ * like this one don't push undo data until after modal mode is done. */
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
return OPERATOR_FINISHED;
@@ -555,7 +562,12 @@ static int edbm_extrude_verts_exec(bContext *C, wmOperator *op)
edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -603,7 +615,12 @@ static int edbm_extrude_edges_exec(bContext *C, wmOperator *op)
edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT, use_normal_flip);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -651,7 +668,12 @@ static int edbm_extrude_faces_exec(bContext *C, wmOperator *op)
edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -884,11 +906,13 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
}
/* This normally happens when pushing undo but modal operators
- * like this one don't push undo data until after modal mode is
- * done. */
- EDBM_mesh_normals_update(vc.em);
-
- EDBM_update_generic(vc.obedit->data, true, true);
+ * like this one don't push undo data until after modal mode is done. */
+ EDBM_update(vc.obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
diff --git a/source/blender/editors/mesh/editmesh_extrude_screw.c b/source/blender/editors/mesh/editmesh_extrude_screw.c
index 4cffd12cb34..1ba6a0f42c6 100644
--- a/source/blender/editors/mesh/editmesh_extrude_screw.c
+++ b/source/blender/editors/mesh/editmesh_extrude_screw.c
@@ -155,7 +155,12 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
diff --git a/source/blender/editors/mesh/editmesh_extrude_spin.c b/source/blender/editors/mesh/editmesh_extrude_spin.c
index 187652ae00f..2146207308c 100644
--- a/source/blender/editors/mesh/editmesh_extrude_spin.c
+++ b/source/blender/editors/mesh/editmesh_extrude_spin.c
@@ -108,7 +108,12 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c
index 73d79805f60..18f51ae9df2 100644
--- a/source/blender/editors/mesh/editmesh_inset.c
+++ b/source/blender/editors/mesh/editmesh_inset.c
@@ -209,7 +209,7 @@ static void edbm_inset_exit(bContext *C, wmOperator *op)
View3D *v3d = CTX_wm_view3d(C);
ARegion *region = CTX_wm_region(C);
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
- EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup, NULL, false);
+ EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup);
}
ED_region_draw_cb_exit(region->type, opdata->draw_handle_pixel);
if (v3d) {
@@ -235,8 +235,13 @@ static void edbm_inset_cancel(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
Object *obedit = opdata->ob_store[ob_index].ob;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup, em, true);
- EDBM_update_generic(obedit->data, false, true);
+ EDBM_redo_state_restore_and_free(&opdata->ob_store[ob_index].mesh_backup, em, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
}
@@ -271,7 +276,7 @@ static bool edbm_inset_calc(wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
if (opdata->is_modal) {
- EDBM_redo_state_restore(opdata->ob_store[ob_index].mesh_backup, em, false);
+ EDBM_redo_state_restore(&opdata->ob_store[ob_index].mesh_backup, em, false);
}
if (use_individual) {
@@ -326,7 +331,12 @@ static bool edbm_inset_calc(wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
changed = true;
}
return changed;
diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c
index d1f228e951a..f2691580a9d 100644
--- a/source/blender/editors/mesh/editmesh_intersect.c
+++ b/source/blender/editors/mesh/editmesh_intersect.c
@@ -116,8 +116,12 @@ static void edbm_intersect_select(BMEditMesh *em, struct Mesh *me, bool do_selec
}
}
- EDBM_mesh_normals_update(em);
- EDBM_update_generic(me, true, true);
+ EDBM_update(me,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
}
/* -------------------------------------------------------------------- */
@@ -963,8 +967,12 @@ static int edbm_face_split_by_edges_exec(bContext *C, wmOperator *UNUSED(op))
}
#endif
- EDBM_mesh_normals_update(em);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
#ifdef USE_NET_ISLAND_CONNECT
/* we may have remaining isolated regions remaining,
@@ -1068,8 +1076,12 @@ static int edbm_face_split_by_edges_exec(bContext *C, wmOperator *UNUSED(op))
BLI_ghash_free(face_edge_map, NULL, NULL);
- EDBM_mesh_normals_update(em);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
}
BLI_stack_free(edges_loose);
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index b5cd9c7f60d..73f6a3f3238 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -157,7 +157,7 @@ typedef struct KnifePosData {
typedef struct KnifeTool_OpData {
ARegion *region; /* region that knifetool was activated in */
void *draw_handle; /* for drawing preview loop */
- ViewContext vc; /* note: _don't_ use 'mval', instead use the one we define below */
+ ViewContext vc; /* NOTE: _don't_ use 'mval', instead use the one we define below. */
float mval[2]; /* mouse value with snapping applied */
// bContext *C;
@@ -272,8 +272,7 @@ static void knifetool_draw_angle_snapping(const KnifeTool_OpData *kcd)
float v1[3], v2[3];
float planes[4][4];
- planes_from_projmat(
- (const float(*)[4])kcd->projmat, planes[2], planes[0], planes[3], planes[1], NULL, NULL);
+ planes_from_projmat(kcd->projmat, planes[2], planes[0], planes[1], planes[3], NULL, NULL);
/* ray-cast all planes */
{
@@ -578,8 +577,8 @@ static void knife_input_ray_segment(KnifeTool_OpData *kcd,
float r_origin_ofs[3])
{
/* unproject to find view ray */
- ED_view3d_unproject(kcd->vc.region, mval[0], mval[1], 0.0f, r_origin);
- ED_view3d_unproject(kcd->vc.region, mval[0], mval[1], ofs, r_origin_ofs);
+ ED_view3d_unproject_v3(kcd->vc.region, mval[0], mval[1], 0.0f, r_origin);
+ ED_view3d_unproject_v3(kcd->vc.region, mval[0], mval[1], ofs, r_origin_ofs);
/* transform into object space */
mul_m4_v3(kcd->ob_imat, r_origin);
@@ -938,7 +937,7 @@ static KnifeVert *knife_split_edge(KnifeTool_OpData *kcd,
static void knife_start_cut(KnifeTool_OpData *kcd)
{
kcd->prev = kcd->curr;
- kcd->curr.is_space = 0; /*TODO: why do we do this? */
+ kcd->curr.is_space = 0; /* TODO: why do we do this? */
if (kcd->prev.vert == NULL && kcd->prev.edge == NULL) {
float origin[3], origin_ofs[3];
@@ -953,7 +952,7 @@ static void knife_start_cut(KnifeTool_OpData *kcd)
zero_v3(kcd->prev.cage);
}
- copy_v3_v3(kcd->prev.co, kcd->prev.cage); /*TODO: do we need this? */
+ copy_v3_v3(kcd->prev.co, kcd->prev.cage); /* TODO: do we need this? */
copy_v3_v3(kcd->curr.cage, kcd->prev.cage);
copy_v3_v3(kcd->curr.co, kcd->prev.co);
}
@@ -1161,7 +1160,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd,
}
else if (lh1->kfe) {
kfe->v1 = knife_split_edge(kcd, lh1->kfe, lh1->hit, lh1->cagehit, &kfe2);
- lh1->v = kfe->v1; /* record the KnifeVert for this hit */
+ lh1->v = kfe->v1; /* Record the #KnifeVert for this hit. */
}
else {
BLI_assert(lh1->f);
@@ -1169,7 +1168,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd,
kfe->v1->is_cut = true;
kfe->v1->is_face = true;
knife_append_list(kcd, &kfe->v1->faces, lh1->f);
- lh1->v = kfe->v1; /* record the KnifeVert for this hit */
+ lh1->v = kfe->v1; /* Record the #KnifeVert for this hit. */
}
if (lh2->v) {
@@ -1476,7 +1475,7 @@ static void knife_add_cut(KnifeTool_OpData *kcd)
}
}
- /* Note: as following loop progresses, the 'v' fields of
+ /* NOTE: as following loop progresses, the 'v' fields of
* the linehits will be filled in (as edges are split or
* in-face verts are made), so it may be true that both
* the v and the kfe or f fields will be non-NULL. */
@@ -1745,7 +1744,7 @@ static bool point_is_visible(KnifeTool_OpData *kcd,
float view[3], p_ofs[3];
/* TODO: I think there's a simpler way to get the required raycast ray */
- ED_view3d_unproject(kcd->vc.region, s[0], s[1], 0.0f, view);
+ ED_view3d_unproject_v3(kcd->vc.region, s[0], s[1], 0.0f, view);
mul_m4_v3(kcd->ob_imat, view);
@@ -1761,7 +1760,7 @@ static bool point_is_visible(KnifeTool_OpData *kcd,
if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) {
float view_clip[2][3];
- /* note: view_clip[0] should never get clipped */
+ /* NOTE: view_clip[0] should never get clipped. */
copy_v3_v3(view_clip[0], p_ofs);
madd_v3_v3v3fl(view_clip[1], p_ofs, view, dist);
@@ -2140,9 +2139,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
BLI_smallhash_release(&faces);
BLI_smallhash_release(&kfes);
BLI_smallhash_release(&kfvs);
- if (results) {
- MEM_freeN(results);
- }
+ MEM_freeN(results);
}
/** \} */
@@ -2807,8 +2804,12 @@ static void knifetool_finish_ex(KnifeTool_OpData *kcd)
knife_make_cuts(kcd);
EDBM_selectmode_flush(kcd->em);
- EDBM_mesh_normals_update(kcd->em);
- EDBM_update_generic(kcd->ob->data, true, true);
+ EDBM_update(kcd->ob->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
/* Re-tessellating makes this invalid, don't use again by accident. */
knifetool_free_bmbvh(kcd);
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
index aa144dd3f3c..09b17acf56d 100644
--- a/source/blender/editors/mesh/editmesh_knife_project.c
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -30,6 +30,7 @@
#include "BKE_context.h"
#include "BKE_curve.h"
+#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
@@ -59,7 +60,7 @@ static LinkNode *knifeproject_poly_from_object(const bContext *C,
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ARegion *region = CTX_wm_region(C);
- struct Mesh *me_eval;
+ const struct Mesh *me_eval;
bool me_eval_needs_free;
if (ob->type == OB_MESH || ob->runtime.data_eval) {
@@ -113,7 +114,7 @@ static LinkNode *knifeproject_poly_from_object(const bContext *C,
BKE_nurbList_free(&nurbslist);
if (me_eval_needs_free) {
- BKE_mesh_free(me_eval);
+ BKE_mesh_free((struct Mesh *)me_eval);
}
}
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 2057738221b..0a4fecde6ea 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -209,7 +209,12 @@ static void ringsel_finish(bContext *C, wmOperator *op)
/* when used in a macro the tessfaces will be recalculated anyway,
* this is needed here because modifiers depend on updated tessellation, see T45920 */
- EDBM_update_generic(lcd->ob->data, true, true);
+ EDBM_update(lcd->ob->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
if (is_single) {
/* de-select endpoints */
@@ -218,7 +223,7 @@ static void ringsel_finish(bContext *C, wmOperator *op)
EDBM_selectmode_flush_ex(lcd->em, SCE_SELECT_VERTEX);
}
- /* we cant slide multiple edges in vertex select mode */
+ /* we can't slide multiple edges in vertex select mode */
else if (is_macro && (cuts > 1) && (em->selectmode & SCE_SELECT_VERTEX)) {
EDBM_selectmode_disable(lcd->vc.scene, em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
}
@@ -236,7 +241,7 @@ static void ringsel_finish(bContext *C, wmOperator *op)
* in editmesh_select.c (around line 1000)... */
/* sets as active, useful for other tools */
if (em->selectmode & SCE_SELECT_VERTEX) {
- /* low priority TODO, get vertrex close to mouse */
+ /* low priority TODO: get vertrex close to mouse. */
BM_select_history_store(em->bm, lcd->eed->v1);
}
if (em->selectmode & SCE_SELECT_EDGE) {
diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c
index 7d849c096e7..cccfc7e934c 100644
--- a/source/blender/editors/mesh/editmesh_mask_extract.c
+++ b/source/blender/editors/mesh/editmesh_mask_extract.c
@@ -126,7 +126,7 @@ static int geometry_extract_apply(bContext *C,
.calc_face_normal = true,
}));
- BMEditMesh *em = BKE_editmesh_create(bm, false);
+ BMEditMesh *em = BKE_editmesh_create(bm);
/* Generate the tags for deleting geometry in the extracted object. */
tag_fn(bm, params);
@@ -206,7 +206,7 @@ static int geometry_extract_apply(bContext *C,
}),
mesh);
- BKE_editmesh_free(em);
+ BKE_editmesh_free_data(em);
MEM_freeN(em);
if (new_mesh->totvert == 0) {
@@ -229,7 +229,7 @@ static int geometry_extract_apply(bContext *C,
/* Remove the mask from the new object so it can be sculpted directly after extracting. */
CustomData_free_layers(&new_ob_mesh->vdata, CD_PAINT_MASK, new_ob_mesh->totvert);
- BKE_mesh_copy_settings(new_ob_mesh, mesh);
+ BKE_mesh_copy_parameters_for_eval(new_ob_mesh, mesh);
if (params->apply_shrinkwrap) {
BKE_shrinkwrap_mesh_nearest_surface_deform(C, new_ob, ob);
@@ -567,7 +567,7 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op)
BKE_mesh_nomain_to_mesh(new_ob_mesh, new_ob->data, new_ob, &CD_MASK_MESH, true);
BKE_mesh_calc_normals(new_ob->data);
- BKE_mesh_copy_settings(new_ob->data, mesh);
+ BKE_mesh_copy_parameters_for_eval(new_ob->data, mesh);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, new_ob);
BKE_mesh_batch_cache_dirty_tag(new_ob->data, BKE_MESH_BATCH_DIRTY_ALL);
DEG_relations_tag_update(bmain);
diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c
index b7f671a4157..30a453a32ee 100644
--- a/source/blender/editors/mesh/editmesh_path.c
+++ b/source/blender/editors/mesh/editmesh_path.c
@@ -29,6 +29,7 @@
#include "DNA_windowmanager_types.h"
#ifdef WITH_FREESTYLE
+# include "BKE_customdata.h"
# include "DNA_meshdata_types.h"
#endif
@@ -270,7 +271,12 @@ static void mouse_mesh_shortest_path_vert(Scene *UNUSED(scene),
}
}
- EDBM_update_generic(obedit->data, false, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
/** \} */
@@ -474,7 +480,12 @@ static void mouse_mesh_shortest_path_edge(Scene *scene,
}
}
- EDBM_update_generic(obedit->data, false, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
if (op_params->edge_mode == EDGE_MODE_TAG_SEAM) {
ED_uvedit_live_unwrap(scene, &obedit, 1);
@@ -591,7 +602,12 @@ static void mouse_mesh_shortest_path_face(Scene *UNUSED(scene),
BM_mesh_active_face_set(bm, f_dst_last);
}
- EDBM_update_generic(obedit->data, false, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
/** \} */
diff --git a/source/blender/editors/mesh/editmesh_polybuild.c b/source/blender/editors/mesh/editmesh_polybuild.c
index 4d37b78c9b7..303cf41df0d 100644
--- a/source/blender/editors/mesh/editmesh_polybuild.c
+++ b/source/blender/editors/mesh/editmesh_polybuild.c
@@ -154,8 +154,12 @@ static int edbm_polybuild_transform_at_cursor_invoke(bContext *C,
BM_face_select_set(bm, (BMFace *)ele_act, true);
}
- EDBM_mesh_normals_update(em);
- EDBM_update_generic(vc.obedit->data, true, true);
+ EDBM_update(vc.obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
if (basact != NULL) {
if (vc.view_layer->basact != basact) {
ED_object_base_activate(C, basact);
@@ -237,8 +241,12 @@ static int edbm_polybuild_delete_at_cursor_invoke(bContext *C,
}
if (changed) {
- EDBM_mesh_normals_update(em);
- EDBM_update_generic(vc.obedit->data, true, true);
+ EDBM_update(vc.obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
if (basact != NULL) {
if (vc.view_layer->basact != basact) {
ED_object_base_activate(C, basact);
@@ -400,8 +408,12 @@ static int edbm_polybuild_face_at_cursor_invoke(bContext *C, wmOperator *op, con
}
if (changed) {
- EDBM_mesh_normals_update(em);
- EDBM_update_generic(vc.obedit->data, true, true);
+ EDBM_update(vc.obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
if (basact != NULL) {
if (vc.view_layer->basact != basact) {
@@ -488,8 +500,12 @@ static int edbm_polybuild_split_at_cursor_invoke(bContext *C,
}
if (changed) {
- EDBM_mesh_normals_update(em);
- EDBM_update_generic(vc.obedit->data, true, true);
+ EDBM_update(vc.obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
WM_event_add_mousemove(vc.win);
@@ -559,7 +575,7 @@ static int edbm_polybuild_dissolve_at_cursor_invoke(bContext *C,
else {
/* too involved to do inline */
- /* Avoid using selection so failure wont leave modified state. */
+ /* Avoid using selection so failure won't leave modified state. */
EDBM_flag_disable_all(em, BM_ELEM_TAG);
BM_elem_flag_enable(v_act, BM_ELEM_TAG);
@@ -578,8 +594,12 @@ static int edbm_polybuild_dissolve_at_cursor_invoke(bContext *C,
if (changed) {
edbm_flag_disable_all_multi(vc.view_layer, vc.v3d, BM_ELEM_SELECT);
- EDBM_mesh_normals_update(em);
- EDBM_update_generic(vc.obedit->data, true, true);
+ EDBM_update(vc.obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
if (vc.view_layer->basact != basact) {
ED_object_base_activate(C, basact);
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index 222d44f85d8..5a2a090b725 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -170,15 +170,15 @@ static float edbm_rip_edge_side_measure(
*
* The method used for checking the side of selection is as follows...
* - First tag all rip-able edges.
- * - Build a contiguous edge list by looping over tagged edges and following each ones tagged
+ * - Build a contiguous edge list by looping over tagged edges and following each one's tagged
* siblings in both directions.
- * - The loops are not stored in an array, Instead both loops on either side of each edge has
- * its index values set to count down from the last edge, this way, once we have the 'last'
- * edge its very easy to walk down the connected edge loops.
- * The reason for using loops like this is because when the edges are split we don't which
- * face user gets the newly created edge
- * (its as good as random so we cant assume new edges will be on once side).
- * After splitting, its very simple to walk along boundary loops since each only has one edge
+ * - The loops are not stored in an array. Instead both loops on either side of each edge has
+ * its index values set to count down from the last edge. This way once we have the 'last'
+ * edge it's very easy to walk down the connected edge loops.
+ * The reason for using loops like this is because when the edges are split we don't know
+ * which face user gets the newly created edge
+ * (it's as good as random so we can't assume new edges will be on one side).
+ * After splitting, it's very simple to walk along boundary loops since each only has one edge
* from a single side.
* - The end loop pairs are stored in an array however to support multiple edge-selection-islands,
* so you can rip multiple selections at once.
@@ -189,7 +189,7 @@ static float edbm_rip_edge_side_measure(
*
* Limitation!
* This currently works very poorly with intersecting edge islands
- * (verts with more than 2 tagged edges). This is nice to but for now not essential.
+ * (verts with more than 2 tagged edges). This is nice to do but for now not essential.
*
* - campbell.
*/
@@ -270,7 +270,7 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm)
break;
}
- /* initialize */
+ /* Initialize. */
e_first = e;
v_step = e_first->v1;
e_step = NULL; /* quiet warning, will never remain this value */
@@ -639,7 +639,7 @@ static int edbm_rip_invoke__vert(bContext *C, const wmEvent *event, Object *obed
/* should we go ahead with edge rip or do we need to do special case, split off vertex?:
* split off vertex if...
- * - we cant find an edge - this means we are ripping a faces vert that is connected to other
+ * - we can't find an edge - this means we are ripping a faces vert that is connected to other
* geometry only at the vertex.
* - the boundary edge total is greater than 2,
* in this case edge split _can_ work but we get far nicer results if we use this special case.
@@ -927,7 +927,7 @@ static int edbm_rip_invoke__edge(bContext *C, const wmEvent *event, Object *obed
/* single edge, extend */
if (i == 1 && e_best->l) {
- /* note: if the case of 3 edges has one change in loop stepping,
+ /* NOTE: if the case of 3 edges has one change in loop stepping,
* if this becomes more involved we may be better off splitting
* the 3 edge case into its own else-if branch */
if ((totedge_manifold == 4 || totedge_manifold == 3) || (all_manifold == false)) {
@@ -975,7 +975,7 @@ static int edbm_rip_invoke__edge(bContext *C, const wmEvent *event, Object *obed
BM_mesh_edgesplit(em->bm, true, true, true);
- /* note: the output of the bmesh operator is ignored, since we built
+ /* NOTE: the output of the bmesh operator is ignored, since we built
* the contiguous loop pairs to split already, its possible that some
* edge did not split even though it was tagged which would not work
* as expected (but not crash), however there are checks to ensure
@@ -1082,7 +1082,12 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
error_rip_failed = false;
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
diff --git a/source/blender/editors/mesh/editmesh_rip_edge.c b/source/blender/editors/mesh/editmesh_rip_edge.c
index 6775cb85ef9..f7e88284d93 100644
--- a/source/blender/editors/mesh/editmesh_rip_edge.c
+++ b/source/blender/editors/mesh/editmesh_rip_edge.c
@@ -223,7 +223,12 @@ static int edbm_rip_edge_invoke(bContext *C, wmOperator *UNUSED(op), const wmEve
BM_mesh_select_mode_flush(bm);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
}
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 6cb103460f6..830c9abb41e 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -35,6 +35,8 @@
#include "BLI_utildefines_stack.h"
#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_report.h"
@@ -434,7 +436,7 @@ struct NearestEdgeUserData {
struct NearestEdgeUserData_Hit hit_cycle;
};
-/* note; uses v3d, so needs active 3d window */
+/* NOTE: uses v3d, so needs active 3d window. */
static void find_nearest_edge__doClosest(
void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
{
@@ -547,8 +549,10 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenEdge(
- vc, find_nearest_edge_center__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenEdge(vc,
+ find_nearest_edge_center__doZBuf,
+ &data,
+ V3D_PROJ_TEST_CLIP_DEFAULT | V3D_PROJ_TEST_CLIP_CONTENT_DEFAULT);
*r_dist_center_px_manhattan = data.dist;
}
@@ -601,7 +605,8 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
*dist_px_manhattan_p;
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenEdge(vc, find_nearest_edge__doClosest, &data, clip_flag);
+ mesh_foreachScreenEdge(
+ vc, find_nearest_edge__doClosest, &data, clip_flag | V3D_PROJ_TEST_CLIP_CONTENT_DEFAULT);
hit = (data.use_cycle && data.hit_cycle.edge) ? &data.hit_cycle : &data.hit;
@@ -961,7 +966,7 @@ static bool unified_findnearest(ViewContext *vc,
}
}
- /* return only one of 3 pointers, for frontbuffer redraws */
+ /* Return only one of 3 pointers, for front-buffer redraws. */
if (hit.v.ele) {
hit.f.ele = NULL;
hit.e.ele = NULL;
@@ -1802,7 +1807,7 @@ static bool mouse_mesh_loop(
V3D_PROJ_RET_OK) {
tdist = len_squared_v2v2(mvalf, co);
if (tdist < best_dist) {
- /* printf("Best face: %p (%f)\n", f, tdist);*/
+ // printf("Best face: %p (%f)\n", f, tdist);
best_dist = tdist;
efa = f;
}
@@ -2568,7 +2573,7 @@ bool EDBM_selectmode_disable(Scene *scene,
const short selectmode_fallback)
{
/* note essential, but switch out of vertex mode since the
- * selected regions wont be nicely isolated after flushing */
+ * selected regions won't be nicely isolated after flushing */
if (em->selectmode & selectmode_disable) {
if (em->selectmode == selectmode_disable) {
em->selectmode = selectmode_fallback;
@@ -2980,7 +2985,7 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
int i_b = BM_elem_index_get(l_pair[1]->f);
if (i_a != i_b) {
/* Only for predictable results that don't depend on the order of radial loops,
- * not essential. */
+ * not essential. */
if (i_a > i_b) {
SWAP(int, i_a, i_b);
}
@@ -3443,7 +3448,7 @@ static void edbm_select_linked_pick_ex(BMEditMesh *em, BMElem *ele, bool sel, in
select_linked_delimit_begin(bm, delimit);
}
- /* Note: logic closely matches 'edbm_select_linked_exec', keep in sync */
+ /* NOTE: logic closely matches #edbm_select_linked_exec, keep in sync. */
if (ele->head.htype == BM_VERT) {
BMVert *eve = (BMVert *)ele;
@@ -3639,8 +3644,9 @@ static int edbm_select_linked_pick_exec(bContext *C, wmOperator *op)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
- const int object_index = RNA_int_get(op->ptr, "object_index");
- const int index = RNA_int_get(op->ptr, "index");
+ /* Intentionally wrap negative values so the lookup fails. */
+ const uint object_index = (uint)RNA_int_get(op->ptr, "object_index");
+ const uint index = (uint)RNA_int_get(op->ptr, "index");
ele = EDBM_elem_from_index_any_multi(view_layer, object_index, index, &obedit);
}
@@ -4270,7 +4276,12 @@ static int edbm_select_nth_exec(bContext *C, wmOperator *op)
if (edbm_deselect_nth(em, &op_params) == true) {
found_active_elt = true;
- EDBM_update_generic(obedit->data, false, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
}
MEM_freeN(objects);
@@ -4643,7 +4654,7 @@ static int edbm_select_random_exec(bContext *C, wmOperator *op)
}
}
- BLI_array_randomize(elem_map, sizeof(*elem_map), elem_map_len, seed);
+ BLI_array_randomize(elem_map, sizeof(*elem_map), elem_map_len, seed_iter);
const int count_select = elem_map_len * randfac;
for (int i = 0; i < count_select; i++) {
BM_vert_select_set(em->bm, elem_map[i], select);
@@ -4659,7 +4670,7 @@ static int edbm_select_random_exec(bContext *C, wmOperator *op)
elem_map[elem_map_len++] = eed;
}
}
- BLI_array_randomize(elem_map, sizeof(*elem_map), elem_map_len, seed);
+ BLI_array_randomize(elem_map, sizeof(*elem_map), elem_map_len, seed_iter);
const int count_select = elem_map_len * randfac;
for (int i = 0; i < count_select; i++) {
BM_edge_select_set(em->bm, elem_map[i], select);
@@ -4675,7 +4686,7 @@ static int edbm_select_random_exec(bContext *C, wmOperator *op)
elem_map[elem_map_len++] = efa;
}
}
- BLI_array_randomize(elem_map, sizeof(*elem_map), elem_map_len, seed);
+ BLI_array_randomize(elem_map, sizeof(*elem_map), elem_map_len, seed_iter);
const int count_select = elem_map_len * randfac;
for (int i = 0; i < count_select; i++) {
BM_face_select_set(em->bm, elem_map[i], select);
@@ -4730,10 +4741,11 @@ static bool edbm_select_ungrouped_poll(bContext *C)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
+ const ListBase *defbase = BKE_object_defgroup_list(obedit);
if ((em->selectmode & SCE_SELECT_VERTEX) == 0) {
CTX_wm_operator_poll_msg_set(C, "Must be in vertex selection mode");
}
- else if (BLI_listbase_is_empty(&obedit->defbase) || cd_dvert_offset == -1) {
+ else if (BLI_listbase_is_empty(defbase) || cd_dvert_offset == -1) {
CTX_wm_operator_poll_msg_set(C, "No weights/vertex groups on object");
}
else {
diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c
index f3c0da67ecc..c452f7a7487 100644
--- a/source/blender/editors/mesh/editmesh_select_similar.c
+++ b/source/blender/editors/mesh/editmesh_select_similar.c
@@ -29,6 +29,8 @@
#include "BLI_math.h"
#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_material.h"
@@ -497,7 +499,12 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
if (changed) {
EDBM_selectmode_flush(em);
- EDBM_update_generic(ob->data, false, false);
+ EDBM_update(ob->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
}
@@ -519,7 +526,12 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
}
}
EDBM_selectmode_flush(em);
- EDBM_update_generic(ob->data, false, false);
+ EDBM_update(ob->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
}
@@ -549,7 +561,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
* \{ */
/**
- * Note: This is not normal, but the edge direction itself and always in
+ * NOTE: This is not normal, but the edge direction itself and always in
* a positive quadrant (tries z, y then x).
* Therefore we need to use the entire object transformation matrix.
*/
@@ -917,7 +929,12 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
if (changed) {
EDBM_selectmode_flush(em);
- EDBM_update_generic(ob->data, false, false);
+ EDBM_update(ob->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
}
@@ -939,7 +956,12 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
}
}
EDBM_selectmode_flush(em);
- EDBM_update_generic(ob->data, false, false);
+ EDBM_update(ob->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
}
@@ -1021,7 +1043,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
if (cd_dvert_offset == -1) {
continue;
}
- defbase_len = BLI_listbase_count(&ob->defbase);
+ defbase_len = BKE_object_defgroup_count(ob);
if (defbase_len == 0) {
continue;
}
@@ -1070,8 +1092,10 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
/* We store the names of the vertex groups, so we can select
* vertex groups with the same name in different objects. */
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+
int i = 0;
- LISTBASE_FOREACH (bDeformGroup *, dg, &ob->defbase) {
+ LISTBASE_FOREACH (bDeformGroup *, dg, defbase) {
if (BLI_BITMAP_TEST(defbase_selected, i)) {
BLI_gset_add(gset, dg->name);
}
@@ -1108,7 +1132,8 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
if (cd_dvert_offset == -1) {
continue;
}
- defbase_len = BLI_listbase_count(&ob->defbase);
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ defbase_len = BLI_listbase_count(defbase);
if (defbase_len == 0) {
continue;
}
@@ -1121,7 +1146,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
GSetIterator gs_iter;
GSET_ITER (gs_iter, gset) {
const char *name = BLI_gsetIterator_getKey(&gs_iter);
- int vgroup_id = BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name));
+ int vgroup_id = BLI_findstringindex(defbase, name, offsetof(bDeformGroup, name));
if (vgroup_id != -1) {
BLI_BITMAP_ENABLE(defbase_selected, vgroup_id);
found_any = true;
@@ -1213,7 +1238,12 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
if (changed) {
EDBM_selectmode_flush(em);
- EDBM_update_generic(ob->data, false, false);
+ EDBM_update(ob->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
}
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index bb332a4094c..41a9f426798 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -44,6 +44,7 @@
#include "BLI_string.h"
#include "BKE_context.h"
+#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_key.h"
@@ -132,7 +133,12 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op)
false,
seed);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -140,7 +146,7 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-/* Note, these values must match delete_mesh() event values */
+/* NOTE: these values must match delete_mesh() event values. */
static const EnumPropertyItem prop_mesh_cornervert_types[] = {
{SUBD_CORNER_INNERVERT, "INNERVERT", 0, "Inner Vert", ""},
{SUBD_CORNER_PATH, "PATH", 0, "Path", ""},
@@ -240,7 +246,7 @@ static void mesh_operator_edgering_props(wmOperatorType *ot,
const int cuts_min,
const int cuts_default)
{
- /* Note, these values must match delete_mesh() event values */
+ /* NOTE: these values must match delete_mesh() event values. */
static const EnumPropertyItem prop_subd_edgering_types[] = {
{SUBD_RING_INTERP_LINEAR, "LINEAR", 0, "Linear", ""},
{SUBD_RING_INTERP_PATH, "PATH", 0, "Blend Path", ""},
@@ -324,7 +330,12 @@ static int edbm_subdivide_edge_ring_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -384,7 +395,12 @@ static int edbm_unsubdivide_exec(bContext *C, wmOperator *op)
}
EDBM_selectmode_flush(em);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -416,7 +432,7 @@ void MESH_OT_unsubdivide(wmOperatorType *ot)
/** \name Delete Operator
* \{ */
-/* Note, these values must match delete_mesh() event values */
+/* NOTE: these values must match delete_mesh() event values. */
enum {
MESH_DELETE_VERT = 0,
MESH_DELETE_EDGE = 1,
@@ -499,7 +515,12 @@ static int edbm_delete_exec(bContext *C, wmOperator *op)
BM_custom_loop_normals_from_vector_layer(em->bm, false);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
@@ -628,7 +649,12 @@ static int edbm_delete_loose_exec(bContext *C, wmOperator *op)
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
int totelem_new[3];
@@ -686,7 +712,12 @@ static int edbm_collapse_edge_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -943,7 +974,7 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
#ifdef USE_FACE_CREATE_SEL_EXTEND
/* normally we would want to leave the new geometry selected,
* but being able to press F many times to add geometry is too useful! */
- if (ele_desel && (BMO_slot_buffer_count(bmop.slots_out, "faces.out") == 1) &&
+ if (ele_desel && (BMO_slot_buffer_len(bmop.slots_out, "faces.out") == 1) &&
(ele_desel_face = BMO_slot_buffer_get_first(bmop.slots_out, "faces.out"))) {
edbm_add_edge_face_exec__tricky_finalize_sel(em->bm, ele_desel, ele_desel_face);
}
@@ -954,7 +985,7 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
* copying face data from surrounding, may have copied hidden face flag too.
*
* Important that faces use flushing since 'edges.out'
- * wont include hidden edges that already existed.
+ * won't include hidden edges that already existed.
*/
BMO_slot_buffer_hflag_disable(
em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_HIDDEN, true);
@@ -971,7 +1002,12 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
changed_multi = true;
}
MEM_freeN(objects);
@@ -1047,7 +1083,12 @@ static int edbm_mark_seam_exec(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -1117,7 +1158,12 @@ static int edbm_mark_sharp_exec(bContext *C, wmOperator *op)
BM_elem_flag_set(eed, BM_ELEM_SMOOTH, clear);
}
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -1219,9 +1265,12 @@ static bool edbm_connect_vert_pair(BMEditMesh *em, struct Mesh *me, wmOperator *
}
}
if (checks_succeded) {
+ BMBackup em_backup = EDBM_redo_state_store(em);
+
BM_custom_loop_normals_to_vector_layer(bm);
BMO_op_exec(bm, &bmop);
+ const bool failure = BMO_error_occurred_at_level(bm, BMO_ERROR_FATAL);
len = BMO_slot_get(bmop.slots_out, "edges.out")->len;
if (len && is_pair) {
@@ -1230,16 +1279,31 @@ static bool edbm_connect_vert_pair(BMEditMesh *em, struct Mesh *me, wmOperator *
em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
}
- if (!EDBM_op_finish(em, &bmop, op, true)) {
+ bool em_backup_free = true;
+ if (!EDBM_op_finish(em, &bmop, op, false)) {
len = 0;
}
+ else if (failure) {
+ len = 0;
+ EDBM_redo_state_restore_and_free(&em_backup, em, true);
+ em_backup_free = false;
+ }
else {
/* so newly created edges get the selection state from the vertex */
EDBM_selectmode_flush(em);
BM_custom_loop_normals_from_vector_layer(bm, false);
- EDBM_update_generic(me, true, true);
+ EDBM_update(me,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
+ }
+
+ if (em_backup_free) {
+ EDBM_redo_state_free(&em_backup);
}
}
MEM_freeN(verts);
@@ -1538,7 +1602,12 @@ static int edbm_vert_connect_path_exec(bContext *C, wmOperator *op)
BM_custom_loop_normals_from_vector_layer(bm, false);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
else {
failed_selection_order_len++;
@@ -1603,7 +1672,12 @@ static int edbm_vert_connect_concave_exec(bContext *C, wmOperator *op)
em, op, "faces.out", true, "connect_verts_concave faces=%hf", BM_ELEM_SELECT)) {
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -1657,7 +1731,12 @@ static int edbm_vert_connect_nonplaner_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -1726,7 +1805,12 @@ static int edbm_face_make_planar_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -1775,7 +1859,12 @@ static bool edbm_edge_split_selected_edges(wmOperator *op, Object *obedit, BMEdi
BM_custom_loop_normals_from_vector_layer(em->bm, false);
EDBM_select_flush(em);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
return true;
}
@@ -1845,7 +1934,12 @@ static bool edbm_edge_split_selected_verts(wmOperator *op, Object *obedit, BMEdi
BM_custom_loop_normals_from_vector_layer(em->bm, false);
EDBM_select_flush(em);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
return true;
}
@@ -1958,7 +2052,12 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op)
if (!EDBM_op_finish(em, &bmop, op, true)) {
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -2114,7 +2213,12 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
lnor_ed->clnors_data);
}
BM_loop_normal_editdata_array_free(lnors_ed_arr);
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
continue;
}
@@ -2133,7 +2237,12 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
}
if (flip_custom_normals(em->bm, lnors_ed_arr) || has_flipped_faces) {
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
if (lnors_ed_arr != NULL) {
@@ -2214,8 +2323,8 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op)
}
}
- /* ok, we don't have two adjacent faces, but we do have two selected ones.
- * that's an error condition.*/
+ /* OK, we don't have two adjacent faces, but we do have two selected ones.
+ * that's an error condition. */
if (tot == 0) {
continue;
}
@@ -2236,7 +2345,7 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op)
BMO_slot_buffer_hflag_enable(
em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
- const int tot_rotate = BMO_slot_buffer_count(bmop.slots_out, "edges.out");
+ const int tot_rotate = BMO_slot_buffer_len(bmop.slots_out, "edges.out");
const int tot_failed = tot - tot_rotate;
tot_rotate_all += tot_rotate;
@@ -2255,7 +2364,12 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -2341,7 +2455,12 @@ static int edbm_hide_exec(bContext *C, wmOperator *op)
}
if (EDBM_mesh_hide(em, unselected)) {
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
changed = true;
}
}
@@ -2392,7 +2511,12 @@ static int edbm_reveal_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
if (EDBM_mesh_reveal(em, select)) {
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
}
MEM_freeN(objects);
@@ -2458,7 +2582,12 @@ static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op)
}
}
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -2570,7 +2699,12 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op)
EDBM_verts_mirror_cache_end(em);
}
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -2694,7 +2828,12 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
EDBM_verts_mirror_cache_end(em);
}
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -2787,7 +2926,12 @@ static int edbm_faces_shade_smooth_exec(bContext *C, wmOperator *UNUSED(op))
}
mesh_set_smooth_faces(em, 1);
- EDBM_update_generic(obedit->data, false, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -2830,7 +2974,12 @@ static int edbm_faces_shade_flat_exec(bContext *C, wmOperator *UNUSED(op))
}
mesh_set_smooth_faces(em, 0);
- EDBM_update_generic(obedit->data, false, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -2877,17 +3026,20 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op)
BMOperator bmop;
- /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
EDBM_op_init(em, &bmop, op, "rotate_uvs faces=%hf use_ccw=%b", BM_ELEM_SELECT, use_ccw);
- /* execute the operator */
BMO_op_exec(em->bm, &bmop);
if (!EDBM_op_finish(em, &bmop, op, true)) {
continue;
}
- EDBM_update_generic(obedit->data, false, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -2910,17 +3062,19 @@ static int edbm_reverse_uvs_exec(bContext *C, wmOperator *op)
BMOperator bmop;
- /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
EDBM_op_init(em, &bmop, op, "reverse_uvs faces=%hf", BM_ELEM_SELECT);
- /* execute the operator */
BMO_op_exec(em->bm, &bmop);
- /* finish the operator */
if (!EDBM_op_finish(em, &bmop, op, true)) {
continue;
}
- EDBM_update_generic(obedit->data, false, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -2946,19 +3100,21 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op)
BMOperator bmop;
- /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
EDBM_op_init(em, &bmop, op, "rotate_colors faces=%hf use_ccw=%b", BM_ELEM_SELECT, use_ccw);
- /* execute the operator */
BMO_op_exec(em->bm, &bmop);
- /* finish the operator */
if (!EDBM_op_finish(em, &bmop, op, true)) {
continue;
}
/* dependencies graph and notification stuff */
- EDBM_update_generic(ob->data, false, false);
+ EDBM_update(ob->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -2983,18 +3139,20 @@ static int edbm_reverse_colors_exec(bContext *C, wmOperator *op)
BMOperator bmop;
- /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
EDBM_op_init(em, &bmop, op, "reverse_colors faces=%hf", BM_ELEM_SELECT);
- /* execute the operator */
BMO_op_exec(em->bm, &bmop);
- /* finish the operator */
if (!EDBM_op_finish(em, &bmop, op, true)) {
- return OPERATOR_CANCELLED;
+ continue;
}
- EDBM_update_generic(obedit->data, false, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -3243,7 +3401,12 @@ static int edbm_merge_exec(bContext *C, wmOperator *op)
BM_custom_loop_normals_from_vector_layer(em->bm, false);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
/* once collapsed, we can't have edge/face selection */
if ((em->selectmode & SCE_SELECT_VERTEX) == 0) {
@@ -3422,7 +3585,12 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op)
if (count) {
count_multi += count;
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
}
MEM_freeN(objects);
@@ -3474,7 +3642,7 @@ void MESH_OT_remove_doubles(wmOperatorType *ot)
/** \name Shape Key Propagate Operator
* \{ */
-/* BMESH_TODO this should be properly encapsulated in a bmop. but later.*/
+/* BMESH_TODO this should be properly encapsulated in a bmop. but later. */
static bool shape_propagate(BMEditMesh *em)
{
BMIter iter;
@@ -3522,7 +3690,12 @@ static int edbm_shape_propagate_to_all_exec(bContext *C, wmOperator *op)
tot_shapekeys++;
}
- EDBM_update_generic(me, false, false);
+ EDBM_update(me,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -3562,7 +3735,7 @@ void MESH_OT_shape_propagate_to_all(wmOperatorType *ot)
/** \name Blend from Shape Operator
* \{ */
-/* BMESH_TODO this should be properly encapsulated in a bmop. but later.*/
+/* BMESH_TODO this should be properly encapsulated in a bmop. but later. */
static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op)
{
Object *obedit_ref = CTX_data_edit_object(C);
@@ -3644,7 +3817,12 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op)
interp_v3_v3v3(eve->co, eve->co, co, blend);
}
}
- EDBM_update_generic(me, true, false);
+ EDBM_update(me,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = false,
+ });
}
}
MEM_freeN(objects);
@@ -3781,7 +3959,12 @@ static int edbm_solidify_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -3858,7 +4041,7 @@ static float bm_edge_seg_isect(const float sco_a[2],
b2 = ((x22 * y21) - (x21 * y22)) / xdiff2;
}
else {
- m2 = MAXSLOPE; /* Vertical slope */
+ m2 = MAXSLOPE; /* Vertical slope. */
b2 = x22;
}
@@ -3908,7 +4091,7 @@ static float bm_edge_seg_isect(const float sco_a[2],
/* Calculate the distance from point to line. */
if (m2 != MAXSLOPE) {
- /* sqrt(m2 * m2 + 1); Only looking for change in sign. Skip extra math .*/
+ /* `sqrt(m2 * m2 + 1);` Only looking for change in sign. Skip extra math. */
dist = (y12 - m2 * x12 - b2);
}
else {
@@ -3930,8 +4113,8 @@ static float bm_edge_seg_isect(const float sco_a[2],
m1 = MAXSLOPE;
b1 = x12;
}
- x2max = max_ff(x21, x22) + 0.001f; /* prevent missed edges */
- x2min = min_ff(x21, x22) - 0.001f; /* due to round off error */
+ x2max = max_ff(x21, x22) + 0.001f; /* Prevent missed edges. */
+ x2min = min_ff(x21, x22) - 0.001f; /* Due to round off error. */
y2max = max_ff(y21, y22) + 0.001f;
y2min = min_ff(y21, y22) - 0.001f;
@@ -3959,9 +4142,9 @@ static float bm_edge_seg_isect(const float sco_a[2],
yi = (b1 * m2 - m1 * b2) / (m2 - m1);
}
- /* Intersect inside bounding box of edge?*/
+ /* Intersect inside bounding box of edge? */
if ((xi >= x2min) && (xi <= x2max) && (yi <= y2max) && (yi >= y2min)) {
- /* test for vertex intersect that may be 'close enough'*/
+ /* Test for vertex intersect that may be 'close enough'. */
if (mode != KNIFE_MULTICUT) {
if (xi <= (x21 + threshold) && xi >= (x21 - threshold)) {
if (yi <= (y21 + threshold) && yi >= (y21 - threshold)) {
@@ -4042,7 +4225,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
/* for ED_view3d_project_float_object */
ED_view3d_init_mats_rv3d(obedit, region->regiondata);
- /* TODO, investigate using index lookup for screen_vert_coords() rather than a hash table */
+ /* TODO: investigate using index lookup for #screen_vert_coords() rather than a hash table. */
/* the floating point coordinates of verts in screen space will be
* stored in a hash table according to the vertices pointer */
@@ -4064,7 +4247,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* store percentage of edge cut for KNIFE_EXACT here.*/
+ /* Store percentage of edge cut for KNIFE_EXACT here. */
BMOpSlot *slot_edge_percents = BMO_slot_get(bmop.slots_in, "edge_percents");
BM_ITER_MESH (be, &iter, bm, BM_EDGES_OF_MESH) {
bool is_cut = false;
@@ -4072,7 +4255,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
const float *sco_a = screen_vert_coords[BM_elem_index_get(be->v1)];
const float *sco_b = screen_vert_coords[BM_elem_index_get(be->v2)];
- /* check for error value (vert cant be projected) */
+ /* check for error value (vert can't be projected) */
if ((sco_a[0] != FLT_MAX) && (sco_b[0] != FLT_MAX)) {
isect = bm_edge_seg_isect(sco_a, sco_b, mouse_path, len, mode, &isected);
@@ -4113,7 +4296,12 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
BM_custom_loop_normals_from_vector_layer(bm, false);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
return OPERATOR_FINISHED;
}
@@ -4516,7 +4704,12 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
}
if (retval) {
- EDBM_update_generic(base->object->data, true, true);
+ EDBM_update(base->object->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
}
MEM_freeN(bases);
@@ -4563,7 +4756,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
.calc_object_remap = true,
}));
- DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY_ALL_MODES);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
}
@@ -4664,7 +4857,12 @@ static int edbm_fill_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -4958,7 +5156,12 @@ static int edbm_fill_grid_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -5030,7 +5233,12 @@ static int edbm_fill_holes_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -5113,7 +5321,12 @@ static int edbm_beautify_fill_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -5197,9 +5410,12 @@ static int edbm_poke_face_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_mesh_normals_update(em);
-
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -5301,7 +5517,12 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op)
BM_custom_loop_normals_from_vector_layer(em->bm, false);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -5413,7 +5634,12 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op)
BM_custom_loop_normals_from_vector_layer(em->bm, false);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -5514,7 +5740,7 @@ static int edbm_decimate_exec(bContext *C, wmOperator *op)
float *vweights = MEM_mallocN(sizeof(*vweights) * bm->totvert, __func__);
{
const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
- const int defbase_act = obedit->actdef - 1;
+ const int defbase_act = BKE_object_defgroup_active_index_get(obedit) - 1;
if (use_vertex_group && (cd_dvert_offset == -1)) {
BKE_report(op->reports, RPT_WARNING, "No active vertex group");
@@ -5597,7 +5823,12 @@ static int edbm_decimate_exec(bContext *C, wmOperator *op)
}
EDBM_selectmode_flush_ex(em, selectmode);
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -5646,7 +5877,7 @@ void MESH_OT_decimate(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* Note, keep in sync with 'rna_def_modifier_decimate' */
+ /* NOTE: keep in sync with 'rna_def_modifier_decimate'. */
RNA_def_float(ot->srna, "ratio", 1.0f, 0.0f, 1.0f, "Ratio", "", 0.0f, 1.0f);
RNA_def_boolean(ot->srna,
@@ -5736,7 +5967,12 @@ static int edbm_dissolve_verts_exec(bContext *C, wmOperator *op)
BM_custom_loop_normals_from_vector_layer(em->bm, false);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -5797,7 +6033,12 @@ static int edbm_dissolve_edges_exec(bContext *C, wmOperator *op)
BM_custom_loop_normals_from_vector_layer(em->bm, false);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -5858,7 +6099,12 @@ static int edbm_dissolve_faces_exec(bContext *C, wmOperator *op)
BM_custom_loop_normals_from_vector_layer(em->bm, false);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -6003,7 +6249,12 @@ static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op)
BM_custom_loop_normals_from_vector_layer(em->bm, false);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -6090,7 +6341,12 @@ static int edbm_dissolve_degenerate_exec(bContext *C, wmOperator *op)
/* tricky to maintain correct selection here, so just flush up from verts */
EDBM_select_flush(em);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
totelem_new[0] += bm->totvert;
totelem_new[1] += bm->totedge;
@@ -6181,7 +6437,12 @@ static int edbm_delete_edgeloop_exec(bContext *C, wmOperator *op)
EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -6242,10 +6503,13 @@ static int edbm_split_exec(bContext *C, wmOperator *op)
continue;
}
- /* Geometry has changed, need to recalc normals and looptris */
- EDBM_mesh_normals_update(em);
-
- EDBM_update_generic(obedit->data, true, true);
+ /* Geometry has changed, need to recalculate normals and tessellation. */
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -6297,7 +6561,7 @@ enum {
typedef struct BMElemSort {
/** Sort factor */
float srt;
- /** Original index of this element _in its mempool_ */
+ /** Original index of this element (in its #BLI_mempool). */
int org_idx;
} BMElemSort;
@@ -6490,7 +6754,7 @@ static void sort_bmelem_flag(bContext *C,
BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) {
if (BM_elem_flag_test(fa, flag)) {
/* Reverse materials' order, not order of faces inside each mat! */
- /* Note: cannot use totcol, as mat_nr may sometimes be greater... */
+ /* NOTE: cannot use totcol, as mat_nr may sometimes be greater... */
float srt = reverse ? (float)(MAXMAT - fa->mat_nr) : (float)fa->mat_nr;
pb[i] = false;
sb[affected[2]].org_idx = i;
@@ -6697,9 +6961,9 @@ static void sort_bmelem_flag(bContext *C,
}
}
- /* printf("%d vertices: %d to be affected...\n", totelem[0], affected[0]);*/
- /* printf("%d edges: %d to be affected...\n", totelem[1], affected[1]);*/
- /* printf("%d faces: %d to be affected...\n", totelem[2], affected[2]);*/
+ // printf("%d vertices: %d to be affected...\n", totelem[0], affected[0]);
+ // printf("%d edges: %d to be affected...\n", totelem[1], affected[1]);
+ // printf("%d faces: %d to be affected...\n", totelem[2], affected[2]);
if (affected[0] == 0 && affected[1] == 0 && affected[2] == 0) {
for (j = 3; j--;) {
if (pblock[j]) {
@@ -6960,7 +7224,7 @@ static int edbm_bridge_tag_boundary_edges(BMesh *bm)
/* check if its only used by selected faces */
BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- /* tag face for removal*/
+ /* Tag face for removal. */
if (!BM_elem_flag_test(f, BM_ELEM_TAG)) {
BM_elem_flag_enable(f, BM_ELEM_TAG);
totface_del++;
@@ -7043,7 +7307,7 @@ static int edbm_bridge_edge_loops_for_single_editmesh(wmOperator *op,
BMO_op_exec(em->bm, &bmop);
- if (!BMO_error_occurred(em->bm)) {
+ if (!BMO_error_occurred_at_level(em->bm, BMO_ERROR_CANCEL)) {
/* when merge is used the edges are joined and remain selected */
if (use_merge == false) {
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
@@ -7085,7 +7349,12 @@ static int edbm_bridge_edge_loops_for_single_editmesh(wmOperator *op,
}
if (EDBM_op_finish(em, &bmop, op, true)) {
- EDBM_update_generic(me, true, true);
+ EDBM_update(me,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
/* Always return finished so the user can select different options. */
@@ -7220,7 +7489,12 @@ static int edbm_wireframe_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
}
MEM_freeN(objects);
@@ -7311,7 +7585,12 @@ static int edbm_offset_edgeloop_exec(bContext *C, wmOperator *op)
em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
if (EDBM_op_finish(em, &bmop, op, true)) {
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
changed_multi = true;
}
}
@@ -7394,7 +7673,7 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
BMO_op_exec(em->bm, &bmop);
/* Hull fails if input is coplanar */
- if (BMO_error_occurred(em->bm)) {
+ if (BMO_error_occurred_at_level(em->bm, BMO_ERROR_CANCEL)) {
EDBM_op_finish(em, &bmop, op, true);
continue;
}
@@ -7441,7 +7720,12 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
EDBM_selectmode_flush(em);
}
@@ -7529,7 +7813,12 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op)
if (!EDBM_op_finish(em, &bmop, op, true)) {
continue;
}
- EDBM_update_generic(obedit->data, true, true);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = true,
+ });
EDBM_selectmode_flush(em);
}
MEM_freeN(objects);
@@ -7671,7 +7960,12 @@ static int mesh_symmetry_snap_exec(bContext *C, wmOperator *op)
}
}
}
- EDBM_update_generic(obedit->data, false, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
/* No need to end cache, just free the array. */
MEM_freeN(index);
@@ -7928,7 +8222,7 @@ enum {
EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED = 114,
};
-/* called in transform_ops.c, on each regeneration of keymaps */
+/* Called in transform_ops.c, on each regeneration of key-maps. */
wmKeyMap *point_normals_modal_keymap(wmKeyConfig *keyconf)
{
static const EnumPropertyItem modal_items[] = {
@@ -8094,7 +8388,7 @@ static void point_normals_update_header(bContext *C, wmOperator *op)
ED_area_status_text(CTX_wm_area(C), header);
}
-/* TODO move that to generic function in BMesh? */
+/* TODO: move that to generic function in BMesh? */
static void bmesh_selected_verts_center_calc(BMesh *bm, float *r_center)
{
BMVert *v;
@@ -8347,7 +8641,12 @@ static int edbm_point_normals_modal(bContext *C, wmOperator *op, const wmEvent *
if (point_normals_ensure(C, op)) {
point_normals_apply(C, op, target, do_reset);
- EDBM_update_generic(obedit->data, true, false); /* Recheck bools. */
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ }); /* Recheck bools. */
point_normals_update_header(C, op);
}
else {
@@ -8404,7 +8703,12 @@ static int edbm_point_normals_exec(bContext *C, wmOperator *op)
point_normals_apply(C, op, target, false);
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
point_normals_cancel(C, op);
return OPERATOR_FINISHED;
@@ -8663,7 +8967,12 @@ static int normals_split_merge(bContext *C, const bool do_merge)
BM_loop_normal_editdata_array_free(lnors_ed_arr);
}
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -8875,7 +9184,12 @@ static int edbm_average_normals_exec(bContext *C, wmOperator *op)
} while ((l_curr = l_curr->next) != l_first);
}
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
BLI_heapsimple_free(loop_weight, NULL);
@@ -9126,7 +9440,12 @@ static int edbm_normals_tools_exec(bContext *C, wmOperator *op)
BM_loop_normal_editdata_array_free(lnors_ed_arr);
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -9280,7 +9599,12 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op)
MEM_freeN(loop_set);
MEM_freeN(vnors);
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -9370,7 +9694,7 @@ static int edbm_smooth_normals_exec(bContext *C, wmOperator *op)
BKE_lnor_space_custom_data_to_normal(
bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->clnors_data, current_normal);
- /* Note: again, this is not true spherical interpolation that normals would need...
+ /* NOTE: again, this is not true spherical interpolation that normals would need...
* But it's probably good enough for now. */
mul_v3_fl(current_normal, 1.0f - factor);
mul_v3_fl(smooth_normal[i], factor);
@@ -9388,7 +9712,12 @@ static int edbm_smooth_normals_exec(bContext *C, wmOperator *op)
BM_loop_normal_editdata_array_free(lnors_ed_arr);
MEM_freeN(smooth_normal);
- EDBM_update_generic(obedit->data, true, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
@@ -9477,7 +9806,12 @@ static int edbm_mod_weighted_strength_exec(bContext *C, wmOperator *op)
}
}
- EDBM_update_generic(obedit->data, false, false);
+ EDBM_update(obedit->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = false,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
MEM_freeN(objects);
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 79385e28aa9..fc9e1aa8b1a 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -33,6 +33,7 @@
#include "BLI_listbase.h"
#include "BKE_context.h"
+#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_key.h"
#include "BKE_layer.h"
@@ -93,6 +94,12 @@ typedef struct BArrayCustomData {
#endif
typedef struct UndoMesh {
+ /**
+ * This undo-meshes in `um_arraystore.local_links`.
+ * Not to be confused with the next and previous undo steps.
+ */
+ struct UndoMesh *local_next, *local_prev;
+
Mesh me;
int selectmode;
@@ -128,7 +135,10 @@ static struct {
struct BArrayStore_AtSize bs_stride;
int users;
- /* We could have the undo API pass in the previous state, for now store a local list */
+ /**
+ * A list of #UndoMesh items ordered from oldest to newest
+ * used to access previous undo data for a mesh.
+ */
ListBase local_links;
# ifdef USE_ARRAY_STORE_THREAD
@@ -520,11 +530,63 @@ static void um_arraystore_free(UndoMesh *um)
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Array Store Utilities
+ * \{ */
+
+/**
+ * Create an array of #UndoMesh from `objects`.
+ *
+ * where each element in the resulting array is the most recently created
+ * undo-mesh for the object's mesh.
+ * When no undo-mesh can be found that array index is NULL.
+ *
+ * This is used for de-duplicating memory between undo steps,
+ * failure to find the undo step will store a full duplicate in memory.
+ * define `DEBUG_PRINT` to check memory is de-duplicating as expected.
+ */
+static UndoMesh **mesh_undostep_reference_elems_from_objects(Object **object, int object_len)
+{
+ /* Map: `Mesh.id.session_uuid` -> `UndoMesh`. */
+ GHash *uuid_map = BLI_ghash_ptr_new_ex(__func__, object_len);
+ UndoMesh **um_references = MEM_callocN(sizeof(UndoMesh *) * object_len, __func__);
+ for (int i = 0; i < object_len; i++) {
+ const Mesh *me = object[i]->data;
+ BLI_ghash_insert(uuid_map, POINTER_FROM_INT(me->id.session_uuid), &um_references[i]);
+ }
+ int uuid_map_len = object_len;
+
+ /* Loop backwards over all previous mesh undo data until either:
+ * - All elements have been found (where `um_references` we'll have every element set).
+ * - There are no undo steps left to look for. */
+ UndoMesh *um_iter = um_arraystore.local_links.last;
+ while (um_iter && (uuid_map_len != 0)) {
+ UndoMesh **um_p;
+ if ((um_p = BLI_ghash_popkey(uuid_map, POINTER_FROM_INT(um_iter->me.id.session_uuid), NULL))) {
+ *um_p = um_iter;
+ uuid_map_len--;
+ }
+ um_iter = um_iter->local_prev;
+ }
+ BLI_assert(uuid_map_len == BLI_ghash_len(uuid_map));
+ BLI_ghash_free(uuid_map, NULL, NULL);
+ if (uuid_map_len == object_len) {
+ MEM_freeN(um_references);
+ um_references = NULL;
+ }
+ return um_references;
+}
+
+/** \} */
+
#endif /* USE_ARRAY_STORE */
/* for callbacks */
/* undo simply makes copies of a bmesh */
-static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key)
+/**
+ * \param um_ref: The reference to use for de-duplicating memory between undo-steps.
+ */
+static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key, UndoMesh *um_ref)
{
BLI_assert(BLI_array_is_zeroed(um, 1));
#ifdef USE_ARRAY_STORE_THREAD
@@ -560,14 +622,8 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key)
#ifdef USE_ARRAY_STORE
{
- /* We could be more clever here,
- * the previous undo state may be from a separate mesh. */
- const UndoMesh *um_ref = um_arraystore.local_links.last ?
- ((LinkData *)um_arraystore.local_links.last)->data :
- NULL;
-
/* Add ourselves. */
- BLI_addtail(&um_arraystore.local_links, BLI_genericNodeN(um));
+ BLI_addtail(&um_arraystore.local_links, um);
# ifdef USE_ARRAY_STORE_THREAD
if (um_arraystore.task_pool == NULL) {
@@ -583,6 +639,8 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key)
um_arraystore_compact_with_info(um, um_ref);
# endif
}
+#else
+ UNUSED_VARS(um_ref);
#endif
return um;
@@ -614,7 +672,7 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em, Key *
em->bm->shapenr = um->shapenr;
- EDBM_mesh_free(em);
+ EDBM_mesh_free_data(em);
bm = BM_mesh_create(&allocsize,
&((struct BMeshCreateParams){
@@ -624,13 +682,21 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em, Key *
BM_mesh_bm_from_me(bm,
&um->me,
(&(struct BMeshFromMeshParams){
- .calc_face_normal = true,
+ /* Handled with tessellation. */
+ .calc_face_normal = false,
.active_shapekey = um->shapenr,
}));
- em_tmp = BKE_editmesh_create(bm, true);
+ em_tmp = BKE_editmesh_create(bm);
*em = *em_tmp;
+ /* Calculate face normals and tessellation at once since it's multi-threaded.
+ * The vertex normals are stored in the undo-mesh, so this doesn't need to be updated. */
+ BKE_editmesh_looptri_calc_ex(em,
+ &(const struct BMeshCalcTessellation_Params){
+ .face_normals = true,
+ });
+
em->selectmode = um->selectmode;
bm->selectmode = um->selectmode;
@@ -682,11 +748,9 @@ static void undomesh_free_data(UndoMesh *um)
/* we need to expand so any allocations in custom-data are freed with the mesh */
um_arraystore_expand(um);
- {
- LinkData *link = BLI_findptr(&um_arraystore.local_links, um, offsetof(LinkData, data));
- BLI_remlink(&um_arraystore.local_links, link);
- MEM_freeN(link);
- }
+ BLI_assert(BLI_findindex(&um_arraystore.local_links, um) != -1);
+ BLI_remlink(&um_arraystore.local_links, um);
+
um_arraystore_free(um);
#endif
@@ -720,7 +784,6 @@ static Object *editmesh_object_from_context(bContext *C)
* \{ */
typedef struct MeshUndoStep_Elem {
- struct MeshUndoStep_Elem *next, *prev;
UndoRefID_Object obedit_ref;
UndoMesh data;
} MeshUndoStep_Elem;
@@ -749,6 +812,12 @@ static bool mesh_undosys_step_encode(struct bContext *C, struct Main *bmain, Und
us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
us->elems_len = objects_len;
+ UndoMesh **um_references = NULL;
+
+#ifdef USE_ARRAY_STORE
+ um_references = mesh_undostep_reference_elems_from_objects(objects, objects_len);
+#endif
+
for (uint i = 0; i < objects_len; i++) {
Object *ob = objects[i];
MeshUndoStep_Elem *elem = &us->elems[i];
@@ -756,12 +825,22 @@ static bool mesh_undosys_step_encode(struct bContext *C, struct Main *bmain, Und
elem->obedit_ref.ptr = ob;
Mesh *me = elem->obedit_ref.ptr->data;
BMEditMesh *em = me->edit_mesh;
- undomesh_from_editmesh(&elem->data, me->edit_mesh, me->key);
+ undomesh_from_editmesh(
+ &elem->data, me->edit_mesh, me->key, um_references ? um_references[i] : NULL);
em->needs_flush_to_id = 1;
us->step.data_size += elem->data.undo_size;
+
+#ifdef USE_ARRAY_STORE
+ /** As this is only data storage it is safe to set the session ID here. */
+ elem->data.me.id.session_uuid = me->id.session_uuid;
+#endif
}
MEM_freeN(objects);
+ if (um_references != NULL) {
+ MEM_freeN(um_references);
+ }
+
bmain->is_memfile_undo_flush_needed = true;
return true;
@@ -795,7 +874,7 @@ static void mesh_undosys_step_decode(struct bContext *C,
BMEditMesh *em = me->edit_mesh;
undomesh_to_editmesh(&elem->data, obedit, em, me->key);
em->needs_flush_to_id = 1;
- DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
}
/* The first element is always active */
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 19c9909039c..85c646d689c 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -68,6 +68,9 @@
* just as the undo stack would.
* So leaving this as an interface for further work */
+/**
+ * Save a copy of the #BMesh for restoring later.
+ */
BMBackup EDBM_redo_state_store(BMEditMesh *em)
{
BMBackup backup;
@@ -75,42 +78,41 @@ BMBackup EDBM_redo_state_store(BMEditMesh *em)
return backup;
}
-void EDBM_redo_state_restore(BMBackup backup, BMEditMesh *em, int recalctess)
+void EDBM_redo_state_restore(BMBackup *backup, BMEditMesh *em, bool recalc_looptri)
{
BMesh *tmpbm;
- if (!em || !backup.bmcopy) {
- return;
- }
BM_mesh_data_free(em->bm);
- tmpbm = BM_mesh_copy(backup.bmcopy);
+ tmpbm = BM_mesh_copy(backup->bmcopy);
*em->bm = *tmpbm;
MEM_freeN(tmpbm);
tmpbm = NULL;
- if (recalctess) {
+ if (recalc_looptri) {
BKE_editmesh_looptri_calc(em);
}
}
-void EDBM_redo_state_free(BMBackup *backup, BMEditMesh *em, int recalctess)
+/**
+ * Delete the backup, flushing it to an edit-mesh.
+ */
+void EDBM_redo_state_restore_and_free(BMBackup *backup, BMEditMesh *em, bool recalc_looptri)
{
- if (em && backup->bmcopy) {
- BM_mesh_data_free(em->bm);
- *em->bm = *backup->bmcopy;
- }
- else if (backup->bmcopy) {
- BM_mesh_data_free(backup->bmcopy);
+ BM_mesh_data_free(em->bm);
+ *em->bm = *backup->bmcopy;
+ MEM_freeN(backup->bmcopy);
+ backup->bmcopy = NULL;
+ if (recalc_looptri) {
+ BKE_editmesh_looptri_calc(em);
}
+}
+void EDBM_redo_state_free(BMBackup *backup)
+{
if (backup->bmcopy) {
+ BM_mesh_data_free(backup->bmcopy);
MEM_freeN(backup->bmcopy);
}
- backup->bmcopy = NULL;
-
- if (recalctess && em) {
- BKE_editmesh_looptri_calc(em);
- }
}
/** \} */
@@ -132,75 +134,76 @@ bool EDBM_op_init(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const char *
return false;
}
- if (!em->emcopy) {
- em->emcopy = BKE_editmesh_copy(em);
- }
- em->emcopyusers++;
-
va_end(list);
return true;
}
-/* returns 0 on error, 1 on success. executes and finishes a bmesh operator */
+/**
+ * The return value:
+ * - False on error (the mesh must not be changed).
+ * - True on success, executes and finishes a #BMesh operator.
+ */
bool EDBM_op_finish(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const bool do_report)
{
const char *errmsg;
- BMO_op_finish(em->bm, bmop);
-
- if (BMO_error_get(em->bm, &errmsg, NULL)) {
- BMEditMesh *emcopy = em->emcopy;
+#ifndef NDEBUG
+ struct {
+ int verts_len, edges_len, loops_len, faces_len;
+ } em_state_prev = {
+ .verts_len = em->bm->totvert,
+ .edges_len = em->bm->totedge,
+ .loops_len = em->bm->totloop,
+ .faces_len = em->bm->totface,
+ };
+#endif
- if (do_report) {
- BKE_report(op->reports, RPT_ERROR, errmsg);
- }
+ BMO_op_finish(em->bm, bmop);
- EDBM_mesh_free(em);
- *em = *emcopy;
-
- MEM_freeN(emcopy);
- em->emcopyusers = 0;
- em->emcopy = NULL;
-
- /**
- * Note, we could pass in the mesh, however this is an exceptional case, allow a slow lookup.
- *
- * This is needed because the COW mesh makes a full copy of the #BMEditMesh
- * instead of sharing the pointer, tagging since this has been freed above,
- * the #BMEditMesh.emcopy needs to be flushed to the COW edit-mesh, see T55457.
- */
- {
- Main *bmain = G_MAIN;
- for (Mesh *mesh = bmain->meshes.first; mesh; mesh = mesh->id.next) {
- if (mesh->edit_mesh == em) {
- DEG_id_tag_update(&mesh->id, ID_RECALC_COPY_ON_WRITE);
- break;
- }
+ bool changed = false;
+ bool changed_was_set = false;
+
+ eBMOpErrorLevel level;
+ while (BMO_error_pop(em->bm, &errmsg, NULL, &level)) {
+ ReportType type = RPT_INFO;
+ switch (level) {
+ case BMO_ERROR_CANCEL: {
+ changed_was_set = true;
+ break;
+ }
+ case BMO_ERROR_WARN: {
+ type = RPT_WARNING;
+ changed_was_set = true;
+ changed = true;
+ break;
+ }
+ case BMO_ERROR_FATAL: {
+ type = RPT_ERROR;
+ changed_was_set = true;
+ changed = true;
+ break;
}
}
- /* when copying, tessellation isn't to for faster copying,
- * but means we need to re-tessellate here */
- if (em->looptris == NULL) {
- BKE_editmesh_looptri_calc(em);
+ if (do_report) {
+ BKE_report(op->reports, type, errmsg);
}
-
- return false;
}
-
- em->emcopyusers--;
- if (em->emcopyusers < 0) {
- printf("warning: em->emcopyusers was less than zero.\n");
+ if (changed_was_set == false) {
+ changed = true;
}
- if (em->emcopyusers <= 0) {
- BKE_editmesh_free(em->emcopy);
- MEM_freeN(em->emcopy);
- em->emcopy = NULL;
+#ifndef NDEBUG
+ if (changed == false) {
+ BLI_assert((em_state_prev.verts_len == em->bm->totvert) &&
+ (em_state_prev.edges_len == em->bm->totedge) &&
+ (em_state_prev.loops_len == em->bm->totloop) &&
+ (em_state_prev.faces_len == em->bm->totface));
}
+#endif
- return true;
+ return changed;
}
bool EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt, ...)
@@ -217,11 +220,6 @@ bool EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt, ...)
return false;
}
- if (!em->emcopy) {
- em->emcopy = BKE_editmesh_copy(em);
- }
- em->emcopyusers++;
-
BMO_op_exec(bm, &bmop);
va_end(list);
@@ -249,11 +247,6 @@ bool EDBM_op_call_and_selectf(BMEditMesh *em,
return false;
}
- if (!em->emcopy) {
- em->emcopy = BKE_editmesh_copy(em);
- }
- em->emcopyusers++;
-
BMO_op_exec(bm, &bmop);
slot_select_out = BMO_slot_get(bmop.slots_out, select_slot_out);
@@ -284,11 +277,6 @@ bool EDBM_op_call_silentf(BMEditMesh *em, const char *fmt, ...)
return false;
}
- if (!em->emcopy) {
- em->emcopy = BKE_editmesh_copy(em);
- }
- em->emcopyusers++;
-
BMO_op_exec(bm, &bmop);
va_end(list);
@@ -317,17 +305,13 @@ void EDBM_mesh_make(Object *ob, const int select_mode, const bool add_key_index)
if (me->edit_mesh) {
/* this happens when switching shape keys */
- EDBM_mesh_free(me->edit_mesh);
+ EDBM_mesh_free_data(me->edit_mesh);
MEM_freeN(me->edit_mesh);
}
- /* currently executing operators re-tessellates, so we can avoid doing here
- * but at some point it may need to be added back. */
-#if 0
- me->edit_mesh = BKE_editmesh_create(bm, true);
-#else
- me->edit_mesh = BKE_editmesh_create(bm, false);
-#endif
+ /* Executing operators re-tessellates,
+ * so we can avoid doing here but at some point it may need to be added back. */
+ me->edit_mesh = BKE_editmesh_create(bm);
me->edit_mesh->selectmode = me->edit_mesh->bm->selectmode = select_mode;
me->edit_mesh->mat_nr = (ob->actcol > 0) ? ob->actcol - 1 : 0;
@@ -338,7 +322,8 @@ void EDBM_mesh_make(Object *ob, const int select_mode, const bool add_key_index)
/**
* \warning This can invalidate the #Mesh runtime cache of other objects (for linked duplicates).
- * Most callers should run #DEG_id_tag_update on \a ob->data, see: T46738, T46913
+ * Most callers should run #DEG_id_tag_update on `ob->data`, see: T46738, T46913.
+ * This ensures #BKE_object_free_derived_caches runs on all objects that use this mesh.
*/
void EDBM_mesh_load_ex(Main *bmain, Object *ob, bool free_data)
{
@@ -358,25 +343,6 @@ void EDBM_mesh_load_ex(Main *bmain, Object *ob, bool free_data)
.calc_object_remap = true,
.update_shapekey_indices = !free_data,
}));
-
- /* Free derived mesh. usually this would happen through depsgraph but there
- * are exceptions like file save that will not cause this, and we want to
- * avoid ending up with an invalid derived mesh then.
- *
- * Do it for all objects which shares the same mesh datablock, since their
- * derived meshes might also be referencing data which was just freed,
- *
- * Annoying enough, but currently seems most efficient way to avoid access
- * of freed data on scene update, especially in cases when there are dependency
- * cycles.
- */
-#if 0
- for (Object *other_object = bmain->objects.first; other_object != NULL; other_object = other_object->id.next) {
- if (other_object->data == ob->data) {
- BKE_object_free_derived_caches(other_object);
- }
- }
-#endif
}
void EDBM_mesh_clear(BMEditMesh *em)
@@ -384,8 +350,8 @@ void EDBM_mesh_clear(BMEditMesh *em)
/* clear bmesh */
BM_mesh_clear(em->bm);
- /* free derived meshes */
- BKE_editmesh_free_derivedmesh(em);
+ /* Free evaluated meshes & cache. */
+ BKE_editmesh_free_derived_caches(em);
/* free tessellation data */
em->tottri = 0;
@@ -401,9 +367,9 @@ void EDBM_mesh_load(Main *bmain, Object *ob)
}
/**
- * Should only be called on the active editmesh, otherwise call #BKE_editmesh_free
+ * Should only be called on the active edit-mesh, otherwise call #BKE_editmesh_free_data.
*/
-void EDBM_mesh_free(BMEditMesh *em)
+void EDBM_mesh_free_data(BMEditMesh *em)
{
/* These tables aren't used yet, so it's not strictly necessary
* to 'end' them but if someone tries to start using them,
@@ -411,7 +377,7 @@ void EDBM_mesh_free(BMEditMesh *em)
ED_mesh_mirror_spatial_table_end(NULL);
ED_mesh_mirror_topo_table_end(NULL);
- BKE_editmesh_free(em);
+ BKE_editmesh_free_data(em);
}
/** \} */
@@ -438,7 +404,7 @@ void EDBM_selectmode_to_scene(bContext *C)
void EDBM_selectmode_flush_ex(BMEditMesh *em, const short selectmode)
{
- BM_mesh_select_mode_flush_ex(em->bm, selectmode);
+ BM_mesh_select_mode_flush_ex(em->bm, selectmode, BM_SELECT_LEN_FLUSH_RECALC_ALL);
}
void EDBM_selectmode_flush(BMEditMesh *em)
@@ -474,7 +440,7 @@ void EDBM_select_more(BMEditMesh *em, const bool use_face_step)
use_faces,
use_face_step);
BMO_op_exec(em->bm, &bmop);
- /* don't flush selection in edge/vertex mode */
+ /* Don't flush selection in edge/vertex mode. */
BMO_slot_buffer_hflag_enable(
em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? true : false);
BMO_op_finish(em->bm, &bmop);
@@ -496,7 +462,7 @@ void EDBM_select_less(BMEditMesh *em, const bool use_face_step)
use_faces,
use_face_step);
BMO_op_exec(em->bm, &bmop);
- /* don't flush selection in edge/vertex mode */
+ /* Don't flush selection in edge/vertex mode. */
BMO_slot_buffer_hflag_disable(
em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? true : false);
BMO_op_finish(em->bm, &bmop);
@@ -1011,7 +977,7 @@ BMFace *EDBM_uv_active_face_get(BMEditMesh *em, const bool sloppy, const bool se
return NULL;
}
-/* can we edit UV's for this mesh?*/
+/* Can we edit UV's for this mesh? */
bool EDBM_uv_check(BMEditMesh *em)
{
/* some of these checks could be a touch overkill */
@@ -1222,12 +1188,12 @@ BMVert *EDBM_verts_mirror_get(BMEditMesh *em, BMVert *v)
BMEdge *EDBM_verts_mirror_get_edge(BMEditMesh *em, BMEdge *e)
{
- BMVert *v1_mirr = EDBM_verts_mirror_get(em, e->v1);
- if (v1_mirr) {
- BMVert *v2_mirr = EDBM_verts_mirror_get(em, e->v2);
- if (v2_mirr) {
- return BM_edge_exists(v1_mirr, v2_mirr);
- }
+ BMVert *v1_mirr, *v2_mirr;
+ if ((v1_mirr = EDBM_verts_mirror_get(em, e->v1)) &&
+ (v2_mirr = EDBM_verts_mirror_get(em, e->v2)) &&
+ /* While highly unlikely, a zero length central edges vertices can match, see T89342. */
+ LIKELY(v1_mirr != v2_mirr)) {
+ return BM_edge_exists(v1_mirr, v2_mirr);
}
return NULL;
@@ -1405,9 +1371,17 @@ bool EDBM_mesh_reveal(BMEditMesh *em, bool select)
/** \name Update API
* \{ */
+void EDBM_mesh_normals_update_ex(BMEditMesh *em, const struct BMeshNormalsUpdate_Params *params)
+{
+ BM_mesh_normals_update_ex(em->bm, params);
+}
+
void EDBM_mesh_normals_update(BMEditMesh *em)
{
- BM_mesh_normals_update(em->bm);
+ EDBM_mesh_normals_update_ex(em,
+ &(const struct BMeshNormalsUpdate_Params){
+ .face_normals = true,
+ });
}
void EDBM_stats_update(BMEditMesh *em)
@@ -1439,21 +1413,32 @@ void EDBM_stats_update(BMEditMesh *em)
}
}
-/* so many tools call these that we better make it a generic function.
+/**
+ * So many tools call these that we better make it a generic function.
*/
-void EDBM_update_generic(Mesh *mesh, const bool do_tessellation, const bool is_destructive)
+void EDBM_update(Mesh *mesh, const struct EDBMUpdate_Params *params)
{
BMEditMesh *em = mesh->edit_mesh;
/* Order of calling isn't important. */
DEG_id_tag_update(&mesh->id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, &mesh->id);
- if (do_tessellation) {
- BKE_editmesh_looptri_calc(em);
+ if (params->calc_normals && params->calc_looptri) {
+ /* Calculating both has some performance gains. */
+ BKE_editmesh_looptri_and_normals_calc(em);
+ }
+ else {
+ if (params->calc_normals) {
+ EDBM_mesh_normals_update(em);
+ }
+
+ if (params->calc_looptri) {
+ BKE_editmesh_looptri_calc(em);
+ }
}
- if (is_destructive) {
- /* TODO. we may be able to remove this now! - Campbell */
+ if (params->is_destructive) {
+ /* TODO(campbell): we may be able to remove this now! */
// BM_mesh_elem_table_free(em->bm, BM_ALL_NOLOOP);
}
else {
@@ -1464,8 +1449,8 @@ void EDBM_update_generic(Mesh *mesh, const bool do_tessellation, const bool is_d
BM_lnorspace_invalidate(em->bm, false);
em->bm->spacearr_dirty &= ~BM_SPACEARR_BMO_SET;
}
- /* don't keep stale derivedMesh data around, see: T38872. */
- BKE_editmesh_free_derivedmesh(em);
+ /* Don't keep stale evaluated mesh data around, see: T38872. */
+ BKE_editmesh_free_derived_caches(em);
#ifdef DEBUG
{
@@ -1477,6 +1462,17 @@ void EDBM_update_generic(Mesh *mesh, const bool do_tessellation, const bool is_d
#endif
}
+/* Bad level call from Python API. */
+void EDBM_update_extern(struct Mesh *me, const bool do_tessellation, const bool is_destructive)
+{
+ EDBM_update(me,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = do_tessellation,
+ .calc_normals = false,
+ .is_destructive = is_destructive,
+ });
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -1544,7 +1540,7 @@ int EDBM_elem_to_index_any(BMEditMesh *em, BMElem *ele)
return index;
}
-BMElem *EDBM_elem_from_index_any(BMEditMesh *em, int index)
+BMElem *EDBM_elem_from_index_any(BMEditMesh *em, uint index)
{
BMesh *bm = em->bm;
@@ -1585,14 +1581,14 @@ int EDBM_elem_to_index_any_multi(ViewLayer *view_layer,
}
BMElem *EDBM_elem_from_index_any_multi(ViewLayer *view_layer,
- int object_index,
- int elem_index,
+ uint object_index,
+ uint elem_index,
Object **r_obedit)
{
uint bases_len;
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(view_layer, NULL, &bases_len);
*r_obedit = NULL;
- Object *obedit = ((uint)object_index < bases_len) ? bases[object_index]->object : NULL;
+ Object *obedit = (object_index < bases_len) ? bases[object_index]->object : NULL;
MEM_freeN(bases);
if (obedit != NULL) {
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -1659,8 +1655,8 @@ bool BMBVH_EdgeVisible(struct BMBVHTree *tree,
scale_point(co1, co2, 0.99);
scale_point(co3, co2, 0.99);
- /* ok, idea is to generate rays going from the camera origin to the
- * three points on the edge (v1, mid, v2)*/
+ /* OK, idea is to generate rays going from the camera origin to the
+ * three points on the edge (v1, mid, v2). */
sub_v3_v3v3(dir1, origin, co1);
sub_v3_v3v3(dir2, origin, co2);
sub_v3_v3v3(dir3, origin, co3);
@@ -1669,8 +1665,8 @@ bool BMBVH_EdgeVisible(struct BMBVHTree *tree,
normalize_v3_length(dir2, epsilon);
normalize_v3_length(dir3, epsilon);
- /* offset coordinates slightly along view vectors, to avoid
- * hitting the faces that own the edge.*/
+ /* Offset coordinates slightly along view vectors,
+ * to avoid hitting the faces that own the edge. */
add_v3_v3v3(co1, co1, dir1);
add_v3_v3v3(co2, co2, dir2);
add_v3_v3v3(co3, co3, dir3);
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 3a05cde7aa1..73b3fb9724e 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -34,6 +34,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
+#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
#include "BKE_report.h"
@@ -61,7 +62,6 @@ static CustomData *mesh_customdata_get_type(Mesh *me, const char htype, int *r_t
BMesh *bm = (me->edit_mesh) ? me->edit_mesh->bm : NULL;
int tot;
- /* this */
switch (htype) {
case BM_VERT:
if (bm) {
@@ -167,7 +167,7 @@ static void mesh_uv_reset_array(float **fuv, const int len)
fuv[3][0] = 0.0;
fuv[3][1] = 1.0;
- /*make sure we ignore 2-sided faces*/
+ /* Make sure we ignore 2-sided faces. */
}
else if (len > 2) {
float fac = 0.0f, dfac = 1.0f / (float)len;
@@ -253,7 +253,7 @@ void ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me)
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
}
-/* note: keep in sync with ED_mesh_color_add */
+/* NOTE: keep in sync with #ED_mesh_color_add. */
int ED_mesh_uv_texture_add(Mesh *me, const char *name, const bool active_set, const bool do_init)
{
BMEditMesh *em;
@@ -378,7 +378,7 @@ bool ED_mesh_uv_texture_remove_named(Mesh *me, const char *name)
return false;
}
-/* note: keep in sync with ED_mesh_uv_texture_add */
+/* NOTE: keep in sync with #ED_mesh_uv_texture_add. */
int ED_mesh_color_add(Mesh *me, const char *name, const bool active_set, const bool do_init)
{
BMEditMesh *em;
@@ -484,7 +484,7 @@ bool ED_mesh_color_remove_named(Mesh *me, const char *name)
/*********************** Sculpt Vertex colors operators ************************/
-/* note: keep in sync with ED_mesh_uv_texture_add */
+/* NOTE: keep in sync with #ED_mesh_uv_texture_add. */
int ED_mesh_sculpt_color_add(Mesh *me, const char *name, const bool active_set, const bool do_init)
{
BMEditMesh *em;
@@ -1097,7 +1097,7 @@ static void mesh_add_edges(Mesh *mesh, int len)
totedge = mesh->totedge + len;
- /* update customdata */
+ /* Update custom-data. */
CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH.emask, CD_DEFAULT, totedge);
CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 763bdf04d83..f25317e8e85 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -51,7 +51,7 @@ bool EDBM_op_call_and_selectf(struct BMEditMesh *em,
const bool select_replace,
const char *fmt,
...);
-/* Same as above, but doesn't report errors.*/
+/* Same as above, but doesn't report errors. */
bool EDBM_op_call_silentf(struct BMEditMesh *em, const char *fmt, ...);
/* these next two functions are the split version of EDBM_op_callf, so you can
@@ -77,15 +77,15 @@ struct BMElem *EDBM_elem_from_selectmode(struct BMEditMesh *em,
struct BMFace *efa);
int EDBM_elem_to_index_any(struct BMEditMesh *em, struct BMElem *ele);
-struct BMElem *EDBM_elem_from_index_any(struct BMEditMesh *em, int index);
+struct BMElem *EDBM_elem_from_index_any(struct BMEditMesh *em, uint index);
int EDBM_elem_to_index_any_multi(struct ViewLayer *view_layer,
struct BMEditMesh *em,
struct BMElem *ele,
int *r_object_index);
struct BMElem *EDBM_elem_from_index_any_multi(struct ViewLayer *view_layer,
- int object_index,
- int elem_index,
+ uint object_index,
+ uint elem_index,
struct Object **r_obedit);
bool edbm_extrude_edges_indiv(struct BMEditMesh *em,
diff --git a/source/blender/editors/mesh/mesh_mirror.c b/source/blender/editors/mesh/mesh_mirror.c
index 0f746dfd3a0..5eb69aab48b 100644
--- a/source/blender/editors/mesh/mesh_mirror.c
+++ b/source/blender/editors/mesh/mesh_mirror.c
@@ -308,8 +308,9 @@ void ED_mesh_mirrtopo_init(BMEditMesh *em,
last = 0;
- /* Get the pairs out of the sorted hashes, note, totvert+1 means we can use the previous 2,
- * but you cant ever access the last 'a' index of MirrTopoPairs */
+ /* Get the pairs out of the sorted hashes.
+ * NOTE: `totvert + 1` means we can use the previous 2,
+ * but you can't ever access the last 'a' index of #MirrTopoPairs. */
if (em) {
BMVert **vtable = em->bm->vtable;
for (a = 1; a <= totvert; a++) {
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 3450d61337c..27fb21e1dfb 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -149,7 +149,7 @@ static void join_mesh_single(Depsgraph *depsgraph,
mul_m4_m4m4(cmat, imat, ob_src->obmat);
/* transform vertex coordinates into new space */
- for (a = 0, mvert = *mvert_pp; a < me->totvert; a++, mvert++) {
+ for (a = 0; a < me->totvert; a++, mvert++) {
mul_m4_v3(cmat, mvert->co);
}
@@ -390,7 +390,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* Apply parent transform if the active object's parent was joined to it.
- * Note: This doesn't apply recursive parenting. */
+ * NOTE: This doesn't apply recursive parenting. */
if (join_parent) {
ob->parent = NULL;
BKE_object_apply_mat4_ex(ob, ob->obmat, ob->parent, ob->parentinv, false);
@@ -475,16 +475,17 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
me = ob_iter->data;
/* Join this object's vertex groups to the base one's */
- for (dg = ob_iter->defbase.first; dg; dg = dg->next) {
+ for (dg = me->vertex_group_names.first; dg; dg = dg->next) {
/* See if this group exists in the object (if it doesn't, add it to the end) */
if (!BKE_object_defgroup_find_name(ob, dg->name)) {
odg = MEM_mallocN(sizeof(bDeformGroup), "join deformGroup");
memcpy(odg, dg, sizeof(bDeformGroup));
- BLI_addtail(&ob->defbase, odg);
+ BLI_addtail(&mesh_active->vertex_group_names, odg);
}
}
- if (ob->defbase.first && ob->actdef == 0) {
- ob->actdef = 1;
+ if (!BLI_listbase_is_empty(&mesh_active->vertex_group_names) &&
+ me->vertex_group_active_index == 0) {
+ me->vertex_group_active_index = 1;
}
/* Join this object's face maps to the base one's. */
@@ -1060,7 +1061,7 @@ static float *editmesh_get_mirror_uv(
cent_vec[1] = face_cent[1];
}
- /* TODO - Optimize */
+ /* TODO: Optimize. */
{
BMIter iter;
BMFace *efa;
@@ -1473,19 +1474,21 @@ bool ED_mesh_pick_vert(
MDeformVert *ED_mesh_active_dvert_get_em(Object *ob, BMVert **r_eve)
{
- if (ob->mode & OB_MODE_EDIT && ob->type == OB_MESH && ob->defbase.first) {
+ if (ob->mode & OB_MODE_EDIT && ob->type == OB_MESH) {
Mesh *me = ob->data;
- BMesh *bm = me->edit_mesh->bm;
- const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
+ if (!BLI_listbase_is_empty(&me->vertex_group_names)) {
+ BMesh *bm = me->edit_mesh->bm;
+ const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
- if (cd_dvert_offset != -1) {
- BMVert *eve = BM_mesh_active_vert_get(bm);
+ if (cd_dvert_offset != -1) {
+ BMVert *eve = BM_mesh_active_vert_get(bm);
- if (eve) {
- if (r_eve) {
- *r_eve = eve;
+ if (eve) {
+ if (r_eve) {
+ *r_eve = eve;
+ }
+ return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
}
- return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
}
}
}
diff --git a/source/blender/editors/metaball/editmball_undo.c b/source/blender/editors/metaball/editmball_undo.c
index a8b471a7c92..f7b53b5513f 100644
--- a/source/blender/editors/metaball/editmball_undo.c
+++ b/source/blender/editors/metaball/editmball_undo.c
@@ -215,7 +215,7 @@ static void mball_undosys_step_decode(struct bContext *C,
}
undomball_to_editmball(&elem->data, mb);
mb->needs_flush_to_id = 1;
- DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(&mb->id, ID_RECALC_GEOMETRY);
}
/* The first element is always active */
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index 77b5379ddd4..4338b043fc9 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -87,7 +87,7 @@ if(WITH_INTERNATIONAL)
endif()
if(WITH_EXPERIMENTAL_FEATURES)
- add_definitions(-DWITH_GEOMETRY_NODES)
+ add_definitions(-DWITH_SIMULATION_DATABLOCK)
add_definitions(-DWITH_POINT_CLOUD)
add_definitions(-DWITH_HAIR_NODES)
endif()
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index c722a0c00ee..8ae74fbfafa 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -407,7 +407,7 @@ void ED_object_add_generic_props(wmOperatorType *ot, bool do_editmode)
"Enter edit mode when adding this object");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
- /* note: this property gets hidden for add-camera operator */
+ /* NOTE: this property gets hidden for add-camera operator. */
prop = RNA_def_enum(
ot->srna, "align", align_options, ALIGN_WORLD, "Align", "The alignment of the new object");
RNA_def_property_update_runtime(prop, view_align_update);
@@ -456,49 +456,53 @@ void ED_object_add_mesh_props(wmOperatorType *ot)
bool ED_object_add_generic_get_opts(bContext *C,
wmOperator *op,
const char view_align_axis,
- float loc[3],
- float rot[3],
- float scale[3],
- bool *enter_editmode,
- ushort *local_view_bits,
- bool *is_view_aligned)
-{
- PropertyRNA *prop;
-
- /* Switch to Edit mode? optional prop */
- if ((prop = RNA_struct_find_property(op->ptr, "enter_editmode"))) {
+ float r_loc[3],
+ float r_rot[3],
+ float r_scale[3],
+ bool *r_enter_editmode,
+ ushort *r_local_view_bits,
+ bool *r_is_view_aligned)
+{
+ /* Edit Mode! (optional) */
+ {
bool _enter_editmode;
- if (!enter_editmode) {
- enter_editmode = &_enter_editmode;
+ if (!r_enter_editmode) {
+ r_enter_editmode = &_enter_editmode;
}
+ /* Only to ensure the value is _always_ set.
+ * Typically the property will exist when the argument is non-NULL. */
+ *r_enter_editmode = false;
- if (RNA_property_is_set(op->ptr, prop) && enter_editmode) {
- *enter_editmode = RNA_property_boolean_get(op->ptr, prop);
- }
- else {
- *enter_editmode = (U.flag & USER_ADD_EDITMODE) != 0;
- RNA_property_boolean_set(op->ptr, prop, *enter_editmode);
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "enter_editmode");
+ if (prop != NULL) {
+ if (RNA_property_is_set(op->ptr, prop) && r_enter_editmode) {
+ *r_enter_editmode = RNA_property_boolean_get(op->ptr, prop);
+ }
+ else {
+ *r_enter_editmode = (U.flag & USER_ADD_EDITMODE) != 0;
+ RNA_property_boolean_set(op->ptr, prop, *r_enter_editmode);
+ }
}
}
- if (local_view_bits) {
+ if (r_local_view_bits) {
View3D *v3d = CTX_wm_view3d(C);
- *local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
+ *r_local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
}
/* Location! */
{
float _loc[3];
- if (!loc) {
- loc = _loc;
+ if (!r_loc) {
+ r_loc = _loc;
}
if (RNA_struct_property_is_set(op->ptr, "location")) {
- RNA_float_get_array(op->ptr, "location", loc);
+ RNA_float_get_array(op->ptr, "location", r_loc);
}
else {
- ED_object_location_from_view(C, loc);
- RNA_float_set_array(op->ptr, "location", loc);
+ ED_object_location_from_view(C, r_loc);
+ RNA_float_set_array(op->ptr, "location", r_loc);
}
}
@@ -506,33 +510,33 @@ bool ED_object_add_generic_get_opts(bContext *C,
{
bool _is_view_aligned;
float _rot[3];
- if (!is_view_aligned) {
- is_view_aligned = &_is_view_aligned;
+ if (!r_is_view_aligned) {
+ r_is_view_aligned = &_is_view_aligned;
}
- if (!rot) {
- rot = _rot;
+ if (!r_rot) {
+ r_rot = _rot;
}
if (RNA_struct_property_is_set(op->ptr, "rotation")) {
/* If rotation is set, always use it. Alignment (and corresponding user preference)
* can be ignored since this is in world space anyways.
* To not confuse (e.g. on redo), don't set it to #ALIGN_WORLD in the op UI though. */
- *is_view_aligned = false;
- RNA_float_get_array(op->ptr, "rotation", rot);
+ *r_is_view_aligned = false;
+ RNA_float_get_array(op->ptr, "rotation", r_rot);
}
else {
int alignment = ALIGN_WORLD;
- prop = RNA_struct_find_property(op->ptr, "align");
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "align");
if (RNA_property_is_set(op->ptr, prop)) {
/* If alignment is set, always use it. */
- *is_view_aligned = alignment == ALIGN_VIEW;
+ *r_is_view_aligned = alignment == ALIGN_VIEW;
alignment = RNA_property_enum_get(op->ptr, prop);
}
else {
/* If alignment is not set, use User Preferences. */
- *is_view_aligned = (U.flag & USER_ADD_VIEWALIGNED) != 0;
- if (*is_view_aligned) {
+ *r_is_view_aligned = (U.flag & USER_ADD_VIEWALIGNED) != 0;
+ if (*r_is_view_aligned) {
RNA_property_enum_set(op->ptr, prop, ALIGN_VIEW);
alignment = ALIGN_VIEW;
}
@@ -547,18 +551,18 @@ bool ED_object_add_generic_get_opts(bContext *C,
}
switch (alignment) {
case ALIGN_WORLD:
- RNA_float_get_array(op->ptr, "rotation", rot);
+ RNA_float_get_array(op->ptr, "rotation", r_rot);
break;
case ALIGN_VIEW:
- ED_object_rotation_from_view(C, rot, view_align_axis);
- RNA_float_set_array(op->ptr, "rotation", rot);
+ ED_object_rotation_from_view(C, r_rot, view_align_axis);
+ RNA_float_set_array(op->ptr, "rotation", r_rot);
break;
case ALIGN_CURSOR: {
const Scene *scene = CTX_data_scene(C);
float tmat[3][3];
BKE_scene_cursor_rot_to_mat3(&scene->cursor, tmat);
- mat3_normalized_to_eul(rot, tmat);
- RNA_float_set_array(op->ptr, "rotation", rot);
+ mat3_normalized_to_eul(r_rot, tmat);
+ RNA_float_set_array(op->ptr, "rotation", r_rot);
break;
}
}
@@ -568,19 +572,21 @@ bool ED_object_add_generic_get_opts(bContext *C,
/* Scale! */
{
float _scale[3];
- if (!scale) {
- scale = _scale;
+ if (!r_scale) {
+ r_scale = _scale;
}
/* For now this is optional, we can make it always use. */
- copy_v3_fl(scale, 1.0f);
- if ((prop = RNA_struct_find_property(op->ptr, "scale"))) {
+ copy_v3_fl(r_scale, 1.0f);
+
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "scale");
+ if (prop != NULL) {
if (RNA_property_is_set(op->ptr, prop)) {
- RNA_property_float_get_array(op->ptr, prop, scale);
+ RNA_property_float_get_array(op->ptr, prop, r_scale);
}
else {
- copy_v3_fl(scale, 1.0f);
- RNA_property_float_set_array(op->ptr, prop, scale);
+ copy_v3_fl(r_scale, 1.0f);
+ RNA_property_float_set_array(op->ptr, prop, r_scale);
}
}
}
@@ -1312,13 +1318,14 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
const int type = RNA_enum_get(op->ptr, "type");
const bool use_in_front = RNA_boolean_get(op->ptr, "use_in_front");
+ const bool use_lights = RNA_boolean_get(op->ptr, "use_lights");
const int stroke_depth_order = RNA_enum_get(op->ptr, "stroke_depth_order");
ushort local_view_bits;
float loc[3], rot[3];
bool newob = false;
- /* Note: We use 'Y' here (not 'Z'), as */
+ /* NOTE: We use 'Y' here (not 'Z'), as. */
WM_operator_view3d_unit_defaults(C, op);
if (!ED_object_add_generic_get_opts(C, op, 'Y', loc, rot, NULL, NULL, &local_view_bits, NULL)) {
return OPERATOR_CANCELLED;
@@ -1432,6 +1439,13 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
id_us_plus(&md->target_material->id);
}
+ if (use_lights) {
+ ob->dtx |= OB_USE_GPENCIL_LIGHTS;
+ }
+ else {
+ ob->dtx &= ~OB_USE_GPENCIL_LIGHTS;
+ }
+
/* Stroke object is drawn in front of meshes by default. */
if (use_in_front) {
ob->dtx |= OB_DRAW_IN_FRONT;
@@ -1474,6 +1488,7 @@ static void object_add_ui(bContext *UNUSED(C), wmOperator *op)
int type = RNA_enum_get(op->ptr, "type");
if (type == GP_LRT_COLLECTION || type == GP_LRT_OBJECT || type == GP_LRT_SCENE) {
+ uiItemR(layout, op->ptr, "use_lights", 0, NULL, ICON_NONE);
uiItemR(layout, op->ptr, "use_in_front", 0, NULL, ICON_NONE);
bool in_front = RNA_boolean_get(op->ptr, "use_in_front");
uiLayout *row = uiLayoutRow(layout, false);
@@ -1520,6 +1535,8 @@ void OBJECT_OT_gpencil_add(wmOperatorType *ot)
false,
"In Front",
"Show line art grease pencil in front of everything");
+ RNA_def_boolean(
+ ot->srna, "use_lights", false, "Use Lights", "Use lights for this grease pencil object");
RNA_def_enum(
ot->srna,
"stroke_depth_order",
@@ -1828,7 +1845,7 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op)
* ready to be moved around to re-time the sound and/or make new sound clips. */
{
/* create new data for NLA hierarchy */
- AnimData *adt = BKE_animdata_add_id(&ob->id);
+ AnimData *adt = BKE_animdata_ensure_id(&ob->id);
NlaTrack *nlt = BKE_nlatrack_add(adt, NULL, is_liboverride);
NlaStrip *strip = BKE_nla_add_soundstrip(bmain, scene, ob->data);
strip->start = CFRA;
@@ -1837,7 +1854,7 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op)
/* hook them up */
BKE_nlatrack_add_strip(nlt, strip, is_liboverride);
- /* auto-name the strip, and give the track an interesting name */
+ /* Auto-name the strip, and give the track an interesting name. */
BLI_strncpy(nlt->name, DATA_("SoundTrack"), sizeof(nlt->name));
BKE_nlastrip_validate_name(adt, strip);
@@ -1960,7 +1977,7 @@ void OBJECT_OT_pointcloud_add(wmOperatorType *ot)
/** \name Delete Object Operator
* \{ */
/* remove base from a specific scene */
-/* note: now unlinks constraints as well */
+/* NOTE: now unlinks constraints as well. */
void ED_object_base_free_and_unlink(Main *bmain, Scene *scene, Object *ob)
{
if (ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0 &&
@@ -2137,8 +2154,7 @@ static void copy_object_set_idnew(bContext *C)
FOREACH_MAIN_ID_END;
#endif
- BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
- BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_newptr_and_tag_clear(bmain);
}
/** \} */
@@ -2147,7 +2163,7 @@ static void copy_object_set_idnew(bContext *C)
/** \name Make Instanced Objects Real Operator
* \{ */
-/* XXX TODO That whole hierarchy handling based on persistent_id tricks is
+/* XXX TODO: That whole hierarchy handling based on persistent_id tricks is
* very confusing and convoluted, and it will fail in many cases besides basic ones.
* Think this should be replaced by a proper tree-like representation of the instantiations,
* should help a lot in both readability, and precise consistent rebuilding of hierarchy.
@@ -2426,7 +2442,7 @@ static void make_object_duplilist_real(bContext *C,
}
if (ob_dst->parent) {
- /* note, this may be the parent of other objects, but it should
+ /* NOTE: this may be the parent of other objects, but it should
* still work out ok */
BKE_object_apply_mat4(ob_dst, dob->mat, false, true);
@@ -2459,7 +2475,7 @@ static void make_object_duplilist_real(bContext *C,
free_object_duplilist(lb_duplis);
- BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_newptr_and_tag_clear(bmain);
base->object->transflag &= ~OB_DUPLI;
DEG_id_tag_update(&base->object->id, ID_RECALC_COPY_ON_WRITE);
@@ -2474,7 +2490,7 @@ static int object_duplicates_make_real_exec(bContext *C, wmOperator *op)
const bool use_base_parent = RNA_boolean_get(op->ptr, "use_base_parent");
const bool use_hierarchy = RNA_boolean_get(op->ptr, "use_hierarchy");
- BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_newptr_and_tag_clear(bmain);
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) {
make_object_duplilist_real(C, depsgraph, scene, base, use_base_parent, use_hierarchy);
@@ -2559,7 +2575,7 @@ static void object_data_convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *
if (ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
/* We need 'for render' ON here, to enable computing bevel dipslist if needed.
* Also makes sense anyway, we would not want e.g. to lose hidden parts etc. */
- BKE_displist_make_curveTypes(depsgraph, scene, ob, true, false);
+ BKE_displist_make_curveTypes(depsgraph, scene, ob, true);
}
else if (ob->type == OB_MBALL) {
BKE_displist_make_mball(depsgraph, scene, ob);
@@ -2587,8 +2603,8 @@ static void object_data_convert_curve_to_mesh(Main *bmain, Depsgraph *depsgraph,
/* Change objects which are using same curve.
* A bit annoying, but:
* - It's possible to have multiple curve objects selected which are sharing the same curve
- * datablock. We don't want mesh to be created for every of those objects.
- * - This is how conversion worked for a long long time. */
+ * data-block. We don't want mesh to be created for every of those objects.
+ * - This is how conversion worked for a long time. */
LISTBASE_FOREACH (Object *, other_object, &bmain->objects) {
if (other_object->data == curve) {
other_object->type = OB_MESH;
@@ -2632,10 +2648,10 @@ static Base *duplibase_for_convert(
ED_object_base_select(basen, BA_SELECT);
ED_object_base_select(base, BA_DESELECT);
- /* XXX An ugly hack needed because if we re-run depsgraph with some new MBall objects
- * having same 'family name' as orig ones, they will affect end result of MBall computation...
+ /* XXX: An ugly hack needed because if we re-run depsgraph with some new meta-ball objects
+ * having same 'family name' as orig ones, they will affect end result of meta-ball computation.
* For until we get rid of that name-based thingy in MBalls, that should do the trick
- * (this is weak, but other solution (to change name of obn) is even worse imho).
+ * (this is weak, but other solution (to change name of `obn`) is even worse imho).
* See T65996. */
const bool is_meta_ball = (obn->type == OB_MBALL);
void *obdata = obn->data;
@@ -2778,11 +2794,11 @@ static int object_convert_exec(bContext *C, wmOperator *op)
basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
newob = basen->object;
- /* decrement original mesh's usage count */
+ /* Decrement original mesh's usage count. */
Mesh *me = newob->data;
id_us_min(&me->id);
- /* make a new copy of the mesh */
+ /* Make a new copy of the mesh. */
newob->data = BKE_id_copy(bmain, &me->id);
}
else {
@@ -2852,11 +2868,11 @@ static int object_convert_exec(bContext *C, wmOperator *op)
basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
newob = basen->object;
- /* decrement original mesh's usage count */
+ /* Decrement original mesh's usage count. */
Mesh *me = newob->data;
id_us_min(&me->id);
- /* make a new copy of the mesh */
+ /* Make a new copy of the mesh. */
newob->data = BKE_id_copy(bmain, &me->id);
}
else {
@@ -2877,11 +2893,11 @@ static int object_convert_exec(bContext *C, wmOperator *op)
basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
newob = basen->object;
- /* decrement original mesh's usage count */
+ /* Decrement original mesh's usage count. */
Mesh *me = newob->data;
id_us_min(&me->id);
- /* make a new copy of the mesh */
+ /* Make a new copy of the mesh. */
newob->data = BKE_id_copy(bmain, &me->id);
}
else {
@@ -2890,7 +2906,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
}
/* make new mesh data from the original copy */
- /* note: get the mesh from the original, not from the copy in some
+ /* NOTE: get the mesh from the original, not from the copy in some
* cases this doesn't give correct results (when MDEF is used for eg)
*/
Scene *scene_eval = (Scene *)DEG_get_evaluated_id(depsgraph, &scene->id);
@@ -2899,6 +2915,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
me_eval = BKE_mesh_copy_for_eval(me_eval, false);
/* Full (edge-angle based) draw calculation should ideally be performed. */
BKE_mesh_edges_set_draw_render(me_eval);
+ BKE_object_material_from_eval_data(bmain, newob, &me_eval->id);
BKE_mesh_nomain_to_mesh(me_eval, newob->data, newob, &CD_MASK_MESH, true);
BKE_object_free_modifiers(newob, 0); /* after derivedmesh calls! */
}
@@ -2909,10 +2926,10 @@ static int object_convert_exec(bContext *C, wmOperator *op)
basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
newob = basen->object;
- /* decrement original curve's usage count */
+ /* Decrement original curve's usage count. */
id_us_min(&((Curve *)newob->data)->id);
- /* make a new copy of the curve */
+ /* Make a new copy of the curve. */
newob->data = BKE_id_copy(bmain, ob->data);
}
else {
@@ -2990,7 +3007,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
newob = basen->object;
- /* decrement original curve's usage count */
+ /* Decrement original curve's usage count. */
id_us_min(&((Curve *)newob->data)->id);
/* make a new copy of the curve */
@@ -3074,11 +3091,11 @@ static int object_convert_exec(bContext *C, wmOperator *op)
basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
newob = basen->object;
- /* decrement original pointclouds's usage count */
+ /* Decrement original point-cloud's usage count. */
PointCloud *pointcloud = newob->data;
id_us_min(&pointcloud->id);
- /* make a new copy of the pointcloud */
+ /* Make a new copy of the point-cloud. */
newob->data = BKE_id_copy(bmain, &pointcloud->id);
}
else {
@@ -3332,8 +3349,8 @@ static Base *object_add_duplicate_internal(Main *bmain,
/* single object duplicate, if dupflag==0, fully linked, else it uses the flags given */
/* leaves selection of base/object unaltered.
- * note: don't call this within a loop since clear_* funcs loop over the entire database.
- * note: caller must do DAG_relations_tag_update(bmain);
+ * NOTE: don't call this within a loop since clear_* funcs loop over the entire database.
+ * NOTE: caller must do DAG_relations_tag_update(bmain);
* this is not done automatic since we may duplicate many objects in a batch */
Base *ED_object_add_duplicate(
Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base, const eDupli_ID_Flags dupflag)
@@ -3358,7 +3375,7 @@ Base *ED_object_add_duplicate(
DEG_id_tag_update_ex(bmain, (ID *)ob->data, ID_RECALC_EDITORS);
}
- BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_newptr_and_tag_clear(bmain);
return basen;
}
@@ -3374,8 +3391,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
/* We need to handle that here ourselves, because we may duplicate several objects, in which case
* we also want to remap pointers between those... */
- BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
- BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_newptr_and_tag_clear(bmain);
CTX_DATA_BEGIN (C, Base *, base, selected_bases) {
Base *basen = object_add_duplicate_internal(
@@ -3452,6 +3468,19 @@ void OBJECT_OT_duplicate(wmOperatorType *ot)
* Use for drag & drop.
* \{ */
+static Base *object_add_ensure_in_view_layer(Main *bmain, ViewLayer *view_layer, Object *ob)
+{
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+
+ if (!base) {
+ LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
+ BKE_collection_object_add(bmain, layer_collection->collection, ob);
+ base = BKE_view_layer_base_find(view_layer, ob);
+ }
+
+ return base;
+}
+
static int object_add_named_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -3459,7 +3488,8 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
Base *basen;
Object *ob;
- const bool linked = RNA_boolean_get(op->ptr, "linked");
+ const bool duplicate = RNA_boolean_get(op->ptr, "duplicate");
+ const bool linked = duplicate && RNA_boolean_get(op->ptr, "linked");
const eDupli_ID_Flags dupflag = (linked) ? 0 : (eDupli_ID_Flags)U.dupflag;
char name[MAX_ID_NAME - 2];
@@ -3473,10 +3503,30 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
}
/* prepare dupli */
- basen = object_add_duplicate_internal(bmain, scene, view_layer, ob, dupflag, 0);
+ if (duplicate) {
+ basen = object_add_duplicate_internal(
+ bmain,
+ scene,
+ view_layer,
+ ob,
+ dupflag,
+ /* Sub-process flag because the new-ID remapping (#BKE_libblock_relink_to_newid()) in this
+ * function will only work if the object is already linked in the view layer, which is not
+ * the case here. So we have to do the new-ID relinking ourselves
+ * (#copy_object_set_idnew()).
+ */
+ LIB_ID_DUPLICATE_IS_SUBPROCESS);
+ }
+ else {
+ /* basen is actually not a new base in this case. */
+ basen = object_add_ensure_in_view_layer(bmain, view_layer, ob);
+ }
if (basen == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Object could not be duplicated");
+ BKE_report(op->reports,
+ RPT_ERROR,
+ duplicate ? "Object could not be duplicated" :
+ "Object could not be linked to the view layer");
return OPERATOR_CANCELLED;
}
@@ -3523,11 +3573,24 @@ void OBJECT_OT_add_named(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ PropertyRNA *prop;
+
+ prop = RNA_def_boolean(
+ ot->srna,
+ "duplicate",
+ true,
+ "Duplicate",
+ "Create a duplicate of the object. If not set, only ensures the object is linked into the "
+ "active view layer, positions and selects/activates it (deselecting others)");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+
RNA_def_boolean(ot->srna,
"linked",
- 0,
+ false,
"Linked",
- "Duplicate object but not object data, linking to the original data");
+ "Duplicate object but not object data, linking to the original data (ignored if "
+ "'duplicate' is false)");
+
RNA_def_string(ot->srna, "name", NULL, MAX_ID_NAME - 2, "Name", "Object name to add");
object_add_drop_xy_props(ot);
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index a5cad4e087c..3a10a423e91 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -566,7 +566,7 @@ static int multiresbake_image_exec(bContext *C, wmOperator *op)
WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS,
WM_JOB_TYPE_OBJECT_BAKE_TEXTURE);
WM_jobs_customdata_set(wm_job, bkr, multiresbake_freejob);
- WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
+ WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO: only draw bake image, can we enforce this. */
WM_jobs_callbacks(wm_job, multiresbake_startjob, NULL, NULL, NULL);
G.is_break = false;
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 3370476d466..233f2a65dac 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -158,7 +158,7 @@ static int bake_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
/**
* for exec() when there is no render job
- * note: this wont check for the escape key being pressed, but doing so isn't thread-safe.
+ * NOTE: this won't check for the escape key being pressed, but doing so isn't thread-safe.
*/
static int bake_break(void *UNUSED(rjv))
{
@@ -1374,7 +1374,7 @@ static int bake(const BakeAPIRender *bkr,
* the cage is supposed to have interpolated normals
* between the faces unless the geometry is physically
* split. So we create a copy of the low poly mesh without
- * the eventual edge split.*/
+ * the eventual edge split. */
if (md->type == eModifierType_EdgeSplit) {
BLI_remlink(&ob_low_eval->modifiers, md);
@@ -1939,7 +1939,7 @@ static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)
WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS,
WM_JOB_TYPE_OBJECT_BAKE);
WM_jobs_customdata_set(wm_job, bkr, bake_freejob);
- /* TODO - only draw bake image, can we enforce this */
+ /* TODO: only draw bake image, can we enforce this. */
WM_jobs_timer(
wm_job, 0.5, (bkr->target == R_BAKE_TARGET_VERTEX_COLORS) ? NC_GEOM | ND_DATA : NC_IMAGE, 0);
WM_jobs_callbacks(wm_job, bake_startjob, NULL, NULL, NULL);
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 244124a6e0a..4970338973d 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -547,7 +547,7 @@ static void test_constraint(
else {
Curve *cu = ct->tar->data;
- /* auto-set 'Path' setting on curve so this works */
+ /* auto-set 'Path' setting on curve so this works. */
cu->flag |= CU_PATH;
}
}
@@ -696,12 +696,11 @@ static bool edit_constraint_poll_generic(bContext *C,
Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : ED_object_active_context(C);
bConstraint *con = ptr.data;
- if (!ob) {
- CTX_wm_operator_poll_msg_set(C, "Context missing active object");
+ if (!ED_operator_object_active_editable_ex(C, ob)) {
return false;
}
- if (ID_IS_LINKED(ob) || (ptr.owner_id && ID_IS_LINKED(ptr.owner_id))) {
+ if (ptr.owner_id != NULL && ID_IS_LINKED(ptr.owner_id)) {
CTX_wm_operator_poll_msg_set(C, "Cannot edit library data");
return false;
}
@@ -1732,7 +1731,7 @@ static int pose_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
/* force depsgraph to get recalculated since relationships removed */
DEG_relations_tag_update(bmain);
- /* note, calling BIK_clear_data() isn't needed here */
+ /* NOTE: calling BIK_clear_data() isn't needed here. */
return OPERATOR_FINISHED;
}
@@ -1746,8 +1745,8 @@ void POSE_OT_constraints_clear(wmOperatorType *ot)
/* callbacks */
ot->exec = pose_constraints_clear_exec;
- ot->poll = ED_operator_posemode_exclusive; /* XXX - do we want to ensure there are selected
- * bones too? */
+ /* XXX: do we want to ensure there are selected bones too? */
+ ot->poll = ED_operator_object_active_local_editable_posemode_exclusive;
}
static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
@@ -1978,7 +1977,7 @@ static bool get_new_constraint_target(
(!only_curve && !only_mesh)) {
/* Only use the object & bone if the bone is visible & selected
- * since we may have multiple objects in pose mode at once. */
+ * since we may have multiple objects in pose mode at once. */
bPoseChannel *pchan = BKE_pose_channel_active_or_first_selected(ob);
if (pchan != NULL) {
*tar_pchan = pchan;
@@ -2101,7 +2100,7 @@ static int constraint_add_exec(
}
}
- /* do type-specific tweaking to the constraint settings */
+ /* Do type-specific tweaking to the constraint settings. */
switch (type) {
case CONSTRAINT_TYPE_PYTHON: /* FIXME: this code is not really valid anymore */
{
@@ -2462,7 +2461,7 @@ static int pose_ik_clear_exec(bContext *C, wmOperator *UNUSED(op))
/* Refresh depsgraph. */
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- /* Note, notifier might evolve. */
+ /* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob);
}
}
@@ -2480,7 +2479,7 @@ void POSE_OT_ik_clear(wmOperatorType *ot)
/* api callbacks */
ot->exec = pose_ik_clear_exec;
- ot->poll = ED_operator_posemode_exclusive;
+ ot->poll = ED_operator_object_active_local_editable_posemode_exclusive;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index 22c9d669ff3..2109fe2a822 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -33,6 +33,7 @@
#include "BKE_context.h"
#include "BKE_data_transfer.h"
+#include "BKE_deform.h"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remap.h"
#include "BKE_mesh_runtime.h"
@@ -96,7 +97,7 @@ static const EnumPropertyItem DT_layer_items[] = {
{0, NULL, 0, NULL, NULL},
};
-/* Note: rna_enum_dt_layers_select_src_items enum is from rna_modifier.c */
+/* NOTE: #rna_enum_dt_layers_select_src_items enum is from rna_modifier.c. */
static const EnumPropertyItem *dt_layers_select_src_itemf(bContext *C,
PointerRNA *ptr,
PropertyRNA *UNUSED(prop),
@@ -133,12 +134,13 @@ static const EnumPropertyItem *dt_layers_select_src_itemf(bContext *C,
}
if (ob_src) {
- bDeformGroup *dg;
+ const bDeformGroup *dg;
int i;
RNA_enum_item_add_separator(&item, &totitem);
- for (i = 0, dg = ob_src->defbase.first; dg; i++, dg = dg->next) {
+ const ListBase *defbase = BKE_object_defgroup_list(ob_src);
+ for (i = 0, dg = defbase->first; dg; i++, dg = dg->next) {
tmp_item.value = i;
tmp_item.identifier = tmp_item.name = dg->name;
RNA_enum_item_add(&item, &totitem, &tmp_item);
@@ -201,7 +203,7 @@ static const EnumPropertyItem *dt_layers_select_src_itemf(bContext *C,
return item;
}
-/* Note: rna_enum_dt_layers_select_dst_items enum is from rna_modifier.c */
+/* NOTE: #rna_enum_dt_layers_select_dst_items enum is from `rna_modifier.c`. */
static const EnumPropertyItem *dt_layers_select_dst_itemf(bContext *C,
PointerRNA *ptr,
PropertyRNA *UNUSED(prop),
@@ -255,7 +257,7 @@ static const EnumPropertyItem *dt_layers_select_itemf(bContext *C,
return dt_layers_select_src_itemf(C, ptr, prop, r_free);
}
-/* Note: rna_enum_dt_mix_mode_items enum is from rna_modifier.c */
+/* NOTE: rna_enum_dt_mix_mode_items enum is from `rna_modifier.c`. */
static const EnumPropertyItem *dt_mix_mode_itemf(bContext *C,
PointerRNA *ptr,
PropertyRNA *UNUSED(prop),
@@ -511,7 +513,7 @@ static int data_transfer_exec(bContext *C, wmOperator *op)
}
#if 0 /* TODO */
- /* Note: issue with that is that if canceled, operator cannot be redone... Nasty in our case. */
+ /* NOTE: issue with that is that if canceled, operator cannot be redone... Nasty in our case. */
return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
#else
return OPERATOR_FINISHED;
@@ -611,23 +613,23 @@ void OBJECT_OT_data_transfer(wmOperatorType *ot)
{
PropertyRNA *prop;
- /* Identifiers.*/
+ /* Identifiers. */
ot->name = "Transfer Mesh Data";
ot->idname = "OBJECT_OT_data_transfer";
ot->description =
"Transfer data layer(s) (weights, edge sharp, etc.) from active to selected meshes";
- /* API callbacks.*/
+ /* API callbacks. */
ot->poll = data_transfer_poll;
ot->poll_property = data_transfer_poll_property;
ot->invoke = WM_menu_invoke;
ot->exec = data_transfer_exec;
ot->check = data_transfer_check;
- /* Flags.*/
+ /* Flags. */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* Properties.*/
+ /* Properties. */
prop = RNA_def_boolean(ot->srna,
"use_reverse_transfer",
false,
@@ -767,7 +769,7 @@ void OBJECT_OT_data_transfer(wmOperatorType *ot)
}
/******************************************************************************/
-/* Note: This operator is hybrid, it can work as a usual standalone Object operator,
+/* NOTE: This operator is hybrid, it can work as a usual standalone Object operator,
* or as a DataTransfer modifier tool.
*/
@@ -886,7 +888,7 @@ void OBJECT_OT_datalayout_transfer(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* Properties.*/
+ /* Properties. */
edit_modifier_properties(ot);
/* Data type to transfer. */
diff --git a/source/blender/editors/object/object_data_transform.c b/source/blender/editors/object/object_data_transform.c
index 6e3a5e715f6..4a4ace309e1 100644
--- a/source/blender/editors/object/object_data_transform.c
+++ b/source/blender/editors/object/object_data_transform.c
@@ -745,8 +745,12 @@ void ED_object_data_xform_tag_update(struct XFormObjectData *xod_base)
case ID_ME: {
Mesh *me = (Mesh *)xod_base->id;
if (xod_base->is_edit_mode) {
- EDBM_update_generic(me, true, false);
- EDBM_mesh_normals_update(me->edit_mesh);
+ EDBM_update(me,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = true,
+ .is_destructive = false,
+ });
}
DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
break;
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 5be572baec5..6108691b2f1 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -105,7 +105,7 @@
#include "CLG_log.h"
-/* for menu/popup icons etc etc*/
+/* For menu/popup icons etc etc. */
#include "UI_interface.h"
#include "UI_resources.h"
@@ -134,8 +134,8 @@ Object *ED_object_context(const bContext *C)
return CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
}
-/* find the correct active object per context
- * note: context can be NULL when called from a enum with PROP_ENUM_NO_CONTEXT */
+/* Find the correct active object per context.
+ * NOTE: context can be NULL when called from a enum with #PROP_ENUM_NO_CONTEXT. */
Object *ED_object_active_context(const bContext *C)
{
Object *ob = NULL;
@@ -157,7 +157,7 @@ Object *ED_object_active_context(const bContext *C)
* (assuming they need to be modified).
*/
Object **ED_object_array_in_mode_or_selected(bContext *C,
- bool (*filter_fn)(Object *ob, void *user_data),
+ bool (*filter_fn)(const Object *ob, void *user_data),
void *filter_user_data,
uint *r_objects_len)
{
@@ -557,7 +557,7 @@ static bool ED_object_editmode_load_free_ex(Main *bmain,
}
if (free_data) {
- EDBM_mesh_free(me->edit_mesh);
+ EDBM_mesh_free_data(me->edit_mesh);
MEM_freeN(me->edit_mesh);
me->edit_mesh = NULL;
}
@@ -794,9 +794,7 @@ bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag
BMEditMesh *em = BKE_editmesh_from_object(ob);
if (LIKELY(em)) {
- /* order doesn't matter */
- EDBM_mesh_normals_update(em);
- BKE_editmesh_looptri_calc(em);
+ BKE_editmesh_looptri_and_normals_calc(em);
}
WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_MESH, NULL);
@@ -1154,7 +1152,7 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene, eObjectPathCalcRang
Depsgraph *depsgraph;
bool free_depsgraph = false;
/* For a single frame update it's faster to re-use existing dependency graph and avoid overhead
- * of building all the relations and so on for a temporary one. */
+ * of building all the relations and so on for a temporary one. */
if (range == OBJECT_PATH_CALC_RANGE_CURRENT_FRAME) {
/* NOTE: Dependency graph will be evaluated at all the frames, but we first need to access some
* nested pointers, like animation data. */
@@ -1992,7 +1990,7 @@ static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent
* Technically we could use #wmOperator.customdata. However there is no free callback
* called to an operator that exit with OPERATOR_INTERFACE to launch a menu.
*
- * So we are left with a memory that will necessarily leak. It's a small leak though.*/
+ * So we are left with a memory that will necessarily leak. It's a small leak though. */
if (master_collection_menu == NULL) {
master_collection_menu = MEM_callocN(sizeof(MoveToCollectionData),
"MoveToCollectionData menu - expected eventual memleak");
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index d56ee17a73f..5065a2c00f0 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -105,14 +105,13 @@ static int return_editmesh_indexar(BMEditMesh *em, int *r_tot, int **r_indexar,
static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *r_name, float r_cent[3])
{
- const int cd_dvert_offset = obedit->actdef ?
+ const int active_index = BKE_object_defgroup_active_index_get(obedit);
+ const int cd_dvert_offset = active_index ?
CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT) :
-1;
- zero_v3(r_cent);
-
if (cd_dvert_offset != -1) {
- const int defgrp_index = obedit->actdef - 1;
+ const int defgrp_index = active_index - 1;
int totvert = 0;
MDeformVert *dvert;
@@ -129,7 +128,8 @@ static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *r_name,
}
}
if (totvert) {
- bDeformGroup *dg = BLI_findlink(&obedit->defbase, defgrp_index);
+ const ListBase *defbase = BKE_object_defgroup_list(obedit);
+ bDeformGroup *dg = BLI_findlink(defbase, defgrp_index);
BLI_strncpy(r_name, dg->name, sizeof(dg->name));
mul_v3_fl(r_cent, 1.0f / (float)totvert);
return true;
@@ -350,8 +350,7 @@ static bool object_hook_index_array(Main *bmain,
em = me->edit_mesh;
- EDBM_mesh_normals_update(em);
- BKE_editmesh_looptri_calc(em);
+ BKE_editmesh_looptri_and_normals_calc(em);
/* check selected vertices first */
if (return_editmesh_indexar(em, r_tot, r_indexar, r_cent) == 0) {
@@ -773,7 +772,7 @@ void OBJECT_OT_hook_remove(wmOperatorType *ot)
/* flags */
/* this operator removes modifier which isn't stored in local undo stack,
- * so redoing it from redo panel gives totally weird results */
+ * so redoing it from redo panel gives totally weird results. */
ot->flag = /*OPTYPE_REGISTER|*/ OPTYPE_UNDO;
/* properties */
@@ -932,7 +931,7 @@ void OBJECT_OT_hook_assign(wmOperatorType *ot)
/* flags */
/* this operator changes data stored in modifier which doesn't get pushed to undo stack,
- * so redoing it from redo panel gives totally weird results */
+ * so redoing it from redo panel gives totally weird results. */
ot->flag = /*OPTYPE_REGISTER|*/ OPTYPE_UNDO;
/* properties */
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 5bf04e195fe..5a3a28b5a3f 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -247,7 +247,6 @@ void OBJECT_OT_vertex_group_assign_new(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_remove_from(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_select(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot);
-void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_copy_to_selected(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c
index dcb294bcb12..36a4f002978 100644
--- a/source/blender/editors/object/object_modes.c
+++ b/source/blender/editors/object/object_modes.c
@@ -30,6 +30,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "PIL_time.h"
+
#include "BLT_translation.h"
#include "BKE_context.h"
@@ -399,9 +401,9 @@ void ED_object_mode_generic_exit(struct Main *bmain,
ed_object_mode_generic_exit_ex(bmain, depsgraph, scene, ob, false);
}
-bool ED_object_mode_generic_has_data(struct Depsgraph *depsgraph, struct Object *ob)
+bool ED_object_mode_generic_has_data(struct Depsgraph *depsgraph, const struct Object *ob)
{
- return ed_object_mode_generic_exit_ex(NULL, depsgraph, NULL, ob, true);
+ return ed_object_mode_generic_exit_ex(NULL, depsgraph, NULL, (Object *)ob, true);
}
/** \} */
@@ -419,7 +421,7 @@ static bool object_transfer_mode_poll(bContext *C)
return false;
}
const Object *ob = CTX_data_active_object(C);
- return ob && (ob->mode & (OB_MODE_SCULPT));
+ return ob && (ob->mode != OB_MODE_OBJECT);
}
/* Update the viewport rotation origin to the mouse cursor. */
@@ -438,6 +440,13 @@ static void object_transfer_mode_reposition_view_pivot(bContext *C, const int mv
ups->last_stroke_valid = true;
}
+static void object_overlay_mode_transfer_animation_start(bContext *C, Object *ob_dst)
+{
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ Object *ob_dst_eval = DEG_get_evaluated_object(depsgraph, ob_dst);
+ ob_dst_eval->runtime.overlay_mode_transfer_start_time = PIL_check_seconds_timer();
+}
+
static bool object_transfer_mode_to_base(bContext *C, wmOperator *op, Base *base_dst)
{
Scene *scene = CTX_data_scene(C);
@@ -475,6 +484,10 @@ static bool object_transfer_mode_to_base(bContext *C, wmOperator *op, Base *base
ob_dst_orig = DEG_get_original_object(ob_dst);
ED_object_mode_set_ex(C, last_mode, true, op->reports);
+ if (RNA_boolean_get(op->ptr, "use_flash_on_transfer")) {
+ object_overlay_mode_transfer_animation_start(C, ob_dst);
+ }
+
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
WM_toolsystem_update_from_context_view3d(C);
mode_transfered = true;
@@ -567,6 +580,12 @@ void OBJECT_OT_transfer_mode(wmOperatorType *ot)
false,
"Use Eyedropper",
"Pick the object to switch to using an eyedropper");
+
+ RNA_def_boolean(ot->srna,
+ "use_flash_on_transfer",
+ true,
+ "Flash On Transfer",
+ "Flash the target object when transfering the mode");
}
/** \} */
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index e71b66b1a72..7bbca7ea9e6 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -63,6 +63,7 @@
#include "BKE_lattice.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
+#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_runtime.h"
@@ -124,7 +125,7 @@ static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object *
BKE_displist_make_mball(depsgraph, scene_eval, ob_eval);
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
- BKE_displist_make_curveTypes(depsgraph, scene_eval, ob_eval, false, false);
+ BKE_displist_make_curveTypes(depsgraph, scene_eval, ob_eval, false);
}
else if (ob->type == OB_GPENCIL) {
BKE_gpencil_modifiers_calc(depsgraph, scene_eval, ob_eval);
@@ -772,6 +773,8 @@ static bool modifier_apply_obdata(
return false;
}
+ Main *bmain = DEG_get_bmain(depsgraph);
+ BKE_object_material_from_eval_data(bmain, ob, &mesh_applied->id);
BKE_mesh_nomain_to_mesh(mesh_applied, me, ob, &CD_MASK_MESH, true);
if (md_eval->type == eModifierType_Multires) {
@@ -2144,7 +2147,7 @@ static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
- /* XXX don't remove.. */
+ /* XXX don't remove. */
CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
return OPERATOR_FINISHED;
@@ -2595,7 +2598,7 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain,
BLI_bitmap *edges_visited = BLI_BITMAP_NEW(me->totedge, "edge_visited");
- /* note: we use EditBones here, easier to set them up and use
+ /* NOTE: we use EditBones here, easier to set them up and use
* edit-armature functions to convert back to regular bones */
for (int v = 0; v < me->totvert; v++) {
if (mvert_skin[v].flag & MVERT_SKIN_ROOT) {
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index b50fc3c88fd..a438c760d3b 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -201,7 +201,6 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_group_remove_from);
WM_operatortype_append(OBJECT_OT_vertex_group_select);
WM_operatortype_append(OBJECT_OT_vertex_group_deselect);
- WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked);
WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_selected);
WM_operatortype_append(OBJECT_OT_vertex_group_copy);
WM_operatortype_append(OBJECT_OT_vertex_group_normalize);
@@ -322,7 +321,7 @@ void ED_keymap_object(wmKeyConfig *keyconf)
keymap = WM_keymap_ensure(keyconf, "Object Non-modal", 0, 0);
/* Object Mode ---------------------------------------------------------------- */
- /* Note: this keymap gets disabled in non-objectmode, */
+ /* NOTE: this keymap gets disabled in non-objectmode. */
keymap = WM_keymap_ensure(keyconf, "Object Mode", 0, 0);
keymap->poll = object_mode_poll;
}
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index b685a93f27b..c61965b3e23 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -153,8 +153,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
em = me->edit_mesh;
- EDBM_mesh_normals_update(em);
- BKE_editmesh_looptri_calc(em);
+ BKE_editmesh_looptri_and_normals_calc(em);
/* Make sure the evaluated mesh is updated.
*
@@ -594,7 +593,7 @@ void ED_object_parent_clear(Object *ob, const int type)
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
}
-/* note, poll should check for editable scene */
+/* NOTE: poll should check for editable scene. */
static int parent_clear_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -716,7 +715,7 @@ bool ED_object_parent_set(ReportList *reports,
cu->flag |= CU_PATH | CU_FOLLOW;
cu_eval->flag |= CU_PATH | CU_FOLLOW;
/* force creation of path data */
- BKE_displist_make_curveTypes(depsgraph, scene, par, false, false);
+ BKE_displist_make_curveTypes(depsgraph, scene, par, false);
}
else {
cu->flag |= CU_FOLLOW;
@@ -792,8 +791,8 @@ bool ED_object_parent_set(ReportList *reports,
* NOTE: the old (2.4x) method was to set ob->partype = PARSKEL,
* creating the virtual modifiers.
*/
- ob->partype = PAROBJECT; /* Note: DNA define, not operator property. */
- /* ob->partype = PARSKEL; */ /* Note: DNA define, not operator property. */
+ ob->partype = PAROBJECT; /* NOTE: DNA define, not operator property. */
+ /* ob->partype = PARSKEL; */ /* NOTE: DNA define, not operator property. */
/* BUT, to keep the deforms, we need a modifier,
* and then we need to set the object that it uses
@@ -838,14 +837,14 @@ bool ED_object_parent_set(ReportList *reports,
}
break;
case PAR_BONE:
- ob->partype = PARBONE; /* Note: DNA define, not operator property. */
+ ob->partype = PARBONE; /* NOTE: DNA define, not operator property. */
if (pchan->bone) {
pchan->bone->flag &= ~BONE_RELATIVE_PARENTING;
pchan_eval->bone->flag &= ~BONE_RELATIVE_PARENTING;
}
break;
case PAR_BONE_RELATIVE:
- ob->partype = PARBONE; /* Note: DNA define, not operator property. */
+ ob->partype = PARBONE; /* NOTE: DNA define, not operator property. */
if (pchan->bone) {
pchan->bone->flag |= BONE_RELATIVE_PARENTING;
pchan_eval->bone->flag |= BONE_RELATIVE_PARENTING;
@@ -861,7 +860,7 @@ bool ED_object_parent_set(ReportList *reports,
break;
case PAR_OBJECT:
case PAR_FOLLOW:
- ob->partype = PAROBJECT; /* Note: DNA define, not operator property. */
+ ob->partype = PAROBJECT; /* NOTE: DNA define, not operator property. */
break;
}
@@ -1249,7 +1248,7 @@ static int parent_noinv_set_exec(bContext *C, wmOperator *op)
/* set parenting type for object - object only... */
ob->parent = par;
- ob->partype = PAROBJECT; /* note, dna define, not operator property */
+ ob->partype = PAROBJECT; /* NOTE: DNA define, not operator property. */
}
}
}
@@ -1299,7 +1298,7 @@ static const EnumPropertyItem prop_clear_track_types[] = {
{0, NULL, 0, NULL, NULL},
};
-/* note, poll should check for editable scene */
+/* NOTE: poll should check for editable scene. */
static int object_track_clear_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -1932,7 +1931,7 @@ static void single_object_users(
}
/* not an especially efficient function, only added so the single user
- * button can be functional.*/
+ * button can be functional. */
void ED_object_single_user(Main *bmain, Scene *scene, Object *ob)
{
FOREACH_SCENE_OBJECT_BEGIN (scene, ob_iter) {
@@ -1944,7 +1943,7 @@ void ED_object_single_user(Main *bmain, Scene *scene, Object *ob)
ob->flag |= OB_DONE;
single_object_users(bmain, scene, NULL, OB_DONE, false);
- BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_newptr_and_tag_clear(bmain);
}
static void single_obdata_users(
@@ -2023,7 +2022,7 @@ static void single_obdata_users(
break;
default:
printf("ERROR %s: can't copy %s\n", __func__, id->name);
- BLI_assert(!"This should never happen.");
+ BLI_assert_msg(0, "This should never happen.");
/* We need to end the FOREACH_OBJECT_FLAG_BEGIN iterator to prevent memory leak. */
BKE_scene_objects_iterator_end(&iter_macro);
@@ -2062,6 +2061,23 @@ static void single_object_action_users(
FOREACH_OBJECT_FLAG_END;
}
+static void single_objectdata_action_users(
+ Main *bmain, Scene *scene, ViewLayer *view_layer, View3D *v3d, const int flag)
+{
+ FOREACH_OBJECT_FLAG_BEGIN (scene, view_layer, v3d, flag, ob) {
+ if (!ID_IS_LINKED(ob) && ob->data != NULL) {
+ ID *id_obdata = (ID *)ob->data;
+ AnimData *adt = BKE_animdata_from_id(id_obdata);
+ ID *id_act = (ID *)adt->action;
+ if (id_act && id_act->us > 1) {
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ BKE_animdata_copy_id_action(bmain, id_obdata);
+ }
+ }
+ }
+ FOREACH_OBJECT_FLAG_END;
+}
+
static void single_mat_users(
Main *bmain, Scene *scene, ViewLayer *view_layer, View3D *v3d, const int flag)
{
@@ -2237,7 +2253,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
const int mode = RNA_enum_get(op->ptr, "type");
int a;
- /* Note: we (ab)use LIB_TAG_PRE_EXISTING to cherry pick which ID to make local... */
+ /* NOTE: we (ab)use LIB_TAG_PRE_EXISTING to cherry pick which ID to make local... */
if (mode == MAKE_LOCAL_ALL) {
ViewLayer *view_layer = CTX_data_view_layer(C);
Collection *collection = CTX_data_collection(C);
@@ -2454,7 +2470,7 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
const bool success = BKE_lib_override_library_create(
- bmain, scene, view_layer, id_root, &obact->id);
+ bmain, scene, view_layer, id_root, &obact->id, NULL);
/* Remove the instance empty from this scene, the items now have an overridden collection
* instead. */
@@ -2570,14 +2586,14 @@ static int convert_proxy_to_override_exec(bContext *C, wmOperator *op)
/* Remove the instance empty from this scene, the items now have an overridden collection
* instead. */
- if (success && is_override_instancing_object) {
+ if (is_override_instancing_object) {
ED_object_base_free_and_unlink(bmain, scene, ob_proxy_group);
}
DEG_id_tag_update(&CTX_data_scene(C)->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_WINDOW, NULL);
- return success ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ return OPERATOR_FINISHED;
}
void OBJECT_OT_convert_proxy_to_override(wmOperatorType *ot)
@@ -2644,7 +2660,11 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
single_object_action_users(bmain, scene, view_layer, v3d, flag);
}
- BKE_main_id_clear_newpoins(bmain);
+ if (RNA_boolean_get(op->ptr, "obdata_animation")) {
+ single_objectdata_action_users(bmain, scene, view_layer, v3d, flag);
+ }
+
+ BKE_main_id_newptr_and_tag_clear(bmain);
WM_event_add_notifier(C, NC_WINDOW, NULL);
@@ -2685,8 +2705,16 @@ void OBJECT_OT_make_single_user(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "object", 0, "Object", "Make single user objects");
RNA_def_boolean(ot->srna, "obdata", 0, "Object Data", "Make single user object data");
RNA_def_boolean(ot->srna, "material", 0, "Materials", "Make materials local to each data-block");
- RNA_def_boolean(
- ot->srna, "animation", 0, "Object Animation", "Make animation data local to each object");
+ RNA_def_boolean(ot->srna,
+ "animation",
+ 0,
+ "Object Animation",
+ "Make object animation data local to each object");
+ RNA_def_boolean(ot->srna,
+ "obdata_animation",
+ 0,
+ "Object Data Animation",
+ "Make object data (mesh, curve etc.) animation data local to each object");
}
/** \} */
diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c
index 9ef2cce875f..05f9980e0ab 100644
--- a/source/blender/editors/object/object_remesh.c
+++ b/source/blender/editors/object/object_remesh.c
@@ -139,6 +139,13 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ if (mesh->totpoly == 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Output mesh will be all smooth or all flat shading. */
+ const bool smooth_normals = mesh->mpoly[0].flag & ME_SMOOTH;
+
float isovalue = 0.0f;
if (mesh->flag & ME_REMESH_REPROJECT_VOLUME) {
isovalue = mesh->remesh_voxel_size * 0.3f;
@@ -185,7 +192,7 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op)
BKE_mesh_nomain_to_mesh(new_mesh, mesh, ob, &CD_MASK_MESH, true);
- if (mesh->flag & ME_REMESH_SMOOTH_NORMALS) {
+ if (smooth_normals) {
BKE_mesh_smooth_flag_set(ob->data, true);
}
@@ -525,7 +532,7 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev
float d_a[3], d_b[3];
float d_a_proj[2], d_b_proj[2];
- float preview_plane_proj[4][3];
+ float preview_plane_proj[4][2];
const float y_axis_proj[2] = {0.0f, 1.0f};
mid_v3_v3v3(text_pos, cd->preview_plane[0], cd->preview_plane[2]);
@@ -534,7 +541,7 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev
for (int i = 0; i < 4; i++) {
float preview_plane_world_space[3];
mul_v3_m4v3(preview_plane_world_space, active_object->obmat, cd->preview_plane[i]);
- ED_view3d_project(region, preview_plane_world_space, preview_plane_proj[i]);
+ ED_view3d_project_v2(region, preview_plane_world_space, preview_plane_proj[i]);
}
/* Get the initial X and Y axis of the basis from the edges of the Bounding Box face. */
@@ -581,7 +588,7 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev
/* Write the text position into the matrix. */
copy_v3_v3(cd->text_mat[3], text_pos);
- /* Scale the text. */
+ /* Scale the text. */
float text_pos_word_space[3];
mul_v3_m4v3(text_pos_word_space, active_object->obmat, text_pos);
const float pixelsize = ED_view3d_pixel_size(rv3d, text_pos_word_space);
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index 9160190764c..eb37aebcff2 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -26,6 +26,8 @@
#include <stdlib.h>
#include <string.h>
+#include "MEM_guardedalloc.h"
+
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_collection_types.h"
@@ -293,7 +295,7 @@ bool ED_object_jump_to_object(bContext *C, Object *ob, const bool UNUSED(reveal_
return false;
}
- /* TODO, use 'reveal_hidden', as is done with bones. */
+ /* TODO: use 'reveal_hidden', as is done with bones. */
if (view_layer->basact != base || !(base->flag & BASE_SELECTED)) {
/* Select if not selected. */
@@ -579,7 +581,7 @@ static bool object_select_all_by_particle(bContext *C, Object *ob)
CTX_DATA_BEGIN (C, Base *, base, visible_bases) {
if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
- /* loop through other particles*/
+ /* Loop through other particles. */
ParticleSystem *psys;
for (psys = base->object->particlesystem.first; psys; psys = psys->next) {
@@ -1454,20 +1456,28 @@ void OBJECT_OT_select_less(wmOperatorType *ot)
static int object_select_random_exec(bContext *C, wmOperator *op)
{
+ const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
- const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
- RNG *rng = BLI_rng_new_srandom(seed);
+ ListBase ctx_data_list;
+ CTX_data_selectable_bases(C, &ctx_data_list);
+ const int tot = BLI_listbase_count(&ctx_data_list);
+ int elem_map_len = 0;
+ Base **elem_map = MEM_mallocN(sizeof(*elem_map) * tot, __func__);
- CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
- if (BLI_rng_get_float(rng) < randfac) {
- ED_object_base_select(base, select);
- }
+ CollectionPointerLink *ctx_link;
+ for (ctx_link = ctx_data_list.first; ctx_link; ctx_link = ctx_link->next) {
+ elem_map[elem_map_len++] = ctx_link->ptr.data;
}
- CTX_DATA_END;
+ BLI_freelistN(&ctx_data_list);
- BLI_rng_free(rng);
+ BLI_array_randomize(elem_map, sizeof(*elem_map), elem_map_len, seed);
+ const int count_select = elem_map_len * randfac;
+ for (int i = 0; i < count_select; i++) {
+ ED_object_base_select(elem_map[i], select);
+ }
+ MEM_freeN(elem_map);
Scene *scene = CTX_data_scene(C);
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
@@ -1486,7 +1496,7 @@ void OBJECT_OT_select_random(wmOperatorType *ot)
ot->idname = "OBJECT_OT_select_random";
/* api callbacks */
- /*ot->invoke = object_select_random_invoke XXX - need a number popup ;*/
+ /*ot->invoke = object_select_random_invoke XXX: need a number popup ;*/
ot->exec = object_select_random_exec;
ot->poll = objects_selectable_poll;
diff --git a/source/blender/editors/object/object_shader_fx.c b/source/blender/editors/object/object_shader_fx.c
index 585a1e22a84..2723d7ad1e3 100644
--- a/source/blender/editors/object/object_shader_fx.c
+++ b/source/blender/editors/object/object_shader_fx.c
@@ -64,7 +64,9 @@
#include "object_intern.h"
-/******************************** API ****************************/
+/* -------------------------------------------------------------------- */
+/** \name Public API
+ * \{ */
ShaderFxData *ED_object_shaderfx_add(
ReportList *reports, Main *bmain, Scene *UNUSED(scene), Object *ob, const char *name, int type)
@@ -261,7 +263,59 @@ void ED_object_shaderfx_copy(Object *dst, ShaderFxData *fx)
WM_main_add_notifier(NC_OBJECT | ND_SHADERFX, dst);
}
-/************************ add effect operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Generic Poll Callback Helpers
+ * \{ */
+
+static bool edit_shaderfx_poll_generic(bContext *C,
+ StructRNA *rna_type,
+ int obtype_flag,
+ const bool is_liboverride_allowed)
+{
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "shaderfx", rna_type);
+ Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : ED_object_active_context(C);
+ ShaderFxData *fx = ptr.data; /* May be NULL. */
+
+ if (!ED_operator_object_active_editable_ex(C, ob)) {
+ return false;
+ }
+
+ /* NOTE: Temporary 'forbid all' for overrides, until we implement support to add shaderfx to
+ * overrides. */
+ if (ID_IS_OVERRIDE_LIBRARY(ob)) {
+ CTX_wm_operator_poll_msg_set(C, "Cannot edit shaderfxs in a library override");
+ return false;
+ }
+
+ if (obtype_flag != 0 && ((1 << ob->type) & obtype_flag) == 0) {
+ CTX_wm_operator_poll_msg_set(C, "Object type is not supported");
+ return false;
+ }
+ if (ptr.owner_id != NULL && ID_IS_LINKED(ptr.owner_id)) {
+ CTX_wm_operator_poll_msg_set(C, "Cannot edit library data");
+ return false;
+ }
+ if (!is_liboverride_allowed && BKE_shaderfx_is_nonlocal_in_liboverride(ob, fx)) {
+ CTX_wm_operator_poll_msg_set(
+ C, "Cannot edit shaderfxs coming from linked data in a library override");
+ return false;
+ }
+
+ return true;
+}
+
+static bool edit_shaderfx_poll(bContext *C)
+{
+ return edit_shaderfx_poll_generic(C, &RNA_ShaderFx, 0, false);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Add Effect Operator
+ * \{ */
static int shaderfx_add_exec(bContext *C, wmOperator *op)
{
@@ -334,7 +388,7 @@ void OBJECT_OT_shaderfx_add(wmOperatorType *ot)
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = shaderfx_add_exec;
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = edit_shaderfx_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -352,37 +406,6 @@ void OBJECT_OT_shaderfx_add(wmOperatorType *ot)
/** \name Generic Functions for Operators Using Names and Data Context
* \{ */
-static bool edit_shaderfx_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
-{
- PointerRNA ptr = CTX_data_pointer_get_type(C, "shaderfx", rna_type);
- Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : ED_object_active_context(C);
- ShaderFxData *fx = ptr.data; /* May be NULL. */
-
- if (!ob || ID_IS_LINKED(ob)) {
- return false;
- }
- if (obtype_flag && ((1 << ob->type) & obtype_flag) == 0) {
- return false;
- }
- if (ptr.owner_id && ID_IS_LINKED(ptr.owner_id)) {
- return false;
- }
-
- if (ID_IS_OVERRIDE_LIBRARY(ob)) {
- if ((fx == NULL) || (fx->flag & eShaderFxFlag_OverrideLibrary_Local) == 0) {
- CTX_wm_operator_poll_msg_set(C, "Cannot edit shaderfxs coming from library override");
- return false;
- }
- }
-
- return true;
-}
-
-static bool edit_shaderfx_poll(bContext *C)
-{
- return edit_shaderfx_poll_generic(C, &RNA_ShaderFx, 0);
-}
-
static void edit_shaderfx_properties(wmOperatorType *ot)
{
PropertyRNA *prop = RNA_def_string(
@@ -461,7 +484,9 @@ static ShaderFxData *edit_shaderfx_property_get(wmOperator *op, Object *ob, int
/** \} */
-/************************ remove shaderfx operator *********************/
+/* -------------------------------------------------------------------- */
+/** \name Remove ShaderFX Operator
+ * \{ */
static int shaderfx_remove_exec(bContext *C, wmOperator *op)
{
@@ -511,7 +536,11 @@ void OBJECT_OT_shaderfx_remove(wmOperatorType *ot)
edit_shaderfx_report_property(ot);
}
-/************************ move up shaderfx operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Move up ShaderFX Operator
+ * \{ */
static int shaderfx_move_up_exec(bContext *C, wmOperator *op)
{
@@ -552,7 +581,11 @@ void OBJECT_OT_shaderfx_move_up(wmOperatorType *ot)
edit_shaderfx_properties(ot);
}
-/************************ move down shaderfx operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Move Down ShaderFX Operator
+ * \{ */
static int shaderfx_move_down_exec(bContext *C, wmOperator *op)
{
@@ -593,12 +626,11 @@ void OBJECT_OT_shaderfx_move_down(wmOperatorType *ot)
edit_shaderfx_properties(ot);
}
-/************************ move shaderfx to index operator *********************/
+/** \} */
-static bool shaderfx_move_to_index_poll(bContext *C)
-{
- return edit_shaderfx_poll_generic(C, &RNA_ShaderFx, 0);
-}
+/* -------------------------------------------------------------------- */
+/** \name Move ShaderFX to Index Operator
+ * \{ */
static int shaderfx_move_to_index_exec(bContext *C, wmOperator *op)
{
@@ -632,7 +664,7 @@ void OBJECT_OT_shaderfx_move_to_index(wmOperatorType *ot)
ot->invoke = shaderfx_move_to_index_invoke;
ot->exec = shaderfx_move_to_index_exec;
- ot->poll = shaderfx_move_to_index_poll;
+ ot->poll = edit_shaderfx_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
@@ -641,7 +673,11 @@ void OBJECT_OT_shaderfx_move_to_index(wmOperatorType *ot)
ot->srna, "index", 0, 0, INT_MAX, "Index", "The index to move the effect to", 0, INT_MAX);
}
-/************************ copy shader operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Copy Shader Operator
+ * \{ */
static int shaderfx_copy_exec(bContext *C, wmOperator *op)
{
@@ -675,11 +711,6 @@ static int shaderfx_copy_invoke(bContext *C, wmOperator *op, const wmEvent *even
return retval;
}
-static bool shaderfx_copy_poll(bContext *C)
-{
- return edit_shaderfx_poll_generic(C, &RNA_ShaderFx, 0);
-}
-
void OBJECT_OT_shaderfx_copy(wmOperatorType *ot)
{
ot->name = "Copy Effect";
@@ -688,9 +719,11 @@ void OBJECT_OT_shaderfx_copy(wmOperatorType *ot)
ot->invoke = shaderfx_copy_invoke;
ot->exec = shaderfx_copy_exec;
- ot->poll = shaderfx_copy_poll;
+ ot->poll = edit_shaderfx_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_shaderfx_properties(ot);
}
+
+/** \} */
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index a87b5054efa..4c4727f51ee 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -709,7 +709,7 @@ static int apply_objects_internal(bContext *C,
if (has_unparented_layers == false) {
BKE_reportf(reports,
RPT_ERROR,
- "Can't apply to a GP datablock where all layers are parented: Object "
+ "Can't apply to a GP data-block where all layers are parented: Object "
"\"%s\", %s \"%s\", aborting",
ob->id.name + 2,
BKE_idtype_idcode_to_name(ID_GD),
@@ -722,7 +722,7 @@ static int apply_objects_internal(bContext *C,
BKE_reportf(
reports,
RPT_ERROR,
- "Can't apply to GP datablock with no layers: Object \"%s\", %s \"%s\", aborting",
+ "Can't apply to GP data-block with no layers: Object \"%s\", %s \"%s\", aborting",
ob->id.name + 2,
BKE_idtype_idcode_to_name(ID_GD),
gpd->id.name + 2);
@@ -1152,51 +1152,53 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
for (int object_index = 0; object_index < num_objects; object_index++) {
Object *ob = objects[object_index];
+ if (ob->flag & OB_DONE) {
+ continue;
+ }
- if ((ob->flag & OB_DONE) == 0) {
- bool do_inverse_offset = false;
- ob->flag |= OB_DONE;
+ bool do_inverse_offset = false;
+ ob->flag |= OB_DONE;
- if (centermode == ORIGIN_TO_CURSOR) {
- copy_v3_v3(cent, cursor);
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_v3(ob->imat, cent);
- }
+ if (centermode == ORIGIN_TO_CURSOR) {
+ copy_v3_v3(cent, cursor);
+ invert_m4_m4(ob->imat, ob->obmat);
+ mul_m4_v3(ob->imat, cent);
+ }
- if (ob->data == NULL) {
- /* special support for dupligroups */
- if ((ob->transflag & OB_DUPLICOLLECTION) && ob->instance_collection &&
- (ob->instance_collection->id.tag & LIB_TAG_DOIT) == 0) {
- if (ID_IS_LINKED(ob->instance_collection)) {
- tot_lib_error++;
+ if (ob->data == NULL) {
+ /* special support for dupligroups */
+ if ((ob->transflag & OB_DUPLICOLLECTION) && ob->instance_collection &&
+ (ob->instance_collection->id.tag & LIB_TAG_DOIT) == 0) {
+ if (ID_IS_LINKED(ob->instance_collection)) {
+ tot_lib_error++;
+ }
+ else {
+ if (centermode == ORIGIN_TO_CURSOR) {
+ /* done */
}
else {
- if (centermode == ORIGIN_TO_CURSOR) {
- /* done */
- }
- else {
- float min[3], max[3];
- /* only bounds support */
- INIT_MINMAX(min, max);
- BKE_object_minmax_dupli(depsgraph, scene, ob, min, max, true);
- mid_v3_v3v3(cent, min, max);
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_v3(ob->imat, cent);
- }
+ float min[3], max[3];
+ /* only bounds support */
+ INIT_MINMAX(min, max);
+ BKE_object_minmax_dupli(depsgraph, scene, ob, min, max, true);
+ mid_v3_v3v3(cent, min, max);
+ invert_m4_m4(ob->imat, ob->obmat);
+ mul_m4_v3(ob->imat, cent);
+ }
- add_v3_v3(ob->instance_collection->instance_offset, cent);
+ add_v3_v3(ob->instance_collection->instance_offset, cent);
- tot_change++;
- ob->instance_collection->id.tag |= LIB_TAG_DOIT;
- do_inverse_offset = true;
- }
+ tot_change++;
+ ob->instance_collection->id.tag |= LIB_TAG_DOIT;
+ do_inverse_offset = true;
}
}
- else if (ID_IS_LINKED(ob->data)) {
- tot_lib_error++;
- }
-
- if (obedit == NULL && ob->type == OB_MESH) {
+ }
+ else if (ID_IS_LINKED(ob->data)) {
+ tot_lib_error++;
+ }
+ else if (ob->type == OB_MESH) {
+ if (obedit == NULL) {
Mesh *me = ob->data;
if (centermode == ORIGIN_TO_CURSOR) {
@@ -1222,265 +1224,265 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
me->id.tag |= LIB_TAG_DOIT;
do_inverse_offset = true;
}
- else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
- Curve *cu = ob->data;
+ }
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ Curve *cu = ob->data;
- if (centermode == ORIGIN_TO_CURSOR) {
- /* done */
- }
- else if (around == V3D_AROUND_CENTER_BOUNDS) {
- BKE_curve_center_bounds(cu, cent);
- }
- else { /* #V3D_AROUND_CENTER_MEDIAN. */
- BKE_curve_center_median(cu, cent);
- }
+ if (centermode == ORIGIN_TO_CURSOR) {
+ /* done */
+ }
+ else if (around == V3D_AROUND_CENTER_BOUNDS) {
+ BKE_curve_center_bounds(cu, cent);
+ }
+ else { /* #V3D_AROUND_CENTER_MEDIAN. */
+ BKE_curve_center_median(cu, cent);
+ }
- /* don't allow Z change if curve is 2D */
- if ((ob->type == OB_CURVE) && !(cu->flag & CU_3D)) {
- cent[2] = 0.0;
- }
+ /* don't allow Z change if curve is 2D */
+ if ((ob->type == OB_CURVE) && !(cu->flag & CU_3D)) {
+ cent[2] = 0.0;
+ }
- negate_v3_v3(cent_neg, cent);
- BKE_curve_translate(cu, cent_neg, 1);
+ negate_v3_v3(cent_neg, cent);
+ BKE_curve_translate(cu, cent_neg, 1);
- tot_change++;
- cu->id.tag |= LIB_TAG_DOIT;
- do_inverse_offset = true;
+ tot_change++;
+ cu->id.tag |= LIB_TAG_DOIT;
+ do_inverse_offset = true;
- if (obedit) {
- if (centermode == GEOMETRY_TO_ORIGIN) {
- DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
- }
- break;
+ if (obedit) {
+ if (centermode == GEOMETRY_TO_ORIGIN) {
+ DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
}
+ break;
}
- else if (ob->type == OB_FONT) {
- /* get from bb */
+ }
+ else if (ob->type == OB_FONT) {
+ /* Get from bounding-box. */
- Curve *cu = ob->data;
+ Curve *cu = ob->data;
- if (ob->runtime.bb == NULL && (centermode != ORIGIN_TO_CURSOR)) {
- /* do nothing*/
+ if (ob->runtime.bb == NULL && (centermode != ORIGIN_TO_CURSOR)) {
+ /* Do nothing. */
+ }
+ else {
+ if (centermode == ORIGIN_TO_CURSOR) {
+ /* Done. */
}
else {
- if (centermode == ORIGIN_TO_CURSOR) {
- /* done */
- }
- else {
- /* extra 0.5 is the height o above line */
- cent[0] = 0.5f * (ob->runtime.bb->vec[4][0] + ob->runtime.bb->vec[0][0]);
- cent[1] = 0.5f * (ob->runtime.bb->vec[0][1] + ob->runtime.bb->vec[2][1]);
- }
+ /* extra 0.5 is the height o above line */
+ cent[0] = 0.5f * (ob->runtime.bb->vec[4][0] + ob->runtime.bb->vec[0][0]);
+ cent[1] = 0.5f * (ob->runtime.bb->vec[0][1] + ob->runtime.bb->vec[2][1]);
+ }
- cent[2] = 0.0f;
+ cent[2] = 0.0f;
- cu->xof = cu->xof - cent[0];
- cu->yof = cu->yof - cent[1];
+ cu->xof = cu->xof - cent[0];
+ cu->yof = cu->yof - cent[1];
- tot_change++;
- cu->id.tag |= LIB_TAG_DOIT;
- do_inverse_offset = true;
- }
+ tot_change++;
+ cu->id.tag |= LIB_TAG_DOIT;
+ do_inverse_offset = true;
}
- else if (ob->type == OB_ARMATURE) {
- bArmature *arm = ob->data;
+ }
+ else if (ob->type == OB_ARMATURE) {
+ bArmature *arm = ob->data;
- if (ID_REAL_USERS(arm) > 1) {
+ if (ID_REAL_USERS(arm) > 1) {
#if 0
BKE_report(op->reports, RPT_ERROR, "Cannot apply to a multi user armature");
return;
#endif
- tot_multiuser_arm_error++;
- }
- else {
- /* Function to recenter armatures in editarmature.c
- * Bone + object locations are handled there.
- */
- ED_armature_origin_set(bmain, ob, cursor, centermode, around);
+ tot_multiuser_arm_error++;
+ }
+ else {
+ /* Function to recenter armatures in editarmature.c
+ * Bone + object locations are handled there.
+ */
+ ED_armature_origin_set(bmain, ob, cursor, centermode, around);
- tot_change++;
- arm->id.tag |= LIB_TAG_DOIT;
- /* do_inverse_offset = true; */ /* docenter_armature() handles this */
+ tot_change++;
+ arm->id.tag |= LIB_TAG_DOIT;
+ /* do_inverse_offset = true; */ /* docenter_armature() handles this */
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- BKE_object_transform_copy(ob_eval, ob);
- BKE_armature_copy_bone_transforms(ob_eval->data, ob->data);
- BKE_object_where_is_calc(depsgraph, scene, ob_eval);
- BKE_pose_where_is(depsgraph, scene, ob_eval); /* needed for bone parents */
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+ BKE_object_transform_copy(ob_eval, ob);
+ BKE_armature_copy_bone_transforms(ob_eval->data, ob->data);
+ BKE_object_where_is_calc(depsgraph, scene, ob_eval);
+ BKE_pose_where_is(depsgraph, scene, ob_eval); /* needed for bone parents */
- ignore_parent_tx(bmain, depsgraph, scene, ob);
+ ignore_parent_tx(bmain, depsgraph, scene, ob);
- if (obedit) {
- break;
- }
+ if (obedit) {
+ break;
}
}
- else if (ob->type == OB_MBALL) {
- MetaBall *mb = ob->data;
+ }
+ else if (ob->type == OB_MBALL) {
+ MetaBall *mb = ob->data;
- if (centermode == ORIGIN_TO_CURSOR) {
- /* done */
- }
- else if (around == V3D_AROUND_CENTER_BOUNDS) {
- BKE_mball_center_bounds(mb, cent);
- }
- else { /* #V3D_AROUND_CENTER_MEDIAN. */
- BKE_mball_center_median(mb, cent);
- }
+ if (centermode == ORIGIN_TO_CURSOR) {
+ /* done */
+ }
+ else if (around == V3D_AROUND_CENTER_BOUNDS) {
+ BKE_mball_center_bounds(mb, cent);
+ }
+ else { /* #V3D_AROUND_CENTER_MEDIAN. */
+ BKE_mball_center_median(mb, cent);
+ }
- negate_v3_v3(cent_neg, cent);
- BKE_mball_translate(mb, cent_neg);
+ negate_v3_v3(cent_neg, cent);
+ BKE_mball_translate(mb, cent_neg);
- tot_change++;
- mb->id.tag |= LIB_TAG_DOIT;
- do_inverse_offset = true;
+ tot_change++;
+ mb->id.tag |= LIB_TAG_DOIT;
+ do_inverse_offset = true;
- if (obedit) {
- if (centermode == GEOMETRY_TO_ORIGIN) {
- DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
- }
- break;
+ if (obedit) {
+ if (centermode == GEOMETRY_TO_ORIGIN) {
+ DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
}
+ break;
}
- else if (ob->type == OB_LATTICE) {
- Lattice *lt = ob->data;
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = ob->data;
- if (centermode == ORIGIN_TO_CURSOR) {
- /* done */
- }
- else if (around == V3D_AROUND_CENTER_BOUNDS) {
- BKE_lattice_center_bounds(lt, cent);
- }
- else { /* #V3D_AROUND_CENTER_MEDIAN. */
- BKE_lattice_center_median(lt, cent);
- }
+ if (centermode == ORIGIN_TO_CURSOR) {
+ /* done */
+ }
+ else if (around == V3D_AROUND_CENTER_BOUNDS) {
+ BKE_lattice_center_bounds(lt, cent);
+ }
+ else { /* #V3D_AROUND_CENTER_MEDIAN. */
+ BKE_lattice_center_median(lt, cent);
+ }
- negate_v3_v3(cent_neg, cent);
- BKE_lattice_translate(lt, cent_neg, 1);
+ negate_v3_v3(cent_neg, cent);
+ BKE_lattice_translate(lt, cent_neg, 1);
- tot_change++;
- lt->id.tag |= LIB_TAG_DOIT;
- do_inverse_offset = true;
- }
- else if (ob->type == OB_GPENCIL) {
- bGPdata *gpd = ob->data;
- float gpcenter[3];
- if (gpd) {
- if (centermode == ORIGIN_TO_GEOMETRY) {
- zero_v3(gpcenter);
- BKE_gpencil_centroid_3d(gpd, gpcenter);
- add_v3_v3(gpcenter, ob->obmat[3]);
- }
- if (centermode == ORIGIN_TO_CURSOR) {
- copy_v3_v3(gpcenter, cursor);
- }
- if (ELEM(centermode, ORIGIN_TO_GEOMETRY, ORIGIN_TO_CURSOR)) {
- bGPDspoint *pt;
- float imat[3][3], bmat[3][3];
- float offset_global[3];
- float offset_local[3];
- int i;
-
- sub_v3_v3v3(offset_global, gpcenter, ob->obmat[3]);
- copy_m3_m4(bmat, obact->obmat);
- invert_m3_m3(imat, bmat);
- mul_m3_v3(imat, offset_global);
- mul_v3_m3v3(offset_local, imat, offset_global);
-
- float diff_mat[4][4];
- float inverse_diff_mat[4][4];
-
- /* recalculate all strokes
- * (all layers are considered without evaluating lock attributes) */
- LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- /* calculate difference matrix */
- BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
- /* undo matrix */
- invert_m4_m4(inverse_diff_mat, diff_mat);
- LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
- LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- float mpt[3];
- mul_v3_m4v3(mpt, inverse_diff_mat, &pt->x);
- sub_v3_v3(mpt, offset_local);
- mul_v3_m4v3(&pt->x, diff_mat, mpt);
- }
+ tot_change++;
+ lt->id.tag |= LIB_TAG_DOIT;
+ do_inverse_offset = true;
+ }
+ else if (ob->type == OB_GPENCIL) {
+ bGPdata *gpd = ob->data;
+ float gpcenter[3];
+ if (gpd) {
+ if (centermode == ORIGIN_TO_GEOMETRY) {
+ zero_v3(gpcenter);
+ BKE_gpencil_centroid_3d(gpd, gpcenter);
+ add_v3_v3(gpcenter, ob->obmat[3]);
+ }
+ if (centermode == ORIGIN_TO_CURSOR) {
+ copy_v3_v3(gpcenter, cursor);
+ }
+ if (ELEM(centermode, ORIGIN_TO_GEOMETRY, ORIGIN_TO_CURSOR)) {
+ bGPDspoint *pt;
+ float imat[3][3], bmat[3][3];
+ float offset_global[3];
+ float offset_local[3];
+ int i;
+
+ sub_v3_v3v3(offset_global, gpcenter, ob->obmat[3]);
+ copy_m3_m4(bmat, obact->obmat);
+ invert_m3_m3(imat, bmat);
+ mul_m3_v3(imat, offset_global);
+ mul_v3_m3v3(offset_local, imat, offset_global);
+
+ float diff_mat[4][4];
+ float inverse_diff_mat[4][4];
+
+ /* recalculate all strokes
+ * (all layers are considered without evaluating lock attributes) */
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* calculate difference matrix */
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+ /* undo matrix */
+ invert_m4_m4(inverse_diff_mat, diff_mat);
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ float mpt[3];
+ mul_v3_m4v3(mpt, inverse_diff_mat, &pt->x);
+ sub_v3_v3(mpt, offset_local);
+ mul_v3_m4v3(&pt->x, diff_mat, mpt);
}
}
}
- tot_change++;
- if (centermode == ORIGIN_TO_GEOMETRY) {
- copy_v3_v3(ob->loc, gpcenter);
- }
- DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
- DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
-
- ob->id.tag |= LIB_TAG_DOIT;
- do_inverse_offset = true;
}
- else {
- BKE_report(op->reports,
- RPT_WARNING,
- "Grease Pencil Object does not support this set origin option");
+ tot_change++;
+ if (centermode == ORIGIN_TO_GEOMETRY) {
+ copy_v3_v3(ob->loc, gpcenter);
}
+ DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
+
+ ob->id.tag |= LIB_TAG_DOIT;
+ do_inverse_offset = true;
+ }
+ else {
+ BKE_report(op->reports,
+ RPT_WARNING,
+ "Grease Pencil Object does not support this set origin option");
}
}
+ }
- /* offset other selected objects */
- if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) {
- float obmat[4][4];
+ /* offset other selected objects */
+ if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) {
+ float obmat[4][4];
- /* was the object data modified
- * note: the functions above must set 'cent' */
+ /* was the object data modified
+ * NOTE: the functions above must set 'cent'. */
- /* convert the offset to parent space */
- BKE_object_to_mat4(ob, obmat);
- mul_v3_mat3_m4v3(centn, obmat, cent); /* omit translation part */
+ /* convert the offset to parent space */
+ BKE_object_to_mat4(ob, obmat);
+ mul_v3_mat3_m4v3(centn, obmat, cent); /* omit translation part */
- add_v3_v3(ob->loc, centn);
+ add_v3_v3(ob->loc, centn);
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- BKE_object_transform_copy(ob_eval, ob);
- BKE_object_where_is_calc(depsgraph, scene, ob_eval);
- if (ob->type == OB_ARMATURE) {
- /* needed for bone parents */
- BKE_armature_copy_bone_transforms(ob_eval->data, ob->data);
- BKE_pose_where_is(depsgraph, scene, ob_eval);
- }
-
- ignore_parent_tx(bmain, depsgraph, scene, ob);
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+ BKE_object_transform_copy(ob_eval, ob);
+ BKE_object_where_is_calc(depsgraph, scene, ob_eval);
+ if (ob->type == OB_ARMATURE) {
+ /* needed for bone parents */
+ BKE_armature_copy_bone_transforms(ob_eval->data, ob->data);
+ BKE_pose_where_is(depsgraph, scene, ob_eval);
+ }
- /* other users? */
- // CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects)
- //{
-
- /* use existing context looper */
- for (int other_object_index = 0; other_object_index < num_objects; other_object_index++) {
- Object *ob_other = objects[other_object_index];
-
- if ((ob_other->flag & OB_DONE) == 0 &&
- ((ob->data && (ob->data == ob_other->data)) ||
- (ob->instance_collection == ob_other->instance_collection &&
- (ob->transflag | ob_other->transflag) & OB_DUPLICOLLECTION))) {
- ob_other->flag |= OB_DONE;
- DEG_id_tag_update(&ob_other->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
-
- mul_v3_mat3_m4v3(centn, ob_other->obmat, cent); /* omit translation part */
- add_v3_v3(ob_other->loc, centn);
-
- Object *ob_other_eval = DEG_get_evaluated_object(depsgraph, ob_other);
- BKE_object_transform_copy(ob_other_eval, ob_other);
- BKE_object_where_is_calc(depsgraph, scene, ob_other_eval);
- if (ob_other->type == OB_ARMATURE) {
- /* needed for bone parents */
- BKE_armature_copy_bone_transforms(ob_eval->data, ob->data);
- BKE_pose_where_is(depsgraph, scene, ob_other_eval);
- }
- ignore_parent_tx(bmain, depsgraph, scene, ob_other);
+ ignore_parent_tx(bmain, depsgraph, scene, ob);
+
+ /* other users? */
+ // CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects)
+ //{
+
+ /* use existing context looper */
+ for (int other_object_index = 0; other_object_index < num_objects; other_object_index++) {
+ Object *ob_other = objects[other_object_index];
+
+ if ((ob_other->flag & OB_DONE) == 0 &&
+ ((ob->data && (ob->data == ob_other->data)) ||
+ (ob->instance_collection == ob_other->instance_collection &&
+ (ob->transflag | ob_other->transflag) & OB_DUPLICOLLECTION))) {
+ ob_other->flag |= OB_DONE;
+ DEG_id_tag_update(&ob_other->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+
+ mul_v3_mat3_m4v3(centn, ob_other->obmat, cent); /* omit translation part */
+ add_v3_v3(ob_other->loc, centn);
+
+ Object *ob_other_eval = DEG_get_evaluated_object(depsgraph, ob_other);
+ BKE_object_transform_copy(ob_other_eval, ob_other);
+ BKE_object_where_is_calc(depsgraph, scene, ob_other_eval);
+ if (ob_other->type == OB_ARMATURE) {
+ /* needed for bone parents */
+ BKE_armature_copy_bone_transforms(ob_eval->data, ob->data);
+ BKE_pose_where_is(depsgraph, scene, ob_other_eval);
}
+ ignore_parent_tx(bmain, depsgraph, scene, ob_other);
}
- // CTX_DATA_END;
}
+ // CTX_DATA_END;
}
}
MEM_freeN(objects);
@@ -1490,7 +1492,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
BKE_object_batch_cache_dirty_tag(tob);
DEG_id_tag_update(&tob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
}
- /* special support for dupligroups */
+ /* Special support for dupli-groups. */
else if (tob->instance_collection && tob->instance_collection->id.tag & LIB_TAG_DOIT) {
DEG_id_tag_update(&tob->id, ID_RECALC_TRANSFORM);
DEG_id_tag_update(&tob->instance_collection->id, ID_RECALC_COPY_ON_WRITE);
@@ -1615,6 +1617,7 @@ struct XFormAxisItem {
struct XFormAxisData {
ViewContext vc;
+ ViewDepths *depths;
struct {
float depth;
float normal[3];
@@ -1654,7 +1657,7 @@ static void object_transform_axis_target_calc_depth_init(struct XFormAxisData *x
if (center_tot) {
mul_v3_fl(center, 1.0f / center_tot);
float center_proj[3];
- ED_view3d_project(xfd->vc.region, center, center_proj);
+ ED_view3d_project_v3(xfd->vc.region, center, center_proj);
xfd->prev.depth = center_proj[2];
xfd->prev.is_depth_valid = true;
}
@@ -1684,8 +1687,8 @@ static void object_transform_axis_target_free_data(wmOperator *op)
struct XFormAxisItem *item = xfd->object_data;
#ifdef USE_RENDER_OVERRIDE
- if (xfd->vc.rv3d->depths) {
- xfd->vc.rv3d->depths->damaged = true;
+ if (xfd->depths) {
+ ED_view3d_depths_free(xfd->depths);
}
#endif
@@ -1782,13 +1785,14 @@ static int object_transform_axis_target_invoke(bContext *C, wmOperator *op, cons
vc.v3d->flag2 |= V3D_HIDE_OVERLAYS;
#endif
- ED_view3d_depth_override(vc.depsgraph, vc.region, vc.v3d, NULL, V3D_DEPTH_NO_GPENCIL, true);
+ ViewDepths *depths = NULL;
+ ED_view3d_depth_override(vc.depsgraph, vc.region, vc.v3d, NULL, V3D_DEPTH_NO_GPENCIL, &depths);
#ifdef USE_RENDER_OVERRIDE
vc.v3d->flag2 = flag2_prev;
#endif
- if (vc.rv3d->depths == NULL) {
+ if (depths == NULL) {
BKE_report(op->reports, RPT_WARNING, "Unable to access depth buffer, using view plane");
return OPERATOR_CANCELLED;
}
@@ -1800,6 +1804,7 @@ static int object_transform_axis_target_invoke(bContext *C, wmOperator *op, cons
/* Don't change this at runtime. */
xfd->vc = vc;
+ xfd->depths = depths;
xfd->vc.mval[0] = event->mval[0];
xfd->vc.mval[1] = event->mval[1];
@@ -1863,7 +1868,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const
const bool is_translate_init = is_translate && (xfd->is_translate != is_translate);
if (event->type == MOUSEMOVE || is_translate_init) {
- const ViewDepths *depths = xfd->vc.rv3d->depths;
+ const ViewDepths *depths = xfd->depths;
if (depths && ((uint)event->mval[0] < depths->w) && ((uint)event->mval[1] < depths->h)) {
float depth_fl = 1.0f;
ED_view3d_depth_read_cached(depths, event->mval, 0, &depth_fl);
@@ -1890,12 +1895,12 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const
if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
xfd->prev.depth = depth_fl;
xfd->prev.is_depth_valid = true;
- if (ED_view3d_depth_unproject(region, event->mval, depth, location_world)) {
+ if (ED_view3d_depth_unproject_v3(region, event->mval, depth, location_world)) {
if (is_translate) {
float normal[3];
bool normal_found = false;
- if (ED_view3d_depth_read_cached_normal(&xfd->vc, event->mval, normal)) {
+ if (ED_view3d_depth_read_cached_normal(region, depths, event->mval, normal)) {
normal_found = true;
/* cheap attempt to smooth normals out a bit! */
@@ -1905,7 +1910,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const
if (x != 0 && y != 0) {
const int mval_ofs[2] = {event->mval[0] + x, event->mval[1] + y};
float n[3];
- if (ED_view3d_depth_read_cached_normal(&xfd->vc, mval_ofs, n)) {
+ if (ED_view3d_depth_read_cached_normal(region, depths, mval_ofs, n)) {
add_v3_v3(normal, n);
}
}
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 5f81f9afe4f..4ea599fd30e 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -83,7 +83,7 @@ static bool vertex_group_supported_poll_ex(bContext *C, const Object *ob);
/** \name Local Utility Functions
* \{ */
-static bool object_array_for_wpaint_filter(Object *ob, void *user_data)
+static bool object_array_for_wpaint_filter(const Object *ob, void *user_data)
{
bContext *C = user_data;
if (vertex_group_supported_poll_ex(C, ob)) {
@@ -130,7 +130,7 @@ bool ED_vgroup_sync_from_pose(Object *ob)
if (arm->act_bone) {
int def_num = BKE_object_defgroup_name_index(ob, arm->act_bone->name);
if (def_num != -1) {
- ob->actdef = def_num + 1;
+ BKE_object_defgroup_active_index_set(ob, def_num + 1);
return true;
}
}
@@ -389,11 +389,16 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
int dvert_tot_from;
int dvert_tot;
int i;
- int defbase_tot_from = BLI_listbase_count(&ob_from->defbase);
- int defbase_tot = BLI_listbase_count(&ob->defbase);
+ ListBase *defbase_dst = BKE_object_defgroup_list_mutable(ob);
+ const ListBase *defbase_src = BKE_object_defgroup_list(ob_from);
+
+ int defbase_tot_from = BLI_listbase_count(defbase_src);
+ int defbase_tot = BLI_listbase_count(defbase_dst);
bool new_vgroup = false;
- if (ob == ob_from) {
+ BLI_assert(ob != ob_from);
+
+ if (ob->data == ob_from->data) {
return true;
}
@@ -429,9 +434,9 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
}
/* do the copy */
- BLI_freelistN(&ob->defbase);
- BLI_duplicatelist(&ob->defbase, &ob_from->defbase);
- ob->actdef = ob_from->actdef;
+ BLI_freelistN(defbase_dst);
+ BLI_duplicatelist(defbase_dst, defbase_src);
+ BKE_object_defgroup_active_index_set(ob, BKE_object_defgroup_active_index_get(ob_from));
if (defbase_tot_from < defbase_tot) {
/* correct vgroup indices because the number of vgroups is being reduced. */
@@ -509,21 +514,21 @@ void ED_vgroup_parray_from_weight_array(MDeformVert **dvert_array,
}
}
-/* TODO, cache flip data to speedup calls within a loop. */
+/* TODO: cache flip data to speedup calls within a loop. */
static void mesh_defvert_mirror_update_internal(Object *ob,
MDeformVert *dvert_dst,
MDeformVert *dvert_src,
const int def_nr)
{
if (def_nr == -1) {
- /* all vgroups, add groups where needed */
+ /* All vgroups, add groups where needed. */
int flip_map_len;
int *flip_map = BKE_object_defgroup_flip_map(ob, &flip_map_len, true);
BKE_defvert_sync_mapped(dvert_dst, dvert_src, flip_map, flip_map_len, true);
MEM_freeN(flip_map);
}
else {
- /* single vgroup */
+ /* Single vgroup. */
MDeformWeight *dw = BKE_defvert_ensure_index(dvert_dst,
BKE_object_defgroup_flip_index(ob, def_nr, 1));
if (dw) {
@@ -882,7 +887,8 @@ void ED_vgroup_vert_add(Object *ob, bDeformGroup *dg, int vertnum, float weight,
/* add the vert to the deform group with the
* specified assign mode
*/
- const int def_nr = BLI_findindex(&ob->defbase, dg);
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ const int def_nr = BLI_findindex(defbase, dg);
MDeformVert *dv = NULL;
int tot;
@@ -913,7 +919,8 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum)
/* TODO(campbell): This is slow in a loop, better pass def_nr directly,
* but leave for later. */
- const int def_nr = BLI_findindex(&ob->defbase, dg);
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ const int def_nr = BLI_findindex(defbase, dg);
if (def_nr != -1) {
MDeformVert *dvert = NULL;
@@ -989,7 +996,8 @@ static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum)
float ED_vgroup_vert_weight(Object *ob, bDeformGroup *dg, int vertnum)
{
- const int def_nr = BLI_findindex(&ob->defbase, dg);
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ const int def_nr = BLI_findindex(defbase, dg);
if (def_nr == -1) {
return -1;
@@ -1000,9 +1008,9 @@ float ED_vgroup_vert_weight(Object *ob, bDeformGroup *dg, int vertnum)
void ED_vgroup_select_by_name(Object *ob, const char *name)
{
- /* note: ob->actdef==0 signals on painting to create a new one,
+ /* NOTE: actdef==0 signals on painting to create a new one,
* if a bone in posemode is selected */
- ob->actdef = BKE_object_defgroup_name_index(ob, name) + 1;
+ BKE_object_defgroup_active_index_set(ob, BKE_object_defgroup_name_index(ob, name) + 1);
}
/** \} */
@@ -1014,9 +1022,10 @@ void ED_vgroup_select_by_name(Object *ob, const char *name)
/* only in editmode */
static void vgroup_select_verts(Object *ob, int select)
{
- const int def_nr = ob->actdef - 1;
+ const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
- if (!BLI_findlink(&ob->defbase, def_nr)) {
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ if (!BLI_findlink(defbase, def_nr)) {
return;
}
@@ -1111,7 +1120,9 @@ static void vgroup_duplicate(Object *ob)
MDeformVert **dvert_array = NULL;
int i, idg, icdg, dvert_tot = 0;
- dg = BLI_findlink(&ob->defbase, (ob->actdef - 1));
+ ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
+
+ dg = BLI_findlink(defbase, BKE_object_defgroup_active_index_get(ob) - 1);
if (!dg) {
return;
}
@@ -1127,13 +1138,13 @@ static void vgroup_duplicate(Object *ob)
BLI_strncpy(cdg->name, name, sizeof(cdg->name));
BKE_object_defgroup_unique_name(cdg, ob);
- BLI_addtail(&ob->defbase, cdg);
+ BLI_addtail(defbase, cdg);
- idg = (ob->actdef - 1);
- ob->actdef = BLI_listbase_count(&ob->defbase);
- icdg = (ob->actdef - 1);
+ idg = BKE_object_defgroup_active_index_get(ob) - 1;
+ BKE_object_defgroup_active_index_set(ob, BLI_listbase_count(defbase));
+ icdg = BKE_object_defgroup_active_index_get(ob) - 1;
- /* TODO, we might want to allow only copy selected verts here? - campbell */
+ /* TODO(campbell): we might want to allow only copy selected verts here? */
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false);
if (dvert_array) {
@@ -1157,11 +1168,12 @@ static bool vgroup_normalize(Object *ob)
MDeformWeight *dw;
MDeformVert *dv, **dvert_array = NULL;
int dvert_tot = 0;
- const int def_nr = ob->actdef - 1;
+ const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
const bool use_vert_sel = vertex_group_use_vert_sel(ob);
- if (!BLI_findlink(&ob->defbase, def_nr)) {
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ if (!BLI_findlink(defbase, def_nr)) {
return false;
}
@@ -1639,7 +1651,7 @@ static bool vgroup_normalize_all(Object *ob,
{
MDeformVert *dv, **dvert_array = NULL;
int i, dvert_tot = 0;
- const int def_nr = ob->actdef - 1;
+ const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
const bool use_vert_sel = vertex_group_use_vert_sel(ob);
@@ -1651,7 +1663,8 @@ static bool vgroup_normalize_all(Object *ob,
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
if (dvert_array) {
- const int defbase_tot = BLI_listbase_count(&ob->defbase);
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ const int defbase_tot = BLI_listbase_count(defbase);
bool *lock_flags = BKE_object_defgroup_lock_flags_get(ob, defbase_tot);
bool changed = false;
@@ -1742,7 +1755,7 @@ static const EnumPropertyItem vgroup_lock_mask[] = {
static bool *vgroup_selected_get(Object *ob)
{
- int sel_count = 0, defbase_tot = BLI_listbase_count(&ob->defbase);
+ int sel_count = 0, defbase_tot = BKE_object_defgroup_count(ob);
bool *mask;
if (ob->mode & OB_MODE_WEIGHT_PAINT) {
@@ -1759,8 +1772,9 @@ static bool *vgroup_selected_get(Object *ob)
mask = MEM_callocN(defbase_tot * sizeof(bool), __func__);
}
- if (sel_count == 0 && ob->actdef >= 1 && ob->actdef <= defbase_tot) {
- mask[ob->actdef - 1] = true;
+ const int actdef = BKE_object_defgroup_active_index_get(ob);
+ if (sel_count == 0 && actdef >= 1 && actdef <= defbase_tot) {
+ mask[actdef - 1] = true;
}
return mask;
@@ -1775,11 +1789,12 @@ static void vgroup_lock_all(Object *ob, int action, int mask)
if (mask != VGROUP_MASK_ALL) {
selected = vgroup_selected_get(ob);
}
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
if (action == VGROUP_TOGGLE) {
action = VGROUP_LOCK;
- for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
+ for (dg = defbase->first, i = 0; dg; dg = dg->next, i++) {
switch (mask) {
case VGROUP_MASK_INVERT_UNSELECTED:
case VGROUP_MASK_SELECTED:
@@ -1802,7 +1817,7 @@ static void vgroup_lock_all(Object *ob, int action, int mask)
}
}
- for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
+ for (dg = defbase->first, i = 0; dg; dg = dg->next, i++) {
switch (mask) {
case VGROUP_MASK_SELECTED:
if (!selected[i]) {
@@ -2352,8 +2367,8 @@ static void dvert_mirror_op(MDeformVert *dvert,
}
}
-/* TODO, vgroup locking */
-/* TODO, face masking */
+/* TODO: vgroup locking. */
+/* TODO: face masking. */
void ED_vgroup_mirror(Object *ob,
const bool mirror_weights,
const bool flip_vgroups,
@@ -2379,13 +2394,15 @@ void ED_vgroup_mirror(Object *ob,
MDeformVert *dvert, *dvert_mirr;
char sel, sel_mirr;
int *flip_map = NULL, flip_map_len;
- const int def_nr = ob->actdef - 1;
+ const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
int totmirr = 0, totfail = 0;
*r_totmirr = *r_totfail = 0;
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+
if ((mirror_weights == false && flip_vgroups == false) ||
- (BLI_findlink(&ob->defbase, def_nr) == NULL)) {
+ (BLI_findlink(defbase, def_nr) == NULL)) {
return;
}
@@ -2569,7 +2586,8 @@ cleanup:
static void vgroup_delete_active(Object *ob)
{
- bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1);
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ bDeformGroup *dg = BLI_findlink(defbase, BKE_object_defgroup_active_index_get(ob) - 1);
if (!dg) {
return;
}
@@ -2580,9 +2598,10 @@ static void vgroup_delete_active(Object *ob)
/* only in editmode */
static void vgroup_assign_verts(Object *ob, const float weight)
{
- const int def_nr = ob->actdef - 1;
+ const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
- if (!BLI_findlink(&ob->defbase, def_nr)) {
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ if (!BLI_findlink(defbase, def_nr)) {
return;
}
@@ -2700,7 +2719,8 @@ static bool vertex_group_poll_ex(bContext *C, Object *ob)
return false;
}
- if (BLI_listbase_is_empty(&ob->defbase)) {
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ if (BLI_listbase_is_empty(defbase)) {
CTX_wm_operator_poll_msg_set(C, "Object has no vertex groups");
return false;
}
@@ -2823,8 +2843,10 @@ static bool vertex_group_vert_select_unlocked_poll(bContext *C)
return false;
}
- if (ob->actdef != 0) {
- bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1);
+ const int def_nr = BKE_object_defgroup_active_index_get(ob);
+ if (def_nr != 0) {
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ const bDeformGroup *dg = BLI_findlink(defbase, def_nr - 1);
if (dg) {
return !(dg->flag & DG_LOCK_WEIGHT);
}
@@ -3025,8 +3047,8 @@ static int vertex_group_remove_from_exec(bContext *C, wmOperator *op)
}
}
else {
- bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1);
-
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ bDeformGroup *dg = BLI_findlink(defbase, BKE_object_defgroup_active_index_get(ob) - 1);
if ((dg == NULL) || (BKE_object_defgroup_clear(ob, dg, !use_all_verts) == false)) {
return OPERATOR_CANCELLED;
}
@@ -3774,7 +3796,7 @@ static int vertex_group_limit_total_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- /* note, would normally return canceled, except we want the redo
+ /* NOTE: would normally return canceled, except we want the redo
* UI to show up for users to change */
return OPERATOR_FINISHED;
}
@@ -3860,55 +3882,6 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Vertex Group Copy to Linked Operator
- * \{ */
-
-static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *UNUSED(op))
-{
- Scene *scene = CTX_data_scene(C);
- Object *ob_active = ED_object_context(C);
- int retval = OPERATOR_CANCELLED;
-
- FOREACH_SCENE_OBJECT_BEGIN (scene, ob_iter) {
- if (ob_iter->type == ob_active->type) {
- if (ob_iter != ob_active && ob_iter->data == ob_active->data) {
- BLI_freelistN(&ob_iter->defbase);
- BLI_duplicatelist(&ob_iter->defbase, &ob_active->defbase);
- ob_iter->actdef = ob_active->actdef;
-
- DEG_id_tag_update(&ob_iter->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_iter);
- WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob_iter->data);
-
- retval = OPERATOR_FINISHED;
- }
- }
- }
- FOREACH_SCENE_OBJECT_END;
-
- return retval;
-}
-
-void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Copy Vertex Groups to Linked";
- ot->idname = "OBJECT_OT_vertex_group_copy_to_linked";
- ot->description =
- "Replace vertex groups of all users of the same geometry data by vertex groups of active "
- "object";
-
- /* api callbacks */
- ot->poll = vertex_group_poll;
- ot->exec = vertex_group_copy_to_linked_exec;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Vertex Group Copy to Selected Operator
* \{ */
@@ -3972,7 +3945,7 @@ static int set_active_group_exec(bContext *C, wmOperator *op)
int nr = RNA_enum_get(op->ptr, "group");
BLI_assert(nr + 1 >= 0);
- ob->actdef = nr + 1;
+ BKE_object_defgroup_active_index_set(ob, nr + 1);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob);
@@ -3985,6 +3958,10 @@ static const EnumPropertyItem *vgroup_itemf(bContext *C,
PropertyRNA *UNUSED(prop),
bool *r_free)
{
+ if (C == NULL) {
+ return DummyRNA_NULL_items;
+ }
+
Object *ob = ED_object_context(C);
EnumPropertyItem tmp = {0, "", 0, "", ""};
EnumPropertyItem *item = NULL;
@@ -3995,7 +3972,8 @@ static const EnumPropertyItem *vgroup_itemf(bContext *C,
return DummyRNA_NULL_items;
}
- for (a = 0, def = ob->defbase.first; def; def = def->next, a++) {
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ for (a = 0, def = defbase->first; def; def = def->next, a++) {
tmp.value = a;
tmp.icon = ICON_GROUP_VERTEX;
tmp.identifier = def->name;
@@ -4044,13 +4022,13 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot)
* with the order of vgroups then call vgroup_do_remap after */
static char *vgroup_init_remap(Object *ob)
{
- bDeformGroup *def;
- int defbase_tot = BLI_listbase_count(&ob->defbase);
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ int defbase_tot = BLI_listbase_count(defbase);
char *name_array = MEM_mallocN(MAX_VGROUP_NAME * sizeof(char) * defbase_tot, "sort vgroups");
char *name;
name = name_array;
- for (def = ob->defbase.first; def; def = def->next) {
+ for (const bDeformGroup *def = defbase->first; def; def = def->next) {
BLI_strncpy(name, def->name, MAX_VGROUP_NAME);
name += MAX_VGROUP_NAME;
}
@@ -4061,10 +4039,11 @@ static char *vgroup_init_remap(Object *ob)
static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
{
MDeformVert *dvert = NULL;
- bDeformGroup *def;
- int defbase_tot = BLI_listbase_count(&ob->defbase);
+ const bDeformGroup *def;
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ int defbase_tot = BLI_listbase_count(defbase);
- /* needs a dummy index at the start*/
+ /* Needs a dummy index at the start. */
int *sort_map_update = MEM_mallocN(sizeof(int) * (defbase_tot + 1), "sort vgroups");
int *sort_map = sort_map_update + 1;
@@ -4072,8 +4051,8 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
int i;
name = name_array;
- for (def = ob->defbase.first, i = 0; def; def = def->next, i++) {
- sort_map[i] = BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name));
+ for (def = defbase->first, i = 0; def; def = def->next, i++) {
+ sort_map[i] = BLI_findstringindex(defbase, name, offsetof(bDeformGroup, name));
name += MAX_VGROUP_NAME;
BLI_assert(sort_map[i] != -1);
@@ -4107,7 +4086,7 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
BKE_object_defgroup_array_get(ob->data, &dvert, &dvert_tot);
- /*create as necessary*/
+ /* Create as necessary. */
if (dvert) {
while (dvert_tot--) {
if (dvert->totweight) {
@@ -4126,8 +4105,9 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
sort_map_update[0] = 0;
BKE_object_defgroup_remap_update_users(ob, sort_map_update);
- BLI_assert(sort_map_update[ob->actdef] >= 0);
- ob->actdef = sort_map_update[ob->actdef];
+ BLI_assert(sort_map_update[BKE_object_defgroup_active_index_get(ob)] >= 0);
+ BKE_object_defgroup_active_index_set(ob,
+ sort_map_update[BKE_object_defgroup_active_index_get(ob)]);
MEM_freeN(sort_map_update);
@@ -4155,6 +4135,7 @@ static void vgroup_sort_bone_hierarchy(Object *ob, ListBase *bonebase)
bonebase = &armature->bonebase;
}
}
+ ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
if (bonebase != NULL) {
Bone *bone;
@@ -4163,8 +4144,8 @@ static void vgroup_sort_bone_hierarchy(Object *ob, ListBase *bonebase)
vgroup_sort_bone_hierarchy(ob, &bone->childbase);
if (dg != NULL) {
- BLI_remlink(&ob->defbase, dg);
- BLI_addhead(&ob->defbase, dg);
+ BLI_remlink(defbase, dg);
+ BLI_addhead(defbase, dg);
}
}
}
@@ -4182,20 +4163,22 @@ static int vertex_group_sort_exec(bContext *C, wmOperator *op)
int ret;
int sort_type = RNA_enum_get(op->ptr, "sort_type");
- /*init remapping*/
+ /* Init remapping. */
name_array = vgroup_init_remap(ob);
- /*sort vgroup names*/
+ ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
+
+ /* Sort vgroup names. */
switch (sort_type) {
case SORT_TYPE_NAME:
- BLI_listbase_sort(&ob->defbase, vgroup_sort_name);
+ BLI_listbase_sort(defbase, vgroup_sort_name);
break;
case SORT_TYPE_BONEHIERARCHY:
vgroup_sort_bone_hierarchy(ob, NULL);
break;
}
- /*remap vgroup data to map to correct names*/
+ /* Remap vgroup data to map to correct names. */
ret = vgroup_do_remap(ob, name_array, op);
if (ret != OPERATOR_CANCELLED) {
@@ -4246,14 +4229,16 @@ static int vgroup_move_exec(bContext *C, wmOperator *op)
int dir = RNA_enum_get(op->ptr, "direction");
int ret = OPERATOR_FINISHED;
- def = BLI_findlink(&ob->defbase, ob->actdef - 1);
+ ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
+
+ def = BLI_findlink(defbase, BKE_object_defgroup_active_index_get(ob) - 1);
if (!def) {
return OPERATOR_CANCELLED;
}
name_array = vgroup_init_remap(ob);
- if (BLI_listbase_link_move(&ob->defbase, def, dir)) {
+ if (BLI_listbase_link_move(defbase, def, dir)) {
ret = vgroup_do_remap(ob, name_array, op);
if (ret != OPERATOR_CANCELLED) {
@@ -4372,7 +4357,8 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr)
static bool check_vertex_group_accessible(wmOperator *op, Object *ob, int def_nr)
{
- bDeformGroup *dg = BLI_findlink(&ob->defbase, def_nr);
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ bDeformGroup *dg = BLI_findlink(defbase, def_nr);
if (!dg) {
BKE_report(op->reports, RPT_ERROR, "Invalid vertex group index");
@@ -4494,7 +4480,7 @@ static int vertex_weight_set_active_exec(bContext *C, wmOperator *op)
const int wg_index = RNA_int_get(op->ptr, "weight_group");
if (wg_index != -1) {
- ob->actdef = wg_index + 1;
+ BKE_object_defgroup_active_index_set(ob, wg_index + 1);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index a761701f60b..56f32ff603c 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -454,7 +454,7 @@ static void dpaint_bake_startjob(void *customdata, short *stop, short *do_update
job->start = PIL_check_seconds_timer();
job->success = 1;
- G.is_break = false; /* reset BKE_blender_test_break*/
+ G.is_break = false;
/* XXX annoying hack: needed to prevent data corruption when changing
* scene frame in separate threads
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 5b545784e5b..f2bbd6d5084 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -300,7 +300,7 @@ static void pe_update_hair_particle_edit_pointers(PTCacheEdit *edit)
/* always gets at least the first particlesystem even if PSYS_CURRENT flag is not set
*
- * note: this function runs on poll, therefore it can runs many times a second
+ * NOTE: this function runs on poll, therefore it can runs many times a second
* keep it fast! */
static PTCacheEdit *pe_get_current(Depsgraph *depsgraph, Scene *scene, Object *ob, bool create)
{
@@ -466,6 +466,7 @@ static int pe_x_mirror(Object *ob)
typedef struct PEData {
ViewContext vc;
+ ViewDepths *depths;
const bContext *context;
Main *bmain;
@@ -524,21 +525,19 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
ED_view3d_viewcontext_init(C, &data->vc, data->depsgraph);
if (!XRAY_ENABLED(data->vc.v3d)) {
- if (!(data->vc.v3d->runtime.flag & V3D_RUNTIME_DEPTHBUF_OVERRIDDEN)) {
- ED_view3d_depth_override(data->depsgraph,
- data->vc.region,
- data->vc.v3d,
- data->vc.obact,
- V3D_DEPTH_OBJECT_ONLY,
- true);
- }
+ ED_view3d_depth_override(data->depsgraph,
+ data->vc.region,
+ data->vc.v3d,
+ data->vc.obact,
+ V3D_DEPTH_OBJECT_ONLY,
+ &data->depths);
}
}
static bool PE_create_shape_tree(PEData *data, Object *shapeob)
{
Object *shapeob_eval = DEG_get_evaluated_object(data->depsgraph, shapeob);
- Mesh *mesh = BKE_object_get_evaluated_mesh(shapeob_eval);
+ const Mesh *mesh = BKE_object_get_evaluated_mesh(shapeob_eval);
memset(&data->shape_bvh, 0, sizeof(data->shape_bvh));
@@ -570,6 +569,16 @@ static void PE_free_random_generator(PEData *data)
}
}
+static void PE_data_free(PEData *data)
+{
+ PE_free_random_generator(data);
+ PE_free_shape_tree(data);
+ if (data->depths) {
+ ED_view3d_depths_free(data->depths);
+ data->depths = NULL;
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -579,7 +588,7 @@ static void PE_free_random_generator(PEData *data)
static bool key_test_depth(const PEData *data, const float co[3], const int screen_co[2])
{
View3D *v3d = data->vc.v3d;
- ViewDepths *vd = data->vc.rv3d->depths;
+ ViewDepths *vd = data->depths;
float depth;
/* nothing to do */
@@ -609,7 +618,7 @@ static bool key_test_depth(const PEData *data, const float co[3], const int scre
}
float win[3];
- ED_view3d_project(data->vc.region, co, win);
+ ED_view3d_project_v3(data->vc.region, co, win);
if (win[2] - 0.00001f > depth) {
return 0;
@@ -622,7 +631,7 @@ static bool key_inside_circle(const PEData *data, float rad, const float co[3],
float dx, dy, dist;
int screen_co[2];
- /* TODO, should this check V3D_PROJ_TEST_CLIP_BB too? */
+ /* TODO: should this check V3D_PROJ_TEST_CLIP_BB too? */
if (ED_view3d_project_int_global(data->vc.region, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) !=
V3D_PROJ_RET_OK) {
return 0;
@@ -1447,7 +1456,7 @@ void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *UNUSED(ob), Part
BLI_kdtree_3d_free(edit->emitter_field);
totface = mesh->totface;
- /*totvert=dm->getNumVerts(dm);*/ /*UNUSED*/
+ // totvert = dm->getNumVerts(dm); /* UNUSED */
edit->emitter_cosnos = MEM_callocN(sizeof(float[6]) * totface, "emitter cosnos");
@@ -1555,7 +1564,7 @@ void update_world_cos(Object *ob, PTCacheEdit *edit)
}
static void update_velocities(PTCacheEdit *edit)
{
- /*TODO: get frs_sec properly */
+ /* TODO: get frs_sec properly. */
float vec1[3], vec2[3], frs_sec, dfra;
POINT_P;
KEY_K;
@@ -1871,15 +1880,13 @@ void PARTICLE_OT_select_all(wmOperatorType *ot)
bool PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
{
- PEData data;
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
POINT_P;
KEY_K;
- PE_set_view3d_data(C, &data);
-
- PTCacheEdit *edit = PE_get_current(data.depsgraph, scene, ob);
+ PTCacheEdit *edit = PE_get_current(depsgraph, scene, ob);
if (!PE_start_edit(edit)) {
return false;
@@ -1894,6 +1901,8 @@ bool PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool desele
}
}
+ PEData data;
+ PE_set_view3d_data(C, &data);
data.mval = mval;
data.rad = ED_view3d_select_dist_px();
@@ -1913,6 +1922,8 @@ bool PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool desele
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, data.ob);
}
+ PE_data_free(&data);
+
return true;
}
@@ -2204,6 +2215,7 @@ static int select_linked_pick_exec(bContext *C, wmOperator *op)
for_mouse_hit_keys(&data, select_keys, PSEL_NEAREST);
PE_update_selection(data.depsgraph, data.scene, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, data.ob);
+ PE_data_free(&data);
return OPERATOR_FINISHED;
}
@@ -2298,11 +2310,14 @@ bool PE_box_select(bContext *C, const rcti *rect, const int sel_op)
for_mouse_hit_keys(&data, select_key_op, PSEL_ALL_KEYS);
}
- if (data.is_changed) {
- PE_update_selection(data.depsgraph, scene, ob, 1);
+ bool is_changed = data.is_changed;
+ PE_data_free(&data);
+
+ if (is_changed) {
+ PE_update_selection(depsgraph, scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, ob);
}
- return data.is_changed;
+ return is_changed;
}
/** \} */
@@ -2311,35 +2326,53 @@ bool PE_box_select(bContext *C, const rcti *rect, const int sel_op)
/** \name Circle Select Operator
* \{ */
-bool PE_circle_select(bContext *C, const int sel_op, const int mval[2], float rad)
+static void pe_select_cache_free_generic_userdata(void *data)
+{
+ PE_data_free(data);
+ MEM_freeN(data);
+}
+
+static void pe_select_cache_init_with_generic_userdata(bContext *C, wmGenericUserData *wm_userdata)
+{
+ struct PEData *data = MEM_callocN(sizeof(*data), __func__);
+ wm_userdata->data = data;
+ wm_userdata->free_fn = pe_select_cache_free_generic_userdata;
+ wm_userdata->use_free = true;
+ PE_set_view3d_data(C, data);
+}
+
+bool PE_circle_select(
+ bContext *C, wmGenericUserData *wm_userdata, const int sel_op, const int mval[2], float rad)
{
BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
PTCacheEdit *edit = PE_get_current(depsgraph, scene, ob);
- PEData data;
if (!PE_start_edit(edit)) {
return false;
}
- const bool select = (sel_op != SEL_OP_SUB);
+ if (wm_userdata->data == NULL) {
+ pe_select_cache_init_with_generic_userdata(C, wm_userdata);
+ }
- PE_set_view3d_data(C, &data);
- data.mval = mval;
- data.rad = rad;
- data.select = select;
+ PEData *data = wm_userdata->data;
+ data->mval = mval;
+ data->rad = rad;
+ data->select = (sel_op != SEL_OP_SUB);
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- data.is_changed = PE_deselect_all_visible_ex(edit);
+ data->is_changed = PE_deselect_all_visible_ex(edit);
}
- for_mouse_hit_keys(&data, select_key, 0);
- if (data.is_changed) {
- PE_update_selection(data.depsgraph, scene, ob, 1);
+ for_mouse_hit_keys(data, select_key, 0);
+
+ if (data->is_changed) {
+ PE_update_selection(depsgraph, scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, ob);
}
- return data.is_changed;
+ return data->is_changed;
}
/** \} */
@@ -2425,8 +2458,11 @@ int PE_lasso_select(bContext *C, const int mcoords[][2], const int mcoords_len,
}
}
- if (data.is_changed) {
- PE_update_selection(data.depsgraph, scene, ob, 1);
+ bool is_changed = data.is_changed;
+ PE_data_free(&data);
+
+ if (is_changed) {
+ PE_update_selection(depsgraph, scene, ob, 1);
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_SELECTED, ob);
return OPERATOR_FINISHED;
}
@@ -2967,7 +3003,7 @@ static void remove_tagged_keys(Depsgraph *depsgraph, Object *ob, ParticleSystem
LOOP_TAGGED_KEYS {
new_totkey--;
}
- /* we can't have elements with less than two keys*/
+ /* We can't have elements with less than two keys. */
if (new_totkey < 2) {
point->flag |= PEP_TAG;
}
@@ -3106,7 +3142,7 @@ static void subdivide_particle(PEData *data, int pa_index)
nkey++;
}
}
- /*tip still not copied*/
+ /* Tip still not copied. */
memcpy(nkey, key, sizeof(HairKey));
memcpy(nekey, ekey, sizeof(PTCacheEditKey));
@@ -3919,7 +3955,7 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance)
/* keep the same distance from the root or we get glitches T35406. */
dist_ensure_v3_v3fl(co, co_root, length_accum);
- /* re-use dco to compare before and after translation and add to the offset */
+ /* Re-use dco to compare before and after translation and add to the offset. */
copy_v3_v3(dco, key->co);
mul_v3_m4v3(key->co, imat, co);
@@ -3938,7 +3974,7 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance)
/* this is simple but looks bad, adds annoying kinks */
add_v3_v3(key->co, ofs);
#else
- /* translate (not rotate) the rest of the hair if its not selected */
+ /* Translate (not rotate) the rest of the hair if its not selected. */
{
/* NOLINTNEXTLINE: readability-redundant-preprocessor */
# if 0 /* kindof works but looks worse than what's below */
@@ -4921,7 +4957,7 @@ static void brush_edit_exit(wmOperator *op)
{
BrushEdit *bedit = op->customdata;
- PE_free_random_generator(&bedit->data);
+ PE_data_free(&bedit->data);
MEM_freeN(bedit);
}
@@ -5408,7 +5444,7 @@ void ED_object_particle_edit_mode_enter_ex(Depsgraph *depsgraph, Scene *scene, O
edit = PE_create_current(depsgraph, scene, ob);
/* Mesh may have changed since last entering editmode.
- * note, this may have run before if the edit data was just created,
+ * NOTE: this may have run before if the edit data was just created,
* so could avoid this and speed up a little. */
if (edit && edit->psys) {
/* Make sure pointer to the evaluated modifier data is up to date,
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 6bcc9df16bf..387d10d538b 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -848,7 +848,8 @@ static bool remap_hair_emitter(Depsgraph *depsgraph,
copy_m4_m4(imat, target_ob->obmat);
}
else {
- /* note: using target_dm here, which is in target_ob object space and has full modifiers */
+ /* NOTE: using target_dm here, which is in target_ob object space and has full modifiers.
+ */
psys_mat_hair_to_object(target_ob, target_mesh, target_psys->part->from, tpa, hairmat);
invert_m4_m4(imat, hairmat);
}
@@ -1160,7 +1161,7 @@ static bool copy_particle_systems_to_object(const bContext *C,
}
MEM_freeN(tmp_psys);
- /* note: do this after creating DM copies for all the particle system modifiers,
+ /* NOTE: do this after creating DM copies for all the particle system modifiers,
* the remapping otherwise makes final_dm invalid!
*/
for (psys = psys_start, psys_from = PSYS_FROM_FIRST, i = 0; psys;
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index a94a2b9b764..cbab4fbd3d1 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -403,8 +403,10 @@ static void fluid_bake_startjob(void *customdata, short *stop, short *do_update,
BLI_path_join(
temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES, NULL);
BLI_path_abs(temp_dir, relbase);
- BLI_dir_create_recursive(
- temp_dir); /* Create 'particles' subdir if it does not exist already */
+
+ /* Create 'particles' subdir if it does not exist already */
+ BLI_dir_create_recursive(temp_dir);
+
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_PARTICLES | FLUID_DOMAIN_OUTDATED_PARTICLES);
fds->cache_flag |= FLUID_DOMAIN_BAKING_PARTICLES;
job->pause_frame = &fds->cache_frame_pause_particles;
diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h
index 4dc3ded9bd7..ef07d73826a 100644
--- a/source/blender/editors/physics/physics_intern.h
+++ b/source/blender/editors/physics/physics_intern.h
@@ -147,7 +147,7 @@ void RIGIDBODY_OT_mass_calculate(struct wmOperatorType *ot);
void RIGIDBODY_OT_constraint_add(struct wmOperatorType *ot);
void RIGIDBODY_OT_constraint_remove(struct wmOperatorType *ot);
-/*rigidbody_world.c */
+/* rigidbody_world.c */
void RIGIDBODY_OT_world_add(struct wmOperatorType *ot);
void RIGIDBODY_OT_world_remove(struct wmOperatorType *ot);
void RIGIDBODY_OT_world_export(struct wmOperatorType *ot);
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 0bec509cd7e..d5ad5a5eb84 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -121,7 +121,7 @@ static bool image_buffer_calc_tile_rect(const RenderResult *rr,
{
int tile_y, tile_height, tile_x, tile_width;
- /* if renrect argument, we only refresh scanlines */
+ /* When `renrect` argument is not NULL, we only refresh scan-lines. */
if (renrect) {
/* if (tile_height == recty), rendering of layer is ready,
* we should not draw, other things happen... */
@@ -285,7 +285,7 @@ static void screen_render_single_layer_set(
scn = (Scene *)BLI_findstring(&mainp->scenes, scene_name, offsetof(ID, name) + 2);
if (scn) {
- /* camera switch wont have updated */
+ /* camera switch won't have updated */
scn->r.cfra = (*scene)->r.cfra;
BKE_scene_camera_switch_update(scn);
@@ -773,7 +773,7 @@ static void render_endjob(void *rjv)
* was locked before running the job.
*/
WM_set_locked_interface(G_MAIN->wm.first, false);
- DEG_on_visible_update(G_MAIN, false);
+ DEG_tag_on_visible_update(G_MAIN, false);
}
}
@@ -793,7 +793,7 @@ static int render_breakjob(void *rjv)
/**
* For exec() when there is no render job
- * note: this wont check for the escape key being pressed, but doing so isn't thread-safe.
+ * NOTE: this won't check for the escape key being pressed, but doing so isn't thread-safe.
*/
static int render_break(void *UNUSED(rjv))
{
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 48f937fb4ec..17aaa5aa79d 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -141,7 +141,9 @@ typedef struct OGLRender {
wmWindowManager *wm;
wmWindow *win;
- wmTimer *timer; /* use to check if running modal or not (invoke'd or exec'd)*/
+ /** Use to check if running modal or not (invoke'd or exec'd). */
+ wmTimer *timer;
+
void **movie_ctx_arr;
TaskPool *task_pool;
@@ -461,7 +463,7 @@ static void screen_opengl_render_write(OGLRender *oglrender)
static void UNUSED_FUNCTION(addAlphaOverFloat)(float dest[4], const float source[4])
{
- /* d = s + (1-alpha_s)d*/
+ /* `d = s + (1-alpha_s)d` */
float mul;
mul = 1.0f - source[3];
@@ -544,7 +546,7 @@ static void gather_frames_to_render_for_adt(const OGLRender *oglrender, const An
continue;
}
- bool found = false; /* Not interesting, we just want a starting point for the for-loop.*/
+ bool found = false; /* Not interesting, we just want a starting point for the for-loop. */
int key_index = BKE_fcurve_bezt_binarysearch_index(
fcu->bezt, frame_start, fcu->totvert, &found);
for (; key_index < fcu->totvert; key_index++) {
@@ -645,7 +647,7 @@ static int gather_frames_to_render_for_id(LibraryIDLinkCallbackData *cb_data)
case ID_WM: /* WindowManager */
case ID_LS: /* FreestyleLineStyle */
case ID_PAL: /* Palette */
- case ID_PC: /* PaintCurve */
+ case ID_PC: /* PaintCurve */
case ID_CF: /* CacheFile */
case ID_WS: /* WorkSpace */
/* Only follow pointers to specific datablocks, to avoid ending up in
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 157f2b3ecb4..7f7ee45a803 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -70,6 +70,7 @@
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_scene.h"
+#include "BKE_screen.h"
#include "BKE_texture.h"
#include "BKE_world.h"
@@ -252,7 +253,7 @@ static const char *preview_collection_name(const char pr_type)
case MA_ATMOS:
return "Atmosphere";
default:
- BLI_assert(!"Unknown preview type");
+ BLI_assert_msg(0, "Unknown preview type");
return "";
}
}
@@ -334,7 +335,7 @@ static ID *duplicate_ids(ID *id, const bool allow_failure)
return NULL;
default:
if (!allow_failure) {
- BLI_assert(!"ID type preview not supported.");
+ BLI_assert_msg(0, "ID type preview not supported.");
}
return NULL;
}
@@ -610,9 +611,7 @@ static bool ed_preview_draw_rect(ScrArea *area, int split, int first, rcti *rect
float fy = rect->ymin;
/* material preview only needs monoscopy (view 0) */
- if (re) {
- RE_AcquiredResultGet32(re, &rres, (uint *)rect_byte, 0);
- }
+ RE_AcquiredResultGet32(re, &rres, (uint *)rect_byte, 0);
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
immDrawPixelsTex(
@@ -776,21 +775,26 @@ static void object_preview_render(IconPreview *preview, IconPreviewSize *preview
U.pixelsize = 2.0f;
+ View3DShading shading;
+ BKE_screen_view3d_shading_init(&shading);
+ /* Enable shadows, makes it a bit easier to see the shape. */
+ shading.flag |= V3D_SHADING_SHADOW;
+
ImBuf *ibuf = ED_view3d_draw_offscreen_imbuf_simple(
depsgraph,
DEG_get_evaluated_scene(depsgraph),
- NULL,
- OB_SOLID,
+ &shading,
+ OB_TEXTURE,
DEG_get_evaluated_object(depsgraph, scene->camera),
preview_sized->sizex,
preview_sized->sizey,
IB_rect,
- V3D_OFSDRAW_NONE,
+ V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS,
R_ALPHAPREMUL,
NULL,
NULL,
err_out);
- /* TODO color-management? */
+ /* TODO: color-management? */
U.pixelsize = pixelsize_old;
@@ -951,7 +955,7 @@ static void shader_preview_texture(ShaderPreview *sp, Tex *tex, Scene *sce, Rend
for (int x = 0; x < width; x++) {
tex_coord[0] = ((float)x / (float)height) * 2.0f - 1.0f;
- /* Evaluate texture at tex_coord .*/
+ /* Evaluate texture at tex_coord. */
TexResult texres = {0};
BKE_texture_get_value_ex(sce, tex, tex_coord, &texres, img_pool, color_manage);
@@ -1465,7 +1469,7 @@ static int icon_previewimg_size_index_get(const IconPreviewSize *icon_size,
}
}
- BLI_assert(!"The searched icon size does not match any in the preview image");
+ BLI_assert_msg(0, "The searched icon size does not match any in the preview image");
return -1;
}
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index b4cac58db1f..d2b1ebdad78 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -103,7 +103,7 @@ static bool object_materials_supported_poll_ex(bContext *C, const Object *ob);
/** \name Local Utilities
* \{ */
-static bool object_array_for_shading_edit_mode_enabled_filter(Object *ob, void *user_data)
+static bool object_array_for_shading_edit_mode_enabled_filter(const Object *ob, void *user_data)
{
bContext *C = user_data;
if (object_materials_supported_poll_ex(C, ob)) {
@@ -120,7 +120,7 @@ static Object **object_array_for_shading_edit_mode_enabled(bContext *C, uint *r_
C, object_array_for_shading_edit_mode_enabled_filter, C, r_objects_len);
}
-static bool object_array_for_shading_edit_mode_disabled_filter(Object *ob, void *user_data)
+static bool object_array_for_shading_edit_mode_disabled_filter(const Object *ob, void *user_data)
{
bContext *C = user_data;
if (object_materials_supported_poll_ex(C, ob)) {
@@ -227,7 +227,7 @@ static int material_slot_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* Removing material slots in edit mode screws things up, see bug T21822.*/
+ /* Removing material slots in edit mode screws things up, see bug T21822. */
if (ob == CTX_data_edit_object(C)) {
BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
return OPERATOR_CANCELLED;
@@ -294,7 +294,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
}
else {
/* Find the first matching material.
- * Note: there may be multiple but that's not a common use case. */
+ * NOTE: there may be multiple but that's not a common use case. */
for (int i = 0; i < ob->totcol; i++) {
const Material *mat = BKE_object_material_get(ob, i + 1);
if (mat_active == mat) {
@@ -401,7 +401,7 @@ static int material_slot_de_select(bContext *C, bool select)
}
else {
/* Find the first matching material.
- * Note: there may be multiple but that's not a common use case. */
+ * NOTE: there may be multiple but that's not a common use case. */
for (int i = 0; i < ob->totcol; i++) {
const Material *mat = BKE_object_material_get(ob, i + 1);
if (mat_active == mat) {
@@ -1183,7 +1183,7 @@ static int light_cache_bake_exec(bContext *C, wmOperator *op)
G.is_break = false;
- /* TODO abort if selected engine is not eevee. */
+ /* TODO: abort if selected engine is not eevee. */
void *rj = EEVEE_lightbake_job_data_alloc(bmain, view_layer, scene, false, scene->r.cfra);
light_cache_bake_tag_cache(scene, op);
@@ -2418,7 +2418,7 @@ static void paste_mtex_copybuf(ID *id)
mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
break;
default:
- BLI_assert(!"invalid id type");
+ BLI_assert_msg(0, "invalid id type");
return;
}
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 3e8a1bda2f0..80b5623b9c3 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -216,7 +216,7 @@ void ED_render_view_layer_changed(Main *bmain, bScreen *screen)
/***************************** Updates ***********************************
* ED_render_id_flush_update gets called from DEG_id_tag_update, to do *
* editor level updates when the ID changes. when these ID blocks are in *
- * the dependency graph, we can get rid of the manual dependency checks */
+ * the dependency graph, we can get rid of the manual dependency checks. */
static void material_changed(Main *UNUSED(bmain), Material *ma)
{
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index 465438f814a..97ecb67d6cc 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -51,9 +51,11 @@
/*********************** utilities for finding areas *************************/
-/* returns biggest area that is not uv/image editor. Note that it uses buttons */
-/* window as the last possible alternative. */
-/* would use BKE_screen_find_big_area(...) but this is too specific */
+/**
+ * Returns biggest area that is not uv/image editor. Note that it uses buttons
+ * window as the last possible alternative.
+ * would use #BKE_screen_find_big_area(...) but this is too specific.
+ */
static ScrArea *biggest_non_image_area(bContext *C)
{
bScreen *screen = CTX_wm_screen(C);
@@ -164,6 +166,7 @@ ScrArea *render_view_open(bContext *C, int mx, int my, ReportList *reports)
sizex,
sizey,
SPACE_IMAGE,
+ true,
false,
true,
WIN_ALIGN_LOCATION_CENTER) == NULL) {
diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c
index 2b2a0d10e29..5195bc8303a 100644
--- a/source/blender/editors/scene/scene_edit.c
+++ b/source/blender/editors/scene/scene_edit.c
@@ -120,7 +120,7 @@ void ED_scene_change_update(Main *bmain, Scene *scene, ViewLayer *layer)
BKE_scene_set_background(bmain, scene);
DEG_graph_relations_update(depsgraph);
- DEG_on_visible_update(bmain, false);
+ DEG_tag_on_visible_update(bmain, false);
ED_render_engine_changed(bmain, false);
ED_update_for_newframe(bmain, depsgraph);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index b83eccdcfdd..f4109981aae 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -1385,7 +1385,7 @@ static void region_rect_recursive(
region->flag |= RGN_FLAG_SIZE_CLAMP_Y;
}
- /* We need to use a test that wont have been previously clamped. */
+ /* We need to use a test that won't have been previously clamped. */
rcti winrct_test = {
.xmin = region->winrct.xmin,
.ymin = region->winrct.ymin,
@@ -1461,7 +1461,7 @@ static void region_rect_recursive(
}
}
else if (ELEM(alignment, RGN_ALIGN_VSPLIT, RGN_ALIGN_HSPLIT)) {
- /* percentage subdiv*/
+ /* Percentage subdiv. */
region->winrct = *remainder;
if (alignment == RGN_ALIGN_HSPLIT) {
@@ -1527,8 +1527,8 @@ static void region_rect_recursive(
BLI_rcti_init(remainder, 0, 0, 0, 0);
}
- /* Fix any negative dimensions. This can happen when a quad split 3d view gets to small. (see
- * T72200). */
+ /* Fix any negative dimensions. This can happen when a quad split 3d view gets too small.
+ * (see T72200). */
BLI_rcti_sanitize(&region->winrct);
quad++;
@@ -1539,8 +1539,8 @@ static void region_rect_recursive(
region->winx = BLI_rcti_size_x(&region->winrct) + 1;
region->winy = BLI_rcti_size_y(&region->winrct) + 1;
- /* if region opened normally, we store this for hide/reveal usage */
- /* prevent rounding errors for UI_DPI_FAC mult and divide */
+ /* If region opened normally, we store this for hide/reveal usage. */
+ /* Prevent rounding errors for UI_DPI_FAC multiply and divide. */
if (region->winx > 1) {
region->sizex = (region->winx + 0.5f) / UI_DPI_FAC;
}
@@ -1680,7 +1680,7 @@ static void ed_default_handlers(
{
BLI_assert(region ? (&region->handlers == handlers) : (&area->handlers == handlers));
- /* note, add-handler checks if it already exists */
+ /* NOTE: add-handler checks if it already exists. */
/* XXX it would be good to have boundbox checks for some of these... */
if (flag & ED_KEYMAP_UI) {
@@ -2081,7 +2081,7 @@ void ED_area_data_copy(ScrArea *area_dst, ScrArea *area_src, const bool do_free)
}
BKE_spacedata_copylist(&area_dst->spacedata, &area_src->spacedata);
- /* Note; SPACE_EMPTY is possible on new screens */
+ /* NOTE: SPACE_EMPTY is possible on new screens. */
/* regions */
if (do_free) {
@@ -2387,7 +2387,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi
* However, add-on install for example, forces the header to the top which shouldn't
* be applied back to the previous space type when closing - see: T57724
*
- * Newly created windows wont have any space data, use the alignment
+ * Newly-created windows won't have any space data, use the alignment
* the space type defaults to in this case instead
* (needed for preferences to have space-type on bottom).
*/
@@ -3325,10 +3325,10 @@ void ED_region_header_layout(const bContext *C, ARegion *region)
maxco += UI_HEADER_OFFSET;
}
- /* always as last */
+ /* Always as last. */
UI_view2d_totRect_set(&region->v2d, maxco, region->winy);
- /* restore view matrix */
+ /* Restore view matrix. */
UI_view2d_view_restore(C);
}
@@ -3672,7 +3672,7 @@ static void region_visible_rect_calc(ARegion *region, rcti *rect)
/* Skip floating. */
}
else {
- BLI_assert(!"Region overlap with unknown alignment");
+ BLI_assert_msg(0, "Region overlap with unknown alignment");
}
}
}
diff --git a/source/blender/editors/screen/area_query.c b/source/blender/editors/screen/area_query.c
index d569e56e11b..fd4f3964398 100644
--- a/source/blender/editors/screen/area_query.c
+++ b/source/blender/editors/screen/area_query.c
@@ -88,7 +88,7 @@ bool ED_region_panel_category_gutter_calc_rect(const ARegion *region, rcti *r_re
r_region_gutter->xmin = r_region_gutter->xmax - category_tabs_width;
}
else {
- BLI_assert(!"Unsupported alignment");
+ BLI_assert_msg(0, "Unsupported alignment");
}
return true;
}
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index e366760a55d..f651fd4fb61 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -126,7 +126,7 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
components = 1;
}
else {
- BLI_assert(!"Incompatible format passed to immDrawPixels");
+ BLI_assert_msg(0, "Incompatible format passed to immDrawPixels");
return;
}
@@ -426,7 +426,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
format = GPU_RGBA16F;
}
else {
- BLI_assert(!"Incompatible number of channels for GLSL display");
+ BLI_assert_msg(0, "Incompatible number of channels for GLSL display");
}
if (format != 0) {
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 627a67358f2..d50962a56a9 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -874,7 +874,7 @@ static eContextResult screen_ctx_editable_gpencil_strokes(const bContext *C,
}
}
}
- /* if not multiedit out of loop */
+ /* If not multi-edit out of loop. */
if (!is_multiedit) {
break;
}
@@ -896,11 +896,11 @@ static eContextResult screen_ctx_active_operator(const bContext *C, bContextData
/* do nothing */
}
else {
- /* note, this checks poll, could be a problem, but this also
+ /* NOTE: this checks poll, could be a problem, but this also
* happens for the toolbar */
op = WM_operator_last_redo(C);
}
- /* TODO, get the operator from popup's */
+ /* TODO: get the operator from popup's. */
if (op && op->ptr) {
CTX_data_pointer_set(result, NULL, &RNA_Operator, op);
diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c
index 2c45524ef94..dca464bbf22 100644
--- a/source/blender/editors/screen/screen_draw.c
+++ b/source/blender/editors/screen/screen_draw.c
@@ -244,7 +244,7 @@ void screen_draw_join_highlight(ScrArea *sa1, ScrArea *sa2)
return;
}
- /* Rect of the combined areas.*/
+ /* Rect of the combined areas. */
const bool vertical = SCREEN_DIR_IS_VERTICAL(dir);
const rctf combined = {
.xmin = vertical ? MAX2(sa1->totrct.xmin, sa2->totrct.xmin) :
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 6fb5f33d836..2a81fcfde8f 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -68,7 +68,7 @@ static ScrArea *screen_addarea_ex(ScrAreaMap *area_map,
ScrVert *top_left,
ScrVert *top_right,
ScrVert *bottom_right,
- short spacetype)
+ const eSpace_Type space_type)
{
ScrArea *area = MEM_callocN(sizeof(ScrArea), "addscrarea");
@@ -76,7 +76,7 @@ static ScrArea *screen_addarea_ex(ScrAreaMap *area_map,
area->v2 = top_left;
area->v3 = top_right;
area->v4 = bottom_right;
- area->spacetype = spacetype;
+ area->spacetype = space_type;
BLI_addtail(&area_map->areabase, area);
@@ -87,10 +87,10 @@ static ScrArea *screen_addarea(bScreen *screen,
ScrVert *left_top,
ScrVert *right_top,
ScrVert *right_bottom,
- short spacetype)
+ const eSpace_Type space_type)
{
return screen_addarea_ex(
- AREAMAP_FROM_SCREEN(screen), left_bottom, left_top, right_top, right_bottom, spacetype);
+ AREAMAP_FROM_SCREEN(screen), left_bottom, left_top, right_top, right_bottom, space_type);
}
static void screen_delarea(bContext *C, bScreen *screen, ScrArea *area)
@@ -125,9 +125,9 @@ ScrArea *area_split(const wmWindow *win,
return NULL;
}
- /* note regarding (fac > 0.5f) checks below.
+ /* NOTE(campbell): regarding (fac > 0.5f) checks below.
* normally it shouldn't matter which is used since the copy should match the original
- * however with viewport rendering and python console this isn't the case. - campbell */
+ * however with viewport rendering and python console this isn't the case. */
if (dir_axis == SCREEN_AXIS_H) {
/* new vertices */
@@ -972,7 +972,7 @@ int ED_screen_area_active(const bContext *C)
*/
static ScrArea *screen_area_create_with_geometry(ScrAreaMap *area_map,
const rcti *rect,
- short spacetype)
+ eSpace_Type space_type)
{
ScrVert *bottom_left = screen_geom_vertex_add_ex(area_map, rect->xmin, rect->ymin);
ScrVert *top_left = screen_geom_vertex_add_ex(area_map, rect->xmin, rect->ymax);
@@ -984,7 +984,7 @@ static ScrArea *screen_area_create_with_geometry(ScrAreaMap *area_map,
screen_geom_edge_add_ex(area_map, top_right, bottom_right);
screen_geom_edge_add_ex(area_map, bottom_right, bottom_left);
- return screen_addarea_ex(area_map, bottom_left, top_left, top_right, bottom_right, spacetype);
+ return screen_addarea_ex(area_map, bottom_left, top_left, top_right, bottom_right, space_type);
}
static void screen_area_set_geometry_rect(ScrArea *area, const rcti *rect)
@@ -1001,7 +1001,7 @@ static void screen_area_set_geometry_rect(ScrArea *area, const rcti *rect)
static void screen_global_area_refresh(wmWindow *win,
bScreen *screen,
- eSpace_Type space_type,
+ const eSpace_Type space_type,
GlobalAreaAlign align,
const rcti *rect,
const short height_cur,
@@ -1275,11 +1275,14 @@ void ED_screen_scene_change(bContext *C, wmWindow *win, Scene *scene)
ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *area, int type)
{
+ bScreen *newscreen = NULL;
ScrArea *newsa = NULL;
SpaceLink *newsl;
if (!area || area->full == NULL) {
- newsa = ED_screen_state_maximized_create(C);
+ newscreen = ED_screen_state_maximized_create(C);
+ newsa = newscreen->areabase.first;
+ BLI_assert(newsa->spacetype == SPACE_EMPTY);
}
if (!newsa) {
@@ -1296,6 +1299,10 @@ ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *area, int type)
ED_area_newspace(C, newsa, type, (newsl && newsl->link_flag & SPACE_FLAG_TYPE_TEMPORARY));
+ if (newscreen) {
+ ED_screen_change(C, newscreen);
+ }
+
return newsa;
}
@@ -1361,6 +1368,10 @@ void ED_screen_full_restore(bContext *C, ScrArea *area)
* \param toggle_area: If this is set, its space data will be swapped with the one of the new empty
* area, when toggling back it can be swapped back again.
* \return The newly created screen with the non-normal area.
+ *
+ * \note The caller must run #ED_screen_change this is not done in this function
+ * as it would attempt to initialize areas that don't yet have a space-type assigned
+ * (converting them to 3D view without creating the space-data).
*/
static bScreen *screen_state_to_nonnormal(bContext *C,
wmWindow *win,
@@ -1429,7 +1440,6 @@ static bScreen *screen_state_to_nonnormal(bContext *C,
}
newa->full = oldscreen;
- ED_screen_change(C, screen);
ED_area_tag_refresh(newa);
return screen;
@@ -1442,10 +1452,9 @@ static bScreen *screen_state_to_nonnormal(bContext *C,
* Use this to just create a new maximized screen/area, rather than maximizing an existing one.
* Otherwise, maximize with #ED_screen_state_toggle().
*/
-ScrArea *ED_screen_state_maximized_create(bContext *C)
+bScreen *ED_screen_state_maximized_create(bContext *C)
{
- bScreen *screen = screen_state_to_nonnormal(C, CTX_wm_window(C), NULL, SCREENMAXIMIZED);
- return screen->areabase.first;
+ return screen_state_to_nonnormal(C, CTX_wm_window(C), NULL, SCREENMAXIMIZED);
}
/**
@@ -1548,11 +1557,21 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const
}
screen = screen_state_to_nonnormal(C, win, toggle_area, state);
+
+ ED_screen_change(C, screen);
}
BLI_assert(CTX_wm_screen(C) == screen);
BLI_assert(CTX_wm_area(C) == NULL); /* May have been freed. */
+ /* Setting the area is only needed for Python scripts that call
+ * operators in succession before returning to the main event loop.
+ * Without this, scripts can't run any operators that require
+ * an area after toggling full-screen for example (see: T89526).
+ * NOTE: an old comment stated this was "bad code",
+ * however it doesn't cause problems so leave as-is. */
+ CTX_wm_area_set(C, screen->areabase.first);
+
return screen->areabase.first;
}
@@ -1585,6 +1604,7 @@ ScrArea *ED_screen_temp_space_open(bContext *C,
sizex,
sizey,
(int)space_type,
+ false,
dialog,
true,
WIN_ALIGN_LOCATION_CENTER)) {
@@ -1663,7 +1683,7 @@ void ED_screen_animation_timer(bContext *C, int redraws, int sync, int enable)
sad->region = CTX_wm_region(C);
/* If start-frame is larger than current frame, we put current-frame on start-frame.
- * note: first frame then is not drawn! (ton) */
+ * NOTE(ton): first frame then is not drawn! */
if (PRVRANGEON) {
if (scene->r.psfra > scene->r.cfra) {
sad->sfra = scene->r.cfra;
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 6b8d4e73f12..ffeaf514642 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -279,6 +279,11 @@ bool ED_operator_file_active(bContext *C)
return ed_spacetype_test(C, SPACE_FILE);
}
+bool ED_operator_spreadsheet_active(bContext *C)
+{
+ return ed_spacetype_test(C, SPACE_SPREADSHEET);
+}
+
bool ED_operator_action_active(bContext *C)
{
return ed_spacetype_test(C, SPACE_ACTION);
@@ -358,9 +363,24 @@ bool ED_operator_object_active(bContext *C)
return ((ob != NULL) && !ed_object_hidden(ob));
}
-bool ED_operator_object_active_editable_ex(bContext *UNUSED(C), const Object *ob)
+bool ED_operator_object_active_editable_ex(bContext *C, const Object *ob)
{
- return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob));
+ if (ob == NULL) {
+ CTX_wm_operator_poll_msg_set(C, "Context missing active object");
+ return false;
+ }
+
+ if (ID_IS_LINKED(ob)) {
+ CTX_wm_operator_poll_msg_set(C, "Cannot edit library linked object");
+ return false;
+ }
+
+ if (ed_object_hidden(ob)) {
+ CTX_wm_operator_poll_msg_set(C, "Cannot edit hidden obect");
+ return false;
+ }
+
+ return true;
}
bool ED_operator_object_active_editable(bContext *C)
@@ -444,28 +464,48 @@ bool ED_operator_editarmature(bContext *C)
}
/**
- * \brief check for pose mode (no mixed modes)
+ * Check for pose mode (no mixed modes).
*
- * We want to enable most pose operations in weight paint mode,
- * when it comes to transforming bones, but managing bones layers/groups
- * can be left for pose mode only. (not weight paint mode)
+ * We want to enable most pose operations in weight paint mode, when it comes to transforming
+ * bones, but managing bones layers/groups and their constraints can be left for pose mode only
+ * (not weight paint mode).
*/
-bool ED_operator_posemode_exclusive(bContext *C)
+static bool ed_operator_posemode_exclusive_ex(bContext *C, Object *obact)
{
- Object *obact = CTX_data_active_object(C);
-
- if (obact && !(obact->mode & OB_MODE_EDIT)) {
- Object *obpose = BKE_object_pose_armature_get(obact);
- if (obpose != NULL) {
- if (obact == obpose) {
- return true;
- }
+ if (obact != NULL && !(obact->mode & OB_MODE_EDIT)) {
+ if (obact == BKE_object_pose_armature_get(obact)) {
+ return true;
}
}
+ CTX_wm_operator_poll_msg_set(C, "No object, or not exclusively in pose mode");
return false;
}
+bool ED_operator_posemode_exclusive(bContext *C)
+{
+ Object *obact = ED_object_active_context(C);
+
+ return ed_operator_posemode_exclusive_ex(C, obact);
+}
+
+/** Object must be editable, fully local (i.e. not an override), and exclusively in Pose mode. */
+bool ED_operator_object_active_local_editable_posemode_exclusive(bContext *C)
+{
+ Object *obact = ED_object_active_context(C);
+
+ if (!ed_operator_posemode_exclusive_ex(C, obact)) {
+ return false;
+ }
+
+ if (ID_IS_OVERRIDE_LIBRARY(obact)) {
+ CTX_wm_operator_poll_msg_set(C, "Object is a local library override");
+ return false;
+ }
+
+ return true;
+}
+
/* allows for pinned pose objects to be used in the object buttons
* and the non-active pose object to be used in the 3D view */
bool ED_operator_posemode_context(bContext *C)
@@ -1362,6 +1402,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
area->winx,
area->winy,
SPACE_EMPTY,
+ false,
true,
false,
WIN_ALIGN_ABSOLUTE);
@@ -2076,16 +2117,16 @@ static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *area, ScrArea *sb)
ScrVert *sbv3 = sb->v3;
ScrVert *sbv4 = sb->v4;
- if (sav1 == sbv4 && sav2 == sbv3) { /* area to right of sb = W */
+ if (sav1 == sbv4 && sav2 == sbv3) { /* Area to right of sb = W. */
return BKE_screen_find_edge(screen, sav1, sav2);
}
- if (sav2 == sbv1 && sav3 == sbv4) { /* area to bottom of sb = N */
+ if (sav2 == sbv1 && sav3 == sbv4) { /* Area to bottom of sb = N. */
return BKE_screen_find_edge(screen, sav2, sav3);
}
- if (sav3 == sbv2 && sav4 == sbv1) { /* area to left of sb = E */
+ if (sav3 == sbv2 && sav4 == sbv1) { /* Area to left of sb = E. */
return BKE_screen_find_edge(screen, sav3, sav4);
}
- if (sav1 == sbv2 && sav4 == sbv3) { /* area on top of sb = S*/
+ if (sav1 == sbv2 && sav4 == sbv3) { /* Area on top of sb = S. */
return BKE_screen_find_edge(screen, sav1, sav4);
}
@@ -2751,9 +2792,9 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
CLAMP(rmd->region->sizey, 0, rmd->maxsize);
- /* note, 'UI_UNIT_Y/4' means you need to drag the footer and execute region
+ /* NOTE: `UI_UNIT_Y / 4` means you need to drag the footer and execute region
* almost all the way down for it to become hidden, this is done
- * otherwise its too easy to do this by accident */
+ * otherwise its too easy to do this by accident. */
if (size_no_snap < (UI_UNIT_Y / 4) / aspect) {
rmd->region->sizey = rmd->origval;
if (!(rmd->region->flag & RGN_FLAG_HIDDEN)) {
@@ -4446,9 +4487,17 @@ static void screen_animation_region_tag_redraw(ScrArea *area,
/* No need to do a full redraw as the current frame indicator is only updated.
* We do need to redraw when this area is in full screen as no other areas
* will be tagged for redrawing. */
- if ((region->regiontype == RGN_TYPE_WINDOW) &&
- (ELEM(area->spacetype, SPACE_GRAPH, SPACE_NLA, SPACE_ACTION)) && !area->full) {
- return;
+ if (region->regiontype == RGN_TYPE_WINDOW && !area->full) {
+ if (ELEM(area->spacetype, SPACE_GRAPH, SPACE_NLA, SPACE_ACTION)) {
+ return;
+ }
+
+ if (area->spacetype == SPACE_SEQ) {
+ const SpaceSeq *sseq = area->spacedata.first;
+ if (!ED_space_sequencer_has_playback_animation(sseq, scene)) {
+ return;
+ }
+ }
}
ED_region_tag_redraw(region);
}
@@ -4948,6 +4997,7 @@ static int userpref_show_exec(bContext *C, wmOperator *op)
sizey,
SPACE_USERPREF,
false,
+ false,
true,
WIN_ALIGN_LOCATION_CENTER) != NULL) {
/* The header only contains the editor switcher and looks empty.
@@ -5014,6 +5064,7 @@ static int drivers_editor_show_exec(bContext *C, wmOperator *op)
sizey,
SPACE_GRAPH,
false,
+ false,
true,
WIN_ALIGN_LOCATION_CENTER) != NULL) {
ED_drivers_editor_init(C, CTX_wm_area(C));
@@ -5082,6 +5133,7 @@ static int info_log_show_exec(bContext *C, wmOperator *op)
sizey,
SPACE_INFO,
false,
+ false,
true,
WIN_ALIGN_LOCATION_CENTER) != NULL) {
return OPERATOR_FINISHED;
@@ -5167,7 +5219,7 @@ static void SCREEN_OT_delete(wmOperatorType *ot)
/* -------------------------------------------------------------------- */
/** \name Region Alpha Blending Operator
*
- * Implementation note: a disappearing region needs at least 1 last draw with
+ * Implementation NOTE: a disappearing region needs at least 1 last draw with
* 100% back-buffer texture over it - then triple buffer will clear it entirely.
* This because flag #RGN_FLAG_HIDDEN is set in end - region doesn't draw at all then.
*
@@ -5546,13 +5598,13 @@ static void SCREEN_OT_workspace_cycle(wmOperatorType *ot)
/* called in spacetypes.c */
void ED_operatortypes_screen(void)
{
- /* generic UI stuff */
+ /* Generic UI stuff. */
WM_operatortype_append(SCREEN_OT_actionzone);
WM_operatortype_append(SCREEN_OT_repeat_last);
WM_operatortype_append(SCREEN_OT_repeat_history);
WM_operatortype_append(SCREEN_OT_redo_last);
- /* screen tools */
+ /* Screen tools. */
WM_operatortype_append(SCREEN_OT_area_move);
WM_operatortype_append(SCREEN_OT_area_split);
WM_operatortype_append(SCREEN_OT_area_join);
@@ -5579,7 +5631,7 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(SCREEN_OT_space_context_cycle);
WM_operatortype_append(SCREEN_OT_workspace_cycle);
- /*frame changes*/
+ /* Frame changes. */
WM_operatortype_append(SCREEN_OT_frame_offset);
WM_operatortype_append(SCREEN_OT_frame_jump);
WM_operatortype_append(SCREEN_OT_keyframe_jump);
@@ -5589,7 +5641,7 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(SCREEN_OT_animation_play);
WM_operatortype_append(SCREEN_OT_animation_cancel);
- /* new/delete */
+ /* New/delete. */
WM_operatortype_append(SCREEN_OT_new);
WM_operatortype_append(SCREEN_OT_delete);
}
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 3829aeebbeb..ab2b2f4b16b 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -940,7 +940,7 @@ static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc)
int j;
PaintCurvePoint *cp_next = cp + 1;
float data[(PAINT_CURVE_NUM_SEGMENTS + 1) * 2];
- /* Use color coding to distinguish handles vs curve segments. */
+ /* Use color coding to distinguish handles vs curve segments. */
draw_bezier_handle_lines(pos, selec_col, &cp->bez);
draw_tri_point(pos, selec_col, pivot_col, &cp->bez.vec[1][0], 10.0f, cp->bez.f2);
draw_rect_point(
@@ -1039,7 +1039,7 @@ static void cursor_draw_point_screen_space(const uint gpuattr,
float translation_vertex_cursor[3], location[3];
copy_v3_v3(location, true_location);
mul_m4_v3(obmat, location);
- ED_view3d_project(region, location, translation_vertex_cursor);
+ ED_view3d_project_v3(region, location, translation_vertex_cursor);
/* Do not draw points behind the view. Z [near, far] is mapped to [-1, 1]. */
if (translation_vertex_cursor[2] <= 1.0f) {
imm_draw_circle_fill_3d(
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 324fd5d3075..39d776e0054 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -176,7 +176,7 @@ void imapaint_image_update(
ibuf->userflags |= IB_MIPMAP_INVALID;
}
- /* todo: should set_tpage create ->rect? */
+ /* TODO: should set_tpage create ->rect? */
if (texpaint || (sima && sima->lock)) {
int w = imapaintpartial.x2 - imapaintpartial.x1;
int h = imapaintpartial.y2 - imapaintpartial.y1;
@@ -681,7 +681,7 @@ static bool paint_stroke_test_start(bContext *C, wmOperator *op, const float mou
{
PaintOperation *pop;
- /* TODO Should avoid putting this here. Instead, last position should be requested
+ /* TODO: Should avoid putting this here. Instead, last position should be requested
* from stroke system. */
if (!(pop = texture_paint_init(C, op, mouse))) {
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index f0923cf3d28..ffa6f6ac962 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -745,7 +745,7 @@ static void brush_painter_2d_tex_mapping(ImagePaintState *s,
mapping->ymax = (ymax - ymin) / (float)diameter;
}
else if (mapmode == MTEX_MAP_MODE_3D) {
- /* 3D mapping, just mapping to canvas 0..1 */
+ /* 3D mapping, just mapping to canvas 0..1. */
mapping->xmin = 2.0f * (ipos[0] * invw - 0.5f);
mapping->ymin = 2.0f * (ipos[1] * invh - 0.5f);
mapping->xmax = 2.0f * invw;
@@ -1248,7 +1248,7 @@ static void paint_2d_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos, short paint
static ImBuf *paint_2d_lift_clone(ImBuf *ibuf, ImBuf *ibufb, const int *pos)
{
- /* note: allocImbuf returns zero'd memory, so regions outside image will
+ /* NOTE: allocImbuf returns zero'd memory, so regions outside image will
* have zero alpha, and hence not be blended onto the image */
int w = ibufb->x, h = ibufb->y, destx = 0, desty = 0, srcx = pos[0], srcy = pos[1];
ImBuf *clonebuf = IMB_allocImBuf(w, h, ibufb->planes, ibufb->flags);
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 530689ce049..bd05d309421 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -122,7 +122,7 @@ BLI_INLINE uchar f_to_char(const float val)
*
* When 3 - a brush should have ~9 buckets under it at once
* ...this helps for threading while painting as well as
- * avoiding initializing pixels that wont touch the brush */
+ * avoiding initializing pixels that won't touch the brush */
#define PROJ_BUCKET_BRUSH_DIV 4
#define PROJ_BUCKET_RECT_MIN 4
@@ -300,7 +300,7 @@ typedef struct ProjPaintState {
/** Calculated from screenMin & screenMax. */
float screen_width;
float screen_height;
- /** from the carea or from the projection render. */
+ /** From the area or from the projection render. */
int winx, winy;
/* options for projection painting */
@@ -391,7 +391,7 @@ typedef struct ProjPaintState {
float *cavities;
#ifndef PROJ_DEBUG_NOSEAMBLEED
- /** store info about faces, if they are initialized etc*/
+ /** Store info about faces, if they are initialized etc. */
ushort *faceSeamFlags;
/** save the winding of the face in uv space,
* helps as an extra validation step for seam detection. */
@@ -576,7 +576,9 @@ static Image *project_paint_face_clone_image(const ProjPaintState *ps, int tri_i
return slot ? slot->ima : ps->clone_ima;
}
-/* fast projection bucket array lookup, use the safe version for bound checking */
+/**
+ * Fast projection bucket array lookup, use the safe version for bound checking.
+ */
static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[2])
{
/* If we were not dealing with screen-space 2D coords we could simple do...
@@ -928,7 +930,7 @@ static bool project_bucket_point_occluded(const ProjPaintState *ps,
}
if (isect_ret >= 1) {
- /* TODO - we may want to cache the first hit,
+ /* TODO: we may want to cache the first hit,
* it is not possible to swap the face order in the list anymore */
return true;
}
@@ -957,7 +959,7 @@ static int line_isect_y(const float p1[2], const float p2[2], const float y_leve
return ISECT_TRUE_P2;
}
- /** yuck, horizontal line, we cant do much here. */
+ /** yuck, horizontal line, we can't do much here. */
y_diff = fabsf(p1[1] - p2[1]);
if (y_diff < 0.000001f) {
@@ -991,10 +993,10 @@ static int line_isect_x(const float p1[2], const float p2[2], const float x_leve
return ISECT_TRUE_P2;
}
- /* yuck, horizontal line, we cant do much here */
+ /* yuck, horizontal line, we can't do much here */
x_diff = fabsf(p1[0] - p2[0]);
- /* yuck, vertical line, we cant do much here */
+ /* yuck, vertical line, we can't do much here */
if (x_diff < 0.000001f) {
*y_isect = (p1[0] + p2[0]) * 0.5f;
return ISECT_TRUE;
@@ -1071,7 +1073,7 @@ static bool pixel_bounds_uv(const float uv_quad[4][2],
bounds_px->xmax = (int)(ibuf_x * max_uv[0]) + 1;
bounds_px->ymax = (int)(ibuf_y * max_uv[1]) + 1;
- /*printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
+ // printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]);
/* face uses no UV area when quantized to pixels? */
return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? false : true;
@@ -1101,7 +1103,7 @@ static bool pixel_bounds_array(
bounds_px->xmax = (int)(ibuf_x * max_uv[0]) + 1;
bounds_px->ymax = (int)(ibuf_y * max_uv[1]) + 1;
- /*printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
+ // printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]);
/* face uses no UV area when quantized to pixels? */
return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? false : true;
@@ -1659,7 +1661,7 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps,
const MLoopTri *lt_other = &ps->mlooptri_eval[tri_index];
const float *lt_other_tri_uv[3] = {PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, lt_other)};
- /* BKE_image_acquire_ibuf - TODO - this may be slow */
+ /* #BKE_image_acquire_ibuf - TODO: this may be slow. */
uchar rgba_ub[4];
float rgba_f[4];
@@ -1766,13 +1768,13 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps,
angle_cos = dot_v3v3(viewDirPersp, no);
}
- /* If backface culling is disabled, allow painting on back faces. */
+ /* If back-face culling is disabled, allow painting on back faces. */
if (!ps->do_backfacecull) {
angle_cos = fabsf(angle_cos);
}
if (angle_cos <= ps->normal_angle__cos) {
- /* outsize the normal limit*/
+ /* Outsize the normal limit. */
return 0.0f;
}
if (angle_cos < ps->normal_angle_inner__cos) {
@@ -1876,7 +1878,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps,
int x_tile, y_tile;
int x_round, y_round;
int tile_offset;
- /* volatile is important here to ensure pending check is not optimized away by compiler*/
+ /* Volatile is important here to ensure pending check is not optimized away by compiler. */
volatile int tile_index;
ProjPaintImage *projima = tinf->pjima;
@@ -1957,7 +1959,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps,
const float *lt_other_tri_uv[3] = {
PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv_clone, lt_other)};
- /* BKE_image_acquire_ibuf - TODO - this may be slow */
+ /* #BKE_image_acquire_ibuf - TODO: this may be slow. */
if (ibuf->rect_float) {
if (ibuf_other->rect_float) { /* from float to float */
@@ -2050,7 +2052,7 @@ static bool line_clip_rect2f(const rctf *cliprect,
float l2_clip[2])
{
/* first account for horizontal, then vertical lines */
- /* horiz */
+ /* Horizontal. */
if (fabsf(l1[1] - l2[1]) < PROJ_PIXEL_TOLERANCE) {
/* is the line out of range on its Y axis? */
if (l1[1] < rect->ymin || l1[1] > rect->ymax) {
@@ -2061,7 +2063,7 @@ static bool line_clip_rect2f(const rctf *cliprect,
return false;
}
- /* this is a single point (or close to)*/
+ /* This is a single point (or close to). */
if (fabsf(l1[0] - l2[0]) < PROJ_PIXEL_TOLERANCE) {
if (BLI_rctf_isect_pt_v(rect, l1)) {
copy_v2_v2(l1_clip, l1);
@@ -2088,7 +2090,7 @@ static bool line_clip_rect2f(const rctf *cliprect,
return false;
}
- /* this is a single point (or close to)*/
+ /* This is a single point (or close to). */
if (fabsf(l1[1] - l2[1]) < PROJ_PIXEL_TOLERANCE) {
if (BLI_rctf_isect_pt_v(rect, l1)) {
copy_v2_v2(l1_clip, l1);
@@ -2600,8 +2602,8 @@ static void project_bucket_clip_face(const bool is_ortho,
return;
}
- /* get the UV space bounding box */
- /* use IsectPT2Df_limit here so we catch points are are touching the tri edge
+ /* Get the UV space bounding box. */
+ /* Use #IsectPT2Df_limit here so we catch points are touching the triangles edge
* (or a small fraction over) */
bucket_bounds_ss[0][0] = bucket_bounds->xmax;
bucket_bounds_ss[0][1] = bucket_bounds->ymin;
@@ -2676,7 +2678,7 @@ static void project_bucket_clip_face(const bool is_ortho,
/* calc center */
float cent[2] = {0.0f, 0.0f};
- /*float up[2] = {0.0f, 1.0f};*/
+ // float up[2] = {0.0f, 1.0f};
bool doubles;
(*tot) = 0;
@@ -2969,7 +2971,7 @@ static void project_paint_face_init(const ProjPaintState *ps,
ImBuf *ibuf,
ImBuf **tmpibuf)
{
- /* Projection vars, to get the 3D locations into screen space */
+ /* Projection vars, to get the 3D locations into screen space. */
MemArena *arena = ps->arena_mt[thread_index];
LinkNode **bucketPixelNodes = ps->bucketRect + bucket_index;
LinkNode *bucketFaceNodes = ps->bucketFaces[bucket_index];
@@ -3011,7 +3013,7 @@ static void project_paint_face_init(const ProjPaintState *ps,
rcti bounds_px;
/* Variables for getting UV-space bounds. */
- /* bucket bounds in UV space so we can init pixels only for this face, */
+ /* Bucket bounds in UV space so we can init pixels only for this face. */
float lt_uv_pxoffset[3][2];
float xhalfpx, yhalfpx;
const float ibuf_xf = (float)ibuf->x, ibuf_yf = (float)ibuf->y;
@@ -3063,7 +3065,7 @@ static void project_paint_face_init(const ProjPaintState *ps,
v2coSS = ps->screenCoords[lt_vtri[1]];
v3coSS = ps->screenCoords[lt_vtri[2]];
- /* This function gives is a concave polyline in UV space from the clipped tri*/
+ /* This function gives is a concave polyline in UV space from the clipped tri. */
project_bucket_clip_face(is_ortho,
is_flip_object,
clip_rect,
@@ -3152,13 +3154,13 @@ static void project_paint_face_init(const ProjPaintState *ps,
}
//#if 0
else if (has_x_isect) {
- /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
+ /* assuming the face is not a bow-tie - we know we can't intersect again on the X */
break;
}
//#endif
}
-#if 0 /* TODO - investigate why this doesn't work sometimes! it should! */
+#if 0 /* TODO: investigate why this doesn't work sometimes! it should! */
/* no intersection for this entire row,
* after some intersection above means we can quit now */
if (has_x_isect == 0 && has_isect) {
@@ -3239,7 +3241,7 @@ static void project_paint_face_init(const ProjPaintState *ps,
uv_image_outset(ps, lt_uv_pxoffset, lt_puv, tri_index, ibuf->x, ibuf->y);
}
- /* ps->loopSeamUVs cant be modified when threading, now this is done we can unlock. */
+ /* ps->loopSeamUVs can't be modified when threading, now this is done we can unlock. */
if (threaded) {
/* Other threads could be modifying these vars */
BLI_thread_unlock(LOCK_CUSTOM1);
@@ -3292,7 +3294,7 @@ static void project_paint_face_init(const ProjPaintState *ps,
interp_v2_v2v2(seam_subsection[3], seam_uvs[0], seam_uvs[1], fac1);
/* if the bucket_clip_edges values Z values was kept we could avoid this
- * Inset needs to be added so occlusion tests wont hit adjacent faces */
+ * Inset needs to be added so occlusion tests won't hit adjacent faces */
interp_v3_v3v3(edge_verts_inset_clip[0], insetCos[fidx1], insetCos[fidx2], fac1);
interp_v3_v3v3(edge_verts_inset_clip[1], insetCos[fidx1], insetCos[fidx2], fac2);
@@ -3399,7 +3401,7 @@ static void project_paint_face_init(const ProjPaintState *ps,
}
}
-# if 0 /* TODO - investigate why this doesn't work sometimes! it should! */
+# if 0 /* TODO: investigate why this doesn't work sometimes! it should! */
/* no intersection for this entire row,
* after some intersection above means we can quit now */
if (has_x_isect == 0 && has_isect) {
@@ -3430,8 +3432,8 @@ static void project_paint_bucket_bounds(const ProjPaintState *ps,
{
/* divide by bucketWidth & bucketHeight so the bounds are offset in bucket grid units */
- /* XXX: the offset of 0.5 is always truncated to zero and the offset of 1.5f
- * is always truncated to 1, is this really correct?? - jwilkins */
+ /* XXX(jwilkins ): the offset of 0.5 is always truncated to zero and the offset of 1.5f
+ * is always truncated to 1, is this really correct? */
/* these offsets of 0.5 and 1.5 seem odd but they are correct */
bucketMin[0] =
@@ -3551,18 +3553,18 @@ static void project_bucket_init(const ProjPaintState *ps,
ps->bucketFlags[bucket_index] |= PROJ_BUCKET_INIT;
}
-/* We want to know if a bucket and a face overlap in screen-space
+/* We want to know if a bucket and a face overlap in screen-space.
*
- * Note, if this ever returns false positives its not that bad, since a face in the bounding area
+ * NOTE: if this ever returns false positives its not that bad, since a face in the bounding area
* will have its pixels calculated when it might not be needed later, (at the moment at least)
- * obviously it shouldn't have bugs though */
+ * obviously it shouldn't have bugs though. */
static bool project_bucket_face_isect(ProjPaintState *ps,
int bucket_x,
int bucket_y,
const MLoopTri *lt)
{
- /* TODO - replace this with a trickier method that uses side-of-line for all
+ /* TODO: replace this with a trickier method that uses side-of-line for all
* #ProjPaintState.screenCoords edges against the closest bucket corner. */
const int lt_vtri[3] = {PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt)};
rctf bucket_bounds;
@@ -3609,7 +3611,7 @@ static bool project_bucket_face_isect(ProjPaintState *ps,
}
/* Add faces to the bucket but don't initialize its pixels
- * TODO - when painting occluded, sort the faces on their min-Z
+ * TODO: when painting occluded, sort the faces on their min-Z
* and only add faces that faces that are not occluded */
static void project_paint_delayed_face_init(ProjPaintState *ps,
const MLoopTri *lt,
@@ -3648,7 +3650,7 @@ static void project_paint_delayed_face_init(ProjPaintState *ps,
has_x_isect = has_isect = 1;
}
else if (has_x_isect) {
- /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
+ /* assuming the face is not a bow-tie - we know we can't intersect again on the X */
break;
}
}
@@ -3822,7 +3824,7 @@ static void proj_paint_state_screen_coords_init(ProjPaintState *ps, const int di
minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo);
}
else {
- /* TODO - deal with cases where 1 side of a face goes behind the view ?
+ /* TODO: deal with cases where 1 side of a face goes behind the view ?
*
* After some research this is actually very tricky, only option is to
* clip the derived mesh before painting, which is a Pain */
@@ -4356,7 +4358,7 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
#endif // PROJ_DEBUG_WINCLIP
- /* backface culls individual triangles but mask normal will use polygon */
+ /* Back-face culls individual triangles but mask normal will use polygon. */
if (ps->do_backfacecull) {
if (ps->do_mask_normal) {
if (prev_poly != lt->poly) {
@@ -4428,7 +4430,7 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
}
}
- /* build an array of images we use*/
+ /* Build an array of images we use. */
if (ps->is_shared_user == false) {
project_paint_build_proj_ima(ps, arena, &used_images);
}
@@ -4516,8 +4518,8 @@ static void project_paint_begin(const bContext *C,
reset_threads = true;
}
- /* really high values could cause problems since it has to allocate a few
- * (ps->buckets_x*ps->buckets_y) sized arrays */
+ /* Really high values could cause problems since it has to allocate a few
+ * `(ps->buckets_x * ps->buckets_y)` sized arrays. */
CLAMP(ps->buckets_x, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
CLAMP(ps->buckets_y, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
@@ -4694,7 +4696,7 @@ static bool project_image_refresh_tagged(ProjPaintState *ps)
/* look over each bound cell */
for (i = 0; i < PROJ_BOUNDBOX_SQUARED; i++) {
pr = &(projIma->partRedrawRect[i]);
- if (pr->x2 != -1) { /* TODO - use 'enabled' ? */
+ if (pr->x2 != -1) { /* TODO: use 'enabled' ? */
set_imapaintpartial(pr);
imapaint_image_update(NULL, projIma->ima, projIma->ibuf, &projIma->iuser, true);
redraw = 1;
@@ -4768,7 +4770,7 @@ static bool project_bucket_iter_next(ProjPaintState *ps,
BLI_assert(bucket_y >= ps->bucketMin[1] && bucket_y < ps->bucketMax[1]);
if (bucket_x >= ps->bucketMin[0] && bucket_x < ps->bucketMax[0]) {
- /* use bucket_bounds for project_bucket_isect_circle and project_bucket_init*/
+ /* Use bucket_bounds for #project_bucket_isect_circle and #project_bucket_init. */
project_bucket_bounds(ps, bucket_x, bucket_y, bucket_bounds);
if ((ps->source != PROJ_SRC_VIEW) ||
@@ -5354,7 +5356,7 @@ static void do_projectpaint_thread(TaskPool *__restrict UNUSED(pool), void *ph_v
dist_sq = len_squared_v2v2(projPixel->projCoSS, pos);
- /*if (dist < radius) {*/ /* correct but uses a sqrtf */
+ /* Faster alternative to `dist < radius` without a #sqrtf. */
if (dist_sq <= brush_radius_sq) {
dist = sqrtf(dist_sq);
@@ -5364,7 +5366,7 @@ static void do_projectpaint_thread(TaskPool *__restrict UNUSED(pool), void *ph_v
float texrgb[3];
float mask;
- /* Extra mask for normal, layer stencil, .. */
+ /* Extra mask for normal, layer stencil, etc. */
float custom_mask = ((float)projPixel->mask) * (1.0f / 65535.0f);
/* Mask texture. */
@@ -5391,7 +5393,7 @@ static void do_projectpaint_thread(TaskPool *__restrict UNUSED(pool), void *ph_v
samplecos[2] = 0.0f;
}
- /* note, for clone and smear,
+ /* NOTE: for clone and smear,
* we only use the alpha, could be a special function */
BKE_brush_sample_tex_3d(ps->scene, brush, samplecos, texrgba, thread_index, pool);
@@ -5447,7 +5449,7 @@ static void do_projectpaint_thread(TaskPool *__restrict UNUSED(pool), void *ph_v
}
/* end copy */
- /* validate undo tile, since we will modify t*/
+ /* Validate undo tile, since we will modify it. */
*projPixel->valid = true;
last_partial_redraw_cell = last_projIma->partRedrawRect + projPixel->bb_cell_index;
@@ -5514,7 +5516,7 @@ static void do_projectpaint_thread(TaskPool *__restrict UNUSED(pool), void *ph_v
if (tool == PAINT_TOOL_SMEAR) {
- for (node = smearPixels; node; node = node->next) { /* this wont run for a float image */
+ for (node = smearPixels; node; node = node->next) { /* this won't run for a float image */
projPixel = node->link;
*projPixel->pixel.uint_pt = ((ProjPixelClone *)projPixel)->clonepx.uint;
if (lock_alpha) {
@@ -5534,7 +5536,7 @@ static void do_projectpaint_thread(TaskPool *__restrict UNUSED(pool), void *ph_v
}
else if (tool == PAINT_TOOL_SOFTEN) {
- for (node = softenPixels; node; node = node->next) { /* this wont run for a float image */
+ for (node = softenPixels; node; node = node->next) { /* this won't run for a float image */
projPixel = node->link;
*projPixel->pixel.uint_pt = projPixel->newColor.uint;
if (lock_alpha) {
@@ -5812,7 +5814,7 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int
ps->is_maskbrush = (brush->mask_mtex.tex) ? true : false;
}
else {
- /* brush may be NULL*/
+ /* Brush may be NULL. */
ps->do_masking = false;
ps->is_texbrush = false;
ps->is_maskbrush = false;
@@ -6468,6 +6470,8 @@ static Image *proj_paint_image_create(wmOperator *op, Main *bmain, bool is_data)
alpha = RNA_boolean_get(op->ptr, "alpha");
RNA_string_get(op->ptr, "name", imagename);
}
+
+ /* TODO(lukas): Add option for tiled image. */
ima = BKE_image_add_generated(bmain,
width,
height,
@@ -6478,7 +6482,7 @@ static Image *proj_paint_image_create(wmOperator *op, Main *bmain, bool is_data)
color,
false,
is_data,
- false); /* TODO(lukas): Add option */
+ false);
return ima;
}
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 3f5093222e9..7341d984c91 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -304,7 +304,7 @@ bool paint_curve_poll(struct bContext *C);
bool facemask_paint_poll(struct bContext *C);
void flip_v3_v3(float out[3], const float in[3], const enum ePaintSymmetryFlags symm);
-void flip_qt_qt(float out[3], const float in[3], const enum ePaintSymmetryFlags symm);
+void flip_qt_qt(float out[4], const float in[4], const enum ePaintSymmetryFlags symm);
/* stroke operator */
typedef enum BrushStrokeMode {
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index b6ae6f8bee7..d968b6cc319 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -293,8 +293,8 @@ typedef struct SculptGestureContext {
/* These store the view origin and normal in world space, which is used in some gestures to
* generate geometry aligned from the view directly in world space. */
/* World space view origin and normal are not affected by object symmetry when doing symmetry
- * passes, so there is no separate variables with the true_ prefix to store their original values
- * without symmetry modifications. */
+ * passes, so there is no separate variables with the `true_` prefix to store their original
+ * values without symmetry modifications. */
float world_space_view_origin[3];
float world_space_view_normal[3];
@@ -1239,10 +1239,9 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext)
}));
const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
- int tottri;
BMLoop *(*looptris)[3];
looptris = MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__);
- BM_mesh_calc_tessellation_beauty(bm, looptris, &tottri);
+ BM_mesh_calc_tessellation_beauty(bm, looptris);
BMIter iter;
int i;
@@ -1290,7 +1289,7 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext)
break;
}
BM_mesh_boolean(
- bm, looptris, tottri, bm_face_isect_pair, NULL, 2, true, true, false, boolean_mode);
+ bm, looptris, looptris_tot, bm_face_isect_pair, NULL, 2, true, true, false, boolean_mode);
}
MEM_freeN(looptris);
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index fed89e02e8f..f08771292a8 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -62,7 +62,7 @@
/* Brush operators */
static int brush_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- /*int type = RNA_enum_get(op->ptr, "type");*/
+ // int type = RNA_enum_get(op->ptr, "type");
Paint *paint = BKE_paint_get_active_from_context(C);
Brush *br = BKE_paint_brush(paint);
Main *bmain = CTX_data_main(C);
@@ -97,7 +97,7 @@ static void BRUSH_OT_add(wmOperatorType *ot)
static int brush_add_gpencil_exec(bContext *C, wmOperator *UNUSED(op))
{
- /*int type = RNA_enum_get(op->ptr, "type");*/
+ // int type = RNA_enum_get(op->ptr, "type");
ToolSettings *ts = CTX_data_tool_settings(C);
Paint *paint = &ts->gp_paint->paint;
Brush *br = BKE_paint_brush(paint);
@@ -1307,7 +1307,7 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(BRUSH_OT_stencil_fit_image_aspect);
WM_operatortype_append(BRUSH_OT_stencil_reset_transform);
- /* note, particle uses a different system, can be added with existing operators in wm.py */
+ /* NOTE: particle uses a different system, can be added with existing operators in `wm.py`. */
WM_operatortype_append(PAINT_OT_brush_select);
/* image */
@@ -1385,7 +1385,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
keymap = WM_keymap_ensure(keyconf, "Weight Paint", 0, 0);
keymap->poll = weight_paint_mode_poll;
- /*Weight paint's Vertex Selection Mode */
+ /* Weight paint's Vertex Selection Mode. */
keymap = WM_keymap_ensure(keyconf, "Paint Vertex Selection (Weight, Vertex)", 0, 0);
keymap->poll = vert_paint_poll;
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index b093f07226e..de01bc3a474 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -541,7 +541,7 @@ static void paint_brush_stroke_add_step(bContext *C,
* It's strange that only texpaint had these guards. */
#if 0
/* special exception here for too high pressure values on first touch in
- * windows for some tablets, then we just skip first touch .. */
+ * windows for some tablets, then we just skip first touch. */
if (tablet && (pressure >= 0.99f) &&
((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) ||
BKE_brush_use_alpha_pressure(pop->s.brush) ||
@@ -846,7 +846,7 @@ static int paint_space_stroke(bContext *C,
while (length > 0.0f) {
float spacing = paint_space_stroke_spacing_variable(
C, scene, stroke, pressure, dpressure, length);
- float mouse[3];
+ float mouse[2];
if (length >= spacing) {
if (use_scene_spacing) {
@@ -856,7 +856,7 @@ static int paint_space_stroke(bContext *C,
add_v3_v3v3(final_world_space_position,
stroke->last_world_space_position,
final_world_space_position);
- ED_view3d_project(region, final_world_space_position, mouse);
+ ED_view3d_project_v2(region, final_world_space_position, mouse);
}
else {
mouse[0] = stroke->last_mouse_position[0] + dmouse[0] * spacing;
@@ -1115,7 +1115,7 @@ bool paint_supports_dynamic_tex_coords(Brush *br, ePaintMode mode)
#define PAINT_STROKE_MODAL_CANCEL 1
-/* called in paint_ops.c, on each regeneration of keymaps */
+/* Called in paint_ops.c, on each regeneration of key-maps. */
struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf)
{
static struct EnumPropertyItem modal_items[] = {
@@ -1240,7 +1240,7 @@ static void paint_line_strokes_spacing(bContext *C,
mul_v3_v3fl(final_world_space_position, d_world_space_position, spacing_final);
add_v3_v3v3(
final_world_space_position, world_space_position_old, final_world_space_position);
- ED_view3d_project(region, final_world_space_position, mouse);
+ ED_view3d_project_v2(region, final_world_space_position, mouse);
}
else {
mouse[0] = stroke->last_mouse_position[0] + dmouse[0] * spacing_final;
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 2484f382ed4..709e04d807d 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -752,7 +752,7 @@ static int vert_select_ungrouped_exec(bContext *C, wmOperator *op)
Object *ob = CTX_data_active_object(C);
Mesh *me = ob->data;
- if (BLI_listbase_is_empty(&ob->defbase) || (me->dvert == NULL)) {
+ if (BLI_listbase_is_empty(&me->vertex_group_names) || (me->dvert == NULL)) {
BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index daccc6f228a..9387b84f437 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -179,7 +179,7 @@ static MDeformVert *defweight_prev_init(MDeformVert *dvert_prev,
* (without evaluating modifiers) */
static bool vertex_paint_use_fast_update_check(Object *ob)
{
- Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
+ const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
if (me_eval != NULL) {
Mesh *me = BKE_mesh_from_object(ob);
@@ -725,7 +725,7 @@ typedef struct WeightPaintInfo {
* length of defbase_tot */
const bool *lock_flags;
/* boolean array for selected bones,
- * length of defbase_tot, cant be const because of how its passed */
+ * length of defbase_tot, can't be const because of how it's passed */
const bool *defbase_sel;
/* same as WeightPaintData.vgroup_validmap,
* only added here for convenience */
@@ -917,7 +917,7 @@ static void do_weight_paint_vertex_single(
* 'resist' so you couldn't instantly zero out other weights by painting 1.0 on the active.
*
* However this gave a problem since applying mirror, then normalize both verts
- * the resulting weight wont match on both sides.
+ * the resulting weight won't match on both sides.
*
* If this 'resisting', slower normalize is nicer, we could call
* do_weight_paint_normalize_all() and only use...
@@ -941,13 +941,13 @@ static void do_weight_paint_vertex_single(
* - Auto normalize is enabled.
* - The group you are painting onto has a L / R version.
*
- * We want L/R vgroups to have the same weight but this cant be if both are over 0.5,
+ * We want L/R vgroups to have the same weight but this can't be if both are over 0.5,
* We _could_ have special check for that, but this would need its own
* normalize function which holds 2 groups from changing at once.
*
* So! just balance out the 2 weights, it keeps them equal and everything normalized.
*
- * While it wont hit the desired weight immediately as the user waggles their mouse,
+ * While it won't hit the desired weight immediately as the user waggles their mouse,
* constant painting and re-normalizing will get there. this is also just simpler logic.
* - campbell */
dw_mirr->weight = dw->weight = (dw_mirr->weight + dw->weight) * 0.5f;
@@ -996,7 +996,7 @@ static void do_weight_paint_vertex_multi(
dv, wpi->defbase_tot, wpi->defbase_sel, wpi->defbase_tot_sel, wpi->is_normalized);
if (curw == 0.0f) {
- /* note: no weight to assign to this vertex, could add all groups? */
+ /* NOTE: no weight to assign to this vertex, could add all groups? */
return;
}
@@ -1607,13 +1607,13 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
/* check if we are attempting to paint onto a locked vertex group,
* and other options disallow it from doing anything useful */
bDeformGroup *dg;
- dg = BLI_findlink(&ob->defbase, vgroup_index.active);
+ dg = BLI_findlink(&me->vertex_group_names, vgroup_index.active);
if (dg->flag & DG_LOCK_WEIGHT) {
BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting");
return false;
}
if (vgroup_index.mirror != -1) {
- dg = BLI_findlink(&ob->defbase, vgroup_index.mirror);
+ dg = BLI_findlink(&me->vertex_group_names, vgroup_index.mirror);
if (dg->flag & DG_LOCK_WEIGHT) {
BKE_report(op->reports, RPT_WARNING, "Mirror group is locked, aborting");
return false;
@@ -1622,7 +1622,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
}
/* check that multipaint groups are unlocked */
- defbase_tot = BLI_listbase_count(&ob->defbase);
+ defbase_tot = BLI_listbase_count(&me->vertex_group_names);
defbase_sel = BKE_object_defgroup_selected_get(ob, defbase_tot, &defbase_tot_sel);
if (ts->multipaint && defbase_tot_sel > 1) {
@@ -1636,7 +1636,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
for (i = 0; i < defbase_tot; i++) {
if (defbase_sel[i]) {
- dg = BLI_findlink(&ob->defbase, i);
+ dg = BLI_findlink(&me->vertex_group_names, i);
if (dg->flag & DG_LOCK_WEIGHT) {
BKE_report(op->reports, RPT_WARNING, "Multipaint group is locked, aborting");
MEM_freeN(defbase_sel);
@@ -2025,7 +2025,7 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata,
const Brush *brush = data->brush;
const StrokeCache *cache = ss->cache;
- /* note: normally `BKE_brush_weight_get(scene, brush)` is used,
+ /* NOTE: normally `BKE_brush_weight_get(scene, brush)` is used,
* however in this case we calculate a new weight each time. */
const float paintweight = data->strength;
float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
@@ -2046,7 +2046,7 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
/* Test to see if the vertex coordinates are within the spherical brush region. */
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- /* Note: grids are 1:1 with corners (aka loops).
+ /* NOTE: grids are 1:1 with corners (aka loops).
* For multires, take the vert whose loop corresponds to the current grid.
* Otherwise, take the current vert. */
const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v :
@@ -2498,7 +2498,7 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
for (i = 0; i < PSYS_TOT_VG; i++) {
- if (psys->vgroup[i] == ob->actdef) {
+ if (psys->vgroup[i] == BKE_object_defgroup_active_index_get(ob)) {
psys->recalc |= ID_RECALC_PSYS_RESET;
break;
}
@@ -2750,11 +2750,11 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
* if not we can skip face map trickiness */
if (vertex_paint_use_fast_update_check(ob)) {
vpd->use_fast_update = true;
- /* printf("Fast update!\n");*/
+ // printf("Fast update!\n");
}
else {
vpd->use_fast_update = false;
- /* printf("No fast update!\n");*/
+ // printf("No fast update!\n");
}
/* to keep tracked of modified loops for shared vertex color blending */
@@ -2885,7 +2885,7 @@ static void do_vpaint_brush_draw_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
/* Test to see if the vertex coordinates are within the spherical brush region. */
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- /* Note: Grids are 1:1 with corners (aka loops).
+ /* NOTE: Grids are 1:1 with corners (aka loops).
* For grid based pbvh, take the vert whose loop corresponds to the current grid.
* Otherwise, take the current vert. */
const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v :
@@ -2912,7 +2912,7 @@ static void do_vpaint_brush_draw_task_cb_ex(void *__restrict userdata,
/* If we're painting with a texture, sample the texture color and alpha. */
float tex_alpha = 1.0;
if (data->vpd->is_texbrush) {
- /* Note: we may want to paint alpha as vertex color alpha. */
+ /* NOTE: we may want to paint alpha as vertex color alpha. */
tex_alpha = tex_color_alpha_ubyte(
data, data->vpd->vertexcosnos[v_index].co, &color_final);
}
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c
index 96d22fe4a21..9f023dd6e63 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c
@@ -149,7 +149,7 @@ static bool vertex_paint_from_weight(Object *ob)
/* TODO: respect selection. */
/* TODO: Do we want to take weights from evaluated mesh instead? 2.7x was not doing it anyway. */
mp = me->mpoly;
- vgroup_active = ob->actdef - 1;
+ vgroup_active = me->vertex_group_active_index - 1;
for (int i = 0; i < me->totpoly; i++, mp++) {
MLoopCol *lcol = &me->mloopcol[mp->loopstart];
uint j = 0;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
index 0fafd3589fe..cb8dc838422 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
@@ -183,7 +183,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even
ED_view3d_viewcontext_init(C, &vc, depsgraph);
me = BKE_mesh_from_object(vc.obact);
- if (me && me->dvert && vc.v3d && vc.rv3d && (vc.obact->actdef != 0)) {
+ if (me && me->dvert && vc.v3d && vc.rv3d && (me->vertex_group_active_index != 0)) {
const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
int v_idx_best = -1;
uint index;
@@ -213,9 +213,9 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even
if (v_idx_best != -1) { /* should always be valid */
ToolSettings *ts = vc.scene->toolsettings;
Brush *brush = BKE_paint_brush(&ts->wpaint->paint);
- const int vgroup_active = vc.obact->actdef - 1;
+ const int vgroup_active = me->vertex_group_active_index - 1;
float vgroup_weight = BKE_defvert_find_weight(&me->dvert[v_idx_best], vgroup_active);
- const int defbase_tot = BLI_listbase_count(&vc.obact->defbase);
+ const int defbase_tot = BLI_listbase_count(&me->vertex_group_names);
bool use_lock_relative = ts->wpaint_lock_relative;
bool *defbase_locked = NULL, *defbase_unlocked = NULL;
@@ -331,8 +331,8 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C,
ED_view3d_viewcontext_init(C, &vc, depsgraph);
me = BKE_mesh_from_object(vc.obact);
- if (me && me->dvert && vc.v3d && vc.rv3d && vc.obact->defbase.first) {
- const int defbase_tot = BLI_listbase_count(&vc.obact->defbase);
+ if (me && me->dvert && vc.v3d && vc.rv3d && me->vertex_group_names.first) {
+ const int defbase_tot = BLI_listbase_count(&me->vertex_group_names);
const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
int *groups = MEM_callocN(defbase_tot * sizeof(int), "groups");
bool found = false;
@@ -372,7 +372,7 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C,
int totitem = 0;
int i = 0;
bDeformGroup *dg;
- for (dg = vc.obact->defbase.first; dg && i < defbase_tot; i++, dg = dg->next) {
+ for (dg = me->vertex_group_names.first; dg && i < defbase_tot; i++, dg = dg->next) {
if (groups[i]) {
item_tmp.identifier = item_tmp.name = dg->name;
item_tmp.value = i;
@@ -401,14 +401,14 @@ static int weight_sample_group_exec(bContext *C, wmOperator *op)
ED_view3d_viewcontext_init(C, &vc, depsgraph);
BLI_assert(type + 1 >= 0);
- vc.obact->actdef = type + 1;
+ BKE_object_defgroup_active_index_set(vc.obact, type + 1);
DEG_id_tag_update(&vc.obact->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, vc.obact);
return OPERATOR_FINISHED;
}
-/* TODO, we could make this a menu into OBJECT_OT_vertex_group_set_active
+/* TODO: we could make this a menu into OBJECT_OT_vertex_group_set_active
* rather than its own operator */
void PAINT_OT_weight_sample_group(wmOperatorType *ot)
{
@@ -458,7 +458,7 @@ static bool weight_paint_set(Object *ob, float paintweight)
return false;
}
- vgroup_active = ob->actdef - 1;
+ vgroup_active = BKE_object_defgroup_active_index_get(ob) - 1;
/* if mirror painting, find the other group */
if (ME_USING_MIRROR_X_VERTEX_GROUPS(me)) {
@@ -540,7 +540,7 @@ static int weight_paint_set_exec(bContext *C, wmOperator *op)
}
if (weight_paint_set(obact, vgroup_weight)) {
- ED_region_tag_redraw(CTX_wm_region(C)); /* XXX - should redraw all 3D views */
+ ED_region_tag_redraw(CTX_wm_region(C)); /* XXX: should redraw all 3D views. */
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
@@ -791,7 +791,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
wpaint_prev_create(
&((WPGradient_vertStoreBase *)gesture->user_data.data)->wpp, me->dvert, me->totvert);
- /* on init only, convert face -> vert sel */
+ /* On initialization only, convert face -> vert sel. */
if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
BKE_mesh_flush_select_from_polys(me);
}
@@ -815,7 +815,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
data.sco_start = sco_start;
data.sco_end = sco_end;
data.sco_line_div = 1.0f / len_v2v2(sco_start, sco_end);
- data.def_nr = ob->actdef - 1;
+ data.def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
data.use_select = (me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
data.vert_cache = vert_cache;
data.vert_visit = NULL;
@@ -863,7 +863,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
}
if (scene->toolsettings->auto_normalize) {
- const int vgroup_num = BLI_listbase_count(&ob->defbase);
+ const int vgroup_num = BLI_listbase_count(&me->vertex_group_names);
bool *vgroup_validmap = BKE_object_defgroup_validmap_get(ob, vgroup_num);
if (vgroup_validmap != NULL) {
MDeformVert *dvert = me->dvert;
@@ -891,7 +891,7 @@ static int paint_weight_gradient_invoke(bContext *C, wmOperator *op, const wmEve
if (ret & OPERATOR_RUNNING_MODAL) {
struct ARegion *region = CTX_wm_region(C);
if (region->regiontype == RGN_TYPE_WINDOW) {
- /* TODO, hardcoded, extend WM_gesture_straightline_ */
+ /* TODO: hard-coded, extend `WM_gesture_straightline_*`. */
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
wmGesture *gesture = op->customdata;
gesture->is_active = true;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
index d6a118bbd59..19ffa0c952d 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
@@ -79,8 +79,10 @@ bool ED_wpaint_ensure_data(bContext *C,
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
}
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+
/* this happens on a Bone select, when no vgroup existed yet */
- if (ob->actdef <= 0) {
+ if (me->vertex_group_active_index <= 0) {
Object *modob;
if ((modob = BKE_modifiers_is_deformed_by_armature(ob))) {
Bone *actbone = ((bArmature *)modob->data)->act_bone;
@@ -94,32 +96,33 @@ bool ED_wpaint_ensure_data(bContext *C,
DEG_relations_tag_update(CTX_data_main(C));
}
else {
- int actdef = 1 + BLI_findindex(&ob->defbase, dg);
+
+ int actdef = 1 + BLI_findindex(defbase, dg);
BLI_assert(actdef >= 0);
- ob->actdef = actdef;
+ me->vertex_group_active_index = actdef;
}
}
}
}
}
- if (BLI_listbase_is_empty(&ob->defbase)) {
+ if (BLI_listbase_is_empty(defbase)) {
BKE_object_defgroup_add(ob);
DEG_relations_tag_update(CTX_data_main(C));
}
/* ensure we don't try paint onto an invalid group */
- if (ob->actdef <= 0) {
+ if (me->vertex_group_active_index <= 0) {
BKE_report(reports, RPT_WARNING, "No active vertex group for painting, aborting");
return false;
}
if (vgroup_index) {
- vgroup_index->active = ob->actdef - 1;
+ vgroup_index->active = me->vertex_group_active_index - 1;
}
if (flag & WPAINT_ENSURE_MIRROR) {
if (ME_USING_MIRROR_X_VERTEX_GROUPS(me)) {
- int mirror = ED_wpaint_mirror_vgroup_ensure(ob, ob->actdef - 1);
+ int mirror = ED_wpaint_mirror_vgroup_ensure(ob, me->vertex_group_active_index - 1);
if (vgroup_index) {
vgroup_index->mirror = mirror;
}
@@ -133,7 +136,8 @@ bool ED_wpaint_ensure_data(bContext *C,
/* mirror_vgroup is set to -1 when invalid */
int ED_wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active)
{
- bDeformGroup *defgroup = BLI_findlink(&ob->defbase, vgroup_active);
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ bDeformGroup *defgroup = BLI_findlink(defbase, vgroup_active);
if (defgroup) {
int mirrdef;
@@ -143,7 +147,7 @@ int ED_wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active)
mirrdef = BKE_object_defgroup_name_index(ob, name_flip);
if (mirrdef == -1) {
if (BKE_object_defgroup_new(ob, name_flip)) {
- mirrdef = BLI_listbase_count(&ob->defbase) - 1;
+ mirrdef = BLI_listbase_count(defbase) - 1;
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 2e1dd928f96..83388c1aef2 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1146,10 +1146,9 @@ void SCULPT_floodfill_add_active(
v = SCULPT_active_vertex_get(ss);
}
else if (radius > 0.0f) {
- float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
float location[3];
flip_v3_v3(location, SCULPT_active_vertex_co_get(ss), i);
- v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
+ v = SCULPT_nearest_vertex_get(sd, ob, location, radius, false);
}
if (v != -1) {
@@ -1854,7 +1853,7 @@ static void flip_v3(float v[3], const ePaintSymmetryFlags symm)
flip_v3_v3(v, v, symm);
}
-static void flip_qt(float quat[3], const ePaintSymmetryFlags symm)
+static void flip_qt(float quat[4], const ePaintSymmetryFlags symm)
{
flip_qt_qt(quat, quat, symm);
}
@@ -2395,7 +2394,7 @@ static float brush_strength(const Sculpt *sd,
case BRUSH_MASK_SMOOTH:
return alpha * pressure * feather;
}
- BLI_assert(!"Not supposed to happen");
+ BLI_assert_msg(0, "Not supposed to happen");
return 0.0f;
case SCULPT_TOOL_CREASE:
@@ -3317,7 +3316,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
mul_v3_v3(offset, ss->cache->scale);
mul_v3_fl(offset, bstrength);
- /* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
+ /* XXX: this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
* initialize before threads so they can do curve mapping. */
BKE_curvemapping_init(brush->curve);
@@ -3396,7 +3395,7 @@ static void do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
mul_v3_v3(offset, ss->cache->scale);
mul_v3_fl(offset, bstrength);
- /* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
+ /* XXX: this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
* initialize before threads so they can do curve mapping. */
BKE_curvemapping_init(brush->curve);
@@ -4196,7 +4195,7 @@ void SCULPT_flip_v3_by_symm_area(float v[3],
}
}
-void SCULPT_flip_quat_by_symm_area(float quat[3],
+void SCULPT_flip_quat_by_symm_area(float quat[4],
const ePaintSymmetryFlags symm,
const ePaintSymmetryAreas symmarea,
const float pivot[3])
@@ -5792,7 +5791,7 @@ void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float (*vertCos)[3])
BKE_keyblock_update_from_vertcos(ob, kb, vertCos);
}
-/* Note: we do the topology update before any brush actions to avoid
+/* NOTE: we do the topology update before any brush actions to avoid
* issues with the proxies. The size of the proxy can't change, so
* topology must be updated first. */
static void sculpt_topology_update(Sculpt *sd,
@@ -6363,7 +6362,7 @@ void SCULPT_flush_stroke_deform(Sculpt *sd, Object *ob, bool is_proxy_used)
MEM_SAFE_FREE(nodes);
/* Modifiers could depend on mesh normals, so we should update them.
- * Note, then if sculpting happens on locked key, normals should be re-calculate after applying
+ * NOTE: then if sculpting happens on locked key, normals should be re-calculate after applying
* coords from key-block on base mesh. */
BKE_mesh_calc_normals(me);
}
@@ -7875,7 +7874,7 @@ static bool over_mesh(bContext *C, struct wmOperator *UNUSED(op), float x, float
static bool sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const float mouse[2])
{
/* Don't start the stroke until mouse goes over the mesh.
- * note: mouse will only be null when re-executing the saved stroke.
+ * NOTE: mouse will only be null when re-executing the saved stroke.
* We have exception for 'exec' strokes since they may not set 'mouse',
* only 'location', see: T52195. */
if (((op->flag & OP_IS_INVOKE) == 0) || (mouse == NULL) ||
diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.c b/source/blender/editors/sculpt_paint/sculpt_automasking.c
index 5f5fb51d75f..35f48400fe2 100644
--- a/source/blender/editors/sculpt_paint/sculpt_automasking.c
+++ b/source/blender/editors/sculpt_paint/sculpt_automasking.c
@@ -209,7 +209,7 @@ static float *SCULPT_topology_automasking_init(Sculpt *sd, Object *ob, float *au
Brush *brush = BKE_paint_brush(&sd->paint);
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) {
- BLI_assert(!"Topology masking: pmap missing");
+ BLI_assert_msg(0, "Topology masking: pmap missing");
return NULL;
}
@@ -248,7 +248,7 @@ static float *sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob, float *a
}
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) {
- BLI_assert(!"Face Sets automasking: pmap missing");
+ BLI_assert_msg(0, "Face Sets automasking: pmap missing");
return NULL;
}
@@ -273,7 +273,7 @@ float *SCULPT_boundary_automasking_init(Object *ob,
SculptSession *ss = ob->sculpt;
if (!ss->pmap) {
- BLI_assert(!"Boundary Edges masking: pmap missing");
+ BLI_assert_msg(0, "Boundary Edges masking: pmap missing");
return NULL;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 087cb6dd94a..696c3332a2b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -278,7 +278,7 @@ void SCULPT_flip_v3_by_symm_area(float v[3],
const ePaintSymmetryFlags symm,
const ePaintSymmetryAreas symmarea,
const float pivot[3]);
-void SCULPT_flip_quat_by_symm_area(float quat[3],
+void SCULPT_flip_quat_by_symm_area(float quat[4],
const ePaintSymmetryFlags symm,
const ePaintSymmetryAreas symmarea,
const float pivot[3]);
@@ -623,7 +623,7 @@ typedef struct SculptUndoNode {
SculptUndoType type;
- char idname[MAX_ID_NAME]; /* name instead of pointer*/
+ char idname[MAX_ID_NAME]; /* Name instead of pointer. */
void *node; /* only during push, not valid afterwards! */
float (*co)[3];
@@ -704,7 +704,7 @@ typedef struct SculptThreadedTaskData {
/* Data specific to some callbacks. */
- /* Note: even if only one or two of those are used at a time,
+ /* NOTE: even if only one or two of those are used at a time,
* keeping them separated, names help figuring out
* what it is, and memory overhead is ridiculous anyway. */
float flippedbstrength;
@@ -977,7 +977,7 @@ typedef struct StrokeCache {
/* Symmetry index between 0 and 7 bit combo 0 is Brush only;
* 1 is X mirror; 2 is Y mirror; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
int symmetry;
- int mirror_symmetry_pass; /* the symmetry pass we are currently on between 0 and 7*/
+ int mirror_symmetry_pass; /* The symmetry pass we are currently on between 0 and 7. */
float true_view_normal[3];
float view_normal[3];
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index 61984610a5a..eabbfe43e03 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -367,7 +367,7 @@ void SCULPT_smooth(Sculpt *sd,
last = max_iterations * (bstrength - count * fract);
if (type == PBVH_FACES && !ss->pmap) {
- BLI_assert(!"sculpt smooth: pmap missing");
+ BLI_assert_msg(0, "sculpt smooth: pmap missing");
return;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index b6205db6f45..501a1e53276 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -766,7 +766,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
case SCULPT_UNDO_DYNTOPO_BEGIN:
case SCULPT_UNDO_DYNTOPO_END:
case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
- BLI_assert(!"Dynamic topology should've already been handled");
+ BLI_assert_msg(0, "Dynamic topology should've already been handled");
break;
}
}
@@ -1065,7 +1065,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt
case SCULPT_UNDO_DYNTOPO_BEGIN:
case SCULPT_UNDO_DYNTOPO_END:
case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
- BLI_assert(!"Dynamic topology should've already been handled");
+ BLI_assert_msg(0, "Dynamic topology should've already been handled");
case SCULPT_UNDO_GEOMETRY:
case SCULPT_UNDO_FACE_SETS:
break;
@@ -1189,9 +1189,7 @@ static SculptUndoNode *sculpt_undo_geometry_push(Object *object, SculptUndoType
static SculptUndoNode *sculpt_undo_face_sets_push(Object *ob, SculptUndoType type)
{
UndoSculpt *usculpt = sculpt_undo_get_nodes();
- SculptUndoNode *unode = usculpt->nodes.first;
-
- unode = MEM_callocN(sizeof(*unode), __func__);
+ SculptUndoNode *unode = MEM_callocN(sizeof(*unode), __func__);
BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname));
unode->type = type;
@@ -1357,7 +1355,7 @@ SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType
case SCULPT_UNDO_DYNTOPO_BEGIN:
case SCULPT_UNDO_DYNTOPO_END:
case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
- BLI_assert(!"Dynamic topology should've already been handled");
+ BLI_assert_msg(0, "Dynamic topology should've already been handled");
case SCULPT_UNDO_GEOMETRY:
case SCULPT_UNDO_FACE_SETS:
break;
@@ -1434,7 +1432,7 @@ void SCULPT_undo_push_end_ex(const bool use_nested_undo)
typedef struct SculptUndoStep {
UndoStep step;
- /* Note: will split out into list for multi-object-sculpt-mode. */
+ /* NOTE: will split out into list for multi-object-sculpt-mode. */
UndoSculpt data;
} SculptUndoStep;
@@ -1551,7 +1549,7 @@ static void sculpt_undosys_step_decode(
ED_object_mode_generic_exit(bmain, depsgraph, scene, ob);
/* Sculpt needs evaluated state.
- * Note: needs to be done here, as #ED_object_mode_generic_exit will usually invalidate
+ * NOTE: needs to be done here, as #ED_object_mode_generic_exit will usually invalidate
* (some) evaluated data. */
BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
@@ -1610,7 +1608,7 @@ void ED_sculpt_undosys_type(UndoType *ut)
ut->step_decode = sculpt_undosys_step_decode;
ut->step_free = sculpt_undosys_step_free;
- ut->flags = 0;
+ ut->flags = UNDOTYPE_FLAG_DECODE_ACTIVE_STEP;
ut->step_size = sizeof(SculptUndoStep);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index 219a8303674..771e0e1e47b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -92,7 +92,7 @@ typedef struct UVInitialStroke {
/* Initial Selection,for grab brushes for instance */
UVInitialStrokeElement *initialSelection;
- /* total initially selected UVs*/
+ /* Total initially selected UV's. */
int totalInitialSelected;
/* initial mouse coordinates */
@@ -101,9 +101,9 @@ typedef struct UVInitialStroke {
/* custom data for uv smoothing brush */
typedef struct UvSculptData {
- /* Contains the first of each set of coincident uvs.
+ /* Contains the first of each set of coincident UV's.
* These will be used to perform smoothing on and propagate the changes
- * to their coincident uvs */
+ * to their coincident UV's */
UvAdjacencyElement *uv;
/* ...Is what it says */
@@ -121,7 +121,7 @@ typedef struct UvSculptData {
/* timer to be used for airbrush-type brush */
wmTimer *timer;
- /* to determine quickly adjacent uvs */
+ /* to determine quickly adjacent UV's */
UvElementMap *elementMap;
/* uvsmooth Paint for fast reference */
@@ -505,7 +505,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
bool do_island_optimization = !(ts->uv_sculpt_settings & UV_SCULPT_ALL_ISLANDS);
int island_index = 0;
- /* Holds, for each UvElement in elementMap, a pointer to its unique uv.*/
+ /* Holds, for each UvElement in elementMap, a pointer to its unique UV. */
int *uniqueUv;
data->tool = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_SMOOTH) ?
UV_SCULPT_TOOL_RELAX :
@@ -550,7 +550,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
island_index = element->island;
}
- /* Count 'unique' uvs */
+ /* Count 'unique' UV's */
for (i = 0; i < data->elementMap->totalUVs; i++) {
if (data->elementMap->buf[i].separate &&
(!do_island_optimization || data->elementMap->buf[i].island == island_index)) {
@@ -603,7 +603,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
data->uv[counter].flag = 0;
data->uv[counter].uv = luv->uv;
}
- /* pointer arithmetic to the rescue, as always :)*/
+ /* Pointer arithmetic to the rescue, as always :). */
uniqueUv[element - data->elementMap->buf] = counter;
}
}
@@ -627,8 +627,8 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
offset2 = uniqueUv[itmp2];
edges[counter].flag = 0;
- /* using an order policy, sort uvs according to address space. This avoids
- * Having two different UvEdges with the same uvs on different positions */
+ /* Using an order policy, sort UV's according to address space.
+ * This avoids having two different UvEdges with the same UV's on different positions. */
if (offset1 < offset2) {
edges[counter].uv1 = offset1;
edges[counter].uv2 = offset2;
@@ -674,7 +674,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
BLI_ghash_free(edgeHash, NULL, NULL);
MEM_freeN(edges);
- /* transfer boundary edge property to uvs */
+ /* transfer boundary edge property to UV's */
if (ts->uv_sculpt_settings & UV_SCULPT_LOCK_BORDERS) {
for (i = 0; i < data->totalUvEdges; i++) {
if (!data->uvedges[i].flag) {
diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c
index efa714e315d..d69c7ab8d48 100644
--- a/source/blender/editors/space_action/action_data.c
+++ b/source/blender/editors/space_action/action_data.c
@@ -723,7 +723,7 @@ static NlaStrip *action_layer_get_nlastrip(ListBase *strips, float ctime)
return NULL;
}
-/* Switch NLA Strips/Actions */
+/* Switch NLA Strips/Actions. */
static void action_layer_switch_strip(
AnimData *adt, NlaTrack *old_track, NlaStrip *old_strip, NlaTrack *nlt, NlaStrip *strip)
{
@@ -813,7 +813,7 @@ static int action_layer_next_exec(bContext *C, wmOperator *op)
NlaTrack *act_track;
Scene *scene = CTX_data_scene(C);
- float ctime = BKE_scene_frame_get(scene);
+ float ctime = BKE_scene_ctime_get(scene);
/* Get active track */
act_track = BKE_nlatrack_find_tweaked(adt);
@@ -925,7 +925,7 @@ static int action_layer_prev_exec(bContext *C, wmOperator *op)
NlaTrack *nlt;
Scene *scene = CTX_data_scene(C);
- float ctime = BKE_scene_frame_get(scene);
+ float ctime = BKE_scene_ctime_get(scene);
/* Sanity Check */
if (adt == NULL) {
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 5036f22fd0e..ce07b9c5fad 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -83,7 +83,7 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region)
/* need to do a view-sync here, so that the keys area doesn't jump around (it must copy this) */
UI_view2d_sync(NULL, ac->area, v2d, V2D_LOCK_COPY);
- /* loop through channels, and set up drawing depending on their type */
+ /* Loop through channels, and set up drawing depending on their type. */
{ /* first pass: just the standard GL-drawing for backdrop + text */
size_t channel_index = 0;
float ymax = ACHANNEL_FIRST_TOP(ac);
@@ -263,7 +263,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region
immRectf(pos, v2d->cur.xmin, ymin, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymax);
}
else if (ac->datatype == ANIMCONT_MASK) {
- /* TODO --- this is a copy of gpencil */
+ /* TODO: this is a copy of gpencil. */
/* frames less than one get less saturated background */
uchar *color = sel ? col1 : col2;
immUniformColor4ubv(color);
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index fea62f0d9c2..6f4e295cbb2 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -163,7 +163,7 @@ void ACTION_OT_markers_make_local(wmOperatorType *ot)
/* *************************** Calculate Range ************************** */
-/* Get the min/max keyframes*/
+/* Get the min/max keyframes. */
static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const short onlySel)
{
ListBase anim_data = {NULL, NULL};
@@ -576,7 +576,7 @@ static int actkeys_copy_exec(bContext *C, wmOperator *op)
}
}
else if (ac.datatype == ANIMCONT_MASK) {
- /* FIXME... */
+ /* FIXME: support this case. */
BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for mask mode");
return OPERATOR_CANCELLED;
}
@@ -629,7 +629,7 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op)
}
}
else if (ac.datatype == ANIMCONT_MASK) {
- /* FIXME... */
+ /* FIXME: support this case. */
BKE_report(op->reports,
RPT_ERROR,
"Keyframe pasting is not available for grease pencil or mask mode");
@@ -1137,7 +1137,7 @@ void ACTION_OT_clean(wmOperatorType *ot)
/* ******************** Sample Keyframes Operator *********************** */
-/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
+/* Evaluates the curves between each selected keyframe on each frame, and keys the value. */
static void sample_action_keys(bAnimContext *ac)
{
ListBase anim_data = {NULL, NULL};
@@ -1149,7 +1149,7 @@ static void sample_action_keys(bAnimContext *ac)
ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* loop through filtered data and add keys between selected keyframes on every frame */
+ /* Loop through filtered data and add keys between selected keyframes on every frame. */
for (ale = anim_data.first; ale; ale = ale->next) {
sample_fcurve((FCurve *)ale->key_data);
@@ -1454,7 +1454,7 @@ static void sethandles_action_keys(bAnimContext *ac, short mode)
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* Loop through setting flags for handles
- * Note: we do not supply KeyframeEditData to the looper yet.
+ * NOTE: we do not supply KeyframeEditData to the looper yet.
* Currently that's not necessary here.
*/
for (ale = anim_data.first; ale; ale = ale->next) {
@@ -1537,7 +1537,7 @@ static void setkeytype_action_keys(bAnimContext *ac, short mode)
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* Loop through setting BezTriple interpolation
- * Note: we do not supply KeyframeEditData to the looper yet.
+ * NOTE: we do not supply KeyframeEditData to the looper yet.
* Currently that's not necessary here.
*/
for (ale = anim_data.first; ale; ale = ale->next) {
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 98e39520e99..0d5b197ae93 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -470,7 +470,7 @@ static void box_select_action(bAnimContext *ac, const rcti rect, short mode, sho
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* get beztriple editing/validation funcs */
+ /* Get beztriple editing/validation funcs. */
sel_data.select_cb = ANIM_editkeyframes_select(selectmode);
if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) {
@@ -708,7 +708,7 @@ static void region_select_action_keys(
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* get beztriple editing/validation funcs */
+ /* Get beztriple editing/validation funcs. */
sel_data.select_cb = ANIM_editkeyframes_select(selectmode);
sel_data.ok_cb = ANIM_editkeyframes_ok(mode);
@@ -933,8 +933,8 @@ static const EnumPropertyItem prop_column_select_types[] = {
/* ------------------- */
/* Selects all visible keyframes between the specified markers */
-/* TODO, this is almost an _exact_ duplicate of a function of the same name in graph_select.c
- * should de-duplicate - campbell */
+/* TODO(campbell): this is almost an _exact_ duplicate of a function of the same name in
+ * graph_select.c should de-duplicate. */
static void markers_selectkeys_between(bAnimContext *ac)
{
ListBase anim_data = {NULL, NULL};
@@ -1497,7 +1497,7 @@ void ACTION_OT_select_leftright(wmOperatorType *ot)
ot->idname = "ACTION_OT_select_leftright";
ot->description = "Select keyframes to the left or the right of the current frame";
- /* api callbacks */
+ /* api callbacks */
ot->invoke = actkeys_select_leftright_invoke;
ot->exec = actkeys_select_leftright_exec;
ot->poll = ED_operator_action_active;
@@ -1840,7 +1840,7 @@ static int actkeys_clickselect_exec(bContext *C, wmOperator *op)
mval[0] = RNA_int_get(op->ptr, "mouse_x");
mval[1] = RNA_int_get(op->ptr, "mouse_y");
- /* select keyframe(s) based upon mouse position*/
+ /* Select keyframe(s) based upon mouse position. */
ret_value = mouse_action_keys(
&ac, mval, selectmode, deselect_all, column, channel, wait_to_deselect_others);
@@ -1872,12 +1872,13 @@ void ACTION_OT_clickselect(wmOperatorType *ot)
/* properties */
WM_operator_properties_generic_select(ot);
+ /* Key-map: Enable with `Shift`. */
prop = RNA_def_boolean(
ot->srna,
"extend",
0,
"Extend Select",
- "Toggle keyframe selection instead of leaving newly selected keyframes only"); /* SHIFTKEY */
+ "Toggle keyframe selection instead of leaving newly selected keyframes only");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna,
@@ -1887,20 +1888,21 @@ void ACTION_OT_clickselect(wmOperatorType *ot)
"Deselect all when nothing under the cursor");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ /* Key-map: Enable with `Alt`. */
prop = RNA_def_boolean(
ot->srna,
"column",
0,
"Column Select",
- "Select all keyframes that occur on the same frame as the one under the mouse"); /* ALTKEY */
+ "Select all keyframes that occur on the same frame as the one under the mouse");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(
- ot->srna,
- "channel",
- 0,
- "Only Channel",
- "Select all the keyframes in the channel under the mouse"); /* CTRLKEY + ALTKEY */
+ /* Key-map: Enable with `Ctrl-Alt`. */
+ prop = RNA_def_boolean(ot->srna,
+ "channel",
+ 0,
+ "Only Channel",
+ "Select all the keyframes in the channel under the mouse");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index f6af2f79890..28482faf6e3 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -153,6 +153,8 @@ static SpaceLink *action_duplicate(SpaceLink *sl)
{
SpaceAction *sactionn = MEM_dupallocN(sl);
+ memset(&sactionn->runtime, 0x0, sizeof(sactionn->runtime));
+
/* clear or remove stuff from old */
return (SpaceLink *)sactionn;
@@ -528,7 +530,7 @@ static void action_listener(const wmSpaceTypeListenerParams *params)
}
break;
case NC_ANIMATION:
- /* for NLA tweakmode enter/exit, need complete refresh */
+ /* For NLA tweak-mode enter/exit, need complete refresh. */
if (wmn->data == ND_NLA_ACTCHANGE) {
saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
ED_area_tag_refresh(area);
diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt
index c71e5e49d8d..b5f6874fcfc 100644
--- a/source/blender/editors/space_buttons/CMakeLists.txt
+++ b/source/blender/editors/space_buttons/CMakeLists.txt
@@ -50,7 +50,7 @@ if(WITH_FREESTYLE)
endif()
if(WITH_EXPERIMENTAL_FEATURES)
- add_definitions(-DWITH_GEOMETRY_NODES)
+ add_definitions(-DWITH_SIMULATION_DATABLOCK)
add_definitions(-DWITH_POINT_CLOUD)
add_definitions(-DWITH_HAIR_NODES)
endif()
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 1699e704a4d..70b715e0119 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -126,7 +126,7 @@ static bool buttons_context_path_view_layer(ButsContextPath *path, wmWindow *win
return false;
}
-/* note: this function can return true without adding a world to the path
+/* NOTE: this function can return true without adding a world to the path
* so the buttons stay visible, but be sure to check the ID type if a ID_WO */
static bool buttons_context_path_world(ButsContextPath *path)
{
@@ -154,7 +154,9 @@ static bool buttons_context_path_world(ButsContextPath *path)
return false;
}
-static bool buttons_context_path_collection(ButsContextPath *path, wmWindow *window)
+static bool buttons_context_path_collection(const bContext *C,
+ ButsContextPath *path,
+ wmWindow *window)
{
PointerRNA *ptr = &path->ptr[path->len - 1];
@@ -162,10 +164,19 @@ static bool buttons_context_path_collection(ButsContextPath *path, wmWindow *win
if (RNA_struct_is_a(ptr->type, &RNA_Collection)) {
return true;
}
+
+ Scene *scene = CTX_data_scene(C);
+
/* if we have a view layer, use the view layer's active collection */
if (buttons_context_path_view_layer(path, window)) {
ViewLayer *view_layer = path->ptr[path->len - 1].data;
Collection *c = view_layer->active_collection->collection;
+
+ /* Do not show collection tab for master collection. */
+ if (c == scene->master_collection) {
+ return false;
+ }
+
if (c) {
RNA_id_pointer_create(&c->id, &path->ptr[path->len]);
path->len++;
@@ -600,7 +611,7 @@ static bool buttons_context_path(
found = buttons_context_path_world(path);
break;
case BCONTEXT_COLLECTION: /* This is for Line Art collection flags */
- found = buttons_context_path_collection(path, window);
+ found = buttons_context_path_collection(C, path, window);
break;
case BCONTEXT_TOOL:
found = true;
@@ -975,7 +986,8 @@ int /*eContextResult*/ buttons_context(const bContext *C,
if (matnr < 0) {
matnr = 0;
}
- CTX_data_pointer_set(result, &ob->id, &RNA_MaterialSlot, &ob->mat[matnr]);
+ /* Keep aligned with rna_Object_material_slots_get. */
+ CTX_data_pointer_set(result, &ob->id, &RNA_MaterialSlot, POINTER_FROM_INT(matnr + 1));
}
}
@@ -1219,7 +1231,7 @@ static void buttons_panel_context_draw(const bContext *C, Panel *panel)
continue;
}
- /* Add icon and name .*/
+ /* Add icon and name. */
int icon = RNA_struct_ui_icon(ptr->type);
char namebuf[128];
char *name = RNA_struct_name_get_alloc(ptr, namebuf, sizeof(namebuf), NULL);
@@ -1272,7 +1284,7 @@ ID *buttons_context_id_path(const bContext *C)
for (int i = path->len - 1; i >= 0; i--) {
PointerRNA *ptr = &path->ptr[i];
- /* pin particle settings instead of system, since only settings are an idblock*/
+ /* Pin particle settings instead of system, since only settings are an idblock. */
if (sbuts->mainb == BCONTEXT_PARTICLE && sbuts->flag & SB_PIN_CONTEXT) {
if (ptr->type == &RNA_ParticleSystem && ptr->data) {
ParticleSystem *psys = ptr->data;
@@ -1280,7 +1292,7 @@ ID *buttons_context_id_path(const bContext *C)
}
}
- /* There is no valid image ID panel, Image Empty objects need this workaround.*/
+ /* There is no valid image ID panel, Image Empty objects need this workaround. */
if (sbuts->mainb == BCONTEXT_DATA && sbuts->flag & SB_PIN_CONTEXT) {
if (ptr->type == &RNA_Image && ptr->data) {
continue;
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 97e3cb750c1..f1debcef5a9 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -451,7 +451,7 @@ static void template_texture_select(bContext *C, void *user_p, void *UNUSED(arg)
/* set user as active */
if (user->node) {
- ED_node_set_active(CTX_data_main(C), user->ntree, user->node, NULL);
+ ED_node_set_active(CTX_data_main(C), NULL, user->ntree, user->node, NULL);
ct->texture = NULL;
/* Not totally sure if we should also change selection? */
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 9db8f7efbb2..57a7fe894b0 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -202,11 +202,11 @@ int ED_buttons_tabs_list(SpaceProperties *sbuts, short *context_tabs_array)
context_tabs_array[length] = BCONTEXT_WORLD;
length++;
}
- if (length != 0) {
- context_tabs_array[length] = -1;
- length++;
- }
if (sbuts->pathflag & (1 << BCONTEXT_COLLECTION)) {
+ if (length != 0) {
+ context_tabs_array[length] = -1;
+ length++;
+ }
context_tabs_array[length] = BCONTEXT_COLLECTION;
length++;
}
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index d555238e949..7379891543b 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -809,12 +809,12 @@ void uiTemplateMovieclipInformation(uiLayout *layout,
char str[1024];
size_t ofs = 0;
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, TIP_("%d x %d"), width, height);
+ ofs += BLI_snprintf_rlen(str + ofs, sizeof(str) - ofs, TIP_("%d x %d"), width, height);
if (ibuf) {
if (ibuf->rect_float) {
if (ibuf->channels != 4) {
- ofs += BLI_snprintf(
+ ofs += BLI_snprintf_rlen(
str + ofs, sizeof(str) - ofs, TIP_(", %d float channel(s)"), ibuf->channels);
}
else if (ibuf->planes == R_IMF_PLANES_RGBA) {
@@ -837,7 +837,7 @@ void uiTemplateMovieclipInformation(uiLayout *layout,
short frs_sec;
float frs_sec_base;
if (IMB_anim_get_fps(clip->anim, &frs_sec, &frs_sec_base, true)) {
- ofs += BLI_snprintf(
+ ofs += BLI_snprintf_rlen(
str + ofs, sizeof(str) - ofs, TIP_(", %.2f fps"), (float)frs_sec / frs_sec_base);
}
}
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 2da13646a8b..67b4fd61d38 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -1025,7 +1025,7 @@ static void prefetch_startjob(void *pjv, short *stop, short *do_update, float *p
progress);
}
else {
- BLI_assert(!"Unknown movie clip source when prefetching frames");
+ BLI_assert_msg(0, "Unknown movie clip source when prefetching frames");
}
}
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 0c54a042a1a..f5e4c4d55d9 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -1235,10 +1235,8 @@ static void do_movie_proxy(void *pjv,
float *progress)
{
ProxyJob *pj = pjv;
- Scene *scene = pj->scene;
MovieClip *clip = pj->clip;
struct MovieDistortion *distortion = NULL;
- int cfra, sfra = SFRA, efra = EFRA;
if (pj->index_context) {
IMB_anim_index_rebuild(pj->index_context, stop, do_update, progress);
@@ -1252,8 +1250,8 @@ static void do_movie_proxy(void *pjv,
return;
}
- sfra = 1;
- efra = clip->len;
+ const int sfra = 1;
+ const int efra = clip->len;
if (build_undistort_count) {
int threads = BLI_system_thread_count();
@@ -1265,7 +1263,7 @@ static void do_movie_proxy(void *pjv,
BKE_tracking_distortion_set_threads(distortion, threads);
}
- for (cfra = sfra; cfra <= efra; cfra++) {
+ for (int cfra = sfra; cfra <= efra; cfra++) {
BKE_movieclip_build_proxy_frame(
clip, pj->clip_flag, distortion, cfra, build_undistort_sizes, build_undistort_count, 1);
diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c
index dbf733413e5..7194e78e940 100644
--- a/source/blender/editors/space_clip/clip_utils.c
+++ b/source/blender/editors/space_clip/clip_utils.c
@@ -398,7 +398,7 @@ void clip_delete_plane_track(bContext *C, MovieClip *clip, MovieTrackingPlaneTra
DEG_id_tag_update(&clip->id, 0);
}
-/* Calculate space clip offset to be centered at the given point. */
+/* Calculate space clip offset to be centered at the given point. */
void clip_view_offset_for_center_to_point(
SpaceClip *sc, const float x, const float y, float *r_offset_x, float *r_offset_y)
{
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index e0a524a79c1..326c221a2e3 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -1214,7 +1214,7 @@ static void clip_header_region_listener(const wmRegionListenerParams *params)
switch (wmn->data) {
/* for proportional editmode only */
case ND_TOOLSETTINGS:
- /* TODO - should do this when in mask mode only but no data available */
+ /* TODO: should do this when in mask mode only but no data available. */
// if (sc->mode == SC_MODE_MASKEDIT)
{
ED_region_tag_redraw(region);
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index bcac4d94bf0..ff62bcf0cfa 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -52,7 +52,9 @@
#include "clip_intern.h"
#include "tracking_ops_intern.h"
-/********************** add marker operator *********************/
+/* -------------------------------------------------------------------- */
+/** \name Add Marker Operator
+ * \{ */
static bool add_marker(const bContext *C, float x, float y)
{
@@ -147,7 +149,11 @@ void CLIP_OT_add_marker(wmOperatorType *ot)
1.0f);
}
-/********************** add marker operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Add Marker Operator
+ * \{ */
static int add_marker_at_click_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
@@ -212,7 +218,11 @@ void CLIP_OT_add_marker_at_click(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
}
-/********************** delete track operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delete Track Operator
+ * \{ */
static int delete_track_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -265,7 +275,11 @@ void CLIP_OT_delete_track(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/********************** delete marker operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delete Marker Operator
+ * \{ */
static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -334,7 +348,11 @@ void CLIP_OT_delete_marker(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/********************** slide marker operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Slide Marker Operator
+ * \{ */
enum {
SLIDE_ACTION_POS = 0,
@@ -1000,7 +1018,11 @@ void CLIP_OT_slide_marker(wmOperatorType *ot)
FLT_MAX);
}
-/********************** clear track operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Clear Track Operator
+ * \{ */
static int clear_track_path_exec(bContext *C, wmOperator *op)
{
@@ -1071,7 +1093,11 @@ void CLIP_OT_clear_track_path(wmOperatorType *ot)
"Clear active track only instead of all selected tracks");
}
-/********************** disable markers operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Disable Markers Operator
+ * \{ */
enum {
MARKER_OP_DISABLE = 0,
@@ -1137,7 +1163,11 @@ void CLIP_OT_disable_markers(wmOperatorType *ot)
RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Disable action to execute");
}
-/********************** set principal center operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Set Principal Center Operator
+ * \{ */
static int set_center_principal_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1174,7 +1204,11 @@ void CLIP_OT_set_center_principal(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/********************** hide tracks operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Hide Tracks Operator
+ * \{ */
static int hide_tracks_exec(bContext *C, wmOperator *op)
{
@@ -1241,7 +1275,11 @@ void CLIP_OT_hide_tracks(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected tracks");
}
-/********************** hide tracks clear operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Hide Tracks Clear Operator
+ * \{ */
static int hide_tracks_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1284,7 +1322,11 @@ void CLIP_OT_hide_tracks_clear(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/********************** frame jump operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Frame Jump Operator
+ * \{ */
static bool frame_jump_poll(bContext *C)
{
@@ -1379,7 +1421,11 @@ void CLIP_OT_frame_jump(wmOperatorType *ot)
RNA_def_enum(ot->srna, "position", position_items, 0, "Position", "Position to jump to");
}
-/********************** join tracks operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Join Tracks Operator
+ * \{ */
static int join_tracks_exec(bContext *C, wmOperator *op)
{
@@ -1475,7 +1521,11 @@ void CLIP_OT_join_tracks(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/********************** Average tracks operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Average Tracks Operator
+ * \{ */
static int average_tracks_exec(bContext *C, wmOperator *op)
{
@@ -1566,7 +1616,11 @@ void CLIP_OT_average_tracks(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-/********************** lock tracks operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Lock Tracks Operator
+ * \{ */
enum {
TRACK_ACTION_LOCK = 0,
@@ -1628,7 +1682,11 @@ void CLIP_OT_lock_tracks(wmOperatorType *ot)
RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Lock action to execute");
}
-/********************** set keyframe operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Set Keyframe Operator
+ * \{ */
enum {
SOLVER_KEYFRAME_A = 0,
@@ -1680,7 +1738,11 @@ void CLIP_OT_set_solver_keyframe(wmOperatorType *ot)
RNA_def_enum(ot->srna, "keyframe", keyframe_items, 0, "Keyframe", "Keyframe to set");
}
-/********************** track copy color operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Track Copy Color Operator
+ * \{ */
static int track_copy_color_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1725,7 +1787,11 @@ void CLIP_OT_track_copy_color(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/********************** clean tracks operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Clean Tracks Operator
+ * \{ */
static bool is_track_clean(MovieTrackingTrack *track, int frames, int del)
{
@@ -1963,7 +2029,11 @@ void CLIP_OT_clean_tracks(wmOperatorType *ot)
RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Cleanup action to execute");
}
-/********************** add tracking object *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Add Tracking Object
+ * \{ */
static int tracking_object_new_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1994,7 +2064,11 @@ void CLIP_OT_tracking_object_new(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/********************** remove tracking object *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Remove Tracking Object
+ * \{ */
static int tracking_object_remove_exec(bContext *C, wmOperator *op)
{
@@ -2033,7 +2107,11 @@ void CLIP_OT_tracking_object_remove(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/********************** copy tracks to clipboard operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Copy Tracks to Clipboard Operator
+ * \{ */
static int copy_tracks_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -2064,7 +2142,11 @@ void CLIP_OT_copy_tracks(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER;
}
-/********************* paste tracks from clipboard operator ********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Paste Tracks From Clipboard Operator
+ * \{ */
static bool paste_tracks_poll(bContext *C)
{
@@ -2106,7 +2188,11 @@ void CLIP_OT_paste_tracks(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/********************** Insert track keyframe operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Insert Track Keyframe Operator
+ * \{ */
static void keyframe_set_flag(bContext *C, bool set)
{
@@ -2181,7 +2267,11 @@ void CLIP_OT_keyframe_insert(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/********************** Delete track keyframe operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delete Track Keyframe Operator
+ * \{ */
static int keyframe_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -2203,3 +2293,5 @@ void CLIP_OT_keyframe_delete(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
+/** \} */
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index 05595e0b393..bdb7c622cd2 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -415,7 +415,7 @@ static int console_insert_exec(bContext *C, wmOperator *op)
static int console_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- /* Note, the "text" property is always set from key-map,
+ /* NOTE: the "text" property is always set from key-map,
* so we can't use #RNA_struct_property_is_set, check the length instead. */
if (!RNA_string_length(op->ptr, "text")) {
/* if alt/ctrl/super are pressed pass through except for utf8 character event
@@ -747,7 +747,7 @@ static int console_clear_exec(bContext *C, wmOperator *op)
const bool scrollback = RNA_boolean_get(op->ptr, "scrollback");
const bool history = RNA_boolean_get(op->ptr, "history");
- /*ConsoleLine *ci = */ console_history_verify(C);
+ /* ConsoleLine *ci = */ console_history_verify(C);
if (scrollback) { /* Last item in history. */
while (sc->scrollback.first) {
@@ -790,7 +790,7 @@ static int console_history_cycle_exec(bContext *C, wmOperator *op)
SpaceConsole *sc = CTX_wm_space_console(C);
ARegion *region = CTX_wm_region(C);
- /* TODO - stupid, just prevents crashes when no command line */
+ /* TODO: stupid, just prevents crashes when no command line. */
ConsoleLine *ci = console_history_verify(C);
const bool reverse = RNA_boolean_get(op->ptr, "reverse"); /* assumes down, reverse is up */
int prev_len = ci->len;
@@ -1109,7 +1109,7 @@ typedef struct SetConsoleCursor {
int sel_init;
} SetConsoleCursor;
-/* TODO, cursor placement without selection */
+/* TODO: cursor placement without selection. */
static void console_cursor_set_to_pos(
SpaceConsole *sc, ARegion *region, SetConsoleCursor *scu, const int mval[2], int UNUSED(sel))
{
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index 56a6204b385..3029eed1017 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -107,7 +107,7 @@ static SpaceLink *console_duplicate(SpaceLink *sl)
/* clear or remove stuff from old */
- /* TODO - duplicate?, then we also need to duplicate the py namespace */
+ /* TODO: duplicate?, then we also need to duplicate the py namespace. */
BLI_listbase_clear(&sconsolen->scrollback);
BLI_listbase_clear(&sconsolen->history);
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index c1dcf2e56d3..faa4b3cc9cc 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -25,6 +25,8 @@
#include <math.h>
#include <string.h>
+#include "MEM_guardedalloc.h"
+
#include "BLI_alloca.h"
#include "BLI_blenlib.h"
#include "BLI_fileops_types.h"
@@ -108,7 +110,7 @@ void ED_file_path_button(bScreen *screen,
UI_but_func_complete_set(but, autocomplete_directory, NULL);
UI_but_funcN_set(but, file_directory_enter_handle, NULL, but);
- /* TODO, directory editing is non-functional while a library is loaded
+ /* TODO: directory editing is non-functional while a library is loaded
* until this is properly supported just disable it. */
if (sfile && sfile->files && filelist_lib(sfile->files)) {
UI_but_flag_enable(but, UI_BUT_DISABLED);
@@ -142,7 +144,8 @@ static void draw_tile(int sx, int sy, int width, int height, int colorid, int sh
color);
}
-static void file_draw_icon(uiBlock *block,
+static void file_draw_icon(const SpaceFile *sfile,
+ uiBlock *block,
const FileDirEntry *file,
const char *path,
int sx,
@@ -164,23 +167,28 @@ static void file_draw_icon(uiBlock *block,
const float a2 = dimmed ? 0.3f : 0.0f;
but = uiDefIconBut(
block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, a1, a2, NULL);
- UI_but_func_tooltip_set(but, file_draw_tooltip_func, BLI_strdup(path));
+ UI_but_func_tooltip_set(but, file_draw_tooltip_func, BLI_strdup(path), MEM_freeN);
if (drag) {
- /* TODO duplicated from file_draw_preview(). */
+ /* TODO: duplicated from file_draw_preview(). */
ID *id;
if ((id = filelist_file_get_id(file))) {
UI_but_drag_set_id(but, id);
}
- else if (file->typeflag & FILE_TYPE_ASSET) {
+ else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS &&
+ (file->typeflag & FILE_TYPE_ASSET) != 0) {
ImBuf *preview_image = filelist_file_getimage(file);
char blend_path[FILE_MAX_LIBEXTRA];
if (BLO_library_path_explode(path, blend_path, NULL, NULL)) {
+ const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile);
+ BLI_assert(asset_params != NULL);
+
UI_but_drag_set_asset(but,
file->name,
BLI_strdup(blend_path),
file->blentype,
+ asset_params->import_type,
icon,
preview_image,
UI_DPI_FAC);
@@ -299,7 +307,8 @@ void file_calc_previews(const bContext *C, ARegion *region)
UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height);
}
-static void file_draw_preview(uiBlock *block,
+static void file_draw_preview(const SpaceFile *sfile,
+ uiBlock *block,
const FileDirEntry *file,
const char *path,
int sx,
@@ -323,6 +332,7 @@ static void file_draw_preview(uiBlock *block,
int ex, ey;
bool show_outline = !is_icon &&
(file->typeflag & (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_BLENDER));
+ const bool is_offline = (file->attributes & FILE_ATTR_OFFLINE);
BLI_assert(imb != NULL);
@@ -390,7 +400,7 @@ static void file_draw_preview(uiBlock *block,
imb->x,
imb->y,
GPU_RGBA8,
- false,
+ true,
imb->rect,
scale,
scale,
@@ -419,14 +429,14 @@ static void file_draw_preview(uiBlock *block,
icon_x, icon_y, icon, icon_aspect / U.dpi_fac, icon_opacity, 0.0f, icon_color, false);
}
- if (is_link) {
- /* Arrow icon to indicate it is a shortcut, link, or alias. */
+ if (is_link || is_offline) {
+ /* Icon at bottom to indicate it is a shortcut, link, alias, or offline. */
float icon_x, icon_y;
icon_x = xco + (2.0f * UI_DPI_FAC);
icon_y = yco + (2.0f * UI_DPI_FAC);
- const int arrow = ICON_LOOP_FORWARDS;
+ const int arrow = is_link ? ICON_LOOP_FORWARDS : ICON_URL;
if (!is_icon) {
- /* Arrow at very bottom-left if preview style. */
+ /* At very bottom-left if preview style. */
const uchar dark[4] = {0, 0, 0, 255};
const uchar light[4] = {255, 255, 255, 255};
UI_icon_draw_ex(icon_x + 1, icon_y - 1, arrow, 1.0f / U.dpi_fac, 0.2f, 0.0f, dark, false);
@@ -481,11 +491,22 @@ static void file_draw_preview(uiBlock *block,
UI_but_drag_set_id(but, id);
}
/* path is no more static, cannot give it directly to but... */
- else if (file->typeflag & FILE_TYPE_ASSET) {
+ else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS &&
+ (file->typeflag & FILE_TYPE_ASSET) != 0) {
char blend_path[FILE_MAX_LIBEXTRA];
+
if (BLO_library_path_explode(path, blend_path, NULL, NULL)) {
- UI_but_drag_set_asset(
- but, file->name, BLI_strdup(blend_path), file->blentype, icon, imb, scale);
+ const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile);
+ BLI_assert(asset_params != NULL);
+
+ UI_but_drag_set_asset(but,
+ file->name,
+ BLI_strdup(blend_path),
+ file->blentype,
+ asset_params->import_type,
+ icon,
+ imb,
+ scale);
}
}
else {
@@ -502,6 +523,7 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
char orgname[FILE_MAX + 12];
char filename[FILE_MAX + 12];
wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C);
ARegion *region = CTX_wm_region(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
@@ -521,17 +543,15 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
else {
/* If rename is successful, scroll to newly renamed entry. */
BLI_strncpy(params->renamefile, filename, sizeof(params->renamefile));
- params->rename_flag = FILE_PARAMS_RENAME_POSTSCROLL_PENDING;
-
- if (sfile->smoothscroll_timer != NULL) {
- WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer);
- }
- sfile->smoothscroll_timer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER1, 1.0 / 1000.0);
- sfile->scroll_offset = 0;
+ file_params_invoke_rename_postscroll(wm, win, sfile);
}
/* to make sure we show what is on disk */
- ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
+ ED_fileselect_clear(wm, sfile);
+ }
+ else {
+ /* Renaming failed, reset the name for further renaming handling. */
+ BLI_strncpy(params->renamefile, oldname, sizeof(params->renamefile));
}
ED_region_tag_redraw(region);
@@ -706,40 +726,45 @@ static void draw_columnheader_columns(const FileSelectParams *params,
/**
* Updates the stat string stored in file->entry if necessary.
*/
-static const char *filelist_get_details_column_string(FileAttributeColumnType column,
- const FileDirEntry *file,
- const bool small_size,
- const bool update_stat_strings)
+static const char *filelist_get_details_column_string(
+ FileAttributeColumnType column,
+ /* Generated string will be cached in the file, so non-const. */
+ FileDirEntry *file,
+ const bool small_size,
+ const bool update_stat_strings)
{
switch (column) {
case COLUMN_DATETIME:
if (!(file->typeflag & FILE_TYPE_BLENDERLIB) && !FILENAME_IS_CURRPAR(file->relpath)) {
- if ((file->entry->datetime_str[0] == '\0') || update_stat_strings) {
+ if ((file->draw_data.datetime_str[0] == '\0') || update_stat_strings) {
char date[FILELIST_DIRENTRY_DATE_LEN], time[FILELIST_DIRENTRY_TIME_LEN];
bool is_today, is_yesterday;
BLI_filelist_entry_datetime_to_string(
- NULL, file->entry->time, small_size, time, date, &is_today, &is_yesterday);
+ NULL, file->time, small_size, time, date, &is_today, &is_yesterday);
if (is_today || is_yesterday) {
BLI_strncpy(date, is_today ? N_("Today") : N_("Yesterday"), sizeof(date));
}
- BLI_snprintf(
- file->entry->datetime_str, sizeof(file->entry->datetime_str), "%s %s", date, time);
+ BLI_snprintf(file->draw_data.datetime_str,
+ sizeof(file->draw_data.datetime_str),
+ "%s %s",
+ date,
+ time);
}
- return file->entry->datetime_str;
+ return file->draw_data.datetime_str;
}
break;
case COLUMN_SIZE:
if ((file->typeflag & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) ||
!(file->typeflag & (FILE_TYPE_DIR | FILE_TYPE_BLENDERLIB))) {
- if ((file->entry->size_str[0] == '\0') || update_stat_strings) {
+ if ((file->draw_data.size_str[0] == '\0') || update_stat_strings) {
BLI_filelist_entry_size_to_string(
- NULL, file->entry->size, small_size, file->entry->size_str);
+ NULL, file->size, small_size, file->draw_data.size_str);
}
- return file->entry->size_str;
+ return file->draw_data.size_str;
}
break;
default:
@@ -751,7 +776,7 @@ static const char *filelist_get_details_column_string(FileAttributeColumnType co
static void draw_details_columns(const FileSelectParams *params,
const FileLayout *layout,
- const FileDirEntry *file,
+ FileDirEntry *file,
const int pos_x,
const int pos_y,
const uchar text_col[4])
@@ -792,6 +817,8 @@ static void draw_details_columns(const FileSelectParams *params,
void file_draw_list(const bContext *C, ARegion *region)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileLayout *layout = ED_fileselect_get_layout(sfile, region);
@@ -862,12 +889,12 @@ void file_draw_list(const bContext *C, ARegion *region)
// printf("%s: preview task: %d\n", __func__, previews_running);
if (previews_running && !sfile->previews_timer) {
sfile->previews_timer = WM_event_add_timer_notifier(
- CTX_wm_manager(C), CTX_wm_window(C), NC_SPACE | ND_SPACE_FILE_PREVIEW, 0.01);
+ wm, win, NC_SPACE | ND_SPACE_FILE_PREVIEW, 0.01);
}
if (!previews_running && sfile->previews_timer) {
/* Preview is not running, no need to keep generating update events! */
// printf("%s: Inactive preview task, sleeping!\n", __func__);
- WM_event_remove_timer_notifier(CTX_wm_manager(C), CTX_wm_window(C), sfile->previews_timer);
+ WM_event_remove_timer_notifier(wm, win, sfile->previews_timer);
sfile->previews_timer = NULL;
}
}
@@ -924,7 +951,8 @@ void file_draw_list(const bContext *C, ARegion *region)
is_icon = 1;
}
- file_draw_preview(block,
+ file_draw_preview(sfile,
+ block,
file,
path,
sx,
@@ -939,7 +967,8 @@ void file_draw_list(const bContext *C, ARegion *region)
is_link);
}
else {
- file_draw_icon(block,
+ file_draw_icon(sfile,
+ block,
file,
path,
sx,
@@ -976,8 +1005,19 @@ void file_draw_list(const bContext *C, ARegion *region)
UI_but_flag_enable(but, UI_BUT_NO_UTF8); /* allow non utf8 names */
UI_but_flag_disable(but, UI_BUT_UNDO);
if (false == UI_but_active_only(C, region, block, but)) {
- file_selflag = filelist_entry_select_set(
- sfile->files, file, FILE_SEL_REMOVE, FILE_SEL_EDITING, CHECK_ALL);
+ /* Note that this is the only place where we can also handle a cancelled renaming. */
+
+ file_params_rename_end(wm, win, sfile, file);
+
+ /* After the rename button is removed, we need to make sure the view is redrawn once more,
+ * in case selection changed. Usually UI code would trigger that redraw, but the rename
+ * operator may have been called from a different region.
+ * Tagging regions for redrawing while drawing is rightfully prevented. However, this
+ * active button removing basically introduces handling logic to drawing code. So a
+ * notifier should be an acceptable workaround. */
+ WM_event_add_notifier_ex(wm, win, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
+
+ file_selflag = filelist_entry_select_get(sfile->files, file, CHECK_ALL);
}
}
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index f1d0197b9ae..0bbed65671c 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -62,6 +62,7 @@ void FILE_OT_bookmark_cleanup(struct wmOperatorType *ot);
void FILE_OT_bookmark_move(struct wmOperatorType *ot);
void FILE_OT_reset_recent(wmOperatorType *ot);
void FILE_OT_hidedot(struct wmOperatorType *ot);
+void FILE_OT_associate_blend(struct wmOperatorType *ot);
void FILE_OT_execute(struct wmOperatorType *ot);
void FILE_OT_mouse_execute(struct wmOperatorType *ot);
void FILE_OT_cancel(struct wmOperatorType *ot);
@@ -108,10 +109,22 @@ FileAttributeColumnType file_attribute_column_type_find_isect(const View2D *v2d,
float file_string_width(const char *str);
float file_font_pointsize(void);
+void file_select_deselect_all(SpaceFile *sfile, uint flag);
int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file);
int autocomplete_directory(struct bContext *C, char *str, void *arg_v);
int autocomplete_file(struct bContext *C, char *str, void *arg_v);
+void file_params_smoothscroll_timer_clear(struct wmWindowManager *wm,
+ struct wmWindow *win,
+ SpaceFile *sfile);
+void file_params_renamefile_clear(struct FileSelectParams *params);
+void file_params_invoke_rename_postscroll(struct wmWindowManager *wm,
+ struct wmWindow *win,
+ SpaceFile *sfile);
+void file_params_rename_end(struct wmWindowManager *wm,
+ struct wmWindow *win,
+ SpaceFile *sfile,
+ struct FileDirEntry *rename_file);
void file_params_renamefile_activate(struct SpaceFile *sfile, struct FileSelectParams *params);
typedef void *onReloadFnData;
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 61f3c046550..995383d9d0e 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -86,7 +86,7 @@ static FileSelection find_file_mouse_rect(SpaceFile *sfile,
BLI_rctf_rcti_copy(&rect_region_fl, rect_region);
- /* Okay, manipulating v2d rects here is hacky... */
+ /* Okay, manipulating v2d rects here is hacky... */
v2d->mask.ymax -= sfile->layout->offset_top;
v2d->cur.ymax -= sfile->layout->offset_top;
UI_view2d_region_to_view_rctf(v2d, &rect_region_fl, &rect_view_fl);
@@ -104,15 +104,6 @@ static FileSelection find_file_mouse_rect(SpaceFile *sfile,
return sel;
}
-static void file_deselect_all(SpaceFile *sfile, uint flag)
-{
- FileSelection sel;
- sel.first = 0;
- sel.last = filelist_files_ensure(sfile->files) - 1;
-
- filelist_entries_select_index_range_set(sfile->files, &sel, FILE_SEL_REMOVE, flag, CHECK_ALL);
-}
-
typedef enum FileSelect {
FILE_SELECT_NOTHING = 0,
FILE_SELECT_DIR = 1,
@@ -239,7 +230,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
}
/**
- * \warning: loops over all files so better use cautiously
+ * \warning Loops over all files so better use cautiously.
*/
static bool file_is_any_selected(struct FileList *files)
{
@@ -444,7 +435,7 @@ static int file_box_select_modal(bContext *C, wmOperator *op, const wmEvent *eve
if ((sel.first != params->sel_first) || (sel.last != params->sel_last)) {
int idx;
- file_deselect_all(sfile, FILE_SEL_HIGHLIGHTED);
+ file_select_deselect_all(sfile, FILE_SEL_HIGHLIGHTED);
filelist_entries_select_index_range_set(
sfile->files, &sel, FILE_SEL_ADD, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
@@ -472,7 +463,7 @@ static int file_box_select_modal(bContext *C, wmOperator *op, const wmEvent *eve
params->highlight_file = -1;
params->sel_first = params->sel_last = -1;
fileselect_file_set(sfile, params->active_file);
- file_deselect_all(sfile, FILE_SEL_HIGHLIGHTED);
+ file_select_deselect_all(sfile, FILE_SEL_HIGHLIGHTED);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
}
@@ -491,7 +482,7 @@ static int file_box_select_exec(bContext *C, wmOperator *op)
const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
const bool select = (sel_op != SEL_OP_SUB);
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- file_deselect_all(sfile, FILE_SEL_SELECTED);
+ file_select_deselect_all(sfile, FILE_SEL_SELECTED);
}
ED_fileselect_layout_isect_rect(sfile->layout, &region->v2d, &rect, &rect);
@@ -573,7 +564,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if ((idx >= 0) && (idx < numfiles)) {
/* single select, deselect all selected first */
if (!extend) {
- file_deselect_all(sfile, FILE_SEL_SELECTED);
+ file_select_deselect_all(sfile, FILE_SEL_SELECTED);
}
}
}
@@ -588,7 +579,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (ret == FILE_SELECT_NOTHING) {
if (deselect_all) {
- file_deselect_all(sfile, FILE_SEL_SELECTED);
+ file_select_deselect_all(sfile, FILE_SEL_SELECTED);
}
}
else if (ret == FILE_SELECT_DIR) {
@@ -721,7 +712,7 @@ static bool file_walk_select_selection_set(wmWindow *win,
}
else {
/* deselect all first */
- file_deselect_all(sfile, FILE_SEL_SELECTED);
+ file_select_deselect_all(sfile, FILE_SEL_SELECTED);
/* highlight file under mouse pos */
params->highlight_file = -1;
@@ -1023,7 +1014,7 @@ void FILE_OT_view_selected(wmOperatorType *ot)
/* Note we could get rid of this one, but it's used by some addon so...
* Does not hurt keeping it around for now. */
-/* TODO disallow bookmark editing in assets mode? */
+/* TODO: disallow bookmark editing in assets mode? */
static int bookmark_select_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -1677,7 +1668,7 @@ void file_draw_check_ex(bContext *C, ScrArea *area)
if (op->type->check(C, op)) {
file_operator_to_sfile(bmain, sfile, op);
- /* redraw, else the changed settings wont get updated */
+ /* redraw, else the changed settings won't get updated */
ED_area_tag_redraw(area);
}
}
@@ -1744,7 +1735,7 @@ static bool file_execute(bContext *C, SpaceFile *sfile)
/* directory change */
if (file && (file->typeflag & FILE_TYPE_DIR)) {
if (!file->relpath) {
- return OPERATOR_CANCELLED;
+ return false;
}
if (FILENAME_IS_PARENT(file->relpath)) {
@@ -1783,7 +1774,7 @@ static bool file_execute(bContext *C, SpaceFile *sfile)
WM_event_fileselect_event(CTX_wm_manager(C), op, EVT_FILESELECT_EXEC);
}
- return OPERATOR_FINISHED;
+ return true;
}
static int file_exec(bContext *C, wmOperator *UNUSED(op))
@@ -1882,7 +1873,7 @@ static int file_refresh_exec(bContext *C, wmOperator *UNUSED(unused))
SpaceFile *sfile = CTX_wm_space_file(C);
struct FSMenu *fsmenu = ED_fsmenu_get();
- ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
+ ED_fileselect_clear(wm, sfile);
/* refresh system directory menu */
fsmenu_refresh_system_category(fsmenu);
@@ -2059,13 +2050,15 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
}
}
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+
/* if we are not editing, we are done */
if (edit_idx == -1) {
/* Do not invalidate timer if filerename is still pending,
* we might still be building the filelist and yet have to find edited entry. */
if (params->rename_flag == 0) {
- WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer);
- sfile->smoothscroll_timer = NULL;
+ file_params_smoothscroll_timer_clear(wm, win, sfile);
}
return OPERATOR_PASS_THROUGH;
}
@@ -2073,8 +2066,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
/* we need the correct area for scrolling */
region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
if (!region || region->regiontype != RGN_TYPE_WINDOW) {
- WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer);
- sfile->smoothscroll_timer = NULL;
+ file_params_smoothscroll_timer_clear(wm, win, sfile);
return OPERATOR_PASS_THROUGH;
}
@@ -2093,7 +2085,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
sfile->layout, (int)region->v2d.cur.xmin, (int)-region->v2d.cur.ymax);
const int last_visible_item = first_visible_item + numfiles_layout + 1;
- /* Note: the special case for vertical layout is because filename is at the bottom of items then,
+ /* NOTE: the special case for vertical layout is because filename is at the bottom of items then,
* so we artificially move current row back one step, to ensure we show bottom of
* active item rather than its top (important in case visible height is low). */
const int middle_offset = max_ii(
@@ -2131,13 +2123,11 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
(max_middle_offset - middle_offset < items_block_size));
if (is_ready && (is_centered || is_full_start || is_full_end)) {
- WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer);
- sfile->smoothscroll_timer = NULL;
+ file_params_smoothscroll_timer_clear(wm, win, sfile);
/* Post-scroll (after rename has been validated by user) is done,
* rename process is totally finished, cleanup. */
if ((params->rename_flag & FILE_PARAMS_RENAME_POSTSCROLL_ACTIVE) != 0) {
- params->renamefile[0] = '\0';
- params->rename_flag = 0;
+ file_params_renamefile_clear(params);
}
return OPERATOR_FINISHED;
}
@@ -2263,23 +2253,24 @@ void FILE_OT_filepath_drop(wmOperatorType *ot)
* \{ */
/**
- * Create a new, non-existing folder name, returns 1 if successful, 0 if name couldn't be created.
+ * Create a new, non-existing folder name, returns true if successful,
+ * false if name couldn't be created.
* The actual name is returned in 'name', 'folder' contains the complete path,
* including the new folder name.
*/
-static int new_folder_path(const char *parent, char *folder, char *name)
+static bool new_folder_path(const char *parent, char folder[FILE_MAX], char name[FILE_MAXFILE])
{
int i = 1;
int len = 0;
BLI_strncpy(name, "New Folder", FILE_MAXFILE);
- BLI_join_dirfile(folder, FILE_MAX, parent, name); /* XXX, not real length */
+ BLI_join_dirfile(folder, FILE_MAX, parent, name);
/* check whether folder with the name already exists, in this case
* add number to the name. Check length of generated name to avoid
* crazy case of huge number of folders each named 'New Folder (x)' */
while (BLI_exists(folder) && (len < FILE_MAXFILE)) {
len = BLI_snprintf(name, FILE_MAXFILE, "New Folder(%d)", i);
- BLI_join_dirfile(folder, FILE_MAX, parent, name); /* XXX, not real length */
+ BLI_join_dirfile(folder, FILE_MAX, parent, name);
i++;
}
@@ -2345,21 +2336,20 @@ static int file_directory_new_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ eFileSel_Params_RenameFlag rename_flag = params->rename_flag;
+
/* If we don't enter the directory directly, remember file to jump into editing. */
if (do_diropen == false) {
+ BLI_assert(params->rename_id == NULL || !"File rename handling should immediately clear rename_id when done, because otherwise it will keep taking precedence over renamefile.");
BLI_strncpy(params->renamefile, name, FILE_MAXFILE);
- params->rename_flag = FILE_PARAMS_RENAME_PENDING;
+ rename_flag = FILE_PARAMS_RENAME_PENDING;
}
- /* Set timer to smoothly view newly generated file. */
- if (sfile->smoothscroll_timer != NULL) {
- WM_event_remove_timer(wm, CTX_wm_window(C), sfile->smoothscroll_timer);
- }
- sfile->smoothscroll_timer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER1, 1.0 / 1000.0);
- sfile->scroll_offset = 0;
+ file_params_invoke_rename_postscroll(wm, CTX_wm_window(C), sfile);
+ params->rename_flag = rename_flag;
/* reload dir to make sure we're seeing what's in the directory */
- ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
+ ED_fileselect_clear(wm, sfile);
if (do_diropen) {
BLI_strncpy(params->dir, path, sizeof(params->dir));
@@ -2399,7 +2389,7 @@ void FILE_OT_directory_new(struct wmOperatorType *ot)
/** \name Refresh File List Operator
* \{ */
-/* TODO This should go to BLI_path_utils. */
+/* TODO: This should go to BLI_path_utils. */
static void file_expand_directory(bContext *C)
{
Main *bmain = CTX_data_main(C);
@@ -2440,7 +2430,7 @@ static void file_expand_directory(bContext *C)
}
}
-/* TODO check we still need this, it's annoying to have OS-specific code here... :/ */
+/* TODO: check we still need this, it's annoying to have OS-specific code here... :/. */
#if defined(WIN32)
static bool can_create_dir(const char *dir)
{
@@ -2610,7 +2600,7 @@ static int file_hidedot_exec(bContext *C, wmOperator *UNUSED(unused))
if (params) {
params->flag ^= FILE_HIDE_DOT;
- ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
+ ED_fileselect_clear(wm, sfile);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
@@ -2632,6 +2622,43 @@ void FILE_OT_hidedot(struct wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Associate File Type Operator (Windows only)
+ * \{ */
+
+static int associate_blend_exec(bContext *UNUSED(C), wmOperator *op)
+{
+#ifdef WIN32
+ WM_cursor_wait(true);
+ if (BLI_windows_register_blend_extension(true)) {
+ BKE_report(op->reports, RPT_INFO, "File association registered");
+ WM_cursor_wait(false);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Unable to register file association");
+ WM_cursor_wait(false);
+ return OPERATOR_CANCELLED;
+ }
+#else
+ BKE_report(op->reports, RPT_WARNING, "Operator Not supported");
+ return OPERATOR_CANCELLED;
+#endif
+}
+
+void FILE_OT_associate_blend(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Register File Association";
+ ot->description = "Use this installation for .blend files and to display thumbnails";
+ ot->idname = "FILE_OT_associate_blend";
+
+ /* api callbacks */
+ ot->exec = associate_blend_exec;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Increment Filename Operator
* \{ */
@@ -2766,6 +2793,11 @@ static int file_rename_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
+static bool file_rename_poll(bContext *C)
+{
+ return ED_operator_file_active(C) && !ED_fileselect_is_asset_browser(CTX_wm_space_file(C));
+}
+
void FILE_OT_rename(struct wmOperatorType *ot)
{
/* identifiers */
@@ -2776,7 +2808,7 @@ void FILE_OT_rename(struct wmOperatorType *ot)
/* api callbacks */
ot->invoke = file_rename_invoke;
ot->exec = file_rename_exec;
- ot->poll = ED_operator_file_active;
+ ot->poll = file_rename_poll;
}
/** \} */
@@ -2870,7 +2902,7 @@ static int file_delete_exec(bContext *C, wmOperator *op)
}
}
- ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
+ ED_fileselect_clear(wm, sfile);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c
index afa85d183d8..7032d55b331 100644
--- a/source/blender/editors/space_file/file_panels.c
+++ b/source/blender/editors/space_file/file_panels.c
@@ -72,7 +72,7 @@ static void file_panel_operator(const bContext *C, Panel *panel)
UI_block_func_set(uiLayoutGetBlock(panel->layout), file_draw_check_cb, NULL, NULL);
- /* Hack: temporary hide.*/
+ /* Hack: temporary hide. */
const char *hide[] = {"filepath", "files", "directory", "filename"};
for (int i = 0; i < ARRAY_SIZE(hide); i++) {
PropertyRNA *prop = RNA_struct_find_property(op->ptr, hide[i]);
@@ -84,7 +84,7 @@ static void file_panel_operator(const bContext *C, Panel *panel)
uiTemplateOperatorPropertyButs(
C, panel->layout, op, UI_BUT_LABEL_ALIGN_NONE, UI_TEMPLATE_OP_PROPS_SHOW_EMPTY);
- /* Hack: temporary hide.*/
+ /* Hack: temporary hide. */
for (int i = 0; i < ARRAY_SIZE(hide); i++) {
PropertyRNA *prop = RNA_struct_find_property(op->ptr, hide[i]);
if (prop) {
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index ca16563a7e2..0e15538e03b 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -263,8 +263,7 @@ ListBase folder_history_list_duplicate(ListBase *listbase)
typedef struct FileListInternEntry {
struct FileListInternEntry *next, *prev;
- /** ASSET_UUID_LENGTH */
- char uuid[16];
+ FileUID uid;
/** eFileSel_File_Types */
int typeflag;
@@ -306,7 +305,7 @@ typedef struct FileListIntern {
ListBase entries;
FileListInternEntry **filtered;
- char curr_uuid[16]; /* Used to generate uuid during internal listing. */
+ FileUID curr_uid; /* Used to generate UID during internal listing. */
} FileListIntern;
#define FILELIST_ENTRYCACHESIZE_DEFAULT 1024 /* Keep it a power of two! */
@@ -315,7 +314,7 @@ typedef struct FileListEntryCache {
int flags;
- /* This one gathers all entries from both block and misc caches. Used for easy bulk-freing. */
+ /* This one gathers all entries from both block and misc caches. Used for easy bulk-freeing. */
ListBase cached_entries;
/* Block cache: all entries between start and end index.
@@ -324,13 +323,13 @@ typedef struct FileListEntryCache {
int block_start_index, block_end_index, block_center_index, block_cursor;
/* Misc cache: random indices, FIFO behavior.
- * Note: Not 100% sure we actually need that, time will say. */
+ * NOTE: Not 100% sure we actually need that, time will say. */
int misc_cursor;
int *misc_entries_indices;
GHash *misc_entries;
- /* Allows to quickly get a cached entry from its UUID. */
- GHash *uuids;
+ /* Allows to quickly get a cached entry from its UID. */
+ GHash *uids;
/* Previews handling. */
TaskPool *previews_pool;
@@ -785,12 +784,12 @@ static bool is_filtered_hidden(const char *filename,
const FileListInternEntry *file)
{
if ((filename[0] == '.') && (filename[1] == '\0')) {
- return true; /* Ignore . */
+ return true; /* Ignore. */
}
if (filter->flags & FLF_HIDE_PARENT) {
if (filename[0] == '.' && filename[1] == '.' && filename[2] == '\0') {
- return true; /* Ignore .. */
+ return true; /* Ignore. */
}
}
@@ -1191,7 +1190,7 @@ static int filelist_geticon_ex(const FileDirEntry *file,
if (FILENAME_IS_PARENT(file->relpath)) {
return is_main ? ICON_FILE_PARENT : ICON_NONE;
}
- if (typeflag & FILE_TYPE_APPLICATIONBUNDLE) {
+ if (typeflag & FILE_TYPE_BUNDLE) {
return ICON_UGLYPACKAGE;
}
if (typeflag & FILE_TYPE_BLENDER) {
@@ -1383,40 +1382,6 @@ static void filelist_entry_clear(FileDirEntry *entry)
BKE_icon_delete(entry->preview_icon_id);
entry->preview_icon_id = 0;
}
- /* For now, consider FileDirEntryRevision::poin as not owned here,
- * so no need to do anything about it */
-
- if (!BLI_listbase_is_empty(&entry->variants)) {
- FileDirEntryVariant *var;
-
- for (var = entry->variants.first; var; var = var->next) {
- if (var->name) {
- MEM_freeN(var->name);
- }
- if (var->description) {
- MEM_freeN(var->description);
- }
-
- if (!BLI_listbase_is_empty(&var->revisions)) {
- FileDirEntryRevision *rev;
-
- for (rev = var->revisions.first; rev; rev = rev->next) {
- if (rev->comment) {
- MEM_freeN(rev->comment);
- }
- }
-
- BLI_freelistN(&var->revisions);
- }
- }
-
- /* TODO: tags! */
-
- BLI_freelistN(&entry->variants);
- }
- else if (entry->entry) {
- MEM_freeN(entry->entry);
- }
}
static void filelist_entry_free(FileDirEntry *entry)
@@ -1601,6 +1566,11 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry
BLI_assert(cache->flags & FLC_PREVIEWS_ACTIVE);
+ if (!entry->preview_icon_id && (entry->attributes & FILE_ATTR_OFFLINE)) {
+ entry->flags |= FILE_ENTRY_INVALID_PREVIEW;
+ return;
+ }
+
if (entry->preview_icon_id) {
return;
}
@@ -1657,9 +1627,8 @@ static void filelist_cache_init(FileListEntryCache *cache, size_t cache_size)
copy_vn_i(cache->misc_entries_indices, cache_size, -1);
cache->misc_cursor = 0;
- /* XXX This assumes uint is 32 bits and uuid is 128 bits (char[16]), be careful! */
- cache->uuids = BLI_ghash_new_ex(
- BLI_ghashutil_uinthash_v4_p, BLI_ghashutil_uinthash_v4_cmp, __func__, cache_size * 2);
+ cache->uids = BLI_ghash_new_ex(
+ BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__, cache_size * 2);
cache->size = cache_size;
cache->flags = FLC_IS_INIT;
@@ -1683,7 +1652,7 @@ static void filelist_cache_free(FileListEntryCache *cache)
BLI_ghash_free(cache->misc_entries, NULL, NULL);
MEM_freeN(cache->misc_entries_indices);
- BLI_ghash_free(cache->uuids, NULL, NULL);
+ BLI_ghash_free(cache->uids, NULL, NULL);
for (entry = cache->cached_entries.first; entry; entry = entry_next) {
entry_next = entry->next;
@@ -1716,7 +1685,7 @@ static void filelist_cache_clear(FileListEntryCache *cache, size_t new_size)
}
copy_vn_i(cache->misc_entries_indices, new_size, -1);
- BLI_ghash_clear_ex(cache->uuids, NULL, NULL, new_size * 2);
+ BLI_ghash_clear_ex(cache->uids, NULL, NULL, new_size * 2);
cache->size = new_size;
@@ -1733,8 +1702,7 @@ FileList *filelist_new(short type)
filelist_cache_init(&p->filelist_cache, FILELIST_ENTRYCACHESIZE_DEFAULT);
- p->selection_state = BLI_ghash_new(
- BLI_ghashutil_uinthash_v4_p, BLI_ghashutil_uinthash_v4_cmp, __func__);
+ p->selection_state = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
p->filelist.nbr_entries = FILEDIR_NBR_ENTRIES_UNSET;
filelist_settype(p, type);
@@ -1793,7 +1761,7 @@ void filelist_clear_ex(struct FileList *filelist, const bool do_cache, const boo
filelist_direntryarr_free(&filelist->filelist);
if (do_selection && filelist->selection_state) {
- BLI_ghash_clear(filelist->selection_state, MEM_freeN, NULL);
+ BLI_ghash_clear(filelist->selection_state, NULL, NULL);
}
}
@@ -1814,7 +1782,7 @@ void filelist_free(struct FileList *filelist)
filelist_cache_free(&filelist->filelist_cache);
if (filelist->selection_state) {
- BLI_ghash_free(filelist->selection_state, MEM_freeN, NULL);
+ BLI_ghash_free(filelist->selection_state, NULL, NULL);
filelist->selection_state = NULL;
}
@@ -1952,16 +1920,12 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in
FileListInternEntry *entry = filelist->filelist_intern.filtered[index];
FileListEntryCache *cache = &filelist->filelist_cache;
FileDirEntry *ret;
- FileDirEntryRevision *rev;
ret = MEM_callocN(sizeof(*ret), __func__);
- rev = MEM_callocN(sizeof(*rev), __func__);
-
- rev->size = (uint64_t)entry->st.st_size;
- rev->time = (int64_t)entry->st.st_mtime;
+ ret->size = (uint64_t)entry->st.st_size;
+ ret->time = (int64_t)entry->st.st_mtime;
- ret->entry = rev;
ret->relpath = BLI_strdup(entry->relpath);
if (entry->free_name) {
ret->name = BLI_strdup(entry->name);
@@ -1971,7 +1935,7 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in
ret->name = entry->name;
}
ret->description = BLI_strdupcat(filelist->filelist.root, entry->relpath);
- memcpy(ret->uuid, entry->uuid, sizeof(ret->uuid));
+ ret->uid = entry->uid;
ret->blentype = entry->blentype;
ret->typeflag = entry->typeflag;
ret->attributes = entry->attributes;
@@ -2029,11 +1993,11 @@ FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index, const
ret = filelist_file_create_entry(filelist, index);
old_index = cache->misc_entries_indices[cache->misc_cursor];
if ((old = BLI_ghash_popkey(cache->misc_entries, POINTER_FROM_INT(old_index), NULL))) {
- BLI_ghash_remove(cache->uuids, old->uuid, NULL, NULL);
+ BLI_ghash_remove(cache->uids, POINTER_FROM_UINT(old->uid), NULL, NULL);
filelist_file_release_entry(filelist, old);
}
BLI_ghash_insert(cache->misc_entries, POINTER_FROM_INT(index), ret);
- BLI_ghash_insert(cache->uuids, ret->uuid, ret);
+ BLI_ghash_insert(cache->uids, POINTER_FROM_UINT(ret->uid), ret);
cache->misc_entries_indices[cache->misc_cursor] = index;
cache->misc_cursor = (cache->misc_cursor + 1) % cache_size;
@@ -2052,19 +2016,21 @@ FileDirEntry *filelist_file(struct FileList *filelist, int index)
return filelist_file_ex(filelist, index, true);
}
-int filelist_file_findpath(struct FileList *filelist, const char *filename)
+/**
+ * Find a file from a file name, or more precisely, its file-list relative path, inside the
+ * filtered items. \return The index of the found file or -1.
+ */
+int filelist_file_find_path(struct FileList *filelist, const char *filename)
{
- int fidx = -1;
-
if (filelist->filelist.nbr_entries_filtered == FILEDIR_NBR_ENTRIES_UNSET) {
- return fidx;
+ return -1;
}
- /* XXX TODO Cache could probably use a ghash on paths too? Not really urgent though.
- * This is only used to find again renamed entry,
- * annoying but looks hairy to get rid of it currently. */
+ /* XXX TODO: Cache could probably use a ghash on paths too? Not really urgent though.
+ * This is only used to find again renamed entry,
+ * annoying but looks hairy to get rid of it currently. */
- for (fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) {
+ for (int fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) {
FileListInternEntry *entry = filelist->filelist_intern.filtered[fidx];
if (STREQ(entry->relpath, filename)) {
return fidx;
@@ -2075,38 +2041,53 @@ int filelist_file_findpath(struct FileList *filelist, const char *filename)
}
/**
- * Get the ID a file represents (if any). For #FILE_MAIN, #FILE_MAIN_ASSET.
+ * Find a file representing \a id.
+ * \return The index of the found file or -1.
*/
-ID *filelist_file_get_id(const FileDirEntry *file)
-{
- return file->id;
-}
-
-FileDirEntry *filelist_entry_find_uuid(struct FileList *filelist, const int uuid[4])
+int filelist_file_find_id(const FileList *filelist, const ID *id)
{
if (filelist->filelist.nbr_entries_filtered == FILEDIR_NBR_ENTRIES_UNSET) {
- return NULL;
+ return -1;
}
- if (filelist->filelist_cache.uuids) {
- FileDirEntry *entry = BLI_ghash_lookup(filelist->filelist_cache.uuids, uuid);
- if (entry) {
- return entry;
+ for (int fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) {
+ FileListInternEntry *entry = filelist->filelist_intern.filtered[fidx];
+ if (entry->local_data.id == id) {
+ return fidx;
}
}
- {
- int fidx;
+ return -1;
+}
- for (fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) {
- FileListInternEntry *entry = filelist->filelist_intern.filtered[fidx];
- if (memcmp(entry->uuid, uuid, sizeof(entry->uuid)) == 0) {
- return filelist_file(filelist, fidx);
- }
- }
- }
+/**
+ * Get the ID a file represents (if any). For #FILE_MAIN, #FILE_MAIN_ASSET.
+ */
+ID *filelist_file_get_id(const FileDirEntry *file)
+{
+ return file->id;
+}
- return NULL;
+#define FILE_UID_UNSET 0
+
+static FileUID filelist_uid_generate(FileList *filelist)
+{
+ /* Using an atomic operation to avoid having to lock thread...
+ * Note that we do not really need this here currently, since there is a single listing thread,
+ * but better remain consistent about threading! */
+ return atomic_add_and_fetch_uint32(&filelist->filelist_intern.curr_uid, 1);
+}
+
+bool filelist_uid_is_set(const FileUID uid)
+{
+ FileUID unset_uid;
+ filelist_uid_unset(&unset_uid);
+ return unset_uid != uid;
+}
+
+void filelist_uid_unset(FileUID *r_uid)
+{
+ *r_uid = FILE_UID_UNSET;
}
void filelist_file_cache_slidingwindow_set(FileList *filelist, size_t window_size)
@@ -2142,7 +2123,7 @@ static bool filelist_file_cache_block_create(FileList *filelist,
/* That entry might have already been requested and stored in misc cache... */
if ((entry = BLI_ghash_popkey(cache->misc_entries, POINTER_FROM_INT(idx), NULL)) == NULL) {
entry = filelist_file_create_entry(filelist, idx);
- BLI_ghash_insert(cache->uuids, entry->uuid, entry);
+ BLI_ghash_insert(cache->uids, POINTER_FROM_UINT(entry->uid), entry);
}
cache->block_entries[cursor] = entry;
}
@@ -2168,7 +2149,7 @@ static void filelist_file_cache_block_release(struct FileList *filelist,
__func__,
cursor /*, cache->block_entries[cursor], cache->block_entries[cursor]->relpath*/);
#endif
- BLI_ghash_remove(cache->uuids, entry->uuid, NULL, NULL);
+ BLI_ghash_remove(cache->uids, POINTER_FROM_UINT(entry->uid), NULL, NULL);
filelist_file_release_entry(filelist, entry);
#ifndef NDEBUG
cache->block_entries[cursor] = NULL;
@@ -2300,7 +2281,7 @@ bool filelist_file_cache_block(struct FileList *filelist, const int index)
if (start_index < cache->block_start_index) {
/* Add (request) needed entries before already cached ones. */
- /* Note: We need some index black magic to wrap around (cycle)
+ /* NOTE: We need some index black magic to wrap around (cycle)
* inside our cache_size array... */
int size1 = cache->block_start_index - start_index;
int size2 = 0;
@@ -2332,7 +2313,7 @@ bool filelist_file_cache_block(struct FileList *filelist, const int index)
// printf("\tstart-extended...\n");
if (end_index > cache->block_end_index) {
/* Add (request) needed entries after already cached ones. */
- /* Note: We need some index black magic to wrap around (cycle)
+ /* NOTE: We need some index black magic to wrap around (cycle)
* inside our cache_size array... */
int size1 = end_index - cache->block_end_index;
int size2 = 0;
@@ -2514,9 +2495,16 @@ int ED_path_extension_type(const char *path)
if (file_is_blend_backup(path)) {
return FILE_TYPE_BLENDER_BACKUP;
}
- if (BLI_path_extension_check(path, ".app")) {
- return FILE_TYPE_APPLICATIONBUNDLE;
+#ifdef __APPLE__
+ if (BLI_path_extension_check_n(path,
+ /* Application bundle */
+ ".app",
+ /* Safari in-progress/paused download */
+ ".download",
+ NULL)) {
+ return FILE_TYPE_BUNDLE;
}
+#endif
if (BLI_path_extension_check(path, ".py")) {
return FILE_TYPE_PYSCRIPT;
}
@@ -2623,7 +2611,7 @@ uint filelist_entry_select_set(const FileList *filelist,
FileCheckType check)
{
/* Default NULL pointer if not found is fine here! */
- void **es_p = BLI_ghash_lookup_p(filelist->selection_state, entry->uuid);
+ void **es_p = BLI_ghash_lookup_p(filelist->selection_state, POINTER_FROM_UINT(entry->uid));
uint entry_flag = es_p ? POINTER_AS_UINT(*es_p) : 0;
const uint org_entry_flag = entry_flag;
@@ -2651,13 +2639,12 @@ uint filelist_entry_select_set(const FileList *filelist,
*es_p = POINTER_FROM_UINT(entry_flag);
}
else {
- BLI_ghash_remove(filelist->selection_state, entry->uuid, MEM_freeN, NULL);
+ BLI_ghash_remove(filelist->selection_state, POINTER_FROM_UINT(entry->uid), NULL, NULL);
}
}
else if (entry_flag) {
- void *key = MEM_mallocN(sizeof(entry->uuid), __func__);
- memcpy(key, entry->uuid, sizeof(entry->uuid));
- BLI_ghash_insert(filelist->selection_state, key, POINTER_FROM_UINT(entry_flag));
+ BLI_ghash_insert(
+ filelist->selection_state, POINTER_FROM_UINT(entry->uid), POINTER_FROM_UINT(entry_flag));
}
}
@@ -2695,7 +2682,8 @@ uint filelist_entry_select_get(FileList *filelist, FileDirEntry *entry, FileChec
if (((check == CHECK_ALL)) || ((check == CHECK_DIRS) && (entry->typeflag & FILE_TYPE_DIR)) ||
((check == CHECK_FILES) && !(entry->typeflag & FILE_TYPE_DIR))) {
/* Default NULL pointer if not found is fine here! */
- return POINTER_AS_UINT(BLI_ghash_lookup(filelist->selection_state, entry->uuid));
+ return POINTER_AS_UINT(
+ BLI_ghash_lookup(filelist->selection_state, POINTER_FROM_UINT(entry->uid)));
}
return 0;
@@ -2720,7 +2708,7 @@ bool filelist_entry_is_selected(FileList *filelist, const int index)
/* BLI_ghash_lookup returns NULL if not found, which gets mapped to 0, which gets mapped to
* "not selected". */
const uint selection_state = POINTER_AS_UINT(
- BLI_ghash_lookup(filelist->selection_state, intern_entry->uuid));
+ BLI_ghash_lookup(filelist->selection_state, POINTER_FROM_UINT(intern_entry->uid)));
return selection_state != 0;
}
@@ -2810,7 +2798,7 @@ static int filelist_readjob_list_dir(const char *root,
entry->attributes = BLI_file_attributes(full_path);
if (S_ISDIR(files[i].s.st_mode)
#ifdef __APPLE__
- && !(ED_path_extension_type(full_path) & FILE_TYPE_APPLICATIONBUNDLE)
+ && !(ED_path_extension_type(full_path) & FILE_TYPE_BUNDLE)
#endif
) {
entry->typeflag = FILE_TYPE_DIR;
@@ -2889,7 +2877,8 @@ static int filelist_readjob_list_lib(const char *root, ListBase *entries, const
}
/* there we go */
- libfiledata = BLO_blendhandle_from_file(dir, NULL);
+ BlendFileReadReport bf_reports = {.reports = NULL};
+ libfiledata = BLO_blendhandle_from_file(dir, &bf_reports);
if (libfiledata == NULL) {
return nbr_entries;
}
@@ -2954,7 +2943,7 @@ static void filelist_readjob_main_recursive(Main *bmain, FileList *filelist)
ListBase *lb;
int a, fake, idcode, ok, totlib, totbl;
- // filelist->type = FILE_MAIN; /* XXX TODO: add modes to filebrowser */
+ // filelist->type = FILE_MAIN; /* XXX TODO: add modes to file-browser */
BLI_assert(filelist->filelist.entries == NULL);
@@ -3060,7 +3049,7 @@ static void filelist_readjob_main_recursive(Main *bmain, FileList *filelist)
files->entry->relpath = BLI_strdup(relname);
}
// files->type |= S_IFREG;
-# if 0 /* XXX TODO show the selection status of the objects */
+# if 0 /* XXX TODO: show the selection status of the objects. */
if (!filelist->has_func) { /* F4 DATA BROWSE */
if (idcode == ID_OB) {
if ( ((Object *)id)->flag & SELECT) {
@@ -3189,14 +3178,7 @@ static void filelist_readjob_do(const bool do_lib,
for (entry = entries.first; entry; entry = entry->next) {
BLI_join_dirfile(dir, sizeof(dir), rel_subdir, entry->relpath);
- /* Generate our entry uuid. Abusing uuid as an uint32, shall be more than enough here,
- * things would crash way before we overflow that counter!
- * Using an atomic operation to avoid having to lock thread...
- * Note that we do not really need this here currently,
- * since there is a single listing thread, but better
- * remain consistent about threading! */
- *((uint32_t *)entry->uuid) = atomic_add_and_fetch_uint32(
- (uint32_t *)filelist->filelist_intern.curr_uuid, 1);
+ entry->uid = filelist_uid_generate(filelist);
/* Only thing we change in direntry here, so we need to free it first. */
MEM_freeN(entry->relpath);
@@ -3321,8 +3303,7 @@ static void filelist_readjob_main_assets(Main *current_main,
entry->free_name = false;
entry->typeflag |= FILE_TYPE_BLENDERLIB | FILE_TYPE_ASSET;
entry->blentype = GS(id_iter->name);
- *((uint32_t *)entry->uuid) = atomic_add_and_fetch_uint32(
- (uint32_t *)filelist->filelist_intern.curr_uuid, 1);
+ entry->uid = filelist_uid_generate(filelist);
entry->local_data.preview_image = BKE_asset_metadata_preview_get_from_id(id_iter->asset_data,
id_iter);
entry->local_data.id = id_iter;
@@ -3368,9 +3349,7 @@ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update
flrj->tmp_filelist->filelist_intern.filtered = NULL;
BLI_listbase_clear(&flrj->tmp_filelist->filelist_intern.entries);
- memset(flrj->tmp_filelist->filelist_intern.curr_uuid,
- 0,
- sizeof(flrj->tmp_filelist->filelist_intern.curr_uuid));
+ filelist_uid_unset(&flrj->tmp_filelist->filelist_intern.curr_uid);
flrj->tmp_filelist->libfiledata = NULL;
memset(&flrj->tmp_filelist->filelist_cache, 0, sizeof(flrj->tmp_filelist->filelist_cache));
@@ -3410,7 +3389,7 @@ static void filelist_readjob_update(void *flrjv)
BLI_mutex_unlock(&flrj->lock);
if (new_nbr_entries) {
- /* Do not clear selection cache, we can assume already 'selected' uuids are still valid! */
+ /* Do not clear selection cache, we can assume already 'selected' UIDs are still valid! */
filelist_clear_ex(flrj->filelist, true, false);
flrj->filelist->flags |= (FL_NEED_SORTING | FL_NEED_FILTERING);
@@ -3492,7 +3471,7 @@ void filelist_readjob_start(FileList *filelist, const bContext *C)
/* setup job */
wm_job = WM_jobs_get(CTX_wm_manager(C),
CTX_wm_window(C),
- CTX_data_scene(C),
+ filelist,
"Listing Dirs...",
WM_JOB_PROGRESS,
WM_JOB_TYPE_FILESEL_READDIR);
@@ -3508,12 +3487,12 @@ void filelist_readjob_start(FileList *filelist, const bContext *C)
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
-void filelist_readjob_stop(wmWindowManager *wm, Scene *owner_scene)
+void filelist_readjob_stop(FileList *filelist, wmWindowManager *wm)
{
- WM_jobs_kill_type(wm, owner_scene, WM_JOB_TYPE_FILESEL_READDIR);
+ WM_jobs_kill_type(wm, filelist, WM_JOB_TYPE_FILESEL_READDIR);
}
-int filelist_readjob_running(wmWindowManager *wm, Scene *owner_scene)
+int filelist_readjob_running(FileList *filelist, wmWindowManager *wm)
{
- return WM_jobs_test(wm, owner_scene, WM_JOB_TYPE_FILESEL_READDIR);
+ return WM_jobs_test(wm, filelist, WM_JOB_TYPE_FILESEL_READDIR);
}
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index 9eb70dd8437..0aace74e621 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -35,6 +35,8 @@ struct wmWindowManager;
struct FileDirEntry;
+typedef uint32_t FileUID;
+
typedef enum FileSelType {
FILE_SEL_REMOVE = 0,
FILE_SEL_ADD = 1,
@@ -95,9 +97,11 @@ int filelist_needs_reading(struct FileList *filelist);
FileDirEntry *filelist_file(struct FileList *filelist, int index);
FileDirEntry *filelist_file_ex(struct FileList *filelist, int index, bool use_request);
-int filelist_file_findpath(struct FileList *filelist, const char *file);
+int filelist_file_find_path(struct FileList *filelist, const char *file);
+int filelist_file_find_id(const struct FileList *filelist, const struct ID *id);
struct ID *filelist_file_get_id(const struct FileDirEntry *file);
-FileDirEntry *filelist_entry_find_uuid(struct FileList *filelist, const int uuid[4]);
+bool filelist_uid_is_set(const FileUID uid);
+void filelist_uid_unset(FileUID *r_uid);
void filelist_file_cache_slidingwindow_set(struct FileList *filelist, size_t window_size);
bool filelist_file_cache_block(struct FileList *filelist, const int index);
@@ -141,8 +145,8 @@ 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);
-void filelist_readjob_stop(struct wmWindowManager *wm, struct Scene *owner_scene);
-int filelist_readjob_running(struct wmWindowManager *wm, struct Scene *owner_scene);
+void filelist_readjob_stop(struct FileList *filelist, struct wmWindowManager *wm);
+int filelist_readjob_running(struct FileList *filelist, struct wmWindowManager *wm);
bool filelist_cache_previews_update(struct FileList *filelist);
void filelist_cache_previews_set(struct FileList *filelist, const bool use_previews);
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 038b9c11bca..7ab93df81d2 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -120,12 +120,13 @@ static void fileselect_ensure_updated_asset_params(SpaceFile *sfile)
asset_params->base_params.details_flags = U_default.file_space_data.details_flags;
asset_params->asset_library.type = FILE_ASSET_LIBRARY_LOCAL;
asset_params->asset_library.custom_library_index = -1;
+ asset_params->import_type = FILE_ASSET_IMPORT_APPEND;
}
FileSelectParams *base_params = &asset_params->base_params;
base_params->file[0] = '\0';
base_params->filter_glob[0] = '\0';
- /* TODO this way of using filters to form categories is notably slower than specifying a
+ /* TODO: this way of using filters to form categories is notably slower than specifying a
* "group" to read. That's because all types are read and filtering is applied afterwards. Would
* be nice if we could lazy-read individual groups. */
base_params->flag |= U_default.file_space_data.flag | FILE_ASSETS_ONLY | FILE_FILTER;
@@ -377,7 +378,7 @@ FileSelectParams *ED_fileselect_ensure_active_params(SpaceFile *sfile)
return &sfile->asset_params->base_params;
}
- BLI_assert(!"Invalid browse mode set in file space.");
+ BLI_assert_msg(0, "Invalid browse mode set in file space.");
return NULL;
}
@@ -398,7 +399,7 @@ FileSelectParams *ED_fileselect_get_active_params(const SpaceFile *sfile)
return (FileSelectParams *)sfile->asset_params;
}
- BLI_assert(!"Invalid browse mode set in file space.");
+ BLI_assert_msg(0, "Invalid browse mode set in file space.");
return NULL;
}
@@ -1046,7 +1047,7 @@ FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, ARegion *region)
* Support updating the directory even when this isn't the active space
* needed so RNA properties update function isn't context sensitive, see T70255.
*/
-void ED_file_change_dir_ex(bContext *C, bScreen *screen, ScrArea *area)
+void ED_file_change_dir_ex(bContext *C, ScrArea *area)
{
/* May happen when manipulating non-active spaces. */
if (UNLIKELY(area->spacetype != SPACE_FILE)) {
@@ -1056,10 +1057,7 @@ void ED_file_change_dir_ex(bContext *C, bScreen *screen, ScrArea *area)
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params) {
wmWindowManager *wm = CTX_wm_manager(C);
- Scene *scene = WM_windows_scene_get_from_screen(wm, screen);
- if (LIKELY(scene != NULL)) {
- ED_fileselect_clear(wm, scene, sfile);
- }
+ ED_fileselect_clear(wm, sfile);
/* Clear search string, it is very rare to want to keep that filter while changing dir,
* and usually very annoying to keep it actually! */
@@ -1084,9 +1082,17 @@ void ED_file_change_dir_ex(bContext *C, bScreen *screen, ScrArea *area)
void ED_file_change_dir(bContext *C)
{
- bScreen *screen = CTX_wm_screen(C);
ScrArea *area = CTX_wm_area(C);
- ED_file_change_dir_ex(C, screen, area);
+ ED_file_change_dir_ex(C, area);
+}
+
+void file_select_deselect_all(SpaceFile *sfile, uint flag)
+{
+ FileSelection sel;
+ sel.first = 0;
+ sel.last = filelist_files_ensure(sfile->files) - 1;
+
+ filelist_entries_select_index_range_set(sfile->files, &sel, FILE_SEL_REMOVE, flag, CHECK_ALL);
}
int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file)
@@ -1182,11 +1188,11 @@ int autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
return match;
}
-void ED_fileselect_clear(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfile)
+void ED_fileselect_clear(wmWindowManager *wm, SpaceFile *sfile)
{
/* only NULL in rare cases - T29734. */
if (sfile->files) {
- filelist_readjob_stop(wm, owner_scene);
+ filelist_readjob_stop(sfile->files, wm);
filelist_freelib(sfile->files);
filelist_clear(sfile->files);
}
@@ -1196,7 +1202,7 @@ void ED_fileselect_clear(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfi
WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
-void ED_fileselect_exit(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfile)
+void ED_fileselect_exit(wmWindowManager *wm, SpaceFile *sfile)
{
if (!sfile) {
return;
@@ -1223,13 +1229,72 @@ void ED_fileselect_exit(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfil
folder_history_list_free(sfile);
if (sfile->files) {
- ED_fileselect_clear(wm, owner_scene, sfile);
+ ED_fileselect_clear(wm, sfile);
filelist_free(sfile->files);
MEM_freeN(sfile->files);
sfile->files = NULL;
}
}
+void file_params_smoothscroll_timer_clear(wmWindowManager *wm, wmWindow *win, SpaceFile *sfile)
+{
+ WM_event_remove_timer(wm, win, sfile->smoothscroll_timer);
+ sfile->smoothscroll_timer = NULL;
+}
+
+/**
+ * Set the renaming-state to #FILE_PARAMS_RENAME_POSTSCROLL_PENDING and trigger the smooth-scroll
+ * timer. To be used right after a file was renamed.
+ * Note that the caller is responsible for setting the correct rename-file info
+ * (#FileSelectParams.renamefile or #FileSelectParams.rename_id).
+ */
+void file_params_invoke_rename_postscroll(wmWindowManager *wm, wmWindow *win, SpaceFile *sfile)
+{
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+
+ params->rename_flag = FILE_PARAMS_RENAME_POSTSCROLL_PENDING;
+
+ if (sfile->smoothscroll_timer != NULL) {
+ file_params_smoothscroll_timer_clear(wm, win, sfile);
+ }
+ sfile->smoothscroll_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 1000.0);
+ sfile->scroll_offset = 0;
+}
+
+/**
+ * To be executed whenever renaming ends (successfully or not).
+ */
+void file_params_rename_end(wmWindowManager *wm,
+ wmWindow *win,
+ SpaceFile *sfile,
+ FileDirEntry *rename_file)
+{
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+
+ filelist_entry_select_set(
+ sfile->files, rename_file, FILE_SEL_REMOVE, FILE_SEL_EDITING, CHECK_ALL);
+
+ /* Ensure smooth-scroll timer is active, even if not needed, because that way rename state is
+ * handled properly. */
+ file_params_invoke_rename_postscroll(wm, win, sfile);
+ /* Also always activate the rename file, even if renaming was cancelled. */
+ file_params_renamefile_activate(sfile, params);
+}
+
+void file_params_renamefile_clear(FileSelectParams *params)
+{
+ params->renamefile[0] = '\0';
+ params->rename_id = NULL;
+ params->rename_flag = 0;
+}
+
+static int file_params_find_renamed(const FileSelectParams *params, struct FileList *filelist)
+{
+ /* Find the file either through the local ID/asset it represents or its relative path. */
+ return (params->rename_id != NULL) ? filelist_file_find_id(filelist, params->rename_id) :
+ filelist_file_find_path(filelist, params->renamefile);
+}
+
/**
* Helper used by both main update code, and smooth-scroll timer,
* to try to enable rename editing from #FileSelectParams.renamefile name.
@@ -1243,28 +1308,33 @@ void file_params_renamefile_activate(SpaceFile *sfile, FileSelectParams *params)
return;
}
- BLI_assert(params->renamefile[0] != '\0');
+ BLI_assert(params->renamefile[0] != '\0' || params->rename_id != NULL);
- const int idx = filelist_file_findpath(sfile->files, params->renamefile);
+ const int idx = file_params_find_renamed(params, sfile->files);
if (idx >= 0) {
FileDirEntry *file = filelist_file(sfile->files, idx);
BLI_assert(file != NULL);
+ params->active_file = idx;
+ filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL);
+
if ((params->rename_flag & FILE_PARAMS_RENAME_PENDING) != 0) {
filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL);
params->rename_flag = FILE_PARAMS_RENAME_ACTIVE;
}
else if ((params->rename_flag & FILE_PARAMS_RENAME_POSTSCROLL_PENDING) != 0) {
- filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
- params->renamefile[0] = '\0';
+ file_select_deselect_all(sfile, FILE_SEL_SELECTED);
+ filelist_entry_select_set(
+ sfile->files, file, FILE_SEL_ADD, FILE_SEL_SELECTED | FILE_SEL_HIGHLIGHTED, CHECK_ALL);
+ params->active_file = idx;
+ file_params_renamefile_clear(params);
params->rename_flag = FILE_PARAMS_RENAME_POSTSCROLL_ACTIVE;
}
}
/* File listing is now async, only reset renaming if matching entry is not found
* when file listing is not done. */
else if (filelist_is_ready(sfile->files)) {
- params->renamefile[0] = '\0';
- params->rename_flag = 0;
+ file_params_renamefile_clear(params);
}
}
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 12bc0a68ca6..05d484d8e2e 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -32,6 +32,7 @@
#include "BKE_appdir.h"
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_main.h"
#include "BKE_screen.h"
#include "RNA_access.h"
@@ -206,7 +207,7 @@ static void file_exit(wmWindowManager *wm, ScrArea *area)
sfile->previews_timer = NULL;
}
- ED_fileselect_exit(wm, NULL, sfile);
+ ED_fileselect_exit(wm, sfile);
}
static SpaceLink *file_duplicate(SpaceLink *sl)
@@ -360,7 +361,7 @@ static void file_refresh(const bContext *C, ScrArea *area)
sfile->recentnr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_RECENT, params->dir);
if (filelist_needs_force_reset(sfile->files)) {
- filelist_readjob_stop(wm, CTX_data_scene(C));
+ filelist_readjob_stop(sfile->files, wm);
filelist_clear(sfile->files);
}
@@ -429,10 +430,10 @@ static void file_reset_filelist_showing_main_data(ScrArea *area, SpaceFile *sfil
}
}
-static void file_listener(const wmSpaceTypeListenerParams *params)
+static void file_listener(const wmSpaceTypeListenerParams *listener_params)
{
- ScrArea *area = params->area;
- wmNotifier *wmn = params->notifier;
+ ScrArea *area = listener_params->area;
+ wmNotifier *wmn = listener_params->notifier;
SpaceFile *sfile = (SpaceFile *)area->spacedata.first;
/* context changes */
@@ -469,10 +470,19 @@ static void file_listener(const wmSpaceTypeListenerParams *params)
break;
case NC_ID: {
switch (wmn->action) {
- case NA_RENAME:
+ case NA_RENAME: {
+ const ID *active_file_id = ED_fileselect_active_asset_get(sfile);
+ /* If a renamed ID is active in the file browser, update scrolling to keep it in view. */
+ if (active_file_id && (wmn->reference == active_file_id)) {
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ params->rename_id = active_file_id;
+ file_params_invoke_rename_postscroll(G_MAIN->wm.first, listener_params->window, sfile);
+ }
+
/* Force list to update sorting (with a full reset for now). */
file_reset_filelist_showing_main_data(area, sfile);
break;
+ }
}
break;
}
@@ -508,10 +518,10 @@ static void file_main_region_init(wmWindowManager *wm, ARegion *region)
WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
}
-static void file_main_region_listener(const wmRegionListenerParams *params)
+static void file_main_region_listener(const wmRegionListenerParams *listener_params)
{
- ARegion *region = params->region;
- wmNotifier *wmn = params->notifier;
+ ARegion *region = listener_params->region;
+ wmNotifier *wmn = listener_params->notifier;
/* context changes */
switch (wmn->category) {
@@ -675,6 +685,7 @@ static void file_operatortypes(void)
WM_operatortype_append(FILE_OT_bookmark_move);
WM_operatortype_append(FILE_OT_reset_recent);
WM_operatortype_append(FILE_OT_hidedot);
+ WM_operatortype_append(FILE_OT_associate_blend);
WM_operatortype_append(FILE_OT_filenum);
WM_operatortype_append(FILE_OT_directory_new);
WM_operatortype_append(FILE_OT_delete);
@@ -715,14 +726,14 @@ static void file_tools_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void file_tools_region_listener(const wmRegionListenerParams *UNUSED(params))
+static void file_tools_region_listener(const wmRegionListenerParams *UNUSED(listener_params))
{
}
-static void file_tool_props_region_listener(const wmRegionListenerParams *params)
+static void file_tool_props_region_listener(const wmRegionListenerParams *listener_params)
{
- const wmNotifier *wmn = params->notifier;
- ARegion *region = params->region;
+ const wmNotifier *wmn = listener_params->notifier;
+ ARegion *region = listener_params->region;
switch (wmn->category) {
case NC_ID:
@@ -788,10 +799,10 @@ static void file_execution_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void file_ui_region_listener(const wmRegionListenerParams *params)
+static void file_ui_region_listener(const wmRegionListenerParams *listener_params)
{
- ARegion *region = params->region;
- wmNotifier *wmn = params->notifier;
+ ARegion *region = listener_params->region;
+ wmNotifier *wmn = listener_params->notifier;
/* context changes */
switch (wmn->category) {
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index d88bf8750c2..ec5f443e2dc 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -1337,8 +1337,8 @@ static void do_graph_region_modifier_buttons(bContext *C, void *UNUSED(arg), int
{
switch (event) {
case B_FMODIFIER_REDRAW: /* XXX this should send depsgraph updates too */
- WM_event_add_notifier(
- C, NC_ANIMATION, NULL); /* XXX need a notifier specially for F-Modifiers */
+ /* XXX: need a notifier specially for F-Modifiers */
+ WM_event_add_notifier(C, NC_ANIMATION, NULL);
break;
}
}
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index c5358cdfa5b..56592cbbd1b 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -414,7 +414,7 @@ static bool draw_fcurve_handles_check(SpaceGraph *sipo, FCurve *fcu)
}
/* draw lines for F-Curve handles only (this is only done in EditMode)
- * note: draw_fcurve_handles_check must be checked before running this. */
+ * NOTE: draw_fcurve_handles_check must be checked before running this. */
static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu)
{
int sel, b;
@@ -1251,7 +1251,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
float x = driver->curval;
float y = fcu->curval * unitfac;
- /* only draw indicators if the point is in range*/
+ /* Only draw indicators if the point is in range. */
if (x >= v2d->cur.xmin) {
float co[2];
@@ -1428,7 +1428,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region)
height = ACHANNEL_TOT_HEIGHT(ac, items);
v2d->tot.ymin = -height;
- /* loop through channels, and set up drawing depending on their type */
+ /* Loop through channels, and set up drawing depending on their type. */
{ /* first pass: just the standard GL-drawing for backdrop + text */
size_t channel_index = 0;
float ymax = ACHANNEL_FIRST_TOP(ac);
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index a2e812a4ed1..6f1b0bb0d7d 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -1481,7 +1481,7 @@ static void setipo_graph_keys(bAnimContext *ac, short mode)
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* Loop through setting BezTriple interpolation
- * Note: we do not supply KeyframeEditData to the looper yet.
+ * NOTE: we do not supply KeyframeEditData to the looper yet.
* Currently that's not necessary here.
*/
for (ale = anim_data.first; ale; ale = ale->next) {
@@ -1558,7 +1558,7 @@ static void seteasing_graph_keys(bAnimContext *ac, short mode)
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* Loop through setting BezTriple easing.
- * Note: we do not supply KeyframeEditData to the looper yet.
+ * NOTE: we do not supply KeyframeEditData to the looper yet.
* Currently that's not necessary here.
*/
for (ale = anim_data.first; ale; ale = ale->next) {
@@ -1636,7 +1636,7 @@ static void sethandles_graph_keys(bAnimContext *ac, short mode)
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* Loop through setting flags for handles.
- * Note: we do not supply KeyframeEditData to the looper yet.
+ * NOTE: we do not supply KeyframeEditData to the looper yet.
* Currently that's not necessary here.
*/
for (ale = anim_data.first; ale; ale = ale->next) {
@@ -3007,7 +3007,7 @@ static int graph_driver_delete_invalid_exec(bContext *C, wmOperator *op)
WM_report(RPT_INFO, "No drivers deleted");
}
- /* Successful or not?*/
+ /* Successful or not? */
if (!ok) {
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 4ab4ef518fb..1421be41124 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -167,7 +167,7 @@ static void nearest_fcurve_vert_store(ListBase *matches,
}
}
else if (fpt) {
- /* TODO... */
+ /* TODO: support #FPoint. */
}
}
@@ -257,7 +257,7 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L
}
}
else if (fcu->fpt) {
- /* TODO; do this for samples too */
+ /* TODO: do this for samples too. */
}
/* un-apply NLA mapping from all the keyframes */
@@ -512,16 +512,19 @@ static rctf initialize_box_select_coords(const bAnimContext *ac, const rctf *rec
return rectf;
}
-static ListBase initialize_box_select_anim_data(const SpaceGraph *sipo, bAnimContext *ac)
+static int initialize_animdata_selection_filter(const SpaceGraph *sipo)
{
- ListBase anim_data = {NULL, NULL};
-
int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
if (sipo->flag & SIPO_SELCUVERTSONLY) {
filter |= ANIMFILTER_FOREDIT | ANIMFILTER_SELEDIT;
}
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ return filter;
+}
+static ListBase initialize_box_select_anim_data(const int filter, bAnimContext *ac)
+{
+ ListBase anim_data = {NULL, NULL};
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
return anim_data;
}
@@ -573,8 +576,11 @@ static void initialize_box_select_key_editing_data(const SpaceGraph *sipo,
* which means that they may be inadvertently moved as well. However, incl_handles overrides
* this, and allow handles to be considered independently too.
* Also, for convenience, handles should get same status as keyframe (if it was within bounds).
+ *
+ * This function returns true if there was any change in the selection of a key (selecting or
+ * deselecting any key returns true, otherwise it returns false).
*/
-static void box_select_graphkeys(bAnimContext *ac,
+static bool box_select_graphkeys(bAnimContext *ac,
const rctf *rectf_view,
short mode,
short selectmode,
@@ -583,20 +589,24 @@ static void box_select_graphkeys(bAnimContext *ac,
{
const rctf rectf = initialize_box_select_coords(ac, rectf_view);
SpaceGraph *sipo = (SpaceGraph *)ac->sl;
- ListBase anim_data = initialize_box_select_anim_data(sipo, ac);
+ const int filter = initialize_animdata_selection_filter(sipo);
+ ListBase anim_data = initialize_box_select_anim_data(filter, ac);
rctf scaled_rectf;
KeyframeEditData ked;
int mapping_flag;
initialize_box_select_key_editing_data(
sipo, incl_handles, mode, ac, data, &scaled_rectf, &ked, &mapping_flag);
- /* Get beztriple editing/validation funcs. */
+ /* Get beztriple editing/validation funcs. */
const KeyframeEditFunc select_cb = ANIM_editkeyframes_select(selectmode);
const KeyframeEditFunc ok_cb = ANIM_editkeyframes_ok(mode);
/* Try selecting the keyframes. */
bAnimListElem *ale = NULL;
+ /* This variable will be set to true if any key is selected or deselected. */
+ bool any_key_selection_changed = false;
+
/* First loop over data, doing box select. try selecting keys only. */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
@@ -634,7 +644,7 @@ static void box_select_graphkeys(bAnimContext *ac,
if (ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, ok_cb, NULL)) {
/* select keyframes that are in the appropriate places */
ANIM_fcurve_keyframes_loop(&ked, fcu, ok_cb, select_cb, NULL);
-
+ any_key_selection_changed = true;
/* Only change selection of channel when the visibility of keyframes
* doesn't depend on this. */
if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
@@ -653,6 +663,143 @@ static void box_select_graphkeys(bAnimContext *ac,
/* Cleanup. */
ANIM_animdata_freelist(&anim_data);
+
+ return any_key_selection_changed;
+}
+
+/* This function is used to set all the keyframes of a given curve as selectable
+ * by the "select_cb" function inside of "box_select_graphcurves".
+ */
+static short ok_bezier_always_ok(KeyframeEditData *UNUSED(ked), BezTriple *UNUSED(bezt))
+{
+ return KEYFRAME_OK_KEY | KEYFRAME_OK_H1 | KEYFRAME_OK_H2;
+}
+
+#define ABOVE 1
+#define INSIDE 0
+#define BELOW -1
+static int rectf_curve_zone_y(
+ FCurve *fcu, const rctf *rectf, const float offset, const float unit_scale, const float eval_x)
+{
+ const float fcurve_y = (evaluate_fcurve(fcu, eval_x) + offset) * unit_scale;
+ return fcurve_y < rectf->ymin ? BELOW : fcurve_y <= rectf->ymax ? INSIDE : ABOVE;
+}
+
+/* Checks whether the given rectangle intersects the given fcurve's calculated curve (i.e. not
+ * only keyframes, but also all the interpolated values). This is done by sampling the curve at
+ * different points between the xmin and the xmax of the rectangle.
+ */
+static bool rectf_curve_intersection(
+ const float offset, const float unit_scale, const rctf *rectf, AnimData *adt, FCurve *fcu)
+{
+ /* 30 sampling points. This worked well in tests. */
+ int num_steps = 30;
+
+ /* Remap the range at which to evaluate the fcurves. This enables us to avoid remapping
+ * the keys themselves. */
+ const float mapped_max = BKE_nla_tweakedit_remap(adt, rectf->xmax, NLATIME_CONVERT_UNMAP);
+ const float mapped_min = BKE_nla_tweakedit_remap(adt, rectf->xmin, NLATIME_CONVERT_UNMAP);
+ const float eval_step = (mapped_max - mapped_min) / num_steps;
+
+ /* Sample points on the given fcurve in the interval defined by the
+ * mapped_min and mapped_max of the selected rectangle.
+ * For each point, check if it is inside of the selection box. If it is, then select
+ * all the keyframes of the curve, the curve, and stop the loop.
+ */
+ struct {
+ float eval_x;
+ int zone;
+ } cur, prev;
+
+ prev.eval_x = mapped_min;
+ prev.zone = rectf_curve_zone_y(fcu, rectf, offset, unit_scale, prev.eval_x);
+ if (prev.zone == INSIDE) {
+ return true;
+ }
+
+ while (num_steps--) {
+ cur.eval_x = prev.eval_x + eval_step;
+ cur.zone = rectf_curve_zone_y(fcu, rectf, offset, unit_scale, cur.eval_x);
+ if (cur.zone != prev.zone) {
+ return true;
+ }
+
+ prev = cur;
+ }
+ return false;
+}
+#undef ABOVE
+#undef INSIDE
+#undef BELOW
+
+/* Perform a box selection of the curves themselves. This means this function tries
+ * to select a curve by sampling it at various points instead of trying to select the
+ * keyframes directly.
+ * The selection actions done to a curve are actually done on all the keyframes of the curve.
+ * NOTE: This function is only called if no keyframe is in the selection area.
+ */
+static void box_select_graphcurves(bAnimContext *ac,
+ const rctf *rectf_view,
+ const short mode,
+ const short selectmode,
+ const bool incl_handles,
+ void *data)
+{
+ const SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ const int filter = initialize_animdata_selection_filter(sipo);
+ ListBase anim_data = initialize_box_select_anim_data(filter, ac);
+ rctf scaled_rectf;
+ KeyframeEditData ked;
+ int mapping_flag;
+ initialize_box_select_key_editing_data(
+ sipo, incl_handles, mode, ac, data, &scaled_rectf, &ked, &mapping_flag);
+
+ FCurve *last_selected_curve = NULL;
+
+ /* Go through all the curves and try selecting them. This function is only called
+ * if no keyframe is in the selection area, so we only have to check if the curve
+ * intersects the area in order to check if the selection/deselection must happen.
+ */
+
+ LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ FCurve *fcu = (FCurve *)ale->key_data;
+ float offset;
+ const float unit_scale = ANIM_unit_mapping_get_factor(
+ ac->scene, ale->id, fcu, mapping_flag, &offset);
+
+ const rctf rectf = initialize_box_select_coords(ac, rectf_view);
+
+ /* scaled_rectf is declared at the top of the block because it is required by the
+ * initialize_box_select_key_editing_data function (which does
+ * data_xxx->rectf_scaled = scaled_rectf). The below assignment therefore modifies the
+ * data we use to iterate over the curves (ked).
+ */
+ scaled_rectf.xmin = rectf.xmin;
+ scaled_rectf.xmax = rectf.xmax;
+ scaled_rectf.ymin = rectf.ymin / unit_scale - offset;
+ scaled_rectf.ymax = rectf.ymax / unit_scale - offset;
+
+ const KeyframeEditFunc select_cb = ANIM_editkeyframes_select(selectmode);
+ if (rectf_curve_intersection(offset, unit_scale, &rectf, adt, fcu)) {
+ if ((selectmode & SELECT_ADD) || (selectmode & SELECT_REPLACE)) {
+ fcu->flag |= FCURVE_SELECTED;
+ last_selected_curve = fcu;
+ }
+ else {
+ fcu->flag &= ~FCURVE_SELECTED;
+ }
+ ANIM_fcurve_keyframes_loop(&ked, fcu, ok_bezier_always_ok, select_cb, NULL);
+ }
+ }
+
+ /* Make sure that one of the selected curves is active in the end. */
+ if (last_selected_curve != NULL) {
+ ANIM_set_active_channel(
+ ac, ac->data, ac->datatype, filter, last_selected_curve, ANIMTYPE_FCURVE);
+ }
+
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
@@ -726,7 +873,12 @@ static int graphkeys_box_select_exec(bContext *C, wmOperator *op)
BLI_rctf_rcti_copy(&rect_fl, &rect);
/* Apply box_select action. */
- box_select_graphkeys(&ac, &rect_fl, mode, selectmode, incl_handles, NULL);
+ const bool any_key_selection_changed = box_select_graphkeys(
+ &ac, &rect_fl, mode, selectmode, incl_handles, NULL);
+ const bool use_curve_selection = RNA_boolean_get(op->ptr, "use_curve_selection");
+ if (use_curve_selection && !any_key_selection_changed) {
+ box_select_graphcurves(&ac, &rect_fl, mode, selectmode, incl_handles, NULL);
+ }
/* Send notifier that keyframe selection has changed. */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
@@ -767,6 +919,14 @@ void GRAPH_OT_select_box(wmOperatorType *ot)
ot->srna, "tweak", 0, "Tweak", "Operator has been activated using a tweak event");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(
+ ot->srna,
+ "use_curve_selection",
+ 1,
+ "Select Curves",
+ "Allow selecting all the keyframes of a curve by selecting the calculated fcurve");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
WM_operator_properties_gesture_box(ot);
WM_operator_properties_select_operation_simple(ot);
}
@@ -815,7 +975,13 @@ static int graphkeys_lassoselect_exec(bContext *C, wmOperator *op)
BLI_rctf_rcti_copy(&rect_fl, &rect);
/* Apply box_select action. */
- box_select_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_LASSO, selectmode, incl_handles, &data_lasso);
+ const bool any_key_selection_changed = box_select_graphkeys(
+ &ac, &rect_fl, BEZT_OK_REGION_LASSO, selectmode, incl_handles, &data_lasso);
+ const bool use_curve_selection = RNA_boolean_get(op->ptr, "use_curve_selection");
+ if (use_curve_selection && !any_key_selection_changed) {
+ box_select_graphcurves(
+ &ac, &rect_fl, BEZT_OK_REGION_LASSO, selectmode, incl_handles, &data_lasso);
+ }
MEM_freeN((void *)data_lasso.mcoords);
@@ -845,6 +1011,13 @@ void GRAPH_OT_select_lasso(wmOperatorType *ot)
/* Properties. */
WM_operator_properties_gesture_lasso(ot);
WM_operator_properties_select_operation_simple(ot);
+ PropertyRNA *prop = RNA_def_boolean(
+ ot->srna,
+ "use_curve_selection",
+ 1,
+ "Select Curves",
+ "Allow selecting all the keyframes of a curve by selecting the curve itself");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ------------------- */
@@ -894,7 +1067,12 @@ static int graph_circle_select_exec(bContext *C, wmOperator *op)
}
/* Apply box_select action. */
- box_select_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_CIRCLE, selectmode, incl_handles, &data);
+ const bool any_key_selection_changed = box_select_graphkeys(
+ &ac, &rect_fl, BEZT_OK_REGION_CIRCLE, selectmode, incl_handles, &data);
+ const bool use_curve_selection = RNA_boolean_get(op->ptr, "use_curve_selection");
+ if (use_curve_selection && !any_key_selection_changed) {
+ box_select_graphcurves(&ac, &rect_fl, BEZT_OK_REGION_CIRCLE, selectmode, incl_handles, &data);
+ }
/* Send notifier that keyframe selection has changed. */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
@@ -920,6 +1098,13 @@ void GRAPH_OT_select_circle(wmOperatorType *ot)
/* properties */
WM_operator_properties_gesture_circle(ot);
WM_operator_properties_select_operation_simple(ot);
+ PropertyRNA *prop = RNA_def_boolean(
+ ot->srna,
+ "use_curve_selection",
+ 1,
+ "Select Curves",
+ "Allow selecting all the keyframes of a curve by selecting the curve itself");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ******************** Column Select Operator **************************** */
@@ -946,8 +1131,8 @@ static const EnumPropertyItem prop_column_select_types[] = {
/* ------------------- */
/* Selects all visible keyframes between the specified markers */
-/* TODO, this is almost an _exact_ duplicate of a function of the same name in action_select.c
- * should de-duplicate - campbell */
+/* TODO(campbell): this is almost an _exact_ duplicate of a function of the same name in
+ * action_select.c should de-duplicate. */
static void markers_selectkeys_between(bAnimContext *ac)
{
ListBase anim_data = {NULL, NULL};
@@ -1426,7 +1611,7 @@ void GRAPH_OT_select_leftright(wmOperatorType *ot)
ot->idname = "GRAPH_OT_select_leftright";
ot->description = "Select keyframes to the left or the right of the current frame";
- /* api callbacks */
+ /* api callbacks */
ot->invoke = graphkeys_select_leftright_invoke;
ot->exec = graphkeys_select_leftright_exec;
ot->poll = graphop_visible_keyframes_poll;
@@ -1496,10 +1681,8 @@ static int mouse_graph_keys(bAnimContext *ac,
/* deselect all other keyframes (+ F-Curves too) */
deselect_graph_keys(ac, 0, SELECT_SUBTRACT, true);
- /* deselect other channels too, but only only do this if
- * selection of channel when the visibility of keyframes
- * doesn't depend on this
- */
+ /* Deselect other channels too, but only do this if selection of channel
+ * when the visibility of keyframes doesn't depend on this. */
if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
ANIM_anim_channels_select_set(ac, ACHANNEL_SETFLAG_CLEAR);
}
@@ -1638,7 +1821,6 @@ static int graphkeys_mselect_column(bAnimContext *ac,
KeyframeEditFunc select_cb, ok_cb;
KeyframeEditData ked;
tNearestVertInfo *nvi;
- float selx = (float)ac->scene->r.cfra;
/* find the beztriple that we're selecting, and the handle that was clicked on */
nvi = find_nearest_fcurve_vert(ac, mval);
@@ -1650,7 +1832,7 @@ static int graphkeys_mselect_column(bAnimContext *ac,
/* get frame number on which elements should be selected */
/* TODO: should we restrict to integer frames only? */
- selx = nvi->frame;
+ const float selx = nvi->frame;
if (select_mode != SELECT_REPLACE) {
/* Doesn't need to deselect anything -> Pass. */
@@ -1774,12 +1956,14 @@ void GRAPH_OT_clickselect(wmOperatorType *ot)
/* properties */
WM_operator_properties_generic_select(ot);
+
+ /* Key-map: Enable with `Shift`. */
prop = RNA_def_boolean(ot->srna,
"extend",
0,
"Extend Select",
"Toggle keyframe selection instead of leaving newly selected "
- "keyframes only"); /* SHIFTKEY */
+ "keyframes only");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna,
@@ -1789,19 +1973,18 @@ void GRAPH_OT_clickselect(wmOperatorType *ot)
"Deselect all when nothing under the cursor");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ /* Key-map: Enable with `Alt`. */
prop = RNA_def_boolean(ot->srna,
"column",
0,
"Column Select",
"Select all keyframes that occur on the same frame as the one under "
- "the mouse"); /* ALTKEY */
+ "the mouse");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna,
- "curves",
- 0,
- "Only Curves",
- "Select all the keyframes in the curve"); /* CTRLKEY + ALTKEY */
+ /* Key-map: Enable with `Ctrl-Atl`. */
+ prop = RNA_def_boolean(
+ ot->srna, "curves", 0, "Only Curves", "Select all the keyframes in the curve");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c
index 4174e1c63ae..10629caa8b0 100644
--- a/source/blender/editors/space_graph/graph_slider_ops.c
+++ b/source/blender/editors/space_graph/graph_slider_ops.c
@@ -50,7 +50,7 @@
/* ******************** GRAPH SLIDER OPERATORS ************************* */
/* This file contains a collection of operators to modify keyframes in the graph editor. All
* operators are modal and use a slider that allows the user to define a percentage to modify the
- * operator.*/
+ * operator. */
/* ******************** Decimate Keyframes Operator ************************* */
@@ -91,7 +91,7 @@ typedef struct tDecimateGraphOp {
/** A 0-1 value for determining how much we should decimate. */
PropertyRNA *percentage_prop;
- /** The original bezt curve data (used for restoring fcurves).*/
+ /** The original bezt curve data (used for restoring fcurves). */
ListBase bezt_arr_list;
NumInput num;
@@ -318,7 +318,7 @@ static int graphkeys_decimate_modal(bContext *C, wmOperator *op, const wmEvent *
/* This assumes that we are in "DECIM_RATIO" mode. This is because the error margin is very hard
* and finicky to control with this modal mouse grab method. Therefore, it is expected that the
* error margin mode is not adjusted by the modal operator but instead tweaked via the redo
- * panel.*/
+ * panel. */
tDecimateGraphOp *dgo = op->customdata;
const bool has_numinput = hasNumInput(&dgo->num);
diff --git a/source/blender/editors/space_graph/graph_view.c b/source/blender/editors/space_graph/graph_view.c
index cde0dab3503..31c53cde62c 100644
--- a/source/blender/editors/space_graph/graph_view.c
+++ b/source/blender/editors/space_graph/graph_view.c
@@ -51,7 +51,7 @@
/* *************************** Calculate Range ************************** */
/* Get the min/max keyframes. */
-/* Note: it should return total boundbox, filter for selection only can be argument... */
+/* NOTE: it should return total boundbox, filter for selection only can be argument... */
void get_graph_keyframe_extents(bAnimContext *ac,
float *xmin,
float *xmax,
@@ -137,7 +137,7 @@ void get_graph_keyframe_extents(bAnimContext *ac,
}
}
- /* Ensure that the extents are not too extreme that view implodes...*/
+ /* Ensure that the extents are not too extreme that view implodes. */
if (foundBounds) {
if ((xmin && xmax) && (fabsf(*xmax - *xmin) < 0.001f)) {
*xmin -= 0.0005f;
@@ -269,7 +269,7 @@ static int graphkeys_viewall(bContext *C,
BLI_rctf_scale(&cur_new, 1.1f);
/* Take regions into account, that could block the view.
- * Marker region is supposed to be larger than the scroll-bar, so prioritize it.*/
+ * Marker region is supposed to be larger than the scroll-bar, so prioritize it. */
float pad_top = UI_TIME_SCRUB_MARGIN_Y;
float pad_bottom = BLI_listbase_is_empty(ED_context_get_markers(C)) ? V2D_SCROLL_HANDLE_HEIGHT :
UI_MARKER_MARGIN_Y;
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 9f01773eadf..49966e880d3 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -172,6 +172,8 @@ static SpaceLink *graph_duplicate(SpaceLink *sl)
{
SpaceGraph *sipon = MEM_dupallocN(sl);
+ memset(&sipon->runtime, 0x0, sizeof(sipon->runtime));
+
/* clear or remove stuff from old */
BLI_duplicatelist(&sipon->runtime.ghost_curves, &((SpaceGraph *)sl)->runtime.ghost_curves);
sipon->ads = MEM_dupallocN(sipon->ads);
@@ -227,7 +229,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region)
graph_draw_curves(&ac, sipo, region, 0);
graph_draw_curves(&ac, sipo, region, 1);
- /* XXX the slow way to set tot rect... but for nice sliders needed (ton) */
+ /* XXX(ton): the slow way to set tot rect... but for nice sliders needed. */
get_graph_keyframe_extents(
&ac, &v2d->tot.xmin, &v2d->tot.xmax, &v2d->tot.ymin, &v2d->tot.ymax, false, true);
/* extra offset so that these items are visible */
@@ -586,7 +588,7 @@ static void graph_listener(const wmSpaceTypeListenerParams *params)
ED_area_tag_refresh(area);
break;
case ND_TRANSFORM:
- break; /*do nothing*/
+ break; /* Do nothing. */
default: /* just redrawing the view will do */
ED_area_tag_redraw(area);
@@ -757,7 +759,7 @@ static void graph_refresh(const bContext *C, ScrArea *area)
break;
}
- case SIPO_MODE_DRIVERS: /* drivers only */
+ case SIPO_MODE_DRIVERS: /* Drivers only. */
{
break;
}
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 6fb64de7e85..50b0ea75052 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -511,7 +511,7 @@ static bool ui_imageuser_pass_menu_step(bContext *C, int direction, void *rnd_pt
return false;
}
- /* note, this looks reversed, but matches menu direction */
+ /* NOTE: this looks reversed, but matches menu direction. */
if (direction == -1) {
RenderPass *rp;
int rp_index = iuser->pass + 1;
@@ -1218,11 +1218,12 @@ void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *i
const int len = MAX_IMAGE_INFO_LEN;
int ofs = 0;
- ofs += BLI_snprintf(str + ofs, len - ofs, TIP_("%d x %d, "), ibuf->x, ibuf->y);
+ ofs += BLI_snprintf_rlen(str + ofs, len - ofs, TIP_("%d x %d, "), ibuf->x, ibuf->y);
if (ibuf->rect_float) {
if (ibuf->channels != 4) {
- ofs += BLI_snprintf(str + ofs, len - ofs, TIP_("%d float channel(s)"), ibuf->channels);
+ ofs += BLI_snprintf_rlen(
+ str + ofs, len - ofs, TIP_("%d float channel(s)"), ibuf->channels);
}
else if (ibuf->planes == R_IMF_PLANES_RGBA) {
ofs += BLI_strncpy_rlen(str + ofs, TIP_(" RGBA float"), len - ofs);
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index c26f92c5463..169dafcb8d0 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -51,7 +51,7 @@
#include "WM_api.h"
#include "WM_types.h"
-/* note; image_panel_properties() uses pointer to sima->image directly */
+/* NOTE: image_panel_properties() uses pointer to sima->image directly. */
Image *ED_space_image(SpaceImage *sima)
{
return sima->image;
@@ -64,8 +64,6 @@ void ED_space_image_set(Main *bmain, SpaceImage *sima, Object *obedit, Image *im
sima->pin = true;
}
- /* change the space ima after because uvedit_face_visible_test uses the space ima
- * to check if the face is displayed in UV-localview */
sima->image = ima;
if (ima == NULL || ima->type == IMA_TYPE_R_RESULT || ima->type == IMA_TYPE_COMPOSITE) {
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 6053253790a..6b9821745c7 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1311,7 +1311,6 @@ static int image_open_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
ImageUser *iuser = NULL;
- ImageOpenData *iod = op->customdata;
Image *ima = NULL;
int frame_seq_len = 0;
int frame_ofs = 1;
@@ -1345,7 +1344,7 @@ static int image_open_exec(bContext *C, wmOperator *op)
}
/* hook into UI */
- iod = op->customdata;
+ ImageOpenData *iod = op->customdata;
if (iod->pprop.prop) {
/* when creating new ID blocks, use is already 1, but RNA
@@ -1608,7 +1607,7 @@ static int image_replace_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "filepath", str);
- /* we cant do much if the str is longer than FILE_MAX :/ */
+ /* we can't do much if the str is longer than FILE_MAX :/ */
BLI_strncpy(sima->image->filepath, str, sizeof(sima->image->filepath));
if (sima->image->source == IMA_SRC_GENERATED) {
@@ -2713,10 +2712,10 @@ static int image_flip_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- const bool flip_horizontal = RNA_boolean_get(op->ptr, "use_flip_horizontal");
- const bool flip_vertical = RNA_boolean_get(op->ptr, "use_flip_vertical");
+ const bool use_flip_x = RNA_boolean_get(op->ptr, "use_flip_x");
+ const bool use_flip_y = RNA_boolean_get(op->ptr, "use_flip_y");
- if (!flip_horizontal && !flip_vertical) {
+ if (!use_flip_x && !use_flip_y) {
BKE_image_release_ibuf(ima, ibuf, NULL);
return OPERATOR_FINISHED;
}
@@ -2735,11 +2734,12 @@ static int image_flip_exec(bContext *C, wmOperator *op)
float *orig_float_pixels = MEM_dupallocN(float_pixels);
for (int x = 0; x < size_x; x++) {
+ const int source_pixel_x = use_flip_x ? size_x - x - 1 : x;
for (int y = 0; y < size_y; y++) {
- const int source_pixel_x = flip_horizontal ? size_x - x - 1 : x;
- const int source_pixel_y = flip_vertical ? size_y - y - 1 : y;
+ const int source_pixel_y = use_flip_y ? size_y - y - 1 : y;
- float *source_pixel = &orig_float_pixels[4 * (source_pixel_x + source_pixel_y * size_x)];
+ const float *source_pixel =
+ &orig_float_pixels[4 * (source_pixel_x + source_pixel_y * size_x)];
float *target_pixel = &float_pixels[4 * (x + y * size_x)];
copy_v4_v4(target_pixel, source_pixel);
@@ -2755,11 +2755,12 @@ static int image_flip_exec(bContext *C, wmOperator *op)
char *char_pixels = (char *)ibuf->rect;
char *orig_char_pixels = MEM_dupallocN(char_pixels);
for (int x = 0; x < size_x; x++) {
+ const int source_pixel_x = use_flip_x ? size_x - x - 1 : x;
for (int y = 0; y < size_y; y++) {
- const int source_pixel_x = flip_horizontal ? size_x - x - 1 : x;
- const int source_pixel_y = flip_vertical ? size_y - y - 1 : y;
+ const int source_pixel_y = use_flip_y ? size_y - y - 1 : y;
- char *source_pixel = &orig_char_pixels[4 * (source_pixel_x + source_pixel_y * size_x)];
+ const char *source_pixel =
+ &orig_char_pixels[4 * (source_pixel_x + source_pixel_y * size_x)];
char *target_pixel = &char_pixels[4 * (x + y * size_x)];
copy_v4_v4_char(target_pixel, source_pixel);
@@ -2805,10 +2806,9 @@ void IMAGE_OT_flip(wmOperatorType *ot)
/* properties */
PropertyRNA *prop;
prop = RNA_def_boolean(
- ot->srna, "use_flip_horizontal", false, "Horizontal", "Flip the image horizontally");
+ ot->srna, "use_flip_x", false, "Horizontal", "Flip the image horizontally");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(
- ot->srna, "use_flip_vertical", false, "Vertical", "Flip the image vertically");
+ prop = RNA_def_boolean(ot->srna, "use_flip_y", false, "Vertical", "Flip the image vertically");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
/* flags */
@@ -3871,7 +3871,7 @@ static void tile_fill_init(PointerRNA *ptr, Image *ima, ImageTile *tile)
/* Acquire ibuf to get the default values.
* If the specified tile has no ibuf, try acquiring the main tile instead
- * (unless the specified tile already was the main tile).*/
+ * (unless the specified tile already was the main tile). */
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
if (ibuf == NULL && (tile != NULL) && (tile->tile_number != 1001)) {
ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c
index feee268c6d3..cc6effd0f71 100644
--- a/source/blender/editors/space_image/image_undo.c
+++ b/source/blender/editors/space_image/image_undo.c
@@ -293,8 +293,9 @@ static void ptile_restore_runtime_list(ListBase *paint_tiles)
SWAP(uint *, ptile->rect.uint, tmpibuf->rect);
}
- BKE_image_free_gputextures(
- image); /* force OpenGL reload (maybe partial update will operate better?) */
+ /* Force OpenGL reload (maybe partial update will operate better?) */
+ BKE_image_free_gputextures(image);
+
if (ibuf->rect_float) {
ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */
}
@@ -1005,7 +1006,7 @@ void ED_image_undosys_type(UndoType *ut)
* specific case, see `image_undosys_step_encode` code. We cannot specify
* `UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE` though, as it can be called with a NULL context by
* current code. */
- ut->flags = 0;
+ ut->flags = UNDOTYPE_FLAG_DECODE_ACTIVE_STEP;
ut->step_size = sizeof(ImageUndoStep);
}
@@ -1040,7 +1041,7 @@ ListBase *ED_image_paint_tile_list_get(void)
return &us->paint_tiles;
}
-/* restore painting image to previous state. Used for anchored and drag-dot style brushes*/
+/* Restore painting image to previous state. Used for anchored and drag-dot style brushes. */
void ED_image_undo_restore(UndoStep *us)
{
ListBase *paint_tiles = &((ImageUndoStep *)us)->paint_tiles;
diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c
index be3b60d581b..9524c2a1d8a 100644
--- a/source/blender/editors/space_info/info_draw.c
+++ b/source/blender/editors/space_info/info_draw.c
@@ -134,14 +134,12 @@ static void report_textview_end(TextViewContext *UNUSED(tvc))
static int report_textview_step(TextViewContext *tvc)
{
/* simple case, but no newline support */
- const Report *report = tvc->iter;
-
if (tvc->iter_char_begin <= 0) {
tvc->iter = (void *)((Link *)tvc->iter)->prev;
if (tvc->iter && report_textview_skip__internal(tvc)) {
tvc->iter_tmp++;
- report = tvc->iter;
+ const Report *report = tvc->iter;
tvc->iter_char_end = report->len; /* reset start */
report_textview_init__internal(tvc);
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index aaf9852e212..94e53958524 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -564,12 +564,11 @@ void FILE_OT_find_missing_files(wmOperatorType *ot)
/** \name Report Box Operator
* \{ */
-/* Hard to decide whether to keep this as an operator,
- * or turn it into a hardcoded ui control feature,
- * handling TIMER events for all regions in interface_handlers.c
+/* NOTE(matt): Hard to decide whether to keep this as an operator,
+ * or turn it into a hard_coded UI control feature,
+ * handling TIMER events for all regions in `interface_handlers.c`.
* Not sure how good that is to be accessing UI data from
- * inactive regions, so use this for now. --matt
- */
+ * inactive regions, so use this for now. */
#define INFO_TIMEOUT 5.0f
#define ERROR_TIMEOUT 10.0f
diff --git a/source/blender/editors/space_info/info_report.c b/source/blender/editors/space_info/info_report.c
index 7dd8382c8ef..1062b76b1df 100644
--- a/source/blender/editors/space_info/info_report.c
+++ b/source/blender/editors/space_info/info_report.c
@@ -102,7 +102,7 @@ int info_report_mask(const SpaceInfo *UNUSED(sinfo))
static int report_replay_exec(bContext *C, wmOperator *UNUSED(op))
{
- /* TODO, get this working again! */
+ /* TODO: get this working again! */
#if 0
SpaceInfo *sc = CTX_wm_space_info(C);
ReportList *reports = CTX_wm_reports(C);
@@ -360,7 +360,7 @@ void INFO_OT_report_delete(wmOperatorType *ot)
ot->exec = report_delete_exec;
/* flags */
- /*ot->flag = OPTYPE_REGISTER;*/
+ // ot->flag = OPTYPE_REGISTER;
/* properties */
}
@@ -404,7 +404,7 @@ void INFO_OT_report_copy(wmOperatorType *ot)
ot->exec = report_copy_exec;
/* flags */
- /*ot->flag = OPTYPE_REGISTER;*/
+ // ot->flag = OPTYPE_REGISTER;
/* properties */
}
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 0bdfceb36b6..d7671a372c6 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -31,6 +31,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h"
#include "BLF_api.h"
@@ -63,6 +64,8 @@
#include "ED_info.h"
+#include "WM_api.h"
+
#include "UI_resources.h"
#include "GPU_capabilities.h"
@@ -93,7 +96,7 @@ typedef struct SceneStatsFmt {
char totgpstroke[MAX_INFO_NUM_LEN], totgppoint[MAX_INFO_NUM_LEN];
} SceneStatsFmt;
-static bool stats_mesheval(Mesh *me_eval, bool is_selected, SceneStats *stats)
+static bool stats_mesheval(const Mesh *me_eval, bool is_selected, SceneStats *stats)
{
if (me_eval == NULL) {
return false;
@@ -123,12 +126,19 @@ static bool stats_mesheval(Mesh *me_eval, bool is_selected, SceneStats *stats)
return true;
}
-static void stats_object(Object *ob, SceneStats *stats, GSet *objects_gset)
+static void stats_object(Object *ob,
+ const View3D *v3d_local,
+ SceneStats *stats,
+ GSet *objects_gset)
{
if ((ob->base_flag & BASE_VISIBLE_VIEWLAYER) == 0) {
return;
}
+ if (v3d_local && !BKE_object_is_visible_in_viewport(v3d_local, ob)) {
+ return;
+ }
+
const bool is_selected = (ob->base_flag & BASE_SELECTED) != 0;
stats->totobj++;
@@ -139,8 +149,8 @@ static void stats_object(Object *ob, SceneStats *stats, GSet *objects_gset)
switch (ob->type) {
case OB_MESH: {
/* we assume evaluated mesh is already built, this strictly does stats now. */
- Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
- if (!BLI_gset_add(objects_gset, me_eval)) {
+ const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
+ if (!BLI_gset_add(objects_gset, (void *)me_eval)) {
break;
}
stats_mesheval(me_eval, is_selected, stats);
@@ -155,8 +165,8 @@ static void stats_object(Object *ob, SceneStats *stats, GSet *objects_gset)
case OB_SURF:
case OB_CURVE:
case OB_FONT: {
- Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
- if ((me_eval != NULL) && !BLI_gset_add(objects_gset, me_eval)) {
+ const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
+ if ((me_eval != NULL) && !BLI_gset_add(objects_gset, (void *)me_eval)) {
break;
}
@@ -169,7 +179,7 @@ static void stats_object(Object *ob, SceneStats *stats, GSet *objects_gset)
int totv = 0, totf = 0, tottri = 0;
if (ob->runtime.curve_cache && ob->runtime.curve_cache->disp.first) {
- /* Note: We only get the same curve_cache for instances of the same curve/font/...
+ /* NOTE: We only get the same curve_cache for instances of the same curve/font/...
* For simple linked duplicated objects, each has its own dispList. */
if (!BLI_gset_add(objects_gset, ob->runtime.curve_cache)) {
break;
@@ -334,7 +344,7 @@ static void stats_object_edit(Object *obedit, SceneStats *stats)
}
}
-static void stats_object_pose(Object *ob, SceneStats *stats)
+static void stats_object_pose(const Object *ob, SceneStats *stats)
{
if (ob->pose) {
bArmature *arm = ob->data;
@@ -351,16 +361,13 @@ static void stats_object_pose(Object *ob, SceneStats *stats)
}
}
-static bool stats_is_object_dynamic_topology_sculpt(Object *ob)
+static bool stats_is_object_dynamic_topology_sculpt(const Object *ob)
{
- if (ob == NULL) {
- return false;
- }
- const eObjectMode object_mode = ob->mode;
- return ((object_mode & OB_MODE_SCULPT) && ob->sculpt && ob->sculpt->bm);
+ BLI_assert(ob->mode & OB_MODE_SCULPT);
+ return (ob->sculpt && ob->sculpt->bm);
}
-static void stats_object_sculpt(Object *ob, SceneStats *stats)
+static void stats_object_sculpt(const Object *ob, SceneStats *stats)
{
SculptSession *ss = ob->sculpt;
@@ -386,81 +393,118 @@ static void stats_object_sculpt(Object *ob, SceneStats *stats)
}
/* Statistics displayed in info header. Called regularly on scene changes. */
-static void stats_update(Depsgraph *depsgraph, ViewLayer *view_layer)
+static void stats_update(Depsgraph *depsgraph,
+ ViewLayer *view_layer,
+ View3D *v3d_local,
+ SceneStats *stats)
{
- SceneStats stats = {0};
- Object *ob = OBACT(view_layer);
- Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
+ const Object *ob = OBACT(view_layer);
+ const Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
+
+ memset(stats, 0x0, sizeof(*stats));
if (obedit) {
- /* Edit Mode */
+ /* Edit Mode. */
FOREACH_OBJECT_BEGIN (view_layer, ob_iter) {
if (ob_iter->base_flag & BASE_VISIBLE_VIEWLAYER) {
- if (ob_iter->mode == OB_MODE_EDIT) {
- stats_object_edit(ob_iter, &stats);
- stats.totobjsel++;
+ if (ob_iter->mode & OB_MODE_EDIT) {
+ stats_object_edit(ob_iter, stats);
+ stats->totobjsel++;
}
- stats.totobj++;
+ else {
+ /* Skip hidden objects in local view that are not in edit-mode,
+ * an exception for edit-mode, in most other modes these would be considered hidden. */
+ if ((v3d_local && !BKE_object_is_visible_in_viewport(v3d_local, ob_iter))) {
+ continue;
+ }
+ }
+ stats->totobj++;
}
}
FOREACH_OBJECT_END;
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
- /* Pose Mode */
- stats_object_pose(ob, &stats);
+ /* Pose Mode. */
+ FOREACH_OBJECT_BEGIN (view_layer, ob_iter) {
+ if (ob_iter->base_flag & BASE_VISIBLE_VIEWLAYER) {
+ if (ob_iter->mode & OB_MODE_POSE) {
+ stats_object_pose(ob_iter, stats);
+ stats->totobjsel++;
+ }
+ else {
+ /* See comment for edit-mode. */
+ if ((v3d_local && !BKE_object_is_visible_in_viewport(v3d_local, ob_iter))) {
+ continue;
+ }
+ }
+ stats->totobj++;
+ }
+ }
+ FOREACH_OBJECT_END;
}
- else if (stats_is_object_dynamic_topology_sculpt(ob)) {
- /* Dynamic topology. Do not count all vertices, dynamic topology stats are initialized later as
- * part of sculpt stats. */
+ else if (ob && (ob->mode & OB_MODE_SCULPT)) {
+ /* Sculpt Mode. */
+ if (stats_is_object_dynamic_topology_sculpt(ob)) {
+ /* Dynamic topology. Do not count all vertices,
+ * dynamic topology stats are initialized later as part of sculpt stats. */
+ }
+ else {
+ /* When dynamic topology is not enabled both sculpt stats and scene stats are collected. */
+ stats_object_sculpt(ob, stats);
+ }
}
else {
- /* Objects */
+ /* Objects. */
GSet *objects_gset = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob_iter) {
- stats_object(ob_iter, &stats, objects_gset);
+ stats_object(ob_iter, v3d_local, stats, objects_gset);
}
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
BLI_gset_free(objects_gset, NULL);
}
-
- if (ob && (ob->mode & OB_MODE_SCULPT)) {
- /* Sculpt Mode. When dynamic topology is not enabled both sculpt stats and scene stats are
- * collected. */
- stats_object_sculpt(ob, &stats);
- }
-
- if (!view_layer->stats) {
- view_layer->stats = MEM_callocN(sizeof(SceneStats), "SceneStats");
- }
-
- *(view_layer->stats) = stats;
}
-void ED_info_stats_clear(ViewLayer *view_layer)
+void ED_info_stats_clear(wmWindowManager *wm, ViewLayer *view_layer)
{
if (view_layer->stats) {
MEM_freeN(view_layer->stats);
view_layer->stats = NULL;
}
+
+ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
+ ViewLayer *view_layer_test = WM_window_get_active_view_layer(win);
+ if (view_layer != view_layer_test) {
+ continue;
+ }
+ const bScreen *screen = WM_window_get_active_screen(win);
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ if (area->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = area->spacedata.first;
+ if (v3d->localvd) {
+ MEM_SAFE_FREE(v3d->runtime.local_stats);
+ }
+ }
+ }
+ }
}
-static bool format_stats(Main *bmain,
- Scene *scene,
- ViewLayer *view_layer,
- SceneStatsFmt *stats_fmt)
+static bool format_stats(
+ Main *bmain, Scene *scene, ViewLayer *view_layer, View3D *v3d_local, SceneStatsFmt *stats_fmt)
{
/* Create stats if they don't already exist. */
- if (!view_layer->stats) {
- /* Do not not access dependency graph if interface is marked as locked. */
+ SceneStats **stats_p = (v3d_local) ? &v3d_local->runtime.local_stats : &view_layer->stats;
+ if (*stats_p == NULL) {
+ /* Don't access dependency graph if interface is marked as locked. */
wmWindowManager *wm = bmain->wm.first;
if (wm->is_interface_locked) {
return false;
}
Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer);
- stats_update(depsgraph, view_layer);
+ *stats_p = MEM_mallocN(sizeof(SceneStats), __func__);
+ stats_update(depsgraph, view_layer, v3d_local, *stats_p);
}
- SceneStats *stats = view_layer->stats;
+ SceneStats *stats = *stats_p;
/* Generate formatted numbers. */
#define SCENE_STATS_FMT_INT(_id) BLI_str_format_uint64_grouped(stats_fmt->_id, stats->_id)
@@ -505,14 +549,14 @@ static void get_stats_string(
LayerCollection *layer_collection = view_layer->active_collection;
if (object_mode == OB_MODE_OBJECT) {
- *ofs += BLI_snprintf(info + *ofs,
- len - *ofs,
- "%s | ",
- BKE_collection_ui_name_get(layer_collection->collection));
+ *ofs += BLI_snprintf_rlen(info + *ofs,
+ len - *ofs,
+ "%s | ",
+ BKE_collection_ui_name_get(layer_collection->collection));
}
if (ob) {
- *ofs += BLI_snprintf(info + *ofs, len - *ofs, "%s | ", ob->id.name + 2);
+ *ofs += BLI_snprintf_rlen(info + *ofs, len - *ofs, "%s | ", ob->id.name + 2);
}
if (obedit) {
@@ -521,72 +565,72 @@ static void get_stats_string(
}
if (obedit->type == OB_MESH) {
- *ofs += BLI_snprintf(info + *ofs,
- len - *ofs,
- TIP_("Verts:%s/%s | Edges:%s/%s | Faces:%s/%s | Tris:%s"),
- stats_fmt->totvertsel,
- stats_fmt->totvert,
- stats_fmt->totedgesel,
- stats_fmt->totedge,
- stats_fmt->totfacesel,
- stats_fmt->totface,
- stats_fmt->tottri);
+ *ofs += BLI_snprintf_rlen(info + *ofs,
+ len - *ofs,
+ TIP_("Verts:%s/%s | Edges:%s/%s | Faces:%s/%s | Tris:%s"),
+ stats_fmt->totvertsel,
+ stats_fmt->totvert,
+ stats_fmt->totedgesel,
+ stats_fmt->totedge,
+ stats_fmt->totfacesel,
+ stats_fmt->totface,
+ stats_fmt->tottri);
}
else if (obedit->type == OB_ARMATURE) {
- *ofs += BLI_snprintf(info + *ofs,
- len - *ofs,
- TIP_("Joints:%s/%s | Bones:%s/%s"),
- stats_fmt->totvertsel,
- stats_fmt->totvert,
- stats_fmt->totbonesel,
- stats_fmt->totbone);
+ *ofs += BLI_snprintf_rlen(info + *ofs,
+ len - *ofs,
+ TIP_("Joints:%s/%s | Bones:%s/%s"),
+ stats_fmt->totvertsel,
+ stats_fmt->totvert,
+ stats_fmt->totbonesel,
+ stats_fmt->totbone);
}
else {
- *ofs += BLI_snprintf(
+ *ofs += BLI_snprintf_rlen(
info + *ofs, len - *ofs, TIP_("Verts:%s/%s"), stats_fmt->totvertsel, stats_fmt->totvert);
}
}
else if (ob && (object_mode & OB_MODE_POSE)) {
- *ofs += BLI_snprintf(
+ *ofs += BLI_snprintf_rlen(
info + *ofs, len - *ofs, TIP_("Bones:%s/%s"), stats_fmt->totbonesel, stats_fmt->totbone);
}
else if ((ob) && (ob->type == OB_GPENCIL)) {
- *ofs += BLI_snprintf(info + *ofs,
- len - *ofs,
- TIP_("Layers:%s | Frames:%s | Strokes:%s | Points:%s"),
- stats_fmt->totgplayer,
- stats_fmt->totgpframe,
- stats_fmt->totgpstroke,
- stats_fmt->totgppoint);
+ *ofs += BLI_snprintf_rlen(info + *ofs,
+ len - *ofs,
+ TIP_("Layers:%s | Frames:%s | Strokes:%s | Points:%s"),
+ stats_fmt->totgplayer,
+ stats_fmt->totgpframe,
+ stats_fmt->totgpstroke,
+ stats_fmt->totgppoint);
}
else if (ob && (object_mode & OB_MODE_SCULPT)) {
if (stats_is_object_dynamic_topology_sculpt(ob)) {
- *ofs += BLI_snprintf(info + *ofs,
- len - *ofs,
- TIP_("Verts:%s | Tris:%s"),
- stats_fmt->totvert,
- stats_fmt->tottri);
+ *ofs += BLI_snprintf_rlen(info + *ofs,
+ len - *ofs,
+ TIP_("Verts:%s | Tris:%s"),
+ stats_fmt->totvert,
+ stats_fmt->tottri);
}
else {
- *ofs += BLI_snprintf(info + *ofs,
- len - *ofs,
- TIP_("Verts:%s/%s | Faces:%s/%s"),
- stats_fmt->totvertsculpt,
- stats_fmt->totvert,
- stats_fmt->totfacesculpt,
- stats_fmt->totface);
+ *ofs += BLI_snprintf_rlen(info + *ofs,
+ len - *ofs,
+ TIP_("Verts:%s/%s | Faces:%s/%s"),
+ stats_fmt->totvertsculpt,
+ stats_fmt->totvert,
+ stats_fmt->totfacesculpt,
+ stats_fmt->totface);
}
}
else {
- *ofs += BLI_snprintf(info + *ofs,
- len - *ofs,
- TIP_("Verts:%s | Faces:%s | Tris:%s"),
- stats_fmt->totvert,
- stats_fmt->totface,
- stats_fmt->tottri);
+ *ofs += BLI_snprintf_rlen(info + *ofs,
+ len - *ofs,
+ TIP_("Verts:%s | Faces:%s | Tris:%s"),
+ stats_fmt->totvert,
+ stats_fmt->totface,
+ stats_fmt->tottri);
}
- *ofs += BLI_snprintf(
+ *ofs += BLI_snprintf_rlen(
info + *ofs, len - *ofs, TIP_(" | Objects:%s/%s"), stats_fmt->totobjsel, stats_fmt->totobj);
}
@@ -605,7 +649,7 @@ static const char *info_statusbar_string(Main *bmain,
/* Scene statistics. */
if (statusbar_flag & STATUSBAR_SHOW_STATS) {
SceneStatsFmt stats_fmt;
- if (format_stats(bmain, scene, view_layer, &stats_fmt)) {
+ if (format_stats(bmain, scene, view_layer, NULL, &stats_fmt)) {
get_stats_string(info + ofs, len, &ofs, view_layer, &stats_fmt);
}
}
@@ -613,11 +657,11 @@ static const char *info_statusbar_string(Main *bmain,
/* Memory status. */
if (statusbar_flag & STATUSBAR_SHOW_MEMORY) {
if (info[0]) {
- ofs += BLI_snprintf(info + ofs, len - ofs, " | ");
+ ofs += BLI_snprintf_rlen(info + ofs, len - ofs, " | ");
}
uintptr_t mem_in_use = MEM_get_memory_in_use();
BLI_str_format_byte_unit(formatted_mem, mem_in_use, false);
- ofs += BLI_snprintf(info + ofs, len, TIP_("Memory: %s"), formatted_mem);
+ ofs += BLI_snprintf_rlen(info + ofs, len, TIP_("Memory: %s"), formatted_mem);
}
/* GPU VRAM status. */
@@ -627,27 +671,27 @@ static const char *info_statusbar_string(Main *bmain,
float gpu_total_gb = gpu_tot_mem_kb / 1048576.0f;
float gpu_free_gb = gpu_free_mem_kb / 1048576.0f;
if (info[0]) {
- ofs += BLI_snprintf(info + ofs, len - ofs, " | ");
+ ofs += BLI_snprintf_rlen(info + ofs, len - ofs, " | ");
}
if (gpu_free_mem_kb && gpu_tot_mem_kb) {
- ofs += BLI_snprintf(info + ofs,
- len - ofs,
- TIP_("VRAM: %.1f/%.1f GiB"),
- gpu_total_gb - gpu_free_gb,
- gpu_total_gb);
+ ofs += BLI_snprintf_rlen(info + ofs,
+ len - ofs,
+ TIP_("VRAM: %.1f/%.1f GiB"),
+ gpu_total_gb - gpu_free_gb,
+ gpu_total_gb);
}
else {
/* Can only show amount of GPU VRAM available. */
- ofs += BLI_snprintf(info + ofs, len - ofs, TIP_("VRAM: %.1f GiB Free"), gpu_free_gb);
+ ofs += BLI_snprintf_rlen(info + ofs, len - ofs, TIP_("VRAM: %.1f GiB Free"), gpu_free_gb);
}
}
/* Blender version. */
if (statusbar_flag & STATUSBAR_SHOW_VERSION) {
if (info[0]) {
- ofs += BLI_snprintf(info + ofs, len - ofs, " | ");
+ ofs += BLI_snprintf_rlen(info + ofs, len - ofs, " | ");
}
- ofs += BLI_snprintf(info + ofs, len - ofs, TIP_("%s"), BKE_blender_version_string());
+ ofs += BLI_snprintf_rlen(info + ofs, len - ofs, TIP_("%s"), BKE_blender_version_string());
}
return info;
@@ -682,18 +726,24 @@ static void stats_row(int col1,
BLF_draw_default(col2, *y, 0.0f, values, sizeof(values));
}
+/**
+ * \param v3d_local: Pass this argument to calculate view-port local statistics.
+ * Note that this must only be used for local-view, otherwise report specific statistics
+ * will be written into the global scene statistics giving incorrect results.
+ */
void ED_info_draw_stats(
- Main *bmain, Scene *scene, ViewLayer *view_layer, int x, int *y, int height)
+ Main *bmain, Scene *scene, ViewLayer *view_layer, View3D *v3d_local, int x, int *y, int height)
{
+ BLI_assert(v3d_local == NULL || v3d_local->localvd != NULL);
SceneStatsFmt stats_fmt;
- if (!format_stats(bmain, scene, view_layer, &stats_fmt)) {
+ if (!format_stats(bmain, scene, view_layer, v3d_local, &stats_fmt)) {
return;
}
Object *ob = OBACT(view_layer);
Object *obedit = OBEDIT_FROM_OBACT(ob);
eObjectMode object_mode = ob ? ob->mode : OB_MODE_OBJECT;
- const int font_id = BLF_default();
+ const int font_id = BLF_set_default();
UI_FontThemeColor(font_id, TH_TEXT_HI);
BLF_enable(font_id, BLF_SHADOW);
@@ -747,8 +797,8 @@ void ED_info_draw_stats(
}
if (obedit) {
+ stats_row(col1, labels[OBJ], col2, stats_fmt.totobjsel, stats_fmt.totobj, y, height);
if (obedit->type == OB_MESH) {
- stats_row(col1, labels[OBJ], col2, stats_fmt.totobjsel, stats_fmt.totobj, y, height);
stats_row(col1, labels[VERTS], col2, stats_fmt.totvertsel, stats_fmt.totvert, y, height);
stats_row(col1, labels[EDGES], col2, stats_fmt.totedgesel, stats_fmt.totedge, y, height);
stats_row(col1, labels[FACES], col2, stats_fmt.totfacesel, stats_fmt.totface, y, height);
@@ -763,6 +813,7 @@ void ED_info_draw_stats(
}
}
else if (ob && (object_mode & OB_MODE_POSE)) {
+ stats_row(col1, labels[OBJ], col2, stats_fmt.totobjsel, stats_fmt.totobj, y, height);
stats_row(col1, labels[BONES], col2, stats_fmt.totbonesel, stats_fmt.totbone, y, height);
}
else if ((ob) && (ob->type == OB_GPENCIL)) {
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index aef59e89325..e656155fb13 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -353,7 +353,7 @@ int textview_draw(TextViewContext *tvc,
tds.lheight = tvc->lheight;
tds.row_vpadding = tvc->row_vpadding;
tds.lofs = -BLF_descender(font_id);
- /* Note, scroll bar must be already subtracted. */
+ /* NOTE: scroll bar must be already subtracted. */
tds.columns = (tvc->draw_rect.xmax - tvc->draw_rect.xmin) / tds.cwidth;
/* Avoid divide by zero on small windows. */
if (tds.columns < 1) {
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index f2cea23af76..0498964c549 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -288,14 +288,14 @@ static int mouse_nla_channels(
/* button region... */
if (x >= (v2d->cur.xmax - NLACHANNEL_BUTTON_WIDTH)) {
if (nlaedit_is_tweakmode_on(ac) == 0) {
- /* 'push-down' action - only usable when not in TweakMode */
+ /* 'push-down' action - only usable when not in tweak-mode */
/* TODO: make this use the operator instead of calling the function directly
* however, calling the operator requires that we supply the args,
* and that works with proper buttons only */
BKE_nla_action_pushdown(adt, ID_IS_OVERRIDE_LIBRARY(ale->id));
}
else {
- /* when in tweakmode, this button becomes the toggle for mapped editing */
+ /* When in tweak-mode, this button becomes the toggle for mapped editing. */
adt->flag ^= ADT_NLA_EDIT_NOMAP;
}
@@ -308,13 +308,13 @@ static int mouse_nla_channels(
/* NOTE: rest of NLA-Action name doubles for operating on the AnimData block
* - this is useful when there's no clear divider, and makes more sense in
* the case of users trying to use this to change actions
- * - in tweakmode, clicking here gets us out of tweakmode, as changing selection
- * while in tweakmode is really evil!
+ * - in tweak-mode, clicking here gets us out of tweak-mode, as changing selection
+ * while in tweak-mode is really evil!
* - we disable "solo" flags too, to make it easier to work with stashed actions
* with less trouble
*/
if (nlaedit_is_tweakmode_on(ac)) {
- /* exit tweakmode immediately */
+ /* Exit tweak-mode immediately. */
nlaedit_disable_tweakmode(ac, true);
/* changes to NLA-Action occurred */
@@ -515,7 +515,7 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* 'push-down' action - only usable when not in TweakMode */
+ /* 'push-down' action - only usable when not in Tweak-mode. */
BKE_nla_action_pushdown(adt, ID_IS_OVERRIDE_LIBRARY(id));
struct Main *bmain = CTX_data_main(C);
@@ -874,7 +874,7 @@ static int nlaedit_objects_add_exec(bContext *C, wmOperator *UNUSED(op))
/* operate on selected objects... */
CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
/* ensure that object has AnimData... that's all */
- BKE_animdata_add_id(&ob->id);
+ BKE_animdata_ensure_id(&ob->id);
}
CTX_DATA_END;
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 7d4011e0812..f9fb386095d 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -127,8 +127,8 @@ static void nla_action_draw_keyframes(
immRectf(pos_id, f1, ymin + 2, f2, ymax - 2);
immUnbindProgram();
- /* count keys before drawing */
- /* Note: It's safe to cast DLRBT_Tree, as it's designed to degrade down to a ListBase */
+ /* Count keys before drawing. */
+ /* NOTE: It's safe to cast #DLRBT_Tree, as it's designed to degrade down to a #ListBase. */
uint key_len = BLI_listbase_count((ListBase *)&keys);
if (key_len > 0) {
@@ -734,7 +734,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region)
int height = NLACHANNEL_TOT_HEIGHT(ac, items);
v2d->tot.ymin = -height;
- /* loop through channels, and set up drawing depending on their type */
+ /* Loop through channels, and set up drawing depending on their type. */
float ymax = NLACHANNEL_FIRST_TOP(ac);
for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next, ymax -= NLACHANNEL_STEP(snla)) {
@@ -894,7 +894,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *region)
/* set blending again, as may not be set in previous step */
GPU_blend(GPU_BLEND_ALPHA);
- /* loop through channels, and set up drawing depending on their type */
+ /* Loop through channels, and set up drawing depending on their type. */
for (ale = anim_data.first; ale;
ale = ale->next, ymax -= NLACHANNEL_STEP(snla), channel_index++) {
float ymin = ymax - NLACHANNEL_HEIGHT(snla);
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index dd381cc92fb..56efcd8571f 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -65,7 +65,7 @@
#include "UI_view2d.h"
#include "nla_intern.h" /* own include */
-#include "nla_private.h" /* FIXME... maybe this shouldn't be included? */
+#include "nla_private.h" /* FIXME: maybe this shouldn't be included? */
/* -------------------------------------------------------------------- */
/** \name Public Utilities
@@ -135,7 +135,7 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op)
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ale->data;
- /* try entering tweakmode if valid */
+ /* Try entering tweak-mode if valid. */
ok |= BKE_nla_tweakmode_enter(adt);
/* mark the active track as being "solo"? */
@@ -154,9 +154,8 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op)
ANIM_animdata_update(&ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
- /* if we managed to enter tweakmode on at least one AnimData block,
- * set the flag for this in the active scene and send notifiers
- */
+ /* If we managed to enter tweak-mode on at least one AnimData block,
+ * set the flag for this in the active scene and send notifiers. */
if (ac.scene && ok) {
/* set editing flag */
ac.scene->flag |= SCE_NLA_EDIT_ON;
@@ -206,7 +205,7 @@ void NLA_OT_tweakmode_enter(wmOperatorType *ot)
/** \name Disable Tweak-Mode Operator
* \{ */
-/* NLA Editor internal API function for exiting tweakmode */
+/* NLA Editor internal API function for exiting tweak-mode. */
bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo)
{
ListBase anim_data = {NULL, NULL};
@@ -232,7 +231,7 @@ bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo)
BKE_nlatrack_solo_toggle(adt, NULL);
}
- /* to be sure that we're doing everything right, just exit tweakmode... */
+ /* To be sure that we're doing everything right, just exit tweak-mode. */
BKE_nla_tweakmode_exit(adt);
ale->update |= ANIM_UPDATE_DEPS;
@@ -242,7 +241,7 @@ bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo)
ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
- /* if we managed to enter tweakmode on at least one AnimData block,
+ /* if we managed to enter tweak-mode on at least one AnimData block,
* set the flag for this in the active scene and send notifiers
*/
if (ac->scene) {
@@ -257,7 +256,7 @@ bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo)
return true;
}
-/* exit tweakmode operator callback */
+/* Exit tweak-mode operator callback. */
static int nlaedit_disable_tweakmode_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
@@ -1157,7 +1156,7 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *op)
NlaStrip *strip, *nstrip, *next;
NlaTrack *track;
- /* Note: We allow this operator in override context because it is almost always (from possible
+ /* NOTE: We allow this operator in override context because it is almost always (from possible
* default user interactions) paired with the transform one, which will ensure that the new
* strip ends up in a valid (local) track. */
@@ -1397,7 +1396,7 @@ static void nlaedit_split_strip_actclip(
nstrip->start = splitframe;
if ((splitaframe > strip->actstart) && (splitaframe < strip->actend)) {
- /* only do this if we're splitting down the middle... */
+ /* only do this if we're splitting down the middle... */
strip->actend = splitaframe;
nstrip->actstart = splitaframe;
}
@@ -1412,7 +1411,7 @@ static void nlaedit_split_strip_actclip(
/* split a given Meta strip */
static void nlaedit_split_strip_meta(NlaTrack *nlt, NlaStrip *strip)
{
- /* simply ungroup it for now... */
+ /* simply ungroup it for now... */
BKE_nlastrips_clear_metastrip(&nlt->strips, strip);
}
@@ -1528,7 +1527,7 @@ static int nlaedit_toggle_mute_exec(bContext *C, wmOperator *UNUSED(op))
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
- /* for every selected strip, toggle muting */
+ /* For every selected strip, toggle muting. */
for (strip = nlt->strips.first; strip; strip = strip->next) {
if (strip->flag & NLASTRIP_FLAG_SELECT) {
/* just flip the mute flag for now */
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index 631dc2e550c..28f194877fa 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -39,17 +39,16 @@
/* ************************** poll callbacks for operators **********************************/
-/* tweakmode is NOT enabled */
+/* Tweak-mode is NOT enabled. */
bool nlaop_poll_tweakmode_off(bContext *C)
{
Scene *scene;
/* for now, we check 2 things:
* 1) active editor must be NLA
- * 2) tweakmode is currently set as a 'per-scene' flag
+ * 2) tweak-mode is currently set as a 'per-scene' flag
* so that it will affect entire NLA data-sets,
- * but not all AnimData blocks will be in tweakmode for
- * various reasons
+ * but not all AnimData blocks will be in tweak-mode for various reasons.
*/
if (ED_operator_nla_active(C) == 0) {
return 0;
@@ -63,17 +62,16 @@ bool nlaop_poll_tweakmode_off(bContext *C)
return 1;
}
-/* tweakmode IS enabled */
+/* Tweak-mode IS enabled. */
bool nlaop_poll_tweakmode_on(bContext *C)
{
Scene *scene;
/* for now, we check 2 things:
* 1) active editor must be NLA
- * 2) tweakmode is currently set as a 'per-scene' flag
+ * 2) tweak-mode is currently set as a 'per-scene' flag
* so that it will affect entire NLA data-sets,
- * but not all AnimData blocks will be in tweakmode for
- * various reasons
+ * but not all AnimData blocks will be in tweak-mode for various reasons.
*/
if (ED_operator_nla_active(C) == 0) {
return 0;
@@ -87,7 +85,7 @@ bool nlaop_poll_tweakmode_on(bContext *C)
return 1;
}
-/* is tweakmode enabled - for use in NLA operator code */
+/* is tweak-mode enabled - for use in NLA operator code */
bool nlaedit_is_tweakmode_on(bAnimContext *ac)
{
if (ac && ac->scene) {
diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c
index 87ad09fe2f9..246c3e0156a 100644
--- a/source/blender/editors/space_nla/nla_select.c
+++ b/source/blender/editors/space_nla/nla_select.c
@@ -453,7 +453,7 @@ static void nlaedit_select_leftright(bContext *C,
Scene *scene = ac->scene;
float xmin, xmax;
- /* if currently in tweakmode, exit tweakmode first */
+ /* if currently in tweak-mode, exit tweak-mode first */
if (scene->flag & SCE_NLA_EDIT_ON) {
WM_operator_name_call(C, "NLA_OT_tweakmode_exit", WM_OP_EXEC_DEFAULT, NULL);
}
@@ -577,7 +577,7 @@ void NLA_OT_select_leftright(wmOperatorType *ot)
ot->idname = "NLA_OT_select_leftright";
ot->description = "Select strips to the left or the right of the current frame";
- /* api callbacks */
+ /* api callbacks */
ot->invoke = nlaedit_select_leftright_invoke;
ot->exec = nlaedit_select_leftright_exec;
ot->poll = ED_operator_nla_active;
@@ -612,7 +612,7 @@ static int mouse_nla_strips(bContext *C,
nlaedit_strip_at_region_position(ac, mval[0], mval[1], &ale, &strip);
- /* if currently in tweakmode, exit tweakmode before changing selection states
+ /* if currently in tweak-mode, exit tweak-mode before changing selection states
* now that we've found our target...
*/
if (scene->flag & SCE_NLA_EDIT_ON) {
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index bc043a4e665..80d3b43bf6b 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -24,6 +24,7 @@ set(INC
../../compositor
../../depsgraph
../../draw
+ ../../functions
../../gpu
../../imbuf
../../makesdna
@@ -37,20 +38,19 @@ set(INC
set(SRC
- drawnode.c
- node_add.c
- node_buttons.c
+ drawnode.cc
+ node_add.cc
node_draw.cc
- node_edit.c
+ node_edit.cc
node_geometry_attribute_search.cc
node_gizmo.c
- node_group.c
+ node_group.cc
node_ops.c
- node_relationships.c
- node_select.c
- node_templates.c
- node_toolbar.c
- node_view.c
+ node_relationships.cc
+ node_select.cc
+ node_templates.cc
+ node_toolbar.cc
+ node_view.cc
space_node.c
node_intern.h
@@ -78,4 +78,20 @@ if(WITH_OPENSUBDIV)
add_definitions(-DWITH_OPENSUBDIV)
endif()
+if(WITH_TBB)
+ add_definitions(-DWITH_TBB)
+ if(WIN32)
+ # TBB includes Windows.h which will define min/max macros
+ # that will collide with the stl versions.
+ add_definitions(-DNOMINMAX)
+ endif()
+ list(APPEND INC_SYS
+ ${TBB_INCLUDE_DIRS}
+ )
+
+ list(APPEND LIB
+ ${TBB_LIBRARIES}
+ )
+endif()
+
blender_add_lib(bf_editor_space_node "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.cc
index 6b4366b2966..243652da608 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.cc
@@ -95,9 +95,9 @@ static void node_socket_button_label(bContext *UNUSED(C),
static void node_buts_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
/* first output stores value */
- bNodeSocket *output = node->outputs.first;
+ bNodeSocket *output = (bNodeSocket *)node->outputs.first;
PointerRNA sockptr;
RNA_pointer_create(ptr->owner_id, &RNA_NodeSocket, output, &sockptr);
@@ -106,15 +106,15 @@ static void node_buts_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *p
static void node_buts_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
/* first output stores value */
- bNodeSocket *output = node->outputs.first;
+ bNodeSocket *output = (bNodeSocket *)node->outputs.first;
PointerRNA sockptr;
uiLayout *col;
RNA_pointer_create(ptr->owner_id, &RNA_NodeSocket, output, &sockptr);
col = uiLayoutColumn(layout, false);
- uiTemplateColorPicker(col, &sockptr, "default_value", 1, 0, 0, 0);
+ uiTemplateColorPicker(col, &sockptr, "default_value", true, false, false, false);
uiItemR(col, &sockptr, "default_value", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
}
@@ -129,14 +129,14 @@ static void node_buts_mix_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA
uiItemR(row, ptr, "use_alpha", DEFAULT_FLAGS, "", ICON_IMAGE_RGB_ALPHA);
}
- uiItemR(col, ptr, "use_clamp", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_clamp", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
#if 0
- /* XXX no context access here .. */
- bNode *node = ptr->data;
+ /* XXX no context access here. */
+ bNode *node = (bNode*)ptr->data;
CurveMapping *cumap = node->storage;
if (cumap) {
@@ -156,7 +156,7 @@ static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *pt
static void node_buts_colorramp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiTemplateColorRamp(layout, ptr, "color_ramp", 0);
+ uiTemplateColorRamp(layout, ptr, "color_ramp", false);
}
static void node_buts_curvevec(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -179,8 +179,8 @@ void ED_node_sample_set(const float col[4])
static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- bNode *node = ptr->data;
- CurveMapping *cumap = node->storage;
+ bNode *node = (bNode *)ptr->data;
+ CurveMapping *cumap = (CurveMapping *)node->storage;
if (_sample_col[0] != SAMPLE_FLT_ISNONE) {
cumap->flag |= CUMA_DRAW_SAMPLE;
@@ -198,9 +198,9 @@ static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA
static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
/* first output stores normal */
- bNodeSocket *output = node->outputs.first;
+ bNodeSocket *output = (bNodeSocket *)node->outputs.first;
PointerRNA sockptr;
RNA_pointer_create(ptr->owner_id, &RNA_NodeSocket, output, &sockptr);
@@ -209,7 +209,7 @@ static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *
static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
short multi = (node->id && ((Tex *)node->id)->use_nodes && (node->type != CMP_NODE_TEXTURE) &&
(node->type != TEX_NODE_TEXTURE));
@@ -217,7 +217,7 @@ static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA
uiItemR(layout, ptr, "texture", DEFAULT_FLAGS, "", ICON_NONE);
if (multi) {
- /* Number Drawing not optimal here, better have a list*/
+ /* Number Drawing not optimal here, better have a list. */
uiItemR(layout, ptr, "node_output", DEFAULT_FLAGS, "", ICON_NONE);
}
}
@@ -233,14 +233,14 @@ static void node_shader_buts_map_range(uiLayout *layout, bContext *UNUSED(C), Po
if (!ELEM(RNA_enum_get(ptr, "interpolation_type"),
NODE_MAP_RANGE_SMOOTHSTEP,
NODE_MAP_RANGE_SMOOTHERSTEP)) {
- uiItemR(layout, ptr, "clamp", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "clamp", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
}
static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "use_clamp", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_clamp", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static int node_resize_area_default(bNode *node, int x, int y)
@@ -274,7 +274,7 @@ static int node_resize_area_default(bNode *node, int x, int y)
static void node_draw_buttons_group(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
uiTemplateIDBrowse(
- layout, C, ptr, "node_tree", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, NULL);
+ layout, C, ptr, "node_tree", nullptr, nullptr, nullptr, UI_TEMPLATE_ID_FILTER_ALL, nullptr);
}
/* XXX Does a bounding box update by iterating over all children.
@@ -311,7 +311,7 @@ static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree,
/* first child initializes frame */
if (bbinit) {
- bbinit = 0;
+ bbinit = false;
rect = noderect;
data->flag &= ~NODE_FRAME_RESIZEABLE;
}
@@ -418,9 +418,9 @@ static void node_draw_frame(const bContext *C,
{
/* skip if out of view */
- if (BLI_rctf_isect(&node->totr, &region->v2d.cur, NULL) == false) {
+ if (BLI_rctf_isect(&node->totr, &region->v2d.cur, nullptr) == false) {
UI_block_end(C, node->block);
- node->block = NULL;
+ node->block = nullptr;
return;
}
@@ -462,7 +462,7 @@ static void node_draw_frame(const bContext *C,
UI_block_end(C, node->block);
UI_block_draw(C, node->block);
- node->block = NULL;
+ node->block = nullptr;
}
static int node_resize_area_frame(bNode *node, int x, int y)
@@ -497,7 +497,7 @@ static void node_buts_frame_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA
{
uiItemR(layout, ptr, "label_size", DEFAULT_FLAGS, IFACE_("Label Size"), ICON_NONE);
uiItemR(layout, ptr, "shrink", DEFAULT_FLAGS, IFACE_("Shrink"), ICON_NONE);
- uiItemR(layout, ptr, "text", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "text", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
#define NODE_REROUTE_SIZE 8.0f
@@ -511,11 +511,11 @@ static void node_draw_reroute_prepare(const bContext *UNUSED(C),
node_to_view(node, 0.0f, 0.0f, &locx, &locy);
/* reroute node has exactly one input and one output, both in the same place */
- bNodeSocket *nsock = node->outputs.first;
+ bNodeSocket *nsock = (bNodeSocket *)node->outputs.first;
nsock->locx = locx;
nsock->locy = locy;
- nsock = node->inputs.first;
+ nsock = (bNodeSocket *)node->inputs.first;
nsock->locx = locx;
nsock->locy = locy;
@@ -541,7 +541,7 @@ static void node_draw_reroute(const bContext *C,
if (node->totr.xmax < region->v2d.cur.xmin || node->totr.xmin > region->v2d.cur.xmax ||
node->totr.ymax < region->v2d.cur.ymin || node->totr.ymin > region->v2d.cur.ymax) {
UI_block_end(C, node->block);
- node->block = NULL;
+ node->block = nullptr;
return;
}
@@ -586,12 +586,12 @@ static void node_draw_reroute(const bContext *C,
(int)(rct->ymax),
(short)512,
(short)NODE_DY,
- NULL,
+ nullptr,
0,
0,
0,
0,
- NULL);
+ nullptr);
}
/* only draw input socket. as they all are placed on the same position.
@@ -601,7 +601,7 @@ static void node_draw_reroute(const bContext *C,
UI_block_end(C, node->block);
UI_block_draw(C, node->block);
- node->block = NULL;
+ node->block = nullptr;
}
/* Special tweak area for reroute node.
@@ -612,7 +612,7 @@ static int node_tweak_area_reroute(bNode *node, int x, int y)
/* square of tweak radius */
const float tweak_radius_sq = square_f(24.0f);
- bNodeSocket *sock = node->inputs.first;
+ bNodeSocket *sock = (bNodeSocket *)node->inputs.first;
float dx = sock->locx - x;
float dy = sock->locy - y;
return (dx * dx + dy * dy <= tweak_radius_sq);
@@ -662,28 +662,28 @@ static void node_buts_image_user(uiLayout *layout,
/* don't use iuser->framenr directly
* because it may not be updated if auto-refresh is off */
Scene *scene = CTX_data_scene(C);
- ImageUser *iuser = iuserptr->data;
+ ImageUser *iuser = (ImageUser *)iuserptr->data;
/* Image *ima = imaptr->data; */ /* UNUSED */
char numstr[32];
- const int framenr = BKE_image_user_frame_get(iuser, CFRA, NULL);
+ const int framenr = BKE_image_user_frame_get(iuser, CFRA, nullptr);
BLI_snprintf(numstr, sizeof(numstr), IFACE_("Frame: %d"), framenr);
uiItemL(layout, numstr, ICON_NONE);
}
if (ELEM(source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "frame_duration", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "frame_start", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "frame_offset", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "use_cyclic", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "use_auto_refresh", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "frame_duration", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "frame_start", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "frame_offset", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "use_cyclic", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "use_auto_refresh", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
if (show_layer_selection && RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER &&
RNA_boolean_get(ptr, "has_layers")) {
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "layer", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "layer", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
if (show_color_management) {
@@ -693,7 +693,7 @@ static void node_buts_image_user(uiLayout *layout,
uiItemR(split, &colorspace_settings_ptr, "name", DEFAULT_FLAGS, "", ICON_NONE);
/* Avoid losing changes image is painted. */
- if (BKE_image_is_dirty(imaptr->data)) {
+ if (BKE_image_is_dirty((Image *)imaptr->data)) {
uiLayoutSetEnabled(split, false);
}
}
@@ -701,13 +701,13 @@ static void node_buts_image_user(uiLayout *layout,
static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "vector_type", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "vector_type", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_shader_buts_vector_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "rotation_type", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "invert", DEFAULT_FLAGS, NULL, 0);
+ uiItemR(layout, ptr, "rotation_type", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "invert", DEFAULT_FLAGS, nullptr, 0);
}
static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -717,7 +717,7 @@ static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), Po
static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "vector_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "vector_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiItemR(layout, ptr, "convert_from", DEFAULT_FLAGS, "", ICON_NONE);
uiItemR(layout, ptr, "convert_to", DEFAULT_FLAGS, "", ICON_NONE);
}
@@ -730,7 +730,7 @@ static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), Po
static void node_shader_buts_wireframe(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "use_pixel_size", DEFAULT_FLAGS, NULL, 0);
+ uiItemR(layout, ptr, "use_pixel_size", DEFAULT_FLAGS, nullptr, 0);
}
static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
@@ -745,10 +745,10 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA
"image",
"IMAGE_OT_new",
"IMAGE_OT_open",
- NULL,
+ nullptr,
UI_TEMPLATE_ID_FILTER_ALL,
false,
- NULL);
+ nullptr);
uiItemR(layout, ptr, "interpolation", DEFAULT_FLAGS, "", ICON_NONE);
uiItemR(layout, ptr, "projection", DEFAULT_FLAGS, "", ICON_NONE);
@@ -758,7 +758,7 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA
uiItemR(layout, ptr, "extension", DEFAULT_FLAGS, "", ICON_NONE);
- /* note: image user properties used directly here, unlike compositor image node,
+ /* NOTE: image user properties used directly here, unlike compositor image node,
* which redefines them in the node struct RNA to get proper updates.
*/
node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr, false, true);
@@ -767,7 +767,7 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA
static void node_shader_buts_tex_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user");
- uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0, 0);
+ uiTemplateImage(layout, C, ptr, "image", &iuserptr, false, false);
}
static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, PointerRNA *ptr)
@@ -782,10 +782,10 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin
"image",
"IMAGE_OT_new",
"IMAGE_OT_open",
- NULL,
+ nullptr,
UI_TEMPLATE_ID_FILTER_ALL,
false,
- NULL);
+ nullptr);
uiItemR(layout, ptr, "interpolation", DEFAULT_FLAGS, "", ICON_NONE);
uiItemR(layout, ptr, "projection", DEFAULT_FLAGS, "", ICON_NONE);
@@ -796,7 +796,7 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin
static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user");
- uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0, 0);
+ uiTemplateImage(layout, C, ptr, "image", &iuserptr, false, false);
uiItemR(layout, ptr, "interpolation", DEFAULT_FLAGS, IFACE_("Interpolation"), ICON_NONE);
uiItemR(layout, ptr, "projection", DEFAULT_FLAGS, IFACE_("Projection"), ICON_NONE);
@@ -808,33 +808,33 @@ static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), Poin
if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_PREETHAM) {
uiItemR(layout, ptr, "sun_direction", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "turbidity", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "turbidity", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_HOSEK) {
uiItemR(layout, ptr, "sun_direction", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "turbidity", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "ground_albedo", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "turbidity", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "ground_albedo", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_NISHITA) {
- uiItemR(layout, ptr, "sun_disc", DEFAULT_FLAGS, NULL, 0);
+ uiItemR(layout, ptr, "sun_disc", DEFAULT_FLAGS, nullptr, 0);
uiLayout *col;
if (RNA_boolean_get(ptr, "sun_disc")) {
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "sun_size", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "sun_intensity", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "sun_size", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "sun_intensity", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "sun_elevation", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "sun_rotation", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "sun_elevation", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "sun_rotation", DEFAULT_FLAGS, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "altitude", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "altitude", DEFAULT_FLAGS, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "air_density", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "dust_density", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "ozone_density", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "air_density", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "dust_density", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "ozone_density", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
}
@@ -845,7 +845,7 @@ static void node_shader_buts_tex_gradient(uiLayout *layout, bContext *UNUSED(C),
static void node_shader_buts_tex_magic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "turbulence_depth", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "turbulence_depth", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_shader_buts_tex_brick(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -901,32 +901,33 @@ static void node_shader_buts_tex_pointdensity(uiLayout *layout,
bContext *UNUSED(C),
PointerRNA *ptr)
{
- bNode *node = ptr->data;
- NodeShaderTexPointDensity *shader_point_density = node->storage;
+ bNode *node = (bNode *)ptr->data;
+ NodeShaderTexPointDensity *shader_point_density = (NodeShaderTexPointDensity *)node->storage;
Object *ob = (Object *)node->id;
PointerRNA ob_ptr, obdata_ptr;
RNA_id_pointer_create((ID *)ob, &ob_ptr);
- RNA_id_pointer_create(ob ? (ID *)ob->data : NULL, &obdata_ptr);
+ RNA_id_pointer_create(ob ? (ID *)ob->data : nullptr, &obdata_ptr);
- uiItemR(layout, ptr, "point_source", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- uiItemR(layout, ptr, "object", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "point_source", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "object", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (node->id && shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_PSYS) {
PointerRNA dataptr;
RNA_id_pointer_create((ID *)node->id, &dataptr);
- uiItemPointerR(layout, ptr, "particle_system", &dataptr, "particle_systems", NULL, ICON_NONE);
+ uiItemPointerR(
+ layout, ptr, "particle_system", &dataptr, "particle_systems", nullptr, ICON_NONE);
}
- uiItemR(layout, ptr, "space", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "radius", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "interpolation", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "resolution", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "space", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "radius", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "interpolation", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "resolution", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_PSYS) {
- uiItemR(layout, ptr, "particle_color_source", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "particle_color_source", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
else {
- uiItemR(layout, ptr, "vertex_color_source", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "vertex_color_source", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (shader_point_density->ob_color_source == SHD_POINTDENSITY_COLOR_VERTWEIGHT) {
if (ob_ptr.data) {
uiItemPointerR(
@@ -944,18 +945,18 @@ static void node_shader_buts_tex_pointdensity(uiLayout *layout,
static void node_shader_buts_tex_coord(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "object", DEFAULT_FLAGS, NULL, 0);
- uiItemR(layout, ptr, "from_instancer", DEFAULT_FLAGS, NULL, 0);
+ uiItemR(layout, ptr, "object", DEFAULT_FLAGS, nullptr, 0);
+ uiItemR(layout, ptr, "from_instancer", DEFAULT_FLAGS, nullptr, 0);
}
static void node_shader_buts_bump(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "invert", DEFAULT_FLAGS, NULL, 0);
+ uiItemR(layout, ptr, "invert", DEFAULT_FLAGS, nullptr, 0);
}
static void node_shader_buts_uvmap(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- uiItemR(layout, ptr, "from_instancer", DEFAULT_FLAGS, NULL, 0);
+ uiItemR(layout, ptr, "from_instancer", DEFAULT_FLAGS, nullptr, 0);
if (!RNA_boolean_get(ptr, "from_instancer")) {
PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
@@ -989,7 +990,7 @@ static void node_shader_buts_vertex_color(uiLayout *layout, bContext *C, Pointer
static void node_shader_buts_uvalongstroke(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "use_tips", DEFAULT_FLAGS, NULL, 0);
+ uiItemR(layout, ptr, "use_tips", DEFAULT_FLAGS, nullptr, 0);
}
static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRNA *ptr)
@@ -1036,7 +1037,7 @@ static void node_shader_buts_tangent(uiLayout *layout, bContext *C, PointerRNA *
}
}
else {
- uiItemR(row, ptr, "axis", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, 0);
+ uiItemR(row, ptr, "axis", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, 0);
}
}
@@ -1083,7 +1084,7 @@ static void node_shader_buts_ies(uiLayout *layout, bContext *UNUSED(C), PointerR
uiLayout *row;
row = uiLayoutRow(layout, false);
- uiItemR(row, ptr, "mode", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, ptr, "mode", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
row = uiLayoutRow(layout, true);
@@ -1100,7 +1101,7 @@ static void node_shader_buts_script(uiLayout *layout, bContext *UNUSED(C), Point
uiLayout *row;
row = uiLayoutRow(layout, false);
- uiItemR(row, ptr, "mode", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, ptr, "mode", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
row = uiLayoutRow(layout, true);
@@ -1122,7 +1123,7 @@ static void node_shader_buts_script_ex(uiLayout *layout, bContext *C, PointerRNA
#if 0 /* not implemented yet */
if (RNA_enum_get(ptr, "mode") == NODE_SCRIPT_EXTERNAL) {
- uiItemR(layout, ptr, "use_auto_update", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_auto_update", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
#endif
}
@@ -1139,21 +1140,21 @@ static void node_buts_output_linestyle(uiLayout *layout, bContext *UNUSED(C), Po
col = uiLayoutColumn(layout, false);
row = uiLayoutRow(col, true);
uiItemR(row, ptr, "blend_type", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(col, ptr, "use_clamp", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_clamp", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_shader_buts_bevel(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "samples", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "samples", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_shader_buts_ambient_occlusion(uiLayout *layout,
bContext *UNUSED(C),
PointerRNA *ptr)
{
- uiItemR(layout, ptr, "samples", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "inside", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "only_local", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "samples", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "inside", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "only_local", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_shader_buts_white_noise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1163,7 +1164,7 @@ static void node_shader_buts_white_noise(uiLayout *layout, bContext *UNUSED(C),
static void node_shader_buts_output_aov(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "name", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "name", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
/* only once called */
@@ -1348,17 +1349,17 @@ static void node_buts_image_views(uiLayout *layout,
if (RNA_boolean_get(ptr, "has_views")) {
if (RNA_enum_get(ptr, "view") == 0) {
- uiItemR(col, ptr, "view", DEFAULT_FLAGS, NULL, ICON_CAMERA_STEREO);
+ uiItemR(col, ptr, "view", DEFAULT_FLAGS, nullptr, ICON_CAMERA_STEREO);
}
else {
- uiItemR(col, ptr, "view", DEFAULT_FLAGS, NULL, ICON_SCENE);
+ uiItemR(col, ptr, "view", DEFAULT_FLAGS, nullptr, ICON_SCENE);
}
}
}
static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
PointerRNA iuserptr;
RNA_pointer_create(ptr->owner_id, &RNA_ImageUser, node->storage, &iuserptr);
@@ -1369,10 +1370,10 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *
"image",
"IMAGE_OT_new",
"IMAGE_OT_open",
- NULL,
+ nullptr,
UI_TEMPLATE_ID_FILTER_ALL,
false,
- NULL);
+ nullptr);
if (!node->id) {
return;
}
@@ -1386,20 +1387,29 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *
static void node_composit_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
PointerRNA iuserptr;
RNA_pointer_create(ptr->owner_id, &RNA_ImageUser, node->storage, &iuserptr);
uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
- uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0, 1);
+ uiTemplateImage(layout, C, ptr, "image", &iuserptr, false, true);
}
static void node_composit_buts_viewlayers(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
uiLayout *col, *row;
- uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
+ uiTemplateID(layout,
+ C,
+ ptr,
+ "scene",
+ nullptr,
+ nullptr,
+ nullptr,
+ UI_TEMPLATE_ID_FILTER_ALL,
+ false,
+ nullptr);
if (!node->id) {
return;
@@ -1423,7 +1433,7 @@ static void node_composit_buts_viewlayers(uiLayout *layout, bContext *C, Pointer
PointerRNA op_ptr;
uiItemFullO(
- row, "RENDER_OT_render", "", ICON_RENDER_STILL, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ row, "RENDER_OT_render", "", ICON_RENDER_STILL, nullptr, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
RNA_string_set(&op_ptr, "layer", layer_name);
RNA_string_set(&op_ptr, "scene", scene_name);
}
@@ -1438,19 +1448,19 @@ static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), Point
uiItemR(col, ptr, "filter_type", DEFAULT_FLAGS, "", ICON_NONE);
if (filter != R_FILTER_FAST_GAUSS) {
- uiItemR(col, ptr, "use_variable_size", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_variable_size", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (!reference) {
- uiItemR(col, ptr, "use_bokeh", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_bokeh", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
- uiItemR(col, ptr, "use_gamma_correction", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_gamma_correction", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
- uiItemR(col, ptr, "use_relative", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_relative", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (RNA_boolean_get(ptr, "use_relative")) {
uiItemL(col, IFACE_("Aspect Correction"), ICON_NONE);
row = uiLayoutRow(layout, true);
- uiItemR(row, ptr, "aspect_correction", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, ptr, "aspect_correction", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "factor_x", DEFAULT_FLAGS, IFACE_("X"), ICON_NONE);
@@ -1461,15 +1471,15 @@ static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), Point
uiItemR(col, ptr, "size_x", DEFAULT_FLAGS, IFACE_("X"), ICON_NONE);
uiItemR(col, ptr, "size_y", DEFAULT_FLAGS, IFACE_("Y"), ICON_NONE);
}
- uiItemR(col, ptr, "use_extended_bounds", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_extended_bounds", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_dblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
- uiItemR(layout, ptr, "iterations", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "use_wrap", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "iterations", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "use_wrap", DEFAULT_FLAGS, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Center:"), ICON_NONE);
@@ -1479,13 +1489,13 @@ static void node_composit_buts_dblur(uiLayout *layout, bContext *UNUSED(C), Poin
uiItemS(layout);
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "distance", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "angle", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "distance", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "angle", DEFAULT_FLAGS, nullptr, ICON_NONE);
uiItemS(layout);
- uiItemR(layout, ptr, "spin", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "zoom", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "spin", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "zoom", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_bilateralblur(uiLayout *layout,
@@ -1495,9 +1505,9 @@ static void node_composit_buts_bilateralblur(uiLayout *layout,
uiLayout *col;
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "iterations", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "sigma_color", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "sigma_space", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "iterations", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "sigma_color", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "sigma_space", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_defocus(uiLayout *layout, bContext *C, PointerRNA *ptr)
@@ -1507,27 +1517,36 @@ static void node_composit_buts_defocus(uiLayout *layout, bContext *C, PointerRNA
col = uiLayoutColumn(layout, false);
uiItemL(col, IFACE_("Bokeh Type:"), ICON_NONE);
uiItemR(col, ptr, "bokeh", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(col, ptr, "angle", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "angle", DEFAULT_FLAGS, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "use_gamma_correction", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_gamma_correction", DEFAULT_FLAGS, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, false);
uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_zbuffer") == true);
- uiItemR(col, ptr, "f_stop", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "f_stop", DEFAULT_FLAGS, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "blur_max", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "threshold", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "blur_max", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "threshold", DEFAULT_FLAGS, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "use_preview", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_preview", DEFAULT_FLAGS, nullptr, ICON_NONE);
- uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
+ uiTemplateID(layout,
+ C,
+ ptr,
+ "scene",
+ nullptr,
+ nullptr,
+ nullptr,
+ UI_TEMPLATE_ID_FILTER_ALL,
+ false,
+ nullptr);
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "use_zbuffer", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_zbuffer", DEFAULT_FLAGS, nullptr, ICON_NONE);
sub = uiLayoutColumn(col, false);
uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_zbuffer") == false);
- uiItemR(sub, ptr, "z_scale", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(sub, ptr, "z_scale", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_antialiasing(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1536,9 +1555,9 @@ static void node_composit_buts_antialiasing(uiLayout *layout, bContext *UNUSED(C
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "threshold", 0, NULL, ICON_NONE);
- uiItemR(col, ptr, "contrast_limit", 0, NULL, ICON_NONE);
- uiItemR(col, ptr, "corner_rounding", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "threshold", 0, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "contrast_limit", 0, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "corner_rounding", 0, nullptr, ICON_NONE);
}
/* qdn: glare node */
@@ -1548,29 +1567,30 @@ static void node_composit_buts_glare(uiLayout *layout, bContext *UNUSED(C), Poin
uiItemR(layout, ptr, "quality", DEFAULT_FLAGS, "", ICON_NONE);
if (RNA_enum_get(ptr, "glare_type") != 1) {
- uiItemR(layout, ptr, "iterations", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "iterations", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (RNA_enum_get(ptr, "glare_type") != 0) {
- uiItemR(layout, ptr, "color_modulation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(
+ layout, ptr, "color_modulation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
}
}
- uiItemR(layout, ptr, "mix", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "threshold", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mix", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "threshold", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (RNA_enum_get(ptr, "glare_type") == 2) {
- uiItemR(layout, ptr, "streaks", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "angle_offset", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "streaks", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "angle_offset", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
if (RNA_enum_get(ptr, "glare_type") == 0 || RNA_enum_get(ptr, "glare_type") == 2) {
- uiItemR(layout, ptr, "fade", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "fade", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
if (RNA_enum_get(ptr, "glare_type") == 0) {
- uiItemR(layout, ptr, "use_rotate_45", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_rotate_45", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
}
if (RNA_enum_get(ptr, "glare_type") == 1) {
- uiItemR(layout, ptr, "size", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "size", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
}
@@ -1581,15 +1601,15 @@ static void node_composit_buts_tonemap(uiLayout *layout, bContext *UNUSED(C), Po
col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "tonemap_type", DEFAULT_FLAGS, "", ICON_NONE);
if (RNA_enum_get(ptr, "tonemap_type") == 0) {
- uiItemR(col, ptr, "key", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "offset", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "gamma", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "key", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "offset", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "gamma", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
else {
- uiItemR(col, ptr, "intensity", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "adaptation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "correction", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(col, ptr, "intensity", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "adaptation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "correction", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
}
}
@@ -1598,12 +1618,12 @@ static void node_composit_buts_lensdist(uiLayout *layout, bContext *UNUSED(C), P
uiLayout *col;
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "use_projector", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_projector", DEFAULT_FLAGS, nullptr, ICON_NONE);
col = uiLayoutColumn(col, false);
uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_projector") == false);
- uiItemR(col, ptr, "use_jitter", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "use_fit", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_jitter", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "use_fit", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_vecblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1611,7 +1631,7 @@ static void node_composit_buts_vecblur(uiLayout *layout, bContext *UNUSED(C), Po
uiLayout *col;
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "samples", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "samples", DEFAULT_FLAGS, nullptr, ICON_NONE);
uiItemR(col, ptr, "factor", DEFAULT_FLAGS, IFACE_("Blur"), ICON_NONE);
col = uiLayoutColumn(layout, true);
@@ -1619,7 +1639,7 @@ static void node_composit_buts_vecblur(uiLayout *layout, bContext *UNUSED(C), Po
uiItemR(col, ptr, "speed_min", DEFAULT_FLAGS, IFACE_("Min"), ICON_NONE);
uiItemR(col, ptr, "speed_max", DEFAULT_FLAGS, IFACE_("Max"), ICON_NONE);
- uiItemR(layout, ptr, "use_curved", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_curved", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_filter(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1636,8 +1656,8 @@ static void node_composit_buts_crop(uiLayout *layout, bContext *UNUSED(C), Point
{
uiLayout *col;
- uiItemR(layout, ptr, "use_crop_size", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "relative", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_crop_size", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "relative", DEFAULT_FLAGS, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, true);
if (RNA_boolean_get(ptr, "relative")) {
@@ -1660,8 +1680,8 @@ static void node_composit_buts_splitviewer(uiLayout *layout, bContext *UNUSED(C)
col = uiLayoutColumn(layout, false);
row = uiLayoutRow(col, false);
- uiItemR(row, ptr, "axis", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- uiItemR(col, ptr, "factor", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(row, ptr, "axis", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "factor", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_double_edge_mask(uiLayout *layout,
@@ -1683,7 +1703,7 @@ static void node_composit_buts_map_range(uiLayout *layout, bContext *UNUSED(C),
uiLayout *col;
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "use_clamp", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_clamp", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1691,17 +1711,17 @@ static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C),
uiLayout *sub, *col;
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "offset", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "size", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "offset", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "size", DEFAULT_FLAGS, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "use_min", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_min", DEFAULT_FLAGS, nullptr, ICON_NONE);
sub = uiLayoutColumn(col, false);
uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min"));
uiItemR(sub, ptr, "min", DEFAULT_FLAGS, "", ICON_NONE);
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "use_max", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_max", DEFAULT_FLAGS, nullptr, ICON_NONE);
sub = uiLayoutColumn(col, false);
uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max"));
uiItemR(sub, ptr, "max", DEFAULT_FLAGS, "", ICON_NONE);
@@ -1712,8 +1732,8 @@ static void node_composit_buts_alphaover(uiLayout *layout, bContext *UNUSED(C),
uiLayout *col;
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "use_premultiply", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "premul", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_premultiply", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "premul", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_zcombine(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1721,27 +1741,27 @@ static void node_composit_buts_zcombine(uiLayout *layout, bContext *UNUSED(C), P
uiLayout *col;
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "use_alpha", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "use_antialias_z", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_alpha", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "use_antialias_z", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "distance", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "distance", DEFAULT_FLAGS, nullptr, ICON_NONE);
switch (RNA_enum_get(ptr, "mode")) {
case CMP_NODE_DILATEERODE_DISTANCE_THRESH:
- uiItemR(layout, ptr, "edge", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "edge", DEFAULT_FLAGS, nullptr, ICON_NONE);
break;
case CMP_NODE_DILATEERODE_DISTANCE_FEATHER:
- uiItemR(layout, ptr, "falloff", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "falloff", DEFAULT_FLAGS, nullptr, ICON_NONE);
break;
}
}
static void node_composit_buts_inpaint(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "distance", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "distance", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_despeckle(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1749,8 +1769,8 @@ static void node_composit_buts_despeckle(uiLayout *layout, bContext *UNUSED(C),
uiLayout *col;
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "threshold", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "threshold_neighbor", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "threshold", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "threshold_neighbor", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1758,8 +1778,8 @@ static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C),
uiLayout *col;
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "tolerance", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "falloff", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(col, ptr, "tolerance", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "falloff", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
}
static void node_composit_buts_distance_matte(uiLayout *layout,
@@ -1772,10 +1792,10 @@ static void node_composit_buts_distance_matte(uiLayout *layout,
uiItemL(layout, IFACE_("Color Space:"), ICON_NONE);
row = uiLayoutRow(layout, false);
- uiItemR(row, ptr, "channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, ptr, "channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
- uiItemR(col, ptr, "tolerance", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "falloff", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(col, ptr, "tolerance", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "falloff", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
}
static void node_composit_buts_color_spill(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1784,23 +1804,23 @@ static void node_composit_buts_color_spill(uiLayout *layout, bContext *UNUSED(C)
uiItemL(layout, IFACE_("Despill Channel:"), ICON_NONE);
row = uiLayoutRow(layout, false);
- uiItemR(row, ptr, "channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, ptr, "channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "limit_method", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "limit_method", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (RNA_enum_get(ptr, "limit_method") == 0) {
uiItemL(col, IFACE_("Limiting Channel:"), ICON_NONE);
row = uiLayoutRow(col, false);
- uiItemR(row, ptr, "limit_channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, ptr, "limit_channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
- uiItemR(col, ptr, "ratio", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "use_unspill", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "ratio", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "use_unspill", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (RNA_boolean_get(ptr, "use_unspill") == true) {
- uiItemR(col, ptr, "unspill_red", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "unspill_green", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "unspill_blue", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(col, ptr, "unspill_red", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "unspill_green", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "unspill_blue", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
}
}
@@ -1809,13 +1829,15 @@ static void node_composit_buts_chroma_matte(uiLayout *layout, bContext *UNUSED(C
uiLayout *col;
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "tolerance", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "threshold", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "tolerance", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "threshold", DEFAULT_FLAGS, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, true);
- /*uiItemR(col, ptr, "lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE); Removed for now */
- uiItemR(col, ptr, "gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- /*uiItemR(col, ptr, "shadow_adjust", UI_ITEM_R_SLIDER, NULL, ICON_NONE); Removed for now*/
+ /* Removed for now. */
+ // uiItemR(col, ptr, "lift", UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ /* Removed for now. */
+ // uiItemR(col, ptr, "shadow_adjust", UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
}
static void node_composit_buts_color_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1823,9 +1845,9 @@ static void node_composit_buts_color_matte(uiLayout *layout, bContext *UNUSED(C)
uiLayout *col;
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "color_hue", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "color_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "color_value", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(col, ptr, "color_hue", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "color_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "color_value", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
}
static void node_composit_buts_channel_matte(uiLayout *layout,
@@ -1836,24 +1858,24 @@ static void node_composit_buts_channel_matte(uiLayout *layout,
uiItemL(layout, IFACE_("Color Space:"), ICON_NONE);
row = uiLayoutRow(layout, false);
- uiItemR(row, ptr, "color_space", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, ptr, "color_space", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, false);
uiItemL(col, IFACE_("Key Channel:"), ICON_NONE);
row = uiLayoutRow(col, false);
- uiItemR(row, ptr, "matte_channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, ptr, "matte_channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "limit_method", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "limit_method", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (RNA_enum_get(ptr, "limit_method") == 0) {
uiItemL(col, IFACE_("Limiting Channel:"), ICON_NONE);
row = uiLayoutRow(col, false);
- uiItemR(row, ptr, "limit_channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, ptr, "limit_channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
- uiItemR(col, ptr, "limit_max", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "limit_min", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(col, ptr, "limit_max", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "limit_min", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
}
static void node_composit_buts_luma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1861,19 +1883,19 @@ static void node_composit_buts_luma_matte(uiLayout *layout, bContext *UNUSED(C),
uiLayout *col;
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "limit_max", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(col, ptr, "limit_min", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(col, ptr, "limit_max", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "limit_min", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
}
static void node_composit_buts_map_uv(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "alpha", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "alpha", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_id_mask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "index", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "use_antialiasing", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "index", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "use_antialiasing", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1905,7 +1927,7 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
/* disable stereo output for multilayer, too much work for something that no one will use */
/* if someone asks for that we can implement it */
if (is_multiview) {
- uiTemplateImageFormatViews(layout, &imfptr, NULL);
+ uiTemplateImageFormatViews(layout, &imfptr, nullptr);
}
uiItemS(layout);
@@ -1926,7 +1948,7 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
"layer_slots",
ptr,
"active_input_index",
- NULL,
+ nullptr,
0,
0,
0,
@@ -1945,7 +1967,7 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
"file_slots",
ptr,
"active_input_index",
- NULL,
+ nullptr,
0,
0,
0,
@@ -1961,9 +1983,9 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
col = uiLayoutColumn(row, true);
wmOperatorType *ot = WM_operatortype_find("NODE_OT_output_file_move_active_socket", false);
- uiItemFullO_ptr(col, ot, "", ICON_TRIA_UP, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ uiItemFullO_ptr(col, ot, "", ICON_TRIA_UP, nullptr, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
RNA_enum_set(&op_ptr, "direction", 1);
- uiItemFullO_ptr(col, ot, "", ICON_TRIA_DOWN, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ uiItemFullO_ptr(col, ot, "", ICON_TRIA_DOWN, nullptr, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
RNA_enum_set(&op_ptr, "direction", 2);
if (active_input_ptr.data) {
@@ -1977,10 +1999,10 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
"NODE_OT_output_file_remove_active_socket",
"",
ICON_X,
- NULL,
+ nullptr,
WM_OP_EXEC_DEFAULT,
UI_ITEM_R_ICON_ONLY,
- NULL);
+ nullptr);
}
else {
col = uiLayoutColumn(layout, true);
@@ -1992,23 +2014,23 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
"NODE_OT_output_file_remove_active_socket",
"",
ICON_X,
- NULL,
+ nullptr,
WM_OP_EXEC_DEFAULT,
UI_ITEM_R_ICON_ONLY,
- NULL);
+ nullptr);
/* format details for individual files */
imfptr = RNA_pointer_get(&active_input_ptr, "format");
col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Format:"), ICON_NONE);
- uiItemR(col, &active_input_ptr, "use_node_format", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, &active_input_ptr, "use_node_format", DEFAULT_FLAGS, nullptr, ICON_NONE);
const bool is_socket_exr = RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_OPENEXR;
const bool use_node_format = RNA_boolean_get(&active_input_ptr, "use_node_format");
if ((!is_exr && use_node_format) || (!is_socket_exr && !use_node_format)) {
- uiItemR(col, &active_input_ptr, "save_as_render", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, &active_input_ptr, "save_as_render", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
col = uiLayoutColumn(layout, false);
@@ -2016,7 +2038,7 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
uiTemplateImageSettings(col, &imfptr, false);
if (is_multiview) {
- uiTemplateImageFormatViews(layout, &imfptr, NULL);
+ uiTemplateImageFormatViews(layout, &imfptr, nullptr);
}
}
}
@@ -2028,7 +2050,7 @@ static void node_composit_buts_scale(uiLayout *layout, bContext *UNUSED(C), Poin
if (RNA_enum_get(ptr, "space") == CMP_SCALE_RENDERPERCENT) {
uiLayout *row;
- uiItemR(layout, ptr, "frame_method", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "frame_method", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "offset_x", DEFAULT_FLAGS, "X", ICON_NONE);
uiItemR(row, ptr, "offset_y", DEFAULT_FLAGS, "Y", ICON_NONE);
@@ -2045,8 +2067,8 @@ static void node_composit_buts_invert(uiLayout *layout, bContext *UNUSED(C), Poi
uiLayout *col;
col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "invert_rgb", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "invert_alpha", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "invert_rgb", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "invert_alpha", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_premulkey(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -2056,86 +2078,86 @@ static void node_composit_buts_premulkey(uiLayout *layout, bContext *UNUSED(C),
static void node_composit_buts_view_levels(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
static void node_composit_buts_colorbalance(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *split, *col, *row;
- uiItemR(layout, ptr, "correction_method", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "correction_method", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (RNA_enum_get(ptr, "correction_method") == 0) {
split = uiLayoutSplit(layout, 0.0f, false);
col = uiLayoutColumn(split, false);
- uiTemplateColorPicker(col, ptr, "lift", 1, 1, 0, 1);
+ uiTemplateColorPicker(col, ptr, "lift", true, true, false, true);
row = uiLayoutRow(col, false);
- uiItemR(row, ptr, "lift", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(row, ptr, "lift", DEFAULT_FLAGS, nullptr, ICON_NONE);
col = uiLayoutColumn(split, false);
- uiTemplateColorPicker(col, ptr, "gamma", 1, 1, 1, 1);
+ uiTemplateColorPicker(col, ptr, "gamma", true, true, true, true);
row = uiLayoutRow(col, false);
- uiItemR(row, ptr, "gamma", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(row, ptr, "gamma", DEFAULT_FLAGS, nullptr, ICON_NONE);
col = uiLayoutColumn(split, false);
- uiTemplateColorPicker(col, ptr, "gain", 1, 1, 1, 1);
+ uiTemplateColorPicker(col, ptr, "gain", true, true, true, true);
row = uiLayoutRow(col, false);
- uiItemR(row, ptr, "gain", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(row, ptr, "gain", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
else {
split = uiLayoutSplit(layout, 0.0f, false);
col = uiLayoutColumn(split, false);
- uiTemplateColorPicker(col, ptr, "offset", 1, 1, 0, 1);
+ uiTemplateColorPicker(col, ptr, "offset", true, true, false, true);
row = uiLayoutRow(col, false);
- uiItemR(row, ptr, "offset", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "offset_basis", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(row, ptr, "offset", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "offset_basis", DEFAULT_FLAGS, nullptr, ICON_NONE);
col = uiLayoutColumn(split, false);
- uiTemplateColorPicker(col, ptr, "power", 1, 1, 0, 1);
+ uiTemplateColorPicker(col, ptr, "power", true, true, false, true);
row = uiLayoutRow(col, false);
- uiItemR(row, ptr, "power", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(row, ptr, "power", DEFAULT_FLAGS, nullptr, ICON_NONE);
col = uiLayoutColumn(split, false);
- uiTemplateColorPicker(col, ptr, "slope", 1, 1, 0, 1);
+ uiTemplateColorPicker(col, ptr, "slope", true, true, false, true);
row = uiLayoutRow(col, false);
- uiItemR(row, ptr, "slope", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(row, ptr, "slope", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
}
static void node_composit_buts_colorbalance_ex(uiLayout *layout,
bContext *UNUSED(C),
PointerRNA *ptr)
{
- uiItemR(layout, ptr, "correction_method", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "correction_method", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (RNA_enum_get(ptr, "correction_method") == 0) {
- uiTemplateColorPicker(layout, ptr, "lift", 1, 1, 0, 1);
- uiItemR(layout, ptr, "lift", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiTemplateColorPicker(layout, ptr, "lift", true, true, false, true);
+ uiItemR(layout, ptr, "lift", DEFAULT_FLAGS, nullptr, ICON_NONE);
- uiTemplateColorPicker(layout, ptr, "gamma", 1, 1, 1, 1);
- uiItemR(layout, ptr, "gamma", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiTemplateColorPicker(layout, ptr, "gamma", true, true, true, true);
+ uiItemR(layout, ptr, "gamma", DEFAULT_FLAGS, nullptr, ICON_NONE);
- uiTemplateColorPicker(layout, ptr, "gain", 1, 1, 1, 1);
- uiItemR(layout, ptr, "gain", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiTemplateColorPicker(layout, ptr, "gain", true, true, true, true);
+ uiItemR(layout, ptr, "gain", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
else {
- uiTemplateColorPicker(layout, ptr, "offset", 1, 1, 0, 1);
- uiItemR(layout, ptr, "offset", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiTemplateColorPicker(layout, ptr, "offset", true, true, false, true);
+ uiItemR(layout, ptr, "offset", DEFAULT_FLAGS, nullptr, ICON_NONE);
- uiTemplateColorPicker(layout, ptr, "power", 1, 1, 0, 1);
- uiItemR(layout, ptr, "power", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiTemplateColorPicker(layout, ptr, "power", true, true, false, true);
+ uiItemR(layout, ptr, "power", DEFAULT_FLAGS, nullptr, ICON_NONE);
- uiTemplateColorPicker(layout, ptr, "slope", 1, 1, 0, 1);
- uiItemR(layout, ptr, "slope", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiTemplateColorPicker(layout, ptr, "slope", true, true, false, true);
+ uiItemR(layout, ptr, "slope", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
}
static void node_composit_buts_huecorrect(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- bNode *node = ptr->data;
- CurveMapping *cumap = node->storage;
+ bNode *node = (bNode *)ptr->data;
+ CurveMapping *cumap = (CurveMapping *)node->storage;
if (_sample_col[0] != SAMPLE_FLT_ISNONE) {
cumap->flag |= CUMA_DRAW_SAMPLE;
@@ -2155,17 +2177,33 @@ static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), Pointe
static void node_composit_buts_movieclip(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- uiTemplateID(
- layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
+ uiTemplateID(layout,
+ C,
+ ptr,
+ "clip",
+ nullptr,
+ "CLIP_OT_open",
+ nullptr,
+ UI_TEMPLATE_ID_FILTER_ALL,
+ false,
+ nullptr);
}
static void node_composit_buts_movieclip_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
PointerRNA clipptr;
- uiTemplateID(
- layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
+ uiTemplateID(layout,
+ C,
+ ptr,
+ "clip",
+ nullptr,
+ "CLIP_OT_open",
+ nullptr,
+ UI_TEMPLATE_ID_FILTER_ALL,
+ false,
+ nullptr);
if (!node->id) {
return;
@@ -2178,23 +2216,31 @@ static void node_composit_buts_movieclip_ex(uiLayout *layout, bContext *C, Point
static void node_composit_buts_stabilize2d(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
- uiTemplateID(
- layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
+ uiTemplateID(layout,
+ C,
+ ptr,
+ "clip",
+ nullptr,
+ "CLIP_OT_open",
+ nullptr,
+ UI_TEMPLATE_ID_FILTER_ALL,
+ false,
+ nullptr);
if (!node->id) {
return;
}
uiItemR(layout, ptr, "filter_type", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "invert", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "invert", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_translate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "use_relative", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "wrap_axis", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_relative", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "wrap_axis", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -2204,10 +2250,18 @@ static void node_composit_buts_transform(uiLayout *layout, bContext *UNUSED(C),
static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
- uiTemplateID(
- layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
+ uiTemplateID(layout,
+ C,
+ ptr,
+ "clip",
+ nullptr,
+ "CLIP_OT_open",
+ nullptr,
+ UI_TEMPLATE_ID_FILTER_ALL,
+ false,
+ nullptr);
if (!node->id) {
return;
@@ -2223,9 +2277,9 @@ static void node_composit_buts_colorcorrection(uiLayout *layout,
uiLayout *row;
row = uiLayoutRow(layout, false);
- uiItemR(row, ptr, "red", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(row, ptr, "green", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(row, ptr, "blue", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(row, ptr, "red", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "green", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "blue", DEFAULT_FLAGS, nullptr, ICON_NONE);
row = uiLayoutRow(layout, false);
uiItemL(row, "", ICON_NONE);
@@ -2268,8 +2322,8 @@ static void node_composit_buts_colorcorrection(uiLayout *layout,
uiItemR(row, ptr, "shadows_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
row = uiLayoutRow(layout, false);
- uiItemR(row, ptr, "midtones_start", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "midtones_end", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "midtones_start", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "midtones_end", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
}
static void node_composit_buts_colorcorrection_ex(uiLayout *layout,
@@ -2279,53 +2333,53 @@ static void node_composit_buts_colorcorrection_ex(uiLayout *layout,
uiLayout *row;
row = uiLayoutRow(layout, false);
- uiItemR(row, ptr, "red", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(row, ptr, "green", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(row, ptr, "blue", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(row, ptr, "red", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "green", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "blue", DEFAULT_FLAGS, nullptr, ICON_NONE);
row = layout;
uiItemL(row, IFACE_("Saturation"), ICON_NONE);
- uiItemR(row, ptr, "master_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "highlights_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "midtones_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "shadows_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "master_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "highlights_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "midtones_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "shadows_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
uiItemL(row, IFACE_("Contrast"), ICON_NONE);
- uiItemR(row, ptr, "master_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "highlights_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "midtones_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "shadows_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "master_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "highlights_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "midtones_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "shadows_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
uiItemL(row, IFACE_("Gamma"), ICON_NONE);
- uiItemR(row, ptr, "master_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "highlights_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "midtones_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "shadows_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "master_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "highlights_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "midtones_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "shadows_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
uiItemL(row, IFACE_("Gain"), ICON_NONE);
- uiItemR(row, ptr, "master_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "highlights_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "midtones_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "shadows_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "master_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "highlights_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "midtones_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "shadows_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
uiItemL(row, IFACE_("Lift"), ICON_NONE);
- uiItemR(row, ptr, "master_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "highlights_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "midtones_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "shadows_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "master_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "highlights_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "midtones_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "shadows_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
row = uiLayoutRow(layout, false);
- uiItemR(row, ptr, "midtones_start", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(row, ptr, "midtones_end", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(row, ptr, "midtones_start", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "midtones_end", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_set_alpha(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_switch(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "check", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "check", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_switch_view_ex(uiLayout *layout,
@@ -2336,10 +2390,10 @@ static void node_composit_buts_switch_view_ex(uiLayout *layout,
"NODE_OT_switch_view_update",
"Update Views",
ICON_FILE_REFRESH,
- NULL,
+ nullptr,
WM_OP_INVOKE_DEFAULT,
0,
- NULL);
+ nullptr);
}
static void node_composit_buts_boxmask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -2347,32 +2401,32 @@ static void node_composit_buts_boxmask(uiLayout *layout, bContext *UNUSED(C), Po
uiLayout *row;
row = uiLayoutRow(layout, true);
- uiItemR(row, ptr, "x", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(row, ptr, "y", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(row, ptr, "x", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "y", DEFAULT_FLAGS, nullptr, ICON_NONE);
row = uiLayoutRow(layout, true);
- uiItemR(row, ptr, "width", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "height", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "width", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "height", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "rotation", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "mask_type", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "rotation", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "mask_type", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_bokehimage(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "flaps", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "angle", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "rounding", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(layout, ptr, "catadioptric", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(layout, ptr, "shift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "flaps", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "angle", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "rounding", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "catadioptric", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "shift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
}
static void node_composit_buts_bokehblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "use_variable_size", DEFAULT_FLAGS, NULL, ICON_NONE);
- // uiItemR(layout, ptr, "f_stop", DEFAULT_FLAGS, NULL, ICON_NONE); /* UNUSED */
- uiItemR(layout, ptr, "blur_max", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "use_extended_bounds", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_variable_size", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ // uiItemR(layout, ptr, "f_stop", DEFAULT_FLAGS, nullptr, ICON_NONE); /* UNUSED */
+ uiItemR(layout, ptr, "blur_max", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "use_extended_bounds", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_backdrop_viewer(
@@ -2407,7 +2461,7 @@ static void node_composit_backdrop_viewer(
static void node_composit_backdrop_boxmask(
SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y)
{
- NodeBoxMask *boxmask = node->storage;
+ NodeBoxMask *boxmask = (NodeBoxMask *)node->storage;
const float backdropWidth = backdrop->x;
const float backdropHeight = backdrop->y;
const float aspect = backdropWidth / backdropHeight;
@@ -2452,7 +2506,7 @@ static void node_composit_backdrop_boxmask(
static void node_composit_backdrop_ellipsemask(
SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y)
{
- NodeEllipseMask *ellipsemask = node->storage;
+ NodeEllipseMask *ellipsemask = (NodeEllipseMask *)node->storage;
const float backdropWidth = backdrop->x;
const float backdropHeight = backdrop->y;
const float aspect = backdropWidth / backdropHeight;
@@ -2498,65 +2552,83 @@ static void node_composit_buts_ellipsemask(uiLayout *layout, bContext *UNUSED(C)
{
uiLayout *row;
row = uiLayoutRow(layout, true);
- uiItemR(row, ptr, "x", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(row, ptr, "y", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(row, ptr, "x", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "y", DEFAULT_FLAGS, nullptr, ICON_NONE);
row = uiLayoutRow(layout, true);
- uiItemR(row, ptr, "width", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
- uiItemR(row, ptr, "height", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "width", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
+ uiItemR(row, ptr, "height", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "rotation", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "mask_type", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "rotation", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "mask_type", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_composite(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "use_alpha", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_alpha", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_viewer(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "use_alpha", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_alpha", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_viewer_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
- uiItemR(layout, ptr, "use_alpha", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "tile_order", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_alpha", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "tile_order", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (RNA_enum_get(ptr, "tile_order") == 0) {
col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "center_x", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(col, ptr, "center_y", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "center_x", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(col, ptr, "center_y", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
}
static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
- uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
- uiItemR(layout, ptr, "use_feather", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiTemplateID(layout,
+ C,
+ ptr,
+ "mask",
+ nullptr,
+ nullptr,
+ nullptr,
+ UI_TEMPLATE_ID_FILTER_ALL,
+ false,
+ nullptr);
+ uiItemR(layout, ptr, "use_feather", DEFAULT_FLAGS, nullptr, ICON_NONE);
uiItemR(layout, ptr, "size_source", DEFAULT_FLAGS, "", ICON_NONE);
if (node->custom1 & (CMP_NODEFLAG_MASK_FIXED | CMP_NODEFLAG_MASK_FIXED_SCENE)) {
- uiItemR(layout, ptr, "size_x", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "size_y", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "size_x", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "size_y", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
- uiItemR(layout, ptr, "use_motion_blur", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_motion_blur", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (node->custom1 & CMP_NODEFLAG_MASK_MOTION_BLUR) {
- uiItemR(layout, ptr, "motion_blur_samples", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "motion_blur_shutter", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "motion_blur_samples", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "motion_blur_shutter", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
}
static void node_composit_buts_keyingscreen(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
- uiTemplateID(layout, C, ptr, "clip", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
+ uiTemplateID(layout,
+ C,
+ ptr,
+ "clip",
+ nullptr,
+ nullptr,
+ nullptr,
+ UI_TEMPLATE_ID_FILTER_ALL,
+ false,
+ nullptr);
if (node->id) {
MovieClip *clip = (MovieClip *)node->id;
@@ -2572,28 +2644,36 @@ static void node_composit_buts_keyingscreen(uiLayout *layout, bContext *C, Point
static void node_composit_buts_keying(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- /* bNode *node = ptr->data; */ /* UNUSED */
+ /* bNode *node = (bNode*)ptr->data; */ /* UNUSED */
- uiItemR(layout, ptr, "blur_pre", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "screen_balance", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "despill_factor", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "despill_balance", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "edge_kernel_radius", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "edge_kernel_tolerance", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "clip_black", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "clip_white", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "dilate_distance", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "feather_falloff", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "feather_distance", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "blur_post", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "blur_pre", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "screen_balance", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "despill_factor", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "despill_balance", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "edge_kernel_radius", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "edge_kernel_tolerance", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "clip_black", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "clip_white", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "dilate_distance", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "feather_falloff", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "feather_distance", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "blur_post", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
- uiTemplateID(
- layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
+ uiTemplateID(layout,
+ C,
+ ptr,
+ "clip",
+ nullptr,
+ "CLIP_OT_open",
+ nullptr,
+ UI_TEMPLATE_ID_FILTER_ALL,
+ false,
+ nullptr);
if (node->id) {
MovieClip *clip = (MovieClip *)node->id;
@@ -2601,7 +2681,7 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN
MovieTrackingObject *object;
uiLayout *col;
PointerRNA tracking_ptr;
- NodeTrackPosData *data = node->storage;
+ NodeTrackPosData *data = (NodeTrackPosData *)node->storage;
RNA_pointer_create(&clip->id, &RNA_MovieTracking, tracking, &tracking_ptr);
@@ -2620,21 +2700,29 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN
uiItemR(layout, ptr, "track_name", DEFAULT_FLAGS, "", ICON_ANIM_DATA);
}
- uiItemR(layout, ptr, "position", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "position", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (ELEM(node->custom1, CMP_TRACKPOS_RELATIVE_FRAME, CMP_TRACKPOS_ABSOLUTE_FRAME)) {
- uiItemR(layout, ptr, "frame_relative", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "frame_relative", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
}
}
static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- bNode *node = ptr->data;
- NodePlaneTrackDeformData *data = node->storage;
+ bNode *node = (bNode *)ptr->data;
+ NodePlaneTrackDeformData *data = (NodePlaneTrackDeformData *)node->storage;
- uiTemplateID(
- layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
+ uiTemplateID(layout,
+ C,
+ ptr,
+ "clip",
+ nullptr,
+ "CLIP_OT_open",
+ nullptr,
+ UI_TEMPLATE_ID_FILTER_ALL,
+ false,
+ nullptr);
if (node->id) {
MovieClip *clip = (MovieClip *)node->id;
@@ -2662,10 +2750,10 @@ static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, P
}
}
- uiItemR(layout, ptr, "use_motion_blur", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_motion_blur", DEFAULT_FLAGS, nullptr, ICON_NONE);
if (data->flag & CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR) {
- uiItemR(layout, ptr, "motion_blur_samples", DEFAULT_FLAGS, NULL, ICON_NONE);
- uiItemR(layout, ptr, "motion_blur_shutter", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "motion_blur_samples", DEFAULT_FLAGS, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "motion_blur_shutter", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
}
@@ -2678,7 +2766,7 @@ static void node_composit_buts_cornerpin(uiLayout *UNUSED(layout),
static void node_composit_buts_sunbeams(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "source", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, "", ICON_NONE);
- uiItemR(layout, ptr, "ray_length", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "ray_length", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
}
static void node_composit_buts_cryptomatte_legacy(uiLayout *layout,
@@ -2706,18 +2794,35 @@ static void node_composit_buts_cryptomatte_legacy_ex(uiLayout *layout,
static void node_composit_buts_cryptomatte(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
uiLayout *row = uiLayoutRow(layout, true);
- uiItemR(row, ptr, "source", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, ptr, "source", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiLayout *col = uiLayoutColumn(layout, false);
if (node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER) {
- uiTemplateID(col, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
+ uiTemplateID(col,
+ C,
+ ptr,
+ "scene",
+ nullptr,
+ nullptr,
+ nullptr,
+ UI_TEMPLATE_ID_FILTER_ALL,
+ false,
+ nullptr);
}
else {
- uiTemplateID(
- col, C, ptr, "image", NULL, "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
+ uiTemplateID(col,
+ C,
+ ptr,
+ "image",
+ nullptr,
+ "IMAGE_OT_open",
+ nullptr,
+ UI_TEMPLATE_ID_FILTER_ALL,
+ false,
+ nullptr);
NodeCryptomatte *crypto = (NodeCryptomatte *)node->storage;
PointerRNA imaptr = RNA_pointer_get(ptr, "image");
@@ -2743,7 +2848,7 @@ static void node_composit_buts_brightcontrast(uiLayout *layout,
bContext *UNUSED(C),
PointerRNA *ptr)
{
- uiItemR(layout, ptr, "use_premultiply", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_premultiply", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_composit_buts_denoise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -2753,14 +2858,13 @@ static void node_composit_buts_denoise(uiLayout *layout, bContext *UNUSED(C), Po
#else
/* Always supported through Accelerate framework BNNS on macOS. */
# ifndef __APPLE__
- if (!BLI_cpu_support_sse41())
-# endif
- {
+ if (!BLI_cpu_support_sse41()) {
uiItemL(layout, IFACE_("Disabled, CPU with SSE4.1 is required"), ICON_ERROR);
}
+# endif
#endif
- uiItemR(layout, ptr, "use_hdr", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_hdr", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
/* only once called */
@@ -3030,7 +3134,7 @@ static void node_texture_buts_bricks(uiLayout *layout, bContext *UNUSED(C), Poin
static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
PointerRNA tex_ptr;
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
ID *id = ptr->owner_id;
Tex *tex = (Tex *)node->storage;
uiLayout *col, *row;
@@ -3043,29 +3147,31 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), Pointe
case TEX_BLEND:
uiItemR(col, &tex_ptr, "progression", DEFAULT_FLAGS, "", ICON_NONE);
row = uiLayoutRow(col, false);
- uiItemR(row, &tex_ptr, "use_flip_axis", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(
+ row, &tex_ptr, "use_flip_axis", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
break;
case TEX_MARBLE:
row = uiLayoutRow(col, false);
- uiItemR(row, &tex_ptr, "marble_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, &tex_ptr, "marble_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
row = uiLayoutRow(col, false);
- uiItemR(row, &tex_ptr, "noise_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, &tex_ptr, "noise_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
row = uiLayoutRow(col, false);
uiItemR(row, &tex_ptr, "noise_basis", DEFAULT_FLAGS, "", ICON_NONE);
row = uiLayoutRow(col, false);
- uiItemR(row, &tex_ptr, "noise_basis_2", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(
+ row, &tex_ptr, "noise_basis_2", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
break;
case TEX_MAGIC:
- uiItemR(col, &tex_ptr, "noise_depth", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, &tex_ptr, "noise_depth", DEFAULT_FLAGS, nullptr, ICON_NONE);
break;
case TEX_STUCCI:
row = uiLayoutRow(col, false);
- uiItemR(row, &tex_ptr, "stucci_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, &tex_ptr, "stucci_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
row = uiLayoutRow(col, false);
- uiItemR(row, &tex_ptr, "noise_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, &tex_ptr, "noise_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiItemR(col, &tex_ptr, "noise_basis", DEFAULT_FLAGS, "", ICON_NONE);
break;
@@ -3073,18 +3179,19 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), Pointe
uiItemR(col, &tex_ptr, "noise_basis", DEFAULT_FLAGS, "", ICON_NONE);
uiItemR(col, &tex_ptr, "wood_type", DEFAULT_FLAGS, "", ICON_NONE);
row = uiLayoutRow(col, false);
- uiItemR(row, &tex_ptr, "noise_basis_2", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(
+ row, &tex_ptr, "noise_basis_2", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
row = uiLayoutRow(col, false);
uiLayoutSetActive(row, !(ELEM(tex->stype, TEX_BAND, TEX_RING)));
- uiItemR(row, &tex_ptr, "noise_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, &tex_ptr, "noise_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
break;
case TEX_CLOUDS:
uiItemR(col, &tex_ptr, "noise_basis", DEFAULT_FLAGS, "", ICON_NONE);
row = uiLayoutRow(col, false);
- uiItemR(row, &tex_ptr, "cloud_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, &tex_ptr, "cloud_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
row = uiLayoutRow(col, false);
- uiItemR(row, &tex_ptr, "noise_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(row, &tex_ptr, "noise_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiItemR(col,
&tex_ptr,
"noise_depth",
@@ -3105,7 +3212,7 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), Pointe
case TEX_VORONOI:
uiItemR(col, &tex_ptr, "distance_metric", DEFAULT_FLAGS, "", ICON_NONE);
if (tex->vn_distm == TEX_MINKOVSKY) {
- uiItemR(col, &tex_ptr, "minkovsky_exponent", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, &tex_ptr, "minkovsky_exponent", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
uiItemR(col, &tex_ptr, "color_mode", DEFAULT_FLAGS, "", ICON_NONE);
break;
@@ -3120,19 +3227,19 @@ static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *p
"image",
"IMAGE_OT_new",
"IMAGE_OT_open",
- NULL,
+ nullptr,
UI_TEMPLATE_ID_FILTER_ALL,
false,
- NULL);
+ nullptr);
}
static void node_texture_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
PointerRNA iuserptr;
RNA_pointer_create(ptr->owner_id, &RNA_ImageUser, node->storage, &iuserptr);
- uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0, 0);
+ uiTemplateImage(layout, C, ptr, "image", &iuserptr, false, false);
}
static void node_texture_buts_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -3189,12 +3296,16 @@ static void node_texture_set_butfunc(bNodeType *ntype)
}
}
-/* ****** init draw callbacks for all tree types, only called in usiblender.c, once ************ */
+/* -------------------------------------------------------------------- */
+/** \name Init Draw Callbacks For All Tree Types
+ *
+ * Only called on node initialization, once.
+ * \{ */
static void node_property_update_default(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
- bNode *node = ptr->data;
+ bNode *node = (bNode *)ptr->data;
ED_node_tag_update_nodetree(bmain, ntree, node);
}
@@ -3204,7 +3315,7 @@ static void node_socket_template_properties_update(bNodeType *ntype, bNodeSocket
PropertyRNA *prop = RNA_struct_type_find_property(srna, stemp->identifier);
if (prop) {
- RNA_def_property_update_runtime(prop, node_property_update_default);
+ RNA_def_property_update_runtime(prop, (const void *)node_property_update_default);
}
}
@@ -3261,6 +3372,8 @@ static void node_socket_undefined_interface_draw_color(bContext *UNUSED(C),
r_color[3] = 1.0f;
}
+/** \} */
+
void ED_node_init_butfuncs(void)
{
/* Fallback types for undefined tree, nodes, sockets
@@ -3272,8 +3385,8 @@ void ED_node_init_butfuncs(void)
NodeTypeUndefined.draw_nodetype_prepare = node_update_default;
NodeTypeUndefined.select_area_func = node_select_area_default;
NodeTypeUndefined.tweak_area_func = node_tweak_area_default;
- NodeTypeUndefined.draw_buttons = NULL;
- NodeTypeUndefined.draw_buttons_ex = NULL;
+ NodeTypeUndefined.draw_buttons = nullptr;
+ NodeTypeUndefined.draw_buttons_ex = nullptr;
NodeTypeUndefined.resize_area_func = node_resize_area_default;
NodeSocketTypeUndefined.draw = node_socket_undefined_draw;
@@ -3350,7 +3463,7 @@ static void std_node_socket_draw_color(bContext *UNUSED(C),
PointerRNA *UNUSED(node_ptr),
float *r_color)
{
- bNodeSocket *sock = ptr->data;
+ bNodeSocket *sock = (bNodeSocket *)ptr->data;
int type = sock->typeinfo->type;
copy_v4_v4(r_color, std_node_socket_colors[type]);
}
@@ -3358,7 +3471,7 @@ static void std_node_socket_interface_draw_color(bContext *UNUSED(C),
PointerRNA *ptr,
float *r_color)
{
- bNodeSocket *sock = ptr->data;
+ bNodeSocket *sock = (bNodeSocket *)ptr->data;
int type = sock->typeinfo->type;
copy_v4_v4(r_color, std_node_socket_colors[type]);
}
@@ -3371,7 +3484,7 @@ static void node_file_output_socket_draw(bContext *C,
PointerRNA *node_ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
- bNodeSocket *sock = ptr->data;
+ bNodeSocket *sock = (bNodeSocket *)ptr->data;
uiLayout *row;
PointerRNA inputptr;
@@ -3381,13 +3494,13 @@ static void node_file_output_socket_draw(bContext *C,
int imtype = RNA_enum_get(&imfptr, "file_format");
if (imtype == R_IMF_IMTYPE_MULTILAYER) {
- NodeImageMultiFileSocket *input = sock->storage;
+ NodeImageMultiFileSocket *input = (NodeImageMultiFileSocket *)sock->storage;
RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotLayer, input, &inputptr);
uiItemL(row, input->layer, ICON_NONE);
}
else {
- NodeImageMultiFileSocket *input = sock->storage;
+ NodeImageMultiFileSocket *input = (NodeImageMultiFileSocket *)sock->storage;
uiBlock *block;
RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotFile, input, &inputptr);
@@ -3414,10 +3527,10 @@ static void node_file_output_socket_draw(bContext *C,
static void std_node_socket_draw(
bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr, const char *text)
{
- bNode *node = node_ptr->data;
- bNodeSocket *sock = ptr->data;
+ bNode *node = (bNode *)node_ptr->data;
+ bNodeSocket *sock = (bNodeSocket *)ptr->data;
int type = sock->typeinfo->type;
- /*int subtype = sock->typeinfo->subtype;*/
+ // int subtype = sock->typeinfo->subtype;
/* XXX not nice, eventually give this node its own socket type ... */
if (node->type == CMP_NODE_OUTPUT_FILE) {
@@ -3430,6 +3543,8 @@ static void std_node_socket_draw(
return;
}
+ text = (sock->flag & SOCK_HIDE_LABEL) ? "" : text;
+
switch (type) {
case SOCK_FLOAT:
case SOCK_INT:
@@ -3483,7 +3598,8 @@ static void std_node_socket_draw(
break;
}
case SOCK_TEXTURE: {
- uiTemplateID(layout, C, ptr, "default_value", "texture.new", NULL, NULL, 0, ICON_NONE, NULL);
+ uiTemplateID(
+ layout, C, ptr, "default_value", "texture.new", nullptr, nullptr, 0, ICON_NONE, nullptr);
break;
}
case SOCK_MATERIAL: {
@@ -3498,7 +3614,7 @@ static void std_node_socket_draw(
static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout, PointerRNA *ptr)
{
- bNodeSocket *sock = ptr->data;
+ bNodeSocket *sock = (bNodeSocket *)ptr->data;
int type = sock->typeinfo->type;
uiLayout *col = uiLayoutColumn(layout, false);
@@ -3533,7 +3649,7 @@ static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout
}
}
- uiItemR(layout, ptr, "hide_value", DEFAULT_FLAGS, NULL, 0);
+ uiItemR(layout, ptr, "hide_value", DEFAULT_FLAGS, nullptr, 0);
}
void ED_init_standard_node_socket_type(bNodeSocketType *stype)
@@ -3600,7 +3716,7 @@ void draw_nodespace_back_pix(const bContext *C,
void *lock;
Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock);
if (ibuf) {
/* somehow the offset has to be calculated inverse */
wmOrtho2_region_pixelspace(region);
@@ -3609,7 +3725,7 @@ void draw_nodespace_back_pix(const bContext *C,
/** \note draw selected info on backdrop */
if (snode->edittree) {
- bNode *node = snode->edittree->nodes.first;
+ bNode *node = (bNode *)snode->edittree->nodes.first;
rctf *viewer_border = &snode->nodetree->viewer_border;
while (node) {
if (node->flag & NODE_SELECT) {
@@ -3646,7 +3762,7 @@ void draw_nodespace_back_pix(const bContext *C,
GPU_matrix_pop();
}
-/* return quadratic beziers points for a given nodelink and clip if v2d is not NULL. */
+/* return quadratic beziers points for a given nodelink and clip if v2d is not nullptr. */
bool node_link_bezier_handles(const View2D *v2d,
const SpaceNode *snode,
const bNodeLink *link,
@@ -3676,7 +3792,7 @@ bool node_link_bezier_handles(const View2D *v2d,
fromreroute = (link->fromnode && link->fromnode->type == NODE_REROUTE);
}
else {
- if (snode == NULL) {
+ if (snode == nullptr) {
return false;
}
copy_v2_v2(vec[0], cursor);
@@ -3695,7 +3811,7 @@ bool node_link_bezier_handles(const View2D *v2d,
toreroute = (link->tonode && link->tonode->type == NODE_REROUTE);
}
else {
- if (snode == NULL) {
+ if (snode == nullptr) {
return false;
}
copy_v2_v2(vec[3], cursor);
@@ -3755,7 +3871,7 @@ bool node_link_bezier_handles(const View2D *v2d,
return true;
}
-/* if v2d not NULL, it clips and returns 0 if not visible */
+/* if v2d not nullptr, it clips and returns 0 if not visible */
bool node_link_bezier_points(const View2D *v2d,
const SpaceNode *snode,
const bNodeLink *link,
@@ -3788,6 +3904,7 @@ static float arrow_expand_axis[3][2] = {{0.7071f, 0.7071f}, {M_SQRT2, 0.0f}, {0.
static float mute_verts[3][2] = {{0.7071f, 1.0f}, {0.7071f, 0.0f}, {0.7071f, -1.0f}};
static float mute_expand_axis[3][2] = {{1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, -0.0f}};
+/* Is zero initialized because it is static data. */
static struct {
GPUBatch *batch; /* for batching line together */
GPUBatch *batch_single; /* for single line */
@@ -3798,9 +3915,9 @@ static struct {
GPUVertBufRaw colid_step, muted_step;
uint count;
bool enabled;
-} g_batch_link = {0};
+} g_batch_link;
-static void nodelink_batch_reset(void)
+static void nodelink_batch_reset()
{
GPU_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p0_id, &g_batch_link.p0_step);
GPU_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p1_id, &g_batch_link.p1_step);
@@ -3827,7 +3944,7 @@ static void set_nodelink_vertex(GPUVertBuf *vbo,
GPU_vertbuf_attr_set(vbo, exp_id, v, exp);
}
-static void nodelink_batch_init(void)
+static void nodelink_batch_init()
{
GPUVertFormat format = {0};
uint uv_id = GPU_vertformat_attr_add(&format, "uv", GPU_COMP_U8, 2, GPU_FETCH_INT_TO_FLOAT_UNIT);
@@ -3906,10 +4023,11 @@ static void nodelink_batch_init(void)
}
}
- g_batch_link.batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ g_batch_link.batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, nullptr, GPU_BATCH_OWNS_VBO);
gpu_batch_presets_register(g_batch_link.batch);
- g_batch_link.batch_single = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, 0);
+ g_batch_link.batch_single = GPU_batch_create_ex(
+ GPU_PRIM_TRI_STRIP, vbo, nullptr, GPU_BATCH_INVALID);
gpu_batch_presets_register(g_batch_link.batch_single);
/* Instances data */
@@ -4009,16 +4127,16 @@ static void nodelink_batch_add_link(const SpaceNode *snode,
BLI_assert(ELEM(th_col3, TH_WIRE, TH_REDALERT, -1));
g_batch_link.count++;
- copy_v2_v2(GPU_vertbuf_raw_step(&g_batch_link.p0_step), p0);
- copy_v2_v2(GPU_vertbuf_raw_step(&g_batch_link.p1_step), p1);
- copy_v2_v2(GPU_vertbuf_raw_step(&g_batch_link.p2_step), p2);
- copy_v2_v2(GPU_vertbuf_raw_step(&g_batch_link.p3_step), p3);
- char *colid = GPU_vertbuf_raw_step(&g_batch_link.colid_step);
+ copy_v2_v2((float *)GPU_vertbuf_raw_step(&g_batch_link.p0_step), p0);
+ copy_v2_v2((float *)GPU_vertbuf_raw_step(&g_batch_link.p1_step), p1);
+ copy_v2_v2((float *)GPU_vertbuf_raw_step(&g_batch_link.p2_step), p2);
+ copy_v2_v2((float *)GPU_vertbuf_raw_step(&g_batch_link.p3_step), p3);
+ char *colid = (char *)GPU_vertbuf_raw_step(&g_batch_link.colid_step);
colid[0] = nodelink_get_color_id(th_col1);
colid[1] = nodelink_get_color_id(th_col2);
colid[2] = nodelink_get_color_id(th_col3);
colid[3] = drawarrow;
- char *muted = GPU_vertbuf_raw_step(&g_batch_link.muted_step);
+ char *muted = (char *)GPU_vertbuf_raw_step(&g_batch_link.muted_step);
muted[0] = drawmuted;
if (g_batch_link.count == NODELINK_GROUP_SIZE) {
@@ -4040,7 +4158,7 @@ void node_draw_link_bezier(const View2D *v2d,
int drawarrow = ((link->tonode && (link->tonode->type == NODE_REROUTE)) &&
(link->fromnode && (link->fromnode->type == NODE_REROUTE)));
int drawmuted = (link->flag & NODE_LINK_MUTED);
- if (g_batch_link.batch == NULL) {
+ if (g_batch_link.batch == nullptr) {
nodelink_batch_init();
}
@@ -4077,12 +4195,12 @@ void node_draw_link_bezier(const View2D *v2d,
}
}
-/* note; this is used for fake links in groups too */
+/* NOTE: this is used for fake links in groups too. */
void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
{
int th_col1 = TH_WIRE_INNER, th_col2 = TH_WIRE_INNER, th_col3 = TH_WIRE;
- if (link->fromsock == NULL && link->tosock == NULL) {
+ if (link->fromsock == nullptr && link->tosock == nullptr) {
return;
}
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.cc
index a28d467df2e..c167744de01 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.cc
@@ -65,13 +65,13 @@
/**
* XXX Does some additional initialization on top of #nodeAddNode
* Can be used with both custom and static nodes,
- * if `idname == NULL` the static int type will be used instead.
+ * if `idname == nullptr` the static int type will be used instead.
*/
bNode *node_add_node(const bContext *C, const char *idname, int type, float locx, float locy)
{
SpaceNode *snode = CTX_wm_space_node(C);
Main *bmain = CTX_data_main(C);
- bNode *node = NULL;
+ bNode *node = nullptr;
node_deselect_all(snode);
@@ -90,7 +90,7 @@ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx
nodeSetSelected(node, true);
ntreeUpdateTree(bmain, snode->edittree);
- ED_node_set_active(bmain, snode->edittree, node, NULL);
+ ED_node_set_active(bmain, snode, snode->edittree, node, nullptr);
snode_update(snode, node);
@@ -114,7 +114,7 @@ static bool add_reroute_intersect_check(bNodeLink *link,
{
float coord_array[NODE_LINK_RESOL + 1][2];
- if (node_link_bezier_points(NULL, NULL, link, coord_array, NODE_LINK_RESOL)) {
+ if (node_link_bezier_points(nullptr, nullptr, link, coord_array, NODE_LINK_RESOL)) {
for (int i = 0; i < tot - 1; i++) {
for (int b = 0; b < NODE_LINK_RESOL; b++) {
if (isect_seg_seg_v2_point(
@@ -127,13 +127,13 @@ static bool add_reroute_intersect_check(bNodeLink *link,
return false;
}
-typedef struct bNodeSocketLink {
+struct bNodeSocketLink {
struct bNodeSocketLink *next, *prev;
struct bNodeSocket *sock;
struct bNodeLink *link;
float point[2];
-} bNodeSocketLink;
+};
static bNodeSocketLink *add_reroute_insert_socket_link(ListBase *lb,
bNodeSocket *sock,
@@ -142,12 +142,12 @@ static bNodeSocketLink *add_reroute_insert_socket_link(ListBase *lb,
{
bNodeSocketLink *socklink, *prev;
- socklink = MEM_callocN(sizeof(bNodeSocketLink), "socket link");
+ socklink = (bNodeSocketLink *)MEM_callocN(sizeof(bNodeSocketLink), "socket link");
socklink->sock = sock;
socklink->link = link;
copy_v2_v2(socklink->point, point);
- for (prev = lb->last; prev; prev = prev->prev) {
+ for (prev = (bNodeSocketLink *)lb->last; prev; prev = prev->prev) {
if (prev->sock == sock) {
break;
}
@@ -162,7 +162,7 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C,
{
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
- bNode *reroute_node = NULL;
+ bNode *reroute_node = nullptr;
bNodeSocket *cursock = socklink->sock;
float insert_point[2];
int num_links;
@@ -184,12 +184,12 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C,
socklink->link->fromnode,
socklink->link->fromsock,
reroute_node,
- reroute_node->inputs.first);
+ (bNodeSocket *)reroute_node->inputs.first);
}
else {
nodeAddLink(ntree,
reroute_node,
- reroute_node->outputs.first,
+ (bNodeSocket *)reroute_node->outputs.first,
socklink->link->tonode,
socklink->link->tosock);
}
@@ -198,11 +198,11 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C,
/* insert the reroute node into the link */
if (in_out == SOCK_OUT) {
socklink->link->fromnode = reroute_node;
- socklink->link->fromsock = reroute_node->outputs.first;
+ socklink->link->fromsock = (bNodeSocket *)reroute_node->outputs.first;
}
else {
socklink->link->tonode = reroute_node;
- socklink->link->tosock = reroute_node->inputs.first;
+ socklink->link->tosock = (bNodeSocket *)reroute_node->inputs.first;
}
add_v2_v2(insert_point, socklink->point);
@@ -259,7 +259,7 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
BLI_listbase_clear(&output_links);
BLI_listbase_clear(&input_links);
- for (link = ntree->links.first; link; link = link->next) {
+ for (link = (bNodeLink *)ntree->links.first; link; link = link->next) {
if (nodeLinkIsHidden(link)) {
continue;
}
@@ -275,11 +275,11 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
/* Create reroute nodes for intersected links.
* Only one reroute if links share the same input/output socket.
*/
- socklink = output_links.first;
+ socklink = (bNodeSocketLink *)output_links.first;
while (socklink) {
socklink = add_reroute_do_socket_section(C, socklink, SOCK_OUT);
}
- socklink = input_links.first;
+ socklink = (bNodeSocketLink *)input_links.first;
while (socklink) {
socklink = add_reroute_do_socket_section(C, socklink, SOCK_IN);
}
@@ -317,7 +317,7 @@ void NODE_OT_add_reroute(wmOperatorType *ot)
/* properties */
PropertyRNA *prop;
prop = RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
/* internal */
RNA_def_int(ot->srna, "cursor", WM_CURSOR_CROSS, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
}
@@ -337,10 +337,10 @@ static bNodeTree *node_add_group_get_and_poll_group_node_tree(Main *bmain,
bNodeTree *node_group = (bNodeTree *)BKE_libblock_find_name(bmain, ID_NT, name);
if (!node_group) {
- return NULL;
+ return nullptr;
}
- const char *disabled_hint = NULL;
+ const char *disabled_hint = nullptr;
if ((node_group->type != ntree->type) || !nodeGroupPoll(ntree, node_group, &disabled_hint)) {
if (disabled_hint) {
BKE_reportf(op->reports,
@@ -358,7 +358,7 @@ static bNodeTree *node_add_group_get_and_poll_group_node_tree(Main *bmain,
ntree->id.name + 2);
}
- return NULL;
+ return nullptr;
}
return node_group;
@@ -450,7 +450,7 @@ static Object *node_add_object_get_and_poll_object_node_tree(Main *bmain, wmOper
Object *object = (Object *)BKE_libblock_find_name(bmain, ID_OB, name);
if (!object) {
- return NULL;
+ return nullptr;
}
return object;
@@ -470,7 +470,7 @@ static int node_add_object_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
bNode *object_node = node_add_node(
- C, NULL, GEO_NODE_OBJECT_INFO, snode->runtime->cursor[0], snode->runtime->cursor[1]);
+ C, nullptr, GEO_NODE_OBJECT_INFO, snode->runtime->cursor[0], snode->runtime->cursor[1]);
if (!object_node) {
BKE_report(op->reports, RPT_WARNING, "Could not add node object");
return OPERATOR_CANCELLED;
@@ -482,7 +482,7 @@ static int node_add_object_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- bNodeSocketValueObject *socket_data = sock->default_value;
+ bNodeSocketValueObject *socket_data = (bNodeSocketValueObject *)sock->default_value;
socket_data->value = object;
id_us_plus(&object->id);
@@ -554,7 +554,7 @@ static Tex *node_add_texture_get_and_poll_texture_node_tree(Main *bmain, wmOpera
Tex *texture = (Tex *)BKE_libblock_find_name(bmain, ID_TE, name);
if (!texture) {
- return NULL;
+ return nullptr;
}
return texture;
@@ -574,7 +574,7 @@ static int node_add_texture_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
bNode *texture_node = node_add_node(C,
- NULL,
+ nullptr,
GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE,
snode->runtime->cursor[0],
snode->runtime->cursor[1]);
@@ -591,6 +591,7 @@ static int node_add_texture_exec(bContext *C, wmOperator *op)
snode_notify(C, snode);
snode_dag_update(C, snode);
+ DEG_relations_tag_update(bmain);
ED_node_tag_update_nodetree(bmain, ntree, texture_node);
@@ -655,7 +656,7 @@ static Collection *node_add_collection_get_and_poll_collection_node_tree(Main *b
Collection *collection = (Collection *)BKE_libblock_find_name(bmain, ID_GR, name);
if (!collection) {
- return NULL;
+ return nullptr;
}
return collection;
@@ -675,7 +676,7 @@ static int node_add_collection_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
bNode *collection_node = node_add_node(
- C, NULL, GEO_NODE_COLLECTION_INFO, snode->runtime->cursor[0], snode->runtime->cursor[1]);
+ C, nullptr, GEO_NODE_COLLECTION_INFO, snode->runtime->cursor[0], snode->runtime->cursor[1]);
if (!collection_node) {
BKE_report(op->reports, RPT_WARNING, "Could not add node collection");
return OPERATOR_CANCELLED;
@@ -687,7 +688,7 @@ static int node_add_collection_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- bNodeSocketValueCollection *socket_data = sock->default_value;
+ bNodeSocketValueCollection *socket_data = (bNodeSocketValueCollection *)sock->default_value;
socket_data->value = collection;
id_us_plus(&collection->id);
@@ -696,6 +697,7 @@ static int node_add_collection_exec(bContext *C, wmOperator *op)
snode_notify(C, snode);
snode_dag_update(C, snode);
+ DEG_relations_tag_update(bmain);
ED_node_tag_update_nodetree(bmain, ntree, collection_node);
@@ -788,7 +790,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
- node = node_add_node(C, NULL, type, snode->runtime->cursor[0], snode->runtime->cursor[1]);
+ node = node_add_node(C, nullptr, type, snode->runtime->cursor[0], snode->runtime->cursor[1]);
if (!node) {
BKE_report(op->reports, RPT_WARNING, "Could not add an image node");
@@ -801,12 +803,13 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
* to get proper image source.
*/
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
- BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_RELOAD);
+ BKE_image_signal(bmain, ima, nullptr, IMA_SIGNAL_RELOAD);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
}
snode_notify(C, snode);
snode_dag_update(C, snode);
+ DEG_relations_tag_update(bmain);
return OPERATOR_FINISHED;
}
@@ -876,7 +879,7 @@ static int node_add_mask_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node;
- ID *mask = NULL;
+ ID *mask = nullptr;
/* check input variables */
char name[MAX_ID_NAME - 2];
@@ -890,7 +893,7 @@ static int node_add_mask_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
node = node_add_node(
- C, NULL, CMP_NODE_MASK, snode->runtime->cursor[0], snode->runtime->cursor[1]);
+ C, nullptr, CMP_NODE_MASK, snode->runtime->cursor[0], snode->runtime->cursor[1]);
if (!node) {
BKE_report(op->reports, RPT_WARNING, "Could not add a mask node");
@@ -902,6 +905,7 @@ static int node_add_mask_exec(bContext *C, wmOperator *op)
snode_notify(C, snode);
snode_dag_update(C, snode);
+ DEG_relations_tag_update(bmain);
return OPERATOR_FINISHED;
}
@@ -976,7 +980,7 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
id_us_min(&ntree->id);
RNA_id_pointer_create(&ntree->id, &idptr);
- RNA_property_pointer_set(&ptr, prop, idptr, NULL);
+ RNA_property_pointer_set(&ptr, prop, idptr, nullptr);
RNA_property_update(C, &ptr, prop);
}
else if (snode) {
@@ -993,7 +997,7 @@ static const EnumPropertyItem *new_node_tree_type_itemf(bContext *UNUSED(C),
PropertyRNA *UNUSED(prop),
bool *r_free)
{
- return rna_node_tree_type_itemf(NULL, NULL, r_free);
+ return rna_node_tree_type_itemf(nullptr, nullptr, r_free);
}
void NODE_OT_new_node_tree(wmOperatorType *ot)
diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c
deleted file mode 100644
index 336b0c46a81..00000000000
--- a/source/blender/editors/space_node/node_buttons.c
+++ /dev/null
@@ -1,223 +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) 2009 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup spnode
- */
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_node_types.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-
-#include "BLT_translation.h"
-
-#include "BKE_context.h"
-#include "BKE_global.h"
-#include "BKE_node.h"
-#include "BKE_screen.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-#include "RNA_access.h"
-
-#include "ED_screen.h"
-
-#include "UI_resources.h"
-
-#include "node_intern.h" /* own include */
-
-/* ******************* node space & buttons ************** */
-
-#if 0
-/* poll for active nodetree */
-static bool active_nodetree_poll(const bContext *C, PanelType *UNUSED(pt))
-{
- SpaceNode *snode = CTX_wm_space_node(C);
-
- return (snode && snode->nodetree);
-}
-#endif
-
-static bool node_sockets_poll(const bContext *C, PanelType *UNUSED(pt))
-{
- SpaceNode *snode = CTX_wm_space_node(C);
-
- return (snode && snode->nodetree && G.debug_value == 777);
-}
-
-static void node_sockets_panel(const bContext *C, Panel *panel)
-{
- SpaceNode *snode = CTX_wm_space_node(C); /* NULL checked in poll function. */
- bNodeTree *ntree = snode->edittree; /* NULL checked in poll function. */
- bNode *node = nodeGetActive(ntree);
- if (node == NULL) {
- return;
- }
-
- LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
- char name[UI_MAX_NAME_STR];
- BLI_snprintf(name, sizeof(name), "%s:", socket->name);
-
- uiLayout *split = uiLayoutSplit(panel->layout, 0.35f, false);
- uiItemL(split, name, ICON_NONE);
- uiTemplateNodeLink(split, (bContext *)C, ntree, node, socket);
- }
-}
-
-static bool node_tree_interface_poll(const bContext *C, PanelType *UNUSED(pt))
-{
- SpaceNode *snode = CTX_wm_space_node(C);
-
- return (snode && snode->edittree &&
- (snode->edittree->inputs.first || snode->edittree->outputs.first));
-}
-
-static bNodeSocket *node_tree_find_active_socket(bNodeTree *ntree, const eNodeSocketInOut in_out)
-{
- ListBase *sockets = (in_out == SOCK_IN) ? &ntree->inputs : &ntree->outputs;
- LISTBASE_FOREACH (bNodeSocket *, socket, sockets) {
- if (socket->flag & SELECT) {
- return socket;
- }
- }
- return NULL;
-}
-
-static void draw_socket_list(const bContext *C,
- uiLayout *layout,
- bNodeTree *ntree,
- const eNodeSocketInOut in_out)
-{
- PointerRNA tree_ptr;
- RNA_id_pointer_create((ID *)ntree, &tree_ptr);
-
- uiLayout *split = uiLayoutRow(layout, false);
- uiLayout *list_col = uiLayoutColumn(split, true);
- uiTemplateList(list_col,
- (bContext *)C,
- "NODE_UL_interface_sockets",
- (in_out == SOCK_IN) ? "inputs" : "outputs",
- &tree_ptr,
- (in_out == SOCK_IN) ? "inputs" : "outputs",
- &tree_ptr,
- (in_out == SOCK_IN) ? "active_input" : "active_output",
- NULL,
- 0,
- 0,
- 0,
- 0,
- false,
- false);
- PointerRNA opptr;
- uiLayout *ops_col = uiLayoutColumn(split, false);
- uiLayout *add_remove_col = uiLayoutColumn(ops_col, true);
- wmOperatorType *ot = WM_operatortype_find("NODE_OT_tree_socket_add", false);
- uiItemFullO_ptr(add_remove_col, ot, "", ICON_ADD, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
- RNA_enum_set(&opptr, "in_out", in_out);
- ot = WM_operatortype_find("NODE_OT_tree_socket_remove", false);
- uiItemFullO_ptr(add_remove_col, ot, "", ICON_REMOVE, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
- RNA_enum_set(&opptr, "in_out", in_out);
-
- uiItemS(ops_col);
-
- uiLayout *up_down_col = uiLayoutColumn(ops_col, true);
- ot = WM_operatortype_find("NODE_OT_tree_socket_move", false);
- uiItemFullO_ptr(up_down_col, ot, "", ICON_TRIA_UP, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
- RNA_enum_set(&opptr, "direction", 1);
- RNA_enum_set(&opptr, "in_out", in_out);
- uiItemFullO_ptr(up_down_col, ot, "", ICON_TRIA_DOWN, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
- RNA_enum_set(&opptr, "direction", 2);
- RNA_enum_set(&opptr, "in_out", in_out);
-
- bNodeSocket *socket = node_tree_find_active_socket(ntree, in_out);
- if (socket != NULL) {
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- PointerRNA socket_ptr;
- RNA_pointer_create((ID *)ntree, &RNA_NodeSocketInterface, socket, &socket_ptr);
- uiItemR(layout, &socket_ptr, "name", 0, NULL, ICON_NONE);
-
- /* Display descriptions only for Geometry Nodes, since it's only used in the modifier panel. */
- if (ntree->type == NTREE_GEOMETRY) {
- uiItemR(layout, &socket_ptr, "description", 0, NULL, ICON_NONE);
- }
-
- if (socket->typeinfo->interface_draw) {
- socket->typeinfo->interface_draw((bContext *)C, layout, &socket_ptr);
- }
- }
-}
-
-static void node_tree_interface_inputs_panel(const bContext *C, Panel *panel)
-{
- SpaceNode *snode = CTX_wm_space_node(C); /* NULL checked in poll function. */
- bNodeTree *ntree = snode->edittree; /* NULL checked in poll function. */
-
- draw_socket_list(C, panel->layout, ntree, SOCK_IN);
-}
-
-static void node_tree_interface_outputs_panel(const bContext *C, Panel *panel)
-{
- SpaceNode *snode = CTX_wm_space_node(C); /* NULL checked in poll function. */
- bNodeTree *ntree = snode->edittree; /* NULL checked in poll function. */
-
- draw_socket_list(C, panel->layout, ntree, SOCK_OUT);
-}
-
-/* ******************* node buttons registration ************** */
-
-void node_buttons_register(ARegionType *art)
-{
- {
- PanelType *pt = MEM_callocN(sizeof(PanelType), __func__);
- strcpy(pt->idname, "NODE_PT_sockets");
- strcpy(pt->category, N_("Node"));
- strcpy(pt->label, N_("Sockets"));
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = node_sockets_panel;
- pt->poll = node_sockets_poll;
- pt->flag |= PANEL_TYPE_DEFAULT_CLOSED;
- BLI_addtail(&art->paneltypes, pt);
- }
-
- {
- PanelType *pt = MEM_callocN(sizeof(PanelType), __func__);
- strcpy(pt->idname, "NODE_PT_node_tree_interface_inputs");
- strcpy(pt->category, N_("Group"));
- strcpy(pt->label, N_("Inputs"));
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = node_tree_interface_inputs_panel;
- pt->poll = node_tree_interface_poll;
- BLI_addtail(&art->paneltypes, pt);
- }
- {
- PanelType *pt = MEM_callocN(sizeof(PanelType), __func__);
- strcpy(pt->idname, "NODE_PT_node_tree_interface_outputs");
- strcpy(pt->category, N_("Group"));
- strcpy(pt->label, N_("Outputs"));
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = node_tree_interface_outputs_panel;
- pt->poll = node_tree_interface_poll;
- BLI_addtail(&art->paneltypes, pt);
- }
-}
diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc
index fd9c0f42f2d..7eca5c0c933 100644
--- a/source/blender/editors/space_node/node_draw.cc
+++ b/source/blender/editors/space_node/node_draw.cc
@@ -45,10 +45,10 @@
#include "BLT_translation.h"
#include "BKE_context.h"
+#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_node.h"
-#include "BKE_node_ui_storage.hh"
#include "BKE_object.h"
#include "DEG_depsgraph.h"
@@ -76,15 +76,21 @@
#include "RNA_access.h"
+#include "NOD_geometry_nodes_eval_log.hh"
+
#include "node_intern.h" /* own include */
#ifdef WITH_COMPOSITOR
# include "COM_compositor.h"
#endif
+using blender::Map;
using blender::Set;
using blender::Span;
using blender::Vector;
+using blender::fn::CPPType;
+using blender::fn::GPointer;
+namespace geo_log = blender::nodes::geometry_nodes_eval_log;
extern "C" {
/* XXX interface.h */
@@ -821,6 +827,149 @@ void node_socket_color_get(
}
}
+struct SocketTooltipData {
+ bNodeTree *ntree;
+ bNode *node;
+ bNodeSocket *socket;
+};
+
+static void create_inspection_string_for_generic_value(const geo_log::GenericValueLog &value_log,
+ std::stringstream &ss)
+{
+ auto id_to_inspection_string = [&](ID *id) {
+ ss << (id ? id->name + 2 : TIP_("None")) << " (" << BKE_idtype_idcode_to_name(GS(id->name))
+ << ")";
+ };
+
+ const GPointer value = value_log.value();
+ if (value.is_type<int>()) {
+ ss << *value.get<int>() << TIP_(" (Integer)");
+ }
+ else if (value.is_type<float>()) {
+ ss << *value.get<float>() << TIP_(" (Float)");
+ }
+ else if (value.is_type<blender::float3>()) {
+ ss << *value.get<blender::float3>() << TIP_(" (Vector)");
+ }
+ else if (value.is_type<bool>()) {
+ ss << (*value.get<bool>() ? TIP_("True") : TIP_("False")) << TIP_(" (Boolean)");
+ }
+ else if (value.is_type<std::string>()) {
+ ss << *value.get<std::string>() << TIP_(" (String)");
+ }
+ else if (value.is_type<Object *>()) {
+ id_to_inspection_string((ID *)*value.get<Object *>());
+ }
+ else if (value.is_type<Material *>()) {
+ id_to_inspection_string((ID *)*value.get<Material *>());
+ }
+ else if (value.is_type<Tex *>()) {
+ id_to_inspection_string((ID *)*value.get<Tex *>());
+ }
+ else if (value.is_type<Collection *>()) {
+ id_to_inspection_string((ID *)*value.get<Collection *>());
+ }
+}
+
+static void create_inspection_string_for_geometry(const geo_log::GeometryValueLog &value_log,
+ std::stringstream &ss)
+{
+ Span<GeometryComponentType> component_types = value_log.component_types();
+ if (component_types.is_empty()) {
+ ss << TIP_("Empty Geometry");
+ return;
+ }
+
+ auto to_string = [](int value) {
+ char str[16];
+ BLI_str_format_int_grouped(str, value);
+ return std::string(str);
+ };
+
+ ss << TIP_("Geometry:\n");
+ for (GeometryComponentType type : component_types) {
+ const char *line_end = (type == component_types.last()) ? "" : ".\n";
+ switch (type) {
+ case GEO_COMPONENT_TYPE_MESH: {
+ const geo_log::GeometryValueLog::MeshInfo &mesh_info = *value_log.mesh_info;
+ char line[256];
+ BLI_snprintf(line,
+ sizeof(line),
+ TIP_("\u2022 Mesh: %s vertices, %s edges, %s faces"),
+ to_string(mesh_info.tot_verts).c_str(),
+ to_string(mesh_info.tot_edges).c_str(),
+ to_string(mesh_info.tot_faces).c_str());
+ ss << line << line_end;
+ break;
+ }
+ case GEO_COMPONENT_TYPE_POINT_CLOUD: {
+ const geo_log::GeometryValueLog::PointCloudInfo &pointcloud_info =
+ *value_log.pointcloud_info;
+ char line[256];
+ BLI_snprintf(line,
+ sizeof(line),
+ TIP_("\u2022 Point Cloud: %s points"),
+ to_string(pointcloud_info.tot_points).c_str());
+ ss << line << line_end;
+ break;
+ }
+ case GEO_COMPONENT_TYPE_CURVE: {
+ const geo_log::GeometryValueLog::CurveInfo &curve_info = *value_log.curve_info;
+ char line[256];
+ BLI_snprintf(line,
+ sizeof(line),
+ TIP_("\u2022 Curve: %s splines"),
+ to_string(curve_info.tot_splines).c_str());
+ ss << line << line_end;
+ break;
+ }
+ case GEO_COMPONENT_TYPE_INSTANCES: {
+ const geo_log::GeometryValueLog::InstancesInfo &instances_info = *value_log.instances_info;
+ char line[256];
+ BLI_snprintf(line,
+ sizeof(line),
+ TIP_("\u2022 Instances: %s"),
+ to_string(instances_info.tot_instances).c_str());
+ ss << line << line_end;
+ break;
+ }
+ case GEO_COMPONENT_TYPE_VOLUME: {
+ ss << TIP_("\u2022 Volume") << line_end;
+ break;
+ }
+ }
+ }
+}
+
+static std::optional<std::string> create_socket_inspection_string(bContext *C,
+ bNodeTree &UNUSED(ntree),
+ bNode &node,
+ bNodeSocket &socket)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ const geo_log::SocketLog *socket_log = geo_log::ModifierLog::find_socket_by_node_editor_context(
+ *snode, node, socket);
+ if (socket_log == nullptr) {
+ return {};
+ }
+ const geo_log::ValueLog *value_log = socket_log->value();
+ if (value_log == nullptr) {
+ return {};
+ }
+
+ std::stringstream ss;
+ if (const geo_log::GenericValueLog *generic_value_log =
+ dynamic_cast<const geo_log::GenericValueLog *>(value_log)) {
+ create_inspection_string_for_generic_value(*generic_value_log, ss);
+ }
+ else if (const geo_log::GeometryValueLog *geo_value_log =
+ dynamic_cast<const geo_log::GeometryValueLog *>(value_log)) {
+ create_inspection_string_for_geometry(*geo_value_log, ss);
+ }
+
+ return ss.str();
+}
+
static void node_socket_draw_nested(const bContext *C,
bNodeTree *ntree,
PointerRNA *node_ptr,
@@ -850,6 +999,55 @@ static void node_socket_draw_nested(const bContext *C,
shape_id,
size_id,
outline_col_id);
+
+ if (ntree->type != NTREE_GEOMETRY) {
+ /* Only geometry nodes has socket value tooltips currently. */
+ return;
+ }
+
+ bNode *node = (bNode *)node_ptr->data;
+ uiBlock *block = node->block;
+
+ /* Ideally sockets themselves should be buttons, but they aren't currently. So add an invisible
+ * button on top of them for the tooltip. */
+ const eUIEmbossType old_emboss = UI_block_emboss_get(block);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ uiBut *but = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_NONE,
+ sock->locx - size / 2,
+ sock->locy - size / 2,
+ size,
+ size,
+ nullptr,
+ 0,
+ 0,
+ 0,
+ 0,
+ nullptr);
+
+ SocketTooltipData *data = (SocketTooltipData *)MEM_mallocN(sizeof(SocketTooltipData), __func__);
+ data->ntree = ntree;
+ data->node = (bNode *)node_ptr->data;
+ data->socket = sock;
+
+ UI_but_func_tooltip_set(
+ but,
+ [](bContext *C, void *argN, const char *UNUSED(tip)) {
+ SocketTooltipData *data = (SocketTooltipData *)argN;
+ std::optional<std::string> str = create_socket_inspection_string(
+ C, *data->ntree, *data->node, *data->socket);
+ if (str.has_value()) {
+ return BLI_strdup(str->c_str());
+ }
+ return BLI_strdup(TIP_("The socket value has not been computed yet"));
+ },
+ data,
+ MEM_freeN);
+ /* Disable the button so that clicks on it are ignored the the link operator still works. */
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ UI_block_emboss_set(block, old_emboss);
}
/**
@@ -1184,14 +1382,14 @@ void node_draw_sockets(const View2D *v2d,
}
}
-static int node_error_type_to_icon(const NodeWarningType type)
+static int node_error_type_to_icon(const geo_log::NodeWarningType type)
{
switch (type) {
- case NodeWarningType::Error:
+ case geo_log::NodeWarningType::Error:
return ICON_ERROR;
- case NodeWarningType::Warning:
+ case geo_log::NodeWarningType::Warning:
return ICON_ERROR;
- case NodeWarningType::Info:
+ case geo_log::NodeWarningType::Info:
return ICON_INFO;
}
@@ -1199,14 +1397,14 @@ static int node_error_type_to_icon(const NodeWarningType type)
return ICON_ERROR;
}
-static uint8_t node_error_type_priority(const NodeWarningType type)
+static uint8_t node_error_type_priority(const geo_log::NodeWarningType type)
{
switch (type) {
- case NodeWarningType::Error:
+ case geo_log::NodeWarningType::Error:
return 3;
- case NodeWarningType::Warning:
+ case geo_log::NodeWarningType::Warning:
return 2;
- case NodeWarningType::Info:
+ case geo_log::NodeWarningType::Info:
return 1;
}
@@ -1214,11 +1412,11 @@ static uint8_t node_error_type_priority(const NodeWarningType type)
return 0;
}
-static NodeWarningType node_error_highest_priority(Span<NodeWarning> warnings)
+static geo_log::NodeWarningType node_error_highest_priority(Span<geo_log::NodeWarning> warnings)
{
uint8_t highest_priority = 0;
- NodeWarningType highest_priority_type = NodeWarningType::Info;
- for (const NodeWarning &warning : warnings) {
+ geo_log::NodeWarningType highest_priority_type = geo_log::NodeWarningType::Info;
+ for (const geo_log::NodeWarning &warning : warnings) {
const uint8_t priority = node_error_type_priority(warning.type);
if (priority > highest_priority) {
highest_priority = priority;
@@ -1228,15 +1426,17 @@ static NodeWarningType node_error_highest_priority(Span<NodeWarning> warnings)
return highest_priority_type;
}
+struct NodeErrorsTooltipData {
+ Span<geo_log::NodeWarning> warnings;
+};
+
static char *node_errors_tooltip_fn(bContext *UNUSED(C), void *argN, const char *UNUSED(tip))
{
- const NodeUIStorage **storage_pointer_alloc = static_cast<const NodeUIStorage **>(argN);
- const NodeUIStorage *node_ui_storage = *storage_pointer_alloc;
- Span<NodeWarning> warnings = node_ui_storage->warnings;
+ NodeErrorsTooltipData &data = *(NodeErrorsTooltipData *)argN;
std::string complete_string;
- for (const NodeWarning &warning : warnings.drop_back(1)) {
+ for (const geo_log::NodeWarning &warning : data.warnings.drop_back(1)) {
complete_string += warning.message;
/* Adding the period is not ideal for multi-line messages, but it is consistent
* with other tooltip implementations in Blender, so it is added here. */
@@ -1245,7 +1445,7 @@ static char *node_errors_tooltip_fn(bContext *UNUSED(C), void *argN, const char
}
/* Let the tooltip system automatically add the last period. */
- complete_string += warnings.last().message;
+ complete_string += data.warnings.last().message;
return BLI_strdupn(complete_string.c_str(), complete_string.size());
}
@@ -1253,20 +1453,26 @@ static char *node_errors_tooltip_fn(bContext *UNUSED(C), void *argN, const char
#define NODE_HEADER_ICON_SIZE (0.8f * U.widget_unit)
static void node_add_error_message_button(
- const bContext *C, bNodeTree &ntree, bNode &node, const rctf &rect, float &icon_offset)
+ const bContext *C, bNodeTree &UNUSED(ntree), bNode &node, const rctf &rect, float &icon_offset)
{
- const NodeUIStorage *node_ui_storage = BKE_node_tree_ui_storage_get_from_context(C, ntree, node);
- if (node_ui_storage == nullptr || node_ui_storage->warnings.is_empty()) {
+ SpaceNode *snode = CTX_wm_space_node(C);
+ const geo_log::NodeLog *node_log = geo_log::ModifierLog::find_node_by_node_editor_context(*snode,
+ node);
+ if (node_log == nullptr) {
+ return;
+ }
+
+ Span<geo_log::NodeWarning> warnings = node_log->warnings();
+
+ if (warnings.is_empty()) {
return;
}
- /* The UI API forces us to allocate memory for each error button, because the
- * ownership of #UI_but_func_tooltip_set's argument is transferred to the button. */
- const NodeUIStorage **storage_pointer_alloc = (const NodeUIStorage **)MEM_mallocN(
- sizeof(NodeUIStorage *), __func__);
- *storage_pointer_alloc = node_ui_storage;
+ NodeErrorsTooltipData *tooltip_data = (NodeErrorsTooltipData *)MEM_mallocN(
+ sizeof(NodeErrorsTooltipData), __func__);
+ tooltip_data->warnings = warnings;
- const NodeWarningType display_type = node_error_highest_priority(node_ui_storage->warnings);
+ const geo_log::NodeWarningType display_type = node_error_highest_priority(warnings);
icon_offset -= NODE_HEADER_ICON_SIZE;
UI_block_emboss_set(node.block, UI_EMBOSS_NONE);
@@ -1284,7 +1490,7 @@ static void node_add_error_message_button(
0,
0,
nullptr);
- UI_but_func_tooltip_set(but, node_errors_tooltip_fn, storage_pointer_alloc);
+ UI_but_func_tooltip_set(but, node_errors_tooltip_fn, tooltip_data, MEM_freeN);
UI_block_emboss_set(node.block, UI_EMBOSS);
}
@@ -1404,28 +1610,6 @@ static void node_draw_basis(const bContext *C,
"");
UI_block_emboss_set(node->block, UI_EMBOSS);
}
- if (ntree->type == NTREE_GEOMETRY) {
- /* Active preview toggle. */
- iconofs -= iconbutw;
- UI_block_emboss_set(node->block, UI_EMBOSS_NONE);
- int icon = (node->flag & NODE_ACTIVE_PREVIEW) ? ICON_RESTRICT_VIEW_OFF : ICON_RESTRICT_VIEW_ON;
- uiBut *but = uiDefIconBut(node->block,
- UI_BTYPE_BUT_TOGGLE,
- 0,
- icon,
- iconofs,
- rct->ymax - NODE_DY,
- iconbutw,
- UI_UNIT_Y,
- nullptr,
- 0,
- 0,
- 0,
- 0,
- "Show this node's geometry output in the spreadsheet");
- UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_active_preview_toggle");
- UI_block_emboss_set(node->block, UI_EMBOSS);
- }
node_add_error_message_button(C, *ntree, *node, *rct, iconofs);
@@ -1765,28 +1949,29 @@ static void node_update(const bContext *C, bNodeTree *ntree, bNode *node)
}
}
-static void count_mutli_input_socket_links(bNodeTree *ntree, SpaceNode *snode)
+static void count_multi_input_socket_links(bNodeTree *ntree, SpaceNode *snode)
{
+ Map<bNodeSocket *, int> counts;
+ LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
+ if (link->tosock->flag & SOCK_MULTI_INPUT) {
+ int &count = counts.lookup_or_add(link->tosock, 0);
+ count++;
+ }
+ }
+ /* Count temporary links going into this socket. */
+ LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->runtime->linkdrag) {
+ LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
+ bNodeLink *link = (bNodeLink *)linkdata->data;
+ if (link->tosock && (link->tosock->flag & SOCK_MULTI_INPUT)) {
+ int &count = counts.lookup_or_add(link->tosock, 0);
+ count++;
+ }
+ }
+ }
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- LISTBASE_FOREACH (struct bNodeSocket *, socket, &node->inputs) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
if (socket->flag & SOCK_MULTI_INPUT) {
- Set<bNodeSocket *> visited_from_sockets;
- socket->total_inputs = 0;
- LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
- if (link->tosock == socket) {
- visited_from_sockets.add(link->fromsock);
- }
- }
- /* Count temporary links going into this socket. */
- LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->runtime->linkdrag) {
- LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
- bNodeLink *link = (bNodeLink *)linkdata->data;
- if (link->tosock == socket) {
- visited_from_sockets.add(link->fromsock);
- }
- }
- }
- socket->total_inputs = visited_from_sockets.size();
+ socket->total_inputs = counts.lookup_default(socket, 0);
}
}
}
@@ -1798,7 +1983,7 @@ void node_update_nodetree(const bContext *C, bNodeTree *ntree)
SpaceNode *snode = CTX_wm_space_node(C);
ntreeTagUsedSockets(ntree);
- count_mutli_input_socket_links(ntree, snode);
+ count_multi_input_socket_links(ntree, snode);
/* Update nodes front to back, so children sizes get updated before parents. */
LISTBASE_FOREACH_BACKWARD (bNode *, node, &ntree->nodes) {
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.cc
index 50fa8b28468..5dd935bdd76 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.cc
@@ -54,6 +54,7 @@
#include "ED_render.h"
#include "ED_screen.h"
#include "ED_select_utils.h"
+#include "ED_spreadsheet.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -83,7 +84,7 @@ enum {
COM_RECALC_VIEWER = 2,
};
-typedef struct CompoJob {
+struct CompoJob {
/* Input parameters. */
Main *bmain;
Scene *scene;
@@ -97,7 +98,7 @@ typedef struct CompoJob {
const short *stop;
short *do_update;
float *progress;
-} CompoJob;
+};
float node_socket_calculate_height(const bNodeSocket *socket)
{
@@ -150,7 +151,7 @@ static int compo_get_recalc_flags(const bContext *C)
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = area->spacedata.first;
+ SpaceImage *sima = (SpaceImage *)area->spacedata.first;
if (sima->image) {
if (sima->image->type == IMA_TYPE_R_RESULT) {
recalc_flags |= COM_RECALC_COMPOSITE;
@@ -161,7 +162,7 @@ static int compo_get_recalc_flags(const bContext *C)
}
}
else if (area->spacetype == SPACE_NODE) {
- SpaceNode *snode = area->spacedata.first;
+ SpaceNode *snode = (SpaceNode *)area->spacedata.first;
if (snode->flag & SNODE_BACKDRAW) {
recalc_flags |= COM_RECALC_VIEWER;
}
@@ -175,9 +176,9 @@ static int compo_get_recalc_flags(const bContext *C)
/* called by compo, only to check job 'stop' value */
static int compo_breakjob(void *cjv)
{
- CompoJob *cj = cjv;
+ CompoJob *cj = (CompoJob *)cjv;
- /* without G.is_break 'ESC' wont quit - which annoys users */
+ /* without G.is_break 'ESC' won't quit - which annoys users */
return (*(cj->stop)
#ifdef USE_ESC_COMPO
|| G.is_break
@@ -188,7 +189,7 @@ static int compo_breakjob(void *cjv)
/* called by compo, wmJob sends notifier */
static void compo_statsdrawjob(void *cjv, const char *UNUSED(str))
{
- CompoJob *cj = cjv;
+ CompoJob *cj = (CompoJob *)cjv;
*(cj->do_update) = true;
}
@@ -196,19 +197,19 @@ static void compo_statsdrawjob(void *cjv, const char *UNUSED(str))
/* called by compo, wmJob sends notifier */
static void compo_redrawjob(void *cjv)
{
- CompoJob *cj = cjv;
+ CompoJob *cj = (CompoJob *)cjv;
*(cj->do_update) = true;
}
static void compo_freejob(void *cjv)
{
- CompoJob *cj = cjv;
+ CompoJob *cj = (CompoJob *)cjv;
if (cj->localtree) {
ntreeLocalMerge(cj->bmain, cj->localtree, cj->ntree);
}
- if (cj->compositor_depsgraph != NULL) {
+ if (cj->compositor_depsgraph != nullptr) {
DEG_graph_free(cj->compositor_depsgraph);
}
MEM_freeN(cj);
@@ -218,7 +219,7 @@ static void compo_freejob(void *cjv)
* sliding buttons doesn't frustrate */
static void compo_initjob(void *cjv)
{
- CompoJob *cj = cjv;
+ CompoJob *cj = (CompoJob *)cjv;
Main *bmain = cj->bmain;
Scene *scene = cj->scene;
ViewLayer *view_layer = cj->view_layer;
@@ -243,12 +244,12 @@ static void compo_initjob(void *cjv)
/* called before redraw notifiers, it moves finished previews over */
static void compo_updatejob(void *UNUSED(cjv))
{
- WM_main_add_notifier(NC_SCENE | ND_COMPO_RESULT, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_COMPO_RESULT, nullptr);
}
static void compo_progressjob(void *cjv, float progress)
{
- CompoJob *cj = cjv;
+ CompoJob *cj = (CompoJob *)cjv;
*(cj->progress) = progress;
}
@@ -261,7 +262,7 @@ static void compo_startjob(void *cjv,
short *do_update,
float *progress)
{
- CompoJob *cj = cjv;
+ CompoJob *cj = (CompoJob *)cjv;
bNodeTree *ntree = cj->localtree;
Scene *scene = cj->scene;
@@ -311,9 +312,9 @@ static void compo_startjob(void *cjv,
}
}
- ntree->test_break = NULL;
- ntree->stats_draw = NULL;
- ntree->progress = NULL;
+ ntree->test_break = nullptr;
+ ntree->stats_draw = nullptr;
+ ntree->progress = nullptr;
}
/**
@@ -347,7 +348,7 @@ void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, Scene
"Compositing",
WM_JOB_EXCL_RENDER | WM_JOB_PROGRESS,
WM_JOB_TYPE_COMPOSITE);
- CompoJob *cj = MEM_callocN(sizeof(CompoJob), "compo job");
+ CompoJob *cj = (CompoJob *)MEM_callocN(sizeof(CompoJob), "compo job");
/* customdata for preview thread */
cj->bmain = bmain;
@@ -359,7 +360,7 @@ void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, Scene
/* setup job */
WM_jobs_customdata_set(wm_job, cj, compo_freejob);
WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_COMPO_RESULT, NC_SCENE | ND_COMPO_RESULT);
- WM_jobs_callbacks(wm_job, compo_startjob, compo_initjob, compo_updatejob, NULL);
+ WM_jobs_callbacks(wm_job, compo_startjob, compo_initjob, compo_updatejob, nullptr);
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
@@ -412,7 +413,7 @@ void snode_notify(bContext *C, SpaceNode *snode)
{
ID *id = snode->id;
- WM_event_add_notifier(C, NC_NODE | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_NODE | NA_EDITED, nullptr);
if (ED_node_is_shader(snode)) {
if (GS(id->name) == ID_MA) {
@@ -490,15 +491,15 @@ void ED_node_shader_default(const bContext *C, ID *id)
}
else if (ELEM(GS(id->name), ID_WO, ID_LA)) {
/* Emission */
- bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
+ bNodeTree *ntree = ntreeAddTree(nullptr, "Shader Nodetree", ntreeType_Shader->idname);
bNode *shader, *output;
if (GS(id->name) == ID_WO) {
World *world = (World *)id;
world->nodetree = ntree;
- shader = nodeAddStaticNode(NULL, ntree, SH_NODE_BACKGROUND);
- output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_WORLD);
+ shader = nodeAddStaticNode(nullptr, ntree, SH_NODE_BACKGROUND);
+ output = nodeAddStaticNode(nullptr, ntree, SH_NODE_OUTPUT_WORLD);
nodeAddLink(ntree,
shader,
nodeFindSocket(shader, SOCK_OUT, "Background"),
@@ -512,8 +513,8 @@ void ED_node_shader_default(const bContext *C, ID *id)
Light *light = (Light *)id;
light->nodetree = ntree;
- shader = nodeAddStaticNode(NULL, ntree, SH_NODE_EMISSION);
- output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_LIGHT);
+ shader = nodeAddStaticNode(nullptr, ntree, SH_NODE_EMISSION);
+ output = nodeAddStaticNode(nullptr, ntree, SH_NODE_OUTPUT_LIGHT);
nodeAddLink(ntree,
shader,
nodeFindSocket(shader, SOCK_OUT, "Emission"),
@@ -546,7 +547,7 @@ void ED_node_composit_default(const bContext *C, struct Scene *sce)
return;
}
- sce->nodetree = ntreeAddTree(NULL, "Compositing Nodetree", ntreeType_Composite->idname);
+ sce->nodetree = ntreeAddTree(nullptr, "Compositing Nodetree", ntreeType_Composite->idname);
sce->nodetree->chunksize = 256;
sce->nodetree->edit_quality = NTREE_QUALITY_HIGH;
@@ -562,8 +563,8 @@ void ED_node_composit_default(const bContext *C, struct Scene *sce)
nodeSetActive(sce->nodetree, in);
/* links from color to color */
- bNodeSocket *fromsock = in->outputs.first;
- bNodeSocket *tosock = out->inputs.first;
+ bNodeSocket *fromsock = (bNodeSocket *)in->outputs.first;
+ bNodeSocket *tosock = (bNodeSocket *)out->inputs.first;
nodeAddLink(sce->nodetree, in, fromsock, out, tosock);
ntreeUpdateTree(CTX_data_main(C), sce->nodetree);
@@ -581,7 +582,7 @@ void ED_node_texture_default(const bContext *C, Tex *tex)
return;
}
- tex->nodetree = ntreeAddTree(NULL, "Texture Nodetree", ntreeType_Texture->idname);
+ tex->nodetree = ntreeAddTree(nullptr, "Texture Nodetree", ntreeType_Texture->idname);
bNode *out = nodeAddStaticNode(C, tex->nodetree, TEX_NODE_OUTPUT);
out->locx = 300.0f;
@@ -592,8 +593,8 @@ void ED_node_texture_default(const bContext *C, Tex *tex)
in->locy = 300.0f;
nodeSetActive(tex->nodetree, in);
- bNodeSocket *fromsock = in->outputs.first;
- bNodeSocket *tosock = out->inputs.first;
+ bNodeSocket *fromsock = (bNodeSocket *)in->outputs.first;
+ bNodeSocket *tosock = (bNodeSocket *)out->inputs.first;
nodeAddLink(tex->nodetree, in, fromsock, out, tosock);
ntreeUpdateTree(CTX_data_main(C), tex->nodetree);
@@ -618,24 +619,24 @@ void snode_set_context(const bContext *C)
if (snode->nodetree && !STREQ(snode->nodetree->idname, snode->tree_idname)) {
/* current tree does not match selected type, clear tree path */
- ntree = NULL;
- id = NULL;
- from = NULL;
+ ntree = nullptr;
+ id = nullptr;
+ from = nullptr;
}
- if (!(snode->flag & SNODE_PIN) || ntree == NULL) {
+ if (!(snode->flag & SNODE_PIN) || ntree == nullptr) {
if (treetype->get_from_context) {
/* reset and update from context */
- ntree = NULL;
- id = NULL;
- from = NULL;
+ ntree = nullptr;
+ id = nullptr;
+ from = nullptr;
treetype->get_from_context(C, treetype, &ntree, &id, &from);
}
}
if (snode->nodetree != ntree || snode->id != id || snode->from != from ||
- (snode->treepath.last == NULL && ntree)) {
+ (snode->treepath.last == nullptr && ntree)) {
ED_node_tree_start(snode, ntree, id, from);
}
}
@@ -648,7 +649,7 @@ void snode_update(SpaceNode *snode, bNode *node)
*/
/* update all edited group nodes */
- bNodeTreePath *path = snode->treepath.last;
+ bNodeTreePath *path = (bNodeTreePath *)snode->treepath.last;
if (path) {
bNodeTree *ngroup = path->nodetree;
for (path = path->prev; path; path = path->prev) {
@@ -662,7 +663,8 @@ void snode_update(SpaceNode *snode, bNode *node)
}
}
-void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_active_texture_changed)
+void ED_node_set_active(
+ Main *bmain, SpaceNode *snode, bNodeTree *ntree, bNode *node, bool *r_active_texture_changed)
{
const bool was_active_texture = (node->flag & NODE_ACTIVE_TEXTURE) != 0;
if (r_active_texture_changed) {
@@ -685,7 +687,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_acti
node->flag |= NODE_DO_OUTPUT;
if (!was_output) {
- do_update = 1;
+ do_update = true;
}
}
@@ -734,7 +736,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_acti
*r_active_texture_changed = true;
}
ED_node_tag_update_nodetree(bmain, ntree, node);
- WM_main_add_notifier(NC_IMAGE, NULL);
+ WM_main_add_notifier(NC_IMAGE, nullptr);
}
WM_main_add_notifier(NC_MATERIAL | ND_NODES, node->id);
@@ -753,7 +755,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_acti
ED_node_tag_update_nodetree(bmain, ntree, node);
}
- /* addnode() doesn't link this yet... */
+ /* Adding a node doesn't link this yet. */
node->id = (ID *)BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
}
else if (node->type == CMP_NODE_COMPOSITE) {
@@ -782,6 +784,19 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_acti
}
#endif
}
+ else if (ntree->type == NTREE_GEOMETRY) {
+ if (node->type == GEO_NODE_VIEWER) {
+ if ((node->flag & NODE_DO_OUTPUT) == 0) {
+ LISTBASE_FOREACH (bNode *, node_iter, &ntree->nodes) {
+ if (node_iter->type == GEO_NODE_VIEWER) {
+ node_iter->flag &= ~NODE_DO_OUTPUT;
+ }
+ }
+ node->flag |= NODE_DO_OUTPUT;
+ ED_spreadsheet_context_paths_set_geometry_node(bmain, snode, node);
+ }
+ }
+ }
}
}
@@ -806,7 +821,7 @@ static bool edit_node_poll(bContext *C)
static void edit_node_properties(wmOperatorType *ot)
{
/* XXX could node be a context pointer? */
- RNA_def_string(ot->srna, "node", NULL, MAX_NAME, "Node", "");
+ RNA_def_string(ot->srna, "node", nullptr, MAX_NAME, "Node", "");
RNA_def_int(ot->srna, "socket", 0, 0, MAX_SOCKET, "Socket", "", 0, MAX_SOCKET);
RNA_def_enum(ot->srna, "in_out", rna_enum_node_socket_in_out_items, SOCK_IN, "Socket Side", "");
}
@@ -838,7 +853,7 @@ static void edit_node_properties_get(
wmOperator *op, bNodeTree *ntree, bNode **r_node, bNodeSocket **r_sock, int *r_in_out)
{
bNode *node;
- bNodeSocket *sock = NULL;
+ bNodeSocket *sock = nullptr;
char nodename[MAX_NAME];
int sockindex;
int in_out;
@@ -876,29 +891,30 @@ static void edit_node_properties_get(
static bNode *visible_node(SpaceNode *snode, const rctf *rct)
{
LISTBASE_FOREACH_BACKWARD (bNode *, node, &snode->edittree->nodes) {
- if (BLI_rctf_isect(&node->totr, rct, NULL)) {
+ if (BLI_rctf_isect(&node->totr, rct, nullptr)) {
return node;
}
}
- return NULL;
+ return nullptr;
}
/* ********************** size widget operator ******************** */
-typedef struct NodeSizeWidget {
+struct NodeSizeWidget {
float mxstart, mystart;
float oldlocx, oldlocy;
float oldoffsetx, oldoffsety;
float oldwidth, oldheight;
int directions;
-} NodeSizeWidget;
+};
static void node_resize_init(
bContext *C, wmOperator *op, const wmEvent *UNUSED(event), bNode *node, int dir)
{
SpaceNode *snode = CTX_wm_space_node(C);
- NodeSizeWidget *nsw = MEM_callocN(sizeof(NodeSizeWidget), "size widget op data");
+ NodeSizeWidget *nsw = (NodeSizeWidget *)MEM_callocN(sizeof(NodeSizeWidget),
+ "size widget op data");
op->customdata = nsw;
nsw->mxstart = snode->runtime->cursor[0] * UI_DPI_FAC;
@@ -926,7 +942,7 @@ static void node_resize_exit(bContext *C, wmOperator *op, bool cancel)
if (cancel) {
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node = nodeGetActive(snode->edittree);
- NodeSizeWidget *nsw = op->customdata;
+ NodeSizeWidget *nsw = (NodeSizeWidget *)op->customdata;
node->locx = nsw->oldlocx;
node->locy = nsw->oldlocy;
@@ -937,7 +953,7 @@ static void node_resize_exit(bContext *C, wmOperator *op, bool cancel)
}
MEM_freeN(op->customdata);
- op->customdata = NULL;
+ op->customdata = nullptr;
}
static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
@@ -945,7 +961,7 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *region = CTX_wm_region(C);
bNode *node = nodeGetActive(snode->edittree);
- NodeSizeWidget *nsw = op->customdata;
+ NodeSizeWidget *nsw = (NodeSizeWidget *)op->customdata;
switch (event->type) {
case MOUSEMOVE: {
@@ -1112,7 +1128,7 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
else {
/* hide unused sockets */
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
- if (sock->link == NULL) {
+ if (sock->link == nullptr) {
sock->flag |= SOCK_HIDDEN;
}
}
@@ -1128,17 +1144,17 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
static bool cursor_isect_multi_input_socket(const float cursor[2], const bNodeSocket *socket)
{
const float node_socket_height = node_socket_calculate_height(socket);
- const rctf multi_socket_rect = {
- .xmin = socket->locx - NODE_SOCKSIZE * 4.0f,
- .xmax = socket->locx + NODE_SOCKSIZE * 2.0f,
- /*.xmax = socket->locx + NODE_SOCKSIZE * 5.5f
- * would be the same behavior as for regular sockets.
- * But keep it smaller because for multi-input socket you
- * sometimes want to drag the link to the other side, if you may
- * accidentally pick the wrong link otherwise. */
- .ymin = socket->locy - node_socket_height,
- .ymax = socket->locy + node_socket_height,
- };
+ rctf multi_socket_rect;
+ /* `.xmax = socket->locx + NODE_SOCKSIZE * 5.5f`
+ * would be the same behavior as for regular sockets.
+ * But keep it smaller because for multi-input socket you
+ * sometimes want to drag the link to the other side, if you may
+ * accidentally pick the wrong link otherwise. */
+ BLI_rctf_init(&multi_socket_rect,
+ socket->locx - NODE_SOCKSIZE * 4.0f,
+ socket->locx + NODE_SOCKSIZE * 2.0f,
+ socket->locy - node_socket_height,
+ socket->locy + node_socket_height);
if (BLI_rctf_isect_pt(&multi_socket_rect, cursor[0], cursor[1])) {
return true;
}
@@ -1151,8 +1167,8 @@ int node_find_indicated_socket(
{
rctf rect;
- *nodep = NULL;
- *sockp = NULL;
+ *nodep = nullptr;
+ *sockp = nullptr;
/* check if we click in a socket */
LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
@@ -1244,7 +1260,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
- bNode *lastnode = ntree->nodes.last;
+ bNode *lastnode = (bNode *)ntree->nodes.last;
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->flag & SELECT) {
BKE_node_copy_store_new_pointers(ntree, node, LIB_ID_COPY_DEFAULT);
@@ -1262,14 +1278,14 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
/* copy links between selected nodes
* NB: this depends on correct node->new_node and sock->new_sock pointers from above copy!
*/
- bNodeLink *lastlink = ntree->links.last;
+ bNodeLink *lastlink = (bNodeLink *)ntree->links.last;
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
/* This creates new links between copied nodes.
- * If keep_inputs is set, also copies input links from unselected (when fromnode==NULL)!
+ * If keep_inputs is set, also copies input links from unselected (when fromnode==nullptr)!
*/
if (link->tonode && (link->tonode->flag & NODE_SELECT) &&
(keep_inputs || (link->fromnode && (link->fromnode->flag & NODE_SELECT)))) {
- bNodeLink *newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink");
+ bNodeLink *newlink = (bNodeLink *)MEM_callocN(sizeof(bNodeLink), "bNodeLink");
newlink->flag = link->flag;
newlink->tonode = link->tonode->new_node;
newlink->tosock = link->tosock->new_sock;
@@ -1317,7 +1333,6 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
nodeSetSelected(node, false);
node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_TEXTURE);
nodeSetSelected(newnode, true);
- newnode->flag &= ~NODE_ACTIVE_PREVIEW;
do_tag_update |= (do_tag_update || node_connected_to_output(bmain, ntree, newnode));
}
@@ -1353,12 +1368,12 @@ void NODE_OT_duplicate(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(
- ot->srna, "keep_inputs", 0, "Keep Inputs", "Keep the input links to duplicated nodes");
+ ot->srna, "keep_inputs", false, "Keep Inputs", "Keep the input links to duplicated nodes");
}
-bool ED_node_select_check(ListBase *lb)
+bool ED_node_select_check(const ListBase *lb)
{
- LISTBASE_FOREACH (bNode *, node, lb) {
+ LISTBASE_FOREACH (const bNode *, node, lb) {
if (node->flag & NODE_SELECT) {
return true;
}
@@ -1414,7 +1429,7 @@ static int node_read_viewlayers_exec(bContext *C, wmOperator *UNUSED(op))
if ((node->type == CMP_NODE_R_LAYERS) ||
(node->type == CMP_NODE_CRYPTOMATTE && node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER)) {
ID *id = node->id;
- if (id == NULL) {
+ if (id == nullptr) {
continue;
}
if (id->tag & LIB_TAG_DOIT) {
@@ -1453,7 +1468,7 @@ int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op))
/* This is actually a test whether scene is used by the compositor or not.
* All the nodes are using same render result, so there is no need to do
* anything smart about check how exactly scene is used. */
- bNode *node = NULL;
+ bNode *node = nullptr;
LISTBASE_FOREACH (bNode *, node_iter, &sce->nodetree->nodes) {
if (node_iter->id == (ID *)sce) {
node = node_iter;
@@ -1462,7 +1477,7 @@ int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op))
}
if (node) {
- ViewLayer *view_layer = BLI_findlink(&sce->view_layers, node->custom1);
+ ViewLayer *view_layer = (ViewLayer *)BLI_findlink(&sce->view_layers, node->custom1);
if (view_layer) {
PointerRNA op_ptr;
@@ -1471,7 +1486,7 @@ int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op))
RNA_string_set(&op_ptr, "layer", view_layer->name);
RNA_string_set(&op_ptr, "scene", sce->id.name + 2);
- /* to keep keypositions */
+ /* To keep keyframe positions. */
sce->r.scemode |= R_NO_FRAME_UPDATE;
WM_operator_name_call(C, "RENDER_OT_render", WM_OP_INVOKE_DEFAULT, &op_ptr);
@@ -1554,13 +1569,13 @@ static int node_hide_toggle_exec(bContext *C, wmOperator *UNUSED(op))
SpaceNode *snode = CTX_wm_space_node(C);
/* sanity checking (poll callback checks this already) */
- if ((snode == NULL) || (snode->edittree == NULL)) {
+ if ((snode == nullptr) || (snode->edittree == nullptr)) {
return OPERATOR_CANCELLED;
}
node_flag_toggle_exec(snode, NODE_HIDDEN);
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
return OPERATOR_FINISHED;
}
@@ -1585,7 +1600,7 @@ static int node_preview_toggle_exec(bContext *C, wmOperator *UNUSED(op))
SpaceNode *snode = CTX_wm_space_node(C);
/* sanity checking (poll callback checks this already) */
- if ((snode == NULL) || (snode->edittree == NULL)) {
+ if ((snode == nullptr) || (snode->edittree == nullptr)) {
return OPERATOR_CANCELLED;
}
@@ -1618,13 +1633,13 @@ static int node_options_toggle_exec(bContext *C, wmOperator *UNUSED(op))
SpaceNode *snode = CTX_wm_space_node(C);
/* sanity checking (poll callback checks this already) */
- if ((snode == NULL) || (snode->edittree == NULL)) {
+ if ((snode == nullptr) || (snode->edittree == nullptr)) {
return OPERATOR_CANCELLED;
}
node_flag_toggle_exec(snode, NODE_OPTIONS);
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
return OPERATOR_FINISHED;
}
@@ -1649,7 +1664,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
SpaceNode *snode = CTX_wm_space_node(C);
/* sanity checking (poll callback checks this already) */
- if ((snode == NULL) || (snode->edittree == NULL)) {
+ if ((snode == nullptr) || (snode->edittree == nullptr)) {
return OPERATOR_CANCELLED;
}
@@ -1674,7 +1689,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
return OPERATOR_FINISHED;
}
@@ -1870,12 +1885,12 @@ static int node_output_file_add_socket_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
SpaceNode *snode = CTX_wm_space_node(C);
PointerRNA ptr = CTX_data_pointer_get(C, "node");
- bNodeTree *ntree = NULL;
- bNode *node = NULL;
+ bNodeTree *ntree = nullptr;
+ bNode *node = nullptr;
char file_path[MAX_NAME];
if (ptr.data) {
- node = ptr.data;
+ node = (bNode *)ptr.data;
ntree = (bNodeTree *)ptr.owner_id;
}
else if (snode && snode->edittree) {
@@ -1919,11 +1934,11 @@ static int node_output_file_remove_active_socket_exec(bContext *C, wmOperator *U
{
SpaceNode *snode = CTX_wm_space_node(C);
PointerRNA ptr = CTX_data_pointer_get(C, "node");
- bNodeTree *ntree = NULL;
- bNode *node = NULL;
+ bNodeTree *ntree = nullptr;
+ bNode *node = nullptr;
if (ptr.data) {
- node = ptr.data;
+ node = (bNode *)ptr.data;
ntree = (bNodeTree *)ptr.owner_id;
}
else if (snode && snode->edittree) {
@@ -1965,10 +1980,10 @@ static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode = CTX_wm_space_node(C);
PointerRNA ptr = CTX_data_pointer_get(C, "node");
- bNode *node = NULL;
+ bNode *node = nullptr;
if (ptr.data) {
- node = ptr.data;
+ node = (bNode *)ptr.data;
}
else if (snode && snode->edittree) {
node = nodeGetActive(snode->edittree);
@@ -1978,9 +1993,9 @@ static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- NodeImageMultiFile *nimf = node->storage;
+ NodeImageMultiFile *nimf = (NodeImageMultiFile *)node->storage;
- bNodeSocket *sock = BLI_findlink(&node->inputs, nimf->active_input);
+ bNodeSocket *sock = (bNodeSocket *)BLI_findlink(&node->inputs, nimf->active_input);
if (!sock) {
return OPERATOR_CANCELLED;
}
@@ -2014,7 +2029,7 @@ static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op)
void NODE_OT_output_file_move_active_socket(wmOperatorType *ot)
{
static const EnumPropertyItem direction_items[] = {
- {1, "UP", 0, "Up", ""}, {2, "DOWN", 0, "Down", ""}, {0, NULL, 0, NULL, NULL}};
+ {1, "UP", 0, "Up", ""}, {2, "DOWN", 0, "Down", ""}, {0, nullptr, 0, nullptr, nullptr}};
/* identifiers */
ot->name = "Move File Node Socket";
@@ -2059,7 +2074,7 @@ static int node_copy_color_exec(bContext *C, wmOperator *UNUSED(op))
}
ED_node_sort(ntree);
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
return OPERATOR_FINISHED;
}
@@ -2097,7 +2112,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
/* No ID refcounting, this node is virtual,
* detached from any actual Blender data currently. */
bNode *new_node = BKE_node_copy_store_new_pointers(
- NULL, node, LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_MAIN);
+ nullptr, node, LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_MAIN);
BKE_node_clipboard_add_node(new_node);
}
}
@@ -2127,7 +2142,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
/* This creates new links between copied nodes. */
if (link->tonode && (link->tonode->flag & NODE_SELECT) && link->fromnode &&
(link->fromnode->flag & NODE_SELECT)) {
- bNodeLink *newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink");
+ bNodeLink *newlink = (bNodeLink *)MEM_callocN(sizeof(bNodeLink), "bNodeLink");
newlink->flag = link->flag;
newlink->tonode = link->tonode->new_node;
newlink->tosock = link->tosock->new_sock;
@@ -2188,7 +2203,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
/* make sure all clipboard nodes would be valid in the target tree */
bool all_nodes_valid = true;
LISTBASE_FOREACH (bNode *, node, clipboard_nodes_lb) {
- const char *disabled_hint = NULL;
+ const char *disabled_hint = nullptr;
if (!node->typeinfo->poll_instance ||
!node->typeinfo->poll_instance(node, ntree, &disabled_hint)) {
all_nodes_valid = false;
@@ -2286,7 +2301,7 @@ static bNodeSocket *ntree_get_active_interface_socket(ListBase *lb)
return socket;
}
}
- return NULL;
+ return nullptr;
}
static int ntree_socket_add_exec(bContext *C, wmOperator *op)
@@ -2297,7 +2312,7 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op)
PointerRNA ntree_ptr;
RNA_id_pointer_create((ID *)ntree, &ntree_ptr);
- const eNodeSocketInOut in_out = RNA_enum_get(op->ptr, "in_out");
+ const eNodeSocketInOut in_out = (eNodeSocketInOut)RNA_enum_get(op->ptr, "in_out");
ListBase *sockets = (in_out == SOCK_IN) ? &ntree->inputs : &ntree->outputs;
const char *default_name = (in_out == SOCK_IN) ? "Input" : "Output";
@@ -2309,10 +2324,10 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op)
sock = ntreeInsertSocketInterface(
ntree, in_out, active_sock->idname, active_sock->next, active_sock->name);
/* XXX this only works for actual sockets, not interface templates! */
- /*nodeSocketCopyValue(sock, &ntree_ptr, active_sock, &ntree_ptr);*/
+ // nodeSocketCopyValue(sock, &ntree_ptr, active_sock, &ntree_ptr);
}
else {
- /* XXX TODO define default socket type for a tree! */
+ /* XXX TODO: define default socket type for a tree! */
sock = ntreeAddSocketInterface(ntree, in_out, "NodeSocketFloat", default_name);
}
@@ -2328,7 +2343,7 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op)
snode_notify(C, snode);
snode_dag_update(C, snode);
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
return OPERATOR_FINISHED;
}
@@ -2356,11 +2371,11 @@ static int ntree_socket_remove_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
- const eNodeSocketInOut in_out = RNA_enum_get(op->ptr, "in_out");
+ const eNodeSocketInOut in_out = (eNodeSocketInOut)RNA_enum_get(op->ptr, "in_out");
bNodeSocket *iosock = ntree_get_active_interface_socket(in_out == SOCK_IN ? &ntree->inputs :
&ntree->outputs);
- if (iosock == NULL) {
+ if (iosock == nullptr) {
return OPERATOR_CANCELLED;
}
@@ -2378,7 +2393,7 @@ static int ntree_socket_remove_exec(bContext *C, wmOperator *op)
snode_notify(C, snode);
snode_dag_update(C, snode);
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
return OPERATOR_FINISHED;
}
@@ -2399,12 +2414,115 @@ void NODE_OT_tree_socket_remove(wmOperatorType *ot)
RNA_def_enum(ot->srna, "in_out", rna_enum_node_socket_in_out_items, SOCK_IN, "Socket Type", "");
}
+/********************** Change interface socket type operator *********************/
+
+static int ntree_socket_change_type_exec(bContext *C, wmOperator *op)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNodeTree *ntree = snode->edittree;
+ const eNodeSocketInOut in_out = (eNodeSocketInOut)RNA_enum_get(op->ptr, "in_out");
+ const bNodeSocketType *socket_type = rna_node_socket_type_from_enum(
+ RNA_enum_get(op->ptr, "socket_type"));
+ ListBase *sockets = (in_out == SOCK_IN) ? &ntree->inputs : &ntree->outputs;
+
+ Main *main = CTX_data_main(C);
+
+ bNodeSocket *iosock = ntree_get_active_interface_socket(sockets);
+ if (iosock == nullptr) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* The type remains the same, so we don't need to change anything. */
+ if (iosock->typeinfo == socket_type) {
+ return OPERATOR_FINISHED;
+ }
+
+ /* Don't handle subtypes for now. */
+ nodeModifySocketType(ntree, nullptr, iosock, socket_type->idname);
+
+ /* Need the extra update here because the loop above does not check for valid links in the node
+ * group we're currently editing. */
+ ntree->update |= NTREE_UPDATE_GROUP | NTREE_UPDATE_LINKS;
+
+ /* Deactivate sockets. */
+ LISTBASE_FOREACH (bNodeSocket *, socket_iter, sockets) {
+ socket_iter->flag &= ~SELECT;
+ }
+ /* Make the new socket active. */
+ iosock->flag |= SELECT;
+
+ ntreeUpdateTree(main, ntree);
+
+ snode_notify(C, snode);
+ snode_dag_update(C, snode);
+
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
+
+ return OPERATOR_FINISHED;
+}
+
+static bool socket_change_poll_type(void *userdata, bNodeSocketType *socket_type)
+{
+ /* Check if the node tree supports the socket type. */
+ bNodeTreeType *ntreetype = (bNodeTreeType *)userdata;
+ if (ntreetype->valid_socket_type && !ntreetype->valid_socket_type(ntreetype, socket_type)) {
+ return false;
+ }
+
+ /* Only use basic socket types for this enum. */
+ if (socket_type->subtype != PROP_NONE) {
+ return false;
+ }
+
+ return true;
+}
+
+static const EnumPropertyItem *socket_change_type_itemf(bContext *C,
+ PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop),
+ bool *r_free)
+{
+ if (!C) {
+ return DummyRNA_NULL_items;
+ }
+
+ SpaceNode *snode = CTX_wm_space_node(C);
+ if (!snode || !snode->edittree) {
+ return DummyRNA_NULL_items;
+ }
+
+ return rna_node_socket_type_itemf(snode->edittree->typeinfo, socket_change_poll_type, r_free);
+}
+
+void NODE_OT_tree_socket_change_type(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Change Node Tree Interface Socket Type";
+ ot->description = "Change the type of a socket of the current node tree";
+ ot->idname = "NODE_OT_tree_socket_change_type";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = ntree_socket_change_type_exec;
+ ot->poll = ED_operator_node_editable;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "in_out", rna_enum_node_socket_in_out_items, SOCK_IN, "Socket Type", "");
+ prop = RNA_def_enum(ot->srna, "socket_type", DummyRNA_DEFAULT_items, 0, "Socket Type", "");
+ RNA_def_enum_funcs(prop, socket_change_type_itemf);
+ ot->prop = prop;
+}
+
/********************** Move interface socket operator *********************/
static const EnumPropertyItem move_direction_items[] = {
{1, "UP", 0, "Up", ""},
{2, "DOWN", 0, "Down", ""},
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
static int ntree_socket_move_exec(bContext *C, wmOperator *op)
@@ -2413,12 +2531,12 @@ static int ntree_socket_move_exec(bContext *C, wmOperator *op)
bNodeTree *ntree = snode->edittree;
int direction = RNA_enum_get(op->ptr, "direction");
- const eNodeSocketInOut in_out = RNA_enum_get(op->ptr, "in_out");
+ const eNodeSocketInOut in_out = (eNodeSocketInOut)RNA_enum_get(op->ptr, "in_out");
ListBase *sockets = in_out == SOCK_IN ? &ntree->inputs : &ntree->outputs;
bNodeSocket *iosock = ntree_get_active_interface_socket(sockets);
- if (iosock == NULL) {
+ if (iosock == nullptr) {
return OPERATOR_CANCELLED;
}
@@ -2453,7 +2571,7 @@ static int ntree_socket_move_exec(bContext *C, wmOperator *op)
snode_notify(C, snode);
snode_dag_update(C, snode);
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
return OPERATOR_FINISHED;
}
@@ -2486,18 +2604,18 @@ static bool node_shader_script_update_poll(bContext *C)
/* test if we have a render engine that supports shaders scripts */
if (!(type && type->update_script_node)) {
- return 0;
+ return false;
}
/* see if we have a shader script node in context */
- bNode *node = CTX_data_pointer_get_type(C, "node", &RNA_ShaderNodeScript).data;
+ bNode *node = (bNode *)CTX_data_pointer_get_type(C, "node", &RNA_ShaderNodeScript).data;
if (!node && snode && snode->edittree) {
node = nodeGetActive(snode->edittree);
}
if (node && node->type == SH_NODE_SCRIPT) {
- NodeShaderScript *nss = node->storage;
+ NodeShaderScript *nss = (NodeShaderScript *)node->storage;
if (node->id || nss->filepath[0]) {
return ED_operator_node_editable(C);
@@ -2505,14 +2623,14 @@ static bool node_shader_script_update_poll(bContext *C)
}
/* see if we have a text datablock in context */
- Text *text = CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data;
+ Text *text = (Text *)CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data;
if (text) {
- return 1;
+ return true;
}
/* we don't check if text datablock is actually in use, too slow for poll */
- return 0;
+ return false;
}
/* recursively check for script nodes in groups using this text and update */
@@ -2556,11 +2674,11 @@ static int node_shader_script_update_exec(bContext *C, wmOperator *op)
engine->reports = op->reports;
/* get node */
- bNodeTree *ntree_base = NULL;
- bNode *node = NULL;
+ bNodeTree *ntree_base = nullptr;
+ bNode *node = nullptr;
if (nodeptr.data) {
ntree_base = (bNodeTree *)nodeptr.owner_id;
- node = nodeptr.data;
+ node = (bNode *)nodeptr.data;
}
else if (snode && snode->edittree) {
ntree_base = snode->edittree;
@@ -2575,7 +2693,7 @@ static int node_shader_script_update_exec(bContext *C, wmOperator *op)
}
else {
/* update all nodes using text datablock */
- Text *text = CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data;
+ Text *text = (Text *)CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data;
if (text) {
/* clear flags for recursion check */
@@ -2647,7 +2765,7 @@ static int viewer_border_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock);
if (ibuf) {
ARegion *region = CTX_wm_region(C);
@@ -2683,7 +2801,7 @@ static int viewer_border_exec(bContext *C, wmOperator *op)
}
snode_notify(C, snode);
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
}
else {
btree->flag &= ~NTREE_VIEWER_BORDER;
@@ -2723,7 +2841,7 @@ static int clear_viewer_border_exec(bContext *C, wmOperator *UNUSED(op))
btree->flag &= ~NTREE_VIEWER_BORDER;
snode_notify(C, snode);
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
return OPERATOR_FINISHED;
}
@@ -2749,11 +2867,11 @@ static int node_cryptomatte_add_socket_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceNode *snode = CTX_wm_space_node(C);
PointerRNA ptr = CTX_data_pointer_get(C, "node");
- bNodeTree *ntree = NULL;
- bNode *node = NULL;
+ bNodeTree *ntree = nullptr;
+ bNode *node = nullptr;
if (ptr.data) {
- node = ptr.data;
+ node = (bNode *)ptr.data;
ntree = (bNodeTree *)ptr.owner_id;
}
else if (snode && snode->edittree) {
@@ -2793,11 +2911,11 @@ static int node_cryptomatte_remove_socket_exec(bContext *C, wmOperator *UNUSED(o
{
SpaceNode *snode = CTX_wm_space_node(C);
PointerRNA ptr = CTX_data_pointer_get(C, "node");
- bNodeTree *ntree = NULL;
- bNode *node = NULL;
+ bNodeTree *ntree = nullptr;
+ bNode *node = nullptr;
if (ptr.data) {
- node = ptr.data;
+ node = (bNode *)ptr.data;
ntree = (bNodeTree *)ptr.owner_id;
}
else if (snode && snode->edittree) {
diff --git a/source/blender/editors/space_node/node_geometry_attribute_search.cc b/source/blender/editors/space_node/node_geometry_attribute_search.cc
index 856a90be5ae..a6901c21862 100644
--- a/source/blender/editors/space_node/node_geometry_attribute_search.cc
+++ b/source/blender/editors/space_node/node_geometry_attribute_search.cc
@@ -27,28 +27,33 @@
#include "DNA_space_types.h"
#include "BKE_context.h"
-#include "BKE_node_ui_storage.hh"
#include "BKE_object.h"
#include "RNA_access.h"
#include "RNA_enum_types.h"
+#include "ED_undo.h"
+
#include "BLT_translation.h"
#include "UI_interface.h"
#include "UI_resources.h"
+#include "NOD_geometry_nodes_eval_log.hh"
+
#include "node_intern.h"
using blender::IndexRange;
using blender::Map;
using blender::Set;
using blender::StringRef;
+namespace geo_log = blender::nodes::geometry_nodes_eval_log;
+using geo_log::GeometryAttributeInfo;
struct AttributeSearchData {
- AvailableAttributeInfo &dummy_info_for_search;
- const NodeUIStorage &ui_storage;
- bNodeSocket &socket;
+ const bNodeTree *tree;
+ const bNode *node;
+ bNodeSocket *socket;
};
/* This class must not have a destructor, since it is used by buttons and freed with #MEM_freeN. */
@@ -71,7 +76,7 @@ static StringRef attribute_domain_string(const AttributeDomain domain)
/* Unicode arrow. */
#define MENU_SEP "\xe2\x96\xb6"
-static bool attribute_search_item_add(uiSearchItems *items, const AvailableAttributeInfo &item)
+static bool attribute_search_item_add(uiSearchItems *items, const GeometryAttributeInfo &item)
{
const StringRef data_type_name = attribute_data_type_string(item.data_type);
const StringRef domain_name = attribute_domain_string(item.domain);
@@ -82,31 +87,47 @@ static bool attribute_search_item_add(uiSearchItems *items, const AvailableAttri
items, search_item_text.c_str(), (void *)&item, ICON_NONE, UI_BUT_HAS_SEP_CHAR, 0);
}
-static void attribute_search_update_fn(const bContext *UNUSED(C),
- void *arg,
- const char *str,
- uiSearchItems *items,
- const bool is_first)
+static GeometryAttributeInfo &get_dummy_item_info()
+{
+ static GeometryAttributeInfo info;
+ return info;
+}
+
+static void attribute_search_update_fn(
+ const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first)
{
AttributeSearchData *data = static_cast<AttributeSearchData *>(arg);
- const Set<AvailableAttributeInfo> &attribute_hints = data->ui_storage.attribute_hints;
+ SpaceNode *snode = CTX_wm_space_node(C);
+ const geo_log::NodeLog *node_log = geo_log::ModifierLog::find_node_by_node_editor_context(
+ *snode, *data->node);
+ if (node_log == nullptr) {
+ return;
+ }
+ blender::Vector<const GeometryAttributeInfo *> infos = node_log->lookup_available_attributes();
+
+ GeometryAttributeInfo &dummy_info = get_dummy_item_info();
/* Any string may be valid, so add the current search string along with the hints. */
if (str[0] != '\0') {
- /* Note that the attribute domain and data type are dummies, since
- * #AvailableAttributeInfo equality is only based on the string. */
- if (!attribute_hints.contains(AvailableAttributeInfo{str, ATTR_DOMAIN_AUTO, CD_PROP_BOOL})) {
- data->dummy_info_for_search.name = std::string(str);
- UI_search_item_add(items, str, &data->dummy_info_for_search, ICON_ADD, 0, 0);
+ bool contained = false;
+ for (const GeometryAttributeInfo *attribute_info : infos) {
+ if (attribute_info->name == str) {
+ contained = true;
+ break;
+ }
+ }
+ if (!contained) {
+ dummy_info.name = str;
+ UI_search_item_add(items, str, &dummy_info, ICON_ADD, 0, 0);
}
}
if (str[0] == '\0' && !is_first) {
/* Allow clearing the text field when the string is empty, but not on the first pass,
* or opening an attribute field for the first time would show this search item. */
- data->dummy_info_for_search.name = std::string(str);
- UI_search_item_add(items, str, &data->dummy_info_for_search, ICON_X, 0, 0);
+ dummy_info.name = str;
+ UI_search_item_add(items, str, &dummy_info, ICON_X, 0, 0);
}
/* Don't filter when the menu is first opened, but still run the search
@@ -114,15 +135,15 @@ static void attribute_search_update_fn(const bContext *UNUSED(C),
const char *string = is_first ? "" : str;
StringSearch *search = BLI_string_search_new();
- for (const AvailableAttributeInfo &item : attribute_hints) {
- BLI_string_search_add(search, item.name.c_str(), (void *)&item);
+ for (const GeometryAttributeInfo *item : infos) {
+ BLI_string_search_add(search, item->name.c_str(), (void *)item);
}
- AvailableAttributeInfo **filtered_items;
+ GeometryAttributeInfo **filtered_items;
const int filtered_amount = BLI_string_search_query(search, string, (void ***)&filtered_items);
for (const int i : IndexRange(filtered_amount)) {
- const AvailableAttributeInfo *item = filtered_items[i];
+ const GeometryAttributeInfo *item = filtered_items[i];
if (!attribute_search_item_add(items, *item)) {
break;
}
@@ -132,32 +153,27 @@ static void attribute_search_update_fn(const bContext *UNUSED(C),
BLI_string_search_free(search);
}
-static void attribute_search_exec_fn(bContext *UNUSED(C), void *data_v, void *item_v)
+static void attribute_search_exec_fn(bContext *C, void *data_v, void *item_v)
{
+ if (item_v == nullptr) {
+ return;
+ }
AttributeSearchData *data = static_cast<AttributeSearchData *>(data_v);
- AvailableAttributeInfo *item = static_cast<AvailableAttributeInfo *>(item_v);
+ GeometryAttributeInfo *item = (GeometryAttributeInfo *)item_v;
- bNodeSocket &socket = data->socket;
+ bNodeSocket &socket = *data->socket;
bNodeSocketValueString *value = static_cast<bNodeSocketValueString *>(socket.default_value);
BLI_strncpy(value->value, item->name.c_str(), MAX_NAME);
+
+ ED_undo_push(C, "Assign Attribute Name");
}
-void node_geometry_add_attribute_search_button(const bContext *C,
+void node_geometry_add_attribute_search_button(const bContext *UNUSED(C),
const bNodeTree *node_tree,
const bNode *node,
PointerRNA *socket_ptr,
uiLayout *layout)
{
- const NodeUIStorage *ui_storage = BKE_node_tree_ui_storage_get_from_context(
- C, *node_tree, *node);
-
- if (ui_storage == nullptr) {
- uiItemR(layout, socket_ptr, "default_value", 0, "", 0);
- return;
- }
-
- const NodeTreeUIStorage *tree_ui_storage = node_tree->ui_storage;
-
uiBlock *block = uiLayoutGetBlock(layout);
uiBut *but = uiDefIconTextButR(block,
UI_BTYPE_SEARCH_MENU,
@@ -177,10 +193,8 @@ void node_geometry_add_attribute_search_button(const bContext *C,
0.0f,
"");
- AttributeSearchData *data = OBJECT_GUARDED_NEW(AttributeSearchData,
- {tree_ui_storage->dummy_info_for_search,
- *ui_storage,
- *static_cast<bNodeSocket *>(socket_ptr->data)});
+ AttributeSearchData *data = OBJECT_GUARDED_NEW(
+ AttributeSearchData, {node_tree, node, (bNodeSocket *)socket_ptr->data});
UI_but_func_search_set_results_are_suggestions(but, true);
UI_but_func_search_set_sep_string(but, MENU_SEP);
diff --git a/source/blender/editors/space_node/node_gizmo.c b/source/blender/editors/space_node/node_gizmo.c
index 28d7e1b8d04..e1deca54890 100644
--- a/source/blender/editors/space_node/node_gizmo.c
+++ b/source/blender/editors/space_node/node_gizmo.c
@@ -97,7 +97,6 @@ static void gizmo_node_backdrop_prop_matrix_set(const wmGizmo *UNUSED(gz),
BLI_assert(gz_prop->type->array_length == 16);
SpaceNode *snode = gz_prop->custom_func.user_data;
snode->zoom = matrix[0][0];
- snode->zoom = matrix[1][1];
snode->xof = matrix[3][0];
snode->yof = matrix[3][1];
}
@@ -156,7 +155,7 @@ static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmGizmoGroup *
WM_gizmo_set_matrix_location(cage, origin);
WM_gizmo_set_flag(cage, WM_GIZMO_HIDDEN, false);
- /* need to set property here for undo. TODO would prefer to do this in _init */
+ /* Need to set property here for undo. TODO: would prefer to do this in _init. */
SpaceNode *snode = CTX_wm_space_node(C);
#if 0
PointerRNA nodeptr;
@@ -493,7 +492,7 @@ static void WIDGETGROUP_node_sbeam_refresh(const bContext *C, wmGizmoGroup *gzgr
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node = nodeGetActive(snode->edittree);
- /* need to set property here for undo. TODO would prefer to do this in _init */
+ /* Need to set property here for undo. TODO: would prefer to do this in _init. */
PointerRNA nodeptr;
RNA_pointer_create((ID *)snode->edittree, &RNA_CompositorNodeSunBeams, node, &nodeptr);
WM_gizmo_target_property_def_rna(gz, "offset", &nodeptr, "source", -1);
@@ -605,7 +604,7 @@ static void WIDGETGROUP_node_corner_pin_refresh(const bContext *C, wmGizmoGroup
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node = nodeGetActive(snode->edittree);
- /* need to set property here for undo. TODO would prefer to do this in _init */
+ /* need to set property here for undo. TODO: would prefer to do this in _init. */
int i = 0;
for (bNodeSocket *sock = node->inputs.first; sock && i < 4; sock = sock->next) {
if (sock->type == SOCK_VECTOR) {
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.cc
index 335e2f93ff3..d7541d8f512 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.cc
@@ -21,7 +21,7 @@
* \ingroup spnode
*/
-#include <stdlib.h>
+#include <cstdlib>
#include "MEM_guardedalloc.h"
@@ -70,9 +70,8 @@ static bool node_group_operator_active_poll(bContext *C)
SpaceNode *snode = CTX_wm_space_node(C);
/* Group operators only defined for standard node tree types.
- * Disabled otherwise to allow pynodes define their own operators
- * with same keymap.
- */
+ * Disabled otherwise to allow python-nodes define their own operators
+ * with same key-map. */
if (STR_ELEM(snode->tree_idname,
"ShaderNodeTree",
"CompositorNodeTree",
@@ -90,9 +89,8 @@ static bool node_group_operator_editable(bContext *C)
SpaceNode *snode = CTX_wm_space_node(C);
/* Group operators only defined for standard node tree types.
- * Disabled otherwise to allow pynodes define their own operators
- * with same keymap.
- */
+ * Disabled otherwise to allow python-nodes define their own operators
+ * with same key-map. */
if (ED_node_is_shader(snode) || ED_node_is_compositor(snode) || ED_node_is_texture(snode) ||
ED_node_is_geometry(snode)) {
return true;
@@ -135,7 +133,7 @@ static bNode *node_group_get_active(bContext *C, const char *node_idname)
if (node && STREQ(node->idname, node_idname)) {
return node;
}
- return NULL;
+ return nullptr;
}
/** \} */
@@ -165,7 +163,7 @@ static int node_group_edit_exec(bContext *C, wmOperator *op)
ED_node_tree_pop(snode);
}
- WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_NODES, nullptr);
return OPERATOR_FINISHED;
}
@@ -200,7 +198,8 @@ void NODE_OT_group_edit(wmOperatorType *ot)
static AnimationBasePathChange *animation_basepath_change_new(const char *src_basepath,
const char *dst_basepath)
{
- AnimationBasePathChange *basepath_change = MEM_callocN(sizeof(*basepath_change), AT);
+ AnimationBasePathChange *basepath_change = (AnimationBasePathChange *)MEM_callocN(
+ sizeof(*basepath_change), AT);
basepath_change->src_basepath = src_basepath;
basepath_change->dst_basepath = dst_basepath;
return basepath_change;
@@ -218,13 +217,13 @@ static void animation_basepath_change_free(AnimationBasePathChange *basepath_cha
/* returns 1 if its OK */
static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
{
- /* clear new pointers, set in copytree */
+ /* Clear new pointers, set in #ntreeCopyTree_ex_new_pointers. */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- node->new_node = NULL;
+ node->new_node = nullptr;
}
- ListBase anim_basepaths = {NULL, NULL};
- LinkNode *nodes_delayed_free = NULL;
+ ListBase anim_basepaths = {nullptr, nullptr};
+ LinkNode *nodes_delayed_free = nullptr;
bNodeTree *ngroup = (bNodeTree *)gnode->id;
/* wgroup is a temporary copy of the NodeTree we're merging in
@@ -247,7 +246,7 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
/* keep track of this node's RNA "base" path (the part of the path identifying the node)
* if the old nodetree has animation data which potentially covers this node
*/
- const char *old_animation_basepath = NULL;
+ const char *old_animation_basepath = nullptr;
if (wgroup->adt) {
PointerRNA ptr;
RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr);
@@ -277,7 +276,7 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
node->flag |= NODE_SELECT;
}
- bNodeLink *glinks_first = ntree->links.last;
+ bNodeLink *glinks_first = (bNodeLink *)ntree->links.last;
/* Add internal links to the ntree */
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &wgroup->links) {
@@ -285,10 +284,10 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
BLI_addtail(&ntree->links, link);
}
- bNodeLink *glinks_last = ntree->links.last;
+ bNodeLink *glinks_last = (bNodeLink *)ntree->links.last;
/* and copy across the animation,
- * note that the animation data's action can be NULL here */
+ * note that the animation data's action can be nullptr here */
if (wgroup->adt) {
bAction *waction;
@@ -307,7 +306,7 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
/* free temp action too */
if (waction) {
BKE_id_free(bmain, waction);
- wgroup->adt->action = NULL;
+ wgroup->adt->action = nullptr;
}
}
@@ -317,14 +316,14 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
/* restore external links to and from the gnode */
/* input links */
- if (glinks_first != NULL) {
+ if (glinks_first != nullptr) {
for (bNodeLink *link = glinks_first->next; link != glinks_last->next; link = link->next) {
if (link->fromnode->type == NODE_GROUP_INPUT) {
const char *identifier = link->fromsock->identifier;
int num_external_links = 0;
/* find external links to this input */
- for (bNodeLink *tlink = ntree->links.first; tlink != glinks_first->next;
+ for (bNodeLink *tlink = (bNodeLink *)ntree->links.first; tlink != glinks_first->next;
tlink = tlink->next) {
if (tlink->tonode == gnode && STREQ(tlink->tosock->identifier, identifier)) {
nodeAddLink(ntree, tlink->fromnode, tlink->fromsock, link->tonode, link->tosock);
@@ -348,10 +347,11 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
}
/* Also iterate over new links to cover passthrough links. */
- glinks_last = ntree->links.last;
+ glinks_last = (bNodeLink *)ntree->links.last;
/* output links */
- for (bNodeLink *link = ntree->links.first; link != glinks_first->next; link = link->next) {
+ for (bNodeLink *link = (bNodeLink *)ntree->links.first; link != glinks_first->next;
+ link = link->next) {
if (link->fromnode == gnode) {
const char *identifier = link->fromsock->identifier;
int num_internal_links = 0;
@@ -384,7 +384,7 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
}
while (nodes_delayed_free) {
- bNode *node = BLI_linklist_pop(&nodes_delayed_free);
+ bNode *node = (bNode *)BLI_linklist_pop(&nodes_delayed_free);
nodeRemoveNode(bmain, ntree, node, false);
}
@@ -455,10 +455,10 @@ static int node_group_separate_selected(
/* clear new pointers, set in BKE_node_copy_ex(). */
LISTBASE_FOREACH (bNode *, node, &ngroup->nodes) {
- node->new_node = NULL;
+ node->new_node = nullptr;
}
- ListBase anim_basepaths = {NULL, NULL};
+ ListBase anim_basepaths = {nullptr, nullptr};
/* add selected nodes into the ntree */
LISTBASE_FOREACH_MUTABLE (bNode *, node, &ngroup->nodes) {
@@ -543,7 +543,7 @@ static int node_group_separate_selected(
}
/* and copy across the animation,
- * note that the animation data's action can be NULL here */
+ * note that the animation data's action can be nullptr here */
if (ngroup->adt) {
/* now perform the moving */
BKE_animdata_transfer_by_basepath(bmain, &ngroup->id, &ntree->id, &anim_basepaths);
@@ -562,16 +562,16 @@ static int node_group_separate_selected(
return 1;
}
-typedef enum eNodeGroupSeparateType {
+enum eNodeGroupSeparateType {
NODE_GS_COPY,
NODE_GS_MOVE,
-} eNodeGroupSeparateType;
+};
/* Operator Property */
static const EnumPropertyItem node_group_separate_types[] = {
{NODE_GS_COPY, "COPY", 0, "Copy", "Copy to parent node tree, keep group intact"},
{NODE_GS_MOVE, "MOVE", 0, "Move", "Move to parent node tree, remove from group"},
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
static int node_group_separate_exec(bContext *C, wmOperator *op)
@@ -628,8 +628,8 @@ static int node_group_separate_invoke(bContext *C,
uiLayout *layout = UI_popup_menu_layout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
- uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_COPY);
- uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_MOVE);
+ uiItemEnumO(layout, "NODE_OT_group_separate", nullptr, 0, "type", NODE_GS_COPY);
+ uiItemEnumO(layout, "NODE_OT_group_separate", nullptr, 0, "type", NODE_GS_MOVE);
UI_popup_menu_end(C, pup);
@@ -674,12 +674,12 @@ static bool node_group_make_test_selected(bNodeTree *ntree,
int ok = true;
/* make a local pseudo node tree to pass to the node poll functions */
- bNodeTree *ngroup = ntreeAddTree(NULL, "Pseudo Node Group", ntree_idname);
+ bNodeTree *ngroup = ntreeAddTree(nullptr, "Pseudo Node Group", ntree_idname);
/* check poll functions for selected nodes */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node_group_make_use_node(node, gnode)) {
- const char *disabled_hint = NULL;
+ const char *disabled_hint = nullptr;
if (node->typeinfo->poll_instance &&
!node->typeinfo->poll_instance(node, ngroup, &disabled_hint)) {
if (disabled_hint) {
@@ -781,7 +781,7 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
expose_visible = true;
}
- ListBase anim_basepaths = {NULL, NULL};
+ ListBase anim_basepaths = {nullptr, nullptr};
/* move nodes over */
LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
@@ -926,7 +926,7 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
}
}
- /* expose all unlinked sockets too but only the visible ones*/
+ /* Expose all unlinked sockets too but only the visible ones. */
if (expose_visible) {
LISTBASE_FOREACH (bNode *, node, &ngroup->nodes) {
if (node_group_make_use_node(node, gnode)) {
@@ -995,10 +995,10 @@ static bNode *node_group_make_from_selected(const bContext *C,
Main *bmain = CTX_data_main(C);
float min[2], max[2];
- const int totselect = node_get_selected_minmax(ntree, NULL, min, max, false);
+ const int totselect = node_get_selected_minmax(ntree, nullptr, min, max, false);
/* don't make empty group */
if (totselect == 0) {
- return NULL;
+ return nullptr;
}
/* new nodetree */
@@ -1029,7 +1029,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
- if (!node_group_make_test_selected(ntree, NULL, ntree_idname, op->reports)) {
+ if (!node_group_make_test_selected(ntree, nullptr, ntree_idname, op->reports)) {
return OPERATOR_CANCELLED;
}
@@ -1042,7 +1042,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
if (ngroup) {
ED_node_tree_push(snode, ngroup, gnode);
LISTBASE_FOREACH (bNode *, node, &ngroup->nodes) {
- sort_multi_input_socket_links(snode, node, NULL, NULL);
+ sort_multi_input_socket_links(snode, node, nullptr, nullptr);
}
ntreeUpdateTree(bmain, ngroup);
}
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 2fcc59cde0b..09e5a110a45 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -25,6 +25,7 @@
#include "BKE_node.h"
#include "UI_interface.h"
+#include "UI_view2d.h"
#include <stddef.h> /* for size_t */
/* internal exports only */
@@ -51,7 +52,7 @@ typedef struct bNodeLinkDrag {
struct bNodeLinkDrag *next, *prev;
/* List of links dragged by the operator.
- * Note: This is a list of LinkData structs on top of the actual bNodeLinks.
+ * NOTE: This is a list of LinkData structs on top of the actual bNodeLinks.
* This way the links can be added to the node tree while being stored in this list.
*/
ListBase links;
@@ -64,6 +65,9 @@ typedef struct bNodeLinkDrag {
/** Temporarily stores the last hovered socket for multi-input socket operator.
* Store it to recalculate sorting after it is no longer hovered. */
struct bNode *last_node_hovered_while_dragging_a_link;
+
+ /* Data for edge panning */
+ View2DEdgePanData pan_data;
} bNodeLinkDrag;
typedef struct SpaceNode_Runtime {
@@ -136,9 +140,6 @@ void node_to_view(const struct bNode *node, float x, float y, float *rx, float *
void node_to_updated_rect(const struct bNode *node, rctf *r_rect);
void node_from_view(const struct bNode *node, float x, float y, float *rx, float *ry);
-/* node_buttons.c */
-void node_buttons_register(struct ARegionType *art);
-
/* node_toolbar.c */
void node_toolbar_register(struct ARegionType *art);
@@ -275,7 +276,6 @@ void NODE_OT_hide_toggle(struct wmOperatorType *ot);
void NODE_OT_hide_socket_toggle(struct wmOperatorType *ot);
void NODE_OT_preview_toggle(struct wmOperatorType *ot);
void NODE_OT_options_toggle(struct wmOperatorType *ot);
-void NODE_OT_active_preview_toggle(struct wmOperatorType *ot);
void NODE_OT_node_copy_color(struct wmOperatorType *ot);
void NODE_OT_read_viewlayers(struct wmOperatorType *ot);
@@ -287,12 +287,13 @@ void NODE_OT_output_file_move_active_socket(struct wmOperatorType *ot);
void NODE_OT_switch_view_update(struct wmOperatorType *ot);
-/* Note: clipboard_cut is a simple macro of copy + delete */
+/* NOTE: clipboard_cut is a simple macro of copy + delete. */
void NODE_OT_clipboard_copy(struct wmOperatorType *ot);
void NODE_OT_clipboard_paste(struct wmOperatorType *ot);
void NODE_OT_tree_socket_add(struct wmOperatorType *ot);
void NODE_OT_tree_socket_remove(struct wmOperatorType *ot);
+void NODE_OT_tree_socket_change_type(struct wmOperatorType *ot);
void NODE_OT_tree_socket_move(struct wmOperatorType *ot);
void NODE_OT_shader_script_update(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index e35b444aa11..610c2889e7a 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -119,6 +119,7 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_tree_socket_add);
WM_operatortype_append(NODE_OT_tree_socket_remove);
+ WM_operatortype_append(NODE_OT_tree_socket_change_type);
WM_operatortype_append(NODE_OT_tree_socket_move);
WM_operatortype_append(NODE_OT_cryptomatte_layer_add);
@@ -157,7 +158,7 @@ void ED_operatormacros_node(void)
WM_operatortype_macro_define(ot, "NODE_OT_attach");
WM_operatortype_macro_define(ot, "NODE_OT_insert_offset");
- /* Note: Currently not in a default keymap or menu due to messy keymaps
+ /* NOTE: Currently not in a default keymap or menu due to messy keymaps
* and tricky invoke functionality.
* Kept around in case users want to make own shortcuts.
*/
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.cc
index 28c660b0632..aadf93961e9 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.cc
@@ -40,11 +40,14 @@
#include "ED_node.h" /* own include */
#include "ED_render.h"
#include "ED_screen.h"
+#include "ED_spreadsheet.h"
#include "ED_util.h"
#include "RNA_access.h"
#include "RNA_define.h"
+#include "DEG_depsgraph.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -55,12 +58,14 @@
#include "node_intern.h" /* own include */
-/* ****************** Relations helpers *********************** */
+/* -------------------------------------------------------------------- */
+/** \name Relations Helpers
+ * \{ */
static bool ntree_has_drivers(bNodeTree *ntree)
{
const AnimData *adt = BKE_animdata_from_id(&ntree->id);
- if (adt == NULL) {
+ if (adt == nullptr) {
return false;
}
return !BLI_listbase_is_empty(&adt->drivers);
@@ -102,7 +107,7 @@ static bool node_group_has_output_dfs(bNode *node)
return false;
}
ntree->id.tag |= LIB_TAG_DOIT;
- for (bNode *current_node = ntree->nodes.first; current_node != NULL;
+ for (bNode *current_node = (bNode *)ntree->nodes.first; current_node != nullptr;
current_node = current_node->next) {
if (current_node->type == NODE_GROUP) {
if (current_node->id && node_group_has_output_dfs(current_node)) {
@@ -120,7 +125,7 @@ static bool node_group_has_output(Main *bmain, bNode *node)
{
BLI_assert(ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP));
bNodeTree *ntree = (bNodeTree *)node->id;
- if (ntree == NULL) {
+ if (ntree == nullptr) {
return false;
}
BKE_main_id_tag_listbase(&bmain->nodetrees, LIB_TAG_DOIT, false);
@@ -145,7 +150,7 @@ bool node_connected_to_output(Main *bmain, bNodeTree *ntree, bNode *node)
* is connected to and so eventually.
*/
if (ELEM(current_node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) {
- if (current_node->id != NULL && ntree_has_drivers((bNodeTree *)current_node->id)) {
+ if (current_node->id != nullptr && ntree_has_drivers((bNodeTree *)current_node->id)) {
return true;
}
if (ntree_check_nodes_connected(ntree, node, current_node) &&
@@ -158,18 +163,27 @@ bool node_connected_to_output(Main *bmain, bNodeTree *ntree, bNode *node)
return true;
}
}
+ if (current_node->type == GEO_NODE_VIEWER) {
+ if (ntree_check_nodes_connected(ntree, node, current_node)) {
+ return true;
+ }
+ }
}
return false;
}
-/* ****************** Add *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Add Node
+ * \{ */
-typedef struct bNodeListItem {
+struct bNodeListItem {
struct bNodeListItem *next, *prev;
struct bNode *node;
-} bNodeListItem;
+};
-typedef struct NodeInsertOfsData {
+struct NodeInsertOfsData {
bNodeTree *ntree;
bNode *insert; /* inserted node */
bNode *prev, *next; /* prev/next node in the chain */
@@ -178,7 +192,7 @@ typedef struct NodeInsertOfsData {
wmTimer *anim_timer;
float offset_x; /* offset to apply to node chain */
-} NodeInsertOfsData;
+};
static void clear_picking_highlight(ListBase *links)
{
@@ -189,8 +203,8 @@ static void clear_picking_highlight(ListBase *links)
static LinkData *create_drag_link(Main *bmain, SpaceNode *snode, bNode *node, bNodeSocket *sock)
{
- LinkData *linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
- bNodeLink *oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
+ LinkData *linkdata = (LinkData *)MEM_callocN(sizeof(LinkData), "drag link op link data");
+ bNodeLink *oplink = (bNodeLink *)MEM_callocN(sizeof(bNodeLink), "drag link op link");
linkdata->data = oplink;
if (sock->in_out == SOCK_OUT) {
oplink->fromnode = node;
@@ -225,10 +239,10 @@ static void pick_link(const bContext *C,
BLI_addtail(&nldrag->links, linkdata);
nodeRemLink(snode->edittree, link_to_pick);
- BLI_assert(nldrag->last_node_hovered_while_dragging_a_link != NULL);
+ BLI_assert(nldrag->last_node_hovered_while_dragging_a_link != nullptr);
sort_multi_input_socket_links(
- snode, nldrag->last_node_hovered_while_dragging_a_link, NULL, NULL);
+ snode, nldrag->last_node_hovered_while_dragging_a_link, nullptr, nullptr);
/* Send changed event to original link->tonode. */
if (node) {
@@ -256,7 +270,7 @@ static void pick_input_link_by_link_intersect(const bContext *C,
const int resolution = NODE_LINK_RESOL;
- bNodeLink *link_to_pick = NULL;
+ bNodeLink *link_to_pick = nullptr;
clear_picking_highlight(&snode->edittree->links);
LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
if (link->tosock == socket) {
@@ -305,8 +319,8 @@ static void pick_input_link_by_link_intersect(const bContext *C,
static int sort_nodes_locx(const void *a, const void *b)
{
- const bNodeListItem *nli1 = a;
- const bNodeListItem *nli2 = b;
+ const bNodeListItem *nli1 = (const bNodeListItem *)a;
+ const bNodeListItem *nli2 = (const bNodeListItem *)b;
const bNode *node1 = nli1->node;
const bNode *node2 = nli2->node;
@@ -319,14 +333,14 @@ static int sort_nodes_locx(const void *a, const void *b)
static bool socket_is_available(bNodeTree *UNUSED(ntree), bNodeSocket *sock, const bool allow_used)
{
if (nodeSocketIsHidden(sock)) {
- return 0;
+ return false;
}
if (!allow_used && (sock->flag & SOCK_IN_USE)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
static bNodeSocket *best_socket_output(bNodeTree *ntree,
@@ -374,10 +388,10 @@ static bNodeSocket *best_socket_output(bNodeTree *ntree,
/* Always allow linking to an reroute node. The socket type of the reroute sockets might change
* after the link has been created. */
if (node->type == NODE_REROUTE) {
- return node->outputs.first;
+ return (bNodeSocket *)node->outputs.first;
}
- return NULL;
+ return nullptr;
}
/* this is a bit complicated, but designed to prioritize finding
@@ -409,7 +423,7 @@ static bNodeSocket *best_socket_input(bNodeTree *ntree, bNode *node, int num, in
}
}
- return NULL;
+ return nullptr;
}
static bool snode_autoconnect_input(SpaceNode *snode,
@@ -430,10 +444,10 @@ static bool snode_autoconnect_input(SpaceNode *snode,
return true;
}
-typedef struct LinkAndPosition {
+struct LinkAndPosition {
struct bNodeLink *link;
float multi_socket_position[2];
-} LinkAndPosition;
+};
static int compare_link_by_y_position(const void *a, const void *b)
{
@@ -457,14 +471,14 @@ void sort_multi_input_socket_links(SpaceNode *snode,
}
/* The total is calculated in #node_update_nodetree, which runs before this draw step. */
int total_inputs = socket->total_inputs + 1;
- struct LinkAndPosition **input_links = MEM_malloc_arrayN(
+ struct LinkAndPosition **input_links = (LinkAndPosition **)MEM_malloc_arrayN(
total_inputs, sizeof(LinkAndPosition *), __func__);
int index = 0;
LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
if (link->tosock == socket) {
- struct LinkAndPosition *link_and_position = MEM_callocN(sizeof(struct LinkAndPosition),
- __func__);
+ struct LinkAndPosition *link_and_position = (LinkAndPosition *)MEM_callocN(
+ sizeof(struct LinkAndPosition), __func__);
link_and_position->link = link;
node_link_calculate_multi_input_position(link->tosock->locx,
link->tosock->locy,
@@ -477,7 +491,8 @@ void sort_multi_input_socket_links(SpaceNode *snode,
}
if (drag_link) {
- LinkAndPosition *link_and_position = MEM_callocN(sizeof(LinkAndPosition), __func__);
+ LinkAndPosition *link_and_position = (LinkAndPosition *)MEM_callocN(sizeof(LinkAndPosition),
+ __func__);
link_and_position->link = drag_link;
copy_v2_v2(link_and_position->multi_socket_position, cursor);
input_links[index] = link_and_position;
@@ -505,11 +520,12 @@ static void snode_autoconnect(Main *bmain,
const bool replace)
{
bNodeTree *ntree = snode->edittree;
- ListBase *nodelist = MEM_callocN(sizeof(ListBase), "items_list");
+ ListBase *nodelist = (ListBase *)MEM_callocN(sizeof(ListBase), "items_list");
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->flag & NODE_SELECT) {
- bNodeListItem *nli = MEM_mallocN(sizeof(bNodeListItem), "temporary node list item");
+ bNodeListItem *nli = (bNodeListItem *)MEM_mallocN(sizeof(bNodeListItem),
+ "temporary node list item");
nli->node = node;
BLI_addtail(nodelist, nli);
}
@@ -522,7 +538,7 @@ static void snode_autoconnect(Main *bmain,
LISTBASE_FOREACH (bNodeListItem *, nli, nodelist) {
bool has_selected_inputs = false;
- if (nli->next == NULL) {
+ if (nli->next == nullptr) {
break;
}
@@ -536,7 +552,7 @@ static void snode_autoconnect(Main *bmain,
/* if there are selected sockets, connect those */
LISTBASE_FOREACH (bNodeSocket *, sock_to, &node_to->inputs) {
if (sock_to->flag & SELECT) {
- has_selected_inputs = 1;
+ has_selected_inputs = true;
if (!socket_is_available(ntree, sock_to, replace)) {
continue;
@@ -588,24 +604,28 @@ static void snode_autoconnect(Main *bmain,
MEM_freeN(nodelist);
}
-/* *************************** link viewer op ******************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Link Viewer Operator
+ * \{ */
static int node_link_viewer(const bContext *C, bNode *tonode)
{
SpaceNode *snode = CTX_wm_space_node(C);
/* context check */
- if (tonode == NULL || BLI_listbase_is_empty(&tonode->outputs)) {
+ if (tonode == nullptr || BLI_listbase_is_empty(&tonode->outputs)) {
return OPERATOR_CANCELLED;
}
- if (ELEM(tonode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
+ if (ELEM(tonode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER)) {
return OPERATOR_CANCELLED;
}
/* get viewer */
- bNode *viewer_node = NULL;
+ bNode *viewer_node = nullptr;
LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
- if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
+ if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER)) {
if (node->flag & NODE_DO_OUTPUT) {
viewer_node = node;
break;
@@ -613,9 +633,9 @@ static int node_link_viewer(const bContext *C, bNode *tonode)
}
}
/* no viewer, we make one active */
- if (viewer_node == NULL) {
+ if (viewer_node == nullptr) {
LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
- if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
+ if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER)) {
node->flag |= NODE_DO_OUTPUT;
viewer_node = node;
break;
@@ -623,14 +643,14 @@ static int node_link_viewer(const bContext *C, bNode *tonode)
}
}
- bNodeSocket *sock = NULL;
- bNodeLink *link = NULL;
+ bNodeSocket *sock = nullptr;
+ bNodeLink *link = nullptr;
/* try to find an already connected socket to cycle to the next */
if (viewer_node) {
- link = NULL;
+ link = nullptr;
- for (link = snode->edittree->links.first; link; link = link->next) {
+ for (link = (bNodeLink *)snode->edittree->links.first; link; link = link->next) {
if (link->tonode == viewer_node && link->fromnode == tonode) {
if (link->tosock == viewer_node->inputs.first) {
break;
@@ -663,7 +683,7 @@ static int node_link_viewer(const bContext *C, bNode *tonode)
/* find a socket starting from the first socket */
if (!sock) {
- for (sock = tonode->outputs.first; sock; sock = sock->next) {
+ for (sock = (bNodeSocket *)tonode->outputs.first; sock; sock = sock->next) {
if (!nodeSocketIsHidden(sock)) {
break;
}
@@ -674,24 +694,26 @@ static int node_link_viewer(const bContext *C, bNode *tonode)
/* add a new viewer if none exists yet */
if (!viewer_node) {
/* XXX location is a quick hack, just place it next to the linked socket */
- viewer_node = node_add_node(C, NULL, CMP_NODE_VIEWER, sock->locx + 100, sock->locy);
+ const int viewer_type = ED_node_is_compositor(snode) ? CMP_NODE_VIEWER : GEO_NODE_VIEWER;
+ viewer_node = node_add_node(C, nullptr, viewer_type, sock->locx + 100, sock->locy);
if (!viewer_node) {
return OPERATOR_CANCELLED;
}
- link = NULL;
+ link = nullptr;
}
else {
/* get link to viewer */
- for (link = snode->edittree->links.first; link; link = link->next) {
+ for (link = (bNodeLink *)snode->edittree->links.first; link; link = link->next) {
if (link->tonode == viewer_node && link->tosock == viewer_node->inputs.first) {
break;
}
}
}
- if (link == NULL) {
- nodeAddLink(snode->edittree, tonode, sock, viewer_node, viewer_node->inputs.first);
+ if (link == nullptr) {
+ nodeAddLink(
+ snode->edittree, tonode, sock, viewer_node, (bNodeSocket *)viewer_node->inputs.first);
}
else {
link->fromnode = tonode;
@@ -699,8 +721,13 @@ static int node_link_viewer(const bContext *C, bNode *tonode)
/* make sure the dependency sorting is updated */
snode->edittree->update |= NTREE_UPDATE_LINKS;
}
+ if (ED_node_is_geometry(snode)) {
+ ED_spreadsheet_context_paths_set_geometry_node(CTX_data_main(C), snode, viewer_node);
+ }
+
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
snode_update(snode, viewer_node);
+ DEG_id_tag_update(&snode->edittree->id, 0);
}
return OPERATOR_FINISHED;
@@ -726,6 +753,15 @@ static int node_active_link_viewer_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
+static bool node_active_link_viewer_poll(bContext *C)
+{
+ if (!ED_operator_node_editable(C)) {
+ return false;
+ }
+ SpaceNode *snode = CTX_wm_space_node(C);
+ return ED_node_is_compositor(snode) || ED_node_is_geometry(snode);
+}
+
void NODE_OT_link_viewer(wmOperatorType *ot)
{
/* identifiers */
@@ -735,13 +771,17 @@ void NODE_OT_link_viewer(wmOperatorType *ot)
/* api callbacks */
ot->exec = node_active_link_viewer_exec;
- ot->poll = composite_node_editable;
+ ot->poll = node_active_link_viewer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* *************************** add link op ******************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Add Link Operator
+ * \{ */
static void node_link_update_header(bContext *C, bNodeLinkDrag *UNUSED(nldrag))
{
@@ -779,7 +819,7 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link)
if (tlink && tlink->fromsock == from) {
if (from_count > from_link_limit) {
nodeRemLink(ntree, tlink);
- tlink = NULL;
+ tlink = nullptr;
from_count--;
}
}
@@ -787,13 +827,13 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link)
if (tlink && tlink->tosock == to) {
if (to_count > to_link_limit) {
nodeRemLink(ntree, tlink);
- tlink = NULL;
+ tlink = nullptr;
to_count--;
}
else if (tlink->fromsock == from) {
/* Also remove link if it comes from the same output. */
nodeRemLink(ntree, tlink);
- tlink = NULL;
+ tlink = nullptr;
to_count--;
from_count--;
}
@@ -806,13 +846,13 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
- bNodeLinkDrag *nldrag = op->customdata;
+ bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op->customdata;
bool do_tag_update = false;
/* avoid updates while applying links */
ntree->is_updating = true;
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
- bNodeLink *link = linkdata->data;
+ bNodeLink *link = (bNodeLink *)linkdata->data;
/* See note below, but basically TEST flag means that the link
* was connected to output (or to a node which affects the
@@ -867,14 +907,14 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
{
SpaceNode *snode = CTX_wm_space_node(C);
- bNodeLinkDrag *nldrag = op->customdata;
+ bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op->customdata;
if (nldrag->in_out == SOCK_OUT) {
bNode *tnode;
- bNodeSocket *tsock = NULL;
+ bNodeSocket *tsock = nullptr;
if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_IN)) {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
- bNodeLink *link = linkdata->data;
+ bNodeLink *link = (bNodeLink *)linkdata->data;
/* skip if socket is on the same node as the fromsock */
if (tnode && link->fromnode == tnode) {
@@ -882,7 +922,7 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
}
/* Skip if tsock is already linked with this output. */
- bNodeLink *existing_link_connected_to_fromsock = NULL;
+ bNodeLink *existing_link_connected_to_fromsock = nullptr;
LISTBASE_FOREACH (bNodeLink *, existing_link, &snode->edittree->links) {
if (existing_link->fromsock == link->fromsock && existing_link->tosock == tsock) {
existing_link_connected_to_fromsock = existing_link;
@@ -906,22 +946,22 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
}
else {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
- bNodeLink *link = linkdata->data;
+ bNodeLink *link = (bNodeLink *)linkdata->data;
if (nldrag->last_node_hovered_while_dragging_a_link) {
sort_multi_input_socket_links(
- snode, nldrag->last_node_hovered_while_dragging_a_link, NULL, cursor);
+ snode, nldrag->last_node_hovered_while_dragging_a_link, nullptr, cursor);
}
- link->tonode = NULL;
- link->tosock = NULL;
+ link->tonode = nullptr;
+ link->tosock = nullptr;
}
}
}
else {
bNode *tnode;
- bNodeSocket *tsock = NULL;
+ bNodeSocket *tsock = nullptr;
if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_OUT)) {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
- bNodeLink *link = linkdata->data;
+ bNodeLink *link = (bNodeLink *)linkdata->data;
/* skip if this is already the target socket */
if (link->fromsock == tsock) {
@@ -939,10 +979,10 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
}
else {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
- bNodeLink *link = linkdata->data;
+ bNodeLink *link = (bNodeLink *)linkdata->data;
- link->fromnode = NULL;
- link->fromsock = NULL;
+ link->fromnode = nullptr;
+ link->fromsock = nullptr;
}
}
}
@@ -952,10 +992,12 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
/* in_out = starting socket */
static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- bNodeLinkDrag *nldrag = op->customdata;
+ bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op->customdata;
ARegion *region = CTX_wm_region(C);
float cursor[2];
+ UI_view2d_edge_pan_apply_event(C, &nldrag->pan_data, event);
+
UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &cursor[0], &cursor[1]);
switch (event->type) {
@@ -977,7 +1019,7 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->val == KM_RELEASE) {
node_link_exit(C, op, true);
- ED_workspace_status_text(C, NULL);
+ ED_workspace_status_text(C, nullptr);
ED_region_tag_redraw(region);
SpaceNode *snode = CTX_wm_space_node(C);
clear_picking_highlight(&snode->edittree->links);
@@ -993,13 +1035,13 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* return 1 when socket clicked */
static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor[2], bool detach)
{
- bNodeLinkDrag *nldrag = NULL;
+ bNodeLinkDrag *nldrag = nullptr;
/* output indicated? */
bNode *node;
bNodeSocket *sock;
if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_OUT)) {
- nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
+ nldrag = (bNodeLinkDrag *)MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
const int num_links = nodeCountSocketLinks(snode->edittree, sock);
int link_limit = nodeSocketLinkLimit(sock);
@@ -1009,11 +1051,11 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
/* detach current links and store them in the operator data */
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &snode->edittree->links) {
if (link->fromsock == sock) {
- LinkData *linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
- bNodeLink *oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
+ LinkData *linkdata = (LinkData *)MEM_callocN(sizeof(LinkData), "drag link op link data");
+ bNodeLink *oplink = (bNodeLink *)MEM_callocN(sizeof(bNodeLink), "drag link op link");
linkdata->data = oplink;
*oplink = *link;
- oplink->next = oplink->prev = NULL;
+ oplink->next = oplink->prev = nullptr;
oplink->flag |= NODE_LINK_VALID;
/* The link could be disconnected and in that case we
@@ -1043,7 +1085,7 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
}
/* or an input? */
else if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN)) {
- nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
+ nldrag = (bNodeLinkDrag *)MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
nldrag->last_node_hovered_while_dragging_a_link = node;
const int num_links = nodeCountSocketLinks(snode->edittree, sock);
@@ -1061,12 +1103,12 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
}
}
- if (link_to_pick != NULL && !nldrag->from_multi_input_socket) {
- LinkData *linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
- bNodeLink *oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
+ if (link_to_pick != nullptr && !nldrag->from_multi_input_socket) {
+ LinkData *linkdata = (LinkData *)MEM_callocN(sizeof(LinkData), "drag link op link data");
+ bNodeLink *oplink = (bNodeLink *)MEM_callocN(sizeof(bNodeLink), "drag link op link");
linkdata->data = oplink;
*oplink = *link_to_pick;
- oplink->next = oplink->prev = NULL;
+ oplink->next = oplink->prev = nullptr;
oplink->flag |= NODE_LINK_VALID;
oplink->flag &= ~NODE_LINK_TEST;
if (node_connected_to_output(bmain, snode->edittree, link_to_pick->tonode)) {
@@ -1113,6 +1155,8 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
bNodeLinkDrag *nldrag = node_link_init(bmain, snode, cursor, detach);
if (nldrag) {
+ UI_view2d_edge_pan_operator_init(C, &nldrag->pan_data, op);
+
op->customdata = nldrag;
BLI_addtail(&snode->runtime->linkdrag, nldrag);
@@ -1127,7 +1171,7 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void node_link_cancel(bContext *C, wmOperator *op)
{
SpaceNode *snode = CTX_wm_space_node(C);
- bNodeLinkDrag *nldrag = op->customdata;
+ bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op->customdata;
BLI_remlink(&snode->runtime->linkdrag, nldrag);
@@ -1167,7 +1211,7 @@ void NODE_OT_link(wmOperatorType *ot)
RNA_def_float_array(ot->srna,
"drag_start",
2,
- 0,
+ nullptr,
-UI_PRECISION_FLOAT_MAX,
UI_PRECISION_FLOAT_MAX,
"Drag Start",
@@ -1176,9 +1220,20 @@ void NODE_OT_link(wmOperatorType *ot)
UI_PRECISION_FLOAT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_property_flag(prop, PROP_HIDDEN);
+
+ UI_view2d_edge_pan_operator_properties_ex(ot,
+ NODE_EDGE_PAN_INSIDE_PAD,
+ NODE_EDGE_PAN_OUTSIDE_PAD,
+ NODE_EDGE_PAN_SPEED_RAMP,
+ NODE_EDGE_PAN_MAX_SPEED,
+ NODE_EDGE_PAN_DELAY);
}
-/* ********************** Make Link operator ***************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Make Link Operator
+ * \{ */
/* makes a link between selected output and input sockets */
static int node_make_link_exec(bContext *C, wmOperator *op)
@@ -1189,11 +1244,11 @@ static int node_make_link_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
- snode_autoconnect(bmain, snode, 1, replace);
+ snode_autoconnect(bmain, snode, true, replace);
/* deselect sockets after linking */
- node_deselect_all_input_sockets(snode, 0);
- node_deselect_all_output_sockets(snode, 0);
+ node_deselect_all_input_sockets(snode, false);
+ node_deselect_all_output_sockets(snode, false);
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
snode_notify(C, snode);
@@ -1218,27 +1273,37 @@ void NODE_OT_link_make(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(
- ot->srna, "replace", 0, "Replace", "Replace socket connections with the new links");
+ ot->srna, "replace", false, "Replace", "Replace socket connections with the new links");
}
-/* ********************** Node Link Intersect ***************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Node Link Intersect
+ * \{ */
+
static bool node_links_intersect(bNodeLink *link, const float mcoords[][2], int tot)
{
float coord_array[NODE_LINK_RESOL + 1][2];
- if (node_link_bezier_points(NULL, NULL, link, coord_array, NODE_LINK_RESOL)) {
+ if (node_link_bezier_points(nullptr, nullptr, link, coord_array, NODE_LINK_RESOL)) {
for (int i = 0; i < tot - 1; i++) {
for (int b = 0; b < NODE_LINK_RESOL; b++) {
if (isect_seg_seg_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0) {
- return 1;
+ return true;
}
}
}
}
- return 0;
+ return false;
}
-/* ********************** Cut Link operator ***************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Cut Link Operator
+ * \{ */
+
static int cut_links_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -1285,7 +1350,7 @@ static int cut_links_exec(bContext *C, wmOperator *op)
snode_update(snode, link->tonode);
bNode *to_node = link->tonode;
nodeRemLink(snode->edittree, link);
- sort_multi_input_socket_links(snode, to_node, NULL, NULL);
+ sort_multi_input_socket_links(snode, to_node, nullptr, nullptr);
}
}
@@ -1324,13 +1389,17 @@ void NODE_OT_links_cut(wmOperatorType *ot)
/* properties */
PropertyRNA *prop;
prop = RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
/* internal */
RNA_def_int(ot->srna, "cursor", WM_CURSOR_KNIFE, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
}
-/* ********************** Mute links operator ***************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Mute Links Operator
+ * \{ */
static int mute_links_exec(bContext *C, wmOperator *op)
{
@@ -1426,13 +1495,17 @@ void NODE_OT_links_mute(wmOperatorType *ot)
/* properties */
PropertyRNA *prop;
prop = RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
/* internal */
RNA_def_int(ot->srna, "cursor", WM_CURSOR_MUTE, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
}
-/* ********************** Detach links operator ***************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Detach Links Operator
+ * \{ */
static int detach_links_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1469,7 +1542,11 @@ void NODE_OT_links_detach(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ****************** Set Parent ******************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Set Parent Operator
+ * \{ */
static int node_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1491,7 +1568,7 @@ static int node_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
}
ED_node_sort(ntree);
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
return OPERATOR_FINISHED;
}
@@ -1511,7 +1588,11 @@ void NODE_OT_parent_set(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ****************** Join Nodes ******************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Join Nodes Operator
+ * \{ */
/* tags for depth-first search */
#define NODE_JOIN_DONE 1
@@ -1563,7 +1644,7 @@ static int node_join_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- bNode *frame = node_add_node(C, NULL, NODE_FRAME, 0.0f, 0.0f);
+ bNode *frame = node_add_node(C, nullptr, NODE_FRAME, 0.0f, 0.0f);
/* reset tags */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
@@ -1584,7 +1665,7 @@ static int node_join_exec(bContext *C, wmOperator *UNUSED(op))
}
ED_node_sort(ntree);
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
return OPERATOR_FINISHED;
}
@@ -1604,7 +1685,11 @@ void NODE_OT_join(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ****************** Attach ******************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Attach Operator
+ * \{ */
static bNode *node_find_frame_to_attach(ARegion *region,
const bNodeTree *ntree,
@@ -1624,7 +1709,7 @@ static bNode *node_find_frame_to_attach(ARegion *region,
}
}
- return NULL;
+ return nullptr;
}
static int node_attach_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
@@ -1637,7 +1722,7 @@ static int node_attach_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent
if (frame) {
LISTBASE_FOREACH_BACKWARD (bNode *, node, &ntree->nodes) {
if (node->flag & NODE_SELECT) {
- if (node->parent == NULL) {
+ if (node->parent == nullptr) {
/* disallow moving a parent into its child */
if (nodeAttachNodeCheck(frame, node) == false) {
/* attach all unparented nodes */
@@ -1666,7 +1751,7 @@ static int node_attach_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent
}
ED_node_sort(ntree);
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
return OPERATOR_FINISHED;
}
@@ -1687,7 +1772,11 @@ void NODE_OT_attach(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ****************** Detach ******************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Detach Operator
+ * \{ */
/* tags for depth-first search */
#define NODE_DETACH_DONE 1
@@ -1738,7 +1827,7 @@ static int node_detach_exec(bContext *C, wmOperator *UNUSED(op))
}
ED_node_sort(ntree);
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
return OPERATOR_FINISHED;
}
@@ -1758,7 +1847,11 @@ void NODE_OT_detach(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ********************* automatic node insert on dragging ******************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Automatic Node Insert on Dragging
+ * \{ */
/* prevent duplicate testing code below */
static bool ed_node_link_conditions(ScrArea *area,
@@ -1766,13 +1859,13 @@ static bool ed_node_link_conditions(ScrArea *area,
SpaceNode **r_snode,
bNode **r_select)
{
- SpaceNode *snode = area ? area->spacedata.first : NULL;
+ SpaceNode *snode = area ? (SpaceNode *)area->spacedata.first : nullptr;
*r_snode = snode;
- *r_select = NULL;
+ *r_select = nullptr;
/* no unlucky accidents */
- if (area == NULL || area->spacetype != SPACE_NODE) {
+ if (area == nullptr || area->spacetype != SPACE_NODE) {
return false;
}
@@ -1782,8 +1875,8 @@ static bool ed_node_link_conditions(ScrArea *area,
}
bNode *node;
- bNode *select = NULL;
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ bNode *select = nullptr;
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
if (node->flag & SELECT) {
if (select) {
break;
@@ -1792,7 +1885,7 @@ static bool ed_node_link_conditions(ScrArea *area,
}
}
/* only one selected */
- if (node || select == NULL) {
+ if (node || select == nullptr) {
return false;
}
@@ -1835,7 +1928,7 @@ void ED_node_link_intersect_test(ScrArea *area, int test)
}
/* find link to select/highlight */
- bNodeLink *selink = NULL;
+ bNodeLink *selink = nullptr;
float dist_best = FLT_MAX;
LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
float coord_array[NODE_LINK_RESOL + 1][2];
@@ -1844,7 +1937,7 @@ void ED_node_link_intersect_test(ScrArea *area, int test)
continue;
}
- if (node_link_bezier_points(NULL, NULL, link, coord_array, NODE_LINK_RESOL)) {
+ if (node_link_bezier_points(nullptr, nullptr, link, coord_array, NODE_LINK_RESOL)) {
float dist = FLT_MAX;
/* loop over link coords to find shortest dist to
@@ -1876,6 +1969,12 @@ void ED_node_link_intersect_test(ScrArea *area, int test)
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Node Insert Offset Operator
+ * \{ */
+
static int get_main_socket_priority(const bNodeSocket *socket)
{
switch ((eNodeSocketDatatype)socket->type) {
@@ -1939,7 +2038,7 @@ static bNodeSocket *get_main_socket(ListBase *sockets)
}
}
- return NULL;
+ return nullptr;
}
static bool node_parents_offset_flag_enable_cb(bNode *parent, void *UNUSED(userdata))
@@ -1977,7 +2076,7 @@ static void node_parent_offset_apply(NodeInsertOfsData *data, bNode *parent, con
#define NODE_INSOFS_ANIM_DURATION 0.25f
/**
- * Callback that applies NodeInsertOfsData.offset_x to a node or its parent, similar
+ * Callback that applies #NodeInsertOfsData.offset_x to a node or its parent, similar
* to node_link_insert_offset_output_chain_cb below, but with slightly different logic
*/
static bool node_link_insert_offset_frame_chain_cb(bNode *fromnode,
@@ -1985,7 +2084,7 @@ static bool node_link_insert_offset_frame_chain_cb(bNode *fromnode,
void *userdata,
const bool reversed)
{
- NodeInsertOfsData *data = userdata;
+ NodeInsertOfsData *data = (NodeInsertOfsData *)userdata;
bNode *ofs_node = reversed ? fromnode : tonode;
if (ofs_node->parent && ofs_node->parent != data->insert_parent) {
@@ -2022,7 +2121,7 @@ static bool node_link_insert_offset_chain_cb(bNode *fromnode,
void *userdata,
const bool reversed)
{
- NodeInsertOfsData *data = userdata;
+ NodeInsertOfsData *data = (NodeInsertOfsData *)userdata;
bNode *ofs_node = reversed ? fromnode : tonode;
if (data->insert_parent) {
@@ -2035,7 +2134,7 @@ static bool node_link_insert_offset_chain_cb(bNode *fromnode,
}
if (nodeIsChildOf(data->insert_parent, ofs_node) == false) {
- data->insert_parent = NULL;
+ data->insert_parent = nullptr;
}
}
else if (ofs_node->parent) {
@@ -2086,7 +2185,7 @@ static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd,
rctf totr_frame;
/* check nodes front to back */
- for (frame = ntree->nodes.last; frame; frame = frame->prev) {
+ for (frame = (bNode *)ntree->nodes.last; frame; frame = frame->prev) {
/* skip selected, those are the nodes we want to attach */
if ((frame->type != NODE_FRAME) || (frame->flag & NODE_SELECT)) {
continue;
@@ -2152,7 +2251,7 @@ static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd,
iofsd->offset_x = margin;
/* flag all parents of insert as offset to prevent them from being offset */
- nodeParentsIter(insert, node_parents_offset_flag_enable_cb, NULL);
+ nodeParentsIter(insert, node_parents_offset_flag_enable_cb, nullptr);
/* iterate over entire chain and apply offsets */
nodeChainIter(ntree,
right_alignment ? next : prev,
@@ -2173,7 +2272,8 @@ static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const w
NodeInsertOfsData *iofsd = snode->runtime->iofsd;
bool redraw = false;
- if (!snode || event->type != TIMER || iofsd == NULL || iofsd->anim_timer != event->customdata) {
+ if (!snode || event->type != TIMER || iofsd == nullptr ||
+ iofsd->anim_timer != event->customdata) {
return OPERATOR_PASS_THROUGH;
}
@@ -2203,13 +2303,13 @@ static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const w
/* end timer + free insert offset data */
if (duration > NODE_INSOFS_ANIM_DURATION) {
- WM_event_remove_timer(CTX_wm_manager(C), NULL, iofsd->anim_timer);
+ WM_event_remove_timer(CTX_wm_manager(C), nullptr, iofsd->anim_timer);
LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
node->anim_init_locx = node->anim_ofsx = 0.0f;
}
- snode->runtime->iofsd = NULL;
+ snode->runtime->iofsd = nullptr;
MEM_freeN(iofsd);
return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
@@ -2259,6 +2359,12 @@ void NODE_OT_insert_offset(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Note Link Insert
+ * \{ */
+
/* assumes link with NODE_LINKFLAG_HILITE set */
void ED_node_link_insert(Main *bmain, ScrArea *area)
{
@@ -2270,7 +2376,7 @@ void ED_node_link_insert(Main *bmain, ScrArea *area)
/* get the link */
bNodeLink *link;
- for (link = snode->edittree->links.first; link; link = link->next) {
+ for (link = (bNodeLink *)snode->edittree->links.first; link; link = link->next) {
if (link->flag & NODE_LINKFLAG_HILITE) {
break;
}
@@ -2298,7 +2404,8 @@ void ED_node_link_insert(Main *bmain, ScrArea *area)
/* set up insert offset data, it needs stuff from here */
if ((snode->flag & SNODE_SKIP_INSOFFSET) == 0) {
- NodeInsertOfsData *iofsd = MEM_callocN(sizeof(NodeInsertOfsData), __func__);
+ NodeInsertOfsData *iofsd = (NodeInsertOfsData *)MEM_callocN(sizeof(NodeInsertOfsData),
+ __func__);
iofsd->insert = select;
iofsd->prev = link->fromnode;
@@ -2314,3 +2421,5 @@ void ED_node_link_insert(Main *bmain, ScrArea *area)
}
}
}
+
+/** \} */
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.cc
index de63aa07acb..a081cc83481 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.cc
@@ -21,7 +21,8 @@
* \ingroup spnode
*/
-#include <stdlib.h>
+#include <array>
+#include <cstdlib>
#include "DNA_node_types.h"
#include "DNA_windowmanager_types.h"
@@ -43,6 +44,7 @@
#include "ED_node.h" /* own include */
#include "ED_screen.h"
#include "ED_select_utils.h"
+#include "ED_spreadsheet.h"
#include "ED_view3d.h"
#include "RNA_access.h"
@@ -81,7 +83,7 @@ static bool has_workbench_in_texture_color(const wmWindowManager *wm,
const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->spacetype == SPACE_VIEW3D) {
- const View3D *v3d = area->spacedata.first;
+ const View3D *v3d = (const View3D *)area->spacedata.first;
if (ED_view3d_has_workbench_in_texture_color(scene, ob, v3d)) {
return true;
@@ -100,28 +102,28 @@ static bNode *node_under_mouse_select(bNodeTree *ntree, int mx, int my)
{
bNode *node;
- for (node = ntree->nodes.last; node; node = node->prev) {
+ for (node = (bNode *)ntree->nodes.last; node; node = node->prev) {
if (node->typeinfo->select_area_func) {
if (node->typeinfo->select_area_func(node, mx, my)) {
return node;
}
}
}
- return NULL;
+ return nullptr;
}
static bNode *node_under_mouse_tweak(bNodeTree *ntree, int mx, int my)
{
bNode *node;
- for (node = ntree->nodes.last; node; node = node->prev) {
+ for (node = (bNode *)ntree->nodes.last; node; node = node->prev) {
if (node->typeinfo->tweak_area_func) {
if (node->typeinfo->tweak_area_func(node, mx, my)) {
return node;
}
}
}
- return NULL;
+ return nullptr;
}
static bool is_position_over_node_or_socket(SpaceNode *snode, float mouse[2])
@@ -168,18 +170,18 @@ void node_socket_deselect(bNode *node, bNodeSocket *sock, const bool deselect_no
sock->flag &= ~SELECT;
if (node && deselect_node) {
- bool sel = 0;
+ bool sel = false;
/* if no selected sockets remain, also deselect the node */
- for (sock = node->inputs.first; sock; sock = sock->next) {
+ for (sock = (bNodeSocket *)node->inputs.first; sock; sock = sock->next) {
if (sock->flag & SELECT) {
- sel = 1;
+ sel = true;
break;
}
}
- for (sock = node->outputs.first; sock; sock = sock->next) {
+ for (sock = (bNodeSocket *)node->outputs.first; sock; sock = sock->next) {
if (sock->flag & SELECT) {
- sel = 1;
+ sel = true;
break;
}
}
@@ -205,7 +207,7 @@ void node_deselect_all(SpaceNode *snode)
{
bNode *node;
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
nodeSetSelected(node, false);
}
}
@@ -220,16 +222,16 @@ void node_deselect_all_input_sockets(SpaceNode *snode, const bool deselect_nodes
* We can do that more efficiently here.
*/
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
int sel = 0;
- for (sock = node->inputs.first; sock; sock = sock->next) {
+ for (sock = (bNodeSocket *)node->inputs.first; sock; sock = sock->next) {
sock->flag &= ~SELECT;
}
/* if no selected sockets remain, also deselect the node */
if (deselect_nodes) {
- for (sock = node->outputs.first; sock; sock = sock->next) {
+ for (sock = (bNodeSocket *)node->outputs.first; sock; sock = sock->next) {
if (sock->flag & SELECT) {
sel = 1;
break;
@@ -253,18 +255,18 @@ void node_deselect_all_output_sockets(SpaceNode *snode, const bool deselect_node
* We can do that more efficiently here.
*/
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
bool sel = false;
- for (sock = node->outputs.first; sock; sock = sock->next) {
+ for (sock = (bNodeSocket *)node->outputs.first; sock; sock = sock->next) {
sock->flag &= ~SELECT;
}
/* if no selected sockets remain, also deselect the node */
if (deselect_nodes) {
- for (sock = node->inputs.first; sock; sock = sock->next) {
+ for (sock = (bNodeSocket *)node->inputs.first; sock; sock = sock->next) {
if (sock->flag & SELECT) {
- sel = 1;
+ sel = true;
break;
}
}
@@ -289,7 +291,7 @@ static bool node_select_grouped_type(SpaceNode *snode, bNode *node_act)
bNode *node;
bool changed = false;
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
if ((node->flag & SELECT) == 0) {
if (node->type == node_act->type) {
nodeSetSelected(node, true);
@@ -306,7 +308,7 @@ static bool node_select_grouped_color(SpaceNode *snode, bNode *node_act)
bNode *node;
bool changed = false;
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
if ((node->flag & SELECT) == 0) {
if (compare_v3v3(node->color, node_act->color, 0.005f)) {
nodeSetSelected(node, true);
@@ -327,20 +329,20 @@ static bool node_select_grouped_name(SpaceNode *snode, bNode *node_act, const bo
const char *sep, *suf_act, *suf_curr;
pref_len_act = BLI_str_partition_ex_utf8(
- node_act->name, NULL, delims, &sep, &suf_act, from_right);
+ node_act->name, nullptr, delims, &sep, &suf_act, from_right);
- /* Note: in case we are searching for suffix, and found none, use whole name as suffix. */
+ /* NOTE: in case we are searching for suffix, and found none, use whole name as suffix. */
if (from_right && !(sep && suf_act)) {
pref_len_act = 0;
suf_act = node_act->name;
}
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
if (node->flag & SELECT) {
continue;
}
pref_len_curr = BLI_str_partition_ex_utf8(
- node->name, NULL, delims, &sep, &suf_curr, from_right);
+ node->name, nullptr, delims, &sep, &suf_curr, from_right);
/* Same as with active node name! */
if (from_right && !(sep && suf_curr)) {
@@ -371,7 +373,7 @@ static int node_select_grouped_exec(bContext *C, wmOperator *op)
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node_act = nodeGetActive(snode->edittree);
- if (node_act == NULL) {
+ if (node_act == nullptr) {
return OPERATOR_CANCELLED;
}
@@ -381,7 +383,7 @@ static int node_select_grouped_exec(bContext *C, wmOperator *op)
const int type = RNA_enum_get(op->ptr, "type");
if (!extend) {
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
nodeSetSelected(node, false);
}
}
@@ -406,7 +408,7 @@ static int node_select_grouped_exec(bContext *C, wmOperator *op)
if (changed) {
ED_node_sort(snode->edittree);
- WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
+ WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
return OPERATOR_FINISHED;
}
@@ -420,7 +422,7 @@ void NODE_OT_select_grouped(wmOperatorType *ot)
{NODE_SELECT_GROUPED_COLOR, "COLOR", 0, "Color", ""},
{NODE_SELECT_GROUPED_PREFIX, "PREFIX", 0, "Prefix", ""},
{NODE_SELECT_GROUPED_SUFIX, "SUFFIX", 0, "Suffix", ""},
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
/* identifiers */
@@ -461,14 +463,14 @@ void node_select_single(bContext *C, bNode *node)
bool active_texture_changed = false;
bNode *tnode;
- for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
+ for (tnode = (bNode *)snode->edittree->nodes.first; tnode; tnode = tnode->next) {
if (tnode != node) {
nodeSetSelected(tnode, false);
}
}
nodeSetSelected(node, true);
- ED_node_set_active(bmain, snode->edittree, node, &active_texture_changed);
+ ED_node_set_active(bmain, snode, snode->edittree, node, &active_texture_changed);
ED_node_set_active_viewer_key(snode);
ED_node_sort(snode->edittree);
@@ -476,7 +478,7 @@ void node_select_single(bContext *C, bNode *node)
DEG_id_tag_update(&snode->edittree->id, ID_RECALC_COPY_ON_WRITE);
}
- WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
+ WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
}
static int node_mouse_select(bContext *C,
@@ -491,7 +493,7 @@ static int node_mouse_select(bContext *C,
const Scene *scene = CTX_data_scene(C);
const wmWindowManager *wm = CTX_wm_manager(C);
bNode *node, *tnode;
- bNodeSocket *sock = NULL;
+ bNodeSocket *sock = nullptr;
bNodeSocket *tsock;
float cursor[2];
int ret_value = OPERATOR_CANCELLED;
@@ -530,7 +532,7 @@ static int node_mouse_select(bContext *C,
/* Only allow one selected output per node, for sensible linking.
* Allow selecting outputs from different nodes though, if extend is true. */
if (node) {
- for (tsock = node->outputs.first; tsock; tsock = tsock->next) {
+ for (tsock = (bNodeSocket *)node->outputs.first; tsock; tsock = tsock->next) {
if (tsock == sock) {
continue;
}
@@ -538,11 +540,11 @@ static int node_mouse_select(bContext *C,
}
}
if (!extend) {
- for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
+ for (tnode = (bNode *)snode->edittree->nodes.first; tnode; tnode = tnode->next) {
if (tnode == node) {
continue;
}
- for (tsock = tnode->outputs.first; tsock; tsock = tsock->next) {
+ for (tsock = (bNodeSocket *)tnode->outputs.first; tsock; tsock = tsock->next) {
node_socket_deselect(tnode, tsock, true);
}
}
@@ -558,7 +560,7 @@ static int node_mouse_select(bContext *C,
node = node_under_mouse_select(snode->edittree, (int)cursor[0], (int)cursor[1]);
if (extend) {
- if (node != NULL) {
+ if (node != nullptr) {
/* If node is selected but not active, we want to make it active,
* but not toggle (deselect) it. */
if (!((node->flag & SELECT) && (node->flag & NODE_ACTIVE) == 0)) {
@@ -567,7 +569,7 @@ static int node_mouse_select(bContext *C,
ret_value = OPERATOR_FINISHED;
}
}
- else if (deselect_all && node == NULL) {
+ else if (deselect_all && node == nullptr) {
/* Rather than deselecting others, users may want to drag to box-select (drag from empty
* space) or tweak-translate an already selected item. If these cases may apply, delay
* deselection. */
@@ -576,13 +578,13 @@ static int node_mouse_select(bContext *C,
}
else {
/* Deselect in empty space. */
- for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
+ for (tnode = (bNode *)snode->edittree->nodes.first; tnode; tnode = tnode->next) {
nodeSetSelected(tnode, false);
}
ret_value = OPERATOR_FINISHED;
}
}
- else if (node != NULL) {
+ else if (node != nullptr) {
/* When clicking on an already selected node, we want to wait to deselect
* others and allow the user to start moving the node without that. */
if (wait_to_deselect_others && (node->flag & SELECT)) {
@@ -591,7 +593,7 @@ static int node_mouse_select(bContext *C,
else {
nodeSetSelected(node, true);
- for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
+ for (tnode = (bNode *)snode->edittree->nodes.first; tnode; tnode = tnode->next) {
if (tnode != node) {
nodeSetSelected(tnode, false);
}
@@ -605,16 +607,22 @@ static int node_mouse_select(bContext *C,
/* update node order */
if (ret_value != OPERATOR_CANCELLED) {
bool active_texture_changed = false;
- if (node != NULL && ret_value != OPERATOR_RUNNING_MODAL) {
- ED_node_set_active(bmain, snode->edittree, node, &active_texture_changed);
+ bool viewer_node_changed = false;
+ if (node != nullptr && ret_value != OPERATOR_RUNNING_MODAL) {
+ viewer_node_changed = (node->flag & NODE_DO_OUTPUT) == 0 && node->type == GEO_NODE_VIEWER;
+ ED_node_set_active(bmain, snode, snode->edittree, node, &active_texture_changed);
+ }
+ else if (node != nullptr && node->type == GEO_NODE_VIEWER) {
+ ED_spreadsheet_context_paths_set_geometry_node(bmain, snode, node);
}
ED_node_set_active_viewer_key(snode);
ED_node_sort(snode->edittree);
- if (active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) {
+ if ((active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) ||
+ viewer_node_changed) {
DEG_id_tag_update(&snode->edittree->id, ID_RECALC_COPY_ON_WRITE);
}
- WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
+ WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
}
return ret_value;
@@ -681,7 +689,7 @@ static int node_box_select_exec(bContext *C, wmOperator *op)
WM_operator_properties_border_to_rctf(op, &rectf);
UI_view2d_region_to_view_rctf(&region->v2d, &rectf, &rectf);
- const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
+ const eSelectOp sel_op = (eSelectOp)RNA_enum_get(op->ptr, "mode");
const bool select = (sel_op != SEL_OP_SUB);
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
ED_node_select_all(&snode->edittree->nodes, SEL_DESELECT);
@@ -693,7 +701,7 @@ static int node_box_select_exec(bContext *C, wmOperator *op)
is_inside = BLI_rctf_inside_rctf(&rectf, &node->totr);
}
else {
- is_inside = BLI_rctf_isect(&rectf, &node->totr, NULL);
+ is_inside = BLI_rctf_isect(&rectf, &node->totr, nullptr);
}
if (is_inside) {
@@ -703,7 +711,7 @@ static int node_box_select_exec(bContext *C, wmOperator *op)
ED_node_sort(snode->edittree);
- WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
+ WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
return OPERATOR_FINISHED;
}
@@ -740,7 +748,7 @@ void NODE_OT_select_box(wmOperatorType *ot)
/* properties */
RNA_def_boolean(ot->srna,
"tweak",
- 0,
+ false,
"Tweak",
"Only activate when mouse is not over a node (useful for tweak gesture)");
@@ -766,8 +774,9 @@ static int node_circleselect_exec(bContext *C, wmOperator *op)
float zoom = (float)(BLI_rcti_size_x(&region->winrct)) /
(float)(BLI_rctf_size_x(&region->v2d.cur));
- const eSelectOp sel_op = ED_select_op_modal(RNA_enum_get(op->ptr, "mode"),
- WM_gesture_is_modal_first(op->customdata));
+ const eSelectOp sel_op = ED_select_op_modal(
+ (eSelectOp)RNA_enum_get(op->ptr, "mode"),
+ WM_gesture_is_modal_first((const wmGesture *)op->customdata));
const bool select = (sel_op != SEL_OP_SUB);
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
ED_node_select_all(&snode->edittree->nodes, SEL_DESELECT);
@@ -780,13 +789,13 @@ static int node_circleselect_exec(bContext *C, wmOperator *op)
UI_view2d_region_to_view(&region->v2d, x, y, &offset[0], &offset[1]);
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
if (BLI_rctf_isect_circle(&node->totr, offset, radius / zoom)) {
nodeSetSelected(node, select);
}
}
- WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
+ WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
return OPERATOR_FINISHED;
}
@@ -853,7 +862,7 @@ static bool do_lasso_select_node(bContext *C,
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
/* do actual selection */
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
if (select && (node->flag & NODE_SELECT)) {
continue;
@@ -873,7 +882,7 @@ static bool do_lasso_select_node(bContext *C,
}
if (changed) {
- WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
+ WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
}
return changed;
@@ -885,7 +894,7 @@ static int node_lasso_select_exec(bContext *C, wmOperator *op)
const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len);
if (mcoords) {
- const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
+ const eSelectOp sel_op = (eSelectOp)RNA_enum_get(op->ptr, "mode");
do_lasso_select_node(C, mcoords, mcoords_len, sel_op);
@@ -916,7 +925,7 @@ void NODE_OT_select_lasso(wmOperatorType *ot)
/* properties */
RNA_def_boolean(ot->srna,
"tweak",
- 0,
+ false,
"Tweak",
"Only activate when mouse is not over a node (useful for tweak gesture)");
@@ -940,7 +949,7 @@ static int node_select_all_exec(bContext *C, wmOperator *op)
ED_node_sort(snode->edittree);
- WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
+ WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
return OPERATOR_FINISHED;
}
@@ -973,11 +982,11 @@ static int node_select_linked_to_exec(bContext *C, wmOperator *UNUSED(op))
bNodeLink *link;
bNode *node;
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
node->flag &= ~NODE_TEST;
}
- for (link = snode->edittree->links.first; link; link = link->next) {
+ for (link = (bNodeLink *)snode->edittree->links.first; link; link = link->next) {
if (nodeLinkIsHidden(link)) {
continue;
}
@@ -986,7 +995,7 @@ static int node_select_linked_to_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
if (node->flag & NODE_TEST) {
nodeSetSelected(node, true);
}
@@ -994,7 +1003,7 @@ static int node_select_linked_to_exec(bContext *C, wmOperator *UNUSED(op))
ED_node_sort(snode->edittree);
- WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
+ WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
return OPERATOR_FINISHED;
}
@@ -1025,11 +1034,11 @@ static int node_select_linked_from_exec(bContext *C, wmOperator *UNUSED(op))
bNodeLink *link;
bNode *node;
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
node->flag &= ~NODE_TEST;
}
- for (link = snode->edittree->links.first; link; link = link->next) {
+ for (link = (bNodeLink *)snode->edittree->links.first; link; link = link->next) {
if (nodeLinkIsHidden(link)) {
continue;
}
@@ -1038,7 +1047,7 @@ static int node_select_linked_from_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
if (node->flag & NODE_TEST) {
nodeSetSelected(node, true);
}
@@ -1046,7 +1055,7 @@ static int node_select_linked_from_exec(bContext *C, wmOperator *UNUSED(op))
ED_node_sort(snode->edittree);
- WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
+ WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
return OPERATOR_FINISHED;
}
@@ -1079,7 +1088,7 @@ static int node_select_same_type_step_exec(bContext *C, wmOperator *op)
bNode *active = nodeGetActive(snode->edittree);
int totnodes;
const bool revert = RNA_boolean_get(op->ptr, "prev");
- const bool same_type = 1;
+ const bool same_type = true;
ntreeGetDependencyList(snode->edittree, &node_array, &totnodes);
@@ -1093,9 +1102,9 @@ static int node_select_same_type_step_exec(bContext *C, wmOperator *op)
}
if (same_type) {
- bNode *node = NULL;
+ bNode *node = nullptr;
- while (node == NULL) {
+ while (node == nullptr) {
if (revert) {
a--;
}
@@ -1112,7 +1121,7 @@ static int node_select_same_type_step_exec(bContext *C, wmOperator *op)
if (node->type == active->type) {
break;
}
- node = NULL;
+ node = nullptr;
}
if (node) {
active = node;
@@ -1168,7 +1177,7 @@ void NODE_OT_select_same_type_step(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "prev", 0, "Previous", "");
+ RNA_def_boolean(ot->srna, "prev", false, "Previous", "");
}
/** \} */
@@ -1223,7 +1232,7 @@ static void node_find_update_fn(const struct bContext *C,
static void node_find_exec_fn(struct bContext *C, void *UNUSED(arg1), void *arg2)
{
SpaceNode *snode = CTX_wm_space_node(C);
- bNode *active = arg2;
+ bNode *active = (bNode *)arg2;
if (active) {
ARegion *region = CTX_wm_region(C);
@@ -1261,7 +1270,7 @@ static uiBlock *node_find_menu(bContext *C, ARegion *region, void *arg_op)
0,
"");
UI_but_func_search_set(
- but, NULL, node_find_update_fn, op->type, false, NULL, node_find_exec_fn, NULL);
+ but, nullptr, node_find_update_fn, op->type, false, nullptr, node_find_exec_fn, nullptr);
UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT);
/* fake button, it holds space for search items */
@@ -1273,22 +1282,23 @@ static uiBlock *node_find_menu(bContext *C, ARegion *region, void *arg_op)
10 - UI_searchbox_size_y(),
UI_searchbox_size_x(),
UI_searchbox_size_y(),
- NULL,
+ nullptr,
0,
0,
0,
0,
- NULL);
+ nullptr);
/* Move it downwards, mouse over button. */
- UI_block_bounds_set_popup(block, 0.3f * U.widget_unit, (const int[2]){0, -UI_UNIT_Y});
+ std::array<int, 2> bounds_offset = {0, -UI_UNIT_Y};
+ UI_block_bounds_set_popup(block, 0.3f * U.widget_unit, bounds_offset.data());
return block;
}
static int node_find_node_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- UI_popup_block_invoke(C, node_find_menu, op, NULL);
+ UI_popup_block_invoke(C, node_find_menu, op, nullptr);
return OPERATOR_CANCELLED;
}
@@ -1306,7 +1316,7 @@ void NODE_OT_find_node(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "prev", 0, "Previous", "");
+ RNA_def_boolean(ot->srna, "prev", false, "Previous", "");
}
/** \} */
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.cc
index c880f3e99d8..cbe33fab64e 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.cc
@@ -18,8 +18,8 @@
* \ingroup edinterface
*/
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -29,6 +29,7 @@
#include "BLI_array.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
+#include "BLI_vector.hh"
#include "BLT_translation.h"
@@ -51,7 +52,7 @@
/************************* Node Socket Manipulation **************************/
/* describes an instance of a node type and a specific socket to link */
-typedef struct NodeLinkItem {
+struct NodeLinkItem {
int socket_index; /* index for linking */
int socket_type; /* socket type for compatibility check */
const char *socket_name; /* ui label of the socket */
@@ -59,7 +60,7 @@ typedef struct NodeLinkItem {
/* extra settings */
bNodeTree *ngroup; /* group node tree */
-} NodeLinkItem;
+};
/* Compare an existing node to a link item to see if it can be reused.
* item must be for the same node type!
@@ -98,7 +99,7 @@ static void node_tag_recursive(bNode *node)
node->flag |= NODE_TEST;
- for (input = node->inputs.first; input; input = input->next) {
+ for (input = (bNodeSocket *)node->inputs.first; input; input = input->next) {
if (input->link) {
node_tag_recursive(input->link->fromnode);
}
@@ -115,7 +116,7 @@ static void node_clear_recursive(bNode *node)
node->flag &= ~NODE_TEST;
- for (input = node->inputs.first; input; input = input->next) {
+ for (input = (bNodeSocket *)node->inputs.first; input; input = input->next) {
if (input->link) {
node_clear_recursive(input->link->fromnode);
}
@@ -132,16 +133,16 @@ static void node_remove_linked(Main *bmain, bNodeTree *ntree, bNode *rem_node)
}
/* tag linked nodes to be removed */
- for (node = ntree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)ntree->nodes.first; node; node = node->next) {
node->flag &= ~NODE_TEST;
}
node_tag_recursive(rem_node);
/* clear tags on nodes that are still used by other nodes */
- for (node = ntree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)ntree->nodes.first; node; node = node->next) {
if (!(node->flag & NODE_TEST)) {
- for (sock = node->inputs.first; sock; sock = sock->next) {
+ for (sock = (bNodeSocket *)node->inputs.first; sock; sock = sock->next) {
if (sock->link && sock->link->fromnode != rem_node) {
node_clear_recursive(sock->link->fromnode);
}
@@ -150,7 +151,7 @@ static void node_remove_linked(Main *bmain, bNodeTree *ntree, bNode *rem_node)
}
/* remove nodes */
- for (node = ntree->nodes.first; node; node = next) {
+ for (node = (bNode *)ntree->nodes.first; node; node = next) {
next = node->next;
if (node->flag & NODE_TEST) {
@@ -205,7 +206,7 @@ static void node_socket_add_replace(const bContext *C,
Main *bmain = CTX_data_main(C);
bNode *node_from;
bNodeSocket *sock_from_tmp;
- bNode *node_prev = NULL;
+ bNode *node_prev = nullptr;
/* unlink existing node */
if (sock_to->link) {
@@ -214,7 +215,7 @@ static void node_socket_add_replace(const bContext *C,
}
/* find existing node that we can use */
- for (node_from = ntree->nodes.first; node_from; node_from = node_from->next) {
+ for (node_from = (bNode *)ntree->nodes.first; node_from; node_from = node_from->next) {
if (node_from->type == type) {
break;
}
@@ -223,7 +224,7 @@ static void node_socket_add_replace(const bContext *C,
if (node_from) {
if (node_from->inputs.first || node_from->typeinfo->draw_buttons ||
node_from->typeinfo->draw_buttons_ex) {
- node_from = NULL;
+ node_from = nullptr;
}
}
@@ -233,7 +234,7 @@ static void node_socket_add_replace(const bContext *C,
}
else if (!node_from) {
node_from = nodeAddStaticNode(C, ntree, type);
- if (node_prev != NULL) {
+ if (node_prev != nullptr) {
/* If we're replacing existing node, use its location. */
node_from->locx = node_prev->locx;
node_from->locy = node_prev->locy;
@@ -241,7 +242,7 @@ static void node_socket_add_replace(const bContext *C,
node_from->offsety = node_prev->offsety;
}
else {
- sock_from_tmp = BLI_findlink(&node_from->outputs, item->socket_index);
+ sock_from_tmp = (bNodeSocket *)BLI_findlink(&node_from->outputs, item->socket_index);
nodePositionRelative(node_from, node_to, sock_from_tmp, sock_to);
}
@@ -251,7 +252,7 @@ static void node_socket_add_replace(const bContext *C,
nodeSetActive(ntree, node_from);
/* add link */
- sock_from_tmp = BLI_findlink(&node_from->outputs, item->socket_index);
+ sock_from_tmp = (bNodeSocket *)BLI_findlink(&node_from->outputs, item->socket_index);
nodeAddLink(ntree, node_from, sock_from_tmp, node_to, sock_to);
sock_to->flag &= ~SOCK_COLLAPSED;
@@ -259,8 +260,10 @@ static void node_socket_add_replace(const bContext *C,
if (node_prev && node_from != node_prev) {
bNodeSocket *sock_prev, *sock_from;
- for (sock_prev = node_prev->inputs.first; sock_prev; sock_prev = sock_prev->next) {
- for (sock_from = node_from->inputs.first; sock_from; sock_from = sock_from->next) {
+ for (sock_prev = (bNodeSocket *)node_prev->inputs.first; sock_prev;
+ sock_prev = sock_prev->next) {
+ for (sock_from = (bNodeSocket *)node_from->inputs.first; sock_from;
+ sock_from = sock_from->next) {
if (nodeCountSocketLinks(ntree, sock_from) >= nodeSocketLinkLimit(sock_from)) {
continue;
}
@@ -282,7 +285,7 @@ static void node_socket_add_replace(const bContext *C,
if (node_from->typeinfo->nclass == NODE_CLASS_TEXTURE &&
node_prev->typeinfo->nclass == NODE_CLASS_TEXTURE &&
/* White noise texture node does not have NodeTexBase. */
- node_from->storage != NULL && node_prev->storage != NULL) {
+ node_from->storage != nullptr && node_prev->storage != nullptr) {
memcpy(node_from->storage, node_prev->storage, sizeof(NodeTexBase));
}
@@ -303,7 +306,7 @@ static void node_socket_add_replace(const bContext *C,
#define UI_NODE_LINK_DISCONNECT -1
#define UI_NODE_LINK_REMOVE -2
-typedef struct NodeLinkArg {
+struct NodeLinkArg {
Main *bmain;
Scene *scene;
bNodeTree *ntree;
@@ -314,7 +317,7 @@ typedef struct NodeLinkArg {
NodeLinkItem item;
uiLayout *layout;
-} NodeLinkArg;
+};
static void ui_node_link_items(NodeLinkArg *arg,
int in_out,
@@ -322,14 +325,15 @@ static void ui_node_link_items(NodeLinkArg *arg,
int *r_totitems)
{
/* XXX this should become a callback for node types! */
- NodeLinkItem *items = NULL;
+ NodeLinkItem *items = nullptr;
int totitems = 0;
if (arg->node_type->type == NODE_GROUP) {
bNodeTree *ngroup;
int i;
- for (ngroup = arg->bmain->nodetrees.first; ngroup; ngroup = ngroup->id.next) {
+ for (ngroup = (bNodeTree *)arg->bmain->nodetrees.first; ngroup;
+ ngroup = (bNodeTree *)ngroup->id.next) {
const char *disabled_hint;
if ((ngroup->type != arg->ntree->type) ||
!nodeGroupPoll(arg->ntree, ngroup, &disabled_hint)) {
@@ -341,10 +345,11 @@ static void ui_node_link_items(NodeLinkArg *arg,
}
if (totitems > 0) {
- items = MEM_callocN(sizeof(NodeLinkItem) * totitems, "ui node link items");
+ items = (NodeLinkItem *)MEM_callocN(sizeof(NodeLinkItem) * totitems, "ui node link items");
i = 0;
- for (ngroup = arg->bmain->nodetrees.first; ngroup; ngroup = ngroup->id.next) {
+ for (ngroup = (bNodeTree *)arg->bmain->nodetrees.first; ngroup;
+ ngroup = (bNodeTree *)ngroup->id.next) {
const char *disabled_hint;
if ((ngroup->type != arg->ntree->type) ||
!nodeGroupPoll(arg->ntree, ngroup, &disabled_hint)) {
@@ -354,11 +359,12 @@ static void ui_node_link_items(NodeLinkArg *arg,
ListBase *lb = (in_out == SOCK_IN ? &ngroup->inputs : &ngroup->outputs);
bNodeSocket *stemp;
int index;
- for (stemp = lb->first, index = 0; stemp; stemp = stemp->next, index++, i++) {
+ for (stemp = (bNodeSocket *)lb->first, index = 0; stemp;
+ stemp = stemp->next, index++, i++) {
NodeLinkItem *item = &items[i];
item->socket_index = index;
- /* note: int stemp->type is not fully reliable, not used for node group
+ /* NOTE: int stemp->type is not fully reliable, not used for node group
* interface sockets. use the typeinfo->type instead.
*/
item->socket_type = stemp->typeinfo->type;
@@ -380,7 +386,7 @@ static void ui_node_link_items(NodeLinkArg *arg,
}
if (totitems > 0) {
- items = MEM_callocN(sizeof(NodeLinkItem) * totitems, "ui node link items");
+ items = (NodeLinkItem *)MEM_callocN(sizeof(NodeLinkItem) * totitems, "ui node link items");
i = 0;
for (stemp = socket_templates; stemp && stemp->type != -1; stemp++, i++) {
@@ -474,15 +480,14 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
bNodeTree *ntree = arg->ntree;
bNodeSocket *sock = arg->sock;
uiLayout *layout = arg->layout;
- uiLayout *column = NULL;
+ uiLayout *column = nullptr;
uiBlock *block = uiLayoutGetBlock(layout);
uiBut *but;
NodeLinkArg *argN;
int first = 1;
/* generate array of node types sorted by UI name */
- bNodeType **sorted_ntypes = NULL;
- BLI_array_declare(sorted_ntypes);
+ blender::Vector<bNodeType *> sorted_ntypes;
NODE_TYPES_BEGIN (ntype) {
const char *disabled_hint;
@@ -498,20 +503,20 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
continue;
}
- BLI_array_append(sorted_ntypes, ntype);
+ sorted_ntypes.append(ntype);
}
NODE_TYPES_END;
qsort(
- sorted_ntypes, BLI_array_len(sorted_ntypes), sizeof(bNodeType *), ui_node_item_name_compare);
+ sorted_ntypes.data(), sorted_ntypes.size(), sizeof(bNodeType *), ui_node_item_name_compare);
/* generate UI */
- for (int j = 0; j < BLI_array_len(sorted_ntypes); j++) {
+ for (int j = 0; j < sorted_ntypes.size(); j++) {
bNodeType *ntype = sorted_ntypes[j];
NodeLinkItem *items;
int totitems;
char name[UI_MAX_NAME_STR];
- const char *cur_node_name = NULL;
+ const char *cur_node_name = nullptr;
int num = 0;
int icon = ICON_NONE;
@@ -531,11 +536,11 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
}
if (first) {
- column = uiLayoutColumn(layout, 0);
+ column = uiLayoutColumn(layout, false);
UI_block_layout_set_current(block, column);
uiItemL(column, IFACE_(cname), ICON_NODE);
- but = block->buttons.last;
+ but = (uiBut *)block->buttons.last;
first = 0;
}
@@ -553,7 +558,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
0,
UI_UNIT_X * 4,
UI_UNIT_Y,
- NULL,
+ nullptr,
0.0,
0.0,
0.0,
@@ -578,24 +583,22 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
0,
UI_UNIT_X * 4,
UI_UNIT_Y,
- NULL,
+ nullptr,
0.0,
0.0,
0.0,
0.0,
TIP_("Add node to input"));
- argN = MEM_dupallocN(arg);
+ argN = (NodeLinkArg *)MEM_dupallocN(arg);
argN->item = items[i];
- UI_but_funcN_set(but, ui_node_link, argN, NULL);
+ UI_but_funcN_set(but, ui_node_link, argN, nullptr);
}
if (items) {
MEM_freeN(items);
}
}
-
- BLI_array_free(sorted_ntypes);
}
static void node_menu_column_foreach_cb(void *calldata, int nclass, const char *name)
@@ -635,7 +638,7 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_
if (sock->link) {
uiItemL(column, IFACE_("Link"), ICON_NONE);
- but = block->buttons.last;
+ but = (uiBut *)block->buttons.last;
but->drawflag = UI_BUT_TEXT_LEFT;
but = uiDefBut(block,
@@ -646,7 +649,7 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_
0,
UI_UNIT_X * 4,
UI_UNIT_Y,
- NULL,
+ nullptr,
0.0,
0.0,
0.0,
@@ -662,7 +665,7 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_
0,
UI_UNIT_X * 4,
UI_UNIT_Y,
- NULL,
+ nullptr,
0.0,
0.0,
0.0,
@@ -683,7 +686,7 @@ void uiTemplateNodeLink(
uiBut *but;
float socket_col[4];
- arg = MEM_callocN(sizeof(NodeLinkArg), "NodeLinkArg");
+ arg = (NodeLinkArg *)MEM_callocN(sizeof(NodeLinkArg), "NodeLinkArg");
arg->ntree = ntree;
arg->node = node;
arg->sock = input;
@@ -698,11 +701,11 @@ void uiTemplateNodeLink(
char name[UI_MAX_NAME_STR];
ui_node_sock_name(ntree, input, name);
but = uiDefMenuBut(
- block, ui_template_node_link_menu, NULL, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, "");
+ block, ui_template_node_link_menu, nullptr, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, "");
}
else {
but = uiDefIconMenuBut(
- block, ui_template_node_link_menu, NULL, ICON_NONE, 0, 0, UI_UNIT_X, UI_UNIT_Y, "");
+ block, ui_template_node_link_menu, nullptr, ICON_NONE, 0, 0, UI_UNIT_X, UI_UNIT_Y, "");
}
UI_but_type_set_menu_from_pulldown(but);
@@ -739,7 +742,7 @@ static void ui_node_draw_node(
}
}
- for (input = node->inputs.first; input; input = input->next) {
+ for (input = (bNodeSocket *)node->inputs.first; input; input = input->next) {
ui_node_draw_input(layout, C, ntree, node, input, depth + 1);
}
}
@@ -749,7 +752,7 @@ static void ui_node_draw_input(
{
PointerRNA inputptr, nodeptr;
uiBlock *block = uiLayoutGetBlock(layout);
- uiLayout *row = NULL;
+ uiLayout *row = nullptr;
bNode *lnode;
bool dependency_loop;
@@ -759,11 +762,11 @@ static void ui_node_draw_input(
/* to avoid eternal loops on cyclic dependencies */
node->flag |= NODE_TEST;
- lnode = (input->link) ? input->link->fromnode : NULL;
+ lnode = (input->link) ? input->link->fromnode : nullptr;
dependency_loop = (lnode && (lnode->flag & NODE_TEST));
if (dependency_loop) {
- lnode = NULL;
+ lnode = nullptr;
}
/* socket RNA pointer */
@@ -862,7 +865,7 @@ static void ui_node_draw_input(
}
if (add_dummy_decorator) {
- uiItemDecoratorR(split_wrapper.decorate_column, NULL, NULL, 0);
+ uiItemDecoratorR(split_wrapper.decorate_column, nullptr, nullptr, 0);
}
/* clear */
@@ -879,7 +882,7 @@ void uiTemplateNodeView(
}
/* clear for cycle check */
- for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) {
+ for (tnode = (bNode *)ntree->nodes.first; tnode; tnode = tnode->next) {
tnode->flag &= ~NODE_TEST;
}
diff --git a/source/blender/editors/space_node/node_toolbar.c b/source/blender/editors/space_node/node_toolbar.cc
index 2e7d6ab6cd5..2e7d6ab6cd5 100644
--- a/source/blender/editors/space_node/node_toolbar.c
+++ b/source/blender/editors/space_node/node_toolbar.cc
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.cc
index 8ecab92aa26..f0db0539c4f 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.cc
@@ -76,7 +76,7 @@ int space_node_view_flag(
BLI_rctf_init_minmax(&cur_new);
if (snode->edittree) {
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
if ((node->flag & node_flag) == node_flag) {
BLI_rctf_union(&cur_new, &node->totr);
tot++;
@@ -191,16 +191,16 @@ void NODE_OT_view_selected(wmOperatorType *ot)
/** \name Background Image Operators
* \{ */
-typedef struct NodeViewMove {
+struct NodeViewMove {
int mvalo[2];
int xmin, ymin, xmax, ymax;
-} NodeViewMove;
+};
static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *region = CTX_wm_region(C);
- NodeViewMove *nvm = op->customdata;
+ NodeViewMove *nvm = (NodeViewMove *)op->customdata;
switch (event->type) {
case MOUSEMOVE:
@@ -215,8 +215,8 @@ static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, const wmEvent *e
CLAMP(snode->yof, nvm->ymin, nvm->ymax);
ED_region_tag_redraw(region);
- WM_main_add_notifier(NC_NODE | ND_DISPLAY, NULL);
- WM_main_add_notifier(NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
+ WM_main_add_notifier(NC_NODE | ND_DISPLAY, nullptr);
+ WM_main_add_notifier(NC_SPACE | ND_SPACE_NODE_VIEW, nullptr);
break;
@@ -225,7 +225,7 @@ static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, const wmEvent *e
case RIGHTMOUSE:
if (event->val == KM_RELEASE) {
MEM_freeN(nvm);
- op->customdata = NULL;
+ op->customdata = nullptr;
return OPERATOR_FINISHED;
}
break;
@@ -247,14 +247,14 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *
void *lock;
ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
- ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+ ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock);
- if (ibuf == NULL) {
+ if (ibuf == nullptr) {
BKE_image_release_ibuf(ima, ibuf, lock);
return OPERATOR_CANCELLED;
}
- nvm = MEM_callocN(sizeof(NodeViewMove), "NodeViewMove struct");
+ nvm = (NodeViewMove *)MEM_callocN(sizeof(NodeViewMove), "NodeViewMove struct");
op->customdata = nvm;
nvm->mvalo[0] = event->mval[0];
nvm->mvalo[1] = event->mval[1];
@@ -275,7 +275,7 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *
static void snode_bg_viewmove_cancel(bContext *UNUSED(C), wmOperator *op)
{
MEM_freeN(op->customdata);
- op->customdata = NULL;
+ op->customdata = nullptr;
}
void NODE_OT_backimage_move(wmOperatorType *ot)
@@ -309,8 +309,8 @@ static int backimage_zoom_exec(bContext *C, wmOperator *op)
snode->zoom *= fac;
ED_region_tag_redraw(region);
- WM_main_add_notifier(NC_NODE | ND_DISPLAY, NULL);
- WM_main_add_notifier(NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
+ WM_main_add_notifier(NC_NODE | ND_DISPLAY, nullptr);
+ WM_main_add_notifier(NC_SPACE | ND_SPACE_NODE_VIEW, nullptr);
return OPERATOR_FINISHED;
}
@@ -356,9 +356,9 @@ static int backimage_fit_exec(bContext *C, wmOperator *UNUSED(op))
float facx, facy;
ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
- ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+ ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock);
- if ((ibuf == NULL) || (ibuf->x == 0) || (ibuf->y == 0)) {
+ if ((ibuf == nullptr) || (ibuf->x == 0) || (ibuf->y == 0)) {
BKE_image_release_ibuf(ima, ibuf, lock);
return OPERATOR_CANCELLED;
}
@@ -374,8 +374,8 @@ static int backimage_fit_exec(bContext *C, wmOperator *UNUSED(op))
snode->yof = 0;
ED_region_tag_redraw(region);
- WM_main_add_notifier(NC_NODE | ND_DISPLAY, NULL);
- WM_main_add_notifier(NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
+ WM_main_add_notifier(NC_NODE | ND_DISPLAY, nullptr);
+ WM_main_add_notifier(NC_SPACE | ND_SPACE_NODE_VIEW, nullptr);
return OPERATOR_FINISHED;
}
@@ -402,7 +402,7 @@ void NODE_OT_backimage_fit(wmOperatorType *ot)
/** \name Sample Backdrop Operator
* \{ */
-typedef struct ImageSampleInfo {
+struct ImageSampleInfo {
ARegionType *art;
void *draw_handle;
int x, y;
@@ -420,12 +420,12 @@ typedef struct ImageSampleInfo {
int draw;
int color_manage;
-} ImageSampleInfo;
+};
static void sample_draw(const bContext *C, ARegion *region, void *arg_info)
{
Scene *scene = CTX_data_scene(C);
- ImageSampleInfo *info = arg_info;
+ ImageSampleInfo *info = (ImageSampleInfo *)arg_info;
if (info->draw) {
ED_image_draw_info(scene,
@@ -445,7 +445,7 @@ static void sample_draw(const bContext *C, ARegion *region, void *arg_info)
/* Returns mouse position in image space. */
bool ED_space_node_get_position(
- Main *bmain, SpaceNode *snode, struct ARegion *ar, const int mval[2], float fpos[2])
+ Main *bmain, SpaceNode *snode, struct ARegion *region, const int mval[2], float fpos[2])
{
if (!ED_node_is_compositor(snode) || (snode->flag & SNODE_BACKDRAW) == 0) {
return false;
@@ -453,7 +453,7 @@ bool ED_space_node_get_position(
void *lock;
Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock);
if (!ibuf) {
BKE_image_release_ibuf(ima, ibuf, lock);
return false;
@@ -462,8 +462,10 @@ bool ED_space_node_get_position(
/* map the mouse coords to the backdrop image space */
float bufx = ibuf->x * snode->zoom;
float bufy = ibuf->y * snode->zoom;
- fpos[0] = (bufx > 0.0f ? ((float)mval[0] - 0.5f * ar->winx - snode->xof) / bufx + 0.5f : 0.0f);
- fpos[1] = (bufy > 0.0f ? ((float)mval[1] - 0.5f * ar->winy - snode->yof) / bufy + 0.5f : 0.0f);
+ fpos[0] = (bufx > 0.0f ? ((float)mval[0] - 0.5f * region->winx - snode->xof) / bufx + 0.5f :
+ 0.0f);
+ fpos[1] = (bufy > 0.0f ? ((float)mval[1] - 0.5f * region->winy - snode->yof) / bufy + 0.5f :
+ 0.0f);
BKE_image_release_ibuf(ima, ibuf, lock);
return true;
@@ -489,7 +491,7 @@ bool ED_space_node_color_sample(
}
ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
- ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+ ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock);
if (!ibuf) {
return false;
}
@@ -532,14 +534,14 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *region = CTX_wm_region(C);
- ImageSampleInfo *info = op->customdata;
+ ImageSampleInfo *info = (ImageSampleInfo *)op->customdata;
void *lock;
Image *ima;
ImBuf *ibuf;
float fx, fy, bufx, bufy;
ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
- ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+ ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock);
if (!ibuf) {
info->draw = 0;
return;
@@ -570,8 +572,8 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
info->draw = 1;
info->channels = ibuf->channels;
- info->zp = NULL;
- info->zfp = NULL;
+ info->zp = nullptr;
+ info->zfp = nullptr;
if (ibuf->rect) {
cp = (uchar *)(ibuf->rect + y * ibuf->x + x);
@@ -616,7 +618,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
}
else {
info->draw = 0;
- ED_node_sample_set(NULL);
+ ED_node_sample_set(nullptr);
}
BKE_image_release_ibuf(ima, ibuf, lock);
@@ -626,9 +628,9 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
static void sample_exit(bContext *C, wmOperator *op)
{
- ImageSampleInfo *info = op->customdata;
+ ImageSampleInfo *info = (ImageSampleInfo *)op->customdata;
- ED_node_sample_set(NULL);
+ ED_node_sample_set(nullptr);
ED_region_draw_cb_exit(info->art, info->draw_handle);
ED_area_tag_redraw(CTX_wm_area(C));
MEM_freeN(info);
@@ -644,7 +646,7 @@ static int sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED;
}
- info = MEM_callocN(sizeof(ImageSampleInfo), "ImageSampleInfo");
+ info = (ImageSampleInfo *)MEM_callocN(sizeof(ImageSampleInfo), "ImageSampleInfo");
info->art = region->type;
info->draw_handle = ED_region_draw_cb_activate(
region->type, sample_draw, info, REGION_DRAW_POST_PIXEL);
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index f20a9409d90..ff848a7bb95 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -345,7 +345,7 @@ static void node_area_listener(const wmSpaceTypeListenerParams *params)
ScrArea *area = params->area;
wmNotifier *wmn = params->notifier;
- /* note, ED_area_tag_refresh will re-execute compositor */
+ /* NOTE: #ED_area_tag_refresh will re-execute compositor. */
SpaceNode *snode = area->spacedata.first;
/* shaderfrom is only used for new shading nodes, otherwise all shaders are from objects */
short shader_type = snode->shaderfrom;
@@ -563,7 +563,7 @@ static SpaceLink *node_duplicate(SpaceLink *sl)
BLI_listbase_clear(&snoden->runtime->linkdrag);
}
- /* Note: no need to set node tree user counts,
+ /* NOTE: no need to set node tree user counts,
* the editor only keeps at least 1 (id_us_ensure_real),
* which is already done by the original SpaceNode.
*/
@@ -651,6 +651,10 @@ static void node_main_region_init(wmWindowManager *wm, ARegion *region)
lb = WM_dropboxmap_find("Node Editor", SPACE_NODE, RGN_TYPE_WINDOW);
WM_event_add_dropbox_handler(&region->handlers, lb);
+
+ /* The backdrop image gizmo needs to change together with the view. So always refresh gizmos on
+ * region size changes. */
+ WM_gizmomap_tag_refresh(region->gizmo_map);
}
static void node_main_region_draw(const bContext *C, ARegion *region)
@@ -1094,8 +1098,6 @@ void ED_spacetype_node(void)
art->draw = node_buttons_region_draw;
BLI_addhead(&st->regiontypes, art);
- node_buttons_register(art);
-
/* regions: toolbar */
art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region");
art->regionid = RGN_TYPE_TOOLS;
diff --git a/source/blender/editors/space_outliner/outliner_context.c b/source/blender/editors/space_outliner/outliner_context.c
index 4293d8da73e..d61bb17f661 100644
--- a/source/blender/editors/space_outliner/outliner_context.c
+++ b/source/blender/editors/space_outliner/outliner_context.c
@@ -64,7 +64,7 @@ int /*eContextResult*/ outliner_context(const bContext *C,
outliner_context_selected_ids(space_outliner, result);
return CTX_RESULT_OK;
}
- /* Note: Querying non-ID selection could also work if tree elements stored their matching RNA
+ /* NOTE: Querying non-ID selection could also work if tree elements stored their matching RNA
* struct type. */
return CTX_RESULT_MEMBER_NOT_FOUND;
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index 8e19f76ea16..86aab86db10 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -818,12 +818,7 @@ static bool datastack_drop_are_types_valid(StackDropData *drop_data)
switch (drop_data->drag_tselem->type) {
case TSE_MODIFIER_BASE:
case TSE_MODIFIER:
- if (ob_parent->type == OB_GPENCIL) {
- return ob_dst->type == OB_GPENCIL;
- }
- else if (ob_parent->type != OB_GPENCIL) {
- return ob_dst->type != OB_GPENCIL;
- }
+ return (ob_parent->type == OB_GPENCIL) == (ob_dst->type == OB_GPENCIL);
break;
case TSE_CONSTRAINT_BASE:
case TSE_CONSTRAINT:
@@ -1008,7 +1003,7 @@ static void datastack_drop_reorder(bContext *C, ReportList *reports, StackDropDa
drag_te, drop_te, insert_type, &ob->greasepencil_modifiers);
ED_object_gpencil_modifier_move_to_index(reports, ob, drop_data->drag_directdata, index);
}
- else if (ob->type != OB_GPENCIL) {
+ else {
index = outliner_get_insert_index(drag_te, drop_te, insert_type, &ob->modifiers);
ED_object_modifier_move_to_index(reports, ob, drop_data->drag_directdata, index);
}
@@ -1330,7 +1325,7 @@ static TreeElement *outliner_item_drag_element_find(SpaceOutliner *space_outline
ARegion *region,
const wmEvent *event)
{
- /* note: using EVT_TWEAK_ events to trigger dragging is fine,
+ /* NOTE: using EVT_TWEAK_ events to trigger dragging is fine,
* it sends coordinates from where dragging was started */
const float my = UI_view2d_region_to_view_y(&region->v2d, event->mval[1]);
return outliner_find_item_at_y(space_outliner, &space_outliner->tree, my);
@@ -1370,7 +1365,7 @@ static int outliner_item_drag_drop_invoke(bContext *C,
wmOperatorType *ot = WM_operatortype_find("VIEW2D_OT_edge_pan", true);
PointerRNA op_ptr;
WM_operator_properties_create_ptr(&op_ptr, ot);
- RNA_int_set(&op_ptr, "outside_padding", OUTLINER_DRAG_SCOLL_OUTSIDE_PAD);
+ RNA_float_set(&op_ptr, "outside_padding", OUTLINER_DRAG_SCOLL_OUTSIDE_PAD);
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_ptr);
WM_operator_properties_free(&op_ptr);
}
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 92cd50560e4..db37c8c1c8c 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -355,7 +355,7 @@ static void outliner_base_or_object_pointer_create(
}
}
-/* Note: Collection is only valid when we want to change the collection data, otherwise we get it
+/* NOTE: Collection is only valid when we want to change the collection data, otherwise we get it
* from layer collection. Layer collection is valid whenever we are looking at a view layer. */
static void outliner_collection_set_flag_recursive(Scene *scene,
ViewLayer *view_layer,
@@ -374,7 +374,7 @@ static void outliner_collection_set_flag_recursive(Scene *scene,
/* Set the same flag for the nested objects as well. */
if (base_or_object_prop) {
- /* Note: We can't use BKE_collection_object_cache_get()
+ /* NOTE: We can't use BKE_collection_object_cache_get()
* otherwise we would not take collection exclusion into account. */
LISTBASE_FOREACH (CollectionObject *, cob, &layer_collection->collection->gobject) {
@@ -414,7 +414,7 @@ static void outliner_collection_set_flag_recursive(Scene *scene,
* A collection is isolated if all its parents and children are "visible".
* All the other collections must be "invisible".
*
- * Note: We could/should boost performance by iterating over the tree twice.
+ * NOTE: We could/should boost performance by iterating over the tree twice.
* First tagging all the children/parent collections, then getting their values and comparing.
* To run BKE_collection_has_collection() so many times is silly and slow.
*/
@@ -1090,7 +1090,8 @@ static void outliner_draw_restrictbuts(uiBlock *block,
RestrictPropertiesActive props_active = props_active_parent;
if (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && te->ys <= region->v2d.cur.ymax) {
- if (tselem->type == TSE_R_LAYER && (space_outliner->outlinevis == SO_SCENES)) {
+ if (tselem->type == TSE_R_LAYER &&
+ ELEM(space_outliner->outlinevis, SO_SCENES, SO_VIEW_LAYER)) {
if (space_outliner->show_restrict_flags & SO_RESTRICT_RENDER) {
/* View layer render toggle. */
ViewLayer *layer = te->directdata;
@@ -2106,7 +2107,7 @@ static void outliner_draw_mode_column_toggle(uiBlock *block,
tip);
UI_but_func_set(but, outliner_mode_toggle_fn, tselem, NULL);
UI_but_flag_enable(but, UI_BUT_DRAG_LOCK);
- /* Mode toggling handles it's own undo state because undo steps need to be grouped. */
+ /* Mode toggling handles its own undo state because undo steps need to be grouped. */
UI_but_flag_disable(but, UI_BUT_UNDO);
if (ID_IS_LINKED(&ob->id)) {
@@ -2355,6 +2356,9 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
case eGpencilModifierType_Texture:
data.icon = ICON_TEXTURE;
break;
+ case eGpencilModifierType_Weight:
+ data.icon = ICON_MOD_VERTEX_WEIGHT;
+ break;
/* Default */
default:
@@ -2960,7 +2964,8 @@ static void outliner_draw_iconrow(bContext *C,
te->flag &= ~(TE_ICONROW | TE_ICONROW_MERGED);
/* object hierarchy always, further constrained on level */
- if ((level < 1) || ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB))) {
+ if ((level < 1) || ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) ||
+ ELEM(tselem->type, TSE_BONE, TSE_EBONE, TSE_POSE_CHANNEL)) {
/* active blocks get white circle */
if (tselem->type == TSE_SOME_ID) {
if (te->idcode == ID_OB) {
@@ -3125,7 +3130,7 @@ static void outliner_draw_tree_element(bContext *C,
*te_edit = te;
}
- /* Icons can be ui buts, we don't want it to overlap with restrict .*/
+ /* Icons can be UI buts, we don't want it to overlap with restrict. */
if (restrict_column_width > 0) {
xmax -= restrict_column_width + UI_UNIT_X;
}
@@ -3727,7 +3732,7 @@ static void outliner_update_viewable_area(ARegion *region,
}
/* ****************************************************** */
-/* Main Entrypoint - Draw contents of Outliner editor */
+/* Main Entry-point - Draw contents of Outliner editor */
void draw_outliner(const bContext *C)
{
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 0c97fdc1c18..5be6c69363e 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -154,7 +154,9 @@ void OUTLINER_OT_highlight_update(wmOperatorType *ot)
/** \name Toggle Open/Closed Operator
* \{ */
-/* Open or close a tree element, optionally toggling all children recursively */
+/**
+ * Open or close a tree element, optionally toggling all children recursively.
+ */
void outliner_item_openclose(SpaceOutliner *space_outliner,
TreeElement *te,
bool open,
@@ -964,7 +966,7 @@ void OUTLINER_OT_lib_relocate(wmOperatorType *ot)
/* XXX This does not work with several items
* (it is only called once in the end, due to the 'deferred'
- * filebrowser invocation through event system...). */
+ * file-browser invocation through event system...). */
void lib_relocate_fn(bContext *C,
ReportList *UNUSED(reports),
Scene *UNUSED(scene),
@@ -1599,8 +1601,10 @@ void OUTLINER_OT_show_one_level(wmOperatorType *ot)
/** \name Show Hierarchy Operator
* \{ */
-/* Helper function for tree_element_shwo_hierarchy() -
- * recursively checks whether subtrees have any objects. */
+/**
+ * Helper function for #tree_element_shwo_hierarchy() -
+ * recursively checks whether subtrees have any objects.
+ */
static int subtree_has_objects(ListBase *lb)
{
LISTBASE_FOREACH (TreeElement *, te, lb) {
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index fea5ddae16b..5336376b576 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -191,7 +191,7 @@ typedef enum {
#define OL_RNA_COL_SPACEX (UI_UNIT_X * 2.5f)
/* The outliner display modes that support the filter system.
- * Note: keep it synced with space_outliner.py */
+ * NOTE: keep it synced with `space_outliner.py`. */
#define SUPPORT_FILTER_OUTLINER(space_outliner_) \
(ELEM((space_outliner_)->outlinevis, SO_VIEW_LAYER, SO_OVERRIDES_LIBRARY))
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 50f089f894a..35015356f0b 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -42,6 +42,7 @@
#include "BKE_collection.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
+#include "BKE_deform.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_modifier.h"
#include "BKE_layer.h"
@@ -450,7 +451,7 @@ static void tree_element_defgroup_activate(bContext *C, TreeElement *te, TreeSto
/* id in tselem is object */
Object *ob = (Object *)tselem->id;
BLI_assert(te->index + 1 >= 0);
- ob->actdef = te->index + 1;
+ BKE_object_defgroup_active_index_set(ob, te->index + 1);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
@@ -830,7 +831,7 @@ static eOLDrawState tree_element_defgroup_state_get(const ViewLayer *view_layer,
{
const Object *ob = (const Object *)tselem->id;
if (ob == OBACT(view_layer)) {
- if (ob->actdef == te->index + 1) {
+ if (BKE_object_defgroup_active_index_get(ob) == te->index + 1) {
return OL_DRAWSEL_NORMAL;
}
}
@@ -1654,7 +1655,7 @@ static int outliner_item_do_activate_from_cursor(bContext *C,
return OPERATOR_FINISHED;
}
-/* event can enterkey, then it opens/closes */
+/* Event can enter-key, then it opens/closes. */
static int outliner_item_activate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
const bool extend = RNA_boolean_get(op->ptr, "extend");
@@ -1816,7 +1817,7 @@ static TreeElement *outliner_find_rightmost_visible_child(SpaceOutliner *space_o
return te;
}
-/* Find previous visible element in the tree */
+/* Find previous visible element in the tree. */
static TreeElement *outliner_find_previous_element(SpaceOutliner *space_outliner, TreeElement *te)
{
if (te->prev) {
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index c532dd8accd..8a3ba9a24c2 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -86,6 +86,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "../../blender/blenloader/BLO_readfile.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -166,7 +168,7 @@ static void get_element_operation_type(
case ID_WM:
case ID_SCR:
/* Those are ignored here. */
- /* Note: while Screens should be manageable here, deleting a screen used by a workspace
+ /* NOTE: while Screens should be manageable here, deleting a screen used by a workspace
* will cause crashes when trying to use that workspace, so for now let's play minimal,
* safe change. */
break;
@@ -740,7 +742,7 @@ static void id_local_fn(bContext *C,
BKE_lib_id_clear_library_data(bmain, tselem->id);
}
else {
- BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_newptr_and_tag_clear(bmain);
}
}
else if (ID_IS_OVERRIDE_LIBRARY_REAL(tselem->id)) {
@@ -846,13 +848,13 @@ static void id_override_library_create_fn(bContext *C,
te->store_elem->id->tag |= LIB_TAG_DOIT;
}
success = BKE_lib_override_library_create(
- bmain, CTX_data_scene(C), CTX_data_view_layer(C), id_root, id_reference);
+ bmain, CTX_data_scene(C), CTX_data_view_layer(C), id_root, id_reference, NULL);
}
else if (ID_IS_OVERRIDABLE_LIBRARY(id_root)) {
success = BKE_lib_override_library_create_from_id(bmain, id_root, true) != NULL;
/* Cleanup. */
- BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_newptr_and_tag_clear(bmain);
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
}
@@ -930,8 +932,14 @@ static void id_override_library_resync_fn(bContext *C,
te->store_elem->id->tag |= LIB_TAG_DOIT;
}
- BKE_lib_override_library_resync(
- bmain, scene, CTX_data_view_layer(C), id_root, NULL, do_hierarchy_enforce, true, reports);
+ BKE_lib_override_library_resync(bmain,
+ scene,
+ CTX_data_view_layer(C),
+ id_root,
+ NULL,
+ do_hierarchy_enforce,
+ true,
+ &(struct BlendFileReadReport){.reports = reports});
WM_event_add_notifier(C, NC_WINDOW, NULL);
}
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index bed7683703f..c5ec656080a 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -1,4 +1,4 @@
-/*
+/*
* 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
@@ -62,6 +62,7 @@
#include "BLT_translation.h"
#include "BKE_armature.h"
+#include "BKE_deform.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
@@ -312,12 +313,8 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
outliner_add_element(space_outliner, &te->subtree, ob, te, TSE_ANIM_DATA, 0);
}
- outliner_add_element(space_outliner,
- &te->subtree,
- ob->poselib,
- te,
- TSE_SOME_ID,
- 0); /* XXX FIXME.. add a special type for this. */
+ /* FIXME: add a special type for this. */
+ outliner_add_element(space_outliner, &te->subtree, ob->poselib, te, TSE_SOME_ID, 0);
if (ob->proxy && !ID_IS_LINKED(ob)) {
outliner_add_element(space_outliner, &te->subtree, ob->proxy, te, TSE_PROXY, 0);
@@ -556,17 +553,20 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
}
/* vertex groups */
- if (!BLI_listbase_is_empty(&ob->defbase)) {
- TreeElement *tenla = outliner_add_element(
- space_outliner, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
- tenla->name = IFACE_("Vertex Groups");
+ if (ELEM(ob->type, OB_MESH, OB_GPENCIL, OB_LATTICE)) {
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+ if (!BLI_listbase_is_empty(defbase)) {
+ TreeElement *tenla = outliner_add_element(
+ space_outliner, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
+ tenla->name = IFACE_("Vertex Groups");
- int index;
- LISTBASE_FOREACH_INDEX (bDeformGroup *, defgroup, &ob->defbase, index) {
- TreeElement *ten = outliner_add_element(
- space_outliner, &tenla->subtree, ob, tenla, TSE_DEFGROUP, index);
- ten->name = defgroup->name;
- ten->directdata = defgroup;
+ int index;
+ LISTBASE_FOREACH_INDEX (bDeformGroup *, defgroup, defbase, index) {
+ TreeElement *ten = outliner_add_element(
+ space_outliner, &tenla->subtree, ob, tenla, TSE_DEFGROUP, index);
+ ten->name = defgroup->name;
+ ten->directdata = defgroup;
+ }
}
}
@@ -592,7 +592,7 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
switch (GS(id->name)) {
case ID_LI:
case ID_SCE:
- BLI_assert(!"ID type expected to be expanded through new tree-element design");
+ BLI_assert_msg(0, "ID type expected to be expanded through new tree-element design");
break;
case ID_OB: {
outliner_add_object_contents(space_outliner, te, tselem, (Object *)id);
@@ -905,12 +905,13 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
else if (type == TSE_SOME_ID) {
if (!te->type) {
- BLI_assert(!"Expected this ID type to be ported to new Outliner tree-element design");
+ BLI_assert_msg(0, "Expected this ID type to be ported to new Outliner tree-element design");
}
}
else if (ELEM(type, TSE_LIBRARY_OVERRIDE_BASE, TSE_LIBRARY_OVERRIDE)) {
if (!te->type) {
- BLI_assert(!"Expected override types to be ported to new Outliner tree-element design");
+ BLI_assert_msg(0,
+ "Expected override types to be ported to new Outliner tree-element design");
}
}
else {
@@ -1324,7 +1325,7 @@ static void outliner_sort(ListBase *lb)
}
TreeStoreElem *tselem = TREESTORE(te);
- /* sorting rules; only object lists, ID lists, or deformgroups */
+ /* Sorting rules; only object lists, ID lists, or deform-groups. */
if (ELEM(tselem->type, TSE_DEFGROUP, TSE_ID_BASE) ||
((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB))) {
int totelem = BLI_listbase_count(lb);
@@ -1925,5 +1926,5 @@ void outliner_build_tree(Main *mainvar,
outliner_filter_tree(space_outliner, view_layer);
outliner_restore_scrolling_position(space_outliner, region, &focus);
- BKE_main_id_clear_newpoins(mainvar);
+ BKE_main_id_newptr_and_tag_clear(mainvar);
}
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 728be1ccaaf..205f0117e6a 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -179,7 +179,7 @@ static void outliner_main_region_listener(const wmRegionListenerParams *params)
}
break;
case NC_GROUP:
- /* all actions now, todo: check outliner view mode? */
+ /* All actions now, TODO: check outliner view mode? */
ED_region_tag_redraw(region);
break;
case NC_LAMP:
@@ -331,6 +331,7 @@ static SpaceLink *outliner_create(const ScrArea *UNUSED(area), const Scene *UNUS
space_outliner->outlinevis = SO_VIEW_LAYER;
space_outliner->sync_select_dirty |= WM_OUTLINER_SYNC_SELECT_FROM_ALL;
space_outliner->flag = SO_SYNC_SELECT | SO_MODE_COLUMN;
+ space_outliner->filter = SO_FILTER_NO_VIEW_LAYERS;
/* header */
region = MEM_callocN(sizeof(ARegion), "header for outliner");
diff --git a/source/blender/editors/space_outliner/tree/tree_display.hh b/source/blender/editors/space_outliner/tree/tree_display.hh
index f089a149805..96af8258010 100644
--- a/source/blender/editors/space_outliner/tree/tree_display.hh
+++ b/source/blender/editors/space_outliner/tree/tree_display.hh
@@ -86,7 +86,7 @@ class TreeDisplayViewLayer final : public AbstractTreeDisplay {
ListBase buildTree(const TreeSourceData &source_data) override;
private:
- void add_view_layer(ListBase &, TreeElement &);
+ void add_view_layer(Scene &, ListBase &, TreeElement *);
void add_layer_collections_recursive(ListBase &, ListBase &, TreeElement &);
void add_layer_collection_objects(ListBase &, LayerCollection &, TreeElement &);
void add_layer_collection_objects_children(TreeElement &);
diff --git a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc
index 91b690d35fa..c6b700318dd 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc
@@ -138,8 +138,8 @@ TreeElement *TreeDisplayLibraries::add_library_contents(Main &mainvar,
}
}
- /* We always want to create an entry for libraries, even if/when we have no more IDs from
- * them. This invalid state is important to show to user as well.*/
+ /* We always want to create an entry for libraries, even if/when we have no more IDs from them.
+ * This invalid state is important to show to user as well. */
if (id != nullptr || is_library) {
if (!tenlib) {
/* Create library tree element on demand, depending if there are any data-blocks. */
diff --git a/source/blender/editors/space_outliner/tree/tree_display_override_library.cc b/source/blender/editors/space_outliner/tree/tree_display_override_library.cc
index 3059f8bfe0c..a17bf174a74 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_override_library.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_override_library.cc
@@ -150,27 +150,25 @@ TreeElement *TreeDisplayOverrideLibrary::add_library_contents(Main &mainvar,
}
/* Create data-block list parent element on demand. */
- if (id != nullptr) {
- TreeElement *ten;
+ TreeElement *ten;
- if (filter_id_type) {
- ten = tenlib;
- }
- else {
- ten = outliner_add_element(
- &space_outliner_, &tenlib->subtree, lbarray[a], nullptr, TSE_ID_BASE, 0);
- ten->directdata = lbarray[a];
- ten->name = outliner_idcode_to_plural(GS(id->name));
- }
+ if (filter_id_type) {
+ ten = tenlib;
+ }
+ else {
+ ten = outliner_add_element(
+ &space_outliner_, &tenlib->subtree, lbarray[a], nullptr, TSE_ID_BASE, 0);
+ ten->directdata = lbarray[a];
+ ten->name = outliner_idcode_to_plural(GS(id->name));
+ }
- for (ID *id : List<ID>(lbarray[a])) {
- if (override_library_id_filter_poll(lib, id)) {
- TreeElement *override_tree_element = outliner_add_element(
- &space_outliner_, &ten->subtree, id, ten, TSE_LIBRARY_OVERRIDE_BASE, 0);
+ for (ID *id : List<ID>(lbarray[a])) {
+ if (override_library_id_filter_poll(lib, id)) {
+ TreeElement *override_tree_element = outliner_add_element(
+ &space_outliner_, &ten->subtree, id, ten, TSE_LIBRARY_OVERRIDE_BASE, 0);
- if (BLI_listbase_is_empty(&override_tree_element->subtree)) {
- outliner_free_tree_element(override_tree_element, &ten->subtree);
- }
+ if (BLI_listbase_is_empty(&override_tree_element->subtree)) {
+ outliner_free_tree_element(override_tree_element, &ten->subtree);
}
}
}
diff --git a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
index f00cf3c34c0..c3d0aecd3cb 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
@@ -70,17 +70,42 @@ TreeDisplayViewLayer::TreeDisplayViewLayer(SpaceOutliner &space_outliner)
ListBase TreeDisplayViewLayer::buildTree(const TreeSourceData &source_data)
{
ListBase tree = {nullptr};
-
- view_layer_ = source_data.view_layer;
+ Scene *scene = source_data.scene;
show_objects_ = !(space_outliner_.filter & SO_FILTER_NO_OBJECT);
+ for (auto *view_layer : ListBaseWrapper<ViewLayer>(scene->view_layers)) {
+ view_layer_ = view_layer;
+
+ if (space_outliner_.filter & SO_FILTER_NO_VIEW_LAYERS) {
+ if (view_layer != source_data.view_layer) {
+ continue;
+ }
+
+ add_view_layer(*scene, tree, (TreeElement *)nullptr);
+ }
+ else {
+ TreeElement &te_view_layer = *outliner_add_element(
+ &space_outliner_, &tree, scene, nullptr, TSE_R_LAYER, 0);
+ TREESTORE(&te_view_layer)->flag &= ~TSE_CLOSED;
+ te_view_layer.name = view_layer->name;
+ te_view_layer.directdata = view_layer;
+
+ add_view_layer(*scene, te_view_layer.subtree, &te_view_layer);
+ }
+ }
+
+ return tree;
+}
+
+void TreeDisplayViewLayer::add_view_layer(Scene &scene, ListBase &tree, TreeElement *parent)
+{
const bool show_children = (space_outliner_.filter & SO_FILTER_NO_CHILDREN) == 0;
if (space_outliner_.filter & SO_FILTER_NO_COLLECTION) {
/* Show objects in the view layer. */
for (Base *base : List<Base>(view_layer_->object_bases)) {
TreeElement *te_object = outliner_add_element(
- &space_outliner_, &tree, base->object, nullptr, TSE_SOME_ID, 0);
+ &space_outliner_, &tree, base->object, parent, TSE_SOME_ID, 0);
te_object->directdata = base;
}
@@ -91,31 +116,24 @@ ListBase TreeDisplayViewLayer::buildTree(const TreeSourceData &source_data)
else {
/* Show collections in the view layer. */
TreeElement &ten = *outliner_add_element(
- &space_outliner_, &tree, source_data.scene, nullptr, TSE_VIEW_COLLECTION_BASE, 0);
+ &space_outliner_, &tree, &scene, parent, TSE_VIEW_COLLECTION_BASE, 0);
ten.name = IFACE_("Scene Collection");
TREESTORE(&ten)->flag &= ~TSE_CLOSED;
- add_view_layer(ten.subtree, ten);
+ /* First layer collection is for master collection, don't show it. */
+ LayerCollection *lc = static_cast<LayerCollection *>(view_layer_->layer_collections.first);
+ if (lc == nullptr) {
+ return;
+ }
+
+ add_layer_collections_recursive(ten.subtree, lc->layer_collections, ten);
+ if (show_objects_) {
+ add_layer_collection_objects(ten.subtree, *lc, ten);
+ }
if (show_children) {
add_layer_collection_objects_children(ten);
}
}
-
- return tree;
-}
-
-void TreeDisplayViewLayer::add_view_layer(ListBase &tree, TreeElement &parent)
-{
- /* First layer collection is for master collection, don't show it. */
- LayerCollection *lc = static_cast<LayerCollection *>(view_layer_->layer_collections.first);
- if (lc == nullptr) {
- return;
- }
-
- add_layer_collections_recursive(tree, lc->layer_collections, parent);
- if (show_objects_) {
- add_layer_collection_objects(tree, *lc, parent);
- }
}
void TreeDisplayViewLayer::add_layer_collections_recursive(ListBase &tree,
@@ -149,8 +167,9 @@ void TreeDisplayViewLayer::add_layer_collections_recursive(ListBase &tree,
add_layer_collection_objects(ten->subtree, *lc, *ten);
}
- const bool lib_overrides_visible = !SUPPORT_FILTER_OUTLINER(&space_outliner_) ||
- ((space_outliner_.filter & SO_FILTER_NO_LIB_OVERRIDE) == 0);
+ const bool lib_overrides_visible = !exclude && (!SUPPORT_FILTER_OUTLINER(&space_outliner_) ||
+ ((space_outliner_.filter &
+ SO_FILTER_NO_LIB_OVERRIDE) == 0));
if (lib_overrides_visible && ID_IS_OVERRIDE_LIBRARY_REAL(&lc->collection->id)) {
outliner_add_element(
diff --git a/source/blender/editors/space_outliner/tree/tree_element_id.cc b/source/blender/editors/space_outliner/tree/tree_element_id.cc
index ce99b954204..7ff5a3285f1 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_id.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element_id.cc
@@ -85,7 +85,7 @@ TreeElementID *TreeElementID::createFromID(TreeElement &legacy_te, ID &id)
return new TreeElementID(legacy_te, id);
/* Deprecated */
case ID_IP:
- BLI_assert(!"Outliner trying to build tree-element for deprecated ID type");
+ BLI_assert_msg(0, "Outliner trying to build tree-element for deprecated ID type");
return nullptr;
}
diff --git a/source/blender/editors/space_outliner/tree/tree_element_overrides.cc b/source/blender/editors/space_outliner/tree/tree_element_overrides.cc
index c5d254242c6..731beb3956e 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_overrides.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element_overrides.cc
@@ -94,9 +94,7 @@ void TreeElementOverridesBase::expand(SpaceOutliner &space_outliner) const
TreeElementOverridesProperty::TreeElementOverridesProperty(TreeElement &legacy_te,
TreeElementOverridesData &override_data)
- : AbstractTreeElement(legacy_te),
- id_(override_data.id),
- override_prop_(override_data.override_property)
+ : AbstractTreeElement(legacy_te), override_prop_(override_data.override_property)
{
BLI_assert(legacy_te.store_elem->type == TSE_LIBRARY_OVERRIDE);
diff --git a/source/blender/editors/space_outliner/tree/tree_element_overrides.hh b/source/blender/editors/space_outliner/tree/tree_element_overrides.hh
index c3caab8e268..0067db6ea56 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_overrides.hh
+++ b/source/blender/editors/space_outliner/tree/tree_element_overrides.hh
@@ -40,7 +40,6 @@ class TreeElementOverridesBase final : public AbstractTreeElement {
};
class TreeElementOverridesProperty final : public AbstractTreeElement {
- ID &id_;
IDOverrideLibraryProperty &override_prop_;
public:
diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c
index 4ce0e454df8..11bee36e914 100644
--- a/source/blender/editors/space_script/space_script.c
+++ b/source/blender/editors/space_script/space_script.c
@@ -81,7 +81,7 @@ static void script_free(SpaceLink *sl)
SpaceScript *sscript = (SpaceScript *)sl;
#ifdef WITH_PYTHON
- /*free buttons references*/
+ /* Free buttons references. */
if (sscript->but_refs) {
sscript->but_refs = NULL;
}
@@ -156,7 +156,7 @@ static void script_header_region_draw(const bContext *C, ARegion *region)
static void script_main_region_listener(const wmRegionListenerParams *UNUSED(params))
{
-/* XXX - Todo, need the ScriptSpace accessible to get the python script to run. */
+/* XXX: Todo, need the ScriptSpace accessible to get the python script to run. */
#if 0
BPY_run_script_space_listener()
#endif
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index cd75bc98b15..1239286d4da 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -158,7 +158,7 @@ static void sequencer_generic_props__internal(wmOperatorType *ot, int flag)
ot->prop = RNA_def_boolean(ot->srna,
"set_view_transform",
true,
- "Set view transform",
+ "Set View Transform",
"Set appropriate view transform based on media colorspace");
}
}
@@ -260,7 +260,7 @@ static void load_data_init_from_operator(SeqLoadData *load_data, bContext *C, wm
RNA_PROP_BEGIN (op->ptr, itemptr, prop) {
char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
BLI_strncpy(load_data->name, filename, sizeof(load_data->name));
- BLI_snprintf(load_data->path, sizeof(load_data->path), "%s%s", directory, filename);
+ BLI_join_dirfile(load_data->path, sizeof(load_data->path), directory, filename);
MEM_freeN(filename);
break;
}
@@ -1081,8 +1081,7 @@ static int sequencer_add_image_strip_invoke(bContext *C,
sequencer_disable_one_time_properties(C, op);
- const SequencerToolSettings *tool_settings = scene->toolsettings->sequencer_tool_settings;
- RNA_enum_set(op->ptr, "fit_method", tool_settings->fit_method);
+ RNA_enum_set(op->ptr, "fit_method", SEQ_tool_settings_fit_method_get(scene));
/* Name set already by drag and drop. */
if (RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) {
diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c
index 11614d94862..1e0ecfd890e 100644
--- a/source/blender/editors/space_sequencer/sequencer_buttons.c
+++ b/source/blender/editors/space_sequencer/sequencer_buttons.c
@@ -111,10 +111,10 @@ void sequencer_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel metadata");
strcpy(pt->idname, "SEQUENCER_PT_metadata");
strcpy(pt->label, N_("Metadata"));
+ strcpy(pt->category, "Metadata");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->poll = metadata_panel_context_poll;
pt->draw = metadata_panel_context_draw;
- pt->flag |= PANEL_TYPE_DEFAULT_CLOSED;
pt->order = 10;
BLI_addtail(&art->paneltypes, pt);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index b55c8035fa3..cdbe5bc63ce 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -101,7 +101,7 @@
#define SEQ_SCROLLER_TEXT_OFFSET 8
#define MUTE_ALPHA 120
-/* Note, Don't use SEQ_ALL_BEGIN/SEQ_ALL_END while drawing!
+/* NOTE: Don't use SEQ_ALL_BEGIN/SEQ_ALL_END while drawing!
* it messes up transform. */
#undef SEQ_ALL_BEGIN
#undef SEQ_ALL_END
@@ -367,8 +367,6 @@ static void draw_seq_waveform_overlay(View2D *v2d,
static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2)
{
- /* Don't use SEQ_ALL_BEGIN/SEQ_ALL_END here,
- * because it changes seq->depth, which is needed for transform. */
Sequence *seq;
uchar col[4];
@@ -455,13 +453,13 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1,
GPU_blend(GPU_BLEND_NONE);
}
-/* Get handle width in pixels. */
+/* Get handle width in 2d-View space. */
float sequence_handle_size_get_clamped(Sequence *seq, const float pixelx)
{
const float maxhandle = (pixelx * SEQ_HANDLE_SIZE) * U.pixelsize;
- /* Ensure that handle is not wider, than half of strip. */
- return min_ff(maxhandle, ((float)(seq->enddisp - seq->startdisp) / 2.0f) / pixelx);
+ /* Ensure that handle is not wider, than quarter of strip. */
+ return min_ff(maxhandle, ((float)(seq->enddisp - seq->startdisp) / 4.0f));
}
/* Draw a handle, on left or right side of strip. */
@@ -870,9 +868,9 @@ static void draw_seq_background(Scene *scene,
/* Draw the main strip body. */
if (is_single_image) {
immRectf(pos,
- SEQ_transform_get_left_handle_frame(seq, false),
+ SEQ_transform_get_left_handle_frame(seq),
y1,
- SEQ_transform_get_right_handle_frame(seq, false),
+ SEQ_transform_get_right_handle_frame(seq),
y2);
}
else {
@@ -1058,7 +1056,7 @@ static void draw_seq_fcurve_overlay(
continue;
}
- /* If some frames were skipped above, we need to close the shape. */
+ /* If some frames were skipped above, we need to close the shape. */
if (skip) {
fcurve_batch_add_verts(
vbo, y1, y2, y_height, timeline_frame - eval_step, prev_val, &vert_count);
@@ -1558,7 +1556,7 @@ static void *sequencer_OCIO_transform_ibuf(const bContext *C,
*r_format = GPU_RGB16F;
}
else {
- BLI_assert(!"Incompatible number of channels for float buffer in sequencer");
+ BLI_assert_msg(0, "Incompatible number of channels for float buffer in sequencer");
*r_format = GPU_RGBA16F;
display_buffer = NULL;
}
@@ -2365,6 +2363,31 @@ static void draw_cache_view(const bContext *C)
}
/* Draw sequencer timeline. */
+static void draw_overlap_frame_indicator(const struct Scene *scene, const View2D *v2d)
+{
+ int overlap_frame = (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) ?
+ scene->ed->over_cfra :
+ scene->r.cfra + scene->ed->over_ofs;
+
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+ /* Shader may have color set from past usage - reset it. */
+ immUniform1i("colors_len", 0);
+ immUniform1f("dash_width", 20.0f * U.pixelsize);
+ immUniform1f("dash_factor", 0.5f);
+ immUniformThemeColor(TH_CFRAME);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, overlap_frame, v2d->cur.ymin);
+ immVertex2f(pos, overlap_frame, v2d->cur.ymax);
+ immEnd();
+
+ immUnbindProgram();
+}
+
void draw_timeline_seq(const bContext *C, ARegion *region)
{
Scene *scene = CTX_data_scene(C);
@@ -2424,31 +2447,6 @@ void draw_timeline_seq(const bContext *C, ARegion *region)
cfra_flag |= DRAWCFRA_UNIT_SECONDS;
}
- /* Draw overlap frame frame indicator. */
- if (scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) {
- int overlap_frame = (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) ?
- scene->ed->over_cfra :
- scene->r.cfra + scene->ed->over_ofs;
-
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
- /* Shader may have color set from past usage - reset it. */
- immUniform1i("colors_len", 0);
- immUniform1f("dash_width", 20.0f * U.pixelsize);
- immUniform1f("dash_factor", 0.5f);
- immUniformThemeColor(TH_CFRAME);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, overlap_frame, v2d->cur.ymin);
- immVertex2f(pos, overlap_frame, v2d->cur.ymax);
- immEnd();
-
- immUnbindProgram();
- }
-
UI_view2d_view_orthoSpecial(region, v2d, 1);
int marker_draw_flag = DRAW_MARKERS_MARGIN;
if (sseq->flag & SEQ_SHOW_MARKERS) {
@@ -2456,11 +2454,6 @@ void draw_timeline_seq(const bContext *C, ARegion *region)
}
UI_view2d_view_ortho(v2d);
-
- if (ed) {
- draw_cache_view(C);
- }
-
ANIM_draw_previewrange(C, v2d, 1);
/* Draw registered callbacks. */
@@ -2486,6 +2479,15 @@ void draw_timeline_seq_display(const bContext *C, ARegion *region)
const SpaceSeq *sseq = CTX_wm_space_seq(C);
View2D *v2d = &region->v2d;
+ if (scene->ed != NULL) {
+ UI_view2d_view_ortho(v2d);
+ draw_cache_view(C);
+ if (scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) {
+ draw_overlap_frame_indicator(scene, v2d);
+ }
+ UI_view2d_view_restore(C);
+ }
+
ED_time_scrub_draw_current_frame(region, scene, !(sseq->flag & SEQ_DRAWFRAMES), true);
UI_view2d_scrollers_draw(v2d, NULL);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 1a1ba5a0754..75cf8542f67 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -34,6 +34,7 @@
#include "BLT_translation.h"
+#include "DNA_anim_types.h"
#include "DNA_scene_types.h"
#include "DNA_sound_types.h"
@@ -138,6 +139,48 @@ bool ED_space_sequencer_check_show_strip(SpaceSeq *sseq)
ELEM(sseq->mainb, SEQ_DRAW_SEQUENCE, SEQ_DRAW_IMG_IMBUF));
}
+static bool sequencer_fcurves_targets_color_strip(const FCurve *fcurve)
+{
+ if (!BLI_str_startswith(fcurve->rna_path, "sequence_editor.sequences_all[\"")) {
+ return false;
+ }
+
+ if (!BLI_str_endswith(fcurve->rna_path, "\"].color")) {
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Check if there is animation shown during playback.
+ *
+ * - Colors of color strips are displayed on the strip itself.
+ * - Backdrop is drawn.
+ */
+bool ED_space_sequencer_has_playback_animation(const struct SpaceSeq *sseq,
+ const struct Scene *scene)
+{
+ if (sseq->draw_flag & SEQ_DRAW_BACKDROP) {
+ return true;
+ }
+
+ if (!scene->adt) {
+ return false;
+ }
+ if (!scene->adt->action) {
+ return false;
+ }
+
+ LISTBASE_FOREACH (FCurve *, fcurve, &scene->adt->action->curves) {
+ if (sequencer_fcurves_targets_color_strip(fcurve)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -292,7 +335,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
/* Check meta-strips. */
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK) &&
+ if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK) &&
SEQ_transform_sequence_can_be_translated(seq)) {
if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) {
SEQ_transform_translate_sequence(
@@ -314,7 +357,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
/* Test for effects and overlap. */
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK)) {
+ if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) {
seq->flag &= ~SEQ_OVERLAP;
if (SEQ_transform_test_overlap(ed->seqbasep, seq)) {
SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene);
@@ -348,7 +391,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
}
}
- SEQ_sort(scene);
+ SEQ_sort(SEQ_active_seqbase_get(ed));
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -557,7 +600,7 @@ static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset)
seq->endofs = endframe - seq->enddisp;
changed = true;
}
- else if (endframe <= seq->enddisp) {
+ else {
seq->endstill = seq->enddisp - endframe;
seq->endofs = 0;
changed = true;
@@ -568,7 +611,7 @@ static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset)
seq->startofs = 0;
changed = true;
}
- else if (seq->start <= seq->startdisp) {
+ else {
seq->startstill = 0;
seq->startofs = seq->startdisp - seq->start;
changed = true;
@@ -1443,7 +1486,7 @@ static int sequencer_split_exec(bContext *C, wmOperator *op)
}
}
- SEQ_sort(scene);
+ SEQ_sort(SEQ_active_seqbase_get(ed));
}
if (changed) {
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -1577,38 +1620,35 @@ void SEQUENCER_OT_split(struct wmOperatorType *ot)
/** \name Duplicate Strips Operator
* \{ */
-static int apply_unique_name_fn(Sequence *seq, void *arg_pt)
-{
- Scene *scene = (Scene *)arg_pt;
- char name[sizeof(seq->name) - 2];
-
- BLI_strncpy_utf8(name, seq->name + 2, sizeof(name));
- SEQ_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
- SEQ_dupe_animdata(scene, name, seq->name + 2);
- return 1;
-}
-
static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
Editing *ed = SEQ_editing_get(scene, false);
- ListBase nseqbase = {NULL, NULL};
-
if (ed == NULL) {
return OPERATOR_CANCELLED;
}
- SEQ_sequence_base_dupli_recursive(scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT, 0);
+ Sequence *active_seq = SEQ_select_active_get(scene);
+ ListBase duplicated = {NULL, NULL};
- if (nseqbase.first) {
- Sequence *seq = nseqbase.first;
+ SEQ_sequence_base_dupli_recursive(scene, scene, &duplicated, ed->seqbasep, 0, 0);
+ ED_sequencer_deselect_all(scene);
+
+ if (duplicated.first) {
+ Sequence *seq = duplicated.first;
/* Rely on the nseqbase list being added at the end.
* Their UUIDs has been re-generated by the SEQ_sequence_base_dupli_recursive(), */
- BLI_movelisttolist(ed->seqbasep, &nseqbase);
+ BLI_movelisttolist(ed->seqbasep, &duplicated);
+ /* Handle duplicated strips: set active, select, ensure unique name and duplicate animation
+ * data. */
for (; seq; seq = seq->next) {
- SEQ_recursive_apply(seq, apply_unique_name_fn, scene);
+ if (active_seq != NULL && STREQ(seq->name, active_seq->name)) {
+ SEQ_select_active_set(scene, seq);
+ }
+ seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK);
+ SEQ_ensure_unique_name(seq, scene);
}
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -1776,11 +1816,11 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
/* Remove seq so overlap tests don't conflict,
* see seq_free_sequence below for the real freeing. */
BLI_remlink(ed->seqbasep, seq);
- /* if (seq->ipo) id_us_min(&seq->ipo->id); */
- /* XXX, remove fcurve and assign to split image strips */
+ /* TODO: remove f-curve and assign to split image strips.
+ * The old animation system would remove the user of `seq->ipo`. */
- start_ofs = timeline_frame = SEQ_transform_get_left_handle_frame(seq, false);
- frame_end = SEQ_transform_get_right_handle_frame(seq, false);
+ start_ofs = timeline_frame = SEQ_transform_get_left_handle_frame(seq);
+ frame_end = SEQ_transform_get_right_handle_frame(seq);
while (timeline_frame < frame_end) {
/* New seq. */
@@ -1829,7 +1869,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
}
}
- SEQ_sort(scene);
+ SEQ_sort(SEQ_active_seqbase_get(ed));
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -1943,7 +1983,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
seqm->machine = active_seq ? active_seq->machine : channel_max;
strcpy(seqm->name + 2, "MetaStrip");
- SEQ_sequence_base_unique_name_recursive(&ed->seqbase, seqm);
+ SEQ_sequence_base_unique_name_recursive(scene, &ed->seqbase, seqm);
seqm->start = meta_start_frame;
seqm->len = meta_end_frame - meta_start_frame;
SEQ_time_update_sequence(scene, seqm);
@@ -2014,7 +2054,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- SEQ_sort(scene);
+ SEQ_sort(active_seqbase);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -2147,7 +2187,7 @@ static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, i
seq = ed->seqbasep->first;
while (seq) {
- if ((seq != test) && (test->machine == seq->machine) && (test->depth == seq->depth) &&
+ if ((seq != test) && (test->machine == seq->machine) &&
((sel == -1) || (sel == (seq->flag & SELECT)))) {
dist = MAXFRAME * 2;
@@ -2218,7 +2258,7 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op)
break;
}
- /* XXX - Should be a generic function. */
+ /* XXX: Should be a generic function. */
for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) {
if ((iseq->type & SEQ_TYPE_EFFECT) &&
(seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) {
@@ -2237,7 +2277,7 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op)
}
}
- SEQ_sort(scene);
+ SEQ_sort(SEQ_active_seqbase_get(ed));
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -2374,6 +2414,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op)
(LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_FREE_NO_MAIN));
seqbase_clipboard_frame = scene->r.cfra;
+ SEQ_clipboard_active_seq_name_store(scene);
/* Remove anything that references the current scene. */
LISTBASE_FOREACH (Sequence *, seq, &seqbase_clipboard) {
@@ -2446,7 +2487,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
min_seq_startdisp = seq->startdisp;
}
}
- /* Paste strips after playhead. */
+ /* Paste strips relative to the current-frame. */
ofs = scene->r.cfra - min_seq_startdisp;
}
@@ -2464,8 +2505,12 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
BLI_movelisttolist(ed->seqbasep, &nseqbase);
for (iseq = iseq_first; iseq; iseq = iseq->next) {
+ if (SEQ_clipboard_pasted_seq_was_active(iseq)) {
+ SEQ_select_active_set(scene, iseq);
+ }
+
/* Make sure, that pasted strips have unique names. */
- SEQ_recursive_apply(iseq, apply_unique_name_fn, scene);
+ SEQ_ensure_unique_name(iseq, scene);
/* Translate after name has been changed, otherwise this will affect animdata of original
* strip. */
SEQ_transform_translate_sequence(scene, iseq, ofs);
@@ -2499,7 +2544,11 @@ void SEQUENCER_OT_paste(wmOperatorType *ot)
/* Properties. */
PropertyRNA *prop = RNA_def_boolean(
- ot->srna, "keep_offset", false, "Keep Offset", "Keep strip offset to playhead when pasting");
+ ot->srna,
+ "keep_offset",
+ false,
+ "Keep Offset",
+ "Keep strip offset relative to the current frame when pasting");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@@ -2760,9 +2809,9 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "directory", directory);
if (is_relative_path) {
- /* TODO, shouldn't this already be relative from the filesel?
+ /* TODO(campbell): shouldn't this already be relative from the filesel?
* (as the 'filepath' is) for now just make relative here,
- * but look into changing after 2.60 - campbell */
+ * but look into changing after 2.60. */
BLI_path_rel(directory, BKE_main_blendfile_path(bmain));
}
BLI_strncpy(seq->strip->dir, directory, sizeof(seq->strip->dir));
@@ -2785,7 +2834,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op)
RNA_END;
}
- /* Reset these else we wont see all the images. */
+ /* Reset these else we won't see all the images. */
seq->anim_startofs = seq->anim_endofs = 0;
/* Correct start/end frames so we don't move.
@@ -2940,8 +2989,10 @@ static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ /* Only text strips that are not muted and don't end with negative frame. */
SEQ_ALL_BEGIN (ed, seq) {
- if (seq->type == SEQ_TYPE_TEXT) {
+ if ((seq->type == SEQ_TYPE_TEXT) && ((seq->flag & SEQ_MUTE) == 0) &&
+ (seq->enddisp > scene->r.sfra)) {
BLI_addtail(&text_seq, MEM_dupallocN(seq));
}
}
@@ -2962,16 +3013,17 @@ static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op)
char timecode_str_start[32];
char timecode_str_end[32];
+ /* Write time-code relative to start frame of scene. Don't allow negative time-codes. */
BLI_timecode_string_from_time(timecode_str_start,
sizeof(timecode_str_start),
-2,
- FRA2TIME(seq->startdisp),
+ FRA2TIME(max_ii(seq->startdisp - scene->r.sfra, 0)),
FPS,
USER_TIMECODE_SUBRIP);
BLI_timecode_string_from_time(timecode_str_end,
sizeof(timecode_str_end),
-2,
- FRA2TIME(seq->enddisp),
+ FRA2TIME(seq->enddisp - scene->r.sfra),
FPS,
USER_TIMECODE_SUBRIP);
@@ -3064,7 +3116,7 @@ static int sequencer_set_range_to_strips_exec(bContext *C, wmOperator *op)
scene->r.efra = efra;
}
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME_RANGE, scene);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_sequencer/sequencer_proxy.c b/source/blender/editors/space_sequencer/sequencer_proxy.c
index df84772aa8c..2dcc2d389d9 100644
--- a/source/blender/editors/space_sequencer/sequencer_proxy.c
+++ b/source/blender/editors/space_sequencer/sequencer_proxy.c
@@ -99,7 +99,7 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports)
return;
}
- if (selected && !WM_jobs_is_running(wm_job)) {
+ if (!WM_jobs_is_running(wm_job)) {
G.is_break = false;
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_scopes.c b/source/blender/editors/space_sequencer/sequencer_scopes.c
index 16768e09cb8..5d857f62b47 100644
--- a/source/blender/editors/space_sequencer/sequencer_scopes.c
+++ b/source/blender/editors/space_sequencer/sequencer_scopes.c
@@ -32,8 +32,8 @@
#include "sequencer_intern.h"
-/* XXX, why is this function better than BLI_math version?
- * only difference is it does some normalize after, need to double check on this - campbell */
+/* XXX(campbell): why is this function better than BLI_math version?
+ * only difference is it does some normalize after, need to double check on this. */
static void rgb_to_yuv_normalized(const float rgb[3], float yuv[3])
{
yuv[0] = 0.299f * rgb[0] + 0.587f * rgb[1] + 0.114f * rgb[2];
@@ -624,8 +624,6 @@ static void vectorscope_put_cross(uchar r, uchar g, uchar b, char *tgt, int w, i
{
float rgb[3], yuv[3];
char *p;
- int x = 0;
- int y = 0;
rgb[0] = (float)r / 255.0f;
rgb[1] = (float)g / 255.0f;
@@ -638,8 +636,8 @@ static void vectorscope_put_cross(uchar r, uchar g, uchar b, char *tgt, int w, i
r = 255;
}
- for (y = -size; y <= size; y++) {
- for (x = -size; x <= size; x++) {
+ for (int y = -size; y <= size; y++) {
+ for (int x = -size; x <= size; x++) {
char *q = p + 4 * (y * w + x);
q[0] = r;
q[1] = g;
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index e08af8f0977..5980bfe37cd 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -42,6 +42,7 @@
#include "SEQ_iterator.h"
#include "SEQ_select.h"
#include "SEQ_sequencer.h"
+#include "SEQ_time.h"
#include "SEQ_transform.h"
/* For menu, popup, icons, etc. */
@@ -533,7 +534,7 @@ static int sequencer_select_exec(bContext *C, wmOperator *op)
seq = find_nearest_seq(scene, v2d, &hand, mval);
- /* XXX - not nice, Ctrl+RMB needs to do side_of_frame only when not over a strip */
+ /* XXX: not nice, Ctrl+RMB needs to do side_of_frame only when not over a strip. */
if (seq && linked_time) {
side_of_frame = false;
}
@@ -807,7 +808,7 @@ static bool select_linked_internal(Scene *scene)
bool changed = false;
LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
- if ((seq->flag & SELECT) != 0) {
+ if ((seq->flag & SELECT) == 0) {
continue;
}
/* Only get unselected neighbors. */
@@ -1186,8 +1187,8 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op)
case 1:
test = (timeline_frame <= seq->startdisp);
break;
- case 0:
- test = (timeline_frame <= seq->enddisp) && (timeline_frame >= seq->startdisp);
+ case 2:
+ test = SEQ_time_strip_intersects_frame(seq, timeline_frame);
break;
}
@@ -1209,6 +1210,7 @@ void SEQUENCER_OT_select_side_of_frame(wmOperatorType *ot)
static const EnumPropertyItem sequencer_select_left_right_types[] = {
{-1, "LEFT", 0, "Left", "Select to the left of the current frame"},
{1, "RIGHT", 0, "Right", "Select to the right of the current frame"},
+ {2, "CURRENT", 0, "Current Frame", "Select intersecting with the current frame"},
{0, NULL, 0, NULL, NULL},
};
@@ -1621,37 +1623,6 @@ static bool select_grouped_time_overlap(Editing *ed, Sequence *actseq)
return changed;
}
-/* Query all effect strips that are directly or indirectly connected to seq_reference. */
-static void query_strip_effect_chain(Sequence *seq_reference,
- ListBase *seqbase,
- SeqCollection *collection)
-{
- if (!SEQ_collection_append_strip(seq_reference, collection)) {
- return; /* Strip is already in set, so all effects connected to it are as well. */
- }
-
- /* Find all strips that seq_reference is connected to. */
- if (seq_reference->type & SEQ_TYPE_EFFECT) {
- if (seq_reference->seq1) {
- query_strip_effect_chain(seq_reference->seq1, seqbase, collection);
- }
- if (seq_reference->seq2) {
- query_strip_effect_chain(seq_reference->seq2, seqbase, collection);
- }
- if (seq_reference->seq3) {
- query_strip_effect_chain(seq_reference->seq3, seqbase, collection);
- }
- }
-
- /* Find all strips connected to seq_reference. */
- LISTBASE_FOREACH (Sequence *, seq_test, seqbase) {
- if (seq_test->seq1 == seq_reference || seq_test->seq2 == seq_reference ||
- seq_test->seq3 == seq_reference) {
- query_strip_effect_chain(seq_test, seqbase, collection);
- }
- }
-}
-
/* Query strips that are in lower channel and intersect in time with seq_reference. */
static void query_lower_channel_strips(Sequence *seq_reference,
ListBase *seqbase,
@@ -1681,7 +1652,7 @@ static bool select_grouped_effect_link(Editing *ed,
SeqCollection *collection = SEQ_query_selected_strips(seqbase);
const int selected_strip_count = BLI_gset_len(collection->set);
SEQ_collection_expand(seqbase, collection, query_lower_channel_strips);
- SEQ_collection_expand(seqbase, collection, query_strip_effect_chain);
+ SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain);
/* Check if other strips will be affected. */
const bool changed = BLI_gset_len(collection->set) > selected_strip_count;
diff --git a/source/blender/editors/space_spreadsheet/CMakeLists.txt b/source/blender/editors/space_spreadsheet/CMakeLists.txt
index b2a0905d4a2..e903feeec1b 100644
--- a/source/blender/editors/space_spreadsheet/CMakeLists.txt
+++ b/source/blender/editors/space_spreadsheet/CMakeLists.txt
@@ -20,12 +20,14 @@ set(INC
../../blenfont
../../blenkernel
../../blenlib
+ ../../blentranslation
../../bmesh
../../depsgraph
../../functions
../../gpu
../../makesdna
../../makesrna
+ ../../nodes
../../windowmanager
../../../../intern/glew-mx
../../../../intern/guardedalloc
@@ -33,23 +35,31 @@ set(INC
set(SRC
space_spreadsheet.cc
- spreadsheet_context.cc
spreadsheet_column.cc
+ spreadsheet_context.cc
spreadsheet_data_source.cc
spreadsheet_data_source_geometry.cc
+ spreadsheet_dataset_draw.cc
+ spreadsheet_dataset_layout.cc
spreadsheet_draw.cc
spreadsheet_layout.cc
spreadsheet_ops.cc
+ spreadsheet_row_filter.cc
+ spreadsheet_row_filter_ui.cc
- spreadsheet_context.hh
spreadsheet_cell_value.hh
spreadsheet_column.hh
spreadsheet_column_values.hh
+ spreadsheet_context.hh
spreadsheet_data_source.hh
spreadsheet_data_source_geometry.hh
+ spreadsheet_dataset_draw.hh
+ spreadsheet_dataset_layout.hh
spreadsheet_draw.hh
spreadsheet_intern.hh
spreadsheet_layout.hh
+ spreadsheet_row_filter.hh
+ spreadsheet_row_filter_ui.hh
)
set(LIB
diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
index 1f0b5d5d13e..fcc92345bea 100644
--- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
+++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
@@ -47,8 +47,11 @@
#include "spreadsheet_context.hh"
#include "spreadsheet_data_source_geometry.hh"
+#include "spreadsheet_dataset_draw.hh"
#include "spreadsheet_intern.hh"
#include "spreadsheet_layout.hh"
+#include "spreadsheet_row_filter.hh"
+#include "spreadsheet_row_filter_ui.hh"
using namespace blender;
using namespace blender::ed::spreadsheet;
@@ -59,6 +62,8 @@ static SpaceLink *spreadsheet_create(const ScrArea *UNUSED(area), const Scene *U
"spreadsheet space");
spreadsheet_space->spacetype = SPACE_SPREADSHEET;
+ spreadsheet_space->filter_flag = SPREADSHEET_FILTER_ENABLE;
+
{
/* Header. */
ARegion *region = (ARegion *)MEM_callocN(sizeof(ARegion), "spreadsheet header");
@@ -76,6 +81,24 @@ static SpaceLink *spreadsheet_create(const ScrArea *UNUSED(area), const Scene *U
}
{
+ /* Dataset Region */
+ ARegion *region = (ARegion *)MEM_callocN(sizeof(ARegion), "spreadsheet dataset region");
+ BLI_addtail(&spreadsheet_space->regionbase, region);
+ region->regiontype = RGN_TYPE_CHANNELS;
+ region->alignment = RGN_ALIGN_LEFT;
+ region->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
+ }
+
+ {
+ /* Properties region. */
+ ARegion *region = (ARegion *)MEM_callocN(sizeof(ARegion), "spreadsheet right region");
+ BLI_addtail(&spreadsheet_space->regionbase, region);
+ region->regiontype = RGN_TYPE_UI;
+ region->alignment = RGN_ALIGN_RIGHT;
+ region->flag = RGN_FLAG_HIDDEN;
+ }
+
+ {
/* Main window. */
ARegion *region = (ARegion *)MEM_callocN(sizeof(ARegion), "spreadsheet main region");
BLI_addtail(&spreadsheet_space->regionbase, region);
@@ -88,8 +111,12 @@ static SpaceLink *spreadsheet_create(const ScrArea *UNUSED(area), const Scene *U
static void spreadsheet_free(SpaceLink *sl)
{
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
+
MEM_SAFE_FREE(sspreadsheet->runtime);
+ LISTBASE_FOREACH_MUTABLE (SpreadsheetRowFilter *, row_filter, &sspreadsheet->row_filters) {
+ spreadsheet_row_filter_free(row_filter);
+ }
LISTBASE_FOREACH_MUTABLE (SpreadsheetColumn *, column, &sspreadsheet->columns) {
spreadsheet_column_free(column);
}
@@ -113,6 +140,11 @@ static SpaceLink *spreadsheet_duplicate(SpaceLink *sl)
SpaceSpreadsheet *sspreadsheet_new = (SpaceSpreadsheet *)MEM_dupallocN(sspreadsheet_old);
sspreadsheet_new->runtime = (SpaceSpreadsheet_Runtime *)MEM_dupallocN(sspreadsheet_old->runtime);
+ BLI_listbase_clear(&sspreadsheet_new->row_filters);
+ LISTBASE_FOREACH (const SpreadsheetRowFilter *, src_filter, &sspreadsheet_old->row_filters) {
+ SpreadsheetRowFilter *new_filter = spreadsheet_row_filter_copy(src_filter);
+ BLI_addtail(&sspreadsheet_new->row_filters, new_filter);
+ }
BLI_listbase_clear(&sspreadsheet_new->columns);
LISTBASE_FOREACH (SpreadsheetColumn *, src_column, &sspreadsheet_old->columns) {
SpreadsheetColumn *new_column = spreadsheet_column_copy(src_column);
@@ -128,8 +160,10 @@ static SpaceLink *spreadsheet_duplicate(SpaceLink *sl)
return (SpaceLink *)sspreadsheet_new;
}
-static void spreadsheet_keymap(wmKeyConfig *UNUSED(keyconf))
+static void spreadsheet_keymap(wmKeyConfig *keyconf)
{
+ /* Entire editor only. */
+ WM_keymap_ensure(keyconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0);
}
static void spreadsheet_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id)
@@ -160,11 +194,18 @@ static void spreadsheet_main_region_init(wmWindowManager *wm, ARegion *region)
UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_LIST, region->winx, region->winy);
- wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "View2D Buttons List", 0, 0);
- WM_event_add_keymap_handler(&region->handlers, keymap);
+ {
+ wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "View2D Buttons List", 0, 0);
+ WM_event_add_keymap_handler(&region->handlers, keymap);
+ }
+ {
+ wmKeyMap *keymap = WM_keymap_ensure(
+ wm->defaultconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0);
+ WM_event_add_keymap_handler(&region->handlers, keymap);
+ }
}
-ID *ED_spreadsheet_get_current_id(struct SpaceSpreadsheet *sspreadsheet)
+ID *ED_spreadsheet_get_current_id(const struct SpaceSpreadsheet *sspreadsheet)
{
if (BLI_listbase_is_empty(&sspreadsheet->context_path)) {
return nullptr;
@@ -181,24 +222,11 @@ ID *ED_spreadsheet_get_current_id(struct SpaceSpreadsheet *sspreadsheet)
static void update_pinned_context_path_if_outdated(const bContext *C)
{
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
-
- /* Currently, this only checks if the object has been deleted. In the future we can have a more
- * sophisticated check for the entire context (including modifier and nodes). */
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- if (context->type == SPREADSHEET_CONTEXT_OBJECT) {
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context;
- if (object_context->object == nullptr) {
- ED_spreadsheet_context_path_clear(sspreadsheet);
- break;
- }
- }
- }
- if (BLI_listbase_is_empty(&sspreadsheet->context_path)) {
- Object *active_object = CTX_data_active_object(C);
- if (active_object != nullptr) {
- SpreadsheetContext *new_context = spreadsheet_context_new(SPREADSHEET_CONTEXT_OBJECT);
- ((SpreadsheetContextObject *)new_context)->object = active_object;
- BLI_addtail(&sspreadsheet->context_path, new_context);
+ Main *bmain = CTX_data_main(C);
+ if (!ED_spreadsheet_context_path_exists(bmain, sspreadsheet)) {
+ ED_spreadsheet_context_path_guess(C, sspreadsheet);
+ if (ED_spreadsheet_context_path_update_tag(sspreadsheet)) {
+ ED_area_tag_redraw(CTX_wm_area(C));
}
}
@@ -211,28 +239,15 @@ static void update_pinned_context_path_if_outdated(const bContext *C)
static void update_context_path_from_context(const bContext *C)
{
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
- Object *active_object = CTX_data_active_object(C);
- if (active_object == nullptr) {
- ED_spreadsheet_context_path_clear(sspreadsheet);
- return;
- }
- if (!BLI_listbase_is_empty(&sspreadsheet->context_path)) {
- SpreadsheetContext *root_context = (SpreadsheetContext *)sspreadsheet->context_path.first;
- if (root_context->type == SPREADSHEET_CONTEXT_OBJECT) {
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)root_context;
- if (object_context->object != active_object) {
- ED_spreadsheet_context_path_clear(sspreadsheet);
- }
+ if (!ED_spreadsheet_context_path_is_active(C, sspreadsheet)) {
+ ED_spreadsheet_context_path_guess(C, sspreadsheet);
+ if (ED_spreadsheet_context_path_update_tag(sspreadsheet)) {
+ ED_area_tag_redraw(CTX_wm_area(C));
}
}
- if (BLI_listbase_is_empty(&sspreadsheet->context_path)) {
- SpreadsheetContext *new_context = spreadsheet_context_new(SPREADSHEET_CONTEXT_OBJECT);
- ((SpreadsheetContextObject *)new_context)->object = active_object;
- BLI_addtail(&sspreadsheet->context_path, new_context);
- }
}
-static void update_context_path(const bContext *C)
+void spreadsheet_update_context_path(const bContext *C)
{
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
if (sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) {
@@ -243,28 +258,40 @@ static void update_context_path(const bContext *C)
}
}
-static std::unique_ptr<DataSource> get_data_source(const bContext *C)
+Object *spreadsheet_get_object_eval(const SpaceSpreadsheet *sspreadsheet,
+ const Depsgraph *depsgraph)
{
- Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
- SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
ID *used_id = ED_spreadsheet_get_current_id(sspreadsheet);
if (used_id == nullptr) {
- return {};
+ return nullptr;
}
const ID_Type id_type = GS(used_id->name);
if (id_type != ID_OB) {
- return {};
+ return nullptr;
}
Object *object_orig = (Object *)used_id;
if (!ELEM(object_orig->type, OB_MESH, OB_POINTCLOUD, OB_VOLUME)) {
- return {};
+ return nullptr;
}
+
Object *object_eval = DEG_get_evaluated_object(depsgraph, object_orig);
if (object_eval == nullptr) {
- return {};
+ return nullptr;
}
- return data_source_from_geometry(C, object_eval);
+ return object_eval;
+}
+
+static std::unique_ptr<DataSource> get_data_source(const bContext *C)
+{
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
+
+ Object *object_eval = spreadsheet_get_object_eval(sspreadsheet, depsgraph);
+ if (object_eval) {
+ return data_source_from_geometry(C, object_eval);
+ }
+ return {};
}
static float get_column_width(const ColumnValues &values)
@@ -327,7 +354,7 @@ static void update_visible_columns(ListBase &columns, DataSource &data_source)
static void spreadsheet_main_region_draw(const bContext *C, ARegion *region)
{
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
- update_context_path(C);
+ spreadsheet_update_context_path(C);
std::unique_ptr<DataSource> data_source = get_data_source(C);
if (!data_source) {
@@ -346,24 +373,14 @@ static void spreadsheet_main_region_draw(const bContext *C, ARegion *region)
const ColumnValues *values = scope.add(std::move(values_ptr), __func__);
const int width = get_column_width_in_pixels(*values);
spreadsheet_layout.columns.append({values, width});
+
+ spreadsheet_column_assign_runtime_data(column, values->type(), values->name());
}
const int tot_rows = data_source->tot_rows();
spreadsheet_layout.index_column_width = get_index_column_width(tot_rows);
- spreadsheet_layout.row_indices = IndexRange(tot_rows).as_span();
-
- if (const GeometryDataSource *geometry_data_source = dynamic_cast<const GeometryDataSource *>(
- data_source.get())) {
- Object *object_eval = geometry_data_source->object_eval();
- Object *object_orig = DEG_get_original_object(object_eval);
- if (object_orig->type == OB_MESH) {
- if (object_orig->mode == OB_MODE_EDIT) {
- if (sspreadsheet->filter_flag & SPREADSHEET_FILTER_SELECTED_ONLY) {
- spreadsheet_layout.row_indices = geometry_data_source->get_selected_element_indices();
- }
- }
- }
- }
+ spreadsheet_layout.row_indices = spreadsheet_filter_rows(
+ *sspreadsheet, spreadsheet_layout, *data_source, scope);
sspreadsheet->runtime->tot_columns = spreadsheet_layout.columns.size();
sspreadsheet->runtime->tot_rows = tot_rows;
@@ -372,9 +389,11 @@ static void spreadsheet_main_region_draw(const bContext *C, ARegion *region)
std::unique_ptr<SpreadsheetDrawer> drawer = spreadsheet_drawer_from_layout(spreadsheet_layout);
draw_spreadsheet_in_region(C, region, *drawer);
- /* Tag footer for redraw, because the main region updates data for the footer. */
+ /* Tag other regions for redraw, because the main region updates data for them. */
ARegion *footer = BKE_area_find_region_type(CTX_wm_area(C), RGN_TYPE_FOOTER);
ED_region_tag_redraw(footer);
+ ARegion *sidebar = BKE_area_find_region_type(CTX_wm_area(C), RGN_TYPE_UI);
+ ED_region_tag_redraw(sidebar);
}
static void spreadsheet_main_region_listener(const wmRegionListenerParams *params)
@@ -419,7 +438,7 @@ static void spreadsheet_header_region_init(wmWindowManager *UNUSED(wm), ARegion
static void spreadsheet_header_region_draw(const bContext *C, ARegion *region)
{
- update_context_path(C);
+ spreadsheet_update_context_path(C);
ED_region_header(C, region);
}
@@ -511,6 +530,77 @@ static void spreadsheet_footer_region_listener(const wmRegionListenerParams *UNU
{
}
+static void spreadsheet_dataset_region_listener(const wmRegionListenerParams *params)
+{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
+ switch (wmn->category) {
+ case NC_SCENE: {
+ switch (wmn->data) {
+ case ND_FRAME:
+ ED_region_tag_redraw(region);
+ break;
+ }
+ break;
+ }
+ case NC_TEXTURE:
+ ED_region_tag_redraw(region);
+ break;
+ }
+
+ spreadsheet_header_region_listener(params);
+}
+
+static void spreadsheet_dataset_region_init(wmWindowManager *wm, ARegion *region)
+{
+ region->v2d.scroll |= V2D_SCROLL_RIGHT;
+ region->v2d.scroll &= ~(V2D_SCROLL_LEFT | V2D_SCROLL_TOP | V2D_SCROLL_BOTTOM);
+ region->v2d.scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
+ region->v2d.scroll |= V2D_SCROLL_VERTICAL_HIDE;
+
+ UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_LIST, region->winx, region->winy);
+
+ wmKeyMap *keymap = WM_keymap_ensure(
+ wm->defaultconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0);
+ WM_event_add_keymap_handler(&region->handlers, keymap);
+}
+
+static void spreadsheet_dataset_region_draw(const bContext *C, ARegion *region)
+{
+ spreadsheet_update_context_path(C);
+
+ View2D *v2d = &region->v2d;
+ UI_view2d_view_ortho(v2d);
+ UI_ThemeClearColor(TH_BACK);
+
+ draw_dataset_in_region(C, region);
+
+ /* reset view matrix */
+ UI_view2d_view_restore(C);
+
+ /* scrollers */
+ UI_view2d_scrollers_draw(v2d, nullptr);
+}
+
+static void spreadsheet_sidebar_init(wmWindowManager *wm, ARegion *region)
+{
+ UI_panel_category_active_set_default(region, "Filters");
+ ED_region_panels_init(wm, region);
+
+ wmKeyMap *keymap = WM_keymap_ensure(
+ wm->defaultconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0);
+ WM_event_add_keymap_handler(&region->handlers, keymap);
+}
+
+static void spreadsheet_right_region_free(ARegion *UNUSED(region))
+{
+}
+
+static void spreadsheet_right_region_listener(const wmRegionListenerParams *UNUSED(params))
+{
+}
+
void ED_spacetype_spreadsheet(void)
{
SpaceType *st = (SpaceType *)MEM_callocN(sizeof(SpaceType), "spacetype spreadsheet");
@@ -563,5 +653,30 @@ void ED_spacetype_spreadsheet(void)
art->listener = spreadsheet_footer_region_listener;
BLI_addhead(&st->regiontypes, art);
+ /* regions: right panel buttons */
+ art = (ARegionType *)MEM_callocN(sizeof(ARegionType), "spacetype spreadsheet right region");
+ art->regionid = RGN_TYPE_UI;
+ art->prefsizex = UI_SIDEBAR_PANEL_WIDTH;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
+
+ art->init = spreadsheet_sidebar_init;
+ art->layout = ED_region_panels_layout;
+ art->draw = ED_region_panels_draw;
+ art->free = spreadsheet_right_region_free;
+ art->listener = spreadsheet_right_region_listener;
+ BLI_addhead(&st->regiontypes, art);
+
+ register_row_filter_panels(*art);
+
+ /* regions: channels */
+ art = (ARegionType *)MEM_callocN(sizeof(ARegionType), "spreadsheet dataset region");
+ art->regionid = RGN_TYPE_CHANNELS;
+ art->prefsizex = 200 + V2D_SCROLL_WIDTH;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D;
+ art->init = spreadsheet_dataset_region_init;
+ art->draw = spreadsheet_dataset_region_draw;
+ art->listener = spreadsheet_dataset_region_listener;
+ BLI_addhead(&st->regiontypes, art);
+
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh b/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh
index d1e80f1d87e..c9b73aabf96 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh
@@ -50,7 +50,7 @@ class CellValue {
std::optional<bool> value_bool;
std::optional<float2> value_float2;
std::optional<float3> value_float3;
- std::optional<Color4f> value_color;
+ std::optional<ColorGeometry4f> value_color;
std::optional<ObjectCellValue> value_object;
std::optional<CollectionCellValue> value_collection;
};
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column.cc b/source/blender/editors/space_spreadsheet/spreadsheet_column.cc
index de40545fdae..ee08c86b29f 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_column.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_column.cc
@@ -56,16 +56,29 @@ SpreadsheetColumn *spreadsheet_column_new(SpreadsheetColumnID *column_id)
return column;
}
+void spreadsheet_column_assign_runtime_data(SpreadsheetColumn *column,
+ const eSpreadsheetColumnValueType data_type,
+ const StringRefNull display_name)
+{
+ column->data_type = data_type;
+ MEM_SAFE_FREE(column->display_name);
+ column->display_name = BLI_strdup(display_name.c_str());
+}
+
SpreadsheetColumn *spreadsheet_column_copy(const SpreadsheetColumn *src_column)
{
SpreadsheetColumnID *new_column_id = spreadsheet_column_id_copy(src_column->id);
SpreadsheetColumn *new_column = spreadsheet_column_new(new_column_id);
+ if (src_column->display_name != nullptr) {
+ new_column->display_name = BLI_strdup(src_column->display_name);
+ }
return new_column;
}
void spreadsheet_column_free(SpreadsheetColumn *column)
{
spreadsheet_column_id_free(column->id);
+ MEM_SAFE_FREE(column->display_name);
MEM_freeN(column);
}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column.hh b/source/blender/editors/space_spreadsheet/spreadsheet_column.hh
index bb245851d55..1a03278acad 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_column.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_column.hh
@@ -43,6 +43,9 @@ void spreadsheet_column_id_free(SpreadsheetColumnID *column_id);
SpreadsheetColumn *spreadsheet_column_new(SpreadsheetColumnID *column_id);
SpreadsheetColumn *spreadsheet_column_copy(const SpreadsheetColumn *src_column);
+void spreadsheet_column_assign_runtime_data(SpreadsheetColumn *column,
+ const eSpreadsheetColumnValueType data_type,
+ const StringRefNull display_name);
void spreadsheet_column_free(SpreadsheetColumn *column);
} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column_values.hh b/source/blender/editors/space_spreadsheet/spreadsheet_column_values.hh
index 373c988a41c..68370cf6a44 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_column_values.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_column_values.hh
@@ -16,6 +16,8 @@
#pragma once
+#include "DNA_space_types.h"
+
#include "BLI_string_ref.hh"
#include "spreadsheet_cell_value.hh"
@@ -28,11 +30,13 @@ namespace blender::ed::spreadsheet {
*/
class ColumnValues {
protected:
+ eSpreadsheetColumnValueType type_;
std::string name_;
int size_;
public:
- ColumnValues(std::string name, const int size) : name_(std::move(name)), size_(size)
+ ColumnValues(const eSpreadsheetColumnValueType type, std::string name, const int size)
+ : type_(type), name_(std::move(name)), size_(size)
{
}
@@ -40,6 +44,11 @@ class ColumnValues {
virtual void get_value(int index, CellValue &r_cell_value) const = 0;
+ eSpreadsheetColumnValueType type() const
+ {
+ return type_;
+ }
+
StringRefNull name() const
{
return name_;
@@ -60,8 +69,11 @@ template<typename GetValueF> class LambdaColumnValues : public ColumnValues {
GetValueF get_value_;
public:
- LambdaColumnValues(std::string name, int size, GetValueF get_value)
- : ColumnValues(std::move(name), size), get_value_(std::move(get_value))
+ LambdaColumnValues(const eSpreadsheetColumnValueType type,
+ std::string name,
+ int size,
+ GetValueF get_value)
+ : ColumnValues(type, std::move(name), size), get_value_(std::move(get_value))
{
}
@@ -73,13 +85,14 @@ template<typename GetValueF> class LambdaColumnValues : public ColumnValues {
/* Utility function that simplifies creating a spreadsheet column from a lambda function. */
template<typename GetValueF>
-std::unique_ptr<ColumnValues> column_values_from_function(std::string name,
+std::unique_ptr<ColumnValues> column_values_from_function(const eSpreadsheetColumnValueType type,
+ std::string name,
const int size,
GetValueF get_value,
const float default_width = 0.0f)
{
std::unique_ptr<ColumnValues> column_values = std::make_unique<LambdaColumnValues<GetValueF>>(
- std::move(name), size, std::move(get_value));
+ type, std::move(name), size, std::move(get_value));
column_values->default_width = default_width;
return column_values;
}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_context.cc b/source/blender/editors/space_spreadsheet/spreadsheet_context.cc
index 3eb43338908..1ac2075e281 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_context.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_context.cc
@@ -24,16 +24,28 @@
#include "BLI_utildefines.h"
#include "BLI_vector.hh"
+#include "ED_screen.h"
#include "ED_spreadsheet.h"
#include "DEG_depsgraph.h"
+#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
+#include "BKE_node.h"
#include "BKE_object.h"
+#include "BKE_workspace.h"
+
+#include "DNA_modifier_types.h"
+#include "DNA_windowmanager_types.h"
#include "spreadsheet_context.hh"
+using blender::IndexRange;
+using blender::Span;
+using blender::StringRef;
+using blender::Vector;
+
namespace blender::ed::spreadsheet {
static SpreadsheetContextObject *spreadsheet_context_object_new()
@@ -206,28 +218,30 @@ void spreadsheet_context_free(SpreadsheetContext *context)
/**
* Tag any data relevant to the spreadsheet's context for recalculation in order to collect
* information to display in the editor, which may be cached during evaluation.
+ * \return True when any data has been tagged for update.
*/
-static void spreadsheet_context_update_tag(SpaceSpreadsheet *sspreadsheet)
+static bool spreadsheet_context_update_tag(SpaceSpreadsheet *sspreadsheet)
{
using namespace blender;
Vector<const SpreadsheetContext *> context_path = sspreadsheet->context_path;
if (context_path.is_empty()) {
- return;
+ return false;
}
if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) {
- return;
+ return false;
}
SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context_path[0];
Object *object = object_context->object;
if (object == nullptr) {
- return;
+ return false;
}
if (context_path.size() == 1) {
/* No need to reevaluate, when the final or original object is viewed. */
- return;
+ return false;
}
DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY);
+ return true;
}
} // namespace blender::ed::spreadsheet
@@ -250,30 +264,47 @@ void ED_spreadsheet_context_path_clear(struct SpaceSpreadsheet *sspreadsheet)
BLI_listbase_clear(&sspreadsheet->context_path);
}
-void ED_spreadsheet_context_path_update_tag(SpaceSpreadsheet *sspreadsheet)
+bool ED_spreadsheet_context_path_update_tag(SpaceSpreadsheet *sspreadsheet)
{
- blender::ed::spreadsheet::spreadsheet_context_update_tag(sspreadsheet);
+ return blender::ed::spreadsheet::spreadsheet_context_update_tag(sspreadsheet);
}
-uint64_t ED_spreadsheet_context_path_hash(SpaceSpreadsheet *sspreadsheet)
+uint64_t ED_spreadsheet_context_path_hash(const SpaceSpreadsheet *sspreadsheet)
{
BLI_HashMurmur2A mm2;
BLI_hash_mm2a_init(&mm2, 1234);
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
+ LISTBASE_FOREACH (const SpreadsheetContext *, context, &sspreadsheet->context_path) {
blender::ed::spreadsheet::spreadsheet_context_hash(context, &mm2);
}
return BLI_hash_mm2a_end(&mm2);
}
-void ED_spreadsheet_set_geometry_node_context(struct SpaceSpreadsheet *sspreadsheet,
- struct SpaceNode *snode,
- struct bNode *node)
+void ED_spreadsheet_context_path_set_geometry_node(struct SpaceSpreadsheet *sspreadsheet,
+ struct SpaceNode *snode,
+ struct bNode *node)
{
using namespace blender::ed::spreadsheet;
- ED_spreadsheet_context_path_clear(sspreadsheet);
Object *object = (Object *)snode->id;
+ /* Try to find the modifier the node tree belongs to. */
ModifierData *modifier = BKE_object_active_modifier(object);
+ if (modifier && modifier->type != eModifierType_Nodes) {
+ modifier = nullptr;
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+ if (md->type == eModifierType_Nodes) {
+ NodesModifierData *nmd = (NodesModifierData *)md;
+ if (nmd->node_group == snode->nodetree) {
+ modifier = md;
+ break;
+ }
+ }
+ }
+ }
+ if (modifier == nullptr) {
+ return;
+ }
+
+ ED_spreadsheet_context_path_clear(sspreadsheet);
{
SpreadsheetContextObject *context = spreadsheet_context_object_new();
@@ -302,5 +333,251 @@ void ED_spreadsheet_set_geometry_node_context(struct SpaceSpreadsheet *sspreadsh
BLI_addtail(&sspreadsheet->context_path, context);
}
- sspreadsheet->object_eval_state = SPREADSHEET_OBJECT_EVAL_STATE_EVALUATED;
+ sspreadsheet->object_eval_state = SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE;
+}
+
+void ED_spreadsheet_context_paths_set_geometry_node(Main *bmain, SpaceNode *snode, bNode *node)
+{
+ wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
+ if (wm == nullptr) {
+ return;
+ }
+ LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
+ bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ SpaceLink *sl = (SpaceLink *)area->spacedata.first;
+ if (sl->spacetype == SPACE_SPREADSHEET) {
+ SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
+ if ((sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) == 0) {
+ const uint64_t context_hash_before = ED_spreadsheet_context_path_hash(sspreadsheet);
+ ED_spreadsheet_context_path_set_geometry_node(sspreadsheet, snode, node);
+ const uint64_t context_hash_after = ED_spreadsheet_context_path_hash(sspreadsheet);
+ if (context_hash_before != context_hash_after) {
+ ED_spreadsheet_context_path_update_tag(sspreadsheet);
+ }
+ ED_area_tag_redraw(area);
+ }
+ }
+ }
+ }
+}
+
+void ED_spreadsheet_context_path_set_evaluated_object(SpaceSpreadsheet *sspreadsheet,
+ Object *object)
+{
+ using namespace blender::ed::spreadsheet;
+ ED_spreadsheet_context_path_clear(sspreadsheet);
+
+ SpreadsheetContextObject *context = spreadsheet_context_object_new();
+ context->object = object;
+ BLI_addtail(&sspreadsheet->context_path, context);
+}
+
+void ED_spreadsheet_context_path_guess(const bContext *C, SpaceSpreadsheet *sspreadsheet)
+{
+ ED_spreadsheet_context_path_clear(sspreadsheet);
+
+ Main *bmain = CTX_data_main(C);
+ wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
+ if (wm == nullptr) {
+ return;
+ }
+
+ if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
+ LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
+ bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ SpaceLink *sl = (SpaceLink *)area->spacedata.first;
+ if (sl->spacetype == SPACE_NODE) {
+ SpaceNode *snode = (SpaceNode *)sl;
+ if (snode->edittree != nullptr) {
+ if (snode->edittree->type == NTREE_GEOMETRY) {
+ LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
+ if (node->type == GEO_NODE_VIEWER) {
+ if (node->flag & NODE_DO_OUTPUT) {
+ ED_spreadsheet_context_path_set_geometry_node(sspreadsheet, snode, node);
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Object *active_object = CTX_data_active_object(C);
+ if (active_object != nullptr) {
+ ED_spreadsheet_context_path_set_evaluated_object(sspreadsheet, active_object);
+ return;
+ }
+}
+
+bool ED_spreadsheet_context_path_is_active(const bContext *C, SpaceSpreadsheet *sspreadsheet)
+{
+ Main *bmain = CTX_data_main(C);
+ wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
+ if (wm == nullptr) {
+ return false;
+ }
+ Vector<SpreadsheetContext *> context_path = sspreadsheet->context_path;
+ if (context_path.is_empty()) {
+ return false;
+ }
+ if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) {
+ return false;
+ }
+ Object *object = ((SpreadsheetContextObject *)context_path[0])->object;
+ if (object == nullptr) {
+ return false;
+ }
+ if (context_path.size() == 1) {
+ if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
+ return false;
+ }
+ Object *active_object = CTX_data_active_object(C);
+ return object == active_object;
+ }
+ if (sspreadsheet->object_eval_state != SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
+ return false;
+ }
+ if (context_path[1]->type != SPREADSHEET_CONTEXT_MODIFIER) {
+ return false;
+ }
+ const char *modifier_name = ((SpreadsheetContextModifier *)context_path[1])->modifier_name;
+ const ModifierData *modifier = BKE_modifiers_findby_name(object, modifier_name);
+ if (modifier == nullptr) {
+ return false;
+ }
+ if (!(modifier->flag & eModifierFlag_Active)) {
+ return false;
+ }
+ if (modifier->type != eModifierType_Nodes) {
+ return false;
+ }
+ bNodeTree *root_node_tree = ((NodesModifierData *)modifier)->node_group;
+ if (root_node_tree == nullptr) {
+ return false;
+ }
+ const Span<SpreadsheetContext *> node_context_path = context_path.as_span().drop_front(2);
+ if (node_context_path.is_empty()) {
+ return false;
+ }
+
+ LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
+ bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ SpaceLink *sl = (SpaceLink *)area->spacedata.first;
+ if (sl->spacetype != SPACE_NODE) {
+ continue;
+ }
+ SpaceNode *snode = (SpaceNode *)sl;
+ if (snode->nodetree != root_node_tree) {
+ continue;
+ }
+ if (snode->id != &object->id) {
+ continue;
+ }
+ Vector<bNodeTreePath *> tree_path = snode->treepath;
+ if (node_context_path.size() != tree_path.size()) {
+ continue;
+ }
+ int valid_count = 0;
+ for (const int i : IndexRange(tree_path.size() - 1)) {
+ if (node_context_path[i]->type != SPREADSHEET_CONTEXT_NODE) {
+ break;
+ }
+ SpreadsheetContextNode *node_context = (SpreadsheetContextNode *)node_context_path[i];
+ if (!STREQ(node_context->node_name, tree_path[i]->node_name)) {
+ break;
+ }
+ valid_count++;
+ }
+ if (valid_count != tree_path.size() - 1) {
+ continue;
+ }
+ SpreadsheetContext *last_context = node_context_path.last();
+ if (last_context->type != SPREADSHEET_CONTEXT_NODE) {
+ return false;
+ }
+ const char *node_name = ((SpreadsheetContextNode *)last_context)->node_name;
+ bNode *node = nodeFindNodebyName(snode->edittree, node_name);
+ if (node == nullptr) {
+ return false;
+ }
+ if (node->type != GEO_NODE_VIEWER) {
+ return false;
+ }
+ if (!(node->flag & NODE_DO_OUTPUT)) {
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ED_spreadsheet_context_path_exists(Main *UNUSED(bmain), SpaceSpreadsheet *sspreadsheet)
+{
+ Vector<SpreadsheetContext *> context_path = sspreadsheet->context_path;
+ if (context_path.is_empty()) {
+ return false;
+ }
+ if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) {
+ return false;
+ }
+ Object *object = ((SpreadsheetContextObject *)context_path[0])->object;
+ if (object == nullptr) {
+ return false;
+ }
+ if (context_path.size() == 1) {
+ return true;
+ }
+ if (context_path[1]->type != SPREADSHEET_CONTEXT_MODIFIER) {
+ return false;
+ }
+ const char *modifier_name = ((SpreadsheetContextModifier *)context_path[1])->modifier_name;
+ const ModifierData *modifier = BKE_modifiers_findby_name(object, modifier_name);
+ if (modifier == nullptr) {
+ return false;
+ }
+ if (modifier->type != eModifierType_Nodes) {
+ return false;
+ }
+ bNodeTree *root_node_tree = ((NodesModifierData *)modifier)->node_group;
+ if (root_node_tree == nullptr) {
+ return false;
+ }
+ const Span<SpreadsheetContext *> node_context_path = context_path.as_span().drop_front(2);
+ if (node_context_path.is_empty()) {
+ return false;
+ }
+ bNodeTree *node_tree = root_node_tree;
+ for (const int i : node_context_path.index_range()) {
+ if (node_context_path[i]->type != SPREADSHEET_CONTEXT_NODE) {
+ return false;
+ }
+ const char *node_name = ((SpreadsheetContextNode *)node_context_path[i])->node_name;
+ bNode *node = nodeFindNodebyName(node_tree, node_name);
+ if (node == nullptr) {
+ return false;
+ }
+ if (node->type == GEO_NODE_VIEWER) {
+ if (i == node_context_path.index_range().last()) {
+ return true;
+ }
+ return false;
+ }
+ if (node->id != nullptr) {
+ if (GS(node->id->name) != ID_NT) {
+ return false;
+ }
+ node_tree = (bNodeTree *)node->id;
+ }
+ else {
+ return false;
+ }
+ }
+ return false;
}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source.hh b/source/blender/editors/space_spreadsheet/spreadsheet_data_source.hh
index de47109a144..2ea7fb5809f 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source.hh
@@ -54,6 +54,15 @@ class DataSource {
}
/**
+ * Returns true if the data source has the ability to limit visible rows
+ * by user interface selection status.
+ */
+ virtual bool has_selection_filter() const
+ {
+ return false;
+ }
+
+ /**
* Returns the number of rows in columns returned by #get_column_values.
*/
virtual int tot_rows() const
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
index 02ffa1259fc..e38c70afd0f 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
@@ -31,11 +31,15 @@
#include "ED_spreadsheet.h"
+#include "NOD_geometry_nodes_eval_log.hh"
+
#include "bmesh.h"
#include "spreadsheet_data_source_geometry.hh"
#include "spreadsheet_intern.hh"
+namespace geo_log = blender::nodes::geometry_nodes_eval_log;
+
namespace blender::ed::spreadsheet {
void GeometryDataSource::foreach_default_column_ids(
@@ -69,28 +73,35 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
const CustomDataType type = bke::cpp_type_to_custom_data_type(varray->type());
switch (type) {
case CD_PROP_FLOAT:
- return column_values_from_function(
- column_id.name, domain_size, [varray](int index, CellValue &r_cell_value) {
- float value;
- varray->get(index, &value);
- r_cell_value.value_float = value;
- });
+ return column_values_from_function(SPREADSHEET_VALUE_TYPE_FLOAT,
+ column_id.name,
+ domain_size,
+ [varray](int index, CellValue &r_cell_value) {
+ float value;
+ varray->get(index, &value);
+ r_cell_value.value_float = value;
+ });
case CD_PROP_INT32:
- return column_values_from_function(
- column_id.name, domain_size, [varray](int index, CellValue &r_cell_value) {
- int value;
- varray->get(index, &value);
- r_cell_value.value_int = value;
- });
+ return column_values_from_function(SPREADSHEET_VALUE_TYPE_INT32,
+ column_id.name,
+ domain_size,
+ [varray](int index, CellValue &r_cell_value) {
+ int value;
+ varray->get(index, &value);
+ r_cell_value.value_int = value;
+ });
case CD_PROP_BOOL:
- return column_values_from_function(
- column_id.name, domain_size, [varray](int index, CellValue &r_cell_value) {
- bool value;
- varray->get(index, &value);
- r_cell_value.value_bool = value;
- });
+ return column_values_from_function(SPREADSHEET_VALUE_TYPE_BOOL,
+ column_id.name,
+ domain_size,
+ [varray](int index, CellValue &r_cell_value) {
+ bool value;
+ varray->get(index, &value);
+ r_cell_value.value_bool = value;
+ });
case CD_PROP_FLOAT2: {
return column_values_from_function(
+ SPREADSHEET_VALUE_TYPE_FLOAT2,
column_id.name,
domain_size,
[varray](int index, CellValue &r_cell_value) {
@@ -102,6 +113,7 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
}
case CD_PROP_FLOAT3: {
return column_values_from_function(
+ SPREADSHEET_VALUE_TYPE_FLOAT3,
column_id.name,
domain_size,
[varray](int index, CellValue &r_cell_value) {
@@ -113,10 +125,11 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
}
case CD_PROP_COLOR: {
return column_values_from_function(
+ SPREADSHEET_VALUE_TYPE_COLOR,
column_id.name,
domain_size,
[varray](int index, CellValue &r_cell_value) {
- Color4f value;
+ ColorGeometry4f value;
varray->get(index, &value);
r_cell_value.value_color = value;
},
@@ -137,55 +150,63 @@ using IsVertexSelectedFn = FunctionRef<bool(int vertex_index)>;
static void get_selected_vertex_indices(const Mesh &mesh,
const IsVertexSelectedFn is_vertex_selected_fn,
- Vector<int64_t> &r_vertex_indices)
+ MutableSpan<bool> selection)
{
for (const int i : IndexRange(mesh.totvert)) {
- if (is_vertex_selected_fn(i)) {
- r_vertex_indices.append(i);
+ if (!selection[i]) {
+ continue;
+ }
+ if (!is_vertex_selected_fn(i)) {
+ selection[i] = false;
}
}
}
static void get_selected_corner_indices(const Mesh &mesh,
const IsVertexSelectedFn is_vertex_selected_fn,
- Vector<int64_t> &r_corner_indices)
+ MutableSpan<bool> selection)
{
for (const int i : IndexRange(mesh.totloop)) {
const MLoop &loop = mesh.mloop[i];
- if (is_vertex_selected_fn(loop.v)) {
- r_corner_indices.append(i);
+ if (!selection[i]) {
+ continue;
+ }
+ if (!is_vertex_selected_fn(loop.v)) {
+ selection[i] = false;
}
}
}
static void get_selected_face_indices(const Mesh &mesh,
const IsVertexSelectedFn is_vertex_selected_fn,
- Vector<int64_t> &r_face_indices)
+ MutableSpan<bool> selection)
{
for (const int poly_index : IndexRange(mesh.totpoly)) {
+ if (!selection[poly_index]) {
+ continue;
+ }
const MPoly &poly = mesh.mpoly[poly_index];
- bool is_selected = true;
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = mesh.mloop[loop_index];
if (!is_vertex_selected_fn(loop.v)) {
- is_selected = false;
+ selection[poly_index] = false;
break;
}
}
- if (is_selected) {
- r_face_indices.append(poly_index);
- }
}
}
static void get_selected_edge_indices(const Mesh &mesh,
const IsVertexSelectedFn is_vertex_selected_fn,
- Vector<int64_t> &r_edge_indices)
+ MutableSpan<bool> selection)
{
for (const int i : IndexRange(mesh.totedge)) {
+ if (!selection[i]) {
+ continue;
+ }
const MEdge &edge = mesh.medge[i];
- if (is_vertex_selected_fn(edge.v1) && is_vertex_selected_fn(edge.v2)) {
- r_edge_indices.append(i);
+ if (!is_vertex_selected_fn(edge.v1) || !is_vertex_selected_fn(edge.v2)) {
+ selection[i] = false;
}
}
}
@@ -193,30 +214,48 @@ static void get_selected_edge_indices(const Mesh &mesh,
static void get_selected_indices_on_domain(const Mesh &mesh,
const AttributeDomain domain,
const IsVertexSelectedFn is_vertex_selected_fn,
- Vector<int64_t> &r_indices)
+ MutableSpan<bool> selection)
{
switch (domain) {
case ATTR_DOMAIN_POINT:
- return get_selected_vertex_indices(mesh, is_vertex_selected_fn, r_indices);
+ return get_selected_vertex_indices(mesh, is_vertex_selected_fn, selection);
case ATTR_DOMAIN_FACE:
- return get_selected_face_indices(mesh, is_vertex_selected_fn, r_indices);
+ return get_selected_face_indices(mesh, is_vertex_selected_fn, selection);
case ATTR_DOMAIN_CORNER:
- return get_selected_corner_indices(mesh, is_vertex_selected_fn, r_indices);
+ return get_selected_corner_indices(mesh, is_vertex_selected_fn, selection);
case ATTR_DOMAIN_EDGE:
- return get_selected_edge_indices(mesh, is_vertex_selected_fn, r_indices);
+ return get_selected_edge_indices(mesh, is_vertex_selected_fn, selection);
default:
return;
}
}
-Span<int64_t> GeometryDataSource::get_selected_element_indices() const
+/**
+ * Only data sets corresponding to mesh objects in edit mode currently support selection filtering.
+ */
+bool GeometryDataSource::has_selection_filter() const
+{
+ Object *object_orig = DEG_get_original_object(object_eval_);
+ if (object_orig->type != OB_MESH) {
+ return false;
+ }
+ if (object_orig->mode != OB_MODE_EDIT) {
+ return false;
+ }
+ if (component_->type() != GEO_COMPONENT_TYPE_MESH) {
+ return false;
+ }
+
+ return true;
+}
+
+void GeometryDataSource::apply_selection_filter(MutableSpan<bool> rows_included) const
{
std::lock_guard lock{mutex_};
BLI_assert(object_eval_->mode == OB_MODE_EDIT);
BLI_assert(component_->type() == GEO_COMPONENT_TYPE_MESH);
Object *object_orig = DEG_get_original_object(object_eval_);
- Vector<int64_t> &indices = scope_.construct<Vector<int64_t>>(__func__);
const MeshComponent *mesh_component = static_cast<const MeshComponent *>(component_);
const Mesh *mesh_eval = mesh_component->get_for_read();
Mesh *mesh_orig = (Mesh *)object_orig->data;
@@ -237,7 +276,7 @@ Span<int64_t> GeometryDataSource::get_selected_element_indices() const
BMVert *vert = bm->vtable[i_orig];
return BM_elem_flag_test(vert, BM_ELEM_SELECT);
};
- get_selected_indices_on_domain(*mesh_eval, domain_, is_vertex_selected, indices);
+ get_selected_indices_on_domain(*mesh_eval, domain_, is_vertex_selected, rows_included);
}
else if (mesh_eval->totvert == bm->totvert) {
/* Use a simple heuristic to match original vertices to evaluated ones. */
@@ -245,10 +284,8 @@ Span<int64_t> GeometryDataSource::get_selected_element_indices() const
BMVert *vert = bm->vtable[vertex_index];
return BM_elem_flag_test(vert, BM_ELEM_SELECT);
};
- get_selected_indices_on_domain(*mesh_eval, domain_, is_vertex_selected, indices);
+ get_selected_indices_on_domain(*mesh_eval, domain_, is_vertex_selected, rows_included);
}
-
- return indices;
}
void InstancesDataSource::foreach_default_column_ids(
@@ -279,7 +316,10 @@ std::unique_ptr<ColumnValues> InstancesDataSource::get_column_values(
Span<int> reference_handles = component_->instance_reference_handles();
Span<InstanceReference> references = component_->references();
std::unique_ptr<ColumnValues> values = column_values_from_function(
- "Name", size, [reference_handles, references](int index, CellValue &r_cell_value) {
+ SPREADSHEET_VALUE_TYPE_INSTANCES,
+ "Name",
+ size,
+ [reference_handles, references](int index, CellValue &r_cell_value) {
const InstanceReference &reference = references[reference_handles[index]];
switch (reference.type()) {
case InstanceReference::Type::Object: {
@@ -303,6 +343,7 @@ std::unique_ptr<ColumnValues> InstancesDataSource::get_column_values(
Span<float4x4> transforms = component_->instance_transforms();
if (STREQ(column_id.name, "Position")) {
return column_values_from_function(
+ SPREADSHEET_VALUE_TYPE_FLOAT3,
column_id.name,
size,
[transforms](int index, CellValue &r_cell_value) {
@@ -312,6 +353,7 @@ std::unique_ptr<ColumnValues> InstancesDataSource::get_column_values(
}
if (STREQ(column_id.name, "Rotation")) {
return column_values_from_function(
+ SPREADSHEET_VALUE_TYPE_FLOAT3,
column_id.name,
size,
[transforms](int index, CellValue &r_cell_value) {
@@ -321,6 +363,7 @@ std::unique_ptr<ColumnValues> InstancesDataSource::get_column_values(
}
if (STREQ(column_id.name, "Scale")) {
return column_values_from_function(
+ SPREADSHEET_VALUE_TYPE_FLOAT3,
column_id.name,
size,
[transforms](int index, CellValue &r_cell_value) {
@@ -332,6 +375,7 @@ std::unique_ptr<ColumnValues> InstancesDataSource::get_column_values(
if (STREQ(column_id.name, "ID")) {
/* Make the column a bit wider by default, since the IDs tend to be large numbers. */
return column_values_from_function(
+ SPREADSHEET_VALUE_TYPE_INT32,
column_id.name,
size,
[ids](int index, CellValue &r_cell_value) { r_cell_value.value_int = ids[index]; },
@@ -345,9 +389,9 @@ int InstancesDataSource::tot_rows() const
return component_->instances_amount();
}
-static GeometrySet get_display_geometry_set(SpaceSpreadsheet *sspreadsheet,
- Object *object_eval,
- const GeometryComponentType used_component_type)
+GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspreadsheet,
+ Object *object_eval,
+ const GeometryComponentType used_component_type)
{
GeometrySet geometry_set;
if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_ORIGINAL) {
@@ -370,7 +414,6 @@ static GeometrySet get_display_geometry_set(SpaceSpreadsheet *sspreadsheet,
Mesh *mesh = (Mesh *)object_orig->data;
mesh_component.replace(mesh, GeometryOwnershipType::ReadOnly);
}
- mesh_component.copy_vertex_group_names_from_object(*object_orig);
}
else if (object_orig->type == OB_POINTCLOUD) {
PointCloud *pointcloud = (PointCloud *)object_orig->data;
@@ -379,7 +422,7 @@ static GeometrySet get_display_geometry_set(SpaceSpreadsheet *sspreadsheet,
pointcloud_component.replace(pointcloud, GeometryOwnershipType::ReadOnly);
}
}
- else if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_EVALUATED) {
+ else {
if (used_component_type == GEO_COMPONENT_TYPE_MESH && object_eval->mode == OB_MODE_EDIT) {
Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(object_eval, false);
if (mesh == nullptr) {
@@ -388,7 +431,6 @@ static GeometrySet get_display_geometry_set(SpaceSpreadsheet *sspreadsheet,
BKE_mesh_wrapper_ensure_mdata(mesh);
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
mesh_component.replace(mesh, GeometryOwnershipType::ReadOnly);
- mesh_component.copy_vertex_group_names_from_object(*object_eval);
}
else {
if (BLI_listbase_count(&sspreadsheet->context_path) == 1) {
@@ -398,13 +440,18 @@ static GeometrySet get_display_geometry_set(SpaceSpreadsheet *sspreadsheet,
}
}
else {
- if (object_eval->runtime.geometry_set_previews != nullptr) {
- GHash *ghash = (GHash *)object_eval->runtime.geometry_set_previews;
- const uint64_t key = ED_spreadsheet_context_path_hash(sspreadsheet);
- GeometrySet *geometry_set_preview = (GeometrySet *)BLI_ghash_lookup_default(
- ghash, POINTER_FROM_UINT(key), nullptr);
- if (geometry_set_preview != nullptr) {
- geometry_set = *geometry_set_preview;
+ const geo_log::NodeLog *node_log =
+ geo_log::ModifierLog::find_node_by_spreadsheet_editor_context(*sspreadsheet);
+ if (node_log != nullptr) {
+ for (const geo_log::SocketLog &input_log : node_log->input_logs()) {
+ if (const geo_log::GeometryValueLog *geo_value_log =
+ dynamic_cast<const geo_log::GeometryValueLog *>(input_log.value())) {
+ const GeometrySet *full_geometry = geo_value_log->full_geometry();
+ if (full_geometry != nullptr) {
+ geometry_set = *full_geometry;
+ break;
+ }
+ }
}
}
}
@@ -430,7 +477,8 @@ std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
const AttributeDomain domain = (AttributeDomain)sspreadsheet->attribute_domain;
const GeometryComponentType component_type = get_display_component_type(C, object_eval);
- GeometrySet geometry_set = get_display_geometry_set(sspreadsheet, object_eval, component_type);
+ GeometrySet geometry_set = spreadsheet_get_display_geometry_set(
+ sspreadsheet, object_eval, component_type);
if (!geometry_set.has(component_type)) {
return {};
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh
index 273d39f27bf..d1b5dc6845e 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh
@@ -58,7 +58,8 @@ class GeometryDataSource : public DataSource {
return object_eval_;
}
- Span<int64_t> get_selected_element_indices() const;
+ bool has_selection_filter() const override;
+ void apply_selection_filter(MutableSpan<bool> rows_included) const;
void foreach_default_column_ids(
FunctionRef<void(const SpreadsheetColumnID &)> fn) const override;
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc
new file mode 100644
index 00000000000..2b31ce7d03c
--- /dev/null
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.cc
@@ -0,0 +1,287 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <array>
+
+#include "DNA_space_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BKE_context.h"
+
+#include "BLF_api.h"
+
+#include "BLI_rect.h"
+
+#include "RNA_access.h"
+
+#include "UI_interface.h"
+#include "UI_view2d.h"
+
+#include "WM_types.h"
+
+#include "spreadsheet_dataset_draw.hh"
+#include "spreadsheet_draw.hh"
+#include "spreadsheet_intern.hh"
+
+static int is_component_row_selected(struct uiBut *but, const void *arg)
+{
+ SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)arg;
+
+ GeometryComponentType component = (GeometryComponentType)UI_but_datasetrow_component_get(but);
+ AttributeDomain domain = (AttributeDomain)UI_but_datasetrow_domain_get(but);
+
+ const bool is_component_selected = (GeometryComponentType)
+ sspreadsheet->geometry_component_type == component;
+ const bool is_domain_selected = (AttributeDomain)sspreadsheet->attribute_domain == domain;
+ bool is_selected = is_component_selected && is_domain_selected;
+
+ if (component == GEO_COMPONENT_TYPE_INSTANCES) {
+ is_selected = is_component_selected;
+ }
+
+ return is_selected;
+}
+
+namespace blender::ed::spreadsheet {
+
+/* -------------------------------------------------------------------- */
+/* Draw Context */
+
+class DatasetDrawContext {
+ std::array<int, 2> mval_;
+
+ public:
+ const SpaceSpreadsheet *sspreadsheet;
+ Object *object_eval;
+ /* Current geometry set, changes per component. */
+ GeometrySet current_geometry_set;
+
+ DatasetDrawContext(const bContext *C);
+
+ GeometrySet geometry_set_from_component(GeometryComponentType component);
+ const std::array<int, 2> &cursor_mval() const;
+};
+
+DatasetDrawContext::DatasetDrawContext(const bContext *C)
+ : sspreadsheet(CTX_wm_space_spreadsheet(C)),
+ object_eval(spreadsheet_get_object_eval(sspreadsheet, CTX_data_depsgraph_pointer(C)))
+{
+ const wmWindow *win = CTX_wm_window(C);
+ const ARegion *region = CTX_wm_region(C);
+ mval_ = {win->eventstate->x - region->winrct.xmin, win->eventstate->y - region->winrct.ymin};
+}
+
+GeometrySet DatasetDrawContext::geometry_set_from_component(GeometryComponentType component)
+{
+ return spreadsheet_get_display_geometry_set(sspreadsheet, object_eval, component);
+}
+
+const std::array<int, 2> &DatasetDrawContext::cursor_mval() const
+{
+ return mval_;
+}
+
+/* -------------------------------------------------------------------- */
+/* Drawer */
+
+DatasetRegionDrawer::DatasetRegionDrawer(const ARegion *region,
+ uiBlock &block,
+ DatasetDrawContext &draw_context)
+ : row_height(UI_UNIT_Y),
+ xmin(region->v2d.cur.xmin),
+ xmax(region->v2d.cur.xmax),
+ block(block),
+ v2d(region->v2d),
+ draw_context(draw_context)
+{
+}
+
+void DatasetRegionDrawer::draw_hierarchy(const DatasetLayoutHierarchy &layout)
+{
+ for (const DatasetComponentLayoutInfo &component : layout.components) {
+ draw_context.current_geometry_set = draw_context.geometry_set_from_component(component.type);
+
+ draw_component_row(component);
+
+ /* Iterate attribute domains, skip unset ones (storage has to be in a enum-based, fixed size
+ * array so uses optionals to support skipping enum values that shouldn't be displayed for a
+ * component). */
+ for (const auto &optional_domain : component.attr_domains) {
+ if (!optional_domain) {
+ continue;
+ }
+
+ const DatasetAttrDomainLayoutInfo &domain_info = *optional_domain;
+ draw_attribute_domain_row(component, domain_info);
+ }
+ }
+}
+
+static int element_count_from_instances(const GeometrySet &geometry_set)
+{
+ if (geometry_set.has_instances()) {
+ const InstancesComponent *instances_component =
+ geometry_set.get_component_for_read<InstancesComponent>();
+ return instances_component->instances_amount();
+ }
+ return 0;
+}
+
+static int element_count_from_component_domain(const GeometrySet &geometry_set,
+ GeometryComponentType component,
+ AttributeDomain domain)
+{
+ if (geometry_set.has_mesh() && component == GEO_COMPONENT_TYPE_MESH) {
+ const MeshComponent *mesh_component = geometry_set.get_component_for_read<MeshComponent>();
+ return mesh_component->attribute_domain_size(domain);
+ }
+
+ if (geometry_set.has_pointcloud() && component == GEO_COMPONENT_TYPE_POINT_CLOUD) {
+ const PointCloudComponent *point_cloud_component =
+ geometry_set.get_component_for_read<PointCloudComponent>();
+ return point_cloud_component->attribute_domain_size(domain);
+ }
+
+ if (geometry_set.has_volume() && component == GEO_COMPONENT_TYPE_VOLUME) {
+ const VolumeComponent *volume_component =
+ geometry_set.get_component_for_read<VolumeComponent>();
+ return volume_component->attribute_domain_size(domain);
+ }
+
+ if (geometry_set.has_curve() && component == GEO_COMPONENT_TYPE_CURVE) {
+ const CurveComponent *curve_component = geometry_set.get_component_for_read<CurveComponent>();
+ return curve_component->attribute_domain_size(domain);
+ }
+
+ return 0;
+}
+
+void DatasetRegionDrawer::draw_dataset_row(const int indentation,
+ const GeometryComponentType component,
+ const std::optional<AttributeDomain> domain,
+ BIFIconID icon,
+ const char *label,
+ const bool is_active)
+{
+
+ const float row_height = UI_UNIT_Y;
+ const float padding_x = UI_UNIT_X * 0.25f;
+
+ const rctf rect = {float(xmin) + padding_x,
+ float(xmax) - V2D_SCROLL_HANDLE_WIDTH,
+ ymin_offset - row_height,
+ ymin_offset};
+
+ char element_count[7];
+ if (component == GEO_COMPONENT_TYPE_INSTANCES) {
+ BLI_str_format_attribute_domain_size(
+ element_count, element_count_from_instances(draw_context.current_geometry_set));
+ }
+ else {
+ BLI_str_format_attribute_domain_size(
+ element_count,
+ domain ? element_count_from_component_domain(
+ draw_context.current_geometry_set, component, *domain) :
+ 0);
+ }
+
+ std::string label_and_element_count = label;
+ label_and_element_count += UI_SEP_CHAR;
+ label_and_element_count += element_count;
+
+ uiBut *bt = uiDefIconTextButO(&block,
+ UI_BTYPE_DATASETROW,
+ "SPREADSHEET_OT_change_spreadsheet_data_source",
+ 0,
+ icon,
+ label,
+ rect.xmin,
+ rect.ymin,
+ BLI_rctf_size_x(&rect),
+ BLI_rctf_size_y(&rect),
+ nullptr);
+
+ UI_but_datasetrow_indentation_set(bt, indentation);
+
+ if (is_active) {
+ UI_but_hint_drawstr_set(bt, element_count);
+ UI_but_datasetrow_component_set(bt, component);
+ if (domain) {
+ UI_but_datasetrow_domain_set(bt, *domain);
+ }
+ UI_but_func_pushed_state_set(bt, &is_component_row_selected, draw_context.sspreadsheet);
+
+ PointerRNA *but_ptr = UI_but_operator_ptr_get((uiBut *)bt);
+ RNA_int_set(but_ptr, "component_type", component);
+ if (domain) {
+ RNA_int_set(but_ptr, "attribute_domain_type", *domain);
+ }
+ }
+
+ ymin_offset -= row_height;
+}
+
+void DatasetRegionDrawer::draw_component_row(const DatasetComponentLayoutInfo &component_info)
+{
+ if (component_info.type == GEO_COMPONENT_TYPE_INSTANCES) {
+ draw_dataset_row(
+ 0, component_info.type, std::nullopt, component_info.icon, component_info.label, true);
+ }
+ else {
+ draw_dataset_row(
+ 0, component_info.type, std::nullopt, component_info.icon, component_info.label, false);
+ }
+}
+
+void DatasetRegionDrawer::draw_attribute_domain_row(
+ const DatasetComponentLayoutInfo &component_info,
+ const DatasetAttrDomainLayoutInfo &domain_info)
+{
+ draw_dataset_row(
+ 1, component_info.type, domain_info.type, domain_info.icon, domain_info.label, true);
+}
+
+/* -------------------------------------------------------------------- */
+/* Drawer */
+
+void draw_dataset_in_region(const bContext *C, ARegion *region)
+{
+ DatasetDrawContext draw_context{C};
+ if (!draw_context.object_eval) {
+ /* No object means nothing to display. Keep the region empty. */
+ return;
+ }
+
+ uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
+
+ DatasetRegionDrawer drawer{region, *block, draw_context};
+
+ /* Start with an offset to align buttons to spreadsheet rows. Use spreadsheet drawing info for
+ * that. */
+ drawer.ymin_offset = -SpreadsheetDrawer().top_row_height + drawer.row_height;
+
+ const DatasetLayoutHierarchy hierarchy = dataset_layout_hierarchy();
+ drawer.draw_hierarchy(hierarchy);
+#ifndef NDEBUG
+ dataset_layout_hierarchy_sanity_check(hierarchy);
+#endif
+
+ UI_block_end(C, block);
+ UI_view2d_totRect_set(&region->v2d, region->winx, abs(drawer.ymin_offset));
+ UI_block_draw(C, block);
+}
+
+} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.hh b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.hh
new file mode 100644
index 00000000000..d9e6d882c2a
--- /dev/null
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_draw.hh
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <array>
+
+#include "BKE_geometry_set.hh"
+#include "UI_interface.h"
+#include "spreadsheet_dataset_layout.hh"
+
+struct ARegion;
+struct uiBlock;
+struct View2D;
+struct bContext;
+
+namespace blender::ed::spreadsheet {
+
+class DatasetDrawContext;
+
+class DatasetRegionDrawer {
+ public:
+ const int row_height;
+ float ymin_offset = 0;
+
+ int xmin;
+ int xmax;
+ uiBlock &block;
+ const View2D &v2d;
+ DatasetDrawContext &draw_context;
+
+ DatasetRegionDrawer(const ARegion *region, uiBlock &block, DatasetDrawContext &draw_context);
+
+ void draw_hierarchy(const DatasetLayoutHierarchy &layout);
+
+ void draw_attribute_domain_row(const DatasetComponentLayoutInfo &component,
+ const DatasetAttrDomainLayoutInfo &domain_info);
+ void draw_component_row(const DatasetComponentLayoutInfo &component_info);
+
+ private:
+ void draw_dataset_row(const int indentation,
+ const GeometryComponentType component,
+ const std::optional<AttributeDomain> domain,
+ const BIFIconID icon,
+ const char *label,
+ const bool is_active);
+};
+
+void draw_dataset_in_region(const bContext *C, ARegion *region);
+
+} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.cc
new file mode 100644
index 00000000000..abbad8c7088
--- /dev/null
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.cc
@@ -0,0 +1,112 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <optional>
+
+#include "BLI_span.hh"
+
+#include "BLT_translation.h"
+
+#include "spreadsheet_dataset_layout.hh"
+
+namespace blender::ed::spreadsheet {
+
+#define ATTR_INFO(type, label, icon) \
+ std::optional<DatasetAttrDomainLayoutInfo> \
+ { \
+ std::in_place, type, label, icon \
+ }
+#define ATTR_INFO_NONE(type) \
+ { \
+ std::nullopt \
+ }
+
+/**
+ * Definition for the component->attribute-domain hierarchy.
+ * Constructed at compile time.
+ *
+ * \warning Order of attribute-domains matters! It __must__ match the #AttributeDomain
+ * definition and fill gaps with unset optionals (i.e. `std::nullopt`). Would be nice to use
+ * array designators for this (which C++ doesn't support).
+ */
+constexpr DatasetComponentLayoutInfo DATASET_layout_hierarchy[] = {
+ {
+ GEO_COMPONENT_TYPE_MESH,
+ N_("Mesh"),
+ ICON_MESH_DATA,
+ {
+ ATTR_INFO(ATTR_DOMAIN_POINT, N_("Vertex"), ICON_VERTEXSEL),
+ ATTR_INFO(ATTR_DOMAIN_EDGE, N_("Edge"), ICON_EDGESEL),
+ ATTR_INFO(ATTR_DOMAIN_FACE, N_("Face"), ICON_FACESEL),
+ ATTR_INFO(ATTR_DOMAIN_CORNER, N_("Face Corner"), ICON_NODE_CORNER),
+ },
+ },
+ {
+ GEO_COMPONENT_TYPE_CURVE,
+ N_("Curves"),
+ ICON_CURVE_DATA,
+ {
+ ATTR_INFO(ATTR_DOMAIN_POINT, N_("Control Point"), ICON_CURVE_BEZCIRCLE),
+ ATTR_INFO_NONE(ATTR_DOMAIN_EDGE),
+ ATTR_INFO_NONE(ATTR_DOMAIN_CORNER),
+ ATTR_INFO_NONE(ATTR_DOMAIN_FACE),
+ ATTR_INFO(ATTR_DOMAIN_CURVE, N_("Spline"), ICON_CURVE_PATH),
+ },
+ },
+ {
+ GEO_COMPONENT_TYPE_POINT_CLOUD,
+ N_("Point Cloud"),
+ ICON_POINTCLOUD_DATA,
+ {
+ ATTR_INFO(ATTR_DOMAIN_POINT, N_("Point"), ICON_PARTICLE_POINT),
+ },
+ },
+ {
+ GEO_COMPONENT_TYPE_INSTANCES,
+ N_("Instances"),
+ ICON_EMPTY_AXIS,
+ {},
+ },
+};
+
+#undef ATTR_INFO
+#undef ATTR_INFO_LABEL
+
+DatasetLayoutHierarchy dataset_layout_hierarchy()
+{
+ return DatasetLayoutHierarchy{
+ Span{DATASET_layout_hierarchy, ARRAY_SIZE(DATASET_layout_hierarchy)}};
+}
+
+#ifndef NDEBUG
+/**
+ * Debug-only sanity check for correct attribute domain initialization (order/indices must
+ * match AttributeDomain). This doesn't check for all possible missuses, but should catch the most
+ * likely mistakes.
+ */
+void dataset_layout_hierarchy_sanity_check(const DatasetLayoutHierarchy &hierarchy)
+{
+ for (const DatasetComponentLayoutInfo &component : hierarchy.components) {
+ for (uint i = 0; i < component.attr_domains.size(); i++) {
+ if (component.attr_domains[i]) {
+ BLI_assert(component.attr_domains[i]->type == static_cast<AttributeDomain>(i));
+ }
+ }
+ }
+}
+#endif
+
+} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.hh b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.hh
new file mode 100644
index 00000000000..d463739a0fa
--- /dev/null
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_dataset_layout.hh
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <array>
+#include <optional>
+
+/* Enum definitions... */
+#include "BKE_attribute.h"
+#include "BKE_geometry_set.h"
+
+#include "BLI_span.hh"
+
+/* More enum definitions... */
+#include "UI_resources.h"
+
+#pragma once
+
+namespace blender::ed::spreadsheet {
+
+struct DatasetAttrDomainLayoutInfo {
+ AttributeDomain type;
+ const char *label;
+ BIFIconID icon;
+
+ constexpr DatasetAttrDomainLayoutInfo(AttributeDomain type, const char *label, BIFIconID icon)
+ : type(type), label(label), icon(icon)
+ {
+ }
+};
+
+struct DatasetComponentLayoutInfo {
+ GeometryComponentType type;
+ const char *label;
+ BIFIconID icon;
+ /** Array of attribute-domains. Has to be fixed size based on #AttributeDomain enum, but not all
+ * values need displaying for all parent components. Hence the optional use. */
+ using AttrDomainArray = std::array<std::optional<DatasetAttrDomainLayoutInfo>, ATTR_DOMAIN_NUM>;
+ const AttrDomainArray attr_domains;
+};
+
+struct DatasetLayoutHierarchy {
+ /** The components for display (with layout info like icon and label). Each component stores
+ * the attribute domains it wants to display (also with layout info like icon and label). */
+ const Span<DatasetComponentLayoutInfo> components;
+};
+
+DatasetLayoutHierarchy dataset_layout_hierarchy();
+
+#ifndef NDEBUG
+void dataset_layout_hierarchy_sanity_check(const DatasetLayoutHierarchy &hierarchy);
+#endif
+
+} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_intern.hh b/source/blender/editors/space_spreadsheet/spreadsheet_intern.hh
index 7e3b79a6706..8be5283fd63 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_intern.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_intern.hh
@@ -16,10 +16,23 @@
#pragma once
+#include "BKE_geometry_set.hh"
+
typedef struct SpaceSpreadsheet_Runtime {
int visible_rows;
int tot_rows;
int tot_columns;
} SpaceSpreadsheet_Runtime;
+struct bContext;
+
void spreadsheet_operatortypes(void);
+void spreadsheet_update_context_path(const bContext *C);
+Object *spreadsheet_get_object_eval(const SpaceSpreadsheet *sspreadsheet,
+ const Depsgraph *depsgraph);
+
+namespace blender::ed::spreadsheet {
+GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspreadsheet,
+ Object *object_eval,
+ const GeometryComponentType used_component_type);
+}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
index f1ca65817f6..8079763a339 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
@@ -170,7 +170,7 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
this->draw_float_vector(params, Span(&value.x, 3));
}
else if (cell_value.value_color.has_value()) {
- const Color4f value = *cell_value.value_color;
+ const ColorGeometry4f value = *cell_value.value_color;
this->draw_float_vector(params, Span(&value.r, 4));
}
else if (cell_value.value_object.has_value()) {
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc b/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc
index 770bd207e8d..11ed88b7dc9 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc
@@ -13,9 +13,137 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include "BKE_screen.h"
+
+#include "DNA_space_types.h"
+
+#include "ED_screen.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "BLI_listbase.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_context.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "ED_screen.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
#include "spreadsheet_intern.hh"
+#include "spreadsheet_row_filter.hh"
+
+using namespace blender::ed::spreadsheet;
+
+static int row_filter_add_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
+
+ SpreadsheetRowFilter *row_filter = spreadsheet_row_filter_new();
+ BLI_addtail(&sspreadsheet->row_filters, row_filter);
+
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_SPREADSHEET, sspreadsheet);
+
+ return OPERATOR_FINISHED;
+}
+
+static void SPREADSHEET_OT_add_row_filter_rule(wmOperatorType *ot)
+{
+ ot->name = "Add Row Filter";
+ ot->description = "Add a filter to remove rows from the displayed data";
+ ot->idname = "SPREADSHEET_OT_add_row_filter_rule";
+
+ ot->exec = row_filter_add_exec;
+ ot->poll = ED_operator_spreadsheet_active;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int row_filter_remove_exec(bContext *C, wmOperator *op)
+{
+ SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
+
+ SpreadsheetRowFilter *row_filter = (SpreadsheetRowFilter *)BLI_findlink(
+ &sspreadsheet->row_filters, RNA_int_get(op->ptr, "index"));
+ if (row_filter == nullptr) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BLI_remlink(&sspreadsheet->row_filters, row_filter);
+ spreadsheet_row_filter_free(row_filter);
+
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_SPREADSHEET, sspreadsheet);
+
+ return OPERATOR_FINISHED;
+}
+
+static void SPREADSHEET_OT_remove_row_filter_rule(wmOperatorType *ot)
+{
+ ot->name = "Remove Row Filter";
+ ot->description = "Remove a row filter from the rules";
+ ot->idname = "SPREADSHEET_OT_remove_row_filter_rule";
+
+ ot->exec = row_filter_remove_exec;
+ ot->poll = ED_operator_spreadsheet_active;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX);
+}
+
+static int select_component_domain_invoke(bContext *C,
+ wmOperator *op,
+ const wmEvent *UNUSED(event))
+{
+ GeometryComponentType component_type = static_cast<GeometryComponentType>(
+ RNA_int_get(op->ptr, "component_type"));
+ AttributeDomain attribute_domain = static_cast<AttributeDomain>(
+ RNA_int_get(op->ptr, "attribute_domain_type"));
+
+ SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
+ sspreadsheet->geometry_component_type = component_type;
+ sspreadsheet->attribute_domain = attribute_domain;
+
+ /* Refresh header and main region. */
+ WM_main_add_notifier(NC_SPACE | ND_SPACE_SPREADSHEET, nullptr);
+
+ return OPERATOR_FINISHED;
+}
+
+static void SPREADSHEET_OT_change_spreadsheet_data_source(wmOperatorType *ot)
+{
+ ot->name = "Change Visible Data Source";
+ ot->description = "Change visible data source in the spreadsheet";
+ ot->idname = "SPREADSHEET_OT_change_spreadsheet_data_source";
+
+ ot->invoke = select_component_domain_invoke;
+
+ RNA_def_int(ot->srna, "component_type", 0, 0, INT16_MAX, "Component Type", "", 0, INT16_MAX);
+ RNA_def_int(ot->srna,
+ "attribute_domain_type",
+ 0,
+ 0,
+ INT16_MAX,
+ "Attribute Domain Type",
+ "",
+ 0,
+ INT16_MAX);
+
+ ot->flag = OPTYPE_INTERNAL;
+}
void spreadsheet_operatortypes()
{
+ WM_operatortype_append(SPREADSHEET_OT_add_row_filter_rule);
+ WM_operatortype_append(SPREADSHEET_OT_remove_row_filter_rule);
+ WM_operatortype_append(SPREADSHEET_OT_change_spreadsheet_data_source);
}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc
new file mode 100644
index 00000000000..ae336edfead
--- /dev/null
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc
@@ -0,0 +1,366 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <cstring>
+
+#include "BLI_listbase.h"
+
+#include "DNA_collection_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+
+#include "DEG_depsgraph_query.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "RNA_access.h"
+
+#include "spreadsheet_intern.hh"
+
+#include "spreadsheet_data_source_geometry.hh"
+#include "spreadsheet_intern.hh"
+#include "spreadsheet_layout.hh"
+#include "spreadsheet_row_filter.hh"
+
+namespace blender::ed::spreadsheet {
+
+template<typename OperationFn>
+static void apply_filter_operation(const ColumnValues &values,
+ OperationFn check_fn,
+ MutableSpan<bool> rows_included)
+{
+ for (const int i : rows_included.index_range()) {
+ if (!rows_included[i]) {
+ continue;
+ }
+ CellValue cell_value;
+ values.get_value(i, cell_value);
+ if (!check_fn(cell_value)) {
+ rows_included[i] = false;
+ }
+ }
+}
+
+static void apply_row_filter(const SpreadsheetLayout &spreadsheet_layout,
+ const SpreadsheetRowFilter &row_filter,
+ MutableSpan<bool> rows_included)
+{
+ for (const ColumnLayout &column : spreadsheet_layout.columns) {
+ const ColumnValues &values = *column.values;
+ if (values.name() != row_filter.column_name) {
+ continue;
+ }
+
+ switch (values.type()) {
+ case SPREADSHEET_VALUE_TYPE_INT32: {
+ const int value = row_filter.value_int;
+ switch (row_filter.operation) {
+ case SPREADSHEET_ROW_FILTER_EQUAL: {
+ apply_filter_operation(
+ values,
+ [value](const CellValue &cell_value) -> bool {
+ return *cell_value.value_int == value;
+ },
+ rows_included);
+ break;
+ }
+ case SPREADSHEET_ROW_FILTER_GREATER: {
+ apply_filter_operation(
+ values,
+ [value](const CellValue &cell_value) -> bool {
+ return *cell_value.value_int > value;
+ },
+ rows_included);
+ break;
+ }
+ case SPREADSHEET_ROW_FILTER_LESS: {
+ apply_filter_operation(
+ values,
+ [value](const CellValue &cell_value) -> bool {
+ return *cell_value.value_int < value;
+ },
+ rows_included);
+ break;
+ }
+ }
+ break;
+ }
+ case SPREADSHEET_VALUE_TYPE_FLOAT: {
+ const float value = row_filter.value_float;
+ switch (row_filter.operation) {
+ case SPREADSHEET_ROW_FILTER_EQUAL: {
+ const float threshold = row_filter.threshold;
+ apply_filter_operation(
+ values,
+ [value, threshold](const CellValue &cell_value) -> bool {
+ return std::abs(*cell_value.value_float - value) < threshold;
+ },
+ rows_included);
+ break;
+ }
+ case SPREADSHEET_ROW_FILTER_GREATER: {
+ apply_filter_operation(
+ values,
+ [value](const CellValue &cell_value) -> bool {
+ return *cell_value.value_float > value;
+ },
+ rows_included);
+ break;
+ }
+ case SPREADSHEET_ROW_FILTER_LESS: {
+ apply_filter_operation(
+ values,
+ [value](const CellValue &cell_value) -> bool {
+ return *cell_value.value_float < value;
+ },
+ rows_included);
+ break;
+ }
+ }
+ break;
+ }
+ case SPREADSHEET_VALUE_TYPE_FLOAT2: {
+ const float2 value = row_filter.value_float2;
+ switch (row_filter.operation) {
+ case SPREADSHEET_ROW_FILTER_EQUAL: {
+ const float threshold_squared = row_filter.threshold * row_filter.threshold;
+ apply_filter_operation(
+ values,
+ [value, threshold_squared](const CellValue &cell_value) -> bool {
+ return float2::distance_squared(*cell_value.value_float2, value) <
+ threshold_squared;
+ },
+ rows_included);
+ break;
+ }
+ case SPREADSHEET_ROW_FILTER_GREATER: {
+ apply_filter_operation(
+ values,
+ [value](const CellValue &cell_value) -> bool {
+ return cell_value.value_float2->x > value.x &&
+ cell_value.value_float2->y > value.y;
+ },
+ rows_included);
+ break;
+ }
+ case SPREADSHEET_ROW_FILTER_LESS: {
+ apply_filter_operation(
+ values,
+ [value](const CellValue &cell_value) -> bool {
+ return cell_value.value_float2->x < value.x &&
+ cell_value.value_float2->y < value.y;
+ },
+ rows_included);
+ break;
+ }
+ }
+ break;
+ }
+ case SPREADSHEET_VALUE_TYPE_FLOAT3: {
+ const float3 value = row_filter.value_float3;
+ switch (row_filter.operation) {
+ case SPREADSHEET_ROW_FILTER_EQUAL: {
+ const float threshold_squared = row_filter.threshold * row_filter.threshold;
+ apply_filter_operation(
+ values,
+ [value, threshold_squared](const CellValue &cell_value) -> bool {
+ return float3::distance_squared(*cell_value.value_float3, value) <
+ threshold_squared;
+ },
+ rows_included);
+ break;
+ }
+ case SPREADSHEET_ROW_FILTER_GREATER: {
+ apply_filter_operation(
+ values,
+ [value](const CellValue &cell_value) -> bool {
+ return cell_value.value_float3->x > value.x &&
+ cell_value.value_float3->y > value.y &&
+ cell_value.value_float3->z > value.z;
+ },
+ rows_included);
+ break;
+ }
+ case SPREADSHEET_ROW_FILTER_LESS: {
+ apply_filter_operation(
+ values,
+ [value](const CellValue &cell_value) -> bool {
+ return cell_value.value_float3->x < value.x &&
+ cell_value.value_float3->y < value.y &&
+ cell_value.value_float3->z < value.z;
+ },
+ rows_included);
+ break;
+ }
+ }
+ break;
+ }
+ case SPREADSHEET_VALUE_TYPE_COLOR: {
+ const ColorGeometry4f value = row_filter.value_color;
+ switch (row_filter.operation) {
+ case SPREADSHEET_ROW_FILTER_EQUAL: {
+ const float threshold_squared = row_filter.threshold * row_filter.threshold;
+ apply_filter_operation(
+ values,
+ [value, threshold_squared](const CellValue &cell_value) -> bool {
+ return len_squared_v4v4(value, *cell_value.value_color) < threshold_squared;
+ },
+ rows_included);
+ break;
+ }
+ }
+ break;
+ }
+ case SPREADSHEET_VALUE_TYPE_BOOL: {
+ const bool value = (row_filter.flag & SPREADSHEET_ROW_FILTER_BOOL_VALUE) != 0;
+ apply_filter_operation(
+ values,
+ [value](const CellValue &cell_value) -> bool {
+ return *cell_value.value_bool == value;
+ },
+ rows_included);
+ break;
+ }
+ case SPREADSHEET_VALUE_TYPE_INSTANCES: {
+ const StringRef value = row_filter.value_string;
+ apply_filter_operation(
+ values,
+ [value](const CellValue &cell_value) -> bool {
+ const ID *id = nullptr;
+ if (cell_value.value_object) {
+ id = &cell_value.value_object->object->id;
+ }
+ else if (cell_value.value_collection) {
+ id = &cell_value.value_collection->collection->id;
+ }
+ if (id == nullptr) {
+ return false;
+ }
+
+ return value == id->name + 2;
+ },
+ rows_included);
+ break;
+ }
+ default:
+ break;
+ }
+
+ /* Only one column should have this name. */
+ break;
+ }
+}
+
+static void index_vector_from_bools(Span<bool> selection, Vector<int64_t> &indices)
+{
+ for (const int i : selection.index_range()) {
+ if (selection[i]) {
+ indices.append(i);
+ }
+ }
+}
+
+static bool use_row_filters(const SpaceSpreadsheet &sspreadsheet)
+{
+ if (!(sspreadsheet.filter_flag & SPREADSHEET_FILTER_ENABLE)) {
+ return false;
+ }
+ if (BLI_listbase_is_empty(&sspreadsheet.row_filters)) {
+ return false;
+ }
+ return true;
+}
+
+static bool use_selection_filter(const SpaceSpreadsheet &sspreadsheet,
+ const DataSource &data_source)
+{
+ if (!(sspreadsheet.filter_flag & SPREADSHEET_FILTER_SELECTED_ONLY)) {
+ return false;
+ }
+ if (!data_source.has_selection_filter()) {
+ return false;
+ }
+ return true;
+}
+
+Span<int64_t> spreadsheet_filter_rows(const SpaceSpreadsheet &sspreadsheet,
+ const SpreadsheetLayout &spreadsheet_layout,
+ const DataSource &data_source,
+ ResourceScope &scope)
+{
+ const int tot_rows = data_source.tot_rows();
+
+ const bool use_selection = use_selection_filter(sspreadsheet, data_source);
+ const bool use_filters = use_row_filters(sspreadsheet);
+
+ /* Avoid allocating an array if no row filtering is necessary. */
+ if (!(use_filters || use_selection)) {
+ return IndexRange(tot_rows).as_span();
+ }
+
+ Array<bool> rows_included(tot_rows, true);
+
+ if (use_filters) {
+ LISTBASE_FOREACH (const SpreadsheetRowFilter *, row_filter, &sspreadsheet.row_filters) {
+ if (row_filter->flag & SPREADSHEET_ROW_FILTER_ENABLED) {
+ apply_row_filter(spreadsheet_layout, *row_filter, rows_included);
+ }
+ }
+ }
+
+ if (use_selection) {
+ const GeometryDataSource *geometry_data_source = dynamic_cast<const GeometryDataSource *>(
+ &data_source);
+ geometry_data_source->apply_selection_filter(rows_included);
+ }
+
+ Vector<int64_t> &indices = scope.construct<Vector<int64_t>>(__func__);
+ index_vector_from_bools(rows_included, indices);
+
+ return indices;
+}
+
+SpreadsheetRowFilter *spreadsheet_row_filter_new()
+{
+ SpreadsheetRowFilter *row_filter = (SpreadsheetRowFilter *)MEM_callocN(
+ sizeof(SpreadsheetRowFilter), __func__);
+ row_filter->flag = (SPREADSHEET_ROW_FILTER_UI_EXPAND | SPREADSHEET_ROW_FILTER_ENABLED);
+ row_filter->operation = SPREADSHEET_ROW_FILTER_LESS;
+ row_filter->threshold = 0.01f;
+ row_filter->column_name[0] = '\0';
+
+ return row_filter;
+}
+
+SpreadsheetRowFilter *spreadsheet_row_filter_copy(const SpreadsheetRowFilter *src_row_filter)
+{
+ SpreadsheetRowFilter *new_filter = spreadsheet_row_filter_new();
+
+ memcpy(new_filter, src_row_filter, sizeof(SpreadsheetRowFilter));
+ new_filter->next = nullptr;
+ new_filter->prev = nullptr;
+
+ return new_filter;
+}
+
+void spreadsheet_row_filter_free(SpreadsheetRowFilter *row_filter)
+{
+ MEM_SAFE_FREE(row_filter->value_string);
+ MEM_freeN(row_filter);
+}
+
+} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.hh b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.hh
new file mode 100644
index 00000000000..0a5783e318d
--- /dev/null
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.hh
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "BLI_resource_scope.hh"
+
+#include "spreadsheet_data_source.hh"
+#include "spreadsheet_layout.hh"
+
+namespace blender::ed::spreadsheet {
+
+Span<int64_t> spreadsheet_filter_rows(const SpaceSpreadsheet &sspreadsheet,
+ const SpreadsheetLayout &spreadsheet_layout,
+ const DataSource &data_source,
+ ResourceScope &scope);
+
+SpreadsheetRowFilter *spreadsheet_row_filter_new();
+SpreadsheetRowFilter *spreadsheet_row_filter_copy(const SpreadsheetRowFilter *src_row_filter);
+void spreadsheet_row_filter_free(SpreadsheetRowFilter *row_filter);
+
+} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc
new file mode 100644
index 00000000000..219d03c1dcd
--- /dev/null
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc
@@ -0,0 +1,347 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <cstring>
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_string_ref.hh"
+
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_screen.h"
+
+#include "RNA_access.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "BLT_translation.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "spreadsheet_column.hh"
+#include "spreadsheet_intern.hh"
+#include "spreadsheet_row_filter.hh"
+#include "spreadsheet_row_filter_ui.hh"
+
+using namespace blender;
+using namespace blender::ed::spreadsheet;
+
+static void filter_panel_id_fn(void *UNUSED(row_filter_v), char *r_name)
+{
+ /* All row filters use the same panel ID. */
+ BLI_snprintf(r_name, BKE_ST_MAXNAME, "SPREADSHEET_PT_filter");
+}
+
+static std::string operation_string(const eSpreadsheetColumnValueType data_type,
+ const eSpreadsheetFilterOperation operation)
+{
+ if (ELEM(data_type,
+ SPREADSHEET_VALUE_TYPE_BOOL,
+ SPREADSHEET_VALUE_TYPE_INSTANCES,
+ SPREADSHEET_VALUE_TYPE_COLOR)) {
+ return "=";
+ }
+
+ switch (operation) {
+ case SPREADSHEET_ROW_FILTER_EQUAL:
+ return "=";
+ case SPREADSHEET_ROW_FILTER_GREATER:
+ return ">";
+ case SPREADSHEET_ROW_FILTER_LESS:
+ return "<";
+ }
+ BLI_assert_unreachable();
+ return "";
+}
+
+static std::string value_string(const SpreadsheetRowFilter &row_filter,
+ const eSpreadsheetColumnValueType data_type)
+{
+ switch (data_type) {
+ case SPREADSHEET_VALUE_TYPE_INT32:
+ return std::to_string(row_filter.value_int);
+ case SPREADSHEET_VALUE_TYPE_FLOAT: {
+ std::ostringstream result;
+ result.precision(3);
+ result << std::fixed << row_filter.value_float;
+ return result.str();
+ }
+ case SPREADSHEET_VALUE_TYPE_FLOAT2: {
+ std::ostringstream result;
+ result.precision(3);
+ result << std::fixed << "(" << row_filter.value_float2[0] << ", "
+ << row_filter.value_float2[1] << ")";
+ return result.str();
+ }
+ case SPREADSHEET_VALUE_TYPE_FLOAT3: {
+ std::ostringstream result;
+ result.precision(3);
+ result << std::fixed << "(" << row_filter.value_float3[0] << ", "
+ << row_filter.value_float3[1] << ", " << row_filter.value_float3[2] << ")";
+ return result.str();
+ }
+ case SPREADSHEET_VALUE_TYPE_BOOL:
+ return (row_filter.flag & SPREADSHEET_ROW_FILTER_BOOL_VALUE) ? IFACE_("True") :
+ IFACE_("False");
+ case SPREADSHEET_VALUE_TYPE_INSTANCES:
+ if (row_filter.value_string != nullptr) {
+ return row_filter.value_string;
+ }
+ return "";
+ case SPREADSHEET_VALUE_TYPE_COLOR:
+ std::ostringstream result;
+ result.precision(3);
+ result << std::fixed << "(" << row_filter.value_color[0] << ", " << row_filter.value_color[1]
+ << ", " << row_filter.value_color[2] << ", " << row_filter.value_color[3] << ")";
+ return result.str();
+ }
+ BLI_assert_unreachable();
+ return "";
+}
+
+static SpreadsheetColumn *lookup_visible_column_for_filter(const SpaceSpreadsheet &sspreadsheet,
+ const StringRef column_name)
+{
+ LISTBASE_FOREACH (SpreadsheetColumn *, column, &sspreadsheet.columns) {
+ if (column->display_name == column_name) {
+ return column;
+ }
+ }
+ return nullptr;
+}
+
+static void spreadsheet_filter_panel_draw_header(const bContext *C, Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+ SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
+ PointerRNA *filter_ptr = UI_panel_custom_data_get(panel);
+ const SpreadsheetRowFilter *filter = (SpreadsheetRowFilter *)filter_ptr->data;
+ const StringRef column_name = filter->column_name;
+ const eSpreadsheetFilterOperation operation = (eSpreadsheetFilterOperation)filter->operation;
+
+ const SpreadsheetColumn *column = lookup_visible_column_for_filter(*sspreadsheet, column_name);
+ if (!(sspreadsheet->filter_flag & SPREADSHEET_FILTER_ENABLE) ||
+ (column == nullptr && !column_name.is_empty())) {
+ uiLayoutSetActive(layout, false);
+ }
+
+ uiLayout *row = uiLayoutRow(layout, true);
+ uiLayoutSetEmboss(row, UI_EMBOSS_NONE);
+ uiItemR(row, filter_ptr, "enabled", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+
+ if (column_name.is_empty()) {
+ uiItemL(row, IFACE_("Filter"), ICON_NONE);
+ }
+ else if (column == nullptr) {
+ uiItemL(row, column_name.data(), ICON_NONE);
+ }
+ else {
+ const eSpreadsheetColumnValueType data_type = (eSpreadsheetColumnValueType)column->data_type;
+ std::stringstream ss;
+ ss << column_name;
+ ss << " ";
+ ss << operation_string(data_type, operation);
+ ss << " ";
+ ss << value_string(*filter, data_type);
+ uiItemL(row, ss.str().c_str(), ICON_NONE);
+ }
+
+ row = uiLayoutRow(layout, true);
+ uiLayoutSetEmboss(row, UI_EMBOSS_NONE);
+ const int current_index = BLI_findindex(&sspreadsheet->row_filters, filter);
+ uiItemIntO(row, "", ICON_X, "SPREADSHEET_OT_remove_row_filter_rule", "index", current_index);
+
+ /* Some padding so the X isn't too close to the drag icon. */
+ uiItemS_ex(layout, 0.25f);
+}
+
+static void spreadsheet_filter_panel_draw(const bContext *C, Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+ SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
+ PointerRNA *filter_ptr = UI_panel_custom_data_get(panel);
+ SpreadsheetRowFilter *filter = (SpreadsheetRowFilter *)filter_ptr->data;
+ const StringRef column_name = filter->column_name;
+ const eSpreadsheetFilterOperation operation = (eSpreadsheetFilterOperation)filter->operation;
+
+ const SpreadsheetColumn *column = lookup_visible_column_for_filter(*sspreadsheet, column_name);
+ if (!(sspreadsheet->filter_flag & SPREADSHEET_FILTER_ENABLE) ||
+ !(filter->flag & SPREADSHEET_ROW_FILTER_ENABLED) ||
+ (column == nullptr && !column_name.is_empty())) {
+ uiLayoutSetActive(layout, false);
+ }
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
+ uiItemR(layout, filter_ptr, "column_name", 0, IFACE_("Column"), ICON_NONE);
+
+ /* Don't draw settings for filters with no corresponding visible column. */
+ if (column == nullptr || column_name.is_empty()) {
+ return;
+ }
+
+ switch (static_cast<eSpreadsheetColumnValueType>(column->data_type)) {
+ case SPREADSHEET_VALUE_TYPE_INT32:
+ uiItemR(layout, filter_ptr, "operation", 0, nullptr, ICON_NONE);
+ uiItemR(layout, filter_ptr, "value_int", 0, IFACE_("Value"), ICON_NONE);
+ break;
+ case SPREADSHEET_VALUE_TYPE_FLOAT:
+ uiItemR(layout, filter_ptr, "operation", 0, nullptr, ICON_NONE);
+ uiItemR(layout, filter_ptr, "value_float", 0, IFACE_("Value"), ICON_NONE);
+ if (operation == SPREADSHEET_ROW_FILTER_EQUAL) {
+ uiItemR(layout, filter_ptr, "threshold", 0, nullptr, ICON_NONE);
+ }
+ break;
+ case SPREADSHEET_VALUE_TYPE_FLOAT2:
+ uiItemR(layout, filter_ptr, "operation", 0, nullptr, ICON_NONE);
+ uiItemR(layout, filter_ptr, "value_float2", 0, IFACE_("Value"), ICON_NONE);
+ if (operation == SPREADSHEET_ROW_FILTER_EQUAL) {
+ uiItemR(layout, filter_ptr, "threshold", 0, nullptr, ICON_NONE);
+ }
+ break;
+ case SPREADSHEET_VALUE_TYPE_FLOAT3:
+ uiItemR(layout, filter_ptr, "operation", 0, nullptr, ICON_NONE);
+ uiItemR(layout, filter_ptr, "value_float3", 0, IFACE_("Value"), ICON_NONE);
+ if (operation == SPREADSHEET_ROW_FILTER_EQUAL) {
+ uiItemR(layout, filter_ptr, "threshold", 0, nullptr, ICON_NONE);
+ }
+ break;
+ case SPREADSHEET_VALUE_TYPE_BOOL:
+ uiItemR(layout, filter_ptr, "value_boolean", 0, IFACE_("Value"), ICON_NONE);
+ break;
+ case SPREADSHEET_VALUE_TYPE_INSTANCES:
+ uiItemR(layout, filter_ptr, "value_string", 0, IFACE_("Value"), ICON_NONE);
+ break;
+ case SPREADSHEET_VALUE_TYPE_COLOR:
+ uiItemR(layout, filter_ptr, "value_color", 0, IFACE_("Value"), ICON_NONE);
+ uiItemR(layout, filter_ptr, "threshold", 0, nullptr, ICON_NONE);
+ break;
+ }
+}
+
+static void spreadsheet_row_filters_layout(const bContext *C, Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+ ARegion *region = CTX_wm_region(C);
+ bScreen *screen = CTX_wm_screen(C);
+ SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
+ ListBase *row_filters = &sspreadsheet->row_filters;
+
+ if (!(sspreadsheet->filter_flag & SPREADSHEET_FILTER_ENABLE)) {
+ uiLayoutSetActive(layout, false);
+ }
+
+ uiItemO(layout, nullptr, ICON_ADD, "SPREADSHEET_OT_add_row_filter_rule");
+
+ const bool panels_match = UI_panel_list_matches_data(region, row_filters, filter_panel_id_fn);
+
+ if (!panels_match) {
+ UI_panels_free_instanced(C, region);
+ LISTBASE_FOREACH (SpreadsheetRowFilter *, row_filter, row_filters) {
+ char panel_idname[MAX_NAME];
+ filter_panel_id_fn(row_filter, panel_idname);
+
+ PointerRNA *filter_ptr = (PointerRNA *)MEM_mallocN(sizeof(PointerRNA), "panel customdata");
+ RNA_pointer_create(&screen->id, &RNA_SpreadsheetRowFilter, row_filter, filter_ptr);
+
+ UI_panel_add_instanced(C, region, &region->panels, panel_idname, filter_ptr);
+ }
+ }
+ else {
+ /* Assuming there's only one group of instanced panels, update the custom data pointers. */
+ Panel *panel_iter = (Panel *)region->panels.first;
+ LISTBASE_FOREACH (SpreadsheetRowFilter *, row_filter, row_filters) {
+
+ /* Move to the next instanced panel corresponding to the next filter. */
+ while ((panel_iter->type == nullptr) || !(panel_iter->type->flag & PANEL_TYPE_INSTANCED)) {
+ panel_iter = panel_iter->next;
+ BLI_assert(panel_iter != nullptr); /* There shouldn't be fewer panels than filters. */
+ }
+
+ PointerRNA *filter_ptr = (PointerRNA *)MEM_mallocN(sizeof(PointerRNA), "panel customdata");
+ RNA_pointer_create(&screen->id, &RNA_SpreadsheetRowFilter, row_filter, filter_ptr);
+ UI_panel_custom_data_set(panel_iter, filter_ptr);
+
+ panel_iter = panel_iter->next;
+ }
+ }
+}
+
+static void filter_reorder(bContext *C, Panel *panel, int new_index)
+{
+ SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
+ ListBase *row_filters = &sspreadsheet->row_filters;
+ PointerRNA *filter_ptr = UI_panel_custom_data_get(panel);
+ SpreadsheetRowFilter *filter = (SpreadsheetRowFilter *)filter_ptr->data;
+
+ int current_index = BLI_findindex(row_filters, filter);
+ BLI_assert(current_index >= 0);
+ BLI_assert(new_index >= 0);
+
+ BLI_listbase_link_move(row_filters, filter, new_index - current_index);
+}
+
+static short get_filter_expand_flag(const bContext *UNUSED(C), Panel *panel)
+{
+ PointerRNA *filter_ptr = UI_panel_custom_data_get(panel);
+ SpreadsheetRowFilter *filter = (SpreadsheetRowFilter *)filter_ptr->data;
+
+ return (short)filter->flag & SPREADSHEET_ROW_FILTER_UI_EXPAND;
+}
+
+static void set_filter_expand_flag(const bContext *UNUSED(C), Panel *panel, short expand_flag)
+{
+ PointerRNA *filter_ptr = UI_panel_custom_data_get(panel);
+ SpreadsheetRowFilter *filter = (SpreadsheetRowFilter *)filter_ptr->data;
+
+ SET_FLAG_FROM_TEST(filter->flag,
+ expand_flag & SPREADSHEET_ROW_FILTER_UI_EXPAND,
+ SPREADSHEET_ROW_FILTER_UI_EXPAND);
+}
+
+void register_row_filter_panels(ARegionType &region_type)
+{
+ {
+ PanelType *panel_type = (PanelType *)MEM_callocN(sizeof(PanelType), __func__);
+ strcpy(panel_type->idname, "SPREADSHEET_PT_row_filters");
+ strcpy(panel_type->label, N_("Filters"));
+ strcpy(panel_type->category, "Filters");
+ strcpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ panel_type->flag = PANEL_TYPE_NO_HEADER;
+ panel_type->draw = spreadsheet_row_filters_layout;
+ BLI_addtail(&region_type.paneltypes, panel_type);
+ }
+
+ {
+ PanelType *panel_type = (PanelType *)MEM_callocN(sizeof(PanelType), __func__);
+ strcpy(panel_type->idname, "SPREADSHEET_PT_filter");
+ strcpy(panel_type->label, "");
+ strcpy(panel_type->category, "Filters");
+ strcpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ panel_type->flag = PANEL_TYPE_INSTANCED | PANEL_TYPE_DRAW_BOX | PANEL_TYPE_HEADER_EXPAND;
+ panel_type->draw_header = spreadsheet_filter_panel_draw_header;
+ panel_type->draw = spreadsheet_filter_panel_draw;
+ panel_type->get_list_data_expand_flag = get_filter_expand_flag;
+ panel_type->set_list_data_expand_flag = set_filter_expand_flag;
+ panel_type->reorder = filter_reorder;
+ BLI_addtail(&region_type.paneltypes, panel_type);
+ }
+}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.hh b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.hh
new file mode 100644
index 00000000000..e22178b63ea
--- /dev/null
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.hh
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+struct ARegionType;
+
+void register_row_filter_panels(ARegionType &region_type);
diff --git a/source/blender/editors/space_statusbar/space_statusbar.c b/source/blender/editors/space_statusbar/space_statusbar.c
index 0b4f483c114..bf2a5534e0b 100644
--- a/source/blender/editors/space_statusbar/space_statusbar.c
+++ b/source/blender/editors/space_statusbar/space_statusbar.c
@@ -39,7 +39,7 @@
#include "WM_message.h"
#include "WM_types.h"
-/* ******************** default callbacks for statusbar space ******************** */
+/* ******************** default callbacks for statusbar space ******************** */
static SpaceLink *statusbar_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 17831c95575..1d8bc427212 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -938,7 +938,7 @@ static void calc_text_rcts(SpaceText *st, ARegion *region, rcti *scroll, rcti *b
hlstart = barstart + barheight;
}
else if (lhlend > st->top && lhlstart < st->top && hlstart > barstart) {
- /*fill out start */
+ /* Fill out start. */
hlstart = barstart;
}
diff --git a/source/blender/editors/space_text/text_format_pov.c b/source/blender/editors/space_text/text_format_pov.c
index a68632c0d56..1200dda7533 100644
--- a/source/blender/editors/space_text/text_format_pov.c
+++ b/source/blender/editors/space_text/text_format_pov.c
@@ -644,7 +644,7 @@ static int txtfmt_pov_find_specialvar(const char *string)
} else if (STR_LITERAL_STARTSWITH(string, "ratio", len)) { i = len;
} else if (STR_LITERAL_STARTSWITH(string, "open", len)) { i = len;
} else if (STR_LITERAL_STARTSWITH(string, "ior", len)) { i = len;
- /* Light Types and options*/
+ /* Light Types and options. */
} else if (STR_LITERAL_STARTSWITH(string, "area_light", len)) { i = len;
} else if (STR_LITERAL_STARTSWITH(string, "looks_like", len)) { i = len;
} else if (STR_LITERAL_STARTSWITH(string, "fade_power", len)) { i = len;
@@ -654,7 +654,7 @@ static int txtfmt_pov_find_specialvar(const char *string)
} else if (STR_LITERAL_STARTSWITH(string, "point_at", len)) { i = len;
} else if (STR_LITERAL_STARTSWITH(string, "falloff", len)) { i = len;
} else if (STR_LITERAL_STARTSWITH(string, "radius", len)) { i = len;
- /* Camera Types and options*/
+ /* Camera Types and options. */
} else if (STR_LITERAL_STARTSWITH(string, "omni_directional_stereo", len)) { i = len;
} else if (STR_LITERAL_STARTSWITH(string, "lambert_cylindrical", len)) { i = len;
} else if (STR_LITERAL_STARTSWITH(string, "miller_cylindrical", len)) { i = len;
diff --git a/source/blender/editors/space_text/text_format_py.c b/source/blender/editors/space_text/text_format_py.c
index 31177c53d6a..2717c0bf5b0 100644
--- a/source/blender/editors/space_text/text_format_py.c
+++ b/source/blender/editors/space_text/text_format_py.c
@@ -290,7 +290,7 @@ static int txtfmt_py_literal_numeral(const char *string, char prev_fmt)
return 1 + txtfmt_py_find_numeral_inner(string + 1);
}
/* Previous was a number; if immediately followed by '.' it's a floating point decimal number.
- * Note: keep the decimal point, it's needed to allow leading zeros. */
+ * NOTE: keep the decimal point, it's needed to allow leading zeros. */
if (first == '.') {
return txtfmt_py_find_numeral_inner(string);
}
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 9ec759ce4ae..b98dae0cd57 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -745,7 +745,7 @@ void TEXT_OT_save_as(wmOperatorType *ot)
FILE_SAVE,
WM_FILESEL_FILEPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_DEFAULT); /* XXX TODO, relative_path. */
+ FILE_SORT_DEFAULT); /* XXX TODO: relative_path. */
}
/** \} */
@@ -2782,8 +2782,7 @@ void TEXT_OT_scroll(wmOperatorType *ot)
/* identifiers */
ot->name = "Scroll";
/* don't really see the difference between this and
- * scroll_bar. Both do basically the same thing (aside
- * from keymaps).*/
+ * scroll_bar. Both do basically the same thing (aside from key-maps). */
ot->idname = "TEXT_OT_scroll";
/* api callbacks */
@@ -2889,8 +2888,7 @@ void TEXT_OT_scroll_bar(wmOperatorType *ot)
/* identifiers */
ot->name = "Scrollbar";
/* don't really see the difference between this and
- * scroll. Both do basically the same thing (aside
- * from keymaps).*/
+ * scroll. Both do basically the same thing (aside from key-maps). */
ot->idname = "TEXT_OT_scroll_bar";
/* api callbacks */
@@ -3470,7 +3468,7 @@ static int text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int ret;
- /* Note, the "text" property is always set from key-map,
+ /* NOTE: the "text" property is always set from key-map,
* so we can't use #RNA_struct_property_is_set, check the length instead. */
if (!RNA_string_length(op->ptr, "text")) {
/* if alt/ctrl/super are pressed pass through except for utf8 character event
diff --git a/source/blender/editors/space_text/text_undo.c b/source/blender/editors/space_text/text_undo.c
index f55db8c3cc9..80af7d8c9f6 100644
--- a/source/blender/editors/space_text/text_undo.c
+++ b/source/blender/editors/space_text/text_undo.c
@@ -265,7 +265,7 @@ void ED_text_undosys_type(UndoType *ut)
ut->step_foreach_ID_ref = text_undosys_foreach_ID_ref;
- ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE;
+ ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE | UNDOTYPE_FLAG_DECODE_ACTIVE_STEP;
ut->step_size = sizeof(TextUndoStep);
}
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index 9242fc15021..fe84a3b8ae9 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -46,7 +46,6 @@ set(SRC
view3d_camera_control.c
view3d_draw.c
view3d_edit.c
- view3d_fly.c
view3d_gizmo_armature.c
view3d_gizmo_camera.c
view3d_gizmo_empty.c
@@ -60,6 +59,8 @@ set(SRC
view3d_gizmo_tool_generic.c
view3d_header.c
view3d_iterators.c
+ view3d_navigate_fly.c
+ view3d_navigate_walk.c
view3d_ops.c
view3d_placement.c
view3d_project.c
@@ -67,7 +68,6 @@ set(SRC
view3d_snap.c
view3d_utils.c
view3d_view.c
- view3d_walk.c
view3d_intern.h
)
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 660ae9da506..6b9da431510 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -117,10 +117,10 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
return;
}
- Mesh *me = ob->data;
+ const Mesh *me = ob->data;
{
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
+ const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
if (me_eval != NULL) {
me = me_eval;
}
@@ -160,7 +160,7 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
const MPoly *mp;
int i;
if (me->runtime.looptris.array) {
- MLoopTri *mlt = me->runtime.looptris.array;
+ const MLoopTri *mlt = me->runtime.looptris.array;
for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) {
if (facemap_data[i] == facemap) {
for (int j = 2; j < mp->totloop; j++) {
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index b5274c2357e..54f10e259f9 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -187,7 +187,7 @@ bool ED_view3d_area_user_region(const ScrArea *area, const View3D *v3d, ARegion
* view3d_project_short_clip and view3d_project_short_noclip in cases where
* these functions are not used during draw_object
*/
-void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d)
+void ED_view3d_init_mats_rv3d(const struct Object *ob, struct RegionView3D *rv3d)
{
/* local viewmat and persmat, to calculate projections */
mul_m4_m4m4(rv3d->viewmatob, rv3d->viewmat, ob->obmat);
@@ -197,7 +197,7 @@ void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d)
ED_view3d_clipping_local(rv3d, ob->obmat);
}
-void ED_view3d_init_mats_rv3d_gl(struct Object *ob, struct RegionView3D *rv3d)
+void ED_view3d_init_mats_rv3d_gl(const struct Object *ob, struct RegionView3D *rv3d)
{
ED_view3d_init_mats_rv3d(ob, rv3d);
@@ -331,6 +331,8 @@ static void view3d_free(SpaceLink *sl)
MEM_freeN(vd->localvd);
}
+ MEM_SAFE_FREE(vd->runtime.local_stats);
+
if (vd->runtime.properties_storage) {
MEM_freeN(vd->runtime.properties_storage);
}
@@ -346,19 +348,25 @@ static void view3d_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(area))
{
}
+static void view3d_exit(wmWindowManager *UNUSED(wm), ScrArea *area)
+{
+ BLI_assert(area->spacetype == SPACE_VIEW3D);
+ View3D *v3d = area->spacedata.first;
+ MEM_SAFE_FREE(v3d->runtime.local_stats);
+}
+
static SpaceLink *view3d_duplicate(SpaceLink *sl)
{
View3D *v3do = (View3D *)sl;
View3D *v3dn = MEM_dupallocN(sl);
+ memset(&v3dn->runtime, 0x0, sizeof(v3dn->runtime));
+
/* clear or remove stuff from old */
if (v3dn->localvd) {
v3dn->localvd = NULL;
- v3dn->runtime.properties_storage = NULL;
}
- /* Only one View3D is allowed to have this flag! */
- v3dn->runtime.flag &= ~V3D_RUNTIME_XR_SESSION_ROOT;
v3dn->local_collections_uuid = 0;
v3dn->flag &= ~(V3D_LOCAL_COLLECTIONS | V3D_XR_SESSION_MIRROR);
@@ -373,8 +381,6 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
/* copy or clear inside new stuff */
- v3dn->runtime.properties_storage = NULL;
-
return (SpaceLink *)v3dn;
}
@@ -625,6 +631,7 @@ static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, ID_OB);
RNA_string_set(drop->ptr, "name", id->name + 2);
+ RNA_boolean_set(drop->ptr, "duplicate", false);
}
static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
@@ -779,12 +786,6 @@ static void view3d_main_region_free(ARegion *region)
RE_engine_free(rv3d->render_engine);
}
- if (rv3d->depths) {
- if (rv3d->depths->depths) {
- MEM_freeN(rv3d->depths->depths);
- }
- MEM_freeN(rv3d->depths);
- }
if (rv3d->sms) {
MEM_freeN(rv3d->sms);
}
@@ -808,7 +809,6 @@ static void *view3d_main_region_duplicate(void *poin)
new->clipbb = MEM_dupallocN(rv3d->clipbb);
}
- new->depths = NULL;
new->render_engine = NULL;
new->sms = NULL;
new->smooth_timer = NULL;
@@ -1096,7 +1096,7 @@ static void view3d_main_region_message_subscribe(const wmRegionMessageSubscribeP
ScrArea *area = params->area;
ARegion *region = params->region;
- /* Developer note: there are many properties that impact 3D view drawing,
+ /* Developer NOTE: there are many properties that impact 3D view drawing,
* so instead of subscribing to individual properties, just subscribe to types
* accepting some redundant redraws.
*
@@ -1583,7 +1583,7 @@ static void space_view3d_listener(const wmSpaceTypeListenerParams *params)
}
}
-static void space_view3d_refresh(const bContext *C, ScrArea *UNUSED(area))
+static void space_view3d_refresh(const bContext *C, ScrArea *area)
{
Scene *scene = CTX_data_scene(C);
LightCache *lcache = scene->eevee.light_cache_data;
@@ -1592,6 +1592,9 @@ static void space_view3d_refresh(const bContext *C, ScrArea *UNUSED(area))
lcache->flag &= ~LIGHTCACHE_UPDATE_AUTO;
view3d_lightcache_update((bContext *)C);
}
+
+ View3D *v3d = (View3D *)area->spacedata.first;
+ MEM_SAFE_FREE(v3d->runtime.local_stats);
}
const char *view3d_context_dir[] = {
@@ -1614,7 +1617,7 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
* This is ignored in the case the object is in any mode (besides object-mode),
* since the object's mode impacts the current tool, cursor, gizmos etc.
* If we didn't have this exception, changing visibility would need to perform
- * many of the the same updates as changing the objects mode.
+ * many of the same updates as changing the objects mode.
*
* Further, there are multiple ways to hide objects - by collection, by object type, etc.
* it's simplest if all these methods behave consistently - respecting the object-mode
@@ -1699,6 +1702,7 @@ void ED_spacetype_view3d(void)
st->create = view3d_create;
st->free = view3d_free;
st->init = view3d_init;
+ st->exit = view3d_exit;
st->listener = space_view3d_listener;
st->refresh = space_view3d_refresh;
st->duplicate = view3d_duplicate;
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index e42f6b5faac..3428a738dde 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -39,6 +39,8 @@
#include "BLT_translation.h"
+#include "BLI_array_utils.h"
+#include "BLI_bitmap.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -112,10 +114,94 @@ typedef struct {
float ob_dims[3];
/* Floats only (treated as an array). */
TransformMedian ve_median, median;
+ bool tag_for_update;
} TransformProperties;
#define TRANSFORM_MEDIAN_ARRAY_LEN (sizeof(TransformMedian) / sizeof(float))
+static TransformProperties *v3d_transform_props_ensure(View3D *v3d);
+
+/* -------------------------------------------------------------------- */
+/** \name Edit Mesh Partial Updates
+ * \{ */
+
+static void *editmesh_partial_update_begin_fn(struct bContext *UNUSED(C),
+ const struct uiBlockInteraction_Params *params,
+ void *arg1)
+{
+ const int retval_test = B_TRANSFORM_PANEL_MEDIAN;
+ if (BLI_array_findindex(
+ params->unique_retval_ids, params->unique_retval_ids_len, &retval_test) == -1) {
+ return NULL;
+ }
+
+ BMEditMesh *em = arg1;
+
+ int verts_mask_count = 0;
+ BMIter iter;
+ BMVert *eve;
+ int i;
+
+ BLI_bitmap *verts_mask = BLI_BITMAP_NEW(em->bm->totvert, __func__);
+ BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ continue;
+ }
+ BLI_BITMAP_ENABLE(verts_mask, i);
+ verts_mask_count += 1;
+ }
+
+ BMPartialUpdate *bmpinfo = BM_mesh_partial_create_from_verts_group_single(
+ em->bm,
+ &(BMPartialUpdate_Params){
+ .do_tessellate = true,
+ .do_normals = true,
+ },
+ verts_mask,
+ verts_mask_count);
+
+ MEM_freeN(verts_mask);
+
+ return bmpinfo;
+}
+
+static void editmesh_partial_update_end_fn(struct bContext *UNUSED(C),
+ const struct uiBlockInteraction_Params *UNUSED(params),
+ void *UNUSED(arg1),
+ void *user_data)
+{
+ BMPartialUpdate *bmpinfo = user_data;
+ if (bmpinfo == NULL) {
+ return;
+ }
+ BM_mesh_partial_destroy(bmpinfo);
+}
+
+static void editmesh_partial_update_update_fn(
+ struct bContext *C,
+ const struct uiBlockInteraction_Params *UNUSED(params),
+ void *arg1,
+ void *user_data)
+{
+ BMPartialUpdate *bmpinfo = user_data;
+ if (bmpinfo == NULL) {
+ return;
+ }
+
+ View3D *v3d = CTX_wm_view3d(C);
+ TransformProperties *tfp = v3d_transform_props_ensure(v3d);
+ if (tfp->tag_for_update == false) {
+ return;
+ }
+ tfp->tag_for_update = false;
+
+ BMEditMesh *em = arg1;
+
+ BKE_editmesh_looptri_and_normals_calc_with_partial(em, bmpinfo);
+}
+
+/** \} */
+
/* Helper function to compute a median changed value,
* when the value should be clamped in [0.0, 1.0].
* Returns either 0.0, 1.0 (both can be applied directly), a positive scale factor
@@ -840,6 +926,20 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
UI_block_align_end(block);
+
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_mesh;
+ if (em != NULL) {
+ UI_block_interaction_set(block,
+ &(uiBlockInteraction_CallbackData){
+ .begin_fn = editmesh_partial_update_begin_fn,
+ .end_fn = editmesh_partial_update_end_fn,
+ .update_fn = editmesh_partial_update_update_fn,
+ .arg1 = em,
+ });
+ }
+ }
}
else { /* apply */
memcpy(&ve_median_basis, &tfp->ve_median, sizeof(tfp->ve_median));
@@ -927,7 +1027,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
if (apply_vcos) {
- EDBM_mesh_normals_update(em);
+ /* Tell the update callback to run. */
+ tfp->tag_for_update = true;
}
/* Edges */
@@ -1150,7 +1251,7 @@ static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = view_layer->basact->object;
ED_vgroup_vert_active_mirror(ob, event - B_VGRP_PNL_EDIT_SINGLE);
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(ob->data, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
}
@@ -1209,7 +1310,9 @@ static void view3d_panel_vgroup(const bContext *C, Panel *panel)
vgroup_validmap = BKE_object_defgroup_subset_from_select_type(
ob, subset_type, &vgroup_tot, &subset_count);
- for (i = 0, dg = ob->defbase.first; dg; i++, dg = dg->next) {
+ const ListBase *defbase = BKE_object_defgroup_list(ob);
+
+ for (i = 0, dg = defbase->first; dg; i++, dg = dg->next) {
bool locked = (dg->flag & DG_LOCK_WEIGHT) != 0;
if (vgroup_validmap[i]) {
MDeformWeight *dw = BKE_defvert_find_index(dv, i);
@@ -1235,7 +1338,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *panel)
but_ptr = UI_but_operator_ptr_get(but);
RNA_int_set(but_ptr, "weight_group", i);
UI_but_drawflag_enable(but, UI_BUT_TEXT_RIGHT);
- if (ob->actdef != i + 1) {
+ if (BKE_object_defgroup_active_index_get(ob) != i + 1) {
UI_but_flag_enable(but, UI_BUT_INACTIVE);
}
xco += x;
@@ -1462,7 +1565,7 @@ static void v3d_posearmature_buts(uiLayout *layout, Object *ob)
/* XXX: RNA buts show data in native types (i.e. quats, 4-component axis/angle, etc.)
* but old-school UI shows in eulers always. Do we want to be able to still display in Eulers?
- * Maybe needs RNA/ui options to display rotations as different types... */
+ * Maybe needs RNA/UI options to display rotations as different types. */
v3d_transform_butsR(col, &pchanptr);
}
@@ -1566,7 +1669,7 @@ static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event
case B_TRANSFORM_PANEL_MEDIAN:
if (ob) {
v3d_editvertex_buts(NULL, v3d, ob, 1.0);
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(ob->data, ID_RECALC_GEOMETRY);
}
break;
case B_TRANSFORM_PANEL_DIMS:
diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c
index 0edd6aeb2ca..638c8a49ffd 100644
--- a/source/blender/editors/space_view3d/view3d_camera_control.c
+++ b/source/blender/editors/space_view3d/view3d_camera_control.c
@@ -140,7 +140,7 @@ struct View3DCameraControl *ED_view3d_cameracontrol_acquire(Depsgraph *depsgraph
vctrl->persp_backup = rv3d->persp;
vctrl->dist_backup = rv3d->dist;
- /* check for flying ortho camera - which we cant support well
+ /* check for flying ortho camera - which we can't support well
* we _could_ also check for an ortho camera but this is easier */
if ((rv3d->persp == RV3D_CAMOB) && (rv3d->is_persp == false)) {
((Camera *)v3d->camera->data)->type = CAM_PERSP;
@@ -278,7 +278,7 @@ void ED_view3d_cameracontrol_update(View3DCameraControl *vctrl,
mul_m4_m4m4(parent_mat, diff_mat, vctrl->root_parent->obmat);
if (object_apply_mat4_with_protect(vctrl->root_parent, parent_mat, false, rv3d, view_mat)) {
- /* Calculate again since the view locking changes the matrix. */
+ /* Calculate again since the view locking changes the matrix. */
ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 1ef37ba4f9b..c97ba7ba7e9 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -140,7 +140,7 @@ void ED_view3d_update_viewmat(Depsgraph *depsgraph,
rect_scale[0] = (float)BLI_rcti_size_x(rect) / (float)region->winx;
rect_scale[1] = (float)BLI_rcti_size_y(rect) / (float)region->winy;
}
- /* note: calls BKE_object_where_is_calc for camera... */
+ /* NOTE: calls BKE_object_where_is_calc for camera... */
view3d_viewmatrix_set(depsgraph, scene, v3d, rv3d, rect ? rect_scale : NULL);
}
/* update utility matrices */
@@ -167,7 +167,7 @@ void ED_view3d_update_viewmat(Depsgraph *depsgraph,
/* Calculate pixel-size factor once, this is used for lights and object-centers. */
{
- /* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
+ /* NOTE: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
* because of float point precision problems at large values T23908. */
float v1[3], v2[3];
float len_px, len_sc;
@@ -563,10 +563,10 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region,
/* apply offsets so the real 3D camera shows through */
- /* note: quite un-scientific but without this bit extra
+ /* NOTE: quite un-scientific but without this bit extra
* 0.0001 on the lower left the 2D border sometimes
* obscures the 3D camera border */
- /* note: with VIEW3D_CAMERA_BORDER_HACK defined this error isn't noticeable
+ /* NOTE: with VIEW3D_CAMERA_BORDER_HACK defined this error isn't noticeable
* but keep it here in case we need to remove the workaround */
x1i = (int)(x1 - 1.0001f);
y1i = (int)(y1 - 1.0001f);
@@ -780,7 +780,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region,
/* draw */
immUniformThemeColorShadeAlpha(TH_VIEW_OVERLAY, 100, 255);
- /* TODO Was using:
+ /* TODO: Was using:
* UI_draw_roundbox_4fv(false, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f, color);
* We'll probably need a new imm_draw_line_roundbox_dashed dor that - though in practice the
* 2.0f round corner effect was nearly not visible anyway... */
@@ -1159,7 +1159,7 @@ static void view3d_draw_border(const bContext *C, ARegion *region)
*/
static void view3d_draw_grease_pencil(const bContext *UNUSED(C))
{
- /* TODO viewport */
+ /* TODO: viewport. */
}
/**
@@ -1404,7 +1404,7 @@ static void draw_selected_name(
/* color depends on whether there is a keyframe */
if (id_frame_has_keyframe(
- (ID *)ob, /* BKE_scene_frame_get(scene) */ (float)cfra, ANIMFILTER_KEYS_LOCAL)) {
+ (ID *)ob, /* BKE_scene_ctime_get(scene) */ (float)cfra, ANIMFILTER_KEYS_LOCAL)) {
UI_FontThemeColor(font_id, TH_TIME_KEYFRAME);
}
else if (ED_gpencil_has_keyframe_v3d(scene, ob, cfra)) {
@@ -1537,7 +1537,9 @@ void view3d_draw_region_info(const bContext *C, ARegion *region)
}
if ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 && (v3d->overlay.flag & V3D_OVERLAY_STATS)) {
- ED_info_draw_stats(bmain, scene, view_layer, xoffset, &yoffset, VIEW3D_OVERLAY_LINEHEIGHT);
+ View3D *v3d_local = v3d->localvd ? v3d : NULL;
+ ED_info_draw_stats(
+ bmain, scene, view_layer, v3d_local, xoffset, &yoffset, VIEW3D_OVERLAY_LINEHEIGHT);
}
BLF_batch_draw_end();
@@ -2022,7 +2024,6 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
source_shading_settings = shading_override;
}
memcpy(&v3d.shading, source_shading_settings, sizeof(View3DShading));
- v3d.shading.type = drawtype;
if (drawtype == OB_MATERIAL) {
v3d.shading.flag = V3D_SHADING_SCENE_WORLD | V3D_SHADING_SCENE_LIGHTS;
@@ -2032,8 +2033,17 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
v3d.shading.flag = V3D_SHADING_SCENE_WORLD_RENDER | V3D_SHADING_SCENE_LIGHTS_RENDER;
v3d.shading.render_pass = SCE_PASS_COMBINED;
}
+ else if (drawtype == OB_TEXTURE) {
+ drawtype = OB_SOLID;
+ v3d.shading.light = V3D_LIGHTING_STUDIO;
+ v3d.shading.color_type = V3D_SHADING_TEXTURE_COLOR;
+ }
+ v3d.shading.type = drawtype;
v3d.flag2 = V3D_HIDE_OVERLAYS;
+ /* HACK: When rendering gpencil objects this opacity is used to mix vertex colors in when not in
+ * render mode. */
+ v3d.overlay.gpencil_vertex_paint_opacity = 1.0f;
if (draw_flags & V3D_OFSDRAW_SHOW_ANNOTATION) {
v3d.flag2 |= V3D_SHOW_ANNOTATION;
@@ -2072,7 +2082,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
return ED_view3d_draw_offscreen_imbuf(depsgraph,
scene,
- drawtype,
+ v3d.shading.type,
&v3d,
&region,
width,
@@ -2211,7 +2221,7 @@ int ED_view3d_backbuf_sample_size_clamp(ARegion *region, const float dist)
/** \name Z-Depth Utilities
* \{ */
-void view3d_update_depths_rect(ARegion *region, ViewDepths *d, rcti *rect)
+void view3d_depths_rect_create(ARegion *region, rcti *rect, ViewDepths *r_d)
{
/* clamp rect by region */
rcti r = {
@@ -2232,70 +2242,44 @@ void view3d_update_depths_rect(ARegion *region, ViewDepths *d, rcti *rect)
int h = BLI_rcti_size_y(rect);
if (w <= 0 || h <= 0) {
- if (d->depths) {
- MEM_freeN(d->depths);
- }
- d->depths = NULL;
-
- d->damaged = false;
+ r_d->depths = NULL;
+ return;
}
- else if (d->w != w || d->h != h || d->x != x || d->y != y || d->depths == NULL) {
- d->x = x;
- d->y = y;
- d->w = w;
- d->h = h;
- if (d->depths) {
- MEM_freeN(d->depths);
- }
+ r_d->x = x;
+ r_d->y = y;
+ r_d->w = w;
+ r_d->h = h;
- d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths Subset");
+ r_d->depths = MEM_mallocN(sizeof(float) * w * h, "View depths Subset");
- d->damaged = true;
- }
-
- if (d->damaged) {
+ {
GPUViewport *viewport = WM_draw_region_get_viewport(region);
- view3d_opengl_read_Z_pixels(viewport, rect, d->depths);
+ view3d_opengl_read_Z_pixels(viewport, rect, r_d->depths);
/* Range is assumed to be this as they are never changed. */
- d->depth_range[0] = 0.0;
- d->depth_range[1] = 1.0;
- d->damaged = false;
+ r_d->depth_range[0] = 0.0;
+ r_d->depth_range[1] = 1.0;
}
}
-/* Note, with nouveau drivers the glReadPixels() is very slow. T24339. */
-static void view3d_depth_cache_update(ARegion *region)
+/* NOTE: with nouveau drivers the glReadPixels() is very slow. T24339. */
+static ViewDepths *view3d_depths_create(ARegion *region)
{
- RegionView3D *rv3d = region->regiondata;
+ ViewDepths *d = MEM_callocN(sizeof(ViewDepths), "ViewDepths");
+ d->w = region->winx;
+ d->h = region->winy;
+ d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths");
- /* Create storage for, and, if necessary, copy depth buffer. */
- if (!rv3d->depths) {
- rv3d->depths = MEM_callocN(sizeof(ViewDepths), "ViewDepths");
- }
- if (rv3d->depths) {
- ViewDepths *d = rv3d->depths;
- if (d->w != region->winx || d->h != region->winy || !d->depths) {
- d->w = region->winx;
- d->h = region->winy;
- if (d->depths) {
- MEM_freeN(d->depths);
- }
- d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths");
- d->damaged = true;
- }
-
- if (d->damaged) {
- GPUViewport *viewport = WM_draw_region_get_viewport(region);
- DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport);
- GPU_framebuffer_read_depth(fbl->depth_only_fb, 0, 0, d->w, d->h, GPU_DATA_FLOAT, d->depths);
+ {
+ GPUViewport *viewport = WM_draw_region_get_viewport(region);
+ DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport);
+ GPU_framebuffer_read_depth(fbl->depth_only_fb, 0, 0, d->w, d->h, GPU_DATA_FLOAT, d->depths);
- /* Assumed to be this as they are never changed. */
- d->depth_range[0] = 0.0;
- d->depth_range[1] = 1.0;
- d->damaged = false;
- }
+ /* Assumed to be this as they are never changed. */
+ d->depth_range[0] = 0.0;
+ d->depth_range[1] = 1.0;
}
+ return d;
}
/* Utility function to find the closest Z value, use for auto-depth. */
@@ -2335,10 +2319,13 @@ void ED_view3d_depth_override(Depsgraph *depsgraph,
View3D *v3d,
Object *obact,
eV3DDepthOverrideMode mode,
- bool update_cache)
+ ViewDepths **r_depths)
{
if (v3d->runtime.flag & V3D_RUNTIME_DEPTHBUF_OVERRIDDEN) {
- return;
+ /* Force redraw if `r_depths` is required. */
+ if (!r_depths || *r_depths != NULL) {
+ return;
+ }
}
struct bThemeState theme_state;
Scene *scene = DEG_get_evaluated_scene(depsgraph);
@@ -2380,12 +2367,11 @@ void ED_view3d_depth_override(Depsgraph *depsgraph,
break;
}
- if (rv3d->depths != NULL) {
- rv3d->depths->damaged = true;
- /* TODO: Clear cache? */
- }
- if (update_cache) {
- view3d_depth_cache_update(region);
+ if (r_depths) {
+ if (*r_depths) {
+ ED_view3d_depths_free(*r_depths);
+ }
+ *r_depths = view3d_depths_create(region);
}
}
@@ -2399,6 +2385,14 @@ void ED_view3d_depth_override(Depsgraph *depsgraph,
UI_Theme_Restore(&theme_state);
}
+void ED_view3d_depths_free(ViewDepths *depths)
+{
+ if (depths->depths) {
+ MEM_freeN(depths->depths);
+ }
+ MEM_freeN(depths);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 967ad966320..651ae8a3000 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -392,9 +392,9 @@ enum eViewOpsFlag {
/** When enabled, use the depth under the cursor for navigation. */
VIEWOPS_FLAG_DEPTH_NAVIGATE = (1 << 1),
/**
- * When enabled run #ED_view3d_persp_ensure this may switch out of
- * camera view when orbiting or switch from ortho to perspective when auto-persp is enabled.
- * Some operations don't require this (view zoom/pan or ndof where subtle rotation is common
+ * When enabled run #ED_view3d_persp_ensure this may switch out of camera view
+ * when orbiting or switch from orthographic to perspective when auto-perspective is enabled.
+ * Some operations don't require this (view zoom/pan or NDOF where subtle rotation is common
* so we don't want it to trigger auto-perspective). */
VIEWOPS_FLAG_PERSP_ENSURE = (1 << 2),
/** When set, ignore any options that depend on initial cursor location. */
@@ -509,7 +509,7 @@ static void viewops_data_create(bContext *C,
negate_v3_v3(my_origin, rv3d->ofs); /* ofs is flipped */
/* Set the dist value to be the distance from this 3d point this means you'll
- * always be able to zoom into it and panning wont go bad when dist was zero. */
+ * always be able to zoom into it and panning won't go bad when dist was zero. */
/* remove dist value */
upvec[0] = upvec[1] = 0;
@@ -611,7 +611,7 @@ enum {
VIEWROT_MODAL_SWITCH_ROTATE = 6,
};
-/* called in transform_ops.c, on each regeneration of keymaps */
+/* Called in transform_ops.c, on each regeneration of key-maps. */
void viewrotate_modal_keymap(wmKeyConfig *keyconf)
{
static const EnumPropertyItem modal_items[] = {
@@ -813,7 +813,6 @@ static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2])
viewrotate_apply_dyn_ofs(vod, vod->curr.viewquat);
}
else {
- /* New turntable view code by John Aughey */
float quat_local_x[4], quat_global_z[4];
float m[3][3];
float m_inv[3][3];
@@ -894,8 +893,8 @@ static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2])
* rotation back into the view we calculate with */
copy_qt_qt(rv3d->viewquat, vod->curr.viewquat);
- /* check for view snap,
- * note: don't apply snap to vod->viewquat so the view wont jam up */
+ /* Check for view snap,
+ * NOTE: don't apply snap to `vod->viewquat` so the view won't jam up. */
if (vod->axis_snap) {
viewrotate_apply_snap(vod);
}
@@ -953,7 +952,6 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else if (event_code == VIEW_CONFIRM) {
- ED_view3d_depth_tag_update(vod->rv3d);
use_autokey = true;
ret = OPERATOR_FINISHED;
}
@@ -1014,7 +1012,6 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
viewrotate_apply(vod, event_xy);
- ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
@@ -1203,7 +1200,7 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof,
if (U.ndof_flag & NDOF_TURNTABLE) {
float rot[3];
- /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
+ /* Turntable view code adapted for 3D mouse use. */
float angle, quat[4];
float xvec[3] = {1, 0, 0};
@@ -1508,7 +1505,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
}
}
else {
- /* Note: based on feedback from T67579, users want to have pan and orbit enabled at once.
+ /* NOTE: based on feedback from T67579, users want to have pan and orbit enabled at once.
* It's arguable that orbit shouldn't pan (since we have a pan only operator),
* so if there are users who like to separate orbit/pan operations - it can be a preference. */
const bool is_orbit_around_pivot = (U.ndof_flag & NDOF_MODE_ORBIT) ||
@@ -1688,7 +1685,7 @@ void VIEW3D_OT_ndof_all(struct wmOperatorType *ot)
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
-/* called in transform_ops.c, on each regeneration of keymaps */
+/* Called in transform_ops.c, on each regeneration of key-maps. */
void viewmove_modal_keymap(wmKeyConfig *keyconf)
{
static const EnumPropertyItem modal_items[] = {
@@ -1799,7 +1796,6 @@ static int viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else if (event_code == VIEW_CONFIRM) {
- ED_view3d_depth_tag_update(vod->rv3d);
use_autokey = true;
ret = OPERATOR_FINISHED;
}
@@ -1840,7 +1836,6 @@ static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (event->type == MOUSEPAN) {
/* invert it, trackpad scroll follows same principle as 2d windows this way */
viewmove_apply(vod, 2 * event->x - event->prevx, 2 * event->y - event->prevy);
- ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
@@ -1885,8 +1880,8 @@ void VIEW3D_OT_move(wmOperatorType *ot)
/** \name View Zoom Operator
* \{ */
-/* viewdolly_modal_keymap has an exact copy of this, apply fixes to both */
-/* called in transform_ops.c, on each regeneration of keymaps */
+/* #viewdolly_modal_keymap has an exact copy of this, apply fixes to both. */
+/* Called in transform_ops.c, on each regeneration of key-maps. */
void viewzoom_modal_keymap(wmKeyConfig *keyconf)
{
static const EnumPropertyItem modal_items[] = {
@@ -2254,7 +2249,6 @@ static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else if (event_code == VIEW_CONFIRM) {
- ED_view3d_depth_tag_update(vod->rv3d);
use_autokey = true;
ret = OPERATOR_FINISHED;
}
@@ -2341,8 +2335,6 @@ static int viewzoom_exec(bContext *C, wmOperator *op)
view3d_boxview_sync(area, region);
}
- ED_view3d_depth_tag_update(rv3d);
-
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
ED_view3d_camera_lock_autokey(v3d, rv3d, C, false, true);
@@ -2398,8 +2390,6 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
(use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)));
ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
- ED_view3d_depth_tag_update(vod->rv3d);
-
viewops_data_free(C, op);
return OPERATOR_FINISHED;
}
@@ -2454,8 +2444,8 @@ void VIEW3D_OT_zoom(wmOperatorType *ot)
* which avoids #RegionView3D.dist approaching zero.
* \{ */
-/* this is an exact copy of viewzoom_modal_keymap */
-/* called in transform_ops.c, on each regeneration of keymaps */
+/* This is an exact copy of #viewzoom_modal_keymap. */
+/* Called in transform_ops.c, on each regeneration of key-maps. */
void viewdolly_modal_keymap(wmKeyConfig *keyconf)
{
static const EnumPropertyItem modal_items[] = {
@@ -2579,7 +2569,6 @@ static int viewdolly_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else if (event_code == VIEW_CONFIRM) {
- ED_view3d_depth_tag_update(vod->rv3d);
use_autokey = true;
ret = OPERATOR_FINISHED;
}
@@ -2636,8 +2625,6 @@ static int viewdolly_exec(bContext *C, wmOperator *op)
view3d_boxview_sync(area, region);
}
- ED_view3d_depth_tag_update(rv3d);
-
ED_view3d_camera_lock_sync(CTX_data_ensure_evaluated_depsgraph(C), v3d, rv3d);
ED_region_tag_redraw(region);
@@ -2718,7 +2705,6 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
event->prevx;
}
viewdolly_apply(vod, &event->prevx, (U.uiflag & USER_ZOOM_INVERT) == 0);
- ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
return OPERATOR_FINISHED;
@@ -2968,7 +2954,7 @@ static int view3d_all_exec(bContext *C, wmOperator *op)
if (!changed) {
ED_region_tag_redraw(region);
- /* TODO - should this be cancel?
+ /* TODO: should this be cancel?
* I think no, because we always move the cursor, with or without
* object, but in this case there is no change in the scene,
* only the cursor so I choice a ED_region_tag like
@@ -3617,7 +3603,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
float depth_close = FLT_MAX;
float cent[2], p[3];
- /* note; otherwise opengl won't work */
+ /* NOTE: otherwise opengl won't work. */
view3d_operator_needs_opengl(C);
/* get box select values using rna */
@@ -3629,13 +3615,13 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
ED_view3d_dist_range_get(v3d, dist_range);
ED_view3d_depth_override(
- CTX_data_ensure_evaluated_depsgraph(C), region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, false);
+ CTX_data_ensure_evaluated_depsgraph(C), region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, NULL);
{
/* avoid allocating the whole depth buffer */
ViewDepths depth_temp = {0};
/* avoid view3d_update_depths() for speed. */
- view3d_update_depths_rect(region, &depth_temp, &rect);
+ view3d_depths_rect_create(region, &rect, &depth_temp);
/* find the closest Z pixel */
depth_close = view3d_depth_near(&depth_temp);
@@ -3660,14 +3646,14 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
if (rv3d->is_persp) {
float p_corner[3];
- /* no depths to use, we cant do anything! */
+ /* no depths to use, we can't do anything! */
if (depth_close == FLT_MAX) {
BKE_report(op->reports, RPT_ERROR, "Depth too large");
return OPERATOR_CANCELLED;
}
/* convert border to 3d coordinates */
- if ((!ED_view3d_unproject(region, cent[0], cent[1], depth_close, p)) ||
- (!ED_view3d_unproject(region, rect.xmin, rect.ymin, depth_close, p_corner))) {
+ if ((!ED_view3d_unproject_v3(region, cent[0], cent[1], depth_close, p)) ||
+ (!ED_view3d_unproject_v3(region, rect.xmin, rect.ymin, depth_close, p_corner))) {
return OPERATOR_CANCELLED;
}
@@ -3690,7 +3676,8 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
new_dist = rv3d->dist;
/* convert the drawn rectangle into 3d space */
- if (depth_close != FLT_MAX && ED_view3d_unproject(region, cent[0], cent[1], depth_close, p)) {
+ if (depth_close != FLT_MAX &&
+ ED_view3d_unproject_v3(region, cent[0], cent[1], depth_close, p)) {
negate_v3_v3(new_ofs, p);
}
else {
@@ -4432,7 +4419,6 @@ static int viewroll_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else if (event_code == VIEW_CONFIRM) {
- ED_view3d_depth_tag_update(vod->rv3d);
use_autokey = true;
ret = OPERATOR_FINISHED;
}
@@ -4540,7 +4526,6 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (event->type == MOUSEROTATE) {
vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x;
viewroll_apply(vod, event->prevx, event->prevy);
- ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
return OPERATOR_FINISHED;
@@ -4637,7 +4622,6 @@ static int viewpan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
viewmove_apply(vod, vod->prev.event_xy[0] + x, vod->prev.event_xy[1] + y);
- ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
return OPERATOR_FINISHED;
@@ -4803,7 +4787,7 @@ static bool background_image_add_poll(bContext *C)
void VIEW3D_OT_background_image_add(wmOperatorType *ot)
{
/* identifiers */
- /* note: having key shortcut here is bad practice,
+ /* NOTE: having key shortcut here is bad practice,
* but for now keep because this displays when dragging an image over the 3D viewport */
ot->name = "Add Background Image";
ot->description = "Add a new background image";
@@ -4972,7 +4956,7 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot)
* \{ */
/* cursor position in vec, result in vec, mval in region coords */
-/* note: cannot use event->mval here (called by object_add() */
+/* NOTE: cannot use `event->mval` here, called by #object_add(). */
void ED_view3d_cursor3d_position(bContext *C,
const int mval[2],
const bool use_depth,
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_armature.c b/source/blender/editors/space_view3d/view3d_gizmo_armature.c
index 4d8102af6ff..83d3286c8b3 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_armature.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_armature.c
@@ -86,12 +86,12 @@ static void gizmo_bbone_offset_get(const wmGizmo *UNUSED(gz),
if (bh->index == 0) {
bh->co[1] = pchan->bone->ease1 / BBONE_SCALE_Y;
bh->co[0] = pchan->curve_in_x;
- bh->co[2] = pchan->curve_in_y;
+ bh->co[2] = pchan->curve_in_z;
}
else {
bh->co[1] = -pchan->bone->ease2 / BBONE_SCALE_Y;
bh->co[0] = pchan->curve_out_x;
- bh->co[2] = pchan->curve_out_y;
+ bh->co[2] = pchan->curve_out_z;
}
copy_v3_v3(value, bh->co);
}
@@ -111,12 +111,12 @@ static void gizmo_bbone_offset_set(const wmGizmo *UNUSED(gz),
if (bh->index == 0) {
pchan->bone->ease1 = max_ff(0.0f, bh->co[1] * BBONE_SCALE_Y);
pchan->curve_in_x = bh->co[0];
- pchan->curve_in_y = bh->co[2];
+ pchan->curve_in_z = bh->co[2];
}
else {
pchan->bone->ease2 = max_ff(0.0f, -bh->co[1] * BBONE_SCALE_Y);
pchan->curve_out_x = bh->co[0];
- pchan->curve_out_y = bh->co[2];
+ pchan->curve_out_z = bh->co[2];
}
}
@@ -199,7 +199,7 @@ static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmGizmoGroup
mul_m4_m4m4(mat, ob->obmat, (i == 0) ? pchan->disp_mat : pchan->disp_tail_mat);
copy_m4_m4(gz->matrix_space, mat);
- /* need to set property here for undo. TODO would prefer to do this in _init */
+ /* need to set property here for undo. TODO: would prefer to do this in _init. */
WM_gizmo_target_property_def_func(gz,
"offset",
&(const struct wmGizmoPropertyFnParams){
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_camera.c b/source/blender/editors/space_view3d/view3d_gizmo_camera.c
index 20d766357e8..e1d439bef15 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_camera.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_camera.c
@@ -153,7 +153,7 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *gzgroup)
WM_gizmo_set_scale(cagzgroup->dop_dist, ca->drawsize);
WM_gizmo_set_flag(cagzgroup->dop_dist, WM_GIZMO_HIDDEN, false);
- /* Need to set property here for undo. TODO would prefer to do this in _init */
+ /* Need to set property here for undo. TODO: would prefer to do this in _init. */
PointerRNA camera_dof_ptr;
RNA_pointer_create(&ca->id, &RNA_CameraDOFSettings, &ca->dof, &camera_dof_ptr);
WM_gizmo_target_property_def_rna(
@@ -163,7 +163,7 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *gzgroup)
WM_gizmo_set_flag(cagzgroup->dop_dist, WM_GIZMO_HIDDEN, true);
}
- /* TODO - make focal length/ortho ob_scale_inv widget optional */
+ /* TODO: make focal length/ortho ob_scale_inv widget optional. */
const Scene *scene = CTX_data_scene(C);
const float aspx = (float)scene->r.xsch * scene->r.xasp;
const float aspy = (float)scene->r.ysch * scene->r.yasp;
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_light.c b/source/blender/editors/space_view3d/view3d_gizmo_light.c
index 5bf105b6775..d92ebfd57a8 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_light.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_light.c
@@ -99,7 +99,7 @@ static void WIDGETGROUP_light_spot_refresh(const bContext *C, wmGizmoGroup *gzgr
WM_gizmo_set_matrix_rotation_from_z_axis(gz, dir);
WM_gizmo_set_matrix_location(gz, ob->obmat[3]);
- /* need to set property here for undo. TODO would prefer to do this in _init */
+ /* need to set property here for undo. TODO: would prefer to do this in _init. */
PointerRNA lamp_ptr;
const char *propname = "spot_size";
RNA_pointer_create(&la->id, &RNA_Light, la, &lamp_ptr);
@@ -212,7 +212,7 @@ static void WIDGETGROUP_light_area_refresh(const bContext *C, wmGizmoGroup *gzgr
}
RNA_enum_set(gz->ptr, "transform", flag);
- /* need to set property here for undo. TODO would prefer to do this in _init */
+ /* need to set property here for undo. TODO: would prefer to do this in _init. */
WM_gizmo_target_property_def_func(gz,
"matrix",
&(const struct wmGizmoPropertyFnParams){
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
index 298a2a7a824..07c3b6bd1d8 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
@@ -154,10 +154,10 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int
* Only pre-select a vertex when the cursor is really close to it. */
if (eve_test) {
BMVert *vert = (BMVert *)eve_test;
- float vert_p_co[3], vert_co[3];
+ float vert_p_co[2], vert_co[3];
const float mval_f[2] = {UNPACK2(vc.mval)};
mul_v3_m4v3(vert_co, gz_ele->bases[base_index_vert]->object->obmat, vert->co);
- ED_view3d_project(vc.region, vert_co, vert_p_co);
+ ED_view3d_project_v2(vc.region, vert_co, vert_p_co);
float len = len_v2v2(vert_p_co, mval_f);
if (len < 35) {
best.ele = (BMElem *)eve_test;
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
index 0d568363b00..49299d73337 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
@@ -580,7 +580,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
UI_GetThemeColor3ubv(TH_TEXT, color_text);
UI_GetThemeColor3ubv(TH_WIRE, color_wire);
- /* Avoid white on white text. (TODO Fix by using theme) */
+ /* Avoid white on white text. (TODO: Fix by using theme). */
if ((int)color_text[0] + (int)color_text[1] + (int)color_text[2] > 127 * 3 * 0.6f) {
copy_v3_fl(color_back, 0.0f);
}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 6f07cb8b44d..ab80928e0c1 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -111,11 +111,11 @@ void view3d_ndof_fly(const struct wmNDOFMotionData *ndof,
bool *r_has_rotate);
#endif /* WITH_INPUT_NDOF */
-/* view3d_fly.c */
+/* view3d_navigate_fly.c */
void view3d_keymap(struct wmKeyConfig *keyconf);
void VIEW3D_OT_fly(struct wmOperatorType *ot);
-/* view3d_walk.c */
+/* view3d_navigate_walk.c */
void VIEW3D_OT_walk(struct wmOperatorType *ot);
/* view3d_draw.c */
@@ -137,7 +137,7 @@ void ED_view3d_draw_depth_loop(struct Depsgraph *depsgraph,
struct ARegion *region,
View3D *v3d);
-void view3d_update_depths_rect(struct ARegion *region, struct ViewDepths *d, struct rcti *rect);
+void view3d_depths_rect_create(struct ARegion *region, struct rcti *rect, struct ViewDepths *r_d);
float view3d_depth_near(struct ViewDepths *d);
/* view3d_select.c */
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index bdb2c3874db..c7a4030c402 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -50,15 +50,179 @@
#include "ED_screen.h"
#include "ED_view3d.h"
+/* -------------------------------------------------------------------- */
+/** \name Internal Clipping Utilities
+ * \{ */
+
+/**
+ * Calculate clipping planes to use when #V3D_PROJ_TEST_CLIP_CONTENT is enabled.
+ *
+ * Planes are selected from the viewpoint using `clip_flag`
+ * to detect which planes should be applied (maximum 6).
+ *
+ * \return The number of planes written into `planes`.
+ */
+static int content_planes_from_clip_flag(const ARegion *region,
+ const Object *ob,
+ const eV3DProjTest clip_flag,
+ float planes[6][4])
+{
+ BLI_assert(clip_flag & V3D_PROJ_TEST_CLIP_CONTENT);
+
+ float *clip_xmin = NULL, *clip_xmax = NULL;
+ float *clip_ymin = NULL, *clip_ymax = NULL;
+ float *clip_zmin = NULL, *clip_zmax = NULL;
+
+ int planes_len = 0;
+
+ /* The order of `planes` has been selected based on the likelihood of points being fully
+ * outside the plane to increase the chance of an early exit in #clip_segment_v3_plane_n.
+ * With "near" being most likely and "far" being unlikely.
+ *
+ * Otherwise the order of axes in `planes` isn't significant. */
+
+ if (clip_flag & V3D_PROJ_TEST_CLIP_NEAR) {
+ clip_zmin = planes[planes_len++];
+ }
+ if (clip_flag & V3D_PROJ_TEST_CLIP_WIN) {
+ clip_xmin = planes[planes_len++];
+ clip_xmax = planes[planes_len++];
+ clip_ymin = planes[planes_len++];
+ clip_ymax = planes[planes_len++];
+ }
+ if (clip_flag & V3D_PROJ_TEST_CLIP_FAR) {
+ clip_zmax = planes[planes_len++];
+ }
+
+ BLI_assert(planes_len <= 6);
+ if (planes_len != 0) {
+ RegionView3D *rv3d = region->regiondata;
+ float projmat[4][4];
+ ED_view3d_ob_project_mat_get(rv3d, ob, projmat);
+ planes_from_projmat(projmat, clip_xmin, clip_xmax, clip_ymin, clip_ymax, clip_zmin, clip_zmax);
+ }
+ return planes_len;
+}
+
+/**
+ * Edge projection is more involved since part of the edge may be behind the view
+ * or extend beyond the far limits. In the case of single points, these can be ignored.
+ * However it just may still be visible on screen, so constrained the edge to planes
+ * defined by the port to ensure both ends of the edge can be projected, see T32214.
+ *
+ * \note This is unrelated to #V3D_PROJ_TEST_CLIP_BB which must be checked separately.
+ */
+static bool view3d_project_segment_to_screen_with_content_clip_planes(
+ const ARegion *region,
+ const float v_a[3],
+ const float v_b[3],
+ const eV3DProjTest clip_flag,
+ const rctf *win_rect,
+ const float content_planes[][4],
+ const int content_planes_len,
+ /* Output. */
+ float r_screen_co_a[2],
+ float r_screen_co_b[2])
+{
+ /* Clipping already handled, no need to check in projection. */
+ eV3DProjTest clip_flag_nowin = clip_flag & ~V3D_PROJ_TEST_CLIP_WIN;
+
+ const eV3DProjStatus status_a = ED_view3d_project_float_object(
+ region, v_a, r_screen_co_a, clip_flag_nowin);
+ const eV3DProjStatus status_b = ED_view3d_project_float_object(
+ region, v_b, r_screen_co_b, clip_flag_nowin);
+
+ if ((status_a == V3D_PROJ_RET_OK) && (status_b == V3D_PROJ_RET_OK)) {
+ if (clip_flag & V3D_PROJ_TEST_CLIP_WIN) {
+ if (!BLI_rctf_isect_segment(win_rect, r_screen_co_a, r_screen_co_b)) {
+ return false;
+ }
+ }
+ }
+ else {
+ if (content_planes_len == 0) {
+ return false;
+ }
+
+ /* Both too near, ignore. */
+ if ((status_a & V3D_PROJ_TEST_CLIP_NEAR) && (status_b & V3D_PROJ_TEST_CLIP_NEAR)) {
+ return false;
+ }
+
+ /* Both too far, ignore. */
+ if ((status_a & V3D_PROJ_TEST_CLIP_FAR) && (status_b & V3D_PROJ_TEST_CLIP_FAR)) {
+ return false;
+ }
+
+ /* Simple cases have been ruled out, clip by viewport planes, then re-project. */
+ float v_a_clip[3], v_b_clip[3];
+ if (!clip_segment_v3_plane_n(
+ v_a, v_b, content_planes, content_planes_len, v_a_clip, v_b_clip)) {
+ return false;
+ }
+
+ if ((ED_view3d_project_float_object(region, v_a_clip, r_screen_co_a, clip_flag_nowin) !=
+ V3D_PROJ_RET_OK) ||
+ (ED_view3d_project_float_object(region, v_b_clip, r_screen_co_b, clip_flag_nowin) !=
+ V3D_PROJ_RET_OK)) {
+ return false;
+ }
+
+ /* No need for #V3D_PROJ_TEST_CLIP_WIN check here,
+ * clipping the segment by planes handle this. */
+ }
+
+ return true;
+}
+
+/**
+ * Project an edge, points that fail to project are tagged with #IS_CLIPPED.
+ */
+static bool view3d_project_segment_to_screen_with_clip_tag(const ARegion *region,
+ const float v_a[3],
+ const float v_b[3],
+ const eV3DProjTest clip_flag,
+ /* Output. */
+ float r_screen_co_a[2],
+ float r_screen_co_b[2])
+{
+ int count = 0;
+
+ if (ED_view3d_project_float_object(region, v_a, r_screen_co_a, clip_flag) == V3D_PROJ_RET_OK) {
+ count++;
+ }
+ else {
+ r_screen_co_a[0] = IS_CLIPPED; /* weak */
+ /* screen_co_a[1]: intentionally don't set this so we get errors on misuse */
+ }
+
+ if (ED_view3d_project_float_object(region, v_b, r_screen_co_b, clip_flag) == V3D_PROJ_RET_OK) {
+ count++;
+ }
+ else {
+ r_screen_co_b[0] = IS_CLIPPED; /* weak */
+ /* screen_co_b[1]: intentionally don't set this so we get errors on misuse */
+ }
+
+ /* Caller may want to know this value, for now it's not needed. */
+ return count != 0;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Private User Data Structures
+ * \{ */
+
typedef struct foreachScreenObjectVert_userData {
- void (*func)(void *userData, MVert *mv, const float screen_co_b[2], int index);
+ void (*func)(void *userData, MVert *mv, const float screen_co[2], int index);
void *userData;
ViewContext vc;
eV3DProjTest clip_flag;
} foreachScreenObjectVert_userData;
typedef struct foreachScreenVert_userData {
- void (*func)(void *userData, BMVert *eve, const float screen_co_b[2], int index);
+ void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index);
void *userData;
ViewContext vc;
eV3DProjTest clip_flag;
@@ -73,8 +237,16 @@ typedef struct foreachScreenEdge_userData {
int index);
void *userData;
ViewContext vc;
- rctf win_rect; /* copy of: vc.region->winx/winy, use for faster tests, minx/y will always be 0 */
eV3DProjTest clip_flag;
+
+ rctf win_rect; /* copy of: vc.region->winx/winy, use for faster tests, minx/y will always be 0 */
+
+ /**
+ * Clip plans defined by the view bounds,
+ * use when #V3D_PROJ_TEST_CLIP_CONTENT is enabled.
+ */
+ float content_planes[6][4];
+ int content_planes_len;
} foreachScreenEdge_userData;
typedef struct foreachScreenFace_userData {
@@ -91,7 +263,11 @@ typedef struct foreachScreenFace_userData {
* use the object matrix in the usual way.
*/
-/* ------------------------------------------------------------------------ */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edit-Mesh: For Each Screen Vertex
+ * \{ */
static void meshobject_foreachScreenVert__mapFunc(void *userData,
int index,
@@ -120,6 +296,7 @@ void meshobject_foreachScreenVert(
void *userData,
eV3DProjTest clip_flag)
{
+ BLI_assert((clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) == 0);
foreachScreenObjectVert_userData data;
Mesh *me;
@@ -150,17 +327,17 @@ static void mesh_foreachScreenVert__mapFunc(void *userData,
{
foreachScreenVert_userData *data = userData;
BMVert *eve = BM_vert_at_index(data->vc.em->bm, index);
+ if (UNLIKELY(BM_elem_flag_test(eve, BM_ELEM_HIDDEN))) {
+ return;
+ }
- if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- float screen_co[2];
-
- if (ED_view3d_project_float_object(data->vc.region, co, screen_co, data->clip_flag) !=
- V3D_PROJ_RET_OK) {
- return;
- }
-
- data->func(data->userData, eve, screen_co, index);
+ float screen_co[2];
+ if (ED_view3d_project_float_object(data->vc.region, co, screen_co, data->clip_flag) !=
+ V3D_PROJ_RET_OK) {
+ return;
}
+
+ data->func(data->userData, eve, screen_co, index);
}
void mesh_foreachScreenVert(
@@ -189,38 +366,37 @@ void mesh_foreachScreenVert(
BKE_mesh_foreach_mapped_vert(me, mesh_foreachScreenVert__mapFunc, &data, MESH_FOREACH_NOP);
}
-/* ------------------------------------------------------------------------ */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edit-Mesh: For Each Screen Mesh Edge
+ * \{ */
static void mesh_foreachScreenEdge__mapFunc(void *userData,
int index,
- const float v0co[3],
- const float v1co[3])
+ const float v_a[3],
+ const float v_b[3])
{
foreachScreenEdge_userData *data = userData;
BMEdge *eed = BM_edge_at_index(data->vc.em->bm, index);
+ if (UNLIKELY(BM_elem_flag_test(eed, BM_ELEM_HIDDEN))) {
+ return;
+ }
- if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float screen_co_a[2];
- float screen_co_b[2];
- eV3DProjTest clip_flag_nowin = data->clip_flag & ~V3D_PROJ_TEST_CLIP_WIN;
-
- if (ED_view3d_project_float_object(data->vc.region, v0co, screen_co_a, clip_flag_nowin) !=
- V3D_PROJ_RET_OK) {
- return;
- }
- if (ED_view3d_project_float_object(data->vc.region, v1co, screen_co_b, clip_flag_nowin) !=
- V3D_PROJ_RET_OK) {
- return;
- }
-
- if (data->clip_flag & V3D_PROJ_TEST_CLIP_WIN) {
- if (!BLI_rctf_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) {
- return;
- }
- }
-
- data->func(data->userData, eed, screen_co_a, screen_co_b, index);
+ float screen_co_a[2], screen_co_b[2];
+ if (!view3d_project_segment_to_screen_with_content_clip_planes(data->vc.region,
+ v_a,
+ v_b,
+ data->clip_flag,
+ &data->win_rect,
+ data->content_planes,
+ data->content_planes_len,
+ screen_co_a,
+ screen_co_b)) {
+ return;
}
+
+ data->func(data->userData, eed, screen_co_a, screen_co_b, index);
}
void mesh_foreachScreenEdge(ViewContext *vc,
@@ -254,11 +430,23 @@ void mesh_foreachScreenEdge(ViewContext *vc,
ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
}
+ if (clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) {
+ data.content_planes_len = content_planes_from_clip_flag(
+ vc->region, vc->obedit, clip_flag, data.content_planes);
+ }
+ else {
+ data.content_planes_len = 0;
+ }
+
BM_mesh_elem_table_ensure(vc->em->bm, BM_EDGE);
BKE_mesh_foreach_mapped_edge(me, mesh_foreachScreenEdge__mapFunc, &data);
}
-/* ------------------------------------------------------------------------ */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edit-Mesh: For Each Screen Edge (Bounding Box Clipped)
+ * \{ */
/**
* Only call for bound-box clipping.
@@ -266,46 +454,36 @@ void mesh_foreachScreenEdge(ViewContext *vc,
*/
static void mesh_foreachScreenEdge_clip_bb_segment__mapFunc(void *userData,
int index,
- const float v0co[3],
- const float v1co[3])
+ const float v_a[3],
+ const float v_b[3])
{
foreachScreenEdge_userData *data = userData;
BMEdge *eed = BM_edge_at_index(data->vc.em->bm, index);
+ if (UNLIKELY(BM_elem_flag_test(eed, BM_ELEM_HIDDEN))) {
+ return;
+ }
BLI_assert(data->clip_flag & V3D_PROJ_TEST_CLIP_BB);
- if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float v0co_clip[3];
- float v1co_clip[3];
-
- if (!clip_segment_v3_plane_n(v0co, v1co, data->vc.rv3d->clip_local, 4, v0co_clip, v1co_clip)) {
- return;
- }
-
- float screen_co_a[2];
- float screen_co_b[2];
-
- /* Clipping already handled, no need to check in projection. */
- eV3DProjTest clip_flag_nowin = data->clip_flag &
- ~(V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_BB);
-
- if (ED_view3d_project_float_object(data->vc.region, v0co_clip, screen_co_a, clip_flag_nowin) !=
- V3D_PROJ_RET_OK) {
- return;
- }
- if (ED_view3d_project_float_object(data->vc.region, v1co_clip, screen_co_b, clip_flag_nowin) !=
- V3D_PROJ_RET_OK) {
- return;
- }
-
- if (data->clip_flag & V3D_PROJ_TEST_CLIP_WIN) {
- if (!BLI_rctf_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) {
- return;
- }
- }
+ float v_a_clip[3], v_b_clip[3];
+ if (!clip_segment_v3_plane_n(v_a, v_b, data->vc.rv3d->clip_local, 4, v_a_clip, v_b_clip)) {
+ return;
+ }
- data->func(data->userData, eed, screen_co_a, screen_co_b, index);
+ float screen_co_a[2], screen_co_b[2];
+ if (!view3d_project_segment_to_screen_with_content_clip_planes(data->vc.region,
+ v_a_clip,
+ v_b_clip,
+ data->clip_flag,
+ &data->win_rect,
+ data->content_planes,
+ data->content_planes_len,
+ screen_co_a,
+ screen_co_b)) {
+ return;
}
+
+ data->func(data->userData, eed, screen_co_a, screen_co_b, index);
}
/**
@@ -339,6 +517,14 @@ void mesh_foreachScreenEdge_clip_bb_segment(ViewContext *vc,
data.userData = userData;
data.clip_flag = clip_flag;
+ if (clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) {
+ data.content_planes_len = content_planes_from_clip_flag(
+ vc->region, vc->obedit, clip_flag, data.content_planes);
+ }
+ else {
+ data.content_planes_len = 0;
+ }
+
BM_mesh_elem_table_ensure(vc->em->bm, BM_EDGE);
if ((clip_flag & V3D_PROJ_TEST_CLIP_BB) && (vc->rv3d->clipbb != NULL)) {
@@ -350,7 +536,11 @@ void mesh_foreachScreenEdge_clip_bb_segment(ViewContext *vc,
}
}
-/* ------------------------------------------------------------------------ */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edit-Mesh: For Each Screen Face Center
+ * \{ */
static void mesh_foreachScreenFace__mapFunc(void *userData,
int index,
@@ -359,14 +549,17 @@ static void mesh_foreachScreenFace__mapFunc(void *userData,
{
foreachScreenFace_userData *data = userData;
BMFace *efa = BM_face_at_index(data->vc.em->bm, index);
+ if (UNLIKELY(BM_elem_flag_test(efa, BM_ELEM_HIDDEN))) {
+ return;
+ }
- if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- float screen_co[2];
- if (ED_view3d_project_float_object(data->vc.region, cent, screen_co, data->clip_flag) ==
- V3D_PROJ_RET_OK) {
- data->func(data->userData, efa, screen_co, index);
- }
+ float screen_co[2];
+ if (ED_view3d_project_float_object(data->vc.region, cent, screen_co, data->clip_flag) !=
+ V3D_PROJ_RET_OK) {
+ return;
}
+
+ data->func(data->userData, efa, screen_co, index);
}
void mesh_foreachScreenFace(
@@ -375,6 +568,7 @@ void mesh_foreachScreenFace(
void *userData,
const eV3DProjTest clip_flag)
{
+ BLI_assert((clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) == 0);
foreachScreenFace_userData data;
Mesh *me = editbmesh_get_eval_cage_from_orig(
@@ -398,7 +592,11 @@ void mesh_foreachScreenFace(
}
}
-/* ------------------------------------------------------------------------ */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edit-Nurbs: For Each Screen Vertex
+ * \{ */
void nurbs_foreachScreenVert(ViewContext *vc,
void (*func)(void *userData,
@@ -486,7 +684,11 @@ void nurbs_foreachScreenVert(ViewContext *vc,
}
}
-/* ------------------------------------------------------------------------ */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edit-Meta: For Each Screen Meta-Element
+ * \{ */
/* ED_view3d_init_mats_rv3d must be called first */
void mball_foreachScreenElem(struct ViewContext *vc,
@@ -510,7 +712,11 @@ void mball_foreachScreenElem(struct ViewContext *vc,
}
}
-/* ------------------------------------------------------------------------ */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edit-Lattice: For Each Screen Vertex
+ * \{ */
void lattice_foreachScreenVert(ViewContext *vc,
void (*func)(void *userData, BPoint *bp, const float screen_co[2]),
@@ -543,7 +749,11 @@ void lattice_foreachScreenVert(ViewContext *vc,
}
}
-/* ------------------------------------------------------------------------ */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edit-Armature: For Each Screen Bone
+ * \{ */
/* ED_view3d_init_mats_rv3d must be called first */
void armature_foreachScreenBone(struct ViewContext *vc,
@@ -559,39 +769,59 @@ void armature_foreachScreenBone(struct ViewContext *vc,
ED_view3d_check_mats_rv3d(vc->rv3d);
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
- if (EBONE_VISIBLE(arm, ebone)) {
- float screen_co_a[2], screen_co_b[2];
- int points_proj_tot = 0;
+ float content_planes[6][4];
+ int content_planes_len;
+ rctf win_rect;
+
+ if (clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) {
+ content_planes_len = content_planes_from_clip_flag(
+ vc->region, vc->obedit, clip_flag, content_planes);
+ win_rect.xmin = 0;
+ win_rect.ymin = 0;
+ win_rect.xmax = vc->region->winx;
+ win_rect.ymax = vc->region->winy;
+ }
+ else {
+ content_planes_len = 0;
+ }
- /* project head location to screenspace */
- if (ED_view3d_project_float_object(vc->region, ebone->head, screen_co_a, clip_flag) ==
- V3D_PROJ_RET_OK) {
- points_proj_tot++;
- }
- else {
- screen_co_a[0] = IS_CLIPPED; /* weak */
- /* screen_co_a[1]: intentionally don't set this so we get errors on misuse */
- }
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (!EBONE_VISIBLE(arm, ebone)) {
+ continue;
+ }
- /* project tail location to screenspace */
- if (ED_view3d_project_float_object(vc->region, ebone->tail, screen_co_b, clip_flag) ==
- V3D_PROJ_RET_OK) {
- points_proj_tot++;
- }
- else {
- screen_co_b[0] = IS_CLIPPED; /* weak */
- /* screen_co_b[1]: intentionally don't set this so we get errors on misuse */
+ float screen_co_a[2], screen_co_b[2];
+ const float *v_a = ebone->head, *v_b = ebone->tail;
+
+ if (clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) {
+ if (!view3d_project_segment_to_screen_with_content_clip_planes(vc->region,
+ v_a,
+ v_b,
+ clip_flag,
+ &win_rect,
+ content_planes,
+ content_planes_len,
+ screen_co_a,
+ screen_co_b)) {
+ continue;
}
-
- if (points_proj_tot) { /* at least one point's projection worked */
- func(userData, ebone, screen_co_a, screen_co_b);
+ }
+ else {
+ if (!view3d_project_segment_to_screen_with_clip_tag(
+ vc->region, v_a, v_b, clip_flag, screen_co_a, screen_co_b)) {
+ continue;
}
}
+
+ func(userData, ebone, screen_co_a, screen_co_b);
}
}
-/* ------------------------------------------------------------------------ */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Pose: For Each Screen Bone
+ * \{ */
/* ED_view3d_init_mats_rv3d must be called first */
/* almost _exact_ copy of #armature_foreachScreenBone */
@@ -610,35 +840,53 @@ void pose_foreachScreenBone(struct ViewContext *vc,
ED_view3d_check_mats_rv3d(vc->rv3d);
+ float content_planes[6][4];
+ int content_planes_len;
+ rctf win_rect;
+
+ if (clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) {
+ content_planes_len = content_planes_from_clip_flag(
+ vc->region, ob_eval, clip_flag, content_planes);
+ win_rect.xmin = 0;
+ win_rect.ymin = 0;
+ win_rect.xmax = vc->region->winx;
+ win_rect.ymax = vc->region->winy;
+ }
+ else {
+ content_planes_len = 0;
+ }
+
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
- if (PBONE_VISIBLE(arm_eval, pchan->bone)) {
- bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
- float screen_co_a[2], screen_co_b[2];
- int points_proj_tot = 0;
-
- /* project head location to screenspace */
- if (ED_view3d_project_float_object(
- vc->region, pchan_eval->pose_head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) {
- points_proj_tot++;
- }
- else {
- screen_co_a[0] = IS_CLIPPED; /* weak */
- /* screen_co_a[1]: intentionally don't set this so we get errors on misuse */
- }
+ if (!PBONE_VISIBLE(arm_eval, pchan->bone)) {
+ continue;
+ }
- /* project tail location to screenspace */
- if (ED_view3d_project_float_object(
- vc->region, pchan_eval->pose_tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) {
- points_proj_tot++;
+ bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
+ float screen_co_a[2], screen_co_b[2];
+ const float *v_a = pchan_eval->pose_head, *v_b = pchan_eval->pose_tail;
+
+ if (clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) {
+ if (!view3d_project_segment_to_screen_with_content_clip_planes(vc->region,
+ v_a,
+ v_b,
+ clip_flag,
+ &win_rect,
+ content_planes,
+ content_planes_len,
+ screen_co_a,
+ screen_co_b)) {
+ continue;
}
- else {
- screen_co_b[0] = IS_CLIPPED; /* weak */
- /* screen_co_b[1]: intentionally don't set this so we get errors on misuse */
- }
-
- if (points_proj_tot) { /* at least one point's projection worked */
- func(userData, pchan, screen_co_a, screen_co_b);
+ }
+ else {
+ if (!view3d_project_segment_to_screen_with_clip_tag(
+ vc->region, v_a, v_b, clip_flag, screen_co_a, screen_co_b)) {
+ continue;
}
}
+
+ func(userData, pchan, screen_co_a, screen_co_b);
}
}
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_navigate_fly.c
index 2d499cf85c7..5752837c40f 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_fly.c
@@ -19,7 +19,7 @@
*
* Interactive fly navigation modal operator (flying around in space).
*
- * \note Similar logic to `view3d_walk.c` changes here may apply there too.
+ * \note Similar logic to `view3d_navigate_walk.c` changes here may apply there too.
*/
/* defines VIEW3D_OT_fly modal operator */
@@ -101,7 +101,7 @@ typedef enum eFlyPanState {
FLY_AXISLOCK_STATE_ACTIVE = 2,
} eFlyPanState;
-/* called in transform_ops.c, on each regeneration of keymaps */
+/* Called in transform_ops.c, on each regeneration of key-maps. */
void fly_modal_keymap(wmKeyConfig *keyconf)
{
static const EnumPropertyItem modal_items[] = {
@@ -122,7 +122,7 @@ void fly_modal_keymap(wmKeyConfig *keyconf)
{FLY_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""},
{FLY_MODAL_AXIS_LOCK_X, "AXIS_LOCK_X", 0, "X Axis Correction", "X axis correction (toggle)"},
- {FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "X Axis Correction", "Z axis correction (toggle)"},
+ {FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "Z Axis Correction", "Z axis correction (toggle)"},
{FLY_MODAL_PRECISION_ENABLE, "PRECISION_ENABLE", 0, "Precision", ""},
{FLY_MODAL_PRECISION_DISABLE, "PRECISION_DISABLE", 0, "Precision (Off)", ""},
@@ -189,7 +189,7 @@ typedef struct FlyInfo {
wmNDOFMotionData *ndof;
#endif
- /* fly state state */
+ /* Fly state. */
/** The speed the view is moving per redraw. */
float speed;
/** Axis index to move along by default Z to move along the view. */
@@ -610,8 +610,7 @@ static void flyEvent(FlyInfo *fly, const wmEvent *event)
fly->pan_view = false;
break;
- /* implement WASD keys,
- * comments only for 'forward '*/
+ /* Implement WASD keys, comments only for 'forward'. */
case FLY_MODAL_DIR_FORWARD:
if (fly->axis == 2 && fly->speed < 0.0f) {
/* reverse direction stops, tap again to continue */
@@ -758,9 +757,6 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
#define FLY_ZUP_CORRECT_ACCEL 0.05f /* increase upright momentum each step */
#define FLY_SMOOTH_FAC 20.0f /* higher value less lag */
- /* fly mode - Shift+F
- * a fly loop where the user can move move the view as if they are flying
- */
RegionView3D *rv3d = fly->rv3d;
/* 3x3 copy of the view matrix so we can move along the view axis */
@@ -772,7 +768,7 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
float moffset[2]; /* mouse offset from the views center */
float tmp_quat[4]; /* used for rotating the view */
- /* x and y margin are define the safe area where the mouses movement wont rotate the view */
+ /* x and y margin defining the safe area where the mouse's movement won't rotate the view */
int xmargin, ymargin;
#ifdef NDOF_FLY_DEBUG
@@ -812,10 +808,10 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
moffset[1] = 0;
}
- /* scale the mouse movement by this value - scales mouse movement to the view size
- * moffset[0] / (region->winx-xmargin * 2) - window size minus margin (same for y)
+ /* Scale the mouse movement by this value - scales mouse movement to the view size
+ * `moffset[0] / (region->winx-xmargin * 2)` - window size minus margin (same for y)
*
- * the mouse moves isn't linear */
+ * the mouse moves isn't linear. */
if (moffset[0]) {
moffset[0] /= fly->width - (xmargin * 2);
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_navigate_walk.c
index ab4cf0c2135..09936b41a74 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_walk.c
@@ -20,7 +20,7 @@
* Interactive walk navigation modal operator
* (similar to walking around in a first person game).
*
- * \note Similar logic to `view3d_fly.c` changes here may apply there too.
+ * \note Similar logic to `view3d_navigate_fly.c` changes here may apply there too.
*/
/* defines VIEW3D_OT_navigate - walk modal operator */
@@ -98,9 +98,10 @@ enum {
WALK_MODAL_JUMP,
WALK_MODAL_JUMP_STOP,
WALK_MODAL_TELEPORT,
- WALK_MODAL_TOGGLE,
+ WALK_MODAL_GRAVITY_TOGGLE,
WALK_MODAL_ACCELERATE,
WALK_MODAL_DECELERATE,
+ WALK_MODAL_AXIS_LOCK_Z,
};
enum {
@@ -129,7 +130,19 @@ typedef enum eWalkGravityState {
WALK_GRAVITY_STATE_ON,
} eWalkGravityState;
-/* called in transform_ops.c, on each regeneration of keymaps */
+/* Relative view axis z axis locking. */
+typedef enum eWalkLockState {
+ /* Disabled. */
+ WALK_AXISLOCK_STATE_OFF = 0,
+
+ /* Moving. */
+ WALK_AXISLOCK_STATE_ACTIVE = 2,
+
+ /* Done moving, it cannot be activated again. */
+ WALK_AXISLOCK_STATE_DONE = 3,
+} eWalkLockState;
+
+/* Called in transform_ops.c, on each regeneration of key-maps. */
void walk_modal_keymap(wmKeyConfig *keyconf)
{
static const EnumPropertyItem modal_items[] = {
@@ -164,7 +177,9 @@ void walk_modal_keymap(wmKeyConfig *keyconf)
{WALK_MODAL_JUMP, "JUMP", 0, "Jump", "Jump when in walk mode"},
{WALK_MODAL_JUMP_STOP, "JUMP_STOP", 0, "Jump (Off)", "Stop pushing jump"},
- {WALK_MODAL_TOGGLE, "GRAVITY_TOGGLE", 0, "Toggle Gravity", "Toggle gravity effect"},
+ {WALK_MODAL_GRAVITY_TOGGLE, "GRAVITY_TOGGLE", 0, "Toggle Gravity", "Toggle gravity effect"},
+
+ {WALK_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "Z Axis Correction", "Z axis correction"},
{0, NULL, 0, NULL, NULL},
};
@@ -234,7 +249,7 @@ typedef struct WalkInfo {
wmNDOFMotionData *ndof;
#endif
- /* walk state state */
+ /* Walk state. */
/** The base speed without run/slow down modifications. */
float base_speed;
/** The speed the view is moving per redraw. */
@@ -292,6 +307,10 @@ typedef struct WalkInfo {
/** To use for fast/slow speeds. */
float speed_factor;
+ eWalkLockState zlock;
+ /** Nicer dynamics. */
+ float zlock_momentum;
+
struct SnapObjectContext *snap_context;
struct View3DCameraControl *v3d_camera_control;
@@ -540,6 +559,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->jump_height = U.walk_navigation.jump_height;
walk->speed = U.walk_navigation.walk_speed;
walk->speed_factor = U.walk_navigation.walk_speed_factor;
+ walk->zlock = WALK_AXISLOCK_STATE_OFF;
walk->gravity_state = WALK_GRAVITY_STATE_OFF;
@@ -694,7 +714,7 @@ static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event)
walk->is_cursor_first = false;
}
else {
- /* note, its possible the system isn't giving us the warp event
+ /* NOTE: its possible the system isn't giving us the warp event
* ideally we shouldn't have to worry about this, see: T45361 */
wmWindow *win = CTX_wm_window(C);
WM_cursor_warp(win,
@@ -708,8 +728,6 @@ static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event)
walk->is_cursor_absolute = true;
copy_v2_v2_int(walk->prev_mval, event->mval);
copy_v2_v2_int(walk->center_mval, event->mval);
- /* Without this we can't turn 180d with the default speed of 1.0. */
- walk->mouse_speed *= 4.0f;
}
#endif /* USE_TABLET_SUPPORT */
@@ -941,7 +959,7 @@ static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event)
#undef JUMP_TIME_MAX
#undef JUMP_SPEED_MIN
- case WALK_MODAL_TOGGLE:
+ case WALK_MODAL_GRAVITY_TOGGLE:
if (walk->navigation_mode == WALK_MODE_GRAVITY) {
walk_navigation_mode_set(walk, WALK_MODE_FREE);
}
@@ -949,6 +967,13 @@ static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event)
walk_navigation_mode_set(walk, WALK_MODE_GRAVITY);
}
break;
+
+ case WALK_MODAL_AXIS_LOCK_Z:
+ if (walk->zlock != WALK_AXISLOCK_STATE_DONE) {
+ walk->zlock = WALK_AXISLOCK_STATE_ACTIVE;
+ walk->zlock_momentum = 0.0f;
+ }
+ break;
}
}
}
@@ -982,16 +1007,15 @@ static float getVelocityZeroTime(const float gravity, const float velocity)
static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
{
-#define WALK_ROTATE_RELATIVE_FAC 2.2f /* More is faster, relative to region size. */
-#define WALK_ROTATE_CONSTANT_FAC DEG2RAD(0.15f) /* More is faster, radians per-pixel. */
+#define WALK_ROTATE_TABLET_FAC 8.8f /* Higher is faster, relative to region size. */
+#define WALK_ROTATE_CONSTANT_FAC DEG2RAD(0.15f) /* Higher is faster, radians per-pixel. */
#define WALK_TOP_LIMIT DEG2RADF(85.0f)
#define WALK_BOTTOM_LIMIT DEG2RADF(-80.0f)
#define WALK_MOVE_SPEED base_speed
#define WALK_BOOST_FACTOR ((void)0, walk->speed_factor)
+#define WALK_ZUP_CORRECT_FAC 0.1f /* Amount to correct per step. */
+#define WALK_ZUP_CORRECT_ACCEL 0.05f /* Increase upright momentum each step. */
- /* walk mode - Ctrl+Shift+F
- * a walk loop where the user can move move the view as if they are in a walk game
- */
RegionView3D *rv3d = walk->rv3d;
ARegion *region = walk->region;
@@ -1025,20 +1049,25 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
/* Should we redraw? */
if ((walk->active_directions) || moffset[0] || moffset[1] ||
- walk->teleport.state == WALK_TELEPORT_STATE_ON ||
- walk->gravity_state != WALK_GRAVITY_STATE_OFF || is_confirm) {
+ walk->zlock == WALK_AXISLOCK_STATE_ACTIVE ||
+ walk->gravity_state != WALK_GRAVITY_STATE_OFF ||
+ walk->teleport.state == WALK_TELEPORT_STATE_ON || is_confirm) {
float dvec_tmp[3];
/* time how fast it takes for us to redraw,
* this is so simple scenes don't walk too fast */
double time_current;
float time_redraw;
+ float time_redraw_clamped;
#ifdef NDOF_WALK_DRAW_TOOMUCH
walk->redraw = 1;
#endif
time_current = PIL_check_seconds_timer();
time_redraw = (float)(time_current - walk->time_lastdraw);
+ /* Clamp redraw time to avoid jitter in roll correction. */
+ time_redraw_clamped = min_ff(0.05f, time_redraw);
+
walk->time_lastdraw = time_current;
/* base speed in m/s */
@@ -1067,7 +1096,7 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
#ifdef USE_TABLET_SUPPORT
if (walk->is_cursor_absolute) {
y /= region->winy;
- y *= WALK_ROTATE_RELATIVE_FAC;
+ y *= WALK_ROTATE_TABLET_FAC;
}
else
#endif
@@ -1116,7 +1145,7 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
#ifdef USE_TABLET_SUPPORT
if (walk->is_cursor_absolute) {
x /= region->winx;
- x *= WALK_ROTATE_RELATIVE_FAC;
+ x *= WALK_ROTATE_TABLET_FAC;
}
else
#endif
@@ -1131,6 +1160,32 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
axis_angle_to_quat_single(tmp_quat, 'Z', x);
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
}
+
+ if (walk->zlock == WALK_AXISLOCK_STATE_ACTIVE) {
+ float upvec[3];
+ copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
+ mul_m3_v3(mat, upvec);
+
+ /* Make sure we have some z rolling. */
+ if (fabsf(upvec[2]) > 0.00001f) {
+ float roll = upvec[2] * 5.0f;
+ /* Rotate the view about this axis. */
+ copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
+ mul_m3_v3(mat, upvec);
+ /* Rotate about the relative up vec. */
+ axis_angle_to_quat(tmp_quat,
+ upvec,
+ roll * time_redraw_clamped * walk->zlock_momentum *
+ WALK_ZUP_CORRECT_FAC);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+
+ walk->zlock_momentum += WALK_ZUP_CORRECT_ACCEL;
+ }
+ else {
+ /* Lock fixed, don't need to check it ever again. */
+ walk->zlock = WALK_AXISLOCK_STATE_DONE;
+ }
+ }
}
/* WASD - 'move' translation code */
@@ -1321,7 +1376,8 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
add_v3_v3(rv3d->ofs, dvec_tmp);
if (rv3d->persp == RV3D_CAMOB) {
- walk->need_rotation_keyframe |= (moffset[0] || moffset[1]);
+ walk->need_rotation_keyframe |= (moffset[0] || moffset[1] ||
+ walk->zlock == WALK_AXISLOCK_STATE_ACTIVE);
walk->need_translation_keyframe |= (len_squared_v3(dvec_tmp) > FLT_EPSILON);
walkMoveCamera(
C, walk, walk->need_rotation_keyframe, walk->need_translation_keyframe, is_confirm);
@@ -1336,7 +1392,7 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
}
return OPERATOR_FINISHED;
-#undef WALK_ROTATE_RELATIVE_FAC
+#undef WALK_ROTATE_TABLET_FAC
#undef WALK_TOP_LIMIT
#undef WALK_BOTTOM_LIMIT
#undef WALK_MOVE_SPEED
diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c
index 00e30f8afae..aa3bf46d2e5 100644
--- a/source/blender/editors/space_view3d/view3d_placement.c
+++ b/source/blender/editors/space_view3d/view3d_placement.c
@@ -252,7 +252,7 @@ static int dot_v3_array_find_max_index(const float dirs[][3],
}
/**
- * Re-order \a mat so \a axis_align uses it's own axis which is closest to \a v.
+ * Re-order \a mat so \a axis_align uses its own axis which is closest to \a v.
*/
static bool mat3_align_axis_to_v3(float mat[3][3], const int axis_align, const float v[3])
{
@@ -584,7 +584,7 @@ static bool calc_bbox(struct InteractivePlaceData *ipd, BoundBox *bounds)
delta_a[x_axis] = 0.0f;
delta_b[y_axis] = 0.0f;
- /* Assign here in case secondary */
+ /* Assign here in case secondary. */
fixed_aspect_dimension = max_ff(fabsf(delta_a[y_axis]), fabsf(delta_b[x_axis]));
if (ipd->step[0].is_fixed_aspect) {
@@ -961,7 +961,7 @@ static void view3d_interactive_add_calc_plane(bContext *C,
const float view_axis_dot = fabsf(dot_v3v3(rv3d->viewinv[2], r_matrix_orient[plane_axis]));
if (view_axis_dot < eps_view_align) {
/* In this case, just project onto the view plane as it's important the location
- * is _always_ under the mouse cursor, even if it turns out that wont lie on
+ * is _always_ under the mouse cursor, even if it turns out that won't lie on
* the original 'plane' that's been calculated for us. */
plane_normal = rv3d->viewinv[2];
}
@@ -974,7 +974,7 @@ static void view3d_interactive_add_calc_plane(bContext *C,
/* Even if the calculation works, it's possible the point found is behind the view,
* or very far away (past the far clipping).
- * In either case creating objects wont be useful. */
+ * In either case creating objects won't be useful. */
if (rv3d->is_persp) {
float dir[3];
sub_v3_v3v3(dir, rv3d->viewinv[3], r_co_src);
@@ -1196,7 +1196,7 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
}
else {
/* If the user runs this as an operator they should set the 'primitive_type',
- * however running from operator search will end up at this point. */
+ * however running from operator search will end up at this point. */
ipd->primitive_type = PLACE_PRIMITIVE_TYPE_CUBE;
ipd->use_tool = false;
}
@@ -1610,7 +1610,7 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
ot->cancel = view3d_interactive_add_cancel;
ot->poll = view3d_interactive_add_poll;
- /* Note, let the operator we call handle undo and registering itself. */
+ /* NOTE: let the operator we call handle undo and registering itself. */
/* flags */
ot->flag = 0;
@@ -1762,7 +1762,7 @@ static void WIDGETGROUP_placement_setup(const bContext *UNUSED(C), wmGizmoGroup
gizmo->flag |= WM_GIZMO_HIDDEN_KEYMAP;
}
- /* Sets the gizmos custom-data which has it's own free callback. */
+ /* Sets the gizmos custom-data which has its own free callback. */
preview_plane_cursor_setup(gzgroup);
}
@@ -1830,7 +1830,7 @@ static void gizmo_plane_update_cursor(const bContext *C,
/* This ensures the snap gizmo has settings from this tool.
* This function call could be moved a more appropriate place,
* responding to the setting being changed for example,
- * however setting the value isn't expensive, so do it here. */
+ * however setting the value isn't expensive, so do it here. */
idp_snap_gizmo_update_snap_elements(scene, snap_to, snap_gizmo);
view3d_interactive_add_calc_plane((bContext *)C,
@@ -1957,7 +1957,7 @@ struct PlacementCursor {
/**
* Enable this while the modal operator is running,
- * so the preview-plane doesn't show at the same time time as add-object preview shape
+ * so the preview-plane doesn't show at the same time as add-object preview shape
* since it's distracting & not helpful.
*/
bool do_draw;
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index 24d34e514c5..d926ea84e0f 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -330,6 +330,17 @@ float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_f
return zfac;
}
+/**
+ * Calculate a depth value from `co` (result should only be used for comparison).
+ */
+float ED_view3d_calc_depth_for_comparison(const RegionView3D *rv3d, const float co[3])
+{
+ if (rv3d->is_persp) {
+ return ED_view3d_calc_zfac(rv3d, co, NULL);
+ }
+ return -dot_v3v3(rv3d->viewinv[2], co);
+}
+
static void view3d_win_to_ray_segment(struct Depsgraph *depsgraph,
const ARegion *region,
const View3D *v3d,
@@ -550,7 +561,7 @@ void ED_view3d_win_to_3d(const View3D *v3d,
copy_v3_v3(ray_origin, rv3d->viewinv[3]);
ED_view3d_win_to_vector(region, mval, ray_direction);
- /* Note: we could use #isect_line_plane_v3()
+ /* NOTE: we could use #isect_line_plane_v3()
* however we want the intersection to be in front of the view no matter what,
* so apply the unsigned factor instead. */
plane_from_point_normal_v3(plane, depth_pt, rv3d->viewinv[2]);
@@ -788,7 +799,7 @@ bool ED_view3d_win_to_segment_clipped(struct Depsgraph *depsgraph,
/** \name Utility functions for projection
* \{ */
-void ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, Object *ob, float r_pmat[4][4])
+void ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, const Object *ob, float r_pmat[4][4])
{
float vmat[4][4];
@@ -809,23 +820,30 @@ void ED_view3d_ob_project_mat_get_from_obmat(const RegionView3D *rv3d,
/**
* Convert between region relative coordinates (x,y) and depth component z and
* a point in world space. */
-void ED_view3d_project(const struct ARegion *region, const float world[3], float r_region_co[3])
+void ED_view3d_project_v3(const struct ARegion *region, const float world[3], float r_region_co[3])
{
/* Viewport is set up to make coordinates relative to the region, not window. */
RegionView3D *rv3d = region->regiondata;
const int viewport[4] = {0, 0, region->winx, region->winy};
+ GPU_matrix_project_3fv(world, rv3d->viewmat, rv3d->winmat, viewport, r_region_co);
+}
- GPU_matrix_project(world, rv3d->viewmat, rv3d->winmat, viewport, r_region_co);
+void ED_view3d_project_v2(const struct ARegion *region, const float world[3], float r_region_co[2])
+{
+ /* Viewport is set up to make coordinates relative to the region, not window. */
+ RegionView3D *rv3d = region->regiondata;
+ const int viewport[4] = {0, 0, region->winx, region->winy};
+ GPU_matrix_project_2fv(world, rv3d->viewmat, rv3d->winmat, viewport, r_region_co);
}
-bool ED_view3d_unproject(
+bool ED_view3d_unproject_v3(
const struct ARegion *region, float regionx, float regiony, float regionz, float world[3])
{
RegionView3D *rv3d = region->regiondata;
const int viewport[4] = {0, 0, region->winx, region->winy};
const float region_co[3] = {regionx, regiony, regionz};
- return GPU_matrix_unproject(region_co, rv3d->viewmat, rv3d->winmat, viewport, world);
+ return GPU_matrix_unproject_3fv(region_co, rv3d->viewmat, rv3d->winmat, viewport, world);
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 757ed13ac28..ecf43c734e2 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -520,42 +520,16 @@ static void do_lasso_select_pose__do_tag(void *userData,
const float screen_co_b[2])
{
LassoSelectUserData *data = userData;
- bArmature *arm = data->vc->obact->data;
-
- if (PBONE_SELECTABLE(arm, pchan->bone)) {
- bool is_point_done = false;
- int points_proj_tot = 0;
-
- /* project head location to screenspace */
- if (screen_co_a[0] != IS_CLIPPED) {
- points_proj_tot++;
- if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_a)) &&
- BLI_lasso_is_point_inside(
- data->mcoords, data->mcoords_len, UNPACK2(screen_co_a), INT_MAX)) {
- is_point_done = true;
- }
- }
-
- /* project tail location to screenspace */
- if (screen_co_b[0] != IS_CLIPPED) {
- points_proj_tot++;
- if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_b)) &&
- BLI_lasso_is_point_inside(
- data->mcoords, data->mcoords_len, UNPACK2(screen_co_b), INT_MAX)) {
- is_point_done = true;
- }
- }
+ const bArmature *arm = data->vc->obact->data;
+ if (!PBONE_SELECTABLE(arm, pchan->bone)) {
+ return;
+ }
- /* if one of points selected, we skip the bone itself */
- if ((is_point_done == true) || ((is_point_done == false) && (points_proj_tot == 2) &&
- BLI_lasso_is_edge_inside(data->mcoords,
- data->mcoords_len,
- UNPACK2(screen_co_a),
- UNPACK2(screen_co_b),
- INT_MAX))) {
- pchan->bone->flag |= BONE_DONE;
- }
- data->is_changed |= is_point_done;
+ if (BLI_rctf_isect_segment(data->rect_fl, screen_co_a, screen_co_b) &&
+ BLI_lasso_is_edge_inside(
+ data->mcoords, data->mcoords_len, UNPACK2(screen_co_a), UNPACK2(screen_co_b), INT_MAX)) {
+ pchan->bone->flag |= BONE_DONE;
+ data->is_changed = true;
}
}
static void do_lasso_tag_pose(ViewContext *vc,
@@ -580,7 +554,11 @@ static void do_lasso_tag_pose(ViewContext *vc,
ED_view3d_init_mats_rv3d(vc_tmp.obact, vc->rv3d);
- pose_foreachScreenBone(&vc_tmp, do_lasso_select_pose__do_tag, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ /* Treat bones as clipped segments (no joints). */
+ pose_foreachScreenBone(&vc_tmp,
+ do_lasso_select_pose__do_tag,
+ &data,
+ V3D_PROJ_TEST_CLIP_DEFAULT | V3D_PROJ_TEST_CLIP_CONTENT_DEFAULT);
}
static bool do_lasso_select_objects(ViewContext *vc,
@@ -876,11 +854,16 @@ static bool do_lasso_select_mesh(ViewContext *vc,
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_NEAR |
(use_zbuf ? 0 : V3D_PROJ_TEST_CLIP_BB);
+ /* Fully inside. */
mesh_foreachScreenEdge_clip_bb_segment(
vc, do_lasso_select_mesh__doSelectEdge_pass0, &data_for_edge, clip_flag);
if (data.is_done == false) {
- mesh_foreachScreenEdge_clip_bb_segment(
- vc, do_lasso_select_mesh__doSelectEdge_pass1, &data_for_edge, clip_flag);
+ /* Fall back to partially inside.
+ * Clip content to account for edges partially behind the view. */
+ mesh_foreachScreenEdge_clip_bb_segment(vc,
+ do_lasso_select_mesh__doSelectEdge_pass1,
+ &data_for_edge,
+ clip_flag | V3D_PROJ_TEST_CLIP_CONTENT_DEFAULT);
}
}
@@ -1022,46 +1005,76 @@ static void do_lasso_select_armature__doSelectBone(void *userData,
const float screen_co_b[2])
{
LassoSelectUserData *data = userData;
- bArmature *arm = data->vc->obedit->data;
- if (EBONE_VISIBLE(arm, ebone)) {
- int is_ignore_flag = 0;
- int is_inside_flag = 0;
-
- if (screen_co_a[0] != IS_CLIPPED) {
- if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_a)) &&
- BLI_lasso_is_point_inside(
- data->mcoords, data->mcoords_len, UNPACK2(screen_co_a), INT_MAX)) {
- is_inside_flag |= BONESEL_ROOT;
- }
- }
- else {
- is_ignore_flag |= BONESEL_ROOT;
- }
+ const bArmature *arm = data->vc->obedit->data;
+ if (!EBONE_VISIBLE(arm, ebone)) {
+ return;
+ }
- if (screen_co_b[0] != IS_CLIPPED) {
- if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_b)) &&
- BLI_lasso_is_point_inside(
- data->mcoords, data->mcoords_len, UNPACK2(screen_co_b), INT_MAX)) {
- is_inside_flag |= BONESEL_TIP;
- }
+ int is_ignore_flag = 0;
+ int is_inside_flag = 0;
+
+ if (screen_co_a[0] != IS_CLIPPED) {
+ if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_a)) &&
+ BLI_lasso_is_point_inside(
+ data->mcoords, data->mcoords_len, UNPACK2(screen_co_a), INT_MAX)) {
+ is_inside_flag |= BONESEL_ROOT;
}
- else {
- is_ignore_flag |= BONESEL_TIP;
+ }
+ else {
+ is_ignore_flag |= BONESEL_ROOT;
+ }
+
+ if (screen_co_b[0] != IS_CLIPPED) {
+ if (BLI_rcti_isect_pt(data->rect, UNPACK2(screen_co_b)) &&
+ BLI_lasso_is_point_inside(
+ data->mcoords, data->mcoords_len, UNPACK2(screen_co_b), INT_MAX)) {
+ is_inside_flag |= BONESEL_TIP;
}
+ }
+ else {
+ is_ignore_flag |= BONESEL_TIP;
+ }
- if (is_ignore_flag == 0) {
- if (is_inside_flag == (BONE_ROOTSEL | BONE_TIPSEL) ||
- BLI_lasso_is_edge_inside(data->mcoords,
- data->mcoords_len,
- UNPACK2(screen_co_a),
- UNPACK2(screen_co_b),
- INT_MAX)) {
- is_inside_flag |= BONESEL_BONE;
- }
+ if (is_ignore_flag == 0) {
+ if (is_inside_flag == (BONE_ROOTSEL | BONE_TIPSEL) ||
+ BLI_lasso_is_edge_inside(data->mcoords,
+ data->mcoords_len,
+ UNPACK2(screen_co_a),
+ UNPACK2(screen_co_b),
+ INT_MAX)) {
+ is_inside_flag |= BONESEL_BONE;
}
+ }
+
+ ebone->temp.i = is_inside_flag | (is_ignore_flag >> 16);
+}
+static void do_lasso_select_armature__doSelectBone_clip_content(void *userData,
+ EditBone *ebone,
+ const float screen_co_a[2],
+ const float screen_co_b[2])
+{
+ LassoSelectUserData *data = userData;
+ bArmature *arm = data->vc->obedit->data;
+ if (!EBONE_VISIBLE(arm, ebone)) {
+ return;
+ }
+
+ const int is_ignore_flag = ebone->temp.i << 16;
+ int is_inside_flag = ebone->temp.i & ~0xFFFF;
- ebone->temp.i = is_inside_flag | (is_ignore_flag >> 16);
+ /* - When #BONESEL_BONE is set, there is nothing to do.
+ * - When #BONE_ROOTSEL or #BONE_TIPSEL have been set - they take priority over bone selection.
+ */
+ if (is_inside_flag & (BONESEL_BONE | BONE_ROOTSEL | BONE_TIPSEL)) {
+ return;
+ }
+
+ if (BLI_lasso_is_edge_inside(
+ data->mcoords, data->mcoords_len, UNPACK2(screen_co_a), UNPACK2(screen_co_b), INT_MAX)) {
+ is_inside_flag |= BONESEL_BONE;
}
+
+ ebone->temp.i = is_inside_flag | (is_ignore_flag >> 16);
}
static bool do_lasso_select_armature(ViewContext *vc,
@@ -1086,9 +1099,18 @@ static bool do_lasso_select_armature(ViewContext *vc,
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+ /* Operate on fully visible (non-clipped) points. */
armature_foreachScreenBone(
vc, do_lasso_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ /* Operate on bones as segments clipped to the viewport bounds
+ * (needed to handle bones with both points outside the view).
+ * A separate pass is needed since clipped coordinates can't be used for selecting joints. */
+ armature_foreachScreenBone(vc,
+ do_lasso_select_armature__doSelectBone_clip_content,
+ &data,
+ V3D_PROJ_TEST_CLIP_DEFAULT | V3D_PROJ_TEST_CLIP_CONTENT_DEFAULT);
+
data.is_changed |= ED_armature_edit_select_op_from_tagged(vc->obedit->data, sel_op);
if (data.is_changed) {
@@ -1356,7 +1378,7 @@ static bool view3d_lasso_select(bContext *C,
changed = do_lasso_select_meta(vc, mcoords, mcoords_len, sel_op);
break;
default:
- BLI_assert(!"lasso select on incorrect object type");
+ BLI_assert_msg(0, "lasso select on incorrect object type");
break;
}
@@ -1811,7 +1833,7 @@ static bool bone_mouse_select_menu(bContext *C,
continue;
}
/* We can hit a bone multiple times, so make sure we are not adding an already included bone
- * to the list.*/
+ * to the list. */
const bool is_duplicate_bone = BLI_gset_haskey(added_bones, bone_ptr);
if (!is_duplicate_bone) {
@@ -2269,7 +2291,7 @@ static bool ed_object_select_pick(bContext *C,
/* In edit-mode do not activate. */
if (obcenter) {
- /* note; shift+alt goes to group-flush-selecting */
+ /* NOTE: shift+alt goes to group-flush-selecting. */
if (enumerate) {
basact = object_mouse_select_menu(C, &vc, NULL, 0, mval, extend, deselect, toggle);
}
@@ -2332,10 +2354,10 @@ static bool ed_object_select_pick(bContext *C,
// TIMEIT_END(select_time);
if (hits > 0) {
- /* note: bundles are handling in the same way as bones */
+ /* NOTE: bundles are handling in the same way as bones. */
const bool has_bones = object ? false : selectbuffer_has_bones(buffer, hits);
- /* note; shift+alt goes to group-flush-selecting */
+ /* NOTE: shift+alt goes to group-flush-selecting. */
if (enumerate) {
if (has_bones &&
bone_mouse_select_menu(C, buffer, hits, false, extend, deselect, toggle)) {
@@ -3071,6 +3093,9 @@ struct BoxSelectUserData_ForMeshEdge {
struct EditSelectBuf_Cache *esel;
uint backbuf_offset;
};
+/**
+ * Pass 0 operates on edges when fully inside.
+ */
static void do_mesh_box_select__doSelectEdge_pass0(
void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
{
@@ -3092,6 +3117,9 @@ static void do_mesh_box_select__doSelectEdge_pass0(
data->is_changed = true;
}
}
+/**
+ * Pass 1 operates on edges when partially inside.
+ */
static void do_mesh_box_select__doSelectEdge_pass1(
void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
{
@@ -3181,11 +3209,16 @@ static bool do_mesh_box_select(ViewContext *vc,
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_NEAR |
(use_zbuf ? 0 : V3D_PROJ_TEST_CLIP_BB);
+ /* Fully inside. */
mesh_foreachScreenEdge_clip_bb_segment(
vc, do_mesh_box_select__doSelectEdge_pass0, &cb_data, clip_flag);
if (data.is_done == false) {
- mesh_foreachScreenEdge_clip_bb_segment(
- vc, do_mesh_box_select__doSelectEdge_pass1, &cb_data, clip_flag);
+ /* Fall back to partially inside.
+ * Clip content to account for edges partially behind the view. */
+ mesh_foreachScreenEdge_clip_bb_segment(vc,
+ do_mesh_box_select__doSelectEdge_pass1,
+ &cb_data,
+ clip_flag | V3D_PROJ_TEST_CLIP_CONTENT_DEFAULT);
}
}
@@ -3571,7 +3604,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
}
break;
default:
- BLI_assert(!"box select on incorrect object type");
+ BLI_assert_msg(0, "box select on incorrect object type");
break;
}
changed_multi |= changed;
@@ -3725,6 +3758,9 @@ static bool mesh_circle_select(ViewContext *vc,
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
if (vc->em->bm->totvertsel) {
EDBM_flag_disable_all(vc->em, BM_ELEM_SELECT);
+ vc->em->bm->totvertsel = 0;
+ vc->em->bm->totedgesel = 0;
+ vc->em->bm->totfacesel = 0;
changed = true;
}
}
@@ -3771,7 +3807,10 @@ static bool mesh_circle_select(ViewContext *vc,
}
else {
mesh_foreachScreenEdge_clip_bb_segment(
- vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR | V3D_PROJ_TEST_CLIP_BB);
+ vc,
+ mesh_circle_doSelectEdge,
+ &data,
+ (V3D_PROJ_TEST_CLIP_NEAR | V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_CONTENT_DEFAULT));
}
}
@@ -3790,7 +3829,8 @@ static bool mesh_circle_select(ViewContext *vc,
changed |= data.is_changed;
if (changed) {
- EDBM_selectmode_flush(vc->em);
+ BM_mesh_select_mode_flush_ex(
+ vc->em->bm, vc->em->selectmode, BM_SELECT_LEN_FLUSH_RECALC_NOTHING);
}
return changed;
}
@@ -4016,47 +4056,48 @@ static void do_circle_select_pose__doSelectBone(void *userData,
{
CircleSelectUserData *data = userData;
bArmature *arm = data->vc->obact->data;
+ if (!PBONE_SELECTABLE(arm, pchan->bone)) {
+ return;
+ }
- if (PBONE_SELECTABLE(arm, pchan->bone)) {
- bool is_point_done = false;
- int points_proj_tot = 0;
+ bool is_point_done = false;
+ int points_proj_tot = 0;
- /* project head location to screenspace */
- if (screen_co_a[0] != IS_CLIPPED) {
- points_proj_tot++;
- if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) {
- is_point_done = true;
- }
+ /* project head location to screenspace */
+ if (screen_co_a[0] != IS_CLIPPED) {
+ points_proj_tot++;
+ if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) {
+ is_point_done = true;
}
+ }
- /* project tail location to screenspace */
- if (screen_co_b[0] != IS_CLIPPED) {
- points_proj_tot++;
- if (pchan_circle_doSelectJoint(data, pchan, screen_co_b)) {
- is_point_done = true;
- }
+ /* project tail location to screenspace */
+ if (screen_co_b[0] != IS_CLIPPED) {
+ points_proj_tot++;
+ if (pchan_circle_doSelectJoint(data, pchan, screen_co_b)) {
+ is_point_done = true;
}
+ }
- /* check if the head and/or tail is in the circle
- * - the call to check also does the selection already
- */
+ /* check if the head and/or tail is in the circle
+ * - the call to check also does the selection already
+ */
- /* only if the endpoints didn't get selected, deal with the middle of the bone too
- * It works nicer to only do this if the head or tail are not in the circle,
- * otherwise there is no way to circle select joints alone */
- if ((is_point_done == false) && (points_proj_tot == 2) &&
- edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) {
- if (data->select) {
- pchan->bone->flag |= BONE_SELECTED;
- }
- else {
- pchan->bone->flag &= ~BONE_SELECTED;
- }
- data->is_changed = true;
+ /* only if the endpoints didn't get selected, deal with the middle of the bone too
+ * It works nicer to only do this if the head or tail are not in the circle,
+ * otherwise there is no way to circle select joints alone */
+ if ((is_point_done == false) && (points_proj_tot == 2) &&
+ edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) {
+ if (data->select) {
+ pchan->bone->flag |= BONE_SELECTED;
}
-
- data->is_changed |= is_point_done;
+ else {
+ pchan->bone->flag &= ~BONE_SELECTED;
+ }
+ data->is_changed = true;
}
+
+ data->is_changed |= is_point_done;
}
static bool pose_circle_select(ViewContext *vc,
const eSelectOp sel_op,
@@ -4075,8 +4116,11 @@ static bool pose_circle_select(ViewContext *vc,
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
- pose_foreachScreenBone(
- vc, do_circle_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ /* Treat bones as clipped segments (no joints). */
+ pose_foreachScreenBone(vc,
+ do_circle_select_pose__doSelectBone,
+ &data,
+ V3D_PROJ_TEST_CLIP_DEFAULT | V3D_PROJ_TEST_CLIP_CONTENT_DEFAULT);
if (data.is_changed) {
ED_pose_bone_select_tag_update(vc->obact);
@@ -4118,47 +4162,74 @@ static void do_circle_select_armature__doSelectBone(void *userData,
const float screen_co_b[2])
{
CircleSelectUserData *data = userData;
- bArmature *arm = data->vc->obedit->data;
+ const bArmature *arm = data->vc->obedit->data;
+ if (!(data->select ? EBONE_SELECTABLE(arm, ebone) : EBONE_VISIBLE(arm, ebone))) {
+ return;
+ }
- if (data->select ? EBONE_SELECTABLE(arm, ebone) : EBONE_VISIBLE(arm, ebone)) {
- bool is_point_done = false;
- int points_proj_tot = 0;
+ /* When true, ignore in the next pass. */
+ ebone->temp.i = false;
- /* project head location to screenspace */
- if (screen_co_a[0] != IS_CLIPPED) {
- points_proj_tot++;
- if (armature_circle_doSelectJoint(data, ebone, screen_co_a, true)) {
- is_point_done = true;
- }
+ bool is_point_done = false;
+ bool is_edge_done = false;
+ int points_proj_tot = 0;
+
+ /* project head location to screenspace */
+ if (screen_co_a[0] != IS_CLIPPED) {
+ points_proj_tot++;
+ if (armature_circle_doSelectJoint(data, ebone, screen_co_a, true)) {
+ is_point_done = true;
}
+ }
- /* project tail location to screenspace */
- if (screen_co_b[0] != IS_CLIPPED) {
- points_proj_tot++;
- if (armature_circle_doSelectJoint(data, ebone, screen_co_b, false)) {
- is_point_done = true;
- }
+ /* project tail location to screenspace */
+ if (screen_co_b[0] != IS_CLIPPED) {
+ points_proj_tot++;
+ if (armature_circle_doSelectJoint(data, ebone, screen_co_b, false)) {
+ is_point_done = true;
}
+ }
- /* check if the head and/or tail is in the circle
- * - the call to check also does the selection already
- */
+ /* check if the head and/or tail is in the circle
+ * - the call to check also does the selection already
+ */
- /* only if the endpoints didn't get selected, deal with the middle of the bone too
- * It works nicer to only do this if the head or tail are not in the circle,
- * otherwise there is no way to circle select joints alone */
- if ((is_point_done == false) && (points_proj_tot == 2) &&
- edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) {
- if (data->select) {
- ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- }
- else {
- ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- }
- data->is_changed = true;
- }
+ /* only if the endpoints didn't get selected, deal with the middle of the bone too
+ * It works nicer to only do this if the head or tail are not in the circle,
+ * otherwise there is no way to circle select joints alone */
+ if ((is_point_done == false) && (points_proj_tot == 2) &&
+ edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) {
+ SET_FLAG_FROM_TEST(ebone->flag, data->select, BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ is_edge_done = true;
+ data->is_changed = true;
+ }
+
+ if (is_point_done || is_edge_done) {
+ ebone->temp.i = true;
+ }
+
+ data->is_changed |= is_point_done;
+}
+static void do_circle_select_armature__doSelectBone_clip_content(void *userData,
+ struct EditBone *ebone,
+ const float screen_co_a[2],
+ const float screen_co_b[2])
+{
+ CircleSelectUserData *data = userData;
+ bArmature *arm = data->vc->obedit->data;
- data->is_changed |= is_point_done;
+ if (!(data->select ? EBONE_SELECTABLE(arm, ebone) : EBONE_VISIBLE(arm, ebone))) {
+ return;
+ }
+
+ /* Set in the first pass, needed so circle select prioritizes joints. */
+ if (ebone->temp.i == true) {
+ return;
+ }
+
+ if (edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) {
+ SET_FLAG_FROM_TEST(ebone->flag, data->select, BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ data->is_changed = true;
}
}
static bool armature_circle_select(ViewContext *vc,
@@ -4179,9 +4250,18 @@ static bool armature_circle_select(ViewContext *vc,
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+ /* Operate on fully visible (non-clipped) points. */
armature_foreachScreenBone(
vc, do_circle_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ /* Operate on bones as segments clipped to the viewport bounds
+ * (needed to handle bones with both points outside the view).
+ * A separate pass is needed since clipped coordinates can't be used for selecting joints. */
+ armature_foreachScreenBone(vc,
+ do_circle_select_armature__doSelectBone_clip_content,
+ &data,
+ V3D_PROJ_TEST_CLIP_DEFAULT | V3D_PROJ_TEST_CLIP_CONTENT_DEFAULT);
+
if (data.is_changed) {
ED_armature_edit_sync_selection(arm->edbo);
ED_armature_edit_validate_active(arm);
@@ -4362,7 +4442,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
FOREACH_OBJECT_IN_MODE_END;
}
else if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) {
- if (PE_circle_select(C, sel_op, mval, (float)radius)) {
+ if (PE_circle_select(C, wm_userdata, sel_op, mval, (float)radius)) {
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 72c62321e88..4482e5897ca 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -155,7 +155,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
/* Get location of grid point in pose space. */
BKE_armature_loc_pose_to_bone(pchan_eval, vec, vec);
- /* adjust location on the original pchan*/
+ /* Adjust location on the original pchan. */
bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, pchan_eval->name);
if ((pchan->protectflag & OB_LOCK_LOCX) == 0) {
pchan->loc[0] = vec[0];
@@ -511,47 +511,47 @@ static int snap_selected_to_location(bContext *C,
for (int ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
+ if (ob->parent && BKE_object_flag_test_recursive(ob->parent, OB_DONE)) {
+ continue;
+ }
- if ((ob->parent && BKE_object_flag_test_recursive(ob->parent, OB_DONE)) == 0) {
-
- float cursor_parent[3]; /* parent-relative */
-
- if (use_offset) {
- add_v3_v3v3(cursor_parent, ob->obmat[3], offset_global);
- }
- else {
- copy_v3_v3(cursor_parent, snap_target_global);
- }
+ float cursor_parent[3]; /* parent-relative */
- sub_v3_v3(cursor_parent, ob->obmat[3]);
+ if (use_offset) {
+ add_v3_v3v3(cursor_parent, ob->obmat[3], offset_global);
+ }
+ else {
+ copy_v3_v3(cursor_parent, snap_target_global);
+ }
- if (ob->parent) {
- float originmat[3][3], parentmat[4][4];
- /* Use the evaluated object here because sometimes
- * `ob->parent->runtime.curve_cache` is required. */
- BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+ sub_v3_v3(cursor_parent, ob->obmat[3]);
- BKE_object_get_parent_matrix(ob_eval, ob_eval->parent, parentmat);
- mul_m3_m4m4(originmat, parentmat, ob->parentinv);
- invert_m3_m3(imat, originmat);
- mul_m3_v3(imat, cursor_parent);
- }
- if ((ob->protectflag & OB_LOCK_LOCX) == 0) {
- ob->loc[0] += cursor_parent[0];
- }
- if ((ob->protectflag & OB_LOCK_LOCY) == 0) {
- ob->loc[1] += cursor_parent[1];
- }
- if ((ob->protectflag & OB_LOCK_LOCZ) == 0) {
- ob->loc[2] += cursor_parent[2];
- }
+ if (ob->parent) {
+ float originmat[3][3], parentmat[4][4];
+ /* Use the evaluated object here because sometimes
+ * `ob->parent->runtime.curve_cache` is required. */
+ BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+
+ BKE_object_get_parent_matrix(ob_eval, ob_eval->parent, parentmat);
+ mul_m3_m4m4(originmat, parentmat, ob->parentinv);
+ invert_m3_m3(imat, originmat);
+ mul_m3_v3(imat, cursor_parent);
+ }
+ if ((ob->protectflag & OB_LOCK_LOCX) == 0) {
+ ob->loc[0] += cursor_parent[0];
+ }
+ if ((ob->protectflag & OB_LOCK_LOCY) == 0) {
+ ob->loc[1] += cursor_parent[1];
+ }
+ if ((ob->protectflag & OB_LOCK_LOCZ) == 0) {
+ ob->loc[2] += cursor_parent[2];
+ }
- /* auto-keyframing */
- ED_autokeyframe_object(C, scene, ob, ks);
+ /* auto-keyframing */
+ ED_autokeyframe_object(C, scene, ob, ks);
- DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
- }
+ DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
}
if (objects) {
@@ -895,7 +895,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
/**
* Calculates the center position of the active object in global space.
*
- * Note: this could be exported to be a generic function.
+ * NOTE: this could be exported to be a generic function.
* see: #calculateCenterActive
*/
static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3])
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index f96c17d7cff..8bcc05c1e55 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -260,7 +260,7 @@ bool ED_view3d_context_activate(bContext *C)
return false;
}
- /* bad context switch .. */
+ /* Bad context switch. */
CTX_wm_area_set(C, area);
CTX_wm_region_set(C, region);
@@ -299,8 +299,8 @@ void ED_view3d_clipping_calc(
float xs = (ELEM(val, 0, 3)) ? rect->xmin : rect->xmax;
float ys = (ELEM(val, 0, 1)) ? rect->ymin : rect->ymax;
- ED_view3d_unproject(region, xs, ys, 0.0, bb->vec[val]);
- ED_view3d_unproject(region, xs, ys, 1.0, bb->vec[4 + val]);
+ ED_view3d_unproject_v3(region, xs, ys, 0.0, bb->vec[val]);
+ ED_view3d_unproject_v3(region, xs, ys, 1.0, bb->vec[4 + val]);
}
/* optionally transform to object space */
@@ -530,7 +530,7 @@ void ED_view3d_persp_switch_from_camera(const Depsgraph *depsgraph,
}
/**
* Action to take when rotating the view,
- * handle auto-persp and logic for switching out of views.
+ * handle auto-perspective and logic for switching out of views.
*
* shared with NDOF.
*/
@@ -1017,7 +1017,7 @@ static float view_autodist_depth_margin(ARegion *region, const int mval[2], int
}
ViewDepths depth_temp = {0};
- view3d_update_depths_rect(region, &depth_temp, &rect);
+ view3d_depths_rect_create(region, &rect, &depth_temp);
float depth_close = view3d_depth_near(&depth_temp);
MEM_SAFE_FREE(depth_temp.depths);
return depth_close;
@@ -1044,7 +1044,7 @@ bool ED_view3d_autodist(Depsgraph *depsgraph,
bool depth_ok = false;
/* Get Z Depths, needed for perspective, nice for ortho */
- ED_view3d_depth_override(depsgraph, region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, false);
+ ED_view3d_depth_override(depsgraph, region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, NULL);
/* Attempt with low margin's first */
int i = 0;
@@ -1057,7 +1057,7 @@ bool ED_view3d_autodist(Depsgraph *depsgraph,
float centx = (float)mval[0] + 0.5f;
float centy = (float)mval[1] + 0.5f;
- if (ED_view3d_unproject(region, centx, centy, depth_close, mouse_worldloc)) {
+ if (ED_view3d_unproject_v3(region, centx, centy, depth_close, mouse_worldloc)) {
return true;
}
}
@@ -1091,7 +1091,7 @@ bool ED_view3d_autodist_simple(ARegion *region,
float centx = (float)mval[0] + 0.5f;
float centy = (float)mval[1] + 0.5f;
- return ED_view3d_unproject(region, centx, centy, depth, mouse_worldloc);
+ return ED_view3d_unproject_v3(region, centx, centy, depth, mouse_worldloc);
}
bool ED_view3d_autodist_depth(ARegion *region, const int mval[2], int margin, float *depth)
@@ -1694,20 +1694,18 @@ bool ED_view3d_depth_read_cached(const ViewDepths *vd,
return false;
}
-bool ED_view3d_depth_read_cached_normal(const ViewContext *vc,
+bool ED_view3d_depth_read_cached_normal(const ARegion *region,
+ const ViewDepths *depths,
const int mval[2],
float r_normal[3])
{
- /* Note: we could support passing in a radius.
+ /* NOTE: we could support passing in a radius.
* For now just read 9 pixels. */
/* pixels surrounding */
bool depths_valid[9] = {false};
float coords[9][3] = {{0}};
- ARegion *region = vc->region;
- const ViewDepths *depths = vc->rv3d->depths;
-
for (int x = 0, i = 0; x < 2; x++) {
for (int y = 0; y < 2; y++) {
const int mval_ofs[2] = {mval[0] + (x - 1), mval[1] + (y - 1)};
@@ -1716,7 +1714,7 @@ bool ED_view3d_depth_read_cached_normal(const ViewContext *vc,
ED_view3d_depth_read_cached(depths, mval_ofs, 0, &depth_fl);
const double depth = (double)depth_fl;
if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
- if (ED_view3d_depth_unproject(region, mval_ofs, depth, coords[i])) {
+ if (ED_view3d_depth_unproject_v3(region, mval_ofs, depth, coords[i])) {
depths_valid[i] = true;
}
}
@@ -1751,21 +1749,14 @@ bool ED_view3d_depth_read_cached_normal(const ViewContext *vc,
return false;
}
-bool ED_view3d_depth_unproject(const ARegion *region,
- const int mval[2],
- const double depth,
- float r_location_world[3])
+bool ED_view3d_depth_unproject_v3(const ARegion *region,
+ const int mval[2],
+ const double depth,
+ float r_location_world[3])
{
float centx = (float)mval[0] + 0.5f;
float centy = (float)mval[1] + 0.5f;
- return ED_view3d_unproject(region, centx, centy, depth, r_location_world);
-}
-
-void ED_view3d_depth_tag_update(RegionView3D *rv3d)
-{
- if (rv3d->depths) {
- rv3d->depths->damaged = true;
- }
+ return ED_view3d_unproject_v3(region, centx, centy, depth, r_location_world);
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 21cb8560e9b..86a610f8dd9 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -85,7 +85,7 @@ struct SmoothView3DState {
};
struct SmoothView3DStore {
- /* source*/
+ /* Source. */
struct SmoothView3DState src; /* source */
struct SmoothView3DState dst; /* destination */
struct SmoothView3DState org; /* original */
@@ -235,7 +235,7 @@ void ED_view3d_smooth_view_ex(
/* grid draw as floor */
if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) {
/* use existing if exists, means multiple calls to smooth view
- * wont lose the original 'view' setting */
+ * won't lose the original 'view' setting */
rv3d->view = RV3D_VIEW_USER;
}
@@ -244,7 +244,7 @@ void ED_view3d_smooth_view_ex(
/* if this is view rotation only
* we can decrease the time allowed by
* the angle between quats
- * this means small rotations wont lag */
+ * this means small rotations won't lag */
if (sview->quat && !sview->ofs && !sview->dist) {
/* scale the time allowed by the rotation */
/* 180deg == 1.0 */
@@ -392,7 +392,7 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, b
view3d_boxview_copy(CTX_wm_area(C), region);
}
- /* note: this doesn't work right because the v3d->lens is now used in ortho mode r51636,
+ /* NOTE: this doesn't work right because the v3d->lens is now used in ortho mode r51636,
* when switching camera in quad-view the other ortho views would zoom & reset.
*
* For now only redraw all regions when smooth-view finishes.
@@ -1261,7 +1261,7 @@ static bool view3d_localview_init(const Depsgraph *depsgraph,
if (local_view_bit == 0) {
/* TODO(dfelinto): We can kick one of the other 3D views out of local view
- * specially if it is not being used. */
+ * specially if it is not being used. */
BKE_report(reports, RPT_ERROR, "No more than 16 local views");
ok = false;
}
@@ -1393,6 +1393,7 @@ static void view3d_localview_exit(const Depsgraph *depsgraph,
MEM_freeN(v3d->localvd);
v3d->localvd = NULL;
+ MEM_SAFE_FREE(v3d->runtime.local_stats);
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->regiontype == RGN_TYPE_WINDOW) {
@@ -1516,7 +1517,7 @@ static int localview_remove_from_exec(bContext *C, wmOperator *op)
}
if (changed) {
- DEG_on_visible_update(bmain, false);
+ DEG_tag_on_visible_update(bmain, false);
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
@@ -1564,7 +1565,7 @@ static uint free_localcollection_bit(Main *bmain, ushort local_collections_uuid,
ushort local_view_bits = 0;
- /* Check all areas: which localviews are in use? */
+ /* Check all areas: which local-views are in use? */
for (screen = bmain->screens.first; screen; screen = screen->id.next) {
for (area = screen->areabase.first; area; area = area->next) {
SpaceLink *sl = area->spacedata.first;
diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt
index b0bc5c6abda..ad0a330f0f4 100644
--- a/source/blender/editors/transform/CMakeLists.txt
+++ b/source/blender/editors/transform/CMakeLists.txt
@@ -102,6 +102,7 @@ set(SRC
transform_orientations.c
transform_snap.c
transform_snap_object.c
+ transform_snap_sequencer.c
transform.h
transform_constraints.h
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index ba8e5c1e2c6..d34cc6f424f 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -536,7 +536,7 @@ static void viewRedrawPost(bContext *C, TransInfo *t)
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
- /* XXX temp, first hack to get auto-render in compositor work (ton) */
+ /* XXX(ton): temp, first hack to get auto-render in compositor work. */
WM_event_add_notifier(C, NC_SCENE | ND_TRANSFORM_DONE, CTX_data_scene(C));
}
@@ -650,7 +650,7 @@ static bool transform_modal_item_poll(const wmOperator *op, int value)
return true;
}
-/* called in transform_ops.c, on each regeneration of keymaps */
+/* Called in transform_ops.c, on each regeneration of key-maps. */
wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
{
static const EnumPropertyItem modal_items[] = {
@@ -724,81 +724,92 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
static bool transform_event_modal_constraint(TransInfo *t, short modal_type)
{
- if (!(t->flag & T_NO_CONSTRAINT)) {
- if (t->flag & T_2D_EDIT && ELEM(modal_type, TFM_MODAL_AXIS_Z, TFM_MODAL_PLANE_Z)) {
+ if (t->flag & T_NO_CONSTRAINT) {
+ return false;
+ }
+
+ if (t->flag & T_2D_EDIT && ELEM(modal_type, TFM_MODAL_AXIS_Z, TFM_MODAL_PLANE_Z)) {
+ return false;
+ }
+
+ int constraint_curr = -1;
+
+ if (t->modifiers & (MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE)) {
+ t->modifiers &= ~(MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE);
+
+ /* Avoid changing orientation in this case. */
+ constraint_curr = -2;
+ }
+ else if (t->con.mode & CON_APPLY) {
+ constraint_curr = t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2);
+ }
+
+ int constraint_new;
+ const char *msg_2d = "", *msg_3d = "";
+
+ /* Initialize */
+ switch (modal_type) {
+ case TFM_MODAL_AXIS_X:
+ msg_2d = TIP_("along X");
+ msg_3d = TIP_("along %s X");
+ constraint_new = CON_AXIS0;
+ break;
+ case TFM_MODAL_AXIS_Y:
+ msg_2d = TIP_("along Y");
+ msg_3d = TIP_("along %s Y");
+ constraint_new = CON_AXIS1;
+ break;
+ case TFM_MODAL_AXIS_Z:
+ msg_2d = TIP_("along Z");
+ msg_3d = TIP_("along %s Z");
+ constraint_new = CON_AXIS2;
+ break;
+ case TFM_MODAL_PLANE_X:
+ msg_3d = TIP_("locking %s X");
+ constraint_new = CON_AXIS1 | CON_AXIS2;
+ break;
+ case TFM_MODAL_PLANE_Y:
+ msg_3d = TIP_("locking %s Y");
+ constraint_new = CON_AXIS0 | CON_AXIS2;
+ break;
+ case TFM_MODAL_PLANE_Z:
+ msg_3d = TIP_("locking %s Z");
+ constraint_new = CON_AXIS0 | CON_AXIS1;
+ break;
+ default:
+ /* Invalid key */
return false;
- }
- int constraint_curr = (t->con.mode & CON_APPLY) ?
- t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2) :
- -1;
- int constraint_new;
- const char *msg_2d = "", *msg_3d = "";
+ }
- /* Initialize */
- switch (modal_type) {
- case TFM_MODAL_AXIS_X:
- msg_2d = TIP_("along X");
- msg_3d = TIP_("along %s X");
- constraint_new = CON_AXIS0;
- break;
- case TFM_MODAL_AXIS_Y:
- msg_2d = TIP_("along Y");
- msg_3d = TIP_("along %s Y");
- constraint_new = CON_AXIS1;
- break;
- case TFM_MODAL_AXIS_Z:
- msg_2d = TIP_("along Z");
- msg_3d = TIP_("along %s Z");
- constraint_new = CON_AXIS2;
- break;
- case TFM_MODAL_PLANE_X:
- msg_3d = TIP_("locking %s X");
- constraint_new = CON_AXIS1 | CON_AXIS2;
- break;
- case TFM_MODAL_PLANE_Y:
- msg_3d = TIP_("locking %s Y");
- constraint_new = CON_AXIS0 | CON_AXIS2;
- break;
- case TFM_MODAL_PLANE_Z:
- msg_3d = TIP_("locking %s Z");
- constraint_new = CON_AXIS0 | CON_AXIS1;
- break;
- default:
- /* Invalid key */
- return false;
+ if (t->flag & T_2D_EDIT) {
+ BLI_assert(modal_type < TFM_MODAL_PLANE_X);
+ if (constraint_new == CON_AXIS2) {
+ return false;
}
-
- if (t->flag & T_2D_EDIT) {
- BLI_assert(modal_type < TFM_MODAL_PLANE_X);
- if (constraint_new == CON_AXIS2) {
- return false;
- }
- if (constraint_curr == constraint_new) {
- stopConstraint(t);
- }
- else {
- setUserConstraint(t, constraint_new, msg_2d);
- }
+ if (constraint_curr == constraint_new) {
+ stopConstraint(t);
}
else {
- short orient_index = 1;
- if (t->orient_curr == O_DEFAULT || ELEM(constraint_curr, -1, constraint_new)) {
- /* Successive presses on existing axis, cycle orientation modes. */
- orient_index = (short)((t->orient_curr + 1) % (int)ARRAY_SIZE(t->orient));
- }
+ setUserConstraint(t, constraint_new, msg_2d);
+ }
+ }
+ else {
+ short orient_index = 1;
+ if (t->orient_curr == O_DEFAULT || ELEM(constraint_curr, -1, constraint_new)) {
+ /* Successive presses on existing axis, cycle orientation modes. */
+ orient_index = (short)((t->orient_curr + 1) % (int)ARRAY_SIZE(t->orient));
+ }
- transform_orientations_current_set(t, orient_index);
- if (orient_index == 0) {
- stopConstraint(t);
- }
- else {
- setUserConstraint(t, constraint_new, msg_3d);
- }
+ transform_orientations_current_set(t, orient_index);
+ if (orient_index == 0) {
+ stopConstraint(t);
+ }
+ else {
+ setUserConstraint(t, constraint_new, msg_3d);
}
- t->redraw |= TREDRAW_HARD;
- return true;
}
- return false;
+ t->redraw |= TREDRAW_HARD;
+ return true;
}
int transformEvent(TransInfo *t, const wmEvent *event)
@@ -814,7 +825,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
}
else if (event->type == MOUSEMOVE) {
- if (t->modifiers & (MOD_CONSTRAINT_SELECT | MOD_CONSTRAINT_PLANE)) {
+ if (t->modifiers & (MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE)) {
t->con.mode |= CON_SELECT;
}
@@ -1062,10 +1073,10 @@ int transformEvent(TransInfo *t, const wmEvent *event)
t->state = TRANS_CONFIRM;
}
else if ((t->flag & T_NO_CONSTRAINT) == 0) {
- if (t->modifiers & (MOD_CONSTRAINT_SELECT | MOD_CONSTRAINT_PLANE)) {
+ if (t->modifiers & (MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE)) {
/* Confirm. */
postSelectConstraint(t);
- t->modifiers &= ~(MOD_CONSTRAINT_SELECT | MOD_CONSTRAINT_PLANE);
+ t->modifiers &= ~(MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE);
}
else {
if (t->options & CTX_CAMERA) {
@@ -1079,8 +1090,9 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
}
else {
- t->modifiers |= (event->val == TFM_MODAL_AUTOCONSTRAINT) ? MOD_CONSTRAINT_SELECT :
- MOD_CONSTRAINT_PLANE;
+ t->modifiers |= (event->val == TFM_MODAL_AUTOCONSTRAINT) ?
+ MOD_CONSTRAINT_SELECT_AXIS :
+ MOD_CONSTRAINT_SELECT_PLANE;
if (t->con.mode & CON_APPLY) {
stopConstraint(t);
}
@@ -1685,31 +1697,11 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->draw_handle_cursor = WM_paint_cursor_activate(
SPACE_TYPE_ANY, RGN_TYPE_ANY, transform_draw_cursor_poll, transform_draw_cursor_draw, t);
}
- else if (t->spacetype == SPACE_IMAGE) {
- t->draw_handle_view = ED_region_draw_cb_activate(
- t->region->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- SPACE_TYPE_ANY, RGN_TYPE_ANY, transform_draw_cursor_poll, transform_draw_cursor_draw, t);
- }
- else if (t->spacetype == SPACE_CLIP) {
- t->draw_handle_view = ED_region_draw_cb_activate(
- t->region->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- SPACE_TYPE_ANY, RGN_TYPE_ANY, transform_draw_cursor_poll, transform_draw_cursor_draw, t);
- }
- else if (t->spacetype == SPACE_NODE) {
- t->draw_handle_view = ED_region_draw_cb_activate(
- t->region->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- SPACE_TYPE_ANY, RGN_TYPE_ANY, transform_draw_cursor_poll, transform_draw_cursor_draw, t);
- }
- else if (t->spacetype == SPACE_GRAPH) {
+ else if (t->spacetype == SPACE_SEQ) {
t->draw_handle_view = ED_region_draw_cb_activate(
t->region->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- SPACE_TYPE_ANY, RGN_TYPE_ANY, transform_draw_cursor_poll, transform_draw_cursor_draw, t);
}
- else if (t->spacetype == SPACE_ACTION) {
+ else if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP, SPACE_NODE, SPACE_GRAPH, SPACE_ACTION)) {
t->draw_handle_view = ED_region_draw_cb_activate(
t->region->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
t->draw_handle_cursor = WM_paint_cursor_activate(
@@ -1945,7 +1937,7 @@ int transformEnd(bContext *C, TransInfo *t)
return exit_code;
}
-/* TODO, move to: transform_query.c */
+/* TODO: move to: `transform_query.c`. */
bool checkUseAxisMatrix(TransInfo *t)
{
/* currently only checks for editmode */
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index a10a53b2983..1a61a594f37 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -46,6 +46,7 @@
* \{ */
struct ARegion;
+struct BMPartialUpdate;
struct Depsgraph;
struct NumInput;
struct Object;
@@ -148,15 +149,18 @@ typedef enum {
T_AUTOMERGE = 1 << 20,
/** Runs auto-merge & splits. */
T_AUTOSPLIT = 1 << 21,
+
+ /** No cursor wrapping on region bounds */
+ T_NO_CURSOR_WRAP = 1 << 23,
} eTFlag;
/** #TransInfo.modifiers */
typedef enum {
- MOD_CONSTRAINT_SELECT = 1 << 0,
+ MOD_CONSTRAINT_SELECT_AXIS = 1 << 0,
MOD_PRECISION = 1 << 1,
MOD_SNAP = 1 << 2,
MOD_SNAP_INVERT = 1 << 3,
- MOD_CONSTRAINT_PLANE = 1 << 4,
+ MOD_CONSTRAINT_SELECT_PLANE = 1 << 4,
} eTModifier;
/** #TransSnap.status */
@@ -331,7 +335,10 @@ typedef struct TransSnap {
/**
* Re-usable snap context data.
*/
- struct SnapObjectContext *object_context;
+ union {
+ struct SnapObjectContext *object_context;
+ struct TransSeqSnapData *seq_context;
+ };
} TransSnap;
typedef struct TransCon {
@@ -346,28 +353,28 @@ typedef struct TransCon {
eTConstraint mode;
void (*drawExtra)(struct TransInfo *t);
- /* Note: if 'tc' is NULL, 'td' must also be NULL.
+ /* NOTE: if 'tc' is NULL, 'td' must also be NULL.
* For constraints that needs to draw differently from the other
* uses this instead of the generic draw function. */
/** Apply function pointer for linear vectorial transformation
* The last three parameters are pointers to the in/out/printable vectors. */
- void (*applyVec)(struct TransInfo *t,
- struct TransDataContainer *tc,
+ void (*applyVec)(const struct TransInfo *t,
+ const struct TransDataContainer *tc,
struct TransData *td,
const float in[3],
- float out[3]);
+ float r_out[3]);
/** Apply function pointer for size transformation. */
- void (*applySize)(struct TransInfo *t,
- struct TransDataContainer *tc,
+ void (*applySize)(const struct TransInfo *t,
+ const struct TransDataContainer *tc,
struct TransData *td,
- float smat[3][3]);
+ float r_smat[3][3]);
/** Apply function pointer for rotation transformation */
- void (*applyRot)(struct TransInfo *t,
- struct TransDataContainer *tc,
+ void (*applyRot)(const struct TransInfo *t,
+ const struct TransDataContainer *tc,
struct TransData *td,
- float vec[3],
- float *angle);
+ float r_axis[3],
+ float *r_angle);
} TransCon;
typedef struct MouseInput {
@@ -419,7 +426,7 @@ typedef struct TransCenterData {
* (typically in transform_conversion.c).
*/
typedef struct TransCustomDataContainer {
- /** Owned by the mode (grab, scale, bend... ).*/
+ /** Owned by the mode (grab, scale, bend... ). */
union {
TransCustomData mode, first_elem;
};
@@ -430,14 +437,14 @@ typedef struct TransCustomDataContainer {
/**
* Container for Transform Data
*
- * Used to implement multi-object modes, so each object can have it's
+ * Used to implement multi-object modes, so each object can have its
* own data array as well as object matrix, local center etc.
*
* Anything that can't be shared between all objects
* and doesn't make sense to store for every vertex (in the #TransDataContainer.data).
*
* \note at some point this could be used to store non object containers
- * although this only makes sense if each container has it's own matrices,
+ * although this only makes sense if each container has its own matrices,
* otherwise all elements may as well be stored in one array (#TransDataContainer.data),
* as is already done for curve-objects, f-curves. etc.
*/
@@ -795,7 +802,7 @@ struct Object *transform_object_deform_pose_armature_get(const TransInfo *t, str
void freeCustomNormalArray(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data);
-/* TODO. transform_query.c */
+/* TODO: `transform_query.c`. */
bool checkUseAxisMatrix(TransInfo *t);
#define TRANSFORM_SNAP_MAX_PX 100.0f
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 615467932a7..7135395ee2d 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -97,7 +97,7 @@ static void view_vector_calc(const TransInfo *t, const float focus[3], float r_v
/* ************************** CONSTRAINTS ************************* */
#define CONSTRAIN_EPSILON 0.0001f
-static void constraint_plane_calc(TransInfo *t, float r_plane[4])
+static void constraint_plane_calc(const TransInfo *t, float r_plane[4])
{
const float *constraint_vector[2];
int n = 0;
@@ -391,8 +391,11 @@ static void planeProjection(const TransInfo *t, const float in[3], float out[3])
* projected along the view vector.
* (in perspective mode, the view vector is relative to the position on screen)
*/
-static void applyAxisConstraintVec(
- TransInfo *t, TransDataContainer *UNUSED(tc), TransData *td, const float in[3], float out[3])
+static void applyAxisConstraintVec(const TransInfo *t,
+ const TransDataContainer *UNUSED(tc),
+ TransData *td,
+ const float in[3],
+ float out[3])
{
copy_v3_v3(out, in);
if (!td && t->con.mode & CON_APPLY) {
@@ -472,8 +475,11 @@ static void applyAxisConstraintVec(
*
* Further down, that vector is mapped to each data's space.
*/
-static void applyObjectConstraintVec(
- TransInfo *t, TransDataContainer *tc, TransData *td, const float in[3], float out[3])
+static void applyObjectConstraintVec(const TransInfo *t,
+ const TransDataContainer *tc,
+ TransData *td,
+ const float in[3],
+ float out[3])
{
if (!td) {
applyAxisConstraintVec(t, tc, td, in, out);
@@ -494,36 +500,36 @@ static void applyObjectConstraintVec(
/**
* Generic callback for constant spatial constraints applied to resize motion.
*/
-static void applyAxisConstraintSize(TransInfo *t,
- TransDataContainer *UNUSED(tc),
+static void applyAxisConstraintSize(const TransInfo *t,
+ const TransDataContainer *UNUSED(tc),
TransData *td,
- float smat[3][3])
+ float r_smat[3][3])
{
if (!td && t->con.mode & CON_APPLY) {
float tmat[3][3];
if (!(t->con.mode & CON_AXIS0)) {
- smat[0][0] = 1.0f;
+ r_smat[0][0] = 1.0f;
}
if (!(t->con.mode & CON_AXIS1)) {
- smat[1][1] = 1.0f;
+ r_smat[1][1] = 1.0f;
}
if (!(t->con.mode & CON_AXIS2)) {
- smat[2][2] = 1.0f;
+ r_smat[2][2] = 1.0f;
}
- mul_m3_m3m3(tmat, smat, t->spacemtx_inv);
- mul_m3_m3m3(smat, t->spacemtx, tmat);
+ mul_m3_m3m3(tmat, r_smat, t->spacemtx_inv);
+ mul_m3_m3m3(r_smat, t->spacemtx, tmat);
}
}
/**
* Callback for object based spatial constraints applied to resize motion.
*/
-static void applyObjectConstraintSize(TransInfo *t,
- TransDataContainer *tc,
+static void applyObjectConstraintSize(const TransInfo *t,
+ const TransDataContainer *tc,
TransData *td,
- float smat[3][3])
+ float r_smat[3][3])
{
if (td && t->con.mode & CON_APPLY) {
float tmat[3][3];
@@ -532,26 +538,26 @@ static void applyObjectConstraintSize(TransInfo *t,
invert_m3_m3(imat, td->axismtx);
if (!(t->con.mode & CON_AXIS0)) {
- smat[0][0] = 1.0f;
+ r_smat[0][0] = 1.0f;
}
if (!(t->con.mode & CON_AXIS1)) {
- smat[1][1] = 1.0f;
+ r_smat[1][1] = 1.0f;
}
if (!(t->con.mode & CON_AXIS2)) {
- smat[2][2] = 1.0f;
+ r_smat[2][2] = 1.0f;
}
- mul_m3_m3m3(tmat, smat, imat);
+ mul_m3_m3m3(tmat, r_smat, imat);
if (t->flag & T_EDIT) {
- mul_m3_m3m3(smat, tc->mat3_unit, smat);
+ mul_m3_m3m3(r_smat, tc->mat3_unit, r_smat);
}
- mul_m3_m3m3(smat, td->axismtx, tmat);
+ mul_m3_m3m3(r_smat, td->axismtx, tmat);
}
}
-static void constraints_rotation_impl(TransInfo *t,
+static void constraints_rotation_impl(const TransInfo *t,
const float axismtx[3][3],
- float r_vec[3],
+ float r_axis[3],
float *r_angle)
{
BLI_assert(t->con.mode & CON_APPLY);
@@ -560,15 +566,15 @@ static void constraints_rotation_impl(TransInfo *t,
switch (mode) {
case CON_AXIS0:
case (CON_AXIS1 | CON_AXIS2):
- copy_v3_v3(r_vec, axismtx[0]);
+ copy_v3_v3(r_axis, axismtx[0]);
break;
case CON_AXIS1:
case (CON_AXIS0 | CON_AXIS2):
- copy_v3_v3(r_vec, axismtx[1]);
+ copy_v3_v3(r_axis, axismtx[1]);
break;
case CON_AXIS2:
case (CON_AXIS0 | CON_AXIS1):
- copy_v3_v3(r_vec, axismtx[2]);
+ copy_v3_v3(r_axis, axismtx[2]);
break;
}
/* don't flip axis if asked to or if num input */
@@ -576,7 +582,7 @@ static void constraints_rotation_impl(TransInfo *t,
!((mode & CON_NOFLIP) || hasNumInput(&t->num) || (t->flag & T_INPUT_IS_VALUES_FINAL))) {
float view_vector[3];
view_vector_calc(t, t->center_global, view_vector);
- if (dot_v3v3(r_vec, view_vector) > 0.0f) {
+ if (dot_v3v3(r_axis, view_vector) > 0.0f) {
*r_angle = -(*r_angle);
}
}
@@ -595,11 +601,14 @@ static void constraints_rotation_impl(TransInfo *t,
* This insures that the rotation is always logically following the mouse.
* (ie: not doing counterclockwise rotations when the mouse moves clockwise).
*/
-static void applyAxisConstraintRot(
- TransInfo *t, TransDataContainer *UNUSED(tc), TransData *td, float vec[3], float *angle)
+static void applyAxisConstraintRot(const TransInfo *t,
+ const TransDataContainer *UNUSED(tc),
+ TransData *td,
+ float r_axis[3],
+ float *r_angle)
{
if (!td && t->con.mode & CON_APPLY) {
- constraints_rotation_impl(t, t->spacemtx, vec, angle);
+ constraints_rotation_impl(t, t->spacemtx, r_axis, r_angle);
}
}
@@ -616,8 +625,11 @@ static void applyAxisConstraintRot(
* This insures that the rotation is always logically following the mouse.
* (ie: not doing counterclockwise rotations when the mouse moves clockwise).
*/
-static void applyObjectConstraintRot(
- TransInfo *t, TransDataContainer *tc, TransData *td, float vec[3], float *angle)
+static void applyObjectConstraintRot(const TransInfo *t,
+ const TransDataContainer *tc,
+ TransData *td,
+ float r_axis[3],
+ float *r_angle)
{
if (t->con.mode & CON_APPLY) {
float tmp_axismtx[3][3];
@@ -638,7 +650,7 @@ static void applyObjectConstraintRot(
axismtx = td->axismtx;
}
- constraints_rotation_impl(t, axismtx, vec, angle);
+ constraints_rotation_impl(t, axismtx, r_axis, r_angle);
}
}
@@ -975,7 +987,6 @@ void initSelectConstraint(TransInfo *t)
}
setUserConstraint(t, CON_APPLY | CON_SELECT, "%s");
- setNearestAxis(t);
}
void selectConstraint(TransInfo *t)
@@ -1062,7 +1073,7 @@ static void setNearestAxis3d(TransInfo *t)
}
if (len[0] <= len[1] && len[0] <= len[2]) {
- if (t->modifiers & MOD_CONSTRAINT_PLANE) {
+ if (t->modifiers & MOD_CONSTRAINT_SELECT_PLANE) {
t->con.mode |= (CON_AXIS1 | CON_AXIS2);
BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s X axis"), t->spacename);
}
@@ -1072,7 +1083,7 @@ static void setNearestAxis3d(TransInfo *t)
}
}
else if (len[1] <= len[0] && len[1] <= len[2]) {
- if (t->modifiers & MOD_CONSTRAINT_PLANE) {
+ if (t->modifiers & MOD_CONSTRAINT_SELECT_PLANE) {
t->con.mode |= (CON_AXIS0 | CON_AXIS2);
BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s Y axis"), t->spacename);
}
@@ -1082,7 +1093,7 @@ static void setNearestAxis3d(TransInfo *t)
}
}
else if (len[2] <= len[1] && len[2] <= len[0]) {
- if (t->modifiers & MOD_CONSTRAINT_PLANE) {
+ if (t->modifiers & MOD_CONSTRAINT_SELECT_PLANE) {
t->con.mode |= (CON_AXIS0 | CON_AXIS1);
BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s Z axis"), t->spacename);
}
@@ -1139,7 +1150,7 @@ int constraintModeToIndex(const TransInfo *t)
}
}
-bool isLockConstraint(TransInfo *t)
+bool isLockConstraint(const TransInfo *t)
{
int mode = t->con.mode;
@@ -1165,7 +1176,7 @@ bool isLockConstraint(TransInfo *t)
* even if they aren't actually used in the callback function.
* (Which could happen for weird constraints not yet designed. Along a path for example.)
*/
-int getConstraintSpaceDimension(TransInfo *t)
+int getConstraintSpaceDimension(const TransInfo *t)
{
int n = 0;
diff --git a/source/blender/editors/transform/transform_constraints.h b/source/blender/editors/transform/transform_constraints.h
index ac62c057f9d..3632b352476 100644
--- a/source/blender/editors/transform/transform_constraints.h
+++ b/source/blender/editors/transform/transform_constraints.h
@@ -46,5 +46,5 @@ void postSelectConstraint(TransInfo *t);
void setNearestAxis(TransInfo *t);
int constraintModeToIndex(const TransInfo *t);
char constraintModeToChar(const TransInfo *t);
-bool isLockConstraint(TransInfo *t);
-int getConstraintSpaceDimension(TransInfo *t);
+bool isLockConstraint(const TransInfo *t);
+int getConstraintSpaceDimension(const TransInfo *t);
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index b4175faacf4..00fd008151d 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -816,7 +816,7 @@ bool constraints_list_needinv(TransInfo *t, ListBase *list)
/* only consider constraint if it is enabled, and has influence on result */
if ((con->flag & CONSTRAINT_DISABLE) == 0 && (con->enforce != 0.0f)) {
/* (affirmative) returns for specific constraints here... */
- /* constraints that require this regardless */
+ /* constraints that require this regardless. */
if (ELEM(con->type,
CONSTRAINT_TYPE_FOLLOWPATH,
CONSTRAINT_TYPE_CLAMPTO,
@@ -849,10 +849,13 @@ bool constraints_list_needinv(TransInfo *t, ListBase *list)
/* Copy Transforms constraint only does this in the Before mode. */
bTransLikeConstraint *data = (bTransLikeConstraint *)con->data;
- if (ELEM(data->mix_mode, TRANSLIKE_MIX_BEFORE) &&
+ if (ELEM(data->mix_mode, TRANSLIKE_MIX_BEFORE, TRANSLIKE_MIX_BEFORE_FULL) &&
ELEM(t->mode, TFM_ROTATION, TFM_TRANSLATION)) {
return true;
}
+ if (ELEM(data->mix_mode, TRANSLIKE_MIX_BEFORE_SPLIT) && ELEM(t->mode, TFM_ROTATION)) {
+ return true;
+ }
}
else if (con->type == CONSTRAINT_TYPE_ACTION) {
/* The Action constraint only does this in the Before mode. */
@@ -1698,9 +1701,11 @@ void recalcData(TransInfo *t)
recalcData_mask_common(t);
break;
case TC_MESH_VERTS:
- case TC_MESH_EDGES:
recalcData_mesh(t);
break;
+ case TC_MESH_EDGES:
+ recalcData_mesh_edge(t);
+ break;
case TC_MESH_SKIN:
recalcData_mesh_skin(t);
break;
diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h
index 11550ec8803..971c23b8c69 100644
--- a/source/blender/editors/transform/transform_convert.h
+++ b/source/blender/editors/transform/transform_convert.h
@@ -48,8 +48,8 @@ void clipUVData(TransInfo *t);
void transform_convert_mesh_customdatacorrect_init(TransInfo *t);
/* transform_convert_sequencer.c */
-int transform_convert_sequencer_get_snap_bound(TransInfo *t);
-void transform_convert_sequencer_channel_clamp(TransInfo *t);
+void transform_convert_sequencer_channel_clamp(TransInfo *t, float r_val[2]);
+
/********************* intern **********************/
/* transform_convert.c */
@@ -169,6 +169,7 @@ void special_aftertrans_update__mesh(bContext *C, TransInfo *t);
/* transform_convert_mesh_edge.c */
void createTransEdge(TransInfo *t);
+void recalcData_mesh_edge(TransInfo *t);
/* transform_convert_mesh_skin.c */
void createTransMeshSkin(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_convert_action.c b/source/blender/editors/transform/transform_convert_action.c
index 8204264e105..cfa14e21d0d 100644
--- a/source/blender/editors/transform/transform_convert_action.c
+++ b/source/blender/editors/transform/transform_convert_action.c
@@ -191,7 +191,7 @@ static TransData *ActionFCurveToTransData(TransData *td,
td->flag |= TD_SELECTED;
}
- /*set flags to move handles as necessary*/
+ /* Set flags to move handles as necessary. */
td->flag |= TD_MOVEHANDLE1 | TD_MOVEHANDLE2;
td2d->h1 = bezt->vec[0];
td2d->h2 = bezt->vec[2];
@@ -210,12 +210,13 @@ static TransData *ActionFCurveToTransData(TransData *td,
return td;
}
-/* This function advances the address to which td points to, so it must return
+/**
+ * This function advances the address to which td points to, so it must return
* the new address so that the next time new transform data is added, it doesn't
- * overwrite the existing ones... i.e. td = GPLayerToTransData(td, ipo, ob, side, cfra);
+ * overwrite the existing ones: e.g. `td += GPLayerToTransData(td, ...);`
*
- * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data
- * on the named side are used.
+ * \param side: is needed for the extend mode. 'B' = both sides,
+ * 'R'/'L' mean only data on the named side are used.
*/
static int GPLayerToTransData(TransData *td,
tGPFtransdata *tfd,
@@ -242,7 +243,7 @@ static int GPLayerToTransData(TransData *td,
tfd->val = (float)gpf->framenum;
tfd->sdata = &gpf->framenum;
- /* advance td now */
+ /* Advance `td` now. */
td++;
tfd++;
count++;
@@ -339,7 +340,7 @@ void createTransActionData(bContext *C, TransInfo *t)
t->frame_side = 'B';
}
- /* loop 1: fully select ipo-keys and count how many BezTriples are selected */
+ /* loop 1: fully select F-curve keys and count how many BezTriples are selected */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
int adt_count = 0;
@@ -554,7 +555,7 @@ void createTransActionData(bContext *C, TransInfo *t)
/** \name Action Transform Flush
* \{ */
-/* This function helps flush transdata written to tempdata into the gp-frames */
+/* This function helps flush transdata written to tempdata into the gp-frames. */
static void flushTransIntFrameActionData(TransInfo *t)
{
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c
index 7f24a0fa5f8..1f1b1f8db97 100644
--- a/source/blender/editors/transform/transform_convert_armature.c
+++ b/source/blender/editors/transform/transform_convert_armature.c
@@ -1268,9 +1268,6 @@ void recalcData_edit_armature(TransInfo *t)
restoreBones(tc);
}
}
-
- /* Tag for redraw/invalidate overlay cache. */
- DEG_id_tag_update(&arm->id, ID_RECALC_SELECT);
}
}
@@ -1452,9 +1449,9 @@ void recalcData_pose(TransInfo *t)
/* TODO: autokeyframe calls need some setting to specify to add samples
* (FPoints) instead of keyframes? */
if ((t->animtimer) && (t->context) && IS_AUTOKEY_ON(t->scene)) {
- int targetless_ik =
- (t->flag &
- T_AUTOIK); /* XXX this currently doesn't work, since flags aren't set yet! */
+
+ /* XXX: this currently doesn't work, since flags aren't set yet! */
+ int targetless_ik = (t->flag & T_AUTOIK);
animrecord_check_state(t, ob);
autokeyframe_pose(t->context, t->scene, ob, t->mode, targetless_ik);
@@ -1613,10 +1610,10 @@ static short apply_targetless_ik(Object *ob)
Bone *bone;
float mat[4][4];
- /* pose_mat(b) = pose_mat(b-1) * offs_bone * channel * constraint * IK */
- /* we put in channel the entire result of mat = (channel * constraint * IK) */
- /* pose_mat(b) = pose_mat(b-1) * offs_bone * mat */
- /* mat = pose_mat(b) * inv(pose_mat(b-1) * offs_bone ) */
+ /* `pose_mat(b) = pose_mat(b-1) * offs_bone * channel * constraint * IK` */
+ /* We put in channel the entire result of: `mat = (channel * constraint * IK)` */
+ /* `pose_mat(b) = pose_mat(b-1) * offs_bone * mat` */
+ /* `mat = pose_mat(b) * inv(pose_mat(b-1) * offs_bone)` */
parchan = chanlist[segcount - 1];
bone = parchan->bone;
diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c
index f294bbbf0aa..255af3feca2 100644
--- a/source/blender/editors/transform/transform_convert_curve.c
+++ b/source/blender/editors/transform/transform_convert_curve.c
@@ -277,8 +277,8 @@ void createTransCurveVerts(TransInfo *t)
}
td->ext = NULL;
- /* TODO - make points scale */
- if (t->mode == TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/
+ /* TODO: make points scale. */
+ if (t->mode == TFM_CURVE_SHRINKFATTEN /* `|| t->mode == TFM_RESIZE` */) {
td->val = &(bezt->radius);
td->ival = bezt->radius;
}
@@ -423,7 +423,7 @@ void createTransCurveVerts(TransInfo *t)
calc_distanceCurveVerts(head, tail, cyclic);
}
- /* TODO - in the case of tilt and radius we can also avoid allocating the
+ /* TODO: in the case of tilt and radius we can also avoid allocating the
* initTransDataCurveHandles but for now just don't change handle types */
if ((nu->type == CU_BEZIER) &&
ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT, TFM_DUMMY) == 0) {
@@ -449,11 +449,11 @@ void recalcData_curve(TransInfo *t)
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
Nurb *nu = nurbs->first;
- DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
+ DEG_id_tag_update(tc->obedit->data, ID_RECALC_GEOMETRY);
if (t->state == TRANS_CANCEL) {
while (nu) {
- /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
+ /* Can't do testhandlesNurb here, it messes up the h1 and h2 flags */
BKE_nurb_handles_calc(nu);
nu = nu->next;
}
diff --git a/source/blender/editors/transform/transform_convert_gpencil.c b/source/blender/editors/transform/transform_convert_gpencil.c
index 4932a5f8d23..f7b78b10868 100644
--- a/source/blender/editors/transform/transform_convert_gpencil.c
+++ b/source/blender/editors/transform/transform_convert_gpencil.c
@@ -176,7 +176,7 @@ static void createTransGPencil_curves(bContext *C,
}
}
- /* If not multiedit out of loop. */
+ /* If not multi-edit out of loop. */
if (!is_multiedit) {
break;
}
@@ -382,7 +382,7 @@ static void createTransGPencil_curves(bContext *C,
}
}
- /* If not multiedit out of loop. */
+ /* If not multi-edit out of loop. */
if (!is_multiedit) {
break;
}
@@ -470,7 +470,7 @@ static void createTransGPencil_strokes(bContext *C,
}
}
}
- /* If not multiedit out of loop. */
+ /* If not multi-edit out of loop. */
if (!is_multiedit) {
break;
}
@@ -674,7 +674,7 @@ static void createTransGPencil_strokes(bContext *C,
}
}
}
- /* if not multiedit out of loop */
+ /* If not multi-edit out of loop. */
if (!is_multiedit) {
break;
}
diff --git a/source/blender/editors/transform/transform_convert_graph.c b/source/blender/editors/transform/transform_convert_graph.c
index d57f7fffe0b..111f81ff87b 100644
--- a/source/blender/editors/transform/transform_convert_graph.c
+++ b/source/blender/editors/transform/transform_convert_graph.c
@@ -939,8 +939,8 @@ static void remake_graph_transdata(TransInfo *t, ListBase *anim_data)
if (fcu->bezt) {
BeztMap *bezm;
- /* adjust transform-data pointers */
- /* note, none of these functions use 'use_handle', it could be removed */
+ /* Adjust transform-data pointers. */
+ /* NOTE: none of these functions use 'use_handle', it could be removed. */
bezm = bezt_to_beztmaps(fcu->bezt, fcu->totvert);
sort_time_beztmaps(bezm, fcu->totvert);
beztmap_to_data(t, fcu, bezm, fcu->totvert);
@@ -1082,7 +1082,7 @@ void special_aftertrans_update__graph(bContext *C, TransInfo *t)
/* Make sure all F-Curves are set correctly, but not if transform was
* canceled, since then curves were already restored to initial state.
- * Note: if the refresh is really needed after cancel then some way
+ * NOTE: if the refresh is really needed after cancel then some way
* has to be added to not update handle types (see bug 22289).
*/
if (!canceled) {
diff --git a/source/blender/editors/transform/transform_convert_lattice.c b/source/blender/editors/transform/transform_convert_lattice.c
index 20ac7dcb998..fbfce41d555 100644
--- a/source/blender/editors/transform/transform_convert_lattice.c
+++ b/source/blender/editors/transform/transform_convert_lattice.c
@@ -122,7 +122,7 @@ void recalcData_lattice(TransInfo *t)
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
Lattice *la = tc->obedit->data;
- DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
+ DEG_id_tag_update(tc->obedit->data, ID_RECALC_GEOMETRY);
if (la->editlatt->latt->flag & LT_OUTSIDE) {
outside_lattice(la->editlatt->latt);
}
diff --git a/source/blender/editors/transform/transform_convert_mask.c b/source/blender/editors/transform/transform_convert_mask.c
index 45dc6df4fde..54df8270702 100644
--- a/source/blender/editors/transform/transform_convert_mask.c
+++ b/source/blender/editors/transform/transform_convert_mask.c
@@ -330,7 +330,7 @@ void createTransMaskingData(bContext *C, TransInfo *t)
}
}
- /* note: in prop mode we need at least 1 selected */
+ /* NOTE: in prop mode we need at least 1 selected. */
if (countsel == 0) {
return;
}
diff --git a/source/blender/editors/transform/transform_convert_mball.c b/source/blender/editors/transform/transform_convert_mball.c
index e47cf4edc4a..f38f3ccf421 100644
--- a/source/blender/editors/transform/transform_convert_mball.c
+++ b/source/blender/editors/transform/transform_convert_mball.c
@@ -142,7 +142,7 @@ void recalcData_mball(TransInfo *t)
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
if (tc->data_len) {
- DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
+ DEG_id_tag_update(tc->obedit->data, ID_RECALC_GEOMETRY);
}
}
}
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index 8d942b1094e..383f9870714 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -27,6 +27,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_alloca.h"
+#include "BLI_bitmap.h"
#include "BLI_linklist_stack.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
@@ -52,6 +53,106 @@
/** \name Container TransCustomData Creation
* \{ */
+static void tc_mesh_customdata_free_fn(struct TransInfo *t,
+ struct TransDataContainer *tc,
+ struct TransCustomData *custom_data);
+
+struct TransCustomDataLayer;
+static void tc_mesh_customdatacorrect_free(struct TransCustomDataLayer *tcld);
+
+struct TransCustomData_PartialUpdate {
+ struct BMPartialUpdate *cache;
+
+ /** The size of proportional editing used for #BMPartialUpdate. */
+ float prop_size;
+ /** The size of proportional editing for the last update. */
+ float prop_size_prev;
+};
+
+/**
+ * \note It's important to order from least to greatest (which updates more data),
+ * since the larger values are used when values change between updates
+ * (which can happen when rotation is enabled with snapping).
+ */
+enum ePartialType {
+ PARTIAL_NONE = -1,
+ /**
+ * Update only faces between tagged and non-tagged faces (affine transformations).
+ * Use when transforming is guaranteed not to change the relative locations of vertices.
+ *
+ * This has the advantage that selecting the entire mesh or only isolated elements,
+ * can skip normal/tessellation updates entirely, so it's worth using when possible.
+ */
+ PARTIAL_TYPE_GROUP = 0,
+ /**
+ * Update for all tagged vertices (any kind of deformation).
+ * Use as a default since it can be used with any kind of deformation.
+ */
+ PARTIAL_TYPE_ALL = 1,
+};
+
+#define PARTIAL_TYPE_MAX 2
+
+/**
+ * Settings used for a single update,
+ * use for comparison with previous updates.
+ */
+struct PartialTypeState {
+ enum ePartialType for_looptri;
+ enum ePartialType for_normals;
+};
+
+struct TransCustomDataMesh {
+ struct TransCustomDataLayer *cd_layer_correct;
+ struct TransCustomData_PartialUpdate partial_update[PARTIAL_TYPE_MAX];
+ struct PartialTypeState partial_update_state_prev;
+};
+
+static struct TransCustomDataMesh *tc_mesh_customdata_ensure(TransDataContainer *tc)
+{
+ struct TransCustomDataMesh *tcmd = tc->custom.type.data;
+ BLI_assert(tc->custom.type.data == NULL ||
+ tc->custom.type.free_cb == tc_mesh_customdata_free_fn);
+ if (tc->custom.type.data == NULL) {
+ tc->custom.type.data = MEM_callocN(sizeof(struct TransCustomDataMesh), __func__);
+ tc->custom.type.free_cb = tc_mesh_customdata_free_fn;
+ tcmd = tc->custom.type.data;
+ tcmd->partial_update_state_prev.for_looptri = PARTIAL_NONE;
+ tcmd->partial_update_state_prev.for_normals = PARTIAL_NONE;
+ }
+ return tcmd;
+}
+
+static void tc_mesh_customdata_free(struct TransCustomDataMesh *tcmd)
+{
+ if (tcmd->cd_layer_correct != NULL) {
+ tc_mesh_customdatacorrect_free(tcmd->cd_layer_correct);
+ }
+
+ for (int i = 0; i < ARRAY_SIZE(tcmd->partial_update); i++) {
+ if (tcmd->partial_update[i].cache != NULL) {
+ BM_mesh_partial_destroy(tcmd->partial_update[i].cache);
+ }
+ }
+
+ MEM_freeN(tcmd);
+}
+
+static void tc_mesh_customdata_free_fn(struct TransInfo *UNUSED(t),
+ struct TransDataContainer *UNUSED(tc),
+ struct TransCustomData *custom_data)
+{
+ struct TransCustomDataMesh *tcmd = custom_data->data;
+ tc_mesh_customdata_free(tcmd);
+ custom_data->data = NULL;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name CustomData TransCustomDataLayer Creation
+ * \{ */
+
struct TransCustomDataMergeGroup {
/** map {BMVert: TransCustomDataLayerVert} */
struct LinkNode **cd_loop_groups;
@@ -83,33 +184,6 @@ struct TransCustomDataLayer {
bool use_merge_group;
};
-static void tc_mesh_customdatacorrect_free_fn(struct TransInfo *UNUSED(t),
- struct TransDataContainer *UNUSED(tc),
- struct TransCustomData *custom_data)
-{
- struct TransCustomDataLayer *tcld = custom_data->data;
- bmesh_edit_end(tcld->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
-
- if (tcld->bm_origfaces) {
- BM_mesh_free(tcld->bm_origfaces);
- }
- if (tcld->origfaces) {
- BLI_ghash_free(tcld->origfaces, NULL, NULL);
- }
- if (tcld->merge_group.origverts) {
- BLI_ghash_free(tcld->merge_group.origverts, NULL, NULL);
- }
- if (tcld->arena) {
- BLI_memarena_free(tcld->arena);
- }
- if (tcld->merge_group.customdatalayer_map) {
- MEM_freeN(tcld->merge_group.customdatalayer_map);
- }
-
- MEM_freeN(tcld);
- custom_data->data = NULL;
-}
-
#define USE_FACE_SUBSTITUTE
#ifdef USE_FACE_SUBSTITUTE
# define FACE_SUBSTITUTE_INDEX INT_MIN
@@ -292,8 +366,8 @@ static void tc_mesh_customdatacorrect_init_container_merge_group(TransDataContai
tcld->arena, tcld->merge_group.data_len * sizeof(*tcld->merge_group.data));
}
-static struct TransCustomDataLayer *tc_mesh_customdatacorrect_create(TransDataContainer *tc,
- const bool use_merge_group)
+static struct TransCustomDataLayer *tc_mesh_customdatacorrect_create_impl(
+ TransDataContainer *tc, const bool use_merge_group)
{
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
BMesh *bm = em->bm;
@@ -341,18 +415,41 @@ static struct TransCustomDataLayer *tc_mesh_customdatacorrect_create(TransDataCo
return tcld;
}
-static void tc_mesh_customdata_create(TransDataContainer *tc, const bool use_merge_group)
+static void tc_mesh_customdatacorrect_create(TransDataContainer *tc, const bool use_merge_group)
{
struct TransCustomDataLayer *customdatacorrect;
- customdatacorrect = tc_mesh_customdatacorrect_create(tc, use_merge_group);
+ customdatacorrect = tc_mesh_customdatacorrect_create_impl(tc, use_merge_group);
if (!customdatacorrect) {
return;
}
- BLI_assert(tc->custom.type.data == NULL);
- tc->custom.type.data = customdatacorrect;
- tc->custom.type.free_cb = tc_mesh_customdatacorrect_free_fn;
+ struct TransCustomDataMesh *tcmd = tc_mesh_customdata_ensure(tc);
+ BLI_assert(tcmd->cd_layer_correct == NULL);
+ tcmd->cd_layer_correct = customdatacorrect;
+}
+
+static void tc_mesh_customdatacorrect_free(struct TransCustomDataLayer *tcld)
+{
+ bmesh_edit_end(tcld->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
+
+ if (tcld->bm_origfaces) {
+ BM_mesh_free(tcld->bm_origfaces);
+ }
+ if (tcld->origfaces) {
+ BLI_ghash_free(tcld->origfaces, NULL, NULL);
+ }
+ if (tcld->merge_group.origverts) {
+ BLI_ghash_free(tcld->merge_group.origverts, NULL, NULL);
+ }
+ if (tcld->arena) {
+ BLI_memarena_free(tcld->arena);
+ }
+ if (tcld->merge_group.customdatalayer_map) {
+ MEM_freeN(tcld->merge_group.customdatalayer_map);
+ }
+
+ MEM_freeN(tcld);
}
void transform_convert_mesh_customdatacorrect_init(TransInfo *t)
@@ -390,10 +487,14 @@ void transform_convert_mesh_customdatacorrect_init(TransInfo *t)
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
if (tc->custom.type.data != NULL) {
- tc_mesh_customdatacorrect_free_fn(t, tc, &tc->custom.type);
+ struct TransCustomDataMesh *tcmd = tc->custom.type.data;
+ if (tcmd && tcmd->cd_layer_correct) {
+ tc_mesh_customdatacorrect_free(tcmd->cd_layer_correct);
+ tcmd->cd_layer_correct = NULL;
+ }
}
- tc_mesh_customdata_create(tc, use_merge_group);
+ tc_mesh_customdatacorrect_create(tc, use_merge_group);
}
}
@@ -555,10 +656,11 @@ static void tc_mesh_customdatacorrect_apply_vert(struct TransCustomDataLayer *tc
static void tc_mesh_customdatacorrect_apply(TransDataContainer *tc, bool is_final)
{
- if (!tc->custom.type.data) {
+ struct TransCustomDataMesh *tcmd = tc->custom.type.data;
+ struct TransCustomDataLayer *tcld = tcmd ? tcmd->cd_layer_correct : NULL;
+ if (tcld == NULL) {
return;
}
- struct TransCustomDataLayer *tcld = tc->custom.type.data;
const bool use_merge_group = tcld->use_merge_group;
struct TransCustomDataMergeGroup *merge_data = tcld->merge_group.data;
@@ -590,7 +692,8 @@ static void tc_mesh_customdatacorrect_apply(TransDataContainer *tc, bool is_fina
static void tc_mesh_customdatacorrect_restore(struct TransInfo *t)
{
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- struct TransCustomDataLayer *tcld = tc->custom.type.data;
+ struct TransCustomDataMesh *tcmd = tc->custom.type.data;
+ struct TransCustomDataLayer *tcld = tcmd ? tcmd->cd_layer_correct : NULL;
if (!tcld) {
continue;
}
@@ -1234,7 +1337,7 @@ void transform_convert_mesh_crazyspace_detect(TransInfo *t,
* correction with \a quats, relative to the coordinates after
* the modifiers that support deform matrices \a defcos. */
-#if 0 /* TODO, fix crazy-space & extrude so it can be enabled for general use - campbell */
+#if 0 /* TODO(campbell): fix crazy-space & extrude so it can be enabled for general use. */
if ((totleft > 0) || (totleft == -1))
#else
if (totleft > 0)
@@ -1614,6 +1717,318 @@ void createTransEditVerts(TransInfo *t)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Recalc Mesh Data (Partial Update)
+ * \{ */
+
+static BMPartialUpdate *tc_mesh_partial_ensure(TransInfo *t,
+ TransDataContainer *tc,
+ enum ePartialType partial_type)
+{
+ struct TransCustomDataMesh *tcmd = tc_mesh_customdata_ensure(tc);
+
+ struct TransCustomData_PartialUpdate *pupdate = &tcmd->partial_update[partial_type];
+
+ if (pupdate->cache) {
+
+ /* Recalculate partial update data when the proportional editing size changes.
+ *
+ * Note that decreasing the proportional editing size requires the existing
+ * partial data is used before recreating this partial data at the smaller size.
+ * Since excluding geometry from being transformed requires an update.
+ *
+ * Extra logic is needed to account for this situation. */
+
+ bool recalc;
+ if (pupdate->prop_size_prev < t->prop_size) {
+ /* Size increase, simply recalculate. */
+ recalc = true;
+ }
+ else if (pupdate->prop_size_prev > t->prop_size) {
+ /* Size decreased, first use this partial data since reducing the size will transform
+ * geometry which needs recalculating. */
+ pupdate->prop_size_prev = t->prop_size;
+ recalc = false;
+ }
+ else if (pupdate->prop_size != t->prop_size) {
+ BLI_assert(pupdate->prop_size > pupdate->prop_size_prev);
+ recalc = true;
+ }
+ else {
+ BLI_assert(t->prop_size == pupdate->prop_size_prev);
+ recalc = false;
+ }
+
+ if (!recalc) {
+ return pupdate->cache;
+ }
+
+ BM_mesh_partial_destroy(pupdate->cache);
+ pupdate->cache = NULL;
+ }
+
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+
+ BM_mesh_elem_index_ensure(em->bm, BM_VERT);
+
+ /* Only use `verts_group` or `verts_mask`. */
+ int *verts_group = NULL;
+ int verts_group_count = 0; /* Number of non-zero elements in `verts_group`. */
+
+ BLI_bitmap *verts_mask = NULL;
+ int verts_mask_count = 0; /* Number of elements enabled in `verts_mask`. */
+
+ if ((partial_type == PARTIAL_TYPE_GROUP) &&
+ ((t->flag & T_PROP_EDIT) || tc->use_mirror_axis_any)) {
+ verts_group = MEM_callocN(sizeof(*verts_group) * em->bm->totvert, __func__);
+ int i;
+ TransData *td;
+ for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
+ if (td->factor == 0.0f) {
+ continue;
+ }
+ const BMVert *v = (BMVert *)td->extra;
+ const int v_index = BM_elem_index_get(v);
+ BLI_assert(verts_group[v_index] == 0);
+ if (td->factor < 1.0f) {
+ /* Don't use grouping logic with the factor is under 1.0. */
+ verts_group[v_index] = -1;
+ }
+ else {
+ BLI_assert(td->factor == 1.0f);
+ verts_group[v_index] = 1;
+ if (tc->use_mirror_axis_any) {
+ /* Use bits 2-4 for central alignment (don't overlap the first bit). */
+ const int flag = td->flag & (TD_MIRROR_EDGE_X | TD_MIRROR_EDGE_Y | TD_MIRROR_EDGE_Z);
+ verts_group[v_index] |= (flag >> TD_MIRROR_EDGE_AXIS_SHIFT) << 1;
+ }
+ }
+ verts_mask_count += 1;
+ }
+
+ TransDataMirror *td_mirror = tc->data_mirror;
+ for (i = 0; i < tc->data_mirror_len; i++, td_mirror++) {
+ BMVert *v_mirr = (BMVert *)POINTER_OFFSET(td_mirror->loc_src, -offsetof(BMVert, co));
+ /* The equality check is to account for the case when topology mirror moves
+ * the vertex from it's original location to match it's symmetrical position,
+ * with proportional editing enabled. */
+ const int v_mirr_index = BM_elem_index_get(v_mirr);
+ if (verts_group[v_mirr_index] == 0 && equals_v3v3(td_mirror->loc, td_mirror->iloc)) {
+ continue;
+ }
+
+ BMVert *v_mirr_other = (BMVert *)td_mirror->extra;
+ /* This assert should never fail since there is no overlap
+ * between mirrored vertices and non-mirrored. */
+ BLI_assert(verts_group[BM_elem_index_get(v_mirr_other)] == 0);
+ const int v_mirr_other_index = BM_elem_index_get(v_mirr_other);
+
+ if (verts_group[v_mirr_index] == -1) {
+ verts_group[v_mirr_other_index] = -1;
+ }
+ else {
+ /* Use bits 5-8 for mirror (don't overlap previous bits). */
+ const int flag = td_mirror->flag & (TD_MIRROR_X | TD_MIRROR_Y | TD_MIRROR_Z);
+ verts_group[v_mirr_other_index] |= (flag >> TD_MIRROR_EDGE_AXIS_SHIFT) << 4;
+ }
+ verts_mask_count += 1;
+ }
+ }
+ else {
+ /* See the body of the comments in the previous block for details. */
+ verts_mask = BLI_BITMAP_NEW(em->bm->totvert, __func__);
+ int i;
+ TransData *td;
+ for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
+ if (td->factor == 0.0f) {
+ continue;
+ }
+ const BMVert *v = (BMVert *)td->extra;
+ const int v_index = BM_elem_index_get(v);
+ BLI_assert(!BLI_BITMAP_TEST(verts_mask, v_index));
+ BLI_BITMAP_ENABLE(verts_mask, v_index);
+ verts_mask_count += 1;
+ }
+
+ TransDataMirror *td_mirror = tc->data_mirror;
+ for (i = 0; i < tc->data_mirror_len; i++, td_mirror++) {
+ BMVert *v_mirr = (BMVert *)POINTER_OFFSET(td_mirror->loc_src, -offsetof(BMVert, co));
+ if (!BLI_BITMAP_TEST(verts_mask, BM_elem_index_get(v_mirr)) &&
+ equals_v3v3(td_mirror->loc, td_mirror->iloc)) {
+ continue;
+ }
+
+ BMVert *v_mirr_other = (BMVert *)td_mirror->extra;
+ BLI_assert(!BLI_BITMAP_TEST(verts_mask, BM_elem_index_get(v_mirr_other)));
+ const int v_mirr_other_index = BM_elem_index_get(v_mirr_other);
+ BLI_BITMAP_ENABLE(verts_mask, v_mirr_other_index);
+ verts_mask_count += 1;
+ }
+ }
+
+ switch (partial_type) {
+ case PARTIAL_TYPE_ALL: {
+ pupdate->cache = BM_mesh_partial_create_from_verts(em->bm,
+ &(BMPartialUpdate_Params){
+ .do_tessellate = true,
+ .do_normals = true,
+ },
+ verts_mask,
+ verts_mask_count);
+ break;
+ }
+ case PARTIAL_TYPE_GROUP: {
+ pupdate->cache =
+ (verts_group ? BM_mesh_partial_create_from_verts_group_multi(em->bm,
+ &(BMPartialUpdate_Params){
+ .do_tessellate = true,
+ .do_normals = true,
+ },
+ verts_group,
+ verts_group_count) :
+ BM_mesh_partial_create_from_verts_group_single(em->bm,
+ &(BMPartialUpdate_Params){
+ .do_tessellate = true,
+ .do_normals = true,
+ },
+ verts_mask,
+ verts_mask_count));
+ break;
+ }
+ case PARTIAL_NONE: {
+ BLI_assert_unreachable();
+ }
+ }
+
+ if (verts_group) {
+ MEM_freeN(verts_group);
+ }
+ else {
+ MEM_freeN(verts_mask);
+ }
+
+ pupdate->prop_size_prev = t->prop_size;
+ pupdate->prop_size = t->prop_size;
+
+ return pupdate->cache;
+}
+
+static void tc_mesh_partial_types_calc(TransInfo *t, struct PartialTypeState *r_partial_state)
+{
+ /* Calculate the kind of partial updates which can be performed. */
+ enum ePartialType partial_for_normals = PARTIAL_NONE;
+ enum ePartialType partial_for_looptri = PARTIAL_NONE;
+
+ /* Note that operations such as #TFM_CREASE are not handled here
+ * (if they were, leaving as #PARTIAL_NONE would be appropriate). */
+ switch (t->mode) {
+ case TFM_TRANSLATION: {
+ partial_for_looptri = PARTIAL_TYPE_GROUP;
+ partial_for_normals = PARTIAL_TYPE_GROUP;
+ /* Translation can rotate when snapping to normal. */
+ if (activeSnap(t) && usingSnappingNormal(t) && validSnappingNormal(t)) {
+ partial_for_normals = PARTIAL_TYPE_ALL;
+ }
+ break;
+ }
+ case TFM_ROTATION: {
+ partial_for_looptri = PARTIAL_TYPE_GROUP;
+ partial_for_normals = PARTIAL_TYPE_ALL;
+ break;
+ }
+ case TFM_RESIZE: {
+ partial_for_looptri = PARTIAL_TYPE_GROUP;
+ partial_for_normals = PARTIAL_TYPE_GROUP;
+ /* Non-uniform scale needs to recalculate all normals
+ * since their relative locations change.
+ * Uniform negative scale can keep normals as-is since the faces are flipped,
+ * normals remain unchanged. */
+ if ((t->con.mode & CON_APPLY) ||
+ (t->values_final[0] != t->values_final[1] || t->values_final[0] != t->values_final[2])) {
+ partial_for_normals = PARTIAL_TYPE_ALL;
+ }
+ break;
+ }
+ default: {
+ partial_for_looptri = PARTIAL_TYPE_ALL;
+ partial_for_normals = PARTIAL_TYPE_ALL;
+ break;
+ }
+ }
+
+ /* With projection, transform isn't affine. */
+ if (activeSnap_with_project(t)) {
+ if (partial_for_looptri == PARTIAL_TYPE_GROUP) {
+ partial_for_looptri = PARTIAL_TYPE_ALL;
+ }
+ if (partial_for_normals == PARTIAL_TYPE_GROUP) {
+ partial_for_normals = PARTIAL_TYPE_ALL;
+ }
+ }
+
+ r_partial_state->for_looptri = partial_for_looptri;
+ r_partial_state->for_normals = partial_for_normals;
+}
+
+static void tc_mesh_partial_update(TransInfo *t,
+ TransDataContainer *tc,
+ const struct PartialTypeState *partial_state)
+{
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+
+ struct TransCustomDataMesh *tcmd = tc_mesh_customdata_ensure(tc);
+
+ const struct PartialTypeState *partial_state_prev = &tcmd->partial_update_state_prev;
+
+ /* Promote the partial update types based on the previous state
+ * so the values that no longer modified are reset before being left as-is.
+ * Needed for translation which can toggle snap-to-normal during transform. */
+ const enum ePartialType partial_for_looptri = MAX2(partial_state->for_looptri,
+ partial_state_prev->for_looptri);
+ const enum ePartialType partial_for_normals = MAX2(partial_state->for_normals,
+ partial_state_prev->for_normals);
+
+ if ((partial_for_looptri == PARTIAL_TYPE_ALL) && (partial_for_normals == PARTIAL_TYPE_ALL) &&
+ (em->bm->totvert == em->bm->totvertsel)) {
+ /* The additional cost of generating the partial connectivity data isn't justified
+ * when all data needs to be updated.
+ *
+ * While proportional editing can cause all geometry to need updating with a partial
+ * selection. It's impractical to calculate this ahead of time. Further, the down side of
+ * using partial updates when their not needed is negligible. */
+ BKE_editmesh_looptri_and_normals_calc(em);
+ }
+ else {
+ if (partial_for_looptri != PARTIAL_NONE) {
+ BMPartialUpdate *bmpinfo = tc_mesh_partial_ensure(t, tc, partial_for_looptri);
+ BKE_editmesh_looptri_calc_with_partial_ex(em,
+ bmpinfo,
+ &(const struct BMeshCalcTessellation_Params){
+ .face_normals = true,
+ });
+ }
+
+ if (partial_for_normals != PARTIAL_NONE) {
+ BMPartialUpdate *bmpinfo = tc_mesh_partial_ensure(t, tc, partial_for_normals);
+ /* While not a large difference, take advantage of existing normals where possible. */
+ const bool face_normals = !((partial_for_looptri == PARTIAL_TYPE_ALL) ||
+ ((partial_for_looptri == PARTIAL_TYPE_GROUP) &&
+ (partial_for_normals == PARTIAL_TYPE_GROUP)));
+ BM_mesh_normals_update_with_partial_ex(em->bm,
+ bmpinfo,
+ &(const struct BMeshNormalsUpdate_Params){
+ .face_normals = face_normals,
+ });
+ }
+ }
+
+ /* Store the previous requested (not the previous used),
+ * since the values used may have been promoted based on the previous types. */
+ tcmd->partial_update_state_prev = *partial_state;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Recalc Mesh Data
* \{ */
@@ -1652,6 +2067,27 @@ static void tc_mesh_transdata_mirror_apply(TransDataContainer *tc)
}
}
+static bool tc_mesh_is_deform_only_update(TransInfo *t, TransDataContainer *tc)
+{
+ if (tc->custom.type.data &&
+ ((struct TransCustomDataMesh *)tc->custom.type.data)->cd_layer_correct) {
+ return false;
+ }
+
+ Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(t->depsgraph, (ID *)tc->obedit->data);
+ Mesh *mesh_eval_cage = me_eval->edit_mesh->mesh_eval_cage;
+ Mesh *mesh_eval_final = me_eval->edit_mesh->mesh_eval_final;
+ if (mesh_eval_cage && !mesh_eval_cage->runtime.is_original) {
+ return false;
+ }
+ if (mesh_eval_final && mesh_eval_final != mesh_eval_cage &&
+ !mesh_eval_final->runtime.is_original) {
+ return false;
+ }
+
+ return me_eval->runtime.deformed_only;
+}
+
void recalcData_mesh(TransInfo *t)
{
bool is_canceling = t->state == TRANS_CANCEL;
@@ -1675,11 +2111,16 @@ void recalcData_mesh(TransInfo *t)
tc_mesh_customdatacorrect_restore(t);
}
+ struct PartialTypeState partial_state;
+ tc_mesh_partial_types_calc(t, &partial_state);
+
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
- BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
- EDBM_mesh_normals_update(em);
- BKE_editmesh_looptri_calc(em);
+ const bool is_deform_only = tc_mesh_is_deform_only_update(t, tc);
+
+ DEG_id_tag_update(tc->obedit->data,
+ is_deform_only ? ID_RECALC_GEOMETRY_DEFORM : ID_RECALC_GEOMETRY);
+
+ tc_mesh_partial_update(t, tc, &partial_state);
}
}
/** \} */
diff --git a/source/blender/editors/transform/transform_convert_mesh_edge.c b/source/blender/editors/transform/transform_convert_mesh_edge.c
index bb9296b4b90..2db3e259153 100644
--- a/source/blender/editors/transform/transform_convert_mesh_edge.c
+++ b/source/blender/editors/transform/transform_convert_mesh_edge.c
@@ -28,6 +28,7 @@
#include "BLI_math.h"
#include "BKE_context.h"
+#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
@@ -123,4 +124,11 @@ void createTransEdge(TransInfo *t)
}
}
+void recalcData_mesh_edge(TransInfo *t)
+{
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ DEG_id_tag_update(tc->obedit->data, ID_RECALC_GEOMETRY);
+ }
+}
+
/** \} */
diff --git a/source/blender/editors/transform/transform_convert_mesh_skin.c b/source/blender/editors/transform/transform_convert_mesh_skin.c
index 68305c45280..69b44998980 100644
--- a/source/blender/editors/transform/transform_convert_mesh_skin.c
+++ b/source/blender/editors/transform/transform_convert_mesh_skin.c
@@ -298,10 +298,9 @@ void recalcData_mesh_skin(TransInfo *t)
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
+ DEG_id_tag_update(tc->obedit->data, ID_RECALC_GEOMETRY);
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
- EDBM_mesh_normals_update(em);
- BKE_editmesh_looptri_calc(em);
+ BKE_editmesh_looptri_and_normals_calc(em);
}
}
/** \} */
diff --git a/source/blender/editors/transform/transform_convert_mesh_uv.c b/source/blender/editors/transform/transform_convert_mesh_uv.c
index a5f90e9ac5f..61397b6ef4b 100644
--- a/source/blender/editors/transform/transform_convert_mesh_uv.c
+++ b/source/blender/editors/transform/transform_convert_mesh_uv.c
@@ -30,6 +30,7 @@
#include "BLI_math.h"
#include "BKE_context.h"
+#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_mesh_mapping.h"
@@ -475,7 +476,7 @@ void recalcData_uv(TransInfo *t)
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
if (tc->data_len) {
- DEG_id_tag_update(tc->obedit->data, 0);
+ DEG_id_tag_update(tc->obedit->data, ID_RECALC_GEOMETRY);
}
}
}
diff --git a/source/blender/editors/transform/transform_convert_node.c b/source/blender/editors/transform/transform_convert_node.c
index 12c4d0816ae..9d2d3713bf0 100644
--- a/source/blender/editors/transform/transform_convert_node.c
+++ b/source/blender/editors/transform/transform_convert_node.c
@@ -27,6 +27,7 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_rect.h"
#include "BKE_context.h"
#include "BKE_node.h"
@@ -35,6 +36,7 @@
#include "ED_node.h"
#include "UI_interface.h"
+#include "UI_view2d.h"
#include "transform.h"
#include "transform_convert.h"
@@ -44,6 +46,12 @@
/** \name Node Transform Creation
* \{ */
+typedef struct NodeTransCustomData {
+ /* Initial rect of the view2d, used for computing offset during edge panning */
+ rctf initial_v2d_cur;
+ View2DEdgePanData edge_pan;
+} NodeTransCustomData;
+
/* transcribe given node into TransData2D for Transforming */
static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node, const float dpi_fac)
{
@@ -107,6 +115,24 @@ void createTransNodeData(TransInfo *t)
const float dpi_fac = UI_DPI_FAC;
SpaceNode *snode = t->area->spacedata.first;
+ if (t->mode == TFM_TRANSLATION) {
+ /* Disable cursor wrapping in the node editor for edge pan */
+ t->flag |= T_NO_CURSOR_WRAP;
+ }
+
+ /* Custom data to enable edge panning during the node transform */
+ NodeTransCustomData *customdata = MEM_callocN(sizeof(*customdata), __func__);
+ UI_view2d_edge_pan_init(t->context,
+ &customdata->edge_pan,
+ NODE_EDGE_PAN_INSIDE_PAD,
+ NODE_EDGE_PAN_OUTSIDE_PAD,
+ NODE_EDGE_PAN_SPEED_RAMP,
+ NODE_EDGE_PAN_MAX_SPEED,
+ NODE_EDGE_PAN_DELAY);
+ customdata->initial_v2d_cur = t->region->v2d.cur;
+ t->custom.type.data = customdata;
+ t->custom.type.use_free = true;
+
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
tc->data_len = 0;
@@ -150,6 +176,19 @@ void flushTransNodes(TransInfo *t)
{
const float dpi_fac = UI_DPI_FAC;
+ NodeTransCustomData *customdata = (NodeTransCustomData *)t->custom.type.data;
+
+ if (t->mode == TFM_TRANSLATION) {
+ /* Edge panning functions expect window coordinates, mval is relative to region */
+ const float x = t->region->winrct.xmin + t->mval[0];
+ const float y = t->region->winrct.ymin + t->mval[1];
+ UI_view2d_edge_pan_apply(t->context, &customdata->edge_pan, x, y);
+ }
+
+ /* Initial and current view2D rects for additional transform due to view panning and zooming */
+ const rctf *rect_src = &customdata->initial_v2d_cur;
+ const rctf *rect_dst = &t->region->v2d.cur;
+
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
applyGridAbsolute(t);
@@ -159,23 +198,28 @@ void flushTransNodes(TransInfo *t)
TransData2D *td2d = &tc->data_2d[i];
bNode *node = td->extra;
- /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */
+ float loc[2];
+ copy_v2_v2(loc, td2d->loc);
+
+ /* additional offset due to change in view2D rect */
+ BLI_rctf_transform_pt_v(rect_dst, rect_src, loc, loc);
+
#ifdef USE_NODE_CENTER
- float locx = (td2d->loc[0] - (BLI_rctf_size_x(&node->totr)) * +0.5f) / dpi_fac;
- float locy = (td2d->loc[1] - (BLI_rctf_size_y(&node->totr)) * -0.5f) / dpi_fac;
-#else
- float locx = td2d->loc[0] / dpi_fac;
- float locy = td2d->loc[1] / dpi_fac;
+ loc[0] -= 0.5f * BLI_rctf_size_x(&node->totr);
+ loc[1] += 0.5f * BLI_rctf_size_y(&node->totr);
#endif
+ /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */
+ loc[0] /= dpi_fac;
+ loc[1] /= dpi_fac;
+
/* account for parents (nested nodes) */
if (node->parent) {
- nodeFromView(node->parent, locx, locy, &node->locx, &node->locy);
- }
- else {
- node->locx = locx;
- node->locy = locy;
+ nodeFromView(node->parent, loc[0], loc[1], &loc[0], &loc[1]);
}
+
+ node->locx = loc[0];
+ node->locy = loc[1];
}
/* handle intersection with noodles */
diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c
index c217478bd04..ee6cb391fdc 100644
--- a/source/blender/editors/transform/transform_convert_object.c
+++ b/source/blender/editors/transform/transform_convert_object.c
@@ -153,7 +153,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
if (t->mode != TFM_DUMMY && ob->rigidbody_object) {
float rot[3][3], scale[3];
- float ctime = BKE_scene_frame_get(scene);
+ float ctime = BKE_scene_ctime_get(scene);
/* only use rigid body transform if simulation is running,
* avoids problems with initial setup of rigid bodies */
@@ -978,7 +978,7 @@ void special_aftertrans_update__object(bContext *C, TransInfo *t)
/* restore rigid body transform */
if (ob->rigidbody_object && canceled) {
- float ctime = BKE_scene_frame_get(t->scene);
+ float ctime = BKE_scene_ctime_get(t->scene);
if (BKE_rigidbody_check_sim_running(t->scene->rigidbody_world, ctime)) {
BKE_rigidbody_aftertrans_update(ob,
td->ext->oloc,
diff --git a/source/blender/editors/transform/transform_convert_particle.c b/source/blender/editors/transform/transform_convert_particle.c
index cb4df28d94b..681d6aea774 100644
--- a/source/blender/editors/transform/transform_convert_particle.c
+++ b/source/blender/editors/transform/transform_convert_particle.c
@@ -91,7 +91,7 @@ void createTransParticleVerts(TransInfo *t)
}
}
- /* note: in prop mode we need at least 1 selected */
+ /* NOTE: in prop mode we need at least 1 selected. */
if (hasselected == 0) {
return;
}
diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c
index c0a66b8846e..a6f5aba5a1d 100644
--- a/source/blender/editors/transform/transform_convert_sequencer.c
+++ b/source/blender/editors/transform/transform_convert_sequencer.c
@@ -33,6 +33,7 @@
#include "ED_markers.h"
+#include "SEQ_iterator.h"
#include "SEQ_relations.h"
#include "SEQ_sequencer.h"
#include "SEQ_time.h"
@@ -62,9 +63,6 @@ typedef struct TransDataSeq {
*/
typedef struct TransSeq {
TransDataSeq *tdseq;
- int min;
- int max;
- bool snap_left;
int selection_channel_range_min;
int selection_channel_range_max;
} TransSeq;
@@ -76,12 +74,9 @@ typedef struct TransSeq {
/* This function applies the rules for transforming a strip so duplicate
* checks don't need to be added in multiple places.
*
- * recursive, count and flag MUST be set.
- *
- * seq->depth must be set before running this function so we know if the strips
- * are root level or not
+ * count and flag MUST be set.
*/
-static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_recursive, int *r_count, int *r_flag)
+static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_count, int *r_flag)
{
/* for extend we need to do some tricks */
if (t->mode == TFM_TIME_EXTEND) {
@@ -90,16 +85,14 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_recursive, int *r_c
Scene *scene = t->scene;
int cfra = CFRA;
- int left = SEQ_transform_get_left_handle_frame(seq, false);
- int right = SEQ_transform_get_right_handle_frame(seq, false);
+ int left = SEQ_transform_get_left_handle_frame(seq);
+ int right = SEQ_transform_get_right_handle_frame(seq);
- if (seq->depth == 0 && ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) {
- *r_recursive = false;
+ if (((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) {
*r_count = 0;
*r_flag = 0;
}
else {
- *r_recursive = false;
*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);
@@ -131,66 +124,34 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_recursive, int *r_c
/* *** Normal Transform *** */
- if (seq->depth == 0) {
-
- /* Count */
+ /* Count */
- /* Non nested strips (resect selection and handles) */
- if ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK)) {
- *r_recursive = false;
- *r_count = 0;
- *r_flag = 0;
+ /* Non nested strips (resect selection and handles) */
+ if ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK)) {
+ *r_count = 0;
+ *r_flag = 0;
+ }
+ else {
+ if ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
+ *r_flag = seq->flag;
+ *r_count = 2; /* we need 2 transdata's */
}
else {
- if ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
- *r_flag = seq->flag;
- *r_count = 2; /* we need 2 transdata's */
- }
- else {
- *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 */
- *r_recursive = true;
- }
- else {
- *r_recursive = false;
- }
+ *r_flag = seq->flag;
+ *r_count = 1; /* selected or with a handle selected */
}
}
- else {
- /* Nested, different rules apply */
-
- *r_flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
- *r_count = 1; /* ignore the selection for nested */
- *r_recursive = (seq->type == SEQ_TYPE_META);
- }
}
}
-static int SeqTransCount(TransInfo *t, Sequence *parent, ListBase *seqbase, int depth)
+static int SeqTransCount(TransInfo *t, ListBase *seqbase)
{
Sequence *seq;
- int tot = 0, recursive, count, flag;
+ int tot = 0, count, flag;
for (seq = seqbase->first; seq; seq = seq->next) {
- seq->depth = depth;
-
- /* 'seq->tmp' is used by seq_tx_get_final_{left, right}
- * to check sequence's range and clamp to it if needed.
- * It's first place where digging into sequences tree, so store link to parent here. */
- seq->tmp = parent;
-
- SeqTransInfo(t, seq, &recursive, &count, &flag); /* ignore the flag */
+ SeqTransInfo(t, seq, &count, &flag); /* ignore the flag */
tot += count;
-
- if (recursive) {
- tot += SeqTransCount(t, seq, &seq->seqbase, depth + 1);
- }
}
return tot;
@@ -206,16 +167,16 @@ static TransData *SeqToTransData(
/* Use seq_tx_get_final_left() and an offset here
* so transform has the left hand location of the strip.
* tdsq->start_offset is used when flushing the tx data back */
- start_left = SEQ_transform_get_left_handle_frame(seq, false);
+ start_left = SEQ_transform_get_left_handle_frame(seq);
td2d->loc[0] = start_left;
tdsq->start_offset = start_left - seq->start; /* use to apply the original location */
break;
case SEQ_LEFTSEL:
- start_left = SEQ_transform_get_left_handle_frame(seq, false);
+ start_left = SEQ_transform_get_left_handle_frame(seq);
td2d->loc[0] = start_left;
break;
case SEQ_RIGHTSEL:
- td2d->loc[0] = SEQ_transform_get_right_handle_frame(seq, false);
+ td2d->loc[0] = SEQ_transform_get_right_handle_frame(seq);
break;
}
@@ -256,27 +217,16 @@ static TransData *SeqToTransData(
return td;
}
-static int SeqToTransData_Recursive(
+static int SeqToTransData_build(
TransInfo *t, ListBase *seqbase, TransData *td, TransData2D *td2d, TransDataSeq *tdsq)
{
Sequence *seq;
- int recursive, count, flag;
+ int count, flag;
int tot = 0;
for (seq = seqbase->first; seq; seq = seq->next) {
- SeqTransInfo(t, seq, &recursive, &count, &flag);
-
- /* add children first so recalculating metastrips does nested strips first */
- if (recursive) {
- int tot_children = SeqToTransData_Recursive(t, &seq->seqbase, td, td2d, tdsq);
-
- td = td + tot_children;
- td2d = td2d + tot_children;
- tdsq = tdsq + tot_children;
-
- tot += tot_children;
- }
+ SeqTransInfo(t, seq, &count, &flag);
/* use 'flag' which is derived from seq->flag but modified for special cases */
if (flag & SELECT) {
@@ -299,224 +249,200 @@ static int SeqToTransData_Recursive(
return tot;
}
-static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts)
+static void free_transform_custom_data(TransCustomData *custom_data)
{
- Sequence *seq;
- int recursive, count, flag;
- int max = INT32_MIN, min = INT32_MAX;
-
- for (seq = seqbase->first; seq; seq = seq->next) {
+ if ((custom_data->data != NULL) && custom_data->use_free) {
+ TransSeq *ts = custom_data->data;
+ MEM_freeN(ts->tdseq);
+ MEM_freeN(custom_data->data);
+ custom_data->data = NULL;
+ }
+}
- /* just to get the flag since there are corner cases where this isn't totally obvious */
- SeqTransInfo(t, seq, &recursive, &count, &flag);
+/* Canceled, need to update the strips display. */
+static void seq_transform_cancel(TransInfo *t, SeqCollection *transformed_strips)
+{
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, transformed_strips) {
+ SEQ_time_update_sequence_bounds(t->scene, seq);
+ }
+}
- /* use 'flag' which is derived from seq->flag but modified for special cases */
- if (flag & SELECT) {
- if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
- if (flag & SEQ_LEFTSEL) {
- min = min_ii(seq->startdisp, min);
- max = max_ii(seq->startdisp, max);
- }
- if (flag & SEQ_RIGHTSEL) {
- min = min_ii(seq->enddisp, min);
- max = max_ii(seq->enddisp, max);
- }
- }
- else {
- min = min_ii(seq->startdisp, min);
- max = max_ii(seq->enddisp, max);
- }
+static bool seq_transform_check_overlap(SeqCollection *transformed_strips)
+{
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, transformed_strips) {
+ if (seq->flag & SEQ_OVERLAP) {
+ return true;
}
}
+ return false;
+}
- if (ts) {
- ts->max = max;
- ts->min = min;
+static SeqCollection *extract_standalone_strips(SeqCollection *transformed_strips)
+{
+ SeqCollection *collection = SEQ_collection_create(__func__);
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, transformed_strips) {
+ if ((seq->type & SEQ_TYPE_EFFECT) == 0 || seq->seq1 == NULL) {
+ SEQ_collection_append_strip(seq, collection);
+ }
}
+ return collection;
}
-static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
+/* Query strips positioned after left edge of transformed strips boundbox. */
+static SeqCollection *query_right_side_strips(ListBase *seqbase, SeqCollection *transformed_strips)
{
- Editing *ed = SEQ_editing_get(t->scene, false);
-
- if (ed != NULL) {
-
- ListBase *seqbasep = ed->seqbasep;
- TransData *td = tc->data;
- int a;
-
- /* prevent updating the same seq twice
- * if the transdata order is changed this will mess up
- * but so will TransDataSeq */
- Sequence *seq_prev = NULL;
+ int minframe = MAXFRAME;
+ {
Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, transformed_strips) {
+ minframe = min_ii(minframe, seq->startdisp);
+ }
+ }
- if (!(t->state == TRANS_CANCEL)) {
+ SeqCollection *collection = SEQ_collection_create(__func__);
+ LISTBASE_FOREACH (Sequence *, seq, seqbase) {
+ if ((seq->flag & SELECT) == 0 && seq->startdisp >= minframe) {
+ SEQ_collection_append_strip(seq, collection);
+ }
+ }
+ return collection;
+}
-#if 0 /* Default 2.4 behavior. */
+static void seq_transform_update_effects(TransInfo *t, SeqCollection *collection)
+{
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, collection) {
+ if ((seq->type & SEQ_TYPE_EFFECT) && (seq->seq1 || seq->seq2 || seq->seq3)) {
+ SEQ_time_update_sequence(t->scene, seq);
+ }
+ }
+}
- /* flush to 2d vector from internally used 3d vector */
- for (a = 0; a < t->total; a++, td++) {
- if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) {
- seq = ((TransDataSeq *)td->extra)->seq;
- SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene);
- }
+/* Check if effect strips with input are transformed. */
+static bool seq_transform_check_strip_effects(SeqCollection *transformed_strips)
+{
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, transformed_strips) {
+ if ((seq->type & SEQ_TYPE_EFFECT) && (seq->seq1 || seq->seq2 || seq->seq3)) {
+ return true;
+ }
+ }
+ return false;
+}
- seq_prev = seq;
- }
+/* Offset all strips positioned after left edge of transformed strips boundbox by amount equal
+ * to overlap of transformed strips. */
+static void seq_transform_handle_expand_to_fit(TransInfo *t, SeqCollection *transformed_strips)
+{
+ Editing *ed = SEQ_editing_get(t->scene, false);
+ ListBase *seqbasep = SEQ_active_seqbase_get(ed);
+ ListBase *markers = &t->scene->markers;
+ const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag &
+ SEQ_MARKER_TRANS) != 0;
-#else /* durian hack */
- {
- int overlap = 0;
+ SeqCollection *right_side_strips = query_right_side_strips(seqbasep, transformed_strips);
- for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
- seq = ((TransDataSeq *)td->extra)->seq;
- if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) {
- overlap = 1;
- break;
- }
- }
+ /* Temporarily move right side strips beyond timeline boundary. */
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, right_side_strips) {
+ seq->machine += MAXSEQ * 2;
+ }
- if (overlap) {
- const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag &
- SEQ_MARKER_TRANS) != 0;
- ListBase *markers = &t->scene->markers;
+ /* Shuffle transformed standalone strips. This is because transformed strips can overlap with
+ * strips on left side. */
+ SeqCollection *standalone_strips = extract_standalone_strips(transformed_strips);
+ SEQ_transform_seqbase_shuffle_time(
+ standalone_strips, seqbasep, t->scene, markers, use_sync_markers);
+ SEQ_collection_free(standalone_strips);
- bool has_effect_root = false, has_effect_any = false;
- for (seq = seqbasep->first; seq; seq = seq->next) {
- seq->tmp = NULL;
- }
+ /* Move temporarily moved strips back to their original place and tag for shuffling. */
+ SEQ_ITERATOR_FOREACH (seq, right_side_strips) {
+ seq->machine -= MAXSEQ * 2;
+ }
+ /* Shuffle again to displace strips on right side. Final effect shuffling is done in
+ * seq_transform_handle_overlap. */
+ SEQ_transform_seqbase_shuffle_time(
+ right_side_strips, seqbasep, t->scene, markers, use_sync_markers);
+ seq_transform_update_effects(t, right_side_strips);
+ SEQ_collection_free(right_side_strips);
+}
- td = tc->data;
- for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
- seq = ((TransDataSeq *)td->extra)->seq;
- if ((seq != seq_prev)) {
- /* check effects strips, we cant change their time */
- if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
- has_effect_any = true;
- if (seq->depth == 0) {
- has_effect_root = true;
- }
- }
- else {
- /* Tag seq with a non zero value, used by
- * SEQ_transform_seqbase_shuffle_time to identify the ones to shuffle */
- if (seq->depth == 0) {
- seq->tmp = (void *)1;
- }
- }
- }
- }
+static void seq_transform_handle_overlap(TransInfo *t, SeqCollection *transformed_strips)
+{
+ Editing *ed = SEQ_editing_get(t->scene, false);
+ ListBase *seqbasep = SEQ_active_seqbase_get(ed);
- if (t->flag & T_ALT_TRANSFORM) {
- int minframe = MAXFRAME;
- td = tc->data;
- for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
- seq = ((TransDataSeq *)td->extra)->seq;
- if ((seq != seq_prev) && (seq->depth == 0)) {
- minframe = min_ii(minframe, seq->startdisp);
- }
- }
-
- for (seq = seqbasep->first; seq; seq = seq->next) {
- if (!(seq->flag & SELECT)) {
- if (seq->startdisp >= minframe) {
- seq->machine += MAXSEQ * 2;
- }
- }
- }
-
- SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers);
-
- for (seq = seqbasep->first; seq; seq = seq->next) {
- if (seq->machine >= MAXSEQ * 2) {
- seq->machine -= MAXSEQ * 2;
- seq->tmp = (void *)1;
- }
- else {
- seq->tmp = NULL;
- }
- }
-
- SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers);
- }
- else {
- SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers);
- }
+ if (t->flag & T_ALT_TRANSFORM) {
+ seq_transform_handle_expand_to_fit(t, transformed_strips);
+ }
+ else {
+ ListBase *markers = &t->scene->markers;
+ const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag &
+ SEQ_MARKER_TRANS) != 0;
+ /* Shuffle non strips with no effects attached. */
+ SeqCollection *standalone_strips = extract_standalone_strips(transformed_strips);
+ SEQ_transform_seqbase_shuffle_time(
+ standalone_strips, seqbasep, t->scene, markers, use_sync_markers);
+ SEQ_collection_free(standalone_strips);
+ }
- if (has_effect_any) {
- /* update effects strips based on strips just moved in time */
- td = tc->data;
- for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
- seq = ((TransDataSeq *)td->extra)->seq;
- if ((seq != seq_prev)) {
- if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
- SEQ_time_update_sequence(t->scene, seq);
- }
- }
- }
- }
+ if (seq_transform_check_strip_effects(transformed_strips)) {
+ /* Update effect strips based on strips just moved in time. */
+ seq_transform_update_effects(t, transformed_strips);
- if (has_effect_root) {
- /* now if any effects _still_ overlap, we need to move them up */
- td = tc->data;
- for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
- seq = ((TransDataSeq *)td->extra)->seq;
- if ((seq != seq_prev) && (seq->depth == 0)) {
- if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
- if (SEQ_transform_test_overlap(seqbasep, seq)) {
- SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene);
- }
- }
- }
- }
- /* done with effects */
- }
+ /* If any effects still overlap, we need to move them up. */
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, transformed_strips) {
+ if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
+ if (SEQ_transform_test_overlap(seqbasep, seq)) {
+ SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene);
}
}
-#endif
+ }
+ }
+}
- for (seq = seqbasep->first; seq; seq = seq->next) {
- /* We might want to build a list of effects that need to be updated during transform */
- if (seq->type & SEQ_TYPE_EFFECT) {
- if (seq->seq1 && seq->seq1->flag & SELECT) {
- SEQ_time_update_sequence(t->scene, seq);
- }
- else if (seq->seq2 && seq->seq2->flag & SELECT) {
- SEQ_time_update_sequence(t->scene, seq);
- }
- else if (seq->seq3 && seq->seq3->flag & SELECT) {
- SEQ_time_update_sequence(t->scene, seq);
- }
- }
- }
+static SeqCollection *seq_transform_collection_from_transdata(TransDataContainer *tc)
+{
+ SeqCollection *collection = SEQ_collection_create(__func__);
+ TransData *td = tc->data;
+ for (int a = 0; a < tc->data_len; a++, td++) {
+ Sequence *seq = ((TransDataSeq *)td->extra)->seq;
+ SEQ_collection_append_strip(seq, collection);
+ }
+ return collection;
+}
- SEQ_sort(t->scene);
- }
- else {
- /* Canceled, need to update the strips display */
- for (a = 0; a < tc->data_len; a++, td++) {
- seq = ((TransDataSeq *)td->extra)->seq;
- if ((seq != seq_prev) && (seq->depth == 0)) {
- if (seq->flag & SEQ_OVERLAP) {
- SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene);
- }
+static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
+{
+ Editing *ed = SEQ_editing_get(t->scene, false);
+ if (ed == NULL) {
+ free_transform_custom_data(custom_data);
+ return;
+ }
- SEQ_time_update_sequence_bounds(t->scene, seq);
- }
- seq_prev = seq;
- }
- }
+ SeqCollection *transformed_strips = seq_transform_collection_from_transdata(tc);
+
+ if (t->state == TRANS_CANCEL) {
+ seq_transform_cancel(t, transformed_strips);
+ SEQ_collection_free(transformed_strips);
+ free_transform_custom_data(custom_data);
+ return;
}
- if ((custom_data->data != NULL) && custom_data->use_free) {
- TransSeq *ts = custom_data->data;
- MEM_freeN(ts->tdseq);
- MEM_freeN(custom_data->data);
- custom_data->data = NULL;
+ if (seq_transform_check_overlap(transformed_strips)) {
+ seq_transform_handle_overlap(t, transformed_strips);
}
+ seq_transform_update_effects(t, transformed_strips);
+ SEQ_collection_free(transformed_strips);
+
+ SEQ_sort(ed->seqbasep);
DEG_id_tag_update(&t->scene->id, ID_RECALC_SEQUENCER_STRIPS);
+ free_transform_custom_data(custom_data);
}
void createTransSeqData(TransInfo *t)
@@ -562,7 +488,7 @@ void createTransSeqData(TransInfo *t)
}
#endif
- count = SeqTransCount(t, NULL, ed->seqbasep, 0);
+ count = SeqTransCount(t, ed->seqbasep);
/* allocate memory for data */
tc->data_len = count;
@@ -579,16 +505,7 @@ void createTransSeqData(TransInfo *t)
ts->tdseq = tdsq = MEM_callocN(tc->data_len * sizeof(TransDataSeq), "TransSeq TransDataSeq");
/* loop 2: build transdata array */
- SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq);
- SeqTransDataBounds(t, ed->seqbasep, ts);
-
- if (t->flag & T_MODAL) {
- /* set the snap mode based on how close the mouse is at the end/start points */
- int xmouse = (int)UI_view2d_region_to_view_x((View2D *)t->view, t->mouse.imval[0]);
- if (abs(xmouse - ts->max) > abs(xmouse - ts->min)) {
- ts->snap_left = true;
- }
- }
+ SeqToTransData_build(t, ed->seqbasep, td, td2d, tdsq);
ts->selection_channel_range_min = MAXSEQ + 1;
LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
@@ -612,15 +529,10 @@ void createTransSeqData(TransInfo *t)
BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int sel_flag)
{
- if (seq->depth == 0) {
- /* Calculate this strip and all nested strips.
- * Children are ALWAYS transformed first so we don't need to do this in another loop.
- */
- SEQ_time_update_sequence(sce, seq);
- }
- else {
- SEQ_time_update_sequence_bounds(sce, seq);
- }
+ /* Calculate this strip and all nested strips.
+ * Children are ALWAYS transformed first so we don't need to do this in another loop.
+ */
+ SEQ_time_update_sequence(sce, seq);
if (sel_flag == SELECT) {
SEQ_offset_animdata(sce, seq, seq->start - old_start);
@@ -640,102 +552,49 @@ static void flushTransSeq(TransInfo *t)
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
- /* prevent updating the same seq twice
- * if the transdata order is changed this will mess up
- * but so will TransDataSeq */
- Sequence *seq_prev = NULL;
- int old_start_prev = 0, sel_flag_prev = 0;
-
- /* flush to 2d vector from internally used 3d vector */
+ /* Flush to 2D vector from internally used 3D vector. */
for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
- int old_start;
tdsq = (TransDataSeq *)td->extra;
seq = tdsq->seq;
- old_start = seq->start;
new_frame = round_fl_to_int(td2d->loc[0]);
switch (tdsq->sel_flag) {
case SELECT:
- if ((seq->depth != 0 || SEQ_transform_sequence_can_be_translated(seq))) {
- /* for meta's, their children move */
- seq->start = new_frame - tdsq->start_offset;
- }
- if (seq->depth == 0) {
- seq->machine = round_fl_to_int(td2d->loc[1]);
- CLAMP(seq->machine, 1, MAXSEQ);
+ if (SEQ_transform_sequence_can_be_translated(seq)) {
+ const int offset = new_frame - tdsq->start_offset - seq->start;
+ SEQ_transform_translate_sequence(t->scene, seq, offset);
}
+ seq->machine = round_fl_to_int(td2d->loc[1]);
+ CLAMP(seq->machine, 1, MAXSEQ);
break;
- case SEQ_LEFTSEL: /* no vertical transform */
+
+ case SEQ_LEFTSEL: /* No vertical transform. */
SEQ_transform_set_left_handle_frame(seq, new_frame);
SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
-
- /* todo - move this into aftertrans update? - old seq tx needed it anyway */
SEQ_transform_fix_single_image_seq_offsets(seq);
+ SEQ_time_update_sequence(t->scene, seq);
break;
- case SEQ_RIGHTSEL: /* no vertical transform */
+ case SEQ_RIGHTSEL: /* No vertical transform. */
SEQ_transform_set_right_handle_frame(seq, new_frame);
SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
-
- /* todo - move this into aftertrans update? - old seq tx needed it anyway */
SEQ_transform_fix_single_image_seq_offsets(seq);
+ SEQ_time_update_sequence(t->scene, seq);
break;
}
-
- /* Update *previous* seq! Else, we would update a seq after its first transform,
- * and if it has more than one (like e.g. SEQ_LEFTSEL and SEQ_RIGHTSEL),
- * the others are not updated! See T38469.
- */
- if (seq != seq_prev) {
- if (seq_prev) {
- trans_update_seq(t->scene, seq_prev, old_start_prev, sel_flag_prev);
- }
-
- seq_prev = seq;
- old_start_prev = old_start;
- sel_flag_prev = tdsq->sel_flag;
- }
- else {
- /* We want to accumulate *all* sel_flags for this seq! */
- sel_flag_prev |= tdsq->sel_flag;
- }
- }
-
- /* Don't forget to update the last seq! */
- if (seq_prev) {
- trans_update_seq(t->scene, seq_prev, old_start_prev, sel_flag_prev);
}
- /* originally TFM_TIME_EXTEND, transform changes */
+ /* Update all effects. */
if (ELEM(t->mode, TFM_SEQ_SLIDE, TFM_TIME_TRANSLATE)) {
- /* Special annoying case here, need to calc meta-strips with TFM_TIME_EXTEND only */
-
- /* calc all meta's then effects T27953. */
- for (seq = seqbasep->first; seq; seq = seq->next) {
- if (seq->type == SEQ_TYPE_META && seq->flag & SELECT) {
- SEQ_time_update_sequence(t->scene, seq);
- }
- }
for (seq = seqbasep->first; seq; seq = seq->next) {
if (seq->seq1 || seq->seq2 || seq->seq3) {
SEQ_time_update_sequence(t->scene, seq);
}
}
-
- /* update effects inside meta's */
- for (a = 0, seq_prev = NULL, td = tc->data, td2d = tc->data_2d; a < tc->data_len;
- a++, td++, td2d++, seq_prev = seq) {
- tdsq = (TransDataSeq *)td->extra;
- seq = tdsq->seq;
- if ((seq != seq_prev) && (seq->depth != 0)) {
- if (seq->seq1 || seq->seq2 || seq->seq3) {
- SEQ_time_update_sequence(t->scene, seq);
- }
- }
- }
}
/* need to do the overlap check in a new loop otherwise adjacent strips
* will not be updated and we'll get false positives */
+ Sequence *seq_prev = NULL;
seq_prev = NULL;
for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
@@ -743,12 +602,10 @@ static void flushTransSeq(TransInfo *t)
seq = tdsq->seq;
if (seq != seq_prev) {
- if (seq->depth == 0) {
- /* test overlap, displays red outline */
- seq->flag &= ~SEQ_OVERLAP;
- if (SEQ_transform_test_overlap(seqbasep, seq)) {
- seq->flag |= SEQ_OVERLAP;
- }
+ /* test overlap, displays red outline */
+ seq->flag &= ~SEQ_OVERLAP;
+ if (SEQ_transform_test_overlap(seqbasep, seq)) {
+ seq->flag |= SEQ_OVERLAP;
}
}
seq_prev = seq;
@@ -792,7 +649,7 @@ void special_aftertrans_update__sequencer(bContext *UNUSED(C), TransInfo *t)
return;
}
/* freeSeqData in transform_conversions.c does this
- * keep here so the else at the end wont run... */
+ * keep here so the else at the end won't run... */
SpaceSeq *sseq = (SpaceSeq *)t->area->spacedata.first;
@@ -815,25 +672,19 @@ void special_aftertrans_update__sequencer(bContext *UNUSED(C), TransInfo *t)
}
}
-void transform_convert_sequencer_channel_clamp(TransInfo *t)
+void transform_convert_sequencer_channel_clamp(TransInfo *t, float r_val[2])
{
const TransSeq *ts = (TransSeq *)TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
- const int channel_offset = round_fl_to_int(t->values[1]);
+ const int channel_offset = round_fl_to_int(r_val[1]);
const int min_channel_after_transform = ts->selection_channel_range_min + channel_offset;
const int max_channel_after_transform = ts->selection_channel_range_max + channel_offset;
if (max_channel_after_transform > MAXSEQ) {
- t->values[1] -= max_channel_after_transform - MAXSEQ;
+ r_val[1] -= max_channel_after_transform - MAXSEQ;
}
if (min_channel_after_transform < 1) {
- t->values[1] -= min_channel_after_transform - 1;
+ r_val[1] -= min_channel_after_transform - 1;
}
}
-int transform_convert_sequencer_get_snap_bound(TransInfo *t)
-{
- TransSeq *ts = TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
- return ts->snap_left ? ts->min : ts->max;
-}
-
/** \} */
diff --git a/source/blender/editors/transform/transform_data.h b/source/blender/editors/transform/transform_data.h
index 5b01433c96b..15e40ec466b 100644
--- a/source/blender/editors/transform/transform_data.h
+++ b/source/blender/editors/transform/transform_data.h
@@ -149,6 +149,8 @@ typedef struct TransData {
short protectflag;
} TransData;
+#define TRANSDATA_THREAD_LIMIT 1024
+
/** #TransData.flag */
enum {
TD_SELECTED = 1 << 0,
@@ -168,15 +170,17 @@ enum {
TD_BEZTRIPLE = 1 << 8,
/** when this is set, don't apply translation changes to this element */
TD_NO_LOC = 1 << 9,
- /** For Graph Editor autosnap, indicates that point should not undergo autosnapping */
+ /** For Graph Editor auto-snap, indicates that point should not undergo auto-snapping. */
TD_NOTIMESNAP = 1 << 10,
/** For Graph Editor - curves that can only have int-values
* need their keyframes tagged with this. */
TD_INTVALUES = 1 << 11,
+#define TD_MIRROR_AXIS_SHIFT 12
/** For editmode mirror. */
TD_MIRROR_X = 1 << 12,
TD_MIRROR_Y = 1 << 13,
TD_MIRROR_Z = 1 << 14,
+#define TD_MIRROR_EDGE_AXIS_SHIFT 12
/** For editmode mirror, clamp axis to 0 */
TD_MIRROR_EDGE_X = 1 << 12,
TD_MIRROR_EDGE_Y = 1 << 13,
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 71c91221fbb..aaac8e21cb9 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -353,13 +353,11 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->around = V3D_AROUND_CENTER_BOUNDS;
}
- BLI_assert(is_zero_v4(t->values_modal_offset));
-
bool t_values_set_is_array = false;
if (op && (prop = RNA_struct_find_property(op->ptr, "value")) &&
RNA_property_is_set(op->ptr, prop)) {
- float values[4] = {0}; /* in case value isn't length 4, avoid uninitialized memory */
+ float values[4] = {0}; /* in case value isn't length 4, avoid uninitialized memory. */
if (RNA_property_array_check(prop)) {
RNA_float_get_array(op->ptr, "value", values);
t_values_set_is_array = true;
@@ -368,7 +366,6 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
values[0] = RNA_float_get(op->ptr, "value");
}
- copy_v4_v4(t->values, values);
if (t->flag & T_MODAL) {
/* Run before init functions so 'values_modal_offset' can be applied on mouse input. */
copy_v4_v4(t->values_modal_offset, values);
@@ -859,8 +856,8 @@ void calculateCenter2D(TransInfo *t)
void calculateCenterLocal(TransInfo *t, const float center_global[3])
{
- /* setting constraint center */
- /* note, init functions may over-ride t->center */
+ /* Setting constraint center. */
+ /* NOTE: init functions may over-ride `t->center`. */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
if (tc->use_local_mat) {
mul_v3_m4v3(tc->center_local, tc->imat, center_global);
@@ -913,7 +910,7 @@ void calculateCenterCursor2D(TransInfo *t, float r_center[2])
BKE_mask_coord_from_movieclip(space_clip->clip, &space_clip->user, co, cursor);
}
else {
- BLI_assert(!"Shall not happen");
+ BLI_assert_msg(0, "Shall not happen");
}
r_center[0] = co[0] * t->aspect[0];
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index 7a780df0def..080a19cce1f 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -521,7 +521,7 @@ static void protectflag_to_drawflags_pchan(RegionView3D *rv3d,
}
}
-/* for editmode*/
+/* For editmode. */
static void protectflag_to_drawflags_ebone(RegionView3D *rv3d, const EditBone *ebo)
{
if (ebo->flag & BONE_EDITMODE_LOCKED) {
diff --git a/source/blender/editors/transform/transform_gizmo_extrude_3d.c b/source/blender/editors/transform/transform_gizmo_extrude_3d.c
index ed6c3eb0255..ca4ed01c0f6 100644
--- a/source/blender/editors/transform/transform_gizmo_extrude_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_extrude_3d.c
@@ -367,7 +367,7 @@ static void gizmo_mesh_extrude_refresh(const bContext *C, wmGizmoGroup *gzgroup)
}
}
- /* TODO: skip calculating axis which wont be used (above). */
+ /* TODO: skip calculating axis which won't be used (above). */
switch (axis_type) {
case EXTRUDE_AXIS_NORMAL:
for (int i = 0; i < 3; i++) {
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 414199badd7..0b46d0b9a13 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -450,17 +450,6 @@ void applyMouseInput(TransInfo *t, MouseInput *mi, const int mval[2], float outp
mi->apply(t, mi, mval_db, output);
}
- if (!is_zero_v3(t->values_modal_offset)) {
- float values_ofs[3];
- if (t->con.mode & CON_APPLY) {
- mul_v3_m3v3(values_ofs, t->spacemtx, t->values_modal_offset);
- }
- else {
- copy_v3_v3(values_ofs, t->values_modal_offset);
- }
- add_v3_v3(t->values, values_ofs);
- }
-
if (mi->post) {
mi->post(t, output);
}
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index d61e7bb867c..65a673940f8 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -68,7 +68,7 @@ int transform_mode_really_used(bContext *C, int mode)
return mode;
}
-bool transdata_check_local_center(TransInfo *t, short around)
+bool transdata_check_local_center(const TransInfo *t, short around)
{
return ((around == V3D_AROUND_LOCAL_ORIGINS) &&
((t->options & (CTX_OBJECT | CTX_POSE_BONE)) ||
@@ -248,7 +248,7 @@ void protectedSizeBits(short protectflag, float size[3])
/** \name Transform Limits
* \{ */
-void constraintTransLim(TransInfo *t, TransData *td)
+void constraintTransLim(const TransInfo *t, TransData *td)
{
if (td->con) {
const bConstraintTypeInfo *ctiLoc = BKE_constraint_typeinfo_from_type(
@@ -359,7 +359,7 @@ static void constraintob_from_transdata(bConstraintOb *cob, TransData *td)
}
}
-static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
+static void constraintRotLim(const TransInfo *UNUSED(t), TransData *td)
{
if (td->con) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_ROTLIMIT);
@@ -432,7 +432,7 @@ static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
}
}
-void constraintSizeLim(TransInfo *t, TransData *td)
+void constraintSizeLim(const TransInfo *t, TransData *td)
{
if (td->con && td->ext) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_SIZELIMIT);
@@ -524,7 +524,7 @@ void constraintSizeLim(TransInfo *t, TransData *td)
/** \name Transform (Rotation Utils)
* \{ */
/* Used by Transform Rotation and Transform Normal Rotation */
-void headerRotation(TransInfo *t, char str[UI_MAX_DRAW_STR], float final)
+void headerRotation(TransInfo *t, char *str, const int str_size, float final)
{
size_t ofs = 0;
@@ -533,25 +533,21 @@ void headerRotation(TransInfo *t, char str[UI_MAX_DRAW_STR], float final)
outputNumInput(&(t->num), c, &t->scene->unit);
- ofs += BLI_snprintf(str + ofs,
- UI_MAX_DRAW_STR - ofs,
- TIP_("Rotation: %s %s %s"),
- &c[0],
- t->con.text,
- t->proptext);
+ ofs += BLI_snprintf_rlen(
+ str + ofs, str_size - ofs, TIP_("Rotation: %s %s %s"), &c[0], t->con.text, t->proptext);
}
else {
- ofs += BLI_snprintf(str + ofs,
- UI_MAX_DRAW_STR - ofs,
- TIP_("Rotation: %.2f%s %s"),
- RAD2DEGF(final),
- t->con.text,
- t->proptext);
+ ofs += BLI_snprintf_rlen(str + ofs,
+ str_size - ofs,
+ TIP_("Rotation: %.2f%s %s"),
+ RAD2DEGF(final),
+ t->con.text,
+ t->proptext);
}
if (t->flag & T_PROP_EDIT_ALL) {
- ofs += BLI_snprintf(
- str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
+ ofs += BLI_snprintf_rlen(
+ str + ofs, str_size - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
}
}
@@ -561,8 +557,8 @@ void headerRotation(TransInfo *t, char str[UI_MAX_DRAW_STR], float final)
*
* Protected axis and other transform settings are taken into account.
*/
-void ElementRotation_ex(TransInfo *t,
- TransDataContainer *tc,
+void ElementRotation_ex(const TransInfo *t,
+ const TransDataContainer *tc,
TransData *td,
const float mat[3][3],
const float *center)
@@ -738,9 +734,25 @@ void ElementRotation_ex(TransInfo *t,
/* can be called for texture space translate for example, then opt out */
if (td->ext->quat) {
mul_m3_series(fmat, td->smtx, mat, td->mtx);
+
+ if (!is_zero_v3(td->ext->dquat)) {
+ /* Correct for delta quat */
+ float tmp_mat[3][3];
+ quat_to_mat3(tmp_mat, td->ext->dquat);
+ mul_m3_m3m3(fmat, fmat, tmp_mat);
+ }
+
mat3_to_quat(quat, fmat); /* Actual transform */
+ if (!is_zero_v4(td->ext->dquat)) {
+ /* Correct back for delta quat. */
+ float idquat[4];
+ invert_qt_qt_normalized(idquat, td->ext->dquat);
+ mul_qt_qtqt(quat, idquat, quat);
+ }
+
mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
+
/* this function works on end result */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
}
@@ -765,21 +777,28 @@ void ElementRotation_ex(TransInfo *t,
td->ext->irotAngle);
}
else {
+ /* Calculate the total rotation in eulers. */
float obmat[3][3];
mul_m3_m3m3(totmat, mat, td->mtx);
mul_m3_m3m3(smat, td->smtx, totmat);
- /* Calculate the total rotation in eulers. */
- add_v3_v3v3(eul, td->ext->irot, td->ext->drot); /* correct for delta rot */
+ if (!is_zero_v3(td->ext->drot)) {
+ /* Correct for delta rot */
+ add_eul_euleul(eul, td->ext->irot, td->ext->drot, td->ext->rotOrder);
+ }
+ else {
+ copy_v3_v3(eul, td->ext->irot);
+ }
+
eulO_to_mat3(obmat, eul, td->ext->rotOrder);
- /* mat = transform, obmat = object rotation */
mul_m3_m3m3(fmat, smat, obmat);
-
mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
- /* correct back for delta rot */
- sub_v3_v3v3(eul, eul, td->ext->drot);
+ if (!is_zero_v3(td->ext->drot)) {
+ /* Correct back for delta rot. */
+ sub_eul_euleul(eul, eul, td->ext->drot, td->ext->rotOrder);
+ }
/* and apply */
protectedRotateBits(td->protectflag, eul, td->ext->irot);
@@ -791,8 +810,11 @@ void ElementRotation_ex(TransInfo *t,
}
}
-void ElementRotation(
- TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3], const short around)
+void ElementRotation(const TransInfo *t,
+ const TransDataContainer *tc,
+ TransData *td,
+ const float mat[3][3],
+ const short around)
{
const float *center;
@@ -811,7 +833,7 @@ void ElementRotation(
/* -------------------------------------------------------------------- */
/** \name Transform (Resize Utils)
* \{ */
-void headerResize(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
+void headerResize(TransInfo *t, const float vec[3], char *str, const int str_size)
{
char tvec[NUM_STR_REP_LEN * 3];
size_t ofs = 0;
@@ -827,59 +849,55 @@ void headerResize(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
if (t->con.mode & CON_APPLY) {
switch (t->num.idx_max) {
case 0:
- ofs += BLI_snprintf(str + ofs,
- UI_MAX_DRAW_STR - ofs,
- TIP_("Scale: %s%s %s"),
- &tvec[0],
- t->con.text,
- t->proptext);
+ ofs += BLI_snprintf_rlen(
+ str + ofs, str_size - ofs, TIP_("Scale: %s%s %s"), &tvec[0], t->con.text, t->proptext);
break;
case 1:
- ofs += BLI_snprintf(str + ofs,
- UI_MAX_DRAW_STR - ofs,
- TIP_("Scale: %s : %s%s %s"),
- &tvec[0],
- &tvec[NUM_STR_REP_LEN],
- t->con.text,
- t->proptext);
+ ofs += BLI_snprintf_rlen(str + ofs,
+ str_size - ofs,
+ TIP_("Scale: %s : %s%s %s"),
+ &tvec[0],
+ &tvec[NUM_STR_REP_LEN],
+ t->con.text,
+ t->proptext);
break;
case 2:
- ofs += BLI_snprintf(str + ofs,
- UI_MAX_DRAW_STR - ofs,
- TIP_("Scale: %s : %s : %s%s %s"),
- &tvec[0],
- &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2],
- t->con.text,
- t->proptext);
+ ofs += BLI_snprintf_rlen(str + ofs,
+ str_size - ofs,
+ TIP_("Scale: %s : %s : %s%s %s"),
+ &tvec[0],
+ &tvec[NUM_STR_REP_LEN],
+ &tvec[NUM_STR_REP_LEN * 2],
+ t->con.text,
+ t->proptext);
break;
}
}
else {
if (t->flag & T_2D_EDIT) {
- ofs += BLI_snprintf(str + ofs,
- UI_MAX_DRAW_STR - ofs,
- TIP_("Scale X: %s Y: %s%s %s"),
- &tvec[0],
- &tvec[NUM_STR_REP_LEN],
- t->con.text,
- t->proptext);
+ ofs += BLI_snprintf_rlen(str + ofs,
+ str_size - ofs,
+ TIP_("Scale X: %s Y: %s%s %s"),
+ &tvec[0],
+ &tvec[NUM_STR_REP_LEN],
+ t->con.text,
+ t->proptext);
}
else {
- ofs += BLI_snprintf(str + ofs,
- UI_MAX_DRAW_STR - ofs,
- TIP_("Scale X: %s Y: %s Z: %s%s %s"),
- &tvec[0],
- &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2],
- t->con.text,
- t->proptext);
+ ofs += BLI_snprintf_rlen(str + ofs,
+ str_size - ofs,
+ TIP_("Scale X: %s Y: %s Z: %s%s %s"),
+ &tvec[0],
+ &tvec[NUM_STR_REP_LEN],
+ &tvec[NUM_STR_REP_LEN * 2],
+ t->con.text,
+ t->proptext);
}
}
if (t->flag & T_PROP_EDIT_ALL) {
- ofs += BLI_snprintf(
- str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
+ ofs += BLI_snprintf_rlen(
+ str + ofs, str_size - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
}
}
@@ -906,7 +924,10 @@ static void TransMat3ToSize(const float mat[3][3], const float smat[3][3], float
}
}
-void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3])
+void ElementResize(const TransInfo *t,
+ const TransDataContainer *tc,
+ TransData *td,
+ const float mat[3][3])
{
float tmat[3][3], smat[3][3], center[3];
float vec[3];
@@ -999,17 +1020,31 @@ void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float ma
sub_v3_v3(vec, td->center);
}
- /* grease pencil falloff */
+ /* Grease pencil falloff.
+ *
+ * FIXME: This is bad on multiple levels!
+ *
+ * - #applyNumInput is not intended to be run for every element,
+ * this writes back into the number input in a way that doesn't make sense to run many times.
+ *
+ * - Writing into #TransInfo should be avoided since it means order of operations
+ * may impact the result and isn't thread-safe.
+ *
+ * Operating on copies as a temporary solution.
+ */
if (t->options & CTX_GPENCIL_STROKES) {
bGPDstroke *gps = (bGPDstroke *)td->extra;
mul_v3_fl(vec, td->factor * gps->runtime.multi_frame_falloff);
- /* scale stroke thickness */
+ /* Scale stroke thickness. */
if (td->val) {
- transform_snap_increment(t, t->values_final);
- applyNumInput(&t->num, t->values_final);
+ NumInput num_evil = t->num;
+ float values_final_evil[4];
+ copy_v4_v4(values_final_evil, t->values_final);
+ transform_snap_increment(t, values_final_evil);
+ applyNumInput(&num_evil, values_final_evil);
- float ratio = t->values_final[0];
+ float ratio = values_final_evil[0];
*td->val = td->ival * ratio * gps->runtime.multi_frame_falloff;
CLAMP_MIN(*td->val, 0.001f);
}
@@ -1029,6 +1064,7 @@ void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float ma
constraintTransLim(t, td);
}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/transform/transform_mode.h b/source/blender/editors/transform/transform_mode.h
index 106dc68c9ee..027fb6b6982 100644
--- a/source/blender/editors/transform/transform_mode.h
+++ b/source/blender/editors/transform/transform_mode.h
@@ -41,22 +41,28 @@ typedef struct TransDataGenericSlideVert {
/* transform_mode.c */
int transform_mode_really_used(struct bContext *C, int mode);
-bool transdata_check_local_center(TransInfo *t, short around);
+bool transdata_check_local_center(const TransInfo *t, short around);
bool transform_mode_is_changeable(const int mode);
void protectedTransBits(short protectflag, float vec[3]);
void protectedSizeBits(short protectflag, float size[3]);
-void constraintTransLim(TransInfo *t, TransData *td);
-void constraintSizeLim(TransInfo *t, TransData *td);
-void headerRotation(TransInfo *t, char *str, float final);
-void ElementRotation_ex(TransInfo *t,
- TransDataContainer *tc,
+void constraintTransLim(const TransInfo *t, TransData *td);
+void constraintSizeLim(const TransInfo *t, TransData *td);
+void headerRotation(TransInfo *t, char *str, int str_size, float final);
+void ElementRotation_ex(const TransInfo *t,
+ const TransDataContainer *tc,
TransData *td,
const float mat[3][3],
const float *center);
-void ElementRotation(
- TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3], const short around);
-void headerResize(TransInfo *t, const float vec[3], char *str);
-void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3]);
+void ElementRotation(const TransInfo *t,
+ const TransDataContainer *tc,
+ TransData *td,
+ const float mat[3][3],
+ const short around);
+void headerResize(TransInfo *t, const float vec[3], char *str, int str_size);
+void ElementResize(const TransInfo *t,
+ const TransDataContainer *tc,
+ TransData *td,
+ const float mat[3][3]);
short getAnimEdit_SnapMode(TransInfo *t);
void doAnimEdit_SnapFrame(
TransInfo *t, TransData *td, TransData2D *td2d, struct AnimData *adt, short autosnap);
diff --git a/source/blender/editors/transform/transform_mode_bend.c b/source/blender/editors/transform/transform_mode_bend.c
index b3b1860f9ec..850d26571cd 100644
--- a/source/blender/editors/transform/transform_mode_bend.c
+++ b/source/blender/editors/transform/transform_mode_bend.c
@@ -29,6 +29,7 @@
#include "BLI_math.h"
#include "BLI_string.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_unit.h"
@@ -47,9 +48,12 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/** \name Transform (Bend)
+/** \name Transform (Bend) Custom Data
* \{ */
+/**
+ * Custom data, stored in #TransInfo.custom.mode.data
+ */
struct BendCustomData {
/* All values are in global space. */
float warp_sta[3];
@@ -62,6 +66,122 @@ struct BendCustomData {
float warp_init_dist;
};
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform (Bend) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be copied for faster memory access.
+ */
+struct TransDataArgs_Bend {
+ const TransInfo *t;
+ const TransDataContainer *tc;
+
+ float angle;
+ struct BendCustomData bend_data;
+
+ const float warp_sta_local[3];
+ const float warp_end_local[3];
+ const float warp_end_radius_local[3];
+ const float pivot_local[3];
+ bool is_clamp;
+};
+
+static void transdata_elem_bend(const TransInfo *t,
+ const TransDataContainer *tc,
+ TransData *td,
+ float angle,
+ const struct BendCustomData *bend_data,
+ const float warp_sta_local[3],
+ const float UNUSED(warp_end_local[3]),
+ const float warp_end_radius_local[3],
+ const float pivot_local[3],
+
+ bool is_clamp)
+{
+ if (UNLIKELY(angle == 0.0f)) {
+ copy_v3_v3(td->loc, td->iloc);
+ return;
+ }
+
+ float vec[3];
+ float mat[3][3];
+ float delta[3];
+ float fac, fac_scaled;
+
+ copy_v3_v3(vec, td->iloc);
+ mul_m3_v3(td->mtx, vec);
+
+ fac = line_point_factor_v3(vec, warp_sta_local, warp_end_radius_local);
+ if (is_clamp) {
+ CLAMP(fac, 0.0f, 1.0f);
+ }
+
+ if (t->options & CTX_GPENCIL_STROKES) {
+ /* grease pencil multiframe falloff */
+ bGPDstroke *gps = (bGPDstroke *)td->extra;
+ if (gps != NULL) {
+ fac_scaled = fac * td->factor * gps->runtime.multi_frame_falloff;
+ }
+ else {
+ fac_scaled = fac * td->factor;
+ }
+ }
+ else {
+ fac_scaled = fac * td->factor;
+ }
+
+ axis_angle_normalized_to_mat3(mat, bend_data->warp_nor, angle * fac_scaled);
+ interp_v3_v3v3(delta, warp_sta_local, warp_end_radius_local, fac_scaled);
+ sub_v3_v3(delta, warp_sta_local);
+
+ /* delta is subtracted, rotation adds back this offset */
+ sub_v3_v3(vec, delta);
+
+ sub_v3_v3(vec, pivot_local);
+ mul_m3_v3(mat, vec);
+ add_v3_v3(vec, pivot_local);
+
+ mul_m3_v3(td->smtx, vec);
+
+ /* rotation */
+ if ((t->flag & T_POINTS) == 0) {
+ ElementRotation(t, tc, td, mat, V3D_AROUND_LOCAL_ORIGINS);
+ }
+
+ /* location */
+ copy_v3_v3(td->loc, vec);
+}
+
+static void transdata_elem_bend_fn(void *__restrict iter_data_v,
+ const int iter,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ struct TransDataArgs_Bend *data = iter_data_v;
+ TransData *td = &data->tc->data[iter];
+ if (td->flag & TD_SKIP) {
+ return;
+ }
+ transdata_elem_bend(data->t,
+ data->tc,
+ td,
+ data->angle,
+ &data->bend_data,
+ data->warp_sta_local,
+ data->warp_end_local,
+ data->warp_end_radius_local,
+ data->pivot_local,
+ data->is_clamp);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform (Bend)
+ * \{ */
+
static eRedrawFlag handleEventBend(TransInfo *UNUSED(t), const wmEvent *event)
{
eRedrawFlag status = TREDRAW_NOTHING;
@@ -75,12 +195,11 @@ static eRedrawFlag handleEventBend(TransInfo *UNUSED(t), const wmEvent *event)
static void Bend(TransInfo *t, const int UNUSED(mval[2]))
{
- float vec[3];
float pivot_global[3];
float warp_end_radius_global[3];
int i;
char str[UI_MAX_DRAW_STR];
- const struct BendCustomData *data = t->custom.mode.data;
+ const struct BendCustomData *bend_data = t->custom.mode.data;
const bool is_clamp = (t->flag & T_ALT_TRANSFORM) == 0;
union {
@@ -100,7 +219,7 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
* this isn't essential but nicer to give reasonable snapping values for radius. */
if (t->tsnap.mode & SCE_SNAP_MODE_INCREMENT) {
const float radius_snap = 0.1f;
- const float snap_hack = (t->snap[0] * data->warp_init_dist) / radius_snap;
+ const float snap_hack = (t->snap[0] * bend_data->warp_init_dist) / radius_snap;
values.scale *= snap_hack;
transform_snap_increment(t, values.vector);
values.scale /= snap_hack;
@@ -108,7 +227,7 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
#endif
if (applyNumInput(&t->num, values.vector)) {
- values.scale = values.scale / data->warp_init_dist;
+ values.scale = values.scale / bend_data->warp_init_dist;
}
copy_v2_v2(t->values_final, values.vector);
@@ -132,34 +251,33 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
sizeof(str),
TIP_("Bend Angle: %.3f Radius: %.4f, Alt, Clamp %s"),
RAD2DEGF(values.angle),
- values.scale * data->warp_init_dist,
+ values.scale * bend_data->warp_init_dist,
WM_bool_as_string(is_clamp));
}
values.angle *= -1.0f;
- values.scale *= data->warp_init_dist;
+ values.scale *= bend_data->warp_init_dist;
/* calc 'data->warp_end' from 'data->warp_end_init' */
- copy_v3_v3(warp_end_radius_global, data->warp_end);
- dist_ensure_v3_v3fl(warp_end_radius_global, data->warp_sta, values.scale);
+ copy_v3_v3(warp_end_radius_global, bend_data->warp_end);
+ dist_ensure_v3_v3fl(warp_end_radius_global, bend_data->warp_sta, values.scale);
/* done */
/* calculate pivot */
- copy_v3_v3(pivot_global, data->warp_sta);
+ copy_v3_v3(pivot_global, bend_data->warp_sta);
if (values.angle > 0.0f) {
madd_v3_v3fl(pivot_global,
- data->warp_tan,
+ bend_data->warp_tan,
-values.scale * shell_angle_to_dist((float)M_PI_2 - values.angle));
}
else {
madd_v3_v3fl(pivot_global,
- data->warp_tan,
+ bend_data->warp_tan,
+values.scale * shell_angle_to_dist((float)M_PI_2 + values.angle));
}
/* TODO(campbell): xform, compensate object center. */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
float warp_sta_local[3];
float warp_end_local[3];
@@ -167,74 +285,52 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
float pivot_local[3];
if (tc->use_local_mat) {
- sub_v3_v3v3(warp_sta_local, data->warp_sta, tc->mat[3]);
- sub_v3_v3v3(warp_end_local, data->warp_end, tc->mat[3]);
+ sub_v3_v3v3(warp_sta_local, bend_data->warp_sta, tc->mat[3]);
+ sub_v3_v3v3(warp_end_local, bend_data->warp_end, tc->mat[3]);
sub_v3_v3v3(warp_end_radius_local, warp_end_radius_global, tc->mat[3]);
sub_v3_v3v3(pivot_local, pivot_global, tc->mat[3]);
}
else {
- copy_v3_v3(warp_sta_local, data->warp_sta);
- copy_v3_v3(warp_end_local, data->warp_end);
+ copy_v3_v3(warp_sta_local, bend_data->warp_sta);
+ copy_v3_v3(warp_end_local, bend_data->warp_end);
copy_v3_v3(warp_end_radius_local, warp_end_radius_global);
copy_v3_v3(pivot_local, pivot_global);
}
- for (i = 0; i < tc->data_len; i++, td++) {
- float mat[3][3];
- float delta[3];
- float fac, fac_scaled;
-
- if (td->flag & TD_SKIP) {
- continue;
- }
+ if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+ TransData *td = tc->data;
- if (UNLIKELY(values.angle == 0.0f)) {
- copy_v3_v3(td->loc, td->iloc);
- continue;
- }
-
- copy_v3_v3(vec, td->iloc);
- mul_m3_v3(td->mtx, vec);
-
- fac = line_point_factor_v3(vec, warp_sta_local, warp_end_radius_local);
- if (is_clamp) {
- CLAMP(fac, 0.0f, 1.0f);
- }
-
- if (t->options & CTX_GPENCIL_STROKES) {
- /* grease pencil multiframe falloff */
- bGPDstroke *gps = (bGPDstroke *)td->extra;
- if (gps != NULL) {
- fac_scaled = fac * td->factor * gps->runtime.multi_frame_falloff;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
}
- else {
- fac_scaled = fac * td->factor;
- }
- }
- else {
- fac_scaled = fac * td->factor;
+ transdata_elem_bend(t,
+ tc,
+ td,
+ values.angle,
+ bend_data,
+ warp_sta_local,
+ warp_end_local,
+ warp_end_radius_local,
+ pivot_local,
+ is_clamp);
}
-
- axis_angle_normalized_to_mat3(mat, data->warp_nor, values.angle * fac_scaled);
- interp_v3_v3v3(delta, warp_sta_local, warp_end_radius_local, fac_scaled);
- sub_v3_v3(delta, warp_sta_local);
-
- /* delta is subtracted, rotation adds back this offset */
- sub_v3_v3(vec, delta);
-
- sub_v3_v3(vec, pivot_local);
- mul_m3_v3(mat, vec);
- add_v3_v3(vec, pivot_local);
-
- mul_m3_v3(td->smtx, vec);
-
- /* rotation */
- if ((t->flag & T_POINTS) == 0) {
- ElementRotation(t, tc, td, mat, V3D_AROUND_LOCAL_ORIGINS);
- }
-
- /* location */
- copy_v3_v3(td->loc, vec);
+ }
+ else {
+ struct TransDataArgs_Bend data = {
+ .t = t,
+ .tc = tc,
+ .angle = values.angle,
+ .bend_data = *bend_data,
+ .warp_sta_local = {UNPACK3(warp_sta_local)},
+ .warp_end_local = {UNPACK3(warp_end_local)},
+ .warp_end_radius_local = {UNPACK3(warp_end_radius_local)},
+ .pivot_local = {UNPACK3(pivot_local)},
+ .is_clamp = is_clamp,
+ };
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_bend_fn, &settings);
}
}
diff --git a/source/blender/editors/transform/transform_mode_edge_bevelweight.c b/source/blender/editors/transform/transform_mode_edge_bevelweight.c
index 3ce52ed3296..425bfec241e 100644
--- a/source/blender/editors/transform/transform_mode_edge_bevelweight.c
+++ b/source/blender/editors/transform/transform_mode_edge_bevelweight.c
@@ -25,6 +25,7 @@
#include "BLI_math.h"
#include "BLI_string.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_unit.h"
@@ -40,6 +41,50 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
+/** \name Transform (Bevel Weight) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be stored copied for faster memory access.
+ */
+struct TransDataArgs_BevelWeight {
+ const TransInfo *t;
+ const TransDataContainer *tc;
+ float weight;
+};
+
+static void transdata_elem_bevel_weight(const TransInfo *UNUSED(t),
+ const TransDataContainer *UNUSED(tc),
+ TransData *td,
+ const float weight)
+{
+ if (td->val == NULL) {
+ return;
+ }
+ *td->val = td->ival + weight * td->factor;
+ if (*td->val < 0.0f) {
+ *td->val = 0.0f;
+ }
+ if (*td->val > 1.0f) {
+ *td->val = 1.0f;
+ }
+}
+
+static void transdata_elem_bevel_weight_fn(void *__restrict iter_data_v,
+ const int iter,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ struct TransDataArgs_BevelWeight *data = iter_data_v;
+ TransData *td = &data->tc->data[iter];
+ if (td->flag & TD_SKIP) {
+ return;
+ }
+ transdata_elem_bevel_weight(data->t, data->tc, td, data->weight);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Transform (Bevel Weight)
* \{ */
@@ -83,18 +128,25 @@ static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2]))
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- if (td->val) {
- *td->val = td->ival + weight * td->factor;
- if (*td->val < 0.0f) {
- *td->val = 0.0f;
- }
- if (*td->val > 1.0f) {
- *td->val = 1.0f;
+ if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+ TransData *td = tc->data;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
}
+ transdata_elem_bevel_weight(t, tc, td, weight);
}
}
+ else {
+ struct TransDataArgs_BevelWeight data = {
+ .t = t,
+ .tc = tc,
+ .weight = weight,
+ };
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_bevel_weight_fn, &settings);
+ }
}
recalcData(t);
diff --git a/source/blender/editors/transform/transform_mode_edge_crease.c b/source/blender/editors/transform/transform_mode_edge_crease.c
index 23fa20b68ff..91e2507e544 100644
--- a/source/blender/editors/transform/transform_mode_edge_crease.c
+++ b/source/blender/editors/transform/transform_mode_edge_crease.c
@@ -25,6 +25,7 @@
#include "BLI_math.h"
#include "BLI_string.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_unit.h"
@@ -40,6 +41,51 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
+/** \name Transform (Crease) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be stored copied for faster memory access.
+ */
+struct TransDataArgs_Crease {
+ const TransInfo *t;
+ const TransDataContainer *tc;
+ float crease;
+};
+
+static void transdata_elem_crease(const TransInfo *UNUSED(t),
+ const TransDataContainer *UNUSED(tc),
+ TransData *td,
+ const float crease)
+{
+ if (td->val == NULL) {
+ return;
+ }
+
+ *td->val = td->ival + crease * td->factor;
+ if (*td->val < 0.0f) {
+ *td->val = 0.0f;
+ }
+ if (*td->val > 1.0f) {
+ *td->val = 1.0f;
+ }
+}
+
+static void transdata_elem_crease_fn(void *__restrict iter_data_v,
+ const int iter,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ struct TransDataArgs_Crease *data = iter_data_v;
+ TransData *td = &data->tc->data[iter];
+ if (td->flag & TD_SKIP) {
+ return;
+ }
+ transdata_elem_crease(data->t, data->tc, td, data->crease);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Transform (Crease)
* \{ */
@@ -83,22 +129,25 @@ static void applyCrease(TransInfo *t, const int UNUSED(mval[2]))
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- if (td->flag & TD_SKIP) {
- continue;
- }
-
- if (td->val) {
- *td->val = td->ival + crease * td->factor;
- if (*td->val < 0.0f) {
- *td->val = 0.0f;
- }
- if (*td->val > 1.0f) {
- *td->val = 1.0f;
+ if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+ TransData *td = tc->data;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
}
+ transdata_elem_crease(t, tc, td, crease);
}
}
+ else {
+ struct TransDataArgs_Crease data = {
+ .t = t,
+ .tc = tc,
+ .crease = crease,
+ };
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_crease_fn, &settings);
+ }
}
recalcData(t);
@@ -124,4 +173,5 @@ void initCrease(TransInfo *t)
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
+
/** \} */
diff --git a/source/blender/editors/transform/transform_mode_edge_rotate_normal.c b/source/blender/editors/transform/transform_mode_edge_rotate_normal.c
index b7b3de69731..6f2bcc148ce 100644
--- a/source/blender/editors/transform/transform_mode_edge_rotate_normal.c
+++ b/source/blender/editors/transform/transform_mode_edge_rotate_normal.c
@@ -103,7 +103,7 @@ static void applyNormalRotation(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &angle);
- headerRotation(t, str, angle);
+ headerRotation(t, str, sizeof(str), angle);
axis_angle_normalized_to_mat3(mat, axis, angle);
diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c
index 4330d5e79be..a8f7fc43b5e 100644
--- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c
@@ -23,8 +23,10 @@
#include <stdlib.h>
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_unit.h"
@@ -37,6 +39,10 @@
#include "UI_interface.h"
#include "UI_view2d.h"
+#include "SEQ_iterator.h"
+#include "SEQ_sequencer.h"
+#include "SEQ_time.h"
+
#include "BLT_translation.h"
#include "transform.h"
@@ -72,7 +78,7 @@ static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRA
BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.0f, %.0f", val[0], val[1]);
}
- ofs += BLI_snprintf(
+ ofs += BLI_snprintf_rlen(
str + ofs, UI_MAX_DRAW_STR - ofs, TIP_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text);
const wmKeyMapItem *kmi = t->custom.mode.data;
@@ -80,10 +86,10 @@ static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRA
ofs += WM_keymap_item_to_string(kmi, false, str + ofs, UI_MAX_DRAW_STR - ofs);
}
- ofs += BLI_snprintf(str + ofs,
- UI_MAX_DRAW_STR - ofs,
- TIP_(" or Alt) Expand to fit %s"),
- WM_bool_as_string((t->flag & T_ALT_TRANSFORM) != 0));
+ ofs += BLI_snprintf_rlen(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ TIP_(" or Alt) Expand to fit %s"),
+ WM_bool_as_string((t->flag & T_ALT_TRANSFORM) != 0));
}
static void applySeqSlideValue(TransInfo *t, const float val[2])
@@ -102,13 +108,11 @@ static void applySeqSlideValue(TransInfo *t, const float val[2])
}
}
-static void applySeqSlide(TransInfo *t, const int mval[2])
+static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2]))
{
char str[UI_MAX_DRAW_STR];
float values_final[3] = {0.0f};
- snapSequenceBounds(t, mval);
- transform_convert_sequencer_channel_clamp(t);
if (applyNumInput(&t->num, values_final)) {
if (t->con.mode & CON_APPLY) {
if (t->con.mode & CON_AXIS0) {
@@ -119,11 +123,14 @@ static void applySeqSlide(TransInfo *t, const int mval[2])
}
}
}
- else if (t->con.mode & CON_APPLY) {
- t->con.applyVec(t, NULL, NULL, t->values, values_final);
- }
else {
copy_v2_v2(values_final, t->values);
+ applySnapping(t, values_final);
+ transform_convert_sequencer_channel_clamp(t, values_final);
+
+ if (t->con.mode & CON_APPLY) {
+ t->con.applyVec(t, NULL, NULL, values_final, values_final);
+ }
}
values_final[0] = floorf(values_final[0] + 0.5f);
@@ -142,6 +149,7 @@ void initSeqSlide(TransInfo *t)
{
t->transform = applySeqSlide;
t->handleEvent = seq_slide_handleEvent;
+ t->tsnap.applySnap = transform_snap_sequencer_apply_translate;
initMouseInputMode(t, &t->mouse, INPUT_VECTOR);
@@ -164,4 +172,5 @@ void initSeqSlide(TransInfo *t)
t->custom.mode.data = (void *)WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE);
}
}
+
/** \} */
diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c
index 16c1c05a6f8..066a2853dc7 100644
--- a/source/blender/editors/transform/transform_mode_edge_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_slide.c
@@ -107,7 +107,7 @@ static TransDataContainer *edge_slide_container_first_ok(TransInfo *t)
return tc;
}
}
- BLI_assert(!"Should never happen, at least one EdgeSlideData should be valid");
+ BLI_assert_msg(0, "Should never happen, at least one EdgeSlideData should be valid");
return NULL;
}
@@ -375,8 +375,8 @@ static void calcEdgeSlide_mval_range(TransInfo *t,
UNUSED_VARS_NDEBUG(sv_table); /* silence warning */
BLI_assert(i == sv_table[BM_elem_index_get(v)]);
- /* search cross edges for visible edge to the mouse cursor,
- * then use the shared vertex to calculate screen vector*/
+ /* Search cross edges for visible edge to the mouse cursor,
+ * then use the shared vertex to calculate screen vector. */
BM_ITER_ELEM (e, &iter_other, v, BM_EDGES_OF_VERT) {
/* screen-space coords */
float sco_a[3], sco_b[3];
@@ -540,7 +540,7 @@ static EdgeSlideData *createEdgeSlideVerts_double_side(TransInfo *t, TransDataCo
sld->curr_sv_index = 0;
- /*ensure valid selection*/
+ /* Ensure valid selection. */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
BMIter iter2;
@@ -548,7 +548,7 @@ static EdgeSlideData *createEdgeSlideVerts_double_side(TransInfo *t, TransDataCo
BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) {
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
/* BMESH_TODO: this is probably very evil,
- * set v->e to a selected edge*/
+ * set `v->e` to a selected edge. */
v->e = e;
numsel++;
@@ -565,7 +565,7 @@ static EdgeSlideData *createEdgeSlideVerts_double_side(TransInfo *t, TransDataCo
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- /* note, any edge with loops can work, but we won't get predictable results, so bail out */
+ /* NOTE: any edge with loops can work, but we won't get predictable results, so bail out. */
if (!BM_edge_is_manifold(e) && !BM_edge_is_boundary(e)) {
/* can edges with at least once face user */
MEM_freeN(sld);
@@ -640,10 +640,10 @@ static EdgeSlideData *createEdgeSlideVerts_double_side(TransInfo *t, TransDataCo
v_first = v;
- /*walk along the edge loop*/
+ /* Walk along the edge loop. */
e = v->e;
- /*first, rewind*/
+ /* First, rewind. */
do {
e = get_other_edge(v, e);
if (!e) {
@@ -709,7 +709,7 @@ static EdgeSlideData *createEdgeSlideVerts_double_side(TransInfo *t, TransDataCo
STACK_PUSH_RET_PTR(sv_array)) : \
(&sv_array[sv_table[BM_elem_index_get(v)]]))
- /*iterate over the loop*/
+ /* Iterate over the loop. */
v_first = v;
do {
bool l_a_ok_prev;
@@ -818,7 +818,7 @@ static EdgeSlideData *createEdgeSlideVerts_double_side(TransInfo *t, TransDataCo
/* if there are non-contiguous faces, we can still recover
* the loops of the new edges faces */
- /* note!, the behavior in this case means edges may move in opposite directions,
+ /* NOTE:, the behavior in this case means edges may move in opposite directions,
* this could be made to work more usefully. */
if (l_a_ok_prev) {
@@ -1220,7 +1220,7 @@ void drawEdgeSlide(TransInfo *t)
immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
immBegin(GPU_PRIM_LINES, sld->totsv * 2);
- /* TODO(campbell): Loop over all verts */
+ /* TODO(campbell): Loop over all verts. */
sv = sld->sv;
for (i = 0; i < sld->totsv; i++, sv++) {
float a[3], b[3];
@@ -1482,15 +1482,15 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
ofs += BLI_strncpy_rlen(str + ofs, &c[0], sizeof(str) - ofs);
}
else {
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, "%.4f ", final);
+ ofs += BLI_snprintf_rlen(str + ofs, sizeof(str) - ofs, "%.4f ", final);
}
- ofs += BLI_snprintf(
+ ofs += BLI_snprintf_rlen(
str + ofs, sizeof(str) - ofs, TIP_("(E)ven: %s, "), WM_bool_as_string(use_even));
if (use_even) {
- ofs += BLI_snprintf(
+ ofs += BLI_snprintf_rlen(
str + ofs, sizeof(str) - ofs, TIP_("(F)lipped: %s, "), WM_bool_as_string(flipped));
}
- ofs += BLI_snprintf(
+ ofs += BLI_snprintf_rlen(
str + ofs, sizeof(str) - ofs, TIP_("Alt or (C)lamp: %s"), WM_bool_as_string(is_clamp));
/* done with header string */
diff --git a/source/blender/editors/transform/transform_mode_maskshrinkfatten.c b/source/blender/editors/transform/transform_mode_maskshrinkfatten.c
index 857ee37f0ad..cfbd6030788 100644
--- a/source/blender/editors/transform/transform_mode_maskshrinkfatten.c
+++ b/source/blender/editors/transform/transform_mode_maskshrinkfatten.c
@@ -89,7 +89,7 @@ static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
/* apply shrink/fatten */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
+ TransData *td;
for (td = tc->data, i = 0; i < tc->data_len; i++, td++) {
if (td->flag & TD_SKIP) {
continue;
diff --git a/source/blender/editors/transform/transform_mode_push_pull.c b/source/blender/editors/transform/transform_mode_push_pull.c
index 8a92978f33f..0492ec8df8c 100644
--- a/source/blender/editors/transform/transform_mode_push_pull.c
+++ b/source/blender/editors/transform/transform_mode_push_pull.c
@@ -25,6 +25,7 @@
#include "BLI_math.h"
#include "BLI_string.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_unit.h"
@@ -41,12 +42,82 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
+/** \name Transform (Push/Pull) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be stored copied for faster memory access.
+ */
+struct TransDataArgs_PushPull {
+ const TransInfo *t;
+ const TransDataContainer *tc;
+
+ float distance;
+ const float axis_global[3];
+ bool is_lock_constraint;
+ bool is_data_space;
+};
+
+static void transdata_elem_push_pull(const TransInfo *t,
+ const TransDataContainer *tc,
+ TransData *td,
+ const float distance,
+ const float axis_global[3],
+ const bool is_lock_constraint,
+ const bool is_data_space)
+{
+ float vec[3];
+ sub_v3_v3v3(vec, tc->center_local, td->center);
+ if (t->con.applyRot && t->con.mode & CON_APPLY) {
+ float axis[3];
+ copy_v3_v3(axis, axis_global);
+ t->con.applyRot(t, tc, td, axis, NULL);
+
+ mul_m3_v3(td->smtx, axis);
+ if (is_lock_constraint) {
+ float dvec[3];
+ project_v3_v3v3(dvec, vec, axis);
+ sub_v3_v3(vec, dvec);
+ }
+ else {
+ project_v3_v3v3(vec, vec, axis);
+ }
+ }
+ normalize_v3_length(vec, distance * td->factor);
+ if (is_data_space) {
+ mul_m3_v3(td->smtx, vec);
+ }
+
+ add_v3_v3v3(td->loc, td->iloc, vec);
+}
+
+static void transdata_elem_push_pull_fn(void *__restrict iter_data_v,
+ const int iter,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ struct TransDataArgs_PushPull *data = iter_data_v;
+ TransData *td = &data->tc->data[iter];
+ if (td->flag & TD_SKIP) {
+ return;
+ }
+ transdata_elem_push_pull(data->t,
+ data->tc,
+ td,
+ data->distance,
+ data->axis_global,
+ data->is_lock_constraint,
+ data->is_data_space);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Transform (Push/Pull)
* \{ */
static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
{
- float vec[3], axis_global[3];
+ float axis_global[3];
float distance;
int i;
char str[UI_MAX_DRAW_STR];
@@ -77,32 +148,31 @@ static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
t->con.applyRot(t, NULL, NULL, axis_global, NULL);
}
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- if (td->flag & TD_SKIP) {
- continue;
- }
+ const bool is_lock_constraint = isLockConstraint(t);
+ const bool is_data_space = (t->options & CTX_POSE_BONE) != 0;
- sub_v3_v3v3(vec, tc->center_local, td->center);
- if (t->con.applyRot && t->con.mode & CON_APPLY) {
- float axis[3];
- copy_v3_v3(axis, axis_global);
- t->con.applyRot(t, tc, td, axis, NULL);
-
- mul_m3_v3(td->smtx, axis);
- if (isLockConstraint(t)) {
- float dvec[3];
- project_v3_v3v3(dvec, vec, axis);
- sub_v3_v3(vec, dvec);
- }
- else {
- project_v3_v3v3(vec, vec, axis);
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+ TransData *td = tc->data;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
}
+ transdata_elem_push_pull(
+ t, tc, td, distance, axis_global, is_lock_constraint, is_data_space);
}
- normalize_v3_length(vec, distance * td->factor);
-
- add_v3_v3v3(td->loc, td->iloc, vec);
+ }
+ else {
+ struct TransDataArgs_PushPull data = {
+ .t = t,
+ .tc = tc,
+ .axis_global = {UNPACK3(axis_global)},
+ .is_lock_constraint = is_lock_constraint,
+ .is_data_space = is_data_space,
+ };
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_push_pull_fn, &settings);
}
}
diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c
index 0d7d0be3c0e..65f4623b3be 100644
--- a/source/blender/editors/transform/transform_mode_resize.c
+++ b/source/blender/editors/transform/transform_mode_resize.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include "BLI_math.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_unit.h"
@@ -39,6 +40,30 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
+/** \name Transform (Resize) Element
+ * \{ */
+
+struct ElemResizeData {
+ const TransInfo *t;
+ const TransDataContainer *tc;
+ float mat[3][3];
+};
+
+static void element_resize_fn(void *__restrict iter_data_v,
+ const int iter,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ struct ElemResizeData *data = iter_data_v;
+ TransData *td = &data->tc->data[iter];
+ if (td->flag & TD_SKIP) {
+ return;
+ }
+ ElementResize(data->t, data->tc, td, data->mat);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Transform (Resize)
* \{ */
@@ -88,6 +113,7 @@ static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
float ratio = t->values[0];
copy_v3_fl(t->values_final, ratio);
+ add_v3_v3(t->values_final, t->values_modal_offset);
transform_snap_increment(t, t->values_final);
@@ -113,22 +139,36 @@ static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
pvec[j++] = t->values_final[i];
}
}
- headerResize(t, pvec, str);
+ headerResize(t, pvec, str, sizeof(str));
}
else {
- headerResize(t, t->values_final, str);
+ headerResize(t, t->values_final, str, sizeof(str));
}
copy_m3_m3(t->mat, mat); /* used in gizmo */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- if (td->flag & TD_SKIP) {
- continue;
- }
- ElementResize(t, tc, td, mat);
+ if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+ TransData *td = tc->data;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
+ }
+
+ ElementResize(t, tc, td, mat);
+ }
+ }
+ else {
+ struct ElemResizeData data = {
+ .t = t,
+ .tc = tc,
+ };
+ copy_m3_m3(data.mat, mat);
+
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ BLI_task_parallel_range(0, tc->data_len, &data, element_resize_fn, &settings);
}
}
diff --git a/source/blender/editors/transform/transform_mode_rotate.c b/source/blender/editors/transform/transform_mode_rotate.c
index 0fdbfb25989..44a29cfac45 100644
--- a/source/blender/editors/transform/transform_mode_rotate.c
+++ b/source/blender/editors/transform/transform_mode_rotate.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include "BLI_math.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_unit.h"
@@ -37,6 +38,140 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
+/** \name Transform (Rotation) Matrix Cache
+ * \{ */
+
+struct RotateMatrixCache {
+ /**
+ * Counter for needed updates (when we need to update to non-default matrix,
+ * we also need another update on next iteration to go back to default matrix,
+ * hence the '2' value used here, instead of a mere boolean).
+ */
+ short do_update_matrix;
+ float mat[3][3];
+};
+
+static void rmat_cache_init(struct RotateMatrixCache *rmc, const float angle, const float axis[3])
+{
+ axis_angle_normalized_to_mat3(rmc->mat, axis, angle);
+ rmc->do_update_matrix = 0;
+}
+
+static void rmat_cache_reset(struct RotateMatrixCache *rmc)
+{
+ rmc->do_update_matrix = 2;
+}
+
+static void rmat_cache_update(struct RotateMatrixCache *rmc,
+ const float axis[3],
+ const float angle)
+{
+ if (rmc->do_update_matrix > 0) {
+ axis_angle_normalized_to_mat3(rmc->mat, axis, angle);
+ rmc->do_update_matrix--;
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform (Rotation) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be stored copied for faster memory access.
+ */
+struct TransDataArgs_Rotate {
+ const TransInfo *t;
+ const TransDataContainer *tc;
+ const float axis[3];
+ float angle;
+ float angle_step;
+ bool is_large_rotation;
+};
+
+struct TransDataArgs_RotateTLS {
+ struct RotateMatrixCache rmc;
+};
+
+static void transdata_elem_rotate(const TransInfo *t,
+ const TransDataContainer *tc,
+ TransData *td,
+ const float axis[3],
+ const float angle,
+ const float angle_step,
+ const bool is_large_rotation,
+ struct RotateMatrixCache *rmc)
+{
+ float axis_buffer[3];
+ const float *axis_final = axis;
+
+ float angle_final = angle;
+ if (t->con.applyRot) {
+ copy_v3_v3(axis_buffer, axis);
+ axis_final = axis_buffer;
+ t->con.applyRot(t, tc, td, axis_buffer, NULL);
+ angle_final = angle * td->factor;
+ /* Even though final angle might be identical to orig value,
+ * we have to update the rotation matrix in that case... */
+ rmat_cache_reset(rmc);
+ }
+ else if (t->flag & T_PROP_EDIT) {
+ angle_final = angle * td->factor;
+ }
+
+ /* Rotation is very likely to be above 180°, we need to do rotation by steps.
+ * Note that this is only needed when doing 'absolute' rotation
+ * (i.e. from initial rotation again, typically when using numinput).
+ * regular incremental rotation (from mouse/widget/...) will be called often enough,
+ * hence steps are small enough to be properly handled without that complicated trick.
+ * Note that we can only do that kind of stepped rotation if we have initial rotation values
+ * (and access to some actual rotation value storage).
+ * Otherwise, just assume it's useless (e.g. in case of mesh/UV/etc. editing).
+ * Also need to be in Euler rotation mode, the others never allow more than one turn anyway.
+ */
+ if (is_large_rotation && td->ext != NULL && td->ext->rotOrder == ROT_MODE_EUL) {
+ copy_v3_v3(td->ext->rot, td->ext->irot);
+ for (float angle_progress = angle_step; fabsf(angle_progress) < fabsf(angle_final);
+ angle_progress += angle_step) {
+ axis_angle_normalized_to_mat3(rmc->mat, axis_final, angle_progress);
+ ElementRotation(t, tc, td, rmc->mat, t->around);
+ }
+ rmat_cache_reset(rmc);
+ }
+ else if (angle_final != angle) {
+ rmat_cache_reset(rmc);
+ }
+
+ rmat_cache_update(rmc, axis_final, angle_final);
+
+ ElementRotation(t, tc, td, rmc->mat, t->around);
+}
+
+static void transdata_elem_rotate_fn(void *__restrict iter_data_v,
+ const int iter,
+ const TaskParallelTLS *__restrict tls)
+{
+ struct TransDataArgs_Rotate *data = iter_data_v;
+ struct TransDataArgs_RotateTLS *tls_data = tls->userdata_chunk;
+
+ TransData *td = &data->tc->data[iter];
+ if (td->flag & TD_SKIP) {
+ return;
+ }
+ transdata_elem_rotate(data->t,
+ data->tc,
+ td,
+ data->axis,
+ data->angle,
+ data->angle_step,
+ data->is_large_rotation,
+ &tls_data->rmc);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Transform (Rotation)
* \{ */
@@ -115,12 +250,9 @@ static float large_rotation_limit(float angle)
static void applyRotationValue(TransInfo *t,
float angle,
- float axis[3],
+ const float axis[3],
const bool is_large_rotation)
{
- float mat[3][3];
- int i;
-
const float angle_sign = angle < 0.0f ? -1.0f : 1.0f;
/* We cannot use something too close to 180°, or 'continuous' rotation may fail
* due to computing error... */
@@ -132,60 +264,37 @@ static void applyRotationValue(TransInfo *t,
angle = large_rotation_limit(angle);
}
- axis_angle_normalized_to_mat3(mat, axis, angle);
- /* Counter for needed updates (when we need to update to non-default matrix,
- * we also need another update on next iteration to go back to default matrix,
- * hence the '2' value used here, instead of a mere boolean). */
- short do_update_matrix = 0;
+ struct RotateMatrixCache rmc = {0};
+ rmat_cache_init(&rmc, angle, axis);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- if (td->flag & TD_SKIP) {
- continue;
- }
-
- float angle_final = angle;
- if (t->con.applyRot) {
- t->con.applyRot(t, tc, td, axis, NULL);
- angle_final = angle * td->factor;
- /* Even though final angle might be identical to orig value,
- * we have to update the rotation matrix in that case... */
- do_update_matrix = 2;
- }
- else if (t->flag & T_PROP_EDIT) {
- angle_final = angle * td->factor;
- }
-
- /* Rotation is very likely to be above 180°, we need to do rotation by steps.
- * Note that this is only needed when doing 'absolute' rotation
- * (i.e. from initial rotation again, typically when using numinput).
- * regular incremental rotation (from mouse/widget/...) will be called often enough,
- * hence steps are small enough to be properly handled without that complicated trick.
- * Note that we can only do that kind of stepped rotation if we have initial rotation values
- * (and access to some actual rotation value storage).
- * Otherwise, just assume it's useless (e.g. in case of mesh/UV/etc. editing).
- * Also need to be in Euler rotation mode, the others never allow more than one turn anyway.
- */
- if (is_large_rotation && td->ext != NULL && td->ext->rotOrder == ROT_MODE_EUL) {
- copy_v3_v3(td->ext->rot, td->ext->irot);
- for (float angle_progress = angle_step; fabsf(angle_progress) < fabsf(angle_final);
- angle_progress += angle_step) {
- axis_angle_normalized_to_mat3(mat, axis, angle_progress);
- ElementRotation(t, tc, td, mat, t->around);
+ if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+ TransData *td = tc->data;
+ for (int i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
}
- do_update_matrix = 2;
+ transdata_elem_rotate(t, tc, td, axis, angle, angle_step, is_large_rotation, &rmc);
}
- else if (angle_final != angle) {
- do_update_matrix = 2;
- }
-
- if (do_update_matrix > 0) {
- axis_angle_normalized_to_mat3(mat, axis, angle_final);
- do_update_matrix--;
- }
-
- ElementRotation(t, tc, td, mat, t->around);
+ }
+ else {
+ struct TransDataArgs_Rotate data = {
+ .t = t,
+ .tc = tc,
+ .axis = {UNPACK3(axis)},
+ .angle = angle,
+ .angle_step = angle_step,
+ .is_large_rotation = is_large_rotation,
+ };
+ struct TransDataArgs_RotateTLS tls_data = {
+ .rmc = rmc,
+ };
+
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.userdata_chunk = &tls_data;
+ settings.userdata_chunk_size = sizeof(tls_data);
+ BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_rotate_fn, &settings);
}
}
}
@@ -194,7 +303,7 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
{
char str[UI_MAX_DRAW_STR];
float axis_final[3];
- float final = t->values[0];
+ float final = t->values[0] + t->values_modal_offset[0];
if ((t->con.mode & CON_APPLY) && t->con.applyRot) {
t->con.applyRot(t, NULL, NULL, axis_final, &final);
@@ -217,7 +326,7 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
t->values_final[0] = final;
- headerRotation(t, str, final);
+ headerRotation(t, str, sizeof(str), final);
const bool is_large_rotation = hasNumInput(&t->num);
applyRotationValue(t, final, axis_final, is_large_rotation);
diff --git a/source/blender/editors/transform/transform_mode_shear.c b/source/blender/editors/transform/transform_mode_shear.c
index 23ee55bf6c5..f5672887905 100644
--- a/source/blender/editors/transform/transform_mode_shear.c
+++ b/source/blender/editors/transform/transform_mode_shear.c
@@ -27,6 +27,7 @@
#include "BLI_math.h"
#include "BLI_string.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_unit.h"
@@ -44,6 +45,79 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
+/** \name Transform (Shear) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be stored copied for faster memory access.
+ */
+struct TransDataArgs_Shear {
+ const TransInfo *t;
+ const TransDataContainer *tc;
+ float mat_final[3][3];
+ bool is_local_center;
+};
+
+static void transdata_elem_shear(const TransInfo *t,
+ const TransDataContainer *tc,
+ TransData *td,
+ const float mat_final[3][3],
+ const bool is_local_center)
+{
+ float tmat[3][3];
+ const float *center;
+ if (t->flag & T_EDIT) {
+ mul_m3_series(tmat, td->smtx, mat_final, td->mtx);
+ }
+ else {
+ copy_m3_m3(tmat, mat_final);
+ }
+
+ if (is_local_center) {
+ center = td->center;
+ }
+ else {
+ center = tc->center_local;
+ }
+
+ float vec[3];
+ sub_v3_v3v3(vec, td->iloc, center);
+ mul_m3_v3(tmat, vec);
+ add_v3_v3(vec, center);
+ sub_v3_v3(vec, td->iloc);
+
+ if (t->options & CTX_GPENCIL_STROKES) {
+ /* Grease pencil multi-frame falloff. */
+ bGPDstroke *gps = (bGPDstroke *)td->extra;
+ if (gps != NULL) {
+ mul_v3_fl(vec, td->factor * gps->runtime.multi_frame_falloff);
+ }
+ else {
+ mul_v3_fl(vec, td->factor);
+ }
+ }
+ else {
+ mul_v3_fl(vec, td->factor);
+ }
+
+ add_v3_v3v3(td->loc, td->iloc, vec);
+}
+
+static void transdata_elem_shear_fn(void *__restrict iter_data_v,
+ const int iter,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ struct TransDataArgs_Shear *data = iter_data_v;
+ TransData *td = &data->tc->data[iter];
+ if (td->flag & TD_SKIP) {
+ return;
+ }
+ transdata_elem_shear(data->t, data->tc, td, data->mat_final, data->is_local_center);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Transform (Shear)
* \{ */
@@ -117,8 +191,7 @@ static eRedrawFlag handleEventShear(TransInfo *t, const wmEvent *event)
static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
{
- float vec[3];
- float smat[3][3], tmat[3][3], totmat[3][3], axismat[3][3], axismat_inv[3][3];
+ float smat[3][3], axismat[3][3], axismat_inv[3][3], mat_final[3][3];
float value;
int i;
char str[UI_MAX_DRAW_STR];
@@ -157,50 +230,29 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
cross_v3_v3v3(axismat_inv[1], axismat_inv[0], axismat_inv[2]);
invert_m3_m3(axismat, axismat_inv);
- mul_m3_series(totmat, axismat_inv, smat, axismat);
+ mul_m3_series(mat_final, axismat_inv, smat, axismat);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- const float *center;
- if (td->flag & TD_SKIP) {
- continue;
- }
-
- if (t->flag & T_EDIT) {
- mul_m3_series(tmat, td->smtx, totmat, td->mtx);
- }
- else {
- copy_m3_m3(tmat, totmat);
- }
-
- if (is_local_center) {
- center = td->center;
- }
- else {
- center = tc->center_local;
- }
-
- sub_v3_v3v3(vec, td->iloc, center);
- mul_m3_v3(tmat, vec);
- add_v3_v3(vec, center);
- sub_v3_v3(vec, td->iloc);
-
- if (t->options & CTX_GPENCIL_STROKES) {
- /* grease pencil multiframe falloff */
- bGPDstroke *gps = (bGPDstroke *)td->extra;
- if (gps != NULL) {
- mul_v3_fl(vec, td->factor * gps->runtime.multi_frame_falloff);
- }
- else {
- mul_v3_fl(vec, td->factor);
+ if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+ TransData *td = tc->data;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
}
+ transdata_elem_shear(t, tc, td, mat_final, is_local_center);
}
- else {
- mul_v3_fl(vec, td->factor);
- }
-
- add_v3_v3v3(td->loc, td->iloc, vec);
+ }
+ else {
+ struct TransDataArgs_Shear data = {
+ .t = t,
+ .tc = tc,
+ .is_local_center = is_local_center,
+ };
+ copy_m3_m3(data.mat_final, mat_final);
+
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_shear_fn, &settings);
}
}
diff --git a/source/blender/editors/transform/transform_mode_shrink_fatten.c b/source/blender/editors/transform/transform_mode_shrink_fatten.c
index 6e497d85417..4cdaab599b4 100644
--- a/source/blender/editors/transform/transform_mode_shrink_fatten.c
+++ b/source/blender/editors/transform/transform_mode_shrink_fatten.c
@@ -25,6 +25,7 @@
#include "BLI_math.h"
#include "BLI_string.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_unit.h"
@@ -43,6 +44,47 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
+/** \name Transform (Shrink-Fatten) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be stored copied for faster memory access.
+ */
+struct TransDataArgs_ShrinkFatten {
+ const TransInfo *t;
+ const TransDataContainer *tc;
+ float distance;
+};
+
+static void transdata_elem_shrink_fatten(const TransInfo *t,
+ const TransDataContainer *UNUSED(tc),
+ TransData *td,
+ const float distance)
+{
+ /* Get the final offset. */
+ float tdistance = distance * td->factor;
+ if (td->ext && (t->flag & T_ALT_TRANSFORM) != 0) {
+ tdistance *= td->ext->isize[0]; /* shell factor */
+ }
+
+ madd_v3_v3v3fl(td->loc, td->iloc, td->axismtx[2], tdistance);
+}
+
+static void transdata_elem_shrink_fatten_fn(void *__restrict iter_data_v,
+ const int iter,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ struct TransDataArgs_ShrinkFatten *data = iter_data_v;
+ TransData *td = &data->tc->data[iter];
+ if (td->flag & TD_SKIP) {
+ return;
+ }
+ transdata_elem_shrink_fatten(data->t, data->tc, td, data->distance);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Transform (Shrink-Fatten)
* \{ */
@@ -79,7 +121,7 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, unit);
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, "%s", c);
+ ofs += BLI_snprintf_rlen(str + ofs, sizeof(str) - ofs, "%s", c);
}
else {
/* default header print */
@@ -93,12 +135,12 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
true);
}
else {
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, "%.4f", distance);
+ ofs += BLI_snprintf_rlen(str + ofs, sizeof(str) - ofs, "%.4f", distance);
}
}
if (t->proptext[0]) {
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, " %s", t->proptext);
+ ofs += BLI_snprintf_rlen(str + ofs, sizeof(str) - ofs, " %s", t->proptext);
}
ofs += BLI_strncpy_rlen(str + ofs, ", (", sizeof(str) - ofs);
@@ -114,20 +156,24 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
/* done with header string */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- float tdistance; /* temp dist */
- if (td->flag & TD_SKIP) {
- continue;
+ if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+ TransData *td = tc->data;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
+ }
+ transdata_elem_shrink_fatten(t, tc, td, distance);
}
-
- /* get the final offset */
- tdistance = distance * td->factor;
- if (td->ext && (t->flag & T_ALT_TRANSFORM) != 0) {
- tdistance *= td->ext->isize[0]; /* shell factor */
- }
-
- madd_v3_v3v3fl(td->loc, td->iloc, td->axismtx[2], tdistance);
+ }
+ else {
+ struct TransDataArgs_ShrinkFatten data = {
+ .t = t,
+ .tc = tc,
+ .distance = distance,
+ };
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_shrink_fatten_fn, &settings);
}
}
diff --git a/source/blender/editors/transform/transform_mode_skin_resize.c b/source/blender/editors/transform/transform_mode_skin_resize.c
index 77e57484bef..0a7eea8a989 100644
--- a/source/blender/editors/transform/transform_mode_skin_resize.c
+++ b/source/blender/editors/transform/transform_mode_skin_resize.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include "BLI_math.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_unit.h"
@@ -38,12 +39,64 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
+/** \name Transform (Skin) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be stored copied for faster memory access.
+ */
+struct TransDataArgs_SkinResize {
+ const TransInfo *t;
+ const TransDataContainer *tc;
+ float mat_final[3][3];
+};
+
+static void transdata_elem_skin_resize(const TransInfo *t,
+ const TransDataContainer *UNUSED(tc),
+ TransData *td,
+ const float mat[3][3])
+{
+ float tmat[3][3], smat[3][3];
+ float fsize[3];
+
+ if (t->flag & T_EDIT) {
+ mul_m3_m3m3(smat, mat, td->mtx);
+ mul_m3_m3m3(tmat, td->smtx, smat);
+ }
+ else {
+ copy_m3_m3(tmat, mat);
+ }
+
+ if (t->con.applySize) {
+ t->con.applySize(t, NULL, NULL, tmat);
+ }
+
+ mat3_to_size(fsize, tmat);
+ td->loc[0] = td->iloc[0] * (1 + (fsize[0] - 1) * td->factor);
+ td->loc[1] = td->iloc[1] * (1 + (fsize[1] - 1) * td->factor);
+}
+
+static void transdata_elem_skin_resize_fn(void *__restrict iter_data_v,
+ const int iter,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ struct TransDataArgs_SkinResize *data = iter_data_v;
+ TransData *td = &data->tc->data[iter];
+ if (td->flag & TD_SKIP) {
+ return;
+ }
+ transdata_elem_skin_resize(data->t, data->tc, td, data->mat_final);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Transform (Skin)
* \{ */
static void applySkinResize(TransInfo *t, const int UNUSED(mval[2]))
{
- float mat[3][3];
+ float mat_final[3][3];
int i;
char str[UI_MAX_DRAW_STR];
@@ -62,34 +115,29 @@ static void applySkinResize(TransInfo *t, const int UNUSED(mval[2]))
applySnapping(t, t->values_final);
}
- size_to_mat3(mat, t->values_final);
+ size_to_mat3(mat_final, t->values_final);
- headerResize(t, t->values_final, str);
+ headerResize(t, t->values_final, str, sizeof(str));
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- float tmat[3][3], smat[3][3];
- float fsize[3];
- if (td->flag & TD_SKIP) {
- continue;
+ if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+ TransData *td = tc->data;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
+ }
+ transdata_elem_skin_resize(t, tc, td, mat_final);
}
-
- if (t->flag & T_EDIT) {
- mul_m3_m3m3(smat, mat, td->mtx);
- mul_m3_m3m3(tmat, td->smtx, smat);
- }
- else {
- copy_m3_m3(tmat, mat);
- }
-
- if (t->con.applySize) {
- t->con.applySize(t, NULL, NULL, tmat);
- }
-
- mat3_to_size(fsize, tmat);
- td->loc[0] = td->iloc[0] * (1 + (fsize[0] - 1) * td->factor);
- td->loc[1] = td->iloc[1] * (1 + (fsize[1] - 1) * td->factor);
+ }
+ else {
+ struct TransDataArgs_SkinResize data = {
+ .t = t,
+ .tc = tc,
+ };
+ copy_m3_m3(data.mat_final, mat_final);
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_skin_resize_fn, &settings);
}
}
diff --git a/source/blender/editors/transform/transform_mode_timetranslate.c b/source/blender/editors/transform/transform_mode_timetranslate.c
index 5ad6d04b4de..948242e547f 100644
--- a/source/blender/editors/transform/transform_mode_timetranslate.c
+++ b/source/blender/editors/transform/transform_mode_timetranslate.c
@@ -76,10 +76,10 @@ static void headerTimeTranslate(TransInfo *t, char str[UI_MAX_DRAW_STR])
}
}
- ofs += BLI_snprintf(str, UI_MAX_DRAW_STR, TIP_("DeltaX: %s"), &tvec[0]);
+ ofs += BLI_snprintf_rlen(str, UI_MAX_DRAW_STR, TIP_("DeltaX: %s"), &tvec[0]);
if (t->flag & T_PROP_EDIT_ALL) {
- ofs += BLI_snprintf(
+ ofs += BLI_snprintf_rlen(
str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
}
}
diff --git a/source/blender/editors/transform/transform_mode_tosphere.c b/source/blender/editors/transform/transform_mode_tosphere.c
index 15906f2c90c..8587d5ae140 100644
--- a/source/blender/editors/transform/transform_mode_tosphere.c
+++ b/source/blender/editors/transform/transform_mode_tosphere.c
@@ -25,6 +25,7 @@
#include "BLI_math.h"
#include "BLI_string.h"
+#include "BLI_task.h"
#include "MEM_guardedalloc.h"
@@ -55,8 +56,10 @@ static void to_sphere_radius_update(TransInfo *t)
{
struct ToSphereInfo *data = t->custom.mode.data;
float radius = 0.0f;
+ float vec[3];
const bool is_local_center = transdata_check_local_center(t, t->around);
+ const bool is_data_space = (t->options & CTX_POSE_BONE) != 0;
if (t->flag & T_PROP_EDIT_ALL) {
int factor_accum = 0.0f;
@@ -67,7 +70,15 @@ static void to_sphere_radius_update(TransInfo *t)
continue;
}
const float *center = is_local_center ? td->center : tc->center_local;
- radius += td->factor * len_v3v3(center, td->iloc);
+ if (is_data_space) {
+ copy_v3_v3(vec, td->center);
+ }
+ else {
+ copy_v3_v3(vec, td->iloc);
+ }
+
+ sub_v3_v3(vec, center);
+ radius += td->factor * len_v3(vec);
factor_accum += td->factor;
}
}
@@ -80,7 +91,15 @@ static void to_sphere_radius_update(TransInfo *t)
TransData *td = tc->data;
for (int i = 0; i < tc->data_len; i++, td++) {
const float *center = is_local_center ? td->center : tc->center_local;
- radius += len_v3v3(center, td->iloc);
+ if (is_data_space) {
+ copy_v3_v3(vec, td->center);
+ }
+ else {
+ copy_v3_v3(vec, td->iloc);
+ }
+
+ sub_v3_v3(vec, center);
+ radius += len_v3(vec);
}
}
radius /= (float)t->data_len_all;
@@ -93,15 +112,83 @@ static void to_sphere_radius_update(TransInfo *t)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Transform (ToSphere) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be stored copied for faster memory access.
+ */
+struct TransDataArgs_ToSphere {
+ const TransInfo *t;
+ const TransDataContainer *tc;
+ float ratio;
+ const struct ToSphereInfo to_sphere_info;
+ bool is_local_center;
+ bool is_data_space;
+};
+
+static void transdata_elem_to_sphere(const TransInfo *UNUSED(t),
+ const TransDataContainer *tc,
+ TransData *td,
+ const float ratio,
+ const struct ToSphereInfo *to_sphere_info,
+ const bool is_local_center,
+ const bool is_data_space)
+{
+ float vec[3];
+ const float *center = is_local_center ? td->center : tc->center_local;
+ if (is_data_space) {
+ copy_v3_v3(vec, td->center);
+ }
+ else {
+ copy_v3_v3(vec, td->iloc);
+ }
+
+ sub_v3_v3(vec, center);
+ const float radius = normalize_v3(vec);
+ const float tratio = ratio * td->factor;
+ mul_v3_fl(vec, radius * (1.0f - tratio) + to_sphere_info->radius * tratio);
+ add_v3_v3(vec, center);
+
+ if (is_data_space) {
+ sub_v3_v3(vec, td->center);
+ mul_m3_v3(td->smtx, vec);
+ add_v3_v3(vec, td->iloc);
+ }
+
+ copy_v3_v3(td->loc, vec);
+}
+
+static void transdata_elem_to_sphere_fn(void *__restrict iter_data_v,
+ const int iter,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ struct TransDataArgs_ToSphere *data = iter_data_v;
+ TransData *td = &data->tc->data[iter];
+ if (td->flag & TD_SKIP) {
+ return;
+ }
+ transdata_elem_to_sphere(data->t,
+ data->tc,
+ td,
+ data->ratio,
+ &data->to_sphere_info,
+ data->is_local_center,
+ data->is_data_space);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Transform (ToSphere)
* \{ */
static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
{
const bool is_local_center = transdata_check_local_center(t, t->around);
+ const bool is_data_space = (t->options & CTX_POSE_BONE) != 0;
- float vec[3];
- float ratio, radius;
+ float ratio;
int i;
char str[UI_MAX_DRAW_STR];
@@ -128,30 +215,33 @@ static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
BLI_snprintf(str, sizeof(str), TIP_("To Sphere: %.4f %s"), ratio, t->proptext);
}
- const struct ToSphereInfo *data = t->custom.mode.data;
- if (data->prop_size_prev != t->prop_size) {
+ const struct ToSphereInfo *to_sphere_info = t->custom.mode.data;
+ if (to_sphere_info->prop_size_prev != t->prop_size) {
to_sphere_radius_update(t);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- float tratio;
- if (td->flag & TD_SKIP) {
- continue;
+ if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+ TransData *td = tc->data;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
+ }
+ transdata_elem_to_sphere(t, tc, td, ratio, to_sphere_info, is_local_center, is_data_space);
}
-
- const float *center = is_local_center ? td->center : tc->center_local;
-
- sub_v3_v3v3(vec, td->iloc, center);
-
- radius = normalize_v3(vec);
-
- tratio = ratio * td->factor;
-
- mul_v3_fl(vec, radius * (1.0f - tratio) + data->radius * tratio);
-
- add_v3_v3v3(td->loc, center, vec);
+ }
+ else {
+ struct TransDataArgs_ToSphere data = {
+ .t = t,
+ .tc = tc,
+ .ratio = ratio,
+ .to_sphere_info = *to_sphere_info,
+ .is_local_center = is_local_center,
+ .is_data_space = is_data_space,
+ };
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_to_sphere_fn, &settings);
}
}
diff --git a/source/blender/editors/transform/transform_mode_trackball.c b/source/blender/editors/transform/transform_mode_trackball.c
index 5a57a69f986..68177c6becf 100644
--- a/source/blender/editors/transform/transform_mode_trackball.c
+++ b/source/blender/editors/transform/transform_mode_trackball.c
@@ -25,6 +25,7 @@
#include "BLI_math.h"
#include "BLI_string.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_unit.h"
@@ -40,6 +41,51 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
+/** \name Transform (Rotation - Trackball) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be stored copied for faster memory access.
+ */
+struct TransDataArgs_Trackball {
+ const TransInfo *t;
+ const TransDataContainer *tc;
+ const float axis[3];
+ const float angle;
+ float mat_final[3][3];
+};
+
+static void transdata_elem_trackball(const TransInfo *t,
+ const TransDataContainer *tc,
+ TransData *td,
+ const float axis[3],
+ const float angle,
+ const float mat_final[3][3])
+{
+ float mat_buf[3][3];
+ const float(*mat)[3] = mat_final;
+ if (t->flag & T_PROP_EDIT) {
+ axis_angle_normalized_to_mat3(mat_buf, axis, td->factor * angle);
+ mat = mat_buf;
+ }
+ ElementRotation(t, tc, td, mat, t->around);
+}
+
+static void transdata_elem_trackball_fn(void *__restrict iter_data_v,
+ const int iter,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ struct TransDataArgs_Trackball *data = iter_data_v;
+ TransData *td = &data->tc->data[iter];
+ if (td->flag & TD_SKIP) {
+ return;
+ }
+ transdata_elem_trackball(data->t, data->tc, td, data->axis, data->angle, data->mat_final);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Transform (Rotation - Trackball)
* \{ */
@@ -48,7 +94,7 @@ static void applyTrackballValue(TransInfo *t,
const float axis2[3],
const float angles[2])
{
- float mat[3][3];
+ float mat_final[3][3];
float axis[3];
float angle;
int i;
@@ -56,20 +102,30 @@ static void applyTrackballValue(TransInfo *t,
mul_v3_v3fl(axis, axis1, angles[0]);
madd_v3_v3fl(axis, axis2, angles[1]);
angle = normalize_v3(axis);
- axis_angle_normalized_to_mat3(mat, axis, angle);
+ axis_angle_normalized_to_mat3(mat_final, axis, angle);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- if (td->flag & TD_SKIP) {
- continue;
+ if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+ TransData *td = tc->data;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
+ }
+ transdata_elem_trackball(t, tc, td, axis, angle, mat_final);
}
-
- if (t->flag & T_PROP_EDIT) {
- axis_angle_normalized_to_mat3(mat, axis, td->factor * angle);
- }
-
- ElementRotation(t, tc, td, mat, t->around);
+ }
+ else {
+ struct TransDataArgs_Trackball data = {
+ .t = t,
+ .tc = tc,
+ .axis = {UNPACK3(axis)},
+ .angle = angle,
+ };
+ copy_m3_m3(data.mat_final, mat_final);
+
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_trackball_fn, &settings);
}
}
}
@@ -102,24 +158,24 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c, &t->scene->unit);
- ofs += BLI_snprintf(str + ofs,
- sizeof(str) - ofs,
- TIP_("Trackball: %s %s %s"),
- &c[0],
- &c[NUM_STR_REP_LEN],
- t->proptext);
+ ofs += BLI_snprintf_rlen(str + ofs,
+ sizeof(str) - ofs,
+ TIP_("Trackball: %s %s %s"),
+ &c[0],
+ &c[NUM_STR_REP_LEN],
+ t->proptext);
}
else {
- ofs += BLI_snprintf(str + ofs,
- sizeof(str) - ofs,
- TIP_("Trackball: %.2f %.2f %s"),
- RAD2DEGF(phi[0]),
- RAD2DEGF(phi[1]),
- t->proptext);
+ ofs += BLI_snprintf_rlen(str + ofs,
+ sizeof(str) - ofs,
+ TIP_("Trackball: %.2f %.2f %s"),
+ RAD2DEGF(phi[0]),
+ RAD2DEGF(phi[1]),
+ t->proptext);
}
if (t->flag & T_PROP_EDIT_ALL) {
- ofs += BLI_snprintf(
+ ofs += BLI_snprintf_rlen(
str + ofs, sizeof(str) - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
}
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c
index 0bef6364214..2cbf52b6100 100644
--- a/source/blender/editors/transform/transform_mode_translate.c
+++ b/source/blender/editors/transform/transform_mode_translate.c
@@ -29,6 +29,7 @@
#include "BLI_math.h"
#include "BLI_string.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_report.h"
@@ -49,15 +50,164 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
+/** \name Transform (Translate) Custom Data
+ * \{ */
+
+/** Rotation may be enabled when snapping. */
+enum eTranslateRotateMode {
+ /** Don't rotate (default). */
+ TRANSLATE_ROTATE_OFF = 0,
+ /** Perform rotation (currently only snap to normal is used). */
+ TRANSLATE_ROTATE_ON,
+ /** Rotate, resetting back to the disabled state. */
+ TRANSLATE_ROTATE_RESET,
+};
+
+/**
+ * Custom data, stored in #TransInfo.custom.mode.data
+ */
+struct TranslateCustomData {
+ /** Settings used in the last call to #applyTranslation. */
+ struct {
+ enum eTranslateRotateMode rotate_mode;
+ } prev;
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform (Translation) Element
+ * \{ */
+
+/**
+ * \note Small arrays / data-structures should be stored copied for faster memory access.
+ */
+struct TransDataArgs_Translate {
+ const TransInfo *t;
+ const TransDataContainer *tc;
+ const float pivot_local[3];
+ const float vec[3];
+ enum eTranslateRotateMode rotate_mode;
+};
+
+static void transdata_elem_translate(const TransInfo *t,
+ const TransDataContainer *tc,
+ TransData *td,
+ const float pivot_local[3],
+ const float vec[3],
+ enum eTranslateRotateMode rotate_mode)
+{
+ float rotate_offset[3] = {0};
+ bool use_rotate_offset = false;
+
+ /* Handle snapping rotation before doing the translation. */
+ if (rotate_mode != TRANSLATE_ROTATE_OFF) {
+ float mat[3][3];
+
+ if (rotate_mode == TRANSLATE_ROTATE_RESET) {
+ unit_m3(mat);
+ }
+ else {
+ BLI_assert(rotate_mode == TRANSLATE_ROTATE_ON);
+
+ const float *original_normal;
+
+ /* In pose mode, we want to align normals with Y axis of bones. */
+ if (t->options & CTX_POSE_BONE) {
+ original_normal = td->axismtx[1];
+ }
+ else {
+ original_normal = td->axismtx[2];
+ }
+
+ rotation_between_vecs_to_mat3(mat, original_normal, t->tsnap.snapNormal);
+ }
+
+ ElementRotation_ex(t, tc, td, mat, pivot_local);
+
+ if (td->loc) {
+ use_rotate_offset = true;
+ sub_v3_v3v3(rotate_offset, td->loc, td->iloc);
+ }
+ }
+
+ float tvec[3];
+
+ if (t->con.applyVec) {
+ t->con.applyVec(t, tc, td, vec, tvec);
+ }
+ else {
+ copy_v3_v3(tvec, vec);
+ }
+
+ mul_m3_v3(td->smtx, tvec);
+
+ if (use_rotate_offset) {
+ add_v3_v3(tvec, rotate_offset);
+ }
+
+ if (t->options & CTX_GPENCIL_STROKES) {
+ /* Grease pencil multi-frame falloff. */
+ bGPDstroke *gps = (bGPDstroke *)td->extra;
+ if (gps != NULL) {
+ mul_v3_fl(tvec, td->factor * gps->runtime.multi_frame_falloff);
+ }
+ else {
+ mul_v3_fl(tvec, td->factor);
+ }
+ }
+ else {
+ /* Proportional editing falloff. */
+ mul_v3_fl(tvec, td->factor);
+ }
+
+ protectedTransBits(td->protectflag, tvec);
+
+ if (td->loc) {
+ add_v3_v3v3(td->loc, td->iloc, tvec);
+ }
+
+ constraintTransLim(t, td);
+}
+
+static void transdata_elem_translate_fn(void *__restrict iter_data_v,
+ const int iter,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ struct TransDataArgs_Translate *data = iter_data_v;
+ TransData *td = &data->tc->data[iter];
+ if (td->flag & TD_SKIP) {
+ return;
+ }
+ transdata_elem_translate(data->t, data->tc, td, data->pivot_local, data->vec, data->rotate_mode);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Transform (Translation)
* \{ */
+static void translate_dist_to_str(char *r_str,
+ const int len_max,
+ const float val,
+ const UnitSettings *unit)
+{
+ if (unit) {
+ BKE_unit_value_as_string(
+ r_str, len_max, val * unit->scale_length, 4, B_UNIT_LENGTH, unit, false);
+ }
+ else {
+ /* Check range to prevent string buffer overflow. */
+ BLI_snprintf(r_str, len_max, IN_RANGE_INCL(val, -1e10f, 1e10f) ? "%.4f" : "%.4e", val);
+ }
+}
+
static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
{
size_t ofs = 0;
- char tvec[NUM_STR_REP_LEN * 3];
- char distvec[NUM_STR_REP_LEN];
- char autoik[NUM_STR_REP_LEN];
+ char dvec_str[3][NUM_STR_REP_LEN];
+ char dist_str[NUM_STR_REP_LEN];
float dist;
UnitSettings *unit = NULL;
@@ -66,7 +216,7 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_
}
if (hasNumInput(&t->num)) {
- outputNumInput(&(t->num), tvec, &t->scene->unit);
+ outputNumInput(&(t->num), dvec_str[0], &t->scene->unit);
dist = len_v3(t->num.val);
}
else {
@@ -94,117 +244,82 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_
dist = len_v3(dvec);
- if (unit) {
- for (int i = 0; i < 3; i++) {
- BKE_unit_value_as_string(&tvec[NUM_STR_REP_LEN * i],
- NUM_STR_REP_LEN,
- dvec[i] * unit->scale_length,
- 4,
- B_UNIT_LENGTH,
- unit,
- true);
- }
- }
- else {
- BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", dvec[0]);
- BLI_snprintf(&tvec[NUM_STR_REP_LEN], NUM_STR_REP_LEN, "%.4f", dvec[1]);
- BLI_snprintf(&tvec[NUM_STR_REP_LEN * 2], NUM_STR_REP_LEN, "%.4f", dvec[2]);
+ for (int i = 0; i < 3; i++) {
+ translate_dist_to_str(dvec_str[i], sizeof(dvec_str[i]), dvec[i], unit);
}
}
- if (unit) {
- BKE_unit_value_as_string(
- distvec, sizeof(distvec), dist * unit->scale_length, 4, B_UNIT_LENGTH, unit, false);
- }
- else if (dist > 1e10f || dist < -1e10f) {
- /* prevent string buffer overflow */
- BLI_snprintf(distvec, NUM_STR_REP_LEN, "%.4e", dist);
- }
- else {
- BLI_snprintf(distvec, NUM_STR_REP_LEN, "%.4f", dist);
+ translate_dist_to_str(dist_str, sizeof(dist_str), dist, unit);
+
+ if (t->flag & T_PROP_EDIT_ALL) {
+ char prop_str[NUM_STR_REP_LEN];
+ translate_dist_to_str(prop_str, sizeof(prop_str), t->prop_size, unit);
+
+ ofs += BLI_snprintf_rlen(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ "%s %s: %s ",
+ TIP_("Proportional Size"),
+ t->proptext,
+ prop_str);
}
if (t->flag & T_AUTOIK) {
short chainlen = t->settings->autoik_chainlen;
-
if (chainlen) {
- BLI_snprintf(autoik, NUM_STR_REP_LEN, TIP_("AutoIK-Len: %d"), chainlen);
- }
- else {
- autoik[0] = '\0';
+ ofs += BLI_snprintf_rlen(str + ofs, UI_MAX_DRAW_STR - ofs, TIP_("AutoIK-Len: %d"), chainlen);
+ ofs += BLI_strncpy_rlen(str + ofs, " ", UI_MAX_DRAW_STR - ofs);
}
}
- else {
- autoik[0] = '\0';
- }
if (t->con.mode & CON_APPLY) {
switch (t->num.idx_max) {
case 0:
- ofs += BLI_snprintf(str + ofs,
- UI_MAX_DRAW_STR - ofs,
- "D: %s (%s)%s %s %s",
- &tvec[0],
- distvec,
- t->con.text,
- t->proptext,
- autoik);
+ ofs += BLI_snprintf_rlen(
+ str + ofs, UI_MAX_DRAW_STR - ofs, "D: %s (%s)%s", dvec_str[0], dist_str, t->con.text);
break;
case 1:
- ofs += BLI_snprintf(str + ofs,
- UI_MAX_DRAW_STR - ofs,
- "D: %s D: %s (%s)%s %s %s",
- &tvec[0],
- &tvec[NUM_STR_REP_LEN],
- distvec,
- t->con.text,
- t->proptext,
- autoik);
+ ofs += BLI_snprintf_rlen(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ "D: %s D: %s (%s)%s",
+ dvec_str[0],
+ dvec_str[1],
+ dist_str,
+ t->con.text);
break;
case 2:
- ofs += BLI_snprintf(str + ofs,
- UI_MAX_DRAW_STR - ofs,
- "D: %s D: %s D: %s (%s)%s %s %s",
- &tvec[0],
- &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2],
- distvec,
- t->con.text,
- t->proptext,
- autoik);
+ ofs += BLI_snprintf_rlen(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ "D: %s D: %s D: %s (%s)%s",
+ dvec_str[0],
+ dvec_str[1],
+ dvec_str[2],
+ dist_str,
+ t->con.text);
break;
}
}
else {
if (t->flag & T_2D_EDIT) {
- ofs += BLI_snprintf(str + ofs,
- UI_MAX_DRAW_STR - ofs,
- "Dx: %s Dy: %s (%s)%s %s",
- &tvec[0],
- &tvec[NUM_STR_REP_LEN],
- distvec,
- t->con.text,
- t->proptext);
+ ofs += BLI_snprintf_rlen(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ "Dx: %s Dy: %s (%s)%s",
+ dvec_str[0],
+ dvec_str[1],
+ dist_str,
+ t->con.text);
}
else {
- ofs += BLI_snprintf(str + ofs,
- UI_MAX_DRAW_STR - ofs,
- "Dx: %s Dy: %s Dz: %s (%s)%s %s %s",
- &tvec[0],
- &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2],
- distvec,
- t->con.text,
- t->proptext,
- autoik);
+ ofs += BLI_snprintf_rlen(str + ofs,
+ UI_MAX_DRAW_STR - ofs,
+ "Dx: %s Dy: %s Dz: %s (%s)%s",
+ dvec_str[0],
+ dvec_str[1],
+ dvec_str[2],
+ dist_str,
+ t->con.text);
}
}
- if (t->flag & T_PROP_EDIT_ALL) {
- ofs += BLI_snprintf(
- str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
- }
-
if (t->spacetype == SPACE_NODE) {
SpaceNode *snode = (SpaceNode *)t->area->spacedata.first;
@@ -217,12 +332,12 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_
WM_modalkeymap_items_to_string(
t->keymap, TFM_MODAL_INSERTOFS_TOGGLE_DIR, true, str_km, sizeof(str_km));
- ofs += BLI_snprintf(str,
- UI_MAX_DRAW_STR,
- TIP_("Auto-offset set to %s - press %s to toggle direction | %s"),
- str_dir,
- str_km,
- str_old);
+ ofs += BLI_snprintf_rlen(str,
+ UI_MAX_DRAW_STR,
+ TIP_("Auto-offset set to %s - press %s to toggle direction | %s"),
+ str_dir,
+ str_km,
+ str_old);
MEM_freeN((void *)str_old);
}
@@ -243,6 +358,9 @@ static void ApplySnapTranslation(TransInfo *t, float vec[3])
vec[1] = point[1] - t->tsnap.snapTarget[1];
}
}
+ else if (t->spacetype == SPACE_SEQ) {
+ transform_snap_sequencer_apply_translate(t, vec);
+ }
else {
if (t->spacetype == SPACE_VIEW3D) {
if (t->options & CTX_PAINT_CURVE) {
@@ -259,99 +377,65 @@ static void ApplySnapTranslation(TransInfo *t, float vec[3])
static void applyTranslationValue(TransInfo *t, const float vec[3])
{
- const bool apply_snap_align_rotation = usingSnappingNormal(
- t); // && (t->tsnap.status & POINT_INIT);
- float tvec[3];
-
- /* The ideal would be "apply_snap_align_rotation" only when a snap point is found
- * so, maybe inside this function is not the best place to apply this rotation.
- * but you need "handle snapping rotation before doing the translation" (really?) */
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
-
- float pivot[3];
- if (apply_snap_align_rotation) {
- copy_v3_v3(pivot, t->tsnap.snapTarget);
- /* The pivot has to be in local-space (see T49494) */
- if (tc->use_local_mat) {
- mul_m4_v3(tc->imat, pivot);
- }
- }
-
- TransData *td = tc->data;
- for (int i = 0; i < tc->data_len; i++, td++) {
- if (td->flag & TD_SKIP) {
- continue;
- }
-
- float rotate_offset[3] = {0};
- bool use_rotate_offset = false;
-
- /* handle snapping rotation before doing the translation */
- if (apply_snap_align_rotation) {
- float mat[3][3];
+ struct TranslateCustomData *custom_data = t->custom.mode.data;
- if (validSnappingNormal(t)) {
- const float *original_normal;
+ enum eTranslateRotateMode rotate_mode = TRANSLATE_ROTATE_OFF;
- /* In pose mode, we want to align normals with Y axis of bones... */
- if (t->options & CTX_POSE_BONE) {
- original_normal = td->axismtx[1];
- }
- else {
- original_normal = td->axismtx[2];
- }
-
- rotation_between_vecs_to_mat3(mat, original_normal, t->tsnap.snapNormal);
- }
- else {
- unit_m3(mat);
- }
-
- ElementRotation_ex(t, tc, td, mat, pivot);
-
- if (td->loc) {
- use_rotate_offset = true;
- sub_v3_v3v3(rotate_offset, td->loc, td->iloc);
- }
- }
+ if (activeSnap(t) && usingSnappingNormal(t) && validSnappingNormal(t)) {
+ rotate_mode = TRANSLATE_ROTATE_ON;
+ }
- if (t->con.applyVec) {
- t->con.applyVec(t, tc, td, vec, tvec);
- }
- else {
- copy_v3_v3(tvec, vec);
+ /* Check to see if this needs to be re-enabled. */
+ if (rotate_mode == TRANSLATE_ROTATE_OFF) {
+ if (t->flag & T_POINTS) {
+ /* When transforming points, only use rotation when snapping is enabled
+ * since re-applying translation without rotation removes rotation. */
+ }
+ else {
+ /* When transforming data that it's self stores rotation (objects, bones etc),
+ * apply rotation if it was applied (with the snap normal) previously.
+ * This is needed because failing to rotate will leave the rotation at the last
+ * value used before snapping was disabled. */
+ if (custom_data->prev.rotate_mode == TRANSLATE_ROTATE_ON) {
+ rotate_mode = TRANSLATE_ROTATE_RESET;
}
+ }
+ }
- mul_m3_v3(td->smtx, tvec);
-
- if (use_rotate_offset) {
- add_v3_v3(tvec, rotate_offset);
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ float pivot_local[3];
+ if (rotate_mode != TRANSLATE_ROTATE_OFF) {
+ copy_v3_v3(pivot_local, t->tsnap.snapTarget);
+ /* The pivot has to be in local-space (see T49494) */
+ if (tc->use_local_mat) {
+ mul_m4_v3(tc->imat, pivot_local);
}
+ }
- if (t->options & CTX_GPENCIL_STROKES) {
- /* grease pencil multiframe falloff */
- bGPDstroke *gps = (bGPDstroke *)td->extra;
- if (gps != NULL) {
- mul_v3_fl(tvec, td->factor * gps->runtime.multi_frame_falloff);
- }
- else {
- mul_v3_fl(tvec, td->factor);
+ if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
+ TransData *td = tc->data;
+ for (int i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
}
+ transdata_elem_translate(t, tc, td, pivot_local, vec, rotate_mode);
}
- else {
- /* proportional editing falloff */
- mul_v3_fl(tvec, td->factor);
- }
-
- protectedTransBits(td->protectflag, tvec);
-
- if (td->loc) {
- add_v3_v3v3(td->loc, td->iloc, tvec);
- }
-
- constraintTransLim(t, td);
+ }
+ else {
+ struct TransDataArgs_Translate data = {
+ .t = t,
+ .tc = tc,
+ .pivot_local = {UNPACK3(pivot_local)},
+ .vec = {UNPACK3(vec)},
+ .rotate_mode = rotate_mode,
+ };
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_translate_fn, &settings);
}
}
+
+ custom_data->prev.rotate_mode = rotate_mode;
}
static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
@@ -383,6 +467,11 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
}
else {
copy_v3_v3(global_dir, t->values);
+ if (!is_zero_v3(t->values_modal_offset)) {
+ float values_ofs[3];
+ mul_v3_m3v3(values_ofs, t->spacemtx, t->values_modal_offset);
+ add_v3_v3(global_dir, values_ofs);
+ }
t->tsnap.snapElem = 0;
applySnapping(t, global_dir);
@@ -471,6 +560,12 @@ void initTranslation(TransInfo *t)
t->num.unit_type[2] = B_UNIT_NONE;
}
- transform_mode_default_modal_orientation_set(t, V3D_ORIENT_GLOBAL);
+ transform_mode_default_modal_orientation_set(
+ t, (t->options & CTX_CAMERA) ? V3D_ORIENT_VIEW : V3D_ORIENT_GLOBAL);
+
+ struct TranslateCustomData *custom_data = MEM_callocN(sizeof(*custom_data), __func__);
+ custom_data->prev.rotate_mode = TRANSLATE_ROTATE_OFF;
+ t->custom.mode.data = custom_data;
+ t->custom.mode.use_free = true;
}
/** \} */
diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c
index 1e5d027e253..def5f911c6f 100644
--- a/source/blender/editors/transform/transform_mode_vert_slide.c
+++ b/source/blender/editors/transform/transform_mode_vert_slide.c
@@ -158,7 +158,7 @@ static void calcVertSlideMouseActiveEdges(struct TransInfo *t, const int mval[2]
TransDataVertSlideVert *sv;
int i;
- /* note: we could save a matrix-multiply for each vertex
+ /* NOTE: we could save a matrix-multiply for each vertex
* by finding the closest edge in local-space.
* However this skews the outcome with non-uniform-scale. */
@@ -606,15 +606,15 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))
ofs += BLI_strncpy_rlen(str + ofs, &c[0], sizeof(str) - ofs);
}
else {
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, "%.4f ", final);
+ ofs += BLI_snprintf_rlen(str + ofs, sizeof(str) - ofs, "%.4f ", final);
}
- ofs += BLI_snprintf(
+ ofs += BLI_snprintf_rlen(
str + ofs, sizeof(str) - ofs, TIP_("(E)ven: %s, "), WM_bool_as_string(use_even));
if (use_even) {
- ofs += BLI_snprintf(
+ ofs += BLI_snprintf_rlen(
str + ofs, sizeof(str) - ofs, TIP_("(F)lipped: %s, "), WM_bool_as_string(flipped));
}
- ofs += BLI_snprintf(
+ ofs += BLI_snprintf_rlen(
str + ofs, sizeof(str) - ofs, TIP_("Alt or (C)lamp: %s"), WM_bool_as_string(is_clamp));
/* done with header string */
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 9b5f15a2574..2c424d8ace3 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -519,10 +519,11 @@ static int transform_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* add temp handler */
WM_event_add_modal_handler(C, op);
- op->flag |= OP_IS_MODAL_GRAB_CURSOR; /* XXX maybe we want this with the gizmo only? */
-
/* Use when modal input has some transformation to begin with. */
TransInfo *t = op->customdata;
+ if ((t->flag & T_NO_CURSOR_WRAP) == 0) {
+ op->flag |= OP_IS_MODAL_GRAB_CURSOR; /* XXX maybe we want this with the gizmo only? */
+ }
if (UNLIKELY(!is_zero_v4(t->values_modal_offset))) {
transformApply(C, t);
}
@@ -538,7 +539,7 @@ static bool transform_poll_property(const bContext *UNUSED(C),
/* Orientation/Constraints. */
{
- /* Hide orientation axis if no constraints are set, since it wont be used. */
+ /* Hide orientation axis if no constraints are set, since it won't be used. */
PropertyRNA *prop_con = RNA_struct_find_property(op->ptr, "orient_type");
if (!ELEM(prop_con, NULL, prop)) {
if (STRPREFIX(prop_id, "constraint")) {
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index b3ed294845d..155250261de 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -445,7 +445,7 @@ int BIF_countTransformOrientation(const bContext *C)
return BLI_listbase_count(transform_orientations);
}
-void applyTransformOrientation(const TransformOrientation *ts, float r_mat[3][3], char *r_name)
+void applyTransformOrientation(const TransformOrientation *ts, float r_mat[3][3], char r_name[64])
{
if (r_name) {
BLI_strncpy(r_name, ts->name, MAX_NAME);
@@ -455,7 +455,7 @@ void applyTransformOrientation(const TransformOrientation *ts, float r_mat[3][3]
/* Updates all `BONE_TRANSFORM` flags.
* Returns total number of bones with `BONE_TRANSFORM`.
- * Note: `transform_convert_pose_transflags_update` has a similar logic. */
+ * NOTE: `transform_convert_pose_transflags_update` has a similar logic. */
static int armature_bone_transflags_update_recursive(bArmature *arm,
ListBase *lb,
const bool do_it)
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 193954fffb6..2619fdf3403 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -41,9 +41,6 @@
#include "RNA_access.h"
-#include "SEQ_sequencer.h"
-#include "SEQ_time.h"
-
#include "WM_types.h"
#include "ED_gizmo_library.h"
@@ -55,12 +52,18 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "SEQ_iterator.h"
+#include "SEQ_sequencer.h"
+#include "SEQ_time.h"
+
#include "MEM_guardedalloc.h"
#include "transform.h"
#include "transform_convert.h"
#include "transform_snap.h"
+static bool doForceIncrementSnap(const TransInfo *t);
+
/* this should be passed as an arg for use in snap functions */
#undef BASACT
@@ -73,7 +76,10 @@
static void setSnappingCallback(TransInfo *t);
/* static void CalcSnapGrid(TransInfo *t, float *vec); */
-static void CalcSnapGeometry(TransInfo *t, float *vec);
+static void snap_calc_view3d_fn(TransInfo *t, float *vec);
+static void snap_calc_uv_fn(TransInfo *t, float *vec);
+static void snap_calc_node_fn(TransInfo *t, float *vec);
+static void snap_calc_sequencer_fn(TransInfo *t, float *vec);
static void TargetSnapMedian(TransInfo *t);
static void TargetSnapCenter(TransInfo *t);
@@ -133,6 +139,23 @@ bool activeSnap(const TransInfo *t)
((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP_INVERT);
}
+bool activeSnap_with_project(const TransInfo *t)
+{
+ if (!t->tsnap.project) {
+ return false;
+ }
+
+ if (!activeSnap(t) || (t->flag & T_NO_PROJECT)) {
+ return false;
+ }
+
+ if (doForceIncrementSnap(t)) {
+ return false;
+ }
+
+ return true;
+}
+
bool transformModeUseSnap(const TransInfo *t)
{
ToolSettings *ts = t->settings;
@@ -145,10 +168,7 @@ bool transformModeUseSnap(const TransInfo *t)
if (t->mode == TFM_RESIZE) {
return (ts->snap_transform_mode_flag & SCE_SNAP_TRANSFORM_MODE_SCALE) != 0;
}
- if (t->mode == TFM_VERT_SLIDE) {
- return true;
- }
- if (t->mode == TFM_EDGE_SLIDE) {
+ if (ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE, TFM_SEQ_SLIDE)) {
return true;
}
@@ -276,6 +296,26 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
GPU_blend(GPU_BLEND_NONE);
}
}
+ else if (t->spacetype == SPACE_SEQ) {
+ if (validSnap(t)) {
+ const ARegion *region = CTX_wm_region(C);
+ GPU_blend(GPU_BLEND_ALPHA);
+ uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ UI_GetThemeColor3ubv(TH_SEQ_ACTIVE, col);
+ col[3] = 128;
+ immUniformColor4ubv(col);
+ float pixelx = BLI_rctf_size_x(&region->v2d.cur) / BLI_rcti_size_x(&region->v2d.mask);
+ immRectf(pos,
+ t->tsnap.snapPoint[0] - pixelx,
+ region->v2d.cur.ymax,
+ t->tsnap.snapPoint[0] + pixelx,
+ region->v2d.cur.ymin);
+ immUnbindProgram();
+ GPU_blend(GPU_BLEND_NONE);
+ }
+ }
}
eRedrawFlag handleSnapping(TransInfo *t, const wmEvent *event)
@@ -299,15 +339,7 @@ eRedrawFlag handleSnapping(TransInfo *t, const wmEvent *event)
void applyProject(TransInfo *t)
{
- if (!t->tsnap.project) {
- return;
- }
-
- if (!activeSnap(t) || (t->flag & T_NO_PROJECT)) {
- return;
- }
-
- if (doForceIncrementSnap(t)) {
+ if (!activeSnap_with_project(t)) {
return;
}
@@ -378,7 +410,7 @@ void applyProject(TransInfo *t)
transform_data_ext_rotate(td, mat, true);
- /* TODO support constraints for rotation too? see ElementRotation */
+ /* TODO: support constraints for rotation too? see #ElementRotation. */
}
}
}
@@ -465,10 +497,13 @@ void applySnapping(TransInfo *t, float *vec)
/* TODO: add exception for object mode, no need to slow it down then. */
if (current - t->tsnap.last >= 0.01) {
t->tsnap.calcSnap(t, vec);
- t->tsnap.targetSnap(t);
-
- t->tsnap.last = current;
+ if (t->tsnap.targetSnap) {
+ t->tsnap.targetSnap(t);
+ }
}
+
+ t->tsnap.last = current;
+
if (validSnap(t)) {
t->tsnap.applySnap(t, vec);
}
@@ -556,6 +591,9 @@ static void initSnappingMode(TransInfo *t)
t->tsnap.mode = ts->snap_uv_mode;
}
+ else if (t->spacetype == SPACE_SEQ) {
+ t->tsnap.mode = SEQ_tool_settings_snap_mode_get(t->scene);
+ }
else {
/* force project off when not supported */
if ((ts->snap_mode & SCE_SNAP_MODE_FACE) == 0) {
@@ -615,16 +653,12 @@ static void initSnappingMode(TransInfo *t)
t->tsnap.mode = SCE_SNAP_MODE_INCREMENT;
}
}
- else if (t->spacetype == SPACE_NODE) {
+ else if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) {
setSnappingCallback(t);
t->tsnap.modeSelect = SNAP_NOT_SELECTED;
}
- else if (t->spacetype == SPACE_SEQ) {
- /* We do our own snapping currently, so nothing here */
- t->tsnap.mode = SCE_SNAP_MODE_GRID; /* Dummy, should we rather add a NOP mode? */
- }
else {
- /* Always increment outside of 3D view */
+ /* Fallback. */
t->tsnap.mode = SCE_SNAP_MODE_INCREMENT;
}
@@ -645,6 +679,11 @@ static void initSnappingMode(TransInfo *t)
}
}
}
+ else if (t->spacetype == SPACE_SEQ) {
+ if (t->tsnap.seq_context == NULL) {
+ t->tsnap.seq_context = transform_snap_sequencer_data_alloc(t);
+ }
+ }
}
void initSnapping(TransInfo *t, wmOperator *op)
@@ -697,6 +736,9 @@ void initSnapping(TransInfo *t, wmOperator *op)
t->tsnap.snap_self = !((t->settings->snap_flag & SCE_SNAP_NO_SELF) != 0);
t->tsnap.peel = ((t->settings->snap_flag & SCE_SNAP_PROJECT) != 0);
}
+ else if ((t->spacetype == SPACE_SEQ) && (ts->snap_flag & SCE_SNAP_SEQ)) {
+ t->modifiers |= MOD_SNAP;
+ }
}
t->tsnap.target = snap_target;
@@ -706,7 +748,11 @@ void initSnapping(TransInfo *t, wmOperator *op)
void freeSnapping(TransInfo *t)
{
- if (t->tsnap.object_context) {
+ if ((t->spacetype == SPACE_SEQ) && t->tsnap.seq_context) {
+ transform_snap_sequencer_data_free(t->tsnap.seq_context);
+ t->tsnap.seq_context = NULL;
+ }
+ else if (t->tsnap.object_context) {
ED_transform_snap_object_context_destroy(t->tsnap.object_context);
t->tsnap.object_context = NULL;
}
@@ -714,7 +760,20 @@ void freeSnapping(TransInfo *t)
static void setSnappingCallback(TransInfo *t)
{
- t->tsnap.calcSnap = CalcSnapGeometry;
+ if (t->spacetype == SPACE_VIEW3D) {
+ t->tsnap.calcSnap = snap_calc_view3d_fn;
+ }
+ else if (t->spacetype == SPACE_IMAGE && t->obedit_type == OB_MESH) {
+ t->tsnap.calcSnap = snap_calc_uv_fn;
+ }
+ else if (t->spacetype == SPACE_NODE) {
+ t->tsnap.calcSnap = snap_calc_node_fn;
+ }
+ else if (t->spacetype == SPACE_SEQ) {
+ t->tsnap.calcSnap = snap_calc_sequencer_fn;
+ /* The target is calculated along with the snap point. */
+ return;
+ }
switch (t->tsnap.target) {
case SCE_SNAP_TARGET_CLOSEST:
@@ -835,89 +894,105 @@ void getSnapPoint(const TransInfo *t, float vec[3])
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Calc Snap (Generic)
+/** \name Calc Snap
* \{ */
-static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
+static void snap_calc_view3d_fn(TransInfo *t, float *UNUSED(vec))
{
- if (t->spacetype == SPACE_VIEW3D) {
- float loc[3];
- float no[3];
- float mval[2];
- bool found = false;
- short snap_elem = 0;
- float dist_px = SNAP_MIN_DISTANCE; /* Use a user defined value here. */
+ BLI_assert(t->spacetype == SPACE_VIEW3D);
+ float loc[3];
+ float no[3];
+ float mval[2];
+ bool found = false;
+ short snap_elem = 0;
+ float dist_px = SNAP_MIN_DISTANCE; /* Use a user defined value here. */
+
+ mval[0] = t->mval[0];
+ mval[1] = t->mval[1];
+
+ if (t->tsnap.mode & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
+ SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
+ zero_v3(no); /* objects won't set this */
+ snap_elem = snapObjectsTransform(t, mval, &dist_px, loc, no);
+ found = snap_elem != 0;
+ }
+ if ((found == false) && (t->tsnap.mode & SCE_SNAP_MODE_VOLUME)) {
+ found = peelObjectsTransform(
+ t, mval, (t->settings->snap_flag & SCE_SNAP_PEEL_OBJECT) != 0, loc, no, NULL);
+
+ if (found) {
+ snap_elem = SCE_SNAP_MODE_VOLUME;
+ }
+ }
- mval[0] = t->mval[0];
- mval[1] = t->mval[1];
+ if (found == true) {
+ copy_v3_v3(t->tsnap.snapPoint, loc);
+ copy_v3_v3(t->tsnap.snapNormal, no);
- if (t->tsnap.mode & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
- SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
- zero_v3(no); /* objects won't set this */
- snap_elem = snapObjectsTransform(t, mval, &dist_px, loc, no);
- found = snap_elem != 0;
- }
- if ((found == false) && (t->tsnap.mode & SCE_SNAP_MODE_VOLUME)) {
- found = peelObjectsTransform(
- t, mval, (t->settings->snap_flag & SCE_SNAP_PEEL_OBJECT) != 0, loc, no, NULL);
+ t->tsnap.status |= POINT_INIT;
+ }
+ else {
+ t->tsnap.status &= ~POINT_INIT;
+ }
- if (found) {
- snap_elem = SCE_SNAP_MODE_VOLUME;
- }
- }
+ t->tsnap.snapElem = (char)snap_elem;
+}
+
+static void snap_calc_uv_fn(TransInfo *t, float *UNUSED(vec))
+{
+ BLI_assert(t->spacetype == SPACE_IMAGE && t->obedit_type == OB_MESH);
+ if (t->tsnap.mode & SCE_SNAP_MODE_VERTEX) {
+ float co[2];
+
+ UI_view2d_region_to_view(&t->region->v2d, t->mval[0], t->mval[1], &co[0], &co[1]);
- if (found == true) {
- copy_v3_v3(t->tsnap.snapPoint, loc);
- copy_v3_v3(t->tsnap.snapNormal, no);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
+ t->view_layer, NULL, &objects_len);
+
+ float dist_sq = FLT_MAX;
+ if (ED_uvedit_nearest_uv_multi(
+ t->scene, objects, objects_len, co, &dist_sq, t->tsnap.snapPoint)) {
+ t->tsnap.snapPoint[0] *= t->aspect[0];
+ t->tsnap.snapPoint[1] *= t->aspect[1];
t->tsnap.status |= POINT_INIT;
}
else {
t->tsnap.status &= ~POINT_INIT;
}
-
- t->tsnap.snapElem = (char)snap_elem;
+ MEM_freeN(objects);
}
- else if (t->spacetype == SPACE_IMAGE && t->obedit_type == OB_MESH) {
- if (t->tsnap.mode & SCE_SNAP_MODE_VERTEX) {
- float co[2];
-
- UI_view2d_region_to_view(&t->region->v2d, t->mval[0], t->mval[1], &co[0], &co[1]);
+}
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
- t->view_layer, NULL, &objects_len);
+static void snap_calc_node_fn(TransInfo *t, float *UNUSED(vec))
+{
+ BLI_assert(t->spacetype == SPACE_NODE);
+ if (t->tsnap.mode & (SCE_SNAP_MODE_NODE_X | SCE_SNAP_MODE_NODE_Y)) {
+ float loc[2];
+ float dist_px = SNAP_MIN_DISTANCE; /* Use a user defined value here. */
+ char node_border;
- float dist_sq = FLT_MAX;
- if (ED_uvedit_nearest_uv_multi(
- t->scene, objects, objects_len, co, &dist_sq, t->tsnap.snapPoint)) {
- t->tsnap.snapPoint[0] *= t->aspect[0];
- t->tsnap.snapPoint[1] *= t->aspect[1];
+ if (snapNodesTransform(t, t->mval, loc, &dist_px, &node_border)) {
+ copy_v2_v2(t->tsnap.snapPoint, loc);
+ t->tsnap.snapNodeBorder = node_border;
- t->tsnap.status |= POINT_INIT;
- }
- else {
- t->tsnap.status &= ~POINT_INIT;
- }
- MEM_freeN(objects);
+ t->tsnap.status |= POINT_INIT;
+ }
+ else {
+ t->tsnap.status &= ~POINT_INIT;
}
}
- else if (t->spacetype == SPACE_NODE) {
- if (t->tsnap.mode & (SCE_SNAP_MODE_NODE_X | SCE_SNAP_MODE_NODE_Y)) {
- float loc[2];
- float dist_px = SNAP_MIN_DISTANCE; /* Use a user defined value here. */
- char node_border;
-
- if (snapNodesTransform(t, t->mval, loc, &dist_px, &node_border)) {
- copy_v2_v2(t->tsnap.snapPoint, loc);
- t->tsnap.snapNodeBorder = node_border;
+}
- t->tsnap.status |= POINT_INIT;
- }
- else {
- t->tsnap.status &= ~POINT_INIT;
- }
- }
+static void snap_calc_sequencer_fn(TransInfo *t, float *UNUSED(vec))
+{
+ BLI_assert(t->spacetype == SPACE_SEQ);
+ if (transform_snap_sequencer_calc(t)) {
+ t->tsnap.status |= (POINT_INIT | TARGET_INIT);
+ }
+ else {
+ t->tsnap.status &= ~(POINT_INIT | TARGET_INIT);
}
}
@@ -1072,7 +1147,7 @@ static void TargetSnapClosest(TransInfo *t)
if (t->options & CTX_OBJECT) {
int i;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
+ TransData *td;
for (td = tc->data, i = 0; i < tc->data_len && td->flag & TD_SELECTED; i++, td++) {
const BoundBox *bb = NULL;
@@ -1430,28 +1505,6 @@ void snapFrameTransform(TransInfo *t,
*r_val = (float)val;
}
-/*================================================================*/
-
-void snapSequenceBounds(TransInfo *t, const int mval[2])
-{
- /* Reuse increment, strictly speaking could be another snap mode, but leave as is. */
- if (!(t->modifiers & MOD_SNAP_INVERT)) {
- return;
- }
-
- /* Convert to frame range. */
- float xmouse, ymouse;
- UI_view2d_region_to_view(&t->region->v2d, mval[0], mval[1], &xmouse, &ymouse);
- const int frame_curr = round_fl_to_int(xmouse);
-
- /* Now find the closest sequence. */
- const int frame_near = SEQ_time_find_next_prev_edit(
- t->scene, frame_curr, SEQ_SIDE_BOTH, true, false, true);
-
- const int frame_snap = transform_convert_sequencer_get_snap_bound(t);
- t->values[0] = frame_near - frame_snap;
-}
-
static void snap_grid_apply(
TransInfo *t, const int max_index, const float grid_dist, const float loc[3], float r_out[3])
{
@@ -1506,7 +1559,7 @@ bool transform_snap_grid(TransInfo *t, float *val)
return true;
}
-static void snap_increment_apply_ex(TransInfo *UNUSED(t),
+static void snap_increment_apply_ex(const TransInfo *UNUSED(t),
const int max_index,
const float increment_val,
const float aspect[3],
@@ -1520,8 +1573,8 @@ static void snap_increment_apply_ex(TransInfo *UNUSED(t),
}
}
-static void snap_increment_apply(TransInfo *t,
- int max_index,
+static void snap_increment_apply(const TransInfo *t,
+ const int max_index,
const float increment_dist,
float *r_val)
{
@@ -1553,7 +1606,7 @@ static void snap_increment_apply(TransInfo *t,
snap_increment_apply_ex(t, max_index, increment_dist, asp, r_val, r_val);
}
-bool transform_snap_increment_ex(TransInfo *t, bool use_local_space, float *r_val)
+bool transform_snap_increment_ex(const TransInfo *t, bool use_local_space, float *r_val)
{
if (!activeSnap(t)) {
return false;
@@ -1584,7 +1637,7 @@ bool transform_snap_increment_ex(TransInfo *t, bool use_local_space, float *r_va
return true;
}
-bool transform_snap_increment(TransInfo *t, float *r_val)
+bool transform_snap_increment(const TransInfo *t, float *r_val)
{
return transform_snap_increment_ex(t, false, r_val);
}
diff --git a/source/blender/editors/transform/transform_snap.h b/source/blender/editors/transform/transform_snap.h
index c557368ed17..6dfaeab93e6 100644
--- a/source/blender/editors/transform/transform_snap.h
+++ b/source/blender/editors/transform/transform_snap.h
@@ -54,13 +54,13 @@ void snapFrameTransform(struct TransInfo *t,
bool transformModeUseSnap(const TransInfo *t);
-bool transform_snap_increment_ex(TransInfo *t, bool use_local_space, float *r_val);
-bool transform_snap_increment(TransInfo *t, float *val);
+bool transform_snap_increment_ex(const TransInfo *t, bool use_local_space, float *r_val);
+bool transform_snap_increment(const TransInfo *t, float *val);
bool transform_snap_grid(TransInfo *t, float *val);
-void snapSequenceBounds(TransInfo *t, const int mval[2]);
-
bool activeSnap(const TransInfo *t);
+bool activeSnap_with_project(const TransInfo *t);
+
bool validSnap(const TransInfo *t);
void initSnapping(struct TransInfo *t, struct wmOperator *op);
@@ -80,3 +80,9 @@ eRedrawFlag updateSelectedSnapPoint(TransInfo *t);
void removeSnapPoint(TransInfo *t);
float transform_snap_distance_len_squared_fn(TransInfo *t, const float p1[3], const float p2[3]);
+
+/* transform_snap_sequencer.c */
+struct TransSeqSnapData *transform_snap_sequencer_data_alloc(const TransInfo *t);
+void transform_snap_sequencer_data_free(struct TransSeqSnapData *data);
+bool transform_snap_sequencer_calc(struct TransInfo *t);
+void transform_snap_sequencer_apply_translate(TransInfo *t, float *vec);
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index 512f912a532..2d98d756dba 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -255,7 +255,7 @@ static SnapObjectData *snap_object_data_lookup(SnapObjectContext *sctx, Object *
static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx,
Object *ob_eval,
- Mesh *me_eval,
+ const Mesh *me_eval,
bool use_hide)
{
SnapObjectData *sod;
@@ -535,7 +535,7 @@ static void iter_snap_objects(SnapObjectContext *sctx,
* \{ */
/* Store all ray-hits
- * Support for storing all depths, not just the first (raycast 'all') */
+ * Support for storing all depths, not just the first (ray-cast 'all'). */
struct RayCastAll_Data {
void *bvhdata;
@@ -626,7 +626,7 @@ static bool raycast_tri_backface_culling_test(
return dot_v3v3(no, dir) < 0.0f;
}
-/* Callback to raycast with backface culling (Mesh). */
+/* Callback to ray-cast with back-face culling (#Mesh). */
static void mesh_looptri_raycast_backface_culling_cb(void *userdata,
int index,
const BVHTreeRay *ray,
@@ -653,7 +653,7 @@ static void mesh_looptri_raycast_backface_culling_cb(void *userdata,
}
}
-/* Callback to raycast with backface culling (EditMesh). */
+/* Callback to ray-cast with back-face culling (#EditMesh). */
static void editmesh_looptri_raycast_backface_culling_cb(void *userdata,
int index,
const BVHTreeRay *ray,
@@ -687,7 +687,7 @@ static bool raycastMesh(SnapObjectContext *sctx,
const float ray_start[3],
const float ray_dir[3],
Object *ob_eval,
- Mesh *me_eval,
+ const Mesh *me_eval,
const float obmat[4][4],
const uint ob_index,
bool use_hide,
@@ -1088,7 +1088,7 @@ static void raycast_obj_fn(SnapObjectContext *sctx,
case OB_SURF:
case OB_FONT: {
if (!is_object_active) {
- Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
+ const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
if (mesh_eval) {
retval = raycastMesh(sctx,
dt->ray_start,
@@ -1142,7 +1142,7 @@ static void raycast_obj_fn(SnapObjectContext *sctx,
* \param r_loc: Hit location.
* \param r_no: Hit normal (optional).
* \param r_index: Hit index or -1 when no valid index is found.
- * (currently only set to the polygon index when when using ``snap_to == SCE_SNAP_MODE_FACE``).
+ * (currently only set to the polygon index when using ``snap_to == SCE_SNAP_MODE_FACE``).
* \param r_ob: Hit object.
* \param r_obmat: Object matrix (may not be #Object.obmat with dupli-instances).
* \param r_hit_list: List of #SnapObjectHitDepth (caller must free).
@@ -2777,7 +2777,7 @@ static void snap_obj_fn(SnapObjectContext *sctx,
* \param r_loc: Hit location.
* \param r_no: Hit normal (optional).
* \param r_index: Hit index or -1 when no valid index is found.
- * (currently only set to the polygon index when when using ``snap_to == SCE_SNAP_MODE_FACE``).
+ * (currently only set to the polygon index when using ``snap_to == SCE_SNAP_MODE_FACE``).
* \param r_ob: Hit object.
* \param r_obmat: Object matrix (may not be #Object.obmat with dupli-instances).
*/
diff --git a/source/blender/editors/transform/transform_snap_sequencer.c b/source/blender/editors/transform/transform_snap_sequencer.c
new file mode 100644
index 00000000000..d0b730383d5
--- /dev/null
+++ b/source/blender/editors/transform/transform_snap_sequencer.c
@@ -0,0 +1,275 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edtransform
+ */
+
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+
+#include "BKE_context.h"
+
+#include "ED_screen.h"
+
+#include "UI_view2d.h"
+
+#include "SEQ_iterator.h"
+#include "SEQ_sequencer.h"
+
+#include "transform.h"
+#include "transform_snap.h"
+
+typedef struct TransSeqSnapData {
+ int *source_snap_points;
+ int *target_snap_points;
+ int source_snap_point_count;
+ int target_snap_point_count;
+ int final_snap_frame;
+} TransSeqSnapData;
+
+/* -------------------------------------------------------------------- */
+/** \name Snap sources
+ * \{ */
+
+static int seq_get_snap_source_points_len(SeqCollection *snap_sources)
+{
+ return SEQ_collection_len(snap_sources) * 2;
+}
+
+static void seq_snap_source_points_alloc(TransSeqSnapData *snap_data, SeqCollection *snap_sources)
+{
+ const size_t point_count = seq_get_snap_source_points_len(snap_sources);
+ snap_data->source_snap_points = MEM_callocN(sizeof(int) * point_count, __func__);
+ memset(snap_data->source_snap_points, 0, sizeof(int));
+ snap_data->source_snap_point_count = point_count;
+}
+
+static int cmp_fn(const void *a, const void *b)
+{
+ return (*(int *)a - *(int *)b);
+}
+
+static void seq_snap_source_points_build(const TransInfo *UNUSED(t),
+ TransSeqSnapData *snap_data,
+ SeqCollection *snap_sources)
+{
+ int i = 0;
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, snap_sources) {
+ int left = 0, right = 0;
+ if (seq->flag & SEQ_LEFTSEL) {
+ left = right = seq->startdisp;
+ }
+ else if (seq->flag & SEQ_RIGHTSEL) {
+ left = right = seq->enddisp;
+ }
+ else {
+ left = seq->startdisp;
+ right = seq->enddisp;
+ }
+
+ snap_data->source_snap_points[i] = left;
+ snap_data->source_snap_points[i + 1] = right;
+ i += 2;
+ BLI_assert(i <= snap_data->source_snap_point_count);
+ }
+
+ qsort(snap_data->source_snap_points, snap_data->source_snap_point_count, sizeof(int), cmp_fn);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Snap targets
+ * \{ */
+
+static SeqCollection *query_snap_targets(const TransInfo *t)
+{
+ const ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene, false));
+ const short snap_flag = SEQ_tool_settings_snap_flag_get(t->scene);
+ SeqCollection *collection = SEQ_collection_create(__func__);
+ LISTBASE_FOREACH (Sequence *, seq, seqbase) {
+ if ((seq->flag & SELECT)) {
+ continue; /* Selected are being transformed. */
+ }
+ if ((seq->flag & SEQ_MUTE) && (snap_flag & SEQ_SNAP_IGNORE_MUTED)) {
+ continue;
+ }
+ if (seq->type == SEQ_TYPE_SOUND_RAM && (snap_flag & SEQ_SNAP_IGNORE_SOUND)) {
+ continue;
+ }
+ SEQ_collection_append_strip(seq, collection);
+ }
+ return collection;
+}
+
+static int seq_get_snap_target_points_count(const TransInfo *t,
+ TransSeqSnapData *UNUSED(snap_data),
+ SeqCollection *snap_targets)
+{
+ const short snap_mode = t->tsnap.mode;
+
+ int count = 2; /* Strip start and end are always used. */
+
+ if (snap_mode & SEQ_SNAP_TO_STRIP_HOLD) {
+ count += 2;
+ }
+
+ count *= SEQ_collection_len(snap_targets);
+
+ if (snap_mode & SEQ_SNAP_TO_CURRENT_FRAME) {
+ count++;
+ }
+
+ return count;
+}
+
+static void seq_snap_target_points_alloc(const TransInfo *t,
+ TransSeqSnapData *snap_data,
+ SeqCollection *snap_targets)
+{
+ const size_t point_count = seq_get_snap_target_points_count(t, snap_data, snap_targets);
+ snap_data->target_snap_points = MEM_callocN(sizeof(int) * point_count, __func__);
+ memset(snap_data->target_snap_points, 0, sizeof(int));
+ snap_data->target_snap_point_count = point_count;
+}
+
+static void seq_snap_target_points_build(const TransInfo *t,
+ TransSeqSnapData *snap_data,
+ SeqCollection *snap_targets)
+{
+ const Scene *scene = t->scene;
+ const short snap_mode = t->tsnap.mode;
+
+ int i = 0;
+
+ if (snap_mode & SEQ_SNAP_TO_CURRENT_FRAME) {
+ snap_data->target_snap_points[i] = CFRA;
+ i++;
+ }
+
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, snap_targets) {
+ snap_data->target_snap_points[i] = seq->startdisp;
+ snap_data->target_snap_points[i + 1] = seq->enddisp;
+ i += 2;
+
+ if (snap_mode & SEQ_SNAP_TO_STRIP_HOLD) {
+ int content_start = min_ii(seq->enddisp, seq->start);
+ int content_end = max_ii(seq->startdisp, seq->start + seq->len);
+ if (seq->anim_startofs == 0) {
+ content_start = seq->startdisp;
+ }
+ if (seq->anim_endofs == 0) {
+ content_end = seq->enddisp;
+ }
+ snap_data->target_snap_points[i] = content_start;
+ snap_data->target_snap_points[i + 1] = content_end;
+ i += 2;
+ }
+ }
+ BLI_assert(i <= snap_data->target_snap_point_count);
+ qsort(snap_data->target_snap_points, snap_data->target_snap_point_count, sizeof(int), cmp_fn);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Snap utilities
+ * \{ */
+
+static int seq_snap_threshold_get_frame_distance(const TransInfo *t)
+{
+ const int snap_distance = SEQ_tool_settings_snap_distance_get(t->scene);
+ const struct View2D *v2d = &t->region->v2d;
+ return round_fl_to_int(UI_view2d_region_to_view_x(v2d, snap_distance) -
+ UI_view2d_region_to_view_x(v2d, 0));
+}
+
+/** \} */
+
+TransSeqSnapData *transform_snap_sequencer_data_alloc(const TransInfo *t)
+{
+ TransSeqSnapData *snap_data = MEM_callocN(sizeof(TransSeqSnapData), __func__);
+ ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene, false));
+
+ /* Build arrays of snap points. */
+ SeqCollection *snap_sources = SEQ_query_selected_strips(seqbase);
+ seq_snap_source_points_alloc(snap_data, snap_sources);
+ seq_snap_source_points_build(t, snap_data, snap_sources);
+ SEQ_collection_free(snap_sources);
+
+ SeqCollection *snap_targets = query_snap_targets(t);
+ seq_snap_target_points_alloc(t, snap_data, snap_targets);
+ seq_snap_target_points_build(t, snap_data, snap_targets);
+ SEQ_collection_free(snap_targets);
+ return snap_data;
+}
+
+void transform_snap_sequencer_data_free(TransSeqSnapData *data)
+{
+ MEM_freeN(data->source_snap_points);
+ MEM_freeN(data->target_snap_points);
+ MEM_freeN(data);
+}
+
+bool transform_snap_sequencer_calc(TransInfo *t)
+{
+ /* Prevent snapping when constrained to Y axis. */
+ if (t->con.mode & CON_APPLY && t->con.mode & CON_AXIS1) {
+ return false;
+ }
+
+ const TransSeqSnapData *snap_data = t->tsnap.seq_context;
+ int best_dist = MAXFRAME, best_target_frame = 0, best_source_frame = 0;
+
+ for (int i = 0; i < snap_data->source_snap_point_count; i++) {
+ int snap_source_frame = snap_data->source_snap_points[i] + round_fl_to_int(t->values[0]);
+ for (int j = 0; j < snap_data->target_snap_point_count; j++) {
+ int snap_target_frame = snap_data->target_snap_points[j];
+
+ int dist = abs(snap_target_frame - snap_source_frame);
+ if (dist > best_dist) {
+ continue;
+ }
+
+ best_dist = dist;
+ best_target_frame = snap_target_frame;
+ best_source_frame = snap_source_frame;
+ }
+ }
+
+ if (best_dist > seq_snap_threshold_get_frame_distance(t)) {
+ return false;
+ }
+
+ t->tsnap.snapPoint[0] = best_target_frame;
+ t->tsnap.snapTarget[0] = best_source_frame;
+ return true;
+}
+
+void transform_snap_sequencer_apply_translate(TransInfo *t, float *vec)
+{
+ *vec += t->tsnap.snapPoint[0] - t->tsnap.snapTarget[0];
+}
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index 7811509ab40..23161028e03 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -202,7 +202,7 @@ static void ed_undo_step_pre(bContext *C,
/* App-Handlers (pre). */
{
- /* Note: ignore grease pencil for now. */
+ /* NOTE: ignore grease pencil for now. */
wm->op_undo_depth++;
BKE_callback_exec_id(
bmain, &scene->id, (undo_dir == STEP_UNDO) ? BKE_CB_EVT_UNDO_PRE : BKE_CB_EVT_REDO_PRE);
@@ -321,7 +321,7 @@ static int ed_undo_step_by_name(bContext *C, const char *undo_name, ReportList *
/* FIXME: See comments in `ed_undo_step_direction`. */
if (ED_gpencil_session_active()) {
- BLI_assert(!"Not implemented currently.");
+ BLI_assert_msg(0, "Not implemented currently.");
}
wmWindowManager *wm = CTX_wm_manager(C);
@@ -369,7 +369,7 @@ static int ed_undo_step_by_index(bContext *C, const int undo_index, ReportList *
/* FIXME: See comments in `ed_undo_step_direction`. */
if (ED_gpencil_session_active()) {
- BLI_assert(!"Not implemented currently.");
+ BLI_assert_msg(0, "Not implemented currently.");
}
wmWindowManager *wm = CTX_wm_manager(C);
@@ -492,7 +492,7 @@ bool ED_undo_is_legacy_compatible_for_property(struct bContext *C, ID *id)
}
/**
- * Ideally we wont access the stack directly,
+ * Ideally we won't access the stack directly,
* this is needed for modes which handle undo themselves (bypassing #ED_undo_push).
*
* Using global isn't great, this just avoids doing inline,
@@ -528,7 +528,7 @@ static int ed_undo_push_exec(bContext *C, wmOperator *op)
{
if (G.background) {
/* Exception for background mode, see: T60934.
- * Note: since the undo stack isn't initialized on startup, background mode behavior
+ * NOTE: since the undo stack isn't initialized on startup, background mode behavior
* won't match regular usage, this is just for scripts to do explicit undo pushes. */
wmWindowManager *wm = CTX_wm_manager(C);
if (wm->undo_stack == NULL) {
@@ -693,11 +693,11 @@ int ED_undo_operator_repeat(bContext *C, wmOperator *op)
}
if ((WM_operator_repeat_check(C, op)) && (WM_operator_poll(C, op->type)) &&
- /* note, undo/redo cant run if there are jobs active,
+ /* NOTE: undo/redo can't run if there are jobs active,
* check for screen jobs only so jobs like material/texture/world preview
- * (which copy their data), wont stop redo, see T29579],
+ * (which copy their data), won't stop redo, see T29579],
*
- * note, - WM_operator_check_ui_enabled() jobs test _must_ stay in sync with this */
+ * NOTE: WM_operator_check_ui_enabled() jobs test _must_ stay in sync with this. */
(WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY) == 0)) {
int retval;
@@ -829,7 +829,7 @@ static int undo_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
return OPERATOR_CANCELLED;
}
-/* note: also check ed_undo_step() in top if you change notifiers */
+/* NOTE: also check #ed_undo_step() in top if you change notifiers. */
static int undo_history_exec(bContext *C, wmOperator *op)
{
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "item");
diff --git a/source/blender/editors/undo/memfile_undo.c b/source/blender/editors/undo/memfile_undo.c
index 9189adaf4d1..7c6ce56eab0 100644
--- a/source/blender/editors/undo/memfile_undo.c
+++ b/source/blender/editors/undo/memfile_undo.c
@@ -224,9 +224,21 @@ static void memfile_undosys_step_decode(struct bContext *C,
/* Tag depsgraph to update data-block for changes that happened between the
* current and the target state, see direct_link_id_restore_recalc(). */
- if (id->recalc) {
+ if (id->recalc != 0) {
DEG_id_tag_update_ex(bmain, id, id->recalc);
}
+
+ bNodeTree *nodetree = ntreeFromID(id);
+ if (nodetree != NULL && nodetree->id.recalc != 0) {
+ DEG_id_tag_update_ex(bmain, &nodetree->id, nodetree->id.recalc);
+ }
+ if (GS(id->name) == ID_SCE) {
+ Scene *scene = (Scene *)id;
+ if (scene->master_collection != NULL && scene->master_collection->id.recalc != 0) {
+ DEG_id_tag_update_ex(
+ bmain, &scene->master_collection->id, scene->master_collection->id.recalc);
+ }
+ }
}
FOREACH_MAIN_ID_END;
diff --git a/source/blender/editors/util/ed_transverts.c b/source/blender/editors/util/ed_transverts.c
index ad45686dc75..b4a93eb996c 100644
--- a/source/blender/editors/util/ed_transverts.c
+++ b/source/blender/editors/util/ed_transverts.c
@@ -54,7 +54,7 @@ void ED_transverts_update_obedit(TransVertStore *tvs, Object *obedit)
const int mode = tvs->mode;
BLI_assert(ED_transverts_check_obedit(obedit) == true);
- DEG_id_tag_update(obedit->data, 0);
+ DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY);
if (obedit->type == OB_MESH) {
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -182,8 +182,8 @@ static void set_mapped_co(void *vuserdata,
if (BM_elem_index_get(eve) != TM_INDEX_SKIP) {
tv = &tv[BM_elem_index_get(eve)];
- /* be clever, get the closest vertex to the original,
- * behaves most logically when the mirror modifier is used for eg T33051*/
+ /* Be clever, get the closest vertex to the original,
+ * behaves most logically when the mirror modifier is used for eg T33051. */
if ((tv->flag & TX_VERT_USE_MAPLOC) == 0) {
/* first time */
copy_v3_v3(tv->maploc, co);
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index b80782b51be..7bbdc58474f 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -295,8 +295,11 @@ bool ED_editors_flush_edits(Main *bmain)
/* ***** XXX: functions are using old blender names, cleanup later ***** */
-/* now only used in 2d spaces, like time, ipo, nla, sima... */
-/* XXX shift/ctrl not configurable */
+/**
+ * Now only used in 2D spaces, like time, f-curve, NLA, image, etc.
+ *
+ * \note Shift/Control are not configurable key-bindings.
+ */
void apply_keyb_grid(
int shift, int ctrl, float *val, float fac1, float fac2, float fac3, int invert)
{
diff --git a/source/blender/editors/util/ed_util_imbuf.c b/source/blender/editors/util/ed_util_imbuf.c
index 0f2e280251f..9e05efca3df 100644
--- a/source/blender/editors/util/ed_util_imbuf.c
+++ b/source/blender/editors/util/ed_util_imbuf.c
@@ -244,7 +244,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event
}
if (ibuf->zbuf) {
- /* TODO, blend depth (not urgent). */
+ /* TODO: blend depth (not urgent). */
info->z = ibuf->zbuf[y * ibuf->x + x];
info->zp = &info->z;
if (ibuf->zbuf == (int *)ibuf->rect) {
@@ -252,7 +252,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event
}
}
if (ibuf->zbuf_float) {
- /* TODO, blend depth (not urgent). */
+ /* TODO: blend depth (not urgent). */
info->zf = ibuf->zbuf_float[y * ibuf->x + x];
info->zfp = &info->zf;
if (ibuf->zbuf_float == ibuf->rect_float) {
diff --git a/source/blender/editors/util/select_utils.c b/source/blender/editors/util/select_utils.c
index 4e8cf1e92e6..5681edd2f5c 100644
--- a/source/blender/editors/util/select_utils.c
+++ b/source/blender/editors/util/select_utils.c
@@ -41,7 +41,7 @@ int ED_select_op_action(const eSelectOp sel_op, const bool is_select, const bool
case SEL_OP_XOR:
return (is_select && is_inside) ? 0 : ((!is_select && is_inside) ? 1 : -1);
}
- BLI_assert(!"invalid sel_op");
+ BLI_assert_msg(0, "invalid sel_op");
return -1;
}
/**
@@ -67,7 +67,7 @@ int ED_select_op_action_deselected(const eSelectOp sel_op,
case SEL_OP_XOR:
return (is_select && is_inside) ? 0 : ((!is_select && is_inside) ? 1 : -1);
}
- BLI_assert(!"invalid sel_op");
+ BLI_assert_msg(0, "invalid sel_op");
return -1;
}
diff --git a/source/blender/editors/uvedit/uvedit_islands.c b/source/blender/editors/uvedit/uvedit_islands.c
index 93948b5ae1b..56bcbc63de1 100644
--- a/source/blender/editors/uvedit/uvedit_islands.c
+++ b/source/blender/editors/uvedit/uvedit_islands.c
@@ -36,6 +36,7 @@
#include "BLI_math.h"
#include "BLI_rect.h"
+#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "DEG_depsgraph.h"
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index e11341429a6..0757e177235 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -608,7 +608,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
/* Projection of point (x, y) over line (x1, y1, x2, y2) along X axis:
* new_y = (y2 - y1) / (x2 - x1) * (x - x1) + y1
* Maybe this should be a BLI func? Or is it already existing?
- * Could use interp_v2_v2v2, but not sure it's worth it here...*/
+ * Could use interp_v2_v2v2, but not sure it's worth it here. */
if (tool_local == UV_STRAIGHTEN_X) {
luv->uv[0] = a * (luv->uv[1] - uv_start[1]) + uv_start[0];
}
@@ -624,7 +624,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
}
}
else {
- /* error - not a line, needs 3+ points */
+ /* error - not a line, needs 3+ points. */
}
if (eve_line) {
@@ -632,7 +632,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
}
}
else {
- /* error - cant find an endpoint */
+ /* error - can't find an endpoint. */
}
}
@@ -1187,15 +1187,15 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Object *obedit)
}
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(f, BM_ELEM_TAG)) { /* face: visible */
+ if (BM_elem_flag_test(f, BM_ELEM_TAG)) { /* Face: visible. */
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- if (BM_elem_flag_test(l, BM_ELEM_TAG)) { /* loop: selected*/
+ if (BM_elem_flag_test(l, BM_ELEM_TAG)) { /* Loop: selected. */
float uv[2] = {0.0f, 0.0f};
int uv_tot = 0;
BM_ITER_ELEM (lsub, &lsubiter, l->v, BM_LOOPS_OF_VERT) {
- if (BM_elem_flag_test(lsub->f, BM_ELEM_TAG) && /* face: visible */
- !BM_elem_flag_test(lsub, BM_ELEM_TAG)) /* loop: unselected */
+ if (BM_elem_flag_test(lsub->f, BM_ELEM_TAG) && /* Face: visible. */
+ !BM_elem_flag_test(lsub, BM_ELEM_TAG)) /* Loop: unselected. */
{
luv = BM_ELEM_CD_GET_VOID_P(lsub, cd_loop_uv_offset);
add_v2_v2(uv, luv->uv);
@@ -1469,9 +1469,14 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (EDBM_mesh_hide(em, swap)) {
- EDBM_update_generic(ob->data, true, false);
+ EDBM_update(ob->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
- return OPERATOR_FINISHED;
+ continue;
}
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -1491,7 +1496,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
}
if (hide) {
- /* note, a special case for edges could be used,
+ /* NOTE: a special case for edges could be used,
* for now edges act like verts and get flushed */
if (use_face_center) {
if (em->selectmode == SCE_SELECT_FACE) {
@@ -1607,9 +1612,14 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
/* call the mesh function if we are in mesh sync sel */
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (EDBM_mesh_reveal(em, select)) {
- EDBM_update_generic(ob->data, true, false);
+ EDBM_update(ob->data,
+ &(const struct EDBMUpdate_Params){
+ .calc_looptri = true,
+ .calc_normals = false,
+ .is_destructive = false,
+ });
}
- return OPERATOR_FINISHED;
+ continue;
}
if (use_face_center) {
if (em->selectmode == SCE_SELECT_FACE) {
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index 7d82884760c..f97403a0919 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -82,10 +82,10 @@ typedef struct PVert {
struct PVert *nextlink;
union PVertUnion {
- PHashKey key; /* construct */
- int id; /* abf/lscm matrix index */
- float distortion; /* area smoothing */
- HeapNode *heaplink; /* edge collapsing */
+ PHashKey key; /* Construct. */
+ int id; /* ABF/LSCM matrix index. */
+ float distortion; /* Area smoothing. */
+ HeapNode *heaplink; /* Edge collapsing. */
} u;
struct PEdge *edge;
@@ -99,10 +99,10 @@ typedef struct PEdge {
struct PEdge *nextlink;
union PEdgeUnion {
- PHashKey key; /* construct */
- int id; /* abf matrix index */
- HeapNode *heaplink; /* fill holes */
- struct PEdge *nextcollapse; /* simplification */
+ PHashKey key; /* Construct. */
+ int id; /* ABF matrix index. */
+ HeapNode *heaplink; /* Fill holes. */
+ struct PEdge *nextcollapse; /* Simplification. */
} u;
struct PVert *vert;
@@ -118,10 +118,10 @@ typedef struct PFace {
struct PFace *nextlink;
union PFaceUnion {
- PHashKey key; /* construct */
- int chart; /* construct splitting*/
- float area3d; /* stretch */
- int id; /* abf matrix index */
+ PHashKey key; /* Construct. */
+ int chart; /* Construct splitting. */
+ float area3d; /* Stretch. */
+ int id; /* ABF matrix index. */
} u;
struct PEdge *edge;
@@ -2154,7 +2154,7 @@ static void p_collapse_cost_vertex(PVert *vert, float *r_mincost, PEdge **r_mine
static void p_chart_post_collapse_flush(PChart *chart, PEdge *collapsed)
{
- /* move to collapsed_ */
+ /* Move to `collapsed_*`. */
PVert *v, *nextv = NULL, *verts = chart->verts;
PEdge *e, *nexte = NULL, *edges = chart->edges, *laste = NULL;
@@ -2224,7 +2224,7 @@ static void p_chart_post_collapse_flush(PChart *chart, PEdge *collapsed)
static void p_chart_post_split_flush(PChart *chart)
{
- /* move from collapsed_ */
+ /* Move from `collapsed_*`. */
PVert *v, *nextv = NULL;
PEdge *e, *nexte = NULL;
@@ -2259,7 +2259,7 @@ static void p_chart_post_split_flush(PChart *chart)
static void p_chart_simplify_compute(PChart *chart)
{
/* Computes a list of edge collapses / vertex splits. The collapsed
- * simplices go in the chart->collapsed_* lists, The original and
+ * simplices go in the `chart->collapsed_*` lists, The original and
* collapsed may then be view as stacks, where the next collapse/split
* is at the top of the respective lists. */
diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c
index 016a054cf21..2613c5b23a0 100644
--- a/source/blender/editors/uvedit/uvedit_path.c
+++ b/source/blender/editors/uvedit/uvedit_path.c
@@ -552,7 +552,7 @@ static bool uv_shortest_path_pick_ex(const SpaceImage *sima,
if (uv_selectmode & UV_SELECT_EDGE) {
/* Special case as we don't use true edge selection,
* flush the selection from the vertices. */
- BM_mesh_select_mode_flush_ex(em->bm, SCE_SELECT_VERTEX);
+ BM_mesh_select_mode_flush_ex(em->bm, SCE_SELECT_VERTEX, BM_SELECT_LEN_FLUSH_RECALC_ALL);
}
}
ED_uvedit_select_sync_flush(scene->toolsettings, em, select);
diff --git a/source/blender/editors/uvedit/uvedit_rip.c b/source/blender/editors/uvedit/uvedit_rip.c
index e1b9a287457..631b831411f 100644
--- a/source/blender/editors/uvedit/uvedit_rip.c
+++ b/source/blender/editors/uvedit/uvedit_rip.c
@@ -572,7 +572,7 @@ static UVRipPairs *uv_rip_pairs_from_loop(BMLoop *l_init,
rip->loops = BLI_gset_ptr_new(__func__);
/* We can rely on this stack being small, as we're walking down two sides of an edge loop,
- * so the stack wont be much larger than the total number of fans at any one vertex. */
+ * so the stack won't be much larger than the total number of fans at any one vertex. */
BLI_SMALLSTACK_DECLARE(stack, BMLoop *);
/* Needed for cases when we walk onto loops which already have a side assigned,
@@ -907,7 +907,7 @@ static int uv_rip_exec(bContext *C, wmOperator *op)
float aspx, aspy;
{
- /* Note that we only want to run this on the */
+ /* Note that we only want to run this on the. */
Object *obedit = CTX_data_edit_object(C);
ED_uvedit_get_aspect(obedit, &aspx, &aspy);
}
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index c10e132a4e2..7709b76290f 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -1296,7 +1296,7 @@ static int uv_select_edgering(
l_step = uvedit_loop_find_other_radial_loop_with_visible_face(
scene, l_step_opposite, cd_loop_uv_offset);
if (l_step == NULL) {
- /* Ensure we touch the opposite edge if we cant walk over it. */
+ /* Ensure we touch the opposite edge if we can't walk over it. */
l_step = l_step_opposite;
}
}
@@ -1351,7 +1351,7 @@ static void uv_select_linked_multi(Scene *scene,
BM_mesh_elem_table_ensure(em->bm, BM_FACE); /* we can use this too */
- /* Note, we had 'use winding' so we don't consider overlapping islands as connected, see T44320
+ /* NOTE: we had 'use winding' so we don't consider overlapping islands as connected, see T44320
* this made *every* projection split the island into front/back islands.
* Keep 'use_winding' to false, see: T50970.
*
@@ -1381,7 +1381,7 @@ static void uv_select_linked_multi(Scene *scene,
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
bool add_to_stack = true;
- if (uv_sync_select && !select_faces) {
+ if (uv_sync_select) {
/* Special case, vertex/edge & sync select being enabled.
*
* Without this, a second linked select will 'grow' each time as each new
@@ -1392,6 +1392,7 @@ static void uv_select_linked_multi(Scene *scene,
* - The only other fully selected face is connected or,
* - There are no connected fully selected faces UV-connected to this loop.
*/
+ BLI_assert(!select_faces);
if (uvedit_face_select_test(scene, l->f, cd_loop_uv_offset)) {
/* pass */
}
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 8ebf000baaa..28853bcdedf 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -76,7 +76,7 @@ typedef struct StitchPreviewer {
float *preview_polys;
/* uvs per polygon. */
uint *uvs_per_polygon;
- /*number of preview polygons */
+ /* Number of preview polygons. */
uint num_polys;
/* preview data. These will be either the previewed vertices or edges
* depending on stitch mode settings */
@@ -1069,8 +1069,7 @@ static int stitch_process_data(StitchStateContainer *ssc,
}
}
- /* remember stitchable candidates as places the 'I' button */
- /* will stop at. */
+ /* Remember stitchable candidates as places the 'I' button will stop at. */
for (int island_idx = 0; island_idx < state->element_map->totalIslands; island_idx++) {
state->island_is_stitchable[island_idx] = island_stitch_data[island_idx].stitchableCandidate ?
true :
@@ -1747,7 +1746,8 @@ static void stitch_draw_vbo(GPUVertBuf *vbo, GPUPrimType prim_type, const float
GPU_batch_discard(batch);
}
-/* TODO make things pretier : store batches inside StitchPreviewer instead of the bare verts pos */
+/* TODO: make things pretier : store batches inside StitchPreviewer instead of the bare verts pos
+ */
static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), void *arg)
{
@@ -1818,7 +1818,7 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), void
/* Closing line */
GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]);
- /* j = uvs_per_polygon[i] - 1*/
+ /* `j = uvs_per_polygon[i] - 1` */
GPU_vertbuf_attr_set(
vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + j * 2]);
@@ -1980,7 +1980,7 @@ static StitchState *stitch_init(bContext *C,
counter++;
state->uvs[counter] = element;
}
- /* pointer arithmetic to the rescue, as always :)*/
+ /* Pointer arithmetic to the rescue, as always :). */
map[element - state->element_map->buf] = counter;
}
}
@@ -2007,8 +2007,8 @@ static StitchState *stitch_init(bContext *C,
all_edges[counter].first = NULL;
all_edges[counter].flag = 0;
all_edges[counter].element = element;
- /* using an order policy, sort uvs according to address space. This avoids
- * Having two different UvEdges with the same uvs on different positions */
+ /* Using an order policy, sort UV's according to address space.
+ * This avoids having two different UvEdges with the same UV's on different positions. */
if (offset1 < offset2) {
all_edges[counter].uv1 = offset1;
all_edges[counter].uv2 = offset2;
@@ -2381,9 +2381,9 @@ static int stitch_init_all(bContext *C, wmOperator *op)
StitchState *state = ssc->states[ssc->active_object_index];
ssc->static_island %= state->element_map->totalIslands;
- /* If the initial active object doesn't have any stitchable islands */
- /* then no active island will be seen in the UI. Make sure we're on */
- /* a stitchable object and island. */
+ /* If the initial active object doesn't have any stitchable islands
+ * then no active island will be seen in the UI.
+ * Make sure we're on a stitchable object and island. */
if (!state->island_is_stitchable[ssc->static_island]) {
goto_next_island(ssc);
state = ssc->states[ssc->active_object_index];
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 87ae112a237..0e9669d0f60 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -498,7 +498,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
/* pointers to modifier data for unwrap control */
ModifierData *md;
SubsurfModifierData *smd_real;
- /* modifier initialization data, will control what type of subdivision will happen*/
+ /* Modifier initialization data, will control what type of subdivision will happen. */
SubsurfModifierData smd = {{NULL}};
/* Used to hold subsurfed Mesh */
DerivedMesh *derivedMesh, *initialDerived;
@@ -509,7 +509,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
MEdge *subsurfedEdges;
MPoly *subsurfedPolys;
MLoop *subsurfedLoops;
- /* number of vertices and faces for subsurfed mesh*/
+ /* Number of vertices and faces for subsurfed mesh. */
int numOfEdges, numOfFaces;
/* holds a map to editfaces for every subsurfed MFace.
@@ -1367,7 +1367,7 @@ static void uv_map_rotation_matrix_ex(float result[4][4],
rotup[2][2] = cosf(upangle) / radius;
rotup[0][0] = 1.0f / radius;
- /* calculate transforms*/
+ /* Calculate transforms. */
mul_m4_series(result, rotup, rotside, viewmatrix, rotobj);
}
@@ -2319,7 +2319,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
const bool use_orthographic = RNA_boolean_get(op->ptr, "orthographic");
- /* Note: objects that aren't touched are set to NULL (to skip clipping). */
+ /* NOTE: objects that aren't touched are set to NULL (to skip clipping). */
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
view_layer, v3d, &objects_len);
@@ -2905,7 +2905,7 @@ void ED_uvedit_add_simple_uvs(Main *bmain, const Scene *scene, Object *ob)
/* select all uv loops first - pack parameters needs this to make sure charts are registered */
ED_uvedit_select_all(bm);
uvedit_unwrap_cube_project(bm, 1.0, false, NULL);
- /* set the margin really quickly before the packing operation*/
+ /* Set the margin really quickly before the packing operation. */
scene->toolsettings->uvcalc_margin = 0.001f;
uvedit_pack_islands(scene, ob, bm);
BM_mesh_bm_to_me(bmain, bm, me, (&(struct BMeshToMeshParams){0}));