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.c67
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c10
-rw-r--r--source/blender/editors/animation/anim_filter.c7
-rw-r--r--source/blender/editors/animation/anim_motion_paths.c2
-rw-r--r--source/blender/editors/animation/anim_ops.c4
-rw-r--r--source/blender/editors/animation/drivers.c1
-rw-r--r--source/blender/editors/animation/keyframes_draw.c96
-rw-r--r--source/blender/editors/animation/keyframes_general.c2
-rw-r--r--source/blender/editors/animation/keyframing.c4
-rw-r--r--source/blender/editors/animation/time_scrub_ui.c33
-rw-r--r--source/blender/editors/armature/armature_add.c6
-rw-r--r--source/blender/editors/armature/armature_ops.c2
-rw-r--r--source/blender/editors/armature/armature_skinning.c3
-rw-r--r--source/blender/editors/armature/armature_utils.c4
-rw-r--r--source/blender/editors/armature/editarmature_undo.c7
-rw-r--r--source/blender/editors/armature/meshlaplacian.c4
-rw-r--r--source/blender/editors/armature/pose_edit.c2
-rw-r--r--source/blender/editors/armature/pose_group.c2
-rw-r--r--source/blender/editors/armature/pose_lib.c4
-rw-r--r--source/blender/editors/armature/pose_slide.c28
-rw-r--r--source/blender/editors/armature/pose_transform.c2
-rw-r--r--source/blender/editors/armature/pose_utils.c3
-rw-r--r--source/blender/editors/asset/CMakeLists.txt4
-rw-r--r--source/blender/editors/asset/asset_edit.cc (renamed from source/blender/editors/asset/asset_edit.c)6
-rw-r--r--source/blender/editors/asset/asset_ops.c247
-rw-r--r--source/blender/editors/asset/asset_ops.cc259
-rw-r--r--source/blender/editors/curve/editcurve.c8
-rw-r--r--source/blender/editors/curve/editcurve_select.c2
-rw-r--r--source/blender/editors/curve/editcurve_undo.c7
-rw-r--r--source/blender/editors/curve/editfont_undo.c7
-rw-r--r--source/blender/editors/geometry/geometry_attributes.c2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_library_presets.c7
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c3
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c11
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c11
-rw-r--r--source/blender/editors/gpencil/editaction_gpencil.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_add_monkey.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_add_stroke.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_armature.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c10
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c39
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c139
-rw-r--r--source/blender/editors/gpencil/gpencil_edit_curve.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c1142
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h16
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c25
-rw-r--r--source/blender/editors/gpencil/gpencil_merge.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_mesh.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_ops.c5
-rw-r--r--source/blender/editors/gpencil/gpencil_ops_versioning.c5
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c92
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c16
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c22
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_trace_ops.c25
-rw-r--r--source/blender/editors/gpencil/gpencil_undo.c23
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c81
-rw-r--r--source/blender/editors/gpencil/gpencil_uv.c1
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_ops.c14
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_paint.c27
-rw-r--r--source/blender/editors/gpencil/gpencil_weight_paint.c25
-rw-r--r--source/blender/editors/include/ED_clip.h24
-rw-r--r--source/blender/editors/include/ED_fileselect.h2
-rw-r--r--source/blender/editors/include/ED_gpencil.h17
-rw-r--r--source/blender/editors/include/ED_keyframes_draw.h2
-rw-r--r--source/blender/editors/include/ED_keyframes_edit.h2
-rw-r--r--source/blender/editors/include/ED_mask.h5
-rw-r--r--source/blender/editors/include/ED_node.h4
-rw-r--r--source/blender/editors/include/ED_object.h2
-rw-r--r--source/blender/editors/include/ED_screen.h44
-rw-r--r--source/blender/editors/include/ED_transform.h24
-rw-r--r--source/blender/editors/include/UI_interface.h78
-rw-r--r--source/blender/editors/include/UI_interface_icons.h5
-rw-r--r--source/blender/editors/include/UI_resources.h2
-rw-r--r--source/blender/editors/include/UI_view2d.h2
-rw-r--r--source/blender/editors/interface/interface.c16
-rw-r--r--source/blender/editors/interface/interface_context_menu.c2
-rw-r--r--source/blender/editors/interface/interface_draw.c734
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c2
-rw-r--r--source/blender/editors/interface/interface_eyedropper_depth.c6
-rw-r--r--source/blender/editors/interface/interface_handlers.c83
-rw-r--r--source/blender/editors/interface/interface_icons_event.c10
-rw-r--r--source/blender/editors/interface/interface_intern.h6
-rw-r--r--source/blender/editors/interface/interface_layout.c4
-rw-r--r--source/blender/editors/interface/interface_ops.c2
-rw-r--r--source/blender/editors/interface/interface_panel.c92
-rw-r--r--source/blender/editors/interface/interface_region_menu_pie.c2
-rw-r--r--source/blender/editors/interface/interface_region_popup.c11
-rw-r--r--source/blender/editors/interface/interface_region_search.c26
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c80
-rw-r--r--source/blender/editors/interface/interface_style.c17
-rw-r--r--source/blender/editors/interface/interface_template_search_menu.c1
-rw-r--r--source/blender/editors/interface/interface_template_search_operator.c3
-rw-r--r--source/blender/editors/interface/interface_templates.c108
-rw-r--r--source/blender/editors/interface/interface_utils.c67
-rw-r--r--source/blender/editors/interface/interface_widgets.c44
-rw-r--r--source/blender/editors/interface/view2d.c2
-rw-r--r--source/blender/editors/interface/view2d_ops.c122
-rw-r--r--source/blender/editors/io/io_alembic.c3
-rw-r--r--source/blender/editors/io/io_cache.c1
-rw-r--r--source/blender/editors/io/io_collada.c2
-rw-r--r--source/blender/editors/lattice/editlattice_select.c2
-rw-r--r--source/blender/editors/lattice/editlattice_undo.c7
-rw-r--r--source/blender/editors/lattice/lattice_ops.c5
-rw-r--r--source/blender/editors/mask/mask_add.c10
-rw-r--r--source/blender/editors/mask/mask_draw.c4
-rw-r--r--source/blender/editors/mask/mask_edit.c36
-rw-r--r--source/blender/editors/mask/mask_intern.h15
-rw-r--r--source/blender/editors/mask/mask_ops.c47
-rw-r--r--source/blender/editors/mask/mask_query.c42
-rw-r--r--source/blender/editors/mask/mask_select.c13
-rw-r--r--source/blender/editors/mesh/editmesh_add.c2
-rw-r--r--source/blender/editors/mesh/editmesh_automerge.c3
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c4
-rw-r--r--source/blender/editors/mesh/editmesh_extrude_spin.c4
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c7
-rw-r--r--source/blender/editors/mesh/editmesh_mask_extract.c6
-rw-r--r--source/blender/editors/mesh/editmesh_select.c6
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c4
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c9
-rw-r--r--source/blender/editors/mesh/mesh_ops.c3
-rw-r--r--source/blender/editors/mesh/meshtools.c4
-rw-r--r--source/blender/editors/metaball/editmball_undo.c7
-rw-r--r--source/blender/editors/metaball/mball_edit.c2
-rw-r--r--source/blender/editors/metaball/mball_ops.c2
-rw-r--r--source/blender/editors/object/object_add.c11
-rw-r--r--source/blender/editors/object/object_bake_api.c2
-rw-r--r--source/blender/editors/object/object_data_transfer.c4
-rw-r--r--source/blender/editors/object/object_modifier.c2
-rw-r--r--source/blender/editors/object/object_ops.c8
-rw-r--r--source/blender/editors/object/object_relations.c35
-rw-r--r--source/blender/editors/object/object_remesh.c6
-rw-r--r--source/blender/editors/object/object_select.c4
-rw-r--r--source/blender/editors/object/object_shapekey.c2
-rw-r--r--source/blender/editors/object/object_transform.c2
-rw-r--r--source/blender/editors/object/object_volume.c3
-rw-r--r--source/blender/editors/object/object_warp.c9
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c2
-rw-r--r--source/blender/editors/physics/particle_boids.c1
-rw-r--r--source/blender/editors/physics/particle_edit.c13
-rw-r--r--source/blender/editors/physics/particle_edit_undo.c2
-rw-r--r--source/blender/editors/physics/physics_fluid.c6
-rw-r--r--source/blender/editors/physics/physics_ops.c5
-rw-r--r--source/blender/editors/physics/physics_pointcache.c1
-rw-r--r--source/blender/editors/physics/rigidbody_object.c2
-rw-r--r--source/blender/editors/render/render_internal.c12
-rw-r--r--source/blender/editors/render/render_opengl.c2
-rw-r--r--source/blender/editors/render/render_preview.c23
-rw-r--r--source/blender/editors/render/render_update.c6
-rw-r--r--source/blender/editors/screen/area.c93
-rw-r--r--source/blender/editors/screen/area_utils.c14
-rw-r--r--source/blender/editors/screen/glutil.c20
-rw-r--r--source/blender/editors/screen/screen_context.c2
-rw-r--r--source/blender/editors/screen/screen_draw.c2
-rw-r--r--source/blender/editors/screen/screen_edit.c9
-rw-r--r--source/blender/editors/screen/screen_intern.h8
-rw-r--r--source/blender/editors/screen/screen_ops.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_curve_undo.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c62
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c11
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c2713
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_automasking.c24
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_boundary.c309
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c283
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_detail.c17
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c168
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c170
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_paint_color.c218
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c78
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c162
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c13
-rw-r--r--source/blender/editors/sound/sound_ops.c3
-rw-r--r--source/blender/editors/space_action/action_buttons.c23
-rw-r--r--source/blender/editors/space_action/action_edit.c6
-rw-r--r--source/blender/editors/space_action/action_ops.c3
-rw-r--r--source/blender/editors/space_action/space_action.c73
-rw-r--r--source/blender/editors/space_api/spacetypes.c72
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c3
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c3
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c40
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c1
-rw-r--r--source/blender/editors/space_clip/clip_editor.c160
-rw-r--r--source/blender/editors/space_clip/clip_intern.h8
-rw-r--r--source/blender/editors/space_clip/clip_ops.c18
-rw-r--r--source/blender/editors/space_clip/clip_toolbar.c12
-rw-r--r--source/blender/editors/space_clip/clip_utils.c227
-rw-r--r--source/blender/editors/space_clip/space_clip.c67
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c114
-rw-r--r--source/blender/editors/space_clip/tracking_ops_detect.c4
-rw-r--r--source/blender/editors/space_clip/tracking_ops_stabilize.c2
-rw-r--r--source/blender/editors/space_clip/tracking_ops_track.c1
-rw-r--r--source/blender/editors/space_clip/tracking_ops_utils.c4
-rw-r--r--source/blender/editors/space_clip/tracking_select.c18
-rw-r--r--source/blender/editors/space_console/console_ops.c4
-rw-r--r--source/blender/editors/space_console/space_console.c13
-rw-r--r--source/blender/editors/space_file/file_draw.c14
-rw-r--r--source/blender/editors/space_file/file_utils.c1
-rw-r--r--source/blender/editors/space_file/filelist.c17
-rw-r--r--source/blender/editors/space_file/filesel.c2
-rw-r--r--source/blender/editors/space_file/space_file.c97
-rw-r--r--source/blender/editors/space_graph/graph_edit.c4
-rw-r--r--source/blender/editors/space_graph/graph_ops.c4
-rw-r--r--source/blender/editors/space_graph/graph_slider_ops.c20
-rw-r--r--source/blender/editors/space_graph/graph_utils.c2
-rw-r--r--source/blender/editors/space_graph/space_graph.c30
-rw-r--r--source/blender/editors/space_image/image_draw.c4
-rw-r--r--source/blender/editors/space_image/image_intern.h1
-rw-r--r--source/blender/editors/space_image/image_ops.c139
-rw-r--r--source/blender/editors/space_image/image_sequence.c4
-rw-r--r--source/blender/editors/space_image/image_undo.c8
-rw-r--r--source/blender/editors/space_image/space_image.c57
-rw-r--r--source/blender/editors/space_info/info_draw.c47
-rw-r--r--source/blender/editors/space_info/info_ops.c13
-rw-r--r--source/blender/editors/space_info/space_info.c36
-rw-r--r--source/blender/editors/space_info/textview.c17
-rw-r--r--source/blender/editors/space_nla/nla_draw.c26
-rw-r--r--source/blender/editors/space_nla/nla_edit.c11
-rw-r--r--source/blender/editors/space_nla/nla_ops.c5
-rw-r--r--source/blender/editors/space_nla/space_nla.c64
-rw-r--r--source/blender/editors/space_node/drawnode.c328
-rw-r--r--source/blender/editors/space_node/node_add.c30
-rw-r--r--source/blender/editors/space_node/node_buttons.c1
-rw-r--r--source/blender/editors/space_node/node_draw.c284
-rw-r--r--source/blender/editors/space_node/node_edit.c53
-rw-r--r--source/blender/editors/space_node/node_group.c2
-rw-r--r--source/blender/editors/space_node/node_intern.h54
-rw-r--r--source/blender/editors/space_node/node_ops.c4
-rw-r--r--source/blender/editors/space_node/node_relationships.c270
-rw-r--r--source/blender/editors/space_node/node_select.c6
-rw-r--r--source/blender/editors/space_node/node_templates.c1
-rw-r--r--source/blender/editors/space_node/node_toolbar.c3
-rw-r--r--source/blender/editors/space_node/node_view.c1
-rw-r--r--source/blender/editors/space_node/space_node.c70
-rw-r--r--source/blender/editors/space_outliner/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_outliner/outliner_context.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_dragdrop.c5
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c59
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c13
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c23
-rw-r--r--source/blender/editors/space_outliner/outliner_sync.c5
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c49
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c280
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.c2
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c35
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display.cc2
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element.cc2
-rw-r--r--source/blender/editors/space_script/space_script.c9
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c5
-rw-r--r--source/blender/editors/space_sequencer/sequencer_buttons.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c21
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c1
-rw-r--r--source/blender/editors/space_sequencer/sequencer_ops.c5
-rw-r--r--source/blender/editors/space_sequencer/sequencer_proxy.c1
-rw-r--r--source/blender/editors/space_sequencer/sequencer_scopes.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c119
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c50
-rw-r--r--source/blender/editors/space_statusbar/space_statusbar.c21
-rw-r--r--source/blender/editors/space_text/space_text.c9
-rw-r--r--source/blender/editors/space_text/text_draw.c28
-rw-r--r--source/blender/editors/space_text/text_format.c2
-rw-r--r--source/blender/editors/space_text/text_ops.c2
-rw-r--r--source/blender/editors/space_text/text_undo.c11
-rw-r--r--source/blender/editors/space_topbar/space_topbar.c31
-rw-r--r--source/blender/editors/space_userpref/space_userpref.c34
-rw-r--r--source/blender/editors/space_userpref/userpref_ops.c4
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c121
-rw-r--r--source/blender/editors/space_view3d/view3d_camera_control.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c35
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_forcefield.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_navigate.c27
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c620
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_preselect.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c7
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c42
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c4
-rw-r--r--source/blender/editors/transform/CMakeLists.txt1
-rw-r--r--source/blender/editors/transform/transform.c34
-rw-r--r--source/blender/editors/transform/transform.h460
-rw-r--r--source/blender/editors/transform/transform_constraints.c143
-rw-r--r--source/blender/editors/transform/transform_convert.c425
-rw-r--r--source/blender/editors/transform/transform_convert.h35
-rw-r--r--source/blender/editors/transform/transform_convert_armature.c6
-rw-r--r--source/blender/editors/transform/transform_convert_curve.c2
-rw-r--r--source/blender/editors/transform/transform_convert_gpencil.c12
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c221
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_skin.c4
-rw-r--r--source/blender/editors/transform/transform_convert_nla.c34
-rw-r--r--source/blender/editors/transform/transform_convert_object.c72
-rw-r--r--source/blender/editors/transform/transform_convert_object_texspace.c126
-rw-r--r--source/blender/editors/transform/transform_convert_sequencer.c28
-rw-r--r--source/blender/editors/transform/transform_convert_tracking.c246
-rw-r--r--source/blender/editors/transform/transform_data.h10
-rw-r--r--source/blender/editors/transform/transform_draw_cursors.c396
-rw-r--r--source/blender/editors/transform/transform_generics.c137
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c4
-rw-r--r--source/blender/editors/transform/transform_input.c24
-rw-r--r--source/blender/editors/transform/transform_mode.c14
-rw-r--r--source/blender/editors/transform/transform_mode_align.c2
-rw-r--r--source/blender/editors/transform/transform_mode_edge_seq_slide.c11
-rw-r--r--source/blender/editors/transform/transform_mode_edge_slide.c2
-rw-r--r--source/blender/editors/transform/transform_mode_mirror.c2
-rw-r--r--source/blender/editors/transform/transform_mode_resize.c2
-rw-r--r--source/blender/editors/transform/transform_mode_shrink_fatten.c17
-rw-r--r--source/blender/editors/transform/transform_mode_translate.c2
-rw-r--r--source/blender/editors/transform/transform_ops.c6
-rw-r--r--source/blender/editors/transform/transform_orientations.c30
-rw-r--r--source/blender/editors/transform/transform_snap.c245
-rw-r--r--source/blender/editors/transform/transform_snap_object.c2
-rw-r--r--source/blender/editors/undo/ed_undo.c222
-rw-r--r--source/blender/editors/undo/memfile_undo.c18
-rw-r--r--source/blender/editors/util/CMakeLists.txt2
-rw-r--r--source/blender/editors/util/ed_transverts.c4
-rw-r--r--source/blender/editors/util/ed_util.c2
-rw-r--r--source/blender/editors/util/ed_util_ops.cc (renamed from source/blender/editors/util/ed_util_ops.c)28
-rw-r--r--source/blender/editors/util/numinput.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c14
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c12
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c6
328 files changed, 8743 insertions, 7714 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 05cbb3ef48f..24bb58535a5 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -133,7 +133,16 @@ static void acf_generic_root_backdrop(bAnimContext *ac,
UI_draw_roundbox_corner_set((expanded) ? UI_CNR_TOP_LEFT :
(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
UI_draw_roundbox_3fv_alpha(
- true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
+ &(const rctf){
+ .xmin = offset,
+ .xmax = v2d->cur.xmax + EXTRA_SCROLL_PAD,
+ .ymin = yminc,
+ .ymax = ymaxc,
+ },
+ true,
+ 8,
+ color,
+ 1.0f);
}
/* get backdrop color for data expanders under top-level Scene/Object */
@@ -421,7 +430,7 @@ static bool acf_generic_dataexpand_setting_valid(bAnimContext *ac,
case ACHANNEL_SETTING_MUTE:
return ((ac) && (ac->spacetype == SPACE_NLA));
- /* select is ok for most "ds*" channels (e.g. dsmat) */
+ /* Select is ok for most `ds*` channels (e.g. `dsmat`) */
case ACHANNEL_SETTING_SELECT:
return true;
@@ -464,7 +473,16 @@ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float ymi
*/
UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
UI_draw_roundbox_3fv_alpha(
- true, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
+ &(const rctf){
+ .xmin = 0,
+ .xmax = v2d->cur.xmax + EXTRA_SCROLL_PAD,
+ .ymin = yminc - 2,
+ .ymax = ymaxc,
+ },
+ true,
+ 8,
+ color,
+ 1.0f);
}
/* name for summary entries */
@@ -875,7 +893,16 @@ static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc
/* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
UI_draw_roundbox_3fv_alpha(
- true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
+ &(const rctf){
+ .xmin = offset,
+ .xmax = v2d->cur.xmax + EXTRA_SCROLL_PAD,
+ .ymin = yminc,
+ .ymax = ymaxc,
+ },
+ true,
+ 8,
+ color,
+ 1.0f);
}
/* name for group entries */
@@ -1149,7 +1176,16 @@ static void acf_nla_controls_backdrop(bAnimContext *ac,
/* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
UI_draw_roundbox_3fv_alpha(
- true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 5, color, 1.0f);
+ &(const rctf){
+ .xmin = offset,
+ .xmax = v2d->cur.xmax + EXTRA_SCROLL_PAD,
+ .ymin = yminc,
+ .ymax = ymaxc,
+ },
+ true,
+ 5,
+ color,
+ 1.0f);
}
/* name for nla controls expander entries */
@@ -3936,13 +3972,16 @@ static void acf_nlaaction_backdrop(bAnimContext *ac, bAnimListElem *ale, float y
/* draw slightly shifted up vertically to look like it has more separation from other channels,
* but we then need to slightly shorten it so that it doesn't look like it overlaps
*/
- UI_draw_roundbox_4fv(true,
- offset,
- yminc + NLACHANNEL_SKIP,
- (float)v2d->cur.xmax,
- ymaxc + NLACHANNEL_SKIP - 1,
- 8,
- color);
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = offset,
+ .xmax = (float)v2d->cur.xmax,
+ .ymin = yminc + NLACHANNEL_SKIP,
+ .ymax = ymaxc + NLACHANNEL_SKIP - 1,
+ },
+ true,
+ 8,
+ color);
}
/* name for nla action entries */
@@ -4710,7 +4749,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
(float)CFRA);
NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
- &nla_cache, &id_ptr, adt, &anim_eval_context, false);
+ &nla_cache, &id_ptr, adt, &anim_eval_context);
/* get current frame and apply NLA-mapping to it (if applicable) */
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
@@ -4766,7 +4805,7 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
(float)CFRA);
NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
- &nla_cache, &id_ptr, key->adt, &anim_eval_context, false);
+ &nla_cache, &id_ptr, key->adt, &anim_eval_context);
/* get current frame and apply NLA-mapping to it (if applicable) */
const float remapped_frame = BKE_nla_tweakedit_remap(
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index a6e96a4d919..109cf79c786 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -393,7 +393,11 @@ static void anim_channels_select_set(bAnimContext *ac,
FCurve *fcu = (FCurve *)ale->data;
ACHANNEL_SET_FLAG(fcu, sel, FCURVE_SELECTED);
- fcu->flag &= ~FCURVE_ACTIVE;
+ if ((fcu->flag & FCURVE_SELECTED) == 0) {
+ /* Only erase the ACTIVE flag when deselecting. This ensures that "select all curves"
+ * retains the currently active curve. */
+ fcu->flag &= ~FCURVE_ACTIVE;
+ }
break;
}
case ANIMTYPE_SHAPEKEY: {
@@ -1197,7 +1201,7 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn
rearrange_animchannel_islands(
&adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK, &anim_data_visible);
- /* Add back non-local NLA tracks at the begining of the animation data's list. */
+ /* Add back non-local NLA tracks at the beginning of the animation data's list. */
if (!BLI_listbase_is_empty(&extracted_nonlocal_nla_tracks)) {
BLI_assert(is_liboverride);
((NlaTrack *)extracted_nonlocal_nla_tracks.last)->next = adt->nla_tracks.first;
@@ -1732,7 +1736,7 @@ static int animchannels_group_exec(bContext *C, wmOperator *op)
/* free temp data */
ANIM_animdata_freelist(&anim_data);
- /* updatss */
+ /* Updates. */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
}
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index f2022194ed5..a03f19d0111 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -2403,6 +2403,13 @@ static void animfilter_modifier_idpoin_cb(void *afm_ptr,
}
break;
}
+ case ID_NT: {
+ bNodeTree *node_tree = (bNodeTree *)id;
+ if (!(afm->ads->filterflag & ADS_FILTER_NONTREE)) {
+ afm->items += animdata_filter_ds_nodetree(
+ afm->ac, &afm->tmp_data, afm->ads, owner_id, node_tree, afm->filter_mode);
+ }
+ }
/* TODO: images? */
default:
diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c
index 088ac9dbcba..aac2465d43a 100644
--- a/source/blender/editors/animation/anim_motion_paths.c
+++ b/source/blender/editors/animation/anim_motion_paths.c
@@ -331,7 +331,7 @@ static void motionpath_calculate_update_range(MPathTarget *mpt,
int fcu_sfra = motionpath_get_prev_prev_keyframe(mpt, &fcu_keys, current_frame);
int fcu_efra = motionpath_get_next_next_keyframe(mpt, &fcu_keys, current_frame);
- /* Extend range furher, since accelleration compensation propagates even further away. */
+ /* Extend range further, since acceleration compensation propagates even further away. */
if (fcu->auto_smoothing != FCURVE_SMOOTH_NONE) {
fcu_sfra = motionpath_get_prev_prev_keyframe(mpt, &fcu_keys, fcu_sfra);
fcu_efra = motionpath_get_next_next_keyframe(mpt, &fcu_keys, fcu_efra);
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index a5514f6517e..72d9bff545a 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -29,12 +29,10 @@
#include "BLI_math_base.h"
#include "BLI_utildefines.h"
-#include "DNA_anim_types.h"
#include "DNA_scene_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
-#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -50,10 +48,8 @@
#include "ED_screen.h"
#include "ED_sequencer.h"
#include "ED_time_scrub_ui.h"
-#include "ED_util.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "SEQ_sequencer.h"
#include "SEQ_time.h"
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index b2a9d6ac9b7..43d5efe9ea9 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -33,7 +33,6 @@
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
-#include "DNA_space_types.h"
#include "DNA_texture_types.h"
#include "BKE_anim_data.h"
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index 542a6d45db7..b9ef69cf8bd 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -258,6 +258,10 @@ static DLRBT_Node *nalloc_ak_gpframe(void *data)
/* count keyframes in this column */
ak->totkey = 1;
+ /* Set as visible block. */
+ ak->totblock = 1;
+ ak->block.sel = ak->sel;
+ ak->block.flag |= ACTKEYBLOCK_FLAG_GPENCIL;
return (DLRBT_Node *)ak;
}
@@ -689,6 +693,7 @@ static void draw_keylist(View2D *v2d,
{
const float icon_sz = U.widget_unit * 0.5f * yscale_fac;
const float half_icon_sz = 0.5f * icon_sz;
+ const float quarter_icon_sz = 0.25f * icon_sz;
const float smaller_sz = 0.35f * icon_sz;
const float ipo_sz = 0.1f * icon_sz;
@@ -724,6 +729,7 @@ static void draw_keylist(View2D *v2d,
ipo_color_mix[3] *= 0.5f;
uint block_len = 0;
+ uint gpencil_len = 0;
LISTBASE_FOREACH (ActKeyColumn *, ab, keys) {
if (actkeyblock_get_valid_hold(ab)) {
block_len++;
@@ -731,50 +737,72 @@ static void draw_keylist(View2D *v2d,
if (show_ipo && actkeyblock_is_valid(ab) && (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) {
block_len++;
}
+ if ((ab->next != NULL) && (ab->block.flag & ACTKEYBLOCK_FLAG_GPENCIL)) {
+ gpencil_len++;
+ }
}
- if (block_len > 0) {
+ if ((block_len > 0) || (gpencil_len > 0)) {
GPUVertFormat *format = immVertexFormat();
uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBegin(GPU_PRIM_TRIS, 6 * block_len);
- LISTBASE_FOREACH (ActKeyColumn *, ab, keys) {
- int valid_hold = actkeyblock_get_valid_hold(ab);
- if (valid_hold != 0) {
- if ((valid_hold & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) {
- /* draw "moving hold" long-keyframe block - slightly smaller */
- immRectf_fast_with_color(pos_id,
- color_id,
- ab->cfra,
- ypos - smaller_sz,
- ab->next->cfra,
- ypos + smaller_sz,
- (ab->block.sel) ? sel_mhcol : unsel_mhcol);
+ /* Normal Dopesheet. */
+ if (block_len > 0) {
+ immBegin(GPU_PRIM_TRIS, 6 * block_len);
+ LISTBASE_FOREACH (ActKeyColumn *, ab, keys) {
+ int valid_hold = actkeyblock_get_valid_hold(ab);
+ if (valid_hold != 0) {
+ if ((valid_hold & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) {
+ /* draw "moving hold" long-keyframe block - slightly smaller */
+ immRectf_fast_with_color(pos_id,
+ color_id,
+ ab->cfra,
+ ypos - smaller_sz,
+ ab->next->cfra,
+ ypos + smaller_sz,
+ (ab->block.sel) ? sel_mhcol : unsel_mhcol);
+ }
+ else {
+ /* draw standard long-keyframe block */
+ immRectf_fast_with_color(pos_id,
+ color_id,
+ ab->cfra,
+ ypos - half_icon_sz,
+ ab->next->cfra,
+ ypos + half_icon_sz,
+ (ab->block.sel) ? sel_color : unsel_color);
+ }
}
- else {
- /* draw standard long-keyframe block */
- immRectf_fast_with_color(pos_id,
- color_id,
- ab->cfra,
- ypos - half_icon_sz,
- ab->next->cfra,
- ypos + half_icon_sz,
- (ab->block.sel) ? sel_color : unsel_color);
+ if (show_ipo && actkeyblock_is_valid(ab) &&
+ (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) {
+ /* draw an interpolation line */
+ immRectf_fast_with_color(
+ pos_id,
+ color_id,
+ ab->cfra,
+ ypos - ipo_sz,
+ ab->next->cfra,
+ ypos + ipo_sz,
+ (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ipo_color_mix : ipo_color);
}
}
- if (show_ipo && actkeyblock_is_valid(ab) &&
- (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) {
- /* draw an interpolation line */
- immRectf_fast_with_color(
- pos_id,
- color_id,
- ab->cfra,
- ypos - ipo_sz,
- ab->next->cfra,
- ypos + ipo_sz,
- (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ipo_color_mix : ipo_color);
+ }
+ /* Grease Pencil Dopesheet. */
+ else {
+ immBegin(GPU_PRIM_TRIS, 6 * gpencil_len);
+ LISTBASE_FOREACH (ActKeyColumn *, ab, keys) {
+ if (ab->next == NULL) {
+ continue;
+ }
+ immRectf_fast_with_color(pos_id,
+ color_id,
+ ab->cfra,
+ ypos - quarter_icon_sz,
+ ab->next->cfra,
+ ypos + quarter_icon_sz,
+ (ab->block.sel) ? sel_mhcol : unsel_mhcol);
}
}
immEnd();
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index 6ed9803dbd3..72e65272f13 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -39,13 +39,11 @@
#include "BKE_action.h"
#include "BKE_curve.h"
-#include "BKE_deform.h"
#include "BKE_fcurve.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "RNA_access.h"
-#include "RNA_enum_types.h"
#include "ED_anim_api.h"
#include "ED_keyframes_edit.h"
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index e8146ca960a..0d1633ab3a2 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -614,7 +614,7 @@ int insert_vert_fcurve(
return -1;
}
- /* set handletype and interpolation */
+ /* Set handle-type and interpolation. */
if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE) == 0) {
BezTriple *bezt = (fcu->bezt + a);
@@ -1384,7 +1384,7 @@ static AnimationEvalContext nla_time_remap(const AnimationEvalContext *anim_eval
if (adt && adt->action == act) {
/* Get NLA context for value remapping. */
*r_nla_context = BKE_animsys_get_nla_keyframing_context(
- nla_cache, id_ptr, adt, anim_eval_context, false);
+ nla_cache, id_ptr, adt, anim_eval_context);
/* Apply NLA-mapping to frame. */
const float remapped_frame = BKE_nla_tweakedit_remap(
diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c
index 98b4d93fbf1..034378399b9 100644
--- a/source/blender/editors/animation/time_scrub_ui.c
+++ b/source/blender/editors/animation/time_scrub_ui.c
@@ -124,23 +124,22 @@ static void draw_current_frame(const Scene *scene,
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_3fv_alpha(true,
- frame_x - box_width / 2 + U.pixelsize / 2,
- scrub_region_rect->ymin + box_padding,
- frame_x + box_width / 2 + U.pixelsize / 2,
- scrub_region_rect->ymax - box_padding,
- 4 * UI_DPI_FAC,
- bg_color,
- 1.0f);
-
- UI_GetThemeColorShade4fv(TH_CFRAME, 5, bg_color);
- UI_draw_roundbox_aa(false,
- frame_x - box_width / 2 + U.pixelsize / 2,
- scrub_region_rect->ymin + box_padding,
- frame_x + box_width / 2 + U.pixelsize / 2,
- scrub_region_rect->ymax - box_padding,
- 4 * UI_DPI_FAC,
- bg_color);
+ float outline_color[4];
+ UI_GetThemeColorShade4fv(TH_CFRAME, 5, outline_color);
+
+ UI_draw_roundbox_4fv_ex(
+ &(const rctf){
+ .xmin = frame_x - box_width / 2 + U.pixelsize / 2,
+ .xmax = frame_x + box_width / 2 + U.pixelsize / 2,
+ .ymin = scrub_region_rect->ymin + box_padding,
+ .ymax = scrub_region_rect->ymax - box_padding,
+ },
+ bg_color,
+ NULL,
+ 1.0f,
+ outline_color,
+ U.pixelsize,
+ 4 * UI_DPI_FAC);
uchar text_color[4];
UI_GetThemeColor4ubv(TH_HEADER_TEXT_HI, text_color);
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index a0b8bf862d7..68fff1091af 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -122,9 +122,6 @@ EditBone *ED_armature_ebone_add_primitive(Object *obedit_arm, float length, bool
return bone;
}
-/* previously addvert_armature */
-/* the ctrl-click method */
-
/**
* Note this is already ported to multi-objects as it is.
* Since only the active bone is extruded even for single objects,
@@ -306,8 +303,7 @@ static EditBone *get_named_editbone(ListBase *edbo, const char *name)
return NULL;
}
-/* Call this before doing any duplications
- * */
+/* Call this before doing any duplications. */
void preEditBoneDuplicate(ListBase *editbones)
{
/* clear temp */
diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c
index da1b29307b1..a0face26bae 100644
--- a/source/blender/editors/armature/armature_ops.c
+++ b/source/blender/editors/armature/armature_ops.c
@@ -28,8 +28,6 @@
#include "ED_armature.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
-#include "ED_transform.h"
#include "armature_intern.h"
diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c
index 6951ed6f305..f86ec545712 100644
--- a/source/blender/editors/armature/armature_skinning.c
+++ b/source/blender/editors/armature/armature_skinning.c
@@ -30,7 +30,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_string_utils.h"
@@ -50,8 +49,6 @@
#include "ED_armature.h"
#include "ED_mesh.h"
-#include "eigen_capi.h"
-
#include "armature_intern.h"
#include "meshlaplacian.h"
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index fba88e78162..3d1d8d0d1f1 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -699,11 +699,11 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm)
BKE_armature_bonelist_free(&arm->bonebase, true);
arm->act_bone = NULL;
- /* remove zero sized bones, this gives unstable restposes */
+ /* Remove zero sized bones, this gives unstable rest-poses. */
for (eBone = arm->edbo->first; eBone; eBone = neBone) {
float len_sq = len_squared_v3v3(eBone->head, eBone->tail);
neBone = eBone->next;
- /* TODO(sergey): How to ensure this is a constexpr? */
+ /* TODO(sergey): How to ensure this is a `constexpr`? */
if (len_sq <= square_f(0.000001f)) { /* FLT_EPSILON is too large? */
EditBone *fBone;
diff --git a/source/blender/editors/armature/editarmature_undo.c b/source/blender/editors/armature/editarmature_undo.c
index c6d7d2eb869..337d1138b23 100644
--- a/source/blender/editors/armature/editarmature_undo.c
+++ b/source/blender/editors/armature/editarmature_undo.c
@@ -178,8 +178,11 @@ static bool armature_undosys_step_encode(struct bContext *C, struct Main *bmain,
return true;
}
-static void armature_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
+static void armature_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir UNUSED(dir),
+ bool UNUSED(is_final))
{
ArmatureUndoStep *us = (ArmatureUndoStep *)us_p;
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 3c0b6dacbf6..e362a2e2f40 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -422,7 +422,7 @@ static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTr
}
}
-/* Raytracing for vertex to bone/vertex visibility */
+/* Ray-tracing for vertex to bone/vertex visibility. */
static void heat_ray_tree_create(LaplacianSystem *sys)
{
const MLoopTri *looptri = sys->heat.mlooptri;
@@ -497,7 +497,7 @@ static float heat_source_distance(LaplacianSystem *sys, int vertex, int source)
{
float closest[3], d[3], dist, cosine;
- /* compute euclidian distance */
+ /* compute Euclidean distance */
closest_to_line_segment_v3(
closest, sys->heat.verts[vertex], sys->heat.root[source], sys->heat.tip[source]);
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index 91893af003f..78bce8679bb 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -149,7 +149,7 @@ bool ED_object_posemode_exit(bContext *C, Object *ob)
return ok;
}
-/* if a selected or active bone is protected, throw error (oonly if warn == 1) and return 1 */
+/* if a selected or active bone is protected, throw error (only if warn == 1) and return 1 */
/* only_selected == 1: the active bone is allowed to be protected */
#if 0 /* UNUSED 2.5 */
static bool pose_has_protected_selected(Object *ob, short warn)
diff --git a/source/blender/editors/armature/pose_group.c b/source/blender/editors/armature/pose_group.c
index 55c9877e55f..38d15d8b880 100644
--- a/source/blender/editors/armature/pose_group.c
+++ b/source/blender/editors/armature/pose_group.c
@@ -423,7 +423,7 @@ static int group_sort_exec(bContext *C, wmOperator *UNUSED(op))
BLI_addtail(&pose->agroups, agrp_array[i].agrp);
}
- /* fix changed bone group indizes in bones */
+ /* Fix changed bone group indices in bones. */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (i = 0; i < agrp_count; i++) {
if (pchan->agrp_index == agrp_array[i].index) {
diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index 947e2dbf5aa..45f623f3a9d 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -1106,7 +1106,7 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, tPoseLib_PreviewData
if (pchan) {
if (!any_bone_selected || ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))) {
if (autokey) {
- /* add datasource override for the PoseChannel, to be used later */
+ /* Add data-source override for the PoseChannel, to be used later. */
ANIM_relative_keyingset_add_source(&dsources, &pld->ob->id, &RNA_PoseBone, pchan);
/* clear any unkeyed tags */
@@ -1142,7 +1142,7 @@ static void poselib_preview_apply(bContext *C, wmOperator *op)
/* only recalc pose (and its dependencies) if pose has changed */
if (pld->redraw == PL_PREVIEW_REDRAWALL) {
- /* don't clear pose if firsttime */
+ /* Don't clear pose if first time. */
if ((pld->flag & PL_PREVIEW_FIRSTTIME) == 0) {
poselib_backup_restore(pld);
}
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index 4b646bb26e2..d636f0d68af 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -689,7 +689,7 @@ static void pose_slide_rest_pose_apply(bContext *C, tPoseSlideOp *pso)
/* 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 */
- // pose_slide_apply_props(pso, pfl, "[\""); /* dummy " for texteditor bugs */
+ // pose_slide_apply_props(pso, pfl, "[\"");
}
}
@@ -702,7 +702,7 @@ static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
{
tPChanFCurveLink *pfl;
- /* sanitise the frame ranges */
+ /* Sanitize the frame ranges. */
if (pso->prevFrame == pso->nextFrame) {
/* move out one step either side */
pso->prevFrame--;
@@ -765,7 +765,7 @@ static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
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). */
- pose_slide_apply_props(pso, pfl, "[\""); /* dummy " for texteditor bugs */
+ pose_slide_apply_props(pso, pfl, "[\"");
}
}
@@ -1125,7 +1125,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->val == KM_PRESS) {
switch (event->type) {
/* Transform Channel Limits */
- /* XXX: Replace these hardcoded hotkeys with a modalmap that can be customised */
+ /* XXX: Replace these hard-coded hotkeys with a modal-map that can be customized. */
case EVT_GKEY: /* Location */
{
pose_slide_toggle_channels_mode(op, pso, PS_TFM_LOC);
@@ -1183,7 +1183,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else {
- /* unhandled event - maybe it was some view manip? */
+ /* unhandled event - maybe it was some view manipulation? */
/* allow to pass through */
return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH;
}
@@ -1246,15 +1246,15 @@ static void pose_slide_opdef_properties(wmOperatorType *ot)
{
PropertyRNA *prop;
- prop = RNA_def_float_percentage(ot->srna,
- "percentage",
- 0.5f,
- 0.0f,
- 1.0f,
- "Percentage",
- "Weighting factor for which keyframe is favored more",
- 0.0,
- 1.0);
+ prop = RNA_def_float_factor(ot->srna,
+ "factor",
+ 0.5f,
+ 0.0f,
+ 1.0f,
+ "Factor",
+ "Weighting factor for which keyframe is favored more",
+ 0.0,
+ 1.0);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_int(ot->srna,
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index 3505aea3f40..722865cc942 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -225,7 +225,7 @@ static void applyarmature_process_selected_recursive(bArmature *arm,
ApplyArmature_ParentState new_pstate = {.bone = bone};
if (BLI_findptr(selected, pchan, offsetof(CollectionPointerLink, ptr.data))) {
- /* SELECTED BONE: Snap to final pose transform minus unapplied parent effects.
+ /* SELECTED BONE: Snap to final pose transform minus un-applied parent effects.
*
* I.e. bone position with accumulated parent effects but no local
* transformation will match the original final pose_mat.
diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c
index 2a6dc9f406b..c75e9c9ef69 100644
--- a/source/blender/editors/armature/pose_utils.c
+++ b/source/blender/editors/armature/pose_utils.c
@@ -33,7 +33,6 @@
#include "BKE_action.h"
#include "BKE_anim_data.h"
-#include "BKE_armature.h"
#include "BKE_idprop.h"
#include "BKE_layer.h"
#include "BKE_object.h"
@@ -312,7 +311,7 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, ListBase *pfLinks,
continue;
}
- /* add datasource override for the PoseChannel, to be used later */
+ /* Add data-source override for the PoseChannel, to be used later. */
ANIM_relative_keyingset_add_source(&dsources, &pfl->ob->id, &RNA_PoseBone, pchan);
/* clear any unkeyed tags */
diff --git a/source/blender/editors/asset/CMakeLists.txt b/source/blender/editors/asset/CMakeLists.txt
index 6cd94783251..8c5f91561b7 100644
--- a/source/blender/editors/asset/CMakeLists.txt
+++ b/source/blender/editors/asset/CMakeLists.txt
@@ -29,8 +29,8 @@ set(INC_SYS
)
set(SRC
- asset_edit.c
- asset_ops.c
+ asset_edit.cc
+ asset_ops.cc
)
set(LIB
diff --git a/source/blender/editors/asset/asset_edit.c b/source/blender/editors/asset/asset_edit.cc
index 3dca87d3a03..d20de4141cb 100644
--- a/source/blender/editors/asset/asset_edit.c
+++ b/source/blender/editors/asset/asset_edit.cc
@@ -20,11 +20,9 @@
#include "BKE_asset.h"
#include "BKE_context.h"
-#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "DNA_ID.h"
-#include "DNA_asset_types.h"
#include "UI_interface_icons.h"
@@ -45,7 +43,7 @@ bool ED_asset_mark_id(const bContext *C, ID *id)
id->asset_data = BKE_asset_metadata_create();
- UI_icon_render_id(C, NULL, id, ICON_SIZE_PREVIEW, true);
+ UI_icon_render_id(C, nullptr, id, ICON_SIZE_PREVIEW, true);
return true;
}
@@ -65,5 +63,5 @@ bool ED_asset_clear_id(ID *id)
bool ED_asset_can_make_single_from_context(const bContext *C)
{
/* Context needs a "id" pointer to be set for #ASSET_OT_mark()/#ASSET_OT_clear() to use. */
- return CTX_data_pointer_get_type_silent(C, "id", &RNA_ID).data != NULL;
+ return CTX_data_pointer_get_type_silent(C, "id", &RNA_ID).data != nullptr;
}
diff --git a/source/blender/editors/asset/asset_ops.c b/source/blender/editors/asset/asset_ops.c
deleted file mode 100644
index 29c3174f051..00000000000
--- a/source/blender/editors/asset/asset_ops.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup edasset
- */
-
-#include <string.h>
-
-#include "BKE_asset.h"
-#include "BKE_context.h"
-#include "BKE_report.h"
-
-#include "BLI_listbase.h"
-#include "BLI_string_utils.h"
-#include "BLI_utildefines.h"
-
-#include "DNA_asset_types.h"
-#include "DNA_userdef_types.h"
-
-#include "ED_asset.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-/* -------------------------------------------------------------------- */
-
-struct AssetMarkResultStats {
- int tot_created;
- int tot_already_asset;
- ID *last_id;
-};
-
-static bool asset_ops_poll(bContext *UNUSED(C))
-{
- return U.experimental.use_asset_browser;
-}
-
-/**
- * Return the IDs to operate on as list of #CollectionPointerLink links. Needs freeing.
- */
-static ListBase /* CollectionPointerLink */ asset_operation_get_ids_from_context(const bContext *C)
-{
- ListBase list = {0};
-
- PointerRNA idptr = CTX_data_pointer_get_type(C, "id", &RNA_ID);
-
- if (idptr.data) {
- CollectionPointerLink *ctx_link = MEM_callocN(sizeof(*ctx_link), __func__);
- ctx_link->ptr = idptr;
- BLI_addtail(&list, ctx_link);
- }
- else {
- CTX_data_selected_ids(C, &list);
- }
-
- return list;
-}
-
-static void asset_mark_for_idptr_list(const bContext *C,
- const ListBase /* CollectionPointerLink */ *ids,
- struct AssetMarkResultStats *r_stats)
-{
- memset(r_stats, 0, sizeof(*r_stats));
-
- LISTBASE_FOREACH (CollectionPointerLink *, ctx_id, ids) {
- BLI_assert(RNA_struct_is_ID(ctx_id->ptr.type));
-
- ID *id = ctx_id->ptr.data;
- if (id->asset_data) {
- r_stats->tot_already_asset++;
- continue;
- }
-
- if (ED_asset_mark_id(C, id)) {
- r_stats->last_id = id;
- r_stats->tot_created++;
- }
- }
-}
-
-static bool asset_mark_results_report(const struct AssetMarkResultStats *stats,
- ReportList *reports)
-{
- /* User feedback on failure. */
- if ((stats->tot_created < 1) && (stats->tot_already_asset > 0)) {
- BKE_report(reports,
- RPT_ERROR,
- "Selected data-blocks are already assets (or do not support use as assets)");
- return false;
- }
- if (stats->tot_created < 1) {
- BKE_report(reports,
- RPT_ERROR,
- "No data-blocks to create assets for found (or do not support use as assets)");
- return false;
- }
-
- /* User feedback on success. */
- if (stats->tot_created == 1) {
- /* If only one data-block: Give more useful message by printing asset name. */
- BKE_reportf(reports, RPT_INFO, "Data-block '%s' is now an asset", stats->last_id->name + 2);
- }
- else {
- BKE_reportf(reports, RPT_INFO, "%i data-blocks are now assets", stats->tot_created);
- }
-
- return true;
-}
-
-static int asset_mark_exec(bContext *C, wmOperator *op)
-{
- ListBase ids = asset_operation_get_ids_from_context(C);
-
- struct AssetMarkResultStats stats;
- asset_mark_for_idptr_list(C, &ids, &stats);
- BLI_freelistN(&ids);
-
- if (!asset_mark_results_report(&stats, op->reports)) {
- return OPERATOR_CANCELLED;
- }
-
- WM_main_add_notifier(NC_ID | NA_EDITED, NULL);
- WM_main_add_notifier(NC_ASSET | NA_ADDED, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-static void ASSET_OT_mark(wmOperatorType *ot)
-{
- ot->name = "Mark Asset";
- ot->description =
- "Enable easier reuse of selected data-blocks through the Asset Browser, with the help of "
- "customizable metadata (like previews, descriptions and tags)";
- ot->idname = "ASSET_OT_mark";
-
- ot->exec = asset_mark_exec;
- ot->poll = asset_ops_poll;
-
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
-/* -------------------------------------------------------------------- */
-
-struct AssetClearResultStats {
- int tot_removed;
- ID *last_id;
-};
-
-static void asset_clear_from_idptr_list(const ListBase /* CollectionPointerLink */ *ids,
- struct AssetClearResultStats *r_stats)
-{
- memset(r_stats, 0, sizeof(*r_stats));
-
- LISTBASE_FOREACH (CollectionPointerLink *, ctx_id, ids) {
- BLI_assert(RNA_struct_is_ID(ctx_id->ptr.type));
-
- ID *id = ctx_id->ptr.data;
- if (!id->asset_data) {
- continue;
- }
-
- if (ED_asset_clear_id(id)) {
- r_stats->tot_removed++;
- r_stats->last_id = id;
- }
- }
-}
-
-static bool asset_clear_result_report(const struct AssetClearResultStats *stats,
- ReportList *reports)
-
-{
- if (stats->tot_removed < 1) {
- BKE_report(reports, RPT_ERROR, "No asset data-blocks selected/focused");
- return false;
- }
-
- if (stats->tot_removed == 1) {
- /* If only one data-block: Give more useful message by printing asset name. */
- BKE_reportf(
- reports, RPT_INFO, "Data-block '%s' is no asset anymore", stats->last_id->name + 2);
- }
- else {
- BKE_reportf(reports, RPT_INFO, "%i data-blocks are no assets anymore", stats->tot_removed);
- }
-
- return true;
-}
-
-static int asset_clear_exec(bContext *C, wmOperator *op)
-{
- ListBase ids = asset_operation_get_ids_from_context(C);
-
- struct AssetClearResultStats stats;
- asset_clear_from_idptr_list(&ids, &stats);
- BLI_freelistN(&ids);
-
- if (!asset_clear_result_report(&stats, op->reports)) {
- return OPERATOR_CANCELLED;
- }
-
- WM_main_add_notifier(NC_ID | NA_EDITED, NULL);
- WM_main_add_notifier(NC_ASSET | NA_REMOVED, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-static void ASSET_OT_clear(wmOperatorType *ot)
-{
- ot->name = "Clear Asset";
- ot->description =
- "Delete all asset metadata and turn the selected asset data-blocks back into normal "
- "data-blocks";
- ot->idname = "ASSET_OT_clear";
-
- ot->exec = asset_clear_exec;
- ot->poll = asset_ops_poll;
-
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
-/* -------------------------------------------------------------------- */
-
-void ED_operatortypes_asset(void)
-{
- WM_operatortype_append(ASSET_OT_mark);
- WM_operatortype_append(ASSET_OT_clear);
-}
diff --git a/source/blender/editors/asset/asset_ops.cc b/source/blender/editors/asset/asset_ops.cc
new file mode 100644
index 00000000000..8ca1b488a1d
--- /dev/null
+++ b/source/blender/editors/asset/asset_ops.cc
@@ -0,0 +1,259 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup edasset
+ */
+
+#include "BKE_context.h"
+#include "BKE_report.h"
+
+#include "BLI_vector.hh"
+
+#include "ED_asset.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* -------------------------------------------------------------------- */
+
+using PointerRNAVec = blender::Vector<PointerRNA>;
+
+static bool asset_operation_poll(bContext * /*C*/)
+{
+ return U.experimental.use_asset_browser;
+}
+
+/**
+ * Return the IDs to operate on as PointerRNA vector. Either a single one ("id" context member) or
+ * multiple ones ("selected_ids" context member).
+ */
+static PointerRNAVec asset_operation_get_ids_from_context(const bContext *C)
+{
+ PointerRNAVec ids;
+
+ PointerRNA idptr = CTX_data_pointer_get_type(C, "id", &RNA_ID);
+ if (idptr.data) {
+ /* Single ID. */
+ ids.append(idptr);
+ }
+ else {
+ ListBase list;
+ CTX_data_selected_ids(C, &list);
+ LISTBASE_FOREACH (CollectionPointerLink *, link, &list) {
+ ids.append(link->ptr);
+ }
+ BLI_freelistN(&list);
+ }
+
+ return ids;
+}
+
+/* -------------------------------------------------------------------- */
+
+class AssetMarkHelper {
+ public:
+ void operator()(const bContext &C, PointerRNAVec &ids);
+
+ void reportResults(ReportList &reports) const;
+ bool wasSuccessful() const;
+
+ private:
+ struct Stats {
+ int tot_created = 0;
+ int tot_already_asset = 0;
+ ID *last_id = nullptr;
+ };
+
+ Stats stats;
+};
+
+void AssetMarkHelper::operator()(const bContext &C, PointerRNAVec &ids)
+{
+ for (PointerRNA &ptr : ids) {
+ BLI_assert(RNA_struct_is_ID(ptr.type));
+
+ ID *id = static_cast<ID *>(ptr.data);
+ if (id->asset_data) {
+ stats.tot_already_asset++;
+ continue;
+ }
+
+ if (ED_asset_mark_id(&C, id)) {
+ stats.last_id = id;
+ stats.tot_created++;
+ }
+ }
+}
+
+bool AssetMarkHelper::wasSuccessful() const
+{
+ return stats.tot_created > 0;
+}
+
+void AssetMarkHelper::reportResults(ReportList &reports) const
+{
+ /* User feedback on failure. */
+ if (!wasSuccessful()) {
+ if ((stats.tot_already_asset > 0)) {
+ BKE_report(&reports,
+ RPT_ERROR,
+ "Selected data-blocks are already assets (or do not support use as assets)");
+ }
+ else {
+ BKE_report(&reports,
+ RPT_ERROR,
+ "No data-blocks to create assets for found (or do not support use as assets)");
+ }
+ }
+ /* User feedback on success. */
+ else if (stats.tot_created == 1) {
+ /* If only one data-block: Give more useful message by printing asset name. */
+ BKE_reportf(&reports, RPT_INFO, "Data-block '%s' is now an asset", stats.last_id->name + 2);
+ }
+ else {
+ BKE_reportf(&reports, RPT_INFO, "%i data-blocks are now assets", stats.tot_created);
+ }
+}
+
+static int asset_mark_exec(bContext *C, wmOperator *op)
+{
+ PointerRNAVec ids = asset_operation_get_ids_from_context(C);
+
+ AssetMarkHelper mark_helper;
+ mark_helper(*C, ids);
+ mark_helper.reportResults(*op->reports);
+
+ if (!mark_helper.wasSuccessful()) {
+ return OPERATOR_CANCELLED;
+ }
+
+ WM_main_add_notifier(NC_ID | NA_EDITED, nullptr);
+ WM_main_add_notifier(NC_ASSET | NA_ADDED, nullptr);
+
+ return OPERATOR_FINISHED;
+}
+
+static void ASSET_OT_mark(wmOperatorType *ot)
+{
+ ot->name = "Mark Asset";
+ ot->description =
+ "Enable easier reuse of selected data-blocks through the Asset Browser, with the help of "
+ "customizable metadata (like previews, descriptions and tags)";
+ ot->idname = "ASSET_OT_mark";
+
+ ot->exec = asset_mark_exec;
+ ot->poll = asset_operation_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* -------------------------------------------------------------------- */
+
+class AssetClearHelper {
+ public:
+ void operator()(PointerRNAVec &ids);
+
+ void reportResults(ReportList &reports) const;
+ bool wasSuccessful() const;
+
+ private:
+ struct Stats {
+ int tot_cleared = 0;
+ ID *last_id = nullptr;
+ };
+
+ Stats stats;
+};
+
+void AssetClearHelper::operator()(PointerRNAVec &ids)
+{
+ for (PointerRNA &ptr : ids) {
+ BLI_assert(RNA_struct_is_ID(ptr.type));
+
+ ID *id = static_cast<ID *>(ptr.data);
+ if (!id->asset_data) {
+ continue;
+ }
+
+ if (ED_asset_clear_id(id)) {
+ stats.tot_cleared++;
+ stats.last_id = id;
+ }
+ }
+}
+
+void AssetClearHelper::reportResults(ReportList &reports) const
+{
+ if (!wasSuccessful()) {
+ BKE_report(&reports, RPT_ERROR, "No asset data-blocks selected/focused");
+ }
+ else if (stats.tot_cleared == 1) {
+ /* If only one data-block: Give more useful message by printing asset name. */
+ BKE_reportf(
+ &reports, RPT_INFO, "Data-block '%s' is no asset anymore", stats.last_id->name + 2);
+ }
+ else {
+ BKE_reportf(&reports, RPT_INFO, "%i data-blocks are no assets anymore", stats.tot_cleared);
+ }
+}
+
+bool AssetClearHelper::wasSuccessful() const
+{
+ return stats.tot_cleared > 0;
+}
+
+static int asset_clear_exec(bContext *C, wmOperator *op)
+{
+ PointerRNAVec ids = asset_operation_get_ids_from_context(C);
+
+ AssetClearHelper clear_helper;
+ clear_helper(ids);
+ clear_helper.reportResults(*op->reports);
+
+ if (!clear_helper.wasSuccessful()) {
+ return OPERATOR_CANCELLED;
+ }
+
+ WM_main_add_notifier(NC_ID | NA_EDITED, nullptr);
+ WM_main_add_notifier(NC_ASSET | NA_REMOVED, nullptr);
+
+ return OPERATOR_FINISHED;
+}
+
+static void ASSET_OT_clear(wmOperatorType *ot)
+{
+ ot->name = "Clear Asset";
+ ot->description =
+ "Delete all asset metadata and turn the selected asset data-blocks back into normal "
+ "data-blocks";
+ ot->idname = "ASSET_OT_clear";
+
+ ot->exec = asset_clear_exec;
+ ot->poll = asset_operation_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* -------------------------------------------------------------------- */
+
+void ED_operatortypes_asset(void)
+{
+ WM_operatortype_append(ASSET_OT_mark);
+ WM_operatortype_append(ASSET_OT_clear);
+}
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index e9ceedf7ce2..8ebc2077619 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -2419,7 +2419,7 @@ static void adduplicateflagNurb(
memcpy(newnu->bp, &nu->bp[a], newu * newv * sizeof(BPoint));
memcpy(&newnu->bp[newu * newv], nu->bp, newu * cyclicv * sizeof(BPoint));
- /* check for actvert in cylicv selection */
+ /* check for actvert in cyclicv selection */
if (cu->actnu == i) {
calc_duplicate_actvert(
editnurb, newnurb, cu, cu->actvert, a, (newu * newv) + cu->actvert);
@@ -6102,7 +6102,7 @@ static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split)
}
if (!split && cut != -1 && nu->pntsu > 2 && !(nu->flagu & CU_NURB_CYCLIC)) {
- /* start and points copied if connecting segment was deleted and not cylic spline */
+ /* start and points copied if connecting segment was deleted and not cyclic spline */
bezt1 = nu->bezt;
bezt2 = &nu->bezt[1];
@@ -6232,7 +6232,7 @@ static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split)
}
if (!split && cut != -1 && nu->pntsu > 2 && !(nu->flagu & CU_NURB_CYCLIC)) {
- /* start and points copied if connecting segment was deleted and not cylic spline */
+ /* start and points copied if connecting segment was deleted and not cyclic spline */
bp1 = nu->bp;
bp2 = &nu->bp[1];
@@ -6352,7 +6352,7 @@ static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split)
}
if (!split && cut != -1 && nu->pntsv > 2 && !(nu->flagv & CU_NURB_CYCLIC)) {
- /* start and points copied if connecting segment was deleted and not cylic spline */
+ /* start and points copied if connecting segment was deleted and not cyclic spline */
bp1 = nu->bp;
bp2 = &nu->bp[nu->pntsu];
diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c
index 4097275a2b9..82f7b456284 100644
--- a/source/blender/editors/curve/editcurve_select.c
+++ b/source/blender/editors/curve/editcurve_select.c
@@ -1242,7 +1242,7 @@ static void curve_select_random(ListBase *editnurb, float randfac, int seed, boo
static int curve_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, "percent") / 100.0f;
+ const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
ViewLayer *view_layer = CTX_data_view_layer(C);
diff --git a/source/blender/editors/curve/editcurve_undo.c b/source/blender/editors/curve/editcurve_undo.c
index 534d29c0cc7..681f387e83e 100644
--- a/source/blender/editors/curve/editcurve_undo.c
+++ b/source/blender/editors/curve/editcurve_undo.c
@@ -238,8 +238,11 @@ static bool curve_undosys_step_encode(struct bContext *C, struct Main *bmain, Un
return true;
}
-static void curve_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
+static void curve_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir UNUSED(dir),
+ bool UNUSED(is_final))
{
CurveUndoStep *us = (CurveUndoStep *)us_p;
diff --git a/source/blender/editors/curve/editfont_undo.c b/source/blender/editors/curve/editfont_undo.c
index 8559234b62f..07f062e7a53 100644
--- a/source/blender/editors/curve/editfont_undo.c
+++ b/source/blender/editors/curve/editfont_undo.c
@@ -356,8 +356,11 @@ static bool font_undosys_step_encode(struct bContext *C, struct Main *bmain, Und
return true;
}
-static void font_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
+static void font_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir UNUSED(dir),
+ bool UNUSED(is_final))
{
/* TODO(campbell): undo_system: use low-level API to set mode. */
ED_object_mode_set_ex(C, OB_MODE_EDIT, false, NULL);
diff --git a/source/blender/editors/geometry/geometry_attributes.c b/source/blender/editors/geometry/geometry_attributes.c
index 4106c03f17d..2807e7c4392 100644
--- a/source/blender/editors/geometry/geometry_attributes.c
+++ b/source/blender/editors/geometry/geometry_attributes.c
@@ -23,7 +23,6 @@
#include "BKE_attribute.h"
#include "BKE_context.h"
-#include "BKE_report.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -34,7 +33,6 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "ED_geometry.h"
#include "ED_object.h"
#include "geometry_intern.h"
diff --git a/source/blender/editors/gizmo_library/gizmo_library_presets.c b/source/blender/editors/gizmo_library/gizmo_library_presets.c
index 9039851da01..4e56ceb9fd4 100644
--- a/source/blender/editors/gizmo_library/gizmo_library_presets.c
+++ b/source/blender/editors/gizmo_library/gizmo_library_presets.c
@@ -22,12 +22,9 @@
* \brief Preset shapes that can be drawn from any gizmo type.
*/
-#include "MEM_guardedalloc.h"
-
#include "BLI_math.h"
#include "DNA_object_types.h"
-#include "DNA_view3d_types.h"
#include "BKE_context.h"
@@ -36,12 +33,8 @@
#include "DEG_depsgraph.h"
-#include "RNA_access.h"
-
-#include "WM_api.h"
#include "WM_types.h"
-#include "ED_screen.h"
#include "ED_view3d.h"
/* own includes */
diff --git a/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c
index 5617b6e125e..1b1f1151053 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c
@@ -28,14 +28,11 @@
#include "BKE_context.h"
#include "ED_gizmo_library.h"
-#include "ED_view3d.h"
#include "WM_api.h"
#include "WM_types.h"
/* own includes */
-#include "../gizmo_geometry.h"
-#include "../gizmo_library_intern.h"
static void gizmo_blank_draw(const bContext *UNUSED(C), wmGizmo *UNUSED(gz))
{
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 eb40500d011..cbca230da7e 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
@@ -320,6 +320,16 @@ static int gizmo_button2d_cursor_get(wmGizmo *gz)
return WM_CURSOR_DEFAULT;
}
+static void gizmo_button2d_bounds(bContext *C, wmGizmo *gz, rcti *r_bounding_box)
+{
+ ScrArea *area = CTX_wm_area(C);
+ float rad = CIRCLE_RESOLUTION * U.dpi_fac / 2.0f;
+ r_bounding_box->xmin = gz->matrix_basis[3][0] + area->totrct.xmin - rad;
+ r_bounding_box->ymin = gz->matrix_basis[3][1] + area->totrct.ymin - rad;
+ r_bounding_box->xmax = r_bounding_box->xmin + rad;
+ r_bounding_box->ymax = r_bounding_box->ymin + rad;
+}
+
static void gizmo_button2d_free(wmGizmo *gz)
{
ButtonGizmo2D *shape = (ButtonGizmo2D *)gz;
@@ -346,6 +356,7 @@ static void GIZMO_GT_button_2d(wmGizmoType *gzt)
gzt->draw_select = gizmo_button2d_draw_select;
gzt->test_select = gizmo_button2d_test_select;
gzt->cursor_get = gizmo_button2d_cursor_get;
+ gzt->screen_bounds_get = gizmo_button2d_bounds;
gzt->free = gizmo_button2d_free;
gzt->struct_size = sizeof(ButtonGizmo2D);
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 4e2951c3571..751f8333aaa 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -171,7 +171,8 @@ static void gpencil_draw_stroke_3d(tGPDdraw *tgpw,
int totpoints = tgpw->gps->totpoints;
const float viewport[2] = {(float)tgpw->winx, (float)tgpw->winy};
- float curpressure = points[0].pressure;
+ const float min_thickness = 0.05f;
+
float fpt[3];
/* if cyclic needs more vertex */
@@ -205,7 +206,6 @@ static void gpencil_draw_stroke_3d(tGPDdraw *tgpw,
immUniform1i("fill_stroke", (int)tgpw->is_fill_stroke);
/* draw stroke curve */
- GPU_line_width(max_ff(curpressure * thickness, 1.0f));
immBeginAtMost(GPU_PRIM_LINE_STRIP_ADJ, totpoints + cyclic_add + 2);
const bGPDspoint *pt = points;
@@ -215,18 +215,19 @@ static void gpencil_draw_stroke_3d(tGPDdraw *tgpw,
gpencil_set_point_varying_color(points, ink, attr_id.color, (bool)tgpw->is_fill_stroke);
if ((cyclic) && (totpoints > 2)) {
- immAttr1f(attr_id.thickness, max_ff((points + totpoints - 1)->pressure * thickness, 1.0f));
+ immAttr1f(attr_id.thickness,
+ max_ff((points + totpoints - 1)->pressure * thickness, min_thickness));
mul_v3_m4v3(fpt, tgpw->diff_mat, &(points + totpoints - 1)->x);
}
else {
- immAttr1f(attr_id.thickness, max_ff((points + 1)->pressure * thickness, 1.0f));
+ immAttr1f(attr_id.thickness, max_ff((points + 1)->pressure * thickness, min_thickness));
mul_v3_m4v3(fpt, tgpw->diff_mat, &(points + 1)->x);
}
immVertex3fv(attr_id.pos, fpt);
}
/* set point */
gpencil_set_point_varying_color(pt, ink, attr_id.color, (bool)tgpw->is_fill_stroke);
- immAttr1f(attr_id.thickness, max_ff(pt->pressure * thickness, 1.0f));
+ immAttr1f(attr_id.thickness, max_ff(pt->pressure * thickness, min_thickness));
mul_v3_m4v3(fpt, tgpw->diff_mat, &pt->x);
immVertex3fv(attr_id.pos, fpt);
}
diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c
index aae31b11025..166111c582c 100644
--- a/source/blender/editors/gpencil/editaction_gpencil.c
+++ b/source/blender/editors/gpencil/editaction_gpencil.c
@@ -276,7 +276,7 @@ void ED_gpencil_layer_frames_duplicate(bGPDlayer *gpl)
bGPDframe *gpfd;
/* duplicate frame, and deselect self */
- gpfd = BKE_gpencil_frame_duplicate(gpf);
+ gpfd = BKE_gpencil_frame_duplicate(gpf, true);
gpf->flag &= ~GP_FRAME_SELECT;
BLI_insertlinkafter(&gpl->frames, gpf, gpfd);
@@ -361,7 +361,7 @@ bool ED_gpencil_anim_copybuf_copy(bAnimContext *ac)
/* if frame is selected, make duplicate it and its strokes */
if (gpf->flag & GP_FRAME_SELECT) {
/* make a copy of this frame */
- bGPDframe *new_frame = BKE_gpencil_frame_duplicate(gpf);
+ bGPDframe *new_frame = BKE_gpencil_frame_duplicate(gpf, true);
BLI_addtail(&copied_frames, new_frame);
/* extend extents for keyframes encountered */
diff --git a/source/blender/editors/gpencil/gpencil_add_monkey.c b/source/blender/editors/gpencil/gpencil_add_monkey.c
index 65141442237..d86bad7ef3c 100644
--- a/source/blender/editors/gpencil/gpencil_add_monkey.c
+++ b/source/blender/editors/gpencil/gpencil_add_monkey.c
@@ -29,16 +29,13 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
-#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "ED_gpencil.h"
diff --git a/source/blender/editors/gpencil/gpencil_add_stroke.c b/source/blender/editors/gpencil/gpencil_add_stroke.c
index 0c8cc621a3b..1e1a70f9c1d 100644
--- a/source/blender/editors/gpencil/gpencil_add_stroke.c
+++ b/source/blender/editors/gpencil/gpencil_add_stroke.c
@@ -29,16 +29,13 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
-#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "ED_gpencil.h"
diff --git a/source/blender/editors/gpencil/gpencil_armature.c b/source/blender/editors/gpencil/gpencil_armature.c
index 5cc5e7ecdcd..3271096c433 100644
--- a/source/blender/editors/gpencil/gpencil_armature.c
+++ b/source/blender/editors/gpencil/gpencil_armature.c
@@ -31,12 +31,9 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLT_translation.h"
-
#include "DNA_armature_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_meshdata_types.h"
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index 09b57029350..ac75ae44c8a 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -178,7 +178,7 @@ static void gpencil_strokepoint_convertcoords(bContext *C,
/* apply parent transform */
float fpt[3];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
mul_v3_m4v3(fpt, diff_mat, &source_pt->x);
copy_v3_v3(&pt->x, fpt);
@@ -370,7 +370,7 @@ static int gpencil_find_end_of_stroke_idx(tGpTimingData *gtd,
static void gpencil_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd,
RNG *rng,
int *nbr_gaps,
- float *tot_gaps_time)
+ float *r_tot_gaps_time)
{
float delta_time = 0.0f;
@@ -387,10 +387,10 @@ static void gpencil_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd,
}
gtd->tot_time -= delta_time;
- *tot_gaps_time = (float)(*nbr_gaps) * gtd->gap_duration;
- gtd->tot_time += *tot_gaps_time;
+ *r_tot_gaps_time = (float)(*nbr_gaps) * gtd->gap_duration;
+ gtd->tot_time += *r_tot_gaps_time;
if (G.debug & G_DEBUG) {
- printf("%f, %f, %f, %d\n", gtd->tot_time, delta_time, *tot_gaps_time, *nbr_gaps);
+ printf("%f, %f, %f, %d\n", gtd->tot_time, delta_time, *r_tot_gaps_time, *nbr_gaps);
}
if (gtd->gap_randomness > 0.0f) {
BLI_rng_srandom(rng, gtd->seed);
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index ad9b72b713e..3be913f342d 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -449,21 +449,32 @@ void GPENCIL_OT_layer_annotation_move(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
}
/* ********************* Duplicate Layer ************************** */
+enum {
+ GP_LAYER_DUPLICATE_ALL = 0,
+ GP_LAYER_DUPLICATE_EMPTY = 1,
+};
-static int gpencil_layer_copy_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_layer_copy_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
bGPDlayer *new_layer;
-
+ const int mode = RNA_enum_get(op->ptr, "mode");
+ const bool dup_strokes = (bool)(mode == GP_LAYER_DUPLICATE_ALL);
/* sanity checks */
if (ELEM(NULL, gpd, gpl)) {
return OPERATOR_CANCELLED;
}
- /* make copy of layer, and add it immediately after the existing layer */
- new_layer = BKE_gpencil_layer_duplicate(gpl);
- BLI_insertlinkafter(&gpd->layers, gpl, new_layer);
+ /* Make copy of layer, and add it immediately after or before the existing layer. */
+ new_layer = BKE_gpencil_layer_duplicate(gpl, true, dup_strokes);
+ if (dup_strokes) {
+ BLI_insertlinkafter(&gpd->layers, gpl, new_layer);
+ }
+ else {
+ /* For empty strokes is better add below. */
+ BLI_insertlinkbefore(&gpd->layers, gpl, new_layer);
+ }
/* ensure new layer has a unique name, and is now the active layer */
BLI_uniquename(&gpd->layers,
@@ -484,6 +495,12 @@ static int gpencil_layer_copy_exec(bContext *C, wmOperator *UNUSED(op))
void GPENCIL_OT_layer_duplicate(wmOperatorType *ot)
{
+ static const EnumPropertyItem copy_mode[] = {
+ {GP_LAYER_DUPLICATE_ALL, "ALL", 0, "All Data", ""},
+ {GP_LAYER_DUPLICATE_EMPTY, "EMPTY", 0, "Empty Keyframes", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
/* identifiers */
ot->name = "Duplicate Layer";
ot->idname = "GPENCIL_OT_layer_duplicate";
@@ -495,6 +512,8 @@ void GPENCIL_OT_layer_duplicate(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "mode", copy_mode, GP_LAYER_DUPLICATE_ALL, "Mode", "");
}
/* ********************* Duplicate Layer in a new object ************************** */
@@ -1560,7 +1579,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* some stroke is already at front*/
@@ -1725,7 +1744,7 @@ static int gpencil_stroke_change_color_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
@@ -2849,12 +2868,12 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
mul_v3_m3v3(offset_local, imat, offset_global);
LISTBASE_FOREACH (bGPDlayer *, gpl_src, &gpd_src->layers) {
- bGPDlayer *gpl_new = BKE_gpencil_layer_duplicate(gpl_src);
+ bGPDlayer *gpl_new = BKE_gpencil_layer_duplicate(gpl_src, true, true);
float diff_mat[4][4];
float inverse_diff_mat[4][4];
/* recalculate all stroke points */
- BKE_gpencil_parent_matrix_get(depsgraph, ob_iter, gpl_src, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob_iter, gpl_src, diff_mat);
invert_m4_m4_safe_ortho(inverse_diff_mat, diff_mat);
Material *ma_src = NULL;
@@ -3388,7 +3407,7 @@ static int gpencil_material_select_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index d1c8eca1be0..aeff2acb04d 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -1867,7 +1867,7 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op)
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
@@ -2610,7 +2610,7 @@ static int gpencil_delete_selected_points(bContext *C)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
@@ -2800,7 +2800,7 @@ static int gpencil_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
float diff_mat[4][4];
/* calculate difference matrix object */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
/* skip strokes that are invalid for current view */
@@ -2808,7 +2808,7 @@ static int gpencil_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
@@ -2935,7 +2935,7 @@ static int gpencil_snap_to_cursor(bContext *C, wmOperator *op)
float diff_mat[4][4];
/* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
bGPDspoint *pt;
@@ -2946,7 +2946,7 @@ static int gpencil_snap_to_cursor(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
@@ -3039,7 +3039,7 @@ static bool gpencil_stroke_points_centroid(Depsgraph *depsgraph,
float diff_mat[4][4];
/* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
bGPDspoint *pt;
@@ -3050,7 +3050,7 @@ static bool gpencil_stroke_points_centroid(Depsgraph *depsgraph,
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
@@ -3565,7 +3565,7 @@ static int gpencil_stroke_join_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable. */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
elem = &strokes_list[tot_strokes];
@@ -3697,7 +3697,7 @@ static int gpencil_stroke_flip_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
@@ -4516,7 +4516,7 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* Separate selected strokes. */
@@ -4717,7 +4717,7 @@ static int gpencil_stroke_split_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* Split selected strokes. */
@@ -4948,11 +4948,14 @@ static int gpencil_cutter_lasso_select(bContext *C,
GPencilTestFn is_inside_fn,
void *user_data)
{
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Object *obact = CTX_data_active_object(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
ScrArea *area = CTX_wm_area(C);
ToolSettings *ts = CTX_data_tool_settings(C);
const float scale = ts->gp_sculpt.isect_threshold;
const bool flat_caps = RNA_boolean_get(op->ptr, "flat_caps");
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
bGPDspoint *pt;
GP_SpaceConversion gsc = {NULL};
@@ -4979,57 +4982,87 @@ static int gpencil_cutter_lasso_select(bContext *C,
}
CTX_DATA_END;
- /* select points */
- GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
- int tot_inside = 0;
- const int oldtot = gps->totpoints;
- for (int i = 0; i < gps->totpoints; i++) {
- pt = &gps->points[i];
- if ((pt->flag & GP_SPOINT_SELECT) || (pt->flag & GP_SPOINT_TAG)) {
- continue;
- }
- /* convert point coords to screen-space */
- const bool is_inside = is_inside_fn(gps, pt, &gsc, gpstroke_iter.diff_mat, user_data);
- if (is_inside) {
- tot_inside++;
- changed = true;
- pt->flag |= GP_SPOINT_SELECT;
- gps->flag |= GP_STROKE_SELECT;
- float r_hita[3], r_hitb[3];
- if (gps->totpoints > 1) {
- ED_gpencil_select_stroke_segment(gpd, gpl, gps, pt, true, true, scale, r_hita, r_hitb);
+ /* Select points */
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ if ((gpl->flag & GP_LAYER_LOCKED) || ((gpl->flag & GP_LAYER_HIDE))) {
+ continue;
+ }
+
+ float diff_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+
+ 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) {
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ } /* check if the color is editable */
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
+ continue;
+ }
+ int tot_inside = 0;
+ const int oldtot = gps->totpoints;
+ for (int i = 0; i < gps->totpoints; i++) {
+ pt = &gps->points[i];
+ if ((pt->flag & GP_SPOINT_SELECT) || (pt->flag & GP_SPOINT_TAG)) {
+ continue;
+ }
+ /* convert point coords to screen-space */
+ const bool is_inside = is_inside_fn(gps, pt, &gsc, diff_mat, user_data);
+ if (is_inside) {
+ tot_inside++;
+ changed = true;
+ pt->flag |= GP_SPOINT_SELECT;
+ gps->flag |= GP_STROKE_SELECT;
+ float r_hita[3], r_hitb[3];
+ if (gps->totpoints > 1) {
+ ED_gpencil_select_stroke_segment(
+ gpd, gpl, gps, pt, true, true, scale, r_hita, r_hitb);
+ }
+ /* avoid infinite loops */
+ if (gps->totpoints > oldtot) {
+ break;
+ }
+ }
+ }
+ /* if mark all points inside lasso set to remove all stroke */
+ if ((tot_inside == oldtot) || ((tot_inside == 1) && (oldtot == 2))) {
+ for (int i = 0; i < gps->totpoints; i++) {
+ pt = &gps->points[i];
+ pt->flag |= GP_SPOINT_SELECT;
+ }
+ }
}
- /* avoid infinite loops */
- if (gps->totpoints > oldtot) {
+ /* if not multiedit, exit loop. */
+ if (!is_multiedit) {
break;
}
}
}
- /* if mark all points inside lasso set to remove all stroke */
- if ((tot_inside == oldtot) || ((tot_inside == 1) && (oldtot == 2))) {
- for (int i = 0; i < gps->totpoints; i++) {
- pt = &gps->points[i];
- pt->flag |= GP_SPOINT_SELECT;
- }
- }
}
- GP_EDITABLE_STROKES_END(gpstroke_iter);
- /* dissolve selected points */
+ /* Dissolve selected points. */
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- if (gpl->flag & GP_LAYER_LOCKED) {
- continue;
- }
-
- bGPDframe *gpf = gpl->actframe;
- if (gpf == NULL) {
- continue;
- }
- LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
- if (gps->flag & GP_STROKE_SELECT) {
- gpencil_cutter_dissolve(gpd, gpl, gps, flat_caps);
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
+ bGPDframe *gpf_act = gpl->actframe;
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ gpl->actframe = gpf;
+ LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
+ if (gps->flag & GP_STROKE_SELECT) {
+ gpencil_cutter_dissolve(gpd, gpl, gps, flat_caps);
+ }
+ }
+ /* if not multiedit, exit loop. */
+ if (!is_multiedit) {
+ break;
}
}
+ gpl->actframe = gpf_act;
}
/* updates */
diff --git a/source/blender/editors/gpencil/gpencil_edit_curve.c b/source/blender/editors/gpencil/gpencil_edit_curve.c
index 60d1d2169b4..031bbd61173 100644
--- a/source/blender/editors/gpencil/gpencil_edit_curve.c
+++ b/source/blender/editors/gpencil/gpencil_edit_curve.c
@@ -28,13 +28,10 @@
#include <stdlib.h>
#include <string.h>
-#include "MEM_guardedalloc.h"
-
#include "DNA_gpencil_types.h"
#include "DNA_view3d_types.h"
#include "BKE_context.h"
-#include "BKE_curve.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_curve.h"
#include "BKE_gpencil_geom.h"
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 8bd0b2f86de..832191c8321 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_stack.h"
#include "BLI_utildefines.h"
@@ -81,8 +82,18 @@
#define LEAK_HORZ 0
#define LEAK_VERT 1
+#define MIN_WINDOW_SIZE 128
-/* Temporary fill operation data (op->customdata) */
+/* Set to 1 to debug filling internal image. By default, the value must be 0. */
+#define FILL_DEBUG 0
+
+/* Duplicated: etempFlags */
+enum {
+ GP_DRAWFILLS_NOSTATUS = (1 << 0), /* don't draw status info */
+ GP_DRAWFILLS_ONLY3D = (1 << 1), /* only draw 3d-strokes */
+};
+
+/* Temporary fill operation data `op->customdata`. */
typedef struct tGPDfill {
bContext *C;
struct Main *bmain;
@@ -101,7 +112,7 @@ typedef struct tGPDfill {
struct View3D *v3d;
/** region where painting originated */
struct ARegion *region;
- /** current GP datablock */
+ /** Current GP data-block. */
struct bGPdata *gpd;
/** current material */
struct Material *mat;
@@ -111,6 +122,8 @@ typedef struct tGPDfill {
struct bGPDlayer *gpl;
/** frame */
struct bGPDframe *gpf;
+ /** Temp mouse position stroke. */
+ struct bGPDstroke *gps_mouse;
/** flags */
short flag;
@@ -118,9 +131,12 @@ typedef struct tGPDfill {
short oldkey;
/** send to back stroke */
bool on_back;
-
+ /** Flag for render mode */
+ bool is_render;
+ /** Flag to check something was done. */
+ bool done;
/** mouse fill center position */
- int center[2];
+ int mouse[2];
/** windows width */
int sizex;
/** window height */
@@ -137,7 +153,7 @@ typedef struct tGPDfill {
/** boundary limits drawing mode */
int fill_draw_mode;
/* scaling factor */
- short fill_factor;
+ float fill_factor;
/* Frame to use. */
int active_cfra;
@@ -156,14 +172,184 @@ typedef struct tGPDfill {
/** handle for drawing strokes while operator is running 3d stuff */
void *draw_handle_3d;
- /* tmp size x */
+ /* Temporary size x. */
int bwinx;
- /* tmp size y */
+ /* Temporary size y. */
int bwiny;
rcti brect;
+ /* Space Conversion Data */
+ GP_SpaceConversion gsc;
+
+ /** Zoom factor. */
+ float zoom;
+
+ /** Factor of extension. */
+ float fill_extend_fac;
+
} tGPDfill;
+bool skip_layer_check(short fill_layer_mode, int gpl_active_index, int gpl_index);
+static void gpencil_draw_boundary_lines(const struct bContext *UNUSED(C), struct tGPDfill *tgpf);
+
+/* Delete any temporary stroke. */
+static void gpencil_delete_temp_stroke_extension(tGPDfill *tgpf, const bool all_frames)
+{
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &tgpf->gpd->layers) {
+ if (gpl->flag & GP_LAYER_HIDE) {
+ continue;
+ }
+
+ bGPDframe *init_gpf = (all_frames) ? gpl->frames.first :
+ BKE_gpencil_layer_frame_get(
+ gpl, tgpf->active_cfra, GP_GETFRAME_USE_PREV);
+ if (init_gpf == NULL) {
+ continue;
+ }
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
+ /* free stroke */
+ if ((gps->flag & GP_STROKE_NOFILL) && (gps->flag & GP_STROKE_TAG)) {
+ BLI_remlink(&gpf->strokes, gps);
+ BKE_gpencil_free_stroke(gps);
+ }
+ }
+ if (!all_frames) {
+ break;
+ }
+ }
+ }
+}
+
+static void extrapolate_points_by_length(bGPDspoint *a,
+ bGPDspoint *b,
+ float length,
+ float r_point[3])
+{
+ float ab[3];
+ sub_v3_v3v3(ab, &b->x, &a->x);
+ normalize_v3(ab);
+ mul_v3_fl(ab, length);
+ add_v3_v3v3(r_point, &b->x, ab);
+}
+
+/* Loop all layers create stroke extensions. */
+static void gpencil_create_extensions(tGPDfill *tgpf)
+{
+ Object *ob = tgpf->ob;
+ bGPdata *gpd = tgpf->gpd;
+ Brush *brush = tgpf->brush;
+ BrushGpencilSettings *brush_settings = brush->gpencil_settings;
+
+ bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd);
+ BLI_assert(gpl_active != NULL);
+
+ const int gpl_active_index = BLI_findindex(&gpd->layers, gpl_active);
+ BLI_assert(gpl_active_index >= 0);
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ if (gpl->flag & GP_LAYER_HIDE) {
+ continue;
+ }
+
+ /* Decide if the strokes of layers are included or not depending on the layer mode. */
+ const int gpl_index = BLI_findindex(&gpd->layers, gpl);
+ bool skip = skip_layer_check(brush_settings->fill_layer_mode, gpl_active_index, gpl_index);
+ if (skip) {
+ continue;
+ }
+
+ bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, tgpf->active_cfra, GP_GETFRAME_USE_PREV);
+ if (gpf == NULL) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ /* Check if stroke can be drawn. */
+ if ((gps->points == NULL) || (gps->totpoints < 2)) {
+ continue;
+ }
+ if (gps->flag & (GP_STROKE_NOFILL | GP_STROKE_TAG)) {
+ continue;
+ }
+ /* Check if the color is visible. */
+ MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
+ if ((gp_style == NULL) || (gp_style->flag & GP_MATERIAL_HIDE)) {
+ continue;
+ }
+
+ /* Extend start. */
+ bGPDspoint *pt0 = &gps->points[1];
+ bGPDspoint *pt1 = &gps->points[0];
+ bGPDstroke *gps_new = BKE_gpencil_stroke_new(gps->mat_nr, 2, gps->thickness);
+ gps_new->flag |= GP_STROKE_NOFILL | GP_STROKE_TAG;
+ BLI_addtail(&gpf->strokes, gps_new);
+
+ bGPDspoint *pt = &gps_new->points[0];
+ copy_v3_v3(&pt->x, &pt1->x);
+ pt->strength = 1.0f;
+ pt->pressure = 1.0f;
+
+ pt = &gps_new->points[1];
+ pt->strength = 1.0f;
+ pt->pressure = 1.0f;
+ extrapolate_points_by_length(pt0, pt1, tgpf->fill_extend_fac * 0.1f, &pt->x);
+
+ /* Extend end. */
+ pt0 = &gps->points[gps->totpoints - 2];
+ pt1 = &gps->points[gps->totpoints - 1];
+ gps_new = BKE_gpencil_stroke_new(gps->mat_nr, 2, gps->thickness);
+ gps_new->flag |= GP_STROKE_NOFILL | GP_STROKE_TAG;
+ BLI_addtail(&gpf->strokes, gps_new);
+
+ pt = &gps_new->points[0];
+ copy_v3_v3(&pt->x, &pt1->x);
+ pt->strength = 1.0f;
+ pt->pressure = 1.0f;
+
+ pt = &gps_new->points[1];
+ pt->strength = 1.0f;
+ pt->pressure = 1.0f;
+ extrapolate_points_by_length(pt0, pt1, tgpf->fill_extend_fac * 0.1f, &pt->x);
+ }
+ }
+}
+
+static void gpencil_update_extend(tGPDfill *tgpf)
+{
+ gpencil_delete_temp_stroke_extension(tgpf, false);
+
+ if (tgpf->fill_extend_fac > 0.0f) {
+ gpencil_create_extensions(tgpf);
+ }
+ WM_event_add_notifier(tgpf->C, NC_GPENCIL | NA_EDITED, NULL);
+}
+
+static bool gpencil_stroke_is_drawable(tGPDfill *tgpf, bGPDstroke *gps)
+{
+ if (tgpf->is_render) {
+ return true;
+ }
+
+ const bool show_help = (tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) != 0;
+ const bool show_extend = (tgpf->flag & GP_BRUSH_FILL_SHOW_EXTENDLINES) != 0;
+ const bool is_extend = (gps->flag & GP_STROKE_NOFILL) && (gps->flag & GP_STROKE_TAG);
+
+ if ((!show_help) && (show_extend)) {
+ if (!is_extend) {
+ return false;
+ }
+ }
+
+ if ((show_help) && (!show_extend)) {
+ if (is_extend) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
/* draw a given stroke using same thickness and color for all points */
static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
bGPDstroke *gps,
@@ -171,7 +357,8 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
const bool cyclic,
const float ink[4],
const int flag,
- const float thershold)
+ const float thershold,
+ const float thickness)
{
bGPDspoint *points = gps->points;
@@ -181,9 +368,19 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
int totpoints = gps->totpoints;
float fpt[3];
float col[4];
+ const float extend_col[4] = {0.0f, 1.0f, 1.0f, 1.0f};
+ const bool is_extend = (gps->flag & GP_STROKE_NOFILL) && (gps->flag & GP_STROKE_TAG);
- copy_v4_v4(col, ink);
+ if (!gpencil_stroke_is_drawable(tgpf, gps)) {
+ return;
+ }
+ if ((is_extend) && (!tgpf->is_render)) {
+ copy_v4_v4(col, extend_col);
+ }
+ else {
+ copy_v4_v4(col, ink);
+ }
/* if cyclic needs more vertex */
int cyclic_add = (cyclic) ? 1 : 0;
@@ -194,7 +391,7 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
/* draw stroke curve */
- GPU_line_width(1.0f);
+ GPU_line_width((!is_extend) ? thickness : thickness * 2.0f);
immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints + cyclic_add);
const bGPDspoint *pt = points;
@@ -225,15 +422,77 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
immUnbindProgram();
}
-/* loop all layers */
-static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
+static void draw_mouse_position(tGPDfill *tgpf)
{
- /* duplicated: etempFlags */
- enum {
- GP_DRAWFILLS_NOSTATUS = (1 << 0), /* don't draw status info */
- GP_DRAWFILLS_ONLY3D = (1 << 1), /* only draw 3d-strokes */
- };
+ if (tgpf->gps_mouse == NULL) {
+ return;
+ }
+ uchar mouse_color[4] = {0, 0, 255, 255};
+ bGPDspoint *pt = &tgpf->gps_mouse->points[0];
+ float point_size = (tgpf->zoom == 1.0f) ? 4.0f * tgpf->fill_factor :
+ (0.5f * tgpf->zoom) + tgpf->fill_factor;
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+
+ /* Draw mouse click position in Blue. */
+ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
+ GPU_point_size(point_size);
+ immBegin(GPU_PRIM_POINTS, 1);
+ immAttr4ubv(col, mouse_color);
+ immVertex3fv(pos, &pt->x);
+ immEnd();
+ immUnbindProgram();
+}
+
+/* Helper: Check if must skip the layer */
+bool skip_layer_check(short fill_layer_mode, int gpl_active_index, int gpl_index)
+{
+ bool skip = false;
+
+ switch (fill_layer_mode) {
+ case GP_FILL_GPLMODE_ACTIVE: {
+ if (gpl_index != gpl_active_index) {
+ skip = true;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_ABOVE: {
+ if (gpl_index != gpl_active_index + 1) {
+ skip = true;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_BELOW: {
+ if (gpl_index != gpl_active_index - 1) {
+ skip = true;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_ALL_ABOVE: {
+ if (gpl_index <= gpl_active_index) {
+ skip = true;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_ALL_BELOW: {
+ if (gpl_index >= gpl_active_index) {
+ skip = true;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_VISIBLE:
+ default:
+ break;
+ }
+
+ return skip;
+}
+
+/* Loop all layers to draw strokes. */
+static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
+{
Object *ob = tgpf->ob;
bGPdata *gpd = tgpf->gpd;
Brush *brush = tgpf->brush;
@@ -247,8 +506,8 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
tgpw.gpd = gpd;
tgpw.offsx = 0;
tgpw.offsy = 0;
- tgpw.winx = tgpf->region->winx;
- tgpw.winy = tgpf->region->winy;
+ tgpw.winx = tgpf->sizex;
+ tgpw.winy = tgpf->sizey;
tgpw.dflag = 0;
tgpw.disable_fill = 1;
tgpw.dflag |= (GP_DRAWFILLS_ONLY3D | GP_DRAWFILLS_NOSTATUS);
@@ -261,54 +520,22 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
const int gpl_active_index = BLI_findindex(&gpd->layers, gpl_active);
BLI_assert(gpl_active_index >= 0);
- LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- /* calculate parent position */
- BKE_gpencil_parent_matrix_get(tgpw.depsgraph, ob, gpl, tgpw.diff_mat);
+ /* Draw blue point where click with mouse. */
+ draw_mouse_position(tgpf);
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* do not draw layer if hidden */
if (gpl->flag & GP_LAYER_HIDE) {
continue;
}
+ /* calculate parent position */
+ BKE_gpencil_layer_transform_matrix_get(tgpw.depsgraph, ob, gpl, tgpw.diff_mat);
+
/* Decide if the strokes of layers are included or not depending on the layer mode.
* Cannot skip the layer because it can use boundary strokes and must be used. */
- bool skip = false;
const int gpl_index = BLI_findindex(&gpd->layers, gpl);
- switch (brush_settings->fill_layer_mode) {
- case GP_FILL_GPLMODE_ACTIVE: {
- if (gpl_index != gpl_active_index) {
- skip = true;
- }
- break;
- }
- case GP_FILL_GPLMODE_ABOVE: {
- if (gpl_index != gpl_active_index + 1) {
- skip = true;
- }
- break;
- }
- case GP_FILL_GPLMODE_BELOW: {
- if (gpl_index != gpl_active_index - 1) {
- skip = true;
- }
- break;
- }
- case GP_FILL_GPLMODE_ALL_ABOVE: {
- if (gpl_index <= gpl_active_index) {
- skip = true;
- }
- break;
- }
- case GP_FILL_GPLMODE_ALL_BELOW: {
- if (gpl_index >= gpl_active_index) {
- skip = true;
- }
- break;
- }
- case GP_FILL_GPLMODE_VISIBLE:
- default:
- break;
- }
+ bool skip = skip_layer_check(brush_settings->fill_layer_mode, gpl_active_index, gpl_index);
/* if active layer and no keyframe, create a new one */
if (gpl == tgpf->gpl) {
@@ -351,17 +578,19 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
tgpw.gpf = gpf;
tgpw.t_gpf = gpf;
- /* reduce thickness to avoid gaps */
tgpw.is_fill_stroke = (tgpf->fill_draw_mode == GP_FILL_DMODE_CONTROL) ? false : true;
+ /* Reduce thickness to avoid gaps. */
tgpw.lthick = gpl->line_change;
tgpw.opacity = 1.0;
copy_v4_v4(tgpw.tintcolor, ink);
tgpw.onion = true;
tgpw.custonion = true;
- /* normal strokes */
+ /* Normal strokes. */
if (ELEM(tgpf->fill_draw_mode, GP_FILL_DMODE_STROKE, GP_FILL_DMODE_BOTH)) {
- ED_gpencil_draw_fill(&tgpw);
+ if (gpencil_stroke_is_drawable(tgpf, gps) && ((gps->flag & GP_STROKE_TAG) == 0)) {
+ ED_gpencil_draw_fill(&tgpw);
+ }
}
/* 3D Lines with basic shapes and invisible lines */
@@ -372,7 +601,8 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
gps->flag & GP_STROKE_CYCLIC,
ink,
tgpf->flag,
- tgpf->fill_threshold);
+ tgpf->fill_threshold,
+ 1.0f);
}
}
}
@@ -380,7 +610,7 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
GPU_blend(GPU_BLEND_NONE);
}
-/* draw strokes in offscreen buffer */
+/* Draw strokes in off-screen buffer. */
static bool gpencil_render_offscreen(tGPDfill *tgpf)
{
bool is_ortho = false;
@@ -391,15 +621,15 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
}
/* set temporary new size */
- tgpf->bwinx = tgpf->region->winx;
- tgpf->bwiny = tgpf->region->winy;
+ tgpf->bwinx = tgpf->region->sizex;
+ tgpf->bwiny = tgpf->region->sizey;
tgpf->brect = tgpf->region->winrct;
/* resize region */
tgpf->region->winrct.xmin = 0;
tgpf->region->winrct.ymin = 0;
- tgpf->region->winrct.xmax = (int)tgpf->region->winx * tgpf->fill_factor;
- tgpf->region->winrct.ymax = (int)tgpf->region->winy * tgpf->fill_factor;
+ tgpf->region->winrct.xmax = max_ii((int)tgpf->region->winx * tgpf->fill_factor, MIN_WINDOW_SIZE);
+ tgpf->region->winrct.ymax = max_ii((int)tgpf->region->winy * tgpf->fill_factor, MIN_WINDOW_SIZE);
tgpf->region->winx = (short)abs(tgpf->region->winrct.xmax - tgpf->region->winrct.xmin);
tgpf->region->winy = (short)abs(tgpf->region->winrct.ymax - tgpf->region->winrct.ymin);
@@ -407,12 +637,6 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
tgpf->sizex = (int)tgpf->region->winx;
tgpf->sizey = (int)tgpf->region->winy;
- /* adjust center */
- float center[2];
- center[0] = (float)tgpf->center[0] * ((float)tgpf->region->winx / (float)tgpf->bwinx);
- center[1] = (float)tgpf->center[1] * ((float)tgpf->region->winy / (float)tgpf->bwiny);
- round_v2i_v2fl(tgpf->center, center);
-
char err_out[256] = "unknown";
GPUOffScreen *offscreen = GPU_offscreen_create(tgpf->sizex, tgpf->sizey, true, false, err_out);
if (offscreen == NULL) {
@@ -421,7 +645,7 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
}
GPU_offscreen_bind(offscreen, true);
- uint flag = IB_rect | IB_rectfloat;
+ uint flag = IB_rectfloat;
ImBuf *ibuf = IMB_allocImBuf(tgpf->sizex, tgpf->sizey, 32, flag);
rctf viewplane;
@@ -436,6 +660,21 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
&clip_start,
&clip_end,
NULL);
+
+ /* Rescale `viewplane` to fit all strokes. */
+ float width = viewplane.xmax - viewplane.xmin;
+ float height = viewplane.ymax - viewplane.ymin;
+
+ float width_new = width * tgpf->zoom;
+ float height_new = height * tgpf->zoom;
+ float scale_x = (width_new - width) / 2.0f;
+ float scale_y = (height_new - height) / 2.0f;
+
+ viewplane.xmin -= scale_x;
+ viewplane.xmax += scale_x;
+ viewplane.ymin -= scale_y;
+ viewplane.ymax += scale_y;
+
if (is_ortho) {
orthographic_m4(winmat,
viewplane.xmin,
@@ -456,7 +695,7 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
}
GPU_matrix_push_projection();
- GPU_matrix_identity_set();
+ GPU_matrix_identity_projection_set();
GPU_matrix_push();
GPU_matrix_identity_set();
@@ -495,45 +734,33 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
BKE_image_release_ibuf(tgpf->ima, ibuf, NULL);
- /* switch back to window-system-provided framebuffer */
+ /* Switch back to window-system-provided frame-buffer. */
GPU_offscreen_unbind(offscreen, true);
GPU_offscreen_free(offscreen);
return true;
}
-/* return pixel data (rgba) at index */
+/* Return pixel data (RGBA) at index. */
static void get_pixel(const ImBuf *ibuf, const int idx, float r_col[4])
{
- if (ibuf->rect_float) {
- const float *frgba = &ibuf->rect_float[idx * 4];
- copy_v4_v4(r_col, frgba);
- }
- else {
- /* XXX: This case probably doesn't happen, as we only write to the float buffer,
- * but we get compiler warnings about uninitialized vars otherwise
- */
- BLI_assert(!"gpencil_fill.c - get_pixel() non-float case is used!");
- zero_v4(r_col);
- }
+ BLI_assert(ibuf->rect_float != NULL);
+ memcpy(r_col, &ibuf->rect_float[idx * 4], sizeof(float[4]));
}
-/* set pixel data (rgba) at index */
+/* Set pixel data (RGBA) at index. */
static void set_pixel(ImBuf *ibuf, int idx, const float col[4])
{
- // BLI_assert(idx <= ibuf->x * ibuf->y);
- if (ibuf->rect) {
- uint *rrect = &ibuf->rect[idx];
- uchar ccol[4];
-
- rgba_float_to_uchar(ccol, col);
- *rrect = *((uint *)ccol);
- }
+ BLI_assert(ibuf->rect_float != NULL);
+ float *rrectf = &ibuf->rect_float[idx * 4];
+ copy_v4_v4(rrectf, col);
+}
- if (ibuf->rect_float) {
- float *rrectf = &ibuf->rect_float[idx * 4];
- copy_v4_v4(rrectf, col);
- }
+/* Helper: Check if one image row is empty. */
+static bool is_row_filled(const ImBuf *ibuf, const int row_index)
+{
+ float *row = &ibuf->rect_float[ibuf->x * 4 * row_index];
+ return (row[0] == 0.0f && memcmp(row, row + 1, ((ibuf->x * 4) - 1) * sizeof(float)) != 0);
}
/**
@@ -541,6 +768,9 @@ static void set_pixel(ImBuf *ibuf, int idx, const float col[4])
* this is used for strokes with small gaps between them to get a full fill
* and do not get a full screen fill.
*
+ * This function assumes that if the furthest pixel is occupied,
+ * the other pixels are occupied.
+ *
* \param ibuf: Image pixel data.
* \param maxpixel: Maximum index.
* \param limit: Limit of pixels to analyze.
@@ -550,10 +780,10 @@ static void set_pixel(ImBuf *ibuf, int idx, const float col[4])
static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index, int type)
{
float rgba[4];
- int i;
int pt;
bool t_a = false;
bool t_b = false;
+ const int extreme = limit - 1;
/* Horizontal leak (check vertical pixels)
* X
@@ -564,37 +794,29 @@ static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index
*/
if (type == LEAK_HORZ) {
/* pixels on top */
- for (i = 1; i <= limit; i++) {
- pt = index + (ibuf->x * i);
- if (pt <= maxpixel) {
- get_pixel(ibuf, pt, rgba);
- if (rgba[0] == 1.0f) {
- t_a = true;
- break;
- }
- }
- else {
- /* edge of image*/
+ pt = index + (ibuf->x * extreme);
+ if (pt <= maxpixel) {
+ get_pixel(ibuf, pt, rgba);
+ if (rgba[0] == 1.0f) {
t_a = true;
- break;
}
}
+ else {
+ /* edge of image*/
+ t_a = true;
+ }
/* pixels on bottom */
- for (i = 1; i <= limit; i++) {
- pt = index - (ibuf->x * i);
- if (pt >= 0) {
- get_pixel(ibuf, pt, rgba);
- if (rgba[0] == 1.0f) {
- t_b = true;
- break;
- }
- }
- else {
- /* edge of image*/
+ pt = index - (ibuf->x * extreme);
+ if (pt >= 0) {
+ get_pixel(ibuf, pt, rgba);
+ if (rgba[0] == 1.0f) {
t_b = true;
- break;
}
}
+ else {
+ /* edge of image*/
+ t_b = true;
+ }
}
/* Vertical leak (check horizontal pixels)
@@ -608,35 +830,27 @@ static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index
int higpix = lowpix + ibuf->x - 1;
/* pixels to right */
- for (i = 0; i < limit; i++) {
- pt = index - (limit - i);
- if (pt >= lowpix) {
- get_pixel(ibuf, pt, rgba);
- if (rgba[0] == 1.0f) {
- t_a = true;
- break;
- }
- }
- else {
- t_a = true; /* edge of image*/
- break;
+ pt = index - extreme;
+ if (pt >= lowpix) {
+ get_pixel(ibuf, pt, rgba);
+ if (rgba[0] == 1.0f) {
+ t_a = true;
}
}
+ else {
+ t_a = true; /* edge of image*/
+ }
/* pixels to left */
- for (i = 0; i < limit; i++) {
- pt = index + (limit - i);
- if (pt <= higpix) {
- get_pixel(ibuf, pt, rgba);
- if (rgba[0] == 1.0f) {
- t_b = true;
- break;
- }
- }
- else {
- t_b = true; /* edge of image */
- break;
+ pt = index + extreme;
+ if (pt <= higpix) {
+ get_pixel(ibuf, pt, rgba);
+ if (rgba[0] == 1.0f) {
+ t_b = true;
}
}
+ else {
+ t_b = true; /* edge of image */
+ }
}
return (bool)(t_a && t_b);
}
@@ -659,23 +873,37 @@ static void gpencil_boundaryfill_area(tGPDfill *tgpf)
BLI_Stack *stack = BLI_stack_new(sizeof(int), __func__);
- /* calculate index of the seed point using the position of the mouse */
- int index = (tgpf->sizex * tgpf->center[1]) + tgpf->center[0];
+ /* Calculate index of the seed point using the position of the mouse looking
+ * for a blue pixel. */
+ int index = -1;
+ for (int i = 0; i < maxpixel; i++) {
+ get_pixel(ibuf, i, rgba);
+ if (rgba[2] == 1.0f) {
+ index = i;
+ break;
+ }
+ }
+
if ((index >= 0) && (index <= maxpixel)) {
- BLI_stack_push(stack, &index);
+ if (!FILL_DEBUG) {
+ BLI_stack_push(stack, &index);
+ }
}
- /* the fill use a stack to save the pixel list instead of the common recursive
+ /**
+ * The fill use a stack to save the pixel list instead of the common recursive
* 4-contact point method.
* The problem with recursive calls is that for big fill areas, we can get max limit
* of recursive calls and STACK_OVERFLOW error.
*
* The 4-contact point analyze the pixels to the left, right, bottom and top
- * -----------
- * | X |
- * | XoX |
- * | X |
- * -----------
+ * <pre>
+ * -----------
+ * | X |
+ * | XoX |
+ * | X |
+ * -----------
+ * </pre>
*/
while (!BLI_stack_is_empty(stack)) {
int v;
@@ -763,7 +991,7 @@ static void gpencil_set_borders(tGPDfill *tgpf, const bool transparent)
tgpf->ima->id.tag |= LIB_TAG_DOIT;
}
-/* Invert image to paint invese area. */
+/* Invert image to paint inverse area. */
static void gpencil_invert_image(tGPDfill *tgpf)
{
ImBuf *ibuf;
@@ -773,18 +1001,24 @@ static void gpencil_invert_image(tGPDfill *tgpf)
ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock);
const int maxpixel = (ibuf->x * ibuf->y) - 1;
+ const int center = ibuf->x / 2;
for (int v = maxpixel; v != 0; v--) {
float color[4];
get_pixel(ibuf, v, color);
- /* Green. */
+ /* Green->Red. */
if (color[1] == 1.0f) {
set_pixel(ibuf, v, fill_col[0]);
}
+ /* Red->Green */
else if (color[0] == 1.0f) {
set_pixel(ibuf, v, fill_col[1]);
+ /* Add thickness of 2 pixels to avoid too thin lines. */
+ int offset = (v % ibuf->x < center) ? 1 : -1;
+ set_pixel(ibuf, v + offset, fill_col[1]);
}
else {
+ /* Set to Transparent. */
set_pixel(ibuf, v, fill_col[2]);
}
}
@@ -821,21 +1055,37 @@ static void gpencil_erase_processed_area(tGPDfill *tgpf)
float rgba[4];
for (int idy = 0; idy < ibuf->y; idy++) {
- bool clear = false;
+ int init = -1;
+ int end = -1;
for (int idx = 0; idx < ibuf->x; idx++) {
int image_idx = ibuf->x * idy + idx;
get_pixel(ibuf, image_idx, rgba);
/* Blue. */
if (rgba[2] == 1.0f) {
- clear = true;
+ if (init < 0) {
+ init = image_idx;
+ }
+ else {
+ end = image_idx;
+ }
}
/* Red. */
else if (rgba[0] == 1.0f) {
- clear = false;
+ if (init > -1) {
+ for (int i = init; i <= max_ii(init, end); i++) {
+ set_pixel(ibuf, i, clear_col);
+ }
+ init = -1;
+ end = -1;
+ }
}
- if (clear) {
- set_pixel(ibuf, image_idx, clear_col);
+ }
+ /* Check last segment. */
+ if (init > -1) {
+ for (int i = init; i <= max_ii(init, end); i++) {
+ set_pixel(ibuf, i, clear_col);
}
+ set_pixel(ibuf, init, clear_col);
}
}
@@ -845,98 +1095,112 @@ static void gpencil_erase_processed_area(tGPDfill *tgpf)
tgpf->ima->id.tag |= LIB_TAG_DOIT;
}
-/* Naive dilate
+/**
+ * Naive dilate
*
* Expand green areas into enclosing red areas.
* Using stack prevents creep when replacing colors directly.
+ * <pre>
* -----------
* XXXXXXX
* XoooooX
* XXooXXX
* XXXX
* -----------
+ * </pre>
*/
-static void dilate_shape(ImBuf *ibuf)
+static bool dilate_shape(ImBuf *ibuf)
{
+ bool done = false;
+
BLI_Stack *stack = BLI_stack_new(sizeof(int), __func__);
const float green[4] = {0.0f, 1.0f, 0.0f, 1.0f};
- const int maxpixel = (ibuf->x * ibuf->y) - 1;
+ // const int maxpixel = (ibuf->x * ibuf->y) - 1;
/* detect pixels and expand into red areas */
- for (int v = maxpixel; v != 0; v--) {
- float color[4];
- int index;
- int tp = 0;
- int bm = 0;
- int lt = 0;
- int rt = 0;
- get_pixel(ibuf, v, color);
- if (color[1] == 1.0f) {
- /* pixel left */
- if (v - 1 >= 0) {
- index = v - 1;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
- lt = index;
+ for (int row = 0; row < ibuf->y; row++) {
+ if (!is_row_filled(ibuf, row)) {
+ continue;
+ }
+ int maxpixel = (ibuf->x * (row + 1)) - 1;
+ int minpixel = ibuf->x * row;
+
+ for (int v = maxpixel; v != minpixel; v--) {
+ float color[4];
+ int index;
+ get_pixel(ibuf, v, color);
+ if (color[1] == 1.0f) {
+ int tp = 0;
+ int bm = 0;
+ int lt = 0;
+ int rt = 0;
+
+ /* pixel left */
+ if (v - 1 >= 0) {
+ index = v - 1;
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ lt = index;
+ }
}
- }
- /* pixel right */
- if (v + 1 <= maxpixel) {
- index = v + 1;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
- rt = index;
+ /* pixel right */
+ if (v + 1 <= maxpixel) {
+ index = v + 1;
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ rt = index;
+ }
}
- }
- /* pixel top */
- if (v + ibuf->x <= maxpixel) {
- index = v + ibuf->x;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
- tp = index;
+ /* pixel top */
+ if (v + (ibuf->x * 1) <= maxpixel) {
+ index = v + (ibuf->x * 1);
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ tp = index;
+ }
}
- }
- /* pixel bottom */
- if (v - ibuf->x >= 0) {
- index = v - ibuf->x;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
- bm = index;
+ /* pixel bottom */
+ if (v - (ibuf->x * 1) >= 0) {
+ index = v - (ibuf->x * 1);
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ bm = index;
+ }
}
- }
- /* pixel top-left */
- if (tp && lt) {
- index = tp - 1;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
+ /* pixel top-left */
+ if (tp && lt) {
+ index = tp - 1;
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ }
}
- }
- /* pixel top-right */
- if (tp && rt) {
- index = tp + 1;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
+ /* pixel top-right */
+ if (tp && rt) {
+ index = tp + 1;
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ }
}
- }
- /* pixel bottom-left */
- if (bm && lt) {
- index = bm - 1;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
+ /* pixel bottom-left */
+ if (bm && lt) {
+ index = bm - 1;
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ }
}
- }
- /* pixel bottom-right */
- if (bm && rt) {
- index = bm + 1;
- get_pixel(ibuf, index, color);
- if (color[0] == 1.0f) {
- BLI_stack_push(stack, &index);
+ /* pixel bottom-right */
+ if (bm && rt) {
+ index = bm + 1;
+ get_pixel(ibuf, index, color);
+ if (color[0] == 1.0f) {
+ BLI_stack_push(stack, &index);
+ }
}
}
}
@@ -946,8 +1210,11 @@ static void dilate_shape(ImBuf *ibuf)
int v;
BLI_stack_pop(stack, &v);
set_pixel(ibuf, v, green);
+ done = true;
}
BLI_stack_free(stack);
+
+ return done;
}
/* Get the outline points of a shape using Moore Neighborhood algorithm
@@ -963,11 +1230,12 @@ static void gpencil_get_outline_points(tGPDfill *tgpf, const bool dilate)
int v[2];
int boundary_co[2];
int start_co[2];
+ int first_co[2] = {-1, -1};
int backtracked_co[2];
int current_check_co[2];
int prev_check_co[2];
int backtracked_offset[1][2] = {{0, 0}};
- // bool boundary_found = false;
+ bool first_pixel = false;
bool start_found = false;
const int NEIGHBOR_COUNT = 8;
@@ -992,7 +1260,6 @@ static void gpencil_get_outline_points(tGPDfill *tgpf, const bool dilate)
dilate_shape(ibuf);
}
- /* find the initial point to start outline analysis */
for (int idx = imagesize - 1; idx != 0; idx--) {
get_pixel(ibuf, idx, rgba);
if (rgba[1] == 1.0f) {
@@ -1015,7 +1282,7 @@ static void gpencil_get_outline_points(tGPDfill *tgpf, const bool dilate)
int cur_back_offset = -1;
for (int i = 0; i < NEIGHBOR_COUNT; i++) {
if (backtracked_offset[0][0] == offset[i][0] && backtracked_offset[0][1] == offset[i][1]) {
- /* Finding the bracktracked pixel offset index */
+ /* Finding the back-tracked pixel offset index */
cur_back_offset = i;
break;
}
@@ -1045,19 +1312,24 @@ static void gpencil_get_outline_points(tGPDfill *tgpf, const bool dilate)
cur_back_offset++;
loop++;
}
- /* current pixel is equal to starting pixel */
- if (boundary_co[0] == start_co[0] && boundary_co[1] == start_co[1]) {
+ /* Current pixel is equal to starting or first pixel. */
+ if ((boundary_co[0] == start_co[0] && boundary_co[1] == start_co[1]) ||
+ (boundary_co[0] == first_co[0] && boundary_co[1] == first_co[1])) {
BLI_stack_pop(tgpf->stack, &v);
- // boundary_found = true;
break;
}
+
+ if (!first_pixel) {
+ first_pixel = true;
+ copy_v2_v2_int(first_co, boundary_co);
+ }
}
/* release ibuf */
BKE_image_release_ibuf(tgpf->ima, ibuf, lock);
}
-/* get z-depth array to reproject on surface */
+/* Get z-depth array to reproject on surface. */
static void gpencil_get_depth_array(tGPDfill *tgpf)
{
tGPspoint *ptc;
@@ -1108,7 +1380,7 @@ static void gpencil_get_depth_array(tGPDfill *tgpf)
}
if (found_depth == false) {
- /* eeh... not much we can do.. :/, ignore depth in this case */
+ /* Sigh! not much we can do here. Ignore depth in this case. */
for (i = totpoints - 1; i >= 0; i--) {
tgpf->depth_arr[i] = 0.9999f;
}
@@ -1171,6 +1443,9 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
return;
}
+ /* Set as done. */
+ tgpf->done = true;
+
/* Get frame or create a new one. */
tgpf->gpf = BKE_gpencil_layer_frame_get(tgpf->gpl, tgpf->active_cfra, GP_GETFRAME_ADD_NEW);
@@ -1275,7 +1550,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
float origin[3];
ED_gpencil_drawing_reference_get(tgpf->scene, tgpf->ob, ts->gpencil_v3d_align, origin);
ED_gpencil_project_stroke_to_plane(
- tgpf->scene, tgpf->ob, tgpf->rv3d, gps, origin, tgpf->lock_axis - 1);
+ tgpf->scene, tgpf->ob, tgpf->rv3d, tgpf->gpl, gps, origin, tgpf->lock_axis - 1);
}
/* if parented change position relative to parent object */
@@ -1326,7 +1601,6 @@ static void gpencil_fill_draw_3d(const bContext *C, ARegion *UNUSED(region), voi
if (region != tgpf->region) {
return;
}
-
gpencil_draw_boundary_lines(C, tgpf);
}
@@ -1377,6 +1651,10 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
tgpf->win = CTX_wm_window(C);
tgpf->active_cfra = CFRA;
+ /* Setup space conversions. */
+ gpencil_point_conversion_init(C, &tgpf->gsc);
+ tgpf->zoom = 1.0f;
+
/* set GP datablock */
tgpf->gpd = gpd;
tgpf->gpl = BKE_gpencil_layer_active_get(gpd);
@@ -1387,6 +1665,7 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
tgpf->lock_axis = ts->gp_sculpt.lock_axis;
tgpf->oldkey = -1;
+ tgpf->is_render = false;
tgpf->sbuffer_used = 0;
tgpf->sbuffer = NULL;
tgpf->depth_arr = NULL;
@@ -1395,11 +1674,13 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
tgpf->brush = brush;
tgpf->flag = brush->gpencil_settings->flag;
- tgpf->fill_leak = brush->gpencil_settings->fill_leak;
tgpf->fill_threshold = brush->gpencil_settings->fill_threshold;
tgpf->fill_simplylvl = brush->gpencil_settings->fill_simplylvl;
tgpf->fill_draw_mode = brush->gpencil_settings->fill_draw_mode;
- tgpf->fill_factor = (short)max_ii(1, min_ii((int)brush->gpencil_settings->fill_factor, 8));
+ tgpf->fill_extend_fac = brush->gpencil_settings->fill_extend_fac;
+ tgpf->fill_factor = max_ff(GPENCIL_MIN_FILL_FAC,
+ min_ff(brush->gpencil_settings->fill_factor, GPENCIL_MAX_FILL_FAC));
+ tgpf->fill_leak = (int)ceil((float)brush->gpencil_settings->fill_leak * tgpf->fill_factor);
int totcol = tgpf->ob->totcol;
@@ -1424,7 +1705,6 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
/* end operator */
static void gpencil_fill_exit(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Object *ob = CTX_data_active_object(C);
/* clear undo stack */
@@ -1443,16 +1723,14 @@ static void gpencil_fill_exit(bContext *C, wmOperator *op)
MEM_SAFE_FREE(tgpf->sbuffer);
MEM_SAFE_FREE(tgpf->depth_arr);
+ /* Remove any temp stroke. */
+ gpencil_delete_temp_stroke_extension(tgpf, true);
+
/* remove drawing handler */
if (tgpf->draw_handle_3d) {
ED_region_draw_cb_exit(tgpf->region->type, tgpf->draw_handle_3d);
}
- /* Delete temp image. */
- if (tgpf->ima) {
- BKE_id_free(bmain, tgpf->ima);
- }
-
/* finally, free memory used by temp data */
MEM_freeN(tgpf);
}
@@ -1536,7 +1814,11 @@ static int gpencil_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
tgpf = op->customdata;
/* Enable custom drawing handlers to show help lines */
- if (tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) {
+ const bool do_extend = (tgpf->fill_extend_fac > 0.0f);
+ const bool help_lines = ((tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) ||
+ ((tgpf->flag & GP_BRUSH_FILL_SHOW_EXTENDLINES) && (do_extend)));
+
+ if (help_lines) {
tgpf->draw_handle_3d = ED_region_draw_cb_activate(
tgpf->region->type, gpencil_fill_draw_3d, tgpf, REGION_DRAW_POST_VIEW);
}
@@ -1554,17 +1836,210 @@ static int gpencil_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
return OPERATOR_RUNNING_MODAL;
}
+/* Helper: Calc the maximum bounding box size of strokes to get the zoom level of the viewport.
+ * For each stroke, the 2D projected bounding box is calculated and using this data, the total
+ * object bounding box (all strokes) is calculated. */
+static void gpencil_zoom_level_set(tGPDfill *tgpf)
+{
+ Brush *brush = tgpf->brush;
+ if (brush->gpencil_settings->flag & GP_BRUSH_FILL_FIT_DISABLE) {
+ tgpf->zoom = 1.0f;
+ return;
+ }
+
+ Object *ob = tgpf->ob;
+ bGPdata *gpd = tgpf->gpd;
+ BrushGpencilSettings *brush_settings = tgpf->brush->gpencil_settings;
+ bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd);
+ BLI_assert(gpl_active != NULL);
+
+ const int gpl_active_index = BLI_findindex(&gpd->layers, gpl_active);
+ BLI_assert(gpl_active_index >= 0);
+
+ /* Init maximum boundbox size. */
+ rctf rect_max;
+ const float winx_half = tgpf->region->winx / 2.0f;
+ const float winy_half = tgpf->region->winy / 2.0f;
+ BLI_rctf_init(&rect_max,
+ 0.0f - winx_half,
+ tgpf->region->winx + winx_half,
+ 0.0f - winy_half,
+ tgpf->region->winy + winy_half);
+
+ float objectbox_min[2], objectbox_max[2];
+ INIT_MINMAX2(objectbox_min, objectbox_max);
+ rctf rect_bound;
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ if (gpl->flag & GP_LAYER_HIDE) {
+ continue;
+ }
+ float diff_mat[4][4];
+ /* calculate parent matrix */
+ BKE_gpencil_layer_transform_matrix_get(tgpf->depsgraph, ob, gpl, diff_mat);
+
+ /* Decide if the strokes of layers are included or not depending on the layer mode.
+ * Cannot skip the layer because it can use boundary strokes and must be used. */
+ const int gpl_index = BLI_findindex(&gpd->layers, gpl);
+ bool skip = skip_layer_check(brush_settings->fill_layer_mode, gpl_active_index, gpl_index);
+
+ /* Get frame to check. */
+ bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, tgpf->active_cfra, GP_GETFRAME_USE_PREV);
+ if (gpf == NULL) {
+ continue;
+ }
+
+ /* Read all strokes. */
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ /* check if stroke can be drawn */
+ if ((gps->points == NULL) || (gps->totpoints < 2)) {
+ continue;
+ }
+ /* check if the color is visible */
+ MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
+ if ((gp_style == NULL) || (gp_style->flag & GP_MATERIAL_HIDE)) {
+ continue;
+ }
+
+ /* If the layer must be skipped, but the stroke is not boundary, skip stroke. */
+ if ((skip) && ((gps->flag & GP_STROKE_NOFILL) == 0)) {
+ continue;
+ }
+
+ float boundbox_min[2];
+ float boundbox_max[2];
+ ED_gpencil_projected_2d_bound_box(&tgpf->gsc, gps, diff_mat, boundbox_min, boundbox_max);
+ minmax_v2v2_v2(objectbox_min, objectbox_max, boundbox_min);
+ minmax_v2v2_v2(objectbox_min, objectbox_max, boundbox_max);
+ }
+ }
+ /* Clamp max bound box. */
+ BLI_rctf_init(
+ &rect_bound, objectbox_min[0], objectbox_max[0], objectbox_min[1], objectbox_max[1]);
+ float r_xy[2];
+ BLI_rctf_clamp(&rect_bound, &rect_max, r_xy);
+
+ /* Calculate total width used. */
+ float width = tgpf->region->winx;
+ if (rect_bound.xmin < 0.0f) {
+ width -= rect_bound.xmin;
+ }
+ if (rect_bound.xmax > tgpf->region->winx) {
+ width += rect_bound.xmax - tgpf->region->winx;
+ }
+ /* Calculate total height used. */
+ float height = tgpf->region->winy;
+ if (rect_bound.ymin < 0.0f) {
+ height -= rect_bound.ymin;
+ }
+ if (rect_bound.ymax > tgpf->region->winy) {
+ height += rect_bound.ymax - tgpf->region->winy;
+ }
+
+ width = ceilf(width);
+ height = ceilf(height);
+
+ float zoomx = (width > tgpf->region->winx) ? width / (float)tgpf->region->winx : 1.0f;
+ float zoomy = (height > tgpf->region->winy) ? height / (float)tgpf->region->winy : 1.0f;
+ if ((zoomx != 1.0f) || (zoomy != 1.0f)) {
+ tgpf->zoom = min_ff(max_ff(zoomx, zoomy) * 1.5f, 5.0f);
+ }
+}
+
+static bool gpencil_do_frame_fill(tGPDfill *tgpf, const bool is_inverted)
+{
+ wmWindow *win = CTX_wm_window(tgpf->C);
+
+ /* render screen to temp image */
+ int totpoints = 1;
+ if (gpencil_render_offscreen(tgpf)) {
+
+ /* Set red borders to create a external limit. */
+ gpencil_set_borders(tgpf, true);
+
+ /* apply boundary fill */
+ gpencil_boundaryfill_area(tgpf);
+
+ /* Invert direction if press Ctrl. */
+ if (is_inverted) {
+ gpencil_invert_image(tgpf);
+ }
+
+ /* Clean borders to avoid infinite loops. */
+ gpencil_set_borders(tgpf, false);
+ WM_cursor_time(win, 50);
+ int totpoints_prv = 0;
+ int loop_limit = 0;
+ while (totpoints > 0) {
+ /* analyze outline */
+ gpencil_get_outline_points(tgpf, (totpoints == 1) ? true : false);
+
+ /* create array of points from stack */
+ totpoints = gpencil_points_from_stack(tgpf);
+
+ /* create z-depth array for reproject */
+ gpencil_get_depth_array(tgpf);
+
+ /* create stroke and reproject */
+ gpencil_stroke_from_buffer(tgpf);
+
+ if (is_inverted) {
+ gpencil_erase_processed_area(tgpf);
+ }
+ else {
+ /* Exit of the loop. */
+ totpoints = 0;
+ }
+
+ /* free temp stack data */
+ if (tgpf->stack) {
+ BLI_stack_free(tgpf->stack);
+ }
+ WM_cursor_time(win, 100);
+
+ /* Free memory. */
+ MEM_SAFE_FREE(tgpf->sbuffer);
+ MEM_SAFE_FREE(tgpf->depth_arr);
+
+ /* Limit very small areas. */
+ if (totpoints < 3) {
+ break;
+ }
+ /* Limit infinite loops is some corner cases. */
+ if (totpoints_prv == totpoints) {
+ loop_limit++;
+ if (loop_limit > 3) {
+ break;
+ }
+ }
+ totpoints_prv = totpoints;
+ }
+
+ /* Delete temp image. */
+ if ((tgpf->ima) && (!FILL_DEBUG)) {
+ BKE_id_free(tgpf->bmain, tgpf->ima);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
/* events handling during interactive part of operator */
static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPDfill *tgpf = op->customdata;
- Scene *scene = tgpf->scene;
Brush *brush = tgpf->brush;
BrushGpencilSettings *brush_settings = brush->gpencil_settings;
+ tgpf->on_back = RNA_boolean_get(op->ptr, "on_back");
+
const bool is_brush_inv = brush_settings->fill_direction == BRUSH_DIR_IN;
const bool is_inverted = (is_brush_inv && !event->ctrl) || (!is_brush_inv && event->ctrl);
-
- int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through */
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(tgpf->gpd);
+ const bool do_extend = (tgpf->fill_extend_fac > 0.0f);
+ const bool help_lines = ((tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) ||
+ ((tgpf->flag & GP_BRUSH_FILL_SHOW_EXTENDLINES) && (do_extend)));
+ int estate = OPERATOR_RUNNING_MODAL;
switch (event->type) {
case EVT_ESCKEY:
@@ -1572,82 +2047,104 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
estate = OPERATOR_CANCELLED;
break;
case LEFTMOUSE:
- tgpf->on_back = RNA_boolean_get(op->ptr, "on_back");
/* first time the event is not enabled to show help lines. */
- if ((tgpf->oldkey != -1) || ((tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) == 0)) {
+ if ((tgpf->oldkey != -1) || (!help_lines)) {
ARegion *region = BKE_area_find_region_xy(
CTX_wm_area(C), RGN_TYPE_ANY, event->x, event->y);
if (region) {
bool in_bounds = false;
-
/* Perform bounds check */
in_bounds = BLI_rcti_isect_pt(&region->winrct, event->x, event->y);
if ((in_bounds) && (region->regiontype == RGN_TYPE_WINDOW)) {
- tgpf->center[0] = event->mval[0];
- tgpf->center[1] = event->mval[1];
-
- /* Set active frame as current for filling. */
- tgpf->active_cfra = CFRA;
+ tgpf->mouse[0] = event->mval[0];
+ tgpf->mouse[1] = event->mval[1];
+ tgpf->is_render = true;
+ /* Define Zoom level. */
+ gpencil_zoom_level_set(tgpf);
+
+ /* Create Temp stroke. */
+ tgpf->gps_mouse = BKE_gpencil_stroke_new(0, 1, 10.0f);
+ tGPspoint point2D;
+ bGPDspoint *pt = &tgpf->gps_mouse->points[0];
+ copy_v2fl_v2i(&point2D.x, tgpf->mouse);
+ gpencil_stroke_convertcoords_tpoint(
+ tgpf->scene, tgpf->region, tgpf->ob, &point2D, NULL, &pt->x);
+
+ /* If not multiframe and there is no frame in CFRA for the active layer, create
+ * a new frame before to make the hash function can find something. */
+ if (!is_multiedit) {
+ tgpf->gpf = BKE_gpencil_layer_frame_get(
+ tgpf->gpl, tgpf->active_cfra, GP_GETFRAME_ADD_NEW);
+ tgpf->gpf->flag |= GP_FRAME_SELECT;
+ }
- /* render screen to temp image */
- int totpoints = 1;
- if (gpencil_render_offscreen(tgpf)) {
+ /* Hash of selected frames.*/
+ GHash *frame_list = BLI_ghash_int_new_ex(__func__, 64);
+ BKE_gpencil_frame_selected_hash(tgpf->gpd, frame_list);
- /* Set red borders to create a external limit. */
- gpencil_set_borders(tgpf, true);
+ /* Loop all frames. */
+ wmWindow *win = CTX_wm_window(C);
- /* apply boundary fill */
- gpencil_boundaryfill_area(tgpf);
+ GHashIterator gh_iter;
+ int total = BLI_ghash_len(frame_list);
+ int i = 1;
+ GHASH_ITER (gh_iter, frame_list) {
+ /* Set active frame as current for filling. */
+ tgpf->active_cfra = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter));
+ int step = ((float)i / (float)total) * 100.0f;
+ WM_cursor_time(win, step);
- /* Invert direction if press Ctrl. */
- if (is_inverted) {
- gpencil_invert_image(tgpf);
+ if (do_extend) {
+ gpencil_update_extend(tgpf);
}
- /* Clean borders to avoid infinite loops. */
- gpencil_set_borders(tgpf, false);
-
- while (totpoints > 0) {
- /* analyze outline */
- gpencil_get_outline_points(tgpf, (totpoints == 1) ? true : false);
-
- /* create array of points from stack */
- totpoints = gpencil_points_from_stack(tgpf);
-
- /* create z-depth array for reproject */
- gpencil_get_depth_array(tgpf);
-
- /* create stroke and reproject */
- gpencil_stroke_from_buffer(tgpf);
-
- if (is_inverted) {
- gpencil_erase_processed_area(tgpf);
- }
- else {
- /* Exit of the loop. */
- totpoints = 0;
- }
-
- /* free temp stack data */
- if (tgpf->stack) {
- BLI_stack_free(tgpf->stack);
+ /* Repeat loop until get something. */
+ tgpf->done = false;
+ int loop_limit = 0;
+ while ((!tgpf->done) && (loop_limit < 2)) {
+ WM_cursor_time(win, loop_limit + 1);
+ /* Render screen to temp image and do fill. */
+ gpencil_do_frame_fill(tgpf, is_inverted);
+
+ /* restore size */
+ tgpf->region->winx = (short)tgpf->bwinx;
+ tgpf->region->winy = (short)tgpf->bwiny;
+ tgpf->region->winrct = tgpf->brect;
+ if (!tgpf->done) {
+ /* If the zoom was not set before, avoid a loop. */
+ if (tgpf->zoom == 1.0f) {
+ loop_limit++;
+ }
+ else {
+ tgpf->zoom = 1.0f;
+ tgpf->fill_factor = max_ff(
+ GPENCIL_MIN_FILL_FAC,
+ min_ff(brush->gpencil_settings->fill_factor, GPENCIL_MAX_FILL_FAC));
+ }
}
+ loop_limit++;
+ }
- /* Free memory. */
- MEM_SAFE_FREE(tgpf->sbuffer);
- MEM_SAFE_FREE(tgpf->depth_arr);
+ if (do_extend) {
+ gpencil_delete_temp_stroke_extension(tgpf, true);
}
+
+ i++;
}
+ WM_cursor_modal_restore(win);
+ /* Free hash table. */
+ BLI_ghash_free(frame_list, NULL, NULL);
- /* restore size */
- tgpf->region->winx = (short)tgpf->bwinx;
- tgpf->region->winy = (short)tgpf->bwiny;
- tgpf->region->winrct = tgpf->brect;
+ /* Free temp stroke. */
+ BKE_gpencil_free_stroke(tgpf->gps_mouse);
/* push undo data */
gpencil_undo_push(tgpf->gpd);
+ /* Save extend value for next operation. */
+ brush_settings->fill_extend_fac = tgpf->fill_extend_fac;
+
estate = OPERATOR_FINISHED;
}
else {
@@ -1658,8 +2155,29 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
estate = OPERATOR_CANCELLED;
}
}
+ else if (do_extend) {
+ gpencil_update_extend(tgpf);
+ }
tgpf->oldkey = event->type;
break;
+ case EVT_PAGEUPKEY:
+ case WHEELUPMOUSE:
+ if (tgpf->oldkey == 1) {
+ tgpf->fill_extend_fac -= (event->shift) ? 0.01f : 0.1f;
+ CLAMP_MIN(tgpf->fill_extend_fac, 0.0f);
+ gpencil_update_extend(tgpf);
+ }
+ break;
+ case EVT_PAGEDOWNKEY:
+ case WHEELDOWNMOUSE:
+ if (tgpf->oldkey == 1) {
+ tgpf->fill_extend_fac += (event->shift) ? 0.01f : 0.1f;
+ CLAMP_MAX(tgpf->fill_extend_fac, 100.0f);
+ gpencil_update_extend(tgpf);
+ }
+ break;
+ default:
+ break;
}
/* process last operations before exiting */
switch (estate) {
@@ -1672,7 +2190,7 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
gpencil_fill_exit(C, op);
break;
- case OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH:
+ default:
break;
}
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 4a908eff92e..5fea46626d5 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -667,7 +667,8 @@ struct GP_EditableStrokes_Iter {
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
- BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
+ BKE_gpencil_layer_transform_matrix_get( \
+ depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
/* loop over strokes */ \
bGPDstroke *gpsn_; \
@@ -678,7 +679,7 @@ struct GP_EditableStrokes_Iter {
continue; \
} \
/* check if the color is editable */ \
- if (ED_gpencil_stroke_color_use(obact_, gpl, gps) == false) { \
+ if (ED_gpencil_stroke_material_editable(obact_, gpl, gps) == false) { \
continue; \
} \
/* ... Do Stuff With Strokes ... */
@@ -718,7 +719,8 @@ struct GP_EditableStrokes_Iter {
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
- BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
+ BKE_gpencil_layer_transform_matrix_get( \
+ depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
/* loop over strokes */ \
bGPDstroke *gpsn_; \
@@ -767,8 +769,10 @@ struct GP_EditableStrokes_Iter {
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
- BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
- invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
+ BKE_gpencil_layer_transform_matrix_get( \
+ depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
+ /* Undo layer transform. */ \
+ mul_m4_m4m4(gpstroke_iter.diff_mat, gpstroke_iter.diff_mat, gpl->layer_invmat); \
/* loop over strokes */ \
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf_->strokes) { \
/* skip strokes that are invalid for current view */ \
@@ -776,7 +780,7 @@ struct GP_EditableStrokes_Iter {
continue; \
} \
/* check if the color is editable */ \
- if (ED_gpencil_stroke_color_use(obact_, gpl, gps) == false) { \
+ if (ED_gpencil_stroke_material_editable(obact_, gpl, gps) == false) { \
continue; \
} \
/* ... Do Stuff With Strokes ... */
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index c666fcb67b7..ecd243ed595 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -48,31 +48,22 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_deform.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
#include "BKE_report.h"
#include "UI_interface.h"
-#include "UI_resources.h"
#include "WM_api.h"
#include "WM_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "UI_view2d.h"
#include "ED_gpencil.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_space_api.h"
-#include "ED_view3d.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "gpencil_intern.h"
@@ -229,7 +220,7 @@ static bool gpencil_interpolate_check_todo(bContext *C, bGPdata *gpd)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps_from) == false) {
continue;
}
@@ -283,8 +274,8 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
tgpil = MEM_callocN(sizeof(tGPDinterpolate_layer), "GPencil Interpolate Layer");
tgpil->gpl = gpl;
- tgpil->prevFrame = BKE_gpencil_frame_duplicate(gpl->actframe);
- tgpil->nextFrame = BKE_gpencil_frame_duplicate(gpl->actframe->next);
+ tgpil->prevFrame = BKE_gpencil_frame_duplicate(gpl->actframe, true);
+ tgpil->nextFrame = BKE_gpencil_frame_duplicate(gpl->actframe->next, true);
BLI_addtail(&tgpi->ilayers, tgpil);
@@ -315,7 +306,7 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, tgpil->gpl, gps_from) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, tgpil->gpl, gps_from) == false) {
valid = false;
}
@@ -734,7 +725,7 @@ void GPENCIL_OT_interpolate(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
/* properties */
- RNA_def_float_percentage(
+ RNA_def_float_factor(
ot->srna,
"shift",
0.0f,
@@ -1008,8 +999,8 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
}
/* store extremes */
- prevFrame = BKE_gpencil_frame_duplicate(gpl->actframe);
- nextFrame = BKE_gpencil_frame_duplicate(gpl->actframe->next);
+ prevFrame = BKE_gpencil_frame_duplicate(gpl->actframe, true);
+ nextFrame = BKE_gpencil_frame_duplicate(gpl->actframe->next, true);
/* Loop over intermediary frames and create the interpolation */
for (cframe = prevFrame->framenum + step; cframe < nextFrame->framenum; cframe += step) {
@@ -1048,7 +1039,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps_from) == false) {
continue;
}
diff --git a/source/blender/editors/gpencil/gpencil_merge.c b/source/blender/editors/gpencil/gpencil_merge.c
index 272dff56291..435bff34998 100644
--- a/source/blender/editors/gpencil/gpencil_merge.c
+++ b/source/blender/editors/gpencil/gpencil_merge.c
@@ -48,12 +48,9 @@
#include "RNA_define.h"
#include "ED_gpencil.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_view3d.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "gpencil_intern.h"
diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c
index 53beaeaa6a0..ffe676f0520 100644
--- a/source/blender/editors/gpencil/gpencil_mesh.c
+++ b/source/blender/editors/gpencil/gpencil_mesh.c
@@ -36,8 +36,6 @@
#include "BKE_anim_data.h"
#include "BKE_context.h"
#include "BKE_duplilist.h"
-#include "BKE_global.h"
-#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
#include "BKE_layer.h"
#include "BKE_main.h"
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 0a29b83bc4f..1a6cb5670c4 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -27,9 +27,7 @@
#include "BLI_sys_types.h"
-#include "BKE_brush.h"
#include "BKE_context.h"
-#include "BKE_gpencil.h"
#include "BKE_paint.h"
#include "DNA_brush_types.h"
@@ -45,9 +43,6 @@
#include "RNA_access.h"
#include "ED_gpencil.h"
-#include "ED_object.h"
-#include "ED_select_utils.h"
-#include "ED_transform.h"
#include "gpencil_intern.h"
diff --git a/source/blender/editors/gpencil/gpencil_ops_versioning.c b/source/blender/editors/gpencil/gpencil_ops_versioning.c
index 815bbbaa254..45842c28dff 100644
--- a/source/blender/editors/gpencil/gpencil_ops_versioning.c
+++ b/source/blender/editors/gpencil/gpencil_ops_versioning.c
@@ -34,16 +34,12 @@
#include "DNA_gpencil_types.h"
#include "DNA_material_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BKE_brush.h"
#include "BKE_context.h"
-#include "BKE_deform.h"
#include "BKE_gpencil.h"
#include "BKE_main.h"
-#include "BKE_material.h"
#include "BKE_object.h"
#include "WM_api.h"
@@ -53,7 +49,6 @@
#include "RNA_define.h"
#include "ED_gpencil.h"
-#include "ED_object.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index ed56f004ca4..b833125cf34 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -426,7 +426,7 @@ static void gpencil_reproject_toplane(tGPsdata *p, bGPDstroke *gps)
/* get drawing origin */
gpencil_get_3d_reference(p, origin);
- ED_gpencil_project_stroke_to_plane(p->scene, obact, rv3d, gps, origin, p->lock_axis - 1);
+ ED_gpencil_project_stroke_to_plane(p->scene, obact, rv3d, p->gpl, gps, origin, p->lock_axis - 1);
}
/* convert screen-coordinates to buffer-coordinates */
@@ -887,11 +887,13 @@ static short gpencil_stroke_addpoint(tGPsdata *p,
gpencil_get_3d_reference(p, origin);
/* reproject current */
ED_gpencil_tpoint_to_point(p->region, origin, pt, &spt);
- ED_gpencil_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt);
+ ED_gpencil_project_point_to_plane(
+ p->scene, obact, p->gpl, rv3d, origin, p->lock_axis - 1, &spt);
/* reproject previous */
ED_gpencil_tpoint_to_point(p->region, origin, ptb, &spt2);
- ED_gpencil_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt2);
+ ED_gpencil_project_point_to_plane(
+ p->scene, obact, p->gpl, rv3d, origin, p->lock_axis - 1, &spt2);
p->totpixlen += len_v3v3(&spt.x, &spt2.x);
pt->uv_fac = p->totpixlen;
}
@@ -1304,6 +1306,12 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(gpd, gps);
+ /* In Multiframe mode, duplicate the stroke in other frames. */
+ if (GPENCIL_MULTIEDIT_SESSIONS_ON(p->gpd)) {
+ const bool tail = (ts->gpencil_flags & GP_TOOL_FLAG_PAINT_ONBACK);
+ BKE_gpencil_stroke_copy_to_keyframes(gpd, gpl, p->gpf, gps, tail);
+ }
+
gpencil_stroke_added_enable(p);
}
@@ -1321,10 +1329,8 @@ static float view3d_point_depth(const RegionView3D *rv3d, const float co[3])
}
/* only erase stroke points that are visible */
-static bool gpencil_stroke_eraser_is_occluded(tGPsdata *p,
- const bGPDspoint *pt,
- const int x,
- const int y)
+static bool gpencil_stroke_eraser_is_occluded(
+ tGPsdata *p, bGPDlayer *gpl, const bGPDspoint *pt, const int x, const int y)
{
Object *obact = (Object *)p->ownerPtr.data;
Brush *brush = p->brush;
@@ -1341,7 +1347,6 @@ static bool gpencil_stroke_eraser_is_occluded(tGPsdata *p,
if ((gp_settings != NULL) && (p->area->spacetype == SPACE_VIEW3D) &&
(gp_settings->flag & GP_BRUSH_OCCLUDE_ERASER)) {
RegionView3D *rv3d = p->region->regiondata;
- bGPDlayer *gpl = p->gpl;
const int mval_i[2] = {x, y};
float mval_3d[3];
@@ -1349,7 +1354,7 @@ static bool gpencil_stroke_eraser_is_occluded(tGPsdata *p,
float diff_mat[4][4];
/* calculate difference matrix if parent object */
- BKE_gpencil_parent_matrix_get(p->depsgraph, obact, gpl, diff_mat);
+ 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);
@@ -1452,6 +1457,7 @@ static void gpencil_stroke_soft_refine(bGPDstroke *gps)
/* eraser tool - evaluation per stroke */
static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
+ bGPDlayer *gpl,
bGPDframe *gpf,
bGPDstroke *gps,
const float mval[2],
@@ -1577,9 +1583,9 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
* - this assumes that linewidth is irrelevant
*/
if (gpencil_stroke_inside_circle(mval, radius, pc0[0], pc0[1], pc2[0], pc2[1])) {
- if ((gpencil_stroke_eraser_is_occluded(p, pt0, pc0[0], pc0[1]) == false) ||
- (gpencil_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) ||
- (gpencil_stroke_eraser_is_occluded(p, pt2, pc2[0], pc2[1]) == false)) {
+ 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)) {
/* Point is affected: */
/* Adjust thickness
* - Influence of eraser falls off with distance from the middle of the eraser
@@ -1681,6 +1687,8 @@ static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
/* erase strokes which fall under the eraser strokes */
static void gpencil_stroke_doeraser(tGPsdata *p)
{
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(p->gpd);
+
rcti rect;
Brush *brush = p->brush;
Brush *eraser = p->eraser;
@@ -1721,40 +1729,53 @@ static void gpencil_stroke_doeraser(tGPsdata *p)
* on multiple layers...
*/
LISTBASE_FOREACH (bGPDlayer *, gpl, &p->gpd->layers) {
- bGPDframe *gpf = gpl->actframe;
-
/* only affect layer if it's editable (and visible) */
if (BKE_gpencil_layer_is_editable(gpl) == false) {
continue;
}
- if (gpf == NULL) {
+
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
+ if (init_gpf == NULL) {
continue;
}
- /* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(p->depsgraph, p->ob, gpl, p->diff_mat);
- /* loop over strokes, checking segments for intersections */
- LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
- /* check if the color is editable */
- if (ED_gpencil_stroke_color_use(p->ob, gpl, gps) == false) {
- continue;
- }
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ if (gpf == NULL) {
+ continue;
+ }
+ /* calculate difference matrix */
+ BKE_gpencil_layer_transform_matrix_get(p->depsgraph, p->ob, gpl, p->diff_mat);
+
+ /* loop over strokes, checking segments for intersections */
+ LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
+ /* check if the color is editable */
+ if (ED_gpencil_stroke_material_editable(p->ob, gpl, gps) == false) {
+ continue;
+ }
- /* Check if the stroke collide with mouse. */
- if (!ED_gpencil_stroke_check_collision(&p->gsc, gps, p->mval, calc_radius, p->diff_mat)) {
- continue;
- }
+ /* Check if the stroke collide with mouse. */
+ if (!ED_gpencil_stroke_check_collision(
+ &p->gsc, gps, p->mval, calc_radius, p->diff_mat)) {
+ continue;
+ }
- /* Not all strokes in the datablock may be valid in the current editor/context
- * (e.g. 2D space strokes in the 3D view, if the same datablock is shared)
- */
- if (ED_gpencil_stroke_can_use_direct(p->area, gps)) {
- gpencil_stroke_eraser_dostroke(p, gpf, gps, p->mval, calc_radius, &rect);
+ /* Not all strokes in the datablock may be valid in the current editor/context
+ * (e.g. 2D space strokes in the 3D view, if the same datablock is shared)
+ */
+ if (ED_gpencil_stroke_can_use_direct(p->area, gps)) {
+ gpencil_stroke_eraser_dostroke(p, gpl, gpf, gps, p->mval, calc_radius, &rect);
+ }
+ }
+
+ /* if not multiedit, exit loop*/
+ if (!is_multiedit) {
+ break;
+ }
}
}
}
}
-
/* ******************************************* */
/* Sketching Operator */
@@ -2103,6 +2124,11 @@ static void gpencil_paint_initstroke(tGPsdata *p,
copy_v3_v3(p->gpl->color, p->custom_color);
}
}
+
+ /* Recalculate layer transform matrix to avoid problems if props are animated. */
+ loc_eul_size_to_mat4(p->gpl->layer_mat, p->gpl->location, p->gpl->rotation, p->gpl->scale);
+ invert_m4_m4(p->gpl->layer_invmat, p->gpl->layer_mat);
+
if ((paintmode != GP_PAINTMODE_ERASER) && (p->gpl->flag & GP_LAYER_LOCKED)) {
p->status = GP_STATUS_ERROR;
if (G.debug & G_DEBUG) {
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 53e0043df37..bcdde49b93d 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -317,6 +317,10 @@ static void gpencil_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
}
tgpi->gpl = gpl;
+ /* Recalculate layer transform matrix to avoid problems if props are animated. */
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
/* create a new temporary frame */
tgpi->gpf = MEM_callocN(sizeof(bGPDframe), "Temp bGPDframe");
tgpi->gpf->framenum = tgpi->cframe = cfra;
@@ -1004,12 +1008,12 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
/* reproject current */
ED_gpencil_tpoint_to_point(tgpi->region, origin, tpt, &spt);
ED_gpencil_project_point_to_plane(
- tgpi->scene, tgpi->ob, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt);
+ tgpi->scene, tgpi->ob, tgpi->gpl, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt);
/* reproject previous */
ED_gpencil_tpoint_to_point(tgpi->region, origin, tptb, &spt2);
ED_gpencil_project_point_to_plane(
- tgpi->scene, tgpi->ob, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt2);
+ tgpi->scene, tgpi->ob, tgpi->gpl, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt2);
tgpi->totpixlen += len_v3v3(&spt.x, &spt2.x);
tpt->uv_fac = tgpi->totpixlen;
}
@@ -1068,7 +1072,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
float origin[3];
ED_gpencil_drawing_reference_get(tgpi->scene, tgpi->ob, ts->gpencil_v3d_align, origin);
ED_gpencil_project_stroke_to_plane(
- tgpi->scene, tgpi->ob, tgpi->rv3d, gps, origin, ts->gp_sculpt.lock_axis - 1);
+ tgpi->scene, tgpi->ob, tgpi->rv3d, tgpi->gpl, gps, origin, ts->gp_sculpt.lock_axis - 1);
}
/* if parented change position relative to parent object */
@@ -1373,6 +1377,12 @@ static void gpencil_primitive_interaction_end(bContext *C,
BKE_gpencil_stroke_geometry_update(tgpi->gpd, gps);
}
+ /* In Multiframe mode, duplicate the stroke in other frames. */
+ if (GPENCIL_MULTIEDIT_SESSIONS_ON(tgpi->gpd)) {
+ const bool tail = (ts->gpencil_flags & GP_TOOL_FLAG_PAINT_ONBACK);
+ BKE_gpencil_stroke_copy_to_keyframes(tgpi->gpd, tgpi->gpl, gpf, gps, tail);
+ }
+
DEG_id_tag_update(&tgpi->gpd->id, ID_RECALC_COPY_ON_WRITE);
DEG_id_tag_update(&tgpi->gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index bb9dd8cac5d..0d3ab9011d6 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -1441,11 +1441,6 @@ static bool gpencil_sculpt_brush_do_stroke(tGP_BrushEditData *gso,
bool changed = false;
float rot_eval = 0.0f;
- /* Check if the stroke collide with brush. */
- if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
- return false;
- }
-
if (gps->totpoints == 1) {
bGPDspoint pt_temp;
pt = &gps->points[0];
@@ -1577,6 +1572,13 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
Object *ob = gso->object;
bGPdata *gpd = ob->data;
char tool = gso->brush->gpencil_sculpt_tool;
+ GP_SpaceConversion *gsc = &gso->gsc;
+ Brush *brush = gso->brush;
+ const int radius = (brush->flag & GP_BRUSH_USE_PRESSURE) ? gso->brush->size * gso->pressure :
+ gso->brush->size;
+ /* Calc bound box matrix. */
+ float bound_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(gso->depsgraph, gso->object, gpl, bound_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
/* skip strokes that are invalid for current view */
@@ -1584,7 +1586,12 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
+ continue;
+ }
+
+ /* Check if the stroke collide with brush. */
+ if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
continue;
}
@@ -1742,7 +1749,8 @@ static bool gpencil_sculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *
/* calculate difference matrix */
float diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+ mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
/* Active Frame or MultiFrame? */
if (gso->is_multiframe) {
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index 281ab8c5adc..a00d21bf88a 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -2473,7 +2473,7 @@ static void gpencil_selected_hue_table(bContext *C,
if (ED_gpencil_stroke_can_use(C, gps) == false) {
continue;
}
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
if ((gps->flag & GP_STROKE_SELECT) == 0) {
diff --git a/source/blender/editors/gpencil/gpencil_trace_ops.c b/source/blender/editors/gpencil/gpencil_trace_ops.c
index 0be9d74278e..0f344909692 100644
--- a/source/blender/editors/gpencil/gpencil_trace_ops.c
+++ b/source/blender/editors/gpencil/gpencil_trace_ops.c
@@ -23,7 +23,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLT_translation.h"
@@ -31,34 +30,26 @@
#include "DNA_gpencil_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
#include "BKE_context.h"
-#include "BKE_duplilist.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
#include "BKE_image.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
-#include "BKE_material.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
-#include "UI_interface.h"
-#include "UI_resources.h"
-
#include "WM_api.h"
#include "WM_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
-#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "ED_gpencil.h"
@@ -66,7 +57,6 @@
#include "gpencil_intern.h"
#include "gpencil_trace.h"
-#include "potracelib.h"
typedef struct TraceJob {
/* from wmJob */
@@ -87,6 +77,7 @@ typedef struct TraceJob {
bGPDlayer *gpl;
bool was_ob_created;
+ bool use_current_frame;
int32_t frame_target;
float threshold;
@@ -228,15 +219,17 @@ static void trace_start_job(void *customdata, short *stop, short *do_update, flo
trace_job->do_update = do_update;
trace_job->progress = progress;
trace_job->was_canceled = false;
+ const int init_frame = max_ii((trace_job->use_current_frame) ? trace_job->frame_target : 0, 0);
G.is_break = false;
/* Single Image. */
-
if ((trace_job->image->source == IMA_SRC_FILE) ||
(trace_job->mode == GPENCIL_TRACE_MODE_SINGLE)) {
void *lock;
- ImBuf *ibuf = BKE_image_acquire_ibuf(trace_job->image, NULL, &lock);
+ ImageUser *iuser = trace_job->ob_active->iuser;
+ iuser->framenr = init_frame;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(trace_job->image, iuser, &lock);
if (ibuf) {
/* Create frame. */
bGPDframe *gpf = BKE_gpencil_layer_frame_get(
@@ -249,7 +242,7 @@ static void trace_start_job(void *customdata, short *stop, short *do_update, flo
/* Image sequence. */
else if (trace_job->image->type == IMA_TYPE_IMAGE) {
ImageUser *iuser = trace_job->ob_active->iuser;
- for (int i = 0; i < iuser->frames; i++) {
+ for (int i = init_frame; i < iuser->frames; i++) {
if (G.is_break) {
trace_job->was_canceled = true;
break;
@@ -320,6 +313,7 @@ static int gpencil_trace_image_exec(bContext *C, wmOperator *op)
job->ob_active = job->base_active->object;
job->image = (Image *)job->ob_active->data;
job->frame_target = CFRA;
+ job->use_current_frame = RNA_boolean_get(op->ptr, "use_current_frame");
/* Create a new grease pencil object or reuse selected. */
eGP_TargetObjectMode target = RNA_enum_get(op->ptr, "target");
@@ -493,4 +487,9 @@ void GPENCIL_OT_trace_image(wmOperatorType *ot)
GPENCIL_TRACE_MODE_SINGLE,
"Mode",
"Determines if trace simple image or full sequence");
+ RNA_def_boolean(ot->srna,
+ "use_current_frame",
+ true,
+ "Start At Current Frame",
+ "Trace Image starting in current image frame");
}
diff --git a/source/blender/editors/gpencil/gpencil_undo.c b/source/blender/editors/gpencil/gpencil_undo.c
index c2504ce329e..4e172104ce7 100644
--- a/source/blender/editors/gpencil/gpencil_undo.c
+++ b/source/blender/editors/gpencil/gpencil_undo.c
@@ -36,6 +36,7 @@
#include "BKE_blender_undo.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
+#include "BKE_undo_system.h"
#include "ED_gpencil.h"
@@ -61,28 +62,22 @@ int ED_gpencil_session_active(void)
return (BLI_listbase_is_empty(&undo_nodes) == false);
}
-int ED_undo_gpencil_step(bContext *C, int step, const char *name)
+int ED_undo_gpencil_step(bContext *C, const eUndoStepDir step)
{
bGPdata **gpd_ptr = NULL, *new_gpd = NULL;
gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
- if (step == 1) { /* undo */
- // printf("\t\tGP - undo step\n");
+ if (step == STEP_UNDO) {
if (cur_node->prev) {
- if (!name || STREQ(cur_node->name, name)) {
- cur_node = cur_node->prev;
- new_gpd = cur_node->gpd;
- }
+ cur_node = cur_node->prev;
+ new_gpd = cur_node->gpd;
}
}
- else if (step == -1) {
- // printf("\t\tGP - redo step\n");
+ else if (step == STEP_REDO) {
if (cur_node->next) {
- if (!name || STREQ(cur_node->name, name)) {
- cur_node = cur_node->next;
- new_gpd = cur_node->gpd;
- }
+ cur_node = cur_node->next;
+ new_gpd = cur_node->gpd;
}
}
@@ -99,7 +94,7 @@ int ED_undo_gpencil_step(bContext *C, int step, const char *name)
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* make a copy of source layer and its data */
- gpld = BKE_gpencil_layer_duplicate(gpl);
+ gpld = BKE_gpencil_layer_duplicate(gpl, true, true);
BLI_addtail(&gpd->layers, gpld);
}
}
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 7c796f7b7a1..9b12772bc9b 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -579,7 +579,7 @@ bool ED_gpencil_stroke_can_use(const bContext *C, const bGPDstroke *gps)
}
/* Check whether given stroke can be edited for the current color */
-bool ED_gpencil_stroke_color_use(Object *ob, const bGPDlayer *gpl, const bGPDstroke *gps)
+bool ED_gpencil_stroke_material_editable(Object *ob, const bGPDlayer *gpl, const bGPDstroke *gps)
{
/* check if the color is editable */
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
@@ -674,7 +674,7 @@ void gpencil_apply_parent(Depsgraph *depsgraph, Object *obact, bGPDlayer *gpl, b
float inverse_diff_mat[4][4];
float fpt[3];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
for (i = 0; i < gps->totpoints; i++) {
@@ -697,10 +697,11 @@ void gpencil_apply_parent_point(Depsgraph *depsgraph,
float inverse_diff_mat[4][4];
float fpt[3];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
mul_v3_m4v3(fpt, inverse_diff_mat, &pt->x);
+
copy_v3_v3(&pt->x, fpt);
}
@@ -997,6 +998,12 @@ void ED_gpencil_drawing_reference_get(const Scene *scene,
else {
/* use object location */
copy_v3_v3(r_vec, ob->obmat[3]);
+ /* Apply layer offset. */
+ bGPdata *gpd = ob->data;
+ bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
+ if (gpl != NULL) {
+ add_v3_v3(r_vec, gpl->layer_mat[3]);
+ }
}
}
}
@@ -1021,7 +1028,7 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
/* init space conversion stuff */
gpencil_point_conversion_init(C, &gsc);
- BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
/* Adjust each point */
@@ -1046,6 +1053,7 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
void ED_gpencil_project_stroke_to_plane(const Scene *scene,
const Object *ob,
const RegionView3D *rv3d,
+ bGPDlayer *gpl,
bGPDstroke *gps,
const float origin[3],
const int axis)
@@ -1058,6 +1066,10 @@ void ED_gpencil_project_stroke_to_plane(const Scene *scene,
float ray[3];
float rpoint[3];
+ /* Recalculate layer transform matrix. */
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
/* normal vector for a plane locked to axis */
zero_v3(plane_normal);
if (axis < 0) {
@@ -1074,24 +1086,27 @@ void ED_gpencil_project_stroke_to_plane(const Scene *scene,
copy_m4_m4(mat, ob->obmat);
/* move origin to cursor */
+ if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
+ if (gpl != NULL) {
+ add_v3_v3(mat[3], gpl->location);
+ }
+ }
if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) {
copy_v3_v3(mat[3], cursor->location);
}
mul_mat3_m4_v3(mat, plane_normal);
}
+
+ if ((gpl != NULL) && (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR)) {
+ mul_mat3_m4_v3(gpl->layer_mat, plane_normal);
+ }
}
else {
const float scale[3] = {1.0f, 1.0f, 1.0f};
plane_normal[2] = 1.0f;
float mat[4][4];
loc_eul_size_to_mat4(mat, cursor->location, cursor->rotation_euler, scale);
-
- /* move origin to object */
- if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
- copy_v3_v3(mat[3], ob->obmat[3]);
- }
-
mul_mat3_m4_v3(mat, plane_normal);
}
@@ -1127,8 +1142,12 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
ARegion *region = gsc->region;
RegionView3D *rv3d = region->regiondata;
+ /* Recalculate layer transform matrix. */
+ loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+ invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
float diff_mat[4][4], inverse_diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, gsc->ob, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, gsc->ob, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
float origin[3];
@@ -1194,7 +1213,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
}
}
- ED_gpencil_project_point_to_plane(gsc->scene, gsc->ob, rv3d, origin, axis, &pt2);
+ ED_gpencil_project_point_to_plane(gsc->scene, gsc->ob, gpl, rv3d, origin, axis, &pt2);
copy_v3_v3(&pt->x, &pt2.x);
@@ -1250,6 +1269,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
*/
void ED_gpencil_project_point_to_plane(const Scene *scene,
const Object *ob,
+ bGPDlayer *gpl,
const RegionView3D *rv3d,
const float origin[3],
const int axis,
@@ -1277,6 +1297,11 @@ void ED_gpencil_project_point_to_plane(const Scene *scene,
if (ob && (ob->type == OB_GPENCIL)) {
float mat[4][4];
copy_m4_m4(mat, ob->obmat);
+ if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
+ if (gpl != NULL) {
+ add_v3_v3(mat[3], gpl->location);
+ }
+ }
/* move origin to cursor */
if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) {
@@ -1284,6 +1309,10 @@ void ED_gpencil_project_point_to_plane(const Scene *scene,
}
mul_mat3_m4_v3(mat, plane_normal);
+ /* Apply layer rotation (local transform). */
+ if ((gpl != NULL) && (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR)) {
+ mul_mat3_m4_v3(gpl->layer_mat, plane_normal);
+ }
}
}
else {
@@ -1449,7 +1478,7 @@ void ED_gpencil_reset_layers_parent(Depsgraph *depsgraph, Object *obact, bGPdata
/* only redo if any change */
if (!equals_m4m4(gpl->inverse, cur_mat)) {
/* first apply current transformation to all strokes */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
/* undo local object */
sub_v3_v3(diff_mat[3], gpl_loc);
@@ -2144,7 +2173,7 @@ void ED_gpencil_update_color_uv(Main *bmain, Material *mat)
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
/* check if it is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
gps_ma = BKE_gpencil_material(ob, gps->mat_nr + 1);
@@ -3003,12 +3032,12 @@ void ED_gpencil_sbuffer_vertex_color_set(Depsgraph *depsgraph,
}
}
-/* Helper to get the bigger 2D bound box points. */
-static void gpencil_projected_2d_bound_box(GP_SpaceConversion *gsc,
- bGPDstroke *gps,
- const float diff_mat[4][4],
- float r_min[2],
- float r_max[2])
+/* Get the bigger 2D bound box points. */
+void ED_gpencil_projected_2d_bound_box(GP_SpaceConversion *gsc,
+ bGPDstroke *gps,
+ const float diff_mat[4][4],
+ float r_min[2],
+ float r_max[2])
{
float bounds[8][2];
BoundBox bb;
@@ -3053,7 +3082,7 @@ bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc,
BKE_gpencil_stroke_boundingbox_calc(gps);
}
- gpencil_projected_2d_bound_box(gsc, gps, diff_mat, boundbox_min, boundbox_max);
+ ED_gpencil_projected_2d_bound_box(gsc, gps, diff_mat, boundbox_min, boundbox_max);
rcti rect_stroke = {boundbox_min[0], boundbox_max[0], boundbox_min[1], boundbox_max[1]};
@@ -3126,7 +3155,7 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
/* calculate difference matrix object */
float diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
/* Calculate the extremes of the stroke in 2D. */
bGPDspoint pt_parent;
@@ -3144,15 +3173,13 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
float dist_min = FLT_MAX;
LISTBASE_FOREACH (bGPDstroke *, gps_target, &gpf->strokes) {
/* Check if the color is editable. */
- if ((gps_target == gps) || (ED_gpencil_stroke_color_use(ob, gpl, gps) == false)) {
+ if ((gps_target == gps) || (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false)) {
continue;
}
/* Check if one of the ends is inside target stroke bounding box. */
- if (!ED_gpencil_stroke_check_collision(gsc, gps, pt2d_start, radius, diff_mat)) {
- continue;
- }
- if (!ED_gpencil_stroke_check_collision(gsc, gps, pt2d_end, radius, diff_mat)) {
+ if ((!ED_gpencil_stroke_check_collision(gsc, gps_target, pt2d_start, radius, diff_mat)) &&
+ (!ED_gpencil_stroke_check_collision(gsc, gps_target, pt2d_end, radius, diff_mat))) {
continue;
}
/* Check the distance of the ends with the ends of target stroke to avoid middle contact.
diff --git a/source/blender/editors/gpencil/gpencil_uv.c b/source/blender/editors/gpencil/gpencil_uv.c
index ec2ccabddfe..677451eaabc 100644
--- a/source/blender/editors/gpencil/gpencil_uv.c
+++ b/source/blender/editors/gpencil/gpencil_uv.c
@@ -31,7 +31,6 @@
#include "BKE_context.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_geom.h"
-#include "BKE_unit.h"
#include "RNA_access.h"
#include "RNA_define.h"
diff --git a/source/blender/editors/gpencil/gpencil_vertex_ops.c b/source/blender/editors/gpencil/gpencil_vertex_ops.c
index b212872b607..bf46fa2544f 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_ops.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_ops.c
@@ -28,16 +28,11 @@
#include "BLI_ghash.h"
#include "BLI_math.h"
-#include "BLT_translation.h"
-
#include "DNA_brush_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_material_types.h"
-#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_gpencil.h"
-#include "BKE_gpencil_modifier.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_paint.h"
@@ -48,16 +43,11 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "UI_view2d.h"
#include "ED_gpencil.h"
#include "ED_screen.h"
-#include "ED_view3d.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "gpencil_intern.h"
@@ -674,7 +664,7 @@ static bool gpencil_extract_palette_from_vertex(bContext *C,
if (ED_gpencil_stroke_can_use(C, gps) == false) {
continue;
}
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
@@ -859,7 +849,7 @@ static int gpencil_material_to_vertex_exec(bContext *C, wmOperator *op)
if (ED_gpencil_stroke_can_use(C, gps) == false) {
continue;
}
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c
index e2c81d53fba..a05cc3c4dbd 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_paint.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c
@@ -151,7 +151,7 @@ typedef struct tGP_BrushVertexpaintData {
tGP_Grid *grid;
/** Total number of rows/cols. */
int grid_size;
- /** Total number of cells elments in the grid array. */
+ /** Total number of cells elements in the grid array. */
int grid_len;
/** Grid sample position (used to determine distance of falloff) */
int grid_sample[2];
@@ -825,7 +825,8 @@ static void gpencil_save_selected_point(tGP_BrushVertexpaintData *gso,
static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
bGPDstroke *gps,
const char tool,
- const float diff_mat[4][4])
+ const float diff_mat[4][4],
+ const float bound_mat[4][4])
{
GP_SpaceConversion *gsc = &gso->gsc;
rcti *rect = &gso->brush_rect;
@@ -853,7 +854,7 @@ static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
}
/* Check if the stroke collide with brush. */
- if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
+ if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
return false;
}
@@ -998,7 +999,8 @@ static bool gpencil_vertexpaint_brush_do_frame(bContext *C,
tGP_BrushVertexpaintData *gso,
bGPDlayer *gpl,
bGPDframe *gpf,
- const float diff_mat[4][4])
+ const float diff_mat[4][4],
+ const float bound_mat[4][4])
{
Object *ob = CTX_data_active_object(C);
const char tool = ob->mode == OB_MODE_VERTEX_GPENCIL ? gso->brush->gpencil_vertex_tool :
@@ -1020,12 +1022,12 @@ static bool gpencil_vertexpaint_brush_do_frame(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* Check points below the brush. */
- bool hit = gpencil_vertexpaint_select_stroke(gso, gps, tool, diff_mat);
+ bool hit = gpencil_vertexpaint_select_stroke(gso, gps, tool, diff_mat, bound_mat);
/* If stroke was hit and has an editcurve the curve needs an update. */
bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
@@ -1130,9 +1132,11 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
continue;
}
- /* calculate difference matrix */
- float diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ /* Calculate transform matrix. */
+ float diff_mat[4][4], bound_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+ copy_m4_m4(bound_mat, diff_mat);
+ mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
/* Active Frame or MultiFrame? */
if (gso->is_multiframe) {
@@ -1159,7 +1163,7 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
}
/* affect strokes in this frame */
- changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
+ changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat, bound_mat);
}
}
}
@@ -1167,7 +1171,8 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
/* Apply to active frame's strokes */
if (gpl->actframe != NULL) {
gso->mf_falloff = 1.0f;
- changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
+ changed |= gpencil_vertexpaint_brush_do_frame(
+ C, gso, gpl, gpl->actframe, diff_mat, bound_mat);
}
}
}
diff --git a/source/blender/editors/gpencil/gpencil_weight_paint.c b/source/blender/editors/gpencil/gpencil_weight_paint.c
index 7fa71fcce3c..a3e5ece5862 100644
--- a/source/blender/editors/gpencil/gpencil_weight_paint.c
+++ b/source/blender/editors/gpencil/gpencil_weight_paint.c
@@ -383,7 +383,8 @@ static void gpencil_save_selected_point(tGP_BrushWeightpaintData *gso,
/* Select points in this stroke and add to an array to be used later. */
static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
bGPDstroke *gps,
- const float diff_mat[4][4])
+ const float diff_mat[4][4],
+ const float bound_mat[4][4])
{
GP_SpaceConversion *gsc = &gso->gsc;
rcti *rect = &gso->brush_rect;
@@ -402,7 +403,7 @@ static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
bool include_last = false;
/* Check if the stroke collide with brush. */
- if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
+ if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
return;
}
@@ -505,7 +506,8 @@ static bool gpencil_weightpaint_brush_do_frame(bContext *C,
tGP_BrushWeightpaintData *gso,
bGPDlayer *gpl,
bGPDframe *gpf,
- const float diff_mat[4][4])
+ const float diff_mat[4][4],
+ const float bound_mat[4][4])
{
Object *ob = CTX_data_active_object(C);
char tool = gso->brush->gpencil_weight_tool;
@@ -526,12 +528,12 @@ static bool gpencil_weightpaint_brush_do_frame(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) {
continue;
}
/* Check points below the brush. */
- gpencil_weightpaint_select_stroke(gso, gps, diff_mat);
+ gpencil_weightpaint_select_stroke(gso, gps, diff_mat, bound_mat);
}
/*---------------------------------------------------------------------
@@ -578,9 +580,11 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
continue;
}
- /* calculate difference matrix */
- float diff_mat[4][4];
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ /* Calculate transform matrix. */
+ float diff_mat[4][4], bound_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+ copy_m4_m4(bound_mat, diff_mat);
+ mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
/* Active Frame or MultiFrame? */
if (gso->is_multiframe) {
@@ -608,7 +612,7 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
}
/* affect strokes in this frame */
- changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
+ changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat, bound_mat);
}
}
}
@@ -616,7 +620,8 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
if (gpl->actframe != NULL) {
/* Apply to active frame's strokes */
gso->mf_falloff = 1.0f;
- changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
+ changed |= gpencil_weightpaint_brush_do_frame(
+ C, gso, gpl, gpl->actframe, diff_mat, bound_mat);
}
}
}
diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h
index 0a66c439f79..56494f87bfe 100644
--- a/source/blender/editors/include/ED_clip.h
+++ b/source/blender/editors/include/ED_clip.h
@@ -99,6 +99,30 @@ void ED_space_clip_set_clip(struct bContext *C,
struct Mask *ED_space_clip_get_mask(struct SpaceClip *sc);
void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask);
+/* Locked state is used to preserve current clip editor viewport upon changes. Example usage:
+ *
+ * ...
+ *
+ * ClipViewLockState lock_state;
+ * ED_clip_view_lock_state_store(C, &lock_state);
+ *
+ * <change selection>
+ *
+ * ED_clip_view_lock_state_restore_no_jump(C, &lock_state);
+ *
+ * These function are to be used from space clip editor context only. Otherwise debug builds will
+ * assert, release builds will crash. */
+
+typedef struct ClipViewLockState {
+ float offset_x, offset_y;
+ float lock_offset_x, lock_offset_y;
+ float zoom;
+} ClipViewLockState;
+
+void ED_clip_view_lock_state_store(const struct bContext *C, ClipViewLockState *state);
+void ED_clip_view_lock_state_restore_no_jump(const struct bContext *C,
+ const ClipViewLockState *state);
+
/* ** clip_ops.c ** */
void ED_operatormacros_clip(void);
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index d12882f0e29..7538dac1354 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -194,7 +194,7 @@ typedef enum FSMenuInsert {
FS_INSERT_SAVE = (1 << 1),
/** moves the item to the front of the list when its not already there */
FS_INSERT_FIRST = (1 << 2),
- /** just append to preseve delivered order */
+ /** just append to preserve delivered order */
FS_INSERT_LAST = (1 << 3),
} FSMenuInsert;
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 1b7caf27ecf..12aef6e9464 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -62,6 +62,8 @@ struct bAnimContext;
struct wmKeyConfig;
struct wmOperator;
+enum eUndoStepDir;
+
#define GPENCIL_MINIMUM_JOIN_DIST 20.0f
/* Reproject stroke modes. */
@@ -147,9 +149,9 @@ bool ED_gpencil_has_keyframe_v3d(struct Scene *scene, struct Object *ob, int cfr
bool ED_gpencil_stroke_can_use_direct(const struct ScrArea *area, const struct bGPDstroke *gps);
bool ED_gpencil_stroke_can_use(const struct bContext *C, const struct bGPDstroke *gps);
-bool ED_gpencil_stroke_color_use(struct Object *ob,
- const struct bGPDlayer *gpl,
- const struct bGPDstroke *gps);
+bool ED_gpencil_stroke_material_editable(struct Object *ob,
+ const struct bGPDlayer *gpl,
+ const struct bGPDstroke *gps);
/* ----------- Grease Pencil Operators ----------------- */
@@ -213,7 +215,7 @@ bool ED_gpencil_anim_copybuf_paste(struct bAnimContext *ac, const short copy_mod
/* ------------ Grease-Pencil Undo System ------------------ */
int ED_gpencil_session_active(void);
-int ED_undo_gpencil_step(struct bContext *C, int step, const char *name);
+int ED_undo_gpencil_step(struct bContext *C, const enum eUndoStepDir step);
/* ------------ Grease-Pencil Armature ------------------ */
bool ED_gpencil_add_armature(const struct bContext *C,
@@ -263,11 +265,13 @@ bool ED_object_gpencil_exit(struct Main *bmain, struct Object *ob);
void ED_gpencil_project_stroke_to_plane(const struct Scene *scene,
const struct Object *ob,
const struct RegionView3D *rv3d,
+ struct bGPDlayer *gpl,
struct bGPDstroke *gps,
const float origin[3],
const int axis);
void ED_gpencil_project_point_to_plane(const struct Scene *scene,
const struct Object *ob,
+ struct bGPDlayer *gpl,
const struct RegionView3D *rv3d,
const float origin[3],
const int axis,
@@ -366,6 +370,11 @@ bool ED_gpencil_stroke_point_is_inside(struct bGPDstroke *gps,
struct GP_SpaceConversion *gsc,
int mouse[2],
const float diff_mat[4][4]);
+void ED_gpencil_projected_2d_bound_box(struct GP_SpaceConversion *gsc,
+ 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,
diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h
index 3cc77887b1a..2f8faf1b2bd 100644
--- a/source/blender/editors/include/ED_keyframes_draw.h
+++ b/source/blender/editors/include/ED_keyframes_draw.h
@@ -95,6 +95,8 @@ typedef enum eActKeyBlock_Hold {
ACTKEYBLOCK_FLAG_ANY_HOLD = (1 << 2),
/* The curve segment uses non-bezier interpolation */
ACTKEYBLOCK_FLAG_NON_BEZIER = (1 << 3),
+ /* The block is grease pencil */
+ ACTKEYBLOCK_FLAG_GPENCIL = (1 << 4),
} eActKeyBlock_Flag;
/* *********************** Keyframe Drawing ****************************** */
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index b08ab57545f..63f124798aa 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -118,7 +118,7 @@ typedef struct KeyframeEdit_CircleData {
} KeyframeEdit_CircleData;
/* ************************************************ */
-/* Non-Destuctive Editing API (keyframes_edit.c) */
+/* Non-Destructive Editing API (keyframes_edit.c) */
/* --- Defines for 'OK' polls + KeyframeEditData Flags --------- */
diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h
index bcf52da3f69..247911bdc55 100644
--- a/source/blender/editors/include/ED_mask.h
+++ b/source/blender/editors/include/ED_mask.h
@@ -63,7 +63,10 @@ void ED_mask_point_pos__reverse(
struct ScrArea *area, struct ARegion *region, float x, float y, float *xr, float *yr);
void ED_mask_cursor_location_get(struct ScrArea *area, float cursor[2]);
-bool ED_mask_selected_minmax(const struct bContext *C, float min[2], float max[2]);
+bool ED_mask_selected_minmax(const struct bContext *C,
+ float min[2],
+ float max[2],
+ bool handles_as_control_point);
/* mask_draw.c */
void ED_mask_draw(const struct bContext *C, const char draw_flag, const char draw_type);
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index 417cae800ea..78f354a300d 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -51,6 +51,10 @@ typedef enum {
#define NODE_GRID_STEPS 5
/* space_node.c */
+
+void ED_node_cursor_location_get(const struct SpaceNode *snode, float value[2]);
+void ED_node_cursor_location_set(struct SpaceNode *snode, const float value[2]);
+
int ED_node_tree_path_length(struct SpaceNode *snode);
void ED_node_tree_path_get(struct SpaceNode *snode, char *value);
void ED_node_tree_path_get_fixedbuf(struct SpaceNode *snode, char *value, int max_length);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index bd1a4a0c63f..73326a2d5f2 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -159,7 +159,7 @@ extern struct EnumPropertyItem prop_clear_parent_types[];
extern struct EnumPropertyItem prop_make_parent_types[];
#endif
-/* Set the object's parent, return true iff successful. */
+/* Set the object's parent, return true if successful. */
bool ED_object_parent_set(struct ReportList *reports,
const struct bContext *C,
struct Scene *scene,
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 20417634020..deb6b7502c7 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -57,15 +57,14 @@ struct wmMsgSubscribeKey;
struct wmMsgSubscribeValue;
struct wmNotifier;
struct wmOperatorType;
+struct wmRegionListenerParams;
+struct wmRegionMessageSubscribeParams;
+struct wmSpaceTypeListenerParams;
struct wmWindow;
struct wmWindowManager;
/* regions */
-void ED_region_do_listen(struct wmWindow *win,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmNotifier *note,
- const Scene *scene);
+void ED_region_do_listen(struct wmRegionListenerParams *params);
void ED_region_do_layout(struct bContext *C, struct ARegion *region);
void ED_region_do_draw(struct bContext *C, struct ARegion *region);
void ED_region_exit(struct bContext *C, struct ARegion *region);
@@ -144,29 +143,11 @@ void ED_area_do_msg_notify_tag_refresh(struct bContext *C,
struct wmMsgSubscribeKey *msg_key,
struct wmMsgSubscribeValue *msg_val);
-void ED_area_do_mgs_subscribe_for_tool_header(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
-void ED_area_do_mgs_subscribe_for_tool_ui(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
+void ED_area_do_mgs_subscribe_for_tool_header(const struct wmRegionMessageSubscribeParams *params);
+void ED_area_do_mgs_subscribe_for_tool_ui(const struct wmRegionMessageSubscribeParams *params);
/* message bus */
-void ED_region_message_subscribe(struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
+void ED_region_message_subscribe(struct wmRegionMessageSubscribeParams *params);
/* spaces */
void ED_spacetypes_keymap(struct wmKeyConfig *keyconf);
@@ -178,7 +159,7 @@ void ED_area_exit(struct bContext *C, struct ScrArea *area);
int ED_screen_area_active(const struct bContext *C);
void ED_screen_global_areas_refresh(struct wmWindow *win);
void ED_screen_global_areas_sync(struct wmWindow *win);
-void ED_area_do_listen(struct wmWindow *win, ScrArea *area, struct wmNotifier *note, Scene *scene);
+void ED_area_do_listen(struct wmSpaceTypeListenerParams *params);
void ED_area_tag_redraw(ScrArea *area);
void ED_area_tag_redraw_no_rebuild(ScrArea *area);
void ED_area_tag_redraw_regiontype(ScrArea *area, int type);
@@ -427,13 +408,8 @@ void ED_region_cache_draw_cached_segments(struct ARegion *region,
const int efra);
/* area_utils.c */
-void ED_region_generic_tools_region_message_subscribe(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus);
+void ED_region_generic_tools_region_message_subscribe(
+ const struct wmRegionMessageSubscribeParams *params);
int ED_region_generic_tools_region_snap_size(const struct ARegion *region, int size, int axis);
/* area_query.c */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index ca3e351a052..8f1be847e2b 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -40,7 +40,7 @@ void transform_operatortypes(void);
/* ******************** Macros & Prototypes *********************** */
/* MODE AND NUMINPUT FLAGS */
-enum TfmMode {
+typedef enum {
TFM_INIT = -1,
TFM_DUMMY,
TFM_TRANSLATION,
@@ -77,29 +77,11 @@ enum TfmMode {
TFM_BONE_ENVELOPE_DIST,
TFM_NORMAL_ROTATION,
TFM_GPENCIL_OPACITY,
-};
-
-/* TRANSFORM CONTEXTS */
-#define CTX_NONE 0
-#define CTX_TEXTURE (1 << 0)
-#define CTX_EDGE (1 << 1)
-#define CTX_NO_PET (1 << 2)
-#define CTX_NO_MIRROR (1 << 3)
-#define CTX_AUTOCONFIRM (1 << 4)
-#define CTX_MOVIECLIP (1 << 6)
-#define CTX_MASK (1 << 7)
-#define CTX_PAINT_CURVE (1 << 8)
-#define CTX_GPENCIL_STROKES (1 << 9)
-#define CTX_CURSOR (1 << 10)
-/** When transforming object's, adjust the object data so it stays in the same place. */
-#define CTX_OBMODE_XFORM_OBDATA (1 << 11)
-/** Transform object parents without moving their children. */
-#define CTX_OBMODE_XFORM_SKIP_CHILDREN (1 << 12)
+} eTfmMode;
/* Standalone call to get the transformation center corresponding to the current situation
* returns 1 if successful, 0 otherwise (usually means there's no selection)
- * (if 0 is returns, *vec is unmodified)
- * */
+ * (if false is returns, `cent3d` is unmodified). */
bool calculateTransformCenter(struct bContext *C,
int centerMode,
float cent3d[3],
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 7bbb7225f14..066d262cc44 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -56,6 +56,7 @@ struct bNode;
struct bNodeSocket;
struct bNodeTree;
struct bScreen;
+struct rctf;
struct rcti;
struct uiButSearch;
struct uiFontStyle;
@@ -414,57 +415,38 @@ void UI_draw_anti_tria(
void UI_draw_anti_fan(float tri_array[][2], unsigned int length, const float color[4]);
void UI_draw_roundbox_corner_set(int type);
-void UI_draw_roundbox_aa(
- bool filled, float minx, float miny, float maxx, float maxy, float rad, const float color[4]);
-void UI_draw_roundbox_4fv(
- bool filled, float minx, float miny, float maxx, float maxy, float rad, const float col[4]);
-void UI_draw_roundbox_3ub_alpha(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
+void UI_draw_roundbox_aa(const struct rctf *rect, bool filled, float rad, const float color[4]);
+void UI_draw_roundbox_4fv(const struct rctf *rect, bool filled, float rad, const float col[4]);
+void UI_draw_roundbox_3ub_alpha(const struct rctf *rect,
+ bool filled,
float rad,
const unsigned char col[3],
unsigned char alpha);
-void UI_draw_roundbox_3fv_alpha(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float rad,
- const float col[3],
- float alpha);
-void UI_draw_roundbox_shade_x(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
+void UI_draw_roundbox_3fv_alpha(
+ const struct rctf *rect, bool filled, float rad, const float col[3], float alpha);
+void UI_draw_roundbox_shade_x(const struct rctf *rect,
+ bool filled,
float rad,
float shadetop,
float shadedown,
const float col[4]);
+void UI_draw_roundbox_4fv_ex(const struct rctf *rect,
+ const float inner1[4],
+ const float inner2[4],
+ float shade_dir,
+ const float outline[4],
+ float outline_width,
+ float rad);
#if 0 /* unused */
int UI_draw_roundbox_corner_get(void);
-void UI_draw_roundbox_shade_y(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float rad,
- float shadeleft,
- float shaderight,
- const float col[4]);
#endif
-void UI_draw_box_shadow(unsigned char alpha, float minx, float miny, float maxx, float maxy);
+void UI_draw_box_shadow(const struct rctf *rect, unsigned char alpha);
void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4]);
void UI_draw_safe_areas(uint pos,
- float x1,
- float x2,
- float y1,
- float y2,
+ const struct rctf *rect,
const float title_aspect[2],
const float action_aspect[2]);
@@ -526,6 +508,7 @@ typedef bool (*uiButSearchContextMenuFn)(struct bContext *C,
const struct wmEvent *event);
typedef struct ARegion *(*uiButSearchTooltipFn)(struct bContext *C,
struct ARegion *region,
+ const struct rcti *item_rect,
void *arg,
void *active);
@@ -664,8 +647,7 @@ bool UI_popup_block_name_exists(const struct bScreen *screen, const char *name);
* Begin/Define Buttons/End/Draw is the typical order in which these
* function should be called, though for popup blocks Draw is left out.
* Freeing blocks is done by the screen/ module automatically.
- *
- * */
+ */
uiBlock *UI_block_begin(const struct bContext *C,
struct ARegion *region,
@@ -1431,6 +1413,8 @@ enum {
int UI_icon_from_id(struct ID *id);
int UI_icon_from_report_type(int type);
+int UI_icon_colorid_from_report_type(int type);
+int UI_text_colorid_from_report_type(int type);
int UI_icon_from_event_type(short event_type, short event_value);
int UI_icon_from_keymap_item(const struct wmKeyMapItem *kmi, int r_icon_mod[4]);
@@ -2499,11 +2483,12 @@ void UI_context_active_but_prop_get_templateID(struct bContext *C,
struct PropertyRNA **r_prop);
struct ID *UI_context_active_but_get_tab_ID(struct bContext *C);
-uiBut *UI_region_active_but_get(struct ARegion *region);
+uiBut *UI_region_active_but_get(const struct ARegion *region);
uiBut *UI_region_but_find_rect_over(const struct ARegion *region, const struct rcti *rect_px);
uiBlock *UI_region_block_find_mouse_over(const struct ARegion *region,
const int xy[2],
bool only_clip);
+struct ARegion *UI_region_searchbox_region_get(const struct ARegion *button_region);
/* uiFontStyle.align */
typedef enum eFontStyle_Align {
@@ -2583,6 +2568,21 @@ struct ARegion *UI_tooltip_create_from_button(struct bContext *C,
struct ARegion *UI_tooltip_create_from_gizmo(struct bContext *C, struct wmGizmo *gz);
void UI_tooltip_free(struct bContext *C, struct bScreen *screen, struct ARegion *region);
+typedef struct {
+ /** A description for the item, e.g. what happens when selecting it. */
+ char description[UI_MAX_DRAW_STR];
+ /* The full name of the item, without prefixes or suffixes (e.g. hint with UI_SEP_CHARP). */
+ const char *name;
+ /** Additional info about the item (e.g. library name of a linked data-block). */
+ char hint[UI_MAX_DRAW_STR];
+} uiSearchItemTooltipData;
+
+struct ARegion *UI_tooltip_create_from_search_item_generic(
+ struct bContext *C,
+ const struct ARegion *searchbox_region,
+ const struct rcti *item_rect,
+ const uiSearchItemTooltipData *item_tooltip_data);
+
/* How long before a tool-tip shows. */
#define UI_TOOLTIP_DELAY 0.5
#define UI_TOOLTIP_DELAY_LABEL 0.2
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index d77a87e7200..266a538b6c3 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -23,6 +23,9 @@
#pragma once
+/* Required for #eIconSizes which can't be forward declared if this file is included in C++. */
+#include "DNA_ID_enums.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -34,8 +37,6 @@ struct PreviewImage;
struct Scene;
struct bContext;
-enum eIconSizes;
-
typedef struct IconFile {
struct IconFile *next, *prev;
char filename[256]; /* FILE_MAXFILE size */
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index c09bf41e152..1820c2f133c 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -433,7 +433,7 @@ void UI_GetColorPtrBlendShade3ubv(const unsigned char cp1[3],
* (for anything fancy use UI_GetThemeColor[Fancy] then BLF_color) */
void UI_FontThemeColor(int fontid, int colorid);
-/* clear the framebuffer using the input colorid */
+/* Clear the frame-buffer using the input colorid. */
void UI_ThemeClearColor(int colorid);
/* internal (blender) usage only, for init and set active */
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index 8df29e5b520..64f881052a1 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -231,7 +231,7 @@ struct View2D *UI_view2d_fromcontext(const struct bContext *C);
struct View2D *UI_view2d_fromcontext_rwin(const struct bContext *C);
void UI_view2d_scroller_size_get(const struct View2D *v2d, float *r_x, float *r_y);
-void UI_view2d_scale_get(struct View2D *v2d, float *r_x, float *r_y);
+void UI_view2d_scale_get(const struct View2D *v2d, float *r_x, float *r_y);
float UI_view2d_scale_get_x(const struct View2D *v2d);
float UI_view2d_scale_get_y(const struct View2D *v2d);
void UI_view2d_scale_get_inverse(const struct View2D *v2d, float *r_x, float *r_y);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 319ae385ffc..10cbc2dc5fa 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1284,12 +1284,10 @@ static bool ui_but_event_property_operator_string(const bContext *C,
char *buf,
const size_t buf_len)
{
- /* context toggle operator names to check... */
+ /* Context toggle operator names to check. */
/* This function could use a refactor to generalize button type to operator relationship
- * as well as which operators use properties.
- * - Campbell
- * */
+ * as well as which operators use properties. - Campbell */
const char *ctx_toggle_opnames[] = {
"WM_OT_context_toggle",
"WM_OT_context_toggle_enum",
@@ -1424,10 +1422,10 @@ static bool ui_but_event_property_operator_string(const bContext *C,
// printf("prop shortcut: '%s' (%s)\n", RNA_property_identifier(prop), data_path);
}
- /* we have a datapath! */
+ /* We have a data-path! */
bool found = false;
if (data_path || (prop_enum_value_ok && prop_enum_value_id)) {
- /* create a property to host the "datapath" property we're sending to the operators */
+ /* Create a property to host the "data_path" property we're sending to the operators. */
IDProperty *prop_path;
const IDPropertyTemplate val = {0};
@@ -1947,7 +1945,7 @@ void ui_fontscale(short *points, float aspect)
}
}
-/* project button or block (but==NULL) to pixels in regionspace */
+/* Project button or block (but==NULL) to pixels in region-space. */
static void ui_but_to_pixelrect(rcti *rect, const ARegion *region, uiBlock *block, uiBut *but)
{
rctf rectf;
@@ -4026,7 +4024,7 @@ static uiBut *ui_def_but(uiBlock *block,
but->emboss = block->emboss;
but->pie_dir = UI_RADIAL_NONE;
- but->block = block; /* pointer back, used for frontbuffer status, and picker */
+ but->block = block; /* pointer back, used for front-buffer status, and picker. */
if ((block->flag & UI_BUT_ALIGN) && ui_but_can_align(but)) {
but->alignnr = block->alignnr;
@@ -4749,7 +4747,7 @@ static int findBitIndex(uint x)
return idx;
}
-/* autocomplete helper functions */
+/* Auto-complete helper functions. */
struct AutoComplete {
size_t maxlen;
int matches;
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index 85730d138ac..53a04ec9db5 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -953,7 +953,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
}
}
- /* If the button reprents an id, it can set the "id" context pointer. */
+ /* If the button represents an id, it can set the "id" context pointer. */
if (U.experimental.use_asset_browser && ED_asset_can_make_single_from_context(C)) {
ID *id = CTX_data_pointer_get_type(C, "id", &RNA_ID).data;
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 5bb6b0f21e7..d10cdc207c2 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -81,544 +81,116 @@ int UI_draw_roundbox_corner_get(void)
}
#endif
-void UI_draw_roundbox_3ub_alpha(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float rad,
- const uchar col[3],
- uchar alpha)
+void UI_draw_roundbox_4fv_ex(const rctf *rect,
+ const float inner1[4],
+ const float inner2[4],
+ float shade_dir,
+ const float outline[4],
+ float outline_width,
+ float rad)
{
- float colv[4];
- colv[0] = ((float)col[0]) / 255;
- colv[1] = ((float)col[1]) / 255;
- colv[2] = ((float)col[2]) / 255;
- colv[3] = ((float)alpha) / 255;
- UI_draw_roundbox_4fv(filled, minx, miny, maxx, maxy, rad, colv);
-}
-
-void UI_draw_roundbox_3fv_alpha(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float rad,
- const float col[3],
- float alpha)
-{
- float colv[4];
- colv[0] = col[0];
- colv[1] = col[1];
- colv[2] = col[2];
- colv[3] = alpha;
- UI_draw_roundbox_4fv(filled, minx, miny, maxx, maxy, rad, colv);
-}
-
-void UI_draw_roundbox_aa(
- bool filled, float minx, float miny, float maxx, float maxy, float rad, const float color[4])
-{
- uiWidgetBaseParameters widget_params = {
- .recti.xmin = minx + U.pixelsize,
- .recti.ymin = miny + U.pixelsize,
- .recti.xmax = maxx - U.pixelsize,
- .recti.ymax = maxy - U.pixelsize,
- .rect.xmin = minx,
- .rect.ymin = miny,
- .rect.xmax = maxx,
- .rect.ymax = maxy,
- .radi = rad,
- .rad = rad,
- .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
- .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
- .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
- .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
- .color_inner1[0] = filled ? color[0] : 0.0f,
- .color_inner1[1] = filled ? color[1] : 0.0f,
- .color_inner1[2] = filled ? color[2] : 0.0f,
- .color_inner1[3] = filled ? color[3] : 0.0f,
- .color_inner2[0] = filled ? color[0] : 0.0f,
- .color_inner2[1] = filled ? color[1] : 0.0f,
- .color_inner2[2] = filled ? color[2] : 0.0f,
- .color_inner2[3] = filled ? color[3] : 0.0f,
- .color_outline[0] = color[0],
- .color_outline[1] = color[1],
- .color_outline[2] = color[2],
- .color_outline[3] = color[3],
- .alpha_discard = 1.0f,
- };
-
- /* XXX this is to emulate previous behavior of semitransparent fills but that's was a side effect
- * of the previous AA method. Better fix the callers. */
- if (filled) {
- widget_params.color_inner1[3] *= 0.65f;
- widget_params.color_inner2[3] *= 0.65f;
- widget_params.color_outline[3] *= 0.65f;
- }
-
/* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space.
* If it has been scaled, then it's no longer valid. */
-
- GPUBatch *batch = ui_batch_roundbox_widget_get();
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params);
-
- GPU_blend(GPU_BLEND_ALPHA);
-
- GPU_batch_draw(batch);
-
- GPU_blend(GPU_BLEND_NONE);
-}
-
-void UI_draw_roundbox_4fv(
- bool filled, float minx, float miny, float maxx, float maxy, float rad, const float col[4])
-{
-#if 0
- float vec[7][2] = {
- {0.195, 0.02},
- {0.383, 0.067},
- {0.55, 0.169},
- {0.707, 0.293},
- {0.831, 0.45},
- {0.924, 0.617},
- {0.98, 0.805},
- };
- int a;
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- /* mult */
- for (a = 0; a < 7; a++) {
- mul_v2_fl(vec[a], rad);
- }
-
- uint vert_len = 0;
- vert_len += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
- vert_len += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
- vert_len += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
- vert_len += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4fv(col);
-
- immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_len);
- /* start with corner right-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
- immVertex2f(pos, maxx - rad, miny);
- for (a = 0; a < 7; a++) {
- immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
- }
- immVertex2f(pos, maxx, miny + rad);
- }
- else {
- immVertex2f(pos, maxx, miny);
- }
-
- /* corner right-top */
- if (roundboxtype & UI_CNR_TOP_RIGHT) {
- immVertex2f(pos, maxx, maxy - rad);
- for (a = 0; a < 7; a++) {
- immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
- }
- immVertex2f(pos, maxx - rad, maxy);
- }
- else {
- immVertex2f(pos, maxx, maxy);
- }
-
- /* corner left-top */
- if (roundboxtype & UI_CNR_TOP_LEFT) {
- immVertex2f(pos, minx + rad, maxy);
- for (a = 0; a < 7; a++) {
- immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
- }
- immVertex2f(pos, minx, maxy - rad);
- }
- else {
- immVertex2f(pos, minx, maxy);
- }
-
- /* corner left-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
- immVertex2f(pos, minx, miny + rad);
- for (a = 0; a < 7; a++) {
- immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
- }
- immVertex2f(pos, minx + rad, miny);
- }
- else {
- immVertex2f(pos, minx, miny);
- }
-
- immEnd();
- immUnbindProgram();
-#endif
uiWidgetBaseParameters widget_params = {
- .recti.xmin = minx + U.pixelsize,
- .recti.ymin = miny + U.pixelsize,
- .recti.xmax = maxx - U.pixelsize,
- .recti.ymax = maxy - U.pixelsize,
- .rect.xmin = minx,
- .rect.ymin = miny,
- .rect.xmax = maxx,
- .rect.ymax = maxy,
+ .recti.xmin = rect->xmin + outline_width,
+ .recti.ymin = rect->ymin + outline_width,
+ .recti.xmax = rect->xmax - outline_width,
+ .recti.ymax = rect->ymax - outline_width,
+ .rect = *rect,
.radi = rad,
.rad = rad,
.round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
.round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
.round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
.round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
- .color_inner1[0] = filled ? col[0] : 0.0f,
- .color_inner1[1] = filled ? col[1] : 0.0f,
- .color_inner1[2] = filled ? col[2] : 0.0f,
- .color_inner1[3] = filled ? col[3] : 0.0f,
- .color_inner2[0] = filled ? col[0] : 0.0f,
- .color_inner2[1] = filled ? col[1] : 0.0f,
- .color_inner2[2] = filled ? col[2] : 0.0f,
- .color_inner2[3] = filled ? col[3] : 0.0f,
- .color_outline[0] = col[0],
- .color_outline[1] = col[1],
- .color_outline[2] = col[2],
- .color_outline[3] = col[3],
+ .color_inner1[0] = inner1 ? inner1[0] : 0.0f,
+ .color_inner1[1] = inner1 ? inner1[1] : 0.0f,
+ .color_inner1[2] = inner1 ? inner1[2] : 0.0f,
+ .color_inner1[3] = inner1 ? inner1[3] : 0.0f,
+ .color_inner2[0] = inner2 ? inner2[0] : inner1 ? inner1[0] : 0.0f,
+ .color_inner2[1] = inner2 ? inner2[1] : inner1 ? inner1[1] : 0.0f,
+ .color_inner2[2] = inner2 ? inner2[2] : inner1 ? inner1[2] : 0.0f,
+ .color_inner2[3] = inner2 ? inner2[3] : inner1 ? inner1[3] : 0.0f,
+ .color_outline[0] = outline ? outline[0] : inner1 ? inner1[0] : 0.0f,
+ .color_outline[1] = outline ? outline[1] : inner1 ? inner1[1] : 0.0f,
+ .color_outline[2] = outline ? outline[2] : inner1 ? inner1[2] : 0.0f,
+ .color_outline[3] = outline ? outline[3] : inner1 ? inner1[3] : 0.0f,
+ .shade_dir = shade_dir,
.alpha_discard = 1.0f,
};
- /* Exactly the same as UI_draw_roundbox_aa but does not do the legacy transparency. */
-
- /* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space.
- * If it has been scaled, then it's no longer valid. */
-
GPUBatch *batch = ui_batch_roundbox_widget_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params);
-
GPU_blend(GPU_BLEND_ALPHA);
-
GPU_batch_draw(batch);
-
GPU_blend(GPU_BLEND_NONE);
}
-#if 0
-static void round_box_shade_col(uint attr,
- const float col1[3],
- float const col2[3],
- const float fac)
+void UI_draw_roundbox_3ub_alpha(
+ const rctf *rect, bool filled, float rad, const uchar col[3], uchar alpha)
{
- float col[4] = {
- fac * col1[0] + (1.0f - fac) * col2[0],
- fac * col1[1] + (1.0f - fac) * col2[1],
- fac * col1[2] + (1.0f - fac) * col2[2],
- 1.0f,
+ float colv[4] = {
+ ((float)col[0]) / 255,
+ ((float)col[1]) / 255,
+ ((float)col[2]) / 255,
+ ((float)alpha) / 255,
};
- immAttr4fv(attr, col);
+ UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : NULL, NULL, 1.0f, colv, U.pixelsize, rad);
}
-#endif
-/* linear horizontal shade within button or in outline */
-/* view2d scrollers use it */
-void UI_draw_roundbox_shade_x(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float rad,
- float shadetop,
- float shadedown,
- const float col[4])
+void UI_draw_roundbox_3fv_alpha(
+ const rctf *rect, bool filled, float rad, const float col[3], float alpha)
{
-#if 0
- float vec[7][2] = {
- {0.195, 0.02},
- {0.383, 0.067},
- {0.55, 0.169},
- {0.707, 0.293},
- {0.831, 0.45},
- {0.924, 0.617},
- {0.98, 0.805},
- };
- const float div = maxy - miny;
- const float idiv = 1.0f / div;
- float coltop[3], coldown[3];
- int vert_count = 0;
- int a;
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
-
- /* mult */
- for (a = 0; a < 7; a++) {
- mul_v2_fl(vec[a], rad);
- }
-
- /* 'shade' defines strength of shading */
- coltop[0] = min_ff(1.0f, col[0] + shadetop);
- coltop[1] = min_ff(1.0f, col[1] + shadetop);
- coltop[2] = min_ff(1.0f, col[2] + shadetop);
- coldown[0] = max_ff(0.0f, col[0] + shadedown);
- coldown[1] = max_ff(0.0f, col[1] + shadedown);
- coldown[2] = max_ff(0.0f, col[2] + shadedown);
-
- vert_count += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
-
- immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_count);
-
- /* start with corner right-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
-
- round_box_shade_col(color, coltop, coldown, 0.0);
- immVertex2f(pos, maxx - rad, miny);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, coltop, coldown, vec[a][1] * idiv);
- immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
- }
-
- round_box_shade_col(color, coltop, coldown, rad * idiv);
- immVertex2f(pos, maxx, miny + rad);
- }
- else {
- round_box_shade_col(color, coltop, coldown, 0.0);
- immVertex2f(pos, maxx, miny);
- }
-
- /* corner right-top */
- if (roundboxtype & UI_CNR_TOP_RIGHT) {
-
- round_box_shade_col(color, coltop, coldown, (div - rad) * idiv);
- immVertex2f(pos, maxx, maxy - rad);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, coltop, coldown, (div - rad + vec[a][1]) * idiv);
- immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
- }
- round_box_shade_col(color, coltop, coldown, 1.0);
- immVertex2f(pos, maxx - rad, maxy);
- }
- else {
- round_box_shade_col(color, coltop, coldown, 1.0);
- immVertex2f(pos, maxx, maxy);
- }
-
- /* corner left-top */
- if (roundboxtype & UI_CNR_TOP_LEFT) {
-
- round_box_shade_col(color, coltop, coldown, 1.0);
- immVertex2f(pos, minx + rad, maxy);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, coltop, coldown, (div - vec[a][1]) * idiv);
- immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
- }
-
- round_box_shade_col(color, coltop, coldown, (div - rad) * idiv);
- immVertex2f(pos, minx, maxy - rad);
- }
- else {
- round_box_shade_col(color, coltop, coldown, 1.0);
- immVertex2f(pos, minx, maxy);
- }
-
- /* corner left-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
-
- round_box_shade_col(color, coltop, coldown, rad * idiv);
- immVertex2f(pos, minx, miny + rad);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, coltop, coldown, (rad - vec[a][1]) * idiv);
- immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
- }
+ float colv[4] = {col[0], col[1], col[2], alpha};
+ UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : NULL, NULL, 1.0f, colv, U.pixelsize, rad);
+}
- round_box_shade_col(color, coltop, coldown, 0.0);
- immVertex2f(pos, minx + rad, miny);
- }
- else {
- round_box_shade_col(color, coltop, coldown, 0.0);
- immVertex2f(pos, minx, miny);
+void UI_draw_roundbox_aa(const rctf *rect, bool filled, float rad, const float color[4])
+{
+ /* XXX this is to emulate previous behavior of semitransparent fills but that's was a side effect
+ * of the previous AA method. Better fix the callers. */
+ float colv[4] = {color[0], color[1], color[2], color[3]};
+ if (filled) {
+ colv[3] *= 0.65f;
}
- immEnd();
- immUnbindProgram();
-#endif
- uiWidgetBaseParameters widget_params = {
- .recti.xmin = minx + U.pixelsize,
- .recti.ymin = miny + U.pixelsize,
- .recti.xmax = maxx - U.pixelsize,
- .recti.ymax = maxy - U.pixelsize,
- .rect.xmin = minx,
- .rect.ymin = miny,
- .rect.xmax = maxx,
- .rect.ymax = maxy,
- .radi = rad,
- .rad = rad,
- .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
- .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
- .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
- .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
- .color_inner1[0] = !filled ? 0.0f : min_ff(1.0f, col[0] + shadetop),
- .color_inner1[1] = !filled ? 0.0f : min_ff(1.0f, col[1] + shadetop),
- .color_inner1[2] = !filled ? 0.0f : min_ff(1.0f, col[2] + shadetop),
- .color_inner1[3] = !filled ? 0.0f : 1.0f,
- .color_inner2[0] = !filled ? 0.0f : max_ff(0.0f, col[0] + shadedown),
- .color_inner2[1] = !filled ? 0.0f : max_ff(0.0f, col[1] + shadedown),
- .color_inner2[2] = !filled ? 0.0f : max_ff(0.0f, col[2] + shadedown),
- .color_inner2[3] = !filled ? 0.0f : 1.0f,
- /* TODO: non-filled box don't have gradients. Just use middle color. */
- .color_outline[0] = clamp_f(col[0] + shadetop + shadedown, 0.0f, 1.0f),
- .color_outline[1] = clamp_f(col[1] + shadetop + shadedown, 0.0f, 1.0f),
- .color_outline[2] = clamp_f(col[2] + shadetop + shadedown, 0.0f, 1.0f),
- .color_outline[3] = clamp_f(col[3] + shadetop + shadedown, 0.0f, 1.0f),
- .shade_dir = 1.0f,
- .alpha_discard = 1.0f,
- };
-
- GPU_blend(GPU_BLEND_ALPHA);
-
- GPUBatch *batch = ui_batch_roundbox_widget_get();
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params);
- GPU_batch_draw(batch);
+ UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : NULL, NULL, 1.0f, colv, U.pixelsize, rad);
+}
- GPU_blend(GPU_BLEND_NONE);
+void UI_draw_roundbox_4fv(const rctf *rect, bool filled, float rad, const float col[4])
+{
+ /* Exactly the same as UI_draw_roundbox_aa but does not do the legacy transparency. */
+ UI_draw_roundbox_4fv_ex(rect, (filled) ? col : NULL, NULL, 1.0f, col, U.pixelsize, rad);
}
-#if 0 /* unused */
-/* linear vertical shade within button or in outline */
+/* linear horizontal shade within button or in outline */
/* view2d scrollers use it */
-void UI_draw_roundbox_shade_y(bool filled,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float rad,
- float shadeleft,
- float shaderight,
- const float col[4])
+void UI_draw_roundbox_shade_x(
+ const rctf *rect, bool filled, float rad, float shadetop, float shadedown, const float col[4])
{
- float vec[7][2] = {
- {0.195, 0.02},
- {0.383, 0.067},
- {0.55, 0.169},
- {0.707, 0.293},
- {0.831, 0.45},
- {0.924, 0.617},
- {0.98, 0.805},
- };
- const float div = maxx - minx;
- const float idiv = 1.0f / div;
- float colLeft[3], colRight[3];
- int vert_count = 0;
- int a;
-
- /* mult */
- for (a = 0; a < 7; a++) {
- mul_v2_fl(vec[a], rad);
- }
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
-
- /* 'shade' defines strength of shading */
- colLeft[0] = min_ff(1.0f, col[0] + shadeleft);
- colLeft[1] = min_ff(1.0f, col[1] + shadeleft);
- colLeft[2] = min_ff(1.0f, col[2] + shadeleft);
- colRight[0] = max_ff(0.0f, col[0] + shaderight);
- colRight[1] = max_ff(0.0f, col[1] + shaderight);
- colRight[2] = max_ff(0.0f, col[2] + shaderight);
-
- vert_count += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
-
- immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_count);
+ float inner1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ float inner2[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ float outline[4];
- /* start with corner right-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
- round_box_shade_col(color, colLeft, colRight, 0.0);
- immVertex2f(pos, maxx - rad, miny);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, colLeft, colRight, vec[a][0] * idiv);
- immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
- }
-
- round_box_shade_col(color, colLeft, colRight, rad * idiv);
- immVertex2f(pos, maxx, miny + rad);
- }
- else {
- round_box_shade_col(color, colLeft, colRight, 0.0);
- immVertex2f(pos, maxx, miny);
- }
-
- /* corner right-top */
- if (roundboxtype & UI_CNR_TOP_RIGHT) {
- round_box_shade_col(color, colLeft, colRight, 0.0);
- immVertex2f(pos, maxx, maxy - rad);
-
- for (a = 0; a < 7; a++) {
-
- round_box_shade_col(color, colLeft, colRight, (div - rad - vec[a][0]) * idiv);
- immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
- }
- round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv);
- immVertex2f(pos, maxx - rad, maxy);
- }
- else {
- round_box_shade_col(color, colLeft, colRight, 0.0);
- immVertex2f(pos, maxx, maxy);
- }
-
- /* corner left-top */
- if (roundboxtype & UI_CNR_TOP_LEFT) {
- round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv);
- immVertex2f(pos, minx + rad, maxy);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, colLeft, colRight, (div - rad + vec[a][0]) * idiv);
- immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
- }
-
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx, maxy - rad);
- }
- else {
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx, maxy);
- }
-
- /* corner left-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx, miny + rad);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, colLeft, colRight, (vec[a][0]) * idiv);
- immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
- }
-
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx + rad, miny);
- }
- else {
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx, miny);
- }
-
- immEnd();
- immUnbindProgram();
+ if (filled) {
+ inner1[0] = min_ff(1.0f, col[0] + shadetop);
+ inner1[1] = min_ff(1.0f, col[1] + shadetop);
+ inner1[2] = min_ff(1.0f, col[2] + shadetop);
+ inner1[3] = 1.0f;
+ inner2[0] = max_ff(0.0f, col[0] + shadedown);
+ inner2[1] = max_ff(0.0f, col[1] + shadedown);
+ inner2[2] = max_ff(0.0f, col[2] + shadedown);
+ inner2[3] = 1.0f;
+ }
+
+ /* TODO: non-filled box don't have gradients. Just use middle color. */
+ outline[0] = clamp_f(col[0] + shadetop + shadedown, 0.0f, 1.0f);
+ outline[1] = clamp_f(col[1] + shadetop + shadedown, 0.0f, 1.0f);
+ outline[2] = clamp_f(col[2] + shadetop + shadedown, 0.0f, 1.0f);
+ outline[3] = clamp_f(col[3] + shadetop + shadedown, 0.0f, 1.0f);
+
+ UI_draw_roundbox_4fv_ex(rect, inner1, inner2, 1.0f, outline, U.pixelsize, rad);
}
-#endif /* unused */
void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4])
{
@@ -783,7 +355,7 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region),
GPU_blend(GPU_BLEND_NONE);
# if 0
- /* restore scissortest */
+ /* Restore scissor-test. */
GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
# endif
@@ -799,15 +371,12 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region),
* \param x1, x2, y1, y2: The offsets for the view, not the zones.
*/
void UI_draw_safe_areas(uint pos,
- float x1,
- float x2,
- float y1,
- float y2,
+ const rctf *rect,
const float title_aspect[2],
const float action_aspect[2])
{
- const float size_x_half = (x2 - x1) * 0.5f;
- const float size_y_half = (y2 - y1) * 0.5f;
+ const float size_x_half = (rect->xmax - rect->xmin) * 0.5f;
+ const float size_y_half = (rect->ymax - rect->ymin) * 0.5f;
const float *safe_areas[] = {title_aspect, action_aspect};
const int safe_len = ARRAY_SIZE(safe_areas);
@@ -817,10 +386,10 @@ void UI_draw_safe_areas(uint pos,
const float margin_x = safe_areas[i][0] * size_x_half;
const float margin_y = safe_areas[i][1] * size_y_half;
- const float minx = x1 + margin_x;
- const float miny = y1 + margin_y;
- const float maxx = x2 - margin_x;
- const float maxy = y2 - margin_y;
+ const float minx = rect->xmin + margin_x;
+ const float miny = rect->ymin + margin_y;
+ const float maxx = rect->xmax - margin_x;
+ const float maxy = rect->ymax - margin_y;
imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy);
}
@@ -835,7 +404,15 @@ static void draw_scope_end(const rctf *rect)
UI_draw_roundbox_corner_set(UI_CNR_ALL);
const float color[4] = {0.0f, 0.0f, 0.0f, 0.5f};
UI_draw_roundbox_4fv(
- false, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect->xmin - 1,
+ .xmax = rect->xmax + 1,
+ .ymin = rect->ymin,
+ .ymax = rect->ymax + 1,
+ },
+ false,
+ 3.0f,
+ color);
}
static void histogram_draw_one(float r,
@@ -928,7 +505,15 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region),
UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
- true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect.xmin - 1,
+ .xmax = rect.xmax + 1,
+ .ymin = rect.ymin - 1,
+ .ymax = rect.ymax + 1,
+ },
+ true,
+ 3.0f,
+ color);
/* need scissor test, histogram can draw outside of boundary */
int scissor[4];
@@ -1070,7 +655,15 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region),
UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
- true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect.xmin - 1,
+ .xmax = rect.xmax + 1,
+ .ymin = rect.ymin - 1,
+ .ymax = rect.ymax + 1,
+ },
+ true,
+ 3.0f,
+ color);
/* need scissor test, waveform can draw outside of boundary */
GPU_scissor_get(scissor);
@@ -1399,7 +992,15 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region),
UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
- true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect.xmin - 1,
+ .xmax = rect.xmax + 1,
+ .ymin = rect.ymin - 1,
+ .ymax = rect.ymax + 1,
+ },
+ true,
+ 3.0f,
+ color);
/* need scissor test, hvectorscope can draw outside of boundary */
int scissor[4];
@@ -1774,7 +1375,16 @@ void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rec
/* backdrop */
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_3ub_alpha(
- true, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f, wcol->inner, 255);
+ &(const rctf){
+ .xmin = rect->xmin,
+ .xmax = rect->xmax,
+ .ymin = rect->ymin,
+ .ymax = rect->ymax,
+ },
+ true,
+ 5.0f,
+ wcol->inner,
+ 255);
GPU_face_culling(GPU_CULL_BACK);
@@ -1800,7 +1410,7 @@ void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rec
GPU_batch_uniform_3fv(sphere, "light", light);
GPU_batch_draw(sphere);
- /* restore */
+ /* Restore. */
GPU_face_culling(GPU_CULL_NONE);
/* AA circle */
@@ -2130,7 +1740,7 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol,
immEnd();
immUnbindProgram();
- /* restore scissortest */
+ /* Restore scissor-test. */
GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
/* outline */
@@ -2420,7 +2030,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
}
immUnbindProgram();
- /* restore scissortest */
+ /* Restore scissor-test. */
GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
/* Outline */
@@ -2465,7 +2075,15 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
const float color[4] = {0.7f, 0.3f, 0.3f, 0.3f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
- true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect.xmin - 1,
+ .xmax = rect.xmax + 1,
+ .ymin = rect.ymin,
+ .ymax = rect.ymax + 1,
+ },
+ true,
+ 3.0f,
+ color);
ok = true;
}
@@ -2514,7 +2132,15 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
- true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect.xmin - 1,
+ .xmax = rect.xmax + 1,
+ .ymin = rect.ymin,
+ .ymax = rect.ymax + 1,
+ },
+ true,
+ 3.0f,
+ color);
}
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
@@ -2577,7 +2203,15 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
- true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ &(const rctf){
+ .xmin = rect.xmin - 1,
+ .xmax = rect.xmax + 1,
+ .ymin = rect.ymin,
+ .ymax = rect.ymax + 1,
+ },
+ true,
+ 3.0f,
+ color);
}
/* Restore scissor test. */
@@ -2594,14 +2228,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
* would replace / modify the following 3 functions - merwin
*/
-static void ui_shadowbox(uint pos,
- uint color,
- float minx,
- float miny,
- float maxx,
- float maxy,
- float shadsize,
- uchar alpha)
+static void ui_shadowbox(const rctf *rect, uint pos, uint color, float shadsize, uchar alpha)
{
/**
* <pre>
@@ -2616,16 +2243,16 @@ static void ui_shadowbox(uint pos,
* v8______v6_-
* </pre>
*/
- const float v1[2] = {maxx, maxy - 0.3f * shadsize};
- const float v2[2] = {maxx + shadsize, maxy - 0.75f * shadsize};
- const float v3[2] = {maxx, miny};
- const float v4[2] = {maxx + shadsize, miny};
+ const float v1[2] = {rect->xmax, rect->ymax - 0.3f * shadsize};
+ const float v2[2] = {rect->xmax + shadsize, rect->ymax - 0.75f * shadsize};
+ const float v3[2] = {rect->xmax, rect->ymin};
+ const float v4[2] = {rect->xmax + shadsize, rect->ymin};
- const float v5[2] = {maxx + 0.7f * shadsize, miny - 0.7f * shadsize};
+ const float v5[2] = {rect->xmax + 0.7f * shadsize, rect->ymin - 0.7f * shadsize};
- const float v6[2] = {maxx, miny - shadsize};
- const float v7[2] = {minx + 0.3f * shadsize, miny};
- const float v8[2] = {minx + 0.5f * shadsize, miny - shadsize};
+ const float v6[2] = {rect->xmax, rect->ymin - shadsize};
+ const float v7[2] = {rect->xmin + 0.3f * shadsize, rect->ymin};
+ const float v8[2] = {rect->xmin + 0.5f * shadsize, rect->ymin - shadsize};
/* right quad */
immAttr4ub(color, 0, 0, 0, alpha);
@@ -2664,7 +2291,7 @@ static void ui_shadowbox(uint pos,
immVertex2fv(pos, v3);
}
-void UI_draw_box_shadow(uchar alpha, float minx, float miny, float maxx, float maxy)
+void UI_draw_box_shadow(const rctf *rect, uchar alpha)
{
GPU_blend(GPU_BLEND_ALPHA);
@@ -2678,9 +2305,9 @@ void UI_draw_box_shadow(uchar alpha, float minx, float miny, float maxx, float m
immBegin(GPU_PRIM_TRIS, 54);
/* accumulated outline boxes to make shade not linear, is more pleasant */
- ui_shadowbox(pos, color, minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8);
- ui_shadowbox(pos, color, minx, miny, maxx, maxy, 7.0, (40 * alpha) >> 8);
- ui_shadowbox(pos, color, minx, miny, maxx, maxy, 5.0, (80 * alpha) >> 8);
+ ui_shadowbox(rect, pos, color, 11.0, (20 * alpha) >> 8);
+ ui_shadowbox(rect, pos, color, 7.0, (40 * alpha) >> 8);
+ ui_shadowbox(rect, pos, color, 5.0, (80 * alpha) >> 8);
immEnd();
@@ -2755,13 +2382,16 @@ void ui_draw_dropshadow(
/* outline emphasis */
const float color[4] = {0.0f, 0.0f, 0.0f, 0.4f};
- UI_draw_roundbox_4fv(false,
- rct->xmin - 0.5f,
- rct->ymin - 0.5f,
- rct->xmax + 0.5f,
- rct->ymax + 0.5f,
- radius + 0.5f,
- color);
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = rct->xmin - 0.5f,
+ .xmax = rct->xmax + 0.5f,
+ .ymin = rct->ymin - 0.5f,
+ .ymax = rct->ymax + 0.5f,
+ },
+ false,
+ radius + 0.5f,
+ color);
GPU_blend(GPU_BLEND_NONE);
}
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index 4d0e1584156..de39484bc1e 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -24,8 +24,6 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
-#include "BLI_blenlib.h"
-
#include "BKE_context.h"
#include "BKE_screen.h"
diff --git a/source/blender/editors/interface/interface_eyedropper_depth.c b/source/blender/editors/interface/interface_eyedropper_depth.c
index ead65a62226..a4adbef0b94 100644
--- a/source/blender/editors/interface/interface_eyedropper_depth.c
+++ b/source/blender/editors/interface/interface_eyedropper_depth.c
@@ -41,8 +41,6 @@
#include "BKE_screen.h"
#include "BKE_unit.h"
-#include "DEG_depsgraph.h"
-
#include "RNA_access.h"
#include "UI_interface.h"
@@ -66,9 +64,9 @@ typedef struct DepthDropper {
bool is_undo;
bool is_set;
- float init_depth; /* for resetting on cancel */
+ float init_depth; /* For resetting on cancel. */
- bool accum_start; /* has mouse been presed */
+ bool accum_start; /* Has mouse been pressed. */
float accum_depth;
int accum_tot;
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 97d9b225d3c..1bfd84a7046 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -349,7 +349,7 @@ typedef struct uiHandleButtonData {
#endif
ColorBand *coba;
- /* tooltip */
+ /* Tool-tip. */
uint tooltip_force : 1;
/* auto open */
@@ -1617,7 +1617,7 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void
static bool ui_but_is_drag_toggle(const uiBut *but)
{
return ((ui_drag_toggle_but_is_supported(but) == true) &&
- /* menu check is importnt so the button dragged over isn't removed instantly */
+ /* Menu check is important so the button dragged over isn't removed instantly. */
(ui_block_is_menu(but->block) == false));
}
@@ -3710,9 +3710,9 @@ static void ui_do_but_textedit(
case EVT_AKEY:
- /* Ctrl + A: Select all */
+ /* Ctrl-A: Select all. */
#if defined(__APPLE__)
- /* OSX uses cmd-a systemwide, so add it */
+ /* OSX uses Command-A system-wide, so add it. */
if ((event->oskey && !IS_EVENT_MOD(event, shift, alt, ctrl)) ||
(event->ctrl && !IS_EVENT_MOD(event, shift, alt, oskey)))
#else
@@ -3726,7 +3726,7 @@ static void ui_do_but_textedit(
break;
case EVT_TABKEY:
- /* there is a key conflict here, we can't tab with autocomplete */
+ /* There is a key conflict here, we can't tab with auto-complete. */
if (but->autocomplete_func || data->searchbox) {
const int autocomplete = ui_textedit_autocomplete(C, but, data);
changed = autocomplete != AUTOCOMPLETE_NO_MATCH;
@@ -3735,13 +3735,14 @@ static void ui_do_but_textedit(
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
- /* the hotkey here is not well defined, was G.qual so we check all */
- else if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
- ui_textedit_prev_but(block, but, data);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else {
- ui_textedit_next_but(block, but, data);
+ else if (!IS_EVENT_MOD(event, ctrl, alt, oskey)) {
+ /* Use standard keys for cycling through buttons Tab, Shift-Tab to reverse. */
+ if (event->shift) {
+ ui_textedit_prev_but(block, but, data);
+ }
+ else {
+ ui_textedit_next_but(block, but, data);
+ }
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
retval = WM_UI_HANDLER_BREAK;
@@ -4575,7 +4576,7 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons
return WM_UI_HANDLER_BREAK;
}
if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
- /* Support ctrl-wheel to cycle values on expanded enum rows. */
+ /* Support Ctrl-Wheel to cycle values on expanded enum rows. */
if (but->type == UI_BTYPE_ROW) {
int type = event->type;
int val = event->val;
@@ -5086,7 +5087,7 @@ static int ui_do_but_NUM(
else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
if (data->dragchange) {
#ifdef USE_DRAG_MULTINUM
- /* if we started multibutton but didn't drag, then edit */
+ /* If we started multi-button but didn't drag, then edit. */
if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
click = 1;
}
@@ -5408,7 +5409,7 @@ static int ui_do_but_SLI(
else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
if (data->dragchange) {
#ifdef USE_DRAG_MULTINUM
- /* if we started multibutton but didn't drag, then edit */
+ /* If we started multi-button but didn't drag, then edit. */
if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
click = 1;
}
@@ -6836,7 +6837,7 @@ static bool ui_numedit_but_CURVE(uiBlock *block,
#ifdef USE_CONT_MOUSE_CORRECT
/* note: using 'cmp_last' is weak since there may be multiple points selected,
- * but in practice this isnt really an issue */
+ * but in practice this isn't really an issue */
if (ui_but_is_cursor_warp(but)) {
/* OK but can go outside bounds */
data->ungrab_mval[0] = but->rect.xmin + ((cmp_last->x - cumap->curr.xmin) * zoomx);
@@ -7107,7 +7108,7 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block,
changed = true;
#ifdef USE_CONT_MOUSE_CORRECT
/* note: using 'cmp_last' is weak since there may be multiple points selected,
- * but in practice this isnt really an issue */
+ * but in practice this isn't really an issue */
if (ui_but_is_cursor_warp(but)) {
/* OK but can go outside bounds */
data->ungrab_mval[0] = but->rect.xmin + ((last_x - profile->view_rect.xmin) * zoomx);
@@ -7822,7 +7823,7 @@ static void ui_blocks_set_tooltips(ARegion *region, const bool enable)
}
/**
- * Recreate tooltip (use to update dynamic tips)
+ * Recreate tool-tip (use to update dynamic tips)
*/
void UI_but_tooltip_refresh(bContext *C, uiBut *but)
{
@@ -7921,7 +7922,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
return;
}
- /* highlight has timers for tooltips and auto open */
+ /* Highlight has timers for tool-tips and auto open. */
if (state == BUTTON_STATE_HIGHLIGHT) {
but->flag &= ~UI_SELECT;
@@ -8261,7 +8262,7 @@ static void button_activate_exit(
}
}
- /* disable tooltips until mousemove + last active flag */
+ /* Disable tool-tips until mouse-move + last active flag. */
LISTBASE_FOREACH (uiBlock *, block_iter, &data->region->uiblocks) {
LISTBASE_FOREACH (uiBut *, bt, &block_iter->buttons) {
bt->flag &= ~UI_BUT_LAST_ACTIVE;
@@ -8325,7 +8326,7 @@ void ui_but_active_free(const bContext *C, uiBut *but)
}
/* returns the active button with an optional checking function */
-static uiBut *ui_context_button_active(ARegion *region, bool (*but_check_cb)(uiBut *))
+static uiBut *ui_context_button_active(const ARegion *region, bool (*but_check_cb)(const uiBut *))
{
uiBut *but_found = NULL;
@@ -8349,7 +8350,7 @@ static uiBut *ui_context_button_active(ARegion *region, bool (*but_check_cb)(uiB
but_found = activebut;
- /* recurse into opened menu, like colorpicker case */
+ /* Recurse into opened menu, like color-picker case. */
if (data && data->menu && (region != data->menu->region)) {
region = data->menu->region;
}
@@ -8366,7 +8367,7 @@ static uiBut *ui_context_button_active(ARegion *region, bool (*but_check_cb)(uiB
return but_found;
}
-static bool ui_context_rna_button_active_test(uiBut *but)
+static bool ui_context_rna_button_active_test(const uiBut *but)
{
return (but->rnapoin.data != NULL);
}
@@ -8391,7 +8392,7 @@ uiBut *UI_context_active_but_get_respect_menu(const bContext *C)
return ui_context_button_active(region_menu ? region_menu : CTX_wm_region(C), NULL);
}
-uiBut *UI_region_active_but_get(ARegion *region)
+uiBut *UI_region_active_but_get(const ARegion *region)
{
return ui_context_button_active(region, NULL);
}
@@ -8489,6 +8490,15 @@ wmOperator *UI_context_active_operator_get(const struct bContext *C)
return NULL;
}
+/**
+ * Try to find a search-box region opened from a button in \a button_region.
+ */
+ARegion *UI_region_searchbox_region_get(const ARegion *button_region)
+{
+ uiBut *but = UI_region_active_but_get(button_region);
+ return (but != NULL) ? but->active->searchbox : NULL;
+}
+
/* helper function for insert keyframe, reset to default, etc operators */
void UI_context_update_anim_flag(const bContext *C)
{
@@ -8522,7 +8532,7 @@ void UI_context_update_anim_flag(const bContext *C)
}
if (activebut) {
- /* always recurse into opened menu, so all buttons update (like colorpicker) */
+ /* Always recurse into opened menu, so all buttons update (like color-picker). */
uiHandleButtonData *data = activebut->active;
if (data && data->menu) {
region = data->menu->region;
@@ -8564,7 +8574,8 @@ static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *reg
button_activate_init(C, region, but, BUTTON_ACTIVATE_OVER);
if (event->alt && but->active) {
- /* display tooltips if holding alt on mouseover when tooltips are off in prefs */
+ /* Display tool-tips if holding Alt on mouse-over when tool-tips are disabled in the
+ * preferences. */
but->active->tooltip_force = true;
}
}
@@ -8606,7 +8617,7 @@ void ui_but_activate_event(bContext *C, ARegion *region, uiBut *but)
* Simulate moving the mouse over a button (or navigating to it with arrow keys).
*
* exported so menus can start with a highlighted button,
- * even if the mouse isnt over it
+ * even if the mouse isn't over it
*/
void ui_but_activate_over(bContext *C, ARegion *region, uiBut *but)
{
@@ -8786,7 +8797,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
else if (event->x != event->prevx || event->y != event->prevy) {
- /* re-enable tooltip on mouse move */
+ /* Re-enable tool-tip on mouse move. */
ui_blocks_set_tooltips(region, true);
button_tooltip_timer_reset(C, but);
}
@@ -8810,7 +8821,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
break;
}
/* XXX hardcoded keymap check... but anyway,
- * while view changes, tooltips should be removed */
+ * while view changes, tool-tips should be removed */
case WHEELUPMOUSE:
case WHEELDOWNMOUSE:
case MIDDLEMOUSE:
@@ -9513,7 +9524,7 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock
/* pass, skip for dialogs */
}
else if (!ui_region_contains_point_px(but->active->region, event->x, event->y)) {
- /* pass, needed to click-exit outside of non-flaoting menus */
+ /* Pass, needed to click-exit outside of non-floating menus. */
ui_region_auto_open_clear(but->active->region);
}
else if ((!ELEM(event->type, MOUSEMOVE, WHEELUPMOUSE, WHEELDOWNMOUSE, MOUSEPAN)) &&
@@ -10135,7 +10146,7 @@ static int ui_handle_menu_event(bContext *C,
ui_mouse_motion_towards_check(block, menu, &event->x, is_parent_inside == false);
- /* check for all parent rects, enables arrowkeys to be used */
+ /* Check for all parent rects, enables arrow-keys to be used. */
for (saferct = block->saferct.first; saferct; saferct = saferct->next) {
/* for mouse move we only check our own rect, for other
* events we check all preceding block rects too to make
@@ -10409,7 +10420,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
}
}
- /* check pie velociy here if gesture has ended */
+ /* Check pie velocity here if gesture has ended. */
if (block->pie_data.flags & UI_PIE_GESTURE_END_WAIT) {
float len_sq = 10;
@@ -10735,7 +10746,7 @@ static int ui_region_handler(bContext *C, const wmEvent *event, void *UNUSED(use
}
}
- /* re-enable tooltips */
+ /* Re-enable tool-tips. */
if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) {
ui_blocks_set_tooltips(region, true);
}
@@ -10832,7 +10843,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
}
}
- /* re-enable tooltips */
+ /* Re-enable tool-tips. */
if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) {
ui_blocks_set_tooltips(region, true);
}
@@ -10926,7 +10937,7 @@ static int ui_popup_handler(bContext *C, const wmEvent *event, void *userdata)
WM_event_add_mousemove(win);
}
else {
- /* re-enable tooltips */
+ /* Re-enable tool-tips */
if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) {
ui_blocks_set_tooltips(menu->region, true);
}
@@ -10936,7 +10947,7 @@ static int ui_popup_handler(bContext *C, const wmEvent *event, void *userdata)
ui_apply_but_funcs_after(C);
if (reset_pie) {
- /* reaqcuire window in case pie invalidates it somehow */
+ /* Reacquire window in case pie invalidates it somehow. */
wmWindow *win = CTX_wm_window(C);
if (win) {
diff --git a/source/blender/editors/interface/interface_icons_event.c b/source/blender/editors/interface/interface_icons_event.c
index 223fcbfd45b..3962ff6a702 100644
--- a/source/blender/editors/interface/interface_icons_event.c
+++ b/source/blender/editors/interface/interface_icons_event.c
@@ -118,7 +118,15 @@ void icon_draw_rect_input(float x,
UI_GetThemeColor4fv(TH_TEXT, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_aa(
- false, (int)x - U.pixelsize, (int)y, (int)(x + w), (int)(y + h), 3.0f * U.pixelsize, color);
+ &(const rctf){
+ .xmin = (int)x - U.pixelsize,
+ .xmax = (int)(x + w),
+ .ymin = (int)y,
+ .ymax = (int)(y + h),
+ },
+ false,
+ 3.0f * U.pixelsize,
+ color);
const enum {
UNIX,
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index f4e68ca3909..6a921f3f541 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -525,7 +525,7 @@ struct uiBlock {
/** for doing delayed */
int bounds, minbounds;
- /** pulldowns, to detect outside, can differ per case how it is created */
+ /** pull-downs, to detect outside, can differ per case how it is created. */
rctf safety;
/** uiSafetyRct list */
ListBase saferct;
@@ -659,7 +659,7 @@ void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3]);
/* interface_regions.c */
struct uiKeyNavLock {
- /* set when we're using keyinput */
+ /* Set when we're using key-input. */
bool is_keynav;
/* only used to check if we've moved the cursor */
int event_xy[2];
@@ -756,7 +756,7 @@ uiBlock *ui_block_func_COLOR(struct bContext *C, uiPopupBlockHandle *handle, voi
ColorPicker *ui_block_colorpicker_create(struct uiBlock *block);
/* interface_region_search.c */
-/* Searchbox for string button */
+/* Search-box for string button. */
struct ARegion *ui_searchbox_create_generic(struct bContext *C,
struct ARegion *butregion,
uiButSearch *search_but);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 3281b8de920..fef243d7193 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -2642,7 +2642,7 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname
static void search_id_collection(StructRNA *ptype, PointerRNA *r_ptr, PropertyRNA **r_prop)
{
/* look for collection property in Main */
- /* Note: using global Main is OK-ish here, UI shall not access other Mains anyay... */
+ /* NOTE: using global Main is OK-ish here, UI shall not access other Mains anyway. */
RNA_main_pointer_create(G_MAIN, r_ptr);
*r_prop = NULL;
@@ -2821,7 +2821,7 @@ void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
UI_menutype_draw(C, mt, layout);
- /* menus are created flipped (from event handling pov) */
+ /* Menus are created flipped (from event handling point of view). */
layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
}
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index e5aa0665a16..05a2a6ef29b 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -901,7 +901,7 @@ bool UI_context_copy_to_selected_list(bContext *C,
MEM_freeN(link);
}
else {
- /* avoid prepending 'data' to the path */
+ /* Avoid prepending 'data' to the path. */
RNA_id_pointer_create(id_data, &link->ptr);
}
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index bf140eb1692..7343417137a 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -926,9 +926,9 @@ bool UI_panel_matches_search_filter(const Panel *panel)
/**
* Set the flag telling the panel to use its search result status for its expansion.
*/
-static void panel_set_expansion_from_seach_filter_recursive(const bContext *C,
- Panel *panel,
- const bool use_search_closed)
+static void panel_set_expansion_from_search_filter_recursive(const bContext *C,
+ Panel *panel,
+ const bool use_search_closed)
{
/* This has to run on inactive panels that may not have a type,
* but we can prevent running on header-less panels in some cases. */
@@ -939,21 +939,21 @@ static void panel_set_expansion_from_seach_filter_recursive(const bContext *C,
LISTBASE_FOREACH (Panel *, child_panel, &panel->children) {
/* Don't check if the sub-panel is active, otherwise the
* expansion won't be reset when the parent is closed. */
- panel_set_expansion_from_seach_filter_recursive(C, child_panel, use_search_closed);
+ panel_set_expansion_from_search_filter_recursive(C, child_panel, use_search_closed);
}
}
/**
* Set the flag telling every panel to override its expansion with its search result status.
*/
-static void region_panels_set_expansion_from_seach_filter(const bContext *C,
- ARegion *region,
- const bool use_search_closed)
+static void region_panels_set_expansion_from_search_filter(const bContext *C,
+ ARegion *region,
+ const bool use_search_closed)
{
LISTBASE_FOREACH (Panel *, panel, &region->panels) {
/* Don't check if the panel is active, otherwise the expansion won't
* be correct when switching back to tab after exiting search. */
- panel_set_expansion_from_seach_filter_recursive(C, panel, use_search_closed);
+ panel_set_expansion_from_search_filter_recursive(C, panel, use_search_closed);
}
set_panels_list_data_expand_flag(C, region);
}
@@ -1121,13 +1121,16 @@ static void panel_draw_highlight_border(const Panel *panel,
float color[4];
UI_GetThemeColor4fv(TH_SELECT_ACTIVE, color);
- UI_draw_roundbox_4fv(false,
- rect->xmin,
- UI_panel_is_closed(panel) ? header_rect->ymin : rect->ymin,
- rect->xmax,
- header_rect->ymax,
- radius,
- color);
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = rect->xmin,
+ .xmax = rect->xmax,
+ .ymin = UI_panel_is_closed(panel) ? header_rect->ymin : rect->ymin,
+ .ymax = header_rect->ymax,
+ },
+ false,
+ radius,
+ color);
}
static void panel_draw_aligned_widgets(const uiStyle *style,
@@ -1253,13 +1256,16 @@ static void panel_draw_aligned_backdrop(const Panel *panel,
float color[4];
UI_GetThemeColor4fv(TH_PANEL_SUB_BACK, color);
/* Change the width a little bit to line up with sides. */
- UI_draw_roundbox_aa(true,
- rect->xmin + U.pixelsize,
- rect->ymin + U.pixelsize,
- rect->xmax - U.pixelsize,
- rect->ymax,
- box_wcol->roundness * U.widget_unit,
- color);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = rect->xmin + U.pixelsize,
+ .xmax = rect->xmax - U.pixelsize,
+ .ymin = rect->ymin + U.pixelsize,
+ .ymax = rect->ymax,
+ },
+ true,
+ box_wcol->roundness * U.widget_unit,
+ color);
}
else {
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1333,7 +1339,7 @@ void ui_draw_aligned_panel(const uiStyle *style,
{
const Panel *panel = block->panel;
- /* Add 0.001f to prevent flicker frpm float inaccuracy. */
+ /* Add 0.001f to prevent flicker from float inaccuracy. */
const rcti header_rect = {
rect->xmin,
rect->xmax,
@@ -1544,20 +1550,26 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active)
{
/* Draw filled rectangle and outline for tab. */
UI_draw_roundbox_corner_set(roundboxtype);
- UI_draw_roundbox_4fv(true,
- rct->xmin,
- rct->ymin,
- rct->xmax,
- rct->ymax,
- tab_curve_radius,
- is_active ? theme_col_tab_active : theme_col_tab_inactive);
- UI_draw_roundbox_4fv(false,
- rct->xmin,
- rct->ymin,
- rct->xmax,
- rct->ymax,
- tab_curve_radius,
- theme_col_tab_outline);
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = rct->xmin,
+ .xmax = rct->xmax,
+ .ymin = rct->ymin,
+ .ymax = rct->ymax,
+ },
+ true,
+ tab_curve_radius,
+ is_active ? theme_col_tab_active : theme_col_tab_inactive);
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = rct->xmin,
+ .xmax = rct->xmax,
+ .ymin = rct->ymin,
+ .ymax = rct->ymax,
+ },
+ false,
+ tab_curve_radius,
+ theme_col_tab_outline);
/* Disguise the outline on one side to join the tab to the panel. */
pos = GPU_vertformat_attr_add(
@@ -1911,10 +1923,10 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y)
const bool region_search_filter_active = region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE;
if (properties_space_needs_realign(area, region)) {
- region_panels_set_expansion_from_seach_filter(C, region, region_search_filter_active);
+ region_panels_set_expansion_from_search_filter(C, region, region_search_filter_active);
}
else if (region->flag & RGN_FLAG_SEARCH_FILTER_UPDATE) {
- region_panels_set_expansion_from_seach_filter(C, region, region_search_filter_active);
+ region_panels_set_expansion_from_search_filter(C, region, region_search_filter_active);
}
if (region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE) {
@@ -2354,7 +2366,7 @@ static int ui_handle_panel_category_cycling(const wmEvent *event,
PanelCategoryDyn *pc_dyn = UI_panel_category_find(region, category);
if (LIKELY(pc_dyn)) {
if (is_mousewheel) {
- /* We can probably get rid of this and only allow ctrl-tabbing. */
+ /* We can probably get rid of this and only allow Ctrl-Tabbing. */
pc_dyn = (event->type == WHEELDOWNMOUSE) ? pc_dyn->next : pc_dyn->prev;
}
else {
diff --git a/source/blender/editors/interface/interface_region_menu_pie.c b/source/blender/editors/interface/interface_region_menu_pie.c
index d047d5421d7..81c627816b9 100644
--- a/source/blender/editors/interface/interface_region_menu_pie.c
+++ b/source/blender/editors/interface/interface_region_menu_pie.c
@@ -392,7 +392,7 @@ void ui_pie_menu_level_create(uiBlock *block,
EnumPropertyItem *remaining = MEM_mallocN(array_size + sizeof(EnumPropertyItem),
"pie_level_item_array");
memcpy(remaining, items + totitem_parent, array_size);
- /* a NULL terminating sentinal element is required */
+ /* A NULL terminating sentinel element is required. */
memset(&remaining[totitem_remain], 0, sizeof(EnumPropertyItem));
/* yuk, static... issue is we can't reliably free this without doing dangerous changes */
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index 93e3dbb2cc8..3228e9741bb 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -413,12 +413,11 @@ static void ui_block_region_draw(const bContext *C, ARegion *region)
/**
* Use to refresh centered popups on screen resizing (for splash).
*/
-static void ui_block_region_popup_window_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void ui_block_region_popup_window_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
switch (wmn->category) {
case NC_WINDOW: {
switch (wmn->action) {
@@ -540,7 +539,7 @@ static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle)
CTX_wm_window_set(C, win);
ui_region_temp_remove(C, screen, handle->region);
- /* Reset context (area and region were NULL'ed when chaning context window). */
+ /* Reset context (area and region were NULL'ed when changing context window). */
CTX_wm_window_set(C, ctx_win);
CTX_wm_area_set(C, ctx_area);
CTX_wm_region_set(C, ctx_region);
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index 816162e9aa2..d1d4290bd11 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -289,7 +289,7 @@ int ui_searchbox_find_index(ARegion *region, const char *name)
return UI_search_items_find_index(&data->items, name);
}
-/* x and y in screencoords */
+/* x and y in screen-coords. */
bool ui_searchbox_inside(ARegion *region, int x, int y)
{
uiSearchboxData *data = region->regiondata;
@@ -347,9 +347,20 @@ static struct ARegion *wm_searchbox_tooltip_init(struct bContext *C,
}
uiButSearch *search_but = (uiButSearch *)but;
- if (search_but->item_tooltip_fn) {
- return search_but->item_tooltip_fn(C, region, search_but->arg, search_but->item_active);
+ if (!search_but->item_tooltip_fn) {
+ continue;
}
+
+ ARegion *searchbox_region = UI_region_searchbox_region_get(region);
+ uiSearchboxData *data = searchbox_region->regiondata;
+
+ BLI_assert(data->items.pointers[data->active] == search_but->item_active);
+
+ rcti rect;
+ ui_searchbox_butrect(&rect, data, data->active);
+
+ return search_but->item_tooltip_fn(
+ C, region, &rect, search_but->arg, search_but->item_active);
}
}
return NULL;
@@ -452,8 +463,11 @@ static void ui_searchbox_update_fn(bContext *C,
const char *str,
uiSearchItems *items)
{
- wmWindow *win = CTX_wm_window(C);
- WM_tooltip_clear(C, win);
+ /* While the button is in text editing mode (searchbox open), remove tooltips on every update. */
+ if (search_but->but.editstr) {
+ wmWindow *win = CTX_wm_window(C);
+ WM_tooltip_clear(C, win);
+ }
search_but->items_update_fn(C, search_but->arg, str, items);
}
@@ -1046,7 +1060,7 @@ void ui_but_search_refresh(uiButSearch *search_but)
ui_searchbox_update_fn(but->block->evil_C, search_but, but->drawstr, items);
- /* only redalert when we are sure of it, this can miss cases when >10 matches */
+ /* Only red-alert when we are sure of it, this can miss cases when >10 matches. */
if (items->totitem == 0) {
UI_but_flag_enable(but, UI_BUT_REDALERT);
}
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index 2bf63955855..050a14cf574 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -1456,15 +1456,91 @@ ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *gz)
{
wmWindow *win = CTX_wm_window(C);
const float aspect = 1.0f;
- float init_position[2];
+ float init_position[2] = {win->eventstate->x, win->eventstate->y};
uiTooltipData *data = ui_tooltip_data_from_gizmo(C, gz);
if (data == NULL) {
return NULL;
}
+ /* TODO(harley):
+ * Julian preferred that the gizmo callback return the 3D bounding box
+ * which we then project to 2D here. Would make a nice improvement.
+ */
+ if (gz->type->screen_bounds_get) {
+ rcti bounds;
+ gz->type->screen_bounds_get(C, gz, &bounds);
+ init_position[0] = bounds.xmin;
+ init_position[1] = bounds.ymin;
+ }
+
+ return ui_tooltip_create_with_data(C, data, init_position, NULL, aspect);
+}
+
+static uiTooltipData *ui_tooltip_data_from_search_item_tooltip_data(
+ const uiSearchItemTooltipData *item_tooltip_data)
+{
+ uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
+
+ if (item_tooltip_data->description[0]) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_HEADER,
+ .color_id = UI_TIP_LC_NORMAL,
+ .is_pad = true,
+ });
+ field->text = BLI_strdup(item_tooltip_data->description);
+ }
+
+ if (item_tooltip_data->name && item_tooltip_data->name[0]) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = BLI_strdup(item_tooltip_data->name);
+ }
+ if (item_tooltip_data->hint[0]) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_NORMAL,
+ .is_pad = true,
+ });
+ field->text = BLI_strdup(item_tooltip_data->hint);
+ }
+
+ if (data->fields_len == 0) {
+ MEM_freeN(data);
+ return NULL;
+ }
+ return data;
+}
+
+/**
+ * Create a tooltip from search-item tooltip data \a item_tooltip data.
+ * To be called from a callback set with #UI_but_func_search_set_tooltip().
+ *
+ * \param item_rect: Rectangle of the search item in search region space (#ui_searchbox_butrect())
+ * which is passed to the tooltip callback.
+ */
+ARegion *UI_tooltip_create_from_search_item_generic(
+ bContext *C,
+ const ARegion *searchbox_region,
+ const rcti *item_rect,
+ const uiSearchItemTooltipData *item_tooltip_data)
+{
+ uiTooltipData *data = ui_tooltip_data_from_search_item_tooltip_data(item_tooltip_data);
+ if (data == NULL) {
+ return NULL;
+ }
+
+ const float aspect = 1.0f;
+ const wmWindow *win = CTX_wm_window(C);
+ float init_position[2];
init_position[0] = win->eventstate->x;
- init_position[1] = win->eventstate->y;
+ init_position[1] = item_rect->ymin + searchbox_region->winrct.ymin - (UI_POPUP_MARGIN / 2);
return ui_tooltip_create_with_data(C, data, init_position, NULL, aspect);
}
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index a37fb0dfde1..eaefc2c3736 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -341,13 +341,16 @@ void UI_fontstyle_draw_simple_backdrop(const uiFontStyle *fs,
const float color[4] = {col_bg[0], col_bg[1], col_bg[2], 0.5f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true,
- x - margin,
- (y + decent) - margin,
- x + width + margin,
- (y + decent) + height + margin,
- margin,
- color);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = x - margin,
+ .xmax = x + width + margin,
+ .ymin = (y + decent) - margin,
+ .ymax = (y + decent) + height + margin,
+ },
+ true,
+ margin,
+ color);
}
BLF_position(fs->uifont_id, x, y, 0.0f);
diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c
index 9f4cd32588d..25cf2e12377 100644
--- a/source/blender/editors/interface/interface_template_search_menu.c
+++ b/source/blender/editors/interface/interface_template_search_menu.c
@@ -1069,6 +1069,7 @@ static bool ui_search_menu_create_context_menu(struct bContext *C,
static struct ARegion *ui_search_menu_create_tooltip(struct bContext *C,
struct ARegion *region,
+ const rcti *UNUSED(item_rect),
void *arg,
void *active)
{
diff --git a/source/blender/editors/interface/interface_template_search_operator.c b/source/blender/editors/interface/interface_template_search_operator.c
index 21529a97c01..ff0f9a2e5cd 100644
--- a/source/blender/editors/interface/interface_template_search_operator.c
+++ b/source/blender/editors/interface/interface_template_search_operator.c
@@ -23,11 +23,8 @@
#include <string.h>
-#include "DNA_gpencil_modifier_types.h"
-#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_shader_fx_types.h"
#include "DNA_texture_types.h"
#include "BLI_alloca.h"
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 003bb110baf..dad8253d101 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -208,6 +208,7 @@ static uiBlock *template_common_search_menu(const bContext *C,
void *search_arg,
uiButHandleFunc search_exec_fn,
void *active_item,
+ uiButSearchTooltipFn item_tooltip_fn,
const int preview_rows,
const int preview_cols,
float scale)
@@ -284,6 +285,7 @@ static uiBlock *template_common_search_menu(const bContext *C,
NULL,
search_exec_fn,
active_item);
+ UI_but_func_search_set_tooltip(but, item_tooltip_fn);
UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
UI_block_direction_set(block, UI_DIR_DOWN);
@@ -347,7 +349,7 @@ static bool id_search_allows_id(TemplateID *template_ui, const int flag, ID *id,
}
}
- /* Hide dot-datablocks, but only if filter does not force them visible. */
+ /* Hide dot prefixed data-blocks, but only if filter does not force them visible. */
if (U.uiflag & USER_HIDE_DOT) {
if ((id->name[2] == '.') && (query[0] != '.')) {
return false;
@@ -485,6 +487,31 @@ static void id_search_cb_objects_from_scene(const bContext *C,
id_search_cb_tagged(C, arg_template, str, items);
}
+static ARegion *template_ID_search_menu_item_tooltip(
+ bContext *C, ARegion *region, const rcti *item_rect, void *arg, void *active)
+{
+ TemplateID *template_ui = arg;
+ ID *active_id = active;
+ StructRNA *type = RNA_property_pointer_type(&template_ui->ptr, template_ui->prop);
+
+ uiSearchItemTooltipData tooltip_data = {0};
+
+ tooltip_data.name = active_id->name + 2;
+ BLI_snprintf(tooltip_data.description,
+ sizeof(tooltip_data.description),
+ TIP_("Choose %s data-block to be assigned to this user"),
+ RNA_struct_ui_name(type));
+ if (ID_IS_LINKED(active_id)) {
+ BLI_snprintf(tooltip_data.hint,
+ sizeof(tooltip_data.hint),
+ TIP_("Source library: %s\n%s"),
+ active_id->lib->id.name + 2,
+ active_id->lib->filepath);
+ }
+
+ return UI_tooltip_create_from_search_item_generic(C, region, item_rect, &tooltip_data);
+}
+
/* ID Search browse menu, open */
static uiBlock *id_search_menu(bContext *C, ARegion *region, void *arg_litem)
{
@@ -512,6 +539,7 @@ static uiBlock *id_search_menu(bContext *C, ARegion *region, void *arg_litem)
&template_ui,
template_ID_set_property_exec_fn,
active_item_ptr.data,
+ template_ID_search_menu_item_tooltip,
template_ui.prv_rows,
template_ui.prv_cols,
template_ui.scale);
@@ -895,7 +923,7 @@ static void template_ID(const bContext *C,
idfrom = template_ui->ptr.owner_id;
// lb = template_ui->idlb;
- /* Allow opertators to take the ID from context. */
+ /* Allow operators to take the ID from context. */
uiLayoutSetContextPointer(layout, "id", &idptr);
block = uiLayoutGetBlock(layout);
@@ -906,7 +934,7 @@ static void template_ID(const bContext *C,
}
if (text) {
- /* Add label resepecting the separated layout property split state. */
+ /* Add label respecting the separated layout property split state. */
uiItemL_respect_property_split(layout, text, ICON_NONE);
}
@@ -1632,6 +1660,7 @@ static uiBlock *template_search_menu(bContext *C, ARegion *region, void *arg_tem
&template_search,
template_search_exec_fn,
active_ptr.data,
+ NULL,
template_search.preview_rows,
template_search.preview_cols,
1.0f);
@@ -6802,20 +6831,16 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
width = min_ii((int)(rti->widthfac * width), width);
width = max_ii(width, 10 * UI_DPI_FAC);
- /* make a box around the report to make it stand out */
UI_block_align_begin(block);
- but = uiDefBut(
- block, UI_BTYPE_ROUNDBOX, 0, "", 0, 0, UI_UNIT_X + 5, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
- /* set the report's bg color in but->col - UI_BTYPE_ROUNDBOX feature */
- rgba_float_to_uchar(but->col, rti->col);
+ /* Background for icon. */
but = uiDefBut(block,
UI_BTYPE_ROUNDBOX,
0,
"",
- UI_UNIT_X + 5,
0,
- UI_UNIT_X + width,
+ 0,
+ UI_UNIT_X + (6 * UI_DPI_FAC),
UI_UNIT_Y,
NULL,
0.0f,
@@ -6823,46 +6848,57 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
0,
0,
"");
- rgba_float_to_uchar(but->col, rti->col);
+ /* UI_BTYPE_ROUNDBOX's bg color is set in but->col. */
+ UI_GetThemeColorType4ubv(UI_icon_colorid_from_report_type(report->type), SPACE_INFO, but->col);
- UI_block_align_end(block);
+ /* Background for the rest of the message. */
+ but = uiDefBut(block,
+ UI_BTYPE_ROUNDBOX,
+ 0,
+ "",
+ UI_UNIT_X + (6 * UI_DPI_FAC),
+ 0,
+ UI_UNIT_X + width,
+ UI_UNIT_Y,
+ NULL,
+ 0.0f,
+ 0.0f,
+ 0,
+ 0,
+ "");
- /* icon and report message on top */
- const int icon = UI_icon_from_report_type(report->type);
+ /* Use icon background at low opacity to highlight, but still contrasting with area TH_TEXT. */
+ UI_GetThemeColorType4ubv(UI_icon_colorid_from_report_type(report->type), SPACE_INFO, but->col);
+ but->col[3] = 64;
- /* XXX: temporary operator to dump all reports to a text block, but only if more than 1 report
- * to be shown instead of icon when appropriate...
- */
+ UI_block_align_end(block);
UI_block_emboss_set(block, UI_EMBOSS_NONE);
- if (reports->list.first != reports->list.last) {
- uiDefIconButO(block,
- UI_BTYPE_BUT,
- "SCREEN_OT_info_log_show",
- WM_OP_INVOKE_REGION_WIN,
- icon,
- 2,
- 0,
- UI_UNIT_X,
- UI_UNIT_Y,
- TIP_("Click to see the remaining reports in text block: 'Recent Reports'"));
- }
- else {
- uiDefIconBut(
- block, UI_BTYPE_LABEL, 0, icon, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
- }
+ /* The report icon itself. */
+ but = uiDefIconButO(block,
+ UI_BTYPE_BUT,
+ "SCREEN_OT_info_log_show",
+ WM_OP_INVOKE_REGION_WIN,
+ UI_icon_from_report_type(report->type),
+ (3 * UI_DPI_FAC),
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ TIP_("Click to see the remaining reports in text block: 'Recent Reports'"));
+ UI_GetThemeColorType4ubv(UI_text_colorid_from_report_type(report->type), SPACE_INFO, but->col);
+ but->col[3] = 255; /* This theme color is RBG only, so have to set alpha here. */
+ /* The report message. */
but = uiDefButO(block,
UI_BTYPE_BUT,
"SCREEN_OT_info_log_show",
WM_OP_INVOKE_REGION_WIN,
report->message,
- UI_UNIT_X + 5,
+ UI_UNIT_X,
0,
- UI_UNIT_X + width,
+ width + UI_UNIT_X,
UI_UNIT_Y,
"Show in Info Log");
- rgba_float_to_uchar(but->col, rti->col);
}
void uiTemplateInputStatus(uiLayout *layout, struct bContext *C)
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 958a0bc03cd..f9eba9eeb6f 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -544,15 +544,74 @@ int UI_icon_from_id(ID *id)
int UI_icon_from_report_type(int type)
{
if (type & RPT_ERROR_ALL) {
- return ICON_ERROR;
+ return ICON_CANCEL;
}
- if (type & RPT_WARNING_ALL) {
+ else if (type & RPT_WARNING_ALL) {
return ICON_ERROR;
}
- if (type & RPT_INFO_ALL) {
+ else if (type & RPT_INFO_ALL) {
return ICON_INFO;
}
- return ICON_NONE;
+ else if (type & RPT_DEBUG_ALL) {
+ return ICON_SYSTEM;
+ }
+ else if (type & RPT_PROPERTY) {
+ return ICON_OPTIONS;
+ }
+ else if (type & RPT_OPERATOR) {
+ return ICON_CHECKMARK;
+ }
+ return ICON_INFO;
+}
+
+int UI_icon_colorid_from_report_type(int type)
+{
+ if (type & RPT_ERROR_ALL) {
+ return TH_INFO_ERROR;
+ }
+ else if (type & RPT_WARNING_ALL) {
+ return TH_INFO_WARNING;
+ }
+ else if (type & RPT_INFO_ALL) {
+ return TH_INFO_INFO;
+ }
+ else if (type & RPT_DEBUG_ALL) {
+ return TH_INFO_DEBUG;
+ }
+ else if (type & RPT_PROPERTY) {
+ return TH_INFO_PROPERTY;
+ }
+ else if (type & RPT_OPERATOR) {
+ return TH_INFO_OPERATOR;
+ }
+ else {
+ return TH_INFO_WARNING;
+ }
+}
+
+int UI_text_colorid_from_report_type(int type)
+{
+ if (type & RPT_ERROR_ALL) {
+ return TH_INFO_ERROR_TEXT;
+ }
+ else if (type & RPT_WARNING_ALL) {
+ return TH_INFO_WARNING_TEXT;
+ }
+ else if (type & RPT_INFO_ALL) {
+ return TH_INFO_INFO_TEXT;
+ }
+ else if (type & RPT_DEBUG_ALL) {
+ return TH_INFO_DEBUG_TEXT;
+ }
+ else if (type & RPT_PROPERTY) {
+ return TH_INFO_PROPERTY_TEXT;
+ }
+ else if (type & RPT_OPERATOR) {
+ return TH_INFO_OPERATOR_TEXT;
+ }
+ else {
+ return TH_INFO_WARNING_TEXT;
+ }
}
/********************************** Misc **************************************/
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 868f62c89c9..5c59d0edeb5 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1311,7 +1311,7 @@ static void widgetbase_draw_ex(uiWidgetBase *wtb,
tria_col[3] = wcol->item[3];
}
- /* Draw everything in one drawcall */
+ /* Draw everything in one draw-call. */
if (inner_col1[3] || inner_col2[3] || outline_col[3] || emboss_col[3] || tria_col[3] ||
show_alpha_checkers) {
widgetbase_set_uniform_colors_ubv(
@@ -1533,25 +1533,22 @@ static void ui_text_clip_right_ex(const uiFontStyle *fstyle,
{
BLI_assert(str[0]);
- /* If the trailing ellipsis takes more than 20% of all available width, just cut the string
- * (as using the ellipsis would remove even more useful chars, and we cannot show much
- * already!).
- */
- if (sep_strwidth / okwidth > 0.2f) {
- float tmp;
- const int l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth, &tmp);
- str[l_end] = '\0';
+ /* How many BYTES (not characters) of this utf-8 string can fit, along with appended ellipsis. */
+ 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. */
+ memcpy(str + l_end, sep, sep_len + 1); /* +1 for trailing '\0'. */
if (r_final_len) {
- *r_final_len = (size_t)l_end;
+ *r_final_len = (size_t)(l_end) + sep_len;
}
}
else {
- float tmp;
- const int l_end = BLF_width_to_strlen(
- fstyle->uifont_id, str, max_len, okwidth - sep_strwidth, &tmp);
- memcpy(str + l_end, sep, sep_len + 1); /* +1 for trailing '\0'. */
+ /* 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) {
- *r_final_len = (size_t)(l_end) + sep_len;
+ *r_final_len = (size_t)l_end;
}
}
}
@@ -2352,7 +2349,7 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle,
int icon_size = BLI_rcti_size_y(rect);
int text_size = 0;
- /* This is a bit britle, but avoids adding an 'UI_BUT_HAS_LABEL' flag to but... */
+ /* This is a bit brittle, but avoids adding an 'UI_BUT_HAS_LABEL' flag to but... */
if (icon_size > BLI_rcti_size_x(rect)) {
/* button is not square, it has extra height for label */
text_size = UI_UNIT_Y;
@@ -2413,7 +2410,9 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle,
rect->xmin += 0.2f * U.widget_unit;
}
- widget_draw_icon(but, icon, alpha, rect, wcol->text);
+ /* By default icon is the color of text, but can optionally override with but->col. */
+ widget_draw_icon(but, icon, alpha, rect, (but->col[3] != 0) ? but->col : wcol->text);
+
if (show_menu_icon) {
BLI_assert(but->block->content_hints & UI_BLOCK_CONTAINS_SUBMENU_BUT);
widget_draw_submenu_tria(but, rect, wcol);
@@ -3617,7 +3616,7 @@ static void widget_scroll(
rect1.xmin = rect1.xmin + ceilf(fac * (value - but->softmin));
rect1.xmax = rect1.xmin + ceilf(fac * (but->a1 - but->softmin));
- /* ensure minimium size */
+ /* Ensure minimum size. */
const float min = BLI_rcti_size_y(rect);
if (BLI_rcti_size_x(&rect1) < min) {
@@ -3634,7 +3633,7 @@ static void widget_scroll(
rect1.ymax = rect1.ymax - ceilf(fac * (value - but->softmin));
rect1.ymin = rect1.ymax - ceilf(fac * (but->a1 - but->softmin));
- /* ensure minimium size */
+ /* Ensure minimum size. */
const float min = BLI_rcti_size_x(rect);
if (BLI_rcti_size_y(&rect1) < min) {
@@ -3671,7 +3670,7 @@ static void widget_progressbar(
const float offs = wcol->roundness * BLI_rcti_size_y(&rect_prog);
float w = value * BLI_rcti_size_x(&rect_prog);
- /* ensure minimium size */
+ /* Ensure minimum size. */
w = MAX2(w, offs);
rect_bar.xmax = rect_bar.xmin + w;
@@ -5224,8 +5223,7 @@ void ui_draw_tooltip_background(const uiStyle *UNUSED(style), uiBlock *UNUSED(bl
*
* \param state: The state of the button,
* typically #UI_ACTIVE, #UI_BUT_DISABLED, #UI_BUT_INACTIVE.
- * \param use_sep: When true, characters after the last #UI_SEP_CHAR are right aligned,
- * use for displaying key shortcuts.
+ * \param separator_type: The kind of separator which controls if and how the string is clipped.
* \param r_xmax: The right hand position of the text, this takes into the icon,
* padding and text clipping when there is not enough room to display the full text.
*/
@@ -5273,7 +5271,7 @@ void ui_draw_menu_item(const uiFontStyle *fstyle,
rect->xmax -= BLF_width(fstyle->uifont_id, cpoin + 1, INT_MAX) + UI_DPI_ICON_SIZE;
}
else if (separator_type == UI_MENU_ITEM_SEPARATOR_HINT) {
- /* Deterimine max-width for the hint string to leave the name string un-clipped (if there's
+ /* Determine max-width for the hint string to leave the name string un-clipped (if there's
* enough space to display it). */
const int available_width = BLI_rcti_size_x(rect) - padding;
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index f115618c13b..59aee0fde29 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -1895,7 +1895,7 @@ void UI_view2d_scroller_size_get(const View2D *v2d, float *r_x, float *r_y)
*
* \param r_x, r_y: scale on each axis
*/
-void UI_view2d_scale_get(View2D *v2d, float *r_x, float *r_y)
+void UI_view2d_scale_get(const View2D *v2d, float *r_x, float *r_y)
{
if (r_x) {
*r_x = UI_view2d_scale_get_x(v2d);
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 222f03ee1d8..e234ab5dcdc 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -46,7 +46,7 @@
#include "UI_interface.h"
#include "UI_view2d.h"
-#include "PIL_time.h" /* USER_ZOOM_CONT */
+#include "PIL_time.h" /* USER_ZOOM_CONTINUE */
/* -------------------------------------------------------------------- */
/** \name Internal Utilities
@@ -1106,14 +1106,9 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
float dx = RNA_float_get(op->ptr, "deltax") / U.dpi_fac;
float dy = RNA_float_get(op->ptr, "deltay") / U.dpi_fac;
- if (U.uiflag & USER_ZOOM_INVERT) {
- dx *= -1;
- dy *= -1;
- }
-
/* Check if the 'timer' is initialized, as zooming with the trackpad
* never uses the "Continuous" zoom method, and the 'timer' is not initialized. */
- if ((U.viewzoom == USER_ZOOM_CONT) && vzd->timer) { /* XXX store this setting as RNA prop? */
+ if ((U.viewzoom == USER_ZOOM_CONTINUE) && vzd->timer) { /* XXX store this setting as RNA prop? */
const double time = PIL_check_seconds_timer();
const float time_step = (float)(time - vzd->timer_lastdraw);
@@ -1232,26 +1227,53 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *even
vzd->lastx = event->prevx;
vzd->lasty = event->prevy;
- /* As we have only 1D information (magnify value), feed both axes
- * with magnify information that is stored in x axis
- */
- float fac = 0.01f * (event->prevx - event->x);
- float dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f;
+ float facx, facy;
+ float zoomfac = 0.01f;
+
+ /* Some view2d's (graph) don't have min/max zoom, or extreme ones. */
+ if (v2d->maxzoom > 0.0f) {
+ zoomfac = clamp_f(0.001f * v2d->maxzoom, 0.001f, 0.01f);
+ }
+
if (event->type == MOUSEPAN) {
- fac = 0.01f * (event->prevy - event->y);
+ facx = zoomfac * WM_event_absolute_delta_x(event);
+ facy = zoomfac * WM_event_absolute_delta_y(event);
+
+ if (U.uiflag & USER_ZOOM_INVERT) {
+ facx *= -1.0f;
+ facy *= -1.0f;
+ }
+ }
+ else { /* MOUSEZOOM */
+ facx = facy = zoomfac * WM_event_absolute_delta_x(event);
+ }
+
+ /* Only respect user setting zoom axis if the view does not have any zoom restrictions
+ * any will be scaled uniformly. */
+ if (((v2d->keepzoom & (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y)) == 0) &&
+ (v2d->keepzoom & V2D_KEEPASPECT)) {
+ if (U.uiflag & USER_ZOOM_HORIZ) {
+ facy = 0.0f;
+ }
+ else {
+ facx = 0.0f;
+ }
}
- float dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f;
/* support trackpad zoom to always zoom entirely - the v2d code uses portrait or
* landscape exceptions */
if (v2d->keepzoom & V2D_KEEPASPECT) {
- if (fabsf(dx) > fabsf(dy)) {
- dy = dx;
+ if (fabsf(facx) > fabsf(facy)) {
+ facy = facx;
}
else {
- dx = dy;
+ facx = facy;
}
}
+
+ const float dx = facx * BLI_rctf_size_x(&v2d->cur);
+ const float dy = facy * BLI_rctf_size_y(&v2d->cur);
+
RNA_float_set(op->ptr, "deltax", dx);
RNA_float_set(op->ptr, "deltay", dy);
@@ -1282,7 +1304,7 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *even
/* add temp handler */
WM_event_add_modal_handler(C, op);
- if (U.viewzoom == USER_ZOOM_CONT) {
+ if (U.viewzoom == USER_ZOOM_CONTINUE) {
/* needs a timer to continue redrawing */
vzd->timer = WM_event_add_timer(CTX_wm_manager(C), window, TIMER, 0.01f);
vzd->timer_lastdraw = PIL_check_seconds_timer();
@@ -1320,19 +1342,13 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, const wmEvent *event
/* x-axis transform */
dist = BLI_rcti_size_x(&v2d->mask) / 2.0f;
- len_old[0] = fabsf(vzd->lastx - vzd->region->winrct.xmin - dist);
- len_new[0] = fabsf(event->x - vzd->region->winrct.xmin - dist);
-
- len_old[0] *= zoomfac * BLI_rctf_size_x(&v2d->cur);
- len_new[0] *= zoomfac * BLI_rctf_size_x(&v2d->cur);
+ len_old[0] = zoomfac * fabsf(vzd->lastx - vzd->region->winrct.xmin - dist);
+ len_new[0] = zoomfac * fabsf(event->x - vzd->region->winrct.xmin - dist);
/* y-axis transform */
dist = BLI_rcti_size_y(&v2d->mask) / 2.0f;
- len_old[1] = fabsf(vzd->lasty - vzd->region->winrct.ymin - dist);
- len_new[1] = fabsf(event->y - vzd->region->winrct.ymin - dist);
-
- len_old[1] *= zoomfac * BLI_rctf_size_y(&v2d->cur);
- len_new[1] *= zoomfac * BLI_rctf_size_y(&v2d->cur);
+ len_old[1] = zoomfac * fabsf(vzd->lasty - vzd->region->winrct.ymin - dist);
+ len_new[1] = zoomfac * fabsf(event->y - vzd->region->winrct.ymin - dist);
/* Calculate distance */
if (v2d->keepzoom & V2D_KEEPASPECT) {
@@ -1343,40 +1359,44 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, const wmEvent *event
dx = len_new[0] - len_old[0];
dy = len_new[1] - len_old[1];
}
- }
- else {
- /* 'continuous' or 'dolly' */
- float fac;
- /* x-axis transform */
- fac = zoomfac * (event->x - vzd->lastx);
- dx = fac * BLI_rctf_size_x(&v2d->cur);
- /* y-axis transform */
- fac = zoomfac * (event->y - vzd->lasty);
- dy = fac * BLI_rctf_size_y(&v2d->cur);
+ dx *= BLI_rctf_size_x(&v2d->cur);
+ dy *= BLI_rctf_size_y(&v2d->cur);
+ }
+ else { /* USER_ZOOM_CONTINUE or USER_ZOOM_DOLLY */
+ float facx = zoomfac * (event->x - vzd->lastx);
+ float facy = zoomfac * (event->y - vzd->lasty);
/* Only respect user setting zoom axis if the view does not have any zoom restrictions
* any will be scaled uniformly */
if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0 && (v2d->keepzoom & V2D_LOCKZOOM_Y) == 0 &&
(v2d->keepzoom & V2D_KEEPASPECT)) {
if (U.uiflag & USER_ZOOM_HORIZ) {
- dy = 0;
+ facy = 0.0f;
}
else {
- dx = 0;
+ facx = 0.0f;
}
}
- }
- /* support zoom to always zoom entirely - the v2d code uses portrait or
- * landscape exceptions */
- if (v2d->keepzoom & V2D_KEEPASPECT) {
- if (fabsf(dx) > fabsf(dy)) {
- dy = dx;
- }
- else {
- dx = dy;
+ /* support zoom to always zoom entirely - the v2d code uses portrait or
+ * landscape exceptions */
+ if (v2d->keepzoom & V2D_KEEPASPECT) {
+ if (fabsf(facx) > fabsf(facy)) {
+ facy = facx;
+ }
+ else {
+ facx = facy;
+ }
}
+
+ dx = facx * BLI_rctf_size_x(&v2d->cur);
+ dy = facy * BLI_rctf_size_y(&v2d->cur);
+ }
+
+ if (U.uiflag & USER_ZOOM_INVERT) {
+ dx *= -1.0f;
+ dy *= -1.0f;
}
/* set transform amount, and add current deltas to stored total delta (for redo) */
@@ -1390,7 +1410,7 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, const wmEvent *event
* - Continuous zoom only depends on distance of mouse
* to starting point to determine rate of change.
*/
- if (U.viewzoom != USER_ZOOM_CONT) { /* XXX store this setting as RNA prop? */
+ if (U.viewzoom != USER_ZOOM_CONTINUE) { /* XXX store this setting as RNA prop? */
vzd->lastx = event->x;
vzd->lasty = event->y;
}
@@ -2204,7 +2224,7 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, const wmEvent *
scroller_activate_init(C, op, event, in_scroller);
v2dScrollerMove *vsm = (v2dScrollerMove *)op->customdata;
- /* support for quick jump to location - gtk and qt do this on linux */
+ /* Support for quick jump to location - GTK and QT do this on Linux. */
if (event->type == MIDDLEMOUSE) {
switch (vsm->scroller) {
case 'h': /* horizontal scroller - so only horizontal movement
diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c
index 636e6688971..a66f53ea839 100644
--- a/source/blender/editors/io/io_alembic.c
+++ b/source/blender/editors/io/io_alembic.c
@@ -35,19 +35,16 @@
# include "MEM_guardedalloc.h"
-# include "DNA_mesh_types.h"
# include "DNA_modifier_types.h"
# include "DNA_object_types.h"
# include "DNA_scene_types.h"
# include "DNA_space_types.h"
# include "BKE_context.h"
-# include "BKE_global.h"
# include "BKE_main.h"
# include "BKE_report.h"
# include "BLI_listbase.h"
-# include "BLI_math_vector.h"
# include "BLI_path_util.h"
# include "BLI_string.h"
# include "BLI_utildefines.h"
diff --git a/source/blender/editors/io/io_cache.c b/source/blender/editors/io/io_cache.c
index b73b8abccfe..1e66a86c8fd 100644
--- a/source/blender/editors/io/io_cache.c
+++ b/source/blender/editors/io/io_cache.c
@@ -26,7 +26,6 @@
#include "DNA_cachefile_types.h"
#include "DNA_space_types.h"
-#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 200786ca99d..2bf975cc4f5 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -29,7 +29,6 @@
# include "BLI_utildefines.h"
# include "BKE_context.h"
-# include "BKE_global.h"
# include "BKE_main.h"
# include "BKE_object.h"
# include "BKE_report.h"
@@ -37,7 +36,6 @@
# include "DEG_depsgraph.h"
# include "ED_object.h"
-# include "ED_screen.h"
# include "RNA_access.h"
# include "RNA_define.h"
diff --git a/source/blender/editors/lattice/editlattice_select.c b/source/blender/editors/lattice/editlattice_select.c
index 4497ca1a379..cb3f9a89e62 100644
--- a/source/blender/editors/lattice/editlattice_select.c
+++ b/source/blender/editors/lattice/editlattice_select.c
@@ -108,7 +108,7 @@ bool ED_lattice_deselect_all_multi(struct bContext *C)
static int lattice_select_random_exec(bContext *C, wmOperator *op)
{
- const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
+ 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);
diff --git a/source/blender/editors/lattice/editlattice_undo.c b/source/blender/editors/lattice/editlattice_undo.c
index 3a5734706f1..3ffbc3712fc 100644
--- a/source/blender/editors/lattice/editlattice_undo.c
+++ b/source/blender/editors/lattice/editlattice_undo.c
@@ -212,8 +212,11 @@ static bool lattice_undosys_step_encode(struct bContext *C, Main *bmain, UndoSte
return true;
}
-static void lattice_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
+static void lattice_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir UNUSED(dir),
+ bool UNUSED(is_final))
{
LatticeUndoStep *us = (LatticeUndoStep *)us_p;
diff --git a/source/blender/editors/lattice/lattice_ops.c b/source/blender/editors/lattice/lattice_ops.c
index d5505c00132..3f96b8a303b 100644
--- a/source/blender/editors/lattice/lattice_ops.c
+++ b/source/blender/editors/lattice/lattice_ops.c
@@ -23,15 +23,10 @@
#include "DNA_scene_types.h"
-#include "RNA_access.h"
-
#include "WM_api.h"
-#include "WM_types.h"
#include "ED_lattice.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "lattice_intern.h"
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index d7b3d74bc7e..1226cc57359 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -507,6 +507,9 @@ static int add_vertex_handle_cyclic(
static int add_vertex_exec(bContext *C, wmOperator *op)
{
+ MaskViewLockState lock_state;
+ ED_mask_view_lock_state_store(C, &lock_state);
+
Mask *mask = CTX_data_edit_mask(C);
if (mask == NULL) {
/* if there's no active mask, create one */
@@ -548,6 +551,8 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+
return OPERATOR_FINISHED;
}
@@ -690,6 +695,9 @@ void MASK_OT_add_feather_vertex(wmOperatorType *ot)
static int create_primitive_from_points(
bContext *C, wmOperator *op, const float (*points)[2], int num_points, char handle_type)
{
+ MaskViewLockState lock_state;
+ ED_mask_view_lock_state_store(C, &lock_state);
+
ScrArea *area = CTX_wm_area(C);
int size = RNA_float_get(op->ptr, "size");
@@ -752,6 +760,8 @@ static int create_primitive_from_points(
DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index 89fd2fa9b62..d3fa0e93597 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -539,7 +539,7 @@ static void draw_spline_curve(const bContext *C,
uint tot_feather_point;
float(*feather_points)[2];
- diff_points = BKE_mask_spline_differentiate_with_resolution(spline, &tot_diff_point, resol);
+ diff_points = BKE_mask_spline_differentiate_with_resolution(spline, resol, &tot_diff_point);
if (!diff_points) {
return;
@@ -550,7 +550,7 @@ static void draw_spline_curve(const bContext *C,
}
feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution(
- spline, &tot_feather_point, resol, (is_fill != false));
+ spline, resol, (is_fill != false), &tot_feather_point);
/* draw feather */
mask_spline_feather_color_get(mask_layer, spline, is_spline_sel, rgb_tmp);
diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c
index 663ae0097ad..f1041d062a8 100644
--- a/source/blender/editors/mask/mask_edit.c
+++ b/source/blender/editors/mask/mask_edit.c
@@ -184,3 +184,39 @@ void ED_operatormacros_mask(void)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Lock-to-selection viewport preservation
+ * \{ */
+
+void ED_mask_view_lock_state_store(const bContext *C, MaskViewLockState *state)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ if (space_clip != NULL) {
+ ED_clip_view_lock_state_store(C, &state->space_clip_state);
+ }
+}
+
+void ED_mask_view_lock_state_restore_no_jump(const bContext *C, const MaskViewLockState *state)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ if (space_clip != NULL) {
+ if ((space_clip->flag & SC_LOCK_SELECTION) == 0) {
+ /* Early output if the editor is not locked to selection.
+ * Avoids forced dependency graph evaluation here. */
+ return;
+ }
+
+ /* Mask's lock-to-selection requires deformed splines to be evaluated to calculate bounds of
+ * points after animation has been evaluated. The restore-no-jump type of function does
+ * calculation of new offset for the view for an updated state of mask to cancel the offset out
+ * by modifying locked offset. In order to do such calculation mask needs to be evaluated after
+ * modification by an operator. */
+ struct Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ (void)depsgraph;
+
+ ED_clip_view_lock_state_restore_no_jump(C, &state->space_clip_state);
+ }
+}
+
+/** \} */
diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h
index f6990583383..ee1784011ea 100644
--- a/source/blender/editors/mask/mask_intern.h
+++ b/source/blender/editors/mask/mask_intern.h
@@ -23,6 +23,8 @@
#pragma once
+#include "ED_clip.h"
+
struct Mask;
struct bContext;
struct wmOperatorType;
@@ -92,6 +94,19 @@ void ED_mask_select_flush_all(struct Mask *mask);
bool ED_maskedit_poll(struct bContext *C);
bool ED_maskedit_mask_poll(struct bContext *C);
+/* Generalized solution for preserving editor viewport when making changes while lock-to-selection
+ * is enabled.
+ * Any mask operator can use this API, without worrying that some editors do not have an idea of
+ * lock-to-selection. */
+
+typedef struct MaskViewLockState {
+ ClipViewLockState space_clip_state;
+} MaskViewLockState;
+
+void ED_mask_view_lock_state_store(const struct bContext *C, MaskViewLockState *state);
+void ED_mask_view_lock_state_restore_no_jump(const struct bContext *C,
+ const MaskViewLockState *state);
+
/* mask_query.c */
bool ED_mask_find_nearest_diff_point(const struct bContext *C,
struct Mask *mask,
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 25cc39bf9a0..14f81520b9a 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -226,13 +226,19 @@ typedef struct SlidePointData {
int width, height;
float prev_mouse_coord[2];
+
+ /* Previous clip coordinate which was resolved from mouse position (0, 0).
+ * Is used to compensate for view offset moving in-between of mouse events when
+ * lock-to-selection is enabled. */
+ float prev_zero_coord[2];
+
float no[2];
bool is_curvature_only, is_accurate, is_initial_feather, is_overall_feather;
bool is_sliding_new_point;
- /* Data needed to restre the state. */
+ /* Data needed to restore the state. */
float vec[3][3];
char old_h1, old_h2;
@@ -431,6 +437,9 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *
const float threshold = 19;
eMaskWhichHandle which_handle;
+ MaskViewLockState lock_state;
+ ED_mask_view_lock_state_store(C, &lock_state);
+
ED_mask_mouse_pos(area, region, event->mval, co);
ED_mask_get_size(area, &width, &height);
@@ -530,7 +539,15 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *
}
customdata->which_handle = which_handle;
+ {
+ WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
+ DEG_id_tag_update(&mask->id, 0);
+
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+ }
+
ED_mask_mouse_pos(area, region, event->mval, customdata->prev_mouse_coord);
+ ED_mask_mouse_pos(area, region, (int[2]){0, 0}, customdata->prev_zero_coord);
}
return customdata;
@@ -655,10 +672,24 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
ED_mask_mouse_pos(area, region, event->mval, co);
sub_v2_v2v2(delta, co, data->prev_mouse_coord);
+ copy_v2_v2(data->prev_mouse_coord, co);
+
+ /* Compensate for possibly moved view offset since the last event.
+ * The idea is to see how mapping of a fixed and known position did change. */
+ {
+ float zero_coord[2];
+ ED_mask_mouse_pos(area, region, (int[2]){0, 0}, zero_coord);
+
+ float zero_delta[2];
+ sub_v2_v2v2(zero_delta, zero_coord, data->prev_zero_coord);
+ sub_v2_v2(delta, zero_delta);
+
+ copy_v2_v2(data->prev_zero_coord, zero_coord);
+ }
+
if (data->is_accurate) {
mul_v2_fl(delta, 0.2f);
}
- copy_v2_v2(data->prev_mouse_coord, co);
if (data->action == SLIDE_ACTION_HANDLE) {
float new_handle[2];
@@ -832,7 +863,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->type == data->event_invoke_type && event->val == KM_RELEASE) {
Scene *scene = CTX_data_scene(C);
- /* dont key sliding feather uw's */
+ /* Don't key sliding feather UW's. */
if ((data->action == SLIDE_ACTION_FEATHER && data->uw) == false) {
if (IS_AUTOKEY_ON(scene)) {
ED_mask_layer_shape_auto_key(data->mask_layer, CFRA);
@@ -966,6 +997,9 @@ static SlideSplineCurvatureData *slide_spline_curvature_customdata(bContext *C,
float u, co[2];
BezTriple *next_bezt;
+ MaskViewLockState lock_state;
+ ED_mask_view_lock_state_store(C, &lock_state);
+
ED_mask_mouse_pos(CTX_wm_area(C), CTX_wm_region(C), event->mval, co);
if (!ED_mask_find_nearest_diff_point(C,
@@ -1019,7 +1053,7 @@ static SlideSplineCurvatureData *slide_spline_curvature_customdata(bContext *C,
slide_data->bezt_backup = *slide_data->adjust_bezt;
slide_data->other_bezt_backup = *slide_data->other_bezt;
- /* Let's dont touch other side of the point for now, so set handle to FREE. */
+ /* Let's don't touch other side of the point for now, so set handle to FREE. */
if (u < 0.5f) {
if (slide_data->adjust_bezt->h2 <= HD_VECT) {
slide_data->adjust_bezt->h2 = HD_FREE;
@@ -1047,6 +1081,9 @@ static SlideSplineCurvatureData *slide_spline_curvature_customdata(bContext *C,
mask_layer->act_point = point;
ED_mask_select_flush_all(mask);
+ DEG_id_tag_update(&mask->id, 0);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+
return slide_data;
}
@@ -1233,7 +1270,7 @@ static int slide_spline_curvature_modal(bContext *C, wmOperator *op, const wmEve
case LEFTMOUSE:
case RIGHTMOUSE:
if (event->type == slide_data->event_invoke_type && event->val == KM_RELEASE) {
- /* dont key sliding feather uw's */
+ /* Don't key sliding feather UW's. */
if (IS_AUTOKEY_ON(scene)) {
ED_mask_layer_shape_auto_key(slide_data->mask_layer, CFRA);
}
diff --git a/source/blender/editors/mask/mask_query.c b/source/blender/editors/mask/mask_query.c
index cfd57ca3477..401b6eac4f2 100644
--- a/source/blender/editors/mask/mask_query.c
+++ b/source/blender/editors/mask/mask_query.c
@@ -604,22 +604,37 @@ void ED_mask_point_pos__reverse(
*yr = co[1];
}
-bool ED_mask_selected_minmax(const bContext *C, float min[2], float max[2])
+static void handle_position_for_minmax(const MaskSplinePoint *point,
+ eMaskWhichHandle which_handle,
+ bool handles_as_control_point,
+ float r_handle[2])
+{
+ if (handles_as_control_point) {
+ copy_v2_v2(r_handle, point->bezt.vec[1]);
+ return;
+ }
+ BKE_mask_point_handle(point, which_handle, r_handle);
+}
+
+bool ED_mask_selected_minmax(const bContext *C,
+ float min[2],
+ float max[2],
+ bool handles_as_control_point)
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
Mask *mask = CTX_data_edit_mask(C);
- /* Use evaluated mask to take animation into account.
- * The animation of splies is not "flushed" back to original, so need to explicitly
- * sue evaluated datablock here. */
- Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask->id);
-
bool ok = false;
if (mask == NULL) {
return ok;
}
+ /* Use evaluated mask to take animation into account.
+ * The animation of splies is not "flushed" back to original, so need to explicitly
+ * sue evaluated datablock here. */
+ Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask->id);
+
INIT_MINMAX2(min, max);
for (MaskLayer *mask_layer = mask_eval->masklayers.first; mask_layer != NULL;
mask_layer = mask_layer->next) {
@@ -638,22 +653,29 @@ bool ED_mask_selected_minmax(const bContext *C, float min[2], float max[2])
}
if (bezt->f2 & SELECT) {
minmax_v2v2_v2(min, max, deform_point->bezt.vec[1]);
+ ok = true;
}
+
if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) {
- BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_STICK, handle);
+ handle_position_for_minmax(
+ deform_point, MASK_WHICH_HANDLE_STICK, handles_as_control_point, handle);
minmax_v2v2_v2(min, max, handle);
+ ok = true;
}
else {
if ((bezt->f1 & SELECT) && (bezt->h1 != HD_VECT)) {
- BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_LEFT, handle);
+ handle_position_for_minmax(
+ deform_point, MASK_WHICH_HANDLE_LEFT, handles_as_control_point, handle);
minmax_v2v2_v2(min, max, handle);
+ ok = true;
}
if ((bezt->f3 & SELECT) && (bezt->h2 != HD_VECT)) {
- BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_RIGHT, handle);
+ handle_position_for_minmax(
+ deform_point, MASK_WHICH_HANDLE_RIGHT, handles_as_control_point, handle);
minmax_v2v2_v2(min, max, handle);
+ ok = true;
}
}
- ok = true;
}
}
}
diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c
index cdc6ece1e84..5c369afc4cd 100644
--- a/source/blender/editors/mask/mask_select.c
+++ b/source/blender/editors/mask/mask_select.c
@@ -214,12 +214,17 @@ static int select_all_exec(bContext *C, wmOperator *op)
Mask *mask = CTX_data_edit_mask(C);
int action = RNA_enum_get(op->ptr, "action");
+ MaskViewLockState lock_state;
+ ED_mask_view_lock_state_store(C, &lock_state);
+
ED_mask_select_toggle_all(mask, action);
ED_mask_select_flush_all(mask);
DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+
return OPERATOR_FINISHED;
}
@@ -261,6 +266,9 @@ static int select_exec(bContext *C, wmOperator *op)
eMaskWhichHandle which_handle;
const float threshold = 19;
+ MaskViewLockState lock_state;
+ ED_mask_view_lock_state_store(C, &lock_state);
+
RNA_float_get_array(op->ptr, "location", co);
point = ED_mask_point_find_nearest(
@@ -324,6 +332,8 @@ static int select_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+
return OPERATOR_FINISHED;
}
@@ -364,12 +374,15 @@ static int select_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
+
return OPERATOR_FINISHED;
}
if (deselect_all) {
/* For clip editor tracks, leave deselect all to clip editor. */
if (!ED_clip_can_select(C)) {
ED_mask_deselect_all(C);
+ ED_mask_view_lock_state_restore_no_jump(C, &lock_state);
return OPERATOR_FINISHED;
}
}
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index a5dd29c9d73..d60d83850a5 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -24,7 +24,6 @@
#include "BLI_math.h"
#include "BLI_sys_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -42,7 +41,6 @@
#include "ED_mesh.h"
#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_uvedit.h"
#include "mesh_intern.h" /* own include */
diff --git a/source/blender/editors/mesh/editmesh_automerge.c b/source/blender/editors/mesh/editmesh_automerge.c
index f9910f01f47..2bd5b9b26ca 100644
--- a/source/blender/editors/mesh/editmesh_automerge.c
+++ b/source/blender/editors/mesh/editmesh_automerge.c
@@ -26,12 +26,9 @@
* - #EDBM_automerge_and_split
*/
-#include "MEM_guardedalloc.h"
-
#include "BKE_editmesh.h"
#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
#include "ED_mesh.h"
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index 8ea3c883433..66a7b97b440 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -28,11 +28,9 @@
#include "BLT_translation.h"
#include "BKE_context.h"
-#include "BKE_curveprofile.h"
#include "BKE_editmesh.h"
#include "BKE_global.h"
#include "BKE_layer.h"
-#include "BKE_mesh.h"
#include "BKE_unit.h"
#include "DNA_curveprofile_types.h"
@@ -575,7 +573,7 @@ static void edbm_bevel_mouse_set_value(wmOperator *op, const wmEvent *event)
opdata->shift_value[vmode] = -1.0f;
}
- /* clamp accordingto value mode, and store value back */
+ /* Clamp according to value mode, and store value back. */
CLAMP(value, value_clamp_min[vmode], value_clamp_max[vmode]);
if (vmode == SEGMENTS_VALUE) {
opdata->segments = value;
diff --git a/source/blender/editors/mesh/editmesh_extrude_spin.c b/source/blender/editors/mesh/editmesh_extrude_spin.c
index 7b3fabf07fc..187652ae00f 100644
--- a/source/blender/editors/mesh/editmesh_extrude_spin.c
+++ b/source/blender/editors/mesh/editmesh_extrude_spin.c
@@ -33,17 +33,13 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
-#include "WM_api.h"
#include "WM_types.h"
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_view3d.h"
-#include "UI_resources.h"
-
#include "MEM_guardedalloc.h"
#include "mesh_intern.h" /* own include */
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index f45f48e0e32..1f894ec0f1d 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -210,7 +210,7 @@ typedef struct KnifeTool_OpData {
/* run by the UI or not */
bool is_interactive;
- /* operatpr options */
+ /* Operator options. */
bool cut_through; /* preference, can be modified at runtime (that feature may go) */
bool only_select; /* set on initialization */
bool select_result; /* set on initialization */
@@ -2752,8 +2752,6 @@ static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
}
- view3d_operator_needs_opengl(C);
-
/* alloc new customdata */
kcd = op->customdata = MEM_callocN(sizeof(KnifeTool_OpData), __func__);
@@ -2831,7 +2829,6 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
em_setup_viewcontext(C, &kcd->vc);
kcd->region = kcd->vc.region;
- view3d_operator_needs_opengl(C);
ED_view3d_init_mats_rv3d(obedit, kcd->vc.rv3d); /* needed to initialize clipping */
if (kcd->mode == MODE_PANNING) {
@@ -3067,8 +3064,6 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
{
KnifeTool_OpData *kcd;
- view3d_operator_needs_opengl(C);
-
/* init */
{
const bool only_select = false;
diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c
index 3e0bee3c4b8..7d849c096e7 100644
--- a/source/blender/editors/mesh/editmesh_mask_extract.c
+++ b/source/blender/editors/mesh/editmesh_mask_extract.c
@@ -81,7 +81,7 @@ typedef struct GeometryExtactParams {
/* For extracting Mask. */
float mask_threshold;
- /* Common paramenters. */
+ /* Common parameters. */
bool add_boundary_loop;
int num_smooth_iterations;
bool apply_shrinkwrap;
@@ -106,7 +106,7 @@ static int geometry_extract_apply(bContext *C,
BKE_sculpt_mask_layers_ensure(ob, NULL);
- /* Ensures that deformation from sculpt mode is taken into accunt before duplicating the mesh to
+ /* Ensures that deformation from sculpt mode is taken into account before duplicating the mesh to
* extract the geometry. */
CTX_data_ensure_evaluated_depsgraph(C);
@@ -385,7 +385,7 @@ static int face_set_extract_modal(bContext *C, wmOperator *op, const wmEvent *ev
ED_workspace_status_text(C, NULL);
/* This modal operator uses and eyedropper to pick a Face Set from the mesh. This ensures
- * that the mouse clicked in a viewport region and its coordinates can be used to raycast
+ * that the mouse clicked in a viewport region and its coordinates can be used to ray-cast
* the PBVH and update the active Face Set ID. */
bScreen *screen = CTX_wm_screen(C);
ARegion *region = BKE_screen_find_main_region_at_xy(
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index b5b4802aa78..c8449644dd0 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -2205,7 +2205,7 @@ void EDBM_selectmode_set(BMEditMesh *em)
}
}
else if (em->selectmode & SCE_SELECT_FACE) {
- /* deselect eges, and select again based on face select */
+ /* Deselect edges, and select again based on face select. */
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
BM_edge_select_set(em->bm, eed, false);
}
@@ -2247,7 +2247,7 @@ void EDBM_selectmode_convert(BMEditMesh *em,
/* first tag-to-select, then select --- this avoids a feedback loop */
- /* have to find out what the selectionmode was previously */
+ /* Have to find out what the selection-mode was previously. */
if (selectmode_old == SCE_SELECT_VERTEX) {
if (bm->totvertsel == 0) {
/* pass */
@@ -4573,7 +4573,7 @@ void MESH_OT_select_non_manifold(wmOperatorType *ot)
static int edbm_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, "percent") / 100.0f;
+ const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
ViewLayer *view_layer = CTX_data_view_layer(C);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 84f4e35cb0c..de37ddec885 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -3905,7 +3905,7 @@ static float bm_edge_seg_isect(const float sco_a[2],
x12 = mouse_path[i][0];
y12 = mouse_path[i][1];
- /* Perp. Distance from point to line */
+ /* Calculate the distance from point to line. */
if (m2 != MAXSLOPE) {
/* sqrt(m2 * m2 + 1); Only looking for change in sign. Skip extra math .*/
dist = (y12 - m2 * x12 - b2);
@@ -4010,7 +4010,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
short numcuts = 1;
const short mode = RNA_int_get(op->ptr, "type");
- /* allocd vars */
+ /* Allocated variables. */
float(*screen_vert_coords)[2], (*sco)[2], (*mouse_path)[2];
/* edit-object needed for matrix, and region->regiondata for projections to work */
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 41bb3faa135..dd51d63961c 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -188,7 +188,7 @@ static void um_arraystore_cd_compact(struct CustomData *cdata,
else {
bcd_reference_current = NULL;
- /* do a full lookup when un-alligned */
+ /* Do a full lookup when unaligned. */
if (bcd_reference) {
const BArrayCustomData *bcd_iter = bcd_reference;
while (bcd_iter) {
@@ -766,8 +766,11 @@ static bool mesh_undosys_step_encode(struct bContext *C, struct Main *bmain, Und
return true;
}
-static void mesh_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
+static void mesh_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir UNUSED(dir),
+ bool UNUSED(is_final))
{
MeshUndoStep *us = (MeshUndoStep *)us_p;
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 2cf97b7235f..27d73497b49 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -21,7 +21,6 @@
* \ingroup edmesh
*/
-#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
#include "RNA_access.h"
@@ -30,9 +29,7 @@
#include "WM_types.h"
#include "ED_mesh.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "mesh_intern.h" /* own include */
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 3b5897de0b0..3450d61337c 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -145,7 +145,7 @@ static void join_mesh_single(Depsgraph *depsgraph,
if (ob_src != ob_dst) {
float cmat[4][4];
- /* watch this: switch matmul order really goes wrong */
+ /* Watch this: switch matrix multiplication order really goes wrong. */
mul_m4_m4m4(cmat, imat, ob_src->obmat);
/* transform vertex coordinates into new space */
@@ -733,7 +733,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
BKE_key_sort(key);
}
- /* Due to dependnecy cycle some other object might access old derived data. */
+ /* Due to dependency cycle some other object might access old derived data. */
BKE_object_free_derived_caches(ob);
DEG_relations_tag_update(bmain); /* removed objects, need to rebuild dag */
diff --git a/source/blender/editors/metaball/editmball_undo.c b/source/blender/editors/metaball/editmball_undo.c
index cbc60bcc031..b817bc3a718 100644
--- a/source/blender/editors/metaball/editmball_undo.c
+++ b/source/blender/editors/metaball/editmball_undo.c
@@ -187,8 +187,11 @@ static bool mball_undosys_step_encode(struct bContext *C, struct Main *bmain, Un
return true;
}
-static void mball_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int UNUSED(dir), bool UNUSED(is_final))
+static void mball_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir UNUSED(dir),
+ bool UNUSED(is_final))
{
MBallUndoStep *us = (MBallUndoStep *)us_p;
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index 094011ebef1..cf453bf0c32 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -483,7 +483,7 @@ void MBALL_OT_select_similar(wmOperatorType *ot)
static int select_random_metaelems_exec(bContext *C, wmOperator *op)
{
const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
- const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
+ const float randfac = RNA_float_get(op->ptr, "ratio");
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
ViewLayer *view_layer = CTX_data_view_layer(C);
diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c
index 100ca4691ca..a54ec384d8e 100644
--- a/source/blender/editors/metaball/mball_ops.c
+++ b/source/blender/editors/metaball/mball_ops.c
@@ -29,9 +29,7 @@
#include "WM_types.h"
#include "ED_mball.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "mball_intern.h"
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index c6d6b8b16b9..b6b6dcfaa59 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -516,7 +516,7 @@ bool ED_object_add_generic_get_opts(bContext *C,
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), dont set it to ALIGN_WORLD in the op UI though. */
+ * 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);
}
@@ -607,7 +607,6 @@ Object *ED_object_add_type_with_obdata(bContext *C,
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- /* For as long scene has editmode... */
{
Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
if (obedit != NULL) {
@@ -1712,9 +1711,8 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_add_type(C, OB_SPEAKER, NULL, loc, rot, false, local_view_bits);
const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ob);
- /* to make it easier to start using this immediately in NLA, a default sound clip is created
- * ready to be moved around to retime the sound and/or make new sound clips
- */
+ /* To make it easier to start using this immediately in NLA, a default sound clip is created
+ * 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);
@@ -3364,6 +3362,9 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
ED_view3d_cursor3d_position(C, mval, false, basen->object->loc);
}
+ /* object_add_duplicate_internal() doesn't deselect other objects, unlike object_add_common() or
+ * BKE_view_layer_base_deselect_all(). */
+ ED_object_base_deselect_all(view_layer, NULL, BA_DESELECT);
ED_object_base_select(basen, BA_SELECT);
ED_object_base_activate(C, basen);
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 7179cc26fc1..9ec0c625f71 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -1364,7 +1364,7 @@ static int bake(const BakeAPIRender *bkr,
highpoly[i].ob_eval->base_flag |= (BASE_VISIBLE_DEPSGRAPH | BASE_ENABLED_RENDER);
highpoly[i].me = BKE_mesh_new_from_object(NULL, highpoly[i].ob_eval, false);
- /* lowpoly to highpoly transformation matrix */
+ /* Low-poly to high-poly transformation matrix. */
copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat);
invert_m4_m4(highpoly[i].imat, highpoly[i].obmat);
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index 4cbb8858bf4..b251e617a4c 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -51,8 +51,6 @@
#include "ED_object.h"
-#include "UI_interface.h"
-
#include "object_intern.h"
/* All possible data to transfer.
@@ -65,7 +63,7 @@ static const EnumPropertyItem DT_layer_items[] = {
0,
"Vertex Group(s)",
"Transfer active or all vertex groups"},
-#if 0 /* XXX For now, would like to finish/merge work from 2014 gsoc first. */
+#if 0 /* XXX For now, would like to finish/merge work from 2014 GSOC first. */
{DT_TYPE_SHAPEKEY, "SHAPEKEYS", 0, "Shapekey(s)", "Transfer active or all shape keys"},
#endif
/* XXX When SkinModifier is enabled,
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 6350ffb9c77..7e0e52d3874 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -3024,7 +3024,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
i++;
}
- /* make a copy of ocean to use for baking - threadsafety */
+ /* Make a copy of ocean to use for baking - thread-safety. */
struct Ocean *ocean = BKE_ocean_add();
BKE_ocean_init_from_modifier(ocean, omd, omd->resolution);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 964d9898ac0..2124d242ee2 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -25,23 +25,15 @@
#include <stdlib.h>
#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-
-#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "RNA_access.h"
-#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_object.h"
-#include "ED_screen.h"
-#include "ED_select_utils.h"
-
-#include "DEG_depsgraph.h"
#include "object_intern.h"
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index acad1b43cbb..5a2ef1c6556 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1790,20 +1790,33 @@ void OBJECT_OT_make_links_scene(wmOperatorType *ot)
void OBJECT_OT_make_links_data(wmOperatorType *ot)
{
static const EnumPropertyItem make_links_items[] = {
- {MAKE_LINKS_OBDATA, "OBDATA", 0, "Object Data", ""},
- {MAKE_LINKS_MATERIALS, "MATERIAL", 0, "Materials", ""},
- {MAKE_LINKS_ANIMDATA, "ANIMATION", 0, "Animation Data", ""},
- {MAKE_LINKS_GROUP, "GROUPS", 0, "Collection", ""},
- {MAKE_LINKS_DUPLICOLLECTION, "DUPLICOLLECTION", 0, "Instance Collection", ""},
- {MAKE_LINKS_MODIFIERS, "MODIFIERS", 0, "Modifiers", ""},
- {MAKE_LINKS_FONTS, "FONTS", 0, "Fonts", ""},
- {MAKE_LINKS_SHADERFX, "EFFECTS", 0, "Effects", ""},
+ {MAKE_LINKS_OBDATA, "OBDATA", 0, "Link Object Data", "Replace assigned Object Data"},
+ {MAKE_LINKS_MATERIALS, "MATERIAL", 0, "Link Materials", "Replace assigned Materials"},
+ {MAKE_LINKS_ANIMDATA,
+ "ANIMATION",
+ 0,
+ "Link Animation Data",
+ "Replace assigned Animation Data"},
+ {MAKE_LINKS_GROUP, "GROUPS", 0, "Link Collections", "Replace assigned Collections"},
+ {MAKE_LINKS_DUPLICOLLECTION,
+ "DUPLICOLLECTION",
+ 0,
+ "Link Instance Collection",
+ "Replace assigned Collection Instance"},
+ {MAKE_LINKS_FONTS, "FONTS", 0, "Link Fonts to Text", "Replace Text object Fonts"},
+ {0, "", 0, NULL, NULL},
+ {MAKE_LINKS_MODIFIERS, "MODIFIERS", 0, "Copy Modifiers", "Replace Modifiers"},
+ {MAKE_LINKS_SHADERFX,
+ "EFFECTS",
+ 0,
+ "Copy Grease Pencil Effects",
+ "Replace Grease Pencil Effects"},
{0, NULL, 0, NULL, NULL},
};
/* identifiers */
- ot->name = "Link Data";
- ot->description = "Apply active object links to other selected objects";
+ ot->name = "Link/Transfer Data";
+ ot->description = "Transfer data from active object to selected objects";
ot->idname = "OBJECT_OT_make_links_data";
/* api callbacks */
@@ -2328,7 +2341,7 @@ void OBJECT_OT_make_local(wmOperatorType *ot)
static bool make_override_library_object_overridable_check(Main *bmain, Object *object)
{
- /* An object is actually overrideable only if it is in at least one local collections.
+ /* An object is actually overridable only if it is in at least one local collection.
* Unfortunately 'direct link' flag is not enough here. */
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
if (!ID_IS_LINKED(collection) && BKE_collection_has_object(collection, object)) {
diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c
index d560d347217..f55ce88b426 100644
--- a/source/blender/editors/object/object_remesh.c
+++ b/source/blender/editors/object/object_remesh.c
@@ -327,7 +327,7 @@ static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar),
const float total_len = len_v3v3(cd->preview_plane[0], cd->preview_plane[1]);
const int tot_lines = (int)(total_len / cd->voxel_size);
- /* Smoothstep to reduce the alpha of the grid as the line number increases. */
+ /* Smooth-step to reduce the alpha of the grid as the line number increases. */
const float a = VOXEL_SIZE_EDIT_MAX_GRIDS_LINES * 0.1f;
const float b = VOXEL_SIZE_EDIT_MAX_GRIDS_LINES;
const float x = clamp_f((tot_lines - a) / (b - a), 0.0f, 1.0);
@@ -738,7 +738,7 @@ static int quadriflow_break_job(void *customdata)
return should_break;
}
-/* called by oceanbake, wmJob sends notifier */
+/** Called by ocean-bake, #wmJob sends notifier. */
static void quadriflow_update_job(void *customdata, float progress, int *cancel)
{
QuadriFlowJob *qj = customdata;
@@ -982,7 +982,7 @@ static int quadriflow_remesh_exec(bContext *C, wmOperator *op)
quadriflow_free_job(job);
}
else {
- /* Non blocking call. For when the operator has been called from the gui */
+ /* Non blocking call. For when the operator has been called from the GUI. */
job->is_nonblocking_job = true;
wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index b36d89dc37a..1e6a7b9f14e 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -317,7 +317,7 @@ bool ED_object_jump_to_object(bContext *C, Object *ob, const bool UNUSED(reveal_
/**
* Select and make the target object and bone active.
* Switches to Pose mode if in Object mode so the selection is visible.
- * Unhides the target bone and bone layer if necessary.
+ * Un-hides the target bone and bone layer if necessary.
*
* \returns false if object not in layer, bone not found, or other error
*/
@@ -1453,7 +1453,7 @@ void OBJECT_OT_select_less(wmOperatorType *ot)
static int object_select_random_exec(bContext *C, wmOperator *op)
{
- const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
+ 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);
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 1bb0246deb5..fd649854d8f 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -36,7 +36,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "DNA_curve_types.h"
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
@@ -44,7 +43,6 @@
#include "DNA_object_types.h"
#include "BKE_context.h"
-#include "BKE_curve.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_main.h"
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 0528d64dca9..13c0740bce6 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -1394,7 +1394,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
* (all layers are considered without evaluating lock attributes) */
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ 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) {
diff --git a/source/blender/editors/object/object_volume.c b/source/blender/editors/object/object_volume.c
index 6b46d43e5bf..fbdee00c29c 100644
--- a/source/blender/editors/object/object_volume.c
+++ b/source/blender/editors/object/object_volume.c
@@ -23,9 +23,6 @@
#include <string.h>
-#include "MEM_guardedalloc.h"
-
-#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_path_util.h"
diff --git a/source/blender/editors/object/object_warp.c b/source/blender/editors/object/object_warp.c
index b36a8543d67..4b15385b537 100644
--- a/source/blender/editors/object/object_warp.c
+++ b/source/blender/editors/object/object_warp.c
@@ -36,7 +36,6 @@
#include "WM_types.h"
#include "ED_transverts.h"
-#include "ED_view3d.h"
#include "object_intern.h"
@@ -75,7 +74,7 @@ static void object_warp_transverts_minmax_x(TransVertStore *tvs,
for (int i = 0; i < tvs->transverts_tot; i++, tv++) {
float val;
- /* convert objectspace->viewspace */
+ /* Convert object-space to view-space. */
val = dot_m4_v3_row_x(mat_view, tv->loc);
min = min_ff(min, val);
@@ -123,7 +122,7 @@ static void object_warp_transverts(TransVertStore *tvs,
float co[3], co_add[2];
float val, phi;
- /* convert objectspace->viewspace */
+ /* Convert object-space to view-space. */
mul_v3_m4v3(co, mat_view, tv->loc);
sub_v2_v2(co, center_view);
@@ -158,7 +157,7 @@ static void object_warp_transverts(TransVertStore *tvs,
add_v2_v2(co, co_add);
- /* convert viewspace->objectspace */
+ /* Convert view-space to object-space. */
add_v2_v2(co, center_view);
mul_v3_m4v3(tv->loc, imat_view, co);
}
@@ -187,7 +186,7 @@ static int object_warp_verts_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* get viewmatrix */
+ /* Get view-matrix. */
{
PropertyRNA *prop_viewmat = RNA_struct_find_property(op->ptr, "viewmat");
if (RNA_property_is_set(op->ptr, prop_viewmat)) {
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index 381bf317bee..a761701f60b 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -233,7 +233,7 @@ static int output_toggle_exec(bContext *C, wmOperator *op)
/* if type is already enabled, toggle it off */
if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
- int exists = dynamicPaint_outputLayerExists(surface, ob, output);
+ bool exists = dynamicPaint_outputLayerExists(surface, ob, output);
const char *name;
if (output == 0) {
diff --git a/source/blender/editors/physics/particle_boids.c b/source/blender/editors/physics/particle_boids.c
index 22cfa50aee9..9b8622e6eac 100644
--- a/source/blender/editors/physics/particle_boids.c
+++ b/source/blender/editors/physics/particle_boids.c
@@ -33,7 +33,6 @@
#include "BKE_boids.h"
#include "BKE_context.h"
#include "BKE_main.h"
-#include "BKE_particle.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 8ab25fa74b8..d7e30f2b65c 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -1999,7 +1999,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
int p;
int k;
- const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
+ 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;
@@ -2905,7 +2905,7 @@ static void remove_tagged_keys(Depsgraph *depsgraph, Object *ob, ParticleSystem
}
}
-/************************ subdivide opertor *********************/
+/************************ subdivide operator *********************/
/* works like normal edit mode subdivide, inserts keys between neighboring selected keys */
static void subdivide_particle(PEData *data, int pa_index)
@@ -3029,7 +3029,7 @@ void PARTICLE_OT_subdivide(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/************************ remove doubles opertor *********************/
+/************************ remove doubles operator *********************/
static int remove_doubles_exec(bContext *C, wmOperator *op)
{
@@ -3750,8 +3750,7 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance)
}
}
else {
- /* compute position as if hair was standing up straight.
- * */
+ /* Compute position as if hair was standing up straight. */
float length;
copy_v3_v3(co_prev, co);
copy_v3_v3(co, key->co);
@@ -4566,7 +4565,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
mval[0] = mouse[0];
mval[1] = mouse[1];
- /* disable locking temporatily for disconnected hair */
+ /* Disable locking temporarily for disconnected hair. */
if (edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR) {
pset->flag &= ~PE_LOCK_FIRST;
}
@@ -5004,7 +5003,7 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
- /* disable locking temporatily for disconnected hair */
+ /* Disable locking temporarily for disconnected hair. */
if (edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR) {
pset->flag &= ~PE_LOCK_FIRST;
}
diff --git a/source/blender/editors/physics/particle_edit_undo.c b/source/blender/editors/physics/particle_edit_undo.c
index 77b8d410d81..5d2e0e5b6ef 100644
--- a/source/blender/editors/physics/particle_edit_undo.c
+++ b/source/blender/editors/physics/particle_edit_undo.c
@@ -247,7 +247,7 @@ static bool particle_undosys_step_encode(struct bContext *C,
static void particle_undosys_step_decode(struct bContext *C,
struct Main *UNUSED(bmain),
UndoStep *us_p,
- int UNUSED(dir),
+ const eUndoStepDir UNUSED(dir),
bool UNUSED(is_final))
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 32d2e39d6f6..a94a2b9b764 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -33,21 +33,17 @@
#include "DNA_object_types.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_path_util.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
#include "BKE_context.h"
-#include "BKE_customdata.h"
#include "BKE_fluid.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
-#include "BKE_object.h"
#include "BKE_report.h"
-#include "BKE_scene.h"
#include "BKE_screen.h"
#include "DEG_depsgraph.h"
@@ -59,11 +55,9 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "manta_fluid_API.h"
#include "physics_intern.h" /* own include */
#include "DNA_fluid_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_scene_types.h"
#define FLUID_JOB_BAKE_ALL "FLUID_OT_bake_all"
diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c
index eb154b97eb0..f5b80679689 100644
--- a/source/blender/editors/physics/physics_ops.c
+++ b/source/blender/editors/physics/physics_ops.c
@@ -23,14 +23,9 @@
#include <stdlib.h>
-#include "RNA_access.h"
-
#include "WM_api.h"
-#include "WM_types.h"
-#include "ED_object.h"
#include "ED_physics.h"
-#include "ED_select_utils.h"
#include "physics_intern.h" /* own include */
diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index 1d5903bf417..ea8a4ce2a79 100644
--- a/source/blender/editors/physics/physics_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -34,7 +34,6 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_layer.h"
-#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "DEG_depsgraph.h"
diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c
index 4fd304ea71d..81a8b57776b 100644
--- a/source/blender/editors/physics/rigidbody_object.c
+++ b/source/blender/editors/physics/rigidbody_object.c
@@ -34,9 +34,7 @@
#include "BLT_translation.h"
-#include "BKE_collection.h"
#include "BKE_context.h"
-#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_rigidbody.h"
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 10cf4131584..50ba5907703 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -43,14 +43,10 @@
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
-#include "BKE_blender_undo.h"
-#include "BKE_blender_version.h"
-#include "BKE_camera.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_image.h"
-#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_node.h"
@@ -58,19 +54,15 @@
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BKE_undo_system.h"
#include "DEG_depsgraph.h"
#include "WM_api.h"
#include "WM_types.h"
-#include "ED_object.h"
#include "ED_render.h"
#include "ED_screen.h"
-#include "ED_undo.h"
#include "ED_util.h"
-#include "ED_view3d.h"
#include "BIF_glutil.h"
@@ -85,8 +77,6 @@
#include "SEQ_relations.h"
-#include "BLO_undofile.h"
-
#include "render_intern.h"
/* Render Callbacks */
@@ -1098,7 +1088,7 @@ void RENDER_OT_render(wmOperatorType *ot)
ot->cancel = screen_render_cancel;
ot->exec = screen_render_exec;
- /* this isn't needed, causes failer in background mode */
+ /* This isn't needed, causes failure in background mode. */
#if 0
ot->poll = ED_operator_screenactive;
#endif
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 546156e3406..6744461b2f2 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -363,7 +363,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
}
}
else {
- /* shouldnt suddenly give errors mid-render but possible */
+ /* shouldn't suddenly give errors mid-render but possible */
char err_out[256] = "unknown";
ImBuf *ibuf_view;
const int alpha_mode = (draw_sky) ? R_ADDSKY : R_ALPHAPREMUL;
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 6cf8515bdbb..4e766841c24 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -200,6 +200,11 @@ static bool check_engine_supports_preview(Scene *scene)
return (type->flag & RE_USE_PREVIEW) != 0;
}
+static bool preview_method_is_render(int pr_method)
+{
+ return ELEM(pr_method, PR_ICON_RENDER, PR_BUTS_RENDER, PR_NODE_RENDER);
+}
+
void ED_preview_free_dbase(void)
{
if (G_pr_main) {
@@ -1179,7 +1184,7 @@ static void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect)
return;
}
- /* waste of cpu cyles... but the imbuf API has no other way to scale fast (ton) */
+ /* Waste of cpu cycles... but the imbuf API has no other way to scale fast (ton). */
ima = IMB_dupImBuf(ibuf);
if (!ima) {
@@ -1352,13 +1357,12 @@ static void common_preview_startjob(void *customdata,
*/
static void other_id_types_preview_render(IconPreview *ip,
IconPreviewSize *cur_size,
- const bool is_deferred,
+ const int pr_method,
short *stop,
short *do_update,
float *progress)
{
ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
- const bool is_render = !is_deferred;
/* These types don't use the ShaderPreview mess, they have their own types and functions. */
BLI_assert(!ip->id || !ELEM(GS(ip->id->name), ID_OB));
@@ -1368,7 +1372,7 @@ static void other_id_types_preview_render(IconPreview *ip,
sp->owner = ip->owner;
sp->sizex = cur_size->sizex;
sp->sizey = cur_size->sizey;
- sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED;
+ sp->pr_method = pr_method;
sp->pr_rect = cur_size->rect;
sp->id = ip->id;
sp->id_copy = ip->id_copy;
@@ -1376,7 +1380,7 @@ static void other_id_types_preview_render(IconPreview *ip,
sp->own_id_copy = false;
Material *ma = NULL;
- if (is_render) {
+ if (sp->pr_method == PR_ICON_RENDER) {
BLI_assert(ip->id);
/* grease pencil use its own preview file */
@@ -1424,6 +1428,8 @@ static void icon_preview_startjob_all_sizes(void *customdata,
for (cur_size = ip->sizes.first; cur_size; cur_size = cur_size->next) {
PreviewImage *prv = ip->owner;
+ /* Is this a render job or a deferred loading job? */
+ const int pr_method = (prv->tag & PRV_TAG_DEFFERED) ? PR_ICON_DEFERRED : PR_ICON_RENDER;
if (*stop) {
break;
@@ -1434,7 +1440,7 @@ static void icon_preview_startjob_all_sizes(void *customdata,
continue;
}
- if (!check_engine_supports_preview(ip->scene)) {
+ if (preview_method_is_render(pr_method) && !check_engine_supports_preview(ip->scene)) {
continue;
}
@@ -1450,8 +1456,7 @@ static void icon_preview_startjob_all_sizes(void *customdata,
object_preview_render(ip, cur_size);
}
else {
- other_id_types_preview_render(
- ip, cur_size, (prv->tag & PRV_TAG_DEFFERED), stop, do_update, progress);
+ other_id_types_preview_render(ip, cur_size, pr_method, stop, do_update, progress);
}
}
}
@@ -1634,7 +1639,7 @@ void ED_preview_shader_job(const bContext *C,
/* Use workspace render only for buttons Window,
* since the other previews are related to the datablock. */
- if (!check_engine_supports_preview(scene)) {
+ if (preview_method_is_render(method) && !check_engine_supports_preview(scene)) {
return;
}
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 499ffac6028..4ed1cbd60a5 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -25,7 +25,6 @@
#include "DNA_light_types.h"
#include "DNA_material_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -33,7 +32,6 @@
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
-#include "DNA_workspace_types.h"
#include "DNA_world_types.h"
#include "DRW_engine.h"
@@ -44,13 +42,11 @@
#include "BKE_context.h"
#include "BKE_icons.h"
-#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_paint.h"
#include "BKE_scene.h"
-#include "BKE_workspace.h"
#include "RE_engine.h"
#include "RE_pipeline.h"
@@ -65,8 +61,6 @@
#include "WM_api.h"
-#include "render_intern.h" /* own include */
-
#include <stdio.h>
/***************************** Render Engines ********************************/
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 581169d823e..2c71345699f 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -141,13 +141,15 @@ void ED_region_pixelspace(ARegion *region)
}
/* only exported for WM */
-void ED_region_do_listen(
- wmWindow *win, ScrArea *area, ARegion *region, wmNotifier *note, const Scene *scene)
+void ED_region_do_listen(wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *notifier = params->notifier;
+
/* generic notes first */
- switch (note->category) {
+ switch (notifier->category) {
case NC_WM:
- if (note->data == ND_FILEREAD) {
+ if (notifier->data == ND_FILEREAD) {
ED_region_tag_redraw(region);
}
break;
@@ -157,16 +159,16 @@ void ED_region_do_listen(
}
if (region->type && region->type->listener) {
- region->type->listener(win, area, region, note, scene);
+ region->type->listener(params);
}
}
/* only exported for WM */
-void ED_area_do_listen(wmWindow *win, ScrArea *area, wmNotifier *note, Scene *scene)
+void ED_area_do_listen(wmSpaceTypeListenerParams *params)
{
/* no generic notes? */
- if (area->type && area->type->listener) {
- area->type->listener(win, area, note, scene);
+ if (params->area->type && params->area->type->listener) {
+ params->area->type->listener(params);
}
}
@@ -289,7 +291,15 @@ static void region_draw_azone_tab_arrow(ScrArea *area, ARegion *region, AZone *a
float alpha = WM_region_use_viewport(area, region) ? 0.6f : 0.4f;
const float color[4] = {0.05f, 0.05f, 0.05f, alpha};
UI_draw_roundbox_aa(
- true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, color);
+ &(const rctf){
+ .xmin = (float)az->x1,
+ .xmax = (float)az->x2,
+ .ymin = (float)az->y1,
+ .ymax = (float)az->y2,
+ },
+ true,
+ 4.0f,
+ color);
draw_azone_arrow((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, az->edge);
}
@@ -373,7 +383,16 @@ static void region_draw_status_text(ScrArea *area, ARegion *region)
float color[4] = {0.0f, 0.0f, 0.0f, 0.5f};
UI_GetThemeColor3fv(TH_BACK, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true, x1, y1, x2, y2, 4.0f, color);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = x1,
+ .xmax = x2,
+ .ymin = y1,
+ .ymax = y2,
+ },
+ true,
+ 4.0f,
+ color);
UI_FontThemeColor(fontid, TH_TEXT);
}
@@ -418,16 +437,13 @@ void ED_area_do_msg_notify_tag_refresh(
ED_area_tag_refresh(area);
}
-void ED_area_do_mgs_subscribe_for_tool_header(
- /* Follow ARegionType.message_subscribe */
- const struct bContext *UNUSED(C),
- struct WorkSpace *workspace,
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+/* Follow ARegionType.message_subscribe */
+void ED_area_do_mgs_subscribe_for_tool_header(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ WorkSpace *workspace = params->workspace;
+ ARegion *region = params->region;
+
BLI_assert(region->regiontype == RGN_TYPE_TOOL_HEADER);
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
@@ -438,16 +454,12 @@ void ED_area_do_mgs_subscribe_for_tool_header(
mbus, &workspace->id, workspace, WorkSpace, tools, &msg_sub_value_region_tag_redraw);
}
-void ED_area_do_mgs_subscribe_for_tool_ui(
- /* Follow ARegionType.message_subscribe */
- const struct bContext *UNUSED(C),
- struct WorkSpace *workspace,
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+void ED_area_do_mgs_subscribe_for_tool_ui(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ WorkSpace *workspace = params->workspace;
+ ARegion *region = params->region;
+
BLI_assert(region->regiontype == RGN_TYPE_UI);
const char *panel_category_tool = "Tool";
const char *category = UI_panel_category_active_get(region, false);
@@ -634,7 +646,16 @@ void ED_region_do_draw(bContext *C, ARegion *region)
WM_msg_subscribe_rna(mbus, &ptr, NULL, &msg_sub_value_region_tag_redraw, __func__);
}
- ED_region_message_subscribe(C, workspace, scene, screen, area, region, mbus);
+ wmRegionMessageSubscribeParams message_subscribe_params = {
+ .context = C,
+ .message_bus = mbus,
+ .workspace = workspace,
+ .scene = scene,
+ .screen = screen,
+ .area = area,
+ .region = region,
+ };
+ ED_region_message_subscribe(&message_subscribe_params);
}
}
@@ -4027,14 +4048,12 @@ void ED_region_cache_draw_cached_segments(
/**
* Generate subscriptions for this region.
*/
-void ED_region_message_subscribe(bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+void ED_region_message_subscribe(wmRegionMessageSubscribeParams *params)
{
+ ARegion *region = params->region;
+ const bContext *C = params->context;
+ struct wmMsgBus *mbus = params->message_bus;
+
if (region->gizmo_map != NULL) {
WM_gizmomap_message_subscribe(C, region->gizmo_map, region, mbus);
}
@@ -4044,7 +4063,7 @@ void ED_region_message_subscribe(bContext *C,
}
if (region->type->message_subscribe != NULL) {
- region->type->message_subscribe(C, workspace, scene, screen, area, region, mbus);
+ region->type->message_subscribe(params);
}
}
diff --git a/source/blender/editors/screen/area_utils.c b/source/blender/editors/screen/area_utils.c
index 075759f1120..30553bb7f07 100644
--- a/source/blender/editors/screen/area_utils.c
+++ b/source/blender/editors/screen/area_utils.c
@@ -22,6 +22,8 @@
#include "DNA_userdef_types.h"
+#include "BKE_screen.h"
+
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -32,7 +34,6 @@
#include "ED_screen.h"
-#include "UI_interface.h"
#include "UI_interface_icons.h"
/* -------------------------------------------------------------------- */
@@ -42,14 +43,11 @@
/**
* Callback for #ARegionType.message_subscribe
*/
-void ED_region_generic_tools_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+void ED_region_generic_tools_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 33b918e6d4d..a88afecd064 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -57,11 +57,12 @@ static void immDrawPixelsTexSetupAttributes(IMMDrawPixelsTexState *state)
vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
}
-/* To be used before calling immDrawPixelsTex
- * Default shader is GPU_SHADER_2D_IMAGE_COLOR
- * You can still set uniforms with :
- * GPU_shader_uniform_int(shader, GPU_shader_get_uniform(shader, "name"), 0);
- * */
+/**
+ * To be used before calling #immDrawPixelsTex
+ * Default shader is #GPU_SHADER_2D_IMAGE_COLOR
+ * You can still set uniforms with:
+ * `GPU_shader_uniform_int(shader, GPU_shader_get_uniform(shader, "name"), 0);`
+ */
IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
{
IMMDrawPixelsTexState state;
@@ -77,10 +78,11 @@ IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
return state;
}
-/* Use the currently bound shader.
+/**
+ * Use the currently bound shader.
*
- * Use immDrawPixelsTexSetup to bind the shader you
- * want before calling immDrawPixelsTex.
+ * Use #immDrawPixelsTexSetup to bind the shader you
+ * want before calling #immDrawPixelsTex.
*
* If using a special shader double check it uses the same
* attributes "pos" "texCoord" and uniform "image".
@@ -89,7 +91,7 @@ IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
*
* Be also aware that this function unbinds the shader when
* it's finished.
- * */
+ */
void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float x,
float y,
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 1dfe606be78..627a67358f2 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -866,7 +866,7 @@ static eContextResult screen_ctx_editable_gpencil_strokes(const bContext *C,
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
if (ED_gpencil_stroke_can_use_direct(area, gps)) {
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c
index 6432bdac1b1..1ea64c542f5 100644
--- a/source/blender/editors/screen/screen_draw.c
+++ b/source/blender/editors/screen/screen_draw.c
@@ -478,7 +478,7 @@ void ED_screen_draw_split_preview(ScrArea *area, const int dir, const float fac)
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- /* splitpoint */
+ /* Split-point. */
GPU_blend(GPU_BLEND_ALPHA);
immUniformColor4ub(255, 255, 255, 100);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index be52874ed0b..c25b572d200 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -871,6 +871,11 @@ static void screen_global_area_refresh(wmWindow *win,
const short height_min,
const short height_max)
{
+ /* Full-screens shouldn't have global areas. Don't touch them. */
+ if (screen->state == SCREENFULL) {
+ return;
+ }
+
ScrArea *area = NULL;
LISTBASE_FOREACH (ScrArea *, area_iter, &win->global_areas.areabase) {
if (area_iter->spacetype == space_type) {
@@ -1019,7 +1024,7 @@ void screen_change_update(bContext *C, wmWindow *win, bScreen *screen)
WM_event_add_notifier(C, NC_WINDOW, NULL);
WM_event_add_notifier(C, NC_SCREEN | ND_LAYOUTSET, layout);
- /* makes button hilites work */
+ /* Makes button highlights work. */
WM_event_add_mousemove(win);
}
@@ -1216,7 +1221,7 @@ 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 emtpy
+ * \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.
*/
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index a03e65d8a9d..c51ff559786 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -29,10 +29,10 @@ struct bContextDataResult;
/* internal exports only */
-#define AZONESPOTW UI_HEADER_OFFSET /* width of corner azone - max */
-#define AZONESPOTH (0.6f * U.widget_unit) /* height of corner azone */
-#define AZONEFADEIN (5.0f * U.widget_unit) /* when azone is totally visible */
-#define AZONEFADEOUT (6.5f * U.widget_unit) /* when we start seeing the azone */
+#define AZONESPOTW UI_HEADER_OFFSET /* width of corner #AZone - max */
+#define AZONESPOTH (0.6f * U.widget_unit) /* height of corner #AZone */
+#define AZONEFADEIN (5.0f * U.widget_unit) /* when #AZone is totally visible */
+#define AZONEFADEOUT (6.5f * U.widget_unit) /* when we start seeing the #AZone */
#define AREAJOINTOLERANCE (1.0f * U.widget_unit) /* Edges must be close to allow joining. */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index ca1c75be0a1..244d8c10e4e 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -1637,7 +1637,7 @@ static int area_snap_calc_location(const bScreen *screen,
/* Thirds. */
1.0f / 3.0f,
2.0f / 3.0f,
- /* Quaters. */
+ /* Quarters. */
1.0f / 4.0f,
3.0f / 4.0f,
/* Eighth. */
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 550913fc8af..7eb08cbabac 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -1755,7 +1755,7 @@ static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorCont
else if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_RADIAL &&
brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
/* Display the simulation limits if sculpting outside them. */
- /* This does not makes much sense of plane falloff as the falloff is infinte or global. */
+ /* This does not makes much sense of plane falloff as the falloff is infinite or global. */
if (len_v3v3(ss->cache->true_location, ss->cache->true_initial_location) >
ss->cache->radius * (1.0f + brush->cloth_sim_limit)) {
diff --git a/source/blender/editors/sculpt_paint/paint_curve_undo.c b/source/blender/editors/sculpt_paint/paint_curve_undo.c
index a8e22f66734..dbe522bf304 100644
--- a/source/blender/editors/sculpt_paint/paint_curve_undo.c
+++ b/source/blender/editors/sculpt_paint/paint_curve_undo.c
@@ -126,7 +126,7 @@ static bool paintcurve_undosys_step_encode(struct bContext *C,
static void paintcurve_undosys_step_decode(struct bContext *UNUSED(C),
struct Main *UNUSED(bmain),
UndoStep *us_p,
- int UNUSED(dir),
+ const eUndoStepDir UNUSED(dir),
bool UNUSED(is_final))
{
PaintCurveUndoStep *us = (PaintCurveUndoStep *)us_p;
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 5c15fd05116..f7c0f7718bb 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -138,7 +138,7 @@ BLI_INLINE uchar f_to_char(const float val)
#ifndef PROJ_DEBUG_NOSEAMBLEED
/* projectFaceSeamFlags options */
-//#define PROJ_FACE_IGNORE (1<<0) /* When the face is hidden, backfacing or occluded */
+//#define PROJ_FACE_IGNORE (1<<0) /* When the face is hidden, back-facing or occluded. */
//#define PROJ_FACE_INIT (1<<1) /* When we have initialized the faces data */
/* If this face has a seam on any of its edges. */
@@ -150,7 +150,7 @@ BLI_INLINE uchar f_to_char(const float val)
# define PROJ_FACE_NOSEAM1 (1 << 5)
# define PROJ_FACE_NOSEAM2 (1 << 6)
-/* If the seam is completely initialized, including adjecent seams. */
+/* If the seam is completely initialized, including adjacent seams. */
# define PROJ_FACE_SEAM_INIT0 (1 << 8)
# define PROJ_FACE_SEAM_INIT1 (1 << 9)
# define PROJ_FACE_SEAM_INIT2 (1 << 10)
@@ -294,7 +294,7 @@ typedef struct ProjPaintState {
/** verts projected into floating point screen space. */
float (*screenCoords)[4];
- /** 2D bounds for mesh verts on the screen's plane (screenspace). */
+ /** 2D bounds for mesh verts on the screen's plane (screen-space). */
float screenMin[2];
float screenMax[2];
/** Calculated from screenMin & screenMax. */
@@ -310,10 +310,10 @@ typedef struct ProjPaintState {
bool do_stencil_brush;
bool do_material_slots;
- /** Use raytraced occlusion? - ortherwise will paint right through to the back. */
+ /** Use ray-traced occlusion? - otherwise will paint right through to the back. */
bool do_occlude;
/** ignore faces with normals pointing away,
- * skips a lot of raycasts if your normals are correctly flipped. */
+ * skips a lot of ray-casts if your normals are correctly flipped. */
bool do_backfacecull;
/** mask out pixels based on their normals. */
bool do_mask_normal;
@@ -579,7 +579,7 @@ static Image *project_paint_face_clone_image(const ProjPaintState *ps, int tri_i
/* 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 screenspace 2D coords we could simple do...
+ /* If we were not dealing with screen-space 2D coords we could simple do...
* ps->bucketRect[x + (y*ps->buckets_y)] */
/* please explain?
@@ -887,8 +887,8 @@ static int project_paint_occlude_ptv_clip(const float pt[3],
return -1;
}
-/* Check if a screenspace location is occluded by any other faces
- * check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison
+/* Check if a screen-space location is occluded by any other faces
+ * check, pixelScreenCo must be in screen-space, its Z-Depth only needs to be used for comparison
* and doesn't need to be correct in relation to X and Y coords
* (this is the case in perspective view) */
static bool project_bucket_point_occluded(const ProjPaintState *ps,
@@ -1514,10 +1514,10 @@ static void project_face_seams_init(const ProjPaintState *ps,
}
#endif // PROJ_DEBUG_NOSEAMBLEED
-/* Converts a UV location to a 3D screenspace location
+/* Converts a UV location to a 3D screen-space location
* Takes a 'uv' and 3 UV coords, and sets the values of pixelScreenCo
*
- * This is used for finding a pixels location in screenspace for painting */
+ * This is used for finding a pixels location in screen-space for painting */
static void screen_px_from_ortho(const float uv[2],
const float v1co[3],
const float v2co[3],
@@ -1537,7 +1537,7 @@ static void screen_px_from_ortho(const float uv[2],
static void screen_px_from_persp(const float uv[2],
const float v1co[4],
const float v2co[4],
- const float v3co[4], /* screenspace coords */
+ const float v3co[4], /* screen-space coords */
const float uv1co[2],
const float uv2co[2],
const float uv3co[2],
@@ -1923,7 +1923,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps,
projPixel->newColor.uint = 0;
}
- /* screenspace unclamped, we could keep its z and w values but don't need them at the moment */
+ /* Screen-space unclamped, we could keep its z and w values but don't need them at the moment. */
if (ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
copy_v3_v3(projPixel->worldCoSS, world_spaceCo);
}
@@ -2304,14 +2304,14 @@ static bool project_bucket_isect_circle(const float cent[2],
return false;
}
-/* Note for rect_to_uvspace_ortho() and rect_to_uvspace_persp()
+/* Note for #rect_to_uvspace_ortho() and #rect_to_uvspace_persp()
* in ortho view this function gives good results when bucket_bounds are outside the triangle
* however in some cases, perspective view will mess up with faces
- * that have minimal screenspace area (viewed from the side).
+ * that have minimal screen-space area (viewed from the side).
*
* for this reason its not reliable in this case so we'll use the Simple Barycentric'
- * funcs that only account for points inside the triangle.
- * however switching back to this for ortho is always an option */
+ * functions that only account for points inside the triangle.
+ * however switching back to this for ortho is always an option. */
static void rect_to_uvspace_ortho(const rctf *bucket_bounds,
const float *v1coSS,
@@ -2415,9 +2415,10 @@ static bool IsectPT2Df_limit(
(area_tri_v2(v1, v2, v3))) < limit;
}
-/* Clip the face by a bucket and set the uv-space bucket_bounds_uv
+/**
+ * Clip the face by a bucket and set the uv-space bucket_bounds_uv
* so we have the clipped UV's to do pixel intersection tests with
- * */
+ */
static int float_z_sort_flip(const void *p1, const void *p2)
{
return (((float *)p1)[2] < ((float *)p2)[2] ? 1 : -1);
@@ -2516,8 +2517,8 @@ static void project_bucket_clip_face(const bool is_ortho,
flip = (((line_point_side_v2(v1coSS, v2coSS, v3coSS) > 0.0f) != is_flip_object) !=
(line_point_side_v2(uv1co, uv2co, uv3co) > 0.0f));
- /* all screenspace points are inside the bucket bounding box,
- * this means we don't need to clip and can simply return the UVs */
+ /* All screen-space points are inside the bucket bounding box,
+ * this means we don't need to clip and can simply return the UVs. */
if (flip) { /* facing the back? */
copy_v2_v2(bucket_bounds_uv[0], uv3co);
copy_v2_v2(bucket_bounds_uv[1], uv2co);
@@ -2634,7 +2635,7 @@ static void project_bucket_clip_face(const bool is_ortho,
(line_point_side_v2(uv1co, uv2co, uv3co) > 0.0f));
if (inside_face_flag == ISECT_ALL4) {
- /* bucket is totally inside the screenspace face, we can safely use weights */
+ /* Bucket is totally inside the screen-space face, we can safely use weights. */
if (is_ortho) {
rect_to_uvspace_ortho(
@@ -2655,7 +2656,7 @@ static void project_bucket_clip_face(const bool is_ortho,
* The 2 cases above are where the face is inside the bucket
* or the bucket is inside the face.
*
- * we need to make a convex polyline from the intersection between the screenspace face
+ * we need to make a convex poly-line from the intersection between the screen-space face
* and the bucket bounds.
*
* There are a number of ways this could be done, currently it just collects all
@@ -2996,7 +2997,7 @@ static void project_paint_face_init(const ProjPaintState *ps,
/* vert co screen-space, these will be assigned to lt_vtri[0-2] */
const float *v1coSS, *v2coSS, *v3coSS;
- /* vertex screenspace coords */
+ /* Vertex screen-space coords. */
const float *vCo[3];
float w[3], wco[3];
@@ -3006,9 +3007,9 @@ static void project_paint_face_init(const ProjPaintState *ps,
float pixelScreenCo[4];
bool do_3d_mapping = ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D;
- /* ispace bounds */
+ /* Image-space bounds. */
rcti bounds_px;
- /* vars for getting uvspace bounds */
+ /* Variables for getting UV-space bounds. */
/* bucket bounds in UV space so we can init pixels only for this face, */
float lt_uv_pxoffset[3][2];
@@ -3206,10 +3207,10 @@ static void project_paint_face_init(const ProjPaintState *ps,
/* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in perspective view */
float insetCos[3][3];
- /* vertex screenspace coords */
+ /* Vertex screen-space coords. */
const float *vCoSS[3];
- /* Store the screenspace coords of the face,
+ /* Store the screen-space coords of the face,
* clipped by the bucket's screen aligned rectangle. */
float bucket_clip_edges[2][2];
float edge_verts_inset_clip[2][3];
@@ -3418,7 +3419,7 @@ static void project_paint_face_init(const ProjPaintState *ps,
}
/**
- * Takes floating point screenspace min/max and
+ * Takes floating point screen-space min/max and
* returns int min/max to be used as indices for ps->bucketRect, ps->bucketFlags
*/
static void project_paint_bucket_bounds(const ProjPaintState *ps,
@@ -3887,7 +3888,7 @@ static void proj_paint_state_cavity_init(ProjPaintState *ps)
float no[3];
mul_v3_fl(edges[a], 1.0f / counter[a]);
normal_short_to_float_v3(no, mv->no);
- /* augment the diffe*/
+ /* Augment the difference. */
cavities[a] = saacos(10.0f * dot_v3v3(no, edges[a])) * (float)M_1_PI;
}
else {
@@ -4307,7 +4308,7 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
slot_last = slot;
}
- /* don't allow using the same inage for painting and stencilling */
+ /* Don't allow using the same image for painting and stenciling. */
if (slot->ima == ps->stencil_ima) {
/* Delay continuing the loop until after loop_uvs and bleed faces are initialized.
* While this shouldn't be used, face-winding reads all polys.
@@ -4337,7 +4338,6 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
continue;
}
- /* tfbase here should be non-null! */
BLI_assert(mloopuv_base != NULL);
if (is_face_sel && tpage) {
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index bacb3b549e3..26e2bcc42cf 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -1073,8 +1073,6 @@ static void sculpt_gesture_trim_calculate_depth(SculptGestureContext *sgcontext)
mid_point_depth = ss->gesture_initial_hit ?
0.0f :
(trim_operation->depth_back + trim_operation->depth_front) * 0.5f;
-
-
}
const float depth_radius = ss->cursor_radius;
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 8eb2ebd0f19..8fd5759d695 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
@@ -168,8 +168,11 @@ void PAINT_OT_weight_from_bones(wmOperatorType *ot)
/** \name Sample Weight Operator
* \{ */
-/* sets wp->weight to the closest weight value to vertex */
-/* note: we cant sample frontbuf, weight colors are interpolated too unpredictable */
+/**
+ * Sets wp->weight to the closest weight value to vertex.
+ *
+ * \note we can't sample front-buffer, weight colors are interpolated too unpredictable.
+ */
static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@@ -201,7 +204,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even
}
else if (ED_mesh_pick_face(
C, vc.obact, event->mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) {
- /* this relies on knowning the internal worksings of ED_mesh_pick_face_vert() */
+ /* This relies on knowing the internal workings of #ED_mesh_pick_face_vert() */
BKE_report(
op->reports, RPT_WARNING, "The modifier used does not support deformed locations");
}
@@ -604,7 +607,7 @@ static void gradientVert_update(WPGradient_userData *grad_data, int index)
Mesh *me = grad_data->me;
WPGradient_vertStore *vs = &grad_data->vert_cache->elem[index];
- /* Optionally restrict to assigned verices only. */
+ /* Optionally restrict to assigned vertices only. */
if (grad_data->use_vgroup_restrict && ((vs->flag & VGRAD_STORE_DW_EXIST) == 0)) {
return;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index cb5d708908b..d1028e5f542 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -391,13 +391,14 @@ void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visibl
case PBVH_FACES:
case PBVH_GRIDS:
for (int i = 0; i < ss->totfaces; i++) {
- if (abs(ss->face_sets[i]) == face_set) {
- if (visible) {
- ss->face_sets[i] = abs(ss->face_sets[i]);
- }
- else {
- ss->face_sets[i] = -abs(ss->face_sets[i]);
- }
+ if (abs(ss->face_sets[i]) != face_set) {
+ continue;
+ }
+ if (visible) {
+ ss->face_sets[i] = abs(ss->face_sets[i]);
+ }
+ else {
+ ss->face_sets[i] = -abs(ss->face_sets[i]);
}
}
break;
@@ -1057,12 +1058,13 @@ bool SCULPT_is_vertex_inside_brush_radius_symm(const float vertex[3],
char symm)
{
for (char i = 0; i <= symm; ++i) {
- if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
- float location[3];
- flip_v3_v3(location, br_co, (char)i);
- if (len_squared_v3v3(location, vertex) < radius * radius) {
- return true;
- }
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
+ }
+ float location[3];
+ flip_v3_v3(location, br_co, (char)i);
+ if (len_squared_v3v3(location, vertex) < radius * radius) {
+ return true;
}
}
return false;
@@ -1107,20 +1109,22 @@ void SCULPT_floodfill_add_initial_with_symmetry(
/* Add active vertex and symmetric vertices to the queue. */
const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
for (char i = 0; i <= symm; ++i) {
- if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
- int v = -1;
- if (i == 0) {
- v = index;
- }
- else if (radius > 0.0f) {
- float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
- float location[3];
- flip_v3_v3(location, SCULPT_vertex_co_get(ss, index), i);
- v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
- }
- if (v != -1) {
- SCULPT_floodfill_add_initial(flood, v);
- }
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
+ }
+ int v = -1;
+ if (i == 0) {
+ v = index;
+ }
+ else if (radius > 0.0f) {
+ float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
+ float location[3];
+ flip_v3_v3(location, SCULPT_vertex_co_get(ss, index), i);
+ v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
+ }
+
+ if (v != -1) {
+ SCULPT_floodfill_add_initial(flood, v);
}
}
}
@@ -1131,20 +1135,22 @@ void SCULPT_floodfill_add_active(
/* Add active vertex and symmetric vertices to the queue. */
const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
for (char i = 0; i <= symm; ++i) {
- if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
- int v = -1;
- if (i == 0) {
- 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);
- }
- if (v != -1) {
- SCULPT_floodfill_add_initial(flood, v);
- }
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
+ }
+ int v = -1;
+ if (i == 0) {
+ 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);
+ }
+
+ if (v != -1) {
+ SCULPT_floodfill_add_initial(flood, v);
}
}
}
@@ -1161,12 +1167,19 @@ void SCULPT_floodfill_execute(
SculptVertexNeighborIter ni;
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
const int to_v = ni.index;
- if (!BLI_BITMAP_TEST(flood->visited_vertices, to_v) && SCULPT_vertex_visible_get(ss, to_v)) {
- BLI_BITMAP_ENABLE(flood->visited_vertices, to_v);
- if (func(ss, from_v, to_v, ni.is_duplicate, userdata)) {
- BLI_gsqueue_push(flood->queue, &to_v);
- }
+ if (BLI_BITMAP_TEST(flood->visited_vertices, to_v)) {
+ continue;
+ }
+
+ if (!SCULPT_vertex_visible_get(ss, to_v)) {
+ continue;
+ }
+
+ BLI_BITMAP_ENABLE(flood->visited_vertices, to_v);
+
+ if (func(ss, from_v, to_v, ni.is_duplicate, userdata)) {
+ BLI_gsqueue_push(flood->queue, &to_v);
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
@@ -1466,40 +1479,42 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
unode = SCULPT_undo_get_node(data->nodes[n]);
}
- if (unode) {
- PBVHVertexIter vd;
- SculptOrigVertData orig_data;
+ if (!unode) {
+ return;
+ }
- SCULPT_orig_vert_data_unode_init(&orig_data, data->ob, unode);
+ PBVHVertexIter vd;
+ SculptOrigVertData orig_data;
- BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
- {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_unode_init(&orig_data, data->ob, unode);
- if (orig_data.unode->type == SCULPT_UNDO_COORDS) {
- copy_v3_v3(vd.co, orig_data.co);
- if (vd.no) {
- copy_v3_v3_short(vd.no, orig_data.no);
- }
- else {
- normal_short_to_float_v3(vd.fno, orig_data.no);
- }
- }
- else if (orig_data.unode->type == SCULPT_UNDO_MASK) {
- *vd.mask = orig_data.mask;
- }
- else if (orig_data.unode->type == SCULPT_UNDO_COLOR) {
- copy_v4_v4(vd.col, orig_data.col);
- }
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ if (orig_data.unode->type == SCULPT_UNDO_COORDS) {
+ copy_v3_v3(vd.co, orig_data.co);
+ if (vd.no) {
+ copy_v3_v3_short(vd.no, orig_data.no);
+ }
+ else {
+ normal_short_to_float_v3(vd.fno, orig_data.no);
}
}
- BKE_pbvh_vertex_iter_end;
+ else if (orig_data.unode->type == SCULPT_UNDO_MASK) {
+ *vd.mask = orig_data.mask;
+ }
+ else if (orig_data.unode->type == SCULPT_UNDO_COLOR) {
+ copy_v4_v4(vd.col, orig_data.col);
+ }
- BKE_pbvh_node_mark_update(data->nodes[n]);
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
}
+ BKE_pbvh_vertex_iter_end;
+
+ BKE_pbvh_node_mark_update(data->nodes[n]);
}
static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
@@ -1545,11 +1560,15 @@ static void sculpt_extend_redraw_rect_previous(Object *ob, rcti *rect)
* mesh parts could disappear from screen (sergey). */
SculptSession *ss = ob->sculpt;
- if (ss->cache) {
- if (!BLI_rcti_is_empty(&ss->cache->previous_r)) {
- BLI_rcti_union(rect, &ss->cache->previous_r);
- }
+ if (!ss->cache) {
+ return;
+ }
+
+ if (BLI_rcti_is_empty(&ss->cache->previous_r)) {
+ return;
}
+
+ BLI_rcti_union(rect, &ss->cache->previous_r);
}
/* Get a screen-space rectangle of the modified area. */
@@ -1651,28 +1670,30 @@ bool SCULPT_brush_test_sphere(SculptBrushTest *test, const float co[3])
{
float distsq = len_squared_v3v3(co, test->location);
- if (distsq <= test->radius_squared) {
- if (sculpt_brush_test_clipping(test, co)) {
- return false;
- }
- test->dist = sqrtf(distsq);
- return true;
+ if (distsq > test->radius_squared) {
+ return false;
}
- return false;
+
+ if (sculpt_brush_test_clipping(test, co)) {
+ return false;
+ }
+
+ test->dist = sqrtf(distsq);
+ return true;
}
bool SCULPT_brush_test_sphere_sq(SculptBrushTest *test, const float co[3])
{
float distsq = len_squared_v3v3(co, test->location);
- if (distsq <= test->radius_squared) {
- if (sculpt_brush_test_clipping(test, co)) {
- return false;
- }
- test->dist = distsq;
- return true;
+ if (distsq > test->radius_squared) {
+ return false;
}
- return false;
+ if (sculpt_brush_test_clipping(test, co)) {
+ return false;
+ }
+ test->dist = distsq;
+ return true;
}
bool SCULPT_brush_test_sphere_fast(const SculptBrushTest *test, const float co[3])
@@ -1689,14 +1710,16 @@ bool SCULPT_brush_test_circle_sq(SculptBrushTest *test, const float co[3])
closest_to_plane_normalized_v3(co_proj, test->plane_view, co);
float distsq = len_squared_v3v3(co_proj, test->location);
- if (distsq <= test->radius_squared) {
- if (sculpt_brush_test_clipping(test, co)) {
- return false;
- }
- test->dist = distsq;
- return true;
+ if (distsq > test->radius_squared) {
+ return false;
}
- return false;
+
+ if (sculpt_brush_test_clipping(test, co)) {
+ return false;
+ }
+
+ test->dist = distsq;
+ return true;
}
bool SCULPT_brush_test_cube(SculptBrushTest *test,
@@ -1724,25 +1747,26 @@ bool SCULPT_brush_test_cube(SculptBrushTest *test,
const float constant_side = hardness * side;
const float falloff_side = roundness * side;
- if (local_co[0] <= side && local_co[1] <= side && local_co[2] <= side) {
+ if (!(local_co[0] <= side && local_co[1] <= side && local_co[2] <= side)) {
+ /* Outside the square. */
+ return false;
+ }
+ if (min_ff(local_co[0], local_co[1]) > constant_side) {
/* Corner, distance to the center of the corner circle. */
- if (min_ff(local_co[0], local_co[1]) > constant_side) {
- float r_point[3];
- copy_v3_fl(r_point, constant_side);
- test->dist = len_v2v2(r_point, local_co) / falloff_side;
- return true;
- }
+ float r_point[3];
+ copy_v3_fl(r_point, constant_side);
+ test->dist = len_v2v2(r_point, local_co) / falloff_side;
+ return true;
+ }
+ if (max_ff(local_co[0], local_co[1]) > constant_side) {
/* Side, distance to the square XY axis. */
- if (max_ff(local_co[0], local_co[1]) > constant_side) {
- test->dist = (max_ff(local_co[0], local_co[1]) - constant_side) / falloff_side;
- return true;
- }
- /* Inside the square, constant distance. */
- test->dist = 0.0f;
+ test->dist = (max_ff(local_co[0], local_co[1]) - constant_side) / falloff_side;
return true;
}
- /* Outside the square. */
- return false;
+
+ /* Inside the square, constant distance. */
+ test->dist = 0.0f;
+ return true;
}
SculptBrushTestFn SCULPT_brush_test_init_with_falloff_shape(SculptSession *ss,
@@ -1777,21 +1801,21 @@ static float frontface(const Brush *br,
const short no[3],
const float fno[3])
{
- if (br->flag & BRUSH_FRONTFACE) {
- float dot;
+ if (!(br->flag & BRUSH_FRONTFACE)) {
+ return 1.0f;
+ }
- if (no) {
- float tmp[3];
+ float dot;
+ if (no) {
+ float tmp[3];
- normal_short_to_float_v3(tmp, no);
- dot = dot_v3v3(tmp, sculpt_normal);
- }
- else {
- dot = dot_v3v3(fno, sculpt_normal);
- }
- return dot > 0.0f ? dot : 0.0f;
+ normal_short_to_float_v3(tmp, no);
+ dot = dot_v3v3(tmp, sculpt_normal);
+ }
+ else {
+ dot = dot_v3v3(fno, sculpt_normal);
}
- return 1.0f;
+ return dot > 0.0f ? dot : 0.0f;
}
#if 0
@@ -1871,25 +1895,25 @@ static float calc_radial_symmetry_feather(Sculpt *sd,
static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache)
{
- if (sd->paint.symmetry_flags & PAINT_SYMMETRY_FEATHER) {
- float overlap;
- const int symm = cache->symmetry;
-
- overlap = 0.0f;
- for (int i = 0; i <= symm; i++) {
- if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
-
- overlap += calc_overlap(cache, i, 0, 0);
+ if (!(sd->paint.symmetry_flags & PAINT_SYMMETRY_FEATHER)) {
+ return 1.0f;
+ }
+ float overlap;
+ const int symm = cache->symmetry;
- overlap += calc_radial_symmetry_feather(sd, cache, i, 'X');
- overlap += calc_radial_symmetry_feather(sd, cache, i, 'Y');
- overlap += calc_radial_symmetry_feather(sd, cache, i, 'Z');
- }
+ overlap = 0.0f;
+ for (int i = 0; i <= symm; i++) {
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
}
- return 1.0f / overlap;
+ overlap += calc_overlap(cache, i, 0, 0);
+
+ overlap += calc_radial_symmetry_feather(sd, cache, i, 'X');
+ overlap += calc_radial_symmetry_feather(sd, cache, i, 'Y');
+ overlap += calc_radial_symmetry_feather(sd, cache, i, 'Z');
}
- return 1.0f;
+ return 1.0f / overlap;
}
/* -------------------------------------------------------------------- */
@@ -1991,35 +2015,37 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
normal_test_r = sculpt_brush_normal_test_sq_fn(&normal_test, co);
area_test_r = sculpt_brush_area_test_sq_fn(&area_test, co);
- if (normal_test_r || area_test_r) {
- float no[3];
- int flip_index;
+ if (!normal_test_r && !area_test_r) {
+ continue;
+ }
- normal_tri_v3(no, UNPACK3(co_tri));
+ float no[3];
+ int flip_index;
- flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f);
- if (use_area_cos && area_test_r) {
- /* Weight the coordinates towards the center. */
- float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
- const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
+ normal_tri_v3(no, UNPACK3(co_tri));
- float disp[3];
- sub_v3_v3v3(disp, co, area_test.location);
- mul_v3_fl(disp, 1.0f - afactor);
- add_v3_v3v3(co, area_test.location, disp);
- add_v3_v3(anctd->area_cos[flip_index], co);
+ flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f);
+ if (use_area_cos && area_test_r) {
+ /* Weight the coordinates towards the center. */
+ float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
+ const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
- anctd->count_co[flip_index] += 1;
- }
- if (use_area_nos && normal_test_r) {
- /* Weight the normals towards the center. */
- float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
- const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
- mul_v3_fl(no, nfactor);
-
- add_v3_v3(anctd->area_nos[flip_index], no);
- anctd->count_no[flip_index] += 1;
- }
+ float disp[3];
+ sub_v3_v3v3(disp, co, area_test.location);
+ mul_v3_fl(disp, 1.0f - afactor);
+ add_v3_v3v3(co, area_test.location, disp);
+ add_v3_v3(anctd->area_cos[flip_index], co);
+
+ anctd->count_co[flip_index] += 1;
+ }
+ if (use_area_nos && normal_test_r) {
+ /* Weight the normals towards the center. */
+ float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
+ const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
+ mul_v3_fl(no, nfactor);
+
+ add_v3_v3(anctd->area_nos[flip_index], no);
+ anctd->count_no[flip_index] += 1;
}
}
}
@@ -2051,49 +2077,51 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
normal_test_r = sculpt_brush_normal_test_sq_fn(&normal_test, co);
area_test_r = sculpt_brush_area_test_sq_fn(&area_test, co);
- if (normal_test_r || area_test_r) {
- float no[3];
- int flip_index;
+ if (!normal_test_r && !area_test_r) {
+ continue;
+ }
+
+ float no[3];
+ int flip_index;
- data->any_vertex_sampled = true;
+ data->any_vertex_sampled = true;
- if (use_original) {
- normal_short_to_float_v3(no, no_s);
+ if (use_original) {
+ normal_short_to_float_v3(no, no_s);
+ }
+ else {
+ if (vd.no) {
+ normal_short_to_float_v3(no, vd.no);
}
else {
- if (vd.no) {
- normal_short_to_float_v3(no, vd.no);
- }
- else {
- copy_v3_v3(no, vd.fno);
- }
+ copy_v3_v3(no, vd.fno);
}
+ }
- flip_index = (dot_v3v3(ss->cache ? ss->cache->view_normal : ss->cursor_view_normal, no) <=
- 0.0f);
+ flip_index = (dot_v3v3(ss->cache ? ss->cache->view_normal : ss->cursor_view_normal, no) <=
+ 0.0f);
- if (use_area_cos && area_test_r) {
- /* Weight the coordinates towards the center. */
- float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
- const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
+ if (use_area_cos && area_test_r) {
+ /* Weight the coordinates towards the center. */
+ float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
+ const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
- float disp[3];
- sub_v3_v3v3(disp, co, area_test.location);
- mul_v3_fl(disp, 1.0f - afactor);
- add_v3_v3v3(co, area_test.location, disp);
+ float disp[3];
+ sub_v3_v3v3(disp, co, area_test.location);
+ mul_v3_fl(disp, 1.0f - afactor);
+ add_v3_v3v3(co, area_test.location, disp);
- add_v3_v3(anctd->area_cos[flip_index], co);
- anctd->count_co[flip_index] += 1;
- }
- if (use_area_nos && normal_test_r) {
- /* Weight the normals towards the center. */
- float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
- const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
- mul_v3_fl(no, nfactor);
-
- add_v3_v3(anctd->area_nos[flip_index], no);
- anctd->count_no[flip_index] += 1;
- }
+ add_v3_v3(anctd->area_cos[flip_index], co);
+ anctd->count_co[flip_index] += 1;
+ }
+ if (use_area_nos && normal_test_r) {
+ /* Weight the normals towards the center. */
+ float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
+ const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
+ mul_v3_fl(no, nfactor);
+
+ add_v3_v3(anctd->area_nos[flip_index], no);
+ anctd->count_no[flip_index] += 1;
}
}
BKE_pbvh_vertex_iter_end;
@@ -2150,10 +2178,12 @@ static void calc_area_center(
/* For flatten center. */
for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) {
- if (anctd.count_co[n] != 0) {
- mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
- break;
+ if (anctd.count_co[n] == 0) {
+ continue;
}
+
+ mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
+ break;
}
if (n == 2) {
@@ -2249,10 +2279,12 @@ static void calc_area_normal_and_center(
/* For flatten center. */
for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) {
- if (anctd.count_co[n] != 0) {
- mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
- break;
+ if (anctd.count_co[n] == 0) {
+ continue;
}
+
+ mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
+ break;
}
if (n == 2) {
@@ -2892,26 +2924,27 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade =
- bstrength *
- SCULPT_brush_strength_factor(
- ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, *vd.mask, vd.index, thread_id) *
- ss->cache->pressure;
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade =
+ bstrength *
+ SCULPT_brush_strength_factor(
+ ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, *vd.mask, vd.index, thread_id) *
+ ss->cache->pressure;
- float avg[3], val[3];
+ float avg[3], val[3];
- SCULPT_bmesh_four_neighbor_average(avg, direction, vd.bm_vert);
+ SCULPT_bmesh_four_neighbor_average(avg, direction, vd.bm_vert);
- sub_v3_v3v3(val, avg, vd.co);
+ sub_v3_v3v3(val, avg, vd.co);
- madd_v3_v3v3fl(val, vd.co, val, fade);
+ madd_v3_v3v3fl(val, vd.co, val, fade);
- SCULPT_clip(sd, ss, vd.co, val);
+ SCULPT_clip(sd, ss, vd.co, val);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -2964,21 +2997,23 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = SCULPT_brush_strength_factor(
- ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.index, thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
- if (bstrength > 0.0f) {
- (*vd.mask) += fade * bstrength * (1.0f - *vd.mask);
- }
- else {
- (*vd.mask) += fade * bstrength * (*vd.mask);
- }
- *vd.mask = clamp_f(*vd.mask, 0.0f, 1.0f);
+ const float fade = SCULPT_brush_strength_factor(
+ ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.index, thread_id);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (bstrength > 0.0f) {
+ (*vd.mask) += fade * bstrength * (1.0f - *vd.mask);
+ }
+ else {
+ (*vd.mask) += fade * bstrength * (*vd.mask);
+ }
+ *vd.mask = clamp_f(*vd.mask, 0.0f, 1.0f);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
BKE_pbvh_vertex_iter_end;
}
@@ -3039,26 +3074,27 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata,
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- float limit_co[3];
- float disp[3];
- SCULPT_vertex_limit_surface_get(ss, vd.index, limit_co);
- sub_v3_v3v3(disp, limit_co, vd.co);
- mul_v3_v3fl(proxy[vd.i], disp, fade);
+ float limit_co[3];
+ float disp[3];
+ SCULPT_vertex_limit_surface_get(ss, vd.index, limit_co);
+ sub_v3_v3v3(disp, limit_co, vd.co);
+ mul_v3_v3fl(proxy[vd.i], disp, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3151,12 +3187,15 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata,
ss->cache->limit_surface_co[vd.index]);
const float *neighbor_limit_surface_disp = ss->cache->prev_displacement[ni.index];
normalize_v3_v3(vertex_disp_norm, vertex_disp);
- if (dot_v3v3(current_disp_norm, vertex_disp_norm) < 0.0f) {
- const float disp_interp = clamp_f(
- -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
- madd_v3_v3fl(interp_limit_surface_disp, neighbor_limit_surface_disp, disp_interp);
- weights_accum += disp_interp;
+
+ if (dot_v3v3(current_disp_norm, vertex_disp_norm) >= 0.0f) {
+ continue;
}
+
+ const float disp_interp = clamp_f(
+ -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
+ madd_v3_v3fl(interp_limit_surface_disp, neighbor_limit_surface_disp, disp_interp);
+ weights_accum += disp_interp;
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
@@ -3246,23 +3285,24 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- /* Offset vertex. */
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ /* Offset vertex. */
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], offset, fade);
+ mul_v3_v3fl(proxy[vd.i], offset, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3325,23 +3365,24 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- /* Offset vertex. */
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- orig_data.co,
- sqrtf(test.dist),
- orig_data.no,
- NULL,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ /* Offset vertex. */
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ orig_data.co,
+ sqrtf(test.dist),
+ orig_data.no,
+ NULL,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], offset, fade);
+ mul_v3_v3fl(proxy[vd.i], offset, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3407,52 +3448,53 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- orig_data.co,
- sqrtf(test.dist),
- orig_data.no,
- NULL,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- float current_disp[3];
- float current_disp_norm[3];
- float final_disp[3] = {0.0f, 0.0f, 0.0f};
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ orig_data.co,
+ sqrtf(test.dist),
+ orig_data.no,
+ NULL,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ float current_disp[3];
+ float current_disp_norm[3];
+ float final_disp[3] = {0.0f, 0.0f, 0.0f};
- switch (brush->slide_deform_type) {
- case BRUSH_SLIDE_DEFORM_DRAG:
- sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
- break;
- case BRUSH_SLIDE_DEFORM_PINCH:
- sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
- break;
- case BRUSH_SLIDE_DEFORM_EXPAND:
- sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
- break;
- }
+ switch (brush->slide_deform_type) {
+ case BRUSH_SLIDE_DEFORM_DRAG:
+ sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
+ break;
+ case BRUSH_SLIDE_DEFORM_PINCH:
+ sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
+ break;
+ case BRUSH_SLIDE_DEFORM_EXPAND:
+ sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
+ break;
+ }
- normalize_v3_v3(current_disp_norm, current_disp);
- mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
-
- SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
- float vertex_disp[3];
- float vertex_disp_norm[3];
- sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
- normalize_v3_v3(vertex_disp_norm, vertex_disp);
- if (dot_v3v3(current_disp_norm, vertex_disp_norm) > 0.0f) {
- madd_v3_v3fl(final_disp, vertex_disp_norm, dot_v3v3(current_disp, vertex_disp));
- }
+ normalize_v3_v3(current_disp_norm, current_disp);
+ mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
+ float vertex_disp[3];
+ float vertex_disp_norm[3];
+ sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
+ normalize_v3_v3(vertex_disp_norm, vertex_disp);
+ if (dot_v3v3(current_disp_norm, vertex_disp_norm) > 0.0f) {
+ madd_v3_v3fl(final_disp, vertex_disp_norm, dot_v3v3(current_disp, vertex_disp));
}
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
- mul_v3_v3fl(proxy[vd.i], final_disp, fade);
+ mul_v3_v3fl(proxy[vd.i], final_disp, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3482,16 +3524,17 @@ void SCULPT_relax_vertex(SculptSession *ss,
/* When the vertex to relax is boundary, use only connected boundary vertices for the average
* position. */
if (is_boundary) {
- if (SCULPT_vertex_is_boundary(ss, ni.index)) {
- add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
- avg_count++;
-
- /* Calculate a normal for the constraint plane using the edges of the boundary. */
- float to_neighbor[3];
- sub_v3_v3v3(to_neighbor, SCULPT_vertex_co_get(ss, ni.index), vd->co);
- normalize_v3(to_neighbor);
- add_v3_v3(boundary_normal, to_neighbor);
+ if (!SCULPT_vertex_is_boundary(ss, ni.index)) {
+ continue;
}
+ add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
+ avg_count++;
+
+ /* Calculate a normal for the constraint plane using the edges of the boundary. */
+ float to_neighbor[3];
+ sub_v3_v3v3(to_neighbor, SCULPT_vertex_co_get(ss, ni.index), vd->co);
+ normalize_v3(to_neighbor);
+ add_v3_v3(boundary_normal, to_neighbor);
}
else {
add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
@@ -3563,21 +3606,22 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- orig_data.co,
- sqrtf(test.dist),
- orig_data.no,
- NULL,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ orig_data.co,
+ sqrtf(test.dist),
+ orig_data.no,
+ NULL,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co);
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3728,38 +3772,39 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- /* Offset vertex. */
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- float val1[3];
- float val2[3];
-
- /* First we pinch. */
- sub_v3_v3v3(val1, test.location, vd.co);
- if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
- project_plane_v3_v3v3(val1, val1, ss->cache->view_normal);
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ /* Offset vertex. */
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ float val1[3];
+ float val2[3];
+
+ /* First we pinch. */
+ sub_v3_v3v3(val1, test.location, vd.co);
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ project_plane_v3_v3v3(val1, val1, ss->cache->view_normal);
+ }
- mul_v3_fl(val1, fade * flippedbstrength);
+ mul_v3_fl(val1, fade * flippedbstrength);
- sculpt_project_v3(spvc, val1, val1);
+ sculpt_project_v3(spvc, val1, val1);
- /* Then we draw. */
- mul_v3_v3fl(val2, offset, fade);
+ /* Then we draw. */
+ mul_v3_v3fl(val2, offset, fade);
- add_v3_v3v3(proxy[vd.i], val1, val2);
+ add_v3_v3v3(proxy[vd.i], val1, val2);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3845,40 +3890,41 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- float disp_center[3];
- float x_disp[3];
- float z_disp[3];
- /* Calculate displacement from the vertex to the brush center. */
- sub_v3_v3v3(disp_center, test.location, vd.co);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ float disp_center[3];
+ float x_disp[3];
+ float z_disp[3];
+ /* Calculate displacement from the vertex to the brush center. */
+ sub_v3_v3v3(disp_center, test.location, vd.co);
- /* Project the displacement into the X vector (aligned to the stroke). */
- mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
+ /* Project the displacement into the X vector (aligned to the stroke). */
+ mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
- /* Project the displacement into the Z vector (aligned to the surface normal). */
- mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
+ /* Project the displacement into the Z vector (aligned to the surface normal). */
+ mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
- /* Add the two projected vectors to calculate the final displacement.
- * The Y component is removed. */
- add_v3_v3v3(disp_center, x_disp, z_disp);
+ /* Add the two projected vectors to calculate the final displacement.
+ * The Y component is removed. */
+ add_v3_v3v3(disp_center, x_disp, z_disp);
- if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
- project_plane_v3_v3v3(disp_center, disp_center, ss->cache->view_normal);
- }
- mul_v3_v3fl(proxy[vd.i], disp_center, fade);
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ project_plane_v3_v3v3(disp_center, disp_center, ss->cache->view_normal);
+ }
+ mul_v3_v3fl(proxy[vd.i], disp_center, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -3961,33 +4007,34 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata,
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- orig_data.co,
- sqrtf(test.dist),
- orig_data.no,
- NULL,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- if (grab_silhouette) {
- float silhouette_test_dir[3];
- normalize_v3_v3(silhouette_test_dir, grab_delta);
- if (dot_v3v3(ss->cache->initial_normal, ss->cache->grab_delta_symmetry) < 0.0f) {
- mul_v3_fl(silhouette_test_dir, -1.0f);
- }
- float vno[3];
- normal_short_to_float_v3(vno, orig_data.no);
- fade *= max_ff(dot_v3v3(vno, silhouette_test_dir), 0.0f);
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ orig_data.co,
+ sqrtf(test.dist),
+ orig_data.no,
+ NULL,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ if (grab_silhouette) {
+ float silhouette_test_dir[3];
+ normalize_v3_v3(silhouette_test_dir, grab_delta);
+ if (dot_v3v3(ss->cache->initial_normal, ss->cache->grab_delta_symmetry) < 0.0f) {
+ mul_v3_fl(silhouette_test_dir, -1.0f);
}
+ float vno[3];
+ normal_short_to_float_v3(vno, orig_data.no);
+ fade *= max_ff(dot_v3v3(vno, silhouette_test_dir), 0.0f);
+ }
- mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
+ mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4149,13 +4196,14 @@ void SCULPT_flip_v3_by_symm_area(float v[3],
{
for (int i = 0; i < 3; i++) {
ePaintSymmetryFlags symm_it = 1 << i;
- if (symm & symm_it) {
- if (symmarea & symm_it) {
- flip_v3(v, symm_it);
- }
- if (pivot[i] < 0.0f) {
- flip_v3(v, symm_it);
- }
+ if (!(symm & symm_it)) {
+ continue;
+ }
+ if (symmarea & symm_it) {
+ flip_v3(v, symm_it);
+ }
+ if (pivot[i] < 0.0f) {
+ flip_v3(v, symm_it);
}
}
}
@@ -4167,13 +4215,14 @@ void SCULPT_flip_quat_by_symm_area(float quat[3],
{
for (int i = 0; i < 3; i++) {
ePaintSymmetryFlags symm_it = 1 << i;
- if (symm & symm_it) {
- if (symmarea & symm_it) {
- flip_qt(quat, symm_it);
- }
- if (pivot[i] < 0.0f) {
- flip_qt(quat, symm_it);
- }
+ if (!(symm & symm_it)) {
+ continue;
+ }
+ if (symmarea & symm_it) {
+ flip_qt(quat, symm_it);
+ }
+ if (pivot[i] < 0.0f) {
+ flip_qt(quat, symm_it);
}
}
}
@@ -4289,22 +4338,23 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], cono, fade);
+ mul_v3_v3fl(proxy[vd.i], cono, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4368,75 +4418,76 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (do_elastic || sculpt_brush_test_sq_fn(&test, vd.co)) {
+ if (!do_elastic && !sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
- float fade;
- if (do_elastic) {
- fade = 1.0f;
- }
- else {
- fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- }
+ float fade;
+ if (do_elastic) {
+ fade = 1.0f;
+ }
+ else {
+ fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ }
- mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
+ mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
- /* Negative pinch will inflate, helps maintain volume. */
- if (do_pinch) {
- float delta_pinch_init[3], delta_pinch[3];
+ /* Negative pinch will inflate, helps maintain volume. */
+ if (do_pinch) {
+ float delta_pinch_init[3], delta_pinch[3];
- sub_v3_v3v3(delta_pinch, vd.co, test.location);
- if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
- project_plane_v3_v3v3(delta_pinch, delta_pinch, ss->cache->true_view_normal);
- }
+ sub_v3_v3v3(delta_pinch, vd.co, test.location);
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ project_plane_v3_v3v3(delta_pinch, delta_pinch, ss->cache->true_view_normal);
+ }
- /* Important to calculate based on the grabbed location
- * (intentionally ignore fade here). */
- add_v3_v3(delta_pinch, grab_delta);
+ /* Important to calculate based on the grabbed location
+ * (intentionally ignore fade here). */
+ add_v3_v3(delta_pinch, grab_delta);
- sculpt_project_v3(spvc, delta_pinch, delta_pinch);
+ sculpt_project_v3(spvc, delta_pinch, delta_pinch);
- copy_v3_v3(delta_pinch_init, delta_pinch);
+ copy_v3_v3(delta_pinch_init, delta_pinch);
- float pinch_fade = pinch * fade;
- /* When reducing, scale reduction back by how close to the center we are,
- * so we don't pinch into nothingness. */
- if (pinch > 0.0f) {
- /* Square to have even less impact for close vertices. */
- pinch_fade *= pow2f(min_ff(1.0f, len_v3(delta_pinch) / ss->cache->radius));
- }
- mul_v3_fl(delta_pinch, 1.0f + pinch_fade);
- sub_v3_v3v3(delta_pinch, delta_pinch_init, delta_pinch);
- add_v3_v3(proxy[vd.i], delta_pinch);
+ float pinch_fade = pinch * fade;
+ /* When reducing, scale reduction back by how close to the center we are,
+ * so we don't pinch into nothingness. */
+ if (pinch > 0.0f) {
+ /* Square to have even less impact for close vertices. */
+ pinch_fade *= pow2f(min_ff(1.0f, len_v3(delta_pinch) / ss->cache->radius));
}
+ mul_v3_fl(delta_pinch, 1.0f + pinch_fade);
+ sub_v3_v3v3(delta_pinch, delta_pinch_init, delta_pinch);
+ add_v3_v3(proxy[vd.i], delta_pinch);
+ }
- if (do_rake_rotation) {
- float delta_rotate[3];
- sculpt_rake_rotate(ss, test.location, vd.co, fade, delta_rotate);
- add_v3_v3(proxy[vd.i], delta_rotate);
- }
+ if (do_rake_rotation) {
+ float delta_rotate[3];
+ sculpt_rake_rotate(ss, test.location, vd.co, fade, delta_rotate);
+ add_v3_v3(proxy[vd.i], delta_rotate);
+ }
- if (do_elastic) {
- float disp[3];
- BKE_kelvinlet_grab_triscale(disp, &params, vd.co, ss->cache->location, proxy[vd.i]);
- mul_v3_fl(disp, bstrength * 20.0f);
- if (vd.mask) {
- mul_v3_fl(disp, 1.0f - *vd.mask);
- }
- mul_v3_fl(disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index));
- copy_v3_v3(proxy[vd.i], disp);
+ if (do_elastic) {
+ float disp[3];
+ BKE_kelvinlet_grab_triscale(disp, &params, vd.co, ss->cache->location, proxy[vd.i]);
+ mul_v3_fl(disp, bstrength * 20.0f);
+ if (vd.mask) {
+ mul_v3_fl(disp, 1.0f - *vd.mask);
}
+ mul_v3_fl(disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index));
+ copy_v3_v3(proxy[vd.i], disp);
+ }
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4507,22 +4558,23 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata,
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- orig_data.co,
- sqrtf(test.dist),
- orig_data.no,
- NULL,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ orig_data.co,
+ sqrtf(test.dist),
+ orig_data.no,
+ NULL,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], cono, fade);
+ mul_v3_v3fl(proxy[vd.i], cono, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4580,27 +4632,28 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata,
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- float vec[3], rot[3][3];
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- orig_data.co,
- sqrtf(test.dist),
- orig_data.no,
- NULL,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ float vec[3], rot[3][3];
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ orig_data.co,
+ sqrtf(test.dist),
+ orig_data.no,
+ NULL,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- sub_v3_v3v3(vec, orig_data.co, ss->cache->location);
- axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade);
- mul_v3_m3v3(proxy[vd.i], rot, vec);
- add_v3_v3(proxy[vd.i], ss->cache->location);
- sub_v3_v3(proxy[vd.i], orig_data.co);
+ sub_v3_v3v3(vec, orig_data.co, ss->cache->location);
+ axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade);
+ mul_v3_m3v3(proxy[vd.i], rot, vec);
+ add_v3_v3(proxy[vd.i], ss->cache->location);
+ sub_v3_v3(proxy[vd.i], orig_data.co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4652,70 +4705,71 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- const int vi = vd.index;
- float *disp_factor;
- if (use_persistent_base) {
- disp_factor = &ss->persistent_base[vi].disp;
- }
- else {
- disp_factor = &ss->cache->layer_displacement_factor[vi];
- }
+ if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+ continue;
+ }
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ const int vi = vd.index;
+ float *disp_factor;
+ if (use_persistent_base) {
+ disp_factor = &ss->persistent_base[vi].disp;
+ }
+ else {
+ disp_factor = &ss->cache->layer_displacement_factor[vi];
+ }
- /* When using persistent base, the layer brush (holding Control) invert mode resets the
- * height of the layer to 0. This makes possible to clean edges of previously added layers
- * on top of the base. */
- /* The main direction of the layers is inverted using the regular brush strength with the
- * brush direction property. */
- if (use_persistent_base && ss->cache->invert) {
- (*disp_factor) += fabsf(fade * bstrength * (*disp_factor)) *
- ((*disp_factor) > 0.0f ? -1.0f : 1.0f);
- }
- else {
- (*disp_factor) += fade * bstrength * (1.05f - fabsf(*disp_factor));
- }
- if (vd.mask) {
- const float clamp_mask = 1.0f - *vd.mask;
- *disp_factor = clamp_f(*disp_factor, -clamp_mask, clamp_mask);
- }
- else {
- *disp_factor = clamp_f(*disp_factor, -1.0f, 1.0f);
- }
+ /* When using persistent base, the layer brush (holding Control) invert mode resets the
+ * height of the layer to 0. This makes possible to clean edges of previously added layers
+ * on top of the base. */
+ /* The main direction of the layers is inverted using the regular brush strength with the
+ * brush direction property. */
+ if (use_persistent_base && ss->cache->invert) {
+ (*disp_factor) += fabsf(fade * bstrength * (*disp_factor)) *
+ ((*disp_factor) > 0.0f ? -1.0f : 1.0f);
+ }
+ else {
+ (*disp_factor) += fade * bstrength * (1.05f - fabsf(*disp_factor));
+ }
+ if (vd.mask) {
+ const float clamp_mask = 1.0f - *vd.mask;
+ *disp_factor = clamp_f(*disp_factor, -clamp_mask, clamp_mask);
+ }
+ else {
+ *disp_factor = clamp_f(*disp_factor, -1.0f, 1.0f);
+ }
- float final_co[3];
- float normal[3];
+ float final_co[3];
+ float normal[3];
- if (use_persistent_base) {
- SCULPT_vertex_persistent_normal_get(ss, vi, normal);
- mul_v3_fl(normal, brush->height);
- madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
- }
- else {
- normal_short_to_float_v3(normal, orig_data.no);
- mul_v3_fl(normal, brush->height);
- madd_v3_v3v3fl(final_co, orig_data.co, normal, *disp_factor);
- }
+ if (use_persistent_base) {
+ SCULPT_vertex_persistent_normal_get(ss, vi, normal);
+ mul_v3_fl(normal, brush->height);
+ madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
+ }
+ else {
+ normal_short_to_float_v3(normal, orig_data.no);
+ mul_v3_fl(normal, brush->height);
+ madd_v3_v3v3fl(final_co, orig_data.co, normal, *disp_factor);
+ }
- float vdisp[3];
- sub_v3_v3v3(vdisp, final_co, vd.co);
- mul_v3_fl(vdisp, fabsf(fade));
- add_v3_v3v3(final_co, vd.co, vdisp);
+ float vdisp[3];
+ sub_v3_v3v3(vdisp, final_co, vd.co);
+ mul_v3_fl(vdisp, fabsf(fade));
+ add_v3_v3v3(final_co, vd.co, vdisp);
- SCULPT_clip(sd, ss, vd.co, final_co);
+ SCULPT_clip(sd, ss, vd.co, final_co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4764,31 +4818,32 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- float val[3];
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ float val[3];
- if (vd.fno) {
- copy_v3_v3(val, vd.fno);
- }
- else {
- normal_short_to_float_v3(val, vd.no);
- }
+ if (vd.fno) {
+ copy_v3_v3(val, vd.fno);
+ }
+ else {
+ normal_short_to_float_v3(val, vd.no);
+ }
- mul_v3_fl(val, fade * ss->cache->radius);
- mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale);
+ mul_v3_fl(val, fade * ss->cache->radius);
+ mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -4869,30 +4924,31 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float intr[3];
- float val[3];
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ float intr[3];
+ float val[3];
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
- sub_v3_v3v3(val, intr, vd.co);
+ sub_v3_v3v3(val, intr, vd.co);
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (SCULPT_plane_trim(ss->cache, brush, val)) {
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], val, fade);
+ mul_v3_v3fl(proxy[vd.i], val, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
}
@@ -4975,16 +5031,17 @@ static void calc_clay_surface_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float plane_dist = dist_signed_to_plane_v3(vd.co, plane);
- float plane_dist_abs = fabsf(plane_dist);
- if (plane_dist > 0.0f) {
- csd->plane_dist[0] = MIN2(csd->plane_dist[0], plane_dist_abs);
- }
- else {
- csd->plane_dist[1] = MIN2(csd->plane_dist[1], plane_dist_abs);
- }
+ float plane_dist = dist_signed_to_plane_v3(vd.co, plane);
+ float plane_dist_abs = fabsf(plane_dist);
+ if (plane_dist > 0.0f) {
+ csd->plane_dist[0] = MIN2(csd->plane_dist[0], plane_dist_abs);
+ }
+ else {
+ csd->plane_dist[1] = MIN2(csd->plane_dist[1], plane_dist_abs);
}
BKE_pbvh_vertex_iter_end;
}
@@ -5025,28 +5082,30 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float intr[3];
- float val[3];
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
- sub_v3_v3v3(val, intr, vd.co);
+ float intr[3];
+ float val[3];
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ sub_v3_v3v3(val, intr, vd.co);
- mul_v3_v3fl(proxy[vd.i], val, fade);
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5143,35 +5202,37 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (SCULPT_brush_test_cube(&test, vd.co, mat, brush->tip_roundness)) {
- if (plane_point_side_flip(vd.co, test.plane_tool, flip)) {
- float intr[3];
- float val[3];
+ if (!SCULPT_brush_test_cube(&test, vd.co, mat, brush->tip_roundness)) {
+ continue;
+ }
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ if (!plane_point_side_flip(vd.co, test.plane_tool, flip)) {
+ continue;
+ }
- sub_v3_v3v3(val, intr, vd.co);
+ float intr[3];
+ float val[3];
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ sub_v3_v3v3(val, intr, vd.co);
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- /* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */
- const float fade = bstrength *
- SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- ss->cache->radius * test.dist,
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!SCULPT_plane_trim(ss->cache, brush, val)) {
+ continue;
+ }
+ /* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ ss->cache->radius * test.dist,
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], val, fade);
+ mul_v3_v3fl(proxy[vd.i], val, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5295,33 +5356,37 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- if (SCULPT_plane_point_side(vd.co, test.plane_tool)) {
- float intr[3];
- float val[3];
-
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
-
- sub_v3_v3v3(val, intr, vd.co);
-
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- mul_v3_v3fl(proxy[vd.i], val, fade);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+
+ if (!SCULPT_plane_point_side(vd.co, test.plane_tool)) {
+ continue;
+ }
+
+ float intr[3];
+ float val[3];
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ sub_v3_v3v3(val, intr, vd.co);
+
+ if (!SCULPT_plane_trim(ss->cache, brush, val)) {
+ continue;
+ }
+
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5390,33 +5455,37 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- if (!SCULPT_plane_point_side(vd.co, test.plane_tool)) {
- float intr[3];
- float val[3];
-
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
-
- sub_v3_v3v3(val, intr, vd.co);
-
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- mul_v3_v3fl(proxy[vd.i], val, fade);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+
+ if (SCULPT_plane_point_side(vd.co, test.plane_tool)) {
+ continue;
+ }
+
+ float intr[3];
+ float val[3];
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ sub_v3_v3v3(val, intr, vd.co);
+
+ if (!SCULPT_plane_trim(ss->cache, brush, val)) {
+ continue;
+ }
+
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5501,38 +5570,39 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float local_co[3];
- mul_v3_m4v3(local_co, mat, vd.co);
- float intr[3], intr_tilt[3];
- float val[3];
-
- closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
- closest_to_plane_normalized_v3(intr_tilt, plane_tilt, vd.co);
-
- /* Mix the deformation of the aligned and the tilted plane based on the brush space vertex
- * coordinates. */
- /* We can also control the mix with a curve if it produces noticeable artifacts in the center
- * of the brush. */
- const float tilt_mix = local_co[1] > 0.0f ? 0.0f : 1.0f;
- interp_v3_v3v3(intr, intr, intr_tilt, tilt_mix);
- sub_v3_v3v3(val, intr_tilt, vd.co);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ float local_co[3];
+ mul_v3_m4v3(local_co, mat, vd.co);
+ float intr[3], intr_tilt[3];
+ float val[3];
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
+ closest_to_plane_normalized_v3(intr_tilt, plane_tilt, vd.co);
- mul_v3_v3fl(proxy[vd.i], val, fade);
+ /* Mix the deformation of the aligned and the tilted plane based on the brush space vertex
+ * coordinates. */
+ /* We can also control the mix with a curve if it produces noticeable artifacts in the center
+ * of the brush. */
+ const float tilt_mix = local_co[1] > 0.0f ? 0.0f : 1.0f;
+ interp_v3_v3v3(intr, intr, intr_tilt, tilt_mix);
+ sub_v3_v3v3(val, intr_tilt, vd.co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5656,22 +5726,23 @@ static void do_gravity_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
- mul_v3_v3fl(proxy[vd.i], offset, fade);
+ mul_v3_v3fl(proxy[vd.i], offset, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -5766,49 +5837,51 @@ static void sculpt_topology_update(Sculpt *sd,
ob, sd, brush, use_original, radius_scale, &totnode);
/* Only act if some verts are inside the brush area. */
- if (totnode) {
- PBVHTopologyUpdateMode mode = 0;
- float location[3];
+ if (totnode == 0) {
+ return;
+ }
- if (!(sd->flags & SCULPT_DYNTOPO_DETAIL_MANUAL)) {
- if (sd->flags & SCULPT_DYNTOPO_SUBDIVIDE) {
- mode |= PBVH_Subdivide;
- }
+ PBVHTopologyUpdateMode mode = 0;
+ float location[3];
- if ((sd->flags & SCULPT_DYNTOPO_COLLAPSE) || (brush->sculpt_tool == SCULPT_TOOL_SIMPLIFY)) {
- mode |= PBVH_Collapse;
- }
+ if (!(sd->flags & SCULPT_DYNTOPO_DETAIL_MANUAL)) {
+ if (sd->flags & SCULPT_DYNTOPO_SUBDIVIDE) {
+ mode |= PBVH_Subdivide;
}
- for (n = 0; n < totnode; n++) {
- SCULPT_undo_push_node(ob,
- nodes[n],
- brush->sculpt_tool == SCULPT_TOOL_MASK ? SCULPT_UNDO_MASK :
- SCULPT_UNDO_COORDS);
- BKE_pbvh_node_mark_update(nodes[n]);
-
- if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
- BKE_pbvh_node_mark_topology_update(nodes[n]);
- BKE_pbvh_bmesh_node_save_orig(ss->bm, nodes[n]);
- }
+ if ((sd->flags & SCULPT_DYNTOPO_COLLAPSE) || (brush->sculpt_tool == SCULPT_TOOL_SIMPLIFY)) {
+ mode |= PBVH_Collapse;
}
+ }
+
+ for (n = 0; n < totnode; n++) {
+ SCULPT_undo_push_node(ob,
+ nodes[n],
+ brush->sculpt_tool == SCULPT_TOOL_MASK ? SCULPT_UNDO_MASK :
+ SCULPT_UNDO_COORDS);
+ BKE_pbvh_node_mark_update(nodes[n]);
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
- BKE_pbvh_bmesh_update_topology(ss->pbvh,
- mode,
- ss->cache->location,
- ss->cache->view_normal,
- ss->cache->radius,
- (brush->flag & BRUSH_FRONTFACE) != 0,
- (brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE));
+ BKE_pbvh_node_mark_topology_update(nodes[n]);
+ BKE_pbvh_bmesh_node_save_orig(ss->bm, nodes[n]);
}
+ }
- MEM_SAFE_FREE(nodes);
-
- /* Update average stroke position. */
- copy_v3_v3(location, ss->cache->true_location);
- mul_m4_v3(ob->obmat, location);
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ BKE_pbvh_bmesh_update_topology(ss->pbvh,
+ mode,
+ ss->cache->location,
+ ss->cache->view_normal,
+ ss->cache->radius,
+ (brush->flag & BRUSH_FRONTFACE) != 0,
+ (brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE));
}
+
+ MEM_SAFE_FREE(nodes);
+
+ /* Update average stroke position. */
+ copy_v3_v3(location, ss->cache->true_location);
+ mul_m4_v3(ob->obmat, location);
}
static void do_brush_action_task_cb(void *__restrict userdata,
@@ -5914,202 +5987,199 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
}
/* Only act if some verts are inside the brush area. */
- if (totnode) {
- float location[3];
+ if (totnode == 0) {
+ return;
+ }
+ float location[3];
- SculptThreadedTaskData task_data = {
- .sd = sd,
- .ob = ob,
- .brush = brush,
- .nodes = nodes,
- };
+ SculptThreadedTaskData task_data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ };
- TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, true, totnode);
- BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings);
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings);
- if (sculpt_brush_needs_normal(ss, brush)) {
- update_sculpt_normal(sd, ob, nodes, totnode);
- }
+ if (sculpt_brush_needs_normal(ss, brush)) {
+ update_sculpt_normal(sd, ob, nodes, totnode);
+ }
- if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) {
- update_brush_local_mat(sd, ob);
- }
+ if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) {
+ update_brush_local_mat(sd, ob);
+ }
- if (brush->sculpt_tool == SCULPT_TOOL_POSE && SCULPT_stroke_is_first_brush_step(ss->cache)) {
- SCULPT_pose_brush_init(sd, ob, ss, brush);
- }
+ if (brush->sculpt_tool == SCULPT_TOOL_POSE && SCULPT_stroke_is_first_brush_step(ss->cache)) {
+ SCULPT_pose_brush_init(sd, ob, ss, brush);
+ }
- if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
- if (!ss->cache->cloth_sim) {
- ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(
- ss, 1.0f, 0.0f, 0.0f, false, true);
- SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
- }
- SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim);
- SCULPT_cloth_brush_ensure_nodes_constraints(
- sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX);
+ if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
+ if (!ss->cache->cloth_sim) {
+ ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(
+ ss, 1.0f, 0.0f, 0.0f, false, true);
+ SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
}
+ SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim);
+ SCULPT_cloth_brush_ensure_nodes_constraints(
+ sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX);
+ }
- bool invert = ss->cache->pen_flip || ss->cache->invert || brush->flag & BRUSH_DIR_IN;
+ bool invert = ss->cache->pen_flip || ss->cache->invert || brush->flag & BRUSH_DIR_IN;
- /* Apply one type of brush action. */
- switch (brush->sculpt_tool) {
- case SCULPT_TOOL_DRAW:
- do_draw_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_SMOOTH:
- if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) {
- SCULPT_do_smooth_brush(sd, ob, nodes, totnode);
- }
- else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) {
- SCULPT_do_surface_smooth_brush(sd, ob, nodes, totnode);
- }
- break;
- case SCULPT_TOOL_CREASE:
- do_crease_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_BLOB:
- do_crease_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_PINCH:
- do_pinch_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_INFLATE:
- do_inflate_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_GRAB:
- do_grab_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_ROTATE:
- do_rotate_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_SNAKE_HOOK:
- do_snake_hook_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_NUDGE:
- do_nudge_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_THUMB:
- do_thumb_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_LAYER:
- do_layer_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_FLATTEN:
- do_flatten_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_CLAY:
- do_clay_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_CLAY_STRIPS:
- do_clay_strips_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_MULTIPLANE_SCRAPE:
- SCULPT_do_multiplane_scrape_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_CLAY_THUMB:
- do_clay_thumb_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_FILL:
- if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
- do_scrape_brush(sd, ob, nodes, totnode);
- }
- else {
- do_fill_brush(sd, ob, nodes, totnode);
- }
- break;
- case SCULPT_TOOL_SCRAPE:
- if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
- do_fill_brush(sd, ob, nodes, totnode);
- }
- else {
- do_scrape_brush(sd, ob, nodes, totnode);
- }
- break;
- case SCULPT_TOOL_MASK:
- do_mask_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_POSE:
- SCULPT_do_pose_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_DRAW_SHARP:
- do_draw_sharp_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_ELASTIC_DEFORM:
- do_elastic_deform_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_SLIDE_RELAX:
- do_slide_relax_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_BOUNDARY:
- SCULPT_do_boundary_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_CLOTH:
- SCULPT_do_cloth_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_DRAW_FACE_SETS:
- SCULPT_do_draw_face_sets_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_DISPLACEMENT_ERASER:
- do_displacement_eraser_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_DISPLACEMENT_SMEAR:
- do_displacement_smear_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_PAINT:
- SCULPT_do_paint_brush(sd, ob, nodes, totnode);
- break;
- case SCULPT_TOOL_SMEAR:
- SCULPT_do_smear_brush(sd, ob, nodes, totnode);
- break;
- }
-
- if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
- brush->autosmooth_factor > 0) {
- if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
- SCULPT_smooth(sd,
- ob,
- nodes,
- totnode,
- brush->autosmooth_factor * (1.0f - ss->cache->pressure),
- false);
+ /* Apply one type of brush action. */
+ switch (brush->sculpt_tool) {
+ case SCULPT_TOOL_DRAW:
+ do_draw_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_SMOOTH:
+ if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) {
+ SCULPT_do_smooth_brush(sd, ob, nodes, totnode);
+ }
+ else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) {
+ SCULPT_do_surface_smooth_brush(sd, ob, nodes, totnode);
+ }
+ break;
+ case SCULPT_TOOL_CREASE:
+ do_crease_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_BLOB:
+ do_crease_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_PINCH:
+ do_pinch_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_INFLATE:
+ do_inflate_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_GRAB:
+ do_grab_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_ROTATE:
+ do_rotate_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_SNAKE_HOOK:
+ do_snake_hook_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_NUDGE:
+ do_nudge_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_THUMB:
+ do_thumb_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_LAYER:
+ do_layer_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_FLATTEN:
+ do_flatten_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_CLAY:
+ do_clay_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_CLAY_STRIPS:
+ do_clay_strips_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_MULTIPLANE_SCRAPE:
+ SCULPT_do_multiplane_scrape_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_CLAY_THUMB:
+ do_clay_thumb_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_FILL:
+ if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
+ do_scrape_brush(sd, ob, nodes, totnode);
}
else {
- SCULPT_smooth(sd, ob, nodes, totnode, brush->autosmooth_factor, false);
+ do_fill_brush(sd, ob, nodes, totnode);
}
- }
+ break;
+ case SCULPT_TOOL_SCRAPE:
+ if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
+ do_fill_brush(sd, ob, nodes, totnode);
+ }
+ else {
+ do_scrape_brush(sd, ob, nodes, totnode);
+ }
+ break;
+ case SCULPT_TOOL_MASK:
+ do_mask_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_POSE:
+ SCULPT_do_pose_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_DRAW_SHARP:
+ do_draw_sharp_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_ELASTIC_DEFORM:
+ do_elastic_deform_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_SLIDE_RELAX:
+ do_slide_relax_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_BOUNDARY:
+ SCULPT_do_boundary_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_CLOTH:
+ SCULPT_do_cloth_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_DRAW_FACE_SETS:
+ SCULPT_do_draw_face_sets_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_DISPLACEMENT_ERASER:
+ do_displacement_eraser_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_DISPLACEMENT_SMEAR:
+ do_displacement_smear_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_PAINT:
+ SCULPT_do_paint_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_SMEAR:
+ SCULPT_do_smear_brush(sd, ob, nodes, totnode);
+ break;
+ }
- if (sculpt_brush_use_topology_rake(ss, brush)) {
- bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
+ if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
+ brush->autosmooth_factor > 0) {
+ if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
+ SCULPT_smooth(
+ sd, ob, nodes, totnode, brush->autosmooth_factor * (1.0f - ss->cache->pressure), false);
}
-
- /* The cloth brush adds the gravity as a regular force and it is processed in the solver. */
- if (ss->cache->supports_gravity && !ELEM(brush->sculpt_tool,
- SCULPT_TOOL_CLOTH,
- SCULPT_TOOL_DRAW_FACE_SETS,
- SCULPT_TOOL_BOUNDARY)) {
- do_gravity(sd, ob, nodes, totnode, sd->gravity_factor);
+ else {
+ SCULPT_smooth(sd, ob, nodes, totnode, brush->autosmooth_factor, false);
}
+ }
- if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
- if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
- SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes, totnode);
- SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
- }
+ if (sculpt_brush_use_topology_rake(ss, brush)) {
+ bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
+ }
+
+ /* The cloth brush adds the gravity as a regular force and it is processed in the solver. */
+ if (ss->cache->supports_gravity && !ELEM(brush->sculpt_tool,
+ SCULPT_TOOL_CLOTH,
+ SCULPT_TOOL_DRAW_FACE_SETS,
+ SCULPT_TOOL_BOUNDARY)) {
+ do_gravity(sd, ob, nodes, totnode, sd->gravity_factor);
+ }
+
+ if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
+ if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
+ SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes, totnode);
+ SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
}
+ }
- MEM_SAFE_FREE(nodes);
+ MEM_SAFE_FREE(nodes);
- /* Update average stroke position. */
- copy_v3_v3(location, ss->cache->true_location);
- mul_m4_v3(ob->obmat, location);
+ /* Update average stroke position. */
+ copy_v3_v3(location, ss->cache->true_location);
+ mul_m4_v3(ob->obmat, location);
- add_v3_v3(ups->average_stroke_accum, location);
- ups->average_stroke_counter++;
- /* Update last stroke position. */
- ups->last_stroke_valid = true;
- }
+ add_v3_v3(ups->average_stroke_accum, location);
+ ups->average_stroke_counter++;
+ /* Update last stroke position. */
+ ups->last_stroke_valid = true;
}
/* Flush displacement from deformed PBVH vertex to original mesh. */
@@ -6199,22 +6269,22 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
PBVHNode **nodes;
int totnode;
- BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
-
- /* First line is tools that don't support proxies. */
- if (ss->cache->supports_gravity || (sculpt_tool_is_proxy_used(brush->sculpt_tool) == false)) {
- SculptThreadedTaskData data = {
- .sd = sd,
- .ob = ob,
- .brush = brush,
- .nodes = nodes,
- };
-
- TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, true, totnode);
- BLI_task_parallel_range(0, totnode, &data, sculpt_combine_proxies_task_cb, &settings);
+ if (!ss->cache->supports_gravity && sculpt_tool_is_proxy_used(brush->sculpt_tool)) {
+ /* First line is tools that don't support proxies. */
+ return;
}
+ BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ };
+
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &data, sculpt_combine_proxies_task_cb, &settings);
MEM_SAFE_FREE(nodes);
}
@@ -6235,12 +6305,14 @@ static void sculpt_update_keyblock(Object *ob)
vertCos = BKE_pbvh_vert_coords_alloc(ss->pbvh);
}
- if (vertCos) {
- SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos);
+ if (!vertCos) {
+ return;
+ }
- if (vertCos != ss->orig_cos) {
- MEM_freeN(vertCos);
- }
+ SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos);
+
+ if (vertCos != ss->orig_cos) {
+ MEM_freeN(vertCos);
}
}
@@ -6259,10 +6331,12 @@ static void SCULPT_flush_stroke_deform_task_cb(void *__restrict userdata,
{
sculpt_flush_pbvhvert_deform(ob, &vd);
- if (vertCos) {
- int index = vd.vert_indices[vd.i];
- copy_v3_v3(vertCos[index], ss->orig_cos[index]);
+ if (!vertCos) {
+ continue;
}
+
+ int index = vd.vert_indices[vd.i];
+ copy_v3_v3(vertCos[index], ss->orig_cos[index]);
}
BKE_pbvh_vertex_iter_end;
}
@@ -6490,17 +6564,18 @@ static void do_symmetrical_brush_actions(Sculpt *sd,
/* `symm` is a bit combination of XYZ -
* 1 is mirror X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
for (int i = 0; i <= symm; i++) {
- if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
- cache->mirror_symmetry_pass = i;
- cache->radial_symmetry_pass = 0;
+ if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ continue;
+ }
+ cache->mirror_symmetry_pass = i;
+ cache->radial_symmetry_pass = 0;
- SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0);
- do_tiled(sd, ob, brush, ups, action);
+ SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0);
+ do_tiled(sd, ob, brush, ups, action);
- do_radial_symmetry(sd, ob, brush, ups, action, i, 'X', feather);
- do_radial_symmetry(sd, ob, brush, ups, action, i, 'Y', feather);
- do_radial_symmetry(sd, ob, brush, ups, action, i, 'Z', feather);
- }
+ do_radial_symmetry(sd, ob, brush, ups, action, i, 'X', feather);
+ do_radial_symmetry(sd, ob, brush, ups, action, i, 'Y', feather);
+ do_radial_symmetry(sd, ob, brush, ups, action, i, 'Z', feather);
}
}
@@ -6668,22 +6743,25 @@ static void sculpt_init_mirror_clipping(Object *ob, SculptSession *ss)
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
- if (md->type == eModifierType_Mirror && (md->mode & eModifierMode_Realtime)) {
- MirrorModifierData *mmd = (MirrorModifierData *)md;
-
- if (mmd->flag & MOD_MIR_CLIPPING) {
- /* Check each axis for mirroring. */
- for (int i = 0; i < 3; i++) {
- if (mmd->flag & (MOD_MIR_AXIS_X << i)) {
- /* Enable sculpt clipping. */
- ss->cache->flag |= CLIP_X << i;
-
- /* Update the clip tolerance. */
- if (mmd->tolerance > ss->cache->clip_tolerance[i]) {
- ss->cache->clip_tolerance[i] = mmd->tolerance;
- }
- }
- }
+ if (!(md->type == eModifierType_Mirror && (md->mode & eModifierMode_Realtime))) {
+ continue;
+ }
+ MirrorModifierData *mmd = (MirrorModifierData *)md;
+
+ if (!(mmd->flag & MOD_MIR_CLIPPING)) {
+ continue;
+ }
+ /* Check each axis for mirroring. */
+ for (int i = 0; i < 3; i++) {
+ if (!(mmd->flag & (MOD_MIR_AXIS_X << i))) {
+ continue;
+ }
+ /* Enable sculpt clipping. */
+ ss->cache->flag |= CLIP_X << i;
+
+ /* Update the clip tolerance. */
+ if (mmd->tolerance > ss->cache->clip_tolerance[i]) {
+ ss->cache->clip_tolerance[i] = mmd->tolerance;
}
}
}
@@ -6926,150 +7004,151 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
};
int tool = brush->sculpt_tool;
- if (ELEM(tool,
- SCULPT_TOOL_PAINT,
- SCULPT_TOOL_GRAB,
- SCULPT_TOOL_ELASTIC_DEFORM,
- SCULPT_TOOL_CLOTH,
- SCULPT_TOOL_NUDGE,
- SCULPT_TOOL_CLAY_STRIPS,
- SCULPT_TOOL_PINCH,
- SCULPT_TOOL_MULTIPLANE_SCRAPE,
- SCULPT_TOOL_CLAY_THUMB,
- SCULPT_TOOL_SNAKE_HOOK,
- SCULPT_TOOL_POSE,
- SCULPT_TOOL_BOUNDARY,
- SCULPT_TOOL_THUMB) ||
- sculpt_brush_use_topology_rake(ss, brush)) {
- float grab_location[3], imat[4][4], delta[3], loc[3];
+ if (!ELEM(tool,
+ SCULPT_TOOL_PAINT,
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_ELASTIC_DEFORM,
+ SCULPT_TOOL_CLOTH,
+ SCULPT_TOOL_NUDGE,
+ SCULPT_TOOL_CLAY_STRIPS,
+ SCULPT_TOOL_PINCH,
+ SCULPT_TOOL_MULTIPLANE_SCRAPE,
+ SCULPT_TOOL_CLAY_THUMB,
+ SCULPT_TOOL_SNAKE_HOOK,
+ SCULPT_TOOL_POSE,
+ SCULPT_TOOL_BOUNDARY,
+ SCULPT_TOOL_THUMB) &&
+ !sculpt_brush_use_topology_rake(ss, brush)) {
+ return;
+ }
+ float grab_location[3], imat[4][4], delta[3], loc[3];
- if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
- if (tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
- copy_v3_v3(cache->orig_grab_location,
- SCULPT_vertex_co_for_grab_active_get(ss, SCULPT_active_vertex_get(ss)));
- }
- else {
- copy_v3_v3(cache->orig_grab_location, cache->true_location);
- }
+ if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
+ if (tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
+ copy_v3_v3(cache->orig_grab_location,
+ SCULPT_vertex_co_for_grab_active_get(ss, SCULPT_active_vertex_get(ss)));
}
- else if (tool == SCULPT_TOOL_SNAKE_HOOK ||
- (tool == SCULPT_TOOL_CLOTH &&
- brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK)) {
- add_v3_v3(cache->true_location, cache->grab_delta);
+ else {
+ copy_v3_v3(cache->orig_grab_location, cache->true_location);
}
+ }
+ else if (tool == SCULPT_TOOL_SNAKE_HOOK ||
+ (tool == SCULPT_TOOL_CLOTH &&
+ brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK)) {
+ add_v3_v3(cache->true_location, cache->grab_delta);
+ }
- /* Compute 3d coordinate at same z from original location + mouse. */
- mul_v3_m4v3(loc, ob->obmat, cache->orig_grab_location);
- ED_view3d_win_to_3d(cache->vc->v3d, cache->vc->region, loc, mouse, grab_location);
+ /* Compute 3d coordinate at same z from original location + mouse. */
+ mul_v3_m4v3(loc, ob->obmat, cache->orig_grab_location);
+ ED_view3d_win_to_3d(cache->vc->v3d, cache->vc->region, loc, mouse, grab_location);
- /* Compute delta to move verts by. */
- if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
- if (sculpt_needs_delta_from_anchored_origin(brush)) {
- sub_v3_v3v3(delta, grab_location, cache->old_grab_location);
- invert_m4_m4(imat, ob->obmat);
- mul_mat3_m4_v3(imat, delta);
- add_v3_v3(cache->grab_delta, delta);
- }
- else if (sculpt_needs_delta_for_tip_orientation(brush)) {
- if (brush->flag & BRUSH_ANCHORED) {
- float orig[3];
- mul_v3_m4v3(orig, ob->obmat, cache->orig_grab_location);
- sub_v3_v3v3(cache->grab_delta, grab_location, orig);
- }
- else {
- sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
- }
- invert_m4_m4(imat, ob->obmat);
- mul_mat3_m4_v3(imat, cache->grab_delta);
+ /* Compute delta to move verts by. */
+ if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
+ if (sculpt_needs_delta_from_anchored_origin(brush)) {
+ sub_v3_v3v3(delta, grab_location, cache->old_grab_location);
+ invert_m4_m4(imat, ob->obmat);
+ mul_mat3_m4_v3(imat, delta);
+ add_v3_v3(cache->grab_delta, delta);
+ }
+ else if (sculpt_needs_delta_for_tip_orientation(brush)) {
+ if (brush->flag & BRUSH_ANCHORED) {
+ float orig[3];
+ mul_v3_m4v3(orig, ob->obmat, cache->orig_grab_location);
+ sub_v3_v3v3(cache->grab_delta, grab_location, orig);
}
else {
- /* Use for 'Brush.topology_rake_factor'. */
sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
}
+ invert_m4_m4(imat, ob->obmat);
+ mul_mat3_m4_v3(imat, cache->grab_delta);
}
else {
- zero_v3(cache->grab_delta);
+ /* Use for 'Brush.topology_rake_factor'. */
+ sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
}
+ }
+ else {
+ zero_v3(cache->grab_delta);
+ }
- if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
- project_plane_v3_v3v3(cache->grab_delta, cache->grab_delta, ss->cache->true_view_normal);
- }
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ project_plane_v3_v3v3(cache->grab_delta, cache->grab_delta, ss->cache->true_view_normal);
+ }
- copy_v3_v3(cache->old_grab_location, grab_location);
+ copy_v3_v3(cache->old_grab_location, grab_location);
- if (tool == SCULPT_TOOL_GRAB) {
- if (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
- copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
- }
- else {
- copy_v3_v3(cache->anchored_location, cache->true_location);
- }
+ if (tool == SCULPT_TOOL_GRAB) {
+ if (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
+ copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
}
- else if (tool == SCULPT_TOOL_ELASTIC_DEFORM || SCULPT_is_cloth_deform_brush(brush)) {
+ else {
copy_v3_v3(cache->anchored_location, cache->true_location);
}
- else if (tool == SCULPT_TOOL_THUMB) {
- copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
- }
+ }
+ else if (tool == SCULPT_TOOL_ELASTIC_DEFORM || SCULPT_is_cloth_deform_brush(brush)) {
+ copy_v3_v3(cache->anchored_location, cache->true_location);
+ }
+ else if (tool == SCULPT_TOOL_THUMB) {
+ copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
+ }
- if (sculpt_needs_delta_from_anchored_origin(brush)) {
- /* Location stays the same for finding vertices in brush radius. */
- copy_v3_v3(cache->true_location, cache->orig_grab_location);
+ if (sculpt_needs_delta_from_anchored_origin(brush)) {
+ /* Location stays the same for finding vertices in brush radius. */
+ copy_v3_v3(cache->true_location, cache->orig_grab_location);
- ups->draw_anchored = true;
- copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
- ups->anchored_size = ups->pixel_radius;
- }
+ ups->draw_anchored = true;
+ copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
+ ups->anchored_size = ups->pixel_radius;
+ }
- /* Handle 'rake' */
- cache->is_rake_rotation_valid = false;
+ /* Handle 'rake' */
+ cache->is_rake_rotation_valid = false;
- invert_m4_m4(imat, ob->obmat);
- mul_mat3_m4_v3(imat, grab_location);
+ invert_m4_m4(imat, ob->obmat);
+ mul_mat3_m4_v3(imat, grab_location);
- if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
- copy_v3_v3(cache->rake_data.follow_co, grab_location);
- }
+ if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
+ copy_v3_v3(cache->rake_data.follow_co, grab_location);
+ }
- if (sculpt_brush_needs_rake_rotation(brush)) {
- cache->rake_data.follow_dist = cache->radius * SCULPT_RAKE_BRUSH_FACTOR;
+ if (!sculpt_brush_needs_rake_rotation(brush)) {
+ return;
+ }
+ cache->rake_data.follow_dist = cache->radius * SCULPT_RAKE_BRUSH_FACTOR;
- if (!is_zero_v3(cache->grab_delta)) {
- const float eps = 0.00001f;
+ if (!is_zero_v3(cache->grab_delta)) {
+ const float eps = 0.00001f;
- float v1[3], v2[3];
+ float v1[3], v2[3];
- copy_v3_v3(v1, cache->rake_data.follow_co);
- copy_v3_v3(v2, cache->rake_data.follow_co);
- sub_v3_v3(v2, cache->grab_delta);
+ copy_v3_v3(v1, cache->rake_data.follow_co);
+ copy_v3_v3(v2, cache->rake_data.follow_co);
+ sub_v3_v3(v2, cache->grab_delta);
- sub_v3_v3(v1, grab_location);
- sub_v3_v3(v2, grab_location);
+ sub_v3_v3(v1, grab_location);
+ sub_v3_v3(v2, grab_location);
- if ((normalize_v3(v2) > eps) && (normalize_v3(v1) > eps) &&
- (len_squared_v3v3(v1, v2) > eps)) {
- const float rake_dist_sq = len_squared_v3v3(cache->rake_data.follow_co, grab_location);
- const float rake_fade = (rake_dist_sq > square_f(cache->rake_data.follow_dist)) ?
- 1.0f :
- sqrtf(rake_dist_sq) / cache->rake_data.follow_dist;
+ if ((normalize_v3(v2) > eps) && (normalize_v3(v1) > eps) && (len_squared_v3v3(v1, v2) > eps)) {
+ const float rake_dist_sq = len_squared_v3v3(cache->rake_data.follow_co, grab_location);
+ const float rake_fade = (rake_dist_sq > square_f(cache->rake_data.follow_dist)) ?
+ 1.0f :
+ sqrtf(rake_dist_sq) / cache->rake_data.follow_dist;
- float axis[3], angle;
- float tquat[4];
+ float axis[3], angle;
+ float tquat[4];
- rotation_between_vecs_to_quat(tquat, v1, v2);
+ rotation_between_vecs_to_quat(tquat, v1, v2);
- /* Use axis-angle to scale rotation since the factor may be above 1. */
- quat_to_axis_angle(axis, &angle, tquat);
- normalize_v3(axis);
+ /* Use axis-angle to scale rotation since the factor may be above 1. */
+ quat_to_axis_angle(axis, &angle, tquat);
+ normalize_v3(axis);
- angle *= brush->rake_factor * rake_fade;
- axis_angle_normalized_to_quat(cache->rake_rotation, axis, angle);
- cache->is_rake_rotation_valid = true;
- }
- }
- sculpt_rake_data_update(&cache->rake_data, grab_location);
+ angle *= brush->rake_factor * rake_fade;
+ axis_angle_normalized_to_quat(cache->rake_rotation, axis, angle);
+ cache->is_rake_rotation_valid = true;
}
}
+ sculpt_rake_data_update(&cache->rake_data, grab_location);
}
static void sculpt_update_cache_paint_variants(StrokeCache *cache, const Brush *brush)
@@ -7257,71 +7336,73 @@ void SCULPT_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *b
static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
{
- if (BKE_pbvh_node_get_tmin(node) < *tmin) {
- SculptRaycastData *srd = data_v;
- float(*origco)[3] = NULL;
- bool use_origco = false;
+ if (BKE_pbvh_node_get_tmin(node) >= *tmin) {
+ return;
+ }
+ SculptRaycastData *srd = data_v;
+ float(*origco)[3] = NULL;
+ bool use_origco = false;
- if (srd->original && srd->ss->cache) {
- if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
- use_origco = true;
- }
- else {
- /* Intersect with coordinates from before we started stroke. */
- SculptUndoNode *unode = SCULPT_undo_get_node(node);
- origco = (unode) ? unode->co : NULL;
- use_origco = origco ? true : false;
- }
+ if (srd->original && srd->ss->cache) {
+ if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
+ use_origco = true;
}
-
- if (BKE_pbvh_node_raycast(srd->ss->pbvh,
- node,
- origco,
- use_origco,
- srd->ray_start,
- srd->ray_normal,
- &srd->isect_precalc,
- &srd->depth,
- &srd->active_vertex_index,
- &srd->active_face_grid_index,
- srd->face_normal)) {
- srd->hit = true;
- *tmin = srd->depth;
+ else {
+ /* Intersect with coordinates from before we started stroke. */
+ SculptUndoNode *unode = SCULPT_undo_get_node(node);
+ origco = (unode) ? unode->co : NULL;
+ use_origco = origco ? true : false;
}
}
+
+ if (BKE_pbvh_node_raycast(srd->ss->pbvh,
+ node,
+ origco,
+ use_origco,
+ srd->ray_start,
+ srd->ray_normal,
+ &srd->isect_precalc,
+ &srd->depth,
+ &srd->active_vertex_index,
+ &srd->active_face_grid_index,
+ srd->face_normal)) {
+ srd->hit = true;
+ *tmin = srd->depth;
+ }
}
static void sculpt_find_nearest_to_ray_cb(PBVHNode *node, void *data_v, float *tmin)
{
- if (BKE_pbvh_node_get_tmin(node) < *tmin) {
- SculptFindNearestToRayData *srd = data_v;
- float(*origco)[3] = NULL;
- bool use_origco = false;
+ if (BKE_pbvh_node_get_tmin(node) >= *tmin) {
+ return;
+ }
+ SculptFindNearestToRayData *srd = data_v;
+ float(*origco)[3] = NULL;
+ bool use_origco = false;
- if (srd->original && srd->ss->cache) {
- if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
- use_origco = true;
- }
- else {
- /* Intersect with coordinates from before we started stroke. */
- SculptUndoNode *unode = SCULPT_undo_get_node(node);
- origco = (unode) ? unode->co : NULL;
- use_origco = origco ? true : false;
- }
+ if (srd->original && srd->ss->cache) {
+ if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
+ use_origco = true;
}
-
- if (BKE_pbvh_node_find_nearest_to_ray(srd->ss->pbvh,
- node,
- origco,
- use_origco,
- srd->ray_start,
- srd->ray_normal,
- &srd->depth,
- &srd->dist_sq_to_ray)) {
- srd->hit = true;
- *tmin = srd->dist_sq_to_ray;
+ else {
+ /* Intersect with coordinates from before we started stroke. */
+ SculptUndoNode *unode = SCULPT_undo_get_node(node);
+ origco = (unode) ? unode->co : NULL;
+ use_origco = origco ? true : false;
}
}
+
+ if (BKE_pbvh_node_find_nearest_to_ray(srd->ss->pbvh,
+ node,
+ origco,
+ use_origco,
+ srd->ray_start,
+ srd->ray_normal,
+ &srd->depth,
+ &srd->dist_sq_to_ray)) {
+ srd->hit = true;
+ *tmin = srd->dist_sq_to_ray;
+ }
}
float SCULPT_raycast_init(ViewContext *vc,
@@ -7546,26 +7627,30 @@ bool SCULPT_stroke_get_location(bContext *C, float out[3], const float mouse[2])
}
}
- if (!hit) {
- if (ELEM(brush->falloff_shape, PAINT_FALLOFF_SHAPE_TUBE)) {
- SculptFindNearestToRayData srd = {
- .original = original,
- .ss = ob->sculpt,
- .hit = false,
- .ray_start = ray_start,
- .ray_normal = ray_normal,
- .depth = FLT_MAX,
- .dist_sq_to_ray = FLT_MAX,
- };
- BKE_pbvh_find_nearest_to_ray(
- ss->pbvh, sculpt_find_nearest_to_ray_cb, &srd, ray_start, ray_normal, srd.original);
- if (srd.hit) {
- hit = true;
- copy_v3_v3(out, ray_normal);
- mul_v3_fl(out, srd.depth);
- add_v3_v3(out, ray_start);
- }
- }
+ if (hit) {
+ return hit;
+ }
+
+ if (!ELEM(brush->falloff_shape, PAINT_FALLOFF_SHAPE_TUBE)) {
+ return hit;
+ }
+
+ SculptFindNearestToRayData srd = {
+ .original = original,
+ .ss = ob->sculpt,
+ .hit = false,
+ .ray_start = ray_start,
+ .ray_normal = ray_normal,
+ .depth = FLT_MAX,
+ .dist_sq_to_ray = FLT_MAX,
+ };
+ BKE_pbvh_find_nearest_to_ray(
+ ss->pbvh, sculpt_find_nearest_to_ray_cb, &srd, ray_start, ray_normal, srd.original);
+ if (srd.hit) {
+ hit = true;
+ copy_v3_v3(out, ray_normal);
+ mul_v3_fl(out, srd.depth);
+ add_v3_v3(out, ray_start);
}
return hit;
@@ -7748,19 +7833,20 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up
bScreen *screen = WM_window_get_active_screen(win);
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
SpaceLink *sl = area->spacedata.first;
- if (sl->spacetype == SPACE_VIEW3D) {
- View3D *v3d = (View3D *)sl;
- if (v3d != current_v3d) {
- need_tag |= !BKE_sculptsession_use_pbvh_draw(ob, v3d);
- }
+ if (sl->spacetype != SPACE_VIEW3D) {
+ continue;
+ }
+ View3D *v3d = (View3D *)sl;
+ if (v3d != current_v3d) {
+ need_tag |= !BKE_sculptsession_use_pbvh_draw(ob, v3d);
+ }
- /* Tag all 3D viewports for redraw now that we are done. Others
- * viewports did not get a full redraw, and anti-aliasing for the
- * current viewport was deactivated. */
- LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
- if (region->regiontype == RGN_TYPE_WINDOW) {
- ED_region_tag_redraw(region);
- }
+ /* Tag all 3D viewports for redraw now that we are done. Others
+ * viewports did not get a full redraw, and anti-aliasing for the
+ * current viewport was deactivated. */
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
+ if (region->regiontype == RGN_TYPE_WINDOW) {
+ ED_region_tag_redraw(region);
}
}
}
@@ -7920,55 +8006,56 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
/* Finished. */
- if (ss->cache) {
- UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
- Brush *brush = BKE_paint_brush(&sd->paint);
- BLI_assert(brush == ss->cache->brush); /* const, so we shouldn't change. */
- ups->draw_inverted = false;
+ if (!ss->cache) {
+ sculpt_brush_exit_tex(sd);
+ return;
+ }
+ UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ BLI_assert(brush == ss->cache->brush); /* const, so we shouldn't change. */
+ ups->draw_inverted = false;
- SCULPT_stroke_modifiers_check(C, ob, brush);
+ SCULPT_stroke_modifiers_check(C, ob, brush);
- /* Alt-Smooth. */
- if (ss->cache->alt_smooth) {
- if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
- brush->mask_tool = ss->cache->saved_mask_brush_tool;
- }
- else if (ELEM(brush->sculpt_tool,
- SCULPT_TOOL_SLIDE_RELAX,
- SCULPT_TOOL_DRAW_FACE_SETS,
- SCULPT_TOOL_PAINT,
- SCULPT_TOOL_SMEAR)) {
- /* Do nothing. */
- }
- else {
- BKE_brush_size_set(scene, brush, ss->cache->saved_smooth_size);
- brush = (Brush *)BKE_libblock_find_name(bmain, ID_BR, ss->cache->saved_active_brush_name);
- if (brush) {
- BKE_paint_brush_set(&sd->paint, brush);
- }
- }
+ /* Alt-Smooth. */
+ if (ss->cache->alt_smooth) {
+ if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
+ brush->mask_tool = ss->cache->saved_mask_brush_tool;
}
-
- if (SCULPT_is_automasking_enabled(sd, ss, brush)) {
- SCULPT_automasking_cache_free(ss->cache->automasking);
+ else if (ELEM(brush->sculpt_tool,
+ SCULPT_TOOL_SLIDE_RELAX,
+ SCULPT_TOOL_DRAW_FACE_SETS,
+ SCULPT_TOOL_PAINT,
+ SCULPT_TOOL_SMEAR)) {
+ /* Do nothing. */
}
+ else {
+ BKE_brush_size_set(scene, brush, ss->cache->saved_smooth_size);
+ brush = (Brush *)BKE_libblock_find_name(bmain, ID_BR, ss->cache->saved_active_brush_name);
+ if (brush) {
+ BKE_paint_brush_set(&sd->paint, brush);
+ }
+ }
+ }
- BKE_pbvh_node_color_buffer_free(ss->pbvh);
- SCULPT_cache_free(ss->cache);
- ss->cache = NULL;
+ if (SCULPT_is_automasking_enabled(sd, ss, brush)) {
+ SCULPT_automasking_cache_free(ss->cache->automasking);
+ }
- SCULPT_undo_push_end();
+ BKE_pbvh_node_color_buffer_free(ss->pbvh);
+ SCULPT_cache_free(ss->cache);
+ ss->cache = NULL;
- if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
- SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
- }
- else {
- SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
- }
+ SCULPT_undo_push_end();
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
+ SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
+ }
+ else {
+ SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
}
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
sculpt_brush_exit_tex(sd);
}
@@ -8090,21 +8177,22 @@ static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op))
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
- if (ss) {
- SCULPT_vertex_random_access_ensure(ss);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
+ if (!ss) {
+ return OPERATOR_FINISHED;
+ }
+ SCULPT_vertex_random_access_ensure(ss);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
- MEM_SAFE_FREE(ss->persistent_base);
+ MEM_SAFE_FREE(ss->persistent_base);
- const int totvert = SCULPT_vertex_count_get(ss);
- ss->persistent_base = MEM_mallocN(sizeof(SculptPersistentBase) * totvert,
- "layer persistent base");
+ const int totvert = SCULPT_vertex_count_get(ss);
+ ss->persistent_base = MEM_mallocN(sizeof(SculptPersistentBase) * totvert,
+ "layer persistent base");
- for (int i = 0; i < totvert; i++) {
- copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, i));
- SCULPT_vertex_normal_get(ss, i, ss->persistent_base[i].no);
- ss->persistent_base[i].disp = 0.0f;
- }
+ for (int i = 0; i < totvert; i++) {
+ copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, i));
+ SCULPT_vertex_normal_get(ss, i, ss->persistent_base[i].no);
+ ss->persistent_base[i].disp = 0.0f;
}
return OPERATOR_FINISHED;
@@ -8564,12 +8652,13 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
totpoints++;
ss->preview_vert_index_list[totpoints] = to_v;
totpoints++;
- if (!BLI_BITMAP_TEST(visited_vertices, to_v)) {
- BLI_BITMAP_ENABLE(visited_vertices, to_v);
- const float *co = SCULPT_vertex_co_for_grab_active_get(ss, to_v);
- if (len_squared_v3v3(brush_co, co) < radius * radius) {
- BLI_gsqueue_push(not_visited_vertices, &to_v);
- }
+ if (BLI_BITMAP_TEST(visited_vertices, to_v)) {
+ continue;
+ }
+ BLI_BITMAP_ENABLE(visited_vertices, to_v);
+ const float *co = SCULPT_vertex_co_for_grab_active_get(ss, to_v);
+ if (len_squared_v3v3(brush_co, co) < radius * radius) {
+ BLI_gsqueue_push(not_visited_vertices, &to_v);
}
}
}
@@ -8993,7 +9082,7 @@ void SCULPT_fake_neighbors_ensure(Sculpt *sd, Object *ob, const float max_dist)
for (int i = 0; i < totvert; i++) {
const int from_v = i;
- /* This vertex does not have a fake neighbor yet, seach one for it. */
+ /* This vertex does not have a fake neighbor yet, search one for it. */
if (ss->fake_neighbors.fake_neighbor_index[from_v] == FAKE_NEIGHBOR_NONE) {
const int to_v = SCULPT_fake_neighbor_search(sd, ob, from_v, max_dist);
if (to_v != -1) {
@@ -9099,11 +9188,12 @@ static void do_mask_by_color_contiguous_update_nodes_cb(
const float current_mask = *vd.mask;
const float new_mask = data->mask_by_color_floodfill[vd.index];
*vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask);
- if (current_mask != *vd.mask) {
- update_node = true;
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (current_mask == *vd.mask) {
+ continue;
+ }
+ update_node = true;
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -9206,11 +9296,12 @@ static void do_mask_by_color_task_cb(void *__restrict userdata,
const float new_mask = sculpt_mask_by_color_delta_get(active_color, vd.col, threshold, invert);
*vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask);
- if (current_mask != *vd.mask) {
- update_node = true;
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (current_mask == *vd.mask) {
+ continue;
+ }
+ update_node = true;
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.c b/source/blender/editors/sculpt_paint/sculpt_automasking.c
index bb68ec56b25..5f5fb51d75f 100644
--- a/source/blender/editors/sculpt_paint/sculpt_automasking.c
+++ b/source/blender/editors/sculpt_paint/sculpt_automasking.c
@@ -298,24 +298,26 @@ float *SCULPT_boundary_automasking_init(Object *ob,
for (int propagation_it = 0; propagation_it < propagation_steps; propagation_it++) {
for (int i = 0; i < totvert; i++) {
- if (edge_distance[i] == EDGE_DISTANCE_INF) {
- SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
- if (edge_distance[ni.index] == propagation_it) {
- edge_distance[i] = propagation_it + 1;
- }
+ if (edge_distance[i] != EDGE_DISTANCE_INF) {
+ continue;
+ }
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
+ if (edge_distance[ni.index] == propagation_it) {
+ edge_distance[i] = propagation_it + 1;
}
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
}
for (int i = 0; i < totvert; i++) {
- if (edge_distance[i] != EDGE_DISTANCE_INF) {
- const float p = 1.0f - ((float)edge_distance[i] / (float)propagation_steps);
- const float edge_boundary_automask = pow2f(p);
- automask_factor[i] *= (1.0f - edge_boundary_automask);
+ if (edge_distance[i] == EDGE_DISTANCE_INF) {
+ continue;
}
+ const float p = 1.0f - ((float)edge_distance[i] / (float)propagation_steps);
+ const float edge_boundary_automask = pow2f(p);
+ automask_factor[i] *= (1.0f - edge_boundary_automask);
}
MEM_SAFE_FREE(edge_distance);
diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c
index 0cfb6f17adb..fca19c04b98 100644
--- a/source/blender/editors/sculpt_paint/sculpt_boundary.c
+++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c
@@ -227,19 +227,19 @@ static bool boundary_floodfill_cb(
{
BoundaryFloodFillData *data = userdata;
SculptBoundary *boundary = data->boundary;
- if (SCULPT_vertex_is_boundary(ss, to_v)) {
- const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v),
- SCULPT_vertex_co_get(ss, to_v));
- const float distance_boundary_to_dst = boundary->distance ?
- boundary->distance[from_v] + edge_len :
- 0.0f;
- sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices);
- if (!is_duplicate) {
- sculpt_boundary_preview_edge_add(boundary, from_v, to_v);
- }
- return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v);
+ if (!SCULPT_vertex_is_boundary(ss, to_v)) {
+ return false;
+ }
+ const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v),
+ SCULPT_vertex_co_get(ss, to_v));
+ const float distance_boundary_to_dst = boundary->distance ?
+ boundary->distance[from_v] + edge_len :
+ 0.0f;
+ sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices);
+ if (!is_duplicate) {
+ sculpt_boundary_preview_edge_add(boundary, from_v, to_v);
}
- return false;
+ return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v);
}
static void sculpt_boundary_indices_init(SculptSession *ss,
@@ -360,49 +360,50 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
SculptVertexNeighborIter ni;
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
const bool is_visible = SCULPT_vertex_visible_get(ss, ni.index);
- if (is_visible &&
- boundary->edit_info[ni.index].num_propagation_steps == BOUNDARY_STEPS_NONE) {
- boundary->edit_info[ni.index].original_vertex =
- boundary->edit_info[from_v].original_vertex;
+ if (!is_visible ||
+ boundary->edit_info[ni.index].num_propagation_steps != BOUNDARY_STEPS_NONE) {
+ continue;
+ }
+ boundary->edit_info[ni.index].original_vertex =
+ boundary->edit_info[from_v].original_vertex;
- BLI_BITMAP_ENABLE(visited_vertices, ni.index);
+ BLI_BITMAP_ENABLE(visited_vertices, ni.index);
- if (ni.is_duplicate) {
- /* Grids duplicates handling. */
- boundary->edit_info[ni.index].num_propagation_steps =
- boundary->edit_info[from_v].num_propagation_steps;
- }
- else {
- boundary->edit_info[ni.index].num_propagation_steps =
- boundary->edit_info[from_v].num_propagation_steps + 1;
-
- BLI_gsqueue_push(next_iteration, &ni.index);
-
- /* When copying the data to the neighbor for the next iteration, it has to be copied to
- * all its duplicates too. This is because it is not possible to know if the updated
- * neighbor or one if its uninitialized duplicates is going to come first in order to
- * copy the data in the from_v neighbor iterator. */
- if (has_duplicates) {
- SculptVertexNeighborIter ni_duplis;
- SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) {
- if (ni_duplis.is_duplicate) {
- boundary->edit_info[ni_duplis.index].original_vertex =
- boundary->edit_info[from_v].original_vertex;
- boundary->edit_info[ni_duplis.index].num_propagation_steps =
- boundary->edit_info[from_v].num_propagation_steps + 1;
- }
+ if (ni.is_duplicate) {
+ /* Grids duplicates handling. */
+ boundary->edit_info[ni.index].num_propagation_steps =
+ boundary->edit_info[from_v].num_propagation_steps;
+ }
+ else {
+ boundary->edit_info[ni.index].num_propagation_steps =
+ boundary->edit_info[from_v].num_propagation_steps + 1;
+
+ BLI_gsqueue_push(next_iteration, &ni.index);
+
+ /* When copying the data to the neighbor for the next iteration, it has to be copied to
+ * all its duplicates too. This is because it is not possible to know if the updated
+ * neighbor or one if its uninitialized duplicates is going to come first in order to
+ * copy the data in the from_v neighbor iterator. */
+ if (has_duplicates) {
+ SculptVertexNeighborIter ni_duplis;
+ SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) {
+ if (ni_duplis.is_duplicate) {
+ boundary->edit_info[ni_duplis.index].original_vertex =
+ boundary->edit_info[from_v].original_vertex;
+ boundary->edit_info[ni_duplis.index].num_propagation_steps =
+ boundary->edit_info[from_v].num_propagation_steps + 1;
}
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
}
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
+ }
- /* Check the distance using the vertex that was propagated from the initial vertex that
- * was used to initialize the boundary. */
- if (boundary->edit_info[from_v].original_vertex == initial_vertex) {
- boundary->pivot_vertex = ni.index;
- copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index));
- accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v),
- SCULPT_vertex_co_get(ss, ni.index));
- }
+ /* Check the distance using the vertex that was propagated from the initial vertex that
+ * was used to initialize the boundary. */
+ if (boundary->edit_info[from_v].original_vertex == initial_vertex) {
+ boundary->pivot_vertex = ni.index;
+ copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index));
+ accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v),
+ SCULPT_vertex_co_get(ss, ni.index));
}
}
}
@@ -552,28 +553,30 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo
totvert, 3 * sizeof(float), "pivot positions");
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) {
- float dir[3];
- float normal[3];
- SCULPT_vertex_normal_get(ss, i, normal);
- sub_v3_v3v3(dir,
- SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
- SCULPT_vertex_co_get(ss, i));
- cross_v3_v3v3(
- boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal);
- normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
- copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex],
- SCULPT_vertex_co_get(ss, i));
+ if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) {
+ continue;
}
+ float dir[3];
+ float normal[3];
+ SCULPT_vertex_normal_get(ss, i, normal);
+ sub_v3_v3v3(dir,
+ SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
+ SCULPT_vertex_co_get(ss, i));
+ cross_v3_v3v3(
+ boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal);
+ normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
+ copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex],
+ SCULPT_vertex_co_get(ss, i));
}
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
- copy_v3_v3(boundary->bend.pivot_positions[i],
- boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]);
- copy_v3_v3(boundary->bend.pivot_rotation_axis[i],
- boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
+ if (boundary->edit_info[i].num_propagation_steps == BOUNDARY_STEPS_NONE) {
+ continue;
}
+ copy_v3_v3(boundary->bend.pivot_positions[i],
+ boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]);
+ copy_v3_v3(boundary->bend.pivot_rotation_axis[i],
+ boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
}
}
@@ -583,19 +586,20 @@ static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *b
boundary->slide.directions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "slide directions");
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) {
- sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex],
- SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
- SCULPT_vertex_co_get(ss, i));
- normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]);
+ if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) {
}
+ sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex],
+ SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
+ SCULPT_vertex_co_get(ss, i));
+ normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]);
}
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
- copy_v3_v3(boundary->slide.directions[i],
- boundary->slide.directions[boundary->edit_info[i].original_vertex]);
+ if (boundary->edit_info[i].num_propagation_steps == BOUNDARY_STEPS_NONE) {
+ continue;
}
+ copy_v3_v3(boundary->slide.directions[i],
+ boundary->slide.directions[boundary->edit_info[i].original_vertex]);
}
}
@@ -662,24 +666,27 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- float t_orig_co[3];
- float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
- sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]);
- rotate_v3_v3v3fl(target_co,
- t_orig_co,
- boundary->bend.pivot_rotation_axis[vd.index],
- angle * boundary->edit_info[vd.index].strength_factor * mask * automask);
- add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ float t_orig_co[3];
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]);
+ rotate_v3_v3v3fl(target_co,
+ t_orig_co,
+ boundary->bend.pivot_rotation_axis[vd.index],
+ angle * boundary->edit_info[vd.index].strength_factor * mask * automask);
+ add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -708,22 +715,25 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
- madd_v3_v3v3fl(target_co,
- orig_data.co,
- boundary->slide.directions[vd.index],
- boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
- strength);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ madd_v3_v3v3fl(target_co,
+ orig_data.co,
+ boundary->slide.directions[vd.index],
+ boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
+ strength);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -752,24 +762,27 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- float normal[3];
- normal_short_to_float_v3(normal, orig_data.no);
- float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
- madd_v3_v3v3fl(target_co,
- orig_data.co,
- normal,
- boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
- strength);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ float normal[3];
+ normal_short_to_float_v3(normal, orig_data.no);
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ madd_v3_v3v3fl(target_co,
+ orig_data.co,
+ normal,
+ boundary->edit_info[vd.index].strength_factor * disp * mask * automask *
+ strength);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -796,21 +809,24 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
- madd_v3_v3v3fl(target_co,
- orig_data.co,
- ss->cache->grab_delta_symmetry,
- boundary->edit_info[vd.index].strength_factor * mask * automask * strength);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ madd_v3_v3v3fl(target_co,
+ orig_data.co,
+ ss->cache->grab_delta_symmetry,
+ boundary->edit_info[vd.index].strength_factor * mask * automask * strength);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -845,24 +861,27 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
+ if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ continue;
+ }
- if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(
- orig_data.co, boundary->initial_vertex_position, symm)) {
- const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
- float t_orig_co[3];
- float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
- sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position);
- rotate_v3_v3v3fl(target_co,
- t_orig_co,
- boundary->twist.rotation_axis,
- angle * mask * automask * boundary->edit_info[vd.index].strength_factor);
- add_v3_v3(target_co, boundary->twist.pivot_position);
- }
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (!SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
+ continue;
}
+ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+ const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ float t_orig_co[3];
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position);
+ rotate_v3_v3v3fl(target_co,
+ t_orig_co,
+ boundary->twist.rotation_axis,
+ angle * mask * automask * boundary->edit_info[vd.index].strength_factor);
+ add_v3_v3(target_co, boundary->twist.pivot_position);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index c97f31fa682..16d10f6d6bb 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -540,97 +540,98 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, vertex_gravity, vd.index);
/* When using the plane falloff mode the falloff is not constrained by the brush radius. */
- if (sculpt_brush_test_sq_fn(&test, current_vertex_location) || use_falloff_plane) {
-
- float dist = sqrtf(test.dist);
+ if (!sculpt_brush_test_sq_fn(&test, current_vertex_location) && !use_falloff_plane) {
+ continue;
+ }
- if (use_falloff_plane) {
- dist = dist_to_plane_v3(current_vertex_location, deform_plane);
- }
+ float dist = sqrtf(test.dist);
- const float fade = sim_factor * bstrength *
- SCULPT_brush_strength_factor(ss,
- brush,
- current_vertex_location,
- dist,
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float brush_disp[3];
- float normal[3];
- if (vd.no) {
- normal_short_to_float_v3(normal, vd.no);
- }
- else {
- copy_v3_v3(normal, vd.fno);
- }
+ if (use_falloff_plane) {
+ dist = dist_to_plane_v3(current_vertex_location, deform_plane);
+ }
- switch (brush->cloth_deform_type) {
- case BRUSH_CLOTH_DEFORM_DRAG:
- sub_v3_v3v3(brush_disp, ss->cache->location, ss->cache->last_location);
- normalize_v3(brush_disp);
- mul_v3_v3fl(force, brush_disp, fade);
- break;
- case BRUSH_CLOTH_DEFORM_PUSH:
- /* Invert the fade to push inwards. */
- mul_v3_v3fl(force, offset, -fade);
- break;
- case BRUSH_CLOTH_DEFORM_GRAB:
- madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index],
- cloth_sim->init_pos[vd.index],
- ss->cache->grab_delta_symmetry,
- fade);
- if (use_falloff_plane) {
- cloth_sim->deformation_strength[vd.index] = clamp_f(fade, 0.0f, 1.0f);
- }
- else {
- cloth_sim->deformation_strength[vd.index] = 1.0f;
- }
- zero_v3(force);
- break;
- case BRUSH_CLOTH_DEFORM_SNAKE_HOOK:
- copy_v3_v3(cloth_sim->deformation_pos[vd.index], cloth_sim->pos[vd.index]);
- madd_v3_v3fl(cloth_sim->deformation_pos[vd.index], ss->cache->grab_delta_symmetry, fade);
- cloth_sim->deformation_strength[vd.index] = fade;
- zero_v3(force);
- break;
- case BRUSH_CLOTH_DEFORM_PINCH_POINT:
- if (use_falloff_plane) {
- float distance = dist_signed_to_plane_v3(vd.co, deform_plane);
- copy_v3_v3(brush_disp, plane_normal);
- mul_v3_fl(brush_disp, -distance);
- }
- else {
- sub_v3_v3v3(brush_disp, ss->cache->location, vd.co);
- }
- normalize_v3(brush_disp);
- mul_v3_v3fl(force, brush_disp, fade);
- break;
- case BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR: {
- float disp_center[3];
- float x_disp[3];
- float z_disp[3];
- sub_v3_v3v3(disp_center, ss->cache->location, vd.co);
- normalize_v3(disp_center);
- mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
- mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
- add_v3_v3v3(disp_center, x_disp, z_disp);
- mul_v3_v3fl(force, disp_center, fade);
- } break;
- case BRUSH_CLOTH_DEFORM_INFLATE:
- mul_v3_v3fl(force, normal, fade);
- break;
- case BRUSH_CLOTH_DEFORM_EXPAND:
- cloth_sim->length_constraint_tweak[vd.index] += fade * 0.1f;
- zero_v3(force);
- break;
- }
+ const float fade = sim_factor * bstrength *
+ SCULPT_brush_strength_factor(ss,
+ brush,
+ current_vertex_location,
+ dist,
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float brush_disp[3];
+ float normal[3];
+ if (vd.no) {
+ normal_short_to_float_v3(normal, vd.no);
+ }
+ else {
+ copy_v3_v3(normal, vd.fno);
+ }
- cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, force, vd.index);
+ switch (brush->cloth_deform_type) {
+ case BRUSH_CLOTH_DEFORM_DRAG:
+ sub_v3_v3v3(brush_disp, ss->cache->location, ss->cache->last_location);
+ normalize_v3(brush_disp);
+ mul_v3_v3fl(force, brush_disp, fade);
+ break;
+ case BRUSH_CLOTH_DEFORM_PUSH:
+ /* Invert the fade to push inwards. */
+ mul_v3_v3fl(force, offset, -fade);
+ break;
+ case BRUSH_CLOTH_DEFORM_GRAB:
+ madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index],
+ cloth_sim->init_pos[vd.index],
+ ss->cache->grab_delta_symmetry,
+ fade);
+ if (use_falloff_plane) {
+ cloth_sim->deformation_strength[vd.index] = clamp_f(fade, 0.0f, 1.0f);
+ }
+ else {
+ cloth_sim->deformation_strength[vd.index] = 1.0f;
+ }
+ zero_v3(force);
+ break;
+ case BRUSH_CLOTH_DEFORM_SNAKE_HOOK:
+ copy_v3_v3(cloth_sim->deformation_pos[vd.index], cloth_sim->pos[vd.index]);
+ madd_v3_v3fl(cloth_sim->deformation_pos[vd.index], ss->cache->grab_delta_symmetry, fade);
+ cloth_sim->deformation_strength[vd.index] = fade;
+ zero_v3(force);
+ break;
+ case BRUSH_CLOTH_DEFORM_PINCH_POINT:
+ if (use_falloff_plane) {
+ float distance = dist_signed_to_plane_v3(vd.co, deform_plane);
+ copy_v3_v3(brush_disp, plane_normal);
+ mul_v3_fl(brush_disp, -distance);
+ }
+ else {
+ sub_v3_v3v3(brush_disp, ss->cache->location, vd.co);
+ }
+ normalize_v3(brush_disp);
+ mul_v3_v3fl(force, brush_disp, fade);
+ break;
+ case BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR: {
+ float disp_center[3];
+ float x_disp[3];
+ float z_disp[3];
+ sub_v3_v3v3(disp_center, ss->cache->location, vd.co);
+ normalize_v3(disp_center);
+ mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
+ mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
+ add_v3_v3v3(disp_center, x_disp, z_disp);
+ mul_v3_v3fl(force, disp_center, fade);
+ } break;
+ case BRUSH_CLOTH_DEFORM_INFLATE:
+ mul_v3_v3fl(force, normal, fade);
+ break;
+ case BRUSH_CLOTH_DEFORM_EXPAND:
+ cloth_sim->length_constraint_tweak[vd.index] += fade * 0.1f;
+ zero_v3(force);
+ break;
}
+
+ cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, force, vd.index);
}
BKE_pbvh_vertex_iter_end;
}
@@ -644,17 +645,22 @@ static ListBase *cloth_brush_collider_cache_create(Depsgraph *depsgraph)
DEG_ITER_OBJECT_FLAG_DUPLI) {
CollisionModifierData *cmd = (CollisionModifierData *)BKE_modifiers_findby_type(
ob, eModifierType_Collision);
- if (cmd && cmd->bvhtree) {
- if (cache == NULL) {
- cache = MEM_callocN(sizeof(ListBase), "ColliderCache array");
- }
+ if (!cmd) {
+ continue;
+ }
- ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
- col->ob = ob;
- col->collmd = cmd;
- collision_move_object(cmd, 1.0, 0.0, true);
- BLI_addtail(cache, col);
+ if (!cmd->bvhtree) {
+ continue;
}
+ if (cache == NULL) {
+ cache = MEM_callocN(sizeof(ListBase), "ColliderCache array");
+ }
+
+ ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
+ col->ob = ob;
+ col->collmd = cmd;
+ collision_move_object(cmd, 1.0, 0.0, true);
+ BLI_addtail(cache, col);
}
DEG_OBJECT_ITER_END;
return cache;
@@ -734,26 +740,27 @@ static void cloth_brush_solve_collision(Object *object,
&col,
raycast_flag);
- if (hit.index != -1) {
-
- float collision_disp[3];
- float movement_disp[3];
- mul_v3_v3fl(collision_disp, hit.no, 0.005f);
- sub_v3_v3v3(movement_disp, pos_world_space, prev_pos_world_space);
- float friction_plane[4];
- float pos_on_friction_plane[3];
- plane_from_point_normal_v3(friction_plane, hit.co, hit.no);
- closest_to_plane_v3(pos_on_friction_plane, friction_plane, pos_world_space);
- sub_v3_v3v3(movement_disp, pos_on_friction_plane, hit.co);
-
- /* TODO(pablodp606): This can be exposed in a brush/filter property as friction. */
- mul_v3_fl(movement_disp, 0.35f);
-
- copy_v3_v3(cloth_sim->pos[i], hit.co);
- add_v3_v3(cloth_sim->pos[i], movement_disp);
- add_v3_v3(cloth_sim->pos[i], collision_disp);
- mul_v3_m4v3(cloth_sim->pos[i], obmat_inv, cloth_sim->pos[i]);
+ if (hit.index == -1) {
+ continue;
}
+
+ float collision_disp[3];
+ float movement_disp[3];
+ mul_v3_v3fl(collision_disp, hit.no, 0.005f);
+ sub_v3_v3v3(movement_disp, pos_world_space, prev_pos_world_space);
+ float friction_plane[4];
+ float pos_on_friction_plane[3];
+ plane_from_point_normal_v3(friction_plane, hit.co, hit.no);
+ closest_to_plane_v3(pos_on_friction_plane, friction_plane, pos_world_space);
+ sub_v3_v3v3(movement_disp, pos_on_friction_plane, hit.co);
+
+ /* TODO(pablodp606): This can be exposed in a brush/filter property as friction. */
+ mul_v3_fl(movement_disp, 0.35f);
+
+ copy_v3_v3(cloth_sim->pos[i], hit.co);
+ add_v3_v3(cloth_sim->pos[i], movement_disp);
+ add_v3_v3(cloth_sim->pos[i], collision_disp);
+ mul_v3_m4v3(cloth_sim->pos[i], obmat_inv, cloth_sim->pos[i]);
}
}
@@ -784,38 +791,40 @@ static void do_cloth_brush_solve_simulation_task_cb_ex(
ss->cache ? cloth_brush_simulation_falloff_get(
brush, ss->cache->radius, sim_location, cloth_sim->init_pos[vd.index]) :
1.0f;
- if (sim_factor > 0.0f) {
- int i = vd.index;
- float temp[3];
- copy_v3_v3(temp, cloth_sim->pos[i]);
+ if (sim_factor <= 0.0f) {
+ continue;
+ }
- mul_v3_fl(cloth_sim->acceleration[i], time_step);
+ int i = vd.index;
+ float temp[3];
+ copy_v3_v3(temp, cloth_sim->pos[i]);
- float pos_diff[3];
- sub_v3_v3v3(pos_diff, cloth_sim->pos[i], cloth_sim->prev_pos[i]);
- mul_v3_fl(pos_diff, (1.0f - cloth_sim->damping) * sim_factor);
+ mul_v3_fl(cloth_sim->acceleration[i], time_step);
- const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) *
- SCULPT_automasking_factor_get(automasking, ss, vd.index);
+ float pos_diff[3];
+ sub_v3_v3v3(pos_diff, cloth_sim->pos[i], cloth_sim->prev_pos[i]);
+ mul_v3_fl(pos_diff, (1.0f - cloth_sim->damping) * sim_factor);
- madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
- madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
+ const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) *
+ SCULPT_automasking_factor_get(automasking, ss, vd.index);
- if (cloth_sim->collider_list != NULL) {
- cloth_brush_solve_collision(data->ob, cloth_sim, i);
- }
+ madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
+ madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
- copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
+ if (cloth_sim->collider_list != NULL) {
+ cloth_brush_solve_collision(data->ob, cloth_sim, i);
+ }
- copy_v3_v3(cloth_sim->prev_pos[i], temp);
- copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
- copy_v3_fl(cloth_sim->acceleration[i], 0.0f);
+ copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
- copy_v3_v3(vd.co, cloth_sim->pos[vd.index]);
+ copy_v3_v3(cloth_sim->prev_pos[i], temp);
+ copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
+ copy_v3_fl(cloth_sim->acceleration[i], 0.0f);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ copy_v3_v3(vd.co, cloth_sim->pos[vd.index]);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.c b/source/blender/editors/sculpt_paint/sculpt_detail.c
index aa1d407dc24..ddf7ba1e412 100644
--- a/source/blender/editors/sculpt_paint/sculpt_detail.c
+++ b/source/blender/editors/sculpt_paint/sculpt_detail.c
@@ -24,46 +24,29 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_hash.h"
#include "BLI_math.h"
-#include "BLI_task.h"
#include "BLT_translation.h"
#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "BKE_brush.h"
#include "BKE_context.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_mapping.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
-#include "BKE_scene.h"
#include "BKE_screen.h"
#include "DEG_depsgraph.h"
#include "WM_api.h"
-#include "WM_message.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_sculpt.h"
#include "ED_view3d.h"
-#include "paint_intern.h"
#include "sculpt_intern.h"
#include "RNA_access.h"
#include "RNA_define.h"
-#include "UI_interface.h"
-
-#include "bmesh.h"
-
#include <math.h>
#include <stdlib.h>
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index 1fba958d695..df03d2adeaf 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -148,40 +148,42 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
float poly_center[3];
BKE_mesh_calc_poly_center(p, &ss->mloop[p->loopstart], mvert, poly_center);
- if (sculpt_brush_test_sq_fn(&test, poly_center)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- if (fade > 0.05f && ss->face_sets[vert_map->indices[j]] > 0) {
- ss->face_sets[vert_map->indices[j]] = abs(ss->cache->paint_face_set);
- }
+ if (!sculpt_brush_test_sq_fn(&test, poly_center)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ if (fade > 0.05f && ss->face_sets[vert_map->indices[j]] > 0) {
+ ss->face_sets[vert_map->indices[j]] = abs(ss->cache->paint_face_set);
}
}
}
else if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- if (fade > 0.05f) {
- SCULPT_vertex_face_set_set(ss, vd.index, ss->cache->paint_face_set);
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ if (fade > 0.05f) {
+ SCULPT_vertex_face_set_set(ss, vd.index, ss->cache->paint_face_set);
}
}
}
@@ -205,7 +207,7 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const bool relax_face_sets = !(ss->cache->iteration_count % 3 == 0);
- /* This operations needs a stregth tweak as the relax deformation is too weak by default. */
+ /* This operations needs a strength tweak as the relax deformation is too weak by default. */
if (relax_face_sets) {
bstrength *= 2.0f;
}
@@ -214,23 +216,26 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- if (relax_face_sets != SCULPT_vertex_has_unique_face_set(ss, vd.index)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ if (relax_face_sets == SCULPT_vertex_has_unique_face_set(ss, vd.index)) {
+ continue;
+ }
- SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co);
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -313,7 +318,7 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
const int mode = RNA_enum_get(op->ptr, "mode");
- /* Dyntopo not suported. */
+ /* Dyntopo not supported. */
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
return OPERATOR_CANCELLED;
}
@@ -582,44 +587,49 @@ static void sculpt_face_sets_init_flood_fill(Object *ob,
int next_face_set = 1;
for (int i = 0; i < totfaces; i++) {
- if (!BLI_BITMAP_TEST(visited_faces, i)) {
- GSQueue *queue;
- queue = BLI_gsqueue_new(sizeof(int));
-
- face_sets[i] = next_face_set;
- BLI_BITMAP_ENABLE(visited_faces, i);
- BLI_gsqueue_push(queue, &i);
-
- while (!BLI_gsqueue_is_empty(queue)) {
- int from_f;
- BLI_gsqueue_pop(queue, &from_f);
-
- BMFace *f, *f_neighbor;
- BMEdge *ed;
- BMIter iter_a, iter_b;
-
- f = BM_face_at_index(bm, from_f);
-
- BM_ITER_ELEM (ed, &iter_a, f, BM_EDGES_OF_FACE) {
- BM_ITER_ELEM (f_neighbor, &iter_b, ed, BM_FACES_OF_EDGE) {
- if (f_neighbor != f) {
- int neighbor_face_index = BM_elem_index_get(f_neighbor);
- if (!BLI_BITMAP_TEST(visited_faces, neighbor_face_index)) {
- if (test(bm, f, ed, f_neighbor, threshold)) {
- face_sets[neighbor_face_index] = next_face_set;
- BLI_BITMAP_ENABLE(visited_faces, neighbor_face_index);
- BLI_gsqueue_push(queue, &neighbor_face_index);
- }
- }
- }
+ if (BLI_BITMAP_TEST(visited_faces, i)) {
+ continue;
+ }
+ GSQueue *queue;
+ queue = BLI_gsqueue_new(sizeof(int));
+
+ face_sets[i] = next_face_set;
+ BLI_BITMAP_ENABLE(visited_faces, i);
+ BLI_gsqueue_push(queue, &i);
+
+ while (!BLI_gsqueue_is_empty(queue)) {
+ int from_f;
+ BLI_gsqueue_pop(queue, &from_f);
+
+ BMFace *f, *f_neighbor;
+ BMEdge *ed;
+ BMIter iter_a, iter_b;
+
+ f = BM_face_at_index(bm, from_f);
+
+ BM_ITER_ELEM (ed, &iter_a, f, BM_EDGES_OF_FACE) {
+ BM_ITER_ELEM (f_neighbor, &iter_b, ed, BM_FACES_OF_EDGE) {
+ if (f_neighbor == f) {
+ continue;
}
+ int neighbor_face_index = BM_elem_index_get(f_neighbor);
+ if (BLI_BITMAP_TEST(visited_faces, neighbor_face_index)) {
+ continue;
+ }
+ if (!test(bm, f, ed, f_neighbor, threshold)) {
+ continue;
+ }
+
+ face_sets[neighbor_face_index] = next_face_set;
+ BLI_BITMAP_ENABLE(visited_faces, neighbor_face_index);
+ BLI_gsqueue_push(queue, &neighbor_face_index);
}
}
+ }
- next_face_set += 1;
+ next_face_set += 1;
- BLI_gsqueue_free(queue);
- }
+ BLI_gsqueue_free(queue);
}
MEM_SAFE_FREE(visited_faces);
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
index e11894a8c01..3cf6a8cc561 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
@@ -553,7 +553,7 @@ static void mesh_filter_sharpen_init(SculptSession *ss,
filter_cache->sharpen_factor[i] = 1.0f - pow2f(1.0f - filter_cache->sharpen_factor[i]);
}
- /* Smooth the calculated factors and directions to remove high frecuency detail. */
+ /* Smooth the calculated factors and directions to remove high frequency detail. */
for (int smooth_iterations = 0;
smooth_iterations < filter_cache->sharpen_curvature_smooth_iterations;
smooth_iterations++) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index d1e17c7e59b..f90cf366ed9 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -511,7 +511,7 @@ void SCULPT_boundary_edges_preview_draw(const uint gpuattr,
const float outline_alpha);
void SCULPT_boundary_pivot_line_preview_draw(const uint gpuattr, struct SculptSession *ss);
-/* Multiplane Scrape Brush. */
+/* Multi-plane Scrape Brush. */
void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr,
Brush *brush,
diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
index e47a94dff90..cfc31e1dcdd 100644
--- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
+++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
@@ -88,38 +88,39 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float local_co[3];
- float normal[3];
- if (vd.no) {
- normal_short_to_float_v3(normal, vd.no);
- }
- else {
- copy_v3_v3(normal, vd.fno);
- }
- mul_v3_m4v3(local_co, mat, vd.co);
- /* Use the brush falloff to weight the sampled normals. */
- const float fade = SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- /* Sample the normal and area of the +X and -X axis individually. */
- if (local_co[0] > 0.0f) {
- madd_v3_v3fl(mssd->area_nos[0], normal, fade);
- add_v3_v3(mssd->area_cos[0], vd.co);
- mssd->area_count[0]++;
- }
- else {
- madd_v3_v3fl(mssd->area_nos[1], normal, fade);
- add_v3_v3(mssd->area_cos[1], vd.co);
- mssd->area_count[1]++;
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ float local_co[3];
+ float normal[3];
+ if (vd.no) {
+ normal_short_to_float_v3(normal, vd.no);
+ }
+ else {
+ copy_v3_v3(normal, vd.fno);
+ }
+ mul_v3_m4v3(local_co, mat, vd.co);
+ /* Use the brush falloff to weight the sampled normals. */
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ /* Sample the normal and area of the +X and -X axis individually. */
+ if (local_co[0] > 0.0f) {
+ madd_v3_v3fl(mssd->area_nos[0], normal, fade);
+ add_v3_v3(mssd->area_cos[0], vd.co);
+ mssd->area_count[0]++;
+ }
+ else {
+ madd_v3_v3fl(mssd->area_nos[1], normal, fade);
+ add_v3_v3(mssd->area_cos[1], vd.co);
+ mssd->area_count[1]++;
}
BKE_pbvh_vertex_iter_end;
}
@@ -168,56 +169,61 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- float local_co[3];
- bool deform = false;
-
- mul_v3_m4v3(local_co, mat, vd.co);
-
- if (local_co[0] > 0.0f) {
- deform = !SCULPT_plane_point_side(vd.co, scrape_planes[0]);
- }
- else {
- deform = !SCULPT_plane_point_side(vd.co, scrape_planes[1]);
- }
-
- if (angle < 0.0f) {
- deform = true;
- }
-
- if (deform) {
- float intr[3];
- float val[3];
-
- if (local_co[0] > 0.0f) {
- closest_to_plane_normalized_v3(intr, scrape_planes[0], vd.co);
- }
- else {
- closest_to_plane_normalized_v3(intr, scrape_planes[1], vd.co);
- }
-
- sub_v3_v3v3(val, intr, vd.co);
- if (SCULPT_plane_trim(ss->cache, brush, val)) {
- /* Deform the local space along the Y axis to avoid artifacts on curved strokes. */
- /* This produces a not round brush tip. */
- local_co[1] *= 2.0f;
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- len_v3(local_co),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- mul_v3_v3fl(proxy[vd.i], val, fade);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+
+ float local_co[3];
+ bool deform = false;
+
+ mul_v3_m4v3(local_co, mat, vd.co);
+
+ if (local_co[0] > 0.0f) {
+ deform = !SCULPT_plane_point_side(vd.co, scrape_planes[0]);
+ }
+ else {
+ deform = !SCULPT_plane_point_side(vd.co, scrape_planes[1]);
+ }
+
+ if (angle < 0.0f) {
+ deform = true;
+ }
+
+ if (!deform) {
+ continue;
+ }
+
+ float intr[3];
+ float val[3];
+
+ if (local_co[0] > 0.0f) {
+ closest_to_plane_normalized_v3(intr, scrape_planes[0], vd.co);
+ }
+ else {
+ closest_to_plane_normalized_v3(intr, scrape_planes[1], vd.co);
+ }
+
+ sub_v3_v3v3(val, intr, vd.co);
+ if (!SCULPT_plane_trim(ss->cache, brush, val)) {
+ continue;
+ }
+ /* Deform the local space along the Y axis to avoid artifacts on curved strokes. */
+ /* This produces a not round brush tip. */
+ local_co[1] *= 2.0f;
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ len_v3(local_co),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ mul_v3_v3fl(proxy[vd.i], val, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
index 39320f3f558..5fdf8415f28 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -87,24 +87,25 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float smooth_color[4];
- SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
- blend_color_interpolate_float(vd.col, vd.col, smooth_color, fade);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float smooth_color[4];
+ SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
+ blend_color_interpolate_float(vd.col, vd.col, smooth_color, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -153,46 +154,49 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
distance_to_stroke_location = sqrtf(test.dist);
}
- if (affect_vertex) {
- float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- distance_to_stroke_location,
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- /* Density. */
- float noise = 1.0f;
- const float density = ss->cache->paint_brush.density;
- if (density < 1.0f) {
- const float hash_noise = BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index);
- if (hash_noise > density) {
- noise = density * hash_noise;
- fade = fade * noise;
- }
+ if (!affect_vertex) {
+ continue;
+ }
+
+ float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ distance_to_stroke_location,
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ /* Density. */
+ float noise = 1.0f;
+ const float density = ss->cache->paint_brush.density;
+ if (density < 1.0f) {
+ const float hash_noise = BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index);
+ if (hash_noise > density) {
+ noise = density * hash_noise;
+ fade = fade * noise;
}
+ }
- /* Brush paint color, brush test falloff and flow. */
- float paint_color[4];
- float wet_mix_color[4];
- float buffer_color[4];
+ /* Brush paint color, brush test falloff and flow. */
+ float paint_color[4];
+ float wet_mix_color[4];
+ float buffer_color[4];
- mul_v4_v4fl(paint_color, brush_color, fade * ss->cache->paint_brush.flow);
- mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * ss->cache->paint_brush.flow);
+ mul_v4_v4fl(paint_color, brush_color, fade * ss->cache->paint_brush.flow);
+ mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * ss->cache->paint_brush.flow);
- /* Interpolate with the wet_mix color for wet paint mixing. */
- blend_color_interpolate_float(
- paint_color, paint_color, wet_mix_color, ss->cache->paint_brush.wet_mix);
- blend_color_mix_float(color_buffer->color[vd.i], color_buffer->color[vd.i], paint_color);
+ /* Interpolate with the wet_mix color for wet paint mixing. */
+ blend_color_interpolate_float(
+ paint_color, paint_color, wet_mix_color, ss->cache->paint_brush.wet_mix);
+ blend_color_mix_float(color_buffer->color[vd.i], color_buffer->color[vd.i], paint_color);
- /* Final mix over the original color using brush alpha. */
- mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha);
+ /* Final mix over the original color using brush alpha. */
+ mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha);
+
+ IMB_blend_color_float(vd.col, orig_data.col, buffer_color, brush->blend);
- IMB_blend_color_float(vd.col, orig_data.col, buffer_color, brush->blend);
- }
CLAMP4(vd.col, 0.0f, 1.0f);
if (vd.mvert) {
@@ -225,10 +229,12 @@ static void do_sample_wet_paint_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- add_v4_v4(swptd->color, vd.col);
- swptd->tot_samples++;
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
}
+
+ add_v4_v4(swptd->color, vd.col);
+ swptd->tot_samples++;
}
BKE_pbvh_vertex_iter_end;
}
@@ -380,59 +386,61 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float current_disp[3];
- float current_disp_norm[3];
- float interp_color[4];
- copy_v4_v4(interp_color, ss->cache->prev_colors[vd.index]);
-
- switch (brush->smear_deform_type) {
- case BRUSH_SMEAR_DEFORM_DRAG:
- sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
- break;
- case BRUSH_SMEAR_DEFORM_PINCH:
- sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
- break;
- case BRUSH_SMEAR_DEFORM_EXPAND:
- sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
- break;
- }
- normalize_v3_v3(current_disp_norm, current_disp);
- mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
-
- SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
- float vertex_disp[3];
- float vertex_disp_norm[3];
- sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
- const float *neighbor_color = ss->cache->prev_colors[ni.index];
- normalize_v3_v3(vertex_disp_norm, vertex_disp);
- if (dot_v3v3(current_disp_norm, vertex_disp_norm) < 0.0f) {
- const float color_interp = clamp_f(
- -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
- float color_mix[4];
- copy_v4_v4(color_mix, neighbor_color);
- mul_v4_fl(color_mix, color_interp * fade);
- blend_color_mix_float(interp_color, interp_color, color_mix);
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float current_disp[3];
+ float current_disp_norm[3];
+ float interp_color[4];
+ copy_v4_v4(interp_color, ss->cache->prev_colors[vd.index]);
+
+ switch (brush->smear_deform_type) {
+ case BRUSH_SMEAR_DEFORM_DRAG:
+ sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
+ break;
+ case BRUSH_SMEAR_DEFORM_PINCH:
+ sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
+ break;
+ case BRUSH_SMEAR_DEFORM_EXPAND:
+ sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
+ break;
+ }
+ normalize_v3_v3(current_disp_norm, current_disp);
+ mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
+ float vertex_disp[3];
+ float vertex_disp_norm[3];
+ sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
+ const float *neighbor_color = ss->cache->prev_colors[ni.index];
+ normalize_v3_v3(vertex_disp_norm, vertex_disp);
+ if (dot_v3v3(current_disp_norm, vertex_disp_norm) >= 0.0f) {
+ continue;
}
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+ const float color_interp = clamp_f(
+ -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
+ float color_mix[4];
+ copy_v4_v4(color_mix, neighbor_color);
+ mul_v4_fl(color_mix, color_interp * fade);
+ blend_color_mix_float(interp_color, interp_color, color_mix);
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
- blend_color_interpolate_float(vd.col, ss->cache->prev_colors[vd.index], interp_color, fade);
+ blend_color_interpolate_float(vd.col, ss->cache->prev_colors[vd.index], interp_color, fade);
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index 1bf9ba60073..a85f805894b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -490,50 +490,52 @@ static bool pose_face_sets_floodfill_cb(
is_vertex_valid = SCULPT_vertex_has_face_set(ss, index, data->current_face_set);
}
- if (is_vertex_valid) {
-
- if (!BLI_BITMAP_TEST(data->is_weighted, index)) {
- data->pose_factor[index] = 1.0f;
- BLI_BITMAP_ENABLE(data->is_weighted, index);
- visit_next = true;
- }
-
- /* Fallback origin accumulation. */
- if (symmetry_check) {
- add_v3_v3(data->fallback_origin, SCULPT_vertex_co_get(ss, index));
- data->fallback_count++;
- }
-
- if (symmetry_check && !SCULPT_vertex_has_unique_face_set(ss, index)) {
+ if (!is_vertex_valid) {
+ return visit_next;
+ }
- /* We only add coordinates for calculating the origin when it is possible to go from this
- * vertex to another vertex in a valid face set for the next iteration. */
- bool count_as_boundary = false;
+ if (!BLI_BITMAP_TEST(data->is_weighted, index)) {
+ data->pose_factor[index] = 1.0f;
+ BLI_BITMAP_ENABLE(data->is_weighted, index);
+ visit_next = true;
+ }
- SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
- int next_face_set_candidate = SCULPT_vertex_face_set_get(ss, ni.index);
+ /* Fallback origin accumulation. */
+ if (symmetry_check) {
+ add_v3_v3(data->fallback_origin, SCULPT_vertex_co_get(ss, index));
+ data->fallback_count++;
+ }
- /* Check if we can get a valid face set for the next iteration from this neighbor. */
- if (SCULPT_vertex_has_unique_face_set(ss, ni.index) &&
- !BLI_gset_haskey(data->visited_face_sets, POINTER_FROM_INT(next_face_set_candidate))) {
- if (!data->next_face_set_found) {
- data->next_face_set = next_face_set_candidate;
- data->next_vertex = ni.index;
- data->next_face_set_found = true;
- }
- count_as_boundary = true;
- }
- }
- SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+ if (!symmetry_check || SCULPT_vertex_has_unique_face_set(ss, index)) {
+ return visit_next;
+ }
- /* Origin accumulation. */
- if (count_as_boundary) {
- add_v3_v3(data->pose_origin, SCULPT_vertex_co_get(ss, index));
- data->tot_co++;
+ /* We only add coordinates for calculating the origin when it is possible to go from this
+ * vertex to another vertex in a valid face set for the next iteration. */
+ bool count_as_boundary = false;
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
+ int next_face_set_candidate = SCULPT_vertex_face_set_get(ss, ni.index);
+
+ /* Check if we can get a valid face set for the next iteration from this neighbor. */
+ if (SCULPT_vertex_has_unique_face_set(ss, ni.index) &&
+ !BLI_gset_haskey(data->visited_face_sets, POINTER_FROM_INT(next_face_set_candidate))) {
+ if (!data->next_face_set_found) {
+ data->next_face_set = next_face_set_candidate;
+ data->next_vertex = ni.index;
+ data->next_face_set_found = true;
}
+ count_as_boundary = true;
}
}
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+ /* Origin accumulation. */
+ if (count_as_boundary) {
+ add_v3_v3(data->pose_origin, SCULPT_vertex_co_get(ss, index));
+ data->tot_co++;
+ }
return visit_next;
}
@@ -738,7 +740,7 @@ static SculptPoseIKChain *pose_ik_chain_init_topology(Sculpt *sd,
* iteration an the current iteration. */
for (int j = 0; j < totvert; j++) {
ik_chain->segments[i].weights[j] = pose_factor_grow[j] - pose_factor_grow_prev[j];
- /* Store the current grow factor status for the next interation. */
+ /* Store the current grow factor status for the next iteration. */
pose_factor_grow_prev[j] = pose_factor_grow[j];
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index 87ee7480c92..4c0795eb0f7 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -231,24 +231,26 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata,
const int thread_id = BLI_task_parallel_thread_id(tls);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float disp[3];
- madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade);
- SCULPT_clip(sd, ss, vd.co, disp);
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float disp[3];
+ madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade);
+ SCULPT_clip(sd, ss, vd.co, disp);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -312,33 +314,34 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(
- ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
- vd.index,
- thread_id);
- if (smooth_mask) {
- float val = SCULPT_neighbor_mask_average(ss, vd.index) - *vd.mask;
- val *= fade * bstrength;
- *vd.mask += val;
- CLAMP(*vd.mask, 0.0f, 1.0f);
- }
- else {
- float avg[3], val[3];
- SCULPT_neighbor_coords_average_interior(ss, avg, vd.index);
- sub_v3_v3v3(val, avg, vd.co);
- madd_v3_v3v3fl(val, vd.co, val, fade);
- SCULPT_clip(sd, ss, vd.co, val);
- }
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(
+ ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
+ vd.index,
+ thread_id);
+ if (smooth_mask) {
+ float val = SCULPT_neighbor_mask_average(ss, vd.index) - *vd.mask;
+ val *= fade * bstrength;
+ *vd.mask += val;
+ CLAMP(*vd.mask, 0.0f, 1.0f);
+ }
+ else {
+ float avg[3], val[3];
+ SCULPT_neighbor_coords_average_interior(ss, avg, vd.index);
+ sub_v3_v3v3(val, avg, vd.co);
+ madd_v3_v3v3fl(val, vd.co, val, fade);
+ SCULPT_clip(sd, ss, vd.co, val);
+ }
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
@@ -473,32 +476,28 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
-
- float disp[3];
- SCULPT_surface_smooth_laplacian_step(ss,
- disp,
- vd.co,
- ss->cache->surface_smooth_laplacian_disp,
- vd.index,
- orig_data.co,
- alpha);
- madd_v3_v3fl(vd.co, disp, clamp_f(fade, 0.0f, 1.0f));
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
+ }
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float disp[3];
+ SCULPT_surface_smooth_laplacian_step(
+ ss, disp, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, orig_data.co, alpha);
+ madd_v3_v3fl(vd.co, disp, clamp_f(fade, 0.0f, 1.0f));
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
- BKE_pbvh_vertex_iter_end;
}
+ BKE_pbvh_vertex_iter_end;
}
static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
@@ -519,19 +518,20 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
- SCULPT_surface_smooth_displace_step(
- ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, beta, fade);
+ if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+ continue;
}
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ SCULPT_surface_smooth_displace_step(
+ ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, beta, fade);
}
BKE_pbvh_vertex_iter_end;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 938080b392d..ec103bd2b98 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -1527,9 +1527,14 @@ static void sculpt_undosys_step_decode_redo(struct bContext *C,
}
}
-static void sculpt_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int dir, bool UNUSED(is_final))
+static void sculpt_undosys_step_decode(struct bContext *C,
+ struct Main *bmain,
+ UndoStep *us_p,
+ const eUndoStepDir dir,
+ bool UNUSED(is_final))
{
+ BLI_assert(dir != STEP_INVALID);
+
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
/* Ensure sculpt mode. */
@@ -1568,10 +1573,10 @@ static void sculpt_undosys_step_decode(
}
SculptUndoStep *us = (SculptUndoStep *)us_p;
- if (dir < 0) {
+ if (dir == STEP_UNDO) {
sculpt_undosys_step_decode_undo(C, depsgraph, us);
}
- else {
+ else if (dir == STEP_REDO) {
sculpt_undosys_step_decode_redo(C, depsgraph, us);
}
}
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 34617804888..85616f6356d 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -31,7 +31,6 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
@@ -877,7 +876,7 @@ static void SOUND_OT_unpack(wmOperatorType *ot)
/* properties */
RNA_def_enum(
ot->srna, "method", rna_enum_unpack_method_items, PF_USE_LOCAL, "Method", "How to unpack");
- /* XXX, weark!, will fail with library, name collisions */
+ /* XXX: weak!, will fail with library, name collisions */
RNA_def_string(
ot->srna, "id", NULL, MAX_ID_NAME - 2, "Sound Name", "Sound data-block name to unpack");
}
diff --git a/source/blender/editors/space_action/action_buttons.c b/source/blender/editors/space_action/action_buttons.c
index 5e1c205f1d4..dfc3789a26c 100644
--- a/source/blender/editors/space_action/action_buttons.c
+++ b/source/blender/editors/space_action/action_buttons.c
@@ -26,33 +26,10 @@
#include <stdio.h>
#include <string.h>
-#include "DNA_anim_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
-#include "BLT_translation.h"
-
#include "BKE_context.h"
-#include "BKE_curve.h"
-#include "BKE_fcurve.h"
#include "BKE_screen.h"
-#include "BKE_unit.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-#include "RNA_access.h"
-
-#include "ED_anim_api.h"
-#include "ED_keyframing.h"
-#include "ED_screen.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
#include "action_intern.h" /* own include */
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index f731fe23b7c..f8389d40831 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -73,7 +73,7 @@
/* ************************************************************************** */
/* POSE MARKERS STUFF */
-/* *************************** Localise Markers ***************************** */
+/* *************************** Localize Markers ***************************** */
/* ensure that there is:
* 1) an active action editor
@@ -322,7 +322,7 @@ static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *min,
bAnimListElem *ale;
int filter;
- /* NOTE: not bool, since we want prioritise individual channels over expanders */
+ /* NOTE: not bool, since we want prioritize individual channels over expanders. */
short found = 0;
/* get all items - we need to do it this way */
@@ -346,7 +346,7 @@ static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *min,
found = acf->channel_role;
/* only stop our search when we've found an actual channel
- * - datablock expanders get less priority so that we don't abort prematurely
+ * - data-block expanders get less priority so that we don't abort prematurely
*/
if (found == ACHANNEL_ROLE_CHANNEL) {
break;
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index 7422c05511c..7821458d1e5 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -27,9 +27,6 @@
#include "DNA_space_types.h"
#include "ED_anim_api.h"
-#include "ED_markers.h"
-#include "ED_object.h"
-#include "ED_select_utils.h"
#include "ED_transform.h"
#include "action_intern.h"
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index ff0201f9702..722005235d3 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -55,7 +55,6 @@
#include "ED_space_api.h"
#include "ED_time_scrub_ui.h"
-#include "GPU_framebuffer.h"
#include "action_intern.h" /* own include */
/* ******************** default callbacks for action space ***************** */
@@ -305,12 +304,11 @@ static void action_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void action_channel_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void action_channel_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -356,14 +354,13 @@ static void action_channel_region_listener(wmWindow *UNUSED(win),
}
}
-static void saction_channel_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void saction_channel_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, area->spacedata.first, &ptr);
@@ -401,12 +398,11 @@ static void saction_channel_region_message_subscribe(const struct bContext *UNUS
}
}
-static void action_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void action_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -460,14 +456,14 @@ static void action_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void saction_main_region_message_subscribe(const struct bContext *C,
- struct WorkSpace *workspace,
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void saction_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ Scene *scene = params->scene;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, area->spacedata.first, &ptr);
@@ -502,15 +498,14 @@ static void saction_main_region_message_subscribe(const struct bContext *C,
}
/* Now run the general "channels region" one - since channels and main should be in sync */
- saction_channel_region_message_subscribe(C, workspace, scene, screen, area, region, mbus);
+ saction_channel_region_message_subscribe(params);
}
/* editor level listener */
-static void action_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void action_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceAction *saction = (SpaceAction *)area->spacedata.first;
/* context changes */
@@ -660,12 +655,11 @@ static void action_listener(wmWindow *UNUSED(win),
}
}
-static void action_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void action_header_region_listener(const wmRegionListenerParams *params)
{
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
SpaceAction *saction = (SpaceAction *)area->spacedata.first;
/* context changes */
@@ -737,12 +731,11 @@ static void action_buttons_area_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void action_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void action_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 10fa2c19919..817760615df 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -70,16 +70,13 @@
#include "io_ops.h"
-/* only call once on startup, storage is global in BKE kernel listbase */
+/* Only called once on startup. storage is global in BKE kernel listbase. */
void ED_spacetypes_init(void)
{
- const ListBase *spacetypes;
- SpaceType *type;
-
- /* UI_UNIT_X is now a variable, is used in some spacetype inits? */
+ /* UI unit is a variable, may be used in some space type inits. */
U.widget_unit = 20;
- /* create space types */
+ /* Create space types. */
ED_spacetype_outliner();
ED_spacetype_view3d();
ED_spacetype_ipo();
@@ -98,9 +95,8 @@ void ED_spacetypes_init(void)
ED_spacetype_clip();
ED_spacetype_statusbar();
ED_spacetype_topbar();
- // ...
- /* register operator types for screen and all spaces */
+ /* Register operator types for screen and all spaces. */
ED_operatortypes_userpref();
ED_operatortypes_workspace();
ED_operatortypes_scene();
@@ -132,7 +128,7 @@ void ED_spacetypes_init(void)
ED_screen_user_menu_register();
- /* gizmo types */
+ /* Gizmo types. */
ED_gizmotypes_button_2d();
ED_gizmotypes_dial_3d();
ED_gizmotypes_move_3d();
@@ -144,10 +140,10 @@ void ED_spacetypes_init(void)
ED_gizmotypes_cage_3d();
ED_gizmotypes_snap_3d();
- /* register types for operators and gizmos */
- spacetypes = BKE_spacetypes_list();
- for (type = spacetypes->first; type; type = type->next) {
- /* init gizmo types first, operator-types need them */
+ /* Register types for operators and gizmos. */
+ const ListBase *spacetypes = BKE_spacetypes_list();
+ LISTBASE_FOREACH (const SpaceType *, type, spacetypes) {
+ /* Initialize gizmo types first, operator types need them. */
if (type->gizmos) {
type->gizmos();
}
@@ -159,11 +155,8 @@ void ED_spacetypes_init(void)
void ED_spacemacros_init(void)
{
- const ListBase *spacetypes;
- SpaceType *type;
-
- /* Macros's must go last since they reference other operators.
- * We need to have them go after python operators too */
+ /* Macros must go last since they reference other operators.
+ * They need to be registered after python operators too. */
ED_operatormacros_armature();
ED_operatormacros_mesh();
ED_operatormacros_uvedit();
@@ -180,24 +173,21 @@ void ED_spacemacros_init(void)
ED_operatormacros_paint();
ED_operatormacros_gpencil();
- /* register dropboxes (can use macros) */
- spacetypes = BKE_spacetypes_list();
- for (type = spacetypes->first; type; type = type->next) {
+ /* Register dropboxes (can use macros). */
+ const ListBase *spacetypes = BKE_spacetypes_list();
+ LISTBASE_FOREACH (const SpaceType *, type, spacetypes) {
if (type->dropboxes) {
type->dropboxes();
}
}
}
-/* called in wm.c */
-/* keymap definitions are registered only once per WM initialize, usually on file read,
- * using the keymap the actual areas/regions add the handlers */
+/**
+ * \note Keymap definitions are registered only once per WM initialize,
+ * usually on file read, using the keymap the actual areas/regions add the handlers.
+ * \note Called in wm.c. */
void ED_spacetypes_keymap(wmKeyConfig *keyconf)
{
- const ListBase *spacetypes;
- SpaceType *stype;
- ARegionType *atype;
-
ED_keymap_screen(keyconf);
ED_keymap_anim(keyconf);
ED_keymap_animchannels(keyconf);
@@ -219,20 +209,20 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf)
ED_keymap_transform(keyconf);
- spacetypes = BKE_spacetypes_list();
- for (stype = spacetypes->first; stype; stype = stype->next) {
- if (stype->keymap) {
- stype->keymap(keyconf);
+ const ListBase *spacetypes = BKE_spacetypes_list();
+ LISTBASE_FOREACH (const SpaceType *, type, spacetypes) {
+ if (type->keymap) {
+ type->keymap(keyconf);
}
- for (atype = stype->regiontypes.first; atype; atype = atype->next) {
- if (atype->keymap) {
- atype->keymap(keyconf);
+ LISTBASE_FOREACH (ARegionType *, region_type, &type->regiontypes) {
+ if (region_type->keymap) {
+ region_type->keymap(keyconf);
}
}
}
}
-/* ********************** custom drawcall api ***************** */
+/* ********************** Custom Draw Call API ***************** */
typedef struct RegionDrawCB {
struct RegionDrawCB *next, *prev;
@@ -261,9 +251,7 @@ void *ED_region_draw_cb_activate(ARegionType *art,
void ED_region_draw_cb_exit(ARegionType *art, void *handle)
{
- RegionDrawCB *rdc;
-
- for (rdc = art->drawcalls.first; rdc; rdc = rdc->next) {
+ LISTBASE_FOREACH (RegionDrawCB *, rdc, &art->drawcalls) {
if (rdc == (RegionDrawCB *)handle) {
BLI_remlink(&art->drawcalls, rdc);
MEM_freeN(rdc);
@@ -274,9 +262,7 @@ void ED_region_draw_cb_exit(ARegionType *art, void *handle)
void ED_region_draw_cb_draw(const bContext *C, ARegion *region, int type)
{
- RegionDrawCB *rdc;
-
- for (rdc = region->type->drawcalls.first; rdc; rdc = rdc->next) {
+ LISTBASE_FOREACH (RegionDrawCB *, rdc, &region->type->drawcalls) {
if (rdc->type == type) {
rdc->draw(C, region, rdc->customdata);
@@ -301,7 +287,7 @@ static void xxx_free(SpaceLink *UNUSED(sl))
{
}
-/* spacetype; init callback for usage, should be redoable */
+/* spacetype; init callback for usage, should be re-doable. */
static void xxx_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(area))
{
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index e2b889bece1..5f347451c4a 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -33,8 +33,6 @@
#include "DNA_armature_types.h"
#include "DNA_brush_types.h"
-#include "DNA_collection_types.h"
-#include "DNA_light_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_material_types.h"
#include "DNA_node_types.h"
@@ -53,7 +51,6 @@
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_screen.h"
-#include "BKE_texture.h"
#include "RNA_access.h"
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 6f743eb1a6b..4847e8738df 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -52,10 +52,7 @@
#include "BKE_node.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
-#include "BKE_scene.h"
-#include "BKE_workspace.h"
#ifdef WITH_FREESTYLE
-# include "BKE_freestyle.h"
#endif
#include "RNA_access.h"
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index e50ca2ec92b..07bc1d42c3f 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -514,12 +514,11 @@ static void buttons_main_region_layout(const bContext *C, ARegion *region)
sbuts->mainbo = sbuts->mainb;
}
-static void buttons_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void buttons_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCREEN:
@@ -567,15 +566,13 @@ static void buttons_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void buttons_header_region_message_subscribe(const bContext *UNUSED(C),
- WorkSpace *UNUSED(workspace),
- Scene *UNUSED(scene),
- bScreen *UNUSED(screen),
- ScrArea *area,
- ARegion *region,
- struct wmMsgBus *mbus)
+static void buttons_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
SpaceProperties *sbuts = area->spacedata.first;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
@@ -621,14 +618,12 @@ static void buttons_navigation_bar_region_draw(const bContext *C, ARegion *regio
ED_region_panels_draw(C, region);
}
-static void buttons_navigation_bar_region_message_subscribe(const bContext *UNUSED(C),
- WorkSpace *UNUSED(workspace),
- Scene *UNUSED(scene),
- bScreen *UNUSED(screen),
- ScrArea *UNUSED(area),
- ARegion *region,
- struct wmMsgBus *mbus)
+static void buttons_navigation_bar_region_message_subscribe(
+ const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
@@ -657,11 +652,10 @@ static void buttons_area_redraw(ScrArea *area, short buttons)
* \{ */
/* reused! */
-static void buttons_area_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void buttons_area_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceProperties *sbuts = area->spacedata.first;
/* context changes */
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index 81bae26efeb..632f3c5147f 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -46,7 +46,6 @@
#include "DEG_depsgraph.h"
#include "ED_clip.h"
-#include "ED_gpencil.h"
#include "ED_screen.h"
#include "UI_interface.h"
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index bd11a746e11..af1d082d317 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -327,118 +327,18 @@ void ED_clip_update_frame(const Main *mainp, int cfra)
}
}
-static bool selected_tracking_boundbox(SpaceClip *sc, float min[2], float max[2])
+bool ED_clip_view_selection(const bContext *C, ARegion *UNUSED(region), bool fit)
{
- MovieClip *clip = ED_space_clip_get_clip(sc);
- MovieTrackingTrack *track;
- int width, height;
- bool ok = false;
- ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
- int framenr = ED_space_clip_get_clip_frame_number(sc);
-
- INIT_MINMAX2(min, max);
-
- ED_space_clip_get_size(sc, &width, &height);
-
- track = tracksbase->first;
- while (track) {
- if (TRACK_VIEW_SELECTED(sc, track)) {
- MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
-
- if (marker) {
- float pos[3];
-
- pos[0] = marker->pos[0] + track->offset[0];
- pos[1] = marker->pos[1] + track->offset[1];
- pos[2] = 0.0f;
-
- /* undistortion happens for normalized coords */
- if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
- /* undistortion happens for normalized coords */
- ED_clip_point_undistorted_pos(sc, pos, pos);
- }
-
- pos[0] *= width;
- pos[1] *= height;
-
- mul_v3_m4v3(pos, sc->stabmat, pos);
-
- minmax_v2v2_v2(min, max, pos);
-
- ok = true;
- }
- }
-
- track = track->next;
- }
-
- return ok;
-}
-
-static bool selected_boundbox(const bContext *C, float min[2], float max[2])
-{
- SpaceClip *sc = CTX_wm_space_clip(C);
- if (sc->mode == SC_MODE_TRACKING) {
- return selected_tracking_boundbox(sc, min, max);
- }
-
- if (ED_mask_selected_minmax(C, min, max)) {
- MovieClip *clip = ED_space_clip_get_clip(sc);
- int width, height;
- ED_space_clip_get_size(sc, &width, &height);
- BKE_mask_coord_to_movieclip(clip, &sc->user, min, min);
- BKE_mask_coord_to_movieclip(clip, &sc->user, max, max);
- min[0] *= width;
- min[1] *= height;
- max[0] *= width;
- max[1] *= height;
- return true;
- }
- return false;
-}
-
-bool ED_clip_view_selection(const bContext *C, ARegion *region, bool fit)
-{
- SpaceClip *sc = CTX_wm_space_clip(C);
- int w, h, frame_width, frame_height;
- float min[2], max[2];
-
- ED_space_clip_get_size(sc, &frame_width, &frame_height);
-
- if ((frame_width == 0) || (frame_height == 0) || (sc->clip == NULL)) {
+ float offset_x, offset_y;
+ float zoom;
+ if (!clip_view_calculate_view_selection(C, fit, &offset_x, &offset_y, &zoom)) {
return false;
}
- if (!selected_boundbox(C, min, max)) {
- return false;
- }
-
- /* center view */
- clip_view_center_to_point(
- sc, (max[0] + min[0]) / (2 * frame_width), (max[1] + min[1]) / (2 * frame_height));
-
- w = max[0] - min[0];
- h = max[1] - min[1];
-
- /* set zoom to see all selection */
- if (w > 0 && h > 0) {
- int width, height;
- float zoomx, zoomy, newzoom, aspx, aspy;
-
- ED_space_clip_get_aspect(sc, &aspx, &aspy);
-
- width = BLI_rcti_size_x(&region->winrct) + 1;
- height = BLI_rcti_size_y(&region->winrct) + 1;
-
- zoomx = (float)width / w / aspx;
- zoomy = (float)height / h / aspy;
-
- newzoom = 1.0f / power_of_2(1.0f / min_ff(zoomx, zoomy));
-
- if (fit || sc->zoom > newzoom) {
- sc->zoom = newzoom;
- }
- }
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ sc->xof = offset_x;
+ sc->yof = offset_y;
+ sc->zoom = zoom;
return true;
}
@@ -1177,3 +1077,47 @@ void clip_start_prefetch_job(const bContext *C)
/* and finally start the job */
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
+
+void ED_clip_view_lock_state_store(const bContext *C, ClipViewLockState *state)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ BLI_assert(space_clip != NULL);
+
+ state->offset_x = space_clip->xof;
+ state->offset_y = space_clip->yof;
+ state->zoom = space_clip->zoom;
+
+ state->lock_offset_x = 0.0f;
+ state->lock_offset_y = 0.0f;
+
+ if ((space_clip->flag & SC_LOCK_SELECTION) == 0) {
+ return;
+ }
+
+ if (!clip_view_calculate_view_selection(
+ C, false, &state->offset_x, &state->offset_y, &state->zoom)) {
+ return;
+ }
+
+ state->lock_offset_x = space_clip->xlockof;
+ state->lock_offset_y = space_clip->ylockof;
+}
+
+void ED_clip_view_lock_state_restore_no_jump(const bContext *C, const ClipViewLockState *state)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ BLI_assert(space_clip != NULL);
+
+ if ((space_clip->flag & SC_LOCK_SELECTION) == 0) {
+ return;
+ }
+
+ float offset_x, offset_y;
+ float zoom;
+ if (!clip_view_calculate_view_selection(C, false, &offset_x, &offset_y, &zoom)) {
+ return;
+ }
+
+ space_clip->xlockof = state->offset_x + state->lock_offset_x - offset_x;
+ space_clip->ylockof = state->offset_y + state->lock_offset_y - offset_y;
+}
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index 4848ec72f79..202dc00e365 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -171,8 +171,15 @@ void clip_delete_plane_track(struct bContext *C,
struct MovieClip *clip,
struct MovieTrackingPlaneTrack *plane_track);
+void clip_view_offset_for_center_to_point(
+ SpaceClip *sc, const float x, const float y, float *r_offset_x, float *r_offset_y);
void clip_view_center_to_point(SpaceClip *sc, float x, float y);
+bool clip_view_calculate_view_selection(
+ const struct bContext *C, bool fit, float *r_offset_x, float *r_offset_y, float *r_zoom);
+
+bool clip_view_has_locked_selection(const struct bContext *C);
+
void clip_draw_sfra_efra(struct View2D *v2d, struct Scene *scene);
/* tracking_ops.c */
@@ -191,6 +198,7 @@ void CLIP_OT_clear_solution(struct wmOperatorType *ot);
void CLIP_OT_clear_track_path(struct wmOperatorType *ot);
void CLIP_OT_join_tracks(struct wmOperatorType *ot);
+void CLIP_OT_average_tracks(struct wmOperatorType *ot);
void CLIP_OT_disable_markers(struct wmOperatorType *ot);
void CLIP_OT_hide_tracks(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index cd4a1ffb526..38a05eef6e3 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -125,7 +125,7 @@ static void sclip_zoom_set(const bContext *C,
dx = ((location[0] - 0.5f) * w - sc->xof) * (sc->zoom - oldzoom) / sc->zoom;
dy = ((location[1] - 0.5f) * h - sc->yof) * (sc->zoom - oldzoom) / sc->zoom;
- if (sc->flag & SC_LOCK_SELECTION) {
+ if (clip_view_has_locked_selection(C)) {
sc->xlockof += dx;
sc->ylockof += dy;
}
@@ -396,7 +396,7 @@ static void view_pan_init(bContext *C, wmOperator *op, const wmEvent *event)
vpd->x = event->x;
vpd->y = event->y;
- if (sc->flag & SC_LOCK_SELECTION) {
+ if (clip_view_has_locked_selection(C)) {
vpd->vec = &sc->xlockof;
}
else {
@@ -434,7 +434,7 @@ static int view_pan_exec(bContext *C, wmOperator *op)
RNA_float_get_array(op->ptr, "offset", offset);
- if (sc->flag & SC_LOCK_SELECTION) {
+ if (clip_view_has_locked_selection(C)) {
sc->xlockof += offset[0];
sc->ylockof += offset[1];
}
@@ -569,7 +569,7 @@ static void view_zoom_init(bContext *C, wmOperator *op, const wmEvent *event)
WM_cursor_modal_set(win, WM_CURSOR_NSEW_SCROLL);
}
- if (U.viewzoom == USER_ZOOM_CONT) {
+ if (U.viewzoom == USER_ZOOM_CONTINUE) {
/* needs a timer to continue redrawing */
vpd->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
vpd->timer_lastdraw = PIL_check_seconds_timer();
@@ -662,7 +662,7 @@ static void view_zoom_apply(
delta = -delta;
}
- if (U.viewzoom == USER_ZOOM_CONT) {
+ if (U.viewzoom == USER_ZOOM_CONTINUE) {
SpaceClip *sclip = CTX_wm_space_clip(C);
double time = PIL_check_seconds_timer();
float time_step = (float)(time - vpd->timer_lastdraw);
@@ -1840,8 +1840,16 @@ void CLIP_OT_cursor_set(wmOperatorType *ot)
static int lock_selection_togglee_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceClip *space_clip = CTX_wm_space_clip(C);
+
+ ClipViewLockState lock_state;
+ ED_clip_view_lock_state_store(C, &lock_state);
+
space_clip->flag ^= SC_LOCK_SELECTION;
+
+ ED_clip_view_lock_state_restore_no_jump(C, &lock_state);
+
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_CLIP, NULL);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_clip/clip_toolbar.c b/source/blender/editors/space_clip/clip_toolbar.c
index b02f3fe16f6..da9e82043f0 100644
--- a/source/blender/editors/space_clip/clip_toolbar.c
+++ b/source/blender/editors/space_clip/clip_toolbar.c
@@ -23,29 +23,17 @@
#include <string.h>
-#include "DNA_windowmanager_types.h"
-#include "DNA_workspace_types.h"
-
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLT_translation.h"
-
#include "BKE_context.h"
#include "BKE_screen.h"
-#include "RNA_access.h"
-
-#include "WM_api.h"
#include "WM_types.h"
#include "ED_screen.h"
-#include "ED_undo.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
#include "clip_intern.h" /* own include */
diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c
index c7f2a027ba8..bb79eb34129 100644
--- a/source/blender/editors/space_clip/clip_utils.c
+++ b/source/blender/editors/space_clip/clip_utils.c
@@ -27,10 +27,12 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_rect.h"
#include "BLI_utildefines.h"
#include "BKE_animsys.h"
#include "BKE_context.h"
+#include "BKE_mask.h"
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
@@ -44,6 +46,7 @@
#include "WM_types.h"
#include "ED_clip.h"
+#include "ED_mask.h"
#include "ED_screen.h"
#include "UI_interface.h"
@@ -395,16 +398,232 @@ void clip_delete_plane_track(bContext *C, MovieClip *clip, MovieTrackingPlaneTra
DEG_id_tag_update(&clip->id, 0);
}
-void clip_view_center_to_point(SpaceClip *sc, float x, float y)
+/* 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)
{
int width, height;
+ ED_space_clip_get_size(sc, &width, &height);
+
float aspx, aspy;
+ ED_space_clip_get_aspect(sc, &aspx, &aspy);
+
+ *r_offset_x = (x - 0.5f) * width * aspx;
+ *r_offset_y = (y - 0.5f) * height * aspy;
+}
+
+void clip_view_center_to_point(SpaceClip *sc, float x, float y)
+{
+ clip_view_offset_for_center_to_point(sc, x, y, &sc->xof, &sc->yof);
+}
+
+static bool selected_tracking_boundbox(SpaceClip *sc, float min[2], float max[2])
+{
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ MovieTrackingTrack *track;
+ int width, height;
+ bool ok = false;
+ ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
+ int framenr = ED_space_clip_get_clip_frame_number(sc);
+
+ INIT_MINMAX2(min, max);
ED_space_clip_get_size(sc, &width, &height);
- ED_space_clip_get_aspect(sc, &aspx, &aspy);
- sc->xof = (x - 0.5f) * width * aspx;
- sc->yof = (y - 0.5f) * height * aspy;
+ track = tracksbase->first;
+ while (track) {
+ if (TRACK_VIEW_SELECTED(sc, track)) {
+ MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
+
+ if (marker) {
+ float pos[3];
+
+ pos[0] = marker->pos[0] + track->offset[0];
+ pos[1] = marker->pos[1] + track->offset[1];
+ pos[2] = 0.0f;
+
+ /* undistortion happens for normalized coords */
+ if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
+ /* undistortion happens for normalized coords */
+ ED_clip_point_undistorted_pos(sc, pos, pos);
+ }
+
+ pos[0] *= width;
+ pos[1] *= height;
+
+ mul_v3_m4v3(pos, sc->stabmat, pos);
+
+ minmax_v2v2_v2(min, max, pos);
+
+ ok = true;
+ }
+ }
+
+ track = track->next;
+ }
+
+ return ok;
+}
+
+static bool tracking_has_selection(SpaceClip *space_clip)
+{
+ MovieClip *clip = ED_space_clip_get_clip(space_clip);
+ ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
+ const int framenr = ED_space_clip_get_clip_frame_number(space_clip);
+
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
+ if (!TRACK_VIEW_SELECTED(space_clip, track)) {
+ continue;
+ }
+ const MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
+ if (marker != NULL) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool mask_has_selection(const bContext *C)
+{
+ Mask *mask = CTX_data_edit_mask(C);
+ if (mask == NULL) {
+ return false;
+ }
+
+ LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
+ if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+ continue;
+ }
+ LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
+ for (int i = 0; i < spline->tot_point; i++) {
+ const MaskSplinePoint *point = &spline->points[i];
+ const BezTriple *bezt = &point->bezt;
+ if (!MASKPOINT_ISSEL_ANY(point)) {
+ continue;
+ }
+ if (bezt->f2 & SELECT) {
+ return true;
+ }
+
+ if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) {
+ return true;
+ }
+ else {
+ if ((bezt->f1 & SELECT) && (bezt->h1 != HD_VECT)) {
+ return true;
+ }
+ if ((bezt->f3 & SELECT) && (bezt->h2 != HD_VECT)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool selected_boundbox(const bContext *C,
+ float min[2],
+ float max[2],
+ bool handles_as_control_point)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ if (sc->mode == SC_MODE_TRACKING) {
+ return selected_tracking_boundbox(sc, min, max);
+ }
+
+ if (ED_mask_selected_minmax(C, min, max, handles_as_control_point)) {
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ int width, height;
+ ED_space_clip_get_size(sc, &width, &height);
+ BKE_mask_coord_to_movieclip(clip, &sc->user, min, min);
+ BKE_mask_coord_to_movieclip(clip, &sc->user, max, max);
+ min[0] *= width;
+ min[1] *= height;
+ max[0] *= width;
+ max[1] *= height;
+ return true;
+ }
+ return false;
+}
+
+bool clip_view_calculate_view_selection(
+ const bContext *C, bool fit, float *r_offset_x, float *r_offset_y, float *r_zoom)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ int frame_width, frame_height;
+ ED_space_clip_get_size(sc, &frame_width, &frame_height);
+
+ if ((frame_width == 0) || (frame_height == 0) || (sc->clip == NULL)) {
+ return false;
+ }
+
+ /* NOTE: The `fit` argument is set to truth when doing "View to Selected" operator, and it set to
+ * false when this function is used for Lock-to-Selection functionality. When locking to
+ * selection the handles are to use control point position. So we can derive the
+ * `handles_as_control_point` from `fit`.
+ *
+ * TODO(sergey): Make such decision more explicit. Maybe pass use-case for the calculation to
+ * tell operator from lock-to-selection apart. */
+ float min[2], max[2];
+ if (!selected_boundbox(C, min, max, !fit)) {
+ return false;
+ }
+
+ /* center view */
+ clip_view_offset_for_center_to_point(sc,
+ (max[0] + min[0]) / (2 * frame_width),
+ (max[1] + min[1]) / (2 * frame_height),
+ r_offset_x,
+ r_offset_y);
+
+ const int w = max[0] - min[0];
+ const int h = max[1] - min[1];
+
+ /* set zoom to see all selection */
+ *r_zoom = sc->zoom;
+ if (w > 0 && h > 0) {
+ ARegion *region = CTX_wm_region(C);
+
+ int width, height;
+ float zoomx, zoomy, newzoom, aspx, aspy;
+
+ ED_space_clip_get_aspect(sc, &aspx, &aspy);
+
+ width = BLI_rcti_size_x(&region->winrct) + 1;
+ height = BLI_rcti_size_y(&region->winrct) + 1;
+
+ zoomx = (float)width / w / aspx;
+ zoomy = (float)height / h / aspy;
+
+ newzoom = 1.0f / power_of_2(1.0f / min_ff(zoomx, zoomy));
+
+ if (fit) {
+ *r_zoom = newzoom;
+ }
+ }
+
+ return true;
+}
+
+/* Returns truth if lock-to-selection is enabled and possible.
+ * Locking to selection is not possible if there is no selection. */
+bool clip_view_has_locked_selection(const bContext *C)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+
+ if ((space_clip->flag & SC_LOCK_SELECTION) == 0) {
+ return false;
+ }
+
+ if (space_clip->mode == SC_MODE_TRACKING) {
+ return tracking_has_selection(space_clip);
+ }
+
+ return mask_has_selection(C);
}
void clip_draw_sfra_efra(View2D *v2d, Scene *scene)
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 3bdf016b64c..2a7c64a83f7 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -47,15 +47,12 @@
#include "ED_clip.h"
#include "ED_mask.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "ED_space_api.h"
#include "ED_time_scrub_ui.h"
-#include "ED_transform.h"
#include "ED_uvedit.h" /* just for ED_image_draw_cursor */
#include "IMB_imbuf.h"
-#include "GPU_framebuffer.h"
#include "GPU_matrix.h"
#include "WM_api.h"
@@ -229,7 +226,7 @@ static void clip_scopes_check_gpencil_change(ScrArea *area)
}
}
-static void clip_area_sync_frame_from_scene(ScrArea *area, Scene *scene)
+static void clip_area_sync_frame_from_scene(ScrArea *area, const Scene *scene)
{
SpaceClip *space_clip = (SpaceClip *)area->spacedata.first;
BKE_movieclip_user_set_frame(&space_clip->user, scene->r.cfra);
@@ -334,8 +331,12 @@ static SpaceLink *clip_duplicate(SpaceLink *sl)
return (SpaceLink *)scn;
}
-static void clip_listener(wmWindow *UNUSED(win), ScrArea *area, wmNotifier *wmn, Scene *scene)
+static void clip_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
+ const Scene *scene = params->scene;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
@@ -514,6 +515,7 @@ static void clip_operatortypes(void)
/* clean-up */
WM_operatortype_append(CLIP_OT_clear_track_path);
WM_operatortype_append(CLIP_OT_join_tracks);
+ WM_operatortype_append(CLIP_OT_average_tracks);
WM_operatortype_append(CLIP_OT_track_copy_color);
WM_operatortype_append(CLIP_OT_clean_tracks);
@@ -988,7 +990,14 @@ static void clip_main_region_draw(const bContext *C, ARegion *region)
}
/* callback */
+ /* TODO(sergey): For being consistent with space image the projection needs to be configured
+ * the way how the commented out code does it. This works correct for tracking data, but it
+ * causes wrong aspect correction for mask editor (see T84990). */
+ // GPU_matrix_push_projection();
+ // wmOrtho2(region->v2d.cur.xmin, region->v2d.cur.xmax, region->v2d.cur.ymin,
+ // region->v2d.cur.ymax);
ED_region_draw_cb_draw(C, region, REGION_DRAW_POST_VIEW);
+ // GPU_matrix_pop_projection();
/* reset view matrix */
UI_view2d_view_restore(C);
@@ -1001,12 +1010,11 @@ static void clip_main_region_draw(const bContext *C, ARegion *region)
WM_gizmomap_draw(region->gizmo_map, C, WM_GIZMOMAP_DRAWSTEP_2D);
}
-static void clip_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void clip_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
@@ -1137,11 +1145,7 @@ static void clip_preview_region_draw(const bContext *C, ARegion *region)
}
}
-static void clip_preview_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void clip_preview_region_listener(const wmRegionListenerParams *UNUSED(params))
{
}
@@ -1182,11 +1186,7 @@ static void clip_channels_region_draw(const bContext *C, ARegion *region)
UI_view2d_view_restore(C);
}
-static void clip_channels_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void clip_channels_region_listener(const wmRegionListenerParams *UNUSED(params))
{
}
@@ -1203,12 +1203,11 @@ static void clip_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void clip_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void clip_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
@@ -1246,12 +1245,11 @@ static void clip_tools_region_draw(const bContext *C, ARegion *region)
/****************** tool properties region ******************/
-static void clip_props_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void clip_props_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_WM:
@@ -1299,12 +1297,11 @@ static void clip_properties_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void clip_properties_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void clip_properties_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 49313005c43..a903aeed380 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -88,17 +88,16 @@ static int add_marker_exec(bContext *C, wmOperator *op)
MovieClip *clip = ED_space_clip_get_clip(sc);
float pos[2];
+ ClipViewLockState lock_state;
+ ED_clip_view_lock_state_store(C, &lock_state);
+
RNA_float_get_array(op->ptr, "location", pos);
if (!add_marker(C, pos[0], pos[1])) {
return OPERATOR_CANCELLED;
}
- /* Reset offset from locked position, so frame jumping wouldn't be so
- * confusing.
- */
- sc->xlockof = 0;
- sc->ylockof = 0;
+ ED_clip_view_lock_state_restore_no_jump(C, &lock_state);
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
@@ -244,8 +243,6 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op))
changed = true;
}
}
- /* Nothing selected now, unlock view so it can be scrolled nice again. */
- sc->flag &= ~SC_LOCK_SELECTION;
if (changed) {
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
}
@@ -314,11 +311,6 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- if (!has_selection) {
- /* Nothing selected now, unlock view so it can be scrolled nice again. */
- sc->flag &= ~SC_LOCK_SELECTION;
- }
-
if (!changed) {
return OPERATOR_CANCELLED;
}
@@ -1225,13 +1217,6 @@ static int hide_tracks_exec(bContext *C, wmOperator *op)
clip->tracking.act_plane_track = NULL;
}
- if (unselected == 0) {
- /* No selection on screen now, unlock view so it can be
- * scrolled nice again.
- */
- sc->flag &= ~SC_LOCK_SELECTION;
- }
-
BKE_tracking_dopesheet_tag_update(tracking);
WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, NULL);
@@ -1490,6 +1475,97 @@ void CLIP_OT_join_tracks(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/********************** Average tracks operator *********************/
+
+static int average_tracks_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip_get_clip(space_clip);
+ MovieTracking *tracking = &clip->tracking;
+
+ /* Collect source tracks. */
+ int num_source_tracks;
+ MovieTrackingTrack **source_tracks = BKE_tracking_selected_tracks_in_active_object(
+ tracking, &num_source_tracks);
+ if (num_source_tracks == 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Create new empty track, which will be the averaged result.
+ * Makes it simple to average all selection to it. */
+ ListBase *tracks_list = BKE_tracking_get_active_tracks(tracking);
+ MovieTrackingTrack *result_track = BKE_tracking_track_add_empty(tracking, tracks_list);
+
+ /* Perform averaging. */
+ BKE_tracking_tracks_average(result_track, source_tracks, num_source_tracks);
+
+ const bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
+ if (!keep_original) {
+ for (int i = 0; i < num_source_tracks; i++) {
+ clip_delete_track(C, clip, source_tracks[i]);
+ }
+ }
+
+ /* Update selection, making the result track active and selected. */
+ /* TODO(sergey): Should become some sort of utility function available for all operators. */
+
+ BKE_tracking_track_select(tracks_list, result_track, TRACK_AREA_ALL, 0);
+ ListBase *plane_tracks_list = BKE_tracking_get_active_plane_tracks(tracking);
+ BKE_tracking_plane_tracks_deselect_all(plane_tracks_list);
+
+ clip->tracking.act_track = result_track;
+ clip->tracking.act_plane_track = NULL;
+
+ /* Inform the dependency graph and interface about changes. */
+ DEG_id_tag_update(&clip->id, 0);
+ WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
+
+ /* Free memory. */
+ MEM_freeN(source_tracks);
+
+ return OPERATOR_FINISHED;
+}
+
+static int average_tracks_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ PropertyRNA *prop_keep_original = RNA_struct_find_property(op->ptr, "keep_original");
+ if (!RNA_property_is_set(op->ptr, prop_keep_original)) {
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip_get_clip(space_clip);
+ MovieTracking *tracking = &clip->tracking;
+
+ const int num_selected_tracks = BKE_tracking_count_selected_tracks_in_active_object(tracking);
+
+ if (num_selected_tracks == 1) {
+ RNA_property_boolean_set(op->ptr, prop_keep_original, false);
+ }
+ }
+
+ return average_tracks_exec(C, op);
+}
+
+void CLIP_OT_average_tracks(wmOperatorType *ot)
+{
+ /* Identifiers. */
+ ot->name = "Average Tracks";
+ ot->description = "Average selected tracks into active";
+ ot->idname = "CLIP_OT_average_tracks";
+
+ /* API callbacks. */
+ ot->exec = average_tracks_exec;
+ ot->invoke = average_tracks_invoke;
+ ot->poll = ED_space_clip_tracking_poll;
+
+ /* Flags. */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* Properties. */
+ PropertyRNA *prop;
+
+ prop = RNA_def_boolean(ot->srna, "keep_original", 1, "Keep Original", "Keep original tracks");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+}
+
/********************** lock tracks operator *********************/
enum {
diff --git a/source/blender/editors/space_clip/tracking_ops_detect.c b/source/blender/editors/space_clip/tracking_ops_detect.c
index 54ec439471d..86ee94df731 100644
--- a/source/blender/editors/space_clip/tracking_ops_detect.c
+++ b/source/blender/editors/space_clip/tracking_ops_detect.c
@@ -21,14 +21,10 @@
* \ingroup spclip
*/
-#include "MEM_guardedalloc.h"
-
#include "DNA_gpencil_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
-#include "BLI_utildefines.h"
-
#include "BKE_context.h"
#include "BKE_movieclip.h"
#include "BKE_report.h"
diff --git a/source/blender/editors/space_clip/tracking_ops_stabilize.c b/source/blender/editors/space_clip/tracking_ops_stabilize.c
index 5e43b7c7ec6..d0b4d18c6d9 100644
--- a/source/blender/editors/space_clip/tracking_ops_stabilize.c
+++ b/source/blender/editors/space_clip/tracking_ops_stabilize.c
@@ -21,8 +21,6 @@
* \ingroup spclip
*/
-#include "MEM_guardedalloc.h"
-
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
diff --git a/source/blender/editors/space_clip/tracking_ops_track.c b/source/blender/editors/space_clip/tracking_ops_track.c
index 585b13b426e..e480ec2db05 100644
--- a/source/blender/editors/space_clip/tracking_ops_track.c
+++ b/source/blender/editors/space_clip/tracking_ops_track.c
@@ -30,7 +30,6 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_movieclip.h"
-#include "BKE_report.h"
#include "BKE_tracking.h"
#include "WM_api.h"
diff --git a/source/blender/editors/space_clip/tracking_ops_utils.c b/source/blender/editors/space_clip/tracking_ops_utils.c
index 1f959e94309..0f6bd6e039a 100644
--- a/source/blender/editors/space_clip/tracking_ops_utils.c
+++ b/source/blender/editors/space_clip/tracking_ops_utils.c
@@ -21,12 +21,8 @@
* \ingroup spclip
*/
-#include "MEM_guardedalloc.h"
-
#include "DNA_space_types.h"
-#include "BLI_utildefines.h"
-
#include "BKE_context.h"
#include "BKE_tracking.h"
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index 063ea9592aa..558c0bec11d 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -304,6 +304,9 @@ static int mouse_select(bContext *C, const float co[2], const bool extend, const
track = find_nearest_track(sc, tracksbase, co, &distance_to_track);
plane_track = find_nearest_plane_track(sc, plane_tracks_base, co, &distance_to_plane_track);
+ ClipViewLockState lock_state;
+ ED_clip_view_lock_state_store(C, &lock_state);
+
/* Do not select beyond some reasonable distance, that is useless and
* prevents the 'deselect on nothing' behavior. */
if (distance_to_track > 0.05f) {
@@ -377,10 +380,7 @@ static int mouse_select(bContext *C, const float co[2], const bool extend, const
ED_mask_deselect_all(C);
}
- if (!extend) {
- sc->xlockof = 0.0f;
- sc->ylockof = 0.0f;
- }
+ ED_clip_view_lock_state_restore_no_jump(C, &lock_state);
BKE_tracking_dopesheet_tag_update(tracking);
@@ -867,14 +867,16 @@ static int select_all_exec(bContext *C, wmOperator *op)
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
- int action = RNA_enum_get(op->ptr, "action");
+ const int action = RNA_enum_get(op->ptr, "action");
- bool has_selection = false;
+ ClipViewLockState lock_state;
+ ED_clip_view_lock_state_store(C, &lock_state);
+ bool has_selection = false;
ED_clip_select_all(sc, action, &has_selection);
- if (!has_selection) {
- sc->flag &= ~SC_LOCK_SELECTION;
+ if (has_selection) {
+ ED_clip_view_lock_state_restore_no_jump(C, &lock_state);
}
BKE_tracking_dopesheet_tag_update(tracking);
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index 77f1111624d..05595e0b393 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -18,7 +18,7 @@
* \ingroup spconsole
*/
-#include <ctype.h> /* ispunct */
+#include <ctype.h> /* #ispunct */
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
@@ -749,7 +749,7 @@ static int console_clear_exec(bContext *C, wmOperator *op)
/*ConsoleLine *ci = */ console_history_verify(C);
- if (scrollback) { /* last item in mistory */
+ if (scrollback) { /* Last item in history. */
while (sc->scrollback.first) {
console_scrollback_free(sc, sc->scrollback.first);
}
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index 9b8e9e0e871..b24579d9871 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -41,7 +41,6 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "GPU_framebuffer.h"
#include "console_intern.h" /* own include */
/* ******************** default callbacks for console space ***************** */
@@ -216,7 +215,7 @@ static void console_main_region_draw(const bContext *C, ARegion *region)
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
- /* worlks best with no view2d matrix set */
+ /* Works best with no view2d matrix set. */
UI_view2d_view_ortho(v2d);
/* data... */
@@ -273,13 +272,11 @@ static void console_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void console_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void console_main_region_listener(const wmRegionListenerParams *params)
{
- // SpaceInfo *sinfo = area->spacedata.first;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
/* context changes */
switch (wmn->category) {
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 8e9093151ba..c1dcf2e56d3 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -131,7 +131,15 @@ static void draw_tile(int sx, int sy, int width, int height, int colorid, int sh
UI_GetThemeColorShade4fv(colorid, shade, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_aa(
- true, (float)sx, (float)(sy - height), (float)(sx + width), (float)sy, 5.0f, color);
+ &(const rctf){
+ .xmin = (float)sx,
+ .xmax = (float)(sx + width),
+ .ymin = (float)(sy - height),
+ .ymax = (float)sy,
+ },
+ true,
+ 5.0f,
+ color);
}
static void file_draw_icon(uiBlock *block,
@@ -465,7 +473,7 @@ static void file_draw_preview(uiBlock *block,
but = uiDefBut(block, UI_BTYPE_LABEL, 0, "", xco, yco, ex, ey, NULL, 0.0, 0.0, 0, 0, NULL);
- /* dragregion */
+ /* Drag-region. */
if (drag) {
ID *id;
@@ -546,7 +554,7 @@ static void draw_background(FileLayout *layout, View2D *v2d)
for (i = 2; (i <= layout->rows + 1); i += 2) {
sy = (int)v2d->cur.ymax - layout->offset_top - i * item_height - layout->tile_border_y;
- /* Offsett pattern slightly to add scroll effect. */
+ /* Offset pattern slightly to add scroll effect. */
sy += round_fl_to_int(item_height * (v2d->tot.ymax - v2d->cur.ymax) / item_height);
immRectf(pos,
diff --git a/source/blender/editors/space_file/file_utils.c b/source/blender/editors/space_file/file_utils.c
index 9d85996c559..186bc04fafe 100644
--- a/source/blender/editors/space_file/file_utils.c
+++ b/source/blender/editors/space_file/file_utils.c
@@ -19,7 +19,6 @@
*/
#include "BLI_fileops.h"
-#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_rect.h"
#include "BLI_string.h"
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index d66219c7549..33c37875372 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -276,6 +276,7 @@ typedef struct FileListInternEntry {
char *redirection_path;
/** not strictly needed, but used during sorting, avoids to have to recompute it there... */
char *name;
+ bool free_name;
/**
* This is data from the current main, represented by this file. It's crucial that this is
@@ -1366,7 +1367,7 @@ static bool filelist_checkdir_main_assets(struct FileList *UNUSED(filelist),
static void filelist_entry_clear(FileDirEntry *entry)
{
- if (entry->name) {
+ if (entry->name && ((entry->flags & FILE_ENTRY_NAME_FREE) != 0)) {
MEM_freeN(entry->name);
}
if (entry->description) {
@@ -1451,7 +1452,7 @@ static void filelist_intern_entry_free(FileListInternEntry *entry)
if (entry->redirection_path) {
MEM_freeN(entry->redirection_path);
}
- if (entry->name) {
+ if (entry->name && entry->free_name) {
MEM_freeN(entry->name);
}
/* If we own the asset-data (it was generated from external file data), free it. */
@@ -1953,7 +1954,13 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in
ret->entry = rev;
ret->relpath = BLI_strdup(entry->relpath);
- ret->name = BLI_strdup(entry->name);
+ if (entry->free_name) {
+ ret->name = BLI_strdup(entry->name);
+ ret->flags |= FILE_ENTRY_NAME_FREE;
+ }
+ else {
+ ret->name = entry->name;
+ }
ret->description = BLI_strdupcat(filelist->filelist.root, entry->relpath);
memcpy(ret->uuid, entry->uuid, sizeof(ret->uuid));
ret->blentype = entry->blentype;
@@ -3175,6 +3182,7 @@ static void filelist_readjob_do(const bool do_lib,
entry->relpath = BLI_strdup(dir + 2); /* + 2 to remove '//'
* added by BLI_path_rel to rel_subdir. */
entry->name = BLI_strdup(fileentry_uiname(root, entry->relpath, entry->typeflag, dir));
+ entry->free_name = true;
/* Here we decide whether current filedirentry is to be listed too, or not. */
if (max_recursion && (is_lib || (recursion_level <= max_recursion))) {
@@ -3288,7 +3296,8 @@ static void filelist_readjob_main_assets(Main *current_main,
entry = MEM_callocN(sizeof(*entry), __func__);
entry->relpath = BLI_strdup(id_code_name);
- entry->name = BLI_strdup(id_iter->name + 2);
+ entry->name = id_iter->name + 2;
+ 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(
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 6b74b344375..6e5791cad52 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -460,7 +460,7 @@ bool ED_fileselect_is_asset_browser(const SpaceFile *sfile)
void ED_fileselect_window_params_get(const wmWindow *win, int win_size[2], bool *is_maximized)
{
- /* Get DPI/pixelsize independent size to be stored in preferences. */
+ /* Get DPI/pixel-size independent size to be stored in preferences. */
WM_window_set_dpi(win); /* Ensure the DPI is taken from the right window. */
win_size[0] = WM_window_pixels_x(win) / UI_DPI_FAC;
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 7f33b0212d6..178ca264182 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -104,6 +104,7 @@ static ARegion *file_tool_props_region_ensure(ScrArea *area, ARegion *region_pre
BLI_insertlinkafter(&area->regionbase, region_prev, region);
region->regiontype = RGN_TYPE_TOOL_PROPS;
region->alignment = RGN_ALIGN_RIGHT;
+ region->flag = RGN_FLAG_HIDDEN;
return region;
}
@@ -246,13 +247,13 @@ static void file_ensure_valid_region_state(bContext *C,
BLI_assert(region_tools);
if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS) {
- ARegion *region_execute = file_execute_region_ensure(area, region_tools);
- ARegion *region_props = file_tool_props_region_ensure(area, region_execute);
-
- /* Hide specific regions by default. */
- region_props->flag |= RGN_FLAG_HIDDEN;
- region_execute->flag |= RGN_FLAG_HIDDEN;
+ file_tool_props_region_ensure(area, region_tools);
+ ARegion *region_execute = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE);
+ if (region_execute) {
+ ED_region_remove(C, area, region_execute);
+ needs_init = true;
+ }
ARegion *region_ui = BKE_area_find_region_type(area, RGN_TYPE_UI);
if (region_ui) {
ED_region_remove(C, area, region_ui);
@@ -260,7 +261,7 @@ static void file_ensure_valid_region_state(bContext *C,
}
}
/* If there's an file-operation, ensure we have the option and execute region */
- else if (sfile->op) {
+ else if (sfile->op && !BKE_area_find_region_type(area, RGN_TYPE_TOOL_PROPS)) {
ARegion *region_ui = file_ui_region_ensure(area, region_tools);
ARegion *region_execute = file_execute_region_ensure(area, region_ui);
ARegion *region_props = file_tool_props_region_ensure(area, region_execute);
@@ -275,17 +276,18 @@ static void file_ensure_valid_region_state(bContext *C,
needs_init = true;
}
/* If there's _no_ file-operation, ensure we _don't_ have the option and execute region */
- else {
+ else if (!sfile->op) {
ARegion *region_props = BKE_area_find_region_type(area, RGN_TYPE_TOOL_PROPS);
ARegion *region_execute = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE);
ARegion *region_ui = file_ui_region_ensure(area, region_tools);
UNUSED_VARS(region_ui);
+ if (region_execute) {
+ ED_region_remove(C, area, region_execute);
+ needs_init = true;
+ }
if (region_props) {
- BLI_assert(region_execute);
-
ED_region_remove(C, area, region_props);
- ED_region_remove(C, area, region_execute);
needs_init = true;
}
}
@@ -390,11 +392,10 @@ static void file_refresh(const bContext *C, ScrArea *area)
ED_area_tag_redraw(area);
}
-static void file_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void file_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceFile *sfile = (SpaceFile *)area->spacedata.first;
/* context changes */
@@ -445,12 +446,11 @@ 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(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void file_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SPACE:
@@ -463,19 +463,24 @@ static void file_main_region_listener(wmWindow *UNUSED(win),
break;
}
break;
+ case NC_ID:
+ if (ELEM(wmn->action, NA_RENAME)) {
+ /* In case the filelist shows ID names. */
+ ED_region_tag_redraw(region);
+ }
+ break;
}
}
-static void file_main_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void file_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
SpaceFile *sfile = area->spacedata.first;
- FileSelectParams *params = ED_fileselect_ensure_active_params(sfile);
+
+ FileSelectParams *file_params = ED_fileselect_ensure_active_params(sfile);
/* This is a bit odd that a region owns the subscriber for an area,
* keep for now since all subscribers for WM are regions.
* May be worth re-visiting later. */
@@ -497,7 +502,7 @@ static void file_main_region_message_subscribe(const struct bContext *UNUSED(C),
/* FileSelectParams */
{
PointerRNA ptr;
- RNA_pointer_create(&screen->id, &RNA_FileSelectParams, params, &ptr);
+ RNA_pointer_create(&screen->id, &RNA_FileSelectParams, file_params, &ptr);
/* All properties for this space type. */
WM_msg_subscribe_rna(mbus, &ptr, NULL, &msg_sub_value_area_tag_refresh, __func__);
@@ -647,18 +652,23 @@ static void file_tools_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void file_tools_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void file_tools_region_listener(const wmRegionListenerParams *UNUSED(params))
{
-#if 0
- /* context changes */
+}
+
+static void file_tool_props_region_listener(const wmRegionListenerParams *params)
+{
+ const wmNotifier *wmn = params->notifier;
+ ARegion *region = params->region;
+
switch (wmn->category) {
- /* pass */
+ case NC_ID:
+ if (ELEM(wmn->action, NA_RENAME)) {
+ /* In case the filelist shows ID names. */
+ ED_region_tag_redraw(region);
+ }
+ break;
}
-#endif
}
/* add handlers, stuff you only do once or on area/region changes */
@@ -715,12 +725,11 @@ static void file_execution_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void file_ui_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void file_ui_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SPACE:
@@ -928,7 +937,7 @@ void ED_spacetype_file(void)
art->prefsizex = 240;
art->prefsizey = 60;
art->keymapflag = ED_KEYMAP_UI;
- art->listener = file_tools_region_listener;
+ art->listener = file_tool_props_region_listener;
art->init = file_tools_region_init;
art->draw = file_tools_region_draw;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index fac38ef7b91..31f606e515d 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -178,7 +178,7 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
x = (float)CFRA;
}
- /* Normalise units of cursor's value. */
+ /* Normalize units of cursor's value. */
if (sipo) {
y = (sipo->cursorVal / unit_scale) - offset;
}
@@ -2263,7 +2263,7 @@ static void snap_graph_keys(bAnimContext *ac, short mode)
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- /* Normalise cursor value (for normalised F-Curves display). */
+ /* Normalize cursor value (for normalized F-Curves display). */
if (mode == GRAPHKEYS_SNAP_VALUE) {
short mapping_flag = ANIM_get_normalization_flags(ac);
float offset;
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 63acc2a1774..32396a70cce 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -32,15 +32,11 @@
#include "BKE_context.h"
#include "BKE_global.h"
-#include "BKE_main.h"
#include "UI_view2d.h"
#include "ED_anim_api.h"
-#include "ED_markers.h"
-#include "ED_object.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "ED_transform.h"
#include "graph_intern.h"
diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c
index 4cda6b34a01..3e52dc7377b 100644
--- a/source/blender/editors/space_graph/graph_slider_ops.c
+++ b/source/blender/editors/space_graph/graph_slider_ops.c
@@ -380,7 +380,7 @@ static int graphkeys_decimate_modal(bContext *C, wmOperator *op, const wmEvent *
break;
}
- /* Unhandled event - maybe it was some view manip? */
+ /* Unhandled event - maybe it was some view manipulation? */
/* Allow to pass through. */
return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH;
}
@@ -505,15 +505,15 @@ void GRAPH_OT_decimate(wmOperatorType *ot)
"Mode",
"Which mode to use for decimation");
- RNA_def_float_percentage(ot->srna,
- "remove_ratio",
- 1.0f / 3.0f,
- 0.0f,
- 1.0f,
- "Remove",
- "The percentage of keyframes to remove",
- 0.0f,
- 1.0f);
+ RNA_def_float_factor(ot->srna,
+ "remove_ratio",
+ 1.0f / 3.0f,
+ 0.0f,
+ 1.0f,
+ "Remove",
+ "The ratio of remaining keyframes after the operation",
+ 0.0f,
+ 1.0f);
RNA_def_float(ot->srna,
"remove_error_margin",
0.0f,
diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c
index 8463c21b1ad..c37d9f42c12 100644
--- a/source/blender/editors/space_graph/graph_utils.c
+++ b/source/blender/editors/space_graph/graph_utils.c
@@ -38,8 +38,6 @@
#include "BKE_fcurve.h"
#include "BKE_screen.h"
-#include "WM_api.h"
-
#include "ED_anim_api.h"
#include "ED_screen.h"
#include "UI_interface.h"
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 791039498e8..9f01773eadf 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -403,12 +403,11 @@ static void graph_buttons_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void graph_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void graph_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -470,14 +469,14 @@ static void graph_region_listener(wmWindow *UNUSED(win),
}
}
-static void graph_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void graph_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ Scene *scene = params->scene;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceGraphEditor, area->spacedata.first, &ptr);
@@ -546,11 +545,10 @@ static void graph_region_message_subscribe(const struct bContext *UNUSED(C),
}
/* editor level listener */
-static void graph_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void graph_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceGraph *sipo = (SpaceGraph *)area->spacedata.first;
/* context changes */
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 63e5ae64a8c..67d5055ec65 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -466,7 +466,7 @@ static void sima_draw_zbuf_pixels(
{
const float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
- /* Slowwww */
+ /* Very slow! */
float *rectf = MEM_mallocN(rectx * recty * sizeof(float), "temp");
for (int a = rectx * recty - 1; a >= 0; a--) {
/* zbuffer values are signed, so we need to shift color range */
@@ -874,7 +874,7 @@ void draw_image_main(const bContext *C, ARegion *region)
if (show_stereo3d) {
if (show_multilayer) {
- /* update multiindex and pass for the current eye */
+ /* Update multi-index and pass for the current eye. */
BKE_image_multilayer_index(ima->rr, &sima->iuser);
}
else {
diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h
index 100556ad29a..0044c6072a4 100644
--- a/source/blender/editors/space_image/image_intern.h
+++ b/source/blender/editors/space_image/image_intern.h
@@ -71,6 +71,7 @@ void IMAGE_OT_save_all_modified(struct wmOperatorType *ot);
void IMAGE_OT_pack(struct wmOperatorType *ot);
void IMAGE_OT_unpack(struct wmOperatorType *ot);
+void IMAGE_OT_flip(struct wmOperatorType *ot);
void IMAGE_OT_invert(struct wmOperatorType *ot);
void IMAGE_OT_resize(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 86e52814d6f..4008ca228ac 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -36,9 +36,7 @@
#include "BLI_blenlib.h"
#include "BLI_fileops.h"
-#include "BLI_fileops_types.h"
#include "BLI_ghash.h"
-#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -48,7 +46,6 @@
#include "DNA_camera_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
-#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -62,14 +59,10 @@
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_packedFile.h"
-#include "BKE_paint.h"
#include "BKE_report.h"
-#include "BKE_scene.h"
-#include "BKE_screen.h"
#include "DEG_depsgraph.h"
-#include "GPU_immediate.h"
#include "GPU_state.h"
#include "IMB_colormanagement.h"
@@ -467,7 +460,7 @@ static void image_view_zoom_init(bContext *C, wmOperator *op, const wmEvent *eve
UI_view2d_region_to_view(
&region->v2d, event->mval[0], event->mval[1], &vpd->location[0], &vpd->location[1]);
- if (U.viewzoom == USER_ZOOM_CONT) {
+ if (U.viewzoom == USER_ZOOM_CONTINUE) {
/* needs a timer to continue redrawing */
vpd->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
vpd->timer_lastdraw = PIL_check_seconds_timer();
@@ -579,12 +572,10 @@ static void image_zoom_apply(ViewZoomData *vpd,
delta = -delta;
}
- if (viewzoom == USER_ZOOM_CONT) {
+ if (viewzoom == USER_ZOOM_CONTINUE) {
double time = PIL_check_seconds_timer();
float time_step = (float)(time - vpd->timer_lastdraw);
float zfac;
-
- /* oldstyle zoom */
zfac = 1.0f + ((delta / 20.0f) * time_step);
vpd->timer_lastdraw = time;
/* this is the final zoom, but instead make it into a factor */
@@ -900,7 +891,7 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
}
}
else if (ED_space_image_check_show_maskedit(sima, obedit)) {
- if (!ED_mask_selected_minmax(C, min, max)) {
+ if (!ED_mask_selected_minmax(C, min, max, false)) {
return OPERATOR_CANCELLED;
}
}
@@ -2663,6 +2654,126 @@ void IMAGE_OT_new(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Flip Operator
+ * \{ */
+
+static int image_flip_exec(bContext *C, wmOperator *op)
+{
+ Image *ima = image_from_context(C);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ SpaceImage *sima = CTX_wm_space_image(C);
+ const bool is_paint = ((sima != NULL) && (sima->mode == SI_MODE_PAINT));
+
+ if (ibuf == NULL) {
+ /* TODO: this should actually never happen, but does for render-results -> cleanup. */
+ 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");
+
+ if (!flip_horizontal && !flip_vertical) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return OPERATOR_FINISHED;
+ }
+
+ ED_image_undo_push_begin_with_image(op->type->name, ima, ibuf, &sima->iuser);
+
+ if (is_paint) {
+ ED_imapaint_clear_partial_redraw();
+ }
+
+ const int size_x = ibuf->x;
+ const int size_y = ibuf->y;
+
+ if (ibuf->rect_float) {
+ float *float_pixels = (float *)ibuf->rect_float;
+
+ float *orig_float_pixels = MEM_dupallocN(float_pixels);
+ for (int x = 0; x < size_x; 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;
+
+ 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);
+ }
+ }
+ MEM_freeN(orig_float_pixels);
+
+ if (ibuf->rect) {
+ IMB_rect_from_float(ibuf);
+ }
+ }
+ else if (ibuf->rect) {
+ char *char_pixels = (char *)ibuf->rect;
+ char *orig_char_pixels = MEM_dupallocN(char_pixels);
+ for (int x = 0; x < size_x; 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;
+
+ 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);
+ }
+ }
+ MEM_freeN(orig_char_pixels);
+ }
+ else {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return OPERATOR_CANCELLED;
+ }
+
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ BKE_image_mark_dirty(ima, ibuf);
+
+ if (ibuf->mipmap[0]) {
+ ibuf->userflags |= IB_MIPMAP_INVALID;
+ }
+
+ ED_image_undo_push_end();
+
+ /* force GPU re-upload, all image is invalid. */
+ BKE_image_free_gputextures(ima);
+
+ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void IMAGE_OT_flip(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Flip Image";
+ ot->idname = "IMAGE_OT_flip";
+ ot->description = "Flip the image";
+
+ /* api callbacks */
+ ot->exec = image_flip_exec;
+ ot->poll = image_from_context_has_data_poll_no_image_user;
+
+ /* properties */
+ PropertyRNA *prop;
+ prop = RNA_def_boolean(
+ ot->srna, "use_flip_horizontal", 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");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Invert Operators
* \{ */
@@ -2747,7 +2858,7 @@ static int image_invert_exec(bContext *C, wmOperator *op)
ED_image_undo_push_end();
- /* force GPU reupload, all image is invalid */
+ /* Force GPU re-upload, all image is invalid. */
BKE_image_free_gputextures(ima);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
@@ -2838,7 +2949,7 @@ static int image_scale_exec(bContext *C, wmOperator *op)
ED_image_undo_push_end();
- /* force GPU reupload, all image is invalid */
+ /* Force GPU re-upload, all image is invalid. */
BKE_image_free_gputextures(ima);
DEG_id_tag_update(&ima->id, 0);
diff --git a/source/blender/editors/space_image/image_sequence.c b/source/blender/editors/space_image/image_sequence.c
index 81f2ced7dee..02546e3e3b3 100644
--- a/source/blender/editors/space_image/image_sequence.c
+++ b/source/blender/editors/space_image/image_sequence.c
@@ -27,7 +27,6 @@
#include "BLI_fileops.h"
#include "BLI_fileops_types.h"
-#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_path_util.h"
@@ -35,7 +34,6 @@
#include "BLI_utildefines.h"
#include "DNA_image_types.h"
-#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h"
#include "RNA_access.h"
@@ -45,8 +43,6 @@
#include "ED_image.h"
-#include "WM_types.h"
-
typedef struct ImageFrame {
struct ImageFrame *next, *prev;
int framenr;
diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c
index 1d5725033e0..391c68f4231 100644
--- a/source/blender/editors/space_image/image_undo.c
+++ b/source/blender/editors/space_image/image_undo.c
@@ -947,13 +947,15 @@ static void image_undosys_step_decode_redo(ImageUndoStep *us)
}
static void image_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int dir, bool is_final)
+ struct bContext *C, struct Main *bmain, UndoStep *us_p, const eUndoStepDir dir, bool is_final)
{
+ BLI_assert(dir != STEP_INVALID);
+
ImageUndoStep *us = (ImageUndoStep *)us_p;
- if (dir < 0) {
+ if (dir == STEP_UNDO) {
image_undosys_step_decode_undo(us, is_final);
}
- else {
+ else if (dir == STEP_REDO) {
image_undosys_step_decode_redo(us);
}
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 186f2d3a5a8..69976bc088c 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -24,8 +24,6 @@
#include "DNA_gpencil_types.h"
#include "DNA_image_types.h"
#include "DNA_mask_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -37,14 +35,9 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_editmesh.h"
#include "BKE_image.h"
-#include "BKE_layer.h"
#include "BKE_lib_id.h"
-#include "BKE_material.h"
-#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BKE_workspace.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -56,7 +49,6 @@
#include "ED_image.h"
#include "ED_mask.h"
-#include "ED_mesh.h"
#include "ED_node.h"
#include "ED_render.h"
#include "ED_screen.h"
@@ -65,19 +57,13 @@
#include "ED_uvedit.h"
#include "WM_api.h"
-#include "WM_message.h"
#include "WM_types.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "GPU_batch_presets.h"
-#include "GPU_framebuffer.h"
-#include "GPU_viewport.h"
-
#include "DRW_engine.h"
-#include "DRW_engine_types.h"
#include "image_intern.h"
@@ -234,6 +220,7 @@ static void image_operatortypes(void)
WM_operatortype_append(IMAGE_OT_pack);
WM_operatortype_append(IMAGE_OT_unpack);
+ WM_operatortype_append(IMAGE_OT_flip);
WM_operatortype_append(IMAGE_OT_invert);
WM_operatortype_append(IMAGE_OT_resize);
@@ -320,8 +307,11 @@ static void image_refresh(const bContext *C, ScrArea *area)
}
}
-static void image_listener(wmWindow *win, ScrArea *area, wmNotifier *wmn, Scene *UNUSED(scene))
+static void image_listener(const wmSpaceTypeListenerParams *params)
{
+ wmWindow *win = params->window;
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceImage *sima = (SpaceImage *)area->spacedata.first;
/* context changes */
@@ -728,12 +718,12 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
draw_image_cache(C, region);
}
-static void image_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void image_main_region_listener(const wmRegionListenerParams *params)
{
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_GEOM:
@@ -843,12 +833,11 @@ static void image_buttons_region_draw(const bContext *C, ARegion *region)
ED_region_panels_draw(C, region);
}
-static void image_buttons_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void image_buttons_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_TEXTURE:
@@ -906,12 +895,11 @@ static void image_tools_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void image_tools_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void image_tools_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
@@ -963,12 +951,11 @@ static void image_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void image_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void image_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c
index 414bce29502..be3b60d581b 100644
--- a/source/blender/editors/space_info/info_draw.c
+++ b/source/blender/editors/space_info/info_draw.c
@@ -35,7 +35,6 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "GPU_framebuffer.h"
#include "info_intern.h"
#include "textview.h"
@@ -56,47 +55,11 @@ static enum eTextViewContext_LineFlag report_line_data(TextViewContext *tvc,
int shade = (tvc->iter_tmp % 2) ? 4 : -4;
UI_GetThemeColorShade4ubv(bg_id, shade, bg);
- /* Icon color and backgound depend of report type. */
+ /* Don't show icon on subsequent rows of multi-row report. */
+ *r_icon = (tvc->iter_char_begin != 0) ? ICON_NONE : UI_icon_from_report_type(report->type);
- int icon_fg_id;
- int icon_bg_id;
-
- if (tvc->iter_char_begin != 0) {
- *r_icon = ICON_NONE;
- }
- else if (report->type & RPT_ERROR_ALL) {
- icon_fg_id = TH_INFO_ERROR_TEXT;
- icon_bg_id = TH_INFO_ERROR;
- *r_icon = ICON_CANCEL;
- }
- else if (report->type & RPT_WARNING_ALL) {
- icon_fg_id = TH_INFO_WARNING_TEXT;
- icon_bg_id = TH_INFO_WARNING;
- *r_icon = ICON_ERROR;
- }
- else if (report->type & RPT_INFO_ALL) {
- icon_fg_id = TH_INFO_INFO_TEXT;
- icon_bg_id = TH_INFO_INFO;
- *r_icon = ICON_INFO;
- }
- else if (report->type & RPT_DEBUG_ALL) {
- icon_fg_id = TH_INFO_DEBUG_TEXT;
- icon_bg_id = TH_INFO_DEBUG;
- *r_icon = ICON_SYSTEM;
- }
- else if (report->type & RPT_PROPERTY) {
- icon_fg_id = TH_INFO_PROPERTY_TEXT;
- icon_bg_id = TH_INFO_PROPERTY;
- *r_icon = ICON_OPTIONS;
- }
- else if (report->type & RPT_OPERATOR) {
- icon_fg_id = TH_INFO_OPERATOR_TEXT;
- icon_bg_id = TH_INFO_OPERATOR;
- *r_icon = ICON_CHECKMARK;
- }
- else {
- *r_icon = ICON_NONE;
- }
+ int icon_fg_id = UI_text_colorid_from_report_type(report->type);
+ int icon_bg_id = UI_icon_colorid_from_report_type(report->type);
if (report->flag & SELECT) {
icon_fg_id = TH_INFO_SELECTED;
@@ -105,6 +68,8 @@ static enum eTextViewContext_LineFlag report_line_data(TextViewContext *tvc,
if (*r_icon != ICON_NONE) {
UI_GetThemeColor4ubv(icon_fg_id, r_icon_fg);
+ /* This theme color is RGB only, so set alpha. */
+ r_icon_fg[3] = 255;
UI_GetThemeColor4ubv(icon_bg_id, r_icon_bg);
return TVC_LINE_FG | TVC_LINE_BG | TVC_LINE_ICON | TVC_LINE_ICON_FG | TVC_LINE_ICON_BG;
}
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 3bd23eab836..0583628be43 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -24,7 +24,6 @@
#include <stdio.h>
#include <string.h>
-#include "DNA_packedFile_types.h"
#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h"
@@ -52,8 +51,6 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "IMB_imbuf_types.h"
-
#include "RNA_access.h"
#include "RNA_define.h"
@@ -567,15 +564,7 @@ static int update_reports_display_invoke(bContext *C, wmOperator *UNUSED(op), co
}
/* set target color based on report type */
- if (report->type & RPT_ERROR_ALL) {
- UI_GetThemeColorType3fv(TH_INFO_ERROR, SPACE_INFO, target_col);
- }
- else if (report->type & RPT_WARNING_ALL) {
- UI_GetThemeColorType3fv(TH_INFO_WARNING, SPACE_INFO, target_col);
- }
- else if (report->type & RPT_INFO_ALL) {
- UI_GetThemeColorType3fv(TH_INFO_INFO, SPACE_INFO, target_col);
- }
+ UI_GetThemeColorType3fv(UI_icon_colorid_from_report_type(report->type), SPACE_INFO, target_col);
target_col[3] = 0.65f;
if (rti->widthfac == 0.0f) {
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index 8d3f21aefeb..dfc0abee704 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -29,8 +29,6 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLT_translation.h"
-
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -43,12 +41,9 @@
#include "RNA_access.h"
-#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "BLO_readfile.h"
-#include "GPU_framebuffer.h"
#include "info_intern.h" /* own include */
/* ******************** default callbacks for info space ***************** */
@@ -150,7 +145,7 @@ static void info_main_region_draw(const bContext *C, ARegion *region)
info_textview_update_rect(C, region);
- /* worlks best with no view2d matrix set */
+ /* Works best with no view2d matrix set. */
UI_view2d_view_ortho(v2d);
info_textview_main(sinfo, region, CTX_wm_reports(C));
@@ -204,13 +199,10 @@ static void info_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void info_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void info_main_region_listener(const wmRegionListenerParams *params)
{
- // SpaceInfo *sinfo = area->spacedata.first;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
/* context changes */
switch (wmn->category) {
@@ -223,12 +215,11 @@ static void info_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void info_header_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void info_header_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCREEN:
@@ -259,14 +250,11 @@ static void info_header_listener(wmWindow *UNUSED(win),
}
}
-static void info_header_region_message_subscribe(const bContext *UNUSED(C),
- WorkSpace *UNUSED(workspace),
- Scene *UNUSED(scene),
- bScreen *UNUSED(screen),
- ScrArea *UNUSED(area),
- ARegion *region,
- struct wmMsgBus *mbus)
+static void info_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index a489216afd1..aef59e89325 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -225,13 +225,16 @@ static bool textview_draw_string(TextViewDrawState *tds,
rgba_uchar_to_float(col, icon_bg);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true,
- hpadding,
- line_top - bg_size - vpadding,
- bg_size + hpadding,
- line_top - vpadding,
- 4 * UI_DPI_FAC,
- col);
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = hpadding,
+ .xmax = bg_size + hpadding,
+ .ymin = line_top - bg_size - vpadding,
+ .ymax = line_top - vpadding,
+ },
+ true,
+ 4 * UI_DPI_FAC,
+ col);
}
if (icon) {
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 6fe980cf657..eea81e425c2 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -493,7 +493,18 @@ static void nla_draw_strip(SpaceNla *snla,
/* strip is in normal track */
UI_draw_roundbox_corner_set(UI_CNR_ALL); /* all corners rounded */
- UI_draw_roundbox_shade_x(true, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1, color);
+ UI_draw_roundbox_shade_x(
+ &(const rctf){
+ .xmin = strip->start,
+ .xmax = strip->end,
+ .ymin = yminc,
+ .ymax = ymaxc,
+ },
+ true,
+ 0.0,
+ 0.5,
+ 0.1,
+ color);
/* restore current vertex format & program (roundbox trashes it) */
shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -547,7 +558,18 @@ static void nla_draw_strip(SpaceNla *snla,
}
else {
/* non-muted - draw solid, rounded outline */
- UI_draw_roundbox_shade_x(false, strip->start, yminc, strip->end, ymaxc, 0.0, 0.0, 0.1, color);
+ UI_draw_roundbox_shade_x(
+ &(const rctf){
+ .xmin = strip->start,
+ .xmax = strip->end,
+ .ymin = yminc,
+ .ymax = ymaxc,
+ },
+ false,
+ 0.0,
+ 0.0,
+ 0.1,
+ color);
/* restore current vertex format & program (roundbox trashes it) */
shdr_pos = nla_draw_use_dashed_outlines(color, muted);
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index d7bf6c324ac..893d2c0e2c8 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -62,7 +62,6 @@
#include "DEG_depsgraph_build.h"
#include "UI_interface.h"
-#include "UI_resources.h"
#include "UI_view2d.h"
#include "nla_intern.h" /* own include */
@@ -215,7 +214,7 @@ bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo)
return false;
}
- /* for each AnimData block with NLA-data, try exitting tweak-mode */
+ /* For each AnimData block with NLA-data, try exiting tweak-mode. */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ale->data;
@@ -418,7 +417,7 @@ static bool nla_channels_get_selected_extents(bAnimContext *ac, float *min, floa
int filter;
SpaceNla *snla = (SpaceNla *)ac->sl;
- /* NOTE: not bool, since we want prioritise individual channels over expanders */
+ /* NOTE: not bool, since we want prioritize individual channels over expanders. */
short found = 0;
/* get all items - we need to do it this way */
@@ -442,7 +441,7 @@ static bool nla_channels_get_selected_extents(bAnimContext *ac, float *min, floa
found = acf->channel_role;
/* only stop our search when we've found an actual channel
- * - datablock expanders get less priority so that we don't abort prematurely
+ * - data-block expanders get less priority so that we don't abort prematurely
*/
if (found == ACHANNEL_ROLE_CHANNEL) {
break;
@@ -1532,11 +1531,11 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op)
const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id);
if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) {
- /* No re-ordering of strips whithin non-local tracks of override data. */
+ /* No re-ordering of strips within non-local tracks of override data. */
continue;
}
- /* make temporary metastrips so that entire islands of selections can be moved around */
+ /* Make temporary meta-strips so that entire islands of selections can be moved around. */
BKE_nlastrips_make_metas(&nlt->strips, 1);
/* special case: if there is only 1 island
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index 2e32c496170..631dc2e550c 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -30,16 +30,11 @@
#include "BKE_screen.h"
#include "ED_anim_api.h"
-#include "ED_markers.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
-#include "ED_transform.h"
#include "WM_api.h"
#include "WM_types.h"
-#include "RNA_access.h"
-
#include "nla_intern.h" /* own include */
/* ************************** poll callbacks for operators **********************************/
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index c6fe1b8539e..011cd7e2651 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -24,7 +24,6 @@
#include <stdio.h>
#include <string.h>
-#include "DNA_anim_types.h"
#include "DNA_collection_types.h"
#include "DNA_scene_types.h"
@@ -52,7 +51,6 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "GPU_framebuffer.h"
#include "nla_intern.h" /* own include */
/* ******************** default callbacks for nla space ***************** */
@@ -324,12 +322,11 @@ static void nla_buttons_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void nla_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void nla_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -364,12 +361,11 @@ static void nla_region_listener(wmWindow *UNUSED(win),
}
}
-static void nla_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void nla_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -423,14 +419,14 @@ static void nla_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void nla_main_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *scene,
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void nla_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ Scene *scene = params->scene;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceNLA, area->spacedata.first, &ptr);
@@ -465,12 +461,11 @@ static void nla_main_region_message_subscribe(const struct bContext *UNUSED(C),
}
}
-static void nla_channel_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void nla_channel_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -508,14 +503,13 @@ static void nla_channel_region_listener(wmWindow *UNUSED(win),
}
}
-static void nla_channel_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *screen,
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void nla_channel_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ bScreen *screen = params->screen;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceNLA, area->spacedata.first, &ptr);
@@ -543,11 +537,11 @@ static void nla_channel_region_message_subscribe(const struct bContext *UNUSED(C
}
/* editor level listener */
-static void nla_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void nla_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index f2ee94af9b3..4716f1c29ea 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -190,7 +190,7 @@ static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA
cumap->flag &= ~CUMA_DRAW_SAMPLE;
}
- /* "Tone" (Standard/Filmlike) only used in the Compositor. */
+ /* "Tone" (Standard/Film-like) only used in the Compositor. */
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
uiTemplateCurveMapping(
layout, ptr, "mapping", 'c', false, false, false, (ntree->type == NTREE_COMPOSIT));
@@ -441,7 +441,7 @@ static void node_draw_frame(const bContext *C,
const rctf *rct = &node->totr;
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color);
+ UI_draw_roundbox_aa(rct, true, BASIS_RAD, color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
@@ -452,11 +452,11 @@ static void node_draw_frame(const bContext *C,
UI_GetThemeColorShadeAlpha4fv(TH_SELECT, 0, -40, color);
}
- UI_draw_roundbox_aa(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color);
+ UI_draw_roundbox_aa(rct, false, BASIS_RAD, color);
}
/* label */
- node_draw_frame_label(ntree, node, snode->aspect);
+ node_draw_frame_label(ntree, node, snode->runtime->aspect);
UI_block_end(C, node->block);
UI_block_draw(C, node->block);
@@ -559,7 +559,7 @@ static void node_draw_reroute(const bContext *C,
if (node->flag & SELECT) {
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
- /* using different shades of TH_TEXT_HI for the empasis, like triangle */
+ /* Using different shades of #TH_TEXT_HI for the emphasis, like triangle. */
if (node->flag & NODE_ACTIVE) {
UI_GetThemeColorShadeAlpha4fv(TH_TEXT_HI, 0, -40, debug_color);
}
@@ -3126,270 +3126,6 @@ static void node_texture_set_butfunc(bNodeType *ntype)
}
}
-/* ****************** BUTTON CALLBACKS FOR GEOMETRY NODES ***************** */
-
-static void node_geometry_buts_boolean_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_geometry_buts_attribute_compare(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "input_type_a", DEFAULT_FLAGS, IFACE_("Type A"), ICON_NONE);
- uiItemR(layout, ptr, "input_type_b", DEFAULT_FLAGS, IFACE_("Type B"), ICON_NONE);
-}
-
-static void node_geometry_buts_subdivision_surface(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *UNUSED(ptr))
-{
-#ifndef WITH_OPENSUBDIV
- uiItemL(layout, IFACE_("Disabled, built without OpenSubdiv"), ICON_ERROR);
-#else
- UNUSED_VARS(layout);
-#endif
-}
-
-static void node_geometry_buts_triangulate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "quad_method", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "ngon_method", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_geometry_buts_random_attribute(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "data_type", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_geometry_buts_attribute_math(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "input_type_a", DEFAULT_FLAGS, IFACE_("Type A"), ICON_NONE);
- uiItemR(layout, ptr, "input_type_b", DEFAULT_FLAGS, IFACE_("Type B"), ICON_NONE);
-}
-
-static void node_geometry_buts_attribute_vector_math(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- bNode *node = (bNode *)ptr->data;
- NodeAttributeVectorMath *node_storage = (NodeAttributeVectorMath *)node->storage;
-
- uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "input_type_a", DEFAULT_FLAGS, IFACE_("Type A"), ICON_NONE);
-
- /* These "use input b / c" checks are copied from the node's code.
- * They could be de-duplicated if the drawing code was moved to the node's file. */
- if (!ELEM(node_storage->operation,
- NODE_VECTOR_MATH_NORMALIZE,
- NODE_VECTOR_MATH_FLOOR,
- NODE_VECTOR_MATH_CEIL,
- NODE_VECTOR_MATH_FRACTION,
- NODE_VECTOR_MATH_ABSOLUTE,
- NODE_VECTOR_MATH_SINE,
- NODE_VECTOR_MATH_COSINE,
- NODE_VECTOR_MATH_TANGENT,
- NODE_VECTOR_MATH_LENGTH)) {
- uiItemR(layout, ptr, "input_type_b", DEFAULT_FLAGS, IFACE_("Type B"), ICON_NONE);
- }
- if (ELEM(node_storage->operation, NODE_VECTOR_MATH_WRAP)) {
- uiItemR(layout, ptr, "input_type_c", DEFAULT_FLAGS, IFACE_("Type C"), ICON_NONE);
- }
-}
-
-static void node_geometry_buts_point_instance(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "instance_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- if (RNA_enum_get(ptr, "instance_type") == GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION) {
- uiItemR(layout, ptr, "use_whole_collection", DEFAULT_FLAGS, NULL, ICON_NONE);
- }
-}
-
-static void node_geometry_buts_attribute_fill(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "data_type", DEFAULT_FLAGS, "", ICON_NONE);
- // uiItemR(layout, ptr, "domain", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_geometry_buts_attribute_mix(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "blend_type", DEFAULT_FLAGS, "", ICON_NONE);
- uiLayout *col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "input_type_factor", DEFAULT_FLAGS, IFACE_("Factor"), ICON_NONE);
- uiItemR(col, ptr, "input_type_a", DEFAULT_FLAGS, IFACE_("A"), ICON_NONE);
- uiItemR(col, ptr, "input_type_b", DEFAULT_FLAGS, IFACE_("B"), ICON_NONE);
-}
-
-static void node_geometry_buts_attribute_point_distribute(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "distribute_method", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_geometry_buts_attribute_color_ramp(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiTemplateColorRamp(layout, ptr, "color_ramp", 0);
-}
-
-static void node_geometry_buts_point_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- NodeGeometryRotatePoints *storage = (NodeGeometryRotatePoints *)((bNode *)ptr->data)->storage;
-
- uiItemR(layout, ptr, "type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- uiItemR(layout, ptr, "space", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
-
- uiLayout *col = uiLayoutColumn(layout, false);
- if (storage->type == GEO_NODE_POINT_ROTATE_TYPE_AXIS_ANGLE) {
- uiItemR(col, ptr, "input_type_axis", DEFAULT_FLAGS, IFACE_("Axis"), ICON_NONE);
- uiItemR(col, ptr, "input_type_angle", DEFAULT_FLAGS, IFACE_("Angle"), ICON_NONE);
- }
- else {
- uiItemR(col, ptr, "input_type_rotation", DEFAULT_FLAGS, IFACE_("Rotation"), ICON_NONE);
- }
-}
-
-static void node_geometry_buts_align_rotation_to_vector(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "axis", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- uiLayout *col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "input_type_factor", DEFAULT_FLAGS, IFACE_("Factor"), ICON_NONE);
- uiItemR(col, ptr, "input_type_vector", DEFAULT_FLAGS, IFACE_("Vector"), ICON_NONE);
-}
-static void node_geometry_buts_point_translate(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "input_type", DEFAULT_FLAGS, IFACE_("Type"), ICON_NONE);
-}
-
-static void node_geometry_buts_point_scale(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "input_type", DEFAULT_FLAGS, IFACE_("Type"), ICON_NONE);
-}
-
-static void node_geometry_buts_object_info(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "transform_space", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
-}
-
-static void node_geometry_set_butfunc(bNodeType *ntype)
-{
- switch (ntype->type) {
- case GEO_NODE_BOOLEAN:
- ntype->draw_buttons = node_geometry_buts_boolean_math;
- break;
- case GEO_NODE_SUBDIVISION_SURFACE:
- ntype->draw_buttons = node_geometry_buts_subdivision_surface;
- break;
- case GEO_NODE_TRIANGULATE:
- ntype->draw_buttons = node_geometry_buts_triangulate;
- break;
- case GEO_NODE_ATTRIBUTE_RANDOMIZE:
- ntype->draw_buttons = node_geometry_buts_random_attribute;
- break;
- case GEO_NODE_ATTRIBUTE_MATH:
- ntype->draw_buttons = node_geometry_buts_attribute_math;
- break;
- case GEO_NODE_ATTRIBUTE_COMPARE:
- ntype->draw_buttons = node_geometry_buts_attribute_compare;
- break;
- case GEO_NODE_POINT_INSTANCE:
- ntype->draw_buttons = node_geometry_buts_point_instance;
- break;
- case GEO_NODE_ATTRIBUTE_FILL:
- ntype->draw_buttons = node_geometry_buts_attribute_fill;
- break;
- case GEO_NODE_ATTRIBUTE_MIX:
- ntype->draw_buttons = node_geometry_buts_attribute_mix;
- break;
- case GEO_NODE_ATTRIBUTE_VECTOR_MATH:
- ntype->draw_buttons = node_geometry_buts_attribute_vector_math;
- break;
- case GEO_NODE_POINT_DISTRIBUTE:
- ntype->draw_buttons = node_geometry_buts_attribute_point_distribute;
- break;
- case GEO_NODE_ATTRIBUTE_COLOR_RAMP:
- ntype->draw_buttons = node_geometry_buts_attribute_color_ramp;
- break;
- case GEO_NODE_POINT_ROTATE:
- ntype->draw_buttons = node_geometry_buts_point_rotate;
- break;
- case GEO_NODE_ALIGN_ROTATION_TO_VECTOR:
- ntype->draw_buttons = node_geometry_buts_align_rotation_to_vector;
- break;
- case GEO_NODE_POINT_TRANSLATE:
- ntype->draw_buttons = node_geometry_buts_point_translate;
- break;
- case GEO_NODE_POINT_SCALE:
- ntype->draw_buttons = node_geometry_buts_point_scale;
- break;
- case GEO_NODE_OBJECT_INFO:
- ntype->draw_buttons = node_geometry_buts_object_info;
- break;
- }
-}
-
-/* ****************** BUTTON CALLBACKS FOR FUNCTION NODES ***************** */
-
-static void node_function_buts_boolean_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_function_buts_float_compare(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_function_buts_switch(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "data_type", DEFAULT_FLAGS, "", ICON_NONE);
-}
-
-static void node_function_buts_input_vector(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayout *col = uiLayoutColumn(layout, true);
- uiItemR(col, ptr, "vector", UI_ITEM_R_EXPAND, "", ICON_NONE);
-}
-
-static void node_function_set_butfunc(bNodeType *ntype)
-{
- switch (ntype->type) {
- case FN_NODE_BOOLEAN_MATH:
- ntype->draw_buttons = node_function_buts_boolean_math;
- break;
- case FN_NODE_FLOAT_COMPARE:
- ntype->draw_buttons = node_function_buts_float_compare;
- break;
- case FN_NODE_SWITCH:
- ntype->draw_buttons = node_function_buts_switch;
- break;
- case FN_NODE_INPUT_VECTOR:
- ntype->draw_buttons = node_function_buts_input_vector;
- break;
- }
-}
-
/* ****** init draw callbacks for all tree types, only called in usiblender.c, once ************ */
static void node_property_update_default(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
@@ -3489,8 +3225,6 @@ void ED_node_init_butfuncs(void)
ntype->draw_nodetype_prepare = node_update_default;
ntype->select_area_func = node_select_area_default;
ntype->tweak_area_func = node_tweak_area_default;
- ntype->draw_buttons = NULL;
- ntype->draw_buttons_ex = NULL;
ntype->resize_area_func = node_resize_area_default;
node_common_set_butfunc(ntype);
@@ -3498,8 +3232,6 @@ void ED_node_init_butfuncs(void)
node_composit_set_butfunc(ntype);
node_shader_set_butfunc(ntype);
node_texture_set_butfunc(ntype);
- node_geometry_set_butfunc(ntype);
- node_function_set_butfunc(ntype);
/* define update callbacks for socket properties */
node_template_properties_update(ntype);
@@ -3828,18 +3560,18 @@ void draw_nodespace_back_pix(const bContext *C,
}
/* return quadratic beziers points for a given nodelink and clip if v2d is not NULL. */
-static bool node_link_bezier_handles(View2D *v2d,
- SpaceNode *snode,
- bNodeLink *link,
- float vec[4][2])
+bool node_link_bezier_handles(const View2D *v2d,
+ const SpaceNode *snode,
+ const bNodeLink *link,
+ float vec[4][2])
{
float cursor[2] = {0.0f, 0.0f};
/* this function can be called with snode null (via cut_links_intersect) */
- /* XXX map snode->cursor back to view space */
+ /* XXX map snode->runtime->cursor back to view space */
if (snode) {
- cursor[0] = snode->cursor[0] * UI_DPI_FAC;
- cursor[1] = snode->cursor[1] * UI_DPI_FAC;
+ cursor[0] = snode->runtime->cursor[0] * UI_DPI_FAC;
+ cursor[1] = snode->runtime->cursor[1] * UI_DPI_FAC;
}
/* in v0 and v3 we put begin/end points */
@@ -3859,6 +3591,9 @@ static bool node_link_bezier_handles(View2D *v2d,
if (link->tosock) {
vec[3][0] = link->tosock->locx;
vec[3][1] = link->tosock->locy;
+ if (!(link->tonode->flag & NODE_HIDDEN) && link->tosock->flag & SOCK_MULTI_INPUT) {
+ node_link_calculate_multi_input_position(link, vec[3]);
+ }
toreroute = (link->tonode && link->tonode->type == NODE_REROUTE);
}
else {
@@ -3923,8 +3658,11 @@ static bool node_link_bezier_handles(View2D *v2d,
}
/* if v2d not NULL, it clips and returns 0 if not visible */
-bool node_link_bezier_points(
- View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
+bool node_link_bezier_points(const View2D *v2d,
+ const SpaceNode *snode,
+ const bNodeLink *link,
+ float coord_array[][2],
+ const int resol)
{
float vec[4][2];
@@ -4087,7 +3825,7 @@ static char nodelink_get_color_id(int th_col)
return 0;
}
-static void nodelink_batch_draw(SpaceNode *snode)
+static void nodelink_batch_draw(const SpaceNode *snode)
{
if (g_batch_link.count == 0) {
return;
@@ -4107,7 +3845,7 @@ static void nodelink_batch_draw(SpaceNode *snode)
GPU_batch_program_set_builtin(g_batch_link.batch, GPU_SHADER_2D_NODELINK_INST);
GPU_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, colors);
- GPU_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->aspect * LINK_WIDTH);
+ GPU_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->runtime->aspect * LINK_WIDTH);
GPU_batch_uniform_1f(g_batch_link.batch, "arrowSize", ARROW_SIZE);
GPU_batch_draw(g_batch_link.batch);
@@ -4127,7 +3865,7 @@ void nodelink_batch_end(SpaceNode *snode)
g_batch_link.enabled = false;
}
-static void nodelink_batch_add_link(SpaceNode *snode,
+static void nodelink_batch_add_link(const SpaceNode *snode,
const float p0[2],
const float p1[2],
const float p2[2],
@@ -4159,11 +3897,15 @@ static void nodelink_batch_add_link(SpaceNode *snode,
}
/* don't do shadows if th_col3 is -1. */
-void node_draw_link_bezier(
- View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int th_col2, int th_col3)
+void node_draw_link_bezier(const View2D *v2d,
+ const SpaceNode *snode,
+ const bNodeLink *link,
+ int th_col1,
+ int th_col2,
+ int th_col3)
{
float vec[4][2];
-
+ const bool highlighted = link->flag & NODE_LINK_TEMP_HIGHLIGHT;
if (node_link_bezier_handles(v2d, snode, link, vec)) {
int drawarrow = ((link->tonode && (link->tonode->type == NODE_REROUTE)) &&
(link->fromnode && (link->fromnode->type == NODE_REROUTE)));
@@ -4172,7 +3914,7 @@ void node_draw_link_bezier(
nodelink_batch_init();
}
- if (g_batch_link.enabled) {
+ if (g_batch_link.enabled && !highlighted) {
/* Add link to batch. */
nodelink_batch_add_link(
snode, vec[0], vec[1], vec[2], vec[3], th_col1, th_col2, th_col3, drawarrow);
@@ -4186,11 +3928,17 @@ void node_draw_link_bezier(
UI_GetThemeColor4fv(th_col1, colors[1]);
UI_GetThemeColor4fv(th_col2, colors[2]);
+ if (highlighted) {
+ float link_preselection_highlight_color[4];
+ UI_GetThemeColor4fv(TH_SELECT, link_preselection_highlight_color);
+ copy_v4_v4(colors[2], link_preselection_highlight_color);
+ }
+
GPUBatch *batch = g_batch_link.batch_single;
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK);
GPU_batch_uniform_2fv_array(batch, "bezierPts", 4, vec);
GPU_batch_uniform_4fv_array(batch, "colors", 3, colors);
- GPU_batch_uniform_1f(batch, "expandSize", snode->aspect * LINK_WIDTH);
+ GPU_batch_uniform_1f(batch, "expandSize", snode->runtime->aspect * LINK_WIDTH);
GPU_batch_uniform_1f(batch, "arrowSize", ARROW_SIZE);
GPU_batch_uniform_1i(batch, "doArrow", drawarrow);
GPU_batch_draw(batch);
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index 508c0a47e21..e665f7b1d52 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -104,9 +104,8 @@ static bool add_reroute_intersect_check(bNodeLink *link,
if (node_link_bezier_points(NULL, NULL, 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) {
- result[0] = (mcoords[i][0] + mcoords[i + 1][0]) / 2.0f;
- result[1] = (mcoords[i][1] + mcoords[i + 1][1]) / 2.0f;
+ if (isect_seg_seg_v2_point(
+ mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1], result) > 0) {
return true;
}
}
@@ -312,6 +311,13 @@ void NODE_OT_add_reroute(wmOperatorType *ot)
/* ****************** Add File Node Operator ******************* */
+static bool node_add_file_poll(bContext *C)
+{
+ const SpaceNode *snode = CTX_wm_space_node(C);
+ return ED_operator_node_editable(C) &&
+ ELEM(snode->nodetree->type, NTREE_SHADER, NTREE_TEXTURE, NTREE_COMPOSIT);
+}
+
static int node_add_file_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -341,7 +347,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->cursor[0], snode->cursor[1]);
+ node = node_add_node(C, NULL, type, snode->runtime->cursor[0], snode->runtime->cursor[1]);
if (!node) {
BKE_report(op->reports, RPT_WARNING, "Could not add an image node");
@@ -370,11 +376,14 @@ static int node_add_file_invoke(bContext *C, wmOperator *op, const wmEvent *even
SpaceNode *snode = CTX_wm_space_node(C);
/* convert mouse coordinates to v2d space */
- UI_view2d_region_to_view(
- &region->v2d, event->mval[0], event->mval[1], &snode->cursor[0], &snode->cursor[1]);
+ UI_view2d_region_to_view(&region->v2d,
+ event->mval[0],
+ event->mval[1],
+ &snode->runtime->cursor[0],
+ &snode->runtime->cursor[1]);
- snode->cursor[0] /= UI_DPI_FAC;
- snode->cursor[1] /= UI_DPI_FAC;
+ snode->runtime->cursor[0] /= UI_DPI_FAC;
+ snode->runtime->cursor[1] /= UI_DPI_FAC;
if (RNA_struct_property_is_set(op->ptr, "filepath") ||
RNA_struct_property_is_set(op->ptr, "name")) {
@@ -393,7 +402,7 @@ void NODE_OT_add_file(wmOperatorType *ot)
/* callbacks */
ot->exec = node_add_file_exec;
ot->invoke = node_add_file_invoke;
- ot->poll = ED_operator_node_editable;
+ ot->poll = node_add_file_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -435,7 +444,8 @@ 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->cursor[0], snode->cursor[1]);
+ node = node_add_node(
+ C, NULL, 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");
diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c
index c9a0c827a09..fa4d6997c83 100644
--- a/source/blender/editors/space_node/node_buttons.c
+++ b/source/blender/editors/space_node/node_buttons.c
@@ -40,7 +40,6 @@
#include "RNA_access.h"
-#include "ED_gpencil.h"
#include "ED_screen.h"
#include "UI_resources.h"
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index d3fec7257f5..c7be5f848f7 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -22,6 +22,8 @@
* \brief higher level node drawing for the node editor.
*/
+#include "MEM_guardedalloc.h"
+
#include "DNA_light_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_material_types.h"
@@ -317,14 +319,14 @@ static void node_uiblocks_init(const bContext *C, bNodeTree *ntree)
}
}
-void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry)
+void node_to_view(const bNode *node, float x, float y, float *rx, float *ry)
{
nodeToView(node, x, y, rx, ry);
*rx *= UI_DPI_FAC;
*ry *= UI_DPI_FAC;
}
-void node_to_updated_rect(struct bNode *node, rctf *r_rect)
+void node_to_updated_rect(const bNode *node, rctf *r_rect)
{
node_to_view(node, node->offsetx, node->offsety, &r_rect->xmin, &r_rect->ymax);
node_to_view(node,
@@ -334,7 +336,7 @@ void node_to_updated_rect(struct bNode *node, rctf *r_rect)
&r_rect->ymin);
}
-void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry)
+void node_from_view(const bNode *node, float x, float y, float *rx, float *ry)
{
x /= UI_DPI_FAC;
y /= UI_DPI_FAC;
@@ -500,6 +502,16 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
PointerRNA sockptr;
RNA_pointer_create(&ntree->id, &RNA_NodeSocket, nsock, &sockptr);
+ /* Add the half the height of a multi-input socket to cursor Y
+ * to account for the increased height of the taller sockets. */
+ float multi_input_socket_offset = 0.0f;
+ if (nsock->flag & SOCK_MULTI_INPUT) {
+ if (nsock->total_inputs > 2) {
+ multi_input_socket_offset = (nsock->total_inputs - 2) * NODE_MULTI_INPUT_LINK_GAP;
+ }
+ }
+ dy -= multi_input_socket_offset * 0.5f;
+
uiLayout *layout = UI_block_layout(node->block,
UI_LAYOUT_VERTICAL,
UI_LAYOUT_PANEL,
@@ -533,7 +545,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
/* place the socket circle in the middle of the layout */
nsock->locy = 0.5f * (dy + buty);
- dy = buty;
+ dy = buty - multi_input_socket_offset * 0.5;
if (nsock->next) {
dy -= NODE_SOCKDY;
}
@@ -689,11 +701,11 @@ int node_get_colorid(bNode *node)
/* note: in cmp_util.c is similar code, for node_compo_pass_on()
* the same goes for shader and texture nodes. */
/* note: in node_edit.c is similar code, for untangle node */
-static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node)
+static void node_draw_mute_line(const View2D *v2d, const SpaceNode *snode, const bNode *node)
{
GPU_blend(GPU_BLEND_ALPHA);
- LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) {
+ LISTBASE_FOREACH (const bNodeLink *, link, &node->internal_links) {
node_draw_link_bezier(v2d, snode, link, TH_REDALERT, TH_REDALERT, -1);
}
@@ -751,6 +763,27 @@ static void node_socket_draw(const bNodeSocket *sock,
immVertex2f(pos_id, locx, locy);
}
+static void node_socket_draw_multi_input(const float color[4],
+ const float color_outline[4],
+ const float width,
+ const float height,
+ const int locx,
+ const int locy)
+{
+ const float outline_width = 1.0f;
+ /* UI_draw_roundbox draws the outline on the outer side, so compensate for the outline width. */
+ const rctf rect = {
+ .xmin = locx - width + outline_width * 0.5f,
+ .xmax = locx + width - outline_width * 0.5f,
+ .ymin = locy - height + outline_width * 0.5f,
+ .ymax = locy + height - outline_width * 0.5f,
+ };
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_4fv_ex(
+ &rect, color, NULL, 1.0f, color_outline, outline_width, width - outline_width * 0.5f);
+}
+
static void node_socket_outline_color_get(bool selected, float r_outline_color[4])
{
if (selected) {
@@ -947,14 +980,14 @@ static void node_toggle_button_cb(struct bContext *C, void *node_argv, void *op_
WM_operator_name_call(C, opname, WM_OP_INVOKE_DEFAULT, NULL);
}
-void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha)
+void node_draw_shadow(const SpaceNode *snode, const bNode *node, float radius, float alpha)
{
- rctf *rct = &node->totr;
+ const rctf *rct = &node->totr;
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- ui_draw_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT);
+ ui_draw_dropshadow(rct, radius, snode->runtime->aspect, alpha, node->flag & SELECT);
}
-void node_draw_sockets(View2D *v2d,
+void node_draw_sockets(const View2D *v2d,
const bContext *C,
bNodeTree *ntree,
bNode *node,
@@ -1006,6 +1039,10 @@ void node_draw_sockets(View2D *v2d,
selected_input_len++;
continue;
}
+ /* Don't draw multi-input sockets here since they are drawn in a different batch. */
+ if (sock->flag & SOCK_MULTI_INPUT) {
+ continue;
+ }
node_socket_draw_nested(C,
ntree,
@@ -1115,11 +1152,33 @@ void node_draw_sockets(View2D *v2d,
GPU_program_point_size(false);
GPU_blend(GPU_BLEND_NONE);
+
+ /* Draw multi-input sockets after the others because they are drawn with `UI_draw_roundbox`
+ * rather than with `GL_POINT`. */
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
+ if (nodeSocketIsHidden(socket)) {
+ continue;
+ }
+ if (!(socket->flag & SOCK_MULTI_INPUT)) {
+ continue;
+ }
+
+ const bool is_node_hidden = (node->flag & NODE_HIDDEN);
+ const float width = NODE_SOCKSIZE;
+ float height = is_node_hidden ? width : node_socket_calculate_height(socket) - width;
+
+ float color[4];
+ float outline_color[4];
+ node_socket_color_get((bContext *)C, ntree, &node_ptr, socket, color);
+ node_socket_outline_color_get(selected, outline_color);
+
+ node_socket_draw_multi_input(color, outline_color, width, height, socket->locx, socket->locy);
+ }
}
static void node_draw_basis(const bContext *C,
- ARegion *region,
- SpaceNode *snode,
+ const View2D *v2d,
+ const SpaceNode *snode,
bNodeTree *ntree,
bNode *node,
bNodeInstanceKey key)
@@ -1127,8 +1186,6 @@ static void node_draw_basis(const bContext *C,
/* float socket_size = NODE_SOCKSIZE*U.dpi/72; */ /* UNUSED */
float iconbutw = 0.8f * UI_UNIT_X;
- View2D *v2d = &region->v2d;
-
/* skip if out of view */
if (BLI_rctf_isect(&node->totr, &v2d->cur, NULL) == false) {
UI_block_end(C, node->block);
@@ -1157,7 +1214,15 @@ static void node_draw_basis(const bContext *C,
rctf *rct = &node->totr;
UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
UI_draw_roundbox_aa(
- true, rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD, color);
+ &(const rctf){
+ .xmin = rct->xmin,
+ .xmax = rct->xmax,
+ .ymin = rct->ymax - NODE_DY,
+ .ymax = rct->ymax,
+ },
+ true,
+ BASIS_RAD,
+ color);
/* show/hide icons */
float iconofs = rct->xmax - 0.35f * U.widget_unit;
@@ -1308,7 +1373,15 @@ static void node_draw_basis(const bContext *C,
UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
UI_draw_roundbox_aa(
- true, rct->xmin, rct->ymin, rct->xmax, rct->ymax - NODE_DY, BASIS_RAD, color);
+ &(const rctf){
+ .xmin = rct->xmin,
+ .xmax = rct->xmax,
+ .ymin = rct->ymin,
+ .ymax = rct->ymax - NODE_DY,
+ },
+ true,
+ BASIS_RAD,
+ color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
@@ -1316,7 +1389,16 @@ static void node_draw_basis(const bContext *C,
(node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, 0, -40, color);
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = rct->xmin,
+ .xmax = rct->xmax,
+ .ymin = rct->ymin,
+ .ymax = rct->ymax,
+ },
+ false,
+ BASIS_RAD,
+ color);
}
/* disable lines */
@@ -1343,8 +1425,8 @@ static void node_draw_basis(const bContext *C,
}
static void node_draw_hidden(const bContext *C,
- ARegion *region,
- SpaceNode *snode,
+ const View2D *v2d,
+ const SpaceNode *snode,
bNodeTree *ntree,
bNode *node,
bNodeInstanceKey UNUSED(key))
@@ -1353,8 +1435,6 @@ static void node_draw_hidden(const bContext *C,
float centy = BLI_rctf_cent_y(rct);
float hiddenrad = BLI_rctf_size_y(rct) / 2.0f;
- View2D *v2d = &region->v2d;
-
float scale;
UI_view2d_scale_get(v2d, &scale, NULL);
@@ -1373,14 +1453,14 @@ static void node_draw_hidden(const bContext *C,
UI_GetThemeColor4fv(color_id, color);
}
- UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad, color);
+ UI_draw_roundbox_aa(rct, true, hiddenrad, color);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
UI_GetThemeColorShadeAlpha4fv(
(node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, 0, -40, color);
- UI_draw_roundbox_aa(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad, color);
+ UI_draw_roundbox_aa(rct, false, hiddenrad, color);
}
/* custom color inline */
@@ -1388,14 +1468,17 @@ static void node_draw_hidden(const bContext *C,
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
- UI_draw_roundbox_3fv_alpha(false,
- rct->xmin + 1,
- rct->ymin + 1,
- rct->xmax - 1,
- rct->ymax - 1,
- hiddenrad,
- node->color,
- 1.0f);
+ UI_draw_roundbox_3fv_alpha(
+ &(const rctf){
+ .xmin = rct->xmin + 1,
+ .xmax = rct->xmax - 1,
+ .ymin = rct->ymin + 1,
+ .ymax = rct->ymax - 1,
+ },
+ false,
+ hiddenrad,
+ node->color,
+ 1.0f);
GPU_line_smooth(false);
GPU_blend(GPU_BLEND_NONE);
@@ -1438,7 +1521,7 @@ static void node_draw_hidden(const bContext *C,
/* disable lines */
if (node->flag & NODE_MUTED) {
- node_draw_mute_line(&region->v2d, snode, node);
+ node_draw_mute_line(v2d, snode, node);
}
char showname[128]; /* 128 is used below */
@@ -1477,19 +1560,19 @@ static void node_draw_hidden(const bContext *C,
immVertex2f(pos, rct->xmax - dx, centy - 4.0f);
immVertex2f(pos, rct->xmax - dx, centy + 4.0f);
- immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f);
- immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->runtime->aspect, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->runtime->aspect, centy + 4.0f);
immEnd();
immUniformThemeColorShade(color_id, 30);
- dx -= snode->aspect;
+ dx -= snode->runtime->aspect;
immBegin(GPU_PRIM_LINES, 4);
immVertex2f(pos, rct->xmax - dx, centy - 4.0f);
immVertex2f(pos, rct->xmax - dx, centy + 4.0f);
- immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy - 4.0f);
- immVertex2f(pos, rct->xmax - dx - 3.0f * snode->aspect, centy + 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->runtime->aspect, centy - 4.0f);
+ immVertex2f(pos, rct->xmax - dx - 3.0f * snode->runtime->aspect, centy + 4.0f);
immEnd();
immUnbindProgram();
@@ -1550,11 +1633,12 @@ void node_draw_default(const bContext *C,
bNode *node,
bNodeInstanceKey key)
{
+ const View2D *v2d = &region->v2d;
if (node->flag & NODE_HIDDEN) {
- node_draw_hidden(C, region, snode, ntree, node, key);
+ node_draw_hidden(C, v2d, snode, ntree, node, key);
}
else {
- node_draw_basis(C, region, snode, ntree, node, key);
+ node_draw_basis(C, v2d, snode, ntree, node, key);
}
}
@@ -1565,17 +1649,67 @@ static void node_update(const bContext *C, bNodeTree *ntree, bNode *node)
}
}
+static void count_mutli_input_socket_links(bNodeTree *ntree, SpaceNode *snode)
+{
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ LISTBASE_FOREACH (struct bNodeSocket *, socket, &node->inputs) {
+ if (socket->flag & SOCK_MULTI_INPUT) {
+ socket->total_inputs = 0;
+ LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
+ if (link->tosock == socket) {
+ socket->total_inputs++;
+ }
+ }
+ /* 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) {
+ socket->total_inputs++;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
void node_update_nodetree(const bContext *C, bNodeTree *ntree)
{
/* make sure socket "used" tags are correct, for displaying value buttons */
+ SpaceNode *snode = CTX_wm_space_node(C);
ntreeTagUsedSockets(ntree);
+ count_mutli_input_socket_links(ntree, snode);
+
/* update nodes front to back, so children sizes get updated before parents */
LISTBASE_FOREACH_BACKWARD (bNode *, node, &ntree->nodes) {
node_update(C, ntree, node);
}
}
+static int compare_link_by_angle_to_node(const void *a, const void *b)
+{
+ const bNodeLink *link_a = *(const bNodeLink **)a;
+ const bNodeLink *link_b = *(const bNodeLink **)b;
+
+ BLI_assert(link_a->tosock == link_b->tosock);
+ const float socket_location[2] = {link_a->tosock->locx, link_a->tosock->locy};
+ const float up_direction[2] = {0.0f, 1.0f};
+
+ float delta_a[2] = {link_a->fromsock->locx - socket_location[0],
+ link_a->fromsock->locy - socket_location[1]};
+ normalize_v2(delta_a);
+ const float angle_a = angle_normalized_v2v2(up_direction, delta_a);
+
+ float delta_b[2] = {link_b->fromsock->locx - socket_location[0],
+ link_b->fromsock->locy - socket_location[1]};
+ normalize_v2(delta_b);
+ const float angle_b = angle_normalized_v2v2(up_direction, delta_b);
+
+ return angle_a < angle_b ? 1 : -1;
+}
+
static void node_draw(const bContext *C,
ARegion *region,
SpaceNode *snode,
@@ -1590,6 +1724,46 @@ static void node_draw(const bContext *C,
#define USE_DRAW_TOT_UPDATE
+/**
+ * Automatically sort the input links to multi-input sockets to avoid crossing noodles.
+ */
+static void sort_multi_input_socket_links(bNodeTree *ntree, SpaceNode *snode)
+{
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
+ if (socket->flag & SOCK_MULTI_INPUT) {
+ /* The total is calculated in #node_update_nodetree, which runs before this draw step. */
+ const int total_inputs = socket->total_inputs;
+ bNodeLink **input_links = MEM_malloc_arrayN(total_inputs, sizeof(bNodeLink *), __func__);
+
+ int index = 0;
+ LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
+ if (link->tosock == socket) {
+ input_links[index] = (bNodeLink *)link;
+ index++;
+ }
+ }
+ LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->runtime->linkdrag) {
+ LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
+ bNodeLink *link = (bNodeLink *)linkdata->data;
+ if (link->tosock == socket) {
+ input_links[index] = (bNodeLink *)link;
+ index++;
+ }
+ }
+ }
+
+ qsort(input_links, total_inputs, sizeof(bNodeLink *), compare_link_by_angle_to_node);
+ for (int i = 0; i < total_inputs; i++) {
+ input_links[i]->multi_input_socket_index = i;
+ }
+
+ MEM_freeN(input_links);
+ }
+ }
+ }
+}
+
void node_draw_nodetree(const bContext *C,
ARegion *region,
SpaceNode *snode,
@@ -1607,8 +1781,7 @@ void node_draw_nodetree(const bContext *C,
#endif
/* draw background nodes, last nodes in front */
- int a = 0;
- LISTBASE_FOREACH_INDEX (bNode *, node, &ntree->nodes, a) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
#ifdef USE_DRAW_TOT_UPDATE
/* unrelated to background nodes, update the v2d->tot,
* can be anywhere before we draw the scroll bars */
@@ -1626,6 +1799,9 @@ void node_draw_nodetree(const bContext *C,
/* node lines */
GPU_blend(GPU_BLEND_ALPHA);
nodelink_batch_start(snode);
+
+ sort_multi_input_socket_links(ntree, snode);
+
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
if (!nodeLinkIsHidden(link)) {
node_draw_link(&region->v2d, snode, link);
@@ -1635,8 +1811,7 @@ void node_draw_nodetree(const bContext *C,
GPU_blend(GPU_BLEND_NONE);
/* draw foreground nodes, last nodes in front */
- a = 0;
- LISTBASE_FOREACH_INDEX (bNode *, node, &ntree->nodes, a) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->flag & NODE_BACKGROUND) {
continue;
}
@@ -1666,7 +1841,7 @@ static void snode_setup_v2d(SpaceNode *snode, ARegion *region, const float cente
UI_view2d_view_ortho(v2d);
/* aspect+font, set each time */
- snode->aspect = BLI_rctf_size_x(&v2d->cur) / (float)region->winx;
+ snode->runtime->aspect = BLI_rctf_size_x(&v2d->cur) / (float)region->winx;
// XXX snode->curfont = uiSetCurFont_ext(snode->aspect);
}
@@ -1686,8 +1861,8 @@ static void draw_nodetree(const bContext *C,
/* shade the parent node group and add a uiBlock to clip mouse events */
static void draw_group_overlay(const bContext *C, ARegion *region)
{
- View2D *v2d = &region->v2d;
- rctf rect = v2d->cur;
+ const View2D *v2d = &region->v2d;
+ const rctf rect = v2d->cur;
float color[4];
/* shade node groups to separate them visually */
@@ -1695,7 +1870,7 @@ static void draw_group_overlay(const bContext *C, ARegion *region)
UI_GetThemeColorShadeAlpha4fv(TH_NODE_GROUP, 0, 0, color);
UI_draw_roundbox_corner_set(UI_CNR_NONE);
- UI_draw_roundbox_4fv(true, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0, color);
+ UI_draw_roundbox_4fv(&rect, true, 0, color);
GPU_blend(GPU_BLEND_NONE);
/* set the block bounds to clip mouse events from underlying nodes */
@@ -1722,14 +1897,15 @@ void node_draw_space(const bContext *C, ARegion *region)
GPU_depth_test(GPU_DEPTH_NONE);
GPU_scissor_test(true);
- /* XXX snode->cursor set in coordspace for placing new nodes, used for drawing noodles too */
+ /* XXX snode->runtime->cursor set in coordspace for placing new nodes, used for drawing noodles
+ * too */
UI_view2d_region_to_view(&region->v2d,
win->eventstate->x - region->winrct.xmin,
win->eventstate->y - region->winrct.ymin,
- &snode->cursor[0],
- &snode->cursor[1]);
- snode->cursor[0] /= UI_DPI_FAC;
- snode->cursor[1] /= UI_DPI_FAC;
+ &snode->runtime->cursor[0],
+ &snode->runtime->cursor[1]);
+ snode->runtime->cursor[0] /= UI_DPI_FAC;
+ snode->runtime->cursor[1] /= UI_DPI_FAC;
int grid_levels = UI_GetThemeValueType(TH_NODE_GRID_LEVELS, SPACE_NODE);
@@ -1819,7 +1995,7 @@ void node_draw_space(const bContext *C, ARegion *region)
/* temporary links */
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
- LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->linkdrag) {
+ LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->runtime->linkdrag) {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
node_draw_link(v2d, snode, (bNodeLink *)linkdata->data);
}
@@ -1847,7 +2023,7 @@ void node_draw_space(const bContext *C, ARegion *region)
if (snode->treepath.last) {
if (snode->flag & SNODE_SHOW_GPENCIL) {
- /* draw grease-pencil (screen strokes, and also paintbuffer) */
+ /* Draw grease-pencil (screen strokes, and also paint-buffer). */
ED_annotation_draw_view2d(C, false);
}
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 30eee416b12..04787748937 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -98,6 +98,25 @@ typedef struct CompoJob {
float *progress;
} CompoJob;
+float node_socket_calculate_height(const bNodeSocket *socket)
+{
+ float sock_height = NODE_SOCKSIZE * 2.0f;
+ if (socket->flag & SOCK_MULTI_INPUT) {
+ sock_height += max_ii(NODE_MULTI_INPUT_LINK_GAP * 0.5f * socket->total_inputs, NODE_SOCKSIZE);
+ }
+ return sock_height;
+}
+
+void node_link_calculate_multi_input_position(const bNodeLink *link, float r[2])
+{
+ float offset = (link->tosock->total_inputs * NODE_MULTI_INPUT_LINK_GAP -
+ NODE_MULTI_INPUT_LINK_GAP) *
+ 0.5;
+ r[0] = link->tosock->locx - NODE_SOCKSIZE * 0.5f;
+ r[1] = link->tosock->locy - offset +
+ (link->multi_input_socket_index * NODE_MULTI_INPUT_LINK_GAP);
+}
+
static void compo_tag_output_nodes(bNodeTree *nodetree, int recalc_flags)
{
LISTBASE_FOREACH (bNode *, node, &nodetree->nodes) {
@@ -770,7 +789,7 @@ void ED_node_post_apply_transform(bContext *UNUSED(C), bNodeTree *UNUSED(ntree))
* which only exists during actual drawing. Can we rely on valid totr rects?
*/
/* make sure nodes have correct bounding boxes after transform */
- /* node_update_nodetree(C, ntree, 0.0f, 0.0f); */
+ // node_update_nodetree(C, ntree, 0.0f, 0.0f);
}
/* ***************** generic operator functions for nodes ***************** */
@@ -880,8 +899,8 @@ static void node_resize_init(
NodeSizeWidget *nsw = MEM_callocN(sizeof(NodeSizeWidget), "size widget op data");
op->customdata = nsw;
- nsw->mxstart = snode->cursor[0] * UI_DPI_FAC;
- nsw->mystart = snode->cursor[1] * UI_DPI_FAC;
+ nsw->mxstart = snode->runtime->cursor[0] * UI_DPI_FAC;
+ nsw->mystart = snode->runtime->cursor[1] * UI_DPI_FAC;
/* store old */
nsw->oldlocx = node->locx;
@@ -1104,6 +1123,21 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
}
/* checks snode->mouse position, and returns found node/socket */
+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,
+ .xmax = socket->locx + NODE_SOCKSIZE,
+ .ymin = socket->locy - node_socket_height * 0.5 - NODE_SOCKSIZE * 2.0f,
+ .ymax = socket->locy + node_socket_height * 0.5 + NODE_SOCKSIZE * 2.0f,
+ };
+ if (BLI_rctf_isect_pt(&multi_socket_rect, cursor[0], cursor[1])) {
+ return true;
+ }
+ return false;
+}
+
/* type is SOCK_IN and/or SOCK_OUT */
int node_find_indicated_socket(
SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, float cursor[2], int in_out)
@@ -1132,7 +1166,16 @@ int node_find_indicated_socket(
if (in_out & SOCK_IN) {
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
if (!nodeSocketIsHidden(sock)) {
- if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
+ if (sock->flag & SOCK_MULTI_INPUT && !(node->flag & NODE_HIDDEN)) {
+ if (cursor_isect_multi_input_socket(cursor, sock)) {
+ if (node == visible_node(snode, &rect)) {
+ *nodep = node;
+ *sockp = sock;
+ return 1;
+ }
+ }
+ }
+ else if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
if (node == visible_node(snode, &rect)) {
*nodep = node;
*sockp = sock;
@@ -1199,7 +1242,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
if (node->flag & SELECT) {
BKE_node_copy_store_new_pointers(ntree, node, LIB_ID_COPY_DEFAULT);
- /* to ensure redraws or rerenders happen */
+ /* To ensure redraws or re-renders happen. */
ED_node_tag_update_id(snode->id);
}
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index f2abe272f48..7f530408ec7 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -1039,7 +1039,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
snode_notify(C, snode);
snode_dag_update(C, snode);
- /* We broke relations in node tree, need to rebuild them in the grahes. */
+ /* We broke relations in node tree, need to rebuild them in the graphs. */
DEG_relations_tag_update(bmain);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index aa59b7293a3..2f3fa6996af 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -37,6 +37,7 @@ struct bContext;
struct bNode;
struct bNodeLink;
struct bNodeSocket;
+struct NodeInsertOfsData;
struct wmGizmoGroupType;
struct wmKeyConfig;
struct wmWindow;
@@ -50,25 +51,49 @@ typedef struct bNodeLinkDrag {
* This way the links can be added to the node tree while being stored in this list.
*/
ListBase links;
+ bool from_multi_input_socket;
int in_out;
} bNodeLinkDrag;
+typedef struct SpaceNode_Runtime {
+ float aspect;
+
+ /** Mouse position for drawing socket-less links and adding nodes. */
+ float cursor[2];
+
+ /** For auto compositing. */
+ bool recalc;
+
+ /** Temporary data for modal linking operator. */
+ struct ListBase linkdrag;
+
+ /* XXX hack for translate_attach op-macros to pass data from transform op to insert_offset op */
+ /** Temporary data for node insert offset (in UI called Auto-offset). */
+ struct NodeInsertOfsData *iofsd;
+} SpaceNode_Runtime;
+
/* space_node.c */
/* transform between View2Ds in the tree path */
void space_node_group_offset(struct SpaceNode *snode, float *x, float *y);
/* node_draw.c */
+float node_socket_calculate_height(const bNodeSocket *socket);
+void node_link_calculate_multi_input_position(const bNodeLink *link, float r[2]);
+
int node_get_colorid(struct bNode *node);
int node_get_resize_cursor(int directions);
-void node_draw_shadow(struct SpaceNode *snode, struct bNode *node, float radius, float alpha);
+void node_draw_shadow(const struct SpaceNode *snode,
+ const struct bNode *node,
+ float radius,
+ float alpha);
void node_draw_default(const struct bContext *C,
struct ARegion *region,
struct SpaceNode *snode,
struct bNodeTree *ntree,
struct bNode *node,
bNodeInstanceKey key);
-void node_draw_sockets(struct View2D *v2d,
+void node_draw_sockets(const struct View2D *v2d,
const struct bContext *C,
struct bNodeTree *ntree,
struct bNode *node,
@@ -92,9 +117,9 @@ void node_draw_space(const bContext *C, ARegion *region);
void node_set_cursor(struct wmWindow *win, struct SpaceNode *snode, float cursor[2]);
/* DPI scaled coords */
-void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry);
-void node_to_updated_rect(struct bNode *node, rctf *r_rect);
-void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry);
+void node_to_view(const struct bNode *node, float x, float y, float *rx, float *ry);
+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);
@@ -145,17 +170,21 @@ void nodelink_batch_start(struct SpaceNode *snode);
void nodelink_batch_end(struct SpaceNode *snode);
void node_draw_link(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link);
-void node_draw_link_bezier(struct View2D *v2d,
- struct SpaceNode *snode,
- struct bNodeLink *link,
+void node_draw_link_bezier(const struct View2D *v2d,
+ const struct SpaceNode *snode,
+ const struct bNodeLink *link,
int th_col1,
int th_col2,
int th_col3);
-bool node_link_bezier_points(struct View2D *v2d,
- struct SpaceNode *snode,
- struct bNodeLink *link,
+bool node_link_bezier_points(const struct View2D *v2d,
+ const struct SpaceNode *snode,
+ const struct bNodeLink *link,
float coord_array[][2],
- int resol);
+ const int resol);
+bool node_link_bezier_handles(const struct View2D *v2d,
+ const struct SpaceNode *snode,
+ const struct bNodeLink *link,
+ float vec[4][2]);
void draw_nodespace_back_pix(const struct bContext *C,
struct ARegion *region,
struct SpaceNode *snode,
@@ -268,6 +297,7 @@ extern const char *node_context_dir[];
#define NODE_HEIGHT(node) (node->height * UI_DPI_FAC)
#define NODE_MARGIN_X (1.10f * U.widget_unit)
#define NODE_SOCKSIZE (0.25f * U.widget_unit)
+#define NODE_MULTI_INPUT_LINK_GAP (0.25f * U.widget_unit)
#define NODE_RESIZE_MARGIN (0.20f * U.widget_unit)
#define NODE_LINK_RESOL 12
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 11933ef0811..d55fd06ddea 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -23,14 +23,10 @@
#include "DNA_node_types.h"
-#include "BLI_utildefines.h"
-
#include "BKE_context.h"
#include "ED_node.h" /* own include */
#include "ED_screen.h"
-#include "ED_select_utils.h"
-#include "ED_transform.h"
#include "RNA_access.h"
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index ba1e752e276..d6edfcce8e8 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -32,6 +32,7 @@
#include "BKE_anim_data.h"
#include "BKE_context.h"
+#include "BKE_curve.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_node.h"
@@ -58,7 +59,7 @@
static bool ntree_has_drivers(bNodeTree *ntree)
{
- AnimData *adt = BKE_animdata_from_id(&ntree->id);
+ const AnimData *adt = BKE_animdata_from_id(&ntree->id);
if (adt == NULL) {
return false;
}
@@ -179,6 +180,137 @@ typedef struct NodeInsertOfsData {
float offset_x; /* offset to apply to node chain */
} NodeInsertOfsData;
+static void clear_picking_highlight(ListBase *links)
+{
+ LISTBASE_FOREACH (bNodeLink *, link, links) {
+ link->flag &= ~NODE_LINK_TEMP_HIGHLIGHT;
+ }
+}
+
+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->data = oplink;
+ if (sock->in_out == SOCK_OUT) {
+ oplink->fromnode = node;
+ oplink->fromsock = sock;
+ }
+ else {
+ oplink->tonode = node;
+ oplink->tosock = sock;
+ }
+ oplink->flag |= NODE_LINK_VALID;
+ oplink->flag &= ~NODE_LINK_TEST;
+ if (node_connected_to_output(bmain, snode->edittree, node)) {
+ oplink->flag |= NODE_LINK_TEST;
+ }
+ return linkdata;
+}
+
+static void pick_link(const bContext *C,
+ wmOperator *op,
+ bNodeLinkDrag *nldrag,
+ SpaceNode *snode,
+ bNode *node,
+ bNodeLink *link_to_pick)
+{
+ clear_picking_highlight(&snode->edittree->links);
+ RNA_boolean_set(op->ptr, "has_link_picked", true);
+
+ Main *bmain = CTX_data_main(C);
+ LinkData *linkdata = create_drag_link(
+ bmain, snode, link_to_pick->fromnode, link_to_pick->fromsock);
+
+ BLI_addtail(&nldrag->links, linkdata);
+ nodeRemLink(snode->edittree, link_to_pick);
+ /* Send changed event to original link->tonode. */
+ if (node) {
+ snode_update(snode, node);
+ }
+}
+
+static void pick_input_link_by_link_intersect(const bContext *C,
+ wmOperator *op,
+ bNodeLinkDrag *nldrag,
+ const float *cursor)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ const ARegion *region = CTX_wm_region(C);
+ const View2D *v2d = &region->v2d;
+
+ float drag_start[2];
+ RNA_float_get_array(op->ptr, "drag_start", drag_start);
+ bNode *node;
+ bNodeSocket *socket;
+ node_find_indicated_socket(snode, &node, &socket, drag_start, SOCK_IN);
+
+ const float trigger_drag_distance = 25.0f;
+ const float cursor_link_touch_distance = 25.0f;
+
+ const float socket_height = node_socket_calculate_height(socket);
+
+ float cursor_to_socket_relative[2];
+ float socket_position[2] = {socket->locx, socket->locy};
+ sub_v2_v2v2(cursor_to_socket_relative, cursor, socket_position);
+ float distance_from_socket_v2[2] = {
+ max_ff(0, fabs(cursor_to_socket_relative[0]) - NODE_SOCKSIZE * 0.5),
+ max_ff(0, fabs(cursor_to_socket_relative[1]) - socket_height)};
+ const float distance_from_socket = len_v2(distance_from_socket_v2);
+
+ const int resolution = NODE_LINK_RESOL;
+
+ bNodeLink *link_to_pick = NULL;
+ clear_picking_highlight(&snode->edittree->links);
+ LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
+ if (link->tosock == socket) {
+ /* Test if the cursor is near a link. */
+ float vec[4][2];
+ node_link_bezier_handles(v2d, snode, link, vec);
+
+ float data[NODE_LINK_RESOL * 2 + 2];
+ BKE_curve_forward_diff_bezier(
+ vec[0][0], vec[1][0], vec[2][0], vec[3][0], data, resolution, sizeof(float[2]));
+ BKE_curve_forward_diff_bezier(
+ vec[0][1], vec[1][1], vec[2][1], vec[3][1], data + 1, resolution, sizeof(float[2]));
+
+ for (int i = 0; i < resolution * 2; i += 2) {
+ float *l1 = &data[i];
+ float *l2 = &data[i + 2];
+ float distance = dist_squared_to_line_segment_v2(cursor, l1, l2);
+ if (distance < cursor_link_touch_distance) {
+ link_to_pick = link;
+ RNA_int_set(op->ptr, "last_picked_link_index", link->multi_input_socket_index);
+ }
+ }
+ }
+ }
+
+ /* If no linked was picked in this call, try using the one picked in the previous call.
+ * Not essential for the basic behavior, but can make interaction feel a bit better if
+ * the mouse moves to the right and loses the "selection." */
+ if (!link_to_pick) {
+ int last_picked_link_index = RNA_int_get(op->ptr, "last_picked_link_index");
+ if (last_picked_link_index > -1) {
+ LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
+ if (link->multi_input_socket_index == last_picked_link_index) {
+ link_to_pick = link;
+ }
+ }
+ }
+ }
+
+ if (link_to_pick) {
+ /* Highlight is set here and cleared in the next iteration or if the operation finishes. */
+ link_to_pick->flag |= NODE_LINK_TEMP_HIGHLIGHT;
+ ED_area_tag_redraw(CTX_wm_area(C));
+
+ if (distance_from_socket > trigger_drag_distance) {
+ pick_link(C, op, nldrag, snode, node, link_to_pick);
+ }
+ }
+}
+
static int sort_nodes_locx(const void *a, const void *b)
{
const bNodeListItem *nli1 = a;
@@ -600,6 +732,13 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link)
tlink = NULL;
to_count--;
}
+ else if (tlink->fromsock == from) {
+ /* Also remove link if it comes from the same output. */
+ nodeRemLink(ntree, tlink);
+ tlink = NULL;
+ to_count--;
+ from_count--;
+ }
}
}
}
@@ -663,7 +802,7 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
snode_dag_update(C, snode);
}
- BLI_remlink(&snode->linkdrag, nldrag);
+ BLI_remlink(&snode->runtime->linkdrag, nldrag);
/* links->data pointers are either held by the tree or freed already */
BLI_freelistN(&nldrag->links);
MEM_freeN(nldrag);
@@ -736,7 +875,7 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
}
}
-/* loop that adds a nodelink, called by function below */
+/* Loop that adds a node-link, called by function below. */
/* in_out = starting socket */
static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
@@ -748,10 +887,15 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
switch (event->type) {
case MOUSEMOVE:
- node_link_find_socket(C, op, cursor);
+ if (nldrag->from_multi_input_socket && !RNA_boolean_get(op->ptr, "has_link_picked")) {
+ pick_input_link_by_link_intersect(C, op, nldrag, cursor);
+ }
+ else {
+ node_link_find_socket(C, op, cursor);
- node_link_update_header(C, nldrag);
- ED_region_tag_redraw(region);
+ node_link_update_header(C, nldrag);
+ ED_region_tag_redraw(region);
+ }
break;
case LEFTMOUSE:
@@ -762,6 +906,8 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
ED_workspace_status_text(C, NULL);
ED_region_tag_redraw(region);
+ SpaceNode *snode = CTX_wm_space_node(C);
+ clear_picking_highlight(&snode->edittree->links);
return OPERATOR_FINISHED;
}
break;
@@ -817,16 +963,7 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
/* dragged links are fixed on output side */
nldrag->in_out = SOCK_OUT;
/* create a new link */
- LinkData *linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
- bNodeLink *oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
- linkdata->data = oplink;
- oplink->fromnode = node;
- oplink->fromsock = sock;
- oplink->flag |= NODE_LINK_VALID;
- oplink->flag &= ~NODE_LINK_TEST;
- if (node_connected_to_output(bmain, snode->edittree, node)) {
- oplink->flag |= NODE_LINK_TEST;
- }
+ LinkData *linkdata = create_drag_link(bmain, snode, node, sock);
BLI_addtail(&nldrag->links, linkdata);
}
@@ -836,31 +973,38 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
const int num_links = nodeCountSocketLinks(snode->edittree, sock);
- int link_limit = nodeSocketLinkLimit(sock);
- if (num_links > 0 && (num_links >= link_limit || detach)) {
+ if (num_links > 0) {
/* dragged links are fixed on output side */
nldrag->in_out = SOCK_OUT;
/* detach current links and store them in the operator data */
+ bNodeLink *link_to_pick;
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &snode->edittree->links) {
if (link->tosock == sock) {
- LinkData *linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
- bNodeLink *oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
- linkdata->data = oplink;
- *oplink = *link;
- oplink->next = oplink->prev = NULL;
- oplink->flag |= NODE_LINK_VALID;
- oplink->flag &= ~NODE_LINK_TEST;
- if (node_connected_to_output(bmain, snode->edittree, link->tonode)) {
- oplink->flag |= NODE_LINK_TEST;
+ if (sock->flag & SOCK_MULTI_INPUT) {
+ nldrag->from_multi_input_socket = true;
}
+ link_to_pick = link;
+ }
+ }
- BLI_addtail(&nldrag->links, linkdata);
- nodeRemLink(snode->edittree, link);
+ 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");
+ linkdata->data = oplink;
+ *oplink = *link_to_pick;
+ oplink->next = oplink->prev = NULL;
+ oplink->flag |= NODE_LINK_VALID;
+ oplink->flag &= ~NODE_LINK_TEST;
+ if (node_connected_to_output(bmain, snode->edittree, link_to_pick->tonode)) {
+ oplink->flag |= NODE_LINK_TEST;
+ }
- /* send changed event to original link->tonode */
- if (node) {
- snode_update(snode, node);
- }
+ BLI_addtail(&nldrag->links, linkdata);
+ nodeRemLink(snode->edittree, link_to_pick);
+
+ /* send changed event to original link->tonode */
+ if (node) {
+ snode_update(snode, node);
}
}
}
@@ -868,16 +1012,7 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
/* dragged links are fixed on input side */
nldrag->in_out = SOCK_IN;
/* create a new link */
- LinkData *linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
- bNodeLink *oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
- linkdata->data = oplink;
- oplink->tonode = node;
- oplink->tosock = sock;
- oplink->flag |= NODE_LINK_VALID;
- oplink->flag &= ~NODE_LINK_TEST;
- if (node_connected_to_output(bmain, snode->edittree, node)) {
- oplink->flag |= NODE_LINK_TEST;
- }
+ LinkData *linkdata = create_drag_link(bmain, snode, node, sock);
BLI_addtail(&nldrag->links, linkdata);
}
@@ -896,6 +1031,9 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
float cursor[2];
UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &cursor[0], &cursor[1]);
+ RNA_float_set_array(op->ptr, "drag_start", cursor);
+ RNA_int_set(op->ptr, "last_picked_link_index", -1);
+ RNA_boolean_set(op->ptr, "has_link_picked", false);
ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
@@ -903,7 +1041,7 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (nldrag) {
op->customdata = nldrag;
- BLI_addtail(&snode->linkdrag, nldrag);
+ BLI_addtail(&snode->runtime->linkdrag, nldrag);
/* add modal handler */
WM_event_add_modal_handler(C, op);
@@ -918,10 +1056,11 @@ static void node_link_cancel(bContext *C, wmOperator *op)
SpaceNode *snode = CTX_wm_space_node(C);
bNodeLinkDrag *nldrag = op->customdata;
- BLI_remlink(&snode->linkdrag, nldrag);
+ BLI_remlink(&snode->runtime->linkdrag, nldrag);
BLI_freelistN(&nldrag->links);
MEM_freeN(nldrag);
+ clear_picking_highlight(&snode->edittree->links);
}
void NODE_OT_link(wmOperatorType *ot)
@@ -941,7 +1080,38 @@ void NODE_OT_link(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
+ PropertyRNA *prop;
+
RNA_def_boolean(ot->srna, "detach", false, "Detach", "Detach and redirect existing links");
+ prop = RNA_def_boolean(
+ ot->srna,
+ "has_link_picked",
+ false,
+ "Has Link Picked",
+ "The operation has placed a link. Only used for multi-input sockets, where the "
+ "link is picked later");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ RNA_def_float_array(ot->srna,
+ "drag_start",
+ 2,
+ 0,
+ -UI_PRECISION_FLOAT_MAX,
+ UI_PRECISION_FLOAT_MAX,
+ "Drag Start",
+ "The position of the mouse cursor at the start of the operation",
+ -UI_PRECISION_FLOAT_MAX,
+ UI_PRECISION_FLOAT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ RNA_def_int(ot->srna,
+ "last_picked_link_index",
+ -1,
+ -1,
+ 4095,
+ "Last Picked Link Index",
+ "The index of the last picked link on a multi-input socket",
+ -1,
+ 4095);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
/* ********************** Make Link operator ***************** */
@@ -1513,7 +1683,7 @@ void ED_node_link_intersect_test(ScrArea *area, int test)
/* loop over link coords to find shortest dist to
* upper left node edge of a intersected line segment */
for (int i = 0; i < NODE_LINK_RESOL; i++) {
- /* check if the node rect intersetcts the line from this point to next one */
+ /* Check if the node rectangle intersects the line from this point to next one. */
if (BLI_rctf_isect_segment(&select->totr, coord_array[i], coord_array[i + 1])) {
/* store the shortest distance to the upper left edge
* of all intersections found so far */
@@ -1798,7 +1968,7 @@ static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd,
static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
- NodeInsertOfsData *iofsd = snode->iofsd;
+ NodeInsertOfsData *iofsd = snode->runtime->iofsd;
bool redraw = false;
if (!snode || event->type != TIMER || iofsd == NULL || iofsd->anim_timer != event->customdata) {
@@ -1837,7 +2007,7 @@ static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const w
node->anim_init_locx = node->anim_ofsx = 0.0f;
}
- snode->iofsd = NULL;
+ snode->runtime->iofsd = NULL;
MEM_freeN(iofsd);
return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
@@ -1851,7 +2021,7 @@ static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const w
static int node_insert_offset_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
const SpaceNode *snode = CTX_wm_space_node(C);
- NodeInsertOfsData *iofsd = snode->iofsd;
+ NodeInsertOfsData *iofsd = snode->runtime->iofsd;
if (!iofsd || !iofsd->insert) {
return OPERATOR_CANCELLED;
@@ -1927,7 +2097,7 @@ void ED_node_link_insert(Main *bmain, ScrArea *area)
iofsd->prev = link->fromnode;
iofsd->next = node;
- snode->iofsd = iofsd;
+ snode->runtime->iofsd = iofsd;
}
ntreeUpdateTree(bmain, snode->edittree); /* needed for pointers */
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index 5060ac0db8a..1e6ca66dd31 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -26,7 +26,6 @@
#include "DNA_node_types.h"
#include "DNA_windowmanager_types.h"
-#include "BLI_alloca.h"
#include "BLI_lasso_2d.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
@@ -62,14 +61,15 @@
#include "node_intern.h" /* own include */
-/* Function to detect if there is a visible view3d that uses workbench in texture mode.
+/**
+ * Function to detect if there is a visible view3d that uses workbench in texture mode.
* This function is for fixing T76970 for Blender 2.83. The actual fix should add a mechanism in
* the depsgraph that can be used by the draw engines to check if they need to be redrawn.
*
* We don't want to add these risky changes this close before releasing 2.83 without good testing
* hence this workaround. There are still cases were too many updates happen. For example when you
* have both a Cycles and workbench with textures viewport.
- * */
+ */
static bool has_workbench_in_texture_color(const wmWindowManager *wm,
const Scene *scene,
const Object *ob)
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index 553971cd0a5..f0e3f5442cc 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -35,7 +35,6 @@
#include "BKE_context.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
-#include "BKE_scene.h"
#include "RNA_access.h"
diff --git a/source/blender/editors/space_node/node_toolbar.c b/source/blender/editors/space_node/node_toolbar.c
index 7afd3fef4db..2e7d6ab6cd5 100644
--- a/source/blender/editors/space_node/node_toolbar.c
+++ b/source/blender/editors/space_node/node_toolbar.c
@@ -29,9 +29,6 @@
#include "BKE_screen.h"
#include "WM_api.h"
-#include "WM_types.h"
-
-#include "ED_screen.h"
#include "node_intern.h" /* own include */
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index d938cb38270..8f1dc3c8c3e 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -52,7 +52,6 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "NOD_composite.h"
#include "node_intern.h" /* own include */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index ad7632377a3..73c6a28a5dc 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -35,7 +35,6 @@
#include "BKE_context.h"
#include "BKE_lib_id.h"
#include "BKE_node.h"
-#include "BKE_scene.h"
#include "BKE_screen.h"
#include "ED_node.h"
@@ -321,18 +320,25 @@ static void node_free(SpaceLink *sl)
LISTBASE_FOREACH_MUTABLE (bNodeTreePath *, path, &snode->treepath) {
MEM_freeN(path);
}
+
+ MEM_SAFE_FREE(snode->runtime);
}
/* spacetype; init callback */
-static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(area))
+static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *area)
{
+ SpaceNode *snode = (SpaceNode *)area->spacedata.first;
+
+ if (snode->runtime == NULL) {
+ snode->runtime = MEM_callocN(sizeof(SpaceNode_Runtime), __func__);
+ }
}
-static void node_area_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+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 */
SpaceNode *snode = area->spacedata.first;
/* shaderfrom is only used for new shading nodes, otherwise all shaders are from objects */
@@ -362,7 +368,7 @@ static void node_area_listener(wmWindow *UNUSED(win),
case ND_TRANSFORM_DONE:
if (ED_node_is_compositor(snode)) {
if (snode->flag & SNODE_AUTO_RENDER) {
- snode->recalc = 1;
+ snode->runtime->recalc = true;
ED_area_tag_refresh(area);
}
}
@@ -521,8 +527,8 @@ static void node_area_refresh(const struct bContext *C, ScrArea *area)
Scene *scene = (Scene *)snode->id;
if (scene->use_nodes) {
/* recalc is set on 3d view changes for auto compo */
- if (snode->recalc) {
- snode->recalc = 0;
+ if (snode->runtime->recalc) {
+ snode->runtime->recalc = false;
node_render_changed_exec((struct bContext *)C, NULL);
}
else {
@@ -546,8 +552,10 @@ static SpaceLink *node_duplicate(SpaceLink *sl)
BLI_duplicatelist(&snoden->treepath, &snode->treepath);
- /* clear or remove stuff from old */
- BLI_listbase_clear(&snoden->linkdrag);
+ if (snode->runtime != NULL) {
+ snoden->runtime = MEM_dupallocN(snode->runtime);
+ BLI_listbase_clear(&snoden->runtime->linkdrag);
+ }
/* Note: no need to set node tree user counts,
* the editor only keeps at least 1 (id_us_ensure_real),
@@ -589,6 +597,16 @@ static void node_toolbar_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
+void ED_node_cursor_location_get(const SpaceNode *snode, float value[2])
+{
+ copy_v2_v2(value, snode->runtime->cursor);
+}
+
+void ED_node_cursor_location_set(SpaceNode *snode, const float value[2])
+{
+ copy_v2_v2(snode->runtime->cursor, value);
+}
+
static void node_cursor(wmWindow *win, ScrArea *area, ARegion *region)
{
SpaceNode *snode = area->spacedata.first;
@@ -597,15 +615,15 @@ static void node_cursor(wmWindow *win, ScrArea *area, ARegion *region)
UI_view2d_region_to_view(&region->v2d,
win->eventstate->x - region->winrct.xmin,
win->eventstate->y - region->winrct.ymin,
- &snode->cursor[0],
- &snode->cursor[1]);
+ &snode->runtime->cursor[0],
+ &snode->runtime->cursor[1]);
- /* here snode->cursor is used to detect the node edge for sizing */
- node_set_cursor(win, snode, snode->cursor);
+ /* here snode->runtime->cursor is used to detect the node edge for sizing */
+ node_set_cursor(win, snode, snode->runtime->cursor);
- /* XXX snode->cursor is in placing new nodes space */
- snode->cursor[0] /= UI_DPI_FAC;
- snode->cursor[1] /= UI_DPI_FAC;
+ /* XXX snode->runtime->cursor is in placing new nodes space */
+ snode->runtime->cursor[0] /= UI_DPI_FAC;
+ snode->runtime->cursor[1] /= UI_DPI_FAC;
}
/* Initialize main region, setting handlers. */
@@ -645,7 +663,7 @@ static bool node_ima_drop_poll(bContext *UNUSED(C),
/* rule might not work? */
return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE));
}
- return WM_drag_get_local_ID(drag, ID_IM) != NULL;
+ return WM_drag_is_ID_type(drag, ID_IM);
}
static bool node_mask_drop_poll(bContext *UNUSED(C),
@@ -653,19 +671,19 @@ static bool node_mask_drop_poll(bContext *UNUSED(C),
const wmEvent *UNUSED(event),
const char **UNUSED(r_tooltip))
{
- return WM_drag_get_local_ID(drag, ID_MSK) != NULL;
+ return WM_drag_is_ID_type(drag, ID_MSK);
}
static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = WM_drag_get_local_ID(drag, 0);
+ ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = WM_drag_get_local_ID(drag, 0);
+ ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
if (id) {
RNA_string_set(drop->ptr, "name", id->name + 2);
@@ -703,12 +721,10 @@ static void node_header_region_draw(const bContext *C, ARegion *region)
}
/* used for header + main region */
-static void node_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void node_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
wmGizmoMap *gzmap = region->gizmo_map;
/* context changes */
diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt
index e0262371559..d54265aa292 100644
--- a/source/blender/editors/space_outliner/CMakeLists.txt
+++ b/source/blender/editors/space_outliner/CMakeLists.txt
@@ -27,6 +27,7 @@ set(INC
../../makesrna
../../sequencer
../../windowmanager
+ ../../../../intern/clog
../../../../intern/glew-mx
../../../../intern/guardedalloc
)
diff --git a/source/blender/editors/space_outliner/outliner_context.c b/source/blender/editors/space_outliner/outliner_context.c
index a314a640e42..e2b3b79e027 100644
--- a/source/blender/editors/space_outliner/outliner_context.c
+++ b/source/blender/editors/space_outliner/outliner_context.c
@@ -27,8 +27,6 @@
#include "DNA_space_types.h"
-#include "RNA_access.h"
-
#include "outliner_intern.h"
static void outliner_context_selected_ids_recursive(const ListBase *subtree,
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index ab515c0c3a8..70aeef76234 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -140,6 +140,11 @@ static TreeElement *outliner_drop_insert_find(bContext *C,
TreeElement *te_hovered;
float view_mval[2];
+ /* Empty tree, e.g. while filtered. */
+ if (BLI_listbase_is_empty(&space_outliner->tree)) {
+ return NULL;
+ }
+
UI_view2d_region_to_view(
&region->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
te_hovered = outliner_find_item_at_y(space_outliner, &space_outliner->tree, view_mval[1]);
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 8104c1e0d58..76c710b3db1 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -314,7 +314,7 @@ static void outliner_object_set_flag_recursive_fn(bContext *C,
/**
* Object properties.
- * */
+ */
static void outliner__object_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
{
Object *ob = poin;
@@ -324,7 +324,7 @@ static void outliner__object_set_flag_recursive_fn(bContext *C, void *poin, void
/**
* Base properties.
- * */
+ */
static void outliner__base_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
{
Base *base = poin;
@@ -697,13 +697,13 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname)
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
- WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL);
break;
}
default:
- WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL);
break;
}
+ WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL);
+
/* Check the library target exists */
if (te->idcode == ID_LI) {
Library *lib = (Library *)tselem->id;
@@ -2287,12 +2287,6 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
case TSE_R_LAYER:
data.icon = ICON_RENDER_RESULT;
break;
- case TSE_LINKED_LAMP:
- data.icon = ICON_LIGHT_DATA;
- break;
- case TSE_LINKED_MAT:
- data.icon = ICON_MATERIAL_DATA;
- break;
case TSE_POSEGRP_BASE:
case TSE_POSEGRP:
data.icon = ICON_GROUP_BONE;
@@ -2695,13 +2689,16 @@ static void outliner_draw_iconrow_number(const uiFontStyle *fstyle,
float offset_x = (float)offsx + UI_UNIT_X * 0.35f;
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true,
- offset_x + ufac,
- (float)ys - UI_UNIT_Y * 0.2f + ufac,
- offset_x + UI_UNIT_X - ufac,
- (float)ys - UI_UNIT_Y * 0.2f + UI_UNIT_Y - ufac,
- (float)UI_UNIT_Y / 2.0f - ufac,
- color);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = offset_x + ufac,
+ .xmax = offset_x + UI_UNIT_X - ufac,
+ .ymin = (float)ys - UI_UNIT_Y * 0.2f + ufac,
+ .ymax = (float)ys - UI_UNIT_Y * 0.2f + UI_UNIT_Y - ufac,
+ },
+ true,
+ (float)UI_UNIT_Y / 2.0f - ufac,
+ color);
/* Now the numbers. */
uchar text_col[4];
@@ -2751,8 +2748,26 @@ static void outliner_draw_active_indicator(const float minx,
const float radius = UI_UNIT_Y / 4.0f;
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true, minx, miny + ufac, maxx, maxy - ufac, radius, icon_color);
- UI_draw_roundbox_aa(false, minx, miny + ufac, maxx, maxy - ufac, radius, icon_border);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = minx,
+ .xmax = maxx,
+ .ymin = miny + ufac,
+ .ymax = maxy - ufac,
+ },
+ true,
+ radius,
+ icon_color);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = minx,
+ .xmax = maxx,
+ .ymin = miny + ufac,
+ .ymax = maxy - ufac,
+ },
+ false,
+ radius,
+ icon_border);
GPU_blend(GPU_BLEND_ALPHA); /* Roundbox disables. */
}
@@ -3038,7 +3053,7 @@ static void outliner_draw_tree_element(bContext *C,
}
else {
active = tree_element_type_active(C, tvc, space_outliner, te, tselem, OL_SETSEL_NONE, false);
- /* active collection*/
+ /* Active collection. */
}
/* active circle */
@@ -3058,7 +3073,7 @@ static void outliner_draw_tree_element(bContext *C,
}
else if (te->subtree.first || (tselem->type == 0 && te->idcode == ID_SCE) ||
(te->flag & TE_LAZY_CLOSED)) {
- /* open/close icon, only when sublevels, except for scene */
+ /* Open/close icon, only when sub-levels, except for scene. */
int icon_x = startx;
/* Icons a bit higher. */
@@ -3496,7 +3511,7 @@ static void outliner_draw_tree(bContext *C,
GPU_scissor(0, 0, mask_x, region->winy);
}
- /* Draw hierarhcy lines for collections and object children. */
+ /* Draw hierarchy lines for collections and object children. */
starty = (int)region->v2d.tot.ymax - OL_Y_OFFSET;
startx = mode_column_offset + UI_UNIT_X / 2 - (U.pixelsize + 1) / 2;
outliner_draw_hierarchy_lines(space_outliner, &space_outliner->tree, startx, &starty);
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index acda5ae82f0..7e5b0c90714 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -21,22 +21,9 @@
* \ingroup spoutliner
*/
-#include "MEM_guardedalloc.h"
-
-#include "DNA_collection_types.h"
-
-#include "BLT_translation.h"
-
-#include "RNA_access.h"
-
-#include "UI_interface.h"
-#include "UI_view2d.h"
-
#include "WM_api.h"
-#include "WM_types.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "outliner_intern.h"
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 600047c4b11..4a58736966c 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -927,25 +927,6 @@ static eOLDrawState tree_element_active_sequence_dup(Scene *scene,
return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_keymap_item(bContext *UNUSED(C),
- Scene *UNUSED(scene),
- ViewLayer *UNUSED(sl),
- TreeElement *te,
- TreeStoreElem *UNUSED(tselem),
- const eOLSetState set)
-{
- wmKeyMapItem *kmi = te->directdata;
-
- if (set == OL_SETSEL_NONE) {
- if (kmi->flag & KMI_INACTIVE) {
- return OL_DRAWSEL_NONE;
- }
- return OL_DRAWSEL_NORMAL;
- }
- kmi->flag ^= KMI_INACTIVE;
- return OL_DRAWSEL_NONE;
-}
-
static eOLDrawState tree_element_active_master_collection(bContext *C,
TreeElement *UNUSED(te),
const eOLSetState set)
@@ -1071,8 +1052,6 @@ eOLDrawState tree_element_type_active(bContext *C,
return tree_element_active_sequence(C, tvc->scene, te, tselem, set);
case TSE_SEQUENCE_DUP:
return tree_element_active_sequence_dup(tvc->scene, te, tselem, set);
- case TSE_KEYMAP_ITEM:
- return tree_element_active_keymap_item(C, tvc->scene, tvc->view_layer, te, tselem, set);
case TSE_GP_LAYER:
return tree_element_active_gplayer(C, tvc->scene, te, tselem, set);
break;
@@ -1543,7 +1522,7 @@ static bool outliner_is_co_within_active_mode_column(bContext *C,
* Action to run when clicking in the outliner,
*
* May expend/collapse branches or activate items.
- * */
+ */
static int outliner_item_do_activate_from_cursor(bContext *C,
const int mval[2],
const bool extend,
diff --git a/source/blender/editors/space_outliner/outliner_sync.c b/source/blender/editors/space_outliner/outliner_sync.c
index 0b2d1ce34ec..8bd5e3a130a 100644
--- a/source/blender/editors/space_outliner/outliner_sync.c
+++ b/source/blender/editors/space_outliner/outliner_sync.c
@@ -38,7 +38,6 @@
#include "BKE_context.h"
#include "BKE_layer.h"
#include "BKE_main.h"
-#include "BKE_object.h"
#include "DEG_depsgraph.h"
@@ -378,7 +377,7 @@ void ED_outliner_select_sync_from_outliner(bContext *C, SpaceOutliner *space_out
selected_items_free(&selected_items);
- /* Tag for updates and clear dirty flag toprevent a sync to the outliner on draw */
+ /* Tag for updates and clear dirty flag to prevent a sync to the outliner on draw. */
if (sync_types.object) {
space_outliner->sync_select_dirty &= ~WM_OUTLINER_SYNC_SELECT_FROM_OBJECT;
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
@@ -545,7 +544,7 @@ static void get_sync_select_active_data(const bContext *C, SyncSelectActiveData
active_data->sequence = SEQ_select_active_get(scene);
}
-/* If outliner is dirty sync selection from view layer and sequwncer */
+/* If outliner is dirty sync selection from view layer and sequencer. */
void outliner_sync_selection(const bContext *C, SpaceOutliner *space_outliner)
{
/* Set which types of data to sync from sync dirty flag and outliner display mode */
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 2a2803c58dd..8b522d41af8 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -23,6 +23,8 @@
#include "MEM_guardedalloc.h"
+#include "CLG_log.h"
+
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_collection_types.h"
@@ -92,6 +94,8 @@
#include "outliner_intern.h"
+static CLG_LogRef LOG = {"ed.outliner.tools"};
+
/* -------------------------------------------------------------------- */
/** \name ID/Library/Data Set/Un-link Utilities
* \{ */
@@ -790,7 +794,7 @@ static void id_override_library_create_fn(bContext *C,
id_root->tag |= LIB_TAG_DOIT;
- /* For now, remapp all local usages of linked ID to local override one here. */
+ /* For now, remap all local usages of linked ID to local override one here. */
ID *id_iter;
FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
if (ID_IS_LINKED(id_iter)) {
@@ -824,6 +828,9 @@ static void id_override_library_create_fn(bContext *C,
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
}
}
+ else {
+ CLOG_WARN(&LOG, "Could not create library override for data block '%s'", id_root->name);
+ }
}
static void id_override_library_reset_fn(bContext *C,
@@ -852,6 +859,9 @@ static void id_override_library_reset_fn(bContext *C,
WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
+ else {
+ CLOG_WARN(&LOG, "Could not reset library override of data block '%s'", id_root->name);
+ }
}
static void id_override_library_resync_fn(bContext *C,
@@ -883,6 +893,9 @@ static void id_override_library_resync_fn(bContext *C,
BKE_lib_override_library_resync(bmain, scene, CTX_data_view_layer(C), id_root);
}
+ else {
+ CLOG_WARN(&LOG, "Could not resync library override of data block '%s'", id_root->name);
+ }
}
static void id_override_library_delete_fn(bContext *C,
@@ -914,6 +927,9 @@ static void id_override_library_delete_fn(bContext *C,
BKE_lib_override_library_delete(bmain, id_root);
}
+ else {
+ CLOG_WARN(&LOG, "Could not delete library override of data block '%s'", id_root->name);
+ }
}
static void id_fake_user_set_fn(bContext *UNUSED(C),
@@ -1789,21 +1805,44 @@ static bool outliner_id_operation_item_poll(bContext *C,
const int enum_value)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
+ TreeElement *te = get_target_element(space_outliner);
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (!TSE_IS_REAL_ID(tselem)) {
+ return false;
+ }
+
+ Object *ob = NULL;
+ if (GS(tselem->id->name) == ID_OB) {
+ ob = (Object *)tselem->id;
+ }
switch (enum_value) {
case OUTLINER_IDOP_MARK_ASSET:
case OUTLINER_IDOP_CLEAR_ASSET:
return U.experimental.use_asset_browser;
case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE:
+ if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id)) {
+ return true;
+ }
+ return false;
case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY:
- return true;
+ if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id) || (ID_IS_LINKED(tselem->id))) {
+ return true;
+ }
+ return false;
+ case OUTLINER_IDOP_OVERRIDE_LIBRARY_PROXY_CONVERT:
+ if (ob != NULL && ob->proxy != NULL) {
+ return true;
+ }
+ return false;
case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET:
case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY:
- return true;
case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY:
- return true;
case OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY:
- return true;
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(tselem->id)) {
+ return true;
+ }
+ return false;
case OUTLINER_IDOP_SINGLE:
if (!space_outliner || ELEM(space_outliner->outlinevis, SO_SCENES, SO_VIEW_LAYER)) {
return true;
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index acfeccca175..f94f19246fa 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -167,8 +167,6 @@ static void outliner_storage_cleanup(SpaceOutliner *space_outliner)
static void check_persistent(
SpaceOutliner *space_outliner, TreeElement *te, ID *id, short type, short nr)
{
- TreeStoreElem *tselem;
-
if (space_outliner->treestore == NULL) {
/* if treestore was not created in readfile.c, create it here */
space_outliner->treestore = BLI_mempool_create(
@@ -181,7 +179,8 @@ static void check_persistent(
/* find any unused tree element in treestore and mark it as used
* (note that there may be multiple unused elements in case of linked objects) */
- tselem = BKE_outliner_treehash_lookup_unused(space_outliner->runtime->treehash, type, nr, id);
+ TreeStoreElem *tselem = BKE_outliner_treehash_lookup_unused(
+ space_outliner->runtime->treehash, type, nr, id);
if (tselem) {
te->store_elem = tselem;
tselem->used = 1;
@@ -204,8 +203,7 @@ static void check_persistent(
void outliner_free_tree(ListBase *tree)
{
- for (TreeElement *element = tree->first, *element_next; element; element = element_next) {
- element_next = element->next;
+ LISTBASE_FOREACH_MUTABLE (TreeElement *, element, tree) {
outliner_free_tree_element(element, tree);
}
}
@@ -271,8 +269,8 @@ static void outliner_add_bone(SpaceOutliner *space_outliner,
te->name = curBone->name;
te->directdata = curBone;
- for (curBone = curBone->childbase.first; curBone; curBone = curBone->next) {
- outliner_add_bone(space_outliner, &te->subtree, id, curBone, te, a);
+ LISTBASE_FOREACH (Bone *, child_bone, &curBone->childbase) {
+ outliner_add_bone(space_outliner, &te->subtree, id, child_bone, te, a);
}
}
@@ -381,35 +379,30 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
if (ob->pose) {
bArmature *arm = ob->data;
- bPoseChannel *pchan;
TreeElement *tenla = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_POSE_BASE, 0);
-
tenla->name = IFACE_("Pose");
/* channels undefined in editmode, but we want the 'tenla' pose icon itself */
if ((arm->edbo == NULL) && (ob->mode & OB_MODE_POSE)) {
- TreeElement *ten;
- int a = 0, const_index = 1000; /* ensure unique id for bone constraints */
-
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next, a++) {
- ten = outliner_add_element(
+ int const_index = 1000; /* ensure unique id for bone constraints */
+ int a;
+ LISTBASE_FOREACH_INDEX (bPoseChannel *, pchan, &ob->pose->chanbase, a) {
+ TreeElement *ten = outliner_add_element(
space_outliner, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a);
ten->name = pchan->name;
ten->directdata = pchan;
pchan->temp = (void *)ten;
- if (pchan->constraints.first) {
+ if (!BLI_listbase_is_empty(&pchan->constraints)) {
/* Object *target; */
- bConstraint *con;
- TreeElement *ten1;
TreeElement *tenla1 = outliner_add_element(
space_outliner, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
+ tenla1->name = IFACE_("Constraints");
/* char *str; */
- tenla1->name = IFACE_("Constraints");
- for (con = pchan->constraints.first; con; con = con->next, const_index++) {
- ten1 = outliner_add_element(
+ LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
+ TreeElement *ten1 = outliner_add_element(
space_outliner, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index);
#if 0 /* disabled as it needs to be reworked for recoded constraints system */
target = get_constraint_target(con, &str);
@@ -427,15 +420,16 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
ten1->directdata = con;
/* possible add all other types links? */
}
+ const_index++;
}
}
/* make hierarchy */
- ten = tenla->subtree.first;
+ TreeElement *ten = tenla->subtree.first;
while (ten) {
TreeElement *nten = ten->next, *par;
tselem = TREESTORE(ten);
if (tselem->type == TSE_POSE_CHANNEL) {
- pchan = (bPoseChannel *)ten->directdata;
+ bPoseChannel *pchan = (bPoseChannel *)ten->directdata;
if (pchan->parent) {
BLI_remlink(&tenla->subtree, ten);
par = (TreeElement *)pchan->parent->temp;
@@ -448,17 +442,15 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
}
/* Pose Groups */
- if (ob->pose->agroups.first) {
- bActionGroup *agrp;
+ if (!BLI_listbase_is_empty(&ob->pose->agroups)) {
TreeElement *ten_bonegrp = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0);
- int a = 0;
-
ten_bonegrp->name = IFACE_("Bone Groups");
- for (agrp = ob->pose->agroups.first; agrp; agrp = agrp->next, a++) {
- TreeElement *ten;
- ten = outliner_add_element(
- space_outliner, &ten_bonegrp->subtree, ob, ten_bonegrp, TSE_POSEGRP, a);
+
+ int index;
+ LISTBASE_FOREACH_INDEX (bActionGroup *, agrp, &ob->pose->agroups, index) {
+ TreeElement *ten = outliner_add_element(
+ space_outliner, &ten_bonegrp->subtree, ob, ten_bonegrp, TSE_POSEGRP, index);
ten->name = agrp->name;
ten->directdata = agrp;
}
@@ -469,18 +461,15 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
outliner_add_element(space_outliner, &te->subtree, ob->mat[a], te, 0, a);
}
- if (ob->constraints.first) {
- /* Object *target; */
- bConstraint *con;
- TreeElement *ten;
+ if (!BLI_listbase_is_empty(&ob->constraints)) {
TreeElement *tenla = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0);
- /* char *str; */
- int a;
-
tenla->name = IFACE_("Constraints");
- for (con = ob->constraints.first, a = 0; con; con = con->next, a++) {
- ten = outliner_add_element(space_outliner, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a);
+
+ int index;
+ LISTBASE_FOREACH_INDEX (bConstraint *, con, &ob->constraints, index) {
+ TreeElement *ten = outliner_add_element(
+ space_outliner, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, index);
#if 0 /* disabled due to constraints system targets recode... code here needs review */
target = get_constraint_target(con, &str);
if (str && str[0]) {
@@ -499,14 +488,13 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
}
}
- if (ob->modifiers.first) {
- ModifierData *md;
+ if (!BLI_listbase_is_empty(&ob->modifiers)) {
TreeElement *ten_mod = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
- int index;
-
ten_mod->name = IFACE_("Modifiers");
- for (index = 0, md = ob->modifiers.first; md; index++, md = md->next) {
+
+ int index;
+ LISTBASE_FOREACH_INDEX (ModifierData *, md, &ob->modifiers, index) {
TreeElement *ten = outliner_add_element(
space_outliner, &ten_mod->subtree, ob, ten_mod, TSE_MODIFIER, index);
ten->name = md->name;
@@ -559,8 +547,8 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
if (!BLI_listbase_is_empty(&ob->greasepencil_modifiers)) {
TreeElement *ten_mod = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
-
ten_mod->name = IFACE_("Modifiers");
+
int index;
LISTBASE_FOREACH_INDEX (GpencilModifierData *, md, &ob->greasepencil_modifiers, index) {
TreeElement *ten = outliner_add_element(
@@ -599,8 +587,8 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
if (!BLI_listbase_is_empty(&ob->shader_fx)) {
TreeElement *ten_fx = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_GPENCIL_EFFECT_BASE, 0);
-
ten_fx->name = IFACE_("Effects");
+
int index;
LISTBASE_FOREACH_INDEX (ShaderFxData *, fx, &ob->shader_fx, index) {
TreeElement *ten = outliner_add_element(
@@ -620,16 +608,15 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
}
/* vertex groups */
- if (ob->defbase.first) {
- bDeformGroup *defgroup;
- TreeElement *ten;
+ if (!BLI_listbase_is_empty(&ob->defbase)) {
TreeElement *tenla = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
- int a;
-
tenla->name = IFACE_("Vertex Groups");
- for (defgroup = ob->defbase.first, a = 0; defgroup; defgroup = defgroup->next, a++) {
- ten = outliner_add_element(space_outliner, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a);
+
+ 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;
}
@@ -694,14 +681,13 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_ME: {
Mesh *me = (Mesh *)id;
- int a;
if (outliner_animdata_test(me->adt)) {
outliner_add_element(space_outliner, &te->subtree, me, te, TSE_ANIM_DATA, 0);
}
outliner_add_element(space_outliner, &te->subtree, me->key, te, 0, 0);
- for (a = 0; a < me->totcol; a++) {
+ for (int a = 0; a < me->totcol; a++) {
outliner_add_element(space_outliner, &te->subtree, me->mat[a], te, 0, a);
}
/* could do tfaces with image links, but the images are not grouped nicely.
@@ -710,33 +696,30 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_CU: {
Curve *cu = (Curve *)id;
- int a;
if (outliner_animdata_test(cu->adt)) {
outliner_add_element(space_outliner, &te->subtree, cu, te, TSE_ANIM_DATA, 0);
}
- for (a = 0; a < cu->totcol; a++) {
+ for (int a = 0; a < cu->totcol; a++) {
outliner_add_element(space_outliner, &te->subtree, cu->mat[a], te, 0, a);
}
break;
}
case ID_MB: {
MetaBall *mb = (MetaBall *)id;
- int a;
if (outliner_animdata_test(mb->adt)) {
outliner_add_element(space_outliner, &te->subtree, mb, te, TSE_ANIM_DATA, 0);
}
- for (a = 0; a < mb->totcol; a++) {
+ for (int a = 0; a < mb->totcol; a++) {
outliner_add_element(space_outliner, &te->subtree, mb->mat[a], te, 0, a);
}
break;
}
case ID_MA: {
Material *ma = (Material *)id;
-
if (outliner_animdata_test(ma->adt)) {
outliner_add_element(space_outliner, &te->subtree, ma, te, TSE_ANIM_DATA, 0);
}
@@ -744,7 +727,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_TE: {
Tex *tex = (Tex *)id;
-
if (outliner_animdata_test(tex->adt)) {
outliner_add_element(space_outliner, &te->subtree, tex, te, TSE_ANIM_DATA, 0);
}
@@ -753,7 +735,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_CA: {
Camera *ca = (Camera *)id;
-
if (outliner_animdata_test(ca->adt)) {
outliner_add_element(space_outliner, &te->subtree, ca, te, TSE_ANIM_DATA, 0);
}
@@ -761,7 +742,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_CF: {
CacheFile *cache_file = (CacheFile *)id;
-
if (outliner_animdata_test(cache_file->adt)) {
outliner_add_element(space_outliner, &te->subtree, cache_file, te, TSE_ANIM_DATA, 0);
}
@@ -770,7 +750,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_LA: {
Light *la = (Light *)id;
-
if (outliner_animdata_test(la->adt)) {
outliner_add_element(space_outliner, &te->subtree, la, te, TSE_ANIM_DATA, 0);
}
@@ -778,7 +757,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_SPK: {
Speaker *spk = (Speaker *)id;
-
if (outliner_animdata_test(spk->adt)) {
outliner_add_element(space_outliner, &te->subtree, spk, te, TSE_ANIM_DATA, 0);
}
@@ -786,7 +764,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_LP: {
LightProbe *prb = (LightProbe *)id;
-
if (outliner_animdata_test(prb->adt)) {
outliner_add_element(space_outliner, &te->subtree, prb, te, TSE_ANIM_DATA, 0);
}
@@ -794,7 +771,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_WO: {
World *wrld = (World *)id;
-
if (outliner_animdata_test(wrld->adt)) {
outliner_add_element(space_outliner, &te->subtree, wrld, te, TSE_ANIM_DATA, 0);
}
@@ -802,7 +778,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_KE: {
Key *key = (Key *)id;
-
if (outliner_animdata_test(key->adt)) {
outliner_add_element(space_outliner, &te->subtree, key, te, TSE_ANIM_DATA, 0);
}
@@ -815,27 +790,25 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_AR: {
bArmature *arm = (bArmature *)id;
- int a = 0;
if (outliner_animdata_test(arm->adt)) {
outliner_add_element(space_outliner, &te->subtree, arm, te, TSE_ANIM_DATA, 0);
}
if (arm->edbo) {
- EditBone *ebone;
- TreeElement *ten;
-
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next, a++) {
- ten = outliner_add_element(space_outliner, &te->subtree, id, te, TSE_EBONE, a);
+ int a = 0;
+ LISTBASE_FOREACH_INDEX (EditBone *, ebone, arm->edbo, a) {
+ TreeElement *ten = outliner_add_element(
+ space_outliner, &te->subtree, id, te, TSE_EBONE, a);
ten->directdata = ebone;
ten->name = ebone->name;
ebone->temp.p = ten;
}
/* make hierarchy */
- ten = arm->edbo->first ? ((EditBone *)arm->edbo->first)->temp.p : NULL;
+ TreeElement *ten = arm->edbo->first ? ((EditBone *)arm->edbo->first)->temp.p : NULL;
while (ten) {
TreeElement *nten = ten->next, *par;
- ebone = (EditBone *)ten->directdata;
+ EditBone *ebone = (EditBone *)ten->directdata;
if (ebone->parent) {
BLI_remlink(&te->subtree, ten);
par = ebone->parent->temp.p;
@@ -852,9 +825,9 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
/* pass */
}
else {
- Bone *curBone;
- for (curBone = arm->bonebase.first; curBone; curBone = curBone->next) {
- outliner_add_bone(space_outliner, &te->subtree, id, curBone, te, &a);
+ int a = 0;
+ LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
+ outliner_add_bone(space_outliner, &te->subtree, id, bone, te, &a);
}
}
}
@@ -862,13 +835,12 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_LS: {
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
- int a;
if (outliner_animdata_test(linestyle->adt)) {
outliner_add_element(space_outliner, &te->subtree, linestyle, te, TSE_ANIM_DATA, 0);
}
- for (a = 0; a < MAX_MTEX; a++) {
+ for (int a = 0; a < MAX_MTEX; a++) {
if (linestyle->mtex[a]) {
outliner_add_element(space_outliner, &te->subtree, linestyle->mtex[a]->tex, te, 0, a);
}
@@ -877,17 +849,16 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_GD: {
bGPdata *gpd = (bGPdata *)id;
- bGPDlayer *gpl;
- int a = 0;
if (outliner_animdata_test(gpd->adt)) {
outliner_add_element(space_outliner, &te->subtree, gpd, te, TSE_ANIM_DATA, 0);
}
/* TODO: base element for layers? */
- for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) {
- outliner_add_element(space_outliner, &te->subtree, gpl, te, TSE_GP_LAYER, a);
- a++;
+ int index = 0;
+ LISTBASE_FOREACH_BACKWARD (bGPDlayer *, gpl, &gpd->layers) {
+ outliner_add_element(space_outliner, &te->subtree, gpl, te, TSE_GP_LAYER, index);
+ index++;
}
break;
}
@@ -957,8 +928,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
short type,
short index)
{
- TreeElement *te;
- TreeStoreElem *tselem;
ID *id = idv;
if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
@@ -985,12 +954,12 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
BLI_assert(TREESTORE_ID_TYPE(id));
}
- te = MEM_callocN(sizeof(TreeElement), "tree elem");
+ TreeElement *te = MEM_callocN(sizeof(TreeElement), __func__);
/* add to the visual tree */
BLI_addtail(lb, te);
/* add to the storage */
check_persistent(space_outliner, te, id, type, index);
- tselem = TREESTORE(te);
+ TreeStoreElem *tselem = TREESTORE(te);
/* if we are searching for something expand to see child elements */
if (SEARCHING_OUTLINER(space_outliner)) {
@@ -1022,9 +991,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
else if (type == TSE_ID_BASE) {
/* pass */
}
- else if (ELEM(type, TSE_KEYMAP, TSE_KEYMAP_ITEM)) {
- /* pass */
- }
else {
/* Other cases must be caught above. */
BLI_assert(TSE_IS_REAL_ID(tselem));
@@ -1062,7 +1028,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
else if (type == TSE_SEQUENCE) {
Sequence *seq = (Sequence *)idv;
- Sequence *p;
/*
* The idcode is a little hack, but the outliner
@@ -1081,10 +1046,8 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
*/
if (seq->type == SEQ_TYPE_META) {
- p = seq->seqbase.first;
- while (p) {
+ LISTBASE_FOREACH (Sequence *, p, &seq->seqbase) {
outliner_add_element(space_outliner, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
- p = p->next;
}
}
else {
@@ -1112,17 +1075,13 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
te->name = seq->strip->stripdata->name;
}
else if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
- PointerRNA pptr, propptr, *ptr = (PointerRNA *)idv;
- PropertyRNA *prop, *iterprop;
- PropertyType proptype;
+ PointerRNA *ptr = (PointerRNA *)idv;
/* Don't display arrays larger, weak but index is stored as a short,
* also the outliner isn't intended for editing such large data-sets. */
BLI_STATIC_ASSERT(sizeof(te->index) == 2, "Index is no longer short!")
const int tot_limit = SHRT_MAX;
- int a, tot;
-
/* we do lazy build, for speed and to avoid infinite recursion */
if (ptr->data == NULL) {
@@ -1144,8 +1103,8 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
tselem->flag &= ~TSE_CHILDSEARCH;
}
- iterprop = RNA_struct_iterator_property(ptr->type);
- tot = RNA_property_collection_length(ptr, iterprop);
+ PropertyRNA *iterprop = RNA_struct_iterator_property(ptr->type);
+ int tot = RNA_property_collection_length(ptr, iterprop);
CLAMP_MAX(tot, tot_limit);
/* auto open these cases */
@@ -1156,7 +1115,8 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
if (TSELEM_OPEN(tselem, space_outliner)) {
- for (a = 0; a < tot; a++) {
+ for (int a = 0; a < tot; a++) {
+ PointerRNA propptr;
RNA_property_collection_lookup_int(ptr, iterprop, a, &propptr);
if (!(RNA_property_flag(propptr.data) & PROP_HIDDEN)) {
outliner_add_element(
@@ -1172,11 +1132,12 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
else if (type == TSE_RNA_PROPERTY) {
/* property */
- iterprop = RNA_struct_iterator_property(ptr->type);
+ PointerRNA propptr;
+ PropertyRNA *iterprop = RNA_struct_iterator_property(ptr->type);
RNA_property_collection_lookup_int(ptr, iterprop, index, &propptr);
- prop = propptr.data;
- proptype = RNA_property_type(prop);
+ PropertyRNA *prop = propptr.data;
+ PropertyType proptype = RNA_property_type(prop);
te->name = RNA_property_ui_name(prop);
te->directdata = prop;
@@ -1188,7 +1149,7 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
if (proptype == PROP_POINTER) {
- pptr = RNA_property_pointer_get(ptr, prop);
+ PointerRNA pptr = RNA_property_pointer_get(ptr, prop);
if (pptr.data) {
if (TSELEM_OPEN(tselem, space_outliner)) {
@@ -1201,11 +1162,12 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
}
else if (proptype == PROP_COLLECTION) {
- tot = RNA_property_collection_length(ptr, prop);
+ int tot = RNA_property_collection_length(ptr, prop);
CLAMP_MAX(tot, tot_limit);
if (TSELEM_OPEN(tselem, space_outliner)) {
- for (a = 0; a < tot; a++) {
+ for (int a = 0; a < tot; a++) {
+ PointerRNA pptr;
RNA_property_collection_lookup_int(ptr, prop, a, &pptr);
outliner_add_element(
space_outliner, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, a);
@@ -1216,11 +1178,11 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
}
else if (ELEM(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
- tot = RNA_property_array_length(ptr, prop);
+ int tot = RNA_property_array_length(ptr, prop);
CLAMP_MAX(tot, tot_limit);
if (TSELEM_OPEN(tselem, space_outliner)) {
- for (a = 0; a < tot; a++) {
+ for (int a = 0; a < tot; a++) {
outliner_add_element(
space_outliner, &te->subtree, (void *)ptr, te, TSE_RNA_ARRAY_ELEM, a);
}
@@ -1231,15 +1193,13 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
}
else if (type == TSE_RNA_ARRAY_ELEM) {
- char c;
-
- prop = parent->directdata;
+ PropertyRNA *prop = parent->directdata;
te->directdata = prop;
te->rnaptr = *ptr;
te->index = index;
- c = RNA_property_array_item_char(prop, index);
+ char c = RNA_property_array_item_char(prop, index);
te->name = MEM_callocN(sizeof(char[20]), "OutlinerRNAArrayName");
if (c) {
@@ -1251,52 +1211,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
te->flag |= TE_FREE_NAME;
}
}
- else if (type == TSE_KEYMAP) {
- wmKeyMap *km = (wmKeyMap *)idv;
- wmKeyMapItem *kmi;
- char opname[OP_MAX_TYPENAME];
-
- te->directdata = idv;
- te->name = km->idname;
-
- if (TSELEM_OPEN(tselem, space_outliner)) {
- int a = 0;
-
- for (kmi = km->items.first; kmi; kmi = kmi->next, a++) {
- const char *key = WM_key_event_string(kmi->type, false);
-
- if (key[0]) {
- wmOperatorType *ot = NULL;
-
- if (kmi->propvalue) {
- /* pass */
- }
- else {
- ot = WM_operatortype_find(kmi->idname, 0);
- }
-
- if (ot || kmi->propvalue) {
- TreeElement *ten = outliner_add_element(
- space_outliner, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a);
-
- ten->directdata = kmi;
-
- if (kmi->propvalue) {
- ten->name = IFACE_("Modal map, not yet");
- }
- else {
- WM_operator_py_idname(opname, ot->idname);
- ten->name = BLI_strdup(opname);
- ten->flag |= TE_FREE_NAME;
- }
- }
- }
- }
- }
- else {
- te->flag |= TE_LAZY_CLOSED;
- }
- }
return te;
}
@@ -1344,21 +1258,18 @@ static TreeElement *outliner_add_collection_recursive(SpaceOutliner *space_outli
/* make sure elements are correctly nested */
void outliner_make_object_parent_hierarchy(ListBase *lb)
{
- TreeElement *te, *ten, *tep;
- TreeStoreElem *tselem;
-
/* build hierarchy */
/* XXX also, set extents here... */
- te = lb->first;
+ TreeElement *te = lb->first;
while (te) {
- ten = te->next;
- tselem = TREESTORE(te);
+ TreeElement *ten = te->next;
+ TreeStoreElem *tselem = TREESTORE(te);
if (tselem->type == 0 && te->idcode == ID_OB) {
Object *ob = (Object *)tselem->id;
if (ob->parent && ob->parent->id.newid) {
BLI_remlink(lb, te);
- tep = (TreeElement *)ob->parent->id.newid;
+ TreeElement *tep = (TreeElement *)ob->parent->id.newid;
BLI_addtail(&tep->subtree, te);
te->parent = tep;
}
@@ -1380,10 +1291,9 @@ typedef struct tTreeSort {
static int treesort_alpha_ob(const void *v1, const void *v2)
{
const tTreeSort *x1 = v1, *x2 = v2;
- int comp;
/* first put objects last (hierarchy) */
- comp = (x1->idcode == ID_OB);
+ int comp = (x1->idcode == ID_OB);
if (x2->idcode == ID_OB) {
comp += 2;
}
@@ -1432,9 +1342,8 @@ static int treesort_child_not_in_collection(const void *v1, const void *v2)
static int treesort_alpha(const void *v1, const void *v2)
{
const tTreeSort *x1 = v1, *x2 = v2;
- int comp;
- comp = BLI_strcasecmp_natural(x1->name, x2->name);
+ int comp = BLI_strcasecmp_natural(x1->name, x2->name);
if (comp > 0) {
return 1;
@@ -1489,14 +1398,11 @@ static int treesort_obtype_alpha(const void *v1, const void *v2)
/* sort happens on each subtree individual */
static void outliner_sort(ListBase *lb)
{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- te = lb->last;
+ TreeElement *te = lb->last;
if (te == NULL) {
return;
}
- tselem = TREESTORE(te);
+ TreeStoreElem *tselem = TREESTORE(te);
/* sorting rules; only object lists, ID lists, or deformgroups */
if (ELEM(tselem->type, TSE_DEFGROUP, TSE_ID_BASE) ||
@@ -1558,14 +1464,11 @@ static void outliner_sort(ListBase *lb)
static void outliner_collections_children_sort(ListBase *lb)
{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- te = lb->last;
+ TreeElement *te = lb->last;
if (te == NULL) {
return;
}
- tselem = TREESTORE(te);
+ TreeStoreElem *tselem = TREESTORE(te);
/* Sorting rules: only object lists. */
if (tselem->type == 0 && te->idcode == ID_OB) {
@@ -1687,8 +1590,7 @@ static TreeElement *outliner_find_first_desired_element_at_y(const SpaceOutliner
const float view_co,
const float view_co_limit)
{
- TreeElement *te, *te_sub;
- te = outliner_find_item_at_y(space_outliner, &space_outliner->tree, view_co);
+ TreeElement *te = outliner_find_item_at_y(space_outliner, &space_outliner->tree, view_co);
bool (*callback_test)(TreeElement *);
if ((space_outliner->outlinevis == SO_VIEW_LAYER) &&
@@ -1700,7 +1602,7 @@ static TreeElement *outliner_find_first_desired_element_at_y(const SpaceOutliner
}
while (te != NULL) {
- te_sub = outliner_find_first_desired_element_at_y_recursive(
+ TreeElement *te_sub = outliner_find_first_desired_element_at_y_recursive(
space_outliner, te, view_co_limit, callback_test);
if (te_sub != NULL) {
/* Skip the element if it was not visible to start with. */
@@ -1742,12 +1644,12 @@ static void outliner_store_scrolling_position(SpaceOutliner *space_outliner,
ARegion *region,
OutlinerTreeElementFocus *focus)
{
- TreeElement *te;
float limit = region->v2d.cur.ymin;
outliner_set_coordinates(region, space_outliner);
- te = outliner_find_first_desired_element_at_y(space_outliner, region->v2d.cur.ymax, limit);
+ TreeElement *te = outliner_find_first_desired_element_at_y(
+ space_outliner, region->v2d.cur.ymax, limit);
if (te != NULL) {
focus->tselem = TREESTORE(te);
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
index e0d63dfcf81..92178cfdfc9 100644
--- a/source/blender/editors/space_outliner/outliner_utils.c
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -169,7 +169,7 @@ TreeElement *outliner_find_item_at_x_in_row(const SpaceOutliner *space_outliner,
return te;
}
-/* Find specific item from the treestore */
+/* Find specific item from the trees-tore. */
TreeElement *outliner_find_tree_element(ListBase *lb, const TreeStoreElem *store_elem)
{
LISTBASE_FOREACH (TreeElement *, te, lb) {
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 6c9d4433abd..87f81a2cc0e 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -31,9 +31,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
-#include "BKE_layer.h"
#include "BKE_outliner_treehash.h"
-#include "BKE_scene.h"
#include "BKE_screen.h"
#include "ED_screen.h"
@@ -51,7 +49,6 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "GPU_framebuffer.h"
#include "outliner_intern.h"
#include "tree/tree_display.h"
@@ -102,12 +99,11 @@ static void outliner_main_region_free(ARegion *UNUSED(region))
{
}
-static void outliner_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void outliner_main_region_listener(const wmRegionListenerParams *params)
{
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
SpaceOutliner *space_outliner = area->spacedata.first;
/* context changes */
@@ -264,15 +260,13 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void outliner_main_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void outliner_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
SpaceOutliner *space_outliner = area->spacedata.first;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
@@ -301,12 +295,11 @@ static void outliner_header_region_free(ARegion *UNUSED(region))
{
}
-static void outliner_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void outliner_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
@@ -332,7 +325,7 @@ static SpaceLink *outliner_create(const ScrArea *UNUSED(area), const Scene *UNUS
space_outliner = MEM_callocN(sizeof(SpaceOutliner), "initoutliner");
space_outliner->spacetype = SPACE_OUTLINER;
space_outliner->filter_id_type = ID_GR;
- space_outliner->show_restrict_flags = SO_RESTRICT_ENABLE | SO_RESTRICT_HIDE;
+ space_outliner->show_restrict_flags = SO_RESTRICT_ENABLE | SO_RESTRICT_HIDE | SO_RESTRICT_RENDER;
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;
diff --git a/source/blender/editors/space_outliner/tree/tree_display.cc b/source/blender/editors/space_outliner/tree/tree_display.cc
index d2070fb9b1c..6632c057814 100644
--- a/source/blender/editors/space_outliner/tree/tree_display.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display.cc
@@ -18,8 +18,6 @@
* \ingroup spoutliner
*/
-#include "BLI_listbase.h"
-
#include "DNA_listBase.h"
#include "tree_display.hh"
diff --git a/source/blender/editors/space_outliner/tree/tree_element.cc b/source/blender/editors/space_outliner/tree/tree_element.cc
index ce2a8fa634d..27846614994 100644
--- a/source/blender/editors/space_outliner/tree/tree_element.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element.cc
@@ -20,8 +20,6 @@
#include "DNA_listBase.h"
-#include "../outliner_intern.h"
-
#include "tree_element_anim_data.hh"
#include "tree_element_driver_base.hh"
#include "tree_element_nla.hh"
diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c
index 3330ba14530..4ce0e454df8 100644
--- a/source/blender/editors/space_script/space_script.c
+++ b/source/blender/editors/space_script/space_script.c
@@ -36,7 +36,6 @@
#include "ED_space_api.h"
#include "WM_api.h"
-#include "WM_types.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -44,7 +43,6 @@
#ifdef WITH_PYTHON
#endif
-#include "GPU_framebuffer.h"
#include "script_intern.h" /* own include */
// static script_run_python(char *funcname, )
@@ -156,13 +154,8 @@ static void script_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void script_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void script_main_region_listener(const wmRegionListenerParams *UNUSED(params))
{
-/* context changes */
/* XXX - Todo, need the ScriptSpace accessible to get the python script to run. */
#if 0
BPY_run_script_space_listener()
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index f9076145f2f..e605cf4a889 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -66,8 +66,6 @@
#include "UI_interface.h"
-#include "BKE_sound.h"
-
#ifdef WITH_AUDASPACE
# include <AUD_Sequence.h>
#endif
@@ -1069,6 +1067,9 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
else if (seq->type == SEQ_TYPE_TEXT) {
seq->blend_mode = SEQ_TYPE_ALPHAOVER;
}
+ else if (SEQ_effect_get_num_inputs(seq->type) == 1) {
+ seq->blend_mode = seq1->blend_mode;
+ }
/* Set channel. If unset, use lowest free one above strips. */
if (!RNA_struct_property_is_set(op->ptr, "channel")) {
diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c
index a8c13d63259..11614d94862 100644
--- a/source/blender/editors/space_sequencer/sequencer_buttons.c
+++ b/source/blender/editors/space_sequencer/sequencer_buttons.c
@@ -35,13 +35,9 @@
#include "BKE_global.h"
#include "BKE_screen.h"
-#include "ED_gpencil.h"
#include "ED_screen.h"
#include "ED_sequencer.h"
-#include "WM_api.h"
-#include "WM_types.h"
-
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 72c3e43185b..201df1ceed6 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -1447,15 +1447,24 @@ static void sequencer_draw_borders_overlay(const SpaceSeq *sseq,
if (sseq->flag & SEQ_SHOW_SAFE_MARGINS) {
immUniformThemeColorBlend(TH_VIEW_OVERLAY, TH_BACK, 0.25f);
- UI_draw_safe_areas(
- shdr_pos, x1, x2, y1, y2, scene->safe_areas.title, scene->safe_areas.action);
+ UI_draw_safe_areas(shdr_pos,
+ &(const rctf){
+ .xmin = x1,
+ .xmax = x2,
+ .ymin = y1,
+ .ymax = y2,
+ },
+ scene->safe_areas.title,
+ scene->safe_areas.action);
if (sseq->flag & SEQ_SHOW_SAFE_CENTER) {
UI_draw_safe_areas(shdr_pos,
- x1,
- x2,
- y1,
- y2,
+ &(const rctf){
+ .xmin = x1,
+ .xmax = x2,
+ .ymin = y1,
+ .ymax = y2,
+ },
scene->safe_areas.title_center,
scene->safe_areas.action_center);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 7474f8034de..608e220c582 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -28,7 +28,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_timecode.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c
index 7bfc8600544..48e6cfcdcd0 100644
--- a/source/blender/editors/space_sequencer/sequencer_ops.c
+++ b/source/blender/editors/space_sequencer/sequencer_ops.c
@@ -29,12 +29,7 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "ED_markers.h"
-#include "ED_select_utils.h"
#include "ED_sequencer.h"
-#include "ED_transform.h" /* Transform keymap. */
-
-#include "SEQ_sequencer.h"
#include "sequencer_intern.h"
diff --git a/source/blender/editors/space_sequencer/sequencer_proxy.c b/source/blender/editors/space_sequencer/sequencer_proxy.c
index b9698492aa5..24fa4ad7a17 100644
--- a/source/blender/editors/space_sequencer/sequencer_proxy.c
+++ b/source/blender/editors/space_sequencer/sequencer_proxy.c
@@ -25,7 +25,6 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
-#include "BLI_timecode.h"
#include "DNA_scene_types.h"
diff --git a/source/blender/editors/space_sequencer/sequencer_scopes.c b/source/blender/editors/space_sequencer/sequencer_scopes.c
index f5707d1ea65..16768e09cb8 100644
--- a/source/blender/editors/space_sequencer/sequencer_scopes.c
+++ b/source/blender/editors/space_sequencer/sequencer_scopes.c
@@ -30,8 +30,6 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "atomic_ops.h"
-
#include "sequencer_intern.h"
/* XXX, why is this function better than BLI_math version?
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 3b476fefe47..ffcb3d35d5a 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -26,6 +26,7 @@
#include <string.h>
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -771,69 +772,83 @@ void SEQUENCER_OT_select(wmOperatorType *ot)
* \{ */
/* Run recursively to select linked. */
-static bool select_more_less_seq__internal(Scene *scene, bool sel, const bool linked)
+static bool select_linked_internal(Scene *scene)
{
Editing *ed = SEQ_editing_get(scene, false);
- Sequence *seq, *neighbor;
- bool changed = false;
- int isel;
if (ed == NULL) {
- return changed;
+ return false;
}
- if (sel) {
- sel = SELECT;
- isel = 0;
+ bool changed = false;
+
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
+ if ((seq->flag & SELECT) != 0) {
+ continue;
+ }
+ /* Only get unselected neighbors. */
+ Sequence *neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_LEFT, 0);
+ if (neighbor) {
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ changed = true;
+ }
+ neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, 0);
+ if (neighbor) {
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ changed = true;
+ }
}
- else {
- sel = 0;
- isel = SELECT;
+
+ return changed;
+}
+
+/* Select only one linked strip on each side. */
+static bool select_more_less_seq__internal(Scene *scene, bool select_more)
+{
+ Editing *ed = SEQ_editing_get(scene, false);
+
+ if (ed == NULL) {
+ return false;
}
- if (!linked) {
- /* If not linked we only want to touch each seq once, newseq. */
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- seq->tmp = NULL;
+ GSet *neighbors = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "Linked strips");
+ const int neighbor_selection_filter = select_more ? 0 : SELECT;
+ const int selection_filter = select_more ? SELECT : 0;
+
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
+ if ((seq->flag & SELECT) != selection_filter) {
+ continue;
+ }
+ Sequence *neighbor = find_neighboring_sequence(
+ scene, seq, SEQ_SIDE_LEFT, neighbor_selection_filter);
+ if (neighbor) {
+ BLI_gset_add(neighbors, neighbor);
+ }
+ neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, neighbor_selection_filter);
+ if (neighbor) {
+ BLI_gset_add(neighbors, neighbor);
}
}
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- if ((seq->flag & SELECT) == sel) {
- if (linked || (seq->tmp == NULL)) {
- /* Only get unselected neighbors. */
- neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_LEFT, isel);
- if (neighbor) {
- if (sel) {
- neighbor->flag |= SELECT;
- recurs_sel_seq(neighbor);
- }
- else {
- neighbor->flag &= ~SELECT;
- }
- if (!linked) {
- neighbor->tmp = (Sequence *)1;
- }
- changed = true;
- }
- neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, isel);
- if (neighbor) {
- if (sel) {
- neighbor->flag |= SELECT;
- recurs_sel_seq(neighbor);
- }
- else {
- neighbor->flag &= ~SELECT;
- }
- if (!linked) {
- neighbor->tmp = (Sequence *)1;
- }
- changed = true;
- }
- }
+ bool changed = false;
+ GSetIterator gsi;
+ BLI_gsetIterator_init(&gsi, neighbors);
+ while (!BLI_gsetIterator_done(&gsi)) {
+ Sequence *neighbor = BLI_gsetIterator_getKey(&gsi);
+ if (select_more) {
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ }
+ else {
+ neighbor->flag &= ~SELECT;
}
+ changed = true;
+ BLI_gsetIterator_step(&gsi);
}
+ BLI_gset_free(neighbors, NULL);
return changed;
}
@@ -841,7 +856,7 @@ static int sequencer_select_more_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- if (!select_more_less_seq__internal(scene, true, false)) {
+ if (!select_more_less_seq__internal(scene, true)) {
return OPERATOR_CANCELLED;
}
@@ -877,7 +892,7 @@ static int sequencer_select_less_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- if (!select_more_less_seq__internal(scene, false, false)) {
+ if (!select_more_less_seq__internal(scene, false)) {
return OPERATOR_CANCELLED;
}
@@ -934,7 +949,7 @@ static int sequencer_select_linked_pick_invoke(bContext *C, wmOperator *op, cons
selected = 1;
while (selected) {
- selected = select_more_less_seq__internal(scene, 1, 1);
+ selected = select_linked_internal(scene);
}
ED_outliner_select_sync_from_sequence_tag(C);
@@ -975,7 +990,7 @@ static int sequencer_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
selected = true;
while (selected) {
- selected = select_more_less_seq__internal(scene, true, true);
+ selected = select_linked_internal(scene);
}
ED_outliner_select_sync_from_sequence_tag(C);
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index b11e2a32b87..b17482cd3a4 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -51,7 +51,6 @@
#include "RNA_access.h"
-#include "SEQ_sequencer.h"
#include "SEQ_utils.h"
#include "UI_interface.h"
@@ -334,11 +333,11 @@ static SpaceLink *sequencer_duplicate(SpaceLink *sl)
return (SpaceLink *)sseqn;
}
-static void sequencer_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void sequencer_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
+
/* Context changes. */
switch (wmn->category) {
case NC_SCENE:
@@ -534,12 +533,11 @@ static void sequencer_main_region_draw_overlay(const bContext *C, ARegion *regio
draw_timeline_seq_display(C, region);
}
-static void sequencer_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void sequencer_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* Context changes. */
switch (wmn->category) {
case NC_SCENE:
@@ -579,14 +577,12 @@ static void sequencer_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void sequencer_main_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *scene,
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void sequencer_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ Scene *scene = params->scene;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
@@ -746,12 +742,11 @@ static void sequencer_preview_region_draw(const bContext *C, ARegion *region)
}
}
-static void sequencer_preview_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void sequencer_preview_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* Context changes. */
switch (wmn->category) {
case NC_GPENCIL:
@@ -816,12 +811,11 @@ static void sequencer_buttons_region_draw(const bContext *C, ARegion *region)
ED_region_panels(C, region);
}
-static void sequencer_buttons_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void sequencer_buttons_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* Context changes. */
switch (wmn->category) {
case NC_GPENCIL:
@@ -959,7 +953,7 @@ void ED_spacetype_sequencer(void)
art->listener = sequencer_main_region_listener;
BLI_addhead(&st->regiontypes, art);
- /* Hud. */
+ /* HUD. */
art = ED_area_type_hud(st->spaceid);
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_statusbar/space_statusbar.c b/source/blender/editors/space_statusbar/space_statusbar.c
index ae56b111360..0b4f483c114 100644
--- a/source/blender/editors/space_statusbar/space_statusbar.c
+++ b/source/blender/editors/space_statusbar/space_statusbar.c
@@ -34,7 +34,6 @@
#include "RNA_access.h"
#include "UI_interface.h"
-#include "UI_view2d.h"
#include "WM_api.h"
#include "WM_message.h"
@@ -95,12 +94,11 @@ static void statusbar_keymap(struct wmKeyConfig *UNUSED(keyconf))
{
}
-static void statusbar_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void statusbar_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCREEN:
@@ -131,14 +129,11 @@ static void statusbar_header_region_listener(wmWindow *UNUSED(win),
}
}
-static void statusbar_header_region_message_subscribe(const bContext *UNUSED(C),
- WorkSpace *UNUSED(workspace),
- Scene *UNUSED(scene),
- bScreen *UNUSED(screen),
- ScrArea *UNUSED(area),
- ARegion *region,
- struct wmMsgBus *mbus)
+static void statusbar_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 0f5ac5abe1d..ea55eaea388 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -33,7 +33,6 @@
#include "BKE_global.h"
#include "BKE_lib_id.h"
#include "BKE_screen.h"
-#include "BKE_text.h"
#include "ED_screen.h"
#include "ED_space_api.h"
@@ -47,7 +46,6 @@
#include "RNA_access.h"
-#include "GPU_framebuffer.h"
#include "text_format.h"
#include "text_intern.h" /* own include */
@@ -122,11 +120,10 @@ static SpaceLink *text_duplicate(SpaceLink *sl)
return (SpaceLink *)stextn;
}
-static void text_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void text_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
SpaceText *st = area->spacedata.first;
/* context changes */
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 849766851aa..883556948e2 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -722,7 +722,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *region)
void text_drawcache_tag_update(SpaceText *st, int full)
{
- /* this happens if text editor ops are caled from python */
+ /* This happens if text editor ops are called from Python. */
if (st == NULL) {
return;
}
@@ -1010,13 +1010,16 @@ static void draw_textscroll(const SpaceText *st, rcti *scroll, rcti *back)
BLI_rcti_size_y(&st->runtime.scroll_region_select));
UI_GetThemeColor3fv(TH_HILITE, col);
col[3] = 0.18f;
- UI_draw_roundbox_aa(true,
- st->runtime.scroll_region_select.xmin + 1,
- st->runtime.scroll_region_select.ymin,
- st->runtime.scroll_region_select.xmax - 1,
- st->runtime.scroll_region_select.ymax,
- rad,
- col);
+ UI_draw_roundbox_aa(
+ &(const rctf){
+ .xmin = st->runtime.scroll_region_select.xmin + 1,
+ .xmax = st->runtime.scroll_region_select.xmax - 1,
+ .ymin = st->runtime.scroll_region_select.ymin,
+ .ymax = st->runtime.scroll_region_select.ymax,
+ },
+ true,
+ rad,
+ col);
}
/*********************** draw documentation *******************************/
@@ -1180,7 +1183,14 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc
}
/* not needed but stands out nicer */
- UI_draw_box_shadow(220, x, y - boxh, x + boxw, y);
+ UI_draw_box_shadow(
+ &(const rctf){
+ .xmin = x,
+ .xmax = x + boxw,
+ .ymin = y - boxh,
+ .ymax = y,
+ },
+ 220);
uint pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
diff --git a/source/blender/editors/space_text/text_format.c b/source/blender/editors/space_text/text_format.c
index d099f2a20d8..66765206fa6 100644
--- a/source/blender/editors/space_text/text_format.c
+++ b/source/blender/editors/space_text/text_format.c
@@ -237,7 +237,7 @@ bool ED_text_is_syntax_highlight_supported(Text *text)
const char *text_ext = BLI_path_extension(text->id.name + 2);
if (text_ext == NULL) {
- /* Extensionless datablocks are considered highlightable as Python. */
+ /* Extensionless data-blocks are considered highlightable as Python. */
return true;
}
text_ext++; /* skip the '.' */
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 932bacfb8a0..526285c076a 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -3832,7 +3832,7 @@ static int text_resolve_conflict_invoke(bContext *C, wmOperator *op, const wmEve
switch (BKE_text_file_modified_check(text)) {
case 1:
if (text->flags & TXT_ISDIRTY) {
- /* modified locally and externally, ahhh. offer more possibilities. */
+ /* Modified locally and externally, ah. offer more possibilities. */
pup = UI_popup_menu_begin(
C, IFACE_("File Modified Outside and Inside Blender"), ICON_NONE);
layout = UI_popup_menu_layout(pup);
diff --git a/source/blender/editors/space_text/text_undo.c b/source/blender/editors/space_text/text_undo.c
index 61b786b2b13..f55db8c3cc9 100644
--- a/source/blender/editors/space_text/text_undo.c
+++ b/source/blender/editors/space_text/text_undo.c
@@ -196,14 +196,19 @@ static bool text_undosys_step_encode(struct bContext *C,
return true;
}
-static void text_undosys_step_decode(
- struct bContext *C, struct Main *UNUSED(bmain), UndoStep *us_p, int dir, bool is_final)
+static void text_undosys_step_decode(struct bContext *C,
+ struct Main *UNUSED(bmain),
+ UndoStep *us_p,
+ const eUndoStepDir dir,
+ bool is_final)
{
+ BLI_assert(dir != STEP_INVALID);
+
TextUndoStep *us = (TextUndoStep *)us_p;
Text *text = us->text_ref.ptr;
TextState *state;
- if ((us->states[0].buf_array_state != NULL) && (dir == -1) && !is_final) {
+ if ((us->states[0].buf_array_state != NULL) && (dir == STEP_UNDO) && !is_final) {
state = &us->states[0];
}
else {
diff --git a/source/blender/editors/space_topbar/space_topbar.c b/source/blender/editors/space_topbar/space_topbar.c
index dc357cdd355..419721cf89e 100644
--- a/source/blender/editors/space_topbar/space_topbar.c
+++ b/source/blender/editors/space_topbar/space_topbar.c
@@ -38,7 +38,6 @@
#include "ED_screen.h"
#include "ED_space_api.h"
-#include "ED_undo.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -129,12 +128,11 @@ static void topbar_header_region_init(wmWindowManager *UNUSED(wm), ARegion *regi
ED_region_header_init(region);
}
-static void topbar_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void topbar_main_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_WM:
@@ -160,12 +158,11 @@ static void topbar_main_region_listener(wmWindow *UNUSED(win),
}
}
-static void topbar_header_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void topbar_header_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_WM:
@@ -191,14 +188,12 @@ static void topbar_header_listener(wmWindow *UNUSED(win),
}
}
-static void topbar_header_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *workspace,
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void topbar_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ WorkSpace *workspace = params->workspace;
+ ARegion *region = params->region;
+
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
.owner = region,
.user_data = region,
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index 3efdee9cec9..d4692f156d3 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -183,46 +183,20 @@ static void userpref_execute_region_init(wmWindowManager *wm, ARegion *region)
region->v2d.keepzoom |= V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y;
}
-static void userpref_main_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void userpref_main_region_listener(const wmRegionListenerParams *UNUSED(params))
{
- /* context changes */
}
-static void userpref_header_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void userpref_header_listener(const wmRegionListenerParams *UNUSED(params))
{
- /* context changes */
-#if 0
- switch (wmn->category) {
- default:
- break;
- }
-#endif
}
-static void userpref_navigation_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void userpref_navigation_region_listener(const wmRegionListenerParams *UNUSED(params))
{
- /* context changes */
}
-static void userpref_execute_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *UNUSED(region),
- wmNotifier *UNUSED(wmn),
- const Scene *UNUSED(scene))
+static void userpref_execute_region_listener(const wmRegionListenerParams *UNUSED(params))
{
- /* context changes */
}
/* only called once, from space/spacetypes.c */
diff --git a/source/blender/editors/space_userpref/userpref_ops.c b/source/blender/editors/space_userpref/userpref_ops.c
index f05d6df9944..7c799f0d97b 100644
--- a/source/blender/editors/space_userpref/userpref_ops.c
+++ b/source/blender/editors/space_userpref/userpref_ops.c
@@ -28,10 +28,8 @@
#include "BLI_listbase.h"
#include "BKE_context.h"
-#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_preferences.h"
-#include "BKE_report.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -39,8 +37,6 @@
#include "UI_interface.h"
-#include "../interface/interface_intern.h"
-
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 4c168c7a243..98e1d927daf 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -393,7 +393,7 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *region)
keymap = WM_keymap_ensure(wm->defaultconf, "Paint Vertex Selection (Weight, Vertex)", 0, 0);
WM_event_add_keymap_handler(&region->handlers, keymap);
- /* Before 'Weight/Vertex Paint' so adding curve points is not overriden. */
+ /* Before 'Weight/Vertex Paint' so adding curve points is not overridden. */
keymap = WM_keymap_ensure(wm->defaultconf, "Paint Curve", 0, 0);
WM_event_add_keymap_handler(&region->handlers, keymap);
@@ -469,16 +469,30 @@ static bool view3d_drop_in_main_region_poll(bContext *C, const wmEvent *event)
return ED_region_overlap_isect_any_xy(area, &event->x) == false;
}
-static ID *view3d_drop_id_in_main_region_poll_id(bContext *C,
- wmDrag *drag,
- const wmEvent *event,
- ID_Type id_type)
+static ID_Type view3d_drop_id_in_main_region_poll_get_id_type(bContext *C,
+ wmDrag *drag,
+ const wmEvent *event)
{
- ScrArea *area = CTX_wm_area(C);
+ const ScrArea *area = CTX_wm_area(C);
+
if (ED_region_overlap_isect_any_xy(area, &event->x)) {
- return NULL;
+ return 0;
+ }
+ if (!view3d_drop_in_main_region_poll(C, event)) {
+ return 0;
+ }
+
+ ID *local_id = WM_drag_get_local_ID(drag, 0);
+ if (local_id) {
+ return GS(local_id->name);
+ }
+
+ wmDragAsset *asset_drag = WM_drag_get_asset_data(drag, 0);
+ if (asset_drag) {
+ return asset_drag->id_type;
}
- return view3d_drop_in_main_region_poll(C, event) ? WM_drag_get_local_ID(drag, id_type) : NULL;
+
+ return 0;
}
static bool view3d_drop_id_in_main_region_poll(bContext *C,
@@ -490,7 +504,7 @@ static bool view3d_drop_id_in_main_region_poll(bContext *C,
return false;
}
- return WM_drag_get_local_ID(drag, id_type) || WM_drag_get_asset_data(drag, id_type);
+ return WM_drag_is_ID_type(drag, id_type);
}
static bool view3d_ob_drop_poll(bContext *C,
@@ -522,9 +536,9 @@ static bool view3d_object_data_drop_poll(bContext *C,
const wmEvent *event,
const char **r_tooltip)
{
- ID *id = view3d_drop_id_in_main_region_poll_id(C, drag, event, 0);
- if (id != NULL) {
- if (BKE_object_obdata_to_type(id) != -1) {
+ ID_Type id_type = view3d_drop_id_in_main_region_poll_get_id_type(C, drag, event);
+ if (id_type) {
+ if (OB_DATA_SUPPORT_ID(id_type)) {
*r_tooltip = TIP_("Create object instance from object-data");
return true;
}
@@ -545,7 +559,7 @@ static bool view3d_ima_drop_poll(bContext *C,
return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE));
}
- return WM_drag_get_local_ID(drag, ID_IM) || WM_drag_get_asset_data(drag, ID_IM);
+ return WM_drag_is_ID_type(drag, ID_IM);
}
static bool view3d_ima_bg_is_camera_view(bContext *C)
@@ -629,7 +643,7 @@ static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
static void view3d_id_drop_copy_with_type(wmDrag *drag, wmDropBox *drop)
{
- ID *id = WM_drag_get_local_ID(drag, 0);
+ ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
RNA_string_set(drop->ptr, "name", id->name + 2);
RNA_enum_set(drop->ptr, "type", GS(id->name));
@@ -784,9 +798,13 @@ static void *view3d_main_region_duplicate(void *poin)
return NULL;
}
-static void view3d_main_region_listener(
- wmWindow *win, ScrArea *area, ARegion *region, wmNotifier *wmn, const Scene *scene)
+static void view3d_main_region_listener(const wmRegionListenerParams *params)
{
+ wmWindow *window = params->window;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+ const Scene *scene = params->scene;
View3D *v3d = area->spacedata.first;
RegionView3D *rv3d = region->regiondata;
wmGizmoMap *gzmap = region->gizmo_map;
@@ -1007,10 +1025,10 @@ static void view3d_main_region_listener(
ED_view3d_xr_shading_update(G_MAIN->wm.first, v3d, scene);
#endif
- ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+ ViewLayer *view_layer = WM_window_get_active_view_layer(window);
Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer);
if (depsgraph) {
- ED_render_view3d_update(depsgraph, win, area, true);
+ ED_render_view3d_update(depsgraph, window, area, true);
}
}
ED_region_tag_redraw(region);
@@ -1048,14 +1066,13 @@ static void view3d_main_region_listener(
}
}
-static void view3d_main_region_message_subscribe(const struct bContext *C,
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *area,
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void view3d_main_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ const bContext *C = params->context;
+ ScrArea *area = params->area;
+ ARegion *region = params->region;
+
/* 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.
@@ -1170,12 +1187,11 @@ static void view3d_header_region_draw(const bContext *C, ARegion *region)
ED_region_header(C, region);
}
-static void view3d_header_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void view3d_header_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_SCENE:
@@ -1240,14 +1256,11 @@ static void view3d_header_region_listener(wmWindow *UNUSED(win),
#endif
}
-static void view3d_header_region_message_subscribe(const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace),
- struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen),
- struct ScrArea *UNUSED(area),
- struct ARegion *region,
- struct wmMsgBus *mbus)
+static void view3d_header_region_message_subscribe(const wmRegionMessageSubscribeParams *params)
{
+ struct wmMsgBus *mbus = params->message_bus;
+ ARegion *region = params->region;
+
wmMsgParams_RNA msg_key_params = {{0}};
/* Only subscribe to types. */
@@ -1385,12 +1398,11 @@ static void view3d_buttons_region_layout(const bContext *C, ARegion *region)
ED_view3d_buttons_region_layout_ex(C, region, NULL);
}
-static void view3d_buttons_region_listener(wmWindow *UNUSED(win),
- ScrArea *UNUSED(area),
- ARegion *region,
- wmNotifier *wmn,
- const Scene *UNUSED(scene))
+static void view3d_buttons_region_listener(const wmRegionListenerParams *params)
{
+ ARegion *region = params->region;
+ wmNotifier *wmn = params->notifier;
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -1509,11 +1521,10 @@ static void view3d_tools_region_draw(const bContext *C, ARegion *region)
}
/* area (not region) level listener */
-static void space_view3d_listener(wmWindow *UNUSED(win),
- ScrArea *area,
- struct wmNotifier *wmn,
- Scene *UNUSED(scene))
+static void space_view3d_listener(const wmSpaceTypeListenerParams *params)
{
+ ScrArea *area = params->area;
+ wmNotifier *wmn = params->notifier;
View3D *v3d = area->spacedata.first;
/* context changes */
@@ -1580,7 +1591,8 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
if (view_layer->basact) {
Object *ob = view_layer->basact->object;
/* if hidden but in edit mode, we still display, can happen with animation */
- if ((view_layer->basact->flag & BASE_VISIBLE_DEPSGRAPH) != 0 || (ob->mode & OB_MODE_EDIT)) {
+ if ((view_layer->basact->flag & BASE_VISIBLE_DEPSGRAPH) != 0 ||
+ (ob->mode != OB_MODE_OBJECT)) {
CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, view_layer->basact);
}
}
@@ -1588,12 +1600,25 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
return 1;
}
else if (CTX_data_equals(member, "active_object")) {
+ /* In most cases the active object is the `view_layer->basact->object`.
+ * For the 3D view however it can be NULL when hidden.
+ *
+ * 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.
+ *
+ * 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
+ * without showing the object.
+ *
+ * See T85532 for alternatives that were considered. */
ViewLayer *view_layer = CTX_data_view_layer(C);
if (view_layer->basact) {
Object *ob = view_layer->basact->object;
/* if hidden but in edit mode, we still display, can happen with animation */
if ((view_layer->basact->flag & BASE_VISIBLE_DEPSGRAPH) != 0 ||
- (ob->mode & OB_MODE_EDIT) != 0) {
+ (ob->mode != OB_MODE_OBJECT)) {
CTX_data_id_pointer_set(result, &ob->id);
}
}
diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c
index 11643960595..0edd6aeb2ca 100644
--- a/source/blender/editors/space_view3d/view3d_camera_control.c
+++ b/source/blender/editors/space_view3d/view3d_camera_control.c
@@ -50,12 +50,8 @@
#include "DEG_depsgraph.h"
-#include "ED_screen.h"
-
#include "view3d_intern.h" /* own include */
-#include "BLI_strict_flags.h"
-
typedef struct View3DCameraControl {
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 9982d44b6be..478f48700ea 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -165,7 +165,7 @@ void ED_view3d_update_viewmat(Depsgraph *depsgraph,
rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
}
- /* calculate pixelsize factor once, is used for lights and obcenters */
+ /* 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])'
* because of float point precision problems at large values T23908. */
@@ -723,15 +723,24 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region,
}
if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
- UI_draw_safe_areas(
- shdr_pos, x1, x2, y1, y2, scene->safe_areas.title, scene->safe_areas.action);
+ UI_draw_safe_areas(shdr_pos,
+ &(const rctf){
+ .xmin = x1,
+ .xmax = x2,
+ .ymin = y1,
+ .ymax = y2,
+ },
+ scene->safe_areas.title,
+ scene->safe_areas.action);
if (ca->flag & CAM_SHOW_SAFE_CENTER) {
UI_draw_safe_areas(shdr_pos,
- x1,
- x2,
- y1,
- y2,
+ &(const rctf){
+ .xmin = x1,
+ .xmax = x2,
+ .ymin = y1,
+ .ymax = y2,
+ },
scene->safe_areas.title_center,
scene->safe_areas.action_center);
}
@@ -1960,13 +1969,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
/* XXX(jbakker): `do_color_management` should be controlled by the caller. Currently when doing a
* viewport render animation and saving to an 8bit file format, color management would be applied
* twice. Once here, and once when saving the saving to disk. In this case the Save As Render
- * option cannot be controlled either. But when doing an offscreen render you want to do the
+ * option cannot be controlled either. But when doing an off-screen render you want to do the
* color management here.
*
- * This option was added here to increase the performance when rendering for a playblast. When
- * using workbench the color differences haven't been reported as a bug. But users also use the
- * viewport rendering to render Eevee scenes. In the later situation the saved colors
- * are totally wrong. */
+ * This option was added here to increase the performance for quick view-port preview renders.
+ * When using workbench the color differences haven't been reported as a bug. But users also use
+ * the viewport rendering to render Eevee scenes. In the later situation the saved colors are
+ * totally wrong. */
const bool do_color_management = (ibuf->rect_float == NULL);
ED_view3d_draw_offscreen(depsgraph,
scene,
@@ -2335,7 +2344,7 @@ void ED_view3d_depth_update(ARegion *region)
}
}
-/* Utility function to find the closest Z value, use for autodepth. */
+/* Utility function to find the closest Z value, use for auto-depth. */
float view3d_depth_near(ViewDepths *d)
{
/* Convert to float for comparisons. */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index ab4e7be88fe..2f8cd5a7517 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -2025,7 +2025,7 @@ static float viewzoom_scale_value(const rcti *winrct,
{
float zfac;
- if (viewzoom == USER_ZOOM_CONT) {
+ if (viewzoom == USER_ZOOM_CONTINUE) {
double time = PIL_check_seconds_timer();
float time_step = (float)(time - *r_timer_lastdraw);
float fac;
@@ -2043,7 +2043,6 @@ static float viewzoom_scale_value(const rcti *winrct,
fac = -fac;
}
- /* oldstyle zoom */
zfac = 1.0f + ((fac / 20.0f) * time_step);
*r_timer_lastdraw = time;
}
@@ -2405,7 +2404,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_FINISHED;
}
- if (U.viewzoom == USER_ZOOM_CONT) {
+ if (U.viewzoom == USER_ZOOM_CONTINUE) {
/* needs a timer to continue redrawing */
vod->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
vod->prev.time = PIL_check_seconds_timer();
@@ -2888,7 +2887,7 @@ static void view3d_from_minmax(bContext *C,
});
}
- /* smooth view does viewlock RV3D_BOXVIEW copy */
+ /* Smooth-view does view-lock #RV3D_BOXVIEW copy. */
}
/**
@@ -3021,7 +3020,6 @@ void VIEW3D_OT_view_all(wmOperatorType *ot)
* Move & Zoom the view to fit selected contents.
* \{ */
-/* like a localview without local!, was centerview() in 2.4x */
static int viewselected_exec(bContext *C, wmOperator *op)
{
ARegion *region = CTX_wm_region(C);
@@ -3282,7 +3280,7 @@ static int viewcenter_cursor_exec(bContext *C, wmOperator *op)
ED_view3d_smooth_view(
C, v3d, region, smooth_viewtx, &(const V3D_SmoothParams){.ofs = new_ofs});
- /* smooth view does viewlock RV3D_BOXVIEW copy */
+ /* Smooth view does view-lock #RV3D_BOXVIEW copy. */
}
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index 6824c526888..2d499cf85c7 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -48,7 +48,7 @@
#include "ED_screen.h"
#include "ED_space_api.h"
-#include "PIL_time.h" /* smoothview */
+#include "PIL_time.h" /* Smooth-view. */
#include "UI_interface.h"
#include "UI_resources.h"
@@ -84,7 +84,7 @@ enum {
FLY_MODAL_PRECISION_DISABLE,
FLY_MODAL_FREELOOK_ENABLE,
FLY_MODAL_FREELOOK_DISABLE,
- FLY_MODAL_SPEED, /* mousepan typically */
+ FLY_MODAL_SPEED, /* mouse-pan typically. */
};
/* relative view axis locking - xlock, zlock */
@@ -537,7 +537,7 @@ static void flyEvent(FlyInfo *fly, const wmEvent *event)
fly->state = FLY_CONFIRM;
break;
- /* speed adjusting with mousepan (trackpad) */
+ /* Speed adjusting with mouse-pan (track-pad). */
case FLY_MODAL_SPEED: {
float fac = 0.02f * (event->prevy - event->y);
@@ -768,7 +768,7 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
/* this is the direction that's added to the view offset per redraw */
float dvec[3] = {0, 0, 0};
- /* Camera Uprighting variables */
+ /* Camera Up-righting variables. */
float moffset[2]; /* mouse offset from the views center */
float tmp_quat[4]; /* used for rotating the view */
@@ -950,7 +950,7 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
}
}
- /* only apply xcorrect when mouse isn't applying x rot */
+ /* Only apply X-axis correction when mouse isn't applying x rotation. */
if (fly->xlock == FLY_AXISLOCK_STATE_ACTIVE && moffset[1] == 0) {
float upvec[3];
copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c b/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
index 242a0a802a6..98597cb2986 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
@@ -22,7 +22,6 @@
#include "BKE_context.h"
#include "BKE_layer.h"
-#include "BKE_object.h"
#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
index 7a201d8841c..6fa974cdb09 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
@@ -22,7 +22,6 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
-#include "BKE_object.h"
#include "DNA_object_types.h"
@@ -45,14 +44,17 @@
/** \name View3D Navigation Gizmo Group
* \{ */
-/* Offset from screen edge. */
-#define GIZMO_OFFSET_FAC 1.2f
/* Size of main icon. */
-#define GIZMO_SIZE 80
-/* Factor for size of smaller button. */
-#define GIZMO_MINI_FAC 0.35f
-/* How much mini buttons offset from the primary. */
-#define GIZMO_MINI_OFFSET_FAC 0.38f
+#define GIZMO_SIZE U.gizmo_size_navigate_v3d
+
+/* Main gizmo offset from screen edges in unscaled pixels. */
+#define GIZMO_OFFSET 10.0f
+
+/* Width of smaller buttons in unscaled pixels. */
+#define GIZMO_MINI_SIZE 28.0f
+
+/* Margin around the smaller buttons. */
+#define GIZMO_MINI_OFFSET 2.0f
enum {
GZ_INDEX_MOVE = 0,
@@ -174,7 +176,7 @@ static void WIDGETGROUP_navigate_setup(const bContext *C, wmGizmoGroup *gzgroup)
}
/* may be overwritten later */
- gz->scale_basis = (GIZMO_SIZE * GIZMO_MINI_FAC) / 2;
+ gz->scale_basis = GIZMO_MINI_SIZE / 2.0f;
if (info->icon != 0) {
PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "icon");
RNA_property_enum_set(gz->ptr, prop, info->icon);
@@ -212,7 +214,7 @@ static void WIDGETGROUP_navigate_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
wmGizmo *gz = navgroup->gz_array[GZ_INDEX_ROTATE];
- gz->scale_basis = GIZMO_SIZE / 2;
+ gz->scale_basis = GIZMO_SIZE / 2.0f;
const char mapping[6] = {
RV3D_VIEW_LEFT,
RV3D_VIEW_RIGHT,
@@ -263,9 +265,8 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g
const bool show_navigate = (U.uiflag & USER_SHOW_GIZMO_NAVIGATE) != 0;
const bool show_rotate_gizmo = (U.mini_axis_type == USER_MINI_AXIS_TYPE_GIZMO);
- const float icon_size = GIZMO_SIZE;
- const float icon_offset = (icon_size * 0.52f) * GIZMO_OFFSET_FAC * UI_DPI_FAC;
- const float icon_offset_mini = icon_size * GIZMO_MINI_OFFSET_FAC * UI_DPI_FAC;
+ const float icon_offset = ((GIZMO_SIZE / 2.0f) + GIZMO_OFFSET) * UI_DPI_FAC;
+ const float icon_offset_mini = (GIZMO_MINI_SIZE + GIZMO_MINI_OFFSET) * UI_DPI_FAC;
const float co_rotate[2] = {
rect_visible->xmax - icon_offset,
rect_visible->ymax - icon_offset,
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
index 8f3d40584aa..4ac16e8fbe8 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
@@ -40,6 +40,8 @@
#include "GPU_matrix.h"
#include "GPU_state.h"
+#include "BLF_api.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -53,169 +55,34 @@
#include "view3d_intern.h"
-#define USE_AXIS_FONT
-#define USE_FADE_BACKGROUND
-
-#ifdef USE_AXIS_FONT
-# include "BLF_api.h"
-#endif
-
-#define DIAL_RESOLUTION 32
-
-/* Sizes of axis spheres containing XYZ characters. */
-#define AXIS_HANDLE_SIZE_FG 0.19f
-/* When pointing away from the view. */
-#define AXIS_HANDLE_SIZE_BG 0.15f
-/* How far axis handles are away from the center. */
-#define AXIS_HANDLE_OFFSET (1.0f - AXIS_HANDLE_SIZE_FG)
-
-struct AxisDrawInfo {
- /* Matrix is needed for screen-aligned font drawing. */
-#ifdef USE_AXIS_FONT
- float matrix_final[4][4];
-#endif
-#ifdef USE_FADE_BACKGROUND
- float color_bg[3];
-#endif
-};
-
-#ifndef USE_AXIS_FONT
-/**
- * \param viewmat_local_unit: is typically the 'rv3d->viewmatob'
- * copied into a 3x3 matrix and normalized.
- */
-static void draw_xyz_wire(
- uint pos_id, const float viewmat_local_unit[3][3], const float c[3], float size, int axis)
-{
- int line_type;
- float buffer[4][3];
- int n = 0;
-
- float v1[3] = {0.0f, 0.0f, 0.0f}, v2[3] = {0.0f, 0.0f, 0.0f};
- float dim = size * 0.1f;
- float dx[3], dy[3];
-
- dx[0] = dim;
- dx[1] = 0.0f;
- dx[2] = 0.0f;
- dy[0] = 0.0f;
- dy[1] = dim;
- dy[2] = 0.0f;
-
- switch (axis) {
- case 0: /* x axis */
- line_type = GPU_PRIM_LINES;
-
- /* bottom left to top right */
- negate_v3_v3(v1, dx);
- sub_v3_v3(v1, dy);
- copy_v3_v3(v2, dx);
- add_v3_v3(v2, dy);
-
- copy_v3_v3(buffer[n++], v1);
- copy_v3_v3(buffer[n++], v2);
-
- /* top left to bottom right */
- mul_v3_fl(dy, 2.0f);
- add_v3_v3(v1, dy);
- sub_v3_v3(v2, dy);
-
- copy_v3_v3(buffer[n++], v1);
- copy_v3_v3(buffer[n++], v2);
-
- break;
- case 1: /* y axis */
- line_type = GPU_PRIM_LINES;
-
- /* bottom left to top right */
- mul_v3_fl(dx, 0.75f);
- negate_v3_v3(v1, dx);
- sub_v3_v3(v1, dy);
- copy_v3_v3(v2, dx);
- add_v3_v3(v2, dy);
-
- copy_v3_v3(buffer[n++], v1);
- copy_v3_v3(buffer[n++], v2);
-
- /* top left to center */
- mul_v3_fl(dy, 2.0f);
- add_v3_v3(v1, dy);
- zero_v3(v2);
-
- copy_v3_v3(buffer[n++], v1);
- copy_v3_v3(buffer[n++], v2);
-
- break;
- case 2: /* z axis */
- line_type = GPU_PRIM_LINE_STRIP;
-
- /* start at top left */
- negate_v3_v3(v1, dx);
- add_v3_v3(v1, dy);
-
- copy_v3_v3(buffer[n++], v1);
-
- mul_v3_fl(dx, 2.0f);
- add_v3_v3(v1, dx);
+/* Radius of the entire background. */
+#define WIDGET_RADIUS ((U.gizmo_size_navigate_v3d / 2.0f) * UI_DPI_FAC)
- copy_v3_v3(buffer[n++], v1);
+/* Sizes of axis spheres containing XYZ characters in relation to above. */
+#define AXIS_HANDLE_SIZE 0.20f
- mul_v3_fl(dy, 2.0f);
- sub_v3_v3(v1, dx);
- sub_v3_v3(v1, dy);
+#define AXIS_LINE_WIDTH ((U.gizmo_size_navigate_v3d / 40.0f) * U.pixelsize)
+#define AXIS_RING_WIDTH ((U.gizmo_size_navigate_v3d / 60.0f) * U.pixelsize)
+#define AXIS_TEXT_SIZE (WIDGET_RADIUS * AXIS_HANDLE_SIZE * 1.25f)
- copy_v3_v3(buffer[n++], v1);
+/* distance within this from center is considered positive. */
+#define AXIS_DEPTH_BIAS 0.01f
- add_v3_v3(v1, dx);
-
- copy_v3_v3(buffer[n++], v1);
-
- break;
- default:
- BLI_assert(0);
- return;
- }
-
- for (int i = 0; i < n; i++) {
- mul_transposed_m3_v3((float(*)[3])viewmat_local_unit, buffer[i]);
- add_v3_v3(buffer[i], c);
- }
-
- immBegin(line_type, n);
- for (int i = 0; i < n; i++) {
- immVertex3fv(pos_id, buffer[i]);
- }
- immEnd();
-}
-#endif /* !USE_AXIS_FONT */
-
-/**
- * \param draw_info: Extra data needed for drawing.
- */
-static void axis_geom_draw(const wmGizmo *gz,
- const float color[4],
- const bool select,
- const struct AxisDrawInfo *draw_info)
+static void gizmo_axis_draw(const bContext *C, wmGizmo *gz)
{
- float viewport[4];
- GPU_viewport_size_get_f(viewport);
-
- GPUVertFormat *format = immVertexFormat();
- const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-
struct {
float depth;
char index;
char axis;
+ char axis_opposite;
bool is_pos;
} axis_order[6] = {
- {-gz->matrix_offset[0][2], 0, 0, false},
- {+gz->matrix_offset[0][2], 1, 0, true},
- {-gz->matrix_offset[1][2], 2, 1, false},
- {+gz->matrix_offset[1][2], 3, 1, true},
- {-gz->matrix_offset[2][2], 4, 2, false},
- {+gz->matrix_offset[2][2], 5, 2, true},
+ {-gz->matrix_offset[0][2], 0, 0, 1, false},
+ {+gz->matrix_offset[0][2], 1, 0, 0, true},
+ {-gz->matrix_offset[1][2], 2, 1, 3, false},
+ {+gz->matrix_offset[1][2], 3, 1, 2, true},
+ {-gz->matrix_offset[2][2], 4, 2, 5, false},
+ {+gz->matrix_offset[2][2], 5, 2, 4, true},
};
int axis_align = -1;
@@ -226,25 +93,35 @@ static void axis_geom_draw(const wmGizmo *gz,
}
}
- /* Show backwards pointing highlight on-top (else we can't see it at all). */
- if ((select == false) && (gz->highlight_part > 0) && (axis_align != -1)) {
- if (axis_order[gz->highlight_part - 1].is_pos == false) {
- axis_order[gz->highlight_part - 1].depth = FLT_MAX;
- }
- }
-
qsort(&axis_order, ARRAY_SIZE(axis_order), sizeof(axis_order[0]), BLI_sortutil_cmp_float);
- static const float axis_highlight[4] = {1, 1, 1, 1};
- static const float axis_black[4] = {0, 0, 0, 1};
- static float axis_color[3][4];
+ /* When the cursor is over any of the gizmos (show circle backdrop). */
+ const bool is_active = ((gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0);
- const float axis_depth_bias = 0.01f;
- const float sphere_scale = 1.15f;
- /* TODO(fclem): Is there a way to get the widget radius? */
- const float widget_pix_size = 40.0f * U.dpi_fac;
+ /* Background color of the View3D, used to mix colors. */
+ float view_color[4];
+ ED_view3d_background_color_get(CTX_data_scene(C), CTX_wm_view3d(C), view_color);
+ view_color[3] = 1.0f;
+
+ float matrix_screen[4][4];
+ float matrix_unit[4][4];
+ unit_m4(matrix_unit);
+ WM_gizmo_calc_matrix_final_params(gz,
+ &((struct WM_GizmoMatrixParams){
+ .matrix_offset = matrix_unit,
+ }),
+ matrix_screen);
+ GPU_matrix_push();
+ GPU_matrix_mul(matrix_screen);
+
+ GPUVertFormat *format = immVertexFormat();
+ const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ const uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+
+ static float axis_color[3][4];
-#ifdef USE_AXIS_FONT
struct {
float matrix[4][4];
float matrix_m3[3][3];
@@ -252,38 +129,29 @@ static void axis_geom_draw(const wmGizmo *gz,
int id;
} font;
- if (select == false) {
- font.id = blf_mono_font;
- BLF_disable(font.id, BLF_ROTATION | BLF_SHADOW | BLF_MATRIX | BLF_ASPECT | BLF_WORD_WRAP);
- BLF_color4fv(font.id, axis_black);
- BLF_size(font.id, 12 * U.dpi_fac, 72);
-
- /* The view matrix is used to position the text. */
- BLF_position(font.id, 0, 0, 0);
-
- /* Calculate the inverse of the (matrix_final * matrix_offset).
- * This allows us to use the final location, while reversing the rotation so fonts
- * show without any rotation. */
- float m3[3][3];
- float m3_offset[3][3];
- copy_m3_m4(m3, draw_info->matrix_final);
- copy_m3_m4(m3_offset, gz->matrix_offset);
- mul_m3_m3m3(m3, m3, m3_offset);
- copy_m3_m3(font.matrix_m3_invert, m3);
- invert_m3(m3);
- copy_m3_m3(font.matrix_m3, m3);
- copy_m4_m3(font.matrix, m3);
- }
-#endif
-
- /* When the cursor is over any of the gizmos (show circle backdrop). */
- const bool is_active = (color[3] != 0.0f);
-
- const float clip_range = gz->scale_final * sphere_scale;
- bool use_project_matrix = (clip_range >= -GPU_MATRIX_ORTHO_CLIP_NEAR_DEFAULT);
+ font.id = BLF_default();
+ BLF_disable(font.id, BLF_ROTATION | BLF_SHADOW | BLF_MATRIX | BLF_ASPECT | BLF_WORD_WRAP);
+ BLF_enable(font.id, BLF_BOLD);
+ BLF_size(font.id, AXIS_TEXT_SIZE, 72);
+ BLF_position(font.id, 0, 0, 0);
+
+ /* Calculate the inverse of the (matrix_final * matrix_offset).
+ * This allows us to use the final location, while reversing the rotation so fonts
+ * show without any rotation. */
+ float m3[3][3];
+ float m3_offset[3][3];
+ copy_m3_m4(m3, matrix_screen);
+ copy_m3_m4(m3_offset, gz->matrix_offset);
+ mul_m3_m3m3(m3, m3, m3_offset);
+ copy_m3_m3(font.matrix_m3_invert, m3);
+ invert_m3(m3);
+ copy_m3_m3(font.matrix_m3, m3);
+ copy_m4_m3(font.matrix, m3);
+
+ bool use_project_matrix = (gz->scale_final >= -GPU_MATRIX_ORTHO_CLIP_NEAR_DEFAULT);
if (use_project_matrix) {
GPU_matrix_push_projection();
- GPU_matrix_ortho_set_z(-clip_range, clip_range);
+ GPU_matrix_ortho_set_z(-gz->scale_final, gz->scale_final);
}
UI_draw_roundbox_corner_set(UI_CNR_ALL);
@@ -291,263 +159,161 @@ static void axis_geom_draw(const wmGizmo *gz,
/* Circle defining active area. */
if (is_active) {
- immUnbindProgram();
-
- float rad = widget_pix_size;
+ const float rad = WIDGET_RADIUS;
GPU_matrix_push();
GPU_matrix_scale_1f(1.0f / rad);
-
- UI_draw_roundbox_4fv(true, -rad, -rad, rad, rad, rad, color);
-
+ UI_draw_roundbox_4fv(
+ &(const rctf){
+ .xmin = -rad,
+ .xmax = rad,
+ .ymin = -rad,
+ .ymax = rad,
+ },
+ true,
+ rad,
+ gz->color_hi);
GPU_matrix_pop();
-
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
}
- GPU_matrix_push();
GPU_matrix_mul(gz->matrix_offset);
for (int axis_index = 0; axis_index < ARRAY_SIZE(axis_order); axis_index++) {
const int index = axis_order[axis_index].index;
const int axis = axis_order[axis_index].axis;
const bool is_pos = axis_order[axis_index].is_pos;
- const bool is_highlight = index + 1 == gz->highlight_part;
+ const float depth = axis_order[axis_index].depth;
+ const bool is_behind = (depth <= (AXIS_DEPTH_BIAS * (is_pos ? -1 : 1)));
+ bool is_aligned_front = (axis_align != -1 && axis_align == axis && !is_behind);
+ bool is_aligned_back = (axis_align != -1 && axis_align == axis && is_behind);
+
+ const float v[3] = {0, 0, (1.0f - AXIS_HANDLE_SIZE) * (is_pos ? 1 : -1)};
+ const float v_final[3] = {v[(axis + 2) % 3], v[(axis + 1) % 3], v[axis]};
+
+ bool is_highlight = index + 1 == gz->highlight_part;
+ /* Check if highlight part is the other side when axis aligned. */
+ if (is_aligned_front && (axis_order[axis_index].axis_opposite + 1 == gz->highlight_part)) {
+ is_highlight = true;
+ }
UI_GetThemeColor3fv(TH_AXIS_X + axis, axis_color[axis]);
axis_color[axis][3] = 1.0f;
- const int index_z = axis;
- const int index_y = (axis + 1) % 3;
- const int index_x = (axis + 2) % 3;
-
- bool ok = true;
-
- /* Skip view align axis when selecting (allows to switch to opposite side). */
- if (select && ((axis_align == axis) && (gz->matrix_offset[axis][2] > 0.0f) == is_pos)) {
- ok = false;
+ /* Color that is full at front, but 50% view background when in back. */
+ float fading_color[4];
+ interp_v4_v4v4(fading_color, view_color, axis_color[axis], ((depth + 1) * 0.25) + 0.5);
+
+ /* Color that is midway between front and back. */
+ float middle_color[4];
+ interp_v4_v4v4(middle_color, view_color, axis_color[axis], 0.75f);
+
+ GPU_blend(GPU_BLEND_ALPHA);
+
+ /* Axis Line. */
+ if (is_pos || axis_align != -1) {
+
+ /* Extend slightly to meet better at the center. */
+ float v_start[3] = {0.0f, 0.0f, 0.0f};
+ mul_v3_v3fl(v_start, v_final, -(AXIS_LINE_WIDTH / WIDGET_RADIUS * 0.66f));
+
+ /* Decrease length of line by ball radius. */
+ float v_end[3] = {0.0f, 0.0f, 0.0f};
+ mul_v3_v3fl(v_end, v_final, 1.0f - AXIS_HANDLE_SIZE);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR);
+ immUniform2fv("viewportSize", &viewport_size[2]);
+ immUniform1f("lineWidth", AXIS_LINE_WIDTH);
+ immBegin(GPU_PRIM_LINES, 2);
+ immAttr4fv(color_id, middle_color);
+ immVertex3fv(pos_id, v_start);
+ immAttr4fv(color_id, fading_color);
+ immVertex3fv(pos_id, v_end);
+ immEnd();
+ immUnbindProgram();
}
- if (ok) {
- /* Check aligned, since the front axis won't display in this case,
- * and we want to make sure all 3 axes have a character at all times. */
- const bool show_axis_char = (is_pos || (axis == axis_align));
- const float v[3] = {0, 0, AXIS_HANDLE_OFFSET * (is_pos ? 1 : -1)};
- const float v_final[3] = {v[index_x], v[index_y], v[index_z]};
- const float *color_current = is_highlight ? axis_highlight : axis_color[axis];
- float color_current_fade[4];
-
- /* Flip the faded state when axis aligned, since we're hiding the front-mode axis
- * otherwise we see the color for the back-most axis, which is useful for
- * click-to-rotate 180d but not useful to visualize.
- *
- * Use depth bias so axis-aligned views show the positive axis as being in-front.
- * This is a detail so primary axes show as dominant.
- */
- const bool is_pos_color = (axis_order[axis_index].depth >
- (axis_depth_bias * (is_pos ? -1 : 1)));
-
- if (select == false) {
-#ifdef USE_FADE_BACKGROUND
- interp_v3_v3v3(
- color_current_fade, draw_info->color_bg, color_current, is_highlight ? 1.0 : 0.5f);
- color_current_fade[3] = color_current[3];
-#else
- copy_v4_v4(color_current_fade, color_current);
- color_current_fade[3] *= 0.2;
-#endif
- }
- else {
- copy_v4_fl(color_current_fade, 1.0f);
- }
-
- /* Axis Line. */
- if (is_pos) {
- float v_start[3];
- immUnbindProgram();
-
- GPU_blend(GPU_BLEND_ALPHA);
-
- immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
- immUniform2fv("viewportSize", &viewport[2]);
- immUniform1f("lineWidth", 2.0f * U.pixelsize);
- immUniformColor4fv(is_pos_color ? color_current : color_current_fade);
- immBegin(GPU_PRIM_LINES, 2);
- if (axis_align == -1) {
- zero_v3(v_start);
+ /* Axis Ball. */
+ if (!is_aligned_back) {
+ float *inner_color = fading_color;
+ float *outline_color = fading_color;
+ float negative_color[4];
+ if (!is_pos) {
+ if (is_aligned_front) {
+ interp_v4_v4v4(
+ negative_color, (float[4]){1.0f, 1.0f, 1.0f, 1.0f}, axis_color[axis], 0.5f);
+ negative_color[3] = MIN2(depth + 1, 1.0f);
+ outline_color = negative_color;
}
else {
- /* When axis aligned we don't draw the front most axis
- * (allowing us to switch to the opposite side).
- * In this case don't draw lines over axis pointing away from us
- * because it obscures character and looks noisy.
- */
- mul_v3_v3fl(v_start, v_final, 0.3f);
+ interp_v4_v4v4(negative_color, view_color, axis_color[axis], 0.25f);
+ negative_color[3] = MIN2(depth + 1, 1.0f);
+ inner_color = negative_color;
}
- immVertex3fv(pos_id, v_start);
- immVertex3fv(pos_id, v_final);
- immEnd();
-
- immUnbindProgram();
-
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
}
- /* Axis Ball. */
-#ifdef USE_AXIS_FONT
- if (select == false) {
- immUnbindProgram();
-
- GPU_matrix_push();
- GPU_matrix_translate_3fv(v_final);
- GPU_matrix_mul(font.matrix);
-
- float rad = widget_pix_size * (is_pos ? AXIS_HANDLE_SIZE_FG : AXIS_HANDLE_SIZE_BG);
-
- /* Black outlines for negative axis balls, otherwise they can be hard to see since
- * they use a faded color which can be similar to the circle backdrop in tone. */
- if (is_active && !is_highlight && !is_pos && !select && !(axis_align == axis)) {
- static const float axis_black_faded[4] = {0.0f, 0.0f, 0.0f, 0.2f};
- float outline = rad * sphere_scale;
- UI_draw_roundbox_4fv(
- true, -outline, -outline, outline, outline, outline, axis_black_faded);
- }
-
- const float *col = is_pos_color ? color_current : color_current_fade;
- UI_draw_roundbox_4fv(true, -rad, -rad, rad, rad, rad, col);
-
- GPU_matrix_pop();
-
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- }
- else
-#endif
- {
- GPU_matrix_push();
- GPU_matrix_translate_3fv(v_final);
- GPU_matrix_scale_1f(is_pos ? AXIS_HANDLE_SIZE_FG : AXIS_HANDLE_SIZE_BG);
-
- GPUBatch *sphere = GPU_batch_preset_sphere(0);
- GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
-
- /* Black outlines for negative axis balls, otherwise they can be hard to see since
- * they use a faded color which can be similar to the circle backdrop in tone. */
- if (is_active && !is_highlight && !is_pos && !select && !(axis_align == axis)) {
- static const float axis_black_faded[4] = {0, 0, 0, 0.2f};
- GPU_matrix_scale_1f(sphere_scale);
- GPU_batch_uniform_4fv(sphere, "color", axis_black_faded);
- GPU_batch_draw(sphere);
- GPU_matrix_scale_1f(1.0 / sphere_scale);
- }
+ GPU_matrix_push();
+ GPU_matrix_translate_3fv(v_final);
+ GPU_matrix_mul(font.matrix);
+ /* Size change from back to front: 0.92f - 1.08f. */
+ float scale = ((depth + 1) * 0.08f) + 0.92f;
+ const float rad = WIDGET_RADIUS * AXIS_HANDLE_SIZE * scale;
+ UI_draw_roundbox_4fv_ex(
+ &(const rctf){
+ .xmin = -rad,
+ .xmax = rad,
+ .ymin = -rad,
+ .ymax = rad,
+ },
+ inner_color,
+ NULL,
+ 0.0f,
+ outline_color,
+ AXIS_RING_WIDTH,
+ rad);
+ GPU_matrix_pop();
+ }
- GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
- GPU_batch_uniform_4fv(sphere, "color", is_pos_color ? color_current : color_current_fade);
- GPU_batch_draw(sphere);
- GPU_matrix_pop();
+ /* Axis XYZ Character. */
+ if ((is_pos || is_highlight || (axis == axis_align)) && !is_aligned_back) {
+ float axis_str_width, axis_string_height;
+ char axis_str[3] = {'X' + axis, 0, 0};
+ if (!is_pos) {
+ axis_str[0] = '-';
+ axis_str[1] = 'X' + axis;
}
-
- /* Axis XYZ Character. */
- if (show_axis_char && (select == false)) {
-#ifdef USE_AXIS_FONT
- float axis_str_size[2] = {0};
- const char axis_str[2] = {'X' + axis, 0};
- BLF_width_and_height(font.id, axis_str, 2, &axis_str_size[0], &axis_str_size[1]);
-
- /* Calculate pixel aligned location, without this text draws fuzzy. */
- float v_final_px[3];
- mul_v3_m3v3(v_final_px, font.matrix_m3_invert, v_final);
- /* Center the test and pixel align, it's important to round once
- * otherwise the characters are noticeably not-centered.
- * If this wasn't an issue we could use #BLF_position to place the text. */
- v_final_px[0] = roundf(v_final_px[0] - (axis_str_size[0] / 2.0f));
- v_final_px[1] = roundf(v_final_px[1] - (axis_str_size[1] / 2.0f));
- mul_m3_v3(font.matrix_m3, v_final_px);
-
- immUnbindProgram();
-
- GPU_matrix_push();
- GPU_matrix_translate_3fv(v_final_px);
- GPU_matrix_mul(font.matrix);
-
- BLF_draw_ascii(font.id, axis_str, 2);
- GPU_blend(GPU_BLEND_ALPHA); /* XXX, blf disables */
- GPU_matrix_pop();
-
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-#else
- immUnbindProgram();
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- GPU_line_width(1.0f);
- float m3[3][3];
- copy_m3_m4(m3, gz->matrix_offset);
- immUniformColor4fv(axis_black);
- draw_xyz_wire(pos_id, m3, v_final, 1.0, axis);
- immUnbindProgram();
-#endif
+ BLF_width_and_height(font.id, axis_str, 3, &axis_str_width, &axis_string_height);
+
+ /* Calculate pixel-aligned location, without this text draws fuzzy. */
+ float v_final_px[3];
+ mul_v3_m3v3(v_final_px, font.matrix_m3_invert, v_final);
+ /* Center the text and pixel align, it's important to round once
+ * otherwise the characters are noticeably not-centered.
+ * If this wasn't an issue we could use #BLF_position to place the text. */
+ v_final_px[0] = roundf(v_final_px[0] - (axis_str_width * (is_pos ? 0.5f : 0.55f)));
+ v_final_px[1] = roundf(v_final_px[1] - (axis_string_height / 2.0f));
+ mul_m3_v3(font.matrix_m3, v_final_px);
+ GPU_matrix_push();
+ GPU_matrix_translate_3fv(v_final_px);
+ GPU_matrix_mul(font.matrix);
+ float text_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ if (!is_highlight) {
+ zero_v4(text_color);
+ text_color[3] = is_active ? 1.0f : 0.9f;
}
+ BLF_color4fv(font.id, text_color);
+ BLF_draw_ascii(font.id, axis_str, 2);
+ GPU_matrix_pop();
}
}
- GPU_matrix_pop();
- immUnbindProgram();
-
if (use_project_matrix) {
GPU_matrix_pop_projection();
}
-}
-
-static void axis3d_draw_intern(const bContext *C,
- wmGizmo *gz,
- const bool select,
- const bool highlight)
-{
- const float *color = highlight ? gz->color_hi : gz->color;
- float matrix_final[4][4];
- float matrix_unit[4][4];
-
- unit_m4(matrix_unit);
-
- WM_gizmo_calc_matrix_final_params(gz,
- &((struct WM_GizmoMatrixParams){
- .matrix_offset = matrix_unit,
- }),
- matrix_final);
-
- GPU_matrix_push();
- GPU_matrix_mul(matrix_final);
-
- struct AxisDrawInfo draw_info;
-#ifdef USE_AXIS_FONT
- if (select == false) {
- copy_m4_m4(draw_info.matrix_final, matrix_final);
- }
-#endif
-#ifdef USE_FADE_BACKGROUND
- if (select == false) {
- ED_view3d_background_color_get(CTX_data_scene(C), CTX_wm_view3d(C), draw_info.color_bg);
- }
-#else
- UNUSED_VARS(C);
-#endif
-
- GPU_blend(GPU_BLEND_ALPHA);
- axis_geom_draw(gz, color, select, &draw_info);
GPU_blend(GPU_BLEND_NONE);
+ BLF_disable(font.id, BLF_BOLD);
GPU_matrix_pop();
}
-static void gizmo_axis_draw(const bContext *C, wmGizmo *gz)
-{
- const bool is_modal = gz->state & WM_GIZMO_STATE_MODAL;
- const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
-
- (void)is_modal;
-
- GPU_blend(GPU_BLEND_ALPHA);
- axis3d_draw_intern(C, gz, false, is_highlight);
- GPU_blend(GPU_BLEND_NONE);
-}
-
static int gizmo_axis_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
{
float point_local[2] = {UNPACK2(mval)};
@@ -601,12 +367,19 @@ static int gizmo_axis_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mv
return -1;
}
-static int gizmo_axis_cursor_get(wmGizmo *gz)
+static int gizmo_axis_cursor_get(wmGizmo *UNUSED(gz))
{
- if (gz->highlight_part > 0) {
- return WM_CURSOR_EDIT;
- }
- return WM_CURSOR_NSEW_SCROLL;
+ return WM_CURSOR_DEFAULT;
+}
+
+static void gizmo_axis_screen_bounds_get(bContext *C, wmGizmo *gz, rcti *r_bounding_box)
+{
+ ScrArea *area = CTX_wm_area(C);
+ const float rad = WIDGET_RADIUS;
+ r_bounding_box->xmin = gz->matrix_basis[3][0] + area->totrct.xmin - rad;
+ r_bounding_box->ymin = gz->matrix_basis[3][1] + area->totrct.ymin - rad;
+ r_bounding_box->xmax = r_bounding_box->xmin + rad;
+ r_bounding_box->ymax = r_bounding_box->ymin + rad;
}
void VIEW3D_GT_navigate_rotate(wmGizmoType *gzt)
@@ -618,6 +391,7 @@ void VIEW3D_GT_navigate_rotate(wmGizmoType *gzt)
gzt->draw = gizmo_axis_draw;
gzt->test_select = gizmo_axis_test_select;
gzt->cursor_get = gizmo_axis_cursor_get;
+ gzt->screen_bounds_get = gizmo_axis_screen_bounds_get;
gzt->struct_size = sizeof(wmGizmo);
}
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect.c
index 3f07653fb2f..171cf721343 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_preselect.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect.c
@@ -30,7 +30,6 @@
#include "UI_resources.h"
#include "WM_api.h"
-#include "WM_toolsystem.h"
#include "WM_types.h"
#include "view3d_intern.h" /* own include */
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index f2e42cd1725..607ca110d0f 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -40,14 +40,11 @@
#include "DEG_depsgraph.h"
#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_mesh.h"
-#include "ED_screen.h"
#include "ED_undo.h"
#include "UI_interface.h"
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 0770bac1313..344168e895b 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -24,7 +24,6 @@
#include <math.h>
#include <stdlib.h>
-#include "DNA_collection_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -36,7 +35,6 @@
#include "BKE_appdir.h"
#include "BKE_blender_copybuffer.h"
-#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -49,7 +47,6 @@
#include "ED_outliner.h"
#include "ED_screen.h"
-#include "ED_select_utils.h"
#include "ED_transform.h"
#include "view3d_intern.h"
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 35ec4de5077..0605ea30806 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -596,7 +596,7 @@ static bool do_lasso_select_objects(ViewContext *vc,
}
for (base = vc->view_layer->object_bases.first; base; base = base->next) {
- if (BASE_SELECTABLE(v3d, base)) { /* use this to avoid un-needed lasso lookups */
+ if (BASE_SELECTABLE(v3d, base)) { /* Use this to avoid unnecessary lasso look-ups. */
const bool is_select = base->flag & BASE_SELECTED;
const bool is_inside = ((ED_view3d_project_base(vc->region, base) == V3D_PROJ_RET_OK) &&
BLI_lasso_is_point_inside(
@@ -1447,7 +1447,7 @@ static const EnumPropertyItem *object_select_menu_enum_itemf(bContext *C,
int totitem = 0;
int i = 0;
- /* don't need context but avoid docgen using this */
+ /* Don't need context but avoid API doc-generation using this. */
if (C == NULL || object_mouse_select_menu_data[i].idname[0] == '\0') {
return DummyRNA_NULL_items;
}
@@ -2494,8 +2494,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
}
/* Pass-through allows tweaks
- * FINISHED to signal one operator worked
- * */
+ * FINISHED to signal one operator worked */
if (retval) {
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 148a0986c5c..cce9287679c 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -27,7 +27,6 @@
#include "DNA_object_types.h"
#include "BLI_array.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index 2b7b8255068..a6a77ecd5f7 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -224,13 +224,11 @@ void view3d_region_operator_needs_opengl(wmWindow *UNUSED(win), ARegion *region)
*/
void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
{
- float viewdist;
-
if (rv3d->rflag & RV3D_ZOFFSET_DISABLED) {
return;
}
- viewdist = rv3d->dist;
+ float viewdist = rv3d->dist;
/* special exception for ortho camera (viewdist isnt used for perspective cameras) */
if (dist != 0.0f) {
@@ -248,7 +246,6 @@ bool ED_view3d_context_activate(bContext *C)
{
bScreen *screen = CTX_wm_screen(C);
ScrArea *area = CTX_wm_area(C);
- ARegion *region;
/* area can be NULL when called from python */
if (area == NULL || area->spacetype != SPACE_VIEW3D) {
@@ -259,7 +256,7 @@ bool ED_view3d_context_activate(bContext *C)
return false;
}
- region = BKE_area_find_region_active_win(area);
+ ARegion *region = BKE_area_find_region_active_win(area);
if (region == NULL) {
return false;
}
@@ -282,9 +279,7 @@ void ED_view3d_clipping_calc_from_boundbox(float clip[4][4],
const BoundBox *bb,
const bool is_flip)
{
- int val;
-
- for (val = 0; val < 4; val++) {
+ for (int val = 0; val < 4; val++) {
normal_tri_v3(clip[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]);
if (UNLIKELY(is_flip)) {
negate_v3(clip[val]);
@@ -752,14 +747,12 @@ bool ED_view3d_camera_lock_autokey(View3D *v3d,
static void view3d_boxview_clip(ScrArea *area)
{
- ARegion *region;
BoundBox *bb = MEM_callocN(sizeof(BoundBox), "clipbb");
float clip[6][4];
float x1 = 0.0f, y1 = 0.0f, z1 = 0.0f, ofs[3] = {0.0f, 0.0f, 0.0f};
- int val;
/* create bounding box */
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = region->regiondata;
@@ -794,7 +787,7 @@ static void view3d_boxview_clip(ScrArea *area)
}
}
- for (val = 0; val < 8; val++) {
+ for (int val = 0; val < 8; val++) {
if (ELEM(val, 0, 3, 4, 7)) {
bb->vec[val][0] = -x1 - ofs[0];
}
@@ -826,12 +819,12 @@ static void view3d_boxview_clip(ScrArea *area)
normal_tri_v3(clip[5], bb->vec[0], bb->vec[2], bb->vec[1]);
/* then plane equations */
- for (val = 0; val < 6; val++) {
+ for (int val = 0; val < 6; val++) {
clip[val][3] = -dot_v3v3(clip[val], bb->vec[val % 5]);
}
/* create bounding box */
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = region->regiondata;
@@ -950,11 +943,10 @@ void ED_view3d_quadview_update(ScrArea *area, ARegion *region, bool do_clip)
{
ARegion *region_sync = NULL;
RegionView3D *rv3d = region->regiondata;
- short viewlock;
/* this function copies flags from the first of the 3 other quadview
* regions to the 2 other, so it assumes this is the region whose
* properties are always being edited, weak */
- viewlock = rv3d->viewlock;
+ short viewlock = rv3d->viewlock;
if ((viewlock & RV3D_LOCK_ROTATION) == 0) {
do_clip = (viewlock & RV3D_BOXCLIP) != 0;
@@ -1015,10 +1007,7 @@ void ED_view3d_quadview_update(ScrArea *area, ARegion *region, bool do_clip)
static float view_autodist_depth_margin(ARegion *region, const int mval[2], int margin)
{
- ViewDepths depth_temp = {0};
rcti rect;
- float depth_close;
-
if (margin == 0) {
/* Get Z Depths, needed for perspective, nice for ortho */
rect.xmin = mval[0];
@@ -1030,8 +1019,9 @@ static float view_autodist_depth_margin(ARegion *region, const int mval[2], int
BLI_rcti_init_pt_radius(&rect, mval, margin);
}
+ ViewDepths depth_temp = {0};
view3d_update_depths_rect(region, &depth_temp, &rect);
- depth_close = view3d_depth_near(&depth_temp);
+ float depth_close = view3d_depth_near(&depth_temp);
MEM_SAFE_FREE(depth_temp.depths);
return depth_close;
}
@@ -1053,14 +1043,13 @@ bool ED_view3d_autodist(Depsgraph *depsgraph,
{
float depth_close;
int margin_arr[] = {0, 2, 4};
- int i;
bool depth_ok = false;
/* Get Z Depths, needed for perspective, nice for ortho */
ED_view3d_draw_depth(depsgraph, region, v3d, alphaoverride);
/* Attempt with low margin's first */
- i = 0;
+ int i = 0;
do {
depth_close = view_autodist_depth_margin(region, mval, margin_arr[i++] * U.pixelsize);
depth_ok = (depth_close != FLT_MAX);
@@ -1104,9 +1093,8 @@ bool ED_view3d_autodist_simple(ARegion *region,
int margin,
const float *force_depth)
{
- float depth;
-
/* Get Z Depths, needed for perspective, nice for ortho */
+ float depth;
if (force_depth) {
depth = *force_depth;
}
@@ -1237,7 +1225,6 @@ float ED_view3d_radius_to_dist(const View3D *v3d,
}
else {
float lens, sensor_size, zoom;
- float angle;
if (persp == RV3D_CAMOB) {
CameraParams params;
@@ -1259,7 +1246,7 @@ float ED_view3d_radius_to_dist(const View3D *v3d,
zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
}
- angle = focallength_to_fov(lens, sensor_size);
+ float angle = focallength_to_fov(lens, sensor_size);
/* zoom influences lens, correct this by scaling the angle as a distance
* (by the zoom-level) */
@@ -1319,14 +1306,13 @@ float ED_view3d_offset_distance(const float mat[4][4],
{
float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f};
- float dist;
mul_m4_v4(mat, pos);
add_v3_v3(pos, ofs);
mul_m4_v4(mat, dir);
normalize_v3(dir);
- dist = dot_v3v3(pos, dir);
+ float dist = dot_v3v3(pos, dir);
if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) {
dist = fallback_dist;
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 9d947384bf0..5c0ca1582a6 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -142,7 +142,7 @@ void ED_view3d_smooth_view_ex(
/* initialize sms */
view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d);
view3d_smooth_view_state_backup(&sms.src, v3d, rv3d);
- /* if smoothview runs multiple times... */
+ /* If smooth-view runs multiple times. */
if (rv3d->sms == NULL) {
view3d_smooth_view_state_backup(&sms.org, v3d, rv3d);
}
@@ -396,7 +396,7 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, b
/* 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 smoothview finishes.
+ * For now only redraw all regions when smooth-view finishes.
*/
if (step >= 1.0f) {
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
@@ -423,7 +423,7 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const w
}
/**
- * Apply the smoothview immediately, use when we need to start a new view operation.
+ * Apply the smooth-view immediately, use when we need to start a new view operation.
* (so we don't end up half-applying a view operation when pressing keys quickly).
*/
void ED_view3d_smooth_view_force_finish(bContext *C, View3D *v3d, ARegion *region)
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 5b42f221c80..cbd65e3175d 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -48,7 +48,7 @@
#include "ED_space_api.h"
#include "ED_transform_snap_object_context.h"
-#include "PIL_time.h" /* smoothview */
+#include "PIL_time.h" /* Smooth-view. */
#include "UI_interface.h"
#include "UI_resources.h"
@@ -872,7 +872,7 @@ static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event)
/* delta time */
t = (float)(PIL_check_seconds_timer() - walk->teleport.initial_time);
- /* reduce the veolocity, if JUMP wasn't hold for long enough */
+ /* Reduce the velocity, if JUMP wasn't hold for long enough. */
t = min_ff(t, JUMP_TIME_MAX);
walk->speed_jump = JUMP_SPEED_MIN +
t * (JUMP_SPEED_MAX - JUMP_SPEED_MIN) / JUMP_TIME_MAX;
diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt
index faed8abb202..b0bc5c6abda 100644
--- a/source/blender/editors/transform/CMakeLists.txt
+++ b/source/blender/editors/transform/CMakeLists.txt
@@ -55,6 +55,7 @@ set(SRC
transform_convert_nla.c
transform_convert_node.c
transform_convert_object.c
+ transform_convert_object_texspace.c
transform_convert_paintcurve.c
transform_convert_particle.c
transform_convert_sculpt.c
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 2a7c247ff2b..2fbcbe22349 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -135,7 +135,7 @@ void setTransformViewAspect(TransInfo *t, float r_aspect[3])
}
}
else if (t->spacetype == SPACE_GRAPH) {
- /* depemds on context of usage */
+ /* Depends on context of usage. */
}
}
@@ -440,7 +440,7 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
}
else {
/* Do we need more refined tags? */
- if (t->flag & T_POSE) {
+ if (t->options & CTX_POSE_BONE) {
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
else {
@@ -471,7 +471,7 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
}
else if (t->spacetype == SPACE_SEQ) {
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, NULL);
- /* Keyframes on strips has been moved, so make sure related editos are informed. */
+ /* Key-frames on strips has been moved, so make sure related editors are informed. */
WM_event_add_notifier(C, NC_ANIMATION, NULL);
}
else if (t->spacetype == SPACE_IMAGE) {
@@ -484,7 +484,7 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
wmWindow *window = CTX_wm_window(C);
WM_paint_cursor_tag_redraw(window, t->region);
}
- else if (t->flag & T_CURSOR) {
+ else if (t->options & CTX_CURSOR) {
ED_area_tag_redraw(t->area);
}
else {
@@ -695,6 +695,7 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
{TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""},
{TFM_MODAL_AUTOCONSTRAINT, "AUTOCONSTRAIN", 0, "Automatic Constraint", ""},
{TFM_MODAL_AUTOCONSTRAINTPLANE, "AUTOCONSTRAINPLANE", 0, "Automatic Constraint Plane", ""},
+ {TFM_MODAL_PRECISION, "PRECISION", 0, "Precision Mode", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -806,8 +807,6 @@ int transformEvent(TransInfo *t, const wmEvent *event)
const int modifiers_prev = t->modifiers;
const int mode_prev = t->mode;
- t->redraw |= handleMouseInput(t, &t->mouse, event);
-
/* Handle modal numinput events first, if already activated. */
if (((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) && hasNumInput(&t->num) &&
handleNumInput(t->context, &(t->num), event)) {
@@ -895,7 +894,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
break;
case TFM_MODAL_ROTATE:
/* only switch when... */
- if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
+ if (!(t->options & CTX_TEXTURE_SPACE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
if (transform_mode_is_changeable(t->mode)) {
restoreTransObjects(t);
resetTransModal(t);
@@ -1069,7 +1068,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
t->modifiers &= ~(MOD_CONSTRAINT_SELECT | MOD_CONSTRAINT_PLANE);
}
else {
- if (t->flag & T_CAMERA) {
+ if (t->options & CTX_CAMERA) {
/* Exception for switching to dolly, or trackball, in camera view. */
if (t->mode == TFM_TRANSLATION) {
setLocalConstraint(t, (CON_AXIS2), TIP_("along local Z"));
@@ -1095,6 +1094,19 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
}
break;
+ case TFM_MODAL_PRECISION:
+ if (event->prevval == KM_PRESS) {
+ t->modifiers |= MOD_PRECISION;
+ /* Shift is modifier for higher precision transform. */
+ t->mouse.precision = 1;
+ t->redraw |= TREDRAW_HARD;
+ }
+ else if (event->prevval == KM_RELEASE) {
+ t->modifiers &= ~MOD_PRECISION;
+ t->mouse.precision = 0;
+ t->redraw |= TREDRAW_HARD;
+ }
+ break;
/* Those two are only handled in transform's own handler, see T44634! */
case TFM_MODAL_EDGESLIDE_UP:
case TFM_MODAL_EDGESLIDE_DOWN:
@@ -1249,7 +1261,7 @@ bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], floa
createTransData(C, t); /* make TransData structs from selection */
- t->around = centerMode; /* override userdefined mode */
+ t->around = centerMode; /* override user-defined mode. */
if (t->data_len_all == 0) {
success = false;
@@ -1382,7 +1394,7 @@ static void drawTransformPixel(const struct bContext *C, ARegion *region, void *
*/
if ((U.autokey_flag & AUTOKEY_FLAG_NOWARNING) == 0) {
if (region == t->region) {
- if (t->flag & (T_OBJECT | T_POSE)) {
+ if (t->options & (CTX_OBJECT | CTX_POSE_BONE)) {
if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) {
drawAutoKeyWarning(t, region);
}
@@ -1652,7 +1664,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
if ((prop = RNA_struct_find_property(op->ptr, "texture_space")) &&
RNA_property_is_set(op->ptr, prop)) {
if (RNA_property_boolean_get(op->ptr, prop)) {
- options |= CTX_TEXTURE;
+ options |= CTX_TEXTURE_SPACE;
}
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index fff7d47cc5b..24335b6b6b7 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -36,6 +36,11 @@
#include "transform_data.h"
+/* use node center for transform instead of upper-left corner.
+ * disabled since it makes absolute snapping not work so nicely
+ */
+// #define USE_NODE_CENTER
+
/* -------------------------------------------------------------------- */
/** \name Types/
* \{ */
@@ -60,6 +65,134 @@ struct wmKeyMap;
struct wmOperator;
struct wmTimer;
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Enums and Flags
+ * \{ */
+
+/** #TransInfo.options */
+typedef enum {
+ CTX_NONE = 0,
+
+ /* These are similar to TransInfo::data_type. */
+ CTX_CAMERA = (1 << 0),
+ CTX_CURSOR = (1 << 1),
+ CTX_EDGE_DATA = (1 << 2),
+ CTX_GPENCIL_STROKES = (1 << 3),
+ CTX_MASK = (1 << 4),
+ CTX_MOVIECLIP = (1 << 5),
+ CTX_OBJECT = (1 << 6),
+ CTX_PAINT_CURVE = (1 << 7),
+ CTX_POSE_BONE = (1 << 8),
+ CTX_TEXTURE_SPACE = (1 << 9),
+
+ CTX_NO_PET = (1 << 10),
+ CTX_NO_MIRROR = (1 << 11),
+ CTX_AUTOCONFIRM = (1 << 12),
+ /** When transforming object's, adjust the object data so it stays in the same place. */
+ CTX_OBMODE_XFORM_OBDATA = (1 << 13),
+ /** Transform object parents without moving their children. */
+ CTX_OBMODE_XFORM_SKIP_CHILDREN = (1 << 14),
+} eTContext;
+
+/** #TransInfo.flag */
+typedef enum {
+ /** \note We could remove 'T_EDIT' and use 'obedit_type', for now ensure they're in sync. */
+ T_EDIT = 1 << 0,
+ /** Transform points, having no rotation/scale. */
+ T_POINTS = 1 << 1,
+ /** restrictions flags */
+ T_NO_CONSTRAINT = 1 << 2,
+ T_NULL_ONE = 1 << 3,
+ T_NO_ZERO = 1 << 4,
+ T_ALL_RESTRICTIONS = T_NO_CONSTRAINT | T_NULL_ONE | T_NO_ZERO,
+
+ T_PROP_EDIT = 1 << 5,
+ T_PROP_CONNECTED = 1 << 6,
+ T_PROP_PROJECTED = 1 << 7,
+ T_PROP_EDIT_ALL = T_PROP_EDIT | T_PROP_CONNECTED | T_PROP_PROJECTED,
+
+ T_V3D_ALIGN = 1 << 8,
+ /** For 2D views such as UV or f-curve. */
+ T_2D_EDIT = 1 << 9,
+ T_CLIP_UV = 1 << 10,
+
+ /** Auto-IK is on. */
+ T_AUTOIK = 1 << 11,
+
+ /** Don't use mirror even if the data-block option is set. */
+ T_NO_MIRROR = 1 << 12,
+
+ /** To indicate that the value set in the `value` parameter is the final
+ * value of the transformation, modified only by the constrain. */
+ T_INPUT_IS_VALUES_FINAL = 1 << 13,
+
+ /** To specify if we save back settings at the end. */
+ T_MODAL = 1 << 14,
+
+ /** No re-topology (projection). */
+ T_NO_PROJECT = 1 << 15,
+
+ T_RELEASE_CONFIRM = 1 << 16,
+
+ /** Alternative transformation. used to add offset to tracking markers. */
+ T_ALT_TRANSFORM = 1 << 17,
+
+ /** #TransInfo.center has been set, don't change it. */
+ T_OVERRIDE_CENTER = 1 << 18,
+
+ T_MODAL_CURSOR_SET = 1 << 19,
+
+ T_CLNOR_REBUILD = 1 << 20,
+
+ /** Merges unselected into selected after transforming (runs after transforming). */
+ T_AUTOMERGE = 1 << 21,
+ /** Runs auto-merge & splits. */
+ T_AUTOSPLIT = 1 << 22,
+} eTFlag;
+
+/** #TransInfo.modifiers */
+typedef enum {
+ MOD_CONSTRAINT_SELECT = 1 << 0,
+ MOD_PRECISION = 1 << 1,
+ MOD_SNAP = 1 << 2,
+ MOD_SNAP_INVERT = 1 << 3,
+ MOD_CONSTRAINT_PLANE = 1 << 4,
+} eTModifier;
+
+/** #TransSnap.status */
+typedef enum {
+ SNAP_FORCED = 1 << 0,
+ TARGET_INIT = 1 << 1,
+ /* Special flag for snap to grid. */
+ TARGET_GRID_INIT = 1 << 2,
+ POINT_INIT = 1 << 3,
+ MULTI_POINTS = 1 << 4,
+} eTSnap;
+
+/** #TransCon.mode, #TransInfo.con.mode */
+typedef enum {
+ /** When set constraints are in use. */
+ CON_APPLY = 1 << 0,
+ /** These are only used for modal execution. */
+ CON_AXIS0 = 1 << 1,
+ CON_AXIS1 = 1 << 2,
+ CON_AXIS2 = 1 << 3,
+ CON_SELECT = 1 << 4,
+ /** Does not reorient vector to face viewport when on. */
+ CON_NOFLIP = 1 << 5,
+ CON_USER = 1 << 6,
+} eTConstraint;
+
+/** #TransInfo.state */
+typedef enum {
+ TRANS_STARTING = 0,
+ TRANS_RUNNING = 1,
+ TRANS_CONFIRM = 2,
+ TRANS_CANCEL = 3,
+} eTState;
+
/** #TransInfo.redraw */
typedef enum {
TREDRAW_NOTHING = 0,
@@ -67,6 +200,97 @@ typedef enum {
TREDRAW_SOFT = 2,
} eRedrawFlag;
+/** #TransInfo.helpline */
+typedef enum {
+ HLP_NONE = 0,
+ HLP_SPRING = 1,
+ HLP_ANGLE = 2,
+ HLP_HARROW = 3,
+ HLP_VARROW = 4,
+ HLP_CARROW = 5,
+ HLP_TRACKBALL = 6,
+} eTHelpline;
+
+typedef enum {
+ TC_NONE = 0,
+ TC_ACTION_DATA,
+ TC_POSE,
+ TC_ARMATURE_VERTS,
+ TC_CURSOR_IMAGE,
+ TC_CURSOR_VIEW3D,
+ TC_CURVE_VERTS,
+ TC_GRAPH_EDIT_DATA,
+ TC_GPENCIL,
+ TC_LATTICE_VERTS,
+ TC_MASKING_DATA,
+ TC_MBALL_VERTS,
+ TC_MESH_VERTS,
+ TC_MESH_EDGES,
+ TC_MESH_SKIN,
+ TC_MESH_UV,
+ TC_NLA_DATA,
+ TC_NODE_DATA,
+ TC_OBJECT,
+ TC_OBJECT_TEXSPACE,
+ TC_PAINT_CURVE_VERTS,
+ TC_PARTICLE_VERTS,
+ TC_SCULPT,
+ TC_SEQ_DATA,
+ TC_TRACKING_DATA,
+} eTConvertType;
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Keymap Modal Items
+ *
+ * \note these values are saved in key-map files, do not change then but just add new ones.
+ * \{ */
+
+enum {
+ TFM_MODAL_CANCEL = 1,
+ TFM_MODAL_CONFIRM = 2,
+ TFM_MODAL_TRANSLATE = 3,
+ TFM_MODAL_ROTATE = 4,
+ TFM_MODAL_RESIZE = 5,
+ TFM_MODAL_SNAP_INV_ON = 6,
+ TFM_MODAL_SNAP_INV_OFF = 7,
+ TFM_MODAL_SNAP_TOGGLE = 8,
+ TFM_MODAL_AXIS_X = 9,
+ TFM_MODAL_AXIS_Y = 10,
+ TFM_MODAL_AXIS_Z = 11,
+ TFM_MODAL_PLANE_X = 12,
+ TFM_MODAL_PLANE_Y = 13,
+ TFM_MODAL_PLANE_Z = 14,
+ TFM_MODAL_CONS_OFF = 15,
+ TFM_MODAL_ADD_SNAP = 16,
+ TFM_MODAL_REMOVE_SNAP = 17,
+
+ /* 18 and 19 used by number-input, defined in `ED_numinput.h`. */
+ // NUM_MODAL_INCREMENT_UP = 18,
+ // NUM_MODAL_INCREMENT_DOWN = 19,
+
+ TFM_MODAL_PROPSIZE_UP = 20,
+ TFM_MODAL_PROPSIZE_DOWN = 21,
+ TFM_MODAL_AUTOIK_LEN_INC = 22,
+ TFM_MODAL_AUTOIK_LEN_DEC = 23,
+
+ TFM_MODAL_EDGESLIDE_UP = 24,
+ TFM_MODAL_EDGESLIDE_DOWN = 25,
+
+ /** For analog input, like track-pad. */
+ TFM_MODAL_PROPSIZE = 26,
+ /** Node editor insert offset (also called auto-offset) direction toggle. */
+ TFM_MODAL_INSERTOFS_TOGGLE_DIR = 27,
+
+ TFM_MODAL_AUTOCONSTRAINT = 28,
+ TFM_MODAL_AUTOCONSTRAINTPLANE = 29,
+
+ TFM_MODAL_PRECISION = 30,
+};
+
+/** \} */
+
typedef struct TransSnapPoint {
struct TransSnapPoint *next, *prev;
float co[3];
@@ -82,13 +306,14 @@ typedef struct TransSnap {
bool snap_self;
bool peel;
bool use_backface_culling;
- char status;
+ eTSnap status;
/* Snapped Element Type (currently for objects only). */
char snapElem;
/** snapping from this point (in global-space). */
float snapPoint[3];
/** to this point (in global-space). */
float snapTarget[3];
+ float snapTargetGrid[3];
float snapNormal[3];
char snapNodeBorder;
ListBase points;
@@ -120,7 +345,7 @@ typedef struct TransCon {
* the one in #TransInfo is not guarantee to stay the same (Rotates change it). */
int imval[2];
/** Mode flags of the constraint. */
- int mode;
+ eTConstraint mode;
void (*drawExtra)(struct TransInfo *t);
/* Note: if 'tc' is NULL, 'td' must also be NULL.
@@ -266,37 +491,45 @@ typedef struct TransInfo {
TransDataContainer *data_container;
int data_container_len;
- /** #eTransConvertType
- * TODO: It should be a member of #TransDataContainer. */
- int data_type;
-
/** Combine length of all #TransDataContainer.data_len
* Use to check if nothing is selected or if we have a single selection. */
int data_len_all;
- /** Current mode. */
- int mode;
+ /** TODO: It should be a member of #TransDataContainer. */
+ eTConvertType data_type;
+
+ /** Current context/options for transform. */
+ eTContext options;
/** Generic flags for special behaviors. */
- int flag;
+ eTFlag flag;
/** Special modifiers, by function, not key. */
- int modifiers;
+ eTModifier modifiers;
/** Current state (running, canceled. */
- short state;
- /** Current context/options for transform. */
- int options;
+ eTState state;
+ /** Redraw flag. */
+ eRedrawFlag redraw;
+ /** Choice of custom cursor with or without a help line from the gizmo to the mouse position. */
+ eTHelpline helpline;
+ /** Current mode. */
+ eTfmMode mode;
+
+ /** Main transform mode function. */
void (*transform)(struct TransInfo *, const int[2]);
- /** Transform function pointer. */
+ /* Event handler function that determines whether the viewport needs to be redrawn. */
eRedrawFlag (*handleEvent)(struct TransInfo *, const struct wmEvent *);
- /* event handler function pointer RETURN 1 if redraw is needed */
- /** transformed constraint. */
+
+ /** Constraint Data. */
TransCon con;
+
+ /** Snap Data. */
TransSnap tsnap;
- /** numerical input. */
+
+ /** Numerical input. */
NumInput num;
- /** mouse input. */
+
+ /** Mouse input. */
MouseInput mouse;
- /** redraw flag. */
- eRedrawFlag redraw;
+
/** proportional circle radius. */
float prop_size;
/** proportional falloff text. */
@@ -310,9 +543,6 @@ typedef struct TransInfo {
float center_global[3];
/** center in screen coordinates. */
float center2d[2];
- /* Lazy initialize center data for when we need other center values.
- * V3D_AROUND_ACTIVE + 1 (static assert checks this) */
- TransCenterData center_cache[5];
/** maximum index on the input vector. */
short idx_max;
/** Snapping Gears. */
@@ -333,8 +563,6 @@ typedef struct TransInfo {
short around;
/** space-type where transforming is. */
char spacetype;
- /** Choice of custom cursor with or without a help line from the gizmo to the mouse position. */
- char helpline;
/** Avoid looking inside #TransDataContainer.obedit. */
short obedit_type;
@@ -422,178 +650,6 @@ typedef struct TransInfo {
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Flags
- * \{ */
-
-/** #TransInfo.state */
-enum {
- TRANS_STARTING = 0,
- TRANS_RUNNING = 1,
- TRANS_CONFIRM = 2,
- TRANS_CANCEL = 3,
-};
-
-/** #TransInfo.flag */
-enum {
- T_OBJECT = 1 << 0,
- /** \note We could remove 'T_EDIT' and use 'obedit_type', for now ensure they're in sync. */
- T_EDIT = 1 << 1,
- T_POSE = 1 << 2,
- T_TEXTURE = 1 << 3,
- /** Transforming the 3d view. */
- T_CAMERA = 1 << 4,
- /** Transforming the 3D cursor. */
- T_CURSOR = 1 << 5,
- /** Transform points, having no rotation/scale. */
- T_POINTS = 1 << 6,
- /** restrictions flags */
- T_NO_CONSTRAINT = 1 << 7,
- T_NULL_ONE = 1 << 8,
- T_NO_ZERO = 1 << 9,
- T_ALL_RESTRICTIONS = T_NO_CONSTRAINT | T_NULL_ONE | T_NO_ZERO,
-
- T_PROP_EDIT = 1 << 10,
- T_PROP_CONNECTED = 1 << 11,
- T_PROP_PROJECTED = 1 << 12,
- T_PROP_EDIT_ALL = T_PROP_EDIT | T_PROP_CONNECTED | T_PROP_PROJECTED,
-
- T_V3D_ALIGN = 1 << 13,
- /** For 2D views such as UV or f-curve. */
- T_2D_EDIT = 1 << 14,
- T_CLIP_UV = 1 << 15,
-
- /** Auto-IK is on. */
- T_AUTOIK = 1 << 16,
-
- /** Don't use mirror even if the data-block option is set. */
- T_NO_MIRROR = 1 << 17,
-
- /** To indicate that the value set in the `value` parameter is the final
- * value of the transformation, modified only by the constrain. */
- T_INPUT_IS_VALUES_FINAL = 1 << 18,
-
- /** To specify if we save back settings at the end. */
- T_MODAL = 1 << 19,
-
- /** No re-topology (projection). */
- T_NO_PROJECT = 1 << 20,
-
- T_RELEASE_CONFIRM = 1 << 21,
-
- /** Alternative transformation. used to add offset to tracking markers. */
- T_ALT_TRANSFORM = 1 << 22,
-
- /** #TransInfo.center has been set, don't change it. */
- T_OVERRIDE_CENTER = 1 << 23,
-
- T_MODAL_CURSOR_SET = 1 << 24,
-
- T_CLNOR_REBUILD = 1 << 25,
-
- /** Merges unselected into selected after transforming (runs after transforming). */
- T_AUTOMERGE = 1 << 26,
- /** Runs auto-merge & splits. */
- T_AUTOSPLIT = 1 << 27,
-};
-
-/** #TransInfo.modifiers */
-enum {
- MOD_CONSTRAINT_SELECT = 1 << 0,
- MOD_PRECISION = 1 << 1,
- MOD_SNAP = 1 << 2,
- MOD_SNAP_INVERT = 1 << 3,
- MOD_CONSTRAINT_PLANE = 1 << 4,
-};
-
-/* use node center for transform instead of upper-left corner.
- * disabled since it makes absolute snapping not work so nicely
- */
-// #define USE_NODE_CENTER
-
-/** #TransInfo.helpline */
-enum {
- HLP_NONE = 0,
- HLP_SPRING = 1,
- HLP_ANGLE = 2,
- HLP_HARROW = 3,
- HLP_VARROW = 4,
- HLP_CARROW = 5,
- HLP_TRACKBALL = 6,
-};
-
-/** #TransCon.mode, #TransInfo.con.mode */
-enum {
- /** When set constraints are in use. */
- CON_APPLY = 1 << 0,
- /** These are only used for modal execution. */
- CON_AXIS0 = 1 << 1,
- CON_AXIS1 = 1 << 2,
- CON_AXIS2 = 1 << 3,
- CON_SELECT = 1 << 4,
- /** Does not reorient vector to face viewport when on. */
- CON_NOFLIP = 1 << 5,
- CON_USER = 1 << 6,
-};
-
-/** #TransSnap.status */
-enum {
- SNAP_FORCED = 1 << 0,
- TARGET_INIT = 1 << 1,
- POINT_INIT = 1 << 2,
- MULTI_POINTS = 1 << 3,
-};
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Keymap Modal Items
- *
- * \note these values are saved in key-map files, do not change then but just add new ones.
- * \{ */
-
-enum {
- TFM_MODAL_CANCEL = 1,
- TFM_MODAL_CONFIRM = 2,
- TFM_MODAL_TRANSLATE = 3,
- TFM_MODAL_ROTATE = 4,
- TFM_MODAL_RESIZE = 5,
- TFM_MODAL_SNAP_INV_ON = 6,
- TFM_MODAL_SNAP_INV_OFF = 7,
- TFM_MODAL_SNAP_TOGGLE = 8,
- TFM_MODAL_AXIS_X = 9,
- TFM_MODAL_AXIS_Y = 10,
- TFM_MODAL_AXIS_Z = 11,
- TFM_MODAL_PLANE_X = 12,
- TFM_MODAL_PLANE_Y = 13,
- TFM_MODAL_PLANE_Z = 14,
- TFM_MODAL_CONS_OFF = 15,
- TFM_MODAL_ADD_SNAP = 16,
- TFM_MODAL_REMOVE_SNAP = 17,
-
- /* 18 and 19 used by number-input, defined in `ED_numinput.h`. */
- // NUM_MODAL_INCREMENT_UP = 18,
- // NUM_MODAL_INCREMENT_DOWN = 19,
-
- TFM_MODAL_PROPSIZE_UP = 20,
- TFM_MODAL_PROPSIZE_DOWN = 21,
- TFM_MODAL_AUTOIK_LEN_INC = 22,
- TFM_MODAL_AUTOIK_LEN_DEC = 23,
-
- TFM_MODAL_EDGESLIDE_UP = 24,
- TFM_MODAL_EDGESLIDE_DOWN = 25,
-
- /** For analog input, like track-pad. */
- TFM_MODAL_PROPSIZE = 26,
- /** Node editor insert offset (also called auto-offset) direction toggle. */
- TFM_MODAL_INSERTOFS_TOGGLE_DIR = 27,
-
- TFM_MODAL_AUTOCONSTRAINT = 28,
- TFM_MODAL_AUTOCONSTRAINTPLANE = 29,
-};
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Public Transform API
* \{ */
@@ -666,9 +722,6 @@ typedef enum {
void initMouseInput(
TransInfo *t, MouseInput *mi, const float center[2], const int mval[2], const bool precision);
void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode);
-eRedrawFlag handleMouseInput(struct TransInfo *t,
- struct MouseInput *mi,
- const struct wmEvent *event);
void applyMouseInput(struct TransInfo *t,
struct MouseInput *mi,
const int mval[2],
@@ -684,10 +737,6 @@ void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *t, float val
/** \name Generics
* \{ */
-void initTransDataContainers_FromObjectData(TransInfo *t,
- struct Object *obact,
- struct Object **objects,
- uint objects_len);
void initTransInfo(struct bContext *C,
TransInfo *t,
struct wmOperator *op,
@@ -709,7 +758,6 @@ void recalcData(TransInfo *t);
void calculateCenter2D(TransInfo *t);
void calculateCenterLocal(TransInfo *t, const float center_global[3]);
-const TransCenterData *transformCenter_from_type(TransInfo *t, int around);
void calculateCenter(TransInfo *t);
/* API functions for getting center points */
@@ -724,6 +772,8 @@ void calculatePropRatio(TransInfo *t);
void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot);
+struct Object *transform_object_deform_pose_armature_get(const TransInfo *t, struct Object *ob);
+
void freeCustomNormalArray(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data);
/* TODO. transform_query.c */
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 2ac7e41a7c9..1f589a830fc 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -58,6 +58,10 @@
static void drawObjectConstraint(TransInfo *t);
+/* -------------------------------------------------------------------- */
+/** \name Internal Utilities
+ * \{ */
+
static void projection_matrix_calc(const TransInfo *t, float r_pmtx[3][3])
{
unit_m3(r_pmtx);
@@ -380,14 +384,13 @@ static void planeProjection(const TransInfo *t, const float in[3], float out[3])
add_v3_v3v3(out, in, vec);
}
-/*
+/**
* Generic callback for constant spatial constraints applied to linear motion
*
- * The IN vector in projected into the constrained space and then further
+ * The `in` vector in projected into the constrained space and then further
* projected along the view vector.
* (in perspective mode, the view vector is relative to the position on screen)
*/
-
static void applyAxisConstraintVec(
TransInfo *t, TransDataContainer *UNUSED(tc), TransData *td, const float in[3], float out[3])
{
@@ -459,17 +462,16 @@ static void applyAxisConstraintVec(
}
}
-/*
+/**
* Generic callback for object based spatial constraints applied to linear motion
*
* At first, the following is applied without orientation
* The IN vector in projected into the constrained space and then further
* projected along the view vector.
- * (in perspective mode, the view vector is relative to the position on screen)
+ * (in perspective mode, the view vector is relative to the position on screen).
*
* 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])
{
@@ -489,10 +491,9 @@ static void applyObjectConstraintVec(
}
}
-/*
- * Generic callback for constant spatial constraints applied to resize motion
+/**
+ * Generic callback for constant spatial constraints applied to resize motion.
*/
-
static void applyAxisConstraintSize(TransInfo *t,
TransDataContainer *UNUSED(tc),
TransData *td,
@@ -516,10 +517,9 @@ static void applyAxisConstraintSize(TransInfo *t,
}
}
-/*
- * Callback for object based spatial constraints applied to resize motion
+/**
+ * Callback for object based spatial constraints applied to resize motion.
*/
-
static void applyObjectConstraintSize(TransInfo *t,
TransDataContainer *tc,
TransData *td,
@@ -549,10 +549,10 @@ static void applyObjectConstraintSize(TransInfo *t,
}
}
-static void constraints_rotation_imp(TransInfo *t,
- float axismtx[3][3],
- float r_vec[3],
- float *r_angle)
+static void constraints_rotation_impl(TransInfo *t,
+ float axismtx[3][3],
+ float r_vec[3],
+ float *r_angle)
{
BLI_assert(t->con.mode & CON_APPLY);
int mode = t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2);
@@ -581,15 +581,15 @@ static void constraints_rotation_imp(TransInfo *t,
}
}
-/*
+/**
* Generic callback for constant spatial constraints applied to rotations
*
- * The rotation axis is copied into VEC.
+ * The rotation axis is copied into `vec`.
*
* In the case of single axis constraints, the rotation axis is directly the one constrained to.
* For planar constraints (2 axis), the rotation axis is the normal of the plane.
*
- * The following only applies when CON_NOFLIP is not set.
+ * The following only applies when #CON_NOFLIP is not set.
* The vector is then modified to always point away from the screen (in global space)
* This insures that the rotation is always logically following the mouse.
* (ie: not doing counterclockwise rotations when the mouse moves clockwise).
@@ -598,19 +598,19 @@ static void applyAxisConstraintRot(
TransInfo *t, TransDataContainer *UNUSED(tc), TransData *td, float vec[3], float *angle)
{
if (!td && t->con.mode & CON_APPLY) {
- constraints_rotation_imp(t, t->spacemtx, vec, angle);
+ constraints_rotation_impl(t, t->spacemtx, vec, angle);
}
}
-/*
+/**
* Callback for object based spatial constraints applied to rotations
*
- * The rotation axis is copied into VEC.
+ * The rotation axis is copied into `vec`.
*
* In the case of single axis constraints, the rotation axis is directly the one constrained to.
* For planar constraints (2 axis), the rotation axis is the normal of the plane.
*
- * The following only applies when CON_NOFLIP is not set.
+ * The following only applies when #CON_NOFLIP is not set.
* The vector is then modified to always point away from the screen (in global space)
* This insures that the rotation is always logically following the mouse.
* (ie: not doing counterclockwise rotations when the mouse moves clockwise).
@@ -637,11 +637,15 @@ static void applyObjectConstraintRot(
axismtx = td->axismtx;
}
- constraints_rotation_imp(t, axismtx, vec, angle);
+ constraints_rotation_impl(t, axismtx, vec, angle);
}
}
-/*--------------------- INTERNAL SETUP CALLS ------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal Setup Calls
+ * \{ */
void setConstraint(TransInfo *t, int mode, const char text[])
{
@@ -676,7 +680,7 @@ void setAxisMatrixConstraint(TransInfo *t, int mode, const char text[])
void setLocalConstraint(TransInfo *t, int mode, const char text[])
{
- if (t->flag & T_EDIT) {
+ if ((t->flag & T_EDIT) || t->data_len_all == 1) {
/* Although in edit-mode each object has its local space, use the
* orientation of the active object. */
setConstraint(t, mode, text);
@@ -686,10 +690,10 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[])
}
}
-/*
+/**
* Set the constraint according to the user defined orientation
*
- * ftext is a format string passed to BLI_snprintf. It will add the name of
+ * `ftext` is a format string passed to #BLI_snprintf. It will add the name of
* the orientation where %s is (logically).
*/
void setUserConstraint(TransInfo *t, int mode, const char ftext[])
@@ -704,40 +708,35 @@ void setUserConstraint(TransInfo *t, int mode, const char ftext[])
const char *spacename = transform_orientations_spacename_get(t, orientation);
BLI_snprintf(text, sizeof(text), ftext, spacename);
- if (t->modifiers & (MOD_CONSTRAINT_SELECT | MOD_CONSTRAINT_PLANE)) {
- /* Force the orientation of the active object.
- * Although possible, it is not convenient to use the local or axis constraint
- * with the modifier to select constraint.
- * This also follows the convention of older versions. */
- setConstraint(t, mode, text);
- }
- else {
- switch (orientation) {
- case V3D_ORIENT_LOCAL:
- setLocalConstraint(t, mode, text);
- break;
- case V3D_ORIENT_NORMAL:
- if (checkUseAxisMatrix(t)) {
- setAxisMatrixConstraint(t, mode, text);
- break;
- }
- ATTR_FALLTHROUGH;
- case V3D_ORIENT_GLOBAL:
- case V3D_ORIENT_VIEW:
- case V3D_ORIENT_CURSOR:
- case V3D_ORIENT_GIMBAL:
- case V3D_ORIENT_CUSTOM_MATRIX:
- case V3D_ORIENT_CUSTOM:
- default: {
- setConstraint(t, mode, text);
+ switch (orientation) {
+ case V3D_ORIENT_LOCAL:
+ setLocalConstraint(t, mode, text);
+ break;
+ case V3D_ORIENT_NORMAL:
+ if (checkUseAxisMatrix(t)) {
+ setAxisMatrixConstraint(t, mode, text);
break;
}
+ ATTR_FALLTHROUGH;
+ case V3D_ORIENT_GLOBAL:
+ case V3D_ORIENT_VIEW:
+ case V3D_ORIENT_CURSOR:
+ case V3D_ORIENT_GIMBAL:
+ case V3D_ORIENT_CUSTOM_MATRIX:
+ case V3D_ORIENT_CUSTOM:
+ default: {
+ setConstraint(t, mode, text);
+ break;
}
}
t->con.mode |= CON_USER;
}
-/*----------------- DRAWING CONSTRAINTS -------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Drawing Constraints
+ * \{ */
void drawConstraint(TransInfo *t)
{
@@ -915,7 +914,7 @@ static void drawObjectConstraint(TransInfo *t)
mul_m3_m3m3(tmp_axismtx, tc->mat3_unit, td->axismtx);
axismtx = tmp_axismtx;
}
- else if (t->flag & T_POSE) {
+ else if (t->options & CTX_POSE_BONE) {
mul_v3_m4v3(co, tc->mat, td->center);
axismtx = td->axismtx;
}
@@ -938,7 +937,11 @@ static void drawObjectConstraint(TransInfo *t)
}
}
-/*--------------------- START / STOP CONSTRAINTS ---------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Start / Stop Constraints
+ * \{ */
void startConstraint(TransInfo *t)
{
@@ -959,7 +962,11 @@ void stopConstraint(TransInfo *t)
t->num.idx_max = t->idx_max;
}
-/*------------------------- MMB Select -------------------------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Middle Mouse Button Select
+ * \{ */
void initSelectConstraint(TransInfo *t)
{
@@ -1106,7 +1113,11 @@ void setNearestAxis(TransInfo *t)
projection_matrix_calc(t, t->con.pmtx);
}
-/*-------------- HELPER FUNCTIONS ----------------*/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Helper Functions
+ * \{ */
int constraintModeToIndex(const TransInfo *t)
{
@@ -1147,14 +1158,13 @@ bool isLockConstraint(TransInfo *t)
return false;
}
-/*
+/**
* Returns the dimension of the constraint space.
*
* For that reason, the flags always needs to be set to properly evaluate here,
- * 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.)
+ * 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 n = 0;
@@ -1172,11 +1182,12 @@ int getConstraintSpaceDimension(TransInfo *t)
}
return n;
- /*
- * Someone willing to do it cryptically could do the following instead:
+ /* Someone willing to do it cryptically could do the following instead:
*
- * return t->con & (CON_AXIS0|CON_AXIS1|CON_AXIS2);
+ * `return t->con & (CON_AXIS0|CON_AXIS1|CON_AXIS2);`
*
* Based on the assumptions that the axis flags are one after the other and start at 1
*/
}
+
+/** \} */
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index 3ea0b0a0a70..6b2e9dd9840 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -23,6 +23,7 @@
#include "DNA_anim_types.h"
#include "DNA_constraint_types.h"
+#include "DNA_mesh_types.h"
#include "MEM_guardedalloc.h"
@@ -892,7 +893,6 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
special_aftertrans_update__node(C, t);
break;
case TC_OBJECT:
- case TC_OBJECT_TEXSPACE:
special_aftertrans_update__object(C, t);
break;
case TC_SCULPT:
@@ -912,6 +912,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
case TC_LATTICE_VERTS:
case TC_MBALL_VERTS:
case TC_MESH_UV:
+ case TC_MESH_SKIN:
+ case TC_OBJECT_TEXSPACE:
case TC_PAINT_CURVE_VERTS:
case TC_PARTICLE_VERTS:
case TC_NONE:
@@ -928,10 +930,10 @@ int special_transform_moving(TransInfo *t)
if (t->spacetype == SPACE_GRAPH) {
return G_TRANSFORM_FCURVES;
}
- if ((t->flag & T_EDIT) || (t->flag & T_POSE)) {
+ if ((t->flag & T_EDIT) || (t->options & CTX_POSE_BONE)) {
return G_TRANSFORM_EDIT;
}
- if (t->flag & (T_OBJECT | T_TEXTURE)) {
+ if (t->options & (CTX_OBJECT | CTX_TEXTURE_SPACE)) {
return G_TRANSFORM_OBJ;
}
@@ -973,53 +975,254 @@ static int countAndCleanTransDataContainer(TransInfo *t)
return t->data_len_all;
}
-void createTransData(bContext *C, TransInfo *t)
+static void init_proportional_edit(TransInfo *t)
{
- Scene *scene = t->scene;
- ViewLayer *view_layer = t->view_layer;
- Object *ob = OBACT(view_layer);
+ eTConvertType convert_type = t->data_type;
+ switch (convert_type) {
+ case TC_ACTION_DATA:
+ case TC_CURVE_VERTS:
+ case TC_GRAPH_EDIT_DATA:
+ case TC_GPENCIL:
+ case TC_LATTICE_VERTS:
+ case TC_MASKING_DATA:
+ case TC_MBALL_VERTS:
+ case TC_MESH_VERTS:
+ case TC_MESH_EDGES:
+ case TC_MESH_SKIN:
+ case TC_MESH_UV:
+ case TC_NODE_DATA:
+ case TC_OBJECT:
+ case TC_PARTICLE_VERTS:
+ break;
+ case TC_POSE: /* Disable PET, its not usable in pose mode yet T32444. */
+ case TC_ARMATURE_VERTS:
+ case TC_CURSOR_IMAGE:
+ case TC_CURSOR_VIEW3D:
+ case TC_NLA_DATA:
+ case TC_OBJECT_TEXSPACE:
+ case TC_PAINT_CURVE_VERTS:
+ case TC_SCULPT:
+ case TC_SEQ_DATA:
+ case TC_TRACKING_DATA:
+ case TC_NONE:
+ default:
+ t->options |= CTX_NO_PET;
+ t->flag &= ~T_PROP_EDIT_ALL;
+ return;
+ }
- t->data_len_all = -1;
+ if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
+ if (convert_type == TC_OBJECT) {
+ /* Selected objects are already first, no need to presort. */
+ }
+ else {
+ sort_trans_data_selected_first(t);
+ }
- eTransConvertType convert_type = TC_NONE;
+ if (ELEM(convert_type, TC_ACTION_DATA, TC_GRAPH_EDIT_DATA)) {
+ /* Distance has already been set. */
+ }
+ else if (ELEM(convert_type, TC_MESH_VERTS, TC_MESH_SKIN)) {
+ if (t->flag & T_PROP_CONNECTED) {
+ /* Already calculated by transform_convert_mesh_connectivity_distance. */
+ }
+ else {
+ set_prop_dist(t, false);
+ }
+ }
+ else if (convert_type == TC_MESH_UV && t->flag & T_PROP_CONNECTED) {
+ /* Already calculated by uv_set_connectivity_distance. */
+ }
+ else if (convert_type == TC_CURVE_VERTS && t->obedit_type == OB_CURVE) {
+ set_prop_dist(t, false);
+ }
+ else {
+ set_prop_dist(t, true);
+ }
+
+ sort_trans_data_dist(t);
+ }
+ else if (ELEM(t->obedit_type, OB_CURVE)) {
+ /* Needed because bezier handles can be partially selected
+ * and are still added into transform data. */
+ sort_trans_data_selected_first(t);
+ }
+}
+
+/* For multi object editing. */
+static void init_TransDataContainers(TransInfo *t,
+ Object *obact,
+ Object **objects,
+ uint objects_len)
+{
+ switch (t->data_type) {
+ case TC_POSE:
+ case TC_ARMATURE_VERTS:
+ case TC_CURVE_VERTS:
+ case TC_GPENCIL:
+ case TC_LATTICE_VERTS:
+ case TC_MBALL_VERTS:
+ case TC_MESH_VERTS:
+ case TC_MESH_EDGES:
+ case TC_MESH_SKIN:
+ case TC_MESH_UV:
+ break;
+ case TC_ACTION_DATA:
+ case TC_GRAPH_EDIT_DATA:
+ case TC_CURSOR_IMAGE:
+ case TC_CURSOR_VIEW3D:
+ case TC_MASKING_DATA:
+ case TC_NLA_DATA:
+ case TC_NODE_DATA:
+ case TC_OBJECT:
+ case TC_OBJECT_TEXSPACE:
+ case TC_PAINT_CURVE_VERTS:
+ case TC_PARTICLE_VERTS:
+ case TC_SCULPT:
+ case TC_SEQ_DATA:
+ case TC_TRACKING_DATA:
+ case TC_NONE:
+ default:
+ /* Does not support Multi object editing. */
+ return;
+ }
+
+ const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
+ const short object_type = obact ? obact->type : -1;
+
+ if ((object_mode & OB_MODE_EDIT) || (t->data_type == TC_GPENCIL) ||
+ ((object_mode & OB_MODE_POSE) && (object_type == OB_ARMATURE))) {
+ if (t->data_container) {
+ MEM_freeN(t->data_container);
+ }
+
+ bool free_objects = false;
+ if (objects == NULL) {
+ objects = BKE_view_layer_array_from_objects_in_mode(
+ t->view_layer,
+ (t->spacetype == SPACE_VIEW3D) ? t->view : NULL,
+ &objects_len,
+ {
+ .object_mode = object_mode,
+ .no_dup_data = true,
+ });
+ free_objects = true;
+ }
+
+ t->data_container = MEM_callocN(sizeof(*t->data_container) * objects_len, __func__);
+ t->data_container_len = objects_len;
+
+ for (int i = 0; i < objects_len; i++) {
+ TransDataContainer *tc = &t->data_container[i];
+ if (((t->flag & T_NO_MIRROR) == 0) && ((t->options & CTX_NO_MIRROR) == 0) &&
+ (objects[i]->type == OB_MESH)) {
+ tc->use_mirror_axis_x = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_X) != 0;
+ tc->use_mirror_axis_y = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_Y) != 0;
+ tc->use_mirror_axis_z = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_Z) != 0;
+ }
+
+ if (object_mode & OB_MODE_EDIT) {
+ tc->obedit = objects[i];
+ /* Check needed for UV's */
+ if ((t->flag & T_2D_EDIT) == 0) {
+ tc->use_local_mat = true;
+ }
+ }
+ else if (object_mode & OB_MODE_POSE) {
+ tc->poseobj = objects[i];
+ tc->use_local_mat = true;
+ }
+ else if (t->data_type == TC_GPENCIL) {
+ tc->use_local_mat = true;
+ }
+
+ if (tc->use_local_mat) {
+ BLI_assert((t->flag & T_2D_EDIT) == 0);
+ copy_m4_m4(tc->mat, objects[i]->obmat);
+ copy_m3_m4(tc->mat3, tc->mat);
+ /* for non-invertible scale matrices, invert_m4_m4_fallback()
+ * can still provide a valid pivot */
+ invert_m4_m4_fallback(tc->imat, tc->mat);
+ invert_m3_m3(tc->imat3, tc->mat3);
+ normalize_m3_m3(tc->mat3_unit, tc->mat3);
+ }
+ /* Otherwise leave as zero. */
+ }
+
+ if (free_objects) {
+ MEM_freeN(objects);
+ }
+ }
+}
+
+static eTFlag flags_from_data_type(eTConvertType data_type)
+{
+ switch (data_type) {
+ case TC_ACTION_DATA:
+ case TC_GRAPH_EDIT_DATA:
+ case TC_MASKING_DATA:
+ case TC_NLA_DATA:
+ case TC_NODE_DATA:
+ case TC_PAINT_CURVE_VERTS:
+ case TC_SEQ_DATA:
+ case TC_TRACKING_DATA:
+ return T_POINTS | T_2D_EDIT;
+ case TC_ARMATURE_VERTS:
+ case TC_CURVE_VERTS:
+ case TC_GPENCIL:
+ case TC_LATTICE_VERTS:
+ case TC_MBALL_VERTS:
+ case TC_MESH_VERTS:
+ case TC_MESH_SKIN:
+ return T_EDIT | T_POINTS;
+ case TC_MESH_EDGES:
+ return T_EDIT;
+ case TC_MESH_UV:
+ return T_EDIT | T_POINTS | T_2D_EDIT;
+ case TC_PARTICLE_VERTS:
+ return T_POINTS;
+ case TC_POSE:
+ case TC_CURSOR_IMAGE:
+ case TC_CURSOR_VIEW3D:
+ case TC_OBJECT:
+ case TC_OBJECT_TEXSPACE:
+ case TC_SCULPT:
+ case TC_NONE:
+ default:
+ break;
+ }
+ return 0;
+}
+
+static eTConvertType convert_type_get(const TransInfo *t, Object **r_obj_armature)
+{
+ ViewLayer *view_layer = t->view_layer;
+ Object *ob = OBACT(view_layer);
+ eTConvertType convert_type = TC_NONE;
/* if tests must match recalcData for correct updates */
if (t->options & CTX_CURSOR) {
- t->flag |= T_CURSOR;
-
if (t->spacetype == SPACE_IMAGE) {
convert_type = TC_CURSOR_IMAGE;
}
else {
convert_type = TC_CURSOR_VIEW3D;
}
-
- /* Since we're transforming the cursor, initialize this value before it's modified.
- * Needed for #snap_grid_apply to access the cursor location. */
- transformCenter_from_type(t, V3D_AROUND_CURSOR);
}
else if (!(t->options & CTX_PAINT_CURVE) && (t->spacetype == SPACE_VIEW3D) && ob &&
(ob->mode == OB_MODE_SCULPT) && ob->sculpt) {
convert_type = TC_SCULPT;
}
- else if (t->options & CTX_TEXTURE) {
- t->flag |= T_TEXTURE;
+ else if (t->options & CTX_TEXTURE_SPACE) {
convert_type = TC_OBJECT_TEXSPACE;
}
- else if (t->options & CTX_EDGE) {
- t->flag |= T_EDIT;
+ else if (t->options & CTX_EDGE_DATA) {
convert_type = TC_MESH_EDGES;
- /* Multi object editing. */
- initTransDataContainers_FromObjectData(t, ob, NULL, 0);
}
else if (t->options & CTX_GPENCIL_STROKES) {
- t->options |= CTX_GPENCIL_STROKES;
- t->flag |= T_POINTS | T_EDIT;
convert_type = TC_GPENCIL;
- initTransDataContainers_FromObjectData(t, ob, NULL, 0);
}
else if (t->spacetype == SPACE_IMAGE) {
- t->flag |= T_POINTS | T_2D_EDIT;
if (t->options & CTX_MASK) {
convert_type = TC_MASKING_DATA;
}
@@ -1029,41 +1232,25 @@ void createTransData(bContext *C, TransInfo *t)
}
}
else if (t->obedit_type == OB_MESH) {
- t->flag |= T_EDIT;
convert_type = TC_MESH_UV;
- initTransDataContainers_FromObjectData(t, ob, NULL, 0);
}
}
else if (t->spacetype == SPACE_ACTION) {
- t->flag |= T_POINTS | T_2D_EDIT;
- t->obedit_type = -1;
convert_type = TC_ACTION_DATA;
}
else if (t->spacetype == SPACE_NLA) {
- t->flag |= T_POINTS | T_2D_EDIT;
- t->obedit_type = -1;
convert_type = TC_NLA_DATA;
}
else if (t->spacetype == SPACE_SEQ) {
- t->flag |= T_POINTS | T_2D_EDIT;
- t->obedit_type = -1;
- t->num.flag |= NUM_NO_FRACTION; /* sequencer has no use for floating point trasnform */
convert_type = TC_SEQ_DATA;
}
else if (t->spacetype == SPACE_GRAPH) {
- t->flag |= T_POINTS | T_2D_EDIT;
- t->obedit_type = -1;
convert_type = TC_GRAPH_EDIT_DATA;
}
else if (t->spacetype == SPACE_NODE) {
- t->flag |= T_POINTS | T_2D_EDIT;
- t->obedit_type = -1;
convert_type = TC_NODE_DATA;
}
else if (t->spacetype == SPACE_CLIP) {
- t->flag |= T_POINTS | T_2D_EDIT;
- t->obedit_type = -1;
-
if (t->options & CTX_MOVIECLIP) {
convert_type = TC_TRACKING_DATA;
}
@@ -1072,11 +1259,6 @@ void createTransData(bContext *C, TransInfo *t)
}
}
else if (t->obedit_type != -1) {
- t->flag |= T_EDIT | T_POINTS;
-
- /* Multi object editing. */
- initTransDataContainers_FromObjectData(t, ob, NULL, 0);
-
if (t->obedit_type == OB_MESH) {
if (t->mode == TFM_SKIN_RESIZE) {
convert_type = TC_MESH_SKIN;
@@ -1095,46 +1277,25 @@ void createTransData(bContext *C, TransInfo *t)
convert_type = TC_MBALL_VERTS;
}
else if (t->obedit_type == OB_ARMATURE) {
- t->flag &= ~T_PROP_EDIT;
convert_type = TC_ARMATURE_VERTS;
}
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
- /* XXX this is currently limited to active armature only... */
-
- /* XXX active-layer checking isn't done
- * as that should probably be checked through context instead. */
-
- /* Multi object editing. */
- initTransDataContainers_FromObjectData(t, ob, NULL, 0);
convert_type = TC_POSE;
}
else if (ob && (ob->mode & OB_MODE_ALL_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) {
- /* Important that ob_armature can be set even when its not selected T23412.
- * Lines below just check is also visible. */
- Object *ob_armature = BKE_modifiers_is_deformed_by_armature(ob);
- if (ob_armature && ob_armature->mode & OB_MODE_POSE) {
- Base *base_arm = BKE_view_layer_base_find(t->view_layer, ob_armature);
- if (base_arm) {
- View3D *v3d = t->view;
- if (BASE_VISIBLE(v3d, base_arm)) {
- Object *objects[1];
- objects[0] = ob_armature;
- uint objects_len = 1;
- initTransDataContainers_FromObjectData(t, ob_armature, objects, objects_len);
- convert_type = TC_POSE;
- }
- }
+ Object *ob_armature = transform_object_deform_pose_armature_get(t, ob);
+ if (ob_armature) {
+ *r_obj_armature = ob_armature;
+ convert_type = TC_POSE;
}
}
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) &&
- PE_start_edit(PE_get_current(t->depsgraph, scene, ob))) {
- t->flag |= T_POINTS;
+ PE_start_edit(PE_get_current(t->depsgraph, t->scene, ob))) {
convert_type = TC_PARTICLE_VERTS;
}
else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
if ((t->options & CTX_PAINT_CURVE) && !ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) {
- t->flag |= T_POINTS | T_2D_EDIT;
convert_type = TC_PAINT_CURVE_VERTS;
}
}
@@ -1146,47 +1307,55 @@ void createTransData(bContext *C, TransInfo *t)
/* In grease pencil all transformations must be canceled if not Object or Edit. */
}
else {
- /* Needed for correct Object.obmat after duplication, see: T62135. */
- BKE_scene_graph_evaluated_ensure(t->depsgraph, CTX_data_main(t->context));
-
- if ((scene->toolsettings->transform_flag & SCE_XFORM_DATA_ORIGIN) != 0) {
- t->options |= CTX_OBMODE_XFORM_OBDATA;
- }
- if ((scene->toolsettings->transform_flag & SCE_XFORM_SKIP_CHILDREN) != 0) {
- t->options |= CTX_OBMODE_XFORM_SKIP_CHILDREN;
- }
-
- t->flag |= T_OBJECT;
convert_type = TC_OBJECT;
}
- t->data_type = convert_type;
- bool init_prop_edit = (t->flag & T_PROP_EDIT) != 0;
+ return convert_type;
+}
+
+void createTransData(bContext *C, TransInfo *t)
+{
+ t->data_len_all = -1;
+
+ Object *ob_armature = NULL;
+ t->data_type = convert_type_get(t, &ob_armature);
+ t->flag |= flags_from_data_type(t->data_type);
- switch (convert_type) {
+ if (ob_armature) {
+ init_TransDataContainers(t, ob_armature, &ob_armature, 1);
+ }
+ else {
+ ViewLayer *view_layer = t->view_layer;
+ Object *ob = OBACT(view_layer);
+ init_TransDataContainers(t, ob, NULL, 0);
+ }
+
+ switch (t->data_type) {
case TC_ACTION_DATA:
+ t->obedit_type = -1;
createTransActionData(C, t);
break;
case TC_POSE:
+ t->options |= CTX_POSE_BONE;
+
+ /* XXX active-layer checking isn't done
+ * as that should probably be checked through context instead. */
createTransPose(t);
- /* Disable PET, its not usable in pose mode yet T32444. */
- init_prop_edit = false;
break;
case TC_ARMATURE_VERTS:
createTransArmatureVerts(t);
break;
case TC_CURSOR_IMAGE:
createTransCursor_image(t);
- init_prop_edit = false;
break;
case TC_CURSOR_VIEW3D:
createTransCursor_view3d(t);
- init_prop_edit = false;
break;
case TC_CURVE_VERTS:
createTransCurveVerts(t);
break;
case TC_GRAPH_EDIT_DATA:
+ t->obedit_type = -1;
createTransGraphEditData(C, t);
break;
case TC_GPENCIL:
@@ -1196,6 +1365,9 @@ void createTransData(bContext *C, TransInfo *t)
createTransLatticeVerts(t);
break;
case TC_MASKING_DATA:
+ if (t->spacetype == SPACE_CLIP) {
+ t->obedit_type = -1;
+ }
createTransMaskingData(C, t);
break;
case TC_MBALL_VERTS:
@@ -1214,13 +1386,25 @@ void createTransData(bContext *C, TransInfo *t)
createTransUVs(C, t);
break;
case TC_NLA_DATA:
+ t->obedit_type = -1;
createTransNlaData(C, t);
- init_prop_edit = false;
break;
case TC_NODE_DATA:
+ t->obedit_type = -1;
createTransNodeData(t);
break;
case TC_OBJECT:
+ t->options |= CTX_OBJECT;
+
+ /* Needed for correct Object.obmat after duplication, see: T62135. */
+ BKE_scene_graph_evaluated_ensure(t->depsgraph, CTX_data_main(t->context));
+
+ if ((t->settings->transform_flag & SCE_XFORM_DATA_ORIGIN) != 0) {
+ t->options |= CTX_OBMODE_XFORM_OBDATA;
+ }
+ if ((t->settings->transform_flag & SCE_XFORM_SKIP_CHILDREN) != 0) {
+ t->options |= CTX_OBMODE_XFORM_SKIP_CHILDREN;
+ }
createTransObject(C, t);
/* Check if we're transforming the camera from the camera */
if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
@@ -1229,36 +1413,34 @@ void createTransData(bContext *C, TransInfo *t)
if ((rv3d->persp == RV3D_CAMOB) && v3d->camera) {
/* we could have a flag to easily check an object is being transformed */
if (v3d->camera->id.tag & LIB_TAG_DOIT) {
- t->flag |= T_CAMERA;
+ t->options |= CTX_CAMERA;
}
}
else if (v3d->ob_center && v3d->ob_center->id.tag & LIB_TAG_DOIT) {
- t->flag |= T_CAMERA;
+ t->options |= CTX_CAMERA;
}
}
break;
case TC_OBJECT_TEXSPACE:
createTransTexspace(t);
- init_prop_edit = false;
break;
case TC_PAINT_CURVE_VERTS:
createTransPaintCurveVerts(C, t);
- init_prop_edit = false;
break;
case TC_PARTICLE_VERTS:
createTransParticleVerts(t);
break;
case TC_SCULPT:
createTransSculpt(C, t);
- init_prop_edit = false;
break;
case TC_SEQ_DATA:
+ t->obedit_type = -1;
+ t->num.flag |= NUM_NO_FRACTION; /* sequencer has no use for floating point transform. */
createTransSeqData(t);
- init_prop_edit = false;
break;
case TC_TRACKING_DATA:
+ t->obedit_type = -1;
createTransTrackingData(C, t);
- init_prop_edit = false;
break;
case TC_NONE:
default:
@@ -1270,48 +1452,7 @@ void createTransData(bContext *C, TransInfo *t)
countAndCleanTransDataContainer(t);
- if (t->data_len_all && init_prop_edit) {
- if (convert_type == TC_OBJECT) {
- /* Selected objects are already first, no need to presort. */
- }
- else {
- sort_trans_data_selected_first(t);
- }
-
- if (ELEM(convert_type, TC_ACTION_DATA, TC_GRAPH_EDIT_DATA)) {
- /* Distance has already been set. */
- }
- else if (ELEM(convert_type, TC_MESH_VERTS, TC_MESH_SKIN)) {
- if (t->flag & T_PROP_CONNECTED) {
- /* Already calculated by transform_convert_mesh_connectivity_distance. */
- }
- else {
- set_prop_dist(t, false);
- }
- }
- else if (convert_type == TC_MESH_UV && t->flag & T_PROP_CONNECTED) {
- /* Already calculated by uv_set_connectivity_distance. */
- }
- else if (convert_type == TC_CURVE_VERTS && t->obedit_type == OB_CURVE) {
- set_prop_dist(t, false);
- }
- else {
- set_prop_dist(t, true);
- }
-
- sort_trans_data_dist(t);
- }
- else {
- if (ELEM(t->obedit_type, OB_CURVE)) {
- /* Needed because bezier handles can be partially selected
- * and are still added into transform data. */
- sort_trans_data_selected_first(t);
- }
-
- if (!init_prop_edit) {
- t->flag &= ~T_PROP_EDIT_ALL;
- }
- }
+ init_proportional_edit(t);
BLI_assert((!(t->flag & T_EDIT)) == (!(t->obedit_type != -1)));
}
@@ -1557,9 +1698,11 @@ void recalcData(TransInfo *t)
flushTransNodes(t);
break;
case TC_OBJECT:
- case TC_OBJECT_TEXSPACE:
recalcData_objects(t);
break;
+ case TC_OBJECT_TEXSPACE:
+ recalcData_texspace(t);
+ break;
case TC_PAINT_CURVE_VERTS:
flushTransPaintCurve(t);
break;
diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h
index 466bfd6b226..bd7569b3771 100644
--- a/source/blender/editors/transform/transform_convert.h
+++ b/source/blender/editors/transform/transform_convert.h
@@ -49,37 +49,9 @@ void 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);
/********************* intern **********************/
-typedef enum eTransConvertType {
- TC_NONE = 0,
- TC_ACTION_DATA,
- TC_POSE,
- TC_ARMATURE_VERTS,
- TC_CURSOR_IMAGE,
- TC_CURSOR_VIEW3D,
- TC_CURVE_VERTS,
- TC_GRAPH_EDIT_DATA,
- TC_GPENCIL,
- TC_LATTICE_VERTS,
- TC_MASKING_DATA,
- TC_MBALL_VERTS,
- TC_MESH_VERTS,
- TC_MESH_EDGES,
- TC_MESH_SKIN,
- TC_MESH_UV,
- TC_NLA_DATA,
- TC_NODE_DATA,
- TC_OBJECT,
- TC_OBJECT_TEXSPACE,
- TC_PAINT_CURVE_VERTS,
- TC_PARTICLE_VERTS,
- TC_SCULPT,
- TC_SEQ_DATA,
- TC_TRACKING_DATA,
-} eTransConvertType;
-
/* transform_convert.c */
bool transform_mode_use_local_origins(const TransInfo *t);
void transform_around_single_fallback_ex(TransInfo *t, int data_len_all);
@@ -215,10 +187,13 @@ void special_aftertrans_update__node(bContext *C, TransInfo *t);
/* transform_convert_object.c */
void createTransObject(bContext *C, TransInfo *t);
-void createTransTexspace(TransInfo *t);
void recalcData_objects(TransInfo *t);
void special_aftertrans_update__object(bContext *C, TransInfo *t);
+/* transform_convert_object_texspace.c */
+void createTransTexspace(TransInfo *t);
+void recalcData_texspace(TransInfo *t);
+
/* transform_convert_paintcurve.c */
void createTransPaintCurveVerts(bContext *C, TransInfo *t);
void flushTransPaintCurve(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c
index e9b2273b343..71b9e11b51f 100644
--- a/source/blender/editors/transform/transform_convert_armature.c
+++ b/source/blender/editors/transform/transform_convert_armature.c
@@ -444,7 +444,7 @@ static short pose_grab_with_ik(Main *bmain, Object *ob)
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone->layer & arm->layer) {
if (pchan->bone->flag & (BONE_SELECTED | BONE_TRANSFORM_MIRROR)) {
- /* Rule: no IK for solitatry (unconnected) bones */
+ /* Rule: no IK for solitary (unconnected) bones. */
for (bonec = pchan->bone->childbase.first; bonec; bonec = bonec->next) {
if (bonec->flag & BONE_CONNECTED) {
break;
@@ -870,8 +870,6 @@ void createTransPose(TransInfo *t)
t->mode = TFM_RESIZE;
}
}
-
- t->flag |= T_POSE;
}
void createTransArmatureVerts(TransInfo *t)
@@ -1354,7 +1352,7 @@ static void pose_transform_mirror_update(TransInfo *t, TransDataContainer *tc, O
}
mul_v3_m4v3(data->grabtarget, flip_mtx, td->loc);
if (pid) {
- /* TODO(germano): Realitve Mirror support */
+ /* TODO(germano): Relative Mirror support. */
}
data->flag |= CONSTRAINT_IK_AUTO;
/* Add a temporary auto IK constraint here, as we will only temporarily active this
diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c
index 445253d5446..3c01c716123 100644
--- a/source/blender/editors/transform/transform_convert_curve.c
+++ b/source/blender/editors/transform/transform_convert_curve.c
@@ -298,7 +298,7 @@ void createTransCurveVerts(TransInfo *t)
}
if ((bezt_tx & SEL_F1) == 0 && (bezt_tx & SEL_F3) == 0) {
- /* If the middle is selected but the sides arnt, this is needed */
+ /* If the middle is selected but the sides aren't, this is needed. */
if (hdata == NULL) {
/* if the handle was not saved by the previous handle */
hdata = initTransDataCurveHandles(td, bezt);
diff --git a/source/blender/editors/transform/transform_convert_gpencil.c b/source/blender/editors/transform/transform_convert_gpencil.c
index deb18b50a22..eaa8962326a 100644
--- a/source/blender/editors/transform/transform_convert_gpencil.c
+++ b/source/blender/editors/transform/transform_convert_gpencil.c
@@ -135,7 +135,7 @@ static void createTransGPencil_curves(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* Check if stroke has an editcurve */
@@ -242,7 +242,7 @@ static void createTransGPencil_curves(bContext *C,
}
/* Calculate difference matrix. */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
copy_m3_m4(mtx, diff_mat);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
@@ -263,7 +263,7 @@ static void createTransGPencil_curves(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* Check if stroke has an editcurve */
@@ -436,7 +436,7 @@ static void createTransGPencil_strokes(bContext *C,
continue;
}
/* Check if the color is editable. */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
@@ -507,7 +507,7 @@ static void createTransGPencil_strokes(bContext *C,
}
/* Calculate difference matrix. */
- BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
/* Undo matrix. */
invert_m4_m4(inverse_diff_mat, diff_mat);
@@ -551,7 +551,7 @@ static void createTransGPencil_strokes(bContext *C,
continue;
}
/* check if the color is editable */
- if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
continue;
}
/* What we need to include depends on proportional editing settings... */
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index b3bd6b31879..ce74c5f5a36 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -251,29 +251,55 @@ void transform_convert_mesh_islanddata_free(struct TransIslandData *island_data)
*
* \{ */
-static bool bmesh_test_dist_add(BMVert *v,
- BMVert *v_other,
+/* Propagate distance from v1 and v2 to v0. */
+static bool bmesh_test_dist_add(BMVert *v0,
+ BMVert *v1,
+ BMVert *v2,
float *dists,
- const float *dists_prev,
/* optionally track original index */
int *index,
- const int *index_prev,
const float mtx[3][3])
{
- if ((BM_elem_flag_test(v_other, BM_ELEM_SELECT) == 0) &&
- (BM_elem_flag_test(v_other, BM_ELEM_HIDDEN) == 0)) {
- const int i = BM_elem_index_get(v);
- const int i_other = BM_elem_index_get(v_other);
- float vec[3];
- float dist_other;
- sub_v3_v3v3(vec, v->co, v_other->co);
- mul_m3_v3(mtx, vec);
-
- dist_other = dists_prev[i] + len_v3(vec);
- if (dist_other < dists[i_other]) {
- dists[i_other] = dist_other;
+ if ((BM_elem_flag_test(v0, BM_ELEM_SELECT) == 0) &&
+ (BM_elem_flag_test(v0, BM_ELEM_HIDDEN) == 0)) {
+ const int i0 = BM_elem_index_get(v0);
+ const int i1 = BM_elem_index_get(v1);
+
+ BLI_assert(dists[i1] != FLT_MAX);
+ if (dists[i0] <= dists[i1]) {
+ return false;
+ }
+
+ float dist0;
+
+ if (v2) {
+ /* Distance across triangle. */
+ const int i2 = BM_elem_index_get(v2);
+ BLI_assert(dists[i2] != FLT_MAX);
+ if (dists[i0] <= dists[i2]) {
+ return false;
+ }
+
+ float vm0[3], vm1[3], vm2[3];
+ mul_v3_m3v3(vm0, mtx, v0->co);
+ mul_v3_m3v3(vm1, mtx, v1->co);
+ mul_v3_m3v3(vm2, mtx, v2->co);
+
+ dist0 = geodesic_distance_propagate_across_triangle(vm0, vm1, vm2, dists[i1], dists[i2]);
+ }
+ else {
+ /* Distance along edge. */
+ float vec[3];
+ sub_v3_v3v3(vec, v1->co, v0->co);
+ mul_m3_v3(mtx, vec);
+
+ dist0 = dists[i1] + len_v3(vec);
+ }
+
+ if (dist0 < dists[i0]) {
+ dists[i0] = dist0;
if (index != NULL) {
- index[i_other] = index_prev[i];
+ index[i0] = index[i1];
}
return true;
}
@@ -292,15 +318,16 @@ void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
float *dists,
int *index)
{
- BLI_LINKSTACK_DECLARE(queue, BMVert *);
+ BLI_LINKSTACK_DECLARE(queue, BMEdge *);
- /* any BM_ELEM_TAG'd vertex is in 'queue_next', so we don't add in twice */
- BLI_LINKSTACK_DECLARE(queue_next, BMVert *);
+ /* any BM_ELEM_TAG'd edge is in 'queue_next', so we don't add in twice */
+ BLI_LINKSTACK_DECLARE(queue_next, BMEdge *);
BLI_LINKSTACK_INIT(queue);
BLI_LINKSTACK_INIT(queue_next);
{
+ /* Set indexes and initial distances for selected vertices. */
BMIter viter;
BMVert *v;
int i;
@@ -308,7 +335,6 @@ void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
float dist;
BM_elem_index_set(v, i); /* set_inline */
- BM_elem_flag_disable(v, BM_ELEM_TAG);
if (BM_elem_flag_test(v, BM_ELEM_SELECT) == 0 || BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
dist = FLT_MAX;
@@ -317,7 +343,6 @@ void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
}
}
else {
- BLI_LINKSTACK_PUSH(queue, v);
dist = 0.0f;
if (index != NULL) {
index[i] = i;
@@ -329,103 +354,99 @@ void transform_convert_mesh_connectivity_distance(struct BMesh *bm,
bm->elem_index_dirty &= ~BM_VERT;
}
- /* need to be very careful of feedback loops here, store previous dist's to avoid feedback */
- float *dists_prev = MEM_dupallocN(dists);
- int *index_prev = MEM_dupallocN(index); /* may be NULL */
+ {
+ /* Add edges with at least one selected vertex to the queue. */
+ BMIter eiter;
+ BMEdge *e;
+
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ BMVert *v1 = e->v1;
+ BMVert *v2 = e->v2;
+ int i1 = BM_elem_index_get(v1);
+ int i2 = BM_elem_index_get(v2);
+
+ if (dists[i1] != FLT_MAX || dists[i2] != FLT_MAX) {
+ BLI_LINKSTACK_PUSH(queue, e);
+ }
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
+ }
+ }
do {
- BMVert *v;
- LinkNode *lnk;
-
- /* this is correct but slow to do each iteration,
- * instead sync the dist's while clearing BM_ELEM_TAG (below) */
-#if 0
- memcpy(dists_prev, dists, sizeof(float) * bm->totvert);
-#endif
-
- while ((v = BLI_LINKSTACK_POP(queue))) {
- BLI_assert(dists[BM_elem_index_get(v)] != FLT_MAX);
-
- /* connected edge-verts */
- if (v->e != NULL) {
- BMEdge *e_iter, *e_first;
-
- e_iter = e_first = v->e;
-
- /* would normally use BM_EDGES_OF_VERT, but this runs so often,
- * its faster to iterate on the data directly */
- do {
-
- if (BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == 0) {
+ BMEdge *e;
+
+ while ((e = BLI_LINKSTACK_POP(queue))) {
+ BMVert *v1 = e->v1;
+ BMVert *v2 = e->v2;
+ int i1 = BM_elem_index_get(v1);
+ int i2 = BM_elem_index_get(v2);
+
+ if (e->l == NULL || (dists[i1] == FLT_MAX || dists[i2] == FLT_MAX)) {
+ /* Propagate along edge from vertex with smallest to largest distance. */
+ if (dists[i1] > dists[i2]) {
+ SWAP(int, i1, i2);
+ SWAP(BMVert *, v1, v2);
+ }
- /* edge distance */
- {
- BMVert *v_other = BM_edge_other_vert(e_iter, v);
- if (bmesh_test_dist_add(v, v_other, dists, dists_prev, index, index_prev, mtx)) {
- if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
- BM_elem_flag_enable(v_other, BM_ELEM_TAG);
- BLI_LINKSTACK_PUSH(queue_next, v_other);
- }
- }
+ if (bmesh_test_dist_add(v2, v1, NULL, dists, index, mtx)) {
+ /* Add adjacent loose edges to the queue, or all edges if this is a loose edge.
+ * Other edges are handled by propagation across edges below. */
+ BMEdge *e_other;
+ BMIter eiter;
+ BM_ITER_ELEM (e_other, &eiter, v2, BM_EDGES_OF_VERT) {
+ if (e_other != e && BM_elem_flag_test(e_other, BM_ELEM_TAG) == 0 &&
+ (e->l == NULL || e_other->l == NULL)) {
+ BM_elem_flag_enable(e_other, BM_ELEM_TAG);
+ BLI_LINKSTACK_PUSH(queue_next, e_other);
}
+ }
+ }
+ }
- /* face distance */
- if (e_iter->l) {
- BMLoop *l_iter_radial, *l_first_radial;
- /**
- * imaginary edge diagonally across quad.
- * \note This takes advantage of the rules of winding that we
- * know 2 or more of a verts edges wont reference the same face twice.
- * Also, if the edge is hidden, the face will be hidden too.
- */
- l_iter_radial = l_first_radial = e_iter->l;
-
- do {
- if ((l_iter_radial->v == v) && (l_iter_radial->f->len == 4) &&
- (BM_elem_flag_test(l_iter_radial->f, BM_ELEM_HIDDEN) == 0)) {
- BMVert *v_other = l_iter_radial->next->next->v;
- if (bmesh_test_dist_add(v, v_other, dists, dists_prev, index, index_prev, mtx)) {
- if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
- BM_elem_flag_enable(v_other, BM_ELEM_TAG);
- BLI_LINKSTACK_PUSH(queue_next, v_other);
- }
- }
+ if (e->l != NULL) {
+ /* Propagate across edge to vertices in adjacent faces. */
+ BMLoop *l;
+ BMIter liter;
+ BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
+ for (BMLoop *l_other = l->next->next; l_other != l; l_other = l_other->next) {
+ BMVert *v_other = l_other->v;
+ BLI_assert(!ELEM(v_other, v1, v2));
+
+ if (bmesh_test_dist_add(v_other, v1, v2, dists, index, mtx)) {
+ /* Add adjacent edges to the queue, if they are ready to propagate across/along.
+ * Always propagate along loose edges, and for other edges only propagate across
+ * if both vertices have a known distances. */
+ BMEdge *e_other;
+ BMIter eiter;
+ BM_ITER_ELEM (e_other, &eiter, v_other, BM_EDGES_OF_VERT) {
+ if (e_other != e && BM_elem_flag_test(e_other, BM_ELEM_TAG) == 0 &&
+ (e_other->l == NULL ||
+ dists[BM_elem_index_get(BM_edge_other_vert(e_other, v_other))] != FLT_MAX)) {
+ BM_elem_flag_enable(e_other, BM_ELEM_TAG);
+ BLI_LINKSTACK_PUSH(queue_next, e_other);
}
- } while ((l_iter_radial = l_iter_radial->radial_next) != l_first_radial);
+ }
}
}
- } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first);
+ }
}
}
- /* clear for the next loop */
- for (lnk = queue_next; lnk; lnk = lnk->next) {
- BMVert *v_link = lnk->link;
- const int i = BM_elem_index_get(v_link);
+ /* Clear for the next loop. */
+ for (LinkNode *lnk = queue_next; lnk; lnk = lnk->next) {
+ BMEdge *e_link = lnk->link;
- BM_elem_flag_disable(v_link, BM_ELEM_TAG);
-
- /* keep in sync, avoid having to do full memcpy each iteration */
- dists_prev[i] = dists[i];
- if (index != NULL) {
- index_prev[i] = index[i];
- }
+ BM_elem_flag_disable(e_link, BM_ELEM_TAG);
}
BLI_LINKSTACK_SWAP(queue, queue_next);
- /* none should be tagged now since 'queue_next' is empty */
- BLI_assert(BM_iter_mesh_count_flag(BM_VERTS_OF_MESH, bm, BM_ELEM_TAG, true) == 0);
-
+ /* None should be tagged now since 'queue_next' is empty. */
+ BLI_assert(BM_iter_mesh_count_flag(BM_EDGES_OF_MESH, bm, BM_ELEM_TAG, true) == 0);
} while (BLI_LINKSTACK_SIZE(queue));
BLI_LINKSTACK_FREE(queue);
BLI_LINKSTACK_FREE(queue_next);
-
- MEM_freeN(dists_prev);
- if (index_prev != NULL) {
- MEM_freeN(index_prev);
- }
}
/** \} */
@@ -1445,7 +1466,7 @@ static void mesh_customdatacorrect_apply_vert(struct TransCustomDataLayer *tcld,
*
* Interpolate from every other loop (not ideal)
* However values will only be taken from loops which overlap other mdisps.
- * */
+ */
const bool update_loop_mdisps = is_moved && do_loop_mdisps && (tcld->cd_loop_mdisp_offset != -1);
if (update_loop_mdisps) {
float(*faces_center)[3] = BLI_array_alloca(faces_center, l_num);
diff --git a/source/blender/editors/transform/transform_convert_mesh_skin.c b/source/blender/editors/transform/transform_convert_mesh_skin.c
index 1807e9adcd1..b1024f5efe4 100644
--- a/source/blender/editors/transform/transform_convert_mesh_skin.c
+++ b/source/blender/editors/transform/transform_convert_mesh_skin.c
@@ -55,9 +55,7 @@ static float *mesh_skin_transdata_center(const struct TransIslandData *island_da
if (island_data->center && island_index != -1) {
return island_data->center[island_index];
}
- else {
- return eve->co;
- }
+ return eve->co;
}
static void mesh_skin_transdata_create(TransDataBasic *td,
diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c
index adc2d03e2dc..5eb3f68787a 100644
--- a/source/blender/editors/transform/transform_convert_nla.c
+++ b/source/blender/editors/transform/transform_convert_nla.c
@@ -304,7 +304,7 @@ void recalcData_nla(TransInfo *t)
for (i = 0; i < tc->data_len; i++, tdn++) {
NlaStrip *strip = tdn->strip;
PointerRNA strip_ptr;
- short pExceeded, nExceeded, iter;
+ short iter;
int delta_y1, delta_y2;
/* if this tdn has no handles, that means it is just a dummy that should be skipped */
@@ -358,21 +358,31 @@ void recalcData_nla(TransInfo *t)
*
* this is done as a iterative procedure (done 5 times max for now)
*/
+ NlaStrip *prev = strip->prev;
+ while (prev != NULL && (prev->type & NLASTRIP_TYPE_TRANSITION)) {
+ prev = prev->prev;
+ }
+
+ NlaStrip *next = strip->next;
+ while (next != NULL && (next->type & NLASTRIP_TYPE_TRANSITION)) {
+ next = next->next;
+ }
+
for (iter = 0; iter < 5; iter++) {
- pExceeded = ((strip->prev) && (strip->prev->type != NLASTRIP_TYPE_TRANSITION) &&
- (tdn->h1[0] < strip->prev->end));
- nExceeded = ((strip->next) && (strip->next->type != NLASTRIP_TYPE_TRANSITION) &&
- (tdn->h2[0] > strip->next->start));
+
+ const bool pExceeded = (prev != NULL) && (tdn->h1[0] < prev->end);
+ const bool nExceeded = (next != NULL) && (tdn->h2[0] > next->start);
if ((pExceeded && nExceeded) || (iter == 4)) {
- /* both endpoints exceeded (or iteration ping-pong'd meaning that we need a compromise)
+ /* both endpoints exceeded (or iteration ping-pong'd meaning that we need a
+ * compromise)
* - Simply crop strip to fit within the bounds of the strips bounding it
* - If there were no neighbors, clear the transforms
* (make it default to the strip's current values).
*/
- if (strip->prev && strip->next) {
- tdn->h1[0] = strip->prev->end;
- tdn->h2[0] = strip->next->start;
+ if (prev && next) {
+ tdn->h1[0] = prev->end;
+ tdn->h2[0] = next->start;
}
else {
tdn->h1[0] = strip->start;
@@ -381,14 +391,14 @@ void recalcData_nla(TransInfo *t)
}
else if (nExceeded) {
/* move backwards */
- float offset = tdn->h2[0] - strip->next->start;
+ float offset = tdn->h2[0] - next->start;
tdn->h1[0] -= offset;
tdn->h2[0] -= offset;
}
else if (pExceeded) {
/* more forwards */
- float offset = strip->prev->end - tdn->h1[0];
+ float offset = prev->end - tdn->h1[0];
tdn->h1[0] += offset;
tdn->h2[0] += offset;
@@ -564,7 +574,7 @@ void special_aftertrans_update__nla(bContext *C, TransInfo *UNUSED(t))
/* free temp memory */
ANIM_animdata_freelist(&anim_data);
- /* perform after-transfrom validation */
+ /* Perform after-transform validation. */
ED_nla_postop_refresh(&ac);
}
}
diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c
index 90ffccfdd7b..5f6f00716f9 100644
--- a/source/blender/editors/transform/transform_convert_object.c
+++ b/source/blender/editors/transform/transform_convert_object.c
@@ -21,12 +21,8 @@
* \ingroup edtransform
*/
-#include "DNA_mesh_types.h"
-
#include "MEM_guardedalloc.h"
-#include "BLI_compiler_compat.h"
-#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
@@ -46,11 +42,11 @@
#include "DEG_depsgraph_query.h"
#include "transform.h"
+#include "transform_orientations.h"
#include "transform_snap.h"
/* Own include. */
#include "transform_convert.h"
-#include "transform_orientations.h"
/* -------------------------------------------------------------------- */
/** \name Object Mode Custom Data
@@ -713,66 +709,6 @@ void createTransObject(bContext *C, TransInfo *t)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Texture Space Transform Creation
- *
- * Instead of transforming the selection, move the 2D/3D cursor.
- *
- * \{ */
-
-void createTransTexspace(TransInfo *t)
-{
- ViewLayer *view_layer = t->view_layer;
- TransData *td;
- Object *ob;
- ID *id;
- short *texflag;
-
- ob = OBACT(view_layer);
-
- if (ob == NULL) { /* Shouldn't logically happen, but still. */
- return;
- }
-
- id = ob->data;
- if (id == NULL || !ELEM(GS(id->name), ID_ME, ID_CU, ID_MB)) {
- BKE_report(t->reports, RPT_ERROR, "Unsupported object type for text-space transform");
- return;
- }
-
- if (BKE_object_obdata_is_libdata(ob)) {
- BKE_report(t->reports, RPT_ERROR, "Linked data can't text-space transform");
- return;
- }
-
- {
- BLI_assert(t->data_container_len == 1);
- TransDataContainer *tc = t->data_container;
- tc->data_len = 1;
- td = tc->data = MEM_callocN(sizeof(TransData), "TransTexspace");
- td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
- }
-
- td->flag = TD_SELECTED;
- copy_v3_v3(td->center, ob->obmat[3]);
- td->ob = ob;
-
- copy_m3_m4(td->mtx, ob->obmat);
- copy_m3_m4(td->axismtx, ob->obmat);
- normalize_m3(td->axismtx);
- pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
-
- if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size)) {
- ob->dtx |= OB_TEXSPACE;
- *texflag &= ~ME_AUTOSPACE;
- }
-
- copy_v3_v3(td->iloc, td->loc);
- copy_v3_v3(td->ext->isize, td->ext->size);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Transform (Auto-Keyframing)
* \{ */
@@ -962,10 +898,6 @@ void recalcData_objects(TransInfo *t)
* otherwise proxies don't function correctly
*/
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
-
- if (t->flag & T_TEXTURE) {
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- }
}
}
@@ -991,7 +923,7 @@ void recalcData_objects(TransInfo *t)
void special_aftertrans_update__object(bContext *C, TransInfo *t)
{
- BLI_assert(t->flag & (T_OBJECT | T_TEXTURE));
+ BLI_assert(t->options & CTX_OBJECT);
Object *ob;
const bool canceled = (t->state == TRANS_CANCEL);
diff --git a/source/blender/editors/transform/transform_convert_object_texspace.c b/source/blender/editors/transform/transform_convert_object_texspace.c
new file mode 100644
index 00000000000..195eb941b3b
--- /dev/null
+++ b/source/blender/editors/transform/transform_convert_object_texspace.c
@@ -0,0 +1,126 @@
+/*
+ * 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 "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+
+#include "BKE_animsys.h"
+#include "BKE_context.h"
+#include "BKE_object.h"
+#include "BKE_report.h"
+
+#include "DNA_mesh_types.h"
+
+#include "transform.h"
+#include "transform_snap.h"
+
+/* Own include. */
+#include "transform_convert.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Texture Space Transform Creation
+ *
+ * Instead of transforming the selection, move the 2D/3D cursor.
+ *
+ * \{ */
+
+void createTransTexspace(TransInfo *t)
+{
+ ViewLayer *view_layer = t->view_layer;
+ TransData *td;
+ Object *ob;
+ ID *id;
+ short *texflag;
+
+ ob = OBACT(view_layer);
+
+ if (ob == NULL) { /* Shouldn't logically happen, but still. */
+ return;
+ }
+
+ id = ob->data;
+ if (id == NULL || !ELEM(GS(id->name), ID_ME, ID_CU, ID_MB)) {
+ BKE_report(t->reports, RPT_ERROR, "Unsupported object type for text-space transform");
+ return;
+ }
+
+ if (BKE_object_obdata_is_libdata(ob)) {
+ BKE_report(t->reports, RPT_ERROR, "Linked data can't text-space transform");
+ return;
+ }
+
+ {
+ BLI_assert(t->data_container_len == 1);
+ TransDataContainer *tc = t->data_container;
+ tc->data_len = 1;
+ td = tc->data = MEM_callocN(sizeof(TransData), "TransTexspace");
+ td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
+ }
+
+ td->flag = TD_SELECTED;
+ copy_v3_v3(td->center, ob->obmat[3]);
+ td->ob = ob;
+
+ copy_m3_m4(td->mtx, ob->obmat);
+ copy_m3_m4(td->axismtx, ob->obmat);
+ normalize_m3(td->axismtx);
+ pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
+
+ if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size)) {
+ ob->dtx |= OB_TEXSPACE;
+ *texflag &= ~ME_AUTOSPACE;
+ }
+
+ copy_v3_v3(td->iloc, td->loc);
+ copy_v3_v3(td->ext->isize, td->ext->size);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Recalc Data object
+ *
+ * \{ */
+
+/* helper for recalcData() - for object transforms, typically in the 3D view */
+void recalcData_texspace(TransInfo *t)
+{
+
+ if (t->state != TRANS_CANCEL) {
+ applyProject(t);
+ }
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ TransData *td = tc->data;
+
+ for (int i = 0; i < tc->data_len; i++, td++) {
+ if (td->flag & TD_SKIP) {
+ continue;
+ }
+ DEG_id_tag_update(&td->ob->id, ID_RECALC_GEOMETRY);
+ }
+ }
+}
+
+/** \} */
diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c
index ebb0b6823a3..22b1f9fd8d7 100644
--- a/source/blender/editors/transform/transform_convert_sequencer.c
+++ b/source/blender/editors/transform/transform_convert_sequencer.c
@@ -25,6 +25,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BKE_context.h"
@@ -64,6 +65,8 @@ typedef struct TransSeq {
int min;
int max;
bool snap_left;
+ int selection_channel_range_min;
+ int selection_channel_range_max;
} TransSeq;
/* -------------------------------------------------------------------- */
@@ -623,6 +626,14 @@ void createTransSeqData(TransInfo *t)
}
}
+ ts->selection_channel_range_min = MAXSEQ + 1;
+ LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
+ if ((seq->flag & SELECT) != 0) {
+ ts->selection_channel_range_min = min_ii(ts->selection_channel_range_min, seq->machine);
+ ts->selection_channel_range_max = max_ii(ts->selection_channel_range_max, seq->machine);
+ }
+ }
+
#undef XXX_DURIAN_ANIM_TX_HACK
}
@@ -834,7 +845,7 @@ void special_aftertrans_update__sequencer(bContext *UNUSED(C), TransInfo *t)
/* Marker transform, not especially nice but we may want to move markers
* at the same time as strips in the Video Sequencer. */
if (sseq->flag & SEQ_MARKER_TRANS) {
- /* cant use TFM_TIME_EXTEND
+ /* can't use TFM_TIME_EXTEND
* for some reason EXTEND is changed into TRANSLATE, so use frame_side instead */
if (t->mode == TFM_SEQ_SLIDE) {
@@ -850,6 +861,21 @@ void special_aftertrans_update__sequencer(bContext *UNUSED(C), TransInfo *t)
}
}
+void transform_convert_sequencer_channel_clamp(TransInfo *t)
+{
+ 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 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;
+ }
+ if (min_channel_after_transform < 1) {
+ t->values[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;
diff --git a/source/blender/editors/transform/transform_convert_tracking.c b/source/blender/editors/transform/transform_convert_tracking.c
index c3f48adca68..5f5f06e388f 100644
--- a/source/blender/editors/transform/transform_convert_tracking.c
+++ b/source/blender/editors/transform/transform_convert_tracking.c
@@ -52,6 +52,7 @@ typedef struct TransDataTracking {
float (*smarkers)[2];
int markersnr;
+ int framenr;
MovieTrackingMarker *markers;
/* marker transformation from curves editor */
@@ -73,9 +74,25 @@ enum transDataTracking_Mode {
*
* \{ */
-static void markerToTransDataInit(TransData *td,
- TransData2D *td2d,
- TransDataTracking *tdt,
+typedef struct TransformInitContext {
+ SpaceClip *space_clip;
+
+ TransInfo *t;
+ TransDataContainer *tc;
+
+ /* NOTE: These pointers will be `nullptr` during counting step.
+ * This means, that the transformation data initialization functions are to increment
+ * `tc->data_len` instead of filling in the transformation data when these pointers are
+ * `nullptr`. For simplicity, check the `current.td` against `nullptr`.
+ * Do not `tc->data_len` when filling in the transformation data. */
+ struct {
+ TransData *td;
+ TransData2D *td2d;
+ TransDataTracking *tdt;
+ } current;
+} TransformInitContext;
+
+static void markerToTransDataInit(TransformInitContext *init_context,
MovieTrackingTrack *track,
MovieTrackingMarker *marker,
int area,
@@ -84,8 +101,19 @@ static void markerToTransDataInit(TransData *td,
const float off[2],
const float aspect[2])
{
+ TransData *td = init_context->current.td;
+ TransData2D *td2d = init_context->current.td2d;
+ TransDataTracking *tdt = init_context->current.tdt;
+
+ if (td == NULL) {
+ init_context->tc->data_len++;
+ return;
+ }
+
int anchor = area == TRACK_AREA_POINT && off;
+ tdt->flag = marker->flag;
+ tdt->framenr = marker->framenr;
tdt->mode = transDataTracking_ModeTracks;
if (anchor) {
@@ -143,23 +171,20 @@ static void markerToTransDataInit(TransData *td,
unit_m3(td->mtx);
unit_m3(td->smtx);
+
+ init_context->current.td++;
+ init_context->current.td2d++;
+ init_context->current.tdt++;
}
-static void trackToTransData(const int framenr,
- TransData *td,
- TransData2D *td2d,
- TransDataTracking *tdt,
+static void trackToTransData(TransformInitContext *init_context,
+ const int framenr,
MovieTrackingTrack *track,
const float aspect[2])
{
MovieTrackingMarker *marker = BKE_tracking_marker_ensure(track, framenr);
- tdt->flag = marker->flag;
- marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
-
- markerToTransDataInit(td++,
- td2d++,
- tdt++,
+ markerToTransDataInit(init_context,
track,
marker,
TRACK_AREA_POINT,
@@ -170,16 +195,14 @@ static void trackToTransData(const int framenr,
if (track->flag & SELECT) {
markerToTransDataInit(
- td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT, marker->pos, NULL, NULL, aspect);
+ init_context, track, marker, TRACK_AREA_POINT, marker->pos, NULL, NULL, aspect);
}
if (track->pat_flag & SELECT) {
int a;
for (a = 0; a < 4; a++) {
- markerToTransDataInit(td++,
- td2d++,
- tdt++,
+ markerToTransDataInit(init_context,
track,
marker,
TRACK_AREA_PAT,
@@ -191,9 +214,7 @@ static void trackToTransData(const int framenr,
}
if (track->search_flag & SELECT) {
- markerToTransDataInit(td++,
- td2d++,
- tdt++,
+ markerToTransDataInit(init_context,
track,
marker,
TRACK_AREA_SEARCH,
@@ -202,9 +223,7 @@ static void trackToTransData(const int framenr,
NULL,
aspect);
- markerToTransDataInit(td++,
- td2d++,
- tdt++,
+ markerToTransDataInit(init_context,
track,
marker,
TRACK_AREA_SEARCH,
@@ -213,15 +232,43 @@ static void trackToTransData(const int framenr,
NULL,
aspect);
}
+
+ if (init_context->current.td != NULL) {
+ marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
+ }
}
-static void planeMarkerToTransDataInit(TransData *td,
- TransData2D *td2d,
- TransDataTracking *tdt,
+static void trackToTransDataIfNeeded(TransformInitContext *init_context,
+ const int framenr,
+ MovieTrackingTrack *track,
+ const float aspect[2])
+{
+ if (!TRACK_VIEW_SELECTED(init_context->space_clip, track)) {
+ return;
+ }
+ if (track->flag & TRACK_LOCKED) {
+ return;
+ }
+ trackToTransData(init_context, framenr, track, aspect);
+}
+
+static void planeMarkerToTransDataInit(TransformInitContext *init_context,
MovieTrackingPlaneTrack *plane_track,
+ MovieTrackingPlaneMarker *plane_marker,
float corner[2],
const float aspect[2])
{
+ TransData *td = init_context->current.td;
+ TransData2D *td2d = init_context->current.td2d;
+ TransDataTracking *tdt = init_context->current.tdt;
+
+ if (td == NULL) {
+ init_context->tc->data_len++;
+ return;
+ }
+
+ tdt->flag = plane_marker->flag;
+ tdt->framenr = plane_marker->framenr;
tdt->mode = transDataTracking_ModePlaneTracks;
tdt->plane_track = plane_track;
@@ -247,24 +294,38 @@ static void planeMarkerToTransDataInit(TransData *td,
unit_m3(td->mtx);
unit_m3(td->smtx);
+
+ init_context->current.td++;
+ init_context->current.td2d++;
+ init_context->current.tdt++;
}
-static void planeTrackToTransData(const int framenr,
- TransData *td,
- TransData2D *td2d,
- TransDataTracking *tdt,
+static void planeTrackToTransData(TransformInitContext *init_context,
+ const int framenr,
MovieTrackingPlaneTrack *plane_track,
const float aspect[2])
{
MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr);
- int i;
- tdt->flag = plane_marker->flag;
- plane_marker->flag &= ~PLANE_MARKER_TRACKED;
+ for (int i = 0; i < 4; i++) {
+ planeMarkerToTransDataInit(
+ init_context, plane_track, plane_marker, plane_marker->corners[i], aspect);
+ }
- for (i = 0; i < 4; i++) {
- planeMarkerToTransDataInit(td++, td2d++, tdt++, plane_track, plane_marker->corners[i], aspect);
+ if (init_context->current.td != NULL) {
+ plane_marker->flag &= ~PLANE_MARKER_TRACKED;
+ }
+}
+
+static void planeTrackToTransDataIfNeeded(TransformInitContext *init_context,
+ const int framenr,
+ MovieTrackingPlaneTrack *plane_track,
+ const float aspect[2])
+{
+ if (!PLANE_TRACK_VIEW_SELECTED(plane_track)) {
+ return;
}
+ planeTrackToTransData(init_context, framenr, plane_track, aspect);
}
static void transDataTrackingFree(TransInfo *UNUSED(t),
@@ -284,101 +345,53 @@ static void transDataTrackingFree(TransInfo *UNUSED(t),
static void createTransTrackingTracksData(bContext *C, TransInfo *t)
{
- TransData *td;
- TransData2D *td2d;
- SpaceClip *sc = CTX_wm_space_clip(C);
- MovieClip *clip = ED_space_clip_get_clip(sc);
- ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
- ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking);
- MovieTrackingTrack *track;
- MovieTrackingPlaneTrack *plane_track;
- TransDataTracking *tdt;
- int framenr = ED_space_clip_get_clip_frame_number(sc);
+ SpaceClip *space_clip = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip_get_clip(space_clip);
+ const ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
+ const ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking);
+ const int framenr = ED_space_clip_get_clip_frame_number(space_clip);
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
- /* count */
- tc->data_len = 0;
-
- track = tracksbase->first;
- while (track) {
- if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
- tc->data_len++; /* offset */
+ TransformInitContext init_context = {NULL};
+ init_context.space_clip = space_clip;
+ init_context.t = t;
+ init_context.tc = tc;
- if (track->flag & SELECT) {
- tc->data_len++;
- }
+ /* Count required transformation data. */
- if (track->pat_flag & SELECT) {
- tc->data_len += 4;
- }
-
- if (track->search_flag & SELECT) {
- tc->data_len += 2;
- }
- }
+ tc->data_len = 0;
- track = track->next;
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
+ trackToTransDataIfNeeded(&init_context, framenr, track, t->aspect);
}
- for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) {
- if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
- tc->data_len += 4;
- }
+ LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) {
+ planeTrackToTransDataIfNeeded(&init_context, framenr, plane_track, t->aspect);
}
if (tc->data_len == 0) {
return;
}
- td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransTracking TransData");
- td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D),
- "TransTracking TransData2D");
- tdt = tc->custom.type.data = MEM_callocN(tc->data_len * sizeof(TransDataTracking),
- "TransTracking TransDataTracking");
-
+ tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransTracking TransData");
+ tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransTracking TransData2D");
+ tc->custom.type.data = MEM_callocN(tc->data_len * sizeof(TransDataTracking),
+ "TransTracking TransDataTracking");
tc->custom.type.free_cb = transDataTrackingFree;
- /* create actual data */
- track = tracksbase->first;
- while (track) {
- if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
- trackToTransData(framenr, td, td2d, tdt, track, t->aspect);
-
- /* offset */
- td++;
- td2d++;
- tdt++;
+ init_context.current.td = tc->data;
+ init_context.current.td2d = tc->data_2d;
+ init_context.current.tdt = tc->custom.type.data;
- if (track->flag & SELECT) {
- td++;
- td2d++;
- tdt++;
- }
-
- if (track->pat_flag & SELECT) {
- td += 4;
- td2d += 4;
- tdt += 4;
- }
+ /* Create actual transformation data. */
- if (track->search_flag & SELECT) {
- td += 2;
- td2d += 2;
- tdt += 2;
- }
- }
-
- track = track->next;
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
+ trackToTransDataIfNeeded(&init_context, framenr, track, t->aspect);
}
- for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) {
- if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
- planeTrackToTransData(framenr, td, td2d, tdt, plane_track, t->aspect);
- td += 4;
- td2d += 4;
- tdt += 4;
- }
+ LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) {
+ planeTrackToTransDataIfNeeded(&init_context, framenr, plane_track, t->aspect);
}
}
@@ -560,17 +573,17 @@ void createTransTrackingData(bContext *C, TransInfo *t)
static void cancelTransTracking(TransInfo *t)
{
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
- SpaceClip *sc = t->area->spacedata.first;
- int i, framenr = ED_space_clip_get_clip_frame_number(sc);
TransDataTracking *tdt_array = tc->custom.type.data;
- i = 0;
+ int i = 0;
while (i < tc->data_len) {
TransDataTracking *tdt = &tdt_array[i];
if (tdt->mode == transDataTracking_ModeTracks) {
MovieTrackingTrack *track = tdt->track;
- MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
+ MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, tdt->framenr);
+
+ BLI_assert(marker != NULL);
marker->flag = tdt->flag;
@@ -606,7 +619,10 @@ static void cancelTransTracking(TransInfo *t)
}
else if (tdt->mode == transDataTracking_ModePlaneTracks) {
MovieTrackingPlaneTrack *plane_track = tdt->plane_track;
- MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
+ MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get_exact(plane_track,
+ tdt->framenr);
+
+ BLI_assert(plane_marker != NULL);
plane_marker->flag = tdt->flag;
i += 3;
diff --git a/source/blender/editors/transform/transform_data.h b/source/blender/editors/transform/transform_data.h
index b59197fcd39..5b01433c96b 100644
--- a/source/blender/editors/transform/transform_data.h
+++ b/source/blender/editors/transform/transform_data.h
@@ -122,11 +122,11 @@ typedef struct TransDataCurveHandleFlags {
typedef struct TransData {
TRANSDATABASIC;
- /** Distance needed to affect element (for Proportionnal Editing). */
+ /** Distance needed to affect element (for Proportional Editing). */
float dist;
- /** Distance to the nearest element (for Proportionnal Editing). */
+ /** Distance to the nearest element (for Proportional Editing). */
float rdist;
- /** Factor of the transformation (for Proportionnal Editing). */
+ /** Factor of the transformation (for Proportional Editing). */
float factor;
/** Value pointer for special transforms. */
float *val;
@@ -141,11 +141,11 @@ typedef struct TransData {
struct Object *ob;
/** For objects/bones, the first constraint in its constraint stack. */
struct bConstraint *con;
- /** For objects, poses. 1 single malloc per TransInfo! */
+ /** For objects, poses. 1 single allocation per #TransInfo! */
TransDataExtension *ext;
/** for curves, stores handle flags for modification/cancel. */
TransDataCurveHandleFlags *hdata;
- /** If set, copy of Object or PoseChannel protection. */
+ /** If set, copy of Object or #bPoseChannel protection. */
short protectflag;
} TransData;
diff --git a/source/blender/editors/transform/transform_draw_cursors.c b/source/blender/editors/transform/transform_draw_cursors.c
index 84fc45e2b45..ead8eae0997 100644
--- a/source/blender/editors/transform/transform_draw_cursors.c
+++ b/source/blender/editors/transform/transform_draw_cursors.c
@@ -45,99 +45,45 @@ enum eArrowDirection {
RIGHT,
};
-struct ArrowDims {
- int offset;
- int length;
- int size;
-};
-
-#define POS_INDEX 0
-/* NOTE: this --^ is a bit hackish, but simplifies GPUVertFormat usage among functions
- * private to this file - merwin
- */
+#define ARROW_WIDTH (2.0f * U.pixelsize)
+#define DASH_WIDTH (1.0f)
+#define DASH_LENGTH (8.0f * DASH_WIDTH * U.pixelsize)
-static void drawArrow(enum eArrowDirection dir, const struct ArrowDims *arrow_dims)
+static void drawArrow(const uint pos_id, const enum eArrowDirection dir)
{
- int offset = arrow_dims->offset;
- int length = arrow_dims->length;
- int size = arrow_dims->size;
-
- immBegin(GPU_PRIM_LINES, 6);
-
- switch (dir) {
- case LEFT:
- offset = -offset;
- length = -length;
- size = -size;
- ATTR_FALLTHROUGH;
- case RIGHT:
- immVertex2f(POS_INDEX, offset, 0);
- immVertex2f(POS_INDEX, offset + length, 0);
- immVertex2f(POS_INDEX, offset + length, 0);
- immVertex2f(POS_INDEX, offset + length - size, -size);
- immVertex2f(POS_INDEX, offset + length, 0);
- immVertex2f(POS_INDEX, offset + length - size, size);
- break;
-
- case DOWN:
- offset = -offset;
- length = -length;
- size = -size;
- ATTR_FALLTHROUGH;
- case UP:
- immVertex2f(POS_INDEX, 0, offset);
- immVertex2f(POS_INDEX, 0, offset + length);
- immVertex2f(POS_INDEX, 0, offset + length);
- immVertex2f(POS_INDEX, -size, offset + length - size);
- immVertex2f(POS_INDEX, 0, offset + length);
- immVertex2f(POS_INDEX, size, offset + length - size);
- break;
+ int offset = 5.0f * UI_DPI_FAC;
+ int length = (6.0f * UI_DPI_FAC) + (4.0f * U.pixelsize);
+ int size = (3.0f * UI_DPI_FAC) + (2.0f * U.pixelsize);
+
+ /* To line up the arrow point nicely, one end has to be extended by half its width. But
+ * being on a 45 degree angle, Pythagoras says a movement of sqrt(2)/2 * (line width /2) */
+ float adjust = (M_SQRT2 * ARROW_WIDTH / 4.0f);
+
+ if (ELEM(dir, LEFT, DOWN)) {
+ offset = -offset;
+ length = -length;
+ size = -size;
+ adjust = -adjust;
}
- immEnd();
-}
-
-static void drawArrowHead(enum eArrowDirection dir, int size)
-{
- immBegin(GPU_PRIM_LINES, 4);
-
- switch (dir) {
- case LEFT:
- size = -size;
- ATTR_FALLTHROUGH;
- case RIGHT:
- immVertex2f(POS_INDEX, 0, 0);
- immVertex2f(POS_INDEX, -size, -size);
- immVertex2f(POS_INDEX, 0, 0);
- immVertex2f(POS_INDEX, -size, size);
- break;
+ immBegin(GPU_PRIM_LINES, 6);
- case DOWN:
- size = -size;
- ATTR_FALLTHROUGH;
- case UP:
- immVertex2f(POS_INDEX, 0, 0);
- immVertex2f(POS_INDEX, -size, -size);
- immVertex2f(POS_INDEX, 0, 0);
- immVertex2f(POS_INDEX, size, -size);
- break;
+ if (ELEM(dir, LEFT, RIGHT)) {
+ immVertex2f(pos_id, offset, 0);
+ immVertex2f(pos_id, offset + length, 0);
+ immVertex2f(pos_id, offset + length + adjust, adjust);
+ immVertex2f(pos_id, offset + length - size, -size);
+ immVertex2f(pos_id, offset + length, 0);
+ immVertex2f(pos_id, offset + length - size, size);
}
-
- immEnd();
-}
-
-static void drawArc(float angle_start, float angle_end, int segments, float size)
-{
- float delta = (angle_end - angle_start) / segments;
- float angle;
- int a;
-
- immBegin(GPU_PRIM_LINE_STRIP, segments + 1);
-
- for (angle = angle_start, a = 0; a < segments; angle += delta, a++) {
- immVertex2f(POS_INDEX, cosf(angle) * size, sinf(angle) * size);
+ else {
+ immVertex2f(pos_id, 0, offset);
+ immVertex2f(pos_id, 0, offset + length);
+ immVertex2f(pos_id, adjust, offset + length + adjust);
+ immVertex2f(pos_id, -size, offset + length - size);
+ immVertex2f(pos_id, 0, offset + length);
+ immVertex2f(pos_id, size, offset + length - size);
}
- immVertex2f(POS_INDEX, cosf(angle_end) * size, sinf(angle_end) * size);
immEnd();
}
@@ -149,11 +95,7 @@ static void drawArc(float angle_start, float angle_end, int segments, float size
bool transform_draw_cursor_poll(bContext *C)
{
ARegion *region = CTX_wm_region(C);
-
- if (region && region->regiontype == RGN_TYPE_WINDOW) {
- return 1;
- }
- return 0;
+ return (region && region->regiontype == RGN_TYPE_WINDOW) ? 1 : 0;
}
/**
@@ -164,181 +106,117 @@ void transform_draw_cursor_draw(bContext *UNUSED(C), int x, int y, void *customd
{
TransInfo *t = (TransInfo *)customdata;
- if (t->helpline != HLP_NONE) {
- struct ArrowDims arrow_dims = {
- .offset = 5 * UI_DPI_FAC,
- .length = 10 * UI_DPI_FAC,
- .size = 5 * UI_DPI_FAC,
- };
-
- float cent[2];
- const float mval[3] = {x, y, 0.0f};
- float tmval[2] = {
- (float)t->mval[0],
- (float)t->mval[1],
- };
-
- projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO);
- /* Offset the values for the area region. */
- const float offset[2] = {
- t->region->winrct.xmin,
- t->region->winrct.ymin,
- };
-
- for (int i = 0; i < 2; i++) {
- cent[i] += offset[i];
- tmval[i] += offset[i];
- }
-
- GPU_line_smooth(true);
- GPU_blend(GPU_BLEND_ALPHA);
-
- GPU_matrix_push();
-
- /* Dashed lines first. */
- if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) {
- const uint shdr_pos = GPU_vertformat_attr_add(
- immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- UNUSED_VARS_NDEBUG(shdr_pos); /* silence warning */
- BLI_assert(shdr_pos == POS_INDEX);
+ if (t->helpline == HLP_NONE) {
+ return;
+ }
- GPU_line_width(1.0f);
+ float cent[2];
+ const float mval[3] = {x, y, 0.0f};
+ float tmval[2] = {
+ (float)t->mval[0],
+ (float)t->mval[1],
+ };
+
+ projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO);
+ /* Offset the values for the area region. */
+ const float offset[2] = {
+ t->region->winrct.xmin,
+ t->region->winrct.ymin,
+ };
+
+ for (int i = 0; i < 2; i++) {
+ cent[i] += offset[i];
+ tmval[i] += offset[i];
+ }
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+
+ GPU_line_smooth(true);
+ GPU_blend(GPU_BLEND_ALPHA);
+ const uint pos_id = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ /* Dashed lines first. */
+ if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) {
+ GPU_line_width(DASH_WIDTH);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+ immUniform1i("colors_len", 0); /* "simple" mode */
+ immUniformThemeColor3(TH_VIEW_OVERLAY);
+ immUniform1f("dash_width", DASH_LENGTH);
+ immUniform1f("dash_factor", 0.5f);
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2fv(pos_id, cent);
+ immVertex2f(pos_id, tmval[0], tmval[1]);
+ immEnd();
+ immUnbindProgram();
+ }
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
+ /* And now, solid lines. */
- immUniform1i("colors_len", 0); /* "simple" mode */
- immUniformThemeColor3(TH_VIEW_OVERLAY);
- immUniform1f("dash_width", 6.0f * UI_DPI_FAC);
- immUniform1f("dash_factor", 0.5f);
+ immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
+ immUniformThemeColor3(TH_VIEW_OVERLAY);
+ immUniform2fv("viewportSize", &viewport_size[2]);
+ immUniform1f("lineWidth", ARROW_WIDTH);
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2fv(POS_INDEX, cent);
- immVertex2f(POS_INDEX, tmval[0], tmval[1]);
- immEnd();
+ GPU_matrix_push();
+ GPU_matrix_translate_3fv(mval);
- immUnbindProgram();
+ switch (t->helpline) {
+ case HLP_SPRING:
+ GPU_matrix_rotate_axis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z');
+ drawArrow(pos_id, UP);
+ drawArrow(pos_id, DOWN);
+ break;
+ case HLP_HARROW:
+ drawArrow(pos_id, RIGHT);
+ drawArrow(pos_id, LEFT);
+ break;
+ case HLP_VARROW:
+ drawArrow(pos_id, UP);
+ drawArrow(pos_id, DOWN);
+ break;
+ case HLP_CARROW: {
+ /* Draw arrow based on direction defined by custom-points. */
+ const int *data = t->mouse.data;
+ const float angle = -atan2f(data[2] - data[0], data[3] - data[1]);
+ GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
+ drawArrow(pos_id, UP);
+ drawArrow(pos_id, DOWN);
+ break;
}
-
- /* And now, solid lines. */
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- UNUSED_VARS_NDEBUG(pos); /* silence warning */
- BLI_assert(pos == POS_INDEX);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- switch (t->helpline) {
- case HLP_SPRING:
- immUniformThemeColor3(TH_VIEW_OVERLAY);
-
- GPU_matrix_translate_3fv(mval);
- GPU_matrix_rotate_axis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z');
-
- GPU_line_width(3.0f);
- drawArrow(UP, &arrow_dims);
- drawArrow(DOWN, &arrow_dims);
- break;
- case HLP_HARROW:
- immUniformThemeColor3(TH_VIEW_OVERLAY);
- GPU_matrix_translate_3fv(mval);
-
- GPU_line_width(3.0f);
- drawArrow(RIGHT, &arrow_dims);
- drawArrow(LEFT, &arrow_dims);
- break;
- case HLP_VARROW:
- immUniformThemeColor3(TH_VIEW_OVERLAY);
-
- GPU_matrix_translate_3fv(mval);
-
- GPU_line_width(3.0f);
- drawArrow(UP, &arrow_dims);
- drawArrow(DOWN, &arrow_dims);
- break;
- case HLP_CARROW: {
- /* Draw arrow based on direction defined by custom-points. */
- immUniformThemeColor3(TH_VIEW_OVERLAY);
-
- GPU_matrix_translate_3fv(mval);
-
- GPU_line_width(3.0f);
-
- const int *data = t->mouse.data;
- const float dx = data[2] - data[0], dy = data[3] - data[1];
- const float angle = -atan2f(dx, dy);
-
- GPU_matrix_push();
-
- GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
-
- drawArrow(UP, &arrow_dims);
- drawArrow(DOWN, &arrow_dims);
-
- GPU_matrix_pop();
- break;
- }
- case HLP_ANGLE: {
- float dx = tmval[0] - cent[0], dy = tmval[1] - cent[1];
- float angle = atan2f(dy, dx);
- float dist = hypotf(dx, dy);
- float delta_angle = min_ff(15.0f / (dist / UI_DPI_FAC), (float)M_PI / 4.0f);
- float spacing_angle = min_ff(5.0f / (dist / UI_DPI_FAC), (float)M_PI / 12.0f);
-
- immUniformThemeColor3(TH_VIEW_OVERLAY);
-
- GPU_matrix_translate_3f(cent[0] - tmval[0] + mval[0], cent[1] - tmval[1] + mval[1], 0);
-
- GPU_line_width(3.0f);
- drawArc(angle - delta_angle, angle - spacing_angle, 10, dist);
- drawArc(angle + spacing_angle, angle + delta_angle, 10, dist);
-
- GPU_matrix_push();
-
- GPU_matrix_translate_3f(
- cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0);
- GPU_matrix_rotate_axis(RAD2DEGF(angle - delta_angle), 'Z');
-
- drawArrowHead(DOWN, arrow_dims.size);
-
- GPU_matrix_pop();
-
- GPU_matrix_translate_3f(
- cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0);
- GPU_matrix_rotate_axis(RAD2DEGF(angle + delta_angle), 'Z');
-
- drawArrowHead(UP, arrow_dims.size);
- break;
- }
- case HLP_TRACKBALL: {
- uchar col[3], col2[3];
- UI_GetThemeColor3ubv(TH_GRID, col);
-
- GPU_matrix_translate_3fv(mval);
-
- GPU_line_width(3.0f);
-
- UI_make_axis_color(col, col2, 'X');
- immUniformColor3ubv(col2);
-
- drawArrow(RIGHT, &arrow_dims);
- drawArrow(LEFT, &arrow_dims);
-
- UI_make_axis_color(col, col2, 'Y');
- immUniformColor3ubv(col2);
-
- drawArrow(UP, &arrow_dims);
- drawArrow(DOWN, &arrow_dims);
- break;
- }
+ case HLP_ANGLE: {
+ GPU_matrix_push();
+ float angle = atan2f(tmval[1] - cent[1], tmval[0] - cent[0]);
+ GPU_matrix_translate_3f(cosf(angle), sinf(angle), 0);
+ GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
+ drawArrow(pos_id, DOWN);
+ GPU_matrix_pop();
+ GPU_matrix_translate_3f(cosf(angle), sinf(angle), 0);
+ GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
+ drawArrow(pos_id, UP);
+ break;
}
-
- immUnbindProgram();
- GPU_matrix_pop();
-
- GPU_line_smooth(false);
- GPU_blend(GPU_BLEND_NONE);
+ case HLP_TRACKBALL: {
+ uchar col[3], col2[3];
+ UI_GetThemeColor3ubv(TH_GRID, col);
+ UI_make_axis_color(col, col2, 'X');
+ immUniformColor3ubv(col2);
+ drawArrow(pos_id, RIGHT);
+ drawArrow(pos_id, LEFT);
+ UI_make_axis_color(col, col2, 'Y');
+ immUniformColor3ubv(col2);
+ drawArrow(pos_id, UP);
+ drawArrow(pos_id, DOWN);
+ break;
+ }
+ case HLP_NONE:
+ break;
}
+
+ GPU_matrix_pop();
+ immUnbindProgram();
+ GPU_line_smooth(false);
+ GPU_blend(GPU_BLEND_NONE);
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index b092b3e3e0b..6fca49495e9 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -26,7 +26,6 @@
#include "MEM_guardedalloc.h"
#include "DNA_gpencil_types.h"
-#include "DNA_mesh_types.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
@@ -44,6 +43,7 @@
#include "BKE_context.h"
#include "BKE_layer.h"
#include "BKE_mask.h"
+#include "BKE_modifier.h"
#include "BKE_paint.h"
#include "ED_clip.h"
@@ -119,79 +119,6 @@ void resetTransRestrictions(TransInfo *t)
t->flag &= ~T_ALL_RESTRICTIONS;
}
-void initTransDataContainers_FromObjectData(TransInfo *t,
- Object *obact,
- Object **objects,
- uint objects_len)
-{
- const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
- const short object_type = obact ? obact->type : -1;
-
- if ((object_mode & OB_MODE_EDIT) || (t->options & CTX_GPENCIL_STROKES) ||
- ((object_mode & OB_MODE_POSE) && (object_type == OB_ARMATURE))) {
- if (t->data_container) {
- MEM_freeN(t->data_container);
- }
-
- bool free_objects = false;
- if (objects == NULL) {
- objects = BKE_view_layer_array_from_objects_in_mode(
- t->view_layer,
- (t->spacetype == SPACE_VIEW3D) ? t->view : NULL,
- &objects_len,
- {
- .object_mode = object_mode,
- .no_dup_data = true,
- });
- free_objects = true;
- }
-
- t->data_container = MEM_callocN(sizeof(*t->data_container) * objects_len, __func__);
- t->data_container_len = objects_len;
-
- for (int i = 0; i < objects_len; i++) {
- TransDataContainer *tc = &t->data_container[i];
- if (((t->flag & T_NO_MIRROR) == 0) && ((t->options & CTX_NO_MIRROR) == 0) &&
- (objects[i]->type == OB_MESH)) {
- tc->use_mirror_axis_x = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_X) != 0;
- tc->use_mirror_axis_y = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_Y) != 0;
- tc->use_mirror_axis_z = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_Z) != 0;
- }
-
- if (object_mode & OB_MODE_EDIT) {
- tc->obedit = objects[i];
- /* Check needed for UV's */
- if ((t->flag & T_2D_EDIT) == 0) {
- tc->use_local_mat = true;
- }
- }
- else if (object_mode & OB_MODE_POSE) {
- tc->poseobj = objects[i];
- tc->use_local_mat = true;
- }
- else if (t->options & CTX_GPENCIL_STROKES) {
- tc->use_local_mat = true;
- }
-
- if (tc->use_local_mat) {
- BLI_assert((t->flag & T_2D_EDIT) == 0);
- copy_m4_m4(tc->mat, objects[i]->obmat);
- copy_m3_m4(tc->mat3, tc->mat);
- /* for non-invertible scale matrices, invert_m4_m4_fallback()
- * can still provide a valid pivot */
- invert_m4_m4_fallback(tc->imat, tc->mat);
- invert_m3_m3(tc->imat3, tc->mat3);
- normalize_m3_m3(tc->mat3_unit, tc->mat3);
- }
- /* Otherwise leave as zero. */
- }
-
- if (free_objects) {
- MEM_freeN(objects);
- }
- }
-}
-
/**
* Setup internal data, mouse, vectors
*
@@ -225,7 +152,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->flag = 0;
- if (obact && !(t->options & (CTX_CURSOR | CTX_TEXTURE)) &&
+ if (obact && !(t->options & (CTX_CURSOR | CTX_TEXTURE_SPACE)) &&
ELEM(object_mode, OB_MODE_EDIT, OB_MODE_EDIT_GPENCIL)) {
t->obedit_type = obact->type;
}
@@ -272,7 +199,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
/* Crease needs edge flag */
if (ELEM(t->mode, TFM_CREASE, TFM_BWEIGHT)) {
- t->options |= CTX_EDGE;
+ t->options |= CTX_EDGE_DATA;
}
t->remove_on_cancel = false;
@@ -1110,7 +1037,7 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
return true;
}
}
- else if (t->flag & T_POSE) {
+ else if (t->options & CTX_POSE_BONE) {
ViewLayer *view_layer = t->view_layer;
Object *ob = OBACT(view_layer);
if (ED_object_calc_active_center_for_posemode(ob, select_only, r_center)) {
@@ -1184,20 +1111,13 @@ void calculateCenter(TransInfo *t)
}
calculateCenterLocal(t, t->center_global);
- /* avoid calculating again */
- {
- TransCenterData *cd = &t->center_cache[t->around];
- copy_v3_v3(cd->global, t->center_global);
- cd->is_set = true;
- }
-
calculateCenter2D(t);
- /* for panning from cameraview */
- if ((t->flag & T_OBJECT) && (t->flag & T_OVERRIDE_CENTER) == 0) {
+ /* For panning from the camera-view. */
+ if ((t->options & CTX_OBJECT) && (t->flag & T_OVERRIDE_CENTER) == 0) {
if (t->spacetype == SPACE_VIEW3D && t->region && t->region->regiontype == RGN_TYPE_WINDOW) {
- if (t->flag & T_CAMERA) {
+ if (t->options & CTX_CAMERA) {
float axis[3];
/* persinv is nasty, use viewinv instead, always right */
copy_v3_v3(axis, t->viewinv[2]);
@@ -1237,23 +1157,6 @@ void calculateCenter(TransInfo *t)
}
}
-BLI_STATIC_ASSERT(ARRAY_SIZE(((TransInfo *)NULL)->center_cache) == (V3D_AROUND_ACTIVE + 1),
- "test size");
-
-/**
- * Lazy initialize transform center data, when we need to access center values from other types.
- */
-const TransCenterData *transformCenter_from_type(TransInfo *t, int around)
-{
- BLI_assert(around <= V3D_AROUND_ACTIVE);
- TransCenterData *cd = &t->center_cache[around];
- if (cd->is_set == false) {
- calculateCenter_FromAround(t, around, cd->global);
- cd->is_set = true;
- }
- return cd;
-}
-
void calculatePropRatio(TransInfo *t)
{
int i;
@@ -1416,7 +1319,7 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
if (td->ext->rotOrder == ROT_MODE_QUAT) {
float quat[4];
- /* calculate the total rotatation */
+ /* Calculate the total rotation. */
quat_to_mat3(obmat, td->ext->iquat);
if (use_drot) {
mul_m3_m3m3(obmat, dmat, obmat);
@@ -1437,7 +1340,7 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
float axis[3], angle;
- /* calculate the total rotatation */
+ /* Calculate the total rotation. */
axis_angle_to_mat3(obmat, td->ext->irotAxis, td->ext->irotAngle);
if (use_drot) {
mul_m3_m3m3(obmat, dmat, obmat);
@@ -1459,7 +1362,7 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
else {
float eul[3];
- /* calculate the total rotatation */
+ /* Calculate the total rotation. */
eulO_to_mat3(obmat, td->ext->irot, td->ext->rotOrder);
if (use_drot) {
mul_m3_m3m3(obmat, dmat, obmat);
@@ -1478,3 +1381,23 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
copy_v3_v3(td->ext->rot, eul);
}
}
+
+Object *transform_object_deform_pose_armature_get(const TransInfo *t, Object *ob)
+{
+ if (!(ob->mode & OB_MODE_ALL_WEIGHT_PAINT)) {
+ return NULL;
+ }
+ /* Important that ob_armature can be set even when its not selected T23412.
+ * Lines below just check is also visible. */
+ Object *ob_armature = BKE_modifiers_is_deformed_by_armature(ob);
+ if (ob_armature && ob_armature->mode & OB_MODE_POSE) {
+ Base *base_arm = BKE_view_layer_base_find(t->view_layer, ob_armature);
+ if (base_arm) {
+ View3D *v3d = t->view;
+ if (BASE_VISIBLE(v3d, base_arm)) {
+ return ob_armature;
+ }
+ }
+ }
+ return NULL;
+}
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index 9c08159cf07..27df29afd8d 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -532,7 +532,7 @@ static void protectflag_to_drawflags_ebone(RegionView3D *rv3d, const EditBone *e
/* could move into BLI_math however this is only useful for display/editing purposes */
static void axis_angle_to_gimbal_axis(float gmat[3][3], const float axis[3], const float angle)
{
- /* X/Y are arbitrary axies, most importantly Z is the axis of rotation */
+ /* X/Y are arbitrary axes, most importantly Z is the axis of rotation. */
float cross_vec[3];
float quat[4];
@@ -704,7 +704,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
/* calculate difference matrix */
- BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
LISTBASE_FOREACH (bGPDstroke *, gps, &gpl->actframe->strokes) {
/* skip strokes that are invalid for current view */
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 70ef5fcde7a..bfeb96d18c4 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -499,28 +499,4 @@ void applyMouseInput(TransInfo *t, MouseInput *mi, const int mval[2], float outp
}
}
-eRedrawFlag handleMouseInput(TransInfo *t, MouseInput *mi, const wmEvent *event)
-{
- eRedrawFlag redraw = TREDRAW_NOTHING;
-
- switch (event->type) {
- case EVT_LEFTSHIFTKEY:
- case EVT_RIGHTSHIFTKEY:
- if (event->val == KM_PRESS) {
- t->modifiers |= MOD_PRECISION;
- /* shift is modifier for higher precision transforn */
- mi->precision = 1;
- redraw = TREDRAW_HARD;
- }
- else if (event->val == KM_RELEASE) {
- t->modifiers &= ~MOD_PRECISION;
- mi->precision = 0;
- redraw = TREDRAW_HARD;
- }
- break;
- }
-
- return redraw;
-}
-
/** \} */
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index a4d999b868d..9e6e4d8807e 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -70,7 +70,7 @@ int transform_mode_really_used(bContext *C, int mode)
bool transdata_check_local_center(TransInfo *t, short around)
{
return ((around == V3D_AROUND_LOCAL_ORIGINS) &&
- ((t->flag & (T_OBJECT | T_POSE)) ||
+ ((t->options & (CTX_OBJECT | CTX_POSE_BONE)) ||
/* implicit: (t->flag & T_EDIT) */
(ELEM(t->obedit_type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE, OB_GPENCIL)) ||
(t->spacetype == SPACE_GRAPH) ||
@@ -513,7 +513,7 @@ void constraintSizeLim(TransInfo *t, TransData *td)
return;
}
- /* extrace scale from matrix and apply back sign */
+ /* Extract scale from matrix and apply back sign. */
mat4_to_size(td->ext->size, cob.matrix);
mul_v3_v3(td->ext->size, size_sign);
}
@@ -629,7 +629,7 @@ void ElementRotation_ex(TransInfo *t,
* matrix (and inverse). That is not all though. Once the proper translation
* has been computed, it has to be converted back into the bone's space.
*/
- else if (t->flag & T_POSE) {
+ else if (t->options & CTX_POSE_BONE) {
/* Extract and invert armature object matrix */
if ((td->flag & TD_NO_LOC) == 0) {
@@ -705,7 +705,7 @@ void ElementRotation_ex(TransInfo *t,
mul_m3_m3m3(totmat, mat, td->ext->r_mtx);
mul_m3_m3m3(smat, td->ext->r_smtx, totmat);
- /* calculate the total rotatation in eulers */
+ /* Calculate the total rotation in eulers. */
copy_v3_v3(eul, td->ext->irot);
eulO_to_mat3(eulmat, eul, td->ext->rotOrder);
@@ -778,7 +778,7 @@ void ElementRotation_ex(TransInfo *t,
mul_m3_m3m3(totmat, mat, td->mtx);
mul_m3_m3m3(smat, td->smtx, totmat);
- /* calculate the total rotatation in eulers */
+ /* Calculate the total rotation in eulers. */
add_v3_v3v3(eul, td->ext->irot, td->ext->drot); /* correct for delta rot */
eulO_to_mat3(obmat, eul, td->ext->rotOrder);
/* mat = transform, obmat = object rotation */
@@ -902,7 +902,7 @@ static void TransMat3ToSize(const float mat[3][3], const float smat[3][3], float
mat3_to_rot_size(rmat, size, mat);
- /* first tried with dotproduct... but the sign flip is crucial */
+ /* First tried with dot-product... but the sign flip is crucial. */
if (dot_v3v3(rmat[0], smat[0]) < 0.0f) {
size[0] = -size[0];
}
@@ -1026,7 +1026,7 @@ void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float ma
mul_v3_fl(vec, td->factor);
}
- if (t->flag & (T_OBJECT | T_POSE)) {
+ if (t->options & (CTX_OBJECT | CTX_POSE_BONE)) {
mul_m3_v3(td->smtx, vec);
}
diff --git a/source/blender/editors/transform/transform_mode_align.c b/source/blender/editors/transform/transform_mode_align.c
index f16021914f1..5bc2aa68443 100644
--- a/source/blender/editors/transform/transform_mode_align.c
+++ b/source/blender/editors/transform/transform_mode_align.c
@@ -55,7 +55,7 @@ static void applyAlign(TransInfo *t, const int UNUSED(mval[2]))
}
/* around local centers */
- if (t->flag & (T_OBJECT | T_POSE)) {
+ if (t->options & (CTX_OBJECT | CTX_POSE_BONE)) {
copy_v3_v3(tc->center_local, td->center);
}
else {
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 7ccfd0149bd..4330d5e79be 100644
--- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c
@@ -35,10 +35,12 @@
#include "WM_types.h"
#include "UI_interface.h"
+#include "UI_view2d.h"
#include "BLT_translation.h"
#include "transform.h"
+#include "transform_convert.h"
#include "transform_mode.h"
#include "transform_snap.h"
@@ -49,9 +51,9 @@
static eRedrawFlag seq_slide_handleEvent(struct TransInfo *t, const wmEvent *event)
{
BLI_assert(t->mode == TFM_SEQ_SLIDE);
- wmKeyMapItem *kmi = t->custom.mode.data;
+ const wmKeyMapItem *kmi = t->custom.mode.data;
if (kmi && event->type == kmi->type && event->val == kmi->val) {
- /* Allows the 'Expand to fit' effect to be enabled as a toogle. */
+ /* Allows the "Expand to Fit" effect to be enabled as a toggle. */
t->flag ^= T_ALT_TRANSFORM;
return TREDRAW_HARD;
}
@@ -73,7 +75,7 @@ static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRA
ofs += BLI_snprintf(
str + ofs, UI_MAX_DRAW_STR - ofs, TIP_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text);
- wmKeyMapItem *kmi = t->custom.mode.data;
+ const wmKeyMapItem *kmi = t->custom.mode.data;
if (kmi) {
ofs += WM_keymap_item_to_string(kmi, false, str + ofs, UI_MAX_DRAW_STR - ofs);
}
@@ -106,6 +108,7 @@ static void applySeqSlide(TransInfo *t, const int mval[2])
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) {
@@ -158,7 +161,7 @@ void initSeqSlide(TransInfo *t)
if (t->keymap) {
/* Workaround to use the same key as the modal keymap. */
- t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE);
+ 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 dae3fe6f7b4..dff9ded6b29 100644
--- a/source/blender/editors/transform/transform_mode_edge_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_slide.c
@@ -143,7 +143,7 @@ static BMEdge *get_other_edge(BMVert *v, BMEdge *e)
return NULL;
}
-/* interpoaltes along a line made up of 2 segments (used for edge slide) */
+/* Interpolates along a line made up of 2 segments (used for edge slide). */
static void interp_line_v3_v3v3v3(
float p[3], const float v1[3], const float v2[3], const float v3[3], float t)
{
diff --git a/source/blender/editors/transform/transform_mode_mirror.c b/source/blender/editors/transform/transform_mode_mirror.c
index 3aa99975fda..9891af8b9a4 100644
--- a/source/blender/editors/transform/transform_mode_mirror.c
+++ b/source/blender/editors/transform/transform_mode_mirror.c
@@ -152,7 +152,7 @@ static void ElementMirror(TransInfo *t, TransDataContainer *tc, TransData *td, i
sub_v3_v3(vec, td->center);
}
- if (t->flag & (T_OBJECT | T_POSE)) {
+ if (t->options & (CTX_OBJECT | CTX_POSE_BONE)) {
mul_m3_v3(td->smtx, vec);
}
diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c
index 62a4fbd6f04..4d0bb7fbe9c 100644
--- a/source/blender/editors/transform/transform_mode_resize.c
+++ b/source/blender/editors/transform/transform_mode_resize.c
@@ -132,7 +132,7 @@ static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
}
}
- /* evil hack - redo resize if cliping needed */
+ /* Evil hack - redo resize if clipping needed. */
if (t->flag & T_CLIP_UV && clipUVTransform(t, t->values_final, 1)) {
size_to_mat3(mat, t->values_final);
diff --git a/source/blender/editors/transform/transform_mode_shrink_fatten.c b/source/blender/editors/transform/transform_mode_shrink_fatten.c
index ba5b1229f3e..6e497d85417 100644
--- a/source/blender/editors/transform/transform_mode_shrink_fatten.c
+++ b/source/blender/editors/transform/transform_mode_shrink_fatten.c
@@ -49,9 +49,9 @@
static eRedrawFlag shrinkfatten_handleEvent(struct TransInfo *t, const wmEvent *event)
{
BLI_assert(t->mode == TFM_SHRINKFATTEN);
- wmKeyMapItem *kmi = t->custom.mode.data;
+ const wmKeyMapItem *kmi = t->custom.mode.data;
if (kmi && event->type == kmi->type && event->val == kmi->val) {
- /* Allows the 'Even Thickness' effect to be enabled as a toogle. */
+ /* Allows the "Even Thickness" effect to be enabled as a toggle. */
t->flag ^= T_ALT_TRANSFORM;
return TREDRAW_HARD;
}
@@ -84,8 +84,13 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
else {
/* default header print */
if (unit != NULL) {
- ofs += BKE_unit_value_as_string(
- str + ofs, sizeof(str) - ofs, distance * unit->scale_length, 4, B_UNIT_LENGTH, unit, true);
+ ofs += BKE_unit_value_as_string(str + ofs,
+ sizeof(str) - ofs,
+ distance * unit->scale_length,
+ 4,
+ B_UNIT_LENGTH,
+ unit,
+ true);
}
else {
ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, "%.4f", distance);
@@ -97,7 +102,7 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
}
ofs += BLI_strncpy_rlen(str + ofs, ", (", sizeof(str) - ofs);
- wmKeyMapItem *kmi = t->custom.mode.data;
+ const wmKeyMapItem *kmi = t->custom.mode.data;
if (kmi) {
ofs += WM_keymap_item_to_string(kmi, false, str + ofs, sizeof(str) - ofs);
}
@@ -157,7 +162,7 @@ void initShrinkFatten(TransInfo *t)
if (t->keymap) {
/* Workaround to use the same key as the modal keymap. */
- t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE);
+ t->custom.mode.data = (void *)WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE);
}
}
}
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c
index 851e0feb5f5..41fc6ee0aaf 100644
--- a/source/blender/editors/transform/transform_mode_translate.c
+++ b/source/blender/editors/transform/transform_mode_translate.c
@@ -294,7 +294,7 @@ static void applyTranslationValue(TransInfo *t, const float vec[3])
const float *original_normal;
/* In pose mode, we want to align normals with Y axis of bones... */
- if (t->flag & T_POSE) {
+ if (t->options & CTX_POSE_BONE) {
original_normal = td->axismtx[1];
}
else {
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 15c215c426d..01c00247a7a 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -411,7 +411,7 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
int exit_code;
TransInfo *t = op->customdata;
- const enum TfmMode mode_prev = t->mode;
+ const eTfmMode mode_prev = t->mode;
#if defined(WITH_INPUT_NDOF) && 0
/* Stable 2D mouse coords map to different 3D coords while the 3D mouse is active
@@ -432,7 +432,7 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
* since we're not reading from 'td->center' in this case. see: T40241 */
if (t->tsnap.target == SCE_SNAP_TARGET_ACTIVE) {
/* In camera view, tsnap callback is not set
- * (see initSnappingMode() in transfrom_snap.c, and T40348). */
+ * (see #initSnappingMode() in transform_snap.c, and T40348). */
if (t->tsnap.targetSnap && ((t->tsnap.status & TARGET_INIT) == 0)) {
t->tsnap.targetSnap(t);
}
@@ -444,7 +444,7 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
if ((exit_code & OPERATOR_RUNNING_MODAL) == 0) {
transformops_exit(C, op);
- exit_code &= ~OPERATOR_PASS_THROUGH; /* preventively remove passthrough */
+ exit_code &= ~OPERATOR_PASS_THROUGH; /* Preventively remove pass-through. */
}
else {
if (mode_prev != t->mode) {
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 3b39f4d06ad..1470d3b7059 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -521,23 +521,19 @@ short ED_transform_calc_orientation_from_type_ex(const bContext *C,
const int pivot_point)
{
switch (orientation_type) {
- case V3D_ORIENT_GLOBAL: {
- unit_m3(r_mat);
- return V3D_ORIENT_GLOBAL;
- }
case V3D_ORIENT_GIMBAL: {
if (ob && gimbal_axis(ob, r_mat)) {
- return V3D_ORIENT_GIMBAL;
+ break;
}
- /* if not gimbal, fall through to normal */
+ /* If not gimbal, fall through to normal. */
ATTR_FALLTHROUGH;
}
case V3D_ORIENT_NORMAL: {
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
ED_getTransformOrientationMatrix(C, ob, obedit, pivot_point, r_mat);
- return V3D_ORIENT_NORMAL;
+ break;
}
- /* no break we define 'normal' as 'local' in Object mode */
+ /* No break we define 'normal' as 'local' in Object mode. */
ATTR_FALLTHROUGH;
}
case V3D_ORIENT_LOCAL: {
@@ -552,10 +548,14 @@ short ED_transform_calc_orientation_from_type_ex(const bContext *C,
else {
transform_orientations_create_from_axis(r_mat, UNPACK3(ob->obmat));
}
- return V3D_ORIENT_LOCAL;
+ break;
}
+ /* If not local, fall through to global. */
+ ATTR_FALLTHROUGH;
+ }
+ case V3D_ORIENT_GLOBAL: {
unit_m3(r_mat);
- return V3D_ORIENT_GLOBAL;
+ break;
}
case V3D_ORIENT_VIEW: {
if (rv3d != NULL) {
@@ -565,11 +565,11 @@ short ED_transform_calc_orientation_from_type_ex(const bContext *C,
else {
unit_m3(r_mat);
}
- return V3D_ORIENT_VIEW;
+ break;
}
case V3D_ORIENT_CURSOR: {
BKE_scene_cursor_rot_to_mat3(&scene->cursor, r_mat);
- return V3D_ORIENT_CURSOR;
+ break;
}
case V3D_ORIENT_CUSTOM_MATRIX: {
/* Do nothing. */;
@@ -609,6 +609,12 @@ short transform_orientation_matrix_get(
orientation_index_custom = orientation - V3D_ORIENT_CUSTOM;
orientation = V3D_ORIENT_CUSTOM;
}
+ else if (ob && (ob->mode & OB_MODE_ALL_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) {
+ Object *ob_armature = transform_object_deform_pose_armature_get(t, ob);
+ if (ob_armature) {
+ ob = ob_armature;
+ }
+ }
if ((t->spacetype == SPACE_VIEW3D) && t->region && (t->region->regiontype == RGN_TYPE_WINDOW)) {
rv3d = t->region->regiondata;
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index c19dd4598cf..6d04de34016 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -235,7 +235,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
}
else if (t->spacetype == SPACE_IMAGE) {
if (validSnap(t)) {
- /* This will not draw, and Im nor sure why - campbell */
+ /* This will not draw, and I'm nor sure why - campbell */
/* TODO: see 2.7x for non-working code */
}
}
@@ -299,83 +299,93 @@ eRedrawFlag handleSnapping(TransInfo *t, const wmEvent *event)
void applyProject(TransInfo *t)
{
- /* XXX FLICKER IN OBJECT MODE */
- if ((t->tsnap.project) && activeSnap(t) && (t->flag & T_NO_PROJECT) == 0) {
- float tvec[3];
- int i;
+ if (!t->tsnap.project) {
+ return;
+ }
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- for (i = 0; i < tc->data_len; i++, td++) {
- float iloc[3], loc[3], no[3];
- float mval_fl[2];
- if (td->flag & TD_SKIP) {
- continue;
- }
+ if (!activeSnap(t) || (t->flag & T_NO_PROJECT)) {
+ return;
+ }
- if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) {
- continue;
- }
+ if (doForceIncrementSnap(t)) {
+ return;
+ }
- copy_v3_v3(iloc, td->loc);
- if (tc->use_local_mat) {
- mul_m4_v3(tc->mat, iloc);
- }
- else if (t->flag & T_OBJECT) {
- BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
- copy_v3_v3(iloc, td->ob->obmat[3]);
- }
+ float tvec[3];
+ int i;
- if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) ==
- V3D_PROJ_RET_OK) {
- if (ED_transform_snap_object_project_view3d(
- t->tsnap.object_context,
- t->depsgraph,
- SCE_SNAP_MODE_FACE,
- &(const struct SnapObjectParams){
- .snap_select = t->tsnap.modeSelect,
- .use_object_edit_cage = (t->flag & T_EDIT) != 0,
- .use_occlusion_test = false,
- .use_backface_culling = t->tsnap.use_backface_culling,
- },
- mval_fl,
- NULL,
- 0,
- loc,
- no)) {
+ /* XXX FLICKER IN OBJECT MODE */
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ TransData *td = tc->data;
+ for (i = 0; i < tc->data_len; i++, td++) {
+ float iloc[3], loc[3], no[3];
+ float mval_fl[2];
+ if (td->flag & TD_SKIP) {
+ continue;
+ }
+
+ if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) {
+ continue;
+ }
+
+ copy_v3_v3(iloc, td->loc);
+ if (tc->use_local_mat) {
+ mul_m4_v3(tc->mat, iloc);
+ }
+ else if (t->options & CTX_OBJECT) {
+ BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
+ copy_v3_v3(iloc, td->ob->obmat[3]);
+ }
+
+ if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) ==
+ V3D_PROJ_RET_OK) {
+ if (ED_transform_snap_object_project_view3d(
+ t->tsnap.object_context,
+ t->depsgraph,
+ SCE_SNAP_MODE_FACE,
+ &(const struct SnapObjectParams){
+ .snap_select = t->tsnap.modeSelect,
+ .use_object_edit_cage = (t->flag & T_EDIT) != 0,
+ .use_occlusion_test = false,
+ .use_backface_culling = t->tsnap.use_backface_culling,
+ },
+ mval_fl,
+ NULL,
+ 0,
+ loc,
+ no)) {
#if 0
if (tc->use_local_mat) {
mul_m4_v3(tc->imat, loc);
}
#endif
- sub_v3_v3v3(tvec, loc, iloc);
+ sub_v3_v3v3(tvec, loc, iloc);
- mul_m3_v3(td->smtx, tvec);
+ mul_m3_v3(td->smtx, tvec);
- add_v3_v3(td->loc, tvec);
+ add_v3_v3(td->loc, tvec);
- if (t->tsnap.align && (t->flag & T_OBJECT)) {
- /* handle alignment as well */
- const float *original_normal;
- float mat[3][3];
+ if (t->tsnap.align && (t->options & CTX_OBJECT)) {
+ /* handle alignment as well */
+ const float *original_normal;
+ float mat[3][3];
- /* In pose mode, we want to align normals with Y axis of bones... */
- original_normal = td->axismtx[2];
+ /* In pose mode, we want to align normals with Y axis of bones... */
+ original_normal = td->axismtx[2];
- rotation_between_vecs_to_mat3(mat, original_normal, no);
+ rotation_between_vecs_to_mat3(mat, original_normal, no);
- transform_data_ext_rotate(td, mat, true);
+ transform_data_ext_rotate(td, mat, true);
- /* TODO support constraints for rotation too? see ElementRotation */
- }
+ /* TODO support constraints for rotation too? see ElementRotation */
}
}
+ }
-#if 0 /* TODO: sipport this? */
+#if 0 /* TODO: support this? */
constraintTransLim(t, td);
#endif
- }
}
}
}
@@ -412,7 +422,7 @@ void applyGridAbsolute(TransInfo *t)
if (tc->use_local_mat) {
mul_m4_v3(tc->mat, iloc);
}
- else if (t->flag & T_OBJECT) {
+ else if (t->options & CTX_OBJECT) {
BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob);
copy_v3_v3(iloc, td->ob->obmat[3]);
}
@@ -561,7 +571,8 @@ static void initSnappingMode(TransInfo *t)
}
}
- if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && (t->flag & T_CAMERA) == 0) {
+ if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) &&
+ (t->options & CTX_CAMERA) == 0) {
/* Only 3D view or UV. */
/* Not with camera selected in camera view. */
@@ -916,6 +927,64 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
/** \name Target
* \{ */
+static void snap_target_median_impl(TransInfo *t, float r_median[3])
+{
+ int i_accum = 0;
+
+ zero_v3(r_median);
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ TransData *td = tc->data;
+ int i;
+ float v[3];
+ zero_v3(v);
+
+ for (i = 0; i < tc->data_len && td->flag & TD_SELECTED; i++, td++) {
+ add_v3_v3(v, td->center);
+ }
+
+ if (i == 0) {
+ /* Is this possible? */
+ continue;
+ }
+
+ mul_v3_fl(v, 1.0 / i);
+
+ if (tc->use_local_mat) {
+ mul_m4_v3(tc->mat, v);
+ }
+
+ add_v3_v3(r_median, v);
+ i_accum++;
+ }
+
+ mul_v3_fl(r_median, 1.0 / i_accum);
+
+ // TargetSnapOffset(t, NULL);
+}
+
+static void snap_target_grid_ensure(TransInfo *t)
+{
+ /* Only need to calculate once. */
+ if ((t->tsnap.status & TARGET_GRID_INIT) == 0) {
+ if (t->data_type == TC_CURSOR_VIEW3D) {
+ /* Use a fallback when transforming the cursor.
+ * In this case the center is _not_ derived from the cursor which is being transformed. */
+ copy_v3_v3(t->tsnap.snapTargetGrid, TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->data->iloc);
+ }
+ else if (t->around == V3D_AROUND_CURSOR) {
+ /* Use a fallback for cursor selection,
+ * this isn't useful as a global center for absolute grid snapping
+ * since its not based on the position of the selection. */
+ snap_target_median_impl(t, t->tsnap.snapTargetGrid);
+ }
+ else {
+ copy_v3_v3(t->tsnap.snapTargetGrid, t->center_global);
+ }
+ t->tsnap.status |= TARGET_GRID_INIT;
+ }
+}
+
static void TargetSnapOffset(TransInfo *t, TransData *td)
{
if (t->spacetype == SPACE_NODE && td != NULL) {
@@ -987,41 +1056,7 @@ static void TargetSnapMedian(TransInfo *t)
{
/* Only need to calculate once. */
if ((t->tsnap.status & TARGET_INIT) == 0) {
- int i_accum = 0;
-
- t->tsnap.snapTarget[0] = 0;
- t->tsnap.snapTarget[1] = 0;
- t->tsnap.snapTarget[2] = 0;
-
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- TransData *td = tc->data;
- int i;
- float v[3];
- zero_v3(v);
-
- for (i = 0; i < tc->data_len && td->flag & TD_SELECTED; i++, td++) {
- add_v3_v3(v, td->center);
- }
-
- if (i == 0) {
- /* Is this possible? */
- continue;
- }
-
- mul_v3_fl(v, 1.0 / i);
-
- if (tc->use_local_mat) {
- mul_m4_v3(tc->mat, v);
- }
-
- add_v3_v3(t->tsnap.snapTarget, v);
- i_accum++;
- }
-
- mul_v3_fl(t->tsnap.snapTarget, 1.0 / i_accum);
-
- TargetSnapOffset(t, NULL);
-
+ snap_target_median_impl(t, t->tsnap.snapTarget);
t->tsnap.status |= TARGET_INIT;
}
}
@@ -1034,7 +1069,7 @@ static void TargetSnapClosest(TransInfo *t)
TransData *closest = NULL;
/* Object mode */
- if (t->flag & T_OBJECT) {
+ if (t->options & CTX_OBJECT) {
int i;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
@@ -1421,28 +1456,10 @@ static void snap_grid_apply(
TransInfo *t, const int max_index, const float grid_dist, const float loc[3], float r_out[3])
{
BLI_assert(max_index <= 2);
- const float *center_global = t->center_global;
+ snap_target_grid_ensure(t);
+ const float *center_global = t->tsnap.snapTargetGrid;
const float *asp = t->aspect;
- if (t->options & CTX_CURSOR) {
- /* Note that we must already have called #transformCenter_from_type, otherwise
- * we would be lazy-initializing data which is being transformed,
- * causing the transformed cursor location to be used instead of it's initial location. */
- BLI_assert(t->center_cache[V3D_AROUND_CURSOR].is_set);
-
- /* Use a fallback when transforming the cursor.
- * In this case the center is _not_ derived from the cursor which is being transformed. */
- const TransCenterData *cd = transformCenter_from_type(t, V3D_AROUND_CURSOR);
- center_global = cd->global;
- }
- else if (t->around == V3D_AROUND_CURSOR) {
- /* Use a fallback for cursor selection,
- * this isn't useful as a global center for absolute grid snapping
- * since its not based on the position of the selection. */
- const TransCenterData *cd = transformCenter_from_type(t, V3D_AROUND_CENTER_MEDIAN);
- center_global = cd->global;
- }
-
float in[3];
if (t->con.mode & CON_APPLY) {
BLI_assert(t->tsnap.snapElem == 0);
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index b610369f82d..58198f21ba2 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -1959,7 +1959,7 @@ static short snapCurve(SnapData *snapdata,
int clip_plane_len = snapdata->clip_plane_len;
if (snapdata->has_occlusion_plane) {
- /* We snap to vertices even if coccluded. */
+ /* We snap to vertices even if occluded. */
clip_planes++;
clip_plane_len--;
}
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index 533416bf85e..baa178a6a94 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -169,16 +169,16 @@ void ED_undo_push(bContext *C, const char *str)
}
/**
- * \note Also check #undo_history_exec in bottom if you change notifiers.
+ * Common pre management of undo/redo (killing all running jobs, calling pre handlers, etc.).
*/
-static int ed_undo_step_impl(
- bContext *C, int step, const char *undoname, int undo_index, ReportList *reports)
+static void ed_undo_step_pre(bContext *C,
+ wmWindowManager *wm,
+ const enum eUndoStepDir undo_dir,
+ ReportList *reports)
{
- /* Mutually exclusives, ensure correct input. */
- BLI_assert(((undoname || undo_index != -1) && !step) ||
- (!(undoname || undo_index != -1) && step));
- CLOG_INFO(&LOG, 1, "name='%s', step=%d", undoname, step);
- wmWindowManager *wm = CTX_wm_manager(C);
+ BLI_assert(ELEM(undo_dir, STEP_UNDO, STEP_REDO));
+
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ScrArea *area = CTX_wm_area(C);
@@ -187,18 +187,12 @@ static int ed_undo_step_impl(
WM_jobs_kill_all(wm);
if (G.debug & G_DEBUG_IO) {
- Main *bmain = CTX_data_main(C);
if (bmain->lock != NULL) {
BKE_report(reports, RPT_INFO, "Checking sanity of current .blend file *BEFORE* undo step");
BLO_main_validate_libraries(bmain, reports);
}
}
- /* TODO(campbell): undo_system: use undo system */
- /* grease pencil can be can be used in plenty of spaces, so check it first */
- if (ED_gpencil_session_active()) {
- return ED_undo_gpencil_step(C, step, undoname);
- }
if (area && (area->spacetype == SPACE_VIEW3D)) {
Object *obact = CTX_data_active_object(C);
if (obact && (obact->type == OB_GPENCIL)) {
@@ -206,89 +200,40 @@ static int ed_undo_step_impl(
}
}
- UndoStep *step_data_from_name = NULL;
- int step_for_callback = step;
- if (undoname != NULL) {
- step_data_from_name = BKE_undosys_step_find_by_name(wm->undo_stack, undoname);
- if (step_data_from_name == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- /* TODO(campbell), could use simple optimization. */
- /* Pointers match on redo. */
- step_for_callback = (BLI_findindex(&wm->undo_stack->steps, step_data_from_name) <
- BLI_findindex(&wm->undo_stack->steps, wm->undo_stack->step_active)) ?
- 1 :
- -1;
- }
- else if (undo_index != -1) {
- step_for_callback = (undo_index <
- BLI_findindex(&wm->undo_stack->steps, wm->undo_stack->step_active)) ?
- 1 :
- -1;
- }
-
/* App-Handlers (pre). */
{
/* Note: ignore grease pencil for now. */
- Main *bmain = CTX_data_main(C);
wm->op_undo_depth++;
BKE_callback_exec_id(
- bmain, &scene->id, (step_for_callback > 0) ? BKE_CB_EVT_UNDO_PRE : BKE_CB_EVT_REDO_PRE);
+ bmain, &scene->id, (undo_dir == STEP_UNDO) ? BKE_CB_EVT_UNDO_PRE : BKE_CB_EVT_REDO_PRE);
wm->op_undo_depth--;
}
+}
- /* Undo System */
- {
- if (undoname) {
- BKE_undosys_step_undo_with_data(wm->undo_stack, C, step_data_from_name);
- }
- else if (undo_index != -1) {
- BKE_undosys_step_undo_from_index(wm->undo_stack, C, undo_index);
- }
- else {
- if (step == 1) {
- BKE_undosys_step_undo(wm->undo_stack, C);
- }
- else {
- BKE_undosys_step_redo(wm->undo_stack, C);
- }
- }
+/**
+ * Common post management of undo/redo (calling post handlers, adding notifiers etc.).
+ *
+ * \note Also check #undo_history_exec in bottom if you change notifiers.
+ */
+static void ed_undo_step_post(bContext *C,
+ wmWindowManager *wm,
+ const enum eUndoStepDir undo_dir,
+ ReportList *reports)
+{
+ BLI_assert(ELEM(undo_dir, STEP_UNDO, STEP_REDO));
- /* Set special modes for grease pencil */
- if (area && (area->spacetype == SPACE_VIEW3D)) {
- Object *obact = CTX_data_active_object(C);
- if (obact && (obact->type == OB_GPENCIL)) {
- /* set cursor */
- if (ELEM(obact->mode,
- OB_MODE_PAINT_GPENCIL,
- OB_MODE_SCULPT_GPENCIL,
- OB_MODE_WEIGHT_GPENCIL,
- OB_MODE_VERTEX_GPENCIL)) {
- ED_gpencil_toggle_brush_cursor(C, true, NULL);
- }
- else {
- ED_gpencil_toggle_brush_cursor(C, false, NULL);
- }
- /* set workspace mode */
- Base *basact = CTX_data_active_base(C);
- ED_object_base_activate(C, basact);
- }
- }
- }
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
/* App-Handlers (post). */
{
- Main *bmain = CTX_data_main(C);
- scene = CTX_data_scene(C);
wm->op_undo_depth++;
BKE_callback_exec_id(
- bmain, &scene->id, step_for_callback > 0 ? BKE_CB_EVT_UNDO_POST : BKE_CB_EVT_REDO_POST);
+ bmain, &scene->id, (undo_dir == STEP_UNDO) ? BKE_CB_EVT_UNDO_POST : BKE_CB_EVT_REDO_POST);
wm->op_undo_depth--;
}
if (G.debug & G_DEBUG_IO) {
- Main *bmain = CTX_data_main(C);
if (bmain->lock != NULL) {
BKE_report(reports, RPT_INFO, "Checking sanity of current .blend file *AFTER* undo step");
BLO_main_validate_libraries(bmain, reports);
@@ -299,30 +244,123 @@ static int ed_undo_step_impl(
WM_event_add_notifier(C, NC_WM | ND_UNDO, NULL);
WM_toolsystem_refresh_active(C);
-
- Main *bmain = CTX_data_main(C);
WM_toolsystem_refresh_screen_all(bmain);
if (CLOG_CHECK(&LOG, 1)) {
BKE_undosys_print(wm->undo_stack);
}
-
- return OPERATOR_FINISHED;
}
-static int ed_undo_step_direction(bContext *C, int step, ReportList *reports)
+/** Undo or redo one step from current active one.
+ * May undo or redo several steps at once only if the target step is a 'skipped' one.
+ * The target step will be the one immediately before or after the active one. */
+static int ed_undo_step_direction(bContext *C, enum eUndoStepDir step, ReportList *reports)
{
- return ed_undo_step_impl(C, step, NULL, -1, reports);
+ BLI_assert(ELEM(step, STEP_UNDO, STEP_REDO));
+
+ CLOG_INFO(&LOG, 1, "direction=%s", (step == STEP_UNDO) ? "STEP_UNDO" : "STEP_REDO");
+
+ /* TODO(campbell): undo_system: use undo system */
+ /* grease pencil can be can be used in plenty of spaces, so check it first */
+ /* FIXME: This gpencil undo effectively only supports the one step undo/redo, undo based on name
+ * or index is fully not implemented.
+ * FIXME: However, it seems to never be used in current code (`ED_gpencil_session_active` seems
+ * to always return false). */
+ if (ED_gpencil_session_active()) {
+ return ED_undo_gpencil_step(C, step);
+ }
+
+ wmWindowManager *wm = CTX_wm_manager(C);
+
+ ed_undo_step_pre(C, wm, step, reports);
+
+ if (step == STEP_UNDO) {
+ BKE_undosys_step_undo(wm->undo_stack, C);
+ }
+ else {
+ BKE_undosys_step_redo(wm->undo_stack, C);
+ }
+
+ ed_undo_step_post(C, wm, step, reports);
+
+ return OPERATOR_FINISHED;
}
+/** Undo the step matching given name.
+ * May undo several steps at once.
+ * The target step will be the one immediately before given named one. */
static int ed_undo_step_by_name(bContext *C, const char *undo_name, ReportList *reports)
{
- return ed_undo_step_impl(C, 0, undo_name, -1, reports);
+ BLI_assert(undo_name != NULL);
+
+ /* FIXME: See comments in `ed_undo_step_direction`. */
+ if (ED_gpencil_session_active()) {
+ BLI_assert(!"Not implemented currently.");
+ }
+
+ wmWindowManager *wm = CTX_wm_manager(C);
+ UndoStep *undo_step_from_name = BKE_undosys_step_find_by_name(wm->undo_stack, undo_name);
+ if (undo_step_from_name == NULL) {
+ CLOG_ERROR(&LOG, "Step name='%s' not found in current undo stack", undo_name);
+
+ return OPERATOR_CANCELLED;
+ }
+
+ UndoStep *undo_step_target = undo_step_from_name->prev;
+ if (undo_step_target == NULL) {
+ CLOG_ERROR(&LOG, "Step name='%s' cannot be undone", undo_name);
+
+ return OPERATOR_CANCELLED;
+ }
+
+ const int undo_dir_i = BKE_undosys_step_calc_direction(wm->undo_stack, undo_step_target, NULL);
+ BLI_assert(ELEM(undo_dir_i, -1, 1));
+ const enum eUndoStepDir undo_dir = (undo_dir_i == -1) ? STEP_UNDO : STEP_REDO;
+
+ CLOG_INFO(&LOG,
+ 1,
+ "name='%s', found direction=%s",
+ undo_name,
+ (undo_dir == STEP_UNDO) ? "STEP_UNDO" : "STEP_REDO");
+
+ ed_undo_step_pre(C, wm, undo_dir, reports);
+
+ BKE_undosys_step_load_data_ex(wm->undo_stack, C, undo_step_target, NULL, true);
+
+ ed_undo_step_post(C, wm, undo_dir, reports);
+
+ return OPERATOR_FINISHED;
}
-static int ed_undo_step_by_index(bContext *C, int index, ReportList *reports)
+/** Load the step matching given index in the stack.
+ * May undo or redo several steps at once.
+ * The target step will be the one indicated by the given index. */
+static int ed_undo_step_by_index(bContext *C, const int undo_index, ReportList *reports)
{
- return ed_undo_step_impl(C, 0, NULL, index, reports);
+ BLI_assert(undo_index >= 0);
+
+ /* FIXME: See comments in `ed_undo_step_direction`. */
+ if (ED_gpencil_session_active()) {
+ BLI_assert(!"Not implemented currently.");
+ }
+
+ wmWindowManager *wm = CTX_wm_manager(C);
+ const int active_step_index = BLI_findindex(&wm->undo_stack->steps, wm->undo_stack->step_active);
+ const enum eUndoStepDir undo_dir = (undo_index < active_step_index) ? STEP_UNDO : STEP_REDO;
+
+ CLOG_INFO(&LOG,
+ 1,
+ "index='%d', found direction=%s",
+ undo_index,
+ (undo_dir == STEP_UNDO) ? "STEP_UNDO" : "STEP_REDO");
+
+ ed_undo_step_pre(C, wm, undo_dir, reports);
+
+ BKE_undosys_step_load_from_index(wm->undo_stack, C, undo_index);
+
+ ed_undo_step_post(C, wm, undo_dir, reports);
+
+ return OPERATOR_FINISHED;
}
void ED_undo_grouped_push(bContext *C, const char *str)
@@ -340,11 +378,11 @@ void ED_undo_grouped_push(bContext *C, const char *str)
void ED_undo_pop(bContext *C)
{
- ed_undo_step_direction(C, 1, NULL);
+ ed_undo_step_direction(C, STEP_UNDO, NULL);
}
void ED_undo_redo(bContext *C)
{
- ed_undo_step_direction(C, -1, NULL);
+ ed_undo_step_direction(C, STEP_REDO, NULL);
}
void ED_undo_push_op(bContext *C, wmOperator *op)
@@ -448,7 +486,7 @@ static int ed_undo_exec(bContext *C, wmOperator *op)
{
/* "last operator" should disappear, later we can tie this with undo stack nicer */
WM_operator_stack_clear(CTX_wm_manager(C));
- int ret = ed_undo_step_direction(C, 1, op->reports);
+ int ret = ed_undo_step_direction(C, STEP_UNDO, op->reports);
if (ret & OPERATOR_FINISHED) {
/* Keep button under the cursor active. */
WM_event_add_mousemove(CTX_wm_window(C));
@@ -477,7 +515,7 @@ static int ed_undo_push_exec(bContext *C, wmOperator *op)
static int ed_redo_exec(bContext *C, wmOperator *op)
{
- int ret = ed_undo_step_direction(C, -1, op->reports);
+ int ret = ed_undo_step_direction(C, STEP_REDO, op->reports);
if (ret & OPERATOR_FINISHED) {
/* Keep button under the cursor active. */
WM_event_add_mousemove(CTX_wm_window(C));
diff --git a/source/blender/editors/undo/memfile_undo.c b/source/blender/editors/undo/memfile_undo.c
index eea0f29d295..4fd8c180a4b 100644
--- a/source/blender/editors/undo/memfile_undo.c
+++ b/source/blender/editors/undo/memfile_undo.c
@@ -145,19 +145,18 @@ static int memfile_undosys_step_id_reused_cb(LibraryIDLinkCallbackData *cb_data)
static void memfile_undosys_step_decode(struct bContext *C,
struct Main *bmain,
UndoStep *us_p,
- int undo_direction,
+ const eUndoStepDir undo_direction,
bool UNUSED(is_final))
{
- BLI_assert(undo_direction != 0);
+ BLI_assert(undo_direction != STEP_INVALID);
bool use_old_bmain_data = true;
if (USER_EXPERIMENTAL_TEST(&U, use_undo_legacy)) {
use_old_bmain_data = false;
}
- else if (undo_direction > 0) {
- /* Redo case.
- * The only time we should have to force a complete redo is when current step is tagged as a
+ else if (undo_direction == STEP_REDO) {
+ /* The only time we should have to force a complete redo is when current step is tagged as a
* redo barrier.
* If previous step was not a memfile one should not matter here, current data in old bmain
* should still always be valid for unchanged data-blocks. */
@@ -165,9 +164,8 @@ static void memfile_undosys_step_decode(struct bContext *C,
use_old_bmain_data = false;
}
}
- else {
- /* Undo case.
- * Here we do not care whether current step is an undo barrier, since we are coming from
+ else if (undo_direction == STEP_UNDO) {
+ /* Here we do not care whether current step is an undo barrier, since we are coming from
* 'the future' we can still re-use old data. However, if *next* undo step
* (i.e. the one immediately in the future, the one we are coming from)
* is a barrier, then we have to force a complete undo.
@@ -316,8 +314,8 @@ struct MemFile *ED_undosys_stack_memfile_get_active(UndoStack *ustack)
* If the last undo step is a memfile one, find the first #MemFileChunk matching given ID
* (using its session UUID), and tag it as "changed in the future".
*
- * Since non-memfile undos cannot automatically set this flag in the previous step as done with
- * memfile ones, this has to be called manually by relevant undo code.
+ * Since non-memfile undo-steps cannot automatically set this flag in the previous step as done
+ * with memfile ones, this has to be called manually by relevant undo code.
*
* \note Only current known case for this is undoing a switch from Object to Sculpt mode (see
* T82388).
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index 0aab3810254..38655b8490e 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -39,7 +39,7 @@ set(SRC
ed_transverts.c
ed_util.c
ed_util_imbuf.c
- ed_util_ops.c
+ ed_util_ops.cc
gizmo_utils.c
numinput.c
select_utils.c
diff --git a/source/blender/editors/util/ed_transverts.c b/source/blender/editors/util/ed_transverts.c
index 1075f256a09..d0234dee856 100644
--- a/source/blender/editors/util/ed_transverts.c
+++ b/source/blender/editors/util/ed_transverts.c
@@ -495,8 +495,8 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, Object *obedit, const
}
if (!tvs->transverts_tot && tvs->transverts) {
- /* prevent memory leak. happens for curves/latticies due to */
- /* difficult condition of adding points to trans data */
+ /* Prevent memory leak. happens for curves/lattices due to
+ * difficult condition of adding points to trans data. */
MEM_freeN(tvs->transverts);
tvs->transverts = NULL;
}
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index c59fbbe1646..695db9ba246 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -183,7 +183,7 @@ void ED_editors_exit(Main *bmain, bool do_undo_system)
return;
}
- /* frees all editmode undos */
+ /* Frees all edit-mode undo-steps. */
if (do_undo_system && G_MAIN->wm.first) {
wmWindowManager *wm = G_MAIN->wm.first;
/* normally we don't check for NULL undo stack,
diff --git a/source/blender/editors/util/ed_util_ops.c b/source/blender/editors/util/ed_util_ops.cc
index bb531b11b12..cb7ff9f3a63 100644
--- a/source/blender/editors/util/ed_util_ops.c
+++ b/source/blender/editors/util/ed_util_ops.cc
@@ -22,6 +22,9 @@
#include <string.h>
+#include "DNA_space_types.h"
+#include "DNA_windowmanager_types.h"
+
#include "BLI_fileops.h"
#include "BLI_utildefines.h"
@@ -33,9 +36,6 @@
#include "BLT_translation.h"
-#include "DNA_space_types.h"
-#include "DNA_windowmanager_types.h"
-
#include "ED_render.h"
#include "ED_undo.h"
#include "ED_util.h"
@@ -56,7 +56,7 @@ static bool lib_id_preview_editing_poll(bContext *C)
const PointerRNA idptr = CTX_data_pointer_get(C, "id");
BLI_assert(!idptr.data || RNA_struct_is_ID(idptr.type));
- const ID *id = idptr.data;
+ const ID *id = (ID *)idptr.data;
if (!id) {
return false;
}
@@ -88,11 +88,11 @@ static int lib_id_load_custom_preview_exec(bContext *C, wmOperator *op)
}
PointerRNA idptr = CTX_data_pointer_get(C, "id");
- ID *id = idptr.data;
+ ID *id = (ID *)idptr.data;
BKE_previewimg_id_custom_set(id, path);
- WM_event_add_notifier(C, NC_ASSET, NULL);
+ WM_event_add_notifier(C, NC_ASSET, nullptr);
return OPERATOR_FINISHED;
}
@@ -123,7 +123,7 @@ static void ED_OT_lib_id_load_custom_preview(wmOperatorType *ot)
static int lib_id_generate_preview_exec(bContext *C, wmOperator *UNUSED(op))
{
PointerRNA idptr = CTX_data_pointer_get(C, "id");
- ID *id = idptr.data;
+ ID *id = (ID *)idptr.data;
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
@@ -131,9 +131,9 @@ static int lib_id_generate_preview_exec(bContext *C, wmOperator *UNUSED(op))
if (preview) {
BKE_previewimg_clear(preview);
}
- UI_icon_render_id(C, NULL, id, ICON_SIZE_PREVIEW, true);
+ UI_icon_render_id(C, nullptr, id, ICON_SIZE_PREVIEW, true);
- WM_event_add_notifier(C, NC_ASSET, NULL);
+ WM_event_add_notifier(C, NC_ASSET, nullptr);
return OPERATOR_FINISHED;
}
@@ -169,15 +169,15 @@ static int lib_id_fake_user_toggle_exec(bContext *C, wmOperator *op)
idptr = RNA_property_pointer_get(&pprop.ptr, pprop.prop);
}
- if ((pprop.prop == NULL) || RNA_pointer_is_null(&idptr) || !RNA_struct_is_ID(idptr.type)) {
+ if ((pprop.prop == nullptr) || RNA_pointer_is_null(&idptr) || !RNA_struct_is_ID(idptr.type)) {
BKE_report(
op->reports, RPT_ERROR, "Incorrect context for running data-block fake user toggling");
return OPERATOR_CANCELLED;
}
- ID *id = idptr.data;
+ ID *id = (ID *)idptr.data;
- if ((id->lib != NULL) || (ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS))) {
+ if ((id->lib != nullptr) || (ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS))) {
BKE_report(op->reports, RPT_ERROR, "Data-block type does not support fake user");
return OPERATOR_CANCELLED;
}
@@ -217,14 +217,14 @@ static int lib_id_unlink_exec(bContext *C, wmOperator *op)
idptr = RNA_property_pointer_get(&pprop.ptr, pprop.prop);
}
- if ((pprop.prop == NULL) || RNA_pointer_is_null(&idptr) || !RNA_struct_is_ID(idptr.type)) {
+ if ((pprop.prop == nullptr) || RNA_pointer_is_null(&idptr) || !RNA_struct_is_ID(idptr.type)) {
BKE_report(
op->reports, RPT_ERROR, "Incorrect context for running data-block fake user toggling");
return OPERATOR_CANCELLED;
}
memset(&idptr, 0, sizeof(idptr));
- RNA_property_pointer_set(&pprop.ptr, pprop.prop, idptr, NULL);
+ RNA_property_pointer_set(&pprop.ptr, pprop.prop, idptr, nullptr);
RNA_property_update(C, &pprop.ptr, pprop.prop);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index ba22bcca0e1..91ec8546225 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -508,7 +508,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
#endif
case EVT_CKEY:
if (event->ctrl) {
- /* Copy current str to the copypaste buffer. */
+ /* Copy current `str` to the copy/paste buffer. */
WM_clipboard_text_set(n->str, 0);
updated = true;
}
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index ed9e5053f10..e94aaa49839 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -978,7 +978,7 @@ static int p_connect_pairs(PHandle *handle, PBool topology_from_uvs)
PChart *chart = handle->construction_chart;
int ncharts = 0;
- /* connect pairs, count edges, set vertex-edge pointer to a pairless edge */
+ /* Connect pairs, count edges, set vertex-edge pointer to a pair-less edge. */
for (first = chart->faces; first; first = first->nextlink) {
if (first->flag & PFACE_CONNECTED) {
continue;
@@ -1974,7 +1974,7 @@ static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair)
b[1] = p_vec_angle(v2->co, v1->co, keepv->co);
b[2] = M_PI - b[0] - b[1];
- /* abf criterion 1: avoid sharp and obtuse angles */
+ /* ABF criterion 1: avoid sharp and obtuse angles. */
minangle = 15.0f * M_PI / 180.0f;
maxangle = M_PI - minangle;
@@ -1991,7 +1991,7 @@ static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair)
} while (e && (e != oldv->edge));
if (p_vert_interior(oldv)) {
- /* hlscm criterion: angular defect smaller than threshold */
+ /* HLSCM criterion: angular defect smaller than threshold. */
if (fabsf(angulardefect) > (float)(M_PI * 30.0 / 180.0)) {
return P_FALSE;
}
@@ -2000,12 +2000,12 @@ static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair)
PVert *v1 = p_boundary_edge_next(oldv->edge)->vert;
PVert *v2 = p_boundary_edge_prev(oldv->edge)->vert;
- /* abf++ criterion 2: avoid collapsing verts inwards */
+ /* ABF++ criterion 2: avoid collapsing verts inwards. */
if (p_vert_interior(keepv)) {
return P_FALSE;
}
- /* don't collapse significant boundary changes */
+ /* Don't collapse significant boundary changes. */
angle = p_vec_angle(v1->co, oldv->co, v2->co);
if (angle < (M_PI * 160.0 / 180.0)) {
return P_FALSE;
@@ -3837,7 +3837,7 @@ static void p_chart_rotate_fit_aabb(PChart *chart)
/* Area Smoothing */
-/* 2d bsp tree for inverse mapping - that's a bit silly */
+/* 2d BSP tree for inverse mapping - that's a bit silly. */
typedef struct SmoothTriangle {
float co1[2], co2[2], co3[2];
@@ -4288,7 +4288,7 @@ static void p_smooth(PChart *chart)
MEM_freeN(hedges);
MEM_freeN(vedges);
- /* create bsp */
+ /* Create BSP. */
t = triangles = MEM_mallocN(sizeof(SmoothTriangle) * esize * 2, "PSmoothTris");
trip = tri = MEM_mallocN(sizeof(SmoothTriangle *) * esize * 2, "PSmoothTriP");
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 7b27bb570cc..8ebf000baaa 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -129,8 +129,10 @@ typedef struct UvEdge {
/** general use flag
* (Used to check if edge is boundary here, and propagates to adjacency elements) */
uchar flag;
- /** element that guarantees element->face
- * has the edge on element->tfindex and element->tfindex+1 is the second uv */
+ /**
+ * Element that guarantees `element.l` has the edge on
+ * `element.loop_of_poly_index` and `element->loop_of_poly_index + 1` is the second UV.
+ */
UvElement *element;
/** next uv edge with the same exact vertices as this one.
* Calculated at startup to save time */
@@ -224,13 +226,13 @@ enum StitchModes {
STITCH_EDGE,
};
-/* UvElement identification. */
+/** #UvElement identification. */
typedef struct UvElementID {
int faceIndex;
int elementIndex;
} UvElementID;
-/* StitchState initializition. */
+/** #StitchState initialization. */
typedef struct StitchStateInit {
int uv_selected_count;
UvElementID *to_select;
@@ -2050,7 +2052,7 @@ static StitchState *stitch_init(bContext *C,
BLI_ghash_free(edge_hash, NULL, NULL);
- /* refill an edge hash to create edge connnectivity data */
+ /* Refill an edge hash to create edge connectivity data. */
state->edge_hash = edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
for (i = 0; i < total_edges; i++) {
BLI_ghash_insert(edge_hash, edges + i, edges + i);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index be54df1ce9e..fc5f41e8ed5 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -1336,9 +1336,9 @@ static void uv_map_rotation_matrix_ex(float result[4][4],
zero_m4(rotup);
zero_m4(rotside);
- /* compensate front/side.. against opengl x,y,z world definition */
- /* this is "kanonen gegen spatzen", a few plus minus 1 will do here */
- /* i wanted to keep the reason here, so we're rotating*/
+ /* Compensate front/side.. against opengl x,y,z world definition.
+ * This is "a sledgehammer to crack a nut" (overkill), a few plus minus 1 will do here.
+ * I wanted to keep the reason here, so we're rotating. */
sideangle = (float)M_PI * (sideangledeg + 180.0f) / 180.0f;
rotside[0][0] = cosf(sideangle);
rotside[0][1] = -sinf(sideangle);