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.c6
-rw-r--r--source/blender/editors/animation/anim_filter.c6
-rw-r--r--source/blender/editors/animation/anim_markers.c13
-rw-r--r--source/blender/editors/animation/anim_motion_paths.c49
-rw-r--r--source/blender/editors/animation/keyframes_keylist.cc48
-rw-r--r--source/blender/editors/armature/pose_edit.c68
-rw-r--r--source/blender/editors/asset/intern/asset_library_reference.cc6
-rw-r--r--source/blender/editors/curve/editcurve.c16
-rw-r--r--source/blender/editors/curve/editcurve_add.c32
-rw-r--r--source/blender/editors/curve/editcurve_undo.c2
-rw-r--r--source/blender/editors/curve/editfont.c4
-rw-r--r--source/blender/editors/curves/CMakeLists.txt2
-rw-r--r--source/blender/editors/curves/intern/curves_add.cc57
-rw-r--r--source/blender/editors/curves/intern/curves_ops.cc59
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c6
-rw-r--r--source/blender/editors/gpencil/annotate_paint.c18
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c31
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c32
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c14
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c23
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_trace_utils.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c37
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_paint.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_weight_paint.c2
-rw-r--r--source/blender/editors/include/ED_anim_api.h9
-rw-r--r--source/blender/editors/include/ED_curves.h11
-rw-r--r--source/blender/editors/include/ED_curves_sculpt.h17
-rw-r--r--source/blender/editors/include/ED_keyframes_keylist.h12
-rw-r--r--source/blender/editors/include/ED_render.h12
-rw-r--r--source/blender/editors/include/ED_screen.h6
-rw-r--r--source/blender/editors/include/ED_util.h2
-rw-r--r--source/blender/editors/include/ED_view3d.h57
-rw-r--r--source/blender/editors/include/UI_interface.h2
-rw-r--r--source/blender/editors/interface/interface.c10
-rw-r--r--source/blender/editors/interface/interface_context_menu.c2
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c3
-rw-r--r--source/blender/editors/interface/interface_eyedropper_gpencil_color.c6
-rw-r--r--source/blender/editors/interface/interface_handlers.c202
-rw-r--r--source/blender/editors/interface/interface_icons.c20
-rw-r--r--source/blender/editors/interface/interface_layout.c4
-rw-r--r--source/blender/editors/interface/interface_ops.c21
-rw-r--r--source/blender/editors/interface/interface_panel.c19
-rw-r--r--source/blender/editors/interface/interface_query.c2
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c2
-rw-r--r--source/blender/editors/interface/interface_template_list.cc2
-rw-r--r--source/blender/editors/interface/interface_templates.c10
-rw-r--r--source/blender/editors/interface/interface_widgets.c4
-rw-r--r--source/blender/editors/interface/view2d_ops.c2
-rw-r--r--source/blender/editors/io/io_obj.c6
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c2
-rw-r--r--source/blender/editors/mesh/editmesh_bisect.c4
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c2
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c9
-rw-r--r--source/blender/editors/mesh/editmesh_select.c4
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c13
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c27
-rw-r--r--source/blender/editors/mesh/mesh_data.c9
-rw-r--r--source/blender/editors/mesh/meshtools.c1
-rw-r--r--source/blender/editors/object/CMakeLists.txt3
-rw-r--r--source/blender/editors/object/object_add.cc (renamed from source/blender/editors/object/object_add.c)508
-rw-r--r--source/blender/editors/object/object_bake_api.c18
-rw-r--r--source/blender/editors/object/object_constraint.c25
-rw-r--r--source/blender/editors/object/object_data_transform.c10
-rw-r--r--source/blender/editors/object/object_edit.c130
-rw-r--r--source/blender/editors/object/object_hook.c4
-rw-r--r--source/blender/editors/object/object_intern.h3
-rw-r--r--source/blender/editors/object/object_modes.c4
-rw-r--r--source/blender/editors/object/object_modifier.c4
-rw-r--r--source/blender/editors/object/object_ops.c1
-rw-r--r--source/blender/editors/object/object_relations.c16
-rw-r--r--source/blender/editors/object/object_remesh.cc2
-rw-r--r--source/blender/editors/object/object_transform.c14
-rw-r--r--source/blender/editors/object/object_utils.c2
-rw-r--r--source/blender/editors/physics/particle_edit.c8
-rw-r--r--source/blender/editors/render/render_internal.cc9
-rw-r--r--source/blender/editors/render/render_opengl.cc48
-rw-r--r--source/blender/editors/render/render_preview.cc367
-rw-r--r--source/blender/editors/render/render_shading.cc4
-rw-r--r--source/blender/editors/screen/area.c31
-rw-r--r--source/blender/editors/screen/glutil.c3
-rw-r--r--source/blender/editors/screen/screen_ops.c29
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt17
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_intern.h16
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_ops.cc411
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.cc (renamed from source/blender/editors/sculpt_paint/paint_image.c)461
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc3
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_ops_paint.cc531
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h13
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c62
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c10
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c36
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c24
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h6
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_mask_expand.c2
-rw-r--r--source/blender/editors/space_action/action_data.c2
-rw-r--r--source/blender/editors/space_api/spacetypes.c2
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c4
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c4
-rw-r--r--source/blender/editors/space_console/console_ops.c15
-rw-r--r--source/blender/editors/space_file/filelist.c2
-rw-r--r--source/blender/editors/space_graph/graph_slider_ops.c22
-rw-r--r--source/blender/editors/space_graph/graph_utils.c1
-rw-r--r--source/blender/editors/space_graph/space_graph.c2
-rw-r--r--source/blender/editors/space_info/info_stats.cc4
-rw-r--r--source/blender/editors/space_nla/nla_channels.c2
-rw-r--r--source/blender/editors/space_nla/nla_draw.c2
-rw-r--r--source/blender/editors/space_node/drawnode.cc20
-rw-r--r--source/blender/editors/space_node/node_context_path.cc2
-rw-r--r--source/blender/editors/space_node/node_draw.cc47
-rw-r--r--source/blender/editors/space_node/node_edit.cc14
-rw-r--r--source/blender/editors/space_node/node_intern.hh8
-rw-r--r--source/blender/editors/space_node/node_relationships.cc22
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.cc2
-rw-r--r--source/blender/editors/space_outliner/outliner_dragdrop.cc33
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.cc20
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.cc2
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.hh2
-rw-r--r--source/blender/editors/space_outliner/outliner_select.cc2
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.cc118
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.cc2
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display.cc8
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_override_library.cc5
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element.hh4
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_id.cc2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c5
-rw-r--r--source/blender/editors/space_spreadsheet/space_spreadsheet.cc2
-rw-r--r--source/blender/editors/space_text/text_autocomplete.c4
-rw-r--r--source/blender/editors/space_text/text_ops.c2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c9
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_cursor_snap.c25
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate.c28
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_dolly.c9
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_move.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_ndof.c80
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_roll.c29
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_rotate.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_zoom.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_zoom_border.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_placement.c11
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c59
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c33
-rw-r--r--source/blender/editors/transform/transform.c32
-rw-r--r--source/blender/editors/transform/transform.h8
-rw-r--r--source/blender/editors/transform/transform_constraints.c3
-rw-r--r--source/blender/editors/transform/transform_convert.c6
-rw-r--r--source/blender/editors/transform/transform_convert_graph.c2
-rw-r--r--source/blender/editors/transform/transform_convert_object_texspace.c2
-rw-r--r--source/blender/editors/transform/transform_generics.c20
-rw-r--r--source/blender/editors/transform/transform_gizmo_2d.c1
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c4
-rw-r--r--source/blender/editors/transform/transform_gizmo_extrude_3d.c2
-rw-r--r--source/blender/editors/transform/transform_mode.c2
-rw-r--r--source/blender/editors/transform/transform_mode_vert_slide.c14
-rw-r--r--source/blender/editors/transform/transform_ops.c2
-rw-r--r--source/blender/editors/transform/transform_orientations.c4
-rw-r--r--source/blender/editors/transform/transform_snap.c9
-rw-r--r--source/blender/editors/transform/transform_snap_object.c8
-rw-r--r--source/blender/editors/util/CMakeLists.txt1
-rw-r--r--source/blender/editors/util/ed_transverts.c7
-rw-r--r--source/blender/editors/util/ed_util.c2
-rw-r--r--source/blender/editors/util/ed_util_ops.cc2
-rw-r--r--source/blender/editors/util/numinput.c24
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c6
173 files changed, 3088 insertions, 1696 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 4780352e5dc..edb6d188ab8 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -668,7 +668,7 @@ static int acf_object_icon(bAnimListElem *ale)
return ICON_OUTLINER_OB_MESH;
case OB_CAMERA:
return ICON_OUTLINER_OB_CAMERA;
- case OB_CURVE:
+ case OB_CURVES_LEGACY:
return ICON_OUTLINER_OB_CURVE;
case OB_MBALL:
return ICON_OUTLINER_OB_META;
@@ -4601,7 +4601,7 @@ void ANIM_channel_draw(
/* Draw slider:
* - Even if we can draw sliders for this view,
* we must also check that the channel-type supports them
- * (only only F-Curves really can support them for now).
+ * (only F-Curves really can support them for now).
* - Slider should start before the toggles (if they're visible)
* to keep a clean line down the side.
*/
@@ -5336,7 +5336,7 @@ void ANIM_channel_draw_widgets(const bContext *C,
/* Draw slider:
* - Even if we can draw sliders for this view, we must also check that the channel-type
- * supports them (only only F-Curves really can support them for now).
+ * supports them (only F-Curves really can support them for now).
* - To make things easier, we use RNA-autobuts for this so that changes are
* reflected immediately, wherever they occurred.
* BUT, we don't use the layout engine, otherwise we'd get wrong alignment,
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index d6163f21c79..0389e57627a 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -2530,9 +2530,9 @@ static size_t animdata_filter_ds_obdata(
expanded = FILTER_LAM_OBJD(la);
break;
}
- case OB_CURVE: /* ------- Curve ---------- */
- case OB_SURF: /* ------- Nurbs Surface ---------- */
- case OB_FONT: /* ------- Text Curve ---------- */
+ case OB_CURVES_LEGACY: /* ------- Curve ---------- */
+ case OB_SURF: /* ------- Nurbs Surface ---------- */
+ case OB_FONT: /* ------- Text Curve ---------- */
{
Curve *cu = (Curve *)ob->data;
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 9566402ad85..95125516fe8 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -700,7 +700,7 @@ static void MARKER_OT_add(wmOperatorType *ot)
typedef struct MarkerMove {
SpaceLink *slink;
ListBase *markers;
- int event_type; /* store invoke-event, to verify */
+ short event_type, event_val; /* store invoke-event, to verify */
int *oldframe, evtx, firstx;
NumInput num;
} MarkerMove;
@@ -844,6 +844,7 @@ static int ed_marker_move_invoke(bContext *C, wmOperator *op, const wmEvent *eve
mm->evtx = event->xy[0];
mm->firstx = event->xy[0];
mm->event_type = event->type;
+ mm->event_val = event->val;
/* add temp handler */
WM_event_add_modal_handler(C, op);
@@ -941,7 +942,7 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *even
case EVT_PADENTER:
case LEFTMOUSE:
case MIDDLEMOUSE:
- if (WM_event_is_modal_tweak_exit(event, mm->event_type)) {
+ if (WM_event_is_modal_drag_exit(event, mm->event_type, mm->event_val)) {
ed_marker_move_exit(C, op);
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
@@ -960,7 +961,13 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *even
mm->evtx = event->xy[0];
fac = ((float)(event->xy[0] - mm->firstx) * dx);
- apply_keyb_grid(event->shift, event->ctrl, &fac, 0.0, FPS, 0.1 * FPS, 0);
+ apply_keyb_grid((event->modifier & KM_SHIFT) != 0,
+ (event->modifier & KM_CTRL) != 0,
+ &fac,
+ 0.0,
+ FPS,
+ 0.1 * FPS,
+ 0);
RNA_int_set(op->ptr, "frames", (int)fac);
ed_marker_move_apply(C, op);
diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c
index 539227933cf..2c99cd1cc1f 100644
--- a/source/blender/editors/animation/anim_motion_paths.c
+++ b/source/blender/editors/animation/anim_motion_paths.c
@@ -340,6 +340,55 @@ static void motionpath_free_free_tree_data(ListBase *targets)
}
}
+void animviz_motionpath_compute_range(Object *ob, Scene *scene)
+{
+ struct AnimKeylist *keylist = ED_keylist_create();
+ bAnimVizSettings *avs;
+ if (ob->mode == OB_MODE_POSE) {
+ avs = &ob->pose->avs;
+ bArmature *arm = ob->data;
+
+ if (!ELEM(NULL, ob->adt, ob->adt->action, arm->adt)) {
+ /* Loop through all the fcurves and get only the keylists for the bone location fcurves */
+ LISTBASE_FOREACH (FCurve *, fcu, &ob->adt->action->curves) {
+ if (strstr(fcu->rna_path, "pose.bones[") && strstr(fcu->rna_path, "location")) {
+ fcurve_to_keylist(arm->adt, fcu, keylist, 0);
+ }
+ }
+ }
+ }
+ else {
+ avs = &ob->avs;
+
+ if (!ELEM(NULL, ob->adt, ob->adt->action)) {
+ /* Loop through all the fcurves and get only the keylists for the location fcurves */
+ LISTBASE_FOREACH (FCurve *, fcu, &ob->adt->action->curves) {
+ if (strcmp(fcu->rna_path, "location") == 0) {
+ fcurve_to_keylist(ob->adt, fcu, keylist, 0);
+ }
+ }
+ }
+ }
+
+ if (ED_keylist_is_empty(keylist) || (avs->path_range == MOTIONPATH_RANGE_SCENE)) {
+ /* Apply scene frame range if no keys where found or if scene range is selected */
+ avs->path_sf = PSFRA;
+ avs->path_ef = PEFRA;
+ }
+ else {
+ /* Compute keys range */
+ Range2f frame_range;
+ const bool only_selected = avs->path_range == MOTIONPATH_RANGE_KEYS_SELECTED;
+ /* Get range for all keys if selected_only is false or if no keys are selected */
+ if (!(only_selected && ED_keylist_selected_keys_frame_range(keylist, &frame_range))) {
+ ED_keylist_all_keys_frame_range(keylist, &frame_range);
+ }
+ avs->path_sf = frame_range.min;
+ avs->path_ef = frame_range.max;
+ }
+ ED_keylist_free(keylist);
+}
+
void animviz_calc_motionpaths(Depsgraph *depsgraph,
Main *bmain,
Scene *scene,
diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc
index 3f9592fb4ae..0b795fea278 100644
--- a/source/blender/editors/animation/keyframes_keylist.cc
+++ b/source/blender/editors/animation/keyframes_keylist.cc
@@ -304,7 +304,21 @@ const struct ListBase *ED_keylist_listbase(const AnimKeylist *keylist)
return &keylist->key_columns;
}
-bool ED_keylist_frame_range(const struct AnimKeylist *keylist, Range2f *r_frame_range)
+static void keylist_first_last(const struct AnimKeylist *keylist,
+ const struct ActKeyColumn **first_column,
+ const struct ActKeyColumn **last_column)
+{
+ if (keylist->is_runtime_initialized) {
+ *first_column = &keylist->runtime.key_columns[0];
+ *last_column = &keylist->runtime.key_columns[keylist->column_len - 1];
+ }
+ else {
+ *first_column = static_cast<const ActKeyColumn *>(keylist->key_columns.first);
+ *last_column = static_cast<const ActKeyColumn *>(keylist->key_columns.last);
+ }
+}
+
+bool ED_keylist_all_keys_frame_range(const struct AnimKeylist *keylist, Range2f *r_frame_range)
{
BLI_assert(r_frame_range);
@@ -314,13 +328,33 @@ bool ED_keylist_frame_range(const struct AnimKeylist *keylist, Range2f *r_frame_
const ActKeyColumn *first_column;
const ActKeyColumn *last_column;
- if (keylist->is_runtime_initialized) {
- first_column = &keylist->runtime.key_columns[0];
- last_column = &keylist->runtime.key_columns[keylist->column_len - 1];
+ keylist_first_last(keylist, &first_column, &last_column);
+ r_frame_range->min = first_column->cfra;
+ r_frame_range->max = last_column->cfra;
+
+ return true;
+}
+
+bool ED_keylist_selected_keys_frame_range(const struct AnimKeylist *keylist,
+ Range2f *r_frame_range)
+{
+ BLI_assert(r_frame_range);
+
+ if (ED_keylist_is_empty(keylist)) {
+ return false;
}
- else {
- first_column = static_cast<const ActKeyColumn *>(keylist->key_columns.first);
- last_column = static_cast<const ActKeyColumn *>(keylist->key_columns.last);
+
+ const ActKeyColumn *first_column;
+ const ActKeyColumn *last_column;
+ keylist_first_last(keylist, &first_column, &last_column);
+ while (first_column && !(first_column->sel & SELECT)) {
+ first_column = first_column->next;
+ }
+ while (last_column && !(last_column->sel & SELECT)) {
+ last_column = last_column->prev;
+ }
+ if (!first_column || !last_column || first_column == last_column) {
+ return false;
}
r_frame_range->min = first_column->cfra;
r_frame_range->max = last_column->cfra;
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index e227e69f9e1..128126e515e 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -220,8 +220,8 @@ static int pose_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEven
bAnimVizSettings *avs = &ob->pose->avs;
PointerRNA avs_ptr;
- RNA_int_set(op->ptr, "start_frame", avs->path_sf);
- RNA_int_set(op->ptr, "end_frame", avs->path_ef);
+ RNA_enum_set(op->ptr, "display_type", avs->path_type);
+ RNA_enum_set(op->ptr, "range", avs->path_range);
RNA_pointer_create(NULL, &RNA_AnimVizMotionPaths, avs, &avs_ptr);
RNA_enum_set(op->ptr, "bake_location", RNA_enum_get(&avs_ptr, "bake_location"));
@@ -229,7 +229,7 @@ static int pose_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEven
/* show popup dialog to allow editing of range... */
/* FIXME: hard-coded dimensions here are just arbitrary. */
- return WM_operator_props_dialog_popup(C, op, 200);
+ return WM_operator_props_dialog_popup(C, op, 270);
}
/* For the object with pose/action: create path curves for selected bones
@@ -249,8 +249,9 @@ static int pose_calculate_paths_exec(bContext *C, wmOperator *op)
bAnimVizSettings *avs = &ob->pose->avs;
PointerRNA avs_ptr;
- avs->path_sf = RNA_int_get(op->ptr, "start_frame");
- avs->path_ef = RNA_int_get(op->ptr, "end_frame");
+ avs->path_type = RNA_enum_get(op->ptr, "display_type");
+ avs->path_range = RNA_enum_get(op->ptr, "range");
+ animviz_motionpath_compute_range(ob, scene);
RNA_pointer_create(NULL, &RNA_AnimVizMotionPaths, avs, &avs_ptr);
RNA_enum_set(&avs_ptr, "bake_location", RNA_enum_get(op->ptr, "bake_location"));
@@ -258,7 +259,6 @@ static int pose_calculate_paths_exec(bContext *C, wmOperator *op)
/* set up path data for bones being calculated */
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones_from_active_object) {
- /* verify makes sure that the selected bone has a bone with the appropriate settings */
animviz_verify_motionpaths(op->reports, scene, ob, pchan);
}
CTX_DATA_END;
@@ -281,6 +281,19 @@ static int pose_calculate_paths_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static bool pose_calculate_paths_poll(bContext *C)
+{
+ if (!ED_operator_posemode_exclusive(C)) {
+ return false;
+ }
+ Object *ob = CTX_data_active_object(C);
+ bArmature *arm = ob->data;
+ if (ELEM(NULL, ob, arm, ob->pose)) {
+ return false;
+ }
+ return true;
+}
+
void POSE_OT_paths_calculate(wmOperatorType *ot)
{
/* identifiers */
@@ -291,30 +304,24 @@ void POSE_OT_paths_calculate(wmOperatorType *ot)
/* api callbacks */
ot->invoke = pose_calculate_paths_invoke;
ot->exec = pose_calculate_paths_exec;
- ot->poll = ED_operator_posemode_exclusive;
+ ot->poll = pose_calculate_paths_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_int(ot->srna,
- "start_frame",
- 1,
- MINAFRAME,
- MAXFRAME,
- "Start",
- "First frame to calculate bone paths on",
- MINFRAME,
- MAXFRAME / 2.0);
- RNA_def_int(ot->srna,
- "end_frame",
- 250,
- MINAFRAME,
- MAXFRAME,
- "End",
- "Last frame to calculate bone paths on",
- MINFRAME,
- MAXFRAME / 2.0);
+ RNA_def_enum(ot->srna,
+ "display_type",
+ rna_enum_motionpath_display_type_items,
+ MOTIONPATH_TYPE_RANGE,
+ "Display type",
+ "");
+ RNA_def_enum(ot->srna,
+ "range",
+ rna_enum_motionpath_range_items,
+ MOTIONPATH_RANGE_SCENE,
+ "Computation Range",
+ "");
RNA_def_enum(ot->srna,
"bake_location",
@@ -336,7 +343,7 @@ static bool pose_update_paths_poll(bContext *C)
return false;
}
-static int pose_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
+static int pose_update_paths_exec(bContext *C, wmOperator *op)
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
Scene *scene = CTX_data_scene(C);
@@ -344,6 +351,13 @@ static int pose_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
if (ELEM(NULL, ob, scene)) {
return OPERATOR_CANCELLED;
}
+ animviz_motionpath_compute_range(ob, scene);
+
+ /* set up path data for bones being calculated */
+ CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones_from_active_object) {
+ animviz_verify_motionpaths(op->reports, scene, ob, pchan);
+ }
+ CTX_DATA_END;
/* Calculate the bones that now have motion-paths. */
/* TODO: only make for the selected bones? */
@@ -427,7 +441,7 @@ static int pose_clear_paths_exec(bContext *C, wmOperator *op)
/* operator callback/wrapper */
static int pose_clear_paths_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if ((event->shift) && !RNA_struct_property_is_set(op->ptr, "only_selected")) {
+ if ((event->modifier & KM_SHIFT) && !RNA_struct_property_is_set(op->ptr, "only_selected")) {
RNA_boolean_set(op->ptr, "only_selected", true);
}
return pose_clear_paths_exec(C, op);
diff --git a/source/blender/editors/asset/intern/asset_library_reference.cc b/source/blender/editors/asset/intern/asset_library_reference.cc
index 04f77821114..5096b9d653d 100644
--- a/source/blender/editors/asset/intern/asset_library_reference.cc
+++ b/source/blender/editors/asset/intern/asset_library_reference.cc
@@ -17,9 +17,9 @@ AssetLibraryReferenceWrapper::AssetLibraryReferenceWrapper(const AssetLibraryRef
bool operator==(const AssetLibraryReferenceWrapper &a, const AssetLibraryReferenceWrapper &b)
{
- return (a.type == b.type) && (a.type == ASSET_LIBRARY_CUSTOM) ?
- (a.custom_library_index == b.custom_library_index) :
- true;
+ return (a.type == b.type) &&
+ ((a.type == ASSET_LIBRARY_CUSTOM) ? (a.custom_library_index == b.custom_library_index) :
+ true);
}
uint64_t AssetLibraryReferenceWrapper::hash() const
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 20a2251b6e1..a33fbb29f85 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -72,7 +72,7 @@ static bool curve_delete_vertices(Object *obedit, View3D *v3d);
ListBase *object_editcurve_get(Object *ob)
{
- if (ob && ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ if (ob && ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
Curve *cu = ob->data;
return &cu->editnurb->nurbs;
}
@@ -1238,7 +1238,7 @@ void ED_curve_editnurb_load(Main *bmain, Object *obedit)
return;
}
- if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
Curve *cu = obedit->data;
ListBase newnurb = {NULL, NULL}, oldnurb = cu->nurb;
@@ -1273,7 +1273,7 @@ void ED_curve_editnurb_make(Object *obedit)
EditNurb *editnurb = cu->editnurb;
KeyBlock *actkey;
- if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
actkey = BKE_keyblock_from_object(obedit);
if (actkey) {
@@ -5637,7 +5637,7 @@ static int curve_extrude_exec(bContext *C, wmOperator *UNUSED(op))
}
/* First test: curve? */
- if (obedit->type != OB_CURVE) {
+ if (obedit->type != OB_CURVES_LEGACY) {
LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if ((nu->pntsv == 1) && (ED_curve_nurb_select_count(v3d, nu) < nu->pntsu)) {
as_curve = true;
@@ -5646,7 +5646,7 @@ static int curve_extrude_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- if (obedit->type == OB_CURVE || as_curve) {
+ if (obedit->type == OB_CURVES_LEGACY || as_curve) {
changed = ed_editcurve_extrude(cu, editnurb, v3d);
}
else {
@@ -6715,7 +6715,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op)
Object *obedit = objects[ob_index];
ListBase *editnurb = object_editcurve_get(obedit);
- if (obedit->type != OB_CURVE) {
+ if (obedit->type != OB_CURVES_LEGACY) {
continue;
}
@@ -6874,7 +6874,7 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op)
cu = ob_active->data;
BLI_movelisttolist(&cu->nurb, &tempbase);
- if (ob_active->type == OB_CURVE && CU_IS_2D(cu)) {
+ if (ob_active->type == OB_CURVES_LEGACY && CU_IS_2D(cu)) {
/* Account for mixed 2D/3D curves when joining */
BKE_curve_dimension_update(cu);
}
@@ -6984,7 +6984,7 @@ static bool match_texture_space_poll(bContext *C)
{
Object *object = CTX_data_active_object(C);
- return object && ELEM(object->type, OB_CURVE, OB_SURF, OB_FONT);
+ return object && ELEM(object->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT);
}
static int match_texture_space_exec(bContext *C, wmOperator *UNUSED(op))
diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c
index 2aaebf494a6..d7201495f75 100644
--- a/source/blender/editors/curve/editcurve_add.c
+++ b/source/blender/editors/curve/editcurve_add.c
@@ -53,25 +53,25 @@ static const char *get_curve_defname(int type)
if ((type & CU_TYPE) == CU_BEZIER) {
switch (stype) {
case CU_PRIM_CURVE:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "BezierCurve");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "BezierCurve");
case CU_PRIM_CIRCLE:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "BezierCircle");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "BezierCircle");
case CU_PRIM_PATH:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "CurvePath");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "CurvePath");
default:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "Curve");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "Curve");
}
}
else {
switch (stype) {
case CU_PRIM_CURVE:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "NurbsCurve");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "NurbsCurve");
case CU_PRIM_CIRCLE:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "NurbsCircle");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "NurbsCircle");
case CU_PRIM_PATH:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "NurbsPath");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "NurbsPath");
default:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "Curve");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "Curve");
}
}
}
@@ -82,17 +82,17 @@ static const char *get_surf_defname(int type)
switch (stype) {
case CU_PRIM_CURVE:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfCurve");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "SurfCurve");
case CU_PRIM_CIRCLE:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfCircle");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "SurfCircle");
case CU_PRIM_PATCH:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfPatch");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "SurfPatch");
case CU_PRIM_SPHERE:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfSphere");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "SurfSphere");
case CU_PRIM_DONUT:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "SurfTorus");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "SurfTorus");
default:
- return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE, "Surface");
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "Surface");
}
}
@@ -510,11 +510,11 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
}
if (!isSurf) { /* adding curve */
- if (obedit == NULL || obedit->type != OB_CURVE) {
+ if (obedit == NULL || obedit->type != OB_CURVES_LEGACY) {
const char *name = get_curve_defname(type);
Curve *cu;
- obedit = ED_object_add_type(C, OB_CURVE, name, loc, rot, true, local_view_bits);
+ obedit = ED_object_add_type(C, OB_CURVES_LEGACY, name, loc, rot, true, local_view_bits);
newob = true;
cu = (Curve *)obedit->data;
diff --git a/source/blender/editors/curve/editcurve_undo.c b/source/blender/editors/curve/editcurve_undo.c
index 7b68c859b43..888bb2169e0 100644
--- a/source/blender/editors/curve/editcurve_undo.c
+++ b/source/blender/editors/curve/editcurve_undo.c
@@ -162,7 +162,7 @@ static Object *editcurve_object_from_context(bContext *C)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
- if (obedit && ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ if (obedit && ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
Curve *cu = obedit->data;
if (BKE_curve_editNurbs_get(cu) != NULL) {
return obedit;
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index b2af0643e2c..02c7f3856e8 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -1640,7 +1640,9 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
EditFont *ef = cu->editfont;
static int accentcode = 0;
uintptr_t ascii = event->ascii;
- int alt = event->alt, shift = event->shift, ctrl = event->ctrl;
+ const bool alt = event->modifier & KM_ALT;
+ const bool shift = event->modifier & KM_SHIFT;
+ const bool ctrl = event->modifier & KM_CTRL;
int event_type = event->type, event_val = event->val;
char32_t inserted_text[2] = {0};
diff --git a/source/blender/editors/curves/CMakeLists.txt b/source/blender/editors/curves/CMakeLists.txt
index d2b7dacbc20..1731d224b3e 100644
--- a/source/blender/editors/curves/CMakeLists.txt
+++ b/source/blender/editors/curves/CMakeLists.txt
@@ -6,6 +6,7 @@ set(INC
../../blenlib
../../blentranslation
../../depsgraph
+ ../../functions
../../makesdna
../../makesrna
../../windowmanager
@@ -13,6 +14,7 @@ set(INC
)
set(SRC
+ intern/curves_add.cc
intern/curves_ops.cc
)
diff --git a/source/blender/editors/curves/intern/curves_add.cc b/source/blender/editors/curves/intern/curves_add.cc
new file mode 100644
index 00000000000..9cde23451dc
--- /dev/null
+++ b/source/blender/editors/curves/intern/curves_add.cc
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup edcurves
+ */
+
+#include "BLI_rand.hh"
+
+#include "BKE_curves.hh"
+
+#include "ED_curves.h"
+
+namespace blender::ed::curves {
+
+bke::CurvesGeometry primitive_random_sphere(const int curves_size, const int points_per_curve)
+{
+ bke::CurvesGeometry curves(points_per_curve * curves_size, curves_size);
+
+ MutableSpan<int> offsets = curves.offsets();
+ MutableSpan<float3> positions = curves.positions();
+
+ float *radius_data = (float *)CustomData_add_layer_named(
+ &curves.point_data, CD_PROP_FLOAT, CD_DEFAULT, nullptr, curves.point_size, "radius");
+ MutableSpan<float> radii{radius_data, curves.points_size()};
+
+ for (const int i : offsets.index_range()) {
+ offsets[i] = points_per_curve * i;
+ }
+
+ RandomNumberGenerator rng;
+
+ for (const int i : curves.curves_range()) {
+ const IndexRange curve_range = curves.range_for_curve(i);
+ MutableSpan<float3> curve_positions = positions.slice(curve_range);
+ MutableSpan<float> curve_radii = radii.slice(curve_range);
+
+ const float theta = 2.0f * M_PI * rng.get_float();
+ const float phi = saacosf(2.0f * rng.get_float() - 1.0f);
+
+ float3 no = {std::sin(theta) * std::sin(phi), std::cos(theta) * std::sin(phi), std::cos(phi)};
+ no = math::normalize(no);
+
+ float3 co = no;
+ for (int key = 0; key < points_per_curve; key++) {
+ float t = key / (float)(points_per_curve - 1);
+ curve_positions[key] = co;
+ curve_radii[key] = 0.02f * (1.0f - t);
+
+ float3 offset = float3(rng.get_float(), rng.get_float(), rng.get_float()) * 2.0f - 1.0f;
+ co += (offset + no) / points_per_curve;
+ }
+ }
+
+ return curves;
+}
+
+} // namespace blender::ed::curves
diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc
index fdda8e636f7..52a55ae1760 100644
--- a/source/blender/editors/curves/intern/curves_ops.cc
+++ b/source/blender/editors/curves/intern/curves_ops.cc
@@ -4,67 +4,8 @@
* \ingroup edcurves
*/
-#include "BLI_utildefines.h"
-
#include "ED_curves.h"
-#include "ED_object.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-#include "BKE_context.h"
-
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_types.h"
-
-static bool curves_sculptmode_toggle_poll(bContext *C)
-{
- Object *ob = CTX_data_active_object(C);
- if (ob == nullptr) {
- return false;
- }
- if (ob->type != OB_CURVES) {
- return false;
- }
- return true;
-}
-
-static int curves_sculptmode_toggle_exec(bContext *C, wmOperator *op)
-{
- Object *ob = CTX_data_active_object(C);
- const bool is_mode_set = ob->mode == OB_MODE_SCULPT_CURVES;
-
- if (is_mode_set) {
- if (!ED_object_mode_compat_set(C, ob, OB_MODE_SCULPT_CURVES, op->reports)) {
- return OPERATOR_CANCELLED;
- }
- }
-
- if (is_mode_set) {
- ob->mode = OB_MODE_OBJECT;
- }
- else {
- ob->mode = OB_MODE_SCULPT_CURVES;
- }
-
- WM_event_add_notifier(C, NC_SCENE | ND_MODE, nullptr);
- return OPERATOR_CANCELLED;
-}
-
-static void CURVES_OT_sculptmode_toggle(wmOperatorType *ot)
-{
- ot->name = "Curve Sculpt Mode Toggle";
- ot->idname = "CURVES_OT_sculptmode_toggle";
- ot->description = "Enter/Exit sculpt mode for curves";
-
- ot->exec = curves_sculptmode_toggle_exec;
- ot->poll = curves_sculptmode_toggle_poll;
-
- ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
-}
void ED_operatortypes_curves()
{
- WM_operatortype_append(CURVES_OT_sculptmode_toggle);
}
diff --git a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c
index aea6d41202e..447fe1005a1 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c
@@ -147,7 +147,7 @@ static void move3d_get_translate(const wmGizmo *gz,
float co_delta[3])
{
MoveInteraction *inter = gz->interaction_data;
- const float mval_delta[2] = {
+ const float xy_delta[2] = {
event->mval[0] - inter->init.mval[0],
event->mval[1] - inter->init.mval[1],
};
@@ -155,9 +155,9 @@ static void move3d_get_translate(const wmGizmo *gz,
RegionView3D *rv3d = region->regiondata;
float co_ref[3];
mul_v3_mat3_m4v3(co_ref, gz->matrix_space, inter->init.prop_co);
- const float zfac = ED_view3d_calc_zfac(rv3d, co_ref, NULL);
+ const float zfac = ED_view3d_calc_zfac(rv3d, co_ref);
- ED_view3d_win_to_delta(region, mval_delta, co_delta, zfac);
+ ED_view3d_win_to_delta(region, xy_delta, zfac, co_delta);
float matrix_space_inv[3][3];
copy_m3_m4(matrix_space_inv, gz->matrix_space);
diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c
index 163b5657326..5ab4a663efe 100644
--- a/source/blender/editors/gpencil/annotate_paint.c
+++ b/source/blender/editors/gpencil/annotate_paint.c
@@ -326,8 +326,7 @@ static void annotation_stroke_convertcoords(tGPsdata *p,
}
else {
float mval_prj[2];
- float rvec[3], dvec[3];
- float zfac;
+ float rvec[3];
/* Current method just converts each point in screen-coordinates to
* 3D-coordinates using the 3D-cursor as reference. In general, this
@@ -339,13 +338,14 @@ static void annotation_stroke_convertcoords(tGPsdata *p,
*/
annotation_get_3d_reference(p, rvec);
- zfac = ED_view3d_calc_zfac(p->region->regiondata, rvec, NULL);
+ const float zfac = ED_view3d_calc_zfac(p->region->regiondata, rvec);
if (ED_view3d_project_float_global(p->region, rvec, mval_prj, V3D_PROJ_TEST_NOP) ==
V3D_PROJ_RET_OK) {
- float mval_f[2];
- sub_v2_v2v2(mval_f, mval_prj, mval);
- ED_view3d_win_to_delta(p->region, mval_f, dvec, zfac);
+ float dvec[3];
+ float xy_delta[2];
+ sub_v2_v2v2(xy_delta, mval_prj, mval);
+ ED_view3d_win_to_delta(p->region, xy_delta, zfac, dvec);
sub_v3_v3v3(out, rvec, dvec);
}
else {
@@ -2060,7 +2060,7 @@ static void annotation_draw_apply_event(
p->mval[1] = (float)event->mval[1] - y;
/* Key to toggle stabilization. */
- if (event->shift && p->paintmode == GP_PAINTMODE_DRAW) {
+ if ((event->modifier & KM_SHIFT) && (p->paintmode == GP_PAINTMODE_DRAW)) {
/* Using permanent stabilization, shift will deactivate the flag. */
if (p->flags & GP_PAINTFLAG_USE_STABILIZER) {
if (p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) {
@@ -2075,7 +2075,7 @@ static void annotation_draw_apply_event(
}
}
/* verify key status for straight lines */
- else if (event->ctrl || event->alt) {
+ else if (event->modifier & (KM_CTRL | KM_ALT)) {
if (p->straight[0] == 0) {
int dx = abs((int)(p->mval[0] - p->mvalo[0]));
int dy = abs((int)(p->mval[1] - p->mvalo[1]));
@@ -2299,7 +2299,7 @@ static int annotation_draw_invoke(bContext *C, wmOperator *op, const wmEvent *ev
p->flags |= GP_PAINTFLAG_USE_STABILIZER | GP_PAINTFLAG_USE_STABILIZER_TEMP;
annotation_draw_toggle_stabilizer_cursor(p, true);
}
- else if (event->shift) {
+ else if (event->modifier & KM_SHIFT) {
p->flags |= GP_PAINTFLAG_USE_STABILIZER_TEMP;
annotation_draw_toggle_stabilizer_cursor(p, true);
}
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index 63239fd6341..d4518f21586 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -1300,8 +1300,8 @@ static void gpencil_layer_to_curve(bContext *C,
/* init the curve object (remove rotation and get curve data from it)
* - must clear transforms set on object, as those skew our results
*/
- ob = BKE_object_add_only_object(bmain, OB_CURVE, gpl->info);
- cu = ob->data = BKE_curve_add(bmain, gpl->info, OB_CURVE);
+ ob = BKE_object_add_only_object(bmain, OB_CURVES_LEGACY, gpl->info);
+ cu = ob->data = BKE_curve_add(bmain, gpl->info, OB_CURVES_LEGACY);
BKE_collection_object_add(bmain, collection, ob);
base_new = BKE_view_layer_base_find(view_layer, ob);
DEG_relations_tag_update(bmain); /* added object */
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 680b313c47b..d734fb2678e 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -4356,6 +4356,7 @@ static int gpencil_stroke_sample_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
const float length = RNA_float_get(op->ptr, "length");
+ const float sharp_threshold = RNA_float_get(op->ptr, "sharp_threshold");
/* sanity checks */
if (ELEM(NULL, gpd)) {
@@ -4365,7 +4366,7 @@ static int gpencil_stroke_sample_exec(bContext *C, wmOperator *op)
/* Go through each editable + selected stroke */
GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
if (gps->flag & GP_STROKE_SELECT) {
- BKE_gpencil_stroke_sample(gpd, gps, length, true);
+ BKE_gpencil_stroke_sample(gpd, gps, length, true, sharp_threshold);
}
}
GP_EDITABLE_STROKES_END(gpstroke_iter);
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 8be34a35ca9..069493025dc 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -1097,7 +1097,7 @@ static void gpencil_erase_processed_area(tGPDfill *tgpf)
/**
* Naive dilate
*
- * Expand green areas into enclosing red areas.
+ * Expand green areas into enclosing red or transparent areas.
* Using stack prevents creep when replacing colors directly.
* <pre>
* -----------
@@ -1110,8 +1110,8 @@ static void gpencil_erase_processed_area(tGPDfill *tgpf)
*/
static bool dilate_shape(ImBuf *ibuf)
{
-#define IS_RED (color[0] == 1.0f)
#define IS_GREEN (color[1] == 1.0f)
+#define IS_NOT_GREEN (color[1] != 1.0f)
bool done = false;
@@ -1140,7 +1140,7 @@ static bool dilate_shape(ImBuf *ibuf)
if (v - 1 >= 0) {
index = v - 1;
get_pixel(ibuf, index, color);
- if (IS_RED) {
+ if (IS_NOT_GREEN) {
BLI_stack_push(stack, &index);
lt = index;
}
@@ -1149,7 +1149,7 @@ static bool dilate_shape(ImBuf *ibuf)
if (v + 1 <= maxpixel) {
index = v + 1;
get_pixel(ibuf, index, color);
- if (IS_RED) {
+ if (IS_NOT_GREEN) {
BLI_stack_push(stack, &index);
rt = index;
}
@@ -1158,7 +1158,7 @@ static bool dilate_shape(ImBuf *ibuf)
if (v + ibuf->x <= max_size) {
index = v + ibuf->x;
get_pixel(ibuf, index, color);
- if (IS_RED) {
+ if (IS_NOT_GREEN) {
BLI_stack_push(stack, &index);
tp = index;
}
@@ -1167,7 +1167,7 @@ static bool dilate_shape(ImBuf *ibuf)
if (v - ibuf->x >= 0) {
index = v - ibuf->x;
get_pixel(ibuf, index, color);
- if (IS_RED) {
+ if (IS_NOT_GREEN) {
BLI_stack_push(stack, &index);
bm = index;
}
@@ -1176,7 +1176,7 @@ static bool dilate_shape(ImBuf *ibuf)
if (tp && lt) {
index = tp - 1;
get_pixel(ibuf, index, color);
- if (IS_RED) {
+ if (IS_NOT_GREEN) {
BLI_stack_push(stack, &index);
}
}
@@ -1184,7 +1184,7 @@ static bool dilate_shape(ImBuf *ibuf)
if (tp && rt) {
index = tp + 1;
get_pixel(ibuf, index, color);
- if (IS_RED) {
+ if (IS_NOT_GREEN) {
BLI_stack_push(stack, &index);
}
}
@@ -1192,7 +1192,7 @@ static bool dilate_shape(ImBuf *ibuf)
if (bm && lt) {
index = bm - 1;
get_pixel(ibuf, index, color);
- if (IS_RED) {
+ if (IS_NOT_GREEN) {
BLI_stack_push(stack, &index);
}
}
@@ -1200,7 +1200,7 @@ static bool dilate_shape(ImBuf *ibuf)
if (bm && rt) {
index = bm + 1;
get_pixel(ibuf, index, color);
- if (IS_RED) {
+ if (IS_NOT_GREEN) {
BLI_stack_push(stack, &index);
}
}
@@ -1218,8 +1218,8 @@ static bool dilate_shape(ImBuf *ibuf)
return done;
-#undef IS_RED
#undef IS_GREEN
+#undef IS_NOT_GREEN
}
/**
@@ -1239,7 +1239,7 @@ static bool contract_shape(ImBuf *ibuf)
const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
const int max_size = (ibuf->x * ibuf->y) - 1;
- /* Detect if pixel is near of no green pixels and mark green to be cleared. */
+ /* Detect if pixel is near of no green pixels and mark green pixel to be cleared. */
for (int row = 0; row < ibuf->y; row++) {
if (!is_row_filled(ibuf, row)) {
continue;
@@ -2172,7 +2172,8 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
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);
+ const bool is_inverted = (is_brush_inv && (event->modifier & KM_CTRL) == 0) ||
+ (!is_brush_inv && (event->modifier & KM_CTRL) != 0);
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) ||
@@ -2313,7 +2314,7 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
case EVT_PAGEUPKEY:
case WHEELUPMOUSE:
if (tgpf->oldkey == 1) {
- tgpf->fill_extend_fac -= (event->shift) ? 0.01f : 0.1f;
+ tgpf->fill_extend_fac -= (event->modifier & KM_SHIFT) ? 0.01f : 0.1f;
CLAMP_MIN(tgpf->fill_extend_fac, 0.0f);
gpencil_update_extend(tgpf);
}
@@ -2321,7 +2322,7 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
case EVT_PAGEDOWNKEY:
case WHEELDOWNMOUSE:
if (tgpf->oldkey == 1) {
- tgpf->fill_extend_fac += (event->shift) ? 0.01f : 0.1f;
+ tgpf->fill_extend_fac += (event->modifier & KM_SHIFT) ? 0.01f : 0.1f;
CLAMP_MAX(tgpf->fill_extend_fac, 100.0f);
gpencil_update_extend(tgpf);
}
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index a6691a12505..5409cea2a2a 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -235,7 +235,7 @@ typedef struct tGPsdata {
/** key used for invoking the operator */
short keymodifier;
/** shift modifier flag */
- short shift;
+ bool shift;
/** size in pixels for uv calculation */
float totpixlen;
/** Special mode for fill brush. */
@@ -447,21 +447,21 @@ static void gpencil_stroke_convertcoords(tGPsdata *p,
}
float mval_prj[2];
- float rvec[3], dvec[3];
- float mval_f[2];
- float zfac;
+ float rvec[3];
/* Current method just converts each point in screen-coordinates to
* 3D-coordinates using the 3D-cursor as reference. In general, this
* works OK, but it could of course be improved. */
gpencil_get_3d_reference(p, rvec);
- zfac = ED_view3d_calc_zfac(p->region->regiondata, rvec, NULL);
+ const float zfac = ED_view3d_calc_zfac(p->region->regiondata, rvec);
if (ED_view3d_project_float_global(p->region, rvec, mval_prj, V3D_PROJ_TEST_NOP) ==
V3D_PROJ_RET_OK) {
- sub_v2_v2v2(mval_f, mval_prj, mval);
- ED_view3d_win_to_delta(p->region, mval_f, dvec, zfac);
+ float dvec[3];
+ float xy_delta[2];
+ sub_v2_v2v2(xy_delta, mval_prj, mval);
+ ED_view3d_win_to_delta(p->region, xy_delta, zfac, dvec);
sub_v3_v3v3(out, rvec, dvec);
}
else {
@@ -2841,11 +2841,11 @@ static void gpencil_draw_apply_event(bContext *C,
* add any x,y override position
*/
copy_v2fl_v2i(p->mval, event->mval);
- p->shift = event->shift;
+ p->shift = (event->modifier & KM_SHIFT) != 0;
/* verify direction for straight lines and guides */
if ((is_speed_guide) ||
- (event->alt && (RNA_boolean_get(op->ptr, "disable_straight") == false))) {
+ ((event->modifier & KM_ALT) && (RNA_boolean_get(op->ptr, "disable_straight") == false))) {
if (p->straight == 0) {
int dx = (int)fabsf(p->mval[0] - p->mvali[0]);
int dy = (int)fabsf(p->mval[1] - p->mvali[1]);
@@ -2886,13 +2886,13 @@ static void gpencil_draw_apply_event(bContext *C,
/* special eraser modes */
if (p->paintmode == GP_PAINTMODE_ERASER) {
- if (event->shift) {
+ if (event->modifier & KM_SHIFT) {
p->flags |= GP_PAINTFLAG_HARD_ERASER;
}
else {
p->flags &= ~GP_PAINTFLAG_HARD_ERASER;
}
- if (event->alt) {
+ if (event->modifier & KM_ALT) {
p->flags |= GP_PAINTFLAG_STROKE_ERASER;
}
else {
@@ -3116,11 +3116,11 @@ static void gpencil_guide_event_handling(bContext *C,
else if ((event->type == EVT_LKEY) && (event->val == KM_RELEASE)) {
add_notifier = true;
guide->use_guide = true;
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
guide->angle = 0.0f;
guide->type = GP_GUIDE_PARALLEL;
}
- else if (event->alt) {
+ else if (event->modifier & KM_ALT) {
guide->type = GP_GUIDE_PARALLEL;
guide->angle = RNA_float_get(op->ptr, "guide_last_angle");
}
@@ -3150,10 +3150,10 @@ static void gpencil_guide_event_handling(bContext *C,
add_notifier = true;
float angle = guide->angle;
float adjust = (float)M_PI / 180.0f;
- if (event->alt) {
+ if (event->modifier & KM_ALT) {
adjust *= 45.0f;
}
- else if (!event->shift) {
+ else if ((event->modifier & KM_SHIFT) == 0) {
adjust *= 15.0f;
}
angle += (event->type == EVT_JKEY) ? adjust : -adjust;
@@ -3633,7 +3633,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
*/
}
else if (event->type == EVT_ZKEY) {
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
p->status = GP_STATUS_DONE;
estate = OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 2d761dd6c91..57a184b0e8d 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -1494,7 +1494,7 @@ static void gpencil_primitive_edit_event_handling(
float dy = (tgpi->mval[1] - tgpi->mvalo[1]);
tgpi->cp1[0] += dx;
tgpi->cp1[1] += dy;
- if (event->shift) {
+ if (event->modifier & KM_SHIFT) {
copy_v2_v2(tgpi->cp2, tgpi->cp1);
}
}
@@ -1503,7 +1503,7 @@ static void gpencil_primitive_edit_event_handling(
float dy = (tgpi->mval[1] - tgpi->mvalo[1]);
tgpi->cp2[0] += dx;
tgpi->cp2[1] += dy;
- if (event->shift) {
+ if (event->modifier & KM_SHIFT) {
copy_v2_v2(tgpi->cp1, tgpi->cp2);
}
}
@@ -1692,7 +1692,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
WM_cursor_modal_set(win, WM_CURSOR_NSEW_SCROLL);
copy_v2_v2(tgpi->end, tgpi->mval);
- if (event->shift) {
+ if (event->modifier & KM_SHIFT) {
gpencil_primitive_constrain(tgpi, true);
}
@@ -1722,7 +1722,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
case EVT_FKEY: /* brush thickness/ brush strength */
{
if ((event->val == KM_PRESS)) {
- if (event->shift) {
+ if (event->modifier & KM_SHIFT) {
tgpi->prev_flag = tgpi->flag;
tgpi->flag = IN_BRUSH_STRENGTH;
}
@@ -1900,7 +1900,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
case EVT_FKEY: /* brush thickness/ brush strength */
{
if ((event->val == KM_PRESS)) {
- if (event->shift) {
+ if (event->modifier & KM_SHIFT) {
tgpi->prev_flag = tgpi->flag;
tgpi->flag = IN_BRUSH_STRENGTH;
}
@@ -1954,12 +1954,12 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
copy_v2_v2(tgpi->origin, tgpi->mval);
}
/* Keep square if shift key */
- if (event->shift) {
+ if (event->modifier & KM_SHIFT) {
gpencil_primitive_constrain(
tgpi, (ELEM(tgpi->type, GP_STROKE_LINE, GP_STROKE_POLYLINE) || tgpi->curve));
}
/* Center primitive if alt key */
- if (event->alt && !ELEM(tgpi->type, GP_STROKE_POLYLINE)) {
+ if ((event->modifier & KM_ALT) && !ELEM(tgpi->type, GP_STROKE_POLYLINE)) {
tgpi->start[0] = tgpi->origin[0] - (tgpi->end[0] - tgpi->origin[0]);
tgpi->start[1] = tgpi->origin[1] - (tgpi->end[1] - tgpi->origin[1]);
}
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index e8f097d0018..67325e8a3d1 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -507,7 +507,7 @@ static void gpencil_brush_grab_calc_dvec(tGP_BrushEditData *gso)
/* Convert mouse-movements to movement vector */
RegionView3D *rv3d = gso->region->regiondata;
float *rvec = gso->object->loc;
- float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL);
+ const float zfac = ED_view3d_calc_zfac(rv3d, rvec);
float mval_f[2];
@@ -525,7 +525,7 @@ static void gpencil_brush_grab_calc_dvec(tGP_BrushEditData *gso)
copy_v2_v2(mval_f, r);
}
- ED_view3d_win_to_delta(gso->region, mval_f, gso->dvec, zfac);
+ ED_view3d_win_to_delta(gso->region, mval_f, zfac, gso->dvec);
}
/* Apply grab transform to all relevant points of the affected strokes */
@@ -624,17 +624,16 @@ static void gpencil_brush_calc_midpoint(tGP_BrushEditData *gso)
*/
RegionView3D *rv3d = gso->region->regiondata;
const float *rvec = gso->object->loc;
- float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL);
+ const float zfac = ED_view3d_calc_zfac(rv3d, rvec);
- float mval_f[2];
- copy_v2_v2(mval_f, gso->mval);
float mval_prj[2];
- float dvec[3];
if (ED_view3d_project_float_global(gso->region, rvec, mval_prj, V3D_PROJ_TEST_NOP) ==
V3D_PROJ_RET_OK) {
- sub_v2_v2v2(mval_f, mval_prj, mval_f);
- ED_view3d_win_to_delta(gso->region, mval_f, dvec, zfac);
+ float dvec[3];
+ float xy_delta[2];
+ sub_v2_v2v2(xy_delta, mval_prj, gso->mval);
+ ED_view3d_win_to_delta(gso->region, xy_delta, zfac, dvec);
sub_v3_v3v3(gso->dvec, rvec, dvec);
}
else {
@@ -830,10 +829,10 @@ static bool gpencil_brush_randomize_apply(tGP_BrushEditData *gso,
/* 3D: Project to 3D space */
bool flip;
RegionView3D *rv3d = gso->region->regiondata;
- float zfac = ED_view3d_calc_zfac(rv3d, &pt->x, &flip);
+ const float zfac = ED_view3d_calc_zfac_ex(rv3d, &pt->x, &flip);
if (flip == false) {
float dvec[3];
- ED_view3d_win_to_delta(gso->gsc.region, svec, dvec, zfac);
+ ED_view3d_win_to_delta(gso->gsc.region, svec, zfac, dvec);
add_v3_v3(&pt->x, dvec);
/* compute lock axis */
gpencil_sculpt_compute_lock_axis(gso, pt, save_pt);
@@ -1883,7 +1882,7 @@ static void gpencil_sculpt_brush_apply_event(bContext *C, wmOperator *op, const
RNA_collection_add(op->ptr, "stroke", &itemptr);
RNA_float_set_array(&itemptr, "mouse", mouse);
- RNA_boolean_set(&itemptr, "pen_flip", event->ctrl != false);
+ RNA_boolean_set(&itemptr, "pen_flip", (event->modifier & KM_CTRL) != 0);
RNA_boolean_set(&itemptr, "is_start", gso->first);
/* handle pressure sensitivity (which is supplied by tablets and otherwise 1.0) */
@@ -1895,7 +1894,7 @@ static void gpencil_sculpt_brush_apply_event(bContext *C, wmOperator *op, const
}
RNA_float_set(&itemptr, "pressure", pressure);
- if (event->shift) {
+ if (event->modifier & KM_SHIFT) {
gso->brush_prev = gso->brush;
gso->brush = gpencil_sculpt_get_smooth_brush(gso);
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index da263d44fc6..fca4ff84dc5 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -2659,7 +2659,7 @@ static int gpencil_select_invoke(bContext *C, wmOperator *op, const wmEvent *eve
RNA_int_set_array(op->ptr, "location", event->mval);
if (!RNA_struct_property_is_set(op->ptr, "use_shift_extend")) {
- RNA_boolean_set(op->ptr, "use_shift_extend", event->shift);
+ RNA_boolean_set(op->ptr, "use_shift_extend", event->modifier & KM_SHIFT);
}
return gpencil_select_exec(C, op);
diff --git a/source/blender/editors/gpencil/gpencil_trace_utils.c b/source/blender/editors/gpencil/gpencil_trace_utils.c
index 10be8c3e91e..735759d40ec 100644
--- a/source/blender/editors/gpencil/gpencil_trace_utils.c
+++ b/source/blender/editors/gpencil/gpencil_trace_utils.c
@@ -314,7 +314,7 @@ void ED_gpencil_trace_data_to_strokes(Main *bmain,
if (sample > 0.0f) {
/* Resample stroke. Don't need to call to BKE_gpencil_stroke_geometry_update() because
* the sample function already call that. */
- BKE_gpencil_stroke_sample(gpd, gps, sample, false);
+ BKE_gpencil_stroke_sample(gpd, gps, sample, false, 0);
}
else {
BKE_gpencil_stroke_geometry_update(gpd, gps);
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index c0777ac3105..9a658b68f21 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -822,17 +822,16 @@ bool gpencil_point_xy_to_3d(const GP_SpaceConversion *gsc,
ED_gpencil_drawing_reference_get(scene, gsc->ob, scene->toolsettings->gpencil_v3d_align, rvec);
- float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL);
+ float zfac = ED_view3d_calc_zfac(rv3d, rvec);
- float mval_f[2], mval_prj[2];
- float dvec[3];
-
- copy_v2_v2(mval_f, screen_co);
+ float mval_prj[2];
if (ED_view3d_project_float_global(gsc->region, rvec, mval_prj, V3D_PROJ_TEST_NOP) ==
V3D_PROJ_RET_OK) {
- sub_v2_v2v2(mval_f, mval_prj, mval_f);
- ED_view3d_win_to_delta(gsc->region, mval_f, dvec, zfac);
+ float dvec[3];
+ float xy_delta[2];
+ sub_v2_v2v2(xy_delta, mval_prj, screen_co);
+ ED_view3d_win_to_delta(gsc->region, xy_delta, zfac, dvec);
sub_v3_v3v3(r_out, rvec, dvec);
return true;
@@ -863,21 +862,21 @@ void gpencil_stroke_convertcoords_tpoint(Scene *scene,
*/
}
else {
- float mval_f[2] = {UNPACK2(point2D->m_xy)};
float mval_prj[2];
- float rvec[3], dvec[3];
- float zfac;
+ float rvec[3];
/* Current method just converts each point in screen-coordinates to
* 3D-coordinates using the 3D-cursor as reference.
*/
ED_gpencil_drawing_reference_get(scene, ob, ts->gpencil_v3d_align, rvec);
- zfac = ED_view3d_calc_zfac(region->regiondata, rvec, NULL);
+ const float zfac = ED_view3d_calc_zfac(region->regiondata, rvec);
if (ED_view3d_project_float_global(region, rvec, mval_prj, V3D_PROJ_TEST_NOP) ==
V3D_PROJ_RET_OK) {
- sub_v2_v2v2(mval_f, mval_prj, mval_f);
- ED_view3d_win_to_delta(region, mval_f, dvec, zfac);
+ float dvec[3];
+ float xy_delta[2];
+ sub_v2_v2v2(xy_delta, mval_prj, point2D->m_xy);
+ ED_view3d_win_to_delta(region, xy_delta, zfac, dvec);
sub_v3_v3v3(r_out, rvec, dvec);
}
else {
@@ -2005,19 +2004,19 @@ static void gpencil_stroke_convertcoords(ARegion *region,
const float origin[3],
float out[3])
{
- float mval_f[2] = {UNPACK2(point2D->m_xy)};
float mval_prj[2];
- float rvec[3], dvec[3];
- float zfac;
+ float rvec[3];
copy_v3_v3(rvec, origin);
- zfac = ED_view3d_calc_zfac(region->regiondata, rvec, NULL);
+ const float zfac = ED_view3d_calc_zfac(region->regiondata, rvec);
if (ED_view3d_project_float_global(region, rvec, mval_prj, V3D_PROJ_TEST_NOP) ==
V3D_PROJ_RET_OK) {
- sub_v2_v2v2(mval_f, mval_prj, mval_f);
- ED_view3d_win_to_delta(region, mval_f, dvec, zfac);
+ float dvec[3];
+ float xy_delta[2];
+ sub_v2_v2v2(xy_delta, mval_prj, point2D->m_xy);
+ ED_view3d_win_to_delta(region, xy_delta, zfac, dvec);
sub_v3_v3v3(out, rvec, dvec);
}
else {
diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c
index 1d1b00e3f08..244942a87ba 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_paint.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c
@@ -1241,7 +1241,7 @@ static void gpencil_vertexpaint_brush_apply_event(bContext *C,
RNA_collection_add(op->ptr, "stroke", &itemptr);
RNA_float_set_array(&itemptr, "mouse", mouse);
- RNA_boolean_set(&itemptr, "pen_flip", event->ctrl != false);
+ RNA_boolean_set(&itemptr, "pen_flip", event->modifier & KM_CTRL);
RNA_boolean_set(&itemptr, "is_start", gso->first);
/* Handle pressure sensitivity (which is supplied by tablets). */
diff --git a/source/blender/editors/gpencil/gpencil_weight_paint.c b/source/blender/editors/gpencil/gpencil_weight_paint.c
index 8fe4cba7021..01e73cd2abd 100644
--- a/source/blender/editors/gpencil/gpencil_weight_paint.c
+++ b/source/blender/editors/gpencil/gpencil_weight_paint.c
@@ -698,7 +698,7 @@ static void gpencil_weightpaint_brush_apply_event(bContext *C,
RNA_collection_add(op->ptr, "stroke", &itemptr);
RNA_float_set_array(&itemptr, "mouse", mouse);
- RNA_boolean_set(&itemptr, "pen_flip", event->ctrl != false);
+ RNA_boolean_set(&itemptr, "pen_flip", event->modifier & KM_CTRL);
RNA_boolean_set(&itemptr, "is_start", gso->first);
/* Handle pressure sensitivity (which is supplied by tablets). */
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index e6a68f7fab7..4b6f5e4cac6 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -1090,6 +1090,15 @@ void animviz_calc_motionpaths(struct Depsgraph *depsgraph,
bool restore);
/**
+ * Update motion path computation range (in `ob.avs` or `armature.avs`) from user choice in
+ * `ob.avs.path_range` or `arm.avs.path_range`, depending on active user mode.
+ *
+ * \param ob: Object to compute range for (must be provided).
+ * \param scene: Used when scene range is chosen.
+ */
+void animviz_motionpath_compute_range(struct Object *ob, struct Scene *scene);
+
+/**
* Get list of motion paths to be baked for the given object.
* - assumes the given list is ready to be used.
*/
diff --git a/source/blender/editors/include/ED_curves.h b/source/blender/editors/include/ED_curves.h
index 7316b045646..9233b65b2ce 100644
--- a/source/blender/editors/include/ED_curves.h
+++ b/source/blender/editors/include/ED_curves.h
@@ -15,3 +15,14 @@ void ED_operatortypes_curves(void);
#ifdef __cplusplus
}
#endif
+
+#ifdef __cplusplus
+
+# include "BKE_curves.hh"
+
+namespace blender::ed::curves {
+
+bke::CurvesGeometry primitive_random_sphere(int curves_size, int points_per_curve);
+
+}
+#endif
diff --git a/source/blender/editors/include/ED_curves_sculpt.h b/source/blender/editors/include/ED_curves_sculpt.h
new file mode 100644
index 00000000000..8aab1533e25
--- /dev/null
+++ b/source/blender/editors/include/ED_curves_sculpt.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup editors
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void ED_operatortypes_sculpt_curves(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/editors/include/ED_keyframes_keylist.h b/source/blender/editors/include/ED_keyframes_keylist.h
index 6a8820d0083..fd3d35e1df7 100644
--- a/source/blender/editors/include/ED_keyframes_keylist.h
+++ b/source/blender/editors/include/ED_keyframes_keylist.h
@@ -131,7 +131,13 @@ const struct ActKeyColumn *ED_keylist_find_any_between(const struct AnimKeylist
const Range2f frame_range);
bool ED_keylist_is_empty(const struct AnimKeylist *keylist);
const struct ListBase /* ActKeyColumn */ *ED_keylist_listbase(const struct AnimKeylist *keylist);
-bool ED_keylist_frame_range(const struct AnimKeylist *keylist, Range2f *r_frame_range);
+bool ED_keylist_all_keys_frame_range(const struct AnimKeylist *keylist, Range2f *r_frame_range);
+/**
+ * Return the selected key-frame's range.
+ * \return False If none are selected and does not affect the frame range.
+ */
+bool ED_keylist_selected_keys_frame_range(const struct AnimKeylist *keylist,
+ Range2f *r_frame_range);
const ActKeyColumn *ED_keylist_array(const struct AnimKeylist *keylist);
int64_t ED_keylist_array_len(const struct AnimKeylist *keylist);
@@ -183,10 +189,10 @@ void mask_to_keylist(struct bDopeSheet *ads,
/* ActKeyColumn API ---------------- */
-/* Checks if ActKeyColumn has any block data */
+/** Checks if #ActKeyColumn has any block data. */
bool actkeyblock_is_valid(const ActKeyColumn *ac);
-/* Checks if ActKeyColumn can be used as a block (i.e. drawn/used to detect "holds") */
+/** Checks if #ActKeyColumn can be used as a block (i.e. drawn/used to detect "holds"). */
int actkeyblock_get_valid_hold(const ActKeyColumn *ac);
#ifdef __cplusplus
diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h
index e1b6a935d6d..ee40cc75e1e 100644
--- a/source/blender/editors/include/ED_render.h
+++ b/source/blender/editors/include/ED_render.h
@@ -24,6 +24,7 @@ struct Scene;
struct ScrArea;
struct bContext;
struct bScreen;
+struct PreviewImage;
struct wmWindow;
struct wmWindowManager;
@@ -87,16 +88,13 @@ void ED_preview_shader_job(const struct bContext *C,
ePreviewRenderMethod method);
void ED_preview_icon_render(const struct bContext *C,
struct Scene *scene,
+ struct PreviewImage *prv_img,
struct ID *id,
- unsigned int *rect,
- int sizex,
- int sizey);
+ enum eIconSizes icon_size);
void ED_preview_icon_job(const struct bContext *C,
- void *owner,
+ struct PreviewImage *prv_img,
struct ID *id,
- unsigned int *rect,
- int sizex,
- int sizey,
+ enum eIconSizes icon_size,
bool delay);
void ED_preview_restart_queue_free(void);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 5b439cb0978..c89df9c3789 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -250,6 +250,12 @@ void ED_area_offscreen_free(struct wmWindowManager *wm,
struct wmWindow *win,
struct ScrArea *area);
+/**
+ * Search all screens, even non-active or overlapping (multiple windows), return the most-likely
+ * area of interest. xy is relative to active window, like all similar functions.
+ */
+ScrArea *ED_area_find_under_cursor(const struct bContext *C, int spacetype, const int xy[2]);
+
ScrArea *ED_screen_areas_iter_first(const struct wmWindow *win, const bScreen *screen);
ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area);
/**
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index bd3a6bce8e8..f235f696ccc 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -106,7 +106,7 @@ void ED_slider_allow_overshoot_set(struct tSlider *slider, bool value);
* \note Shift/Control are not configurable key-bindings.
*/
void apply_keyb_grid(
- int shift, int ctrl, float *val, float fac1, float fac2, float fac3, int invert);
+ bool shift, bool ctrl, float *val, float fac1, float fac2, float fac3, int invert);
/* where else to go ? */
void unpack_menu(struct bContext *C,
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 46c9a1973eb..b1435e76eb2 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -507,9 +507,18 @@ float ED_view3d_pixel_size(const struct RegionView3D *rv3d, const float co[3]);
float ED_view3d_pixel_size_no_ui_scale(const struct RegionView3D *rv3d, const float co[3]);
/**
- * Calculate a depth value from \a co, use with #ED_view3d_win_to_delta
+ * Calculate a depth value from \a co, use with #ED_view3d_win_to_delta.
+ *
+ * \param r_flip: Set to `zfac < 0.0` before the value is made signed.
+ * Since it's important in some cases to know if the value was flipped.
+ *
+ * \return The unsigned depth component of `co` multiplied by `rv3d->persmat` matrix,
+ * with additional sanitation to ensure the result is never negative
+ * as this isn't useful for tool-code.
*/
-float ED_view3d_calc_zfac(const struct RegionView3D *rv3d, const float co[3], bool *r_flip);
+float ED_view3d_calc_zfac_ex(const struct RegionView3D *rv3d, const float co[3], bool *r_flip);
+/** See #ED_view3d_calc_zfac_ex doc-string. */
+float ED_view3d_calc_zfac(const struct RegionView3D *rv3d, const float co[3]);
/**
* Calculate a depth value from `co` (result should only be used for comparison).
*/
@@ -627,16 +636,24 @@ bool ED_view3d_win_to_3d_on_plane_int(const struct ARegion *region,
float r_out[3]);
/**
* Calculate a 3d difference vector from 2d window offset.
- * note that #ED_view3d_calc_zfac() must be called first to determine
+ *
+ * \note that #ED_view3d_calc_zfac() must be called first to determine
* the depth used to calculate the delta.
+ *
+ * When the `zfac` is calculated based on a world-space location directly under the cursor,
+ * the value of `r_out` can be subtracted from #RegionView3D.ofs to pan the view
+ * with the contents following the cursor perfectly (without sliding).
+ *
* \param region: The region (used for the window width and height).
- * \param mval: The area relative 2d difference (such as `event->mval[0] - other_x`).
- * \param out: The resulting world-space delta.
+ * \param xy_delta: 2D difference (in pixels) such as `event->mval[0] - other_x`.
+ * \param zfac: The depth result typically calculated by by #ED_view3d_calc_zfac
+ * (see it's doc-string for details).
+ * \param r_out: The resulting world-space delta.
*/
void ED_view3d_win_to_delta(const struct ARegion *region,
- const float mval[2],
- float out[3],
- float zfac);
+ const float xy_delta[2],
+ float zfac,
+ float r_out[3]);
/**
* Calculate a 3d origin from 2d window coordinates.
* \note Orthographic views have a less obvious origin,
@@ -645,23 +662,23 @@ void ED_view3d_win_to_delta(const struct ARegion *region,
*
* \param region: The region (used for the window width and height).
* \param mval: The area relative 2d location (such as event->mval converted to floats).
- * \param out: The resulting normalized world-space direction vector.
+ * \param r_out: The resulting normalized world-space direction vector.
*/
-void ED_view3d_win_to_origin(const struct ARegion *region, const float mval[2], float out[3]);
+void ED_view3d_win_to_origin(const struct ARegion *region, const float mval[2], float r_out[3]);
/**
* Calculate a 3d direction vector from 2d window coordinates.
* This direction vector starts and the view in the direction of the 2d window coordinates.
* In orthographic view all window coordinates yield the same vector.
*
- * \note doesn't rely on ED_view3d_calc_zfac
+ * \note doesn't rely on #ED_view3d_calc_zfac
* for perspective view, get the vector direction to
* the mouse cursor as a normalized vector.
*
* \param region: The region (used for the window width and height).
* \param mval: The area relative 2d location (such as event->mval converted to floats).
- * \param out: The resulting normalized world-space direction vector.
+ * \param r_out: The resulting normalized world-space direction vector.
*/
-void ED_view3d_win_to_vector(const struct ARegion *region, const float mval[2], float out[3]);
+void ED_view3d_win_to_vector(const struct ARegion *region, const float mval[2], float r_out[3]);
/**
* Calculate a 3d segment from 2d window coordinates.
* This ray_start is located at the viewpoint, ray_end is a far point.
@@ -1078,6 +1095,20 @@ bool ED_view3d_persp_ensure(const struct Depsgraph *depsgraph,
struct View3D *v3d,
struct ARegion *region);
+/* Camera view functions. */
+
+/**
+ * Utility to scale zoom level when in camera-view #RegionView3D.camzoom and apply limits.
+ * \return true a change was made.
+ */
+bool ED_view3d_camera_view_zoom_scale(struct RegionView3D *rv3d, const float scale);
+/**
+ * Utility to pan when in camera view.
+ * \param event_ofs: The offset the pan in screen (pixel) coordinates.
+ * \return true when a change was made.
+ */
+bool ED_view3d_camera_view_pan(struct ARegion *region, const float event_ofs[2]);
+
/* Camera lock functions */
/**
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 7bbc8249a97..060c9dc33d6 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -2902,7 +2902,7 @@ uiBut *UI_context_active_but_prop_get(const struct bContext *C,
struct PointerRNA *r_ptr,
struct PropertyRNA **r_prop,
int *r_index);
-void UI_context_active_but_prop_handle(struct bContext *C);
+void UI_context_active_but_prop_handle(struct bContext *C, bool handle_undo);
void UI_context_active_but_clear(struct bContext *C, struct wmWindow *win, struct ARegion *region);
struct wmOperator *UI_context_active_operator_get(const struct bContext *C);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 4819e8ed82c..3619a7ce317 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1418,7 +1418,7 @@ static bool ui_but_event_property_operator_string(const bContext *C,
}
/* This version is only for finding hotkeys for properties.
- * These are set set via a data-path which is appended to the context,
+ * These are set via a data-path which is appended to the context,
* manipulated using operators (see #ctx_toggle_opnames). */
if (ptr->owner_id) {
@@ -3087,11 +3087,11 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
PointerRNA rptr;
/* This is kind of hackish, in theory think we could only ever use the second member of
- * this if/else, since ui_searchbox_apply() is supposed to always set that pointer when
+ * this if/else, since #ui_searchbox_apply() is supposed to always set that pointer when
* we are storing pointers... But keeping str search first for now,
* to try to break as little as possible existing code. All this is band-aids anyway.
- * Fact remains, using editstr as main 'reference' over whole search button thingy
- * is utterly weak and should be redesigned imho, but that's not a simple task. */
+ * Fact remains, using `editstr` as main 'reference' over whole search button thingy
+ * is utterly weak and should be redesigned IMHO, but that's not a simple task. */
if (search_but && search_but->rnasearchprop &&
RNA_property_collection_lookup_string(
&search_but->rnasearchpoin, search_but->rnasearchprop, str, &rptr)) {
@@ -6529,7 +6529,7 @@ void UI_but_focus_on_enter_event(wmWindow *win, uiBut *but)
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
- event.is_repeat = false;
+ event.flag = 0;
event.customdata = but;
event.customdata_free = false;
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index 34a20b91172..07efcdcbe38 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -201,7 +201,7 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *region, void *arg)
/* XXX this guess_opname can potentially return a different keymap
* than being found on adding later... */
wmKeyMap *km = WM_keymap_guess_opname(C, idname);
- wmKeyMapItem *kmi = WM_keymap_add_item(km, idname, EVT_AKEY, KM_PRESS, 0, 0);
+ wmKeyMapItem *kmi = WM_keymap_add_item(km, idname, EVT_AKEY, KM_PRESS, 0, 0, KM_ANY);
const int kmi_id = kmi->id;
/* This takes ownership of prop, or prop can be NULL for reset. */
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index e72381821e8..eaec1e249b7 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -147,8 +147,7 @@ void datadropper_win_area_find(
*r_win = CTX_wm_window(C);
*r_area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mval);
if (*r_area == NULL) {
- wmWindowManager *wm = CTX_wm_manager(C);
- *r_win = WM_window_find_under_cursor(wm, NULL, *r_win, mval, r_mval);
+ *r_win = WM_window_find_under_cursor(*r_win, mval, r_mval);
if (*r_win) {
screen = WM_window_get_active_screen(*r_win);
*r_area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, r_mval);
diff --git a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c
index d6f529f9f94..f3c70e6a96a 100644
--- a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c
+++ b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c
@@ -222,9 +222,9 @@ static void eyedropper_add_palette_color(bContext *C, const float col_conv[4])
static void eyedropper_gpencil_color_set(bContext *C, const wmEvent *event, EyedropperGPencil *eye)
{
- const bool only_stroke = ((!event->ctrl) && (!event->shift));
- const bool only_fill = ((!event->ctrl) && (event->shift));
- const bool both = ((event->ctrl) && (event->shift));
+ const bool only_stroke = (event->modifier & (KM_CTRL | KM_SHIFT)) == 0;
+ const bool only_fill = ((event->modifier & KM_CTRL) == 0 && (event->modifier & KM_SHIFT));
+ const bool both = ((event->modifier & KM_CTRL) && (event->modifier & KM_SHIFT));
float col_conv[4];
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index bbb6bfabdd1..e0b64dcd4d6 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -275,7 +275,7 @@ static void ui_selectcontext_apply(bContext *C,
const double value,
const double value_orig);
-# define IS_ALLSELECT_EVENT(event) ((event)->alt != 0)
+# define IS_ALLSELECT_EVENT(event) (((event)->modifier & KM_ALT) != 0)
/** just show a tinted color so users know its activated */
# define UI_BUT_IS_SELECT_CONTEXT UI_BUT_NODE_ACTIVE
@@ -708,7 +708,8 @@ enum eSnapType {
static enum eSnapType ui_event_to_snap(const wmEvent *event)
{
- return (event->ctrl) ? (event->shift) ? SNAP_ON_SMALL : SNAP_ON : SNAP_OFF;
+ return (event->modifier & KM_CTRL) ? (event->modifier & KM_SHIFT) ? SNAP_ON_SMALL : SNAP_ON :
+ SNAP_OFF;
}
static bool ui_event_is_snap(const wmEvent *event)
@@ -1937,7 +1938,7 @@ static void ui_selectcontext_apply(bContext *C,
/* could check for 'handle_layer_buttons' */
but->func) {
wmWindow *win = CTX_wm_window(C);
- if (!win->eventstate->shift) {
+ if ((win->eventstate->modifier & KM_SHIFT) == 0) {
const int len = RNA_property_array_length(&but->rnapoin, prop);
bool *tmparray = MEM_callocN(sizeof(bool) * len, __func__);
@@ -3747,11 +3748,11 @@ static void ui_do_but_textedit(
case EVT_XKEY:
case EVT_CKEY:
#if defined(__APPLE__)
- if ((event->oskey && !IS_EVENT_MOD(event, shift, alt, ctrl)) ||
- (event->ctrl && !IS_EVENT_MOD(event, shift, alt, oskey))) {
+ if (ELEM(event->modifier, KM_OSKEY, KM_CTRL))
#else
- if (event->ctrl && !IS_EVENT_MOD(event, shift, alt, oskey)) {
+ if (event->modifier == KM_CTRL)
#endif
+ {
if (event->type == EVT_VKEY) {
changed = ui_textedit_copypaste(but, data, UI_TEXTEDIT_PASTE);
}
@@ -3769,16 +3770,16 @@ static void ui_do_but_textedit(
ui_textedit_move(but,
data,
STRCUR_DIR_NEXT,
- event->shift != 0,
- event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
+ event->modifier & KM_SHIFT,
+ (event->modifier & KM_CTRL) ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
retval = WM_UI_HANDLER_BREAK;
break;
case EVT_LEFTARROWKEY:
ui_textedit_move(but,
data,
STRCUR_DIR_PREV,
- event->shift != 0,
- event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
+ event->modifier & KM_SHIFT,
+ (event->modifier & KM_CTRL) ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
retval = WM_UI_HANDLER_BREAK;
break;
case WHEELDOWNMOUSE:
@@ -3795,7 +3796,7 @@ static void ui_do_but_textedit(
}
ATTR_FALLTHROUGH;
case EVT_ENDKEY:
- ui_textedit_move(but, data, STRCUR_DIR_NEXT, event->shift != 0, STRCUR_JUMP_ALL);
+ ui_textedit_move(but, data, STRCUR_DIR_NEXT, event->modifier & KM_SHIFT, STRCUR_JUMP_ALL);
retval = WM_UI_HANDLER_BREAK;
break;
case WHEELUPMOUSE:
@@ -3812,7 +3813,7 @@ static void ui_do_but_textedit(
}
ATTR_FALLTHROUGH;
case EVT_HOMEKEY:
- ui_textedit_move(but, data, STRCUR_DIR_PREV, event->shift != 0, STRCUR_JUMP_ALL);
+ ui_textedit_move(but, data, STRCUR_DIR_PREV, event->modifier & KM_SHIFT, STRCUR_JUMP_ALL);
retval = WM_UI_HANDLER_BREAK;
break;
case EVT_PADENTER:
@@ -3822,13 +3823,13 @@ static void ui_do_but_textedit(
break;
case EVT_DELKEY:
changed = ui_textedit_delete(
- but, data, 1, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
+ but, data, 1, (event->modifier & KM_CTRL) ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
retval = WM_UI_HANDLER_BREAK;
break;
case EVT_BACKSPACEKEY:
changed = ui_textedit_delete(
- but, data, 0, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
+ but, data, 0, (event->modifier & KM_CTRL) ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
retval = WM_UI_HANDLER_BREAK;
break;
@@ -3837,10 +3838,9 @@ static void ui_do_but_textedit(
/* Ctrl-A: Select all. */
#if defined(__APPLE__)
/* 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)))
+ if (ELEM(event->modifier, KM_OSKEY, KM_CTRL))
#else
- if (event->ctrl && !IS_EVENT_MOD(event, shift, alt, oskey))
+ if (event->modifier == KM_CTRL)
#endif
{
ui_textedit_move(but, data, STRCUR_DIR_PREV, false, STRCUR_JUMP_ALL);
@@ -3859,9 +3859,9 @@ static void ui_do_but_textedit(
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
- else if (!IS_EVENT_MOD(event, ctrl, alt, oskey)) {
+ else if ((event->modifier & (KM_CTRL | KM_ALT | KM_OSKEY)) == 0) {
/* Use standard keys for cycling through buttons Tab, Shift-Tab to reverse. */
- if (event->shift) {
+ if (event->modifier & KM_SHIFT) {
ui_textedit_prev_but(block, but, data);
}
else {
@@ -3874,12 +3874,12 @@ static void ui_do_but_textedit(
case EVT_ZKEY: {
/* Ctrl-Z or Ctrl-Shift-Z: Undo/Redo (allowing for OS-Key on Apple). */
- const bool is_redo = (event->shift != 0);
+ const bool is_redo = (event->modifier & KM_SHIFT);
if (
#if defined(__APPLE__)
- (event->oskey && !IS_EVENT_MOD(event, alt, ctrl)) ||
+ ((event->modifier & KM_OSKEY) && ((event->modifier & (KM_ALT | KM_CTRL)) == 0)) ||
#endif
- (event->ctrl && !IS_EVENT_MOD(event, alt, oskey))) {
+ ((event->modifier & KM_CTRL) && ((event->modifier & (KM_ALT | KM_OSKEY)) == 0))) {
int undo_pos;
const char *undo_str = ui_textedit_undo(
data->undo_stack_text, is_redo ? 1 : -1, &undo_pos);
@@ -4542,19 +4542,7 @@ static int ui_do_but_HOTKEYEVT(bContext *C,
}
/* always set */
- but->modifier_key = 0;
- if (event->shift) {
- but->modifier_key |= KM_SHIFT;
- }
- if (event->alt) {
- but->modifier_key |= KM_ALT;
- }
- if (event->ctrl) {
- but->modifier_key |= KM_CTRL;
- }
- if (event->oskey) {
- but->modifier_key |= KM_OSKEY;
- }
+ but->modifier_key = event->modifier;
ui_but_update(but);
ED_region_tag_redraw(data->region);
@@ -4633,7 +4621,8 @@ static int ui_do_but_TAB(
const int rna_type = but->rnaprop ? RNA_property_type(but->rnaprop) : 0;
if (is_property && ELEM(rna_type, PROP_POINTER, PROP_STRING) && (but->custom_data != NULL) &&
- (event->type == LEFTMOUSE) && ((event->val == KM_DBL_CLICK) || event->ctrl)) {
+ (event->type == LEFTMOUSE) &&
+ ((event->val == KM_DBL_CLICK) || (event->modifier & KM_CTRL))) {
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
return WM_UI_HANDLER_BREAK;
}
@@ -4666,7 +4655,8 @@ static int ui_do_but_TEX(
if (ELEM(event->type, EVT_PADENTER, EVT_RETKEY) && (!UI_but_is_utf8(but))) {
/* pass - allow filesel, enter to execute */
}
- else if (ELEM(but->emboss, UI_EMBOSS_NONE, UI_EMBOSS_NONE_OR_STATUS) && !event->ctrl) {
+ else if (ELEM(but->emboss, UI_EMBOSS_NONE, UI_EMBOSS_NONE_OR_STATUS) &&
+ ((event->modifier & KM_CTRL) == 0)) {
/* pass */
}
else {
@@ -4735,7 +4725,7 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons
button_activate_state(C, but, BUTTON_STATE_EXIT);
return WM_UI_HANDLER_BREAK;
}
- if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
+ if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && (event->modifier & KM_CTRL)) {
/* Support Ctrl-Wheel to cycle values on expanded enum rows. */
if (but->type == UI_BTYPE_ROW) {
int type = event->type;
@@ -5325,24 +5315,24 @@ static int ui_do_but_NUM(
}
/* XXX hardcoded keymap check.... */
- if (type == MOUSEPAN && event->ctrl) {
+ if (type == MOUSEPAN && (event->modifier & KM_CTRL)) {
/* allow accumulating values, otherwise scrolling gets preference */
retval = WM_UI_HANDLER_BREAK;
}
- else if (type == WHEELDOWNMOUSE && event->ctrl) {
+ else if (type == WHEELDOWNMOUSE && (event->modifier & KM_CTRL)) {
mx = but->rect.xmin;
but->drawflag &= ~UI_BUT_ACTIVE_RIGHT;
but->drawflag |= UI_BUT_ACTIVE_LEFT;
click = 1;
}
- else if (type == WHEELUPMOUSE && event->ctrl) {
+ else if ((type == WHEELUPMOUSE) && (event->modifier & KM_CTRL)) {
mx = but->rect.xmax;
but->drawflag &= ~UI_BUT_ACTIVE_LEFT;
but->drawflag |= UI_BUT_ACTIVE_RIGHT;
click = 1;
}
else if (event->val == KM_PRESS) {
- if (ELEM(event->type, LEFTMOUSE, EVT_PADENTER, EVT_RETKEY) && event->ctrl) {
+ if (ELEM(event->type, LEFTMOUSE, EVT_PADENTER, EVT_RETKEY) && (event->modifier & KM_CTRL)) {
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
retval = WM_UI_HANDLER_BREAK;
}
@@ -5402,7 +5392,7 @@ static int ui_do_but_NUM(
#endif
fac = 1.0f;
- if (event->shift) {
+ if (event->modifier & KM_SHIFT) {
fac /= 10.0f;
}
@@ -5668,27 +5658,27 @@ static int ui_do_but_SLI(
}
/* XXX hardcoded keymap check.... */
- if (type == MOUSEPAN && event->ctrl) {
+ if ((type == MOUSEPAN) && (event->modifier & KM_CTRL)) {
/* allow accumulating values, otherwise scrolling gets preference */
retval = WM_UI_HANDLER_BREAK;
}
- else if (type == WHEELDOWNMOUSE && event->ctrl) {
+ else if ((type == WHEELDOWNMOUSE) && (event->modifier & KM_CTRL)) {
mx = but->rect.xmin;
click = 2;
}
- else if (type == WHEELUPMOUSE && event->ctrl) {
+ else if ((type == WHEELUPMOUSE) && (event->modifier & KM_CTRL)) {
mx = but->rect.xmax;
click = 2;
}
else if (event->val == KM_PRESS) {
- if (ELEM(event->type, LEFTMOUSE, EVT_PADENTER, EVT_RETKEY) && event->ctrl) {
+ if (ELEM(event->type, LEFTMOUSE, EVT_PADENTER, EVT_RETKEY) && (event->modifier & KM_CTRL)) {
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
retval = WM_UI_HANDLER_BREAK;
}
#ifndef USE_ALLSELECT
/* alt-click on sides to get "arrows" like in UI_BTYPE_NUM buttons,
* and match wheel usage above */
- else if (event->type == LEFTMOUSE && event->alt) {
+ else if ((event->type == LEFTMOUSE) && (event->modifier & KM_ALT)) {
int halfpos = BLI_rctf_cent_x(&but->rect);
click = 2;
if (mx < halfpos) {
@@ -5754,8 +5744,13 @@ static int ui_do_but_SLI(
data->multi_data.drag_dir[0] += abs(data->draglastx - mx);
data->multi_data.drag_dir[1] += abs(data->draglasty - my);
#endif
- if (ui_numedit_but_SLI(
- but, data, mx, true, is_motion, event->ctrl != 0, event->shift != 0)) {
+ if (ui_numedit_but_SLI(but,
+ data,
+ mx,
+ true,
+ is_motion,
+ event->modifier & KM_CTRL,
+ event->modifier & KM_SHIFT)) {
ui_numedit_apply(C, block, but, data);
}
@@ -5981,8 +5976,8 @@ static int ui_do_but_LISTROW(bContext *C,
/* hack to pass on ctrl+click and double click to overlapping text
* editing field for editing list item names
*/
- if ((ELEM(event->type, LEFTMOUSE, EVT_PADENTER, EVT_RETKEY) && event->val == KM_PRESS &&
- event->ctrl) ||
+ if ((ELEM(event->type, LEFTMOUSE, EVT_PADENTER, EVT_RETKEY) && (event->val == KM_PRESS) &&
+ (event->modifier & KM_CTRL)) ||
(event->type == LEFTMOUSE && event->val == KM_DBL_CLICK)) {
uiBut *labelbut = ui_but_list_row_text_activate(
C, but, data, event, BUTTON_ACTIVATE_TEXT_EDITING);
@@ -6023,7 +6018,8 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
return WM_UI_HANDLER_BREAK;
}
if (ui_but_supports_cycling(but)) {
- if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
+ if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) &&
+ (event->modifier & KM_CTRL)) {
int type = event->type;
int val = event->val;
@@ -6210,7 +6206,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
return WM_UI_HANDLER_BREAK;
}
- if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
+ if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && (event->modifier & KM_CTRL)) {
ColorPicker *cpicker = but->custom_data;
float hsv_static[3] = {0.0f};
float *hsv = cpicker ? cpicker->hsv_perceptual : hsv_static;
@@ -6269,7 +6265,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
if (color_but->is_pallete_color) {
- if (!event->ctrl) {
+ if ((event->modifier & KM_CTRL) == 0) {
float color[3];
Paint *paint = BKE_paint_get_active_from_context(C);
Brush *brush = BKE_paint_brush(paint);
@@ -6639,7 +6635,7 @@ static int ui_do_but_HSVCUBE(
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
/* also do drag the first time */
- if (ui_numedit_but_HSVCUBE(but, data, mx, my, snap, event->shift != 0)) {
+ if (ui_numedit_but_HSVCUBE(but, data, mx, my, snap, event->modifier & KM_SHIFT)) {
ui_numedit_apply(C, block, but, data);
}
@@ -6650,7 +6646,7 @@ static int ui_do_but_HSVCUBE(
const wmNDOFMotionData *ndof = event->customdata;
const enum eSnapType snap = ui_event_to_snap(event);
- ui_ndofedit_but_HSVCUBE(hsv_but, data, ndof, snap, event->shift != 0);
+ ui_ndofedit_but_HSVCUBE(hsv_but, data, ndof, snap, event->modifier & KM_SHIFT);
button_activate_state(C, but, BUTTON_STATE_EXIT);
ui_apply_but(C, but->block, but, data, true);
@@ -6702,7 +6698,7 @@ static int ui_do_but_HSVCUBE(
if (mx != data->draglastx || my != data->draglasty || event->type != MOUSEMOVE) {
const enum eSnapType snap = ui_event_to_snap(event);
- if (ui_numedit_but_HSVCUBE(but, data, mx, my, snap, event->shift != 0)) {
+ if (ui_numedit_but_HSVCUBE(but, data, mx, my, snap, event->modifier & KM_SHIFT)) {
ui_numedit_apply(C, block, but, data);
}
}
@@ -6914,7 +6910,7 @@ static int ui_do_but_HSVCIRCLE(
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
/* also do drag the first time */
- if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, event->shift != 0)) {
+ if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, event->modifier & KM_SHIFT)) {
ui_numedit_apply(C, block, but, data);
}
@@ -6925,7 +6921,7 @@ static int ui_do_but_HSVCIRCLE(
const enum eSnapType snap = ui_event_to_snap(event);
const wmNDOFMotionData *ndof = event->customdata;
- ui_ndofedit_but_HSVCIRCLE(but, data, ndof, snap, event->shift != 0);
+ ui_ndofedit_but_HSVCIRCLE(but, data, ndof, snap, event->modifier & KM_SHIFT);
button_activate_state(C, but, BUTTON_STATE_EXIT);
ui_apply_but(C, but->block, but, data, true);
@@ -6987,7 +6983,7 @@ static int ui_do_but_HSVCIRCLE(
if (mx != data->draglastx || my != data->draglasty || event->type != MOUSEMOVE) {
const enum eSnapType snap = ui_event_to_snap(event);
- if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, event->shift != 0)) {
+ if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, event->modifier & KM_SHIFT)) {
ui_numedit_apply(C, block, but, data);
}
}
@@ -7037,7 +7033,7 @@ static int ui_do_but_COLORBAND(
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
ColorBand *coba = (ColorBand *)but->poin;
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
/* insert new key on mouse location */
const float pos = ((float)(mx - but->rect.xmin)) / BLI_rctf_size_x(&but->rect);
BKE_colorband_element_add(coba, pos);
@@ -7237,7 +7233,7 @@ static int ui_do_but_CURVE(
float dist_min_sq = square_f(U.dpi_fac * 14.0f); /* 14 pixels radius */
int sel = -1;
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
float f_xy[2];
BLI_rctf_transform_pt_v(&cumap->curr, &but->rect, f_xy, m_xy);
@@ -7301,7 +7297,7 @@ static int ui_do_but_CURVE(
if (sel != -1) {
/* ok, we move a point */
/* deselect all if this one is deselect. except if we hold shift */
- if (!event->shift) {
+ if ((event->modifier & KM_SHIFT) == 0) {
for (int a = 0; a < cuma->totpoint; a++) {
cmp[a].flag &= ~CUMA_SELECT;
}
@@ -7336,8 +7332,8 @@ static int ui_do_but_CURVE(
data,
event->xy[0],
event->xy[1],
- event->ctrl != 0,
- event->shift != 0)) {
+ event->modifier & KM_CTRL,
+ event->modifier & KM_SHIFT)) {
ui_numedit_apply(C, block, but, data);
}
}
@@ -7350,7 +7346,7 @@ static int ui_do_but_CURVE(
if (data->dragchange == false) {
/* deselect all, select one */
- if (!event->shift) {
+ if ((event->modifier & KM_SHIFT) == 0) {
for (int a = 0; a < cuma->totpoint; a++) {
cmp[a].flag &= ~CUMA_SELECT;
}
@@ -7539,7 +7535,7 @@ static int ui_do_but_CURVEPROFILE(
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
const float m_xy[2] = {mx, my};
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
float f_xy[2];
BLI_rctf_transform_pt_v(&profile->view_rect, &but->rect, f_xy, m_xy);
@@ -7616,7 +7612,7 @@ static int ui_do_but_CURVEPROFILE(
/* Change the flag for the point(s) if one was selected or added. */
if (i_selected != -1) {
/* Deselect all if this one is deselected, except if we hold shift. */
- if (event->shift) {
+ if (event->modifier & KM_SHIFT) {
pts[i_selected].flag ^= selection_type;
}
else {
@@ -7647,7 +7643,7 @@ static int ui_do_but_CURVEPROFILE(
if (event->type == MOUSEMOVE) {
if (mx != data->draglastx || my != data->draglasty) {
if (ui_numedit_but_CURVEPROFILE(
- block, but, data, mx, my, event->ctrl != 0, event->shift != 0)) {
+ block, but, data, mx, my, event->modifier & KM_CTRL, event->modifier & KM_SHIFT)) {
ui_numedit_apply(C, block, but, data);
}
}
@@ -7871,7 +7867,7 @@ static int ui_do_but_TRACKPREVIEW(
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
/* also do drag the first time */
- if (ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift != 0)) {
+ if (ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->modifier & KM_SHIFT)) {
ui_numedit_apply(C, block, but, data);
}
@@ -7888,7 +7884,7 @@ static int ui_do_but_TRACKPREVIEW(
}
else if (event->type == MOUSEMOVE) {
if (mx != data->draglastx || my != data->draglasty) {
- if (ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift != 0)) {
+ if (ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->modifier & KM_SHIFT)) {
ui_numedit_apply(C, block, but, data);
}
}
@@ -7918,8 +7914,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
if (data->state == BUTTON_STATE_HIGHLIGHT) {
/* handle copy and paste */
- bool is_press_ctrl_but_no_shift = event->val == KM_PRESS && IS_EVENT_MOD(event, ctrl, oskey) &&
- !event->shift;
+ bool is_press_ctrl_but_no_shift = (event->val == KM_PRESS) &&
+ (event->modifier & (KM_CTRL | KM_OSKEY)) &&
+ (event->modifier & KM_SHIFT) == 0;
const bool do_copy = event->type == EVT_CKEY && is_press_ctrl_but_no_shift;
const bool do_paste = event->type == EVT_VKEY && is_press_ctrl_but_no_shift;
@@ -7934,12 +7931,14 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
/* do copy first, because it is the only allowed operator when disabled */
if (do_copy) {
- ui_but_copy(C, but, event->alt);
+ ui_but_copy(C, but, event->modifier & KM_ALT);
return WM_UI_HANDLER_BREAK;
}
/* handle menu */
- if ((event->type == RIGHTMOUSE) && !IS_EVENT_MOD(event, shift, ctrl, alt, oskey) &&
+
+ if ((event->type == RIGHTMOUSE) &&
+ (event->modifier & (KM_SHIFT | KM_CTRL | KM_ALT | KM_OSKEY)) == 0 &&
(event->val == KM_PRESS)) {
/* For some button types that are typically representing entire sets of data, right-clicking
* to spawn the context menu should also activate the item. This makes it clear which item
@@ -7960,7 +7959,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
}
if (do_paste) {
- ui_but_paste(C, but, data, event->alt);
+ ui_but_paste(C, but, data, event->modifier & KM_ALT);
return WM_UI_HANDLER_BREAK;
}
@@ -8793,7 +8792,7 @@ uiBut *UI_context_active_but_prop_get(const bContext *C,
return activebut;
}
-void UI_context_active_but_prop_handle(bContext *C)
+void UI_context_active_but_prop_handle(bContext *C, const bool handle_undo)
{
uiBut *activebut = ui_context_rna_button_active(C);
if (activebut) {
@@ -8804,6 +8803,11 @@ void UI_context_active_but_prop_handle(bContext *C)
if (block->handle_func) {
block->handle_func(C, block->handle_func_arg, activebut->retval);
}
+ if (handle_undo) {
+ /* Update the button so the undo text uses the correct value. */
+ ui_but_update(activebut);
+ ui_apply_but_undo(activebut);
+ }
}
}
@@ -8942,7 +8946,7 @@ static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *reg
if (but) {
button_activate_init(C, region, but, BUTTON_ACTIVATE_OVER);
- if (event->alt && but->active) {
+ if ((event->modifier & KM_ALT) && but->active) {
/* Display tool-tips if holding Alt on mouse-over when tool-tips are disabled in the
* preferences. */
but->active->tooltip_force = true;
@@ -8970,7 +8974,7 @@ void ui_but_activate_event(bContext *C, ARegion *region, uiBut *but)
wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
- event.is_repeat = false;
+ event.flag = 0;
event.customdata = but;
event.customdata_free = false;
@@ -9394,7 +9398,7 @@ static int ui_list_activate_hovered_row(bContext *C,
}
}
- const int *mouse_xy = ISTWEAK(event->type) ? event->prev_click_xy : event->xy;
+ const int *mouse_xy = (event->val == KM_CLICK_DRAG) ? event->prev_click_xy : event->xy;
uiBut *listrow = ui_list_row_find_mouse_over(region, mouse_xy);
if (listrow) {
wmOperatorType *custom_activate_optype = ui_list->dyn_data->custom_activate_optype;
@@ -9421,7 +9425,7 @@ static bool ui_list_is_hovering_draggable_but(bContext *C,
const wmEvent *event)
{
/* On a tweak event, uses the coordinates from where tweaking was started. */
- const int *mouse_xy = ISTWEAK(event->type) ? event->prev_click_xy : event->xy;
+ const int *mouse_xy = (event->val == KM_CLICK_DRAG) ? event->prev_click_xy : event->xy;
const uiBut *hovered_but = ui_but_find_mouse_over_ex(region, mouse_xy, false, NULL, NULL);
if (list->dyn_data->custom_drag_optype) {
@@ -9438,7 +9442,7 @@ static int ui_list_handle_click_drag(bContext *C,
ARegion *region,
const wmEvent *event)
{
- if (!ELEM(event->type, LEFTMOUSE, EVT_TWEAK_L)) {
+ if (event->type != LEFTMOUSE) {
return WM_HANDLER_CONTINUE;
}
@@ -9448,7 +9452,7 @@ static int ui_list_handle_click_drag(bContext *C,
bool activate = false;
bool activate_dragging = false;
- if (event->type == EVT_TWEAK_L) {
+ if (event->val == KM_CLICK_DRAG) {
if (is_draggable) {
activate_dragging = true;
activate = true;
@@ -9458,7 +9462,7 @@ static int ui_list_handle_click_drag(bContext *C,
* regular events (including mouse presses to start dragging) and this part only kicks in if it
* hasn't handled the release event. Note that if there's no overlaid button, the row selects
* on the press event already via regular #UI_BTYPE_LISTROW handling. */
- else if ((event->type == LEFTMOUSE) && (event->val == KM_CLICK)) {
+ else if (event->val == KM_CLICK) {
activate = true;
}
@@ -9534,7 +9538,7 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *regi
ui_pan_to_scroll(event, &type, &val);
/* 'ui_pan_to_scroll' gives the absolute direction. */
- if (event->is_direction_inverted) {
+ if (event->flag & WM_EVENT_SCROLL_INVERT) {
scroll_dir = -1;
}
@@ -9545,14 +9549,14 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *regi
}
}
- if (ELEM(event->type, LEFTMOUSE, EVT_TWEAK_L)) {
+ if (event->type == LEFTMOUSE) {
retval = ui_list_handle_click_drag(C, ui_list, region, event);
}
else if (val == KM_PRESS) {
if ((ELEM(type, EVT_UPARROWKEY, EVT_DOWNARROWKEY, EVT_LEFTARROWKEY, EVT_RIGHTARROWKEY) &&
- !IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) ||
- ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->ctrl &&
- !IS_EVENT_MOD(event, shift, alt, oskey)))) {
+ (event->modifier & (KM_SHIFT | KM_CTRL | KM_ALT | KM_OSKEY)) == 0) ||
+ ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && (event->modifier & KM_CTRL) &&
+ (event->modifier & (KM_SHIFT | KM_ALT | KM_OSKEY)) == 0))) {
const int value_orig = RNA_property_int_get(&listbox->rnapoin, listbox->rnaprop);
int value, min, max;
@@ -9609,7 +9613,7 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *regi
}
retval = WM_UI_HANDLER_BREAK;
}
- else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->shift) {
+ else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && (event->modifier & KM_SHIFT)) {
/* We now have proper grip, but keep this anyway! */
if (ui_list->list_grip < (dyn_data->visual_height_min - UI_LIST_AUTO_SIZE_THRESHOLD)) {
ui_list->list_grip = dyn_data->visual_height;
@@ -10263,7 +10267,7 @@ static int ui_handle_menu_event(bContext *C,
/* Smooth scrolling for popovers. */
case MOUSEPAN: {
- if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
+ if (event->modifier & (KM_SHIFT | KM_CTRL | KM_ALT | KM_OSKEY)) {
/* pass */
}
else if (!ui_block_is_menu(block)) {
@@ -10285,7 +10289,7 @@ static int ui_handle_menu_event(bContext *C,
}
case WHEELUPMOUSE:
case WHEELDOWNMOUSE: {
- if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
+ if (event->modifier & (KM_SHIFT | KM_CTRL | KM_ALT | KM_OSKEY)) {
/* pass */
}
else if (!ui_block_is_menu(block)) {
@@ -10308,7 +10312,7 @@ static int ui_handle_menu_event(bContext *C,
case EVT_HOMEKEY:
case EVT_ENDKEY:
/* Arrow-keys: only handle for block_loop blocks. */
- if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
+ if (event->modifier & (KM_SHIFT | KM_CTRL | KM_ALT | KM_OSKEY)) {
/* pass */
}
else if (inside || (block->flag & UI_BLOCK_LOOP)) {
@@ -10455,11 +10459,11 @@ static int ui_handle_menu_event(bContext *C,
/* Only respond to explicit press to avoid the event that opened the menu
* activating an item when the key is held. */
- if (event->is_repeat) {
+ if (event->flag & WM_EVENT_IS_REPEAT) {
break;
}
- if (event->alt) {
+ if (event->modifier & KM_ALT) {
act += 10;
}
@@ -10539,10 +10543,10 @@ static int ui_handle_menu_event(bContext *C,
case EVT_YKEY:
case EVT_ZKEY: {
if (ELEM(event->val, KM_PRESS, KM_DBL_CLICK) &&
- !IS_EVENT_MOD(event, shift, ctrl, oskey) &&
+ ((event->modifier & (KM_SHIFT | KM_CTRL | KM_OSKEY)) == 0) &&
/* Only respond to explicit press to avoid the event that opened the menu
* activating an item when the key is held. */
- !event->is_repeat) {
+ (event->flag & WM_EVENT_IS_REPEAT) == 0) {
if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval)) {
break;
}
@@ -11066,7 +11070,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
case EVT_YKEY:
case EVT_ZKEY: {
if ((ELEM(event->val, KM_PRESS, KM_DBL_CLICK)) &&
- !IS_EVENT_MOD(event, shift, ctrl, oskey)) {
+ ((event->modifier & (KM_SHIFT | KM_CTRL | KM_OSKEY)) == 0)) {
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->menu_key == event->type) {
ui_but_pie_button_activate(C, but, menu);
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index e277aa2e629..9dfc9be2a30 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -573,18 +573,6 @@ int UI_icon_from_event_type(short event_type, short event_value)
else if (event_type == EVT_RIGHTALTKEY) {
event_type = EVT_LEFTALTKEY;
}
- else if (event_type == EVT_TWEAK_L) {
- event_type = LEFTMOUSE;
- event_value = KM_CLICK_DRAG;
- }
- else if (event_type == EVT_TWEAK_M) {
- event_type = MIDDLEMOUSE;
- event_value = KM_CLICK_DRAG;
- }
- else if (event_type == EVT_TWEAK_R) {
- event_type = RIGHTMOUSE;
- event_value = KM_CLICK_DRAG;
- }
DrawInfo *di = g_di_event_list;
do {
@@ -1399,19 +1387,17 @@ static void icon_set_image(const bContext *C,
const bool delay = prv_img->rect[size] != NULL;
icon_create_rect(prv_img, size);
- prv_img->flag[size] |= PRV_RENDERING;
if (use_job && (!id || BKE_previewimg_id_supports_jobs(id))) {
/* Job (background) version */
- ED_preview_icon_job(
- C, prv_img, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size], delay);
+ ED_preview_icon_job(C, prv_img, id, size, delay);
}
else {
if (!scene) {
scene = CTX_data_scene(C);
}
/* Immediate version */
- ED_preview_icon_render(C, scene, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]);
+ ED_preview_icon_render(C, scene, prv_img, id, size);
}
}
@@ -2271,7 +2257,7 @@ int UI_icon_from_idcode(const int idcode)
return ICON_CAMERA_DATA;
case ID_CF:
return ICON_FILE;
- case ID_CU:
+ case ID_CU_LEGACY:
return ICON_CURVE_DATA;
case ID_GD:
return ICON_OUTLINER_DATA_GREASEPENCIL;
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 54a5b496048..bd55d2d9d81 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -492,7 +492,7 @@ static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index)
PointerRNA *ptr = &but->rnapoin;
PropertyRNA *prop = but->rnaprop;
const int index = POINTER_AS_INT(arg_index);
- const int shift = win->eventstate->shift;
+ const bool shift = win->eventstate->modifier & KM_SHIFT;
const int len = RNA_property_array_length(ptr, prop);
if (!shift) {
@@ -752,7 +752,7 @@ static void ui_item_enum_expand_handle(bContext *C, void *arg1, void *arg2)
{
wmWindow *win = CTX_wm_window(C);
- if (!win->eventstate->shift) {
+ if ((win->eventstate->modifier & KM_SHIFT) == 0) {
uiBut *but = (uiBut *)arg1;
const int enum_value = POINTER_AS_INT(arg2);
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index a96f14d7435..498c22748ce 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -314,7 +314,7 @@ static int operator_button_property_finish(bContext *C, PointerRNA *ptr, Propert
RNA_property_update(C, ptr, prop);
/* as if we pressed the button */
- UI_context_active_but_prop_handle(C);
+ UI_context_active_but_prop_handle(C, false);
/* Since we don't want to undo _all_ edits to settings, eg window
* edits on the screen or on operator settings.
@@ -326,6 +326,19 @@ static int operator_button_property_finish(bContext *C, PointerRNA *ptr, Propert
return OPERATOR_CANCELLED;
}
+static int operator_button_property_finish_with_undo(bContext *C,
+ PointerRNA *ptr,
+ PropertyRNA *prop)
+{
+ /* Perform updates required for this property. */
+ RNA_property_update(C, ptr, prop);
+
+ /* As if we pressed the button. */
+ UI_context_active_but_prop_handle(C, true);
+
+ return OPERATOR_FINISHED;
+}
+
static bool reset_default_button_poll(bContext *C)
{
PointerRNA ptr;
@@ -350,7 +363,7 @@ static int reset_default_button_exec(bContext *C, wmOperator *op)
/* if there is a valid property that is editable... */
if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
if (RNA_property_reset(&ptr, prop, (all) ? -1 : index)) {
- return operator_button_property_finish(C, &ptr, prop);
+ return operator_button_property_finish_with_undo(C, &ptr, prop);
}
}
@@ -369,7 +382,9 @@ static void UI_OT_reset_default_button(wmOperatorType *ot)
ot->exec = reset_default_button_exec;
/* flags */
- ot->flag = OPTYPE_UNDO;
+ /* Don't set #OPTYPE_UNDO because #operator_button_property_finish_with_undo
+ * is responsible for the undo push. */
+ ot->flag = 0;
/* properties */
RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array");
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 2cb0f256b71..c7f2eb230cb 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -2061,8 +2061,8 @@ static void ui_handle_panel_header(const bContext *C,
const uiBlock *block,
const int mx,
const int event_type,
- const short ctrl,
- const short shift)
+ const bool ctrl,
+ const bool shift)
{
Panel *panel = block->panel;
ARegion *region = CTX_wm_region(C);
@@ -2274,7 +2274,7 @@ static int ui_handle_panel_category_cycling(const wmEvent *event,
(event->mval[0] > ((PanelCategoryDyn *)region->panels_category.first)->rect.xmin));
/* If mouse is inside non-tab region, ctrl key is required. */
- if (is_mousewheel && !event->ctrl && !inside_tabregion) {
+ if (is_mousewheel && (event->modifier & KM_CTRL) == 0 && !inside_tabregion) {
return WM_UI_HANDLER_CONTINUE;
}
@@ -2291,7 +2291,7 @@ static int ui_handle_panel_category_cycling(const wmEvent *event,
pc_dyn = (event->type == WHEELDOWNMOUSE) ? pc_dyn->next : pc_dyn->prev;
}
else {
- const bool backwards = event->shift;
+ const bool backwards = event->modifier & KM_SHIFT;
pc_dyn = backwards ? pc_dyn->prev : pc_dyn->next;
if (!pc_dyn) {
/* Proper cyclic behavior, back to first/last category (only used for ctrl+tab). */
@@ -2349,7 +2349,7 @@ int ui_handler_panel_region(bContext *C,
retval = WM_UI_HANDLER_BREAK;
}
}
- else if ((event->type == EVT_TABKEY && event->ctrl) ||
+ else if (((event->type == EVT_TABKEY) && (event->modifier & KM_CTRL)) ||
ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
/* Cycle tabs. */
retval = ui_handle_panel_category_cycling(event, region, active_but);
@@ -2386,9 +2386,11 @@ int ui_handler_panel_region(bContext *C,
/* The panel collapse / expand key "A" is special as it takes priority over
* active button handling. */
- if (event->type == EVT_AKEY && !IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
+ if (event->type == EVT_AKEY &&
+ ((event->modifier & (KM_SHIFT | KM_CTRL | KM_ALT | KM_OSKEY)) == 0)) {
retval = WM_UI_HANDLER_BREAK;
- ui_handle_panel_header(C, block, mx, event->type, event->ctrl, event->shift);
+ ui_handle_panel_header(
+ C, block, mx, event->type, event->modifier & KM_CTRL, event->modifier & KM_SHIFT);
break;
}
}
@@ -2402,7 +2404,8 @@ int ui_handler_panel_region(bContext *C,
/* All mouse clicks inside panel headers should return in break. */
if (ELEM(event->type, EVT_RETKEY, EVT_PADENTER, LEFTMOUSE)) {
retval = WM_UI_HANDLER_BREAK;
- ui_handle_panel_header(C, block, mx, event->type, event->ctrl, event->shift);
+ ui_handle_panel_header(
+ C, block, mx, event->type, event->modifier & KM_CTRL, event->modifier & KM_SHIFT);
}
else if (event->type == RIGHTMOUSE) {
retval = WM_UI_HANDLER_BREAK;
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index 8a945c8c913..4703367671d 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -310,7 +310,7 @@ uiBut *ui_but_find_mouse_over_ex(const ARegion *region,
uiBut *ui_but_find_mouse_over(const ARegion *region, const wmEvent *event)
{
- return ui_but_find_mouse_over_ex(region, event->xy, event->ctrl != 0, NULL, NULL);
+ return ui_but_find_mouse_over_ex(region, event->xy, event->modifier & KM_CTRL, NULL, NULL);
}
uiBut *ui_but_find_rect_over(const struct ARegion *region, const rcti *rect_px)
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index 09faf493ce7..29553ff65d1 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -701,7 +701,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
/* Keymap */
/* This is too handy not to expose somehow, let's be sneaky for now. */
- if ((is_label == false) && CTX_wm_window(C)->eventstate->shift) {
+ if ((is_label == false) && CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
const char *expr_imports[] = {"bpy", "bl_ui", NULL};
char expr[256];
SNPRINTF(expr,
diff --git a/source/blender/editors/interface/interface_template_list.cc b/source/blender/editors/interface/interface_template_list.cc
index 40675da71a9..6139ac8e702 100644
--- a/source/blender/editors/interface/interface_template_list.cc
+++ b/source/blender/editors/interface/interface_template_list.cc
@@ -598,7 +598,7 @@ static char *uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const cha
}
/**
- * \note Note that \a layout_type may be null.
+ * \note that \a layout_type may be null.
*/
static uiList *ui_list_ensure(bContext *C,
uiListType *ui_list_type,
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 2b7ca1f8b71..32b3bb5e926 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -609,7 +609,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
RNA_property_update(C, &template_ui->ptr, template_ui->prop);
- if (id && CTX_wm_window(C)->eventstate->shift) {
+ if (id && CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
/* only way to force-remove data (on save) */
id_us_clear_real(id);
id_fake_user_clear(id);
@@ -635,7 +635,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
case UI_ID_LOCAL:
if (id) {
Main *bmain = CTX_data_main(C);
- if (CTX_wm_window(C)->eventstate->shift) {
+ if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
if (ID_IS_OVERRIDABLE_LIBRARY(id)) {
/* Only remap that specific ID usage to overriding local data-block. */
ID *override_id = BKE_lib_override_library_create_from_id(bmain, id, false);
@@ -731,7 +731,7 @@ static const char *template_id_browse_tip(const StructRNA *type)
return N_("Browse Object to be linked");
case ID_ME:
return N_("Browse Mesh Data to be linked");
- case ID_CU:
+ case ID_CU_LEGACY:
return N_("Browse Curve Data to be linked");
case ID_MB:
return N_("Browse Metaball Data to be linked");
@@ -844,7 +844,7 @@ static uiBut *template_id_def_new_but(uiBlock *block,
BLT_I18NCONTEXT_ID_SCENE,
BLT_I18NCONTEXT_ID_OBJECT,
BLT_I18NCONTEXT_ID_MESH,
- BLT_I18NCONTEXT_ID_CURVE,
+ BLT_I18NCONTEXT_ID_CURVE_LEGACY,
BLT_I18NCONTEXT_ID_METABALL,
BLT_I18NCONTEXT_ID_MATERIAL,
BLT_I18NCONTEXT_ID_TEXTURE,
@@ -5539,7 +5539,7 @@ static void handle_layer_buttons(bContext *C, void *arg1, void *arg2)
uiBut *but = arg1;
const int cur = POINTER_AS_INT(arg2);
wmWindow *win = CTX_wm_window(C);
- const int shift = win->eventstate->shift;
+ const bool shift = win->eventstate->modifier & KM_SHIFT;
if (!shift) {
const int tot = RNA_property_array_length(&but->rnapoin, but->rnaprop);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index fbbf3c6fdf1..d1f3843c643 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -2579,7 +2579,7 @@ static void widget_state(uiWidgetType *wt, int state, int drawflag, eUIEmbossTyp
*
* A lot of places of the UI like the Node Editor or panels are zoomable. In most cases we can
* get the zoom factor from the aspect, but in some cases like popups we need to fall back to
- * using the the size of the element. The latter method relies on the element always being the same
+ * using the size of the element. The latter method relies on the element always being the same
* size.
* \{ */
@@ -4293,7 +4293,7 @@ static void widget_tab(
const bool is_active = (state & UI_SELECT);
/* Draw shaded outline - Disabled for now,
- * seems incorrect and also looks nicer without it imho ;) */
+ * seems incorrect and also looks nicer without it IMHO ;). */
// #define USE_TAB_SHADED_HIGHLIGHT
uchar theme_col_tab_highlight[3];
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 09d57d3ea99..28a025ee581 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -1449,7 +1449,7 @@ static int view2d_ndof_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* tune these until it feels right */
const float zoom_sensitivity = 0.5f;
const float speed = 10.0f; /* match view3d ortho */
- const bool has_translate = (ndof->tvec[0] && ndof->tvec[1]) && view_pan_poll(C);
+ const bool has_translate = !is_zero_v2(ndof->tvec) && view_pan_poll(C);
const bool has_zoom = (ndof->tvec[2] != 0.0f) && view_zoom_poll(C);
if (has_translate) {
diff --git a/source/blender/editors/io/io_obj.c b/source/blender/editors/io/io_obj.c
index 28e14a14f5f..1c821eebdee 100644
--- a/source/blender/editors/io/io_obj.c
+++ b/source/blender/editors/io/io_obj.c
@@ -38,12 +38,12 @@ static const EnumPropertyItem io_obj_transform_axis_forward[] = {
{OBJ_AXIS_Z_FORWARD, "Z_FORWARD", 0, "Z", "Positive Z axis"},
{OBJ_AXIS_NEGATIVE_X_FORWARD, "NEGATIVE_X_FORWARD", 0, "-X", "Negative X axis"},
{OBJ_AXIS_NEGATIVE_Y_FORWARD, "NEGATIVE_Y_FORWARD", 0, "-Y", "Negative Y axis"},
- {OBJ_AXIS_NEGATIVE_Z_FORWARD, "NEGATIVE_Z_FORWARD", 0, "-Z (Default)", "Negative Z axis"},
+ {OBJ_AXIS_NEGATIVE_Z_FORWARD, "NEGATIVE_Z_FORWARD", 0, "-Z", "Negative Z axis"},
{0, NULL, 0, NULL, NULL}};
static const EnumPropertyItem io_obj_transform_axis_up[] = {
{OBJ_AXIS_X_UP, "X_UP", 0, "X", "Positive X axis"},
- {OBJ_AXIS_Y_UP, "Y_UP", 0, "Y (Default)", "Positive Y axis"},
+ {OBJ_AXIS_Y_UP, "Y_UP", 0, "Y", "Positive Y axis"},
{OBJ_AXIS_Z_UP, "Z_UP", 0, "Z", "Positive Z axis"},
{OBJ_AXIS_NEGATIVE_X_UP, "NEGATIVE_X_UP", 0, "-X", "Negative X axis"},
{OBJ_AXIS_NEGATIVE_Y_UP, "NEGATIVE_Y_UP", 0, "-Y", "Negative Y axis"},
@@ -55,7 +55,7 @@ static const EnumPropertyItem io_obj_export_evaluation_mode[] = {
{DAG_EVAL_VIEWPORT,
"DAG_EVAL_VIEWPORT",
0,
- "Viewport (Default)",
+ "Viewport",
"Export objects as they appear in the viewport"},
{0, NULL, 0, NULL, NULL}};
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index 429db50f321..e53dda1760e 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -546,7 +546,7 @@ static void edbm_bevel_mouse_set_value(wmOperator *op, const wmEvent *event)
value = value_start[vmode] + value * opdata->scale[vmode];
/* Fake shift-transform... */
- if (event->shift) {
+ if (event->modifier & KM_SHIFT) {
if (opdata->shift_value[vmode] < 0.0f) {
opdata->shift_value[vmode] = (vmode == SEGMENTS_VALUE) ?
opdata->segments :
diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c
index 58bd906101c..7b251b77750 100644
--- a/source/blender/editors/mesh/editmesh_bisect.c
+++ b/source/blender/editors/mesh/editmesh_bisect.c
@@ -77,14 +77,14 @@ static void mesh_bisect_interactive_calc(bContext *C,
const float *co_ref = rv3d->ofs;
float co_a_ss[2] = {x_start, y_start}, co_b_ss[2] = {x_end, y_end}, co_delta_ss[2];
float co_a[3], co_b[3];
- const float zfac = ED_view3d_calc_zfac(rv3d, co_ref, NULL);
+ const float zfac = ED_view3d_calc_zfac(rv3d, co_ref);
/* view vector */
ED_view3d_win_to_vector(region, co_a_ss, co_a);
/* view delta */
sub_v2_v2v2(co_delta_ss, co_a_ss, co_b_ss);
- ED_view3d_win_to_delta(region, co_delta_ss, co_b, zfac);
+ ED_view3d_win_to_delta(region, co_delta_ss, zfac, co_b);
/* cross both to get a normal */
cross_v3_v3v3(plane_no, co_a, co_b);
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
index 84bda411d4a..bce46dd7cf7 100644
--- a/source/blender/editors/mesh/editmesh_knife_project.c
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -58,7 +58,7 @@ static LinkNode *knifeproject_poly_from_object(const bContext *C,
}
me_eval_needs_free = false;
}
- else if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
+ else if (ELEM(ob->type, OB_FONT, OB_CURVES_LEGACY, OB_SURF)) {
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
me_eval = BKE_mesh_new_nomain_from_curve(ob_eval);
me_eval_needs_free = true;
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 72844908685..c9fc48c3568 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -581,7 +581,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
handled = true;
break;
case MOUSEPAN:
- if (event->alt == 0) {
+ if ((event->modifier & KM_ALT) == 0) {
cuts += 0.02f * (event->xy[1] - event->prev_xy[1]);
if (cuts < 1 && lcd->cuts >= 1) {
cuts = 1;
@@ -598,7 +598,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->val == KM_RELEASE) {
break;
}
- if (event->alt == 0) {
+ if ((event->modifier & KM_ALT) == 0) {
cuts += 1;
}
else {
@@ -612,7 +612,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->val == KM_RELEASE) {
break;
}
- if (event->alt == 0) {
+ if ((event->modifier & KM_ALT) == 0) {
cuts = max_ff(cuts - 1, 1);
}
else {
@@ -755,7 +755,8 @@ void MESH_OT_loopcut(wmOperatorType *ot)
RNA_def_property_enum_items(prop, rna_enum_proportional_falloff_curve_only_items);
RNA_def_property_enum_default(prop, PROP_INVSQUARE);
RNA_def_property_ui_text(prop, "Falloff", "Falloff type the feather");
- RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
+ RNA_def_property_translation_context(prop,
+ BLT_I18NCONTEXT_ID_CURVE_LEGACY); /* Abusing id_curve :/ */
/* For redo only. */
prop = RNA_def_int(ot->srna, "object_index", -1, -1, INT_MAX, "Object Index", "", 0, INT_MAX);
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index fc1d60fc768..d8fc7a4f9d4 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -1367,10 +1367,10 @@ static int edbm_select_mode_invoke(bContext *C, wmOperator *op, const wmEvent *e
/* detecting these options based on shift/ctrl here is weak, but it's done
* to make this work when clicking buttons or menus */
if (!RNA_struct_property_is_set(op->ptr, "use_extend")) {
- RNA_boolean_set(op->ptr, "use_extend", event->shift);
+ RNA_boolean_set(op->ptr, "use_extend", event->modifier & KM_SHIFT);
}
if (!RNA_struct_property_is_set(op->ptr, "use_expand")) {
- RNA_boolean_set(op->ptr, "use_expand", event->ctrl);
+ RNA_boolean_set(op->ptr, "use_expand", event->modifier & KM_CTRL);
}
return edbm_select_mode_exec(C, op);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index a1e661cf2ac..2577218d6a9 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -269,7 +269,8 @@ static void mesh_operator_edgering_props(wmOperatorType *ot,
RNA_def_property_enum_items(prop, rna_enum_proportional_falloff_curve_only_items);
RNA_def_property_enum_default(prop, PROP_SMOOTH);
RNA_def_property_ui_text(prop, "Profile Shape", "Shape of the profile");
- RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
+ RNA_def_property_translation_context(prop,
+ BLT_I18NCONTEXT_ID_CURVE_LEGACY); /* Abusing id_curve :/ */
}
static void mesh_operator_edgering_props_get(wmOperator *op, struct EdgeRingOpSubdProps *op_props)
@@ -9640,13 +9641,13 @@ static int edbm_smooth_normals_exec(bContext *C, wmOperator *op)
float(*smooth_normal)[3] = MEM_callocN(sizeof(*smooth_normal) * lnors_ed_arr->totloop,
__func__);
- /* This is weird choice of operation, taking all loops of faces of current vertex.
- * Could lead to some rather far away loops weighting as much as very close ones
+ /* NOTE(@mont29): This is weird choice of operation, taking all loops of faces of current
+ * vertex. Could lead to some rather far away loops weighting as much as very close ones
* (topologically speaking), with complex polygons.
* Using topological distance here (rather than geometrical one)
- * makes sense imho, but would rather go with a more consistent and flexible code,
- * we could even add max topological distance to take into account, * and a weighting curve.
- * Would do that later though, think for now we can live with that choice. --mont29. */
+ * makes sense IMHO, but would rather go with a more consistent and flexible code,
+ * we could even add max topological distance to take into account, and a weighting curve.
+ * Would do that later though, think for now we can live with that choice. */
BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
l = lnor_ed->loop;
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 92f2f859965..417fdca4988 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -632,7 +632,7 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key, Undo
return um;
}
-static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em, Key *key)
+static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em)
{
BMEditMesh *em_tmp;
BMesh *bm;
@@ -688,29 +688,6 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em, Key *
bm->spacearr_dirty = BM_SPACEARR_DIRTY_ALL;
- /* T35170: Restore the active key on the RealMesh. Otherwise 'fake' offset propagation happens
- * if the active is a basis for any other. */
- if (key && (key->type == KEY_RELATIVE)) {
- /* Since we can't add, remove or reorder keyblocks in editmode, it's safe to assume
- * shapenr from restored bmesh and keyblock indices are in sync. */
- const int kb_act_idx = ob->shapenr - 1;
-
- /* If it is, let's patch the current mesh key block to its restored value.
- * Else, the offsets won't be computed and it won't matter. */
- if (BKE_keyblock_is_basis(key, kb_act_idx)) {
- KeyBlock *kb_act = BLI_findlink(&key->block, kb_act_idx);
-
- if (kb_act->totelem != um->me.totvert) {
- /* The current mesh has some extra/missing verts compared to the undo, adjust. */
- MEM_SAFE_FREE(kb_act->data);
- kb_act->data = MEM_mallocN((size_t)(key->elemsize) * bm->totvert, __func__);
- kb_act->totelem = um->me.totvert;
- }
-
- BKE_keyblock_update_from_mesh(&um->me, kb_act);
- }
- }
-
ob->shapenr = um->shapenr;
MEM_freeN(em_tmp);
@@ -858,7 +835,7 @@ static void mesh_undosys_step_decode(struct bContext *C,
continue;
}
BMEditMesh *em = me->edit_mesh;
- undomesh_to_editmesh(&elem->data, obedit, em, me->key);
+ undomesh_to_editmesh(&elem->data, obedit, em);
em->needs_flush_to_id = 1;
DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
}
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 49a5345d048..b3f90880388 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -21,6 +21,7 @@
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_report.h"
#include "DEG_depsgraph.h"
@@ -1110,6 +1111,8 @@ static void mesh_add_verts(Mesh *mesh, int len)
mesh->vdata = vdata;
BKE_mesh_update_customdata_pointers(mesh, false);
+ BKE_mesh_runtime_clear_cache(mesh);
+
/* scan the input list and insert the new vertices */
/* set default flags */
@@ -1146,6 +1149,8 @@ static void mesh_add_edges(Mesh *mesh, int len)
mesh->edata = edata;
BKE_mesh_update_customdata_pointers(mesh, false); /* new edges don't change tessellation */
+ BKE_mesh_runtime_clear_cache(mesh);
+
/* set default flags */
medge = &mesh->medge[mesh->totedge];
for (i = 0; i < len; i++, medge++) {
@@ -1174,6 +1179,8 @@ static void mesh_add_loops(Mesh *mesh, int len)
CustomData_add_layer(&ldata, CD_MLOOP, CD_CALLOC, NULL, totloop);
}
+ BKE_mesh_runtime_clear_cache(mesh);
+
CustomData_free(&mesh->ldata, mesh->totloop);
mesh->ldata = ldata;
BKE_mesh_update_customdata_pointers(mesh, true);
@@ -1205,6 +1212,8 @@ static void mesh_add_polys(Mesh *mesh, int len)
mesh->pdata = pdata;
BKE_mesh_update_customdata_pointers(mesh, true);
+ BKE_mesh_runtime_clear_cache(mesh);
+
/* set default flags */
mpoly = &mesh->mpoly[mesh->totpoly];
for (i = 0; i < len; i++, mpoly++) {
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 5a8708c84b6..f3782c17845 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -412,6 +412,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
* Even though this mesh wont typically have run-time data, the Python API can for e.g.
* create loop-triangle cache here, which is confusing when left in the mesh, see: T90798. */
BKE_mesh_runtime_clear_geometry(me);
+ BKE_mesh_clear_derived_normals(me);
/* new material indices and material array */
if (totmat) {
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index 54db59dc2fa..39ccadd1445 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -8,6 +8,7 @@ set(INC
../../blentranslation
../../bmesh
../../depsgraph
+ ../../functions
../../gpencil_modifiers
../../gpu
../../ikplugin
@@ -28,7 +29,7 @@ set(INC
)
set(SRC
- object_add.c
+ object_add.cc
object_bake.c
object_bake_api.c
object_collection.c
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.cc
index c2d811f56dc..7befad3b8d7 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.cc
@@ -5,9 +5,9 @@
* \ingroup edobj
*/
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cctype>
+#include <cstdlib>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -93,6 +93,7 @@
#include "ED_armature.h"
#include "ED_curve.h"
+#include "ED_curves.h"
#include "ED_gpencil.h"
#include "ED_mball.h"
#include "ED_mesh.h"
@@ -122,7 +123,7 @@ const EnumPropertyItem rna_enum_light_type_items[] = {
{LA_SUN, "SUN", ICON_LIGHT_SUN, "Sun", "Constant direction parallel ray light source"},
{LA_SPOT, "SPOT", ICON_LIGHT_SPOT, "Spot", "Directional cone light source"},
{LA_AREA, "AREA", ICON_LIGHT_AREA, "Area", "Directional area light source"},
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
/* copy from rna_object_force.c */
@@ -140,7 +141,7 @@ static const EnumPropertyItem field_type_items[] = {
{PFIELD_TURBULENCE, "TURBULENCE", ICON_FORCE_TURBULENCE, "Turbulence", ""},
{PFIELD_DRAG, "DRAG", ICON_FORCE_DRAG, "Drag", ""},
{PFIELD_FLUIDFLOW, "FLUID", ICON_FORCE_FLUIDFLOW, "Fluid Flow", ""},
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
static EnumPropertyItem lightprobe_type_items[] = {
@@ -159,7 +160,7 @@ static EnumPropertyItem lightprobe_type_items[] = {
ICON_LIGHTPROBE_GRID,
"Irradiance Volume",
"Irradiance probe to capture diffuse indirect lighting"},
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
enum {
@@ -172,7 +173,7 @@ static const EnumPropertyItem align_options[] = {
{ALIGN_WORLD, "WORLD", 0, "World", "Align the new object to the world"},
{ALIGN_VIEW, "VIEW", 0, "View", "Align the new object to the view"},
{ALIGN_CURSOR, "CURSOR", 0, "3D Cursor", "Use the 3D cursor orientation for the new object"},
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
/** \} */
@@ -198,7 +199,7 @@ static void object_add_drop_xy_props(wmOperatorType *ot)
"X-coordinate (screen space) to place the new object under",
INT_MIN,
INT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
prop = RNA_def_int(ot->srna,
"drop_y",
0,
@@ -208,7 +209,7 @@ static void object_add_drop_xy_props(wmOperatorType *ot)
"Y-coordinate (screen space) to place the new object under",
INT_MIN,
INT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
}
static bool object_add_drop_xy_is_set(const wmOperator *op)
@@ -343,13 +344,13 @@ float ED_object_new_primitive_matrix(bContext *C,
invert_m3_m3(imat, mat);
mul_m3_v3(imat, r_primmat[3]);
- if (scale != NULL) {
+ if (scale != nullptr) {
rescale_m4(r_primmat, scale);
}
{
- const float dia = v3d ? ED_view3d_grid_scale(scene, v3d, NULL) :
- ED_scene_grid_scale(scene, NULL);
+ const float dia = v3d ? ED_view3d_grid_scale(scene, v3d, nullptr) :
+ ED_scene_grid_scale(scene, nullptr);
return dia;
}
@@ -393,20 +394,20 @@ void ED_object_add_generic_props(wmOperatorType *ot, bool do_editmode)
if (do_editmode) {
prop = RNA_def_boolean(ot->srna,
"enter_editmode",
- 0,
+ false,
"Enter Edit Mode",
"Enter edit mode when adding this object");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
}
/* NOTE: this property gets hidden for add-camera operator. */
prop = RNA_def_enum(
ot->srna, "align", align_options, ALIGN_WORLD, "Align", "The alignment of the new object");
- RNA_def_property_update_runtime(prop, view_align_update);
+ RNA_def_property_update_runtime(prop, (void *)view_align_update);
prop = RNA_def_float_vector_xyz(ot->srna,
"location",
3,
- NULL,
+ nullptr,
-OBJECT_ADD_SIZE_MAXF,
OBJECT_ADD_SIZE_MAXF,
"Location",
@@ -417,7 +418,7 @@ void ED_object_add_generic_props(wmOperatorType *ot, bool do_editmode)
prop = RNA_def_float_rotation(ot->srna,
"rotation",
3,
- NULL,
+ nullptr,
-OBJECT_ADD_SIZE_MAXF,
OBJECT_ADD_SIZE_MAXF,
"Rotation",
@@ -429,14 +430,14 @@ void ED_object_add_generic_props(wmOperatorType *ot, bool do_editmode)
prop = RNA_def_float_vector_xyz(ot->srna,
"scale",
3,
- NULL,
+ nullptr,
-OBJECT_ADD_SIZE_MAXF,
OBJECT_ADD_SIZE_MAXF,
"Scale",
"Scale for the newly added object",
-1000.0f,
1000.0f);
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
}
void ED_object_add_mesh_props(wmOperatorType *ot)
@@ -461,11 +462,11 @@ bool ED_object_add_generic_get_opts(bContext *C,
r_enter_editmode = &_enter_editmode;
}
/* Only to ensure the value is _always_ set.
- * Typically the property will exist when the argument is non-NULL. */
+ * Typically the property will exist when the argument is non-nullptr. */
*r_enter_editmode = false;
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "enter_editmode");
- if (prop != NULL) {
+ if (prop != nullptr) {
if (RNA_property_is_set(op->ptr, prop) && r_enter_editmode) {
*r_enter_editmode = RNA_property_boolean_get(op->ptr, prop);
}
@@ -571,7 +572,7 @@ bool ED_object_add_generic_get_opts(bContext *C,
copy_v3_fl(r_scale, 1.0f);
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "scale");
- if (prop != NULL) {
+ if (prop != nullptr) {
if (RNA_property_is_set(op->ptr, prop)) {
RNA_property_float_get_array(op->ptr, prop, r_scale);
}
@@ -600,19 +601,19 @@ Object *ED_object_add_type_with_obdata(bContext *C,
{
Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
- if (obedit != NULL) {
+ if (obedit != nullptr) {
ED_object_editmode_exit_ex(bmain, scene, obedit, EM_FREEDATA);
}
}
/* deselects all, sets active object */
Object *ob;
- if (obdata != NULL) {
+ if (obdata != nullptr) {
BLI_assert(type == BKE_object_obdata_to_type(obdata));
ob = BKE_object_add_for_data(bmain, view_layer, type, name, obdata, true);
const short *materials_len_p = BKE_id_material_len_p(obdata);
if (materials_len_p && *materials_len_p > 0) {
- BKE_object_materials_test(bmain, ob, ob->data);
+ BKE_object_materials_test(bmain, ob, static_cast<ID *>(ob->data));
}
}
else {
@@ -630,7 +631,7 @@ Object *ED_object_add_type_with_obdata(bContext *C,
*/
DEG_id_type_tag(bmain, ID_OB);
DEG_relations_tag_update(bmain);
- if (ob->data != NULL) {
+ if (ob->data != nullptr) {
DEG_id_tag_update_ex(bmain, (ID *)ob->data, ID_RECALC_EDITORS);
}
@@ -657,7 +658,7 @@ Object *ED_object_add_type(bContext *C,
const ushort local_view_bits)
{
return ED_object_add_type_with_obdata(
- C, type, name, loc, rot, enter_editmode, local_view_bits, NULL);
+ C, type, name, loc, rot, enter_editmode, local_view_bits, nullptr);
}
/* for object add operator */
@@ -668,12 +669,12 @@ static int object_add_exec(bContext *C, wmOperator *op)
float loc[3], rot[3], radius;
WM_operator_view3d_unit_defaults(C, op);
if (!ED_object_add_generic_get_opts(
- C, op, 'Z', loc, rot, NULL, &enter_editmode, &local_view_bits, NULL)) {
+ C, op, 'Z', loc, rot, nullptr, &enter_editmode, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
radius = RNA_float_get(op->ptr, "radius");
Object *ob = ED_object_add_type(
- C, RNA_enum_get(op->ptr, "type"), NULL, loc, rot, enter_editmode, local_view_bits);
+ C, RNA_enum_get(op->ptr, "type"), nullptr, loc, rot, enter_editmode, local_view_bits);
if (ob->type == OB_LATTICE) {
/* lattice is a special case!
@@ -737,7 +738,7 @@ static int lightprobe_add_exec(bContext *C, wmOperator *op)
float loc[3], rot[3];
WM_operator_view3d_unit_defaults(C, op);
if (!ED_object_add_generic_get_opts(
- C, op, 'Z', loc, rot, NULL, &enter_editmode, &local_view_bits, NULL)) {
+ C, op, 'Z', loc, rot, nullptr, &enter_editmode, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
int type = RNA_enum_get(op->ptr, "type");
@@ -829,26 +830,25 @@ static int effector_add_exec(bContext *C, wmOperator *op)
float loc[3], rot[3];
WM_operator_view3d_unit_defaults(C, op);
if (!ED_object_add_generic_get_opts(
- C, op, 'Z', loc, rot, NULL, &enter_editmode, &local_view_bits, NULL)) {
+ C, op, 'Z', loc, rot, nullptr, &enter_editmode, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
- int type = RNA_enum_get(op->ptr, "type");
+ const ePFieldType type = static_cast<ePFieldType>(RNA_enum_get(op->ptr, "type"));
float dia = RNA_float_get(op->ptr, "radius");
Object *ob;
if (type == PFIELD_GUIDE) {
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Curve *cu;
ob = ED_object_add_type(
- C, OB_CURVE, get_effector_defname(type), loc, rot, false, local_view_bits);
+ C, OB_CURVES_LEGACY, get_effector_defname(type), loc, rot, false, local_view_bits);
- cu = ob->data;
+ Curve *cu = static_cast<Curve *>(ob->data);
cu->flag |= CU_PATH | CU_3D;
ED_object_editmode_enter_ex(bmain, scene, ob, 0);
float mat[4][4];
- ED_object_new_primitive_matrix(C, ob, loc, rot, NULL, mat);
+ ED_object_new_primitive_matrix(C, ob, loc, rot, nullptr, mat);
mul_mat3_m4_fl(mat, dia);
BLI_addtail(&cu->editnurb->nurbs,
ED_curve_add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, 1));
@@ -909,22 +909,23 @@ static int object_camera_add_exec(bContext *C, wmOperator *op)
bool enter_editmode;
float loc[3], rot[3];
if (!ED_object_add_generic_get_opts(
- C, op, 'Z', loc, rot, NULL, &enter_editmode, &local_view_bits, NULL)) {
+ C, op, 'Z', loc, rot, nullptr, &enter_editmode, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
- Object *ob = ED_object_add_type(C, OB_CAMERA, NULL, loc, rot, false, local_view_bits);
+ Object *ob = ED_object_add_type(C, OB_CAMERA, nullptr, loc, rot, false, local_view_bits);
if (v3d) {
- if (v3d->camera == NULL) {
+ if (v3d->camera == nullptr) {
v3d->camera = ob;
}
- if (v3d->scenelock && scene->camera == NULL) {
+ if (v3d->scenelock && scene->camera == nullptr) {
scene->camera = ob;
}
}
- Camera *cam = ob->data;
- cam->drawsize = v3d ? ED_view3d_grid_scale(scene, v3d, NULL) : ED_scene_grid_scale(scene, NULL);
+ Camera *cam = static_cast<Camera *>(ob->data);
+ cam->drawsize = v3d ? ED_view3d_grid_scale(scene, v3d, nullptr) :
+ ED_scene_grid_scale(scene, nullptr);
return OPERATOR_FINISHED;
}
@@ -969,14 +970,14 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op)
float loc[3], rot[3];
WM_operator_view3d_unit_defaults(C, op);
if (!ED_object_add_generic_get_opts(
- C, op, 'Z', loc, rot, NULL, &enter_editmode, &local_view_bits, NULL)) {
+ C, op, 'Z', loc, rot, nullptr, &enter_editmode, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
bool newob = false;
Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
- if (obedit == NULL || obedit->type != OB_MBALL) {
- obedit = ED_object_add_type(C, OB_MBALL, NULL, loc, rot, true, local_view_bits);
+ if (obedit == nullptr || obedit->type != OB_MBALL) {
+ obedit = ED_object_add_type(C, OB_MBALL, nullptr, loc, rot, true, local_view_bits);
newob = true;
}
else {
@@ -984,7 +985,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op)
}
float mat[4][4];
- ED_object_new_primitive_matrix(C, obedit, loc, rot, NULL, mat);
+ ED_object_new_primitive_matrix(C, obedit, loc, rot, nullptr, mat);
/* Halving here is done to account for constant values from #BKE_mball_element_add.
* While the default radius of the resulting meta element is 2,
* we want to pass in 1 so other values such as resolution are scaled by 1.0. */
@@ -1040,14 +1041,14 @@ static int object_add_text_exec(bContext *C, wmOperator *op)
WM_operator_view3d_unit_defaults(C, op);
if (!ED_object_add_generic_get_opts(
- C, op, 'Z', loc, rot, NULL, &enter_editmode, &local_view_bits, NULL)) {
+ C, op, 'Z', loc, rot, nullptr, &enter_editmode, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
if (obedit && obedit->type == OB_FONT) {
return OPERATOR_CANCELLED;
}
- obedit = ED_object_add_type(C, OB_FONT, NULL, loc, rot, enter_editmode, local_view_bits);
+ obedit = ED_object_add_type(C, OB_FONT, nullptr, loc, rot, enter_editmode, local_view_bits);
BKE_object_obdata_size_init(obedit, RNA_float_get(op->ptr, "radius"));
return OPERATOR_FINISHED;
@@ -1094,11 +1095,11 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
WM_operator_view3d_unit_defaults(C, op);
if (!ED_object_add_generic_get_opts(
- C, op, 'Z', loc, rot, NULL, &enter_editmode, &local_view_bits, NULL)) {
+ C, op, 'Z', loc, rot, nullptr, &enter_editmode, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
- if ((obedit == NULL) || (obedit->type != OB_ARMATURE)) {
- obedit = ED_object_add_type(C, OB_ARMATURE, NULL, loc, rot, true, local_view_bits);
+ if ((obedit == nullptr) || (obedit->type != OB_ARMATURE)) {
+ obedit = ED_object_add_type(C, OB_ARMATURE, nullptr, loc, rot, true, local_view_bits);
ED_object_editmode_enter_ex(bmain, scene, obedit, 0);
newob = true;
}
@@ -1106,7 +1107,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
}
- if (obedit == NULL) {
+ if (obedit == nullptr) {
BKE_report(op->reports, RPT_ERROR, "Cannot create editmode armature");
return OPERATOR_CANCELLED;
}
@@ -1155,10 +1156,11 @@ static int object_empty_add_exec(bContext *C, wmOperator *op)
float loc[3], rot[3];
WM_operator_view3d_unit_defaults(C, op);
- if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, NULL, &local_view_bits, NULL)) {
+ if (!ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, nullptr, nullptr, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
- ob = ED_object_add_type(C, OB_EMPTY, NULL, loc, rot, false, local_view_bits);
+ ob = ED_object_add_type(C, OB_EMPTY, nullptr, loc, rot, false, local_view_bits);
BKE_object_empty_draw_type_set(ob, type);
BKE_object_obdata_size_init(ob, RNA_float_get(op->ptr, "radius"));
@@ -1192,7 +1194,7 @@ static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEv
{
Scene *scene = CTX_data_scene(C);
- Image *ima = NULL;
+ Image *ima = nullptr;
ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
if (!ima) {
@@ -1201,7 +1203,7 @@ static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEv
/* handled below */
id_us_min(&ima->id);
- Object *ob = NULL;
+ Object *ob = nullptr;
Object *ob_cursor = ED_view3d_give_object_under_cursor(C, event->mval);
/* either change empty under cursor or create a new empty */
@@ -1216,10 +1218,10 @@ static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEv
float rot[3];
if (!ED_object_add_generic_get_opts(
- C, op, 'Z', NULL, rot, NULL, NULL, &local_view_bits, NULL)) {
+ C, op, 'Z', nullptr, rot, nullptr, nullptr, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
- ob = ED_object_add_type(C, OB_EMPTY, NULL, NULL, rot, false, local_view_bits);
+ ob = ED_object_add_type(C, OB_EMPTY, nullptr, nullptr, rot, false, local_view_bits);
ED_object_location_from_view(C, ob->loc);
ED_view3d_cursor3d_position(C, event->mval, false, ob->loc);
@@ -1229,9 +1231,9 @@ static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEv
BKE_object_empty_draw_type_set(ob, OB_EMPTY_IMAGE);
- id_us_min(ob->data);
+ id_us_min(static_cast<ID *>(ob->data));
ob->data = ima;
- id_us_plus(ob->data);
+ id_us_plus(static_cast<ID *>(ob->data));
return OPERATOR_FINISHED;
}
@@ -1253,16 +1255,17 @@ void OBJECT_OT_drop_named_image(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- prop = RNA_def_string(ot->srna, "filepath", NULL, FILE_MAX, "Filepath", "Path to image file");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ prop = RNA_def_string(ot->srna, "filepath", nullptr, FILE_MAX, "Filepath", "Path to image file");
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
RNA_def_boolean(ot->srna,
"relative_path",
true,
"Relative Path",
"Select the file relative to the blend file");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- prop = RNA_def_string(ot->srna, "name", NULL, MAX_ID_NAME - 2, "Name", "Image name to assign");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
+ prop = RNA_def_string(
+ ot->srna, "name", nullptr, MAX_ID_NAME - 2, "Name", "Image name to assign");
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
ED_object_add_generic_props(ot, false);
}
@@ -1277,7 +1280,7 @@ static bool object_gpencil_add_poll(bContext *C)
Scene *scene = CTX_data_scene(C);
Object *obact = CTX_data_active_object(C);
- if ((scene == NULL) || (ID_IS_LINKED(scene))) {
+ if ((scene == nullptr) || (ID_IS_LINKED(scene))) {
return false;
}
@@ -1293,7 +1296,7 @@ static bool object_gpencil_add_poll(bContext *C)
static int object_gpencil_add_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C), *ob_orig = ob;
- bGPdata *gpd = (ob && (ob->type == OB_GPENCIL)) ? ob->data : NULL;
+ bGPdata *gpd = (ob && (ob->type == OB_GPENCIL)) ? static_cast<bGPdata *>(ob->data) : nullptr;
const int type = RNA_enum_get(op->ptr, "type");
const bool use_in_front = RNA_boolean_get(op->ptr, "use_in_front");
@@ -1307,12 +1310,13 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
/* NOTE: We use 'Y' here (not 'Z'), as. */
WM_operator_view3d_unit_defaults(C, op);
- if (!ED_object_add_generic_get_opts(C, op, 'Y', loc, rot, NULL, NULL, &local_view_bits, NULL)) {
+ if (!ED_object_add_generic_get_opts(
+ C, op, 'Y', loc, rot, nullptr, nullptr, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
/* Add new object if not currently editing a GP object. */
- if ((gpd == NULL) || (GPENCIL_ANY_MODE(gpd) == false)) {
- const char *ob_name = NULL;
+ if ((gpd == nullptr) || (GPENCIL_ANY_MODE(gpd) == false)) {
+ const char *ob_name = nullptr;
switch (type) {
case GP_EMPTY: {
ob_name = "GPencil";
@@ -1338,12 +1342,12 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
}
ob = ED_object_add_type(C, OB_GPENCIL, ob_name, loc, rot, true, local_view_bits);
- gpd = ob->data;
+ gpd = static_cast<bGPdata *>(ob->data);
newob = true;
}
else {
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_ADDED, NULL);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_ADDED, nullptr);
}
/* create relevant geometry */
@@ -1351,7 +1355,7 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
case GP_EMPTY: {
float mat[4][4];
- ED_object_new_primitive_matrix(C, ob, loc, rot, NULL, mat);
+ ED_object_new_primitive_matrix(C, ob, loc, rot, nullptr, mat);
ED_gpencil_create_blank(C, ob, mat);
break;
}
@@ -1389,7 +1393,7 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
ED_gpencil_create_lineart(C, ob);
- gpd = ob->data;
+ gpd = static_cast<bGPdata *>(ob->data);
/* Add Line Art modifier */
LineartGpencilModifierData *md = (LineartGpencilModifierData *)BKE_gpencil_modifier_new(
@@ -1458,21 +1462,21 @@ static void object_add_ui(bContext *UNUSED(C), wmOperator *op)
uiLayoutSetPropSep(layout, true);
- uiItemR(layout, op->ptr, "radius", 0, NULL, ICON_NONE);
- uiItemR(layout, op->ptr, "align", 0, NULL, ICON_NONE);
- uiItemR(layout, op->ptr, "location", 0, NULL, ICON_NONE);
- uiItemR(layout, op->ptr, "rotation", 0, NULL, ICON_NONE);
- uiItemR(layout, op->ptr, "type", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "radius", 0, nullptr, ICON_NONE);
+ uiItemR(layout, op->ptr, "align", 0, nullptr, ICON_NONE);
+ uiItemR(layout, op->ptr, "location", 0, nullptr, ICON_NONE);
+ uiItemR(layout, op->ptr, "rotation", 0, nullptr, ICON_NONE);
+ uiItemR(layout, op->ptr, "type", 0, nullptr, ICON_NONE);
int type = RNA_enum_get(op->ptr, "type");
if (ELEM(type, GP_LRT_COLLECTION, GP_LRT_OBJECT, GP_LRT_SCENE)) {
- uiItemR(layout, op->ptr, "use_lights", 0, NULL, ICON_NONE);
- uiItemR(layout, op->ptr, "use_in_front", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "use_lights", 0, nullptr, ICON_NONE);
+ uiItemR(layout, op->ptr, "use_in_front", 0, nullptr, ICON_NONE);
bool in_front = RNA_boolean_get(op->ptr, "use_in_front");
uiLayout *col = uiLayoutColumn(layout, false);
uiLayoutSetActive(col, !in_front);
- uiItemR(col, op->ptr, "stroke_depth_offset", 0, NULL, ICON_NONE);
- uiItemR(col, op->ptr, "stroke_depth_order", 0, NULL, ICON_NONE);
+ uiItemR(col, op->ptr, "stroke_depth_offset", 0, nullptr, ICON_NONE);
+ uiItemR(col, op->ptr, "stroke_depth_order", 0, nullptr, ICON_NONE);
}
}
@@ -1483,7 +1487,7 @@ static EnumPropertyItem rna_enum_gpencil_add_stroke_depth_order_items[] = {
"2D Layers",
"Display strokes using grease pencil layers to define order"},
{GP_DRAWMODE_3D, "3D", 0, "3D Location", "Display strokes using real 3D position in 3D space"},
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
void OBJECT_OT_gpencil_add(wmOperatorType *ot)
@@ -1565,7 +1569,8 @@ static int object_light_add_exec(bContext *C, wmOperator *op)
float loc[3], rot[3];
WM_operator_view3d_unit_defaults(C, op);
- if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, NULL, &local_view_bits, NULL)) {
+ if (!ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, nullptr, nullptr, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
ob = ED_object_add_type(C, OB_LAMP, get_light_defname(type), loc, rot, false, local_view_bits);
@@ -1648,7 +1653,8 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op)
update_location_if_necessary = true;
}
else {
- collection = BLI_findlink(&bmain->collections, RNA_enum_get(op->ptr, "collection"));
+ collection = static_cast<Collection *>(
+ BLI_findlink(&bmain->collections, RNA_enum_get(op->ptr, "collection")));
}
if (update_location_if_necessary) {
@@ -1660,11 +1666,12 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op)
}
}
- if (collection == NULL) {
+ if (collection == nullptr) {
return OPERATOR_CANCELLED;
}
- if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, NULL, &local_view_bits, NULL)) {
+ if (!ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, nullptr, nullptr, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
@@ -1735,7 +1742,7 @@ void OBJECT_OT_collection_instance_add(wmOperatorType *ot)
"Session UUID of the collection to add",
INT32_MIN,
INT32_MAX);
- RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_SKIP_SAVE | PROP_HIDDEN));
object_add_drop_xy_props(ot);
}
@@ -1751,7 +1758,7 @@ void OBJECT_OT_collection_instance_add(wmOperatorType *ot)
static int object_data_instance_add_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- ID *id = NULL;
+ ID *id = nullptr;
ushort local_view_bits;
float loc[3], rot[3];
@@ -1767,7 +1774,7 @@ static int object_data_instance_add_exec(bContext *C, wmOperator *op)
char name[MAX_ID_NAME - 2];
RNA_property_string_get(op->ptr, prop_name, name);
id = BKE_libblock_find_name(bmain, id_type, name);
- if (id == NULL) {
+ if (id == nullptr) {
return OPERATOR_CANCELLED;
}
const int object_type = BKE_object_obdata_to_type(id);
@@ -1782,7 +1789,8 @@ static int object_data_instance_add_exec(bContext *C, wmOperator *op)
RNA_property_float_set_array(op->ptr, prop_location, loc);
}
- if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, NULL, &local_view_bits, NULL)) {
+ if (!ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, nullptr, nullptr, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
@@ -1829,10 +1837,11 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op)
ushort local_view_bits;
float loc[3], rot[3];
- if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, NULL, &local_view_bits, NULL)) {
+ if (!ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, nullptr, nullptr, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
- Object *ob = ED_object_add_type(C, OB_SPEAKER, NULL, loc, rot, false, local_view_bits);
+ Object *ob = ED_object_add_type(C, OB_SPEAKER, nullptr, 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
@@ -1840,8 +1849,8 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op)
{
/* create new data for NLA hierarchy */
AnimData *adt = BKE_animdata_ensure_id(&ob->id);
- NlaTrack *nlt = BKE_nlatrack_add(adt, NULL, is_liboverride);
- NlaStrip *strip = BKE_nla_add_soundstrip(bmain, scene, ob->data);
+ NlaTrack *nlt = BKE_nlatrack_add(adt, nullptr, is_liboverride);
+ NlaStrip *strip = BKE_nla_add_soundstrip(bmain, scene, static_cast<Speaker *>(ob->data));
strip->start = CFRA;
strip->end += strip->start;
@@ -1852,7 +1861,7 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op)
BLI_strncpy(nlt->name, DATA_("SoundTrack"), sizeof(nlt->name));
BKE_nlastrip_validate_name(adt, strip);
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, nullptr);
}
return OPERATOR_FINISHED;
@@ -1891,15 +1900,21 @@ static bool object_hair_curves_add_poll(bContext *C)
static int object_hair_curves_add_exec(bContext *C, wmOperator *op)
{
+ using namespace blender;
+
ushort local_view_bits;
float loc[3], rot[3];
- if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, NULL, &local_view_bits, NULL)) {
+ if (!ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, nullptr, nullptr, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
- Object *object = ED_object_add_type(C, OB_CURVES, NULL, loc, rot, false, local_view_bits);
+ Object *object = ED_object_add_type(C, OB_CURVES, nullptr, loc, rot, false, local_view_bits);
object->dtx |= OB_DRAWBOUNDOX; /* TODO: remove once there is actual drawing. */
+ Curves *curves_id = static_cast<Curves *>(object->data);
+ bke::CurvesGeometry::wrap(curves_id->geometry) = ed::curves::primitive_random_sphere(500, 8);
+
return OPERATOR_FINISHED;
}
@@ -1938,11 +1953,12 @@ static int object_pointcloud_add_exec(bContext *C, wmOperator *op)
{
ushort local_view_bits;
float loc[3], rot[3];
- if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, NULL, &local_view_bits, NULL)) {
+ if (!ED_object_add_generic_get_opts(
+ C, op, 'Z', loc, rot, nullptr, nullptr, &local_view_bits, nullptr)) {
return OPERATOR_CANCELLED;
}
- Object *object = ED_object_add_type(C, OB_POINTCLOUD, NULL, loc, rot, false, local_view_bits);
+ Object *object = ED_object_add_type(C, OB_POINTCLOUD, nullptr, loc, rot, false, local_view_bits);
object->dtx |= OB_DRAWBOUNDOX; /* TODO: remove once there is actual drawing. */
return OPERATOR_FINISHED;
@@ -2062,11 +2078,11 @@ static int object_delete_exec(bContext *C, wmOperator *op)
/* FIXME: this will also remove parent from grease pencil from other scenes. */
/* Remove from Grease Pencil parent */
- for (bGPdata *gpd = bmain->gpencils.first; gpd; gpd = gpd->id.next) {
+ LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) {
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- if (gpl->parent != NULL) {
+ if (gpl->parent != nullptr) {
if (gpl->parent == ob) {
- gpl->parent = NULL;
+ gpl->parent = nullptr;
}
}
}
@@ -2123,8 +2139,8 @@ void OBJECT_OT_delete(wmOperatorType *ot)
PropertyRNA *prop;
prop = RNA_def_boolean(
- ot->srna, "use_global", 0, "Delete Globally", "Remove object from all scenes");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ ot->srna, "use_global", false, "Delete Globally", "Remove object from all scenes");
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
WM_operator_properties_confirm_or_exec(ot);
}
@@ -2188,7 +2204,7 @@ static void copy_object_set_idnew(bContext *C)
*/
static uint dupliobject_hash(const void *ptr)
{
- const DupliObject *dob = ptr;
+ const DupliObject *dob = static_cast<const DupliObject *>(ptr);
uint hash = BLI_ghashutil_ptrhash(dob->ob);
if (dob->type == OB_DUPLICOLLECTION) {
@@ -2210,7 +2226,7 @@ static uint dupliobject_hash(const void *ptr)
*/
static uint dupliobject_instancer_hash(const void *ptr)
{
- const DupliObject *dob = ptr;
+ const DupliObject *dob = static_cast<const DupliObject *>(ptr);
uint hash = BLI_ghashutil_inthash(dob->persistent_id[0]);
for (int i = 1; (i < MAX_DUPLI_RECUR) && dob->persistent_id[i] != INT_MAX; i++) {
hash ^= (dob->persistent_id[i] ^ i);
@@ -2221,8 +2237,8 @@ static uint dupliobject_instancer_hash(const void *ptr)
/* Compare function that matches dupliobject_hash */
static bool dupliobject_cmp(const void *a_, const void *b_)
{
- const DupliObject *a = a_;
- const DupliObject *b = b_;
+ const DupliObject *a = static_cast<const DupliObject *>(a_);
+ const DupliObject *b = static_cast<const DupliObject *>(b_);
if (a->ob != b->ob) {
return true;
@@ -2255,8 +2271,8 @@ static bool dupliobject_cmp(const void *a_, const void *b_)
/* Compare function that matches dupliobject_instancer_hash. */
static bool dupliobject_instancer_cmp(const void *a_, const void *b_)
{
- const DupliObject *a = a_;
- const DupliObject *b = b_;
+ const DupliObject *a = static_cast<const DupliObject *>(a_);
+ const DupliObject *b = static_cast<const DupliObject *>(b_);
for (int i = 0; (i < MAX_DUPLI_RECUR); i++) {
if (a->persistent_id[i] != b->persistent_id[i]) {
@@ -2280,7 +2296,7 @@ static void make_object_duplilist_real(bContext *C,
{
Main *bmain = CTX_data_main(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- GHash *parent_gh = NULL, *instancer_gh = NULL;
+ GHash *parent_gh = nullptr, *instancer_gh = nullptr;
Object *object_eval = DEG_get_evaluated_object(depsgraph, base->object);
@@ -2308,19 +2324,19 @@ static void make_object_duplilist_real(bContext *C,
LISTBASE_FOREACH (DupliObject *, dob, lb_duplis) {
Object *ob_src = DEG_get_original_object(dob->ob);
- Object *ob_dst = ID_NEW_SET(ob_src, BKE_id_copy(bmain, &ob_src->id));
+ Object *ob_dst = static_cast<Object *>(ID_NEW_SET(ob_src, BKE_id_copy(bmain, &ob_src->id)));
id_us_min(&ob_dst->id);
/* font duplis can have a totcol without material, we get them from parent
* should be implemented better...
*/
- if (ob_dst->mat == NULL) {
+ if (ob_dst->mat == nullptr) {
ob_dst->totcol = 0;
}
BKE_collection_object_add_from(bmain, scene, base->object, ob_dst);
Base *base_dst = BKE_view_layer_base_find(view_layer, ob_dst);
- BLI_assert(base_dst != NULL);
+ BLI_assert(base_dst != nullptr);
ED_object_base_select(base_dst, BA_SELECT);
DEG_id_tag_update(&ob_dst->id, ID_RECALC_SELECT);
@@ -2329,17 +2345,17 @@ static void make_object_duplilist_real(bContext *C,
/* make sure apply works */
BKE_animdata_free(&ob_dst->id, true);
- ob_dst->adt = NULL;
+ ob_dst->adt = nullptr;
- ob_dst->parent = NULL;
+ ob_dst->parent = nullptr;
BKE_constraints_free(&ob_dst->constraints);
- ob_dst->runtime.curve_cache = NULL;
+ ob_dst->runtime.curve_cache = nullptr;
const bool is_dupli_instancer = (ob_dst->transflag & OB_DUPLI) != 0;
ob_dst->transflag &= ~OB_DUPLI;
/* Remove instantiated collection, it's annoying to keep it here
* (and get potentially a lot of usages of it then...). */
id_us_min((ID *)ob_dst->instance_collection);
- ob_dst->instance_collection = NULL;
+ ob_dst->instance_collection = nullptr;
copy_m4_m4(ob_dst->obmat, dob->mat);
BKE_object_apply_mat4(ob_dst, ob_dst->obmat, false, false);
@@ -2365,7 +2381,7 @@ static void make_object_duplilist_real(bContext *C,
LISTBASE_FOREACH (DupliObject *, dob, lb_duplis) {
Object *ob_src = dob->ob;
- Object *ob_dst = BLI_ghash_lookup(dupli_gh, dob);
+ Object *ob_dst = static_cast<Object *>(BLI_ghash_lookup(dupli_gh, dob));
/* Remap new object to itself, and clear again newid pointer of orig object. */
BKE_libblock_relink_to_newid(bmain, &ob_dst->id, 0);
@@ -2375,7 +2391,7 @@ static void make_object_duplilist_real(bContext *C,
if (use_hierarchy) {
/* original parents */
Object *ob_src_par = ob_src->parent;
- Object *ob_dst_par = NULL;
+ Object *ob_dst_par = nullptr;
/* find parent that was also made real */
if (ob_src_par) {
@@ -2392,7 +2408,7 @@ static void make_object_duplilist_real(bContext *C,
else {
dob_key.persistent_id[0] = dob->persistent_id[0];
}
- ob_dst_par = BLI_ghash_lookup(parent_gh, &dob_key);
+ ob_dst_par = static_cast<Object *>(BLI_ghash_lookup(parent_gh, &dob_key));
}
if (ob_dst_par) {
@@ -2408,10 +2424,10 @@ static void make_object_duplilist_real(bContext *C,
ob_dst->parent = ob_dst_par;
}
}
- if (use_base_parent && ob_dst->parent == NULL) {
- Object *ob_dst_par = NULL;
+ if (use_base_parent && ob_dst->parent == nullptr) {
+ Object *ob_dst_par = nullptr;
- if (instancer_gh != NULL) {
+ if (instancer_gh != nullptr) {
/* OK to keep most of the members uninitialized,
* they won't be read, this is simply for a hash lookup. */
DupliObject dob_key;
@@ -2421,10 +2437,10 @@ static void make_object_duplilist_real(bContext *C,
memcpy(&dob_key.persistent_id[0],
&dob->persistent_id[1],
sizeof(dob_key.persistent_id[0]) * (MAX_DUPLI_RECUR - 1));
- ob_dst_par = BLI_ghash_lookup(instancer_gh, &dob_key);
+ ob_dst_par = static_cast<Object *>(BLI_ghash_lookup(instancer_gh, &dob_key));
}
- if (ob_dst_par == NULL) {
+ if (ob_dst_par == nullptr) {
/* Default to parenting to root object...
* Always the case when use_hierarchy is false. */
ob_dst_par = base->object;
@@ -2445,18 +2461,18 @@ static void make_object_duplilist_real(bContext *C,
}
if (base->object->transflag & OB_DUPLICOLLECTION && base->object->instance_collection) {
- base->object->instance_collection = NULL;
+ base->object->instance_collection = nullptr;
}
ED_object_base_select(base, BA_DESELECT);
DEG_id_tag_update(&base->object->id, ID_RECALC_SELECT);
- BLI_ghash_free(dupli_gh, NULL, NULL);
+ BLI_ghash_free(dupli_gh, nullptr, nullptr);
if (parent_gh) {
- BLI_ghash_free(parent_gh, NULL, NULL);
+ BLI_ghash_free(parent_gh, nullptr, nullptr);
}
if (instancer_gh) {
- BLI_ghash_free(instancer_gh, NULL, NULL);
+ BLI_ghash_free(instancer_gh, nullptr, nullptr);
}
free_object_duplilist(lb_duplis);
@@ -2488,7 +2504,7 @@ static int object_duplicates_make_real_exec(bContext *C, wmOperator *op)
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE, scene);
- WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, nullptr);
ED_outliner_select_sync_from_object_tag(C);
return OPERATOR_FINISHED;
@@ -2511,11 +2527,11 @@ void OBJECT_OT_duplicates_make_real(wmOperatorType *ot)
RNA_def_boolean(ot->srna,
"use_base_parent",
- 0,
+ false,
"Parent",
"Parent newly created objects to the original instancer");
RNA_def_boolean(
- ot->srna, "use_hierarchy", 0, "Keep Hierarchy", "Maintain parent child relationships");
+ ot->srna, "use_hierarchy", false, "Keep Hierarchy", "Maintain parent child relationships");
}
/** \} */
@@ -2525,7 +2541,11 @@ void OBJECT_OT_duplicates_make_real(wmOperatorType *ot)
* \{ */
static const EnumPropertyItem convert_target_items[] = {
- {OB_CURVE, "CURVE", ICON_OUTLINER_OB_CURVE, "Curve", "Curve from Mesh or Text objects"},
+ {OB_CURVES_LEGACY,
+ "CURVE",
+ ICON_OUTLINER_OB_CURVE,
+ "Curve",
+ "Curve from Mesh or Text objects"},
{OB_MESH,
"MESH",
ICON_OUTLINER_OB_MESH,
@@ -2547,19 +2567,19 @@ static const EnumPropertyItem convert_target_items[] = {
"Point Cloud",
"Point Cloud from Mesh objects"},
#endif
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
static void object_data_convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
- if (ob->runtime.curve_cache == NULL) {
+ if (ob->runtime.curve_cache == nullptr) {
/* Force creation. This is normally not needed but on operator
* redo we might end up with an object which isn't evaluated yet.
* Also happens in case we are working on a copy of the object
* (all its caches have been nuked then).
*/
- if (ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
- /* We need 'for render' ON here, to enable computing bevel dipslist if needed.
+ if (ELEM(ob->type, OB_SURF, OB_CURVES_LEGACY, OB_FONT)) {
+ /* We need 'for render' ON here, to enable computing bevel #DispList if needed.
* Also makes sense anyway, we would not want e.g. to lose hidden parts etc. */
BKE_displist_make_curveTypes(depsgraph, scene, ob, true);
}
@@ -2572,10 +2592,10 @@ static void object_data_convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *
static void object_data_convert_curve_to_mesh(Main *bmain, Depsgraph *depsgraph, Object *ob)
{
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
- Curve *curve = ob->data;
+ Curve *curve = static_cast<Curve *>(ob->data);
Mesh *mesh = BKE_mesh_new_from_object_to_bmain(bmain, depsgraph, object_eval, true);
- if (mesh == NULL) {
+ if (mesh == nullptr) {
/* Unable to convert the curve to a mesh. */
return;
}
@@ -2606,9 +2626,9 @@ static bool object_convert_poll(bContext *C)
{
Scene *scene = CTX_data_scene(C);
Base *base_act = CTX_data_active_base(C);
- Object *obact = base_act ? base_act->object : NULL;
+ Object *obact = base_act ? base_act->object : nullptr;
- if (obact == NULL || obact->data == NULL || ID_IS_LINKED(obact) ||
+ if (obact == nullptr || obact->data == nullptr || ID_IS_LINKED(obact) ||
ID_IS_OVERRIDE_LIBRARY(obact) || ID_IS_OVERRIDE_LIBRARY(obact->data)) {
return false;
}
@@ -2621,7 +2641,7 @@ static bool object_convert_poll(bContext *C)
static Base *duplibase_for_convert(
Main *bmain, Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, Base *base, Object *ob)
{
- if (ob == NULL) {
+ if (ob == nullptr) {
ob = base->object;
}
@@ -2636,14 +2656,14 @@ static Base *duplibase_for_convert(
/* XXX: An ugly hack needed because if we re-run depsgraph with some new meta-ball objects
* having same 'family name' as orig ones, they will affect end result of meta-ball computation.
- * For until we get rid of that name-based thingy in MBalls, that should do the trick
- * (this is weak, but other solution (to change name of `obn`) is even worse imho).
+ * For until we get rid of that name-based thingy in meta-balls, that should do the trick
+ * (this is weak, but other solution (to change name of `obn`) is even worse IMHO).
* See T65996. */
const bool is_meta_ball = (obn->type == OB_MBALL);
void *obdata = obn->data;
if (is_meta_ball) {
obn->type = OB_EMPTY;
- obn->data = NULL;
+ obn->data = nullptr;
}
/* XXX Doing that here is stupid, it means we update and re-evaluate the whole depsgraph every
@@ -2675,7 +2695,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
- Base *basen = NULL, *basact = NULL;
+ Base *basen = nullptr, *basact = nullptr;
Object *ob1, *obact = CTX_data_active_object(C);
const short target = RNA_enum_get(op->ptr, "target");
bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
@@ -2723,7 +2743,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
* on other objects data masks too, see: T50950. */
{
LISTBASE_FOREACH (CollectionPointerLink *, link, &selected_editable_bases) {
- Base *base = link->ptr.data;
+ Base *base = static_cast<Base *>(link->ptr.data);
Object *ob = base->object;
/* The way object type conversion works currently (enforcing conversion of *all* objects
@@ -2750,8 +2770,8 @@ static int object_convert_exec(bContext *C, wmOperator *op)
}
LISTBASE_FOREACH (CollectionPointerLink *, link, &selected_editable_bases) {
- Object *newob = NULL;
- Base *base = link->ptr.data;
+ Object *newob = nullptr;
+ Base *base = static_cast<Base *>(link->ptr.data);
Object *ob = base->object;
if (ob->flag & OB_DONE || !IS_TAGGED(ob->data)) {
@@ -2773,15 +2793,15 @@ static int object_convert_exec(bContext *C, wmOperator *op)
}
}
}
- else if (ob->type == OB_MESH && target == OB_CURVE) {
+ else if (ob->type == OB_MESH && target == OB_CURVES_LEGACY) {
ob->flag |= OB_DONE;
if (keep_original) {
- basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
+ basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, nullptr);
newob = basen->object;
/* Decrement original mesh's usage count. */
- Mesh *me = newob->data;
+ Mesh *me = static_cast<Mesh *>(newob->data);
id_us_min(&me->id);
/* Make a new copy of the mesh. */
@@ -2793,9 +2813,9 @@ static int object_convert_exec(bContext *C, wmOperator *op)
BKE_mesh_to_curve(bmain, depsgraph, scene, newob);
- if (newob->type == OB_CURVE) {
+ if (newob->type == OB_CURVES_LEGACY) {
BKE_object_free_modifiers(newob, 0); /* after derivedmesh calls! */
- if (newob->rigidbody_object != NULL) {
+ if (newob->rigidbody_object != nullptr) {
ED_rigidbody_object_remove(bmain, scene, newob);
}
}
@@ -2851,11 +2871,11 @@ static int object_convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
if (keep_original) {
- basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
+ basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, nullptr);
newob = basen->object;
/* Decrement original mesh's usage count. */
- Mesh *me = newob->data;
+ Mesh *me = static_cast<Mesh *>(newob->data);
id_us_min(&me->id);
/* Make a new copy of the mesh. */
@@ -2876,11 +2896,11 @@ static int object_convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
if (keep_original) {
- basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
+ basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, nullptr);
newob = basen->object;
/* Decrement original mesh's usage count. */
- Mesh *me = newob->data;
+ Mesh *me = static_cast<Mesh *>(newob->data);
id_us_min(&me->id);
/* Make a new copy of the mesh. */
@@ -2912,50 +2932,58 @@ static int object_convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
if (keep_original) {
- basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
+ basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, nullptr);
newob = basen->object;
/* Decrement original curve's usage count. */
id_us_min(&((Curve *)newob->data)->id);
/* Make a new copy of the curve. */
- newob->data = BKE_id_copy(bmain, ob->data);
+ newob->data = BKE_id_copy(bmain, static_cast<ID *>(ob->data));
}
else {
newob = ob;
}
- Curve *cu = newob->data;
+ Curve *cu = static_cast<Curve *>(newob->data);
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- BKE_vfont_to_curve_ex(ob_eval, ob_eval->data, FO_EDIT, &cu->nurb, NULL, NULL, NULL, NULL);
-
- newob->type = OB_CURVE;
- cu->type = OB_CURVE;
+ BKE_vfont_to_curve_ex(ob_eval,
+ static_cast<Curve *>(ob_eval->data),
+ FO_EDIT,
+ &cu->nurb,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr);
+
+ newob->type = OB_CURVES_LEGACY;
+ cu->type = OB_CURVES_LEGACY;
if (cu->vfont) {
id_us_min(&cu->vfont->id);
- cu->vfont = NULL;
+ cu->vfont = nullptr;
}
if (cu->vfontb) {
id_us_min(&cu->vfontb->id);
- cu->vfontb = NULL;
+ cu->vfontb = nullptr;
}
if (cu->vfonti) {
id_us_min(&cu->vfonti->id);
- cu->vfonti = NULL;
+ cu->vfonti = nullptr;
}
if (cu->vfontbi) {
id_us_min(&cu->vfontbi->id);
- cu->vfontbi = NULL;
+ cu->vfontbi = nullptr;
}
if (!keep_original) {
/* other users */
if (ID_REAL_USERS(&cu->id) > 1) {
- for (ob1 = bmain->objects.first; ob1; ob1 = ob1->id.next) {
+ for (ob1 = static_cast<Object *>(bmain->objects.first); ob1;
+ ob1 = static_cast<Object *>(ob1->id.next)) {
if (ob1->data == ob->data) {
- ob1->type = OB_CURVE;
+ ob1->type = OB_CURVES_LEGACY;
DEG_id_tag_update(&ob1->id,
ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
}
@@ -2985,22 +3013,22 @@ static int object_convert_exec(bContext *C, wmOperator *op)
BKE_gpencil_convert_curve(bmain, scene, ob_gpencil, newob, false, 1.0f, 0.0f);
gpencilConverted = true;
gpencilCurveConverted = true;
- basen = NULL;
+ basen = nullptr;
}
}
- else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
ob->flag |= OB_DONE;
if (target == OB_MESH) {
if (keep_original) {
- basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
+ basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, nullptr);
newob = basen->object;
/* Decrement original curve's usage count. */
id_us_min(&((Curve *)newob->data)->id);
/* make a new copy of the curve */
- newob->data = BKE_id_copy(bmain, ob->data);
+ newob->data = BKE_id_copy(bmain, static_cast<ID *>(ob->data));
}
else {
newob = ob;
@@ -3013,7 +3041,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
BKE_object_free_curve_cache(newob);
}
else if (target == OB_GPENCIL) {
- if (ob->type != OB_CURVE) {
+ if (ob->type != OB_CURVES_LEGACY) {
ob->flag &= ~OB_DONE;
BKE_report(op->reports, RPT_ERROR, "Convert Surfaces to Grease Pencil is not supported");
}
@@ -3047,23 +3075,24 @@ static int object_convert_exec(bContext *C, wmOperator *op)
basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, baseob);
newob = basen->object;
- MetaBall *mb = newob->data;
+ MetaBall *mb = static_cast<MetaBall *>(newob->data);
id_us_min(&mb->id);
newob->data = BKE_mesh_add(bmain, "Mesh");
newob->type = OB_MESH;
- Mesh *me = newob->data;
+ Mesh *me = static_cast<Mesh *>(newob->data);
me->totcol = mb->totcol;
if (newob->totcol) {
- me->mat = MEM_dupallocN(mb->mat);
+ me->mat = static_cast<Material **>(MEM_dupallocN(mb->mat));
for (a = 0; a < newob->totcol; a++) {
id_us_plus((ID *)me->mat[a]);
}
}
object_data_convert_ensure_curve_cache(depsgraph, scene, baseob);
- BKE_mesh_from_metaball(&baseob->runtime.curve_cache->disp, newob->data);
+ BKE_mesh_from_metaball(&baseob->runtime.curve_cache->disp,
+ static_cast<Mesh *>(newob->data));
if (obact->type == OB_MBALL) {
basact = basen;
@@ -3077,11 +3106,11 @@ static int object_convert_exec(bContext *C, wmOperator *op)
ob->flag |= OB_DONE;
if (keep_original) {
- basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
+ basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, nullptr);
newob = basen->object;
/* Decrement original point cloud's usage count. */
- PointCloud *pointcloud = newob->data;
+ PointCloud *pointcloud = static_cast<PointCloud *>(newob->data);
id_us_min(&pointcloud->id);
/* Make a new copy of the point cloud. */
@@ -3104,7 +3133,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
/* Ensure new object has consistent material data with its new obdata. */
if (newob) {
- BKE_object_materials_test(bmain, newob, newob->data);
+ BKE_object_materials_test(bmain, newob, static_cast<ID *>(newob->data));
}
/* tag obdata if it was been changed */
@@ -3116,7 +3145,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
basact = basen;
}
- basen = NULL;
+ basen = nullptr;
}
if (!keep_original && (ob->flag & OB_DONE)) {
@@ -3137,7 +3166,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
* their basis happens to be removed first. */
FOREACH_SCENE_OBJECT_BEGIN (scene, ob_mball) {
if (ob_mball->type == OB_MBALL) {
- Object *ob_basis = NULL;
+ Object *ob_basis = nullptr;
if (!BKE_mball_is_basis(ob_mball) &&
((ob_basis = BKE_mball_basis_find(scene, ob_mball)) && (ob_basis->flag & OB_DONE))) {
ED_object_base_free_and_unlink(bmain, scene, ob_mball);
@@ -3159,7 +3188,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
/* Remove curves and meshes converted to Grease Pencil object. */
if (gpencilConverted) {
FOREACH_SCENE_OBJECT_BEGIN (scene, ob_delete) {
- if (ELEM(ob_delete->type, OB_CURVE, OB_MESH)) {
+ if (ELEM(ob_delete->type, OB_CURVES_LEGACY, OB_MESH)) {
if (ob_delete->flag & OB_DONE) {
ED_object_base_free_and_unlink(bmain, scene, ob_delete);
}
@@ -3172,7 +3201,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
/* Remove Text curves converted to Grease Pencil object to avoid duplicated curves. */
if (gpencilCurveConverted) {
FOREACH_SCENE_OBJECT_BEGIN (scene, ob_delete) {
- if (ELEM(ob_delete->type, OB_CURVE) && (ob_delete->flag & OB_DONE)) {
+ if (ELEM(ob_delete->type, OB_CURVES_LEGACY) && (ob_delete->flag & OB_DONE)) {
ED_object_base_free_and_unlink(bmain, scene, ob_delete);
}
}
@@ -3181,7 +3210,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
}
// XXX ED_object_editmode_enter(C, 0);
- // XXX exit_editmode(C, EM_FREEDATA|); /* freedata, but no undo */
+ // XXX exit_editmode(C, EM_FREEDATA|); /* free data, but no undo */
if (basact) {
/* active base was changed */
@@ -3208,15 +3237,15 @@ static void object_convert_ui(bContext *UNUSED(C), wmOperator *op)
uiLayoutSetPropSep(layout, true);
- uiItemR(layout, op->ptr, "target", 0, NULL, ICON_NONE);
- uiItemR(layout, op->ptr, "keep_original", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "target", 0, nullptr, ICON_NONE);
+ uiItemR(layout, op->ptr, "keep_original", 0, nullptr, ICON_NONE);
if (RNA_enum_get(op->ptr, "target") == OB_GPENCIL) {
- uiItemR(layout, op->ptr, "thickness", 0, NULL, ICON_NONE);
- uiItemR(layout, op->ptr, "angle", 0, NULL, ICON_NONE);
- uiItemR(layout, op->ptr, "offset", 0, NULL, ICON_NONE);
- uiItemR(layout, op->ptr, "seams", 0, NULL, ICON_NONE);
- uiItemR(layout, op->ptr, "faces", 0, NULL, ICON_NONE);
+ uiItemR(layout, op->ptr, "thickness", 0, nullptr, ICON_NONE);
+ uiItemR(layout, op->ptr, "angle", 0, nullptr, ICON_NONE);
+ uiItemR(layout, op->ptr, "offset", 0, nullptr, ICON_NONE);
+ uiItemR(layout, op->ptr, "seams", 0, nullptr, ICON_NONE);
+ uiItemR(layout, op->ptr, "faces", 0, nullptr, ICON_NONE);
}
}
@@ -3243,14 +3272,14 @@ void OBJECT_OT_convert(wmOperatorType *ot)
ot->srna, "target", convert_target_items, OB_MESH, "Target", "Type of object to convert to");
RNA_def_boolean(ot->srna,
"keep_original",
- 0,
+ false,
"Keep Original",
"Keep original objects instead of replacing them");
prop = RNA_def_float_rotation(ot->srna,
"angle",
0,
- NULL,
+ nullptr,
DEG2RADF(0.0f),
DEG2RADF(180.0f),
"Threshold Angle",
@@ -3260,8 +3289,8 @@ void OBJECT_OT_convert(wmOperatorType *ot)
RNA_def_property_float_default(prop, DEG2RADF(70.0f));
RNA_def_int(ot->srna, "thickness", 5, 1, 100, "Thickness", "", 1, 100);
- RNA_def_boolean(ot->srna, "seams", 0, "Only Seam Edges", "Convert only seam edges");
- RNA_def_boolean(ot->srna, "faces", 1, "Export Faces", "Export faces as filled strokes");
+ RNA_def_boolean(ot->srna, "seams", false, "Only Seam Edges", "Convert only seam edges");
+ RNA_def_boolean(ot->srna, "faces", true, "Export Faces", "Export faces as filled strokes");
RNA_def_float_distance(ot->srna,
"offset",
0.01f,
@@ -3279,16 +3308,11 @@ void OBJECT_OT_convert(wmOperatorType *ot)
/** \name Duplicate Object Operator
* \{ */
-/*
- * dupflag: a flag made from constants declared in DNA_userdef_types.h
- * The flag tells adduplicate() whether to copy data linked to the object,
- * or to reference the existing data.
- * U.dupflag for default operations or you can construct a flag as python does
- * if the dupflag is 0 then no data will be copied (linked duplicate). */
-
-/* used below, assumes id.new is correct */
-/* leaves selection of base/object unaltered */
-/* Does set ID->newid pointers. */
+/**
+ * - Assumes `id.new` is correct.
+ * - Leaves selection of base/object unaltered.
+ * - Sets #ID.newid pointers.
+ */
static Base *object_add_duplicate_internal(Main *bmain,
Scene *scene,
ViewLayer *view_layer,
@@ -3296,18 +3320,19 @@ static Base *object_add_duplicate_internal(Main *bmain,
const eDupli_ID_Flags dupflag,
const eLibIDDuplicateFlags duplicate_options)
{
- Base *base, *basen = NULL;
+ Base *base, *basen = nullptr;
Object *obn;
if (ob->mode & OB_MODE_POSE) {
/* nothing? */
}
else {
- obn = ID_NEW_SET(ob, BKE_object_duplicate(bmain, ob, dupflag, duplicate_options));
+ obn = static_cast<Object *>(
+ ID_NEW_SET(ob, BKE_object_duplicate(bmain, ob, dupflag, duplicate_options)));
DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
base = BKE_view_layer_base_find(view_layer, ob);
- if ((base != NULL) && (base->flag & BASE_VISIBLE_DEPSGRAPH)) {
+ if ((base != nullptr) && (base->flag & BASE_VISIBLE_DEPSGRAPH)) {
BKE_collection_object_add_from(bmain, scene, ob, obn);
}
else {
@@ -3316,7 +3341,7 @@ static Base *object_add_duplicate_internal(Main *bmain,
}
basen = BKE_view_layer_base_find(view_layer, obn);
- if (base != NULL) {
+ if (base != nullptr) {
basen->local_view_bits = base->local_view_bits;
}
@@ -3325,8 +3350,7 @@ static Base *object_add_duplicate_internal(Main *bmain,
*/
/* XXX: is 2) really a good measure here? */
if (ob->rigidbody_object || ob->rigidbody_constraint) {
- Collection *collection;
- for (collection = bmain->collections.first; collection; collection = collection->id.next) {
+ LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
if (BKE_collection_has_object(collection, ob)) {
BKE_collection_object_add(bmain, collection, obn);
}
@@ -3349,8 +3373,8 @@ Base *ED_object_add_duplicate(
dupflag,
LIB_ID_DUPLICATE_IS_SUBPROCESS |
LIB_ID_DUPLICATE_IS_ROOT_ID);
- if (basen == NULL) {
- return NULL;
+ if (basen == nullptr) {
+ return nullptr;
}
ob = basen->object;
@@ -3363,7 +3387,7 @@ Base *ED_object_add_duplicate(
/* DAG_relations_tag_update(bmain); */ /* caller must do */
- if (ob->data != NULL) {
+ if (ob->data != nullptr) {
DEG_id_tag_update_ex(bmain, (ID *)ob->data, ID_RECALC_EDITORS);
}
@@ -3379,7 +3403,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const bool linked = RNA_boolean_get(op->ptr, "linked");
- const eDupli_ID_Flags dupflag = (linked) ? 0 : (eDupli_ID_Flags)U.dupflag;
+ const eDupli_ID_Flags dupflag = (linked) ? (eDupli_ID_Flags)0 : (eDupli_ID_Flags)U.dupflag;
/* We need to handle that here ourselves, because we may duplicate several objects, in which case
* we also want to remap pointers between those... */
@@ -3399,7 +3423,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
ED_object_base_select(base, BA_DESELECT);
ED_object_base_select(basen, BA_SELECT);
- if (basen == NULL) {
+ if (basen == nullptr) {
continue;
}
@@ -3409,7 +3433,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
}
if (basen->object->data) {
- DEG_id_tag_update(basen->object->data, 0);
+ DEG_id_tag_update(static_cast<ID *>(basen->object->data), 0);
}
}
CTX_DATA_END;
@@ -3447,7 +3471,7 @@ void OBJECT_OT_duplicate(wmOperatorType *ot)
/* to give to transform */
prop = RNA_def_boolean(ot->srna,
"linked",
- 0,
+ false,
"Linked",
"Duplicate object but not object data, linking to the original data");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
@@ -3473,14 +3497,14 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
Base *basen;
Object *ob;
const bool linked = RNA_boolean_get(op->ptr, "linked");
- const eDupli_ID_Flags dupflag = (linked) ? 0 : (eDupli_ID_Flags)U.dupflag;
+ const eDupli_ID_Flags dupflag = (linked) ? (eDupli_ID_Flags)0 : (eDupli_ID_Flags)U.dupflag;
char name[MAX_ID_NAME - 2];
/* find object, create fake base */
RNA_string_get(op->ptr, "name", name);
ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, name);
- if (ob == NULL) {
+ if (ob == nullptr) {
BKE_report(op->reports, RPT_ERROR, "Object not found");
return OPERATOR_CANCELLED;
}
@@ -3499,7 +3523,7 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
*/
LIB_ID_DUPLICATE_IS_SUBPROCESS | LIB_ID_DUPLICATE_IS_ROOT_ID);
- if (basen == NULL) {
+ if (basen == nullptr) {
BKE_report(op->reports, RPT_ERROR, "Object could not be duplicated");
return OPERATOR_CANCELLED;
}
@@ -3510,7 +3534,7 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
/* 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, SEL_DESELECT);
+ ED_object_base_deselect_all(view_layer, nullptr, SEL_DESELECT);
ED_object_base_select(basen, BA_SELECT);
ED_object_base_activate(C, basen);
@@ -3566,11 +3590,11 @@ void OBJECT_OT_add_named(wmOperatorType *ot)
"Linked",
"Duplicate object but not object data, linking to the original data");
- RNA_def_string(ot->srna, "name", NULL, MAX_ID_NAME - 2, "Name", "Object name to add");
+ RNA_def_string(ot->srna, "name", nullptr, MAX_ID_NAME - 2, "Name", "Object name to add");
prop = RNA_def_float_matrix(
- ot->srna, "matrix", 4, 4, NULL, 0.0f, 0.0f, "Matrix", "", 0.0f, 0.0f);
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ ot->srna, "matrix", 4, 4, nullptr, 0.0f, 0.0f, "Matrix", "", 0.0f, 0.0f);
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
object_add_drop_xy_props(ot);
}
@@ -3599,7 +3623,7 @@ static int object_transform_to_mouse_exec(bContext *C, wmOperator *op)
ob = OBACT(view_layer);
}
- if (ob == NULL) {
+ if (ob == nullptr) {
BKE_report(op->reports, RPT_ERROR, "Object not found");
return OPERATOR_CANCELLED;
}
@@ -3615,8 +3639,10 @@ static int object_transform_to_mouse_exec(bContext *C, wmOperator *op)
PropertyRNA *prop_matrix = RNA_struct_find_property(op->ptr, "matrix");
if (RNA_property_is_set(op->ptr, prop_matrix)) {
+ ObjectsInViewLayerParams params = {0};
uint objects_len;
- Object **objects = BKE_view_layer_array_selected_objects(view_layer, NULL, &objects_len, {0});
+ Object **objects = BKE_view_layer_array_selected_objects_params(
+ view_layer, nullptr, &objects_len, &params);
float matrix[4][4];
RNA_property_float_get_array(op->ptr, prop_matrix, &matrix[0][0]);
@@ -3674,14 +3700,14 @@ void OBJECT_OT_transform_to_mouse(wmOperatorType *ot)
PropertyRNA *prop;
RNA_def_string(ot->srna,
"name",
- NULL,
+ nullptr,
MAX_ID_NAME - 2,
"Name",
"Object name to place (when unset use the active object)");
prop = RNA_def_float_matrix(
- ot->srna, "matrix", 4, 4, NULL, 0.0f, 0.0f, "Matrix", "", 0.0f, 0.0f);
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ ot->srna, "matrix", 4, 4, nullptr, 0.0f, 0.0f, "Matrix", "", 0.0f, 0.0f);
+ RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
object_add_drop_xy_props(ot);
}
@@ -3696,12 +3722,12 @@ static bool object_join_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
- if (ob == NULL || ob->data == NULL || ID_IS_LINKED(ob) || ID_IS_OVERRIDE_LIBRARY(ob) ||
+ if (ob == nullptr || ob->data == nullptr || ID_IS_LINKED(ob) || ID_IS_OVERRIDE_LIBRARY(ob) ||
ID_IS_OVERRIDE_LIBRARY(ob->data)) {
return false;
}
- if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE, OB_GPENCIL)) {
+ if (ELEM(ob->type, OB_MESH, OB_CURVES_LEGACY, OB_SURF, OB_ARMATURE, OB_GPENCIL)) {
return ED_operator_screenactive(C);
}
return false;
@@ -3740,7 +3766,7 @@ static int object_join_exec(bContext *C, wmOperator *op)
if (ob->type == OB_MESH) {
ret = ED_mesh_join_objects_exec(C, op);
}
- else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
ret = ED_curve_join_objects_exec(C, op);
}
else if (ob->type == OB_ARMATURE) {
@@ -3802,7 +3828,7 @@ static bool join_shapes_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
- if (ob == NULL || ob->data == NULL || ID_IS_LINKED(ob) || ID_IS_OVERRIDE_LIBRARY(ob) ||
+ if (ob == nullptr || ob->data == nullptr || ID_IS_LINKED(ob) || ID_IS_OVERRIDE_LIBRARY(ob) ||
ID_IS_OVERRIDE_LIBRARY(ob->data)) {
return false;
}
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 30e3f2b0c69..3b40a10eb2a 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -301,6 +301,7 @@ static void bake_targets_refresh(BakeTargets *targets)
Image *ima = targets->images[i].image;
if (ima) {
+ BKE_image_partial_update_mark_full_update(ima);
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
BKE_image_free_gputextures(ima);
DEG_id_tag_update(&ima->id, 0);
@@ -605,7 +606,7 @@ static bool bake_objects_check(Main *bmain,
continue;
}
- if (ELEM(ob_iter->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL) == false) {
+ if (ELEM(ob_iter->type, OB_MESH, OB_FONT, OB_CURVES_LEGACY, OB_SURF, OB_MBALL) == false) {
BKE_reportf(reports,
RPT_ERROR,
"Object \"%s\" is not a mesh or can't be converted to a mesh (Curve, Text, "
@@ -1038,19 +1039,18 @@ static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets,
* materials and UVs. */
pixel->seed = v;
- /* Barycentric coordinates, nudged a bit to avoid precision issues that
- * may happen when exactly at the vertex coordinate. */
+ /* Barycentric coordinates. */
if (j == 0) {
- pixel->uv[0] = 1.0f - FLT_EPSILON;
- pixel->uv[1] = FLT_EPSILON / 2.0f;
+ pixel->uv[0] = 1.0f;
+ pixel->uv[1] = 0.0f;
}
else if (j == 1) {
- pixel->uv[0] = FLT_EPSILON / 2.0f;
- pixel->uv[1] = 1.0f - FLT_EPSILON;
+ pixel->uv[0] = 0.0f;
+ pixel->uv[1] = 1.0f;
}
else if (j == 2) {
- pixel->uv[0] = FLT_EPSILON / 2.0f;
- pixel->uv[1] = FLT_EPSILON / 2.0f;
+ pixel->uv[0] = 0.0f;
+ pixel->uv[1] = 0.0f;
}
}
}
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 4ccd35b512b..3f4ed27a175 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -511,7 +511,7 @@ static void test_constraint(
*
* In other cases it should be impossible to have a type mismatch.
*/
- if (ct->tar->type != OB_CURVE) {
+ if (ct->tar->type != OB_CURVES_LEGACY) {
con->flag |= CONSTRAINT_DISABLE;
}
else {
@@ -1443,6 +1443,11 @@ static int constraint_delete_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(C, op, ob, 0);
+
+ if (con == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
ListBase *lb = ED_object_constraint_list_from_constraint(ob, con, NULL);
/* Store name temporarily for report. */
@@ -1510,6 +1515,11 @@ static int constraint_apply_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(C, op, ob, 0);
+
+ if (con == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
bPoseChannel *pchan;
ListBase *constraints = ED_object_constraint_list_from_constraint(ob, con, &pchan);
@@ -1602,6 +1612,11 @@ static int constraint_copy_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(C, op, ob, 0);
+
+ if (con == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
bPoseChannel *pchan;
ListBase *constraints = ED_object_constraint_list_from_constraint(ob, con, &pchan);
@@ -1682,6 +1697,11 @@ static int constraint_copy_to_selected_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Object *obact = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(C, op, obact, 0);
+
+ if (con == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
bPoseChannel *pchan;
ED_object_constraint_list_from_constraint(obact, con, &pchan);
@@ -2275,7 +2295,8 @@ static bool get_new_constraint_target(
break;
}
- if (((!only_curve) || (ob->type == OB_CURVE)) && ((!only_mesh) || (ob->type == OB_MESH))) {
+ if (((!only_curve) || (ob->type == OB_CURVES_LEGACY)) &&
+ ((!only_mesh) || (ob->type == OB_MESH))) {
/* set target */
*tar_ob = ob;
found = true;
diff --git a/source/blender/editors/object/object_data_transform.c b/source/blender/editors/object/object_data_transform.c
index f74556e3639..63513eac965 100644
--- a/source/blender/editors/object/object_data_transform.c
+++ b/source/blender/editors/object/object_data_transform.c
@@ -382,7 +382,7 @@ struct XFormObjectData *ED_object_data_xform_create_ex(ID *id, bool is_edit_mode
break;
}
- case ID_CU: {
+ case ID_CU_LEGACY: {
Curve *cu = (Curve *)id;
struct Key *key = cu->key;
@@ -505,7 +505,7 @@ void ED_object_data_xform_destroy(struct XFormObjectData *xod_base)
}
break;
}
- case ID_CU: {
+ case ID_CU_LEGACY: {
struct XFormObjectData_Curve *xod = (struct XFormObjectData_Curve *)xod_base;
if (xod->key_data != NULL) {
MEM_freeN(xod->key_data);
@@ -565,7 +565,7 @@ void ED_object_data_xform_by_mat4(struct XFormObjectData *xod_base, const float
break;
}
- case ID_CU: {
+ case ID_CU_LEGACY: {
BLI_assert(xod_base->is_edit_mode == false); /* Not used currently. */
Curve *cu = (Curve *)xod_base->id;
@@ -670,7 +670,7 @@ void ED_object_data_xform_restore(struct XFormObjectData *xod_base)
break;
}
- case ID_CU: {
+ case ID_CU_LEGACY: {
Curve *cu = (Curve *)xod_base->id;
struct Key *key = cu->key;
@@ -745,7 +745,7 @@ void ED_object_data_xform_tag_update(struct XFormObjectData *xod_base)
DEG_id_tag_update(&lt->id, ID_RECALC_GEOMETRY);
break;
}
- case ID_CU: {
+ case ID_CU_LEGACY: {
/* Generic update. */
Curve *cu = (Curve *)xod_base->id;
DEG_id_tag_update(&cu->id, ID_RECALC_GEOMETRY);
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index fd40ac7bc7c..82b14787d9b 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -21,6 +21,7 @@
#include "BLT_translation.h"
+#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_collection_types.h"
#include "DNA_curve_types.h"
@@ -73,6 +74,7 @@
#include "ED_curve.h"
#include "ED_gpencil.h"
#include "ED_image.h"
+#include "ED_keyframes_keylist.h"
#include "ED_lattice.h"
#include "ED_mball.h"
#include "ED_mesh.h"
@@ -89,7 +91,7 @@
#include "CLG_log.h"
-/* For menu/popup icons etc etc. */
+/* For menu/popup icons etc. */
#include "UI_interface.h"
#include "UI_resources.h"
@@ -340,10 +342,10 @@ static int object_hide_collection_exec(bContext *C, wmOperator *op)
View3D *v3d = CTX_wm_view3d(C);
int index = RNA_int_get(op->ptr, "collection_index");
- const bool extend = (win->eventstate->shift != 0);
+ const bool extend = (win->eventstate->modifier & KM_SHIFT) != 0;
const bool toggle = RNA_boolean_get(op->ptr, "toggle");
- if (win->eventstate->alt != 0) {
+ if (win->eventstate->modifier & KM_ALT) {
index += 10;
}
@@ -568,7 +570,7 @@ static bool ED_object_editmode_load_free_ex(Main *bmain,
*/
DEG_relations_tag_update(bmain);
}
- else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
const Curve *cu = obedit->data;
if (cu->editnurb == NULL) {
return false;
@@ -799,12 +801,16 @@ bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag
WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_LATTICE, scene);
}
- else if (ELEM(ob->type, OB_SURF, OB_CURVE)) {
+ else if (ELEM(ob->type, OB_SURF, OB_CURVES_LEGACY)) {
ok = true;
ED_curve_editnurb_make(ob);
WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_CURVE, scene);
}
+ else if (ob->type == OB_CURVES) {
+ ok = true;
+ WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_CURVES, scene);
+ }
if (ok) {
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
@@ -1019,7 +1025,7 @@ void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object)
if (!md) {
if (pd && (pd->shape == PFIELD_SHAPE_SURFACE) &&
!ELEM(pd->forcefield, 0, PFIELD_GUIDE, PFIELD_TEXTURE)) {
- if (ELEM(object->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) {
+ if (ELEM(object->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVES_LEGACY)) {
ED_object_modifier_add(NULL, bmain, scene, object, NULL, eModifierType_Surface);
}
}
@@ -1205,30 +1211,32 @@ static int object_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEv
/* set default settings from existing/stored settings */
{
bAnimVizSettings *avs = &ob->avs;
-
- RNA_int_set(op->ptr, "start_frame", avs->path_sf);
- RNA_int_set(op->ptr, "end_frame", avs->path_ef);
+ RNA_enum_set(op->ptr, "display_type", avs->path_type);
+ RNA_enum_set(op->ptr, "range", avs->path_range);
}
/* show popup dialog to allow editing of range... */
/* FIXME: hard-coded dimensions here are just arbitrary. */
- return WM_operator_props_dialog_popup(C, op, 200);
+ return WM_operator_props_dialog_popup(C, op, 270);
}
/* Calculate/recalculate whole paths (avs.path_sf to avs.path_ef) */
static int object_calculate_paths_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- int start = RNA_int_get(op->ptr, "start_frame");
- int end = RNA_int_get(op->ptr, "end_frame");
+ short path_type = RNA_enum_get(op->ptr, "display_type");
+ short path_range = RNA_enum_get(op->ptr, "range");
- /* set up path data for bones being calculated */
+ /* set up path data for objects being calculated */
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
- bAnimVizSettings *avs = &ob->avs;
-
- /* grab baking settings from operator settings */
- avs->path_sf = start;
- avs->path_ef = end;
+ /* When operator is not invoked, dismiss the operator settings */
+ if (op->flag & OP_IS_INVOKE) {
+ bAnimVizSettings *avs = &ob->avs;
+ /* grab baking settings from operator settings */
+ avs->path_type = path_type;
+ avs->path_range = path_range;
+ }
+ animviz_motionpath_compute_range(ob, scene);
/* verify that the selected object has the appropriate settings */
animviz_verify_motionpaths(op->reports, scene, ob, NULL);
@@ -1247,9 +1255,9 @@ static int object_calculate_paths_exec(bContext *C, wmOperator *op)
void OBJECT_OT_paths_calculate(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Calculate Object Paths";
+ ot->name = "Calculate Object Motion Paths";
ot->idname = "OBJECT_OT_paths_calculate";
- ot->description = "Calculate motion paths for the selected objects";
+ ot->description = "Generate motion paths for the selected objects";
/* api callbacks */
ot->invoke = object_calculate_paths_invoke;
@@ -1260,24 +1268,18 @@ void OBJECT_OT_paths_calculate(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_int(ot->srna,
- "start_frame",
- 1,
- MINAFRAME,
- MAXFRAME,
- "Start",
- "First frame to calculate object paths on",
- MINFRAME,
- MAXFRAME / 2.0);
- RNA_def_int(ot->srna,
- "end_frame",
- 250,
- MINAFRAME,
- MAXFRAME,
- "End",
- "Last frame to calculate object paths on",
- MINFRAME,
- MAXFRAME / 2.0);
+ RNA_def_enum(ot->srna,
+ "display_type",
+ rna_enum_motionpath_display_type_items,
+ MOTIONPATH_TYPE_RANGE,
+ "Display type",
+ "");
+ RNA_def_enum(ot->srna,
+ "range",
+ rna_enum_motionpath_range_items,
+ MOTIONPATH_RANGE_SCENE,
+ "Computation Range",
+ "");
}
/** \} */
@@ -1296,13 +1298,19 @@ static bool object_update_paths_poll(bContext *C)
return false;
}
-static int object_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
+static int object_update_paths_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
if (scene == NULL) {
return OPERATOR_CANCELLED;
}
+ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
+ animviz_motionpath_compute_range(ob, scene);
+ /* verify that the selected object has the appropriate settings */
+ animviz_verify_motionpaths(op->reports, scene, ob, NULL);
+ }
+ CTX_DATA_END;
/* calculate the paths for objects that have them (and are tagged to get refreshed) */
ED_objects_recalculate_paths_selected(C, scene, OBJECT_PATH_CALC_RANGE_FULL);
@@ -1423,7 +1431,7 @@ static int object_clear_paths_exec(bContext *C, wmOperator *op)
/* operator callback/wrapper */
static int object_clear_paths_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if ((event->shift) && !RNA_struct_property_is_set(op->ptr, "only_selected")) {
+ if ((event->modifier & KM_SHIFT) && !RNA_struct_property_is_set(op->ptr, "only_selected")) {
RNA_boolean_set(op->ptr, "only_selected", true);
}
return object_clear_paths_exec(C, op);
@@ -1453,46 +1461,6 @@ void OBJECT_OT_paths_clear(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Update Motion Paths Range from Scene Operator
- * \{ */
-
-static int object_update_paths_range_exec(bContext *C, wmOperator *UNUSED(op))
-{
- Scene *scene = CTX_data_scene(C);
-
- /* Loop over all editable objects in scene. */
- CTX_DATA_BEGIN (C, Object *, ob, editable_objects) {
- /* use Preview Range or Full Frame Range - whichever is in use */
- ob->avs.path_sf = PSFRA;
- ob->avs.path_ef = PEFRA;
-
- /* tag for updates */
- DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
- }
- CTX_DATA_END;
-
- return OPERATOR_FINISHED;
-}
-
-void OBJECT_OT_paths_range_update(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Update Range from Scene";
- ot->idname = "OBJECT_OT_paths_range_update";
- ot->description = "Update frame range for motion paths from the Scene's current frame range";
-
- /* callbacks */
- ot->exec = object_update_paths_range_exec;
- ot->poll = ED_operator_object_active_editable;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Object Shade Smooth/Flat Operator
* \{ */
@@ -1548,7 +1516,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op)
BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
changed = true;
}
- else if (ELEM(ob->type, OB_SURF, OB_CURVE)) {
+ else if (ELEM(ob->type, OB_SURF, OB_CURVES_LEGACY)) {
BKE_curve_smooth_flag_set(ob->data, use_smooth);
changed = true;
}
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index 338307dc8ca..dffbb3bedd5 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -342,7 +342,7 @@ static bool object_hook_index_array(Main *bmain,
}
return true;
}
- case OB_CURVE:
+ case OB_CURVES_LEGACY:
case OB_SURF:
ED_curve_editnurb_load(bmain, obedit);
ED_curve_editnurb_make(obedit);
@@ -447,7 +447,7 @@ static void object_hook_select(Object *ob, HookModifierData *hmd)
else if (ob->type == OB_LATTICE) {
select_editlattice_hook(ob, hmd);
}
- else if (ob->type == OB_CURVE) {
+ else if (ob->type == OB_CURVES_LEGACY) {
select_editcurve_hook(ob, hmd);
}
else if (ob->type == OB_SURF) {
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 0aac5957c9d..135c76140c1 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -76,7 +76,6 @@ void OBJECT_OT_shade_flat(struct wmOperatorType *ot);
void OBJECT_OT_paths_calculate(struct wmOperatorType *ot);
void OBJECT_OT_paths_update(struct wmOperatorType *ot);
void OBJECT_OT_paths_clear(struct wmOperatorType *ot);
-void OBJECT_OT_paths_range_update(struct wmOperatorType *ot);
void OBJECT_OT_paths_update_visible(struct wmOperatorType *ot);
void OBJECT_OT_forcefield_toggle(struct wmOperatorType *ot);
@@ -97,7 +96,7 @@ void OBJECT_OT_select_more(struct wmOperatorType *ot);
void OBJECT_OT_select_less(struct wmOperatorType *ot);
void OBJECT_OT_select_same_collection(struct wmOperatorType *ot);
-/* object_add.c */
+/* object_add.cc */
void OBJECT_OT_add(struct wmOperatorType *ot);
void OBJECT_OT_add_named(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c
index 509e496c39a..8e9e8558016 100644
--- a/source/blender/editors/object/object_modes.c
+++ b/source/blender/editors/object/object_modes.c
@@ -118,7 +118,7 @@ bool ED_object_mode_compat_test(const Object *ob, eObjectMode mode)
}
}
break;
- case OB_CURVE:
+ case OB_CURVES_LEGACY:
case OB_SURF:
case OB_FONT:
case OB_MBALL:
@@ -143,7 +143,7 @@ bool ED_object_mode_compat_test(const Object *ob, eObjectMode mode)
}
break;
case OB_CURVES:
- if (mode & (OB_MODE_SCULPT_CURVES)) {
+ if (mode & (OB_MODE_EDIT | OB_MODE_SCULPT_CURVES)) {
return true;
}
break;
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 38a955dca0a..e0d25baec16 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -110,7 +110,7 @@ static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object *
else if (ob->type == OB_MBALL) {
BKE_displist_make_mball(depsgraph, scene_eval, ob_eval);
}
- else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
+ else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
BKE_displist_make_curveTypes(depsgraph, scene_eval, ob_eval, false);
}
else if (ob->type == OB_GPENCIL) {
@@ -757,7 +757,7 @@ static bool modifier_apply_obdata(
}
}
}
- else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
Curve *curve = ob->data;
Curve *curve_eval = (Curve *)object_eval->data;
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 35f5ede270d..45ee4daa441 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -45,7 +45,6 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_paths_calculate);
WM_operatortype_append(OBJECT_OT_paths_update);
WM_operatortype_append(OBJECT_OT_paths_clear);
- WM_operatortype_append(OBJECT_OT_paths_range_update);
WM_operatortype_append(OBJECT_OT_paths_update_visible);
WM_operatortype_append(OBJECT_OT_forcefield_toggle);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 8834941d083..3ecf86d14ed 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -169,7 +169,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
}
}
}
- else if (ELEM(obedit->type, OB_SURF, OB_CURVE)) {
+ else if (ELEM(obedit->type, OB_SURF, OB_CURVES_LEGACY)) {
ListBase *editnurb = object_editcurve_get(obedit);
for (Nurb *nu = editnurb->first; nu != NULL; nu = nu->next) {
@@ -341,7 +341,7 @@ EnumPropertyItem prop_clear_parent_types[] = {
/* Helper for ED_object_parent_clear() - Remove deform-modifiers associated with parent */
static void object_remove_parent_deform_modifiers(Object *ob, const Object *par)
{
- if (ELEM(par->type, OB_ARMATURE, OB_LATTICE, OB_CURVE)) {
+ if (ELEM(par->type, OB_ARMATURE, OB_LATTICE, OB_CURVES_LEGACY)) {
ModifierData *md, *mdn;
/* assume that we only need to remove the first instance of matching deform modifier here */
@@ -363,7 +363,7 @@ static void object_remove_parent_deform_modifiers(Object *ob, const Object *par)
free = true;
}
}
- else if ((md->type == eModifierType_Curve) && (par->type == OB_CURVE)) {
+ else if ((md->type == eModifierType_Curve) && (par->type == OB_CURVES_LEGACY)) {
CurveModifierData *cmd = (CurveModifierData *)md;
if (cmd->object == par) {
free = true;
@@ -531,7 +531,7 @@ bool ED_object_parent_set(ReportList *reports,
switch (partype) {
case PAR_FOLLOW:
case PAR_PATH_CONST: {
- if (par->type != OB_CURVE) {
+ if (par->type != OB_CURVES_LEGACY) {
return false;
}
Curve *cu = par->data;
@@ -626,7 +626,7 @@ bool ED_object_parent_set(ReportList *reports,
*/
/* XXX currently this should only happen for meshes, curves, surfaces,
* and lattices - this stuff isn't available for meta-balls yet. */
- if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
+ if (ELEM(ob->type, OB_MESH, OB_CURVES_LEGACY, OB_SURF, OB_FONT, OB_LATTICE)) {
ModifierData *md;
switch (partype) {
@@ -968,7 +968,7 @@ static int parent_set_invoke_menu(bContext *C, wmOperatorType *ot)
uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_BONE);
uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_BONE_RELATIVE);
}
- else if (parent->type == OB_CURVE) {
+ else if (parent->type == OB_CURVES_LEGACY) {
uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_CURVE);
uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_FOLLOW);
uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_PATH_CONST);
@@ -1820,7 +1820,7 @@ static void single_obdata_users(
ob->data,
BKE_id_copy_ex(bmain, ob->data, NULL, LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS));
break;
- case OB_CURVE:
+ case OB_CURVES_LEGACY:
case OB_SURF:
case OB_FONT:
ob->data = cu = ID_NEW_SET(
@@ -2318,7 +2318,7 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
const bool success = BKE_lib_override_library_create(
- bmain, scene, view_layer, NULL, id_root, &obact->id, NULL);
+ bmain, scene, view_layer, NULL, id_root, id_root, &obact->id, NULL);
/* Remove the instance empty from this scene, the items now have an overridden collection
* instead. */
diff --git a/source/blender/editors/object/object_remesh.cc b/source/blender/editors/object/object_remesh.cc
index 44e6fb10528..2e495ac6147 100644
--- a/source/blender/editors/object/object_remesh.cc
+++ b/source/blender/editors/object/object_remesh.cc
@@ -406,7 +406,7 @@ static int voxel_size_edit_modal(bContext *C, wmOperator *op, const wmEvent *eve
d = cd->slow_mval[0] - mval[0];
}
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
/* Linear mode, enables jumping to any voxel size. */
d = d * 0.0005f;
}
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index f017fea7cdf..9e82abf4d07 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -613,7 +613,7 @@ static int apply_objects_internal(bContext *C,
OB_ARMATURE,
OB_LATTICE,
OB_MBALL,
- OB_CURVE,
+ OB_CURVES_LEGACY,
OB_SURF,
OB_FONT,
OB_GPENCIL)) {
@@ -639,13 +639,13 @@ static int apply_objects_internal(bContext *C,
}
}
- if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
ID *obdata = ob->data;
Curve *cu;
cu = ob->data;
- if (((ob->type == OB_CURVE) && !(cu->flag & CU_3D)) && (apply_rot || apply_loc)) {
+ if (((ob->type == OB_CURVES_LEGACY) && !(cu->flag & CU_3D)) && (apply_rot || apply_loc)) {
BKE_reportf(
reports,
RPT_ERROR,
@@ -811,7 +811,7 @@ static int apply_objects_internal(bContext *C,
MetaBall *mb = ob->data;
BKE_mball_transform(mb, mat, do_props);
}
- else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
Curve *cu = ob->data;
scale = mat3_to_scale(rsmat);
BKE_curve_transform_ex(cu, mat, true, do_props, scale);
@@ -1209,7 +1209,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
do_inverse_offset = true;
}
}
- else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
Curve *cu = ob->data;
if (centermode == ORIGIN_TO_CURSOR) {
@@ -1223,7 +1223,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
}
/* don't allow Z change if curve is 2D */
- if ((ob->type == OB_CURVE) && !(cu->flag & CU_3D)) {
+ if ((ob->type == OB_CURVES_LEGACY) && !(cu->flag & CU_3D)) {
cent[2] = 0.0;
}
@@ -1861,7 +1861,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const
view3d_operator_needs_opengl(C);
- const bool is_translate = (event->ctrl != 0);
+ const bool is_translate = event->modifier & KM_CTRL;
const bool is_translate_init = is_translate && (xfd->is_translate != is_translate);
if (event->type == MOUSEMOVE || is_translate_init) {
diff --git a/source/blender/editors/object/object_utils.c b/source/blender/editors/object/object_utils.c
index 19940fbb0fc..cb9c8a92abe 100644
--- a/source/blender/editors/object/object_utils.c
+++ b/source/blender/editors/object/object_utils.c
@@ -64,7 +64,7 @@ bool ED_object_calc_active_center_for_editmode(Object *obedit,
break;
}
- case OB_CURVE:
+ case OB_CURVES_LEGACY:
case OB_SURF: {
Curve *cu = obedit->data;
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index af9496263e7..fc815ebe682 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -4684,7 +4684,7 @@ static int brush_edit_init(bContext *C, wmOperator *op)
bedit->ob = ob;
bedit->edit = edit;
- bedit->zfac = ED_view3d_calc_zfac(region->regiondata, min, NULL);
+ bedit->zfac = ED_view3d_calc_zfac(region->regiondata, min);
/* cache view depths and settings for re-use */
PE_set_view3d_data(C, &bedit->data);
@@ -4757,7 +4757,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
switch (pset->brushtype) {
case PE_BRUSH_COMB: {
- const float mval_f[2] = {dx, dy};
+ const float xy_delta[2] = {dx, dy};
data.mval = mval;
data.rad = pe_brush_size_get(scene, brush);
@@ -4771,7 +4771,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
invert_m4_m4(ob->imat, ob->obmat);
- ED_view3d_win_to_delta(region, mval_f, vec, bedit->zfac);
+ ED_view3d_win_to_delta(region, xy_delta, bedit->zfac, vec);
data.dvec = vec;
foreach_mouse_hit_key(&data, brush_comb, selected);
@@ -4963,7 +4963,7 @@ static void brush_edit_apply_event(bContext *C, wmOperator *op, const wmEvent *e
RNA_collection_add(op->ptr, "stroke", &itemptr);
RNA_float_set_array(&itemptr, "mouse", mouse);
- RNA_boolean_set(&itemptr, "pen_flip", event->shift != false); /* XXX hardcoded */
+ RNA_boolean_set(&itemptr, "pen_flip", event->modifier & KM_SHIFT); /* XXX hardcoded */
/* apply */
brush_edit_apply(C, op, &itemptr);
diff --git a/source/blender/editors/render/render_internal.cc b/source/blender/editors/render/render_internal.cc
index 5308d4611e7..03c0f3977b7 100644
--- a/source/blender/editors/render/render_internal.cc
+++ b/source/blender/editors/render/render_internal.cc
@@ -618,6 +618,12 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
static void current_scene_update(void *rjv, Scene *scene)
{
RenderJob *rj = static_cast<RenderJob *>(rjv);
+
+ if (rj->current_scene != scene) {
+ /* Image must be updated when rendered scene changes. */
+ BKE_image_partial_update_mark_full_update(rj->image);
+ }
+
rj->current_scene = scene;
rj->iuser.scene = scene;
}
@@ -1188,5 +1194,6 @@ void RENDER_OT_shutter_curve_preset(wmOperatorType *ot)
ot->exec = render_shutter_curve_preset_exec;
prop = RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", "");
- RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
+ RNA_def_property_translation_context(prop,
+ BLT_I18NCONTEXT_ID_CURVE_LEGACY); /* Abusing id_curve :/ */
}
diff --git a/source/blender/editors/render/render_opengl.cc b/source/blender/editors/render/render_opengl.cc
index 1ca2b01a2cb..be66e87f2e5 100644
--- a/source/blender/editors/render/render_opengl.cc
+++ b/source/blender/editors/render/render_opengl.cc
@@ -599,30 +599,30 @@ static int gather_frames_to_render_for_id(LibraryIDLinkCallbackData *cb_data)
const ID_Type id_type = GS(id->name);
switch (id_type) {
/* Whitelist: */
- case ID_ME: /* Mesh */
- case ID_CU: /* Curve */
- case ID_MB: /* MetaBall */
- case ID_MA: /* Material */
- case ID_TE: /* Tex (Texture) */
- case ID_IM: /* Image */
- case ID_LT: /* Lattice */
- case ID_LA: /* Light */
- case ID_CA: /* Camera */
- case ID_KE: /* Key (shape key) */
- case ID_VF: /* VFont (Vector Font) */
- case ID_TXT: /* Text */
- case ID_SPK: /* Speaker */
- case ID_SO: /* Sound */
- case ID_AR: /* bArmature */
- case ID_NT: /* bNodeTree */
- case ID_PA: /* ParticleSettings */
- case ID_MC: /* MovieClip */
- case ID_MSK: /* Mask */
- case ID_LP: /* LightProbe */
- case ID_CV: /* Curves */
- case ID_PT: /* PointCloud */
- case ID_VO: /* Volume */
- case ID_SIM: /* Simulation */
+ case ID_ME: /* Mesh */
+ case ID_CU_LEGACY: /* Curve */
+ case ID_MB: /* MetaBall */
+ case ID_MA: /* Material */
+ case ID_TE: /* Tex (Texture) */
+ case ID_IM: /* Image */
+ case ID_LT: /* Lattice */
+ case ID_LA: /* Light */
+ case ID_CA: /* Camera */
+ case ID_KE: /* Key (shape key) */
+ case ID_VF: /* VFont (Vector Font) */
+ case ID_TXT: /* Text */
+ case ID_SPK: /* Speaker */
+ case ID_SO: /* Sound */
+ case ID_AR: /* bArmature */
+ case ID_NT: /* bNodeTree */
+ case ID_PA: /* ParticleSettings */
+ case ID_MC: /* MovieClip */
+ case ID_MSK: /* Mask */
+ case ID_LP: /* LightProbe */
+ case ID_CV: /* Curves */
+ case ID_PT: /* PointCloud */
+ case ID_VO: /* Volume */
+ case ID_SIM: /* Simulation */
break;
/* Blacklist: */
diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc
index 6aaf551a88a..eca30a6ac25 100644
--- a/source/blender/editors/render/render_preview.cc
+++ b/source/blender/editors/render/render_preview.cc
@@ -10,6 +10,7 @@
#include <cmath>
#include <cstdlib>
#include <cstring>
+#include <list>
#ifndef WIN32
# include <unistd.h>
@@ -1370,89 +1371,73 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat
ShaderPreview *sp = static_cast<ShaderPreview *>(customdata);
if (sp->pr_method == PR_ICON_DEFERRED) {
- PreviewImage *prv = static_cast<PreviewImage *>(sp->owner);
- ImBuf *thumb;
- char *deferred_data = static_cast<char *>(PRV_DEFERRED_DATA(prv));
- ThumbSource source = static_cast<ThumbSource>(deferred_data[0]);
- char *path = &deferred_data[1];
-
- // printf("generating deferred %d×%d preview for %s\n", sp->sizex, sp->sizey, path);
-
- thumb = IMB_thumb_manage(path, THB_LARGE, source);
-
- if (thumb) {
- /* PreviewImage assumes premultiplied alhpa... */
- IMB_premultiply_alpha(thumb);
-
- icon_copy_rect(thumb, sp->sizex, sp->sizey, sp->pr_rect);
- IMB_freeImBuf(thumb);
- }
+ BLI_assert_unreachable();
+ return;
}
- else {
- ID *id = sp->id;
- short idtype = GS(id->name);
- BLI_assert(id != nullptr);
-
- if (idtype == ID_IM) {
- Image *ima = (Image *)id;
- ImBuf *ibuf = nullptr;
- ImageUser iuser;
- BKE_imageuser_default(&iuser);
+ ID *id = sp->id;
+ short idtype = GS(id->name);
- if (ima == nullptr) {
- return;
- }
+ BLI_assert(id != nullptr);
- /* setup dummy image user */
- iuser.framenr = 1;
- iuser.scene = sp->scene;
-
- /* NOTE(@elubie): this needs to be changed: here image is always loaded if not
- * already there. Very expensive for large images. Need to find a way to
- * only get existing `ibuf`. */
- ibuf = BKE_image_acquire_ibuf(ima, &iuser, nullptr);
- if (ibuf == nullptr || (ibuf->rect == nullptr && ibuf->rect_float == nullptr)) {
- BKE_image_release_ibuf(ima, ibuf, nullptr);
- return;
- }
+ if (idtype == ID_IM) {
+ Image *ima = (Image *)id;
+ ImBuf *ibuf = nullptr;
+ ImageUser iuser;
+ BKE_imageuser_default(&iuser);
- icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);
+ if (ima == nullptr) {
+ return;
+ }
- *do_update = true;
+ /* setup dummy image user */
+ iuser.framenr = 1;
+ iuser.scene = sp->scene;
+ /* NOTE(@elubie): this needs to be changed: here image is always loaded if not
+ * already there. Very expensive for large images. Need to find a way to
+ * only get existing `ibuf`. */
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, nullptr);
+ if (ibuf == nullptr || (ibuf->rect == nullptr && ibuf->rect_float == nullptr)) {
BKE_image_release_ibuf(ima, ibuf, nullptr);
+ return;
}
- else if (idtype == ID_BR) {
- Brush *br = (Brush *)id;
- br->icon_imbuf = icon_preview_imbuf_from_brush(br);
+ icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);
- memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(uint));
+ *do_update = true;
- if (!(br->icon_imbuf) || !(br->icon_imbuf->rect)) {
- return;
- }
+ BKE_image_release_ibuf(ima, ibuf, nullptr);
+ }
+ else if (idtype == ID_BR) {
+ Brush *br = (Brush *)id;
- icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect);
+ br->icon_imbuf = icon_preview_imbuf_from_brush(br);
- *do_update = true;
- }
- else if (idtype == ID_SCR) {
- bScreen *screen = (bScreen *)id;
+ memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(uint));
- ED_screen_preview_render(screen, sp->sizex, sp->sizey, sp->pr_rect);
- *do_update = true;
+ if (!(br->icon_imbuf) || !(br->icon_imbuf->rect)) {
+ return;
}
- else {
- /* re-use shader job */
- shader_preview_startjob(customdata, stop, do_update);
- /* world is rendered with alpha=0, so it wasn't displayed
- * this could be render option for sky to, for later */
- if (idtype == ID_WO) {
- set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255);
- }
+ icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect);
+
+ *do_update = true;
+ }
+ else if (idtype == ID_SCR) {
+ bScreen *screen = (bScreen *)id;
+
+ ED_screen_preview_render(screen, sp->sizex, sp->sizey, sp->pr_rect);
+ *do_update = true;
+ }
+ else {
+ /* re-use shader job */
+ shader_preview_startjob(customdata, stop, do_update);
+
+ /* world is rendered with alpha=0, so it wasn't displayed
+ * this could be render option for sky to, for later */
+ if (idtype == ID_WO) {
+ set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255);
}
}
}
@@ -1670,6 +1655,197 @@ static void icon_preview_endjob(void *customdata)
}
}
+/**
+ * Background job to manage requests for deferred loading of previews from the hard drive.
+ *
+ * Launches a single job to manage all incoming preview requests. The job is kept running until all
+ * preview requests are done loading (or it's otherwise aborted, e.g. by closing Blender).
+ *
+ * Note that this will use the OS thumbnail cache, i.e. load a preview from there or add it if not
+ * there yet. These two cases may lead to different performance.
+ */
+class PreviewLoadJob {
+ struct RequestedPreview {
+ PreviewImage *preview;
+ /** Requested size. */
+ eIconSizes icon_size;
+ };
+
+ /** The previews that are still to be loaded. */
+ ThreadQueue *todo_queue_; /* RequestedPreview * */
+ /** All unfinished preview requests, #update_fn() calls #finish_preview_request() on loaded
+ * previews and removes them from this list. Only access from the main thread! */
+ std::list<struct RequestedPreview> requested_previews_;
+
+ public:
+ PreviewLoadJob();
+ ~PreviewLoadJob();
+
+ static PreviewLoadJob &ensure_job(wmWindowManager *, wmWindow *);
+ static void load_jobless(PreviewImage *, eIconSizes);
+
+ void push_load_request(PreviewImage *, eIconSizes);
+
+ private:
+ static void run_fn(void *, short *, short *, float *);
+ static void update_fn(void *);
+ static void end_fn(void *);
+ static void free_fn(void *);
+
+ /** Mark a single requested preview as being done, remove the request. */
+ static void finish_request(RequestedPreview &);
+};
+
+PreviewLoadJob::PreviewLoadJob() : todo_queue_(BLI_thread_queue_init())
+{
+}
+
+PreviewLoadJob::~PreviewLoadJob()
+{
+ BLI_thread_queue_free(todo_queue_);
+}
+
+PreviewLoadJob &PreviewLoadJob::ensure_job(wmWindowManager *wm, wmWindow *win)
+{
+ wmJob *wm_job = WM_jobs_get(wm, win, nullptr, "Load Previews", 0, WM_JOB_TYPE_LOAD_PREVIEW);
+
+ if (!WM_jobs_is_running(wm_job)) {
+ PreviewLoadJob *job_data = MEM_new<PreviewLoadJob>("PreviewLoadJobData");
+
+ WM_jobs_customdata_set(wm_job, job_data, free_fn);
+ WM_jobs_timer(wm_job, 0.1, NC_WINDOW, NC_WINDOW);
+ WM_jobs_callbacks(wm_job, run_fn, nullptr, update_fn, end_fn);
+
+ WM_jobs_start(wm, wm_job);
+ }
+
+ return *reinterpret_cast<PreviewLoadJob *>(WM_jobs_customdata_get(wm_job));
+}
+
+void PreviewLoadJob::load_jobless(PreviewImage *preview, const eIconSizes icon_size)
+{
+ PreviewLoadJob job_data{};
+
+ job_data.push_load_request(preview, icon_size);
+
+ short stop = 0, do_update = 0;
+ float progress = 0;
+ run_fn(&job_data, &stop, &do_update, &progress);
+ update_fn(&job_data);
+ end_fn(&job_data);
+}
+
+void PreviewLoadJob::push_load_request(PreviewImage *preview, const eIconSizes icon_size)
+{
+ BLI_assert(preview->tag & PRV_TAG_DEFFERED);
+ RequestedPreview requested_preview{};
+ requested_preview.preview = preview;
+ requested_preview.icon_size = icon_size;
+
+ preview->flag[icon_size] |= PRV_RENDERING;
+ /* Warn main thread code that this preview is being rendered and cannot be freed. */
+ preview->tag |= PRV_TAG_DEFFERED_RENDERING;
+
+ requested_previews_.push_back(requested_preview);
+ BLI_thread_queue_push(todo_queue_, &requested_previews_.back());
+}
+
+void PreviewLoadJob::run_fn(void *customdata,
+ short *stop,
+ short *do_update,
+ float *UNUSED(progress))
+{
+ PreviewLoadJob *job_data = reinterpret_cast<PreviewLoadJob *>(customdata);
+
+ IMB_thumb_locks_acquire();
+
+ while (RequestedPreview *request = reinterpret_cast<RequestedPreview *>(
+ BLI_thread_queue_pop_timeout(job_data->todo_queue_, 100))) {
+ if (*stop) {
+ break;
+ }
+
+ PreviewImage *preview = request->preview;
+
+ const char *deferred_data = static_cast<char *>(PRV_DEFERRED_DATA(preview));
+ const ThumbSource source = static_cast<ThumbSource>(deferred_data[0]);
+ const char *path = &deferred_data[1];
+
+ // printf("loading deferred %d×%d preview for %s\n", request->sizex, request->sizey, path);
+
+ IMB_thumb_path_lock(path);
+ ImBuf *thumb = IMB_thumb_manage(path, THB_LARGE, source);
+ IMB_thumb_path_unlock(path);
+
+ if (thumb) {
+ /* PreviewImage assumes premultiplied alpha... */
+ IMB_premultiply_alpha(thumb);
+
+ icon_copy_rect(thumb,
+ preview->w[request->icon_size],
+ preview->h[request->icon_size],
+ preview->rect[request->icon_size]);
+ IMB_freeImBuf(thumb);
+ }
+
+ *do_update = true;
+ }
+
+ IMB_thumb_locks_release();
+}
+
+/* Only execute on the main thread! */
+void PreviewLoadJob::finish_request(RequestedPreview &request)
+{
+ PreviewImage *preview = request.preview;
+
+ preview->tag &= ~PRV_TAG_DEFFERED_RENDERING;
+ BKE_previewimg_finish(preview, request.icon_size);
+
+ BLI_assert_msg(BLI_thread_is_main(),
+ "Deferred releasing of preview images should only run on the main thread");
+ if (preview->tag & PRV_TAG_DEFFERED_DELETE) {
+ BLI_assert(preview->tag & PRV_TAG_DEFFERED);
+ BKE_previewimg_deferred_release(preview);
+ }
+}
+
+void PreviewLoadJob::update_fn(void *customdata)
+{
+ PreviewLoadJob *job_data = reinterpret_cast<PreviewLoadJob *>(customdata);
+
+ for (auto request_it = job_data->requested_previews_.begin();
+ request_it != job_data->requested_previews_.end();) {
+ RequestedPreview &requested = *request_it;
+ /* Skip items that are not done loading yet. */
+ if (requested.preview->tag & PRV_TAG_DEFFERED_RENDERING) {
+ ++request_it;
+ continue;
+ }
+ finish_request(requested);
+
+ /* Remove properly finished previews from the job data. */
+ auto next_it = job_data->requested_previews_.erase(request_it);
+ request_it = next_it;
+ }
+}
+
+void PreviewLoadJob::end_fn(void *customdata)
+{
+ PreviewLoadJob *job_data = reinterpret_cast<PreviewLoadJob *>(customdata);
+
+ /* Finish any possibly remaining queued previews. */
+ for (RequestedPreview &request : job_data->requested_previews_) {
+ finish_request(request);
+ }
+ job_data->requested_previews_.clear();
+}
+
+void PreviewLoadJob::free_fn(void *customdata)
+{
+ MEM_delete(reinterpret_cast<PreviewLoadJob *>(customdata));
+}
+
static void icon_preview_free(void *customdata)
{
IconPreview *ip = (IconPreview *)customdata;
@@ -1698,8 +1874,19 @@ bool ED_preview_id_is_supported(const ID *id)
}
void ED_preview_icon_render(
- const bContext *C, Scene *scene, ID *id, uint *rect, int sizex, int sizey)
+ const bContext *C, Scene *scene, PreviewImage *prv_img, ID *id, eIconSizes icon_size)
{
+ /* Deferred loading of previews from the file system. */
+ if (prv_img->tag & PRV_TAG_DEFFERED) {
+ if (prv_img->flag[icon_size] & PRV_RENDERING) {
+ /* Already in the queue, don't add it again. */
+ return;
+ }
+
+ PreviewLoadJob::load_jobless(prv_img, icon_size);
+ return;
+ }
+
IconPreview ip = {nullptr};
short stop = false, update = false;
float progress = 0.0f;
@@ -1716,7 +1903,10 @@ void ED_preview_icon_render(
ip.id_copy = duplicate_ids(id, true);
ip.active_object = CTX_data_active_object(C);
- icon_preview_add_size(&ip, rect, sizex, sizey);
+ prv_img->flag[icon_size] |= PRV_RENDERING;
+
+ icon_preview_add_size(
+ &ip, prv_img->rect[icon_size], prv_img->w[icon_size], prv_img->h[icon_size]);
icon_preview_startjob_all_sizes(&ip, &stop, &update, &progress);
@@ -1729,20 +1919,31 @@ void ED_preview_icon_render(
}
void ED_preview_icon_job(
- const bContext *C, void *owner, ID *id, uint *rect, int sizex, int sizey, const bool delay)
+ const bContext *C, PreviewImage *prv_img, ID *id, eIconSizes icon_size, const bool delay)
{
- wmJob *wm_job;
+ /* Deferred loading of previews from the file system. */
+ if (prv_img->tag & PRV_TAG_DEFFERED) {
+ if (prv_img->flag[icon_size] & PRV_RENDERING) {
+ /* Already in the queue, don't add it again. */
+ return;
+ }
+ PreviewLoadJob &load_job = PreviewLoadJob::ensure_job(CTX_wm_manager(C), CTX_wm_window(C));
+ load_job.push_load_request(prv_img, icon_size);
+
+ return;
+ }
+
IconPreview *ip, *old_ip;
ED_preview_ensure_dbase();
/* suspended start means it starts after 1 timer step, see WM_jobs_timer below */
- wm_job = WM_jobs_get(CTX_wm_manager(C),
- CTX_wm_window(C),
- owner,
- "Icon Preview",
- WM_JOB_EXCL_RENDER,
- WM_JOB_TYPE_RENDER_PREVIEW);
+ wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
+ CTX_wm_window(C),
+ prv_img,
+ "Icon Preview",
+ WM_JOB_EXCL_RENDER,
+ WM_JOB_TYPE_RENDER_PREVIEW);
ip = MEM_cnew<IconPreview>("icon preview");
@@ -1757,20 +1958,14 @@ void ED_preview_icon_job(
ip->depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ip->scene = DEG_get_input_scene(ip->depsgraph);
ip->active_object = CTX_data_active_object(C);
- ip->owner = owner;
+ ip->owner = prv_img;
ip->id = id;
ip->id_copy = duplicate_ids(id, false);
- icon_preview_add_size(ip, rect, sizex, sizey);
+ prv_img->flag[icon_size] |= PRV_RENDERING;
- /* Special threading hack:
- * warn main code that this preview is being rendered and cannot be freed... */
- {
- PreviewImage *prv_img = static_cast<PreviewImage *>(owner);
- if (prv_img->tag & PRV_TAG_DEFFERED) {
- prv_img->tag |= PRV_TAG_DEFFERED_RENDERING;
- }
- }
+ icon_preview_add_size(
+ ip, prv_img->rect[icon_size], prv_img->w[icon_size], prv_img->h[icon_size]);
/* setup job */
WM_jobs_customdata_set(wm_job, ip, icon_preview_free);
diff --git a/source/blender/editors/render/render_shading.cc b/source/blender/editors/render/render_shading.cc
index bad4208cf19..cd395674177 100644
--- a/source/blender/editors/render/render_shading.cc
+++ b/source/blender/editors/render/render_shading.cc
@@ -310,7 +310,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
}
}
}
- else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
Nurb *nu;
ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
@@ -411,7 +411,7 @@ static int material_slot_de_select(bContext *C, bool select)
changed = EDBM_deselect_by_material(em, mat_nr_active, select);
}
}
- else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
Nurb *nu;
BPoint *bp;
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 95534d2a036..af84f6f99a9 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -3438,6 +3438,37 @@ bool ED_area_is_global(const ScrArea *area)
return area->global != NULL;
}
+ScrArea *ED_area_find_under_cursor(const bContext *C, int spacetype, const int xy[2])
+{
+ bScreen *screen = CTX_wm_screen(C);
+ wmWindow *win = CTX_wm_window(C);
+
+ ScrArea *area = NULL;
+
+ if (win->parent) {
+ /* If active window is a child, check itself first. */
+ area = BKE_screen_find_area_xy(screen, spacetype, xy);
+ }
+
+ if (!area) {
+ /* Check all windows except the active one. */
+ int scr_pos[2];
+ wmWindow *r_win = WM_window_find_under_cursor(win, xy, scr_pos);
+ if (r_win && r_win != win) {
+ win = r_win;
+ screen = WM_window_get_active_screen(win);
+ area = BKE_screen_find_area_xy(screen, spacetype, scr_pos);
+ }
+ }
+
+ if (!area && !win->parent) {
+ /* If active window is a parent window, check itself last. */
+ area = BKE_screen_find_area_xy(screen, spacetype, xy);
+ }
+
+ return area;
+}
+
ScrArea *ED_screen_areas_iter_first(const wmWindow *win, const bScreen *screen)
{
ScrArea *global_area = win->global_areas.areabase.first;
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index f43bc08151a..8a84f4cf079 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -77,8 +77,9 @@ void immDrawPixelsTexScaledFullSize(const IMMDrawPixelsTexState *state,
* filtering results. Mipmaps can be used to get better results (i.e. #GL_LINEAR_MIPMAP_LINEAR),
* so always use mipmaps when filtering. */
const bool use_mipmap = use_filter && ((draw_width < img_w) || (draw_height < img_h));
+ const int mips = use_mipmap ? 9999 : 1;
- GPUTexture *tex = GPU_texture_create_2d("immDrawPixels", img_w, img_h, 1, gpu_format, NULL);
+ GPUTexture *tex = GPU_texture_create_2d("immDrawPixels", img_w, img_h, mips, gpu_format, NULL);
const bool use_float_data = ELEM(gpu_format, GPU_RGBA16F, GPU_RGB16F, GPU_R16F);
eGPUDataFormat gpu_data_format = (use_float_data) ? GPU_DATA_FLOAT : GPU_DATA_UBYTE;
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 7171aa7ac3b..ee3bc3cba76 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -585,7 +585,7 @@ bool ED_operator_uvmap(bContext *C)
bool ED_operator_editsurfcurve(bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
- if (obedit && ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ if (obedit && ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
return NULL != ((Curve *)obedit->data)->editnurb;
}
return false;
@@ -604,7 +604,7 @@ bool ED_operator_editsurfcurve_region_view3d(bContext *C)
bool ED_operator_editcurve(bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
- if (obedit && obedit->type == OB_CURVE) {
+ if (obedit && obedit->type == OB_CURVES_LEGACY) {
return NULL != ((Curve *)obedit->data)->editnurb;
}
return false;
@@ -613,7 +613,7 @@ bool ED_operator_editcurve(bContext *C)
bool ED_operator_editcurve_3d(bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
- if (obedit && obedit->type == OB_CURVE) {
+ if (obedit && obedit->type == OB_CURVES_LEGACY) {
Curve *cu = (Curve *)obedit->data;
return (cu->flag & CU_3D) && (NULL != cu->editnurb);
@@ -1008,9 +1008,6 @@ static void actionzone_exit(wmOperator *op)
static void actionzone_apply(bContext *C, wmOperator *op, int type)
{
wmWindow *win = CTX_wm_window(C);
- sActionzoneData *sad = op->customdata;
-
- sad->modifier = RNA_int_get(op->ptr, "modifier");
wmEvent event;
wm_event_init_from_window(win, &event);
@@ -1026,7 +1023,7 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type)
}
event.val = KM_NOTHING;
- event.is_repeat = false;
+ event.flag = 0;
event.customdata = op->customdata;
event.customdata_free = true;
op->customdata = NULL;
@@ -1051,6 +1048,7 @@ static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
sad->az = az;
sad->x = event->xy[0];
sad->y = event->xy[1];
+ sad->modifier = RNA_int_get(op->ptr, "modifier");
/* region azone directly reacts on mouse clicks */
if (ELEM(sad->az->type, AZONE_REGION, AZONE_FULLSCREEN)) {
@@ -1114,7 +1112,17 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* What area are we now in? */
ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->xy);
- if (area == sad->sa1) {
+ if (sad->modifier == 1) {
+ /* Duplicate area into new window. */
+ WM_cursor_set(win, WM_CURSOR_EDIT);
+ is_gesture = (delta_max > area_threshold);
+ }
+ else if (sad->modifier == 2) {
+ /* Swap areas. */
+ WM_cursor_set(win, WM_CURSOR_SWAP_AREA);
+ is_gesture = true;
+ }
+ else if (area == sad->sa1) {
/* Same area, so possible split. */
WM_cursor_set(win,
SCREEN_DIR_IS_VERTICAL(sad->gesture_dir) ? WM_CURSOR_H_SPLIT :
@@ -1320,8 +1328,9 @@ static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event)
switch (event->type) {
case MOUSEMOVE:
- /* second area, for join */
- sad->sa2 = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, event->xy);
+ /* Second area to swap with. */
+ sad->sa2 = ED_area_find_under_cursor(C, SPACE_TYPE_ANY, event->xy);
+ WM_cursor_set(CTX_wm_window(C), (sad->sa2) ? WM_CURSOR_SWAP_AREA : WM_CURSOR_STOP);
break;
case LEFTMOUSE: /* release LMB */
if (event->val == KM_RELEASE) {
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 55099e2e750..59fbc3a64fb 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -9,6 +9,7 @@ set(INC
../../bmesh
../../depsgraph
../../draw
+ ../../functions
../../gpu
../../imbuf
../../makesdna
@@ -24,11 +25,13 @@ set(INC
)
set(SRC
+ curves_sculpt_ops.cc
paint_cursor.c
paint_curve.c
paint_curve_undo.c
paint_hide.c
- paint_image.c
+ paint_image.cc
+ paint_image_ops_paint.cc
paint_image_2d.c
paint_image_2d_curve_mask.cc
paint_image_proj.c
@@ -66,6 +69,7 @@ set(SRC
sculpt_undo.c
sculpt_uv.c
+ curves_sculpt_intern.h
paint_intern.h
sculpt_intern.h
)
@@ -75,5 +79,16 @@ set(LIB
bf_blenlib
)
+if(WITH_TBB)
+ list(APPEND INC_SYS
+ ${TBB_INCLUDE_DIRS}
+ )
+ add_definitions(-DWITH_TBB)
+ if(WIN32)
+ # TBB includes Windows.h which will define min/max macros
+ # that will collide with the stl versions.
+ add_definitions(-DNOMINMAX)
+ endif()
+endif()
blender_add_lib(bf_editor_sculpt_paint "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_intern.h b/source/blender/editors/sculpt_paint/curves_sculpt_intern.h
new file mode 100644
index 00000000000..0d99e61192f
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_intern.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+struct bContext;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool CURVES_SCULPT_mode_poll(struct bContext *C);
+bool CURVES_SCULPT_mode_poll_view3d(struct bContext *C);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
new file mode 100644
index 00000000000..936226a03ed
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
@@ -0,0 +1,411 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_utildefines.h"
+
+#include "BKE_brush.h"
+#include "BKE_context.h"
+#include "BKE_curves.hh"
+#include "BKE_paint.h"
+
+#include "WM_api.h"
+#include "WM_toolsystem.h"
+
+#include "ED_curves_sculpt.h"
+#include "ED_object.h"
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+#include "DEG_depsgraph.h"
+
+#include "DNA_brush_types.h"
+#include "DNA_curves_types.h"
+#include "DNA_screen_types.h"
+
+#include "RNA_access.h"
+
+#include "BLI_index_mask_ops.hh"
+#include "BLI_math_vector.hh"
+
+#include "curves_sculpt_intern.h"
+#include "paint_intern.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Poll Functions
+ * \{ */
+
+bool CURVES_SCULPT_mode_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+ return ob && ob->mode & OB_MODE_SCULPT_CURVES;
+}
+
+bool CURVES_SCULPT_mode_poll_view3d(bContext *C)
+{
+ if (!CURVES_SCULPT_mode_poll(C)) {
+ return false;
+ }
+ if (CTX_wm_region_view3d(C) == nullptr) {
+ return false;
+ }
+ return true;
+}
+
+/** \} */
+
+namespace blender::ed::sculpt_paint {
+
+using blender::bke::CurvesGeometry;
+
+/* -------------------------------------------------------------------- */
+/** \name * SCULPT_CURVES_OT_brush_stroke
+ * \{ */
+
+struct StrokeExtension {
+ bool is_first;
+ float2 mouse_position;
+};
+
+/**
+ * Base class for stroke based operations in curves sculpt mode.
+ */
+class CurvesSculptStrokeOperation {
+ public:
+ virtual ~CurvesSculptStrokeOperation() = default;
+ virtual void on_stroke_extended(bContext *C, const StrokeExtension &stroke_extension) = 0;
+};
+
+class DeleteOperation : public CurvesSculptStrokeOperation {
+ private:
+ float2 last_mouse_position_;
+
+ public:
+ void on_stroke_extended(bContext *C, const StrokeExtension &stroke_extension)
+ {
+ Scene &scene = *CTX_data_scene(C);
+ Object &object = *CTX_data_active_object(C);
+ ARegion *region = CTX_wm_region(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+
+ CurvesSculpt &curves_sculpt = *scene.toolsettings->curves_sculpt;
+ Brush &brush = *BKE_paint_brush(&curves_sculpt.paint);
+ const float brush_radius = BKE_brush_size_get(&scene, &brush);
+
+ float4x4 projection;
+ ED_view3d_ob_project_mat_get(rv3d, &object, projection.values);
+
+ Curves &curves_id = *static_cast<Curves *>(object.data);
+ CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
+ MutableSpan<float3> positions = curves.positions();
+
+ const float2 mouse_start = stroke_extension.is_first ? stroke_extension.mouse_position :
+ last_mouse_position_;
+ const float2 mouse_end = stroke_extension.mouse_position;
+
+ /* Find indices of curves that have to be removed. */
+ Vector<int64_t> indices;
+ const IndexMask curves_to_remove = index_mask_ops::find_indices_based_on_predicate(
+ curves.curves_range(), 512, indices, [&](const int curve_i) {
+ const IndexRange point_range = curves.range_for_curve(curve_i);
+ for (const int segment_i : IndexRange(point_range.size() - 1)) {
+ const float3 pos1 = positions[point_range[segment_i]];
+ const float3 pos2 = positions[point_range[segment_i + 1]];
+
+ float2 pos1_proj, pos2_proj;
+ ED_view3d_project_float_v2_m4(region, pos1, pos1_proj, projection.values);
+ ED_view3d_project_float_v2_m4(region, pos2, pos2_proj, projection.values);
+
+ const float dist = dist_seg_seg_v2(pos1_proj, pos2_proj, mouse_start, mouse_end);
+ if (dist <= brush_radius) {
+ return true;
+ }
+ }
+ return false;
+ });
+
+ /* Just reset positions instead of actually removing the curves. This is just a prototype. */
+ threading::parallel_for(curves_to_remove.index_range(), 512, [&](const IndexRange range) {
+ for (const int curve_i : curves_to_remove.slice(range)) {
+ for (const int point_i : curves.range_for_curve(curve_i)) {
+ positions[point_i] = {0.0f, 0.0f, 0.0f};
+ }
+ }
+ });
+
+ curves.tag_positions_changed();
+ DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY);
+ ED_region_tag_redraw(region);
+
+ last_mouse_position_ = stroke_extension.mouse_position;
+ }
+};
+
+class MoveOperation : public CurvesSculptStrokeOperation {
+ private:
+ Vector<int64_t> points_to_move_indices_;
+ IndexMask points_to_move_;
+ float2 last_mouse_position_;
+
+ public:
+ void on_stroke_extended(bContext *C, const StrokeExtension &stroke_extension)
+ {
+ Scene &scene = *CTX_data_scene(C);
+ Object &object = *CTX_data_active_object(C);
+ ARegion *region = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+
+ CurvesSculpt &curves_sculpt = *scene.toolsettings->curves_sculpt;
+ Brush &brush = *BKE_paint_brush(&curves_sculpt.paint);
+ const float brush_radius = BKE_brush_size_get(&scene, &brush);
+
+ float4x4 projection;
+ ED_view3d_ob_project_mat_get(rv3d, &object, projection.values);
+
+ Curves &curves_id = *static_cast<Curves *>(object.data);
+ CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
+ MutableSpan<float3> positions = curves.positions();
+
+ if (stroke_extension.is_first) {
+ /* Find point indices to move. */
+ points_to_move_ = index_mask_ops::find_indices_based_on_predicate(
+ curves.points_range(), 512, points_to_move_indices_, [&](const int64_t point_i) {
+ const float3 position = positions[point_i];
+ float2 screen_position;
+ ED_view3d_project_float_v2_m4(region, position, screen_position, projection.values);
+ const float distance = len_v2v2(screen_position, stroke_extension.mouse_position);
+ return distance <= brush_radius;
+ });
+ }
+ else {
+ /* Move points based on mouse movement. */
+ const float2 mouse_diff = stroke_extension.mouse_position - last_mouse_position_;
+ threading::parallel_for(points_to_move_.index_range(), 512, [&](const IndexRange range) {
+ for (const int point_i : points_to_move_.slice(range)) {
+ const float3 old_position = positions[point_i];
+ float2 old_position_screen;
+ ED_view3d_project_float_v2_m4(
+ region, old_position, old_position_screen, projection.values);
+ const float2 new_position_screen = old_position_screen + mouse_diff;
+ float3 new_position;
+ ED_view3d_win_to_3d(v3d, region, old_position, new_position_screen, new_position);
+ positions[point_i] = new_position;
+ }
+ });
+
+ curves.tag_positions_changed();
+ DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY);
+ ED_region_tag_redraw(region);
+ }
+
+ last_mouse_position_ = stroke_extension.mouse_position;
+ }
+};
+
+static std::unique_ptr<CurvesSculptStrokeOperation> start_brush_operation(bContext *C,
+ wmOperator *UNUSED(op))
+{
+ Scene &scene = *CTX_data_scene(C);
+ CurvesSculpt &curves_sculpt = *scene.toolsettings->curves_sculpt;
+ Brush &brush = *BKE_paint_brush(&curves_sculpt.paint);
+ switch (brush.curves_sculpt_tool) {
+ case CURVES_SCULPT_TOOL_TEST1:
+ return std::make_unique<MoveOperation>();
+ case CURVES_SCULPT_TOOL_TEST2:
+ return std::make_unique<DeleteOperation>();
+ }
+ BLI_assert_unreachable();
+ return {};
+}
+
+struct SculptCurvesBrushStrokeData {
+ std::unique_ptr<CurvesSculptStrokeOperation> operation;
+ PaintStroke *stroke;
+};
+
+static bool stroke_get_location(bContext *C, float out[3], const float mouse[2])
+{
+ out[0] = mouse[0];
+ out[1] = mouse[1];
+ out[2] = 0;
+ UNUSED_VARS(C);
+ return true;
+}
+
+static bool stroke_test_start(bContext *C, struct wmOperator *op, const float mouse[2])
+{
+ UNUSED_VARS(C, op, mouse);
+ return true;
+}
+
+static void stroke_update_step(bContext *C,
+ wmOperator *op,
+ PaintStroke *UNUSED(stroke),
+ PointerRNA *stroke_element)
+{
+ SculptCurvesBrushStrokeData *op_data = static_cast<SculptCurvesBrushStrokeData *>(
+ op->customdata);
+
+ StrokeExtension stroke_extension;
+ RNA_float_get_array(stroke_element, "mouse", stroke_extension.mouse_position);
+
+ if (!op_data->operation) {
+ stroke_extension.is_first = true;
+ op_data->operation = start_brush_operation(C, op);
+ }
+ else {
+ stroke_extension.is_first = false;
+ }
+
+ op_data->operation->on_stroke_extended(C, stroke_extension);
+}
+
+static void stroke_done(const bContext *C, PaintStroke *stroke)
+{
+ UNUSED_VARS(C, stroke);
+}
+
+static int sculpt_curves_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ SculptCurvesBrushStrokeData *op_data = MEM_new<SculptCurvesBrushStrokeData>(__func__);
+ op_data->stroke = paint_stroke_new(C,
+ op,
+ stroke_get_location,
+ stroke_test_start,
+ stroke_update_step,
+ nullptr,
+ stroke_done,
+ event->type);
+ op->customdata = op_data;
+
+ int return_value = op->type->modal(C, op, event);
+ if (return_value == OPERATOR_FINISHED) {
+ paint_stroke_free(C, op, op_data->stroke);
+ MEM_delete(op_data);
+ return OPERATOR_FINISHED;
+ }
+
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int sculpt_curves_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ SculptCurvesBrushStrokeData *op_data = static_cast<SculptCurvesBrushStrokeData *>(
+ op->customdata);
+ int return_value = paint_stroke_modal(C, op, event, op_data->stroke);
+ if (ELEM(return_value, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
+ MEM_delete(op_data);
+ }
+ return return_value;
+}
+
+static void sculpt_curves_stroke_cancel(bContext *C, wmOperator *op)
+{
+ SculptCurvesBrushStrokeData *op_data = static_cast<SculptCurvesBrushStrokeData *>(
+ op->customdata);
+ paint_stroke_cancel(C, op, op_data->stroke);
+ MEM_delete(op_data);
+}
+
+static void SCULPT_CURVES_OT_brush_stroke(struct wmOperatorType *ot)
+{
+ ot->name = "Stroke Curves Sculpt";
+ ot->idname = "SCULPT_CURVES_OT_brush_stroke";
+ ot->description = "Sculpt curves using a brush";
+
+ ot->invoke = sculpt_curves_stroke_invoke;
+ ot->modal = sculpt_curves_stroke_modal;
+ ot->cancel = sculpt_curves_stroke_cancel;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ paint_stroke_operator_properties(ot);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name * CURVES_OT_sculptmode_toggle
+ * \{ */
+
+static bool curves_sculptmode_toggle_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+ if (ob == nullptr) {
+ return false;
+ }
+ if (ob->type != OB_CURVES) {
+ return false;
+ }
+ return true;
+}
+
+static void curves_sculptmode_enter(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ BKE_paint_ensure(scene->toolsettings, (Paint **)&scene->toolsettings->curves_sculpt);
+ CurvesSculpt *curves_sculpt = scene->toolsettings->curves_sculpt;
+
+ ob->mode = OB_MODE_SCULPT_CURVES;
+
+ paint_cursor_start(&curves_sculpt->paint, CURVES_SCULPT_mode_poll_view3d);
+}
+
+static void curves_sculptmode_exit(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+ ob->mode = OB_MODE_OBJECT;
+}
+
+static int curves_sculptmode_toggle_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = CTX_data_active_object(C);
+ const bool is_mode_set = ob->mode == OB_MODE_SCULPT_CURVES;
+
+ if (is_mode_set) {
+ if (!ED_object_mode_compat_set(C, ob, OB_MODE_SCULPT_CURVES, op->reports)) {
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ if (is_mode_set) {
+ curves_sculptmode_exit(C);
+ }
+ else {
+ curves_sculptmode_enter(C);
+ }
+
+ WM_toolsystem_update_from_context_view3d(C);
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE, nullptr);
+ return OPERATOR_CANCELLED;
+}
+
+static void CURVES_OT_sculptmode_toggle(wmOperatorType *ot)
+{
+ ot->name = "Curve Sculpt Mode Toggle";
+ ot->idname = "CURVES_OT_sculptmode_toggle";
+ ot->description = "Enter/Exit sculpt mode for curves";
+
+ ot->exec = curves_sculptmode_toggle_exec;
+ ot->poll = curves_sculptmode_toggle_poll;
+
+ ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
+}
+
+} // namespace blender::ed::sculpt_paint
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name * Registration
+ * \{ */
+
+void ED_operatortypes_sculpt_curves()
+{
+ using namespace blender::ed::sculpt_paint;
+ WM_operatortype_append(SCULPT_CURVES_OT_brush_stroke);
+ WM_operatortype_append(CURVES_OT_sculptmode_toggle);
+}
+
+/** \} */
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.cc
index df9e2cf136f..0c73c2e1f43 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.cc
@@ -6,10 +6,10 @@
* \brief Functions to paint images in 2D and 3D.
*/
-#include <float.h>
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
+#include <cfloat>
+#include <cmath>
+#include <cstdio>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -67,6 +67,8 @@
#include "paint_intern.h"
+extern "C" {
+
/**
* This is a static resource for non-global access.
* Maybe it should be exposed as part of the paint operation,
@@ -84,7 +86,7 @@ void set_imapaintpartial(struct ImagePaintPartialRedraw *ippr)
imapaintpartial = *ippr;
}
-/* Imagepaint Partial Redraw & Dirty Region */
+/* Image paint Partial Redraw & Dirty Region. */
void ED_imapaint_clear_partial_redraw(void)
{
@@ -96,7 +98,7 @@ void imapaint_region_tiles(
{
int srcx = 0, srcy = 0;
- IMB_rectclip(ibuf, NULL, &x, &y, &srcx, &srcy, &w, &h);
+ IMB_rectclip(ibuf, nullptr, &x, &y, &srcx, &srcy, &w, &h);
*tw = ((x + w - 1) >> ED_IMAGE_UNDO_TILE_BITS);
*th = ((y + h - 1) >> ED_IMAGE_UNDO_TILE_BITS);
@@ -107,11 +109,11 @@ void imapaint_region_tiles(
void ED_imapaint_dirty_region(
Image *ima, ImBuf *ibuf, ImageUser *iuser, int x, int y, int w, int h, bool find_old)
{
- ImBuf *tmpibuf = NULL;
+ ImBuf *tmpibuf = nullptr;
int tilex, tiley, tilew, tileh, tx, ty;
int srcx = 0, srcy = 0;
- IMB_rectclip(ibuf, NULL, &x, &y, &srcx, &srcy, &w, &h);
+ IMB_rectclip(ibuf, nullptr, &x, &y, &srcx, &srcy, &w, &h);
if (w == 0 || h == 0) {
return;
@@ -128,7 +130,7 @@ void ED_imapaint_dirty_region(
for (ty = tiley; ty <= tileh; ty++) {
for (tx = tilex; tx <= tilew; tx++) {
ED_image_paint_tile_push(
- undo_tiles, ima, ibuf, &tmpibuf, iuser, tx, ty, NULL, NULL, false, find_old);
+ undo_tiles, ima, ibuf, &tmpibuf, iuser, tx, ty, nullptr, nullptr, false, find_old);
}
}
@@ -169,17 +171,19 @@ void imapaint_image_update(
BlurKernel *paint_new_blur_kernel(Brush *br, bool proj)
{
int i, j;
- BlurKernel *kernel = MEM_mallocN(sizeof(BlurKernel), "blur kernel");
+ BlurKernel *kernel = MEM_new<BlurKernel>("BlurKernel");
+
float radius;
int side;
- eBlurKernelType type = br->blur_mode;
+ eBlurKernelType type = static_cast<eBlurKernelType>(br->blur_mode);
if (proj) {
radius = 0.5f;
side = kernel->side = 2;
kernel->side_squared = kernel->side * kernel->side;
- kernel->wdata = MEM_mallocN(sizeof(float) * kernel->side_squared, "blur kernel data");
+ kernel->wdata = static_cast<float *>(
+ MEM_mallocN(sizeof(float) * kernel->side_squared, "blur kernel data"));
kernel->pixel_len = radius;
}
else {
@@ -191,7 +195,8 @@ BlurKernel *paint_new_blur_kernel(Brush *br, bool proj)
side = kernel->side = radius * 2 + 1;
kernel->side_squared = kernel->side * kernel->side;
- kernel->wdata = MEM_mallocN(sizeof(float) * kernel->side_squared, "blur kernel data");
+ kernel->wdata = static_cast<float *>(
+ MEM_mallocN(sizeof(float) * kernel->side_squared, "blur kernel data"));
kernel->pixel_len = br->blur_kernel_radius;
}
@@ -224,9 +229,9 @@ BlurKernel *paint_new_blur_kernel(Brush *br, bool proj)
default:
printf("unidentified kernel type, aborting\n");
- MEM_freeN(kernel->wdata);
- MEM_freeN(kernel);
- return NULL;
+ paint_delete_blur_kernel(kernel);
+ MEM_delete(kernel);
+ return nullptr;
}
return kernel;
@@ -267,7 +272,7 @@ static bool image_paint_poll_ex(bContext *C, bool check_tool)
SpaceImage *sima = CTX_wm_space_image(C);
if (sima) {
- if (sima->image != NULL && ID_IS_LINKED(sima->image)) {
+ if (sima->image != nullptr && ID_IS_LINKED(sima->image)) {
return false;
}
ARegion *region = CTX_wm_region(C);
@@ -281,7 +286,7 @@ static bool image_paint_poll_ex(bContext *C, bool check_tool)
return false;
}
-static bool image_paint_poll(bContext *C)
+bool image_paint_poll(bContext *C)
{
return image_paint_poll_ex(C, true);
}
@@ -307,24 +312,6 @@ static bool image_paint_2d_clone_poll(bContext *C)
}
/************************ paint operator ************************/
-typedef enum eTexPaintMode {
- PAINT_MODE_2D,
- PAINT_MODE_3D_PROJECT,
-} eTexPaintMode;
-
-typedef struct PaintOperation {
- eTexPaintMode mode;
-
- void *custom_paint;
-
- float prevmouse[2];
- float startmouse[2];
- double starttime;
-
- void *cursor;
- ViewContext vc;
-} PaintOperation;
-
bool paint_use_opacity_masking(Brush *brush)
{
return ((brush->flag & BRUSH_AIRBRUSH) || (brush->flag & BRUSH_DRAG_DOT) ||
@@ -369,7 +356,7 @@ void paint_brush_color_get(struct Scene *scene,
break;
}
}
- /* Gradient / Colorband colors are not considered PROP_COLOR_GAMMA.
+ /* Gradient / Color-band colors are not considered #PROP_COLOR_GAMMA.
* Brush colors are expected to be in sRGB though. */
IMB_colormanagement_scene_linear_to_srgb_v3(color_gr);
@@ -414,340 +401,11 @@ void paint_brush_exit_tex(Brush *brush)
}
}
-static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customdata)
-{
- PaintOperation *pop = (PaintOperation *)customdata;
-
- if (pop) {
- GPU_line_smooth(true);
- GPU_blend(GPU_BLEND_ALPHA);
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
-
- ARegion *region = pop->vc.region;
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- GPU_line_width(4.0);
- immUniformColor4ub(0, 0, 0, 255);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2i(pos, x, y);
- immVertex2i(
- pos, pop->startmouse[0] + region->winrct.xmin, pop->startmouse[1] + region->winrct.ymin);
- immEnd();
-
- GPU_line_width(2.0);
- immUniformColor4ub(255, 255, 255, 255);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2i(pos, x, y);
- immVertex2i(
- pos, pop->startmouse[0] + region->winrct.xmin, pop->startmouse[1] + region->winrct.ymin);
- immEnd();
-
- immUnbindProgram();
-
- GPU_blend(GPU_BLEND_NONE);
- GPU_line_smooth(false);
- }
-}
-
-static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const float mouse[2])
-{
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Scene *scene = CTX_data_scene(C);
- ToolSettings *settings = scene->toolsettings;
- PaintOperation *pop = MEM_callocN(sizeof(PaintOperation), "PaintOperation"); /* caller frees */
- Brush *brush = BKE_paint_brush(&settings->imapaint.paint);
- int mode = RNA_enum_get(op->ptr, "mode");
- ED_view3d_viewcontext_init(C, &pop->vc, depsgraph);
-
- copy_v2_v2(pop->prevmouse, mouse);
- copy_v2_v2(pop->startmouse, mouse);
-
- /* initialize from context */
- if (CTX_wm_region_view3d(C)) {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
- bool uvs, mat, tex, stencil;
- if (!ED_paint_proj_mesh_data_check(scene, ob, &uvs, &mat, &tex, &stencil)) {
- ED_paint_data_warning(op->reports, uvs, mat, tex, stencil);
- MEM_freeN(pop);
- WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
- return NULL;
- }
- pop->mode = PAINT_MODE_3D_PROJECT;
- pop->custom_paint = paint_proj_new_stroke(C, ob, mouse, mode);
- }
- else {
- pop->mode = PAINT_MODE_2D;
- pop->custom_paint = paint_2d_new_stroke(C, op, mode);
- }
-
- if (!pop->custom_paint) {
- MEM_freeN(pop);
- return NULL;
- }
-
- if ((brush->imagepaint_tool == PAINT_TOOL_FILL) && (brush->flag & BRUSH_USE_GRADIENT)) {
- pop->cursor = WM_paint_cursor_activate(
- SPACE_TYPE_ANY, RGN_TYPE_ANY, image_paint_poll, gradient_draw_line, pop);
- }
-
- settings->imapaint.flag |= IMAGEPAINT_DRAWING;
- ED_image_undo_push_begin(op->type->name, PAINT_MODE_TEXTURE_2D);
-
- return pop;
-}
-
-static void paint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
-{
- PaintOperation *pop = paint_stroke_mode_data(stroke);
- Scene *scene = CTX_data_scene(C);
- ToolSettings *toolsettings = CTX_data_tool_settings(C);
- UnifiedPaintSettings *ups = &toolsettings->unified_paint_settings;
- Brush *brush = BKE_paint_brush(&toolsettings->imapaint.paint);
-
- float alphafac = (brush->flag & BRUSH_ACCUMULATE) ? ups->overlap_factor : 1.0f;
-
- /* initial brush values. Maybe it should be considered moving these to stroke system */
- float startalpha = BKE_brush_alpha_get(scene, brush);
-
- float mouse[2];
- float pressure;
- float size;
- float distance = paint_stroke_distance_get(stroke);
- int eraser;
-
- RNA_float_get_array(itemptr, "mouse", mouse);
- pressure = RNA_float_get(itemptr, "pressure");
- eraser = RNA_boolean_get(itemptr, "pen_flip");
- size = RNA_float_get(itemptr, "size");
-
- /* stroking with fill tool only acts on stroke end */
- if (brush->imagepaint_tool == PAINT_TOOL_FILL) {
- copy_v2_v2(pop->prevmouse, mouse);
- return;
- }
-
- if (BKE_brush_use_alpha_pressure(brush)) {
- BKE_brush_alpha_set(scene, brush, max_ff(0.0f, startalpha * pressure * alphafac));
- }
- else {
- BKE_brush_alpha_set(scene, brush, max_ff(0.0f, startalpha * alphafac));
- }
-
- if ((brush->flag & BRUSH_DRAG_DOT) || (brush->flag & BRUSH_ANCHORED)) {
- UndoStack *ustack = CTX_wm_manager(C)->undo_stack;
- ED_image_undo_restore(ustack->step_init);
- }
-
- if (pop->mode == PAINT_MODE_3D_PROJECT) {
- paint_proj_stroke(
- C, pop->custom_paint, pop->prevmouse, mouse, eraser, pressure, distance, size);
- }
- else {
- paint_2d_stroke(pop->custom_paint, pop->prevmouse, mouse, eraser, pressure, distance, size);
- }
-
- copy_v2_v2(pop->prevmouse, mouse);
-
- /* restore brush values */
- BKE_brush_alpha_set(scene, brush, startalpha);
-}
-
-static void paint_stroke_redraw(const bContext *C, struct PaintStroke *stroke, bool final)
-{
- PaintOperation *pop = paint_stroke_mode_data(stroke);
-
- if (pop->mode == PAINT_MODE_3D_PROJECT) {
- paint_proj_redraw(C, pop->custom_paint, final);
- }
- else {
- paint_2d_redraw(C, pop->custom_paint, final);
- }
-}
-
-static void paint_stroke_done(const bContext *C, struct PaintStroke *stroke)
-{
- Scene *scene = CTX_data_scene(C);
- ToolSettings *toolsettings = scene->toolsettings;
- PaintOperation *pop = paint_stroke_mode_data(stroke);
- Brush *brush = BKE_paint_brush(&toolsettings->imapaint.paint);
-
- toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
-
- if (brush->imagepaint_tool == PAINT_TOOL_FILL) {
- if (brush->flag & BRUSH_USE_GRADIENT) {
- if (pop->mode == PAINT_MODE_2D) {
- paint_2d_gradient_fill(C, brush, pop->startmouse, pop->prevmouse, pop->custom_paint);
- }
- else {
- paint_proj_stroke(C,
- pop->custom_paint,
- pop->startmouse,
- pop->prevmouse,
- paint_stroke_flipped(stroke),
- 1.0,
- 0.0,
- BKE_brush_size_get(scene, brush));
- /* two redraws, one for GPU update, one for notification */
- paint_proj_redraw(C, pop->custom_paint, false);
- paint_proj_redraw(C, pop->custom_paint, true);
- }
- }
- else {
- if (pop->mode == PAINT_MODE_2D) {
- float color[3];
- if (paint_stroke_inverted(stroke)) {
- srgb_to_linearrgb_v3_v3(color, BKE_brush_secondary_color_get(scene, brush));
- }
- else {
- srgb_to_linearrgb_v3_v3(color, BKE_brush_color_get(scene, brush));
- }
- paint_2d_bucket_fill(C, color, brush, pop->startmouse, pop->prevmouse, pop->custom_paint);
- }
- else {
- paint_proj_stroke(C,
- pop->custom_paint,
- pop->startmouse,
- pop->prevmouse,
- paint_stroke_flipped(stroke),
- 1.0,
- 0.0,
- BKE_brush_size_get(scene, brush));
- /* two redraws, one for GPU update, one for notification */
- paint_proj_redraw(C, pop->custom_paint, false);
- paint_proj_redraw(C, pop->custom_paint, true);
- }
- }
- }
- if (pop->mode == PAINT_MODE_3D_PROJECT) {
- paint_proj_stroke_done(pop->custom_paint);
- }
- else {
- paint_2d_stroke_done(pop->custom_paint);
- }
-
- if (pop->cursor) {
- WM_paint_cursor_end(pop->cursor);
- }
-
- ED_image_undo_push_end();
-
- /* duplicate warning, see texpaint_init */
-#if 0
- if (pop->s.warnmultifile) {
- BKE_reportf(op->reports,
- RPT_WARNING,
- "Image requires 4 color channels to paint: %s",
- pop->s.warnmultifile);
- }
- if (pop->s.warnpackedfile) {
- BKE_reportf(op->reports,
- RPT_WARNING,
- "Packed MultiLayer files cannot be painted: %s",
- pop->s.warnpackedfile);
- }
-#endif
- MEM_freeN(pop);
-}
-
-static bool paint_stroke_test_start(bContext *C, wmOperator *op, const float mouse[2])
-{
- PaintOperation *pop;
-
- /* TODO: Should avoid putting this here. Instead, last position should be requested
- * from stroke system. */
-
- if (!(pop = texture_paint_init(C, op, mouse))) {
- return false;
- }
-
- paint_stroke_set_mode_data(op->customdata, pop);
-
- return true;
-}
-
-static int paint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- int retval;
-
- op->customdata = paint_stroke_new(C,
- op,
- NULL,
- paint_stroke_test_start,
- paint_stroke_update_step,
- paint_stroke_redraw,
- paint_stroke_done,
- event->type);
-
- if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
- paint_stroke_free(C, op);
- return OPERATOR_FINISHED;
- }
- /* add modal handler */
- WM_event_add_modal_handler(C, op);
-
- OPERATOR_RETVAL_CHECK(retval);
- BLI_assert(retval == OPERATOR_RUNNING_MODAL);
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-static int paint_exec(bContext *C, wmOperator *op)
-{
- PropertyRNA *strokeprop;
- PointerRNA firstpoint;
- float mouse[2];
-
- strokeprop = RNA_struct_find_property(op->ptr, "stroke");
-
- if (!RNA_property_collection_lookup_int(op->ptr, strokeprop, 0, &firstpoint)) {
- return OPERATOR_CANCELLED;
- }
-
- RNA_float_get_array(&firstpoint, "mouse", mouse);
-
- op->customdata = paint_stroke_new(C,
- op,
- NULL,
- paint_stroke_test_start,
- paint_stroke_update_step,
- paint_stroke_redraw,
- paint_stroke_done,
- 0);
- /* frees op->customdata */
- return paint_stroke_exec(C, op);
-}
-
-void PAINT_OT_image_paint(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Image Paint";
- ot->idname = "PAINT_OT_image_paint";
- ot->description = "Paint a stroke into the image";
-
- /* api callbacks */
- ot->invoke = paint_invoke;
- ot->modal = paint_stroke_modal;
- ot->exec = paint_exec;
- ot->poll = image_paint_poll;
- ot->cancel = paint_stroke_cancel;
-
- /* flags */
- ot->flag = OPTYPE_BLOCKING;
-
- paint_stroke_operator_properties(ot);
-}
-
bool get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
{
ScrArea *area = CTX_wm_area(C);
if (area && area->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = area->spacedata.first;
+ SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
if (sima->mode == SI_MODE_PAINT) {
ARegion *region = CTX_wm_region(C);
ED_space_image_get_zoom(sima, region, zoomx, zoomy);
@@ -768,8 +426,8 @@ static void toggle_paint_cursor(Scene *scene, bool enable)
Paint *p = &settings->imapaint.paint;
if (p->paint_cursor && !enable) {
- WM_paint_cursor_end(p->paint_cursor);
- p->paint_cursor = NULL;
+ WM_paint_cursor_end(static_cast<wmPaintCursor *>(p->paint_cursor));
+ p->paint_cursor = nullptr;
paint_cursor_delete_textures();
}
else if (enable) {
@@ -807,10 +465,10 @@ void ED_space_image_paint_update(Main *bmain, wmWindowManager *wm, Scene *scene)
/************************ grab clone operator ************************/
-typedef struct GrabClone {
+struct GrabClone {
float startoffset[2];
int startx, starty;
-} GrabClone;
+};
static void grab_clone_apply(bContext *C, wmOperator *op)
{
@@ -834,7 +492,7 @@ static int grab_clone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Brush *brush = image_paint_brush(C);
GrabClone *cmv;
- cmv = MEM_callocN(sizeof(GrabClone), "GrabClone");
+ cmv = MEM_new<GrabClone>("GrabClone");
copy_v2_v2(cmv->startoffset, brush->clone.offset);
cmv->startx = event->xy[0];
cmv->starty = event->xy[1];
@@ -849,7 +507,7 @@ static int grab_clone_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Brush *brush = image_paint_brush(C);
ARegion *region = CTX_wm_region(C);
- GrabClone *cmv = op->customdata;
+ GrabClone *cmv = static_cast<GrabClone *>(op->customdata);
float startfx, startfy, fx, fy, delta[2];
int xmin = region->winrct.xmin, ymin = region->winrct.ymin;
@@ -880,7 +538,8 @@ static int grab_clone_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void grab_clone_cancel(bContext *UNUSED(C), wmOperator *op)
{
- MEM_freeN(op->customdata);
+ GrabClone *cmv = static_cast<GrabClone *>(op->customdata);
+ MEM_delete(cmv);
}
void PAINT_OT_grab_clone(wmOperatorType *ot)
@@ -904,7 +563,7 @@ void PAINT_OT_grab_clone(wmOperatorType *ot)
RNA_def_float_vector(ot->srna,
"delta",
2,
- NULL,
+ nullptr,
-FLT_MAX,
FLT_MAX,
"Delta",
@@ -914,12 +573,12 @@ void PAINT_OT_grab_clone(wmOperatorType *ot)
}
/******************** sample color operator ********************/
-typedef struct {
+struct SampleColorData {
bool show_cursor;
short launch_event;
float initcolor[3];
bool sample_palette;
-} SampleColorData;
+};
static void sample_color_update_header(SampleColorData *data, bContext *C)
{
@@ -973,7 +632,7 @@ static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event
Scene *scene = CTX_data_scene(C);
Paint *paint = BKE_paint_get_active_from_context(C);
Brush *brush = BKE_paint_brush(paint);
- SampleColorData *data = MEM_mallocN(sizeof(SampleColorData), "sample color custom data");
+ SampleColorData *data = MEM_new<SampleColorData>("sample color custom data");
ARegion *region = CTX_wm_region(C);
wmWindow *win = CTX_wm_window(C);
@@ -1009,7 +668,7 @@ static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event
static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
- SampleColorData *data = op->customdata;
+ SampleColorData *data = static_cast<SampleColorData *>(op->customdata);
Paint *paint = BKE_paint_get_active_from_context(C);
Brush *brush = BKE_paint_brush(paint);
@@ -1023,8 +682,8 @@ static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event)
RNA_boolean_set(op->ptr, "palette", true);
}
WM_cursor_modal_restore(CTX_wm_window(C));
- MEM_freeN(data);
- ED_workspace_status_text(C, NULL);
+ MEM_delete(data);
+ ED_workspace_status_text(C, nullptr);
return OPERATOR_FINISHED;
}
@@ -1083,25 +742,26 @@ void PAINT_OT_sample_color(wmOperatorType *ot)
/* properties */
PropertyRNA *prop;
- prop = RNA_def_int_vector(ot->srna, "location", 2, NULL, 0, INT_MAX, "Location", "", 0, 16384);
- RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
+ prop = RNA_def_int_vector(
+ ot->srna, "location", 2, nullptr, 0, INT_MAX, "Location", "", 0, 16384);
+ RNA_def_property_flag(prop, static_cast<PropertyFlag>(PROP_SKIP_SAVE | PROP_HIDDEN));
- RNA_def_boolean(ot->srna, "merged", 0, "Sample Merged", "Sample the output display color");
- RNA_def_boolean(ot->srna, "palette", 0, "Add to Palette", "");
+ RNA_def_boolean(ot->srna, "merged", false, "Sample Merged", "Sample the output display color");
+ RNA_def_boolean(ot->srna, "palette", false, "Add to Palette", "");
}
/******************** texture paint toggle operator ********************/
void ED_object_texture_paint_mode_enter_ex(Main *bmain, Scene *scene, Object *ob)
{
- Image *ima = NULL;
+ Image *ima = nullptr;
ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
/* This has to stay here to regenerate the texture paint
* cache in case we are loading a file */
BKE_texpaint_slots_refresh_object(scene, ob);
- ED_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ ED_paint_proj_mesh_data_check(scene, ob, nullptr, nullptr, nullptr, nullptr);
/* entering paint mode also sets image to editors */
if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) {
@@ -1117,11 +777,11 @@ void ED_object_texture_paint_mode_enter_ex(Main *bmain, Scene *scene, Object *ob
}
if (ima) {
- wmWindowManager *wm = bmain->wm.first;
- for (wmWindow *win = wm->windows.first; win; win = win->next) {
+ wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
+ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
const bScreen *screen = WM_window_get_active_screen(win);
- for (ScrArea *area = screen->areabase.first; area; area = area->next) {
- SpaceLink *sl = area->spacedata.first;
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ SpaceLink *sl = static_cast<SpaceLink *>(area->spacedata.first);
if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sl;
@@ -1142,12 +802,12 @@ void ED_object_texture_paint_mode_enter_ex(Main *bmain, Scene *scene, Object *ob
if (U.glreslimit != 0) {
BKE_image_free_all_gputextures(bmain);
}
- BKE_image_paint_set_mipmap(bmain, 0);
+ BKE_image_paint_set_mipmap(bmain, false);
toggle_paint_cursor(scene, true);
Mesh *me = BKE_mesh_from_object(ob);
- BLI_assert(me != NULL);
+ BLI_assert(me != nullptr);
DEG_id_tag_update(&me->id, ID_RECALC_COPY_ON_WRITE);
WM_main_add_notifier(NC_SCENE | ND_MODE, scene);
}
@@ -1167,11 +827,11 @@ void ED_object_texture_paint_mode_exit_ex(Main *bmain, Scene *scene, Object *ob)
if (U.glreslimit != 0) {
BKE_image_free_all_gputextures(bmain);
}
- BKE_image_paint_set_mipmap(bmain, 1);
+ BKE_image_paint_set_mipmap(bmain, true);
toggle_paint_cursor(scene, false);
Mesh *me = BKE_mesh_from_object(ob);
- BLI_assert(me != NULL);
+ BLI_assert(me != nullptr);
DEG_id_tag_update(&me->id, ID_RECALC_COPY_ON_WRITE);
WM_main_add_notifier(NC_SCENE | ND_MODE, scene);
}
@@ -1187,7 +847,7 @@ void ED_object_texture_paint_mode_exit(bContext *C)
static bool texture_paint_toggle_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
- if (ob == NULL || ob->type != OB_MESH) {
+ if (ob == nullptr || ob->type != OB_MESH) {
return false;
}
if (!ob->data || ID_IS_LINKED(ob->data)) {
@@ -1207,7 +867,7 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
const bool is_mode_set = (ob->mode & mode_flag) != 0;
if (!is_mode_set) {
- if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
+ if (!ED_object_mode_compat_set(C, ob, static_cast<eObjectMode>(mode_flag), op->reports)) {
return OPERATOR_CANCELLED;
}
}
@@ -1274,7 +934,7 @@ static bool brush_colors_flip_poll(bContext *C)
}
else {
Object *ob = CTX_data_active_object(C);
- if (ob != NULL) {
+ if (ob != nullptr) {
if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_TEXTURE_PAINT | OB_MODE_SCULPT)) {
return true;
}
@@ -1310,8 +970,8 @@ void ED_imapaint_bucket_fill(struct bContext *C,
ED_image_undo_push_begin(op->type->name, PAINT_MODE_TEXTURE_2D);
- const float mouse_init[2] = {mouse[0], mouse[1]};
- paint_2d_bucket_fill(C, color, NULL, mouse_init, NULL, NULL);
+ const float mouse_init[2] = {static_cast<float>(mouse[0]), static_cast<float>(mouse[1])};
+ paint_2d_bucket_fill(C, color, nullptr, mouse_init, nullptr, nullptr);
ED_image_undo_push_end();
@@ -1349,3 +1009,4 @@ bool mask_paint_poll(bContext *C)
{
return BKE_paint_select_elem_test(CTX_data_active_object(C));
}
+}
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc b/source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc
index 64115f7c6eb..f5657b004e2 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc
+++ b/source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc
@@ -53,6 +53,7 @@ static void update_curve_mask(CurveMaskCache *curve_mask_cache,
{
BLI_assert(curve_mask_cache->curve_mask != nullptr);
int offset = (int)floorf(diameter / 2.0f);
+ int clamped_radius = max_ff(radius, 1.0);
unsigned short *m = curve_mask_cache->curve_mask;
@@ -76,7 +77,7 @@ static void update_curve_mask(CurveMaskCache *curve_mask_cache,
pixel_xy[1] = static_cast<float>(y) + aa_offset;
for (int j = 0; j < aa_samples; j++) {
const float len = len_v2v2(pixel_xy, bpos);
- const int sample_index = min_ii((len / radius) * CurveSamplesBaseLen,
+ const int sample_index = min_ii((len / clamped_radius) * CurveSamplesBaseLen,
CurveSamplesLen - 1);
const float sample_weight = curve_mask_cache->sampled_curve[sample_index];
diff --git a/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc b/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc
new file mode 100644
index 00000000000..786fcc47526
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc
@@ -0,0 +1,531 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
+
+/** \file
+ * \ingroup edsculpt
+ * \brief Painting operator to paint in 2D and 3D.
+ */
+
+#include "DNA_brush_types.h"
+#include "DNA_color_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_brush.h"
+#include "BKE_context.h"
+#include "BKE_paint.h"
+#include "BKE_undo_system.h"
+
+#include "DEG_depsgraph.h"
+
+#include "ED_paint.h"
+#include "ED_view3d.h"
+
+#include "GPU_immediate.h"
+#include "GPU_state.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_message.h"
+#include "WM_toolsystem.h"
+#include "WM_types.h"
+
+#include "paint_intern.h"
+
+namespace blender::ed::sculpt_paint::image::ops::paint {
+
+/**
+ * Interface to use the same painting operator for 3D and 2D painting. Interface removes the
+ * differences between the actual calls that are being performed.
+ */
+class AbstractPaintMode {
+ public:
+ virtual ~AbstractPaintMode() = default;
+ virtual void *paint_new_stroke(
+ bContext *C, wmOperator *op, Object *ob, const float mouse[2], int mode) = 0;
+ virtual void paint_stroke(bContext *C,
+ void *stroke_handle,
+ float prev_mouse[2],
+ float mouse[2],
+ int eraser,
+ float pressure,
+ float distance,
+ float size) = 0;
+
+ virtual void paint_stroke_redraw(const bContext *C, void *stroke_handle, bool final) = 0;
+ virtual void paint_stroke_done(void *stroke_handle) = 0;
+ virtual void paint_gradient_fill(const bContext *C,
+ const Scene *scene,
+ Brush *brush,
+ struct PaintStroke *stroke,
+ void *stroke_handle,
+ float mouse_start[2],
+ float mouse_end[2]) = 0;
+ virtual void paint_bucket_fill(const bContext *C,
+ const Scene *scene,
+ Brush *brush,
+ struct PaintStroke *stroke,
+ void *stroke_handle,
+ float mouse_start[2],
+ float mouse_end[2]) = 0;
+};
+
+class ImagePaintMode : public AbstractPaintMode {
+ public:
+ void *paint_new_stroke(bContext *C,
+ wmOperator *op,
+ Object *UNUSED(ob),
+ const float UNUSED(mouse[2]),
+ int mode) override
+ {
+ return paint_2d_new_stroke(C, op, mode);
+ }
+
+ void paint_stroke(bContext *UNUSED(C),
+ void *stroke_handle,
+ float prev_mouse[2],
+ float mouse[2],
+ int eraser,
+ float pressure,
+ float distance,
+ float size) override
+ {
+ paint_2d_stroke(stroke_handle, prev_mouse, mouse, eraser, pressure, distance, size);
+ }
+
+ void paint_stroke_redraw(const bContext *C, void *stroke_handle, bool final) override
+ {
+ paint_2d_redraw(C, stroke_handle, final);
+ }
+
+ void paint_stroke_done(void *stroke_handle) override
+ {
+ paint_2d_stroke_done(stroke_handle);
+ }
+
+ void paint_gradient_fill(const bContext *C,
+ const Scene *UNUSED(scene),
+ Brush *brush,
+ struct PaintStroke *UNUSED(stroke),
+ void *stroke_handle,
+ float mouse_start[2],
+ float mouse_end[2]) override
+ {
+ paint_2d_gradient_fill(C, brush, mouse_start, mouse_end, stroke_handle);
+ }
+
+ void paint_bucket_fill(const bContext *C,
+ const Scene *scene,
+ Brush *brush,
+ struct PaintStroke *stroke,
+ void *stroke_handle,
+ float mouse_start[2],
+ float mouse_end[2]) override
+ {
+ float color[3];
+ if (paint_stroke_inverted(stroke)) {
+ srgb_to_linearrgb_v3_v3(color, BKE_brush_secondary_color_get(scene, brush));
+ }
+ else {
+ srgb_to_linearrgb_v3_v3(color, BKE_brush_color_get(scene, brush));
+ }
+ paint_2d_bucket_fill(C, color, brush, mouse_start, mouse_end, stroke_handle);
+ }
+};
+
+class ProjectionPaintMode : public AbstractPaintMode {
+ public:
+ void *paint_new_stroke(
+ bContext *C, wmOperator *UNUSED(op), Object *ob, const float mouse[2], int mode) override
+ {
+ return paint_proj_new_stroke(C, ob, mouse, mode);
+ }
+
+ void paint_stroke(bContext *C,
+ void *stroke_handle,
+ float prev_mouse[2],
+ float mouse[2],
+ int eraser,
+ float pressure,
+ float distance,
+ float size) override
+ {
+ paint_proj_stroke(C, stroke_handle, prev_mouse, mouse, eraser, pressure, distance, size);
+ };
+
+ void paint_stroke_redraw(const bContext *C, void *stroke_handle, bool final) override
+ {
+ paint_proj_redraw(C, stroke_handle, final);
+ }
+
+ void paint_stroke_done(void *stroke_handle) override
+ {
+ paint_proj_stroke_done(stroke_handle);
+ }
+
+ void paint_gradient_fill(const bContext *C,
+ const Scene *scene,
+ Brush *brush,
+ struct PaintStroke *stroke,
+ void *stroke_handle,
+ float mouse_start[2],
+ float mouse_end[2]) override
+ {
+ paint_fill(C, scene, brush, stroke, stroke_handle, mouse_start, mouse_end);
+ }
+
+ void paint_bucket_fill(const bContext *C,
+ const Scene *scene,
+ Brush *brush,
+ struct PaintStroke *stroke,
+ void *stroke_handle,
+ float mouse_start[2],
+ float mouse_end[2]) override
+ {
+ paint_fill(C, scene, brush, stroke, stroke_handle, mouse_start, mouse_end);
+ }
+
+ private:
+ void paint_fill(const bContext *C,
+ const Scene *scene,
+ Brush *brush,
+ struct PaintStroke *stroke,
+ void *stroke_handle,
+ float mouse_start[2],
+ float mouse_end[2])
+ {
+ paint_proj_stroke(C,
+ stroke_handle,
+ mouse_start,
+ mouse_end,
+ paint_stroke_flipped(stroke),
+ 1.0,
+ 0.0,
+ BKE_brush_size_get(scene, brush));
+ /* two redraws, one for GPU update, one for notification */
+ paint_proj_redraw(C, stroke_handle, false);
+ paint_proj_redraw(C, stroke_handle, true);
+ }
+};
+
+struct PaintOperation {
+ AbstractPaintMode *mode = nullptr;
+
+ void *stroke_handle = nullptr;
+
+ float prevmouse[2] = {0.0f, 0.0f};
+ float startmouse[2] = {0.0f, 0.0f};
+ double starttime = 0.0;
+
+ wmPaintCursor *cursor = nullptr;
+ ViewContext vc = {nullptr};
+
+ PaintOperation() = default;
+ ~PaintOperation()
+ {
+ MEM_delete(mode);
+ mode = nullptr;
+
+ if (cursor) {
+ WM_paint_cursor_end(cursor);
+ cursor = nullptr;
+ }
+ }
+};
+
+static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customdata)
+{
+ PaintOperation *pop = (PaintOperation *)customdata;
+
+ if (pop) {
+ GPU_line_smooth(true);
+ GPU_blend(GPU_BLEND_ALPHA);
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+
+ ARegion *region = pop->vc.region;
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ GPU_line_width(4.0);
+ immUniformColor4ub(0, 0, 0, 255);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2i(pos, x, y);
+ immVertex2i(
+ pos, pop->startmouse[0] + region->winrct.xmin, pop->startmouse[1] + region->winrct.ymin);
+ immEnd();
+
+ GPU_line_width(2.0);
+ immUniformColor4ub(255, 255, 255, 255);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2i(pos, x, y);
+ immVertex2i(
+ pos, pop->startmouse[0] + region->winrct.xmin, pop->startmouse[1] + region->winrct.ymin);
+ immEnd();
+
+ immUnbindProgram();
+
+ GPU_blend(GPU_BLEND_NONE);
+ GPU_line_smooth(false);
+ }
+}
+
+static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const float mouse[2])
+{
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *settings = scene->toolsettings;
+ PaintOperation *pop = MEM_new<PaintOperation>("PaintOperation"); /* caller frees */
+ Brush *brush = BKE_paint_brush(&settings->imapaint.paint);
+ int mode = RNA_enum_get(op->ptr, "mode");
+ ED_view3d_viewcontext_init(C, &pop->vc, depsgraph);
+
+ copy_v2_v2(pop->prevmouse, mouse);
+ copy_v2_v2(pop->startmouse, mouse);
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+
+ /* initialize from context */
+ if (CTX_wm_region_view3d(C)) {
+ bool uvs, mat, tex, stencil;
+ if (!ED_paint_proj_mesh_data_check(scene, ob, &uvs, &mat, &tex, &stencil)) {
+ ED_paint_data_warning(op->reports, uvs, mat, tex, stencil);
+ MEM_delete(pop);
+ WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, nullptr);
+ return nullptr;
+ }
+ pop->mode = MEM_new<ProjectionPaintMode>("ProjectionPaintMode");
+ }
+ else {
+ pop->mode = MEM_new<ImagePaintMode>("ImagePaintMode");
+ }
+
+ pop->stroke_handle = pop->mode->paint_new_stroke(C, op, ob, mouse, mode);
+ if (!pop->stroke_handle) {
+ MEM_delete(pop);
+ return nullptr;
+ }
+
+ if ((brush->imagepaint_tool == PAINT_TOOL_FILL) && (brush->flag & BRUSH_USE_GRADIENT)) {
+ pop->cursor = WM_paint_cursor_activate(
+ SPACE_TYPE_ANY, RGN_TYPE_ANY, image_paint_poll, gradient_draw_line, pop);
+ }
+
+ settings->imapaint.flag |= IMAGEPAINT_DRAWING;
+ ED_image_undo_push_begin(op->type->name, PAINT_MODE_TEXTURE_2D);
+
+ return pop;
+}
+
+static void paint_stroke_update_step(bContext *C,
+ wmOperator *UNUSED(op),
+ struct PaintStroke *stroke,
+ PointerRNA *itemptr)
+{
+ PaintOperation *pop = static_cast<PaintOperation *>(paint_stroke_mode_data(stroke));
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *toolsettings = CTX_data_tool_settings(C);
+ UnifiedPaintSettings *ups = &toolsettings->unified_paint_settings;
+ Brush *brush = BKE_paint_brush(&toolsettings->imapaint.paint);
+
+ float alphafac = (brush->flag & BRUSH_ACCUMULATE) ? ups->overlap_factor : 1.0f;
+
+ /* initial brush values. Maybe it should be considered moving these to stroke system */
+ float startalpha = BKE_brush_alpha_get(scene, brush);
+
+ float mouse[2];
+ float pressure;
+ float size;
+ float distance = paint_stroke_distance_get(stroke);
+ int eraser;
+
+ RNA_float_get_array(itemptr, "mouse", mouse);
+ pressure = RNA_float_get(itemptr, "pressure");
+ eraser = RNA_boolean_get(itemptr, "pen_flip");
+ size = RNA_float_get(itemptr, "size");
+
+ /* stroking with fill tool only acts on stroke end */
+ if (brush->imagepaint_tool == PAINT_TOOL_FILL) {
+ copy_v2_v2(pop->prevmouse, mouse);
+ return;
+ }
+
+ if (BKE_brush_use_alpha_pressure(brush)) {
+ BKE_brush_alpha_set(scene, brush, max_ff(0.0f, startalpha * pressure * alphafac));
+ }
+ else {
+ BKE_brush_alpha_set(scene, brush, max_ff(0.0f, startalpha * alphafac));
+ }
+
+ if ((brush->flag & BRUSH_DRAG_DOT) || (brush->flag & BRUSH_ANCHORED)) {
+ UndoStack *ustack = CTX_wm_manager(C)->undo_stack;
+ ED_image_undo_restore(ustack->step_init);
+ }
+
+ pop->mode->paint_stroke(
+ C, pop->stroke_handle, pop->prevmouse, mouse, eraser, pressure, distance, size);
+
+ copy_v2_v2(pop->prevmouse, mouse);
+
+ /* restore brush values */
+ BKE_brush_alpha_set(scene, brush, startalpha);
+}
+
+static void paint_stroke_redraw(const bContext *C, struct PaintStroke *stroke, bool final)
+{
+ PaintOperation *pop = static_cast<PaintOperation *>(paint_stroke_mode_data(stroke));
+ pop->mode->paint_stroke_redraw(C, pop->stroke_handle, final);
+}
+
+static void paint_stroke_done(const bContext *C, struct PaintStroke *stroke)
+{
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *toolsettings = scene->toolsettings;
+ PaintOperation *pop = static_cast<PaintOperation *>(paint_stroke_mode_data(stroke));
+ Brush *brush = BKE_paint_brush(&toolsettings->imapaint.paint);
+
+ toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
+
+ if (brush->imagepaint_tool == PAINT_TOOL_FILL) {
+ if (brush->flag & BRUSH_USE_GRADIENT) {
+ pop->mode->paint_gradient_fill(
+ C, scene, brush, stroke, pop->stroke_handle, pop->startmouse, pop->prevmouse);
+ }
+ else {
+ pop->mode->paint_bucket_fill(
+ C, scene, brush, stroke, pop->stroke_handle, pop->startmouse, pop->prevmouse);
+ }
+ }
+ pop->mode->paint_stroke_done(pop->stroke_handle);
+ pop->stroke_handle = nullptr;
+
+ ED_image_undo_push_end();
+
+/* duplicate warning, see texpaint_init */
+#if 0
+ if (pop->s.warnmultifile) {
+ BKE_reportf(op->reports,
+ RPT_WARNING,
+ "Image requires 4 color channels to paint: %s",
+ pop->s.warnmultifile);
+ }
+ if (pop->s.warnpackedfile) {
+ BKE_reportf(op->reports,
+ RPT_WARNING,
+ "Packed MultiLayer files cannot be painted: %s",
+ pop->s.warnpackedfile);
+ }
+#endif
+ MEM_delete(pop);
+}
+
+static bool paint_stroke_test_start(bContext *C, wmOperator *op, const float mouse[2])
+{
+ PaintOperation *pop;
+
+ /* TODO: Should avoid putting this here. Instead, last position should be requested
+ * from stroke system. */
+
+ if (!(pop = texture_paint_init(C, op, mouse))) {
+ return false;
+ }
+
+ paint_stroke_set_mode_data(static_cast<PaintStroke *>(op->customdata), pop);
+
+ return true;
+}
+
+static int paint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ int retval;
+
+ op->customdata = paint_stroke_new(C,
+ op,
+ nullptr,
+ paint_stroke_test_start,
+ paint_stroke_update_step,
+ paint_stroke_redraw,
+ paint_stroke_done,
+ event->type);
+
+ if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
+ paint_stroke_free(C, op, static_cast<PaintStroke *>(op->customdata));
+ return OPERATOR_FINISHED;
+ }
+ /* add modal handler */
+ WM_event_add_modal_handler(C, op);
+
+ OPERATOR_RETVAL_CHECK(retval);
+ BLI_assert(retval == OPERATOR_RUNNING_MODAL);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int paint_exec(bContext *C, wmOperator *op)
+{
+ PropertyRNA *strokeprop;
+ PointerRNA firstpoint;
+ float mouse[2];
+
+ strokeprop = RNA_struct_find_property(op->ptr, "stroke");
+
+ if (!RNA_property_collection_lookup_int(op->ptr, strokeprop, 0, &firstpoint)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ RNA_float_get_array(&firstpoint, "mouse", mouse);
+
+ op->customdata = paint_stroke_new(C,
+ op,
+ nullptr,
+ paint_stroke_test_start,
+ paint_stroke_update_step,
+ paint_stroke_redraw,
+ paint_stroke_done,
+ 0);
+ /* frees op->customdata */
+ return paint_stroke_exec(C, op, static_cast<PaintStroke *>(op->customdata));
+}
+
+static int paint_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ return paint_stroke_modal(C, op, event, static_cast<PaintStroke *>(op->customdata));
+}
+
+static void paint_cancel(bContext *C, wmOperator *op)
+{
+ paint_stroke_cancel(C, op, static_cast<PaintStroke *>(op->customdata));
+}
+} // namespace blender::ed::sculpt_paint::image::ops::paint
+
+extern "C" {
+void PAINT_OT_image_paint(wmOperatorType *ot)
+{
+ using namespace blender::ed::sculpt_paint::image::ops::paint;
+
+ /* identifiers */
+ ot->name = "Image Paint";
+ ot->idname = "PAINT_OT_image_paint";
+ ot->description = "Paint a stroke into the image";
+
+ /* api callbacks */
+ ot->invoke = paint_invoke;
+ ot->modal = paint_modal;
+ ot->exec = paint_exec;
+ ot->poll = image_paint_poll;
+ ot->cancel = paint_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING;
+
+ paint_stroke_operator_properties(ot);
+}
+}
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index f1e79b98b83..82fdf49c28e 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -49,6 +49,7 @@ typedef struct CoNo {
typedef bool (*StrokeGetLocation)(struct bContext *C, float location[3], const float mouse[2]);
typedef bool (*StrokeTestStart)(struct bContext *C, struct wmOperator *op, const float mouse[2]);
typedef void (*StrokeUpdateStep)(struct bContext *C,
+ struct wmOperator *op,
struct PaintStroke *stroke,
struct PointerRNA *itemptr);
typedef void (*StrokeRedraw)(const struct bContext *C, struct PaintStroke *stroke, bool final);
@@ -62,7 +63,7 @@ struct PaintStroke *paint_stroke_new(struct bContext *C,
StrokeRedraw redraw,
StrokeDone done,
int event_type);
-void paint_stroke_free(struct bContext *C, struct wmOperator *op);
+void paint_stroke_free(struct bContext *C, struct wmOperator *op, struct PaintStroke *stroke);
/**
* Returns zero if the stroke dots should not be spaced, non-zero otherwise.
@@ -84,9 +85,12 @@ bool paint_supports_jitter(enum ePaintMode mode);
* Called in paint_ops.c, on each regeneration of key-maps.
*/
struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf);
-int paint_stroke_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
-int paint_stroke_exec(struct bContext *C, struct wmOperator *op);
-void paint_stroke_cancel(struct bContext *C, struct wmOperator *op);
+int paint_stroke_modal(struct bContext *C,
+ struct wmOperator *op,
+ const struct wmEvent *event,
+ struct PaintStroke *stroke);
+int paint_stroke_exec(struct bContext *C, struct wmOperator *op, struct PaintStroke *stroke);
+void paint_stroke_cancel(struct bContext *C, struct wmOperator *op, struct PaintStroke *stroke);
bool paint_stroke_flipped(struct PaintStroke *stroke);
bool paint_stroke_inverted(struct PaintStroke *stroke);
struct ViewContext *paint_stroke_view_context(struct PaintStroke *stroke);
@@ -265,6 +269,7 @@ void paint_brush_color_get(struct Scene *scene,
bool paint_use_opacity_masking(struct Brush *brush);
void paint_brush_init_tex(struct Brush *brush);
void paint_brush_exit_tex(struct Brush *brush);
+bool image_paint_poll(struct bContext *C);
void PAINT_OT_grab_clone(struct wmOperatorType *ot);
void PAINT_OT_sample_color(struct wmOperatorType *ot);
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 1b876235ad0..926a564184a 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -39,6 +39,7 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "curves_sculpt_intern.h"
#include "paint_intern.h"
#include "sculpt_intern.h"
@@ -758,6 +759,7 @@ static const ePaintMode brush_select_paint_modes[] = {
PAINT_MODE_VERTEX_GPENCIL,
PAINT_MODE_SCULPT_GPENCIL,
PAINT_MODE_WEIGHT_GPENCIL,
+ PAINT_MODE_SCULPT_CURVES,
};
static int brush_select_exec(bContext *C, wmOperator *op)
@@ -1388,6 +1390,10 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
keymap = paint_stroke_modal_keymap(keyconf);
WM_modalkeymap_assign(keymap, "SCULPT_OT_brush_stroke");
+ /* Curves Sculpt mode. */
+ keymap = WM_keymap_ensure(keyconf, "Sculpt Curves", 0, 0);
+ keymap->poll = CURVES_SCULPT_mode_poll;
+
/* sculpt expand. */
sculpt_expand_modal_keymap(keyconf);
}
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 9bbfb81e08e..ae7570d21a1 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -505,16 +505,13 @@ static bool paint_stroke_use_jitter(ePaintMode mode, Brush *brush, bool invert)
}
/* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */
-static void paint_brush_stroke_add_step(bContext *C,
- wmOperator *op,
- const float mouse_in[2],
- float pressure)
+static void paint_brush_stroke_add_step(
+ bContext *C, wmOperator *op, PaintStroke *stroke, const float mouse_in[2], float pressure)
{
Scene *scene = CTX_data_scene(C);
Paint *paint = BKE_paint_get_active_from_context(C);
ePaintMode mode = BKE_paintmode_get_active_from_context(C);
Brush *brush = BKE_paint_brush(paint);
- PaintStroke *stroke = op->customdata;
UnifiedPaintSettings *ups = stroke->ups;
float mouse_out[2];
PointerRNA itemptr;
@@ -614,7 +611,7 @@ static void paint_brush_stroke_add_step(bContext *C,
RNA_float_set(&itemptr, "x_tilt", stroke->x_tilt);
RNA_float_set(&itemptr, "y_tilt", stroke->y_tilt);
- stroke->update_step(C, stroke, &itemptr);
+ stroke->update_step(C, op, stroke, &itemptr);
/* don't record this for now, it takes up a lot of memory when doing long
* strokes with small brush size, and operators have register disabled */
@@ -785,12 +782,12 @@ static float paint_space_stroke_spacing_variable(bContext *C,
* towards the final mouse location. */
static int paint_space_stroke(bContext *C,
wmOperator *op,
+ PaintStroke *stroke,
const float final_mouse[2],
float final_pressure)
{
const Scene *scene = CTX_data_scene(C);
ARegion *region = CTX_wm_region(C);
- PaintStroke *stroke = op->customdata;
UnifiedPaintSettings *ups = stroke->ups;
Paint *paint = BKE_paint_get_active_from_context(C);
ePaintMode mode = BKE_paintmode_get_active_from_context(C);
@@ -852,7 +849,7 @@ static int paint_space_stroke(bContext *C,
spacing / no_pressure_spacing);
stroke->stroke_distance += spacing / stroke->zoom_2d;
- paint_brush_stroke_add_step(C, op, mouse, pressure);
+ paint_brush_stroke_add_step(C, op, stroke, mouse, pressure);
length -= spacing;
pressure = stroke->last_pressure;
@@ -929,7 +926,7 @@ PaintStroke *paint_stroke_new(bContext *C,
return stroke;
}
-void paint_stroke_free(bContext *C, wmOperator *op)
+void paint_stroke_free(bContext *C, wmOperator *UNUSED(op), PaintStroke *stroke)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
if (rv3d) {
@@ -938,7 +935,6 @@ void paint_stroke_free(bContext *C, wmOperator *op)
BKE_paint_set_overlay_override(0);
- PaintStroke *stroke = op->customdata;
if (stroke == NULL) {
return;
}
@@ -961,12 +957,11 @@ void paint_stroke_free(bContext *C, wmOperator *op)
BLI_freelistN(&stroke->line);
- MEM_SAFE_FREE(op->customdata);
+ MEM_SAFE_FREE(stroke);
}
-static void stroke_done(bContext *C, wmOperator *op)
+static void stroke_done(bContext *C, wmOperator *op, PaintStroke *stroke)
{
- PaintStroke *stroke = op->customdata;
UnifiedPaintSettings *ups = stroke->ups;
/* reset rotation here to avoid doing so in cursor display */
@@ -988,7 +983,7 @@ static void stroke_done(bContext *C, wmOperator *op)
}
}
- paint_stroke_free(C, op);
+ paint_stroke_free(C, op, stroke);
}
bool paint_space_stroke_enabled(Brush *br, ePaintMode mode)
@@ -1230,7 +1225,7 @@ static void paint_line_strokes_spacing(bContext *C,
ups->overlap_factor = paint_stroke_integrate_overlap(stroke->brush, 1.0);
stroke->stroke_distance += spacing / stroke->zoom_2d;
- paint_brush_stroke_add_step(C, op, mouse, 1.0);
+ paint_brush_stroke_add_step(C, op, stroke, mouse, 1.0);
length -= spacing;
spacing_final = spacing;
@@ -1252,8 +1247,8 @@ static void paint_stroke_line_end(bContext *C,
if (stroke->stroke_started && (br->flag & BRUSH_LINE)) {
stroke->ups->overlap_factor = paint_stroke_integrate_overlap(br, 1.0);
- paint_brush_stroke_add_step(C, op, stroke->last_mouse_position, 1.0);
- paint_space_stroke(C, op, mouse, 1.0);
+ paint_brush_stroke_add_step(C, op, stroke, stroke->last_mouse_position, 1.0);
+ paint_space_stroke(C, op, stroke, mouse, 1.0);
}
}
@@ -1331,7 +1326,7 @@ static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *str
stroke->stroke_started = stroke->test_start(C, op, stroke->last_mouse_position);
if (stroke->stroke_started) {
- paint_brush_stroke_add_step(C, op, data + 2 * j, 1.0);
+ paint_brush_stroke_add_step(C, op, stroke, data + 2 * j, 1.0);
paint_line_strokes_spacing(
C, op, stroke, spacing, &length_residue, data + 2 * j, data + 2 * (j + 1));
}
@@ -1343,7 +1338,7 @@ static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *str
}
}
- stroke_done(C, op);
+ stroke_done(C, op, stroke);
#ifdef DEBUG_TIME
TIMEIT_END_AVERAGED(whole_stroke);
@@ -1384,11 +1379,10 @@ static void paint_stroke_line_constrain(PaintStroke *stroke, float mouse[2])
}
}
-int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
+int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintStroke *stroke)
{
Paint *p = BKE_paint_get_active_from_context(C);
ePaintMode mode = BKE_paintmode_get_active_from_context(C);
- PaintStroke *stroke = op->customdata;
Brush *br = stroke->brush = BKE_paint_brush(p);
PaintSample sample_average;
float mouse[2];
@@ -1482,7 +1476,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
op->type->cancel(C, op);
}
else {
- paint_stroke_cancel(C, op);
+ paint_stroke_cancel(C, op, stroke);
}
return OPERATOR_CANCELLED;
}
@@ -1492,17 +1486,17 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
copy_v2_fl2(mouse, event->mval[0], event->mval[1]);
paint_stroke_line_constrain(stroke, mouse);
paint_stroke_line_end(C, op, stroke, mouse);
- stroke_done(C, op);
+ stroke_done(C, op, stroke);
return OPERATOR_FINISHED;
}
}
else if (ELEM(event->type, EVT_RETKEY, EVT_SPACEKEY)) {
paint_stroke_line_end(C, op, stroke, sample_average.mouse);
- stroke_done(C, op);
+ stroke_done(C, op, stroke);
return OPERATOR_FINISHED;
}
else if (br->flag & BRUSH_LINE) {
- if (event->alt) {
+ if (event->modifier & KM_ALT) {
stroke->constrain_line = true;
}
else {
@@ -1530,7 +1524,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (paint_smooth_stroke(stroke, &sample_average, mode, mouse, &pressure)) {
if (stroke->stroke_started) {
if (paint_space_stroke_enabled(br, mode)) {
- if (paint_space_stroke(C, op, mouse, pressure)) {
+ if (paint_space_stroke(C, op, stroke, mouse, pressure)) {
redraw = true;
}
}
@@ -1538,7 +1532,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
float dmouse[2];
sub_v2_v2v2(dmouse, mouse, stroke->last_mouse_position);
stroke->stroke_distance += len_v2(dmouse);
- paint_brush_stroke_add_step(C, op, mouse, pressure);
+ paint_brush_stroke_add_step(C, op, stroke, mouse, pressure);
redraw = true;
}
}
@@ -1549,7 +1543,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
* instead of waiting till we have moved the space distance */
if (first_dab && paint_space_stroke_enabled(br, mode) && !(br->flag & BRUSH_SMOOTH_STROKE)) {
stroke->ups->overlap_factor = paint_stroke_integrate_overlap(br, 1.0);
- paint_brush_stroke_add_step(C, op, sample_average.mouse, sample_average.pressure);
+ paint_brush_stroke_add_step(C, op, stroke, sample_average.mouse, sample_average.pressure);
redraw = true;
}
@@ -1572,10 +1566,8 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-int paint_stroke_exec(bContext *C, wmOperator *op)
+int paint_stroke_exec(bContext *C, wmOperator *op, PaintStroke *stroke)
{
- PaintStroke *stroke = op->customdata;
-
/* only when executed for the first time */
if (stroke->stroke_started == 0) {
PropertyRNA *strokeprop;
@@ -1592,21 +1584,21 @@ int paint_stroke_exec(bContext *C, wmOperator *op)
if (stroke->stroke_started) {
RNA_BEGIN (op->ptr, itemptr, "stroke") {
- stroke->update_step(C, stroke, &itemptr);
+ stroke->update_step(C, op, stroke, &itemptr);
}
RNA_END;
}
bool ok = (stroke->stroke_started != 0);
- stroke_done(C, op);
+ stroke_done(C, op, stroke);
return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
-void paint_stroke_cancel(bContext *C, wmOperator *op)
+void paint_stroke_cancel(bContext *C, wmOperator *op, PaintStroke *stroke)
{
- stroke_done(C, op);
+ stroke_done(C, op, stroke);
}
ViewContext *paint_stroke_view_context(PaintStroke *stroke)
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index f54b012b8dd..31b965c6a92 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -130,13 +130,12 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3], flo
{
Object *ob = vc->obact;
float delta[3], scale, loc[3];
- const float mval_f[2] = {pixel_radius, 0.0f};
- float zfac;
+ const float xy_delta[2] = {pixel_radius, 0.0f};
mul_v3_m4v3(loc, ob->obmat, center);
- zfac = ED_view3d_calc_zfac(vc->rv3d, loc, NULL);
- ED_view3d_win_to_delta(vc->region, mval_f, delta, zfac);
+ const float zfac = ED_view3d_calc_zfac(vc->rv3d, loc);
+ ED_view3d_win_to_delta(vc->region, xy_delta, zfac, delta);
scale = fabsf(mat4_to_scale(ob->obmat));
scale = (scale == 0.0f) ? 1.0f : scale;
@@ -585,7 +584,8 @@ void BRUSH_OT_curve_preset(wmOperatorType *ot)
ot->poll = brush_curve_preset_poll;
prop = RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", "");
- RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
+ RNA_def_property_translation_context(prop,
+ BLT_I18NCONTEXT_ID_CURVE_LEGACY); /* Abusing id_curve :/ */
}
/* face-select ops */
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index a82636023f8..e2f8d81fe13 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -2370,7 +2370,10 @@ static void wpaint_do_symmetrical_brush_actions(
cache->is_last_valid = true;
}
-static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
+static void wpaint_stroke_update_step(bContext *C,
+ wmOperator *UNUSED(op),
+ struct PaintStroke *stroke,
+ PointerRNA *itemptr)
{
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -2551,7 +2554,7 @@ static int wpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
event->type);
if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
- paint_stroke_free(C, op);
+ paint_stroke_free(C, op, op->customdata);
return OPERATOR_FINISHED;
}
/* add modal handler */
@@ -2575,7 +2578,7 @@ static int wpaint_exec(bContext *C, wmOperator *op)
0);
/* frees op->customdata */
- paint_stroke_exec(C, op);
+ paint_stroke_exec(C, op, op->customdata);
return OPERATOR_FINISHED;
}
@@ -2588,7 +2591,12 @@ static void wpaint_cancel(bContext *C, wmOperator *op)
ob->sculpt->cache = NULL;
}
- paint_stroke_cancel(C, op);
+ paint_stroke_cancel(C, op, op->customdata);
+}
+
+static int wpaint_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ return paint_stroke_modal(C, op, event, op->customdata);
}
void PAINT_OT_weight_paint(wmOperatorType *ot)
@@ -2600,7 +2608,7 @@ void PAINT_OT_weight_paint(wmOperatorType *ot)
/* api callbacks */
ot->invoke = wpaint_invoke;
- ot->modal = paint_stroke_modal;
+ ot->modal = wpaint_modal;
ot->exec = wpaint_exec;
ot->poll = weight_paint_poll;
ot->cancel = wpaint_cancel;
@@ -3395,7 +3403,10 @@ static void vpaint_do_symmetrical_brush_actions(
cache->is_last_valid = true;
}
-static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
+static void vpaint_stroke_update_step(bContext *C,
+ wmOperator *UNUSED(op),
+ struct PaintStroke *stroke,
+ PointerRNA *itemptr)
{
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -3497,7 +3508,7 @@ static int vpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
event->type);
if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
- paint_stroke_free(C, op);
+ paint_stroke_free(C, op, op->customdata);
return OPERATOR_FINISHED;
}
@@ -3522,7 +3533,7 @@ static int vpaint_exec(bContext *C, wmOperator *op)
0);
/* frees op->customdata */
- paint_stroke_exec(C, op);
+ paint_stroke_exec(C, op, op->customdata);
return OPERATOR_FINISHED;
}
@@ -3535,7 +3546,12 @@ static void vpaint_cancel(bContext *C, wmOperator *op)
ob->sculpt->cache = NULL;
}
- paint_stroke_cancel(C, op);
+ paint_stroke_cancel(C, op, op->customdata);
+}
+
+static int vpaint_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ return paint_stroke_modal(C, op, event, op->customdata);
}
void PAINT_OT_vertex_paint(wmOperatorType *ot)
@@ -3547,7 +3563,7 @@ void PAINT_OT_vertex_paint(wmOperatorType *ot)
/* api callbacks */
ot->invoke = vpaint_invoke;
- ot->modal = paint_stroke_modal;
+ ot->modal = vpaint_modal;
ot->exec = vpaint_exec;
ot->poll = vertex_paint_poll;
ot->cancel = vpaint_cancel;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 68edf9cd54a..70ff7596d6d 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -2648,13 +2648,13 @@ static void update_sculpt_normal(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
static void calc_local_y(ViewContext *vc, const float center[3], float y[3])
{
Object *ob = vc->obact;
- float loc[3], mval_f[2] = {0.0f, 1.0f};
- float zfac;
+ float loc[3];
+ const float xy_delta[2] = {0.0f, 1.0f};
mul_v3_m4v3(loc, ob->imat, center);
- zfac = ED_view3d_calc_zfac(vc->rv3d, loc, NULL);
+ const float zfac = ED_view3d_calc_zfac(vc->rv3d, loc);
- ED_view3d_win_to_delta(vc->region, mval_f, y, zfac);
+ ED_view3d_win_to_delta(vc->region, xy_delta, zfac, y);
normalize_v3(y);
add_v3_v3(y, ob->loc);
@@ -5186,6 +5186,7 @@ static bool sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const f
}
static void sculpt_stroke_update_step(bContext *C,
+ wmOperator *UNUSED(op),
struct PaintStroke *UNUSED(stroke),
PointerRNA *itemptr)
{
@@ -5333,12 +5334,12 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent
ignore_background_click = RNA_boolean_get(op->ptr, "ignore_background_click");
if (ignore_background_click && !over_mesh(C, op, event->xy[0], event->xy[1])) {
- paint_stroke_free(C, op);
+ paint_stroke_free(C, op, op->customdata);
return OPERATOR_PASS_THROUGH;
}
if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
- paint_stroke_free(C, op);
+ paint_stroke_free(C, op, op->customdata);
return OPERATOR_FINISHED;
}
/* Add modal handler. */
@@ -5364,7 +5365,7 @@ static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op)
0);
/* Frees op->customdata. */
- paint_stroke_exec(C, op);
+ paint_stroke_exec(C, op, op->customdata);
return OPERATOR_FINISHED;
}
@@ -5382,7 +5383,7 @@ static void sculpt_brush_stroke_cancel(bContext *C, wmOperator *op)
paint_mesh_restore_co(sd, ob);
}
- paint_stroke_cancel(C, op);
+ paint_stroke_cancel(C, op, op->customdata);
if (ss->cache) {
SCULPT_cache_free(ss->cache);
@@ -5392,6 +5393,11 @@ static void sculpt_brush_stroke_cancel(bContext *C, wmOperator *op)
sculpt_brush_exit_tex(sd);
}
+static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ return paint_stroke_modal(C, op, event, op->customdata);
+}
+
void SCULPT_OT_brush_stroke(wmOperatorType *ot)
{
/* Identifiers. */
@@ -5401,7 +5407,7 @@ void SCULPT_OT_brush_stroke(wmOperatorType *ot)
/* API callbacks. */
ot->invoke = sculpt_brush_stroke_invoke;
- ot->modal = paint_stroke_modal;
+ ot->modal = sculpt_brush_stroke_modal;
ot->exec = sculpt_brush_stroke_exec;
ot->poll = SCULPT_poll;
ot->cancel = sculpt_brush_stroke_cancel;
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index a6b412b2b7e..6f9df4d8252 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -1105,10 +1105,10 @@ bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v);
bool SCULPT_search_circle_cb(PBVHNode *node, void *data_v);
/**
- * Initialize a point-in-brush test with a given falloff shape
+ * Initialize a point-in-brush test with a given falloff shape.
*
- * \param falloff_shape PAINT_FALLOFF_SHAPE_SPHERE or PAINT_FALLOFF_SHAPE_TUBE
- * \return The brush falloff function
+ * \param falloff_shape: #PAINT_FALLOFF_SHAPE_SPHERE or #PAINT_FALLOFF_SHAPE_TUBE.
+ * \return The brush falloff function.
*/
SculptBrushTestFn SCULPT_brush_test_init_with_falloff_shape(SculptSession *ss,
SculptBrushTest *test,
diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
index 72640893dea..8fc10061f83 100644
--- a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
+++ b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
@@ -245,7 +245,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
/* When pressing Ctrl, expand directly to the max number of iterations. This allows to flood fill
* mask and face sets by connectivity directly. */
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
mask_expand_update_it = ss->filter_cache->mask_update_last_it - 1;
}
diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c
index e383ada1331..8e8902c2ea7 100644
--- a/source/blender/editors/space_action/action_data.c
+++ b/source/blender/editors/space_action/action_data.c
@@ -659,7 +659,7 @@ static int action_unlink_invoke(bContext *C, wmOperator *op, const wmEvent *even
{
/* NOTE: this is hardcoded to match the behavior for the unlink button
* (in interface_templates.c). */
- RNA_boolean_set(op->ptr, "force_delete", event->shift != 0);
+ RNA_boolean_set(op->ptr, "force_delete", event->modifier & KM_SHIFT);
return action_unlink_exec(C, op);
}
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 897091731a4..d53fe2efb03 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -29,6 +29,7 @@
#include "ED_clip.h"
#include "ED_curve.h"
#include "ED_curves.h"
+#include "ED_curves_sculpt.h"
#include "ED_fileselect.h"
#include "ED_geometry.h"
#include "ED_gizmo_library.h"
@@ -96,6 +97,7 @@ void ED_spacetypes_init(void)
ED_operatortypes_mesh();
ED_operatortypes_geometry();
ED_operatortypes_sculpt();
+ ED_operatortypes_sculpt_curves();
ED_operatortypes_uvedit();
ED_operatortypes_paint();
ED_operatortypes_physics();
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 287aef178ae..4e80e7ea5c2 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -230,7 +230,7 @@ static bool buttons_context_path_data(ButsContextPath *path, int type)
return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_Curve) &&
- (type == -1 || ELEM(type, OB_CURVE, OB_SURF, OB_FONT))) {
+ (type == -1 || ELEM(type, OB_CURVES_LEGACY, OB_SURF, OB_FONT))) {
return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_Armature) && (ELEM(type, -1, OB_ARMATURE))) {
@@ -293,7 +293,7 @@ static bool buttons_context_path_modifier(ButsContextPath *path)
if (ELEM(ob->type,
OB_MESH,
- OB_CURVE,
+ OB_CURVES_LEGACY,
OB_FONT,
OB_SURF,
OB_LATTICE,
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index cad6d34af24..e215b7c7992 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -282,11 +282,11 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* Useful yet irritating feature, Shift+Click to open the file
* Alt+Click to browse a folder in the OS's browser. */
- if (event->shift || event->alt) {
+ if (event->modifier & (KM_SHIFT | KM_ALT)) {
wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
PointerRNA props_ptr;
- if (event->alt) {
+ if (event->modifier & KM_ALT) {
char *lslash = (char *)BLI_path_slash_rfind(str);
if (lslash) {
*lslash = '\0';
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index ba0b3a59e24..a24eae6a0ce 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -408,7 +408,7 @@ static int console_insert_invoke(bContext *C, wmOperator *op, const wmEvent *eve
* (when input method are used for utf8 inputs, the user may assign key event
* including alt/ctrl/super like ctrl+m to commit utf8 string. in such case,
* the modifiers in the utf8 character event make no sense.) */
- if ((event->ctrl || event->oskey) && !event->utf8_buf[0]) {
+ if ((event->modifier & (KM_CTRL | KM_OSKEY)) && !event->utf8_buf[0]) {
return OPERATOR_PASS_THROUGH;
}
@@ -456,7 +456,18 @@ void CONSOLE_OT_insert(wmOperatorType *ot)
static int console_indent_or_autocomplete_exec(bContext *C, wmOperator *UNUSED(op))
{
ConsoleLine *ci = console_history_verify(C);
- bool text_before_cursor = ci->cursor != 0 && !ELEM(ci->line[ci->cursor - 1], ' ', '\t');
+ bool text_before_cursor = false;
+
+ /* Check any text before cursor (not just the previous character) as is done for
+ * #TEXT_OT_indent_or_autocomplete because Python auto-complete operates on import
+ * statements such as completing possible sub-modules: `from bpy import `. */
+ for (int i = 0; i < ci->cursor; i += BLI_str_utf8_size_safe(&ci->line[i])) {
+ if (!ELEM(ci->line[i], ' ', '\t')) {
+ text_before_cursor = true;
+ break;
+ }
+ }
+
if (text_before_cursor) {
WM_operator_name_call(C, "CONSOLE_OT_autocomplete", WM_OP_INVOKE_DEFAULT, NULL);
}
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 3b3d968aed6..daa4b53803f 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -2245,7 +2245,7 @@ FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index, const
cache->misc_entries_indices[cache->misc_cursor] = index;
cache->misc_cursor = (cache->misc_cursor + 1) % cache_size;
-#if 0 /* Actually no, only block cached entries should have preview imho. */
+#if 0 /* Actually no, only block cached entries should have preview IMHO. */
if (cache->previews_pool) {
filelist_cache_previews_push(filelist, ret, index);
}
diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c
index 1006ba4b3f4..1a3355b0139 100644
--- a/source/blender/editors/space_graph/graph_slider_ops.c
+++ b/source/blender/editors/space_graph/graph_slider_ops.c
@@ -163,6 +163,18 @@ static void reset_bezts(tGraphSliderOp *gso)
ANIM_animdata_freelist(&anim_data);
}
+/**
+ * Get factor value and store it in RNA property.
+ * Custom data of #wmOperator needs to contain #tGraphSliderOp.
+ */
+static float slider_factor_get_and_remember(wmOperator *op)
+{
+ tGraphSliderOp *gso = op->customdata;
+ const float factor = ED_slider_factor_get(gso->slider);
+ RNA_property_float_set(op->ptr, gso->factor_prop, factor);
+ return factor;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -378,8 +390,7 @@ static void decimate_modal_update(bContext *C, wmOperator *op)
reset_bezts(gso);
/* Apply... */
- float factor = ED_slider_factor_get(gso->slider);
- RNA_property_float_set(op->ptr, gso->factor_prop, factor);
+ const float factor = slider_factor_get_and_remember(op);
/* We don't want to limit the decimation to a certain error margin. */
const float error_sq_max = FLT_MAX;
decimate_graph_keys(&gso->ac, factor, error_sq_max);
@@ -598,8 +609,7 @@ static void blend_to_neighbor_modal_update(bContext *C, wmOperator *op)
/* Reset keyframe data to the state at invoke. */
reset_bezts(gso);
- const float factor = ED_slider_factor_get(gso->slider);
- RNA_property_float_set(op->ptr, gso->factor_prop, factor);
+ const float factor = slider_factor_get_and_remember(op);
blend_to_neighbor_graph_keys(&gso->ac, factor);
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
@@ -725,7 +735,8 @@ static void breakdown_modal_update(bContext *C, wmOperator *op)
/* Reset keyframe data to the state at invoke. */
reset_bezts(gso);
- breakdown_graph_keys(&gso->ac, ED_slider_factor_get(gso->slider));
+ const float factor = slider_factor_get_and_remember(op);
+ breakdown_graph_keys(&gso->ac, factor);
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
@@ -739,6 +750,7 @@ static int breakdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
tGraphSliderOp *gso = op->customdata;
gso->modal_update = breakdown_modal_update;
+ gso->factor_prop = RNA_struct_find_property(op->ptr, "factor");
breakdown_draw_status_header(C, gso);
return invoke_result;
diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c
index 4351186dc6f..9f934e47ebb 100644
--- a/source/blender/editors/space_graph/graph_utils.c
+++ b/source/blender/editors/space_graph/graph_utils.c
@@ -185,6 +185,7 @@ bool graphop_editable_keyframes_poll(bContext *C)
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE);
items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
if (items == 0) {
+ CTX_wm_operator_poll_msg_set(C, "There is no animation data to operate on");
return found;
}
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 27ac34ba346..22427675ff3 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -242,7 +242,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region)
GPU_blend(GPU_BLEND_NONE);
- /* Vertical component of of the cursor. */
+ /* Vertical component of the cursor. */
if (sipo->mode == SIPO_MODE_DRIVERS) {
/* cursor x-value */
float x = sipo->cursorTime;
diff --git a/source/blender/editors/space_info/info_stats.cc b/source/blender/editors/space_info/info_stats.cc
index da899ef4c9a..6f0d5c2dbe9 100644
--- a/source/blender/editors/space_info/info_stats.cc
+++ b/source/blender/editors/space_info/info_stats.cc
@@ -152,7 +152,7 @@ static void stats_object(Object *ob,
}
break;
case OB_SURF:
- case OB_CURVE:
+ case OB_CURVES_LEGACY:
case OB_FONT: {
const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
if ((me_eval != nullptr) && !BLI_gset_add(objects_gset, (void *)me_eval)) {
@@ -260,7 +260,7 @@ static void stats_object_edit(Object *obedit, SceneStats *stats)
stats->totvert += 2;
}
}
- else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { /* OB_FONT has no cu->editnurb */
+ else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) { /* OB_FONT has no cu->editnurb */
/* Curve Edit */
Curve *cu = static_cast<Curve *>(obedit->data);
BezTriple *bezt;
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index 4a507aa3bf2..8b059b33a9a 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -583,7 +583,7 @@ static int nla_action_unlink_invoke(bContext *C, wmOperator *op, const wmEvent *
{
/* NOTE: this is hardcoded to match the behavior for the unlink button
* (in interface_templates.c) */
- RNA_boolean_set(op->ptr, "force_delete", event->shift != 0);
+ RNA_boolean_set(op->ptr, "force_delete", event->modifier & KM_SHIFT);
return nla_action_unlink_exec(C, op);
}
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index eda9f89b51c..d8a0fde6d07 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -110,7 +110,7 @@ static void nla_action_draw_keyframes(
*/
Range2f frame_range;
- ED_keylist_frame_range(keylist, &frame_range);
+ ED_keylist_all_keys_frame_range(keylist, &frame_range);
immRectf(pos_id, frame_range.min, ymin + 2, frame_range.max, ymax - 2);
immUnbindProgram();
diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc
index 28ac7a34fa8..afb205f9f9e 100644
--- a/source/blender/editors/space_node/drawnode.cc
+++ b/source/blender/editors/space_node/drawnode.cc
@@ -147,7 +147,7 @@ static void node_buts_curvefloat(uiLayout *layout, bContext *UNUSED(C), PointerR
} // namespace blender::ed::space_node
#define SAMPLE_FLT_ISNONE FLT_MAX
-/* Bad bad, 2.5 will do better? ... no it won't! */
+/* Bad! 2.5 will do better? ... no it won't! */
static float _sample_col[4] = {SAMPLE_FLT_ISNONE};
void ED_node_sample_set(const float col[4])
{
@@ -1967,9 +1967,10 @@ void node_draw_link_bezier(const bContext &C,
const bNodeLink &link,
const int th_col1,
const int th_col2,
- const int th_col3)
+ const int th_col3,
+ const bool selected)
{
- const float dim_factor = node_link_dim_factor(v2d, link);
+ const float dim_factor = selected ? 1.0f : node_link_dim_factor(v2d, link);
float thickness = 1.5f;
float dash_factor = 1.0f;
@@ -2025,19 +2026,17 @@ void node_draw_link_bezier(const bContext &C,
}
/* Highlight links connected to selected nodes. */
- const bool is_fromnode_selected = link.fromnode && link.fromnode->flag & SELECT;
- const bool is_tonode_selected = link.tonode && link.tonode->flag & SELECT;
- if (is_fromnode_selected || is_tonode_selected) {
+ if (selected) {
float color_selected[4];
UI_GetThemeColor4fv(TH_EDGE_SELECT, color_selected);
const float alpha = color_selected[3];
/* Interpolate color if highlight color is not fully transparent. */
if (alpha != 0.0) {
- if (is_fromnode_selected) {
+ if (link.fromsock) {
interp_v3_v3v3(colors[1], colors[1], color_selected, alpha);
}
- if (is_tonode_selected) {
+ if (link.tosock) {
interp_v3_v3v3(colors[2], colors[2], color_selected, alpha);
}
}
@@ -2102,7 +2101,8 @@ void node_draw_link_bezier(const bContext &C,
void node_draw_link(const bContext &C,
const View2D &v2d,
const SpaceNode &snode,
- const bNodeLink &link)
+ const bNodeLink &link,
+ const bool selected)
{
int th_col1 = TH_WIRE_INNER, th_col2 = TH_WIRE_INNER, th_col3 = TH_WIRE;
@@ -2146,7 +2146,7 @@ void node_draw_link(const bContext &C,
}
}
- node_draw_link_bezier(C, v2d, snode, link, th_col1, th_col2, th_col3);
+ node_draw_link_bezier(C, v2d, snode, link, th_col1, th_col2, th_col3, selected);
}
} // namespace blender::ed::space_node
diff --git a/source/blender/editors/space_node/node_context_path.cc b/source/blender/editors/space_node/node_context_path.cc
index a76988a60d0..349fa92d06d 100644
--- a/source/blender/editors/space_node/node_context_path.cc
+++ b/source/blender/editors/space_node/node_context_path.cc
@@ -47,7 +47,7 @@ static void context_path_add_object_data(Vector<ui::ContextPathItem> &path, Obje
Light *light = (Light *)object.data;
ui::context_path_add_generic(path, RNA_Light, light);
}
- if (ELEM(object.type, OB_CURVE, OB_FONT, OB_SURF) && object.data) {
+ if (ELEM(object.type, OB_CURVES_LEGACY, OB_FONT, OB_SURF) && object.data) {
Curve *curve = (Curve *)object.data;
ui::context_path_add_generic(path, RNA_Curve, curve);
}
diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc
index 455eceed293..1286f6a818c 100644
--- a/source/blender/editors/space_node/node_draw.cc
+++ b/source/blender/editors/space_node/node_draw.cc
@@ -660,7 +660,7 @@ static void node_draw_mute_line(const bContext &C,
GPU_blend(GPU_BLEND_ALPHA);
LISTBASE_FOREACH (const bNodeLink *, link, &node.internal_links) {
- node_draw_link_bezier(C, v2d, snode, *link, TH_WIRE_INNER, TH_WIRE_INNER, TH_WIRE);
+ node_draw_link_bezier(C, v2d, snode, *link, TH_WIRE_INNER, TH_WIRE_INNER, TH_WIRE, false);
}
GPU_blend(GPU_BLEND_NONE);
@@ -718,7 +718,12 @@ static void node_socket_draw_multi_input(const float color[4],
const int locx,
const int locy)
{
- const float outline_width = 1.0f;
+ /* The other sockets are drawn with the keyframe shader. There, the outline has a base thickness
+ * that can be varied but always scales with the size the socket is drawn at. Using `U.dpi_fac`
+ * has the the same effect here. It scales the outline correctly across different screen DPIs
+ * and UI scales without being affected by the 'line-width'. */
+ const float outline_width = NODE_SOCK_OUTLINE_SCALE * U.dpi_fac;
+
/* UI_draw_roundbox draws the outline on the outer side, so compensate for the outline width. */
const rctf rect = {
locx - width + outline_width * 0.5f,
@@ -1049,7 +1054,7 @@ static void node_socket_draw_nested(const bContext &C,
},
data,
MEM_freeN);
- /* Disable the button so that clicks on it are ignored the the link operator still works. */
+ /* Disable the button so that clicks on it are ignored the link operator still works. */
UI_but_flag_enable(but, UI_BUT_DISABLED);
UI_block_emboss_set(&block, old_emboss);
}
@@ -1060,7 +1065,7 @@ void ED_node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[
{
using namespace blender::ed::space_node;
- const float size = 2.25f * NODE_SOCKSIZE * scale;
+ const float size = NODE_SOCKSIZE_DRAW_MULIPLIER * NODE_SOCKSIZE * scale;
rcti draw_rect = *rect;
float outline_color[4] = {0};
@@ -1081,7 +1086,7 @@ void ED_node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[
GPU_program_point_size(true);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_SHAPE);
- immUniform1f("outline_scale", 1.0f);
+ immUniform1f("outline_scale", NODE_SOCK_OUTLINE_SCALE);
immUniform2f("ViewportSize", -1.0f, -1.0f);
/* Single point. */
@@ -1232,13 +1237,14 @@ static void node_draw_sockets(const View2D &v2d,
GPU_blend(GPU_BLEND_ALPHA);
GPU_program_point_size(true);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_SHAPE);
- immUniform1f("outline_scale", 1.0f);
+ immUniform1f("outline_scale", NODE_SOCK_OUTLINE_SCALE);
immUniform2f("ViewportSize", -1.0f, -1.0f);
/* Set handle size. */
+ const float socket_draw_size = NODE_SOCKSIZE * NODE_SOCKSIZE_DRAW_MULIPLIER;
float scale;
UI_view2d_scale_get(&v2d, &scale, nullptr);
- scale *= 2.25f * NODE_SOCKSIZE;
+ scale *= socket_draw_size;
if (!select_all) {
immBeginAtMost(GPU_PRIM_POINTS, total_input_len + total_output_len);
@@ -1251,7 +1257,10 @@ static void node_draw_sockets(const View2D &v2d,
continue;
}
if (select_all || (sock->flag & SELECT)) {
- selected_input_len++;
+ if (!(sock->flag & SOCK_MULTI_INPUT)) {
+ /* Don't add multi-input sockets here since they are drawn in a different batch. */
+ selected_input_len++;
+ }
continue;
}
/* Don't draw multi-input sockets here since they are drawn in a different batch. */
@@ -1318,6 +1327,10 @@ static void node_draw_sockets(const View2D &v2d,
if (nodeSocketIsHidden(sock)) {
continue;
}
+ /* Don't draw multi-input sockets here since they are drawn in a different batch. */
+ if (sock->flag & SOCK_MULTI_INPUT) {
+ continue;
+ }
if (select_all || (sock->flag & SELECT)) {
node_socket_draw_nested(C,
ntree,
@@ -1383,13 +1396,13 @@ static void node_draw_sockets(const View2D &v2d,
}
const bool is_node_hidden = (node.flag & NODE_HIDDEN);
- const float width = NODE_SOCKSIZE;
+ const float width = 0.5f * socket_draw_size;
float height = is_node_hidden ? width : node_socket_calculate_height(*socket) - width;
float color[4];
float outline_color[4];
node_socket_color_get(C, ntree, node_ptr, *socket, color);
- node_socket_outline_color_get(selected, socket->type, outline_color);
+ node_socket_outline_color_get(socket->flag & SELECT, socket->type, outline_color);
node_socket_draw_multi_input(color, outline_color, width, height, socket->locx, socket->locy);
}
@@ -2650,10 +2663,18 @@ static void node_draw_nodetree(const bContext &C,
nodelink_batch_start(snode);
LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
- if (!nodeLinkIsHidden(link)) {
- node_draw_link(C, region.v2d, snode, *link);
+ if (!nodeLinkIsHidden(link) && !nodeLinkIsSelected(link)) {
+ node_draw_link(C, region.v2d, snode, *link, false);
}
}
+
+ /* Draw selected node links after the unselected ones, so they are shown on top. */
+ LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
+ if (!nodeLinkIsHidden(link) && nodeLinkIsSelected(link)) {
+ node_draw_link(C, region.v2d, snode, *link, true);
+ }
+ }
+
nodelink_batch_end(snode);
GPU_blend(GPU_BLEND_NONE);
@@ -2838,7 +2859,7 @@ void node_draw_space(const bContext &C, ARegion &region)
GPU_line_smooth(true);
if (snode.runtime->linkdrag) {
for (const bNodeLink *link : snode.runtime->linkdrag->links) {
- node_draw_link(C, v2d, snode, *link);
+ node_draw_link(C, v2d, snode, *link, true);
}
}
GPU_line_smooth(false);
diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc
index 7b7aaef518b..b30be6ae0af 100644
--- a/source/blender/editors/space_node/node_edit.cc
+++ b/source/blender/editors/space_node/node_edit.cc
@@ -89,7 +89,7 @@ struct CompoJob {
float node_socket_calculate_height(const bNodeSocket &socket)
{
- float sock_height = NODE_SOCKSIZE * 2.0f;
+ float sock_height = NODE_SOCKSIZE * NODE_SOCKSIZE_DRAW_MULIPLIER;
if (socket.flag & SOCK_MULTI_INPUT) {
sock_height += max_ii(NODE_MULTI_INPUT_LINK_GAP * 0.5f * socket.total_inputs, NODE_SOCKSIZE);
}
@@ -1160,12 +1160,16 @@ bool node_find_indicated_socket(SpaceNode &snode,
{
rctf rect;
+ const float size_sock_padded = NODE_SOCKSIZE + 4;
+
*nodep = nullptr;
*sockp = nullptr;
/* check if we click in a socket */
LISTBASE_FOREACH (bNode *, node, &snode.edittree->nodes) {
- BLI_rctf_init_pt_radius(&rect, cursor, NODE_SOCKSIZE + 4);
+ BLI_rctf_init_pt_radius(&rect, cursor, size_sock_padded);
+ rctf node_visible;
+ BLI_rctf_init_pt_radius(&node_visible, cursor, size_sock_padded);
if (!(node->flag & NODE_HIDDEN)) {
/* extra padding inside and out - allow dragging on the text areas too */
@@ -1184,7 +1188,7 @@ bool node_find_indicated_socket(SpaceNode &snode,
if (!nodeSocketIsHidden(sock)) {
if (sock->flag & SOCK_MULTI_INPUT && !(node->flag & NODE_HIDDEN)) {
if (cursor_isect_multi_input_socket(cursor, *sock)) {
- if (node == visible_node(snode, rect)) {
+ if (node == visible_node(snode, node_visible)) {
*nodep = node;
*sockp = sock;
return true;
@@ -1192,7 +1196,7 @@ bool node_find_indicated_socket(SpaceNode &snode,
}
}
else if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
- if (node == visible_node(snode, rect)) {
+ if (node == visible_node(snode, node_visible)) {
*nodep = node;
*sockp = sock;
return true;
@@ -1205,7 +1209,7 @@ bool node_find_indicated_socket(SpaceNode &snode,
LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
if (!nodeSocketIsHidden(sock)) {
if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
- if (node == visible_node(snode, rect)) {
+ if (node == visible_node(snode, node_visible)) {
*nodep = node;
*sockp = sock;
return true;
diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh
index 592db3f7877..319f97e57f5 100644
--- a/source/blender/editors/space_node/node_intern.hh
+++ b/source/blender/editors/space_node/node_intern.hh
@@ -104,6 +104,8 @@ ENUM_OPERATORS(NodeResizeDirection, NODE_RESIZE_LEFT);
#define NODE_HEIGHT(node) (node.height * UI_DPI_FAC)
#define NODE_MARGIN_X (1.2f * U.widget_unit)
#define NODE_SOCKSIZE (0.25f * U.widget_unit)
+#define NODE_SOCKSIZE_DRAW_MULIPLIER 2.25f
+#define NODE_SOCK_OUTLINE_SCALE 1.0f
#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
@@ -196,7 +198,8 @@ void nodelink_batch_end(SpaceNode &snode);
void node_draw_link(const bContext &C,
const View2D &v2d,
const SpaceNode &snode,
- const bNodeLink &link);
+ const bNodeLink &link,
+ bool selected);
/**
* Don't do shadows if th_col3 is -1.
*/
@@ -206,7 +209,8 @@ void node_draw_link_bezier(const bContext &C,
const bNodeLink &link,
int th_col1,
int th_col2,
- int th_col3);
+ int th_col3,
+ bool selected);
/** If v2d not nullptr, it clips and returns 0 if not visible. */
bool node_link_bezier_points(const View2D *v2d,
const SpaceNode *snode,
diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc
index 1cfa932356b..299e7e5658c 100644
--- a/source/blender/editors/space_node/node_relationships.cc
+++ b/source/blender/editors/space_node/node_relationships.cc
@@ -2436,16 +2436,18 @@ void ED_node_link_insert(Main *bmain, ScrArea *area)
bNodeSocket *best_input = get_main_socket(ntree, *node_to_insert, SOCK_IN);
bNodeSocket *best_output = get_main_socket(ntree, *node_to_insert, SOCK_OUT);
- /* Ignore main sockets when the types don't match. */
- if (best_input != nullptr && ntree.typeinfo->validate_link != nullptr &&
- !ntree.typeinfo->validate_link(static_cast<eNodeSocketDatatype>(old_link->fromsock->type),
- static_cast<eNodeSocketDatatype>(best_input->type))) {
- best_input = nullptr;
- }
- if (best_output != nullptr && ntree.typeinfo->validate_link != nullptr &&
- !ntree.typeinfo->validate_link(static_cast<eNodeSocketDatatype>(best_output->type),
- static_cast<eNodeSocketDatatype>(old_link->tosock->type))) {
- best_output = nullptr;
+ if (node_to_insert->type != NODE_REROUTE) {
+ /* Ignore main sockets when the types don't match. */
+ if (best_input != nullptr && ntree.typeinfo->validate_link != nullptr &&
+ !ntree.typeinfo->validate_link(static_cast<eNodeSocketDatatype>(old_link->fromsock->type),
+ static_cast<eNodeSocketDatatype>(best_input->type))) {
+ best_input = nullptr;
+ }
+ if (best_output != nullptr && ntree.typeinfo->validate_link != nullptr &&
+ !ntree.typeinfo->validate_link(static_cast<eNodeSocketDatatype>(best_output->type),
+ static_cast<eNodeSocketDatatype>(old_link->tosock->type))) {
+ best_output = nullptr;
+ }
}
bNode *from_node = old_link->fromnode;
diff --git a/source/blender/editors/space_outliner/outliner_collections.cc b/source/blender/editors/space_outliner/outliner_collections.cc
index 765661aa9d5..f38f6c2855d 100644
--- a/source/blender/editors/space_outliner/outliner_collections.cc
+++ b/source/blender/editors/space_outliner/outliner_collections.cc
@@ -1071,7 +1071,7 @@ static int collection_isolate_exec(bContext *C, wmOperator *op)
static int collection_isolate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "extend");
- if (!RNA_property_is_set(op->ptr, prop) && (event->shift)) {
+ if (!RNA_property_is_set(op->ptr, prop) && (event->modifier & KM_SHIFT)) {
RNA_property_boolean_set(op->ptr, prop, true);
}
return collection_isolate_exec(C, op);
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.cc b/source/blender/editors/space_outliner/outliner_dragdrop.cc
index 0d8ee76d2f0..edd2e5f304f 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.cc
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.cc
@@ -319,7 +319,7 @@ static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
}
if (!allow_parenting_without_modifier_key(space_outliner)) {
- if (!event->shift) {
+ if ((event->modifier & KM_SHIFT) == 0) {
return false;
}
}
@@ -417,8 +417,12 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ListBase *lb = reinterpret_cast<ListBase *>(event->customdata);
wmDrag *drag = reinterpret_cast<wmDrag *>(lb->first);
- parent_drop_set_parents(
- C, op->reports, reinterpret_cast<wmDragID *>(drag->ids.first), par, PAR_OBJECT, event->alt);
+ parent_drop_set_parents(C,
+ op->reports,
+ reinterpret_cast<wmDragID *>(drag->ids.first),
+ par,
+ PAR_OBJECT,
+ event->modifier & KM_ALT);
return OPERATOR_FINISHED;
}
@@ -446,7 +450,7 @@ static bool parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event)
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
if (!allow_parenting_without_modifier_key(space_outliner)) {
- if (!event->shift) {
+ if ((event->modifier & KM_SHIFT) == 0) {
return false;
}
}
@@ -471,7 +475,7 @@ static bool parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event)
case ID_OB:
return ELEM(tselem->type, TSE_MODIFIER_BASE, TSE_CONSTRAINT_BASE);
case ID_GR:
- return event->shift || ELEM(tselem->type, TSE_LIBRARY_OVERRIDE_BASE);
+ return (event->modifier & KM_SHIFT) || ELEM(tselem->type, TSE_LIBRARY_OVERRIDE_BASE);
default:
return true;
}
@@ -496,7 +500,8 @@ static int parent_clear_invoke(bContext *C, wmOperator *UNUSED(op), const wmEven
if (GS(drag_id->id->name) == ID_OB) {
Object *object = (Object *)drag_id->id;
- ED_object_parent_clear(object, event->alt ? CLEAR_PARENT_KEEP_TRANSFORM : CLEAR_PARENT_ALL);
+ ED_object_parent_clear(
+ object, (event->modifier & KM_ALT) ? CLEAR_PARENT_KEEP_TRANSFORM : CLEAR_PARENT_ALL);
}
}
@@ -1166,10 +1171,11 @@ static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event
&space_outliner->tree, TSE_HIGHLIGHTED_ANY | TSE_DRAG_ANY, false);
CollectionDrop data;
- if (!event->shift && collection_drop_init(C, drag, event->xy, event->ctrl, &data)) {
+ if (((event->modifier & KM_SHIFT) == 0) &&
+ collection_drop_init(C, drag, event->xy, event->modifier & KM_CTRL, &data)) {
TreeElement *te = data.te;
TreeStoreElem *tselem = TREESTORE(te);
- if (!data.from || event->ctrl) {
+ if (!data.from || event->modifier & KM_CTRL) {
tselem->flag |= TSE_DRAG_INTO;
changed = true;
}
@@ -1210,9 +1216,10 @@ static char *collection_drop_tooltip(bContext *C,
const wmEvent *event = win ? win->eventstate : nullptr;
CollectionDrop data;
- if (event && !event->shift && collection_drop_init(C, drag, xy, event->ctrl, &data)) {
+ if (event && ((event->modifier & KM_SHIFT) == 0) &&
+ collection_drop_init(C, drag, xy, event->modifier & KM_CTRL, &data)) {
TreeElement *te = data.te;
- if (!data.from || event->ctrl) {
+ if (!data.from || event->modifier & KM_CTRL) {
return BLI_strdup(TIP_("Link inside Collection"));
}
switch (data.insert_type) {
@@ -1263,7 +1270,7 @@ static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmE
wmDrag *drag = reinterpret_cast<wmDrag *>(lb->first);
CollectionDrop data;
- if (!collection_drop_init(C, drag, event->xy, event->ctrl, &data)) {
+ if (!collection_drop_init(C, drag, event->xy, event->modifier & KM_CTRL, &data)) {
return OPERATOR_CANCELLED;
}
@@ -1291,7 +1298,9 @@ static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmE
LISTBASE_FOREACH (wmDragID *, drag_id, &drag->ids) {
/* Ctrl enables linking, so we don't need a from collection then. */
- Collection *from = (event->ctrl) ? nullptr : collection_parent_from_ID(drag_id->from_parent);
+ Collection *from = (event->modifier & KM_CTRL) ?
+ nullptr :
+ collection_parent_from_ID(drag_id->from_parent);
if (GS(drag_id->id->name) == ID_OB) {
/* Move/link object into collection. */
diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc
index dd7ca128282..2da416c8671 100644
--- a/source/blender/editors/space_outliner/outliner_draw.cc
+++ b/source/blender/editors/space_outliner/outliner_draw.cc
@@ -166,7 +166,7 @@ static void restrictbutton_bone_visibility_fn(bContext *C, void *poin, void *UNU
{
Bone *bone = (Bone *)poin;
- if (CTX_wm_window(C)->eventstate->shift) {
+ if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
restrictbutton_recursive_bone(bone, BONE_HIDDEN_P, (bone->flag & BONE_HIDDEN_P) != 0);
}
}
@@ -178,7 +178,7 @@ static void restrictbutton_bone_select_fn(bContext *C, void *UNUSED(poin), void
bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
}
- if (CTX_wm_window(C)->eventstate->shift) {
+ if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
restrictbutton_recursive_bone(bone, BONE_UNSELECTABLE, (bone->flag & BONE_UNSELECTABLE) != 0);
}
@@ -194,7 +194,7 @@ static void restrictbutton_ebone_select_fn(bContext *C, void *poin, void *poin2)
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
}
- if (CTX_wm_window(C)->eventstate->shift) {
+ if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
restrictbutton_recursive_ebone(
arm, ebone, BONE_UNSELECTABLE, (ebone->flag & BONE_UNSELECTABLE) != 0);
}
@@ -210,7 +210,7 @@ static void restrictbutton_ebone_visibility_fn(bContext *C, void *poin, void *po
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
}
- if (CTX_wm_window(C)->eventstate->shift) {
+ if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
restrictbutton_recursive_ebone(arm, ebone, BONE_HIDDEN_A, (ebone->flag & BONE_HIDDEN_A) != 0);
}
@@ -250,7 +250,7 @@ static void outliner_object_set_flag_recursive_fn(bContext *C,
ViewLayer *view_layer = CTX_data_view_layer(C);
PointerRNA ptr;
- bool extend = (win->eventstate->shift != 0);
+ bool extend = (win->eventstate->modifier & KM_SHIFT);
if (!extend) {
return;
@@ -571,8 +571,8 @@ static void outliner_collection_set_flag_recursive_fn(bContext *C,
ViewLayer *view_layer = CTX_data_view_layer(C);
PointerRNA ptr;
- bool do_isolate = (win->eventstate->ctrl != 0);
- bool extend = (win->eventstate->shift != 0);
+ bool do_isolate = (win->eventstate->modifier & KM_CTRL);
+ bool extend = (win->eventstate->modifier & KM_SHIFT);
if (!ELEM(true, do_isolate, extend)) {
return;
@@ -2043,7 +2043,7 @@ static void outliner_mode_toggle_fn(bContext *C, void *tselem_poin, void *UNUSED
const bool object_data_shared = (ob->data == tvc.obact->data);
wmWindow *win = CTX_wm_window(C);
- const bool do_extend = win->eventstate->ctrl != 0 && !object_data_shared;
+ const bool do_extend = (win->eventstate->modifier & KM_CTRL) && !object_data_shared;
outliner_item_mode_toggle(C, &tvc, te, do_extend);
}
@@ -2592,7 +2592,7 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
case OB_CAMERA:
data.icon = ICON_OUTLINER_OB_CAMERA;
break;
- case OB_CURVE:
+ case OB_CURVES_LEGACY:
data.icon = ICON_OUTLINER_OB_CURVE;
break;
case OB_MBALL:
@@ -2655,7 +2655,7 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
case ID_ME:
data.icon = ICON_OUTLINER_DATA_MESH;
break;
- case ID_CU:
+ case ID_CU_LEGACY:
data.icon = ICON_OUTLINER_DATA_CURVE;
break;
case ID_MB:
diff --git a/source/blender/editors/space_outliner/outliner_edit.cc b/source/blender/editors/space_outliner/outliner_edit.cc
index a6ac2a5a1f3..6916f5fe502 100644
--- a/source/blender/editors/space_outliner/outliner_edit.cc
+++ b/source/blender/editors/space_outliner/outliner_edit.cc
@@ -240,7 +240,7 @@ static int outliner_item_openclose_invoke(bContext *C, wmOperator *op, const wmE
outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region);
/* Only toggle once for single click toggling */
- if (event->type == LEFTMOUSE) {
+ if ((event->type == LEFTMOUSE) && (event->val != KM_CLICK_DRAG)) {
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_outliner/outliner_intern.hh b/source/blender/editors/space_outliner/outliner_intern.hh
index bba4bac0e37..0516758e887 100644
--- a/source/blender/editors/space_outliner/outliner_intern.hh
+++ b/source/blender/editors/space_outliner/outliner_intern.hh
@@ -108,7 +108,7 @@ typedef struct TreeElementIcon {
ID_LI, \
ID_OB, \
ID_ME, \
- ID_CU, \
+ ID_CU_LEGACY, \
ID_MB, \
ID_NT, \
ID_MA, \
diff --git a/source/blender/editors/space_outliner/outliner_select.cc b/source/blender/editors/space_outliner/outliner_select.cc
index df10ce002c3..c6b9d9577b5 100644
--- a/source/blender/editors/space_outliner/outliner_select.cc
+++ b/source/blender/editors/space_outliner/outliner_select.cc
@@ -1171,7 +1171,7 @@ static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreE
context = BCONTEXT_OBJECT;
break;
case ID_ME:
- case ID_CU:
+ case ID_CU_LEGACY:
case ID_MB:
case ID_IM:
case ID_LT:
diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc
index 18c37e08eff..8fcf967bce8 100644
--- a/source/blender/editors/space_outliner/outliner_tools.cc
+++ b/source/blender/editors/space_outliner/outliner_tools.cc
@@ -117,7 +117,7 @@ static void get_element_operation_type(
break;
case ID_ME:
- case ID_CU:
+ case ID_CU_LEGACY:
case ID_MB:
case ID_LT:
case ID_LA:
@@ -236,7 +236,7 @@ static void unlink_material_fn(bContext *UNUSED(C),
totcol = me->totcol;
matar = me->mat;
}
- else if (GS(tsep->id->name) == ID_CU) {
+ else if (GS(tsep->id->name) == ID_CU_LEGACY) {
Curve *cu = (Curve *)tsep->id;
totcol = cu->totcol;
matar = cu->mat;
@@ -766,29 +766,37 @@ static void id_override_library_create_fn(bContext *C,
void *user_data)
{
BLI_assert(TSE_IS_REAL_ID(tselem));
- ID *id_root = tselem->id;
+
+ /* We can only safely apply this operation on one item at a time, so only do it on the active
+ * one. */
+ if ((tselem->flag & TSE_ACTIVE) == 0) {
+ return;
+ }
+
+ ID *id_root_reference = tselem->id;
OutlinerLibOverrideData *data = reinterpret_cast<OutlinerLibOverrideData *>(user_data);
const bool do_hierarchy = data->do_hierarchy;
bool success = false;
- ID *id_reference = nullptr;
+ ID *id_instance_hint = nullptr;
bool is_override_instancing_object = false;
if (tsep != nullptr && tsep->type == TSE_SOME_ID && tsep->id != nullptr &&
GS(tsep->id->name) == ID_OB && !ID_IS_OVERRIDE_LIBRARY(tsep->id)) {
Object *ob = (Object *)tsep->id;
- if (ob->type == OB_EMPTY && &ob->instance_collection->id == id_root) {
- BLI_assert(GS(id_root->name) == ID_GR);
+ if (ob->type == OB_EMPTY && &ob->instance_collection->id == id_root_reference) {
+ BLI_assert(GS(id_root_reference->name) == ID_GR);
/* Empty instantiating the collection we override, we need to pass it to BKE overriding code
* for proper handling. */
- id_reference = tsep->id;
+ id_instance_hint = tsep->id;
is_override_instancing_object = true;
}
}
- if (ID_IS_OVERRIDABLE_LIBRARY(id_root) || (ID_IS_LINKED(id_root) && do_hierarchy)) {
+ if (ID_IS_OVERRIDABLE_LIBRARY(id_root_reference) ||
+ (ID_IS_LINKED(id_root_reference) && do_hierarchy)) {
Main *bmain = CTX_data_main(C);
- id_root->tag |= LIB_TAG_DOIT;
+ id_root_reference->tag |= LIB_TAG_DOIT;
/* For now, remap all local usages of linked ID to local override one here. */
ID *id_iter;
@@ -804,38 +812,100 @@ static void id_override_library_create_fn(bContext *C,
if (do_hierarchy) {
/* Tag all linked parents in tree hierarchy to be also overridden. */
+ ID *id_hierarchy_root_reference = id_root_reference;
while ((te = te->parent) != nullptr) {
if (!TSE_IS_REAL_ID(te->store_elem)) {
continue;
}
- if (!ID_IS_LINKED(te->store_elem->id)) {
+
+ /* Tentative hierarchy root. */
+ ID *id_current_hierarchy_root = te->store_elem->id;
+
+ /* If the parent ID is from a different library than the reference root one, we are done
+ * with upwards tree processing in any case. */
+ if (id_current_hierarchy_root->lib != id_root_reference->lib) {
+ if (ID_IS_OVERRIDE_LIBRARY_VIRTUAL(id_current_hierarchy_root)) {
+ /* Virtual overrides (i.e. embedded IDs), we can simply keep processing their parent to
+ * get an actual real override. */
+ continue;
+ }
+
+ /* If the parent ID is already an override, and is valid (i.e. local override), we can
+ * access its hierarchy root directly. */
+ if (!ID_IS_LINKED(id_current_hierarchy_root) &&
+ ID_IS_OVERRIDE_LIBRARY_REAL(id_current_hierarchy_root) &&
+ id_current_hierarchy_root->override_library->reference->lib ==
+ id_root_reference->lib) {
+ id_hierarchy_root_reference =
+ id_current_hierarchy_root->override_library->hierarchy_root;
+ BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root_reference));
+ break;
+ }
+
+ if (ID_IS_LINKED(id_current_hierarchy_root)) {
+ /* No local 'anchor' was found for the hierarchy to override, do not proceed, as this
+ * would most likely generate invisible/confusing/hard to use and manage overrides. */
+ BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Invalid anchor ('%s') found, needed to create library override from "
+ "data-block '%s'",
+ id_current_hierarchy_root->name,
+ id_root_reference->name);
+ return;
+ }
+
+ /* In all other cases, `id_current_hierarchy_root` cannot be a valid hierarchy root, so
+ * current `id_hierarchy_root_reference` is our best candidate. */
+
break;
}
+
/* If some element in the tree needs to be overridden, but its ID is not overridable,
* abort. */
- if (!ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(te->store_elem->id)) {
+ if (!ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(id_current_hierarchy_root)) {
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
BKE_reportf(reports,
RPT_WARNING,
"Could not create library override from data-block '%s', one of its parents "
"is not overridable ('%s')",
- id_root->name,
- te->store_elem->id->name);
+ id_root_reference->name,
+ id_current_hierarchy_root->name);
return;
}
- te->store_elem->id->tag |= LIB_TAG_DOIT;
+ id_current_hierarchy_root->tag |= LIB_TAG_DOIT;
+ id_hierarchy_root_reference = id_current_hierarchy_root;
+ }
+
+ /* That case can happen when linked data is a complex mix involving several libraries and/or
+ * linked overrides. E.g. a mix of overrides from one library, and indirectly linked data
+ * from another library. Do not try to support such cases for now. */
+ if (!((id_hierarchy_root_reference->lib == id_root_reference->lib) ||
+ (!ID_IS_LINKED(id_hierarchy_root_reference) &&
+ ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root_reference) &&
+ id_hierarchy_root_reference->override_library->reference->lib ==
+ id_root_reference->lib))) {
+ BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Invalid hierarchy root ('%s') found, needed to create library override from "
+ "data-block '%s'",
+ id_hierarchy_root_reference->name,
+ id_root_reference->name);
+ return;
}
success = BKE_lib_override_library_create(bmain,
CTX_data_scene(C),
CTX_data_view_layer(C),
nullptr,
- id_root,
- id_reference,
+ id_root_reference,
+ id_hierarchy_root_reference,
+ id_instance_hint,
nullptr);
}
- else if (ID_IS_OVERRIDABLE_LIBRARY(id_root)) {
- success = BKE_lib_override_library_create_from_id(bmain, id_root, true) != nullptr;
+ else if (ID_IS_OVERRIDABLE_LIBRARY(id_root_reference)) {
+ success = BKE_lib_override_library_create_from_id(bmain, id_root_reference, true) != nullptr;
/* Cleanup. */
BKE_main_id_newptr_and_tag_clear(bmain);
@@ -845,14 +915,14 @@ static void id_override_library_create_fn(bContext *C,
/* Remove the instance empty from this scene, the items now have an overridden collection
* instead. */
if (success && is_override_instancing_object) {
- ED_object_base_free_and_unlink(bmain, scene, (Object *)id_reference);
+ ED_object_base_free_and_unlink(bmain, scene, (Object *)id_instance_hint);
}
}
if (!success) {
BKE_reportf(reports,
RPT_WARNING,
"Could not create library override from data-block '%s'",
- id_root->name);
+ id_root_reference->name);
}
}
@@ -1770,13 +1840,15 @@ static const EnumPropertyItem prop_id_op_types[] = {
{OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE,
"OVERRIDE_LIBRARY_CREATE",
0,
- "Make Library Override",
- "Make a local override of this linked data-block"},
+ "Make Library Override Single",
+ "Make a single, out-of-hierarchy local override of this linked data-block - only applies to "
+ "active Outliner item"},
{OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY,
"OVERRIDE_LIBRARY_CREATE_HIERARCHY",
0,
"Make Library Override Hierarchy",
- "Make a local override of this linked data-block, and its hierarchy of dependencies"},
+ "Make a local override of this linked data-block, and its hierarchy of dependencies - only "
+ "applies to active Outliner item"},
{OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET,
"OVERRIDE_LIBRARY_RESET",
0,
diff --git a/source/blender/editors/space_outliner/outliner_tree.cc b/source/blender/editors/space_outliner/outliner_tree.cc
index 1605d5874ae..06a5918f25c 100644
--- a/source/blender/editors/space_outliner/outliner_tree.cc
+++ b/source/blender/editors/space_outliner/outliner_tree.cc
@@ -579,7 +579,7 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
* would require going over all tfaces, sort images in use. etc... */
break;
}
- case ID_CU: {
+ case ID_CU_LEGACY: {
Curve *cu = (Curve *)id;
if (outliner_animdata_test(cu->adt)) {
diff --git a/source/blender/editors/space_outliner/tree/tree_display.cc b/source/blender/editors/space_outliner/tree/tree_display.cc
index 6b68f1ee4a4..f9141dffd6a 100644
--- a/source/blender/editors/space_outliner/tree/tree_display.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display.cc
@@ -7,6 +7,8 @@
#include "DNA_listBase.h"
#include "DNA_space_types.h"
+#include "BLI_utildefines.h"
+
#include "tree_display.hh"
using namespace blender::ed::outliner;
@@ -30,11 +32,11 @@ std::unique_ptr<AbstractTreeDisplay> AbstractTreeDisplay::createFromDisplayMode(
case SO_OVERRIDES_LIBRARY:
return std::make_unique<TreeDisplayOverrideLibrary>(space_outliner);
case SO_VIEW_LAYER:
- /* FIXME(Julian): this should not be the default! Return nullptr and handle that as valid
- * case. */
- default:
return std::make_unique<TreeDisplayViewLayer>(space_outliner);
}
+
+ BLI_assert_unreachable();
+ return nullptr;
}
bool AbstractTreeDisplay::hasWarnings() const
diff --git a/source/blender/editors/space_outliner/tree/tree_display_override_library.cc b/source/blender/editors/space_outliner/tree/tree_display_override_library.cc
index 43d67ee106d..f94727ba356 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_override_library.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_override_library.cc
@@ -23,11 +23,6 @@
namespace blender::ed::outliner {
/* Convenience/readability. */
-/* Convenience/readability. */
-/* Convenience/readability. */
-/* Convenience/readability. */
-/* Convenience/readability. */
-/* Convenience/readability. */
template<typename T> using List = ListBaseWrapper<T>;
TreeDisplayOverrideLibrary::TreeDisplayOverrideLibrary(SpaceOutliner &space_outliner)
diff --git a/source/blender/editors/space_outliner/tree/tree_element.hh b/source/blender/editors/space_outliner/tree/tree_element.hh
index 996f51eee82..2fbc86705b9 100644
--- a/source/blender/editors/space_outliner/tree/tree_element.hh
+++ b/source/blender/editors/space_outliner/tree/tree_element.hh
@@ -89,8 +89,8 @@ void tree_element_expand(const AbstractTreeElement &tree_element, SpaceOutliner
/**
* Get actual warning data of a tree element, if any.
*
- * \param r_icon The icon to display as warning.
- * \param r_message The message to display as warning.
+ * \param r_icon: The icon to display as warning.
+ * \param r_message: The message to display as warning.
* \return true if there is a warning, false otherwise.
*/
bool tree_element_warnings_get(struct TreeElement *te, int *r_icon, const char **r_message);
diff --git a/source/blender/editors/space_outliner/tree/tree_element_id.cc b/source/blender/editors/space_outliner/tree/tree_element_id.cc
index e126b024d52..64c73f57107 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_id.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element_id.cc
@@ -34,7 +34,7 @@ std::unique_ptr<TreeElementID> TreeElementID::createFromID(TreeElement &legacy_t
return std::make_unique<TreeElementIDScene>(legacy_te, (Scene &)id);
case ID_OB:
case ID_ME:
- case ID_CU:
+ case ID_CU_LEGACY:
case ID_MB:
case ID_MA:
case ID_TE:
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 8c12193fb88..5ac4363e63d 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -1636,7 +1636,9 @@ static void sequencer_draw_gpencil_overlay(const bContext *C)
ED_annotation_draw_view2d(C, 0);
}
-/* Draw content and safety borders borders. */
+/**
+ * Draw content and safety borders.
+ */
static void sequencer_draw_borders_overlay(const SpaceSeq *sseq,
const View2D *v2d,
const Scene *scene)
@@ -1926,7 +1928,6 @@ static void sequencer_draw_display_buffer(const bContext *C,
if (!glsl_used) {
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
immUniformColor3f(1.0f, 1.0f, 1.0f);
- immUniform1i("image", 0);
}
immBegin(GPU_PRIM_TRI_FAN, 4);
diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
index 3be890bfcc5..fbdc451cf06 100644
--- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
+++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
@@ -264,7 +264,7 @@ Object *spreadsheet_get_object_eval(const SpaceSpreadsheet *sspreadsheet,
return nullptr;
}
Object *object_orig = (Object *)used_id;
- if (!ELEM(object_orig->type, OB_MESH, OB_POINTCLOUD, OB_VOLUME, OB_CURVE, OB_FONT)) {
+ if (!ELEM(object_orig->type, OB_MESH, OB_POINTCLOUD, OB_VOLUME, OB_CURVES_LEGACY, OB_FONT)) {
return nullptr;
}
diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c
index 496f500ef04..55873740491 100644
--- a/source/blender/editors/space_text/text_autocomplete.c
+++ b/source/blender/editors/space_text/text_autocomplete.c
@@ -408,7 +408,7 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e
case EVT_BACKSPACEKEY:
if (event->val == KM_PRESS) {
if (tools & TOOL_SUGG_LIST) {
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
texttool_suggest_clear();
retval = OPERATOR_CANCELLED;
draw = 1;
@@ -445,7 +445,7 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e
case EVT_RIGHTARROWKEY:
if (event->val == KM_PRESS) {
if (tools & TOOL_SUGG_LIST) {
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
texttool_suggest_clear();
retval = OPERATOR_CANCELLED;
draw = 1;
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index ddba6803f61..3c29b32c2fa 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -3495,7 +3495,7 @@ static int text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
* (when input method are used for utf8 inputs, the user may assign key event
* including alt/ctrl/super like ctrl+m to commit utf8 string. in such case,
* the modifiers in the utf8 character event make no sense.) */
- if ((event->ctrl || event->oskey) && !event->utf8_buf[0]) {
+ if ((event->modifier & (KM_CTRL | KM_OSKEY)) && !event->utf8_buf[0]) {
return OPERATOR_PASS_THROUGH;
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 7addda0f8c3..4656540c19b 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -413,6 +413,9 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *region)
keymap = WM_keymap_ensure(wm->defaultconf, "Particle", 0, 0);
WM_event_add_keymap_handler(&region->handlers, keymap);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Sculpt Curves", 0, 0);
+ WM_event_add_keymap_handler(&region->handlers, keymap);
+
/* editfont keymap swallows all... */
keymap = WM_keymap_ensure(wm->defaultconf, "Font", 0, 0);
WM_event_add_keymap_handler(&region->handlers, keymap);
@@ -1475,6 +1478,9 @@ void ED_view3d_buttons_region_layout_ex(const bContext *C,
case CTX_MODE_EDIT_CURVE:
ARRAY_SET_ITEMS(contexts, ".curve_edit");
break;
+ case CTX_MODE_EDIT_CURVES:
+ ARRAY_SET_ITEMS(contexts, ".curves_edit");
+ break;
case CTX_MODE_EDIT_SURFACE:
ARRAY_SET_ITEMS(contexts, ".curve_edit");
break;
@@ -1523,6 +1529,9 @@ void ED_view3d_buttons_region_layout_ex(const bContext *C,
case CTX_MODE_VERTEX_GPENCIL:
ARRAY_SET_ITEMS(contexts, ".greasepencil_vertex");
break;
+ case CTX_MODE_SCULPT_CURVES:
+ ARRAY_SET_ITEMS(contexts, ".curves_sculpt");
+ break;
default:
break;
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index b77994e28cb..cf52134f5ab 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -355,7 +355,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
has_meshdata = (tot || totedgedata);
}
- else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
TransformMedian_Curve *median = &median_basis.curve;
Curve *cu = ob->data;
BPoint *bp;
@@ -1089,7 +1089,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
}
}
- else if (ELEM(ob->type, OB_CURVE, OB_SURF) &&
+ else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF) &&
(apply_vcos || median_basis.curve.b_weight || median_basis.curve.weight ||
median_basis.curve.radius || median_basis.curve.tilt)) {
const TransformMedian_Curve *median = &median_basis.curve,
diff --git a/source/blender/editors/space_view3d/view3d_cursor_snap.c b/source/blender/editors/space_view3d/view3d_cursor_snap.c
index 785c5ab28c8..53f7b3d5871 100644
--- a/source/blender/editors/space_view3d/view3d_cursor_snap.c
+++ b/source/blender/editors/space_view3d/view3d_cursor_snap.c
@@ -63,7 +63,7 @@ typedef struct SnapCursorDataIntern {
int x;
int y;
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
- short shift, ctrl, alt, oskey;
+ uint8_t modifier;
#endif
} last_eventstate;
@@ -478,10 +478,7 @@ static bool v3d_cursor_eventstate_has_changed(SnapCursorDataIntern *data_intern,
}
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
if (!(state && (state->flag & V3D_SNAPCURSOR_TOGGLE_ALWAYS_TRUE))) {
- if ((event->ctrl != data_intern->last_eventstate.ctrl) ||
- (event->shift != data_intern->last_eventstate.shift) ||
- (event->alt != data_intern->last_eventstate.alt) ||
- (event->oskey != data_intern->last_eventstate.oskey)) {
+ if (event->modifier != data_intern->last_eventstate.modifier) {
return true;
}
}
@@ -507,19 +504,13 @@ static bool v3d_cursor_is_snap_invert(SnapCursorDataIntern *data_intern, const w
}
const wmEvent *event = wm->winactive->eventstate;
- if ((event->ctrl == data_intern->last_eventstate.ctrl) &&
- (event->shift == data_intern->last_eventstate.shift) &&
- (event->alt == data_intern->last_eventstate.alt) &&
- (event->oskey == data_intern->last_eventstate.oskey)) {
+ if (event->modifier == data_intern->last_eventstate.modifier) {
/* Nothing has changed. */
return data_intern->snap_data.is_snap_invert;
}
/* Save new eventstate. */
- data_intern->last_eventstate.ctrl = event->ctrl;
- data_intern->last_eventstate.shift = event->shift;
- data_intern->last_eventstate.alt = event->alt;
- data_intern->last_eventstate.oskey = event->oskey;
+ data_intern->last_eventstate.modifier = event->modifier;
const int snap_on = data_intern->snap_on;
@@ -530,10 +521,10 @@ static bool v3d_cursor_is_snap_invert(SnapCursorDataIntern *data_intern, const w
}
if (kmi->propvalue == snap_on) {
- if ((ELEM(kmi->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY) && event->ctrl) ||
- (ELEM(kmi->type, EVT_LEFTSHIFTKEY, EVT_RIGHTSHIFTKEY) && event->shift) ||
- (ELEM(kmi->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY) && event->alt) ||
- ((kmi->type == EVT_OSKEY) && event->oskey)) {
+ if ((ELEM(kmi->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY) && (event->modifier & KM_CTRL)) ||
+ (ELEM(kmi->type, EVT_LEFTSHIFTKEY, EVT_RIGHTSHIFTKEY) && (event->modifier & KM_SHIFT)) ||
+ (ELEM(kmi->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY) && (event->modifier & KM_ALT)) ||
+ ((kmi->type == EVT_OSKEY) && (event->modifier & KM_OSKEY))) {
return true;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index c4078c4a690..593c4f6e755 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1351,7 +1351,7 @@ static void draw_selected_name(
}
}
}
- else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) {
+ else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVES_LEGACY)) {
/* try to display active bone and active shapekey too (if they exist) */
if (ob->type == OB_MESH && ob->mode & OB_MODE_WEIGHT_PAINT) {
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index d6bc7ded92e..5adce170e06 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -832,13 +832,13 @@ void ED_view3d_cursor3d_position(bContext *C,
return;
}
- ED_view3d_calc_zfac(rv3d, cursor_co, &flip);
+ ED_view3d_calc_zfac_ex(rv3d, cursor_co, &flip);
/* Reset the depth based on the view offset (we _know_ the offset is in front of us). */
if (flip) {
negate_v3_v3(cursor_co, rv3d->ofs);
/* re initialize, no need to check flip again */
- ED_view3d_calc_zfac(rv3d, cursor_co, NULL /* &flip */);
+ ED_view3d_calc_zfac(rv3d, cursor_co);
}
if (use_depth) { /* maybe this should be accessed some other way */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
index 6cc197c8a43..a0c010a6813 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
@@ -105,8 +105,8 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int
MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
/* Hack: Switch action mode based on key input */
- const bool is_ctrl_pressed = WM_event_modifier_flag(event) & KM_CTRL;
- const bool is_shift_pressed = WM_event_modifier_flag(event) & KM_SHIFT;
+ const bool is_ctrl_pressed = (event->modifier & KM_CTRL) != 0;
+ const bool is_shift_pressed = (event->modifier & KM_SHIFT) != 0;
EDBM_preselect_action_set(gz_ele->psel, PRESELECT_ACTION_TRANSFORM);
if (is_ctrl_pressed && !is_shift_pressed) {
EDBM_preselect_action_set(gz_ele->psel, PRESELECT_ACTION_CREATE);
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index e1fd96ca1d4..055aac041f1 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -25,6 +25,7 @@
#include "BKE_editmesh.h"
#include "BKE_mesh_iterators.h"
#include "BKE_mesh_runtime.h"
+#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
#include "DEG_depsgraph.h"
@@ -334,6 +335,7 @@ void mesh_foreachScreenVert(
Mesh *me = editbmesh_get_eval_cage_from_orig(
vc->depsgraph, vc->scene, vc->obedit, &CD_MASK_BAREMESH);
+ me = BKE_mesh_wrapper_ensure_subdivision(vc->obedit, me);
ED_view3d_check_mats_rv3d(vc->rv3d);
@@ -396,6 +398,7 @@ void mesh_foreachScreenEdge(ViewContext *vc,
Mesh *me = editbmesh_get_eval_cage_from_orig(
vc->depsgraph, vc->scene, vc->obedit, &CD_MASK_BAREMESH);
+ me = BKE_mesh_wrapper_ensure_subdivision(vc->obedit, me);
ED_view3d_check_mats_rv3d(vc->rv3d);
@@ -483,6 +486,7 @@ void mesh_foreachScreenEdge_clip_bb_segment(ViewContext *vc,
Mesh *me = editbmesh_get_eval_cage_from_orig(
vc->depsgraph, vc->scene, vc->obedit, &CD_MASK_BAREMESH);
+ me = BKE_mesh_wrapper_ensure_subdivision(vc->obedit, me);
ED_view3d_check_mats_rv3d(vc->rv3d);
@@ -554,6 +558,7 @@ void mesh_foreachScreenFace(
Mesh *me = editbmesh_get_eval_cage_from_orig(
vc->depsgraph, vc->scene, vc->obedit, &CD_MASK_BAREMESH);
+ me = BKE_mesh_wrapper_ensure_subdivision(vc->obedit, me);
ED_view3d_check_mats_rv3d(vc->rv3d);
data.vc = *vc;
diff --git a/source/blender/editors/space_view3d/view3d_navigate.c b/source/blender/editors/space_view3d/view3d_navigate.c
index 0305989d142..d1e7f6ffb12 100644
--- a/source/blender/editors/space_view3d/view3d_navigate.c
+++ b/source/blender/editors/space_view3d/view3d_navigate.c
@@ -396,7 +396,7 @@ ViewOpsData *viewops_data_create(bContext *C, const wmEvent *event, enum eViewOp
{
float tvec[3];
negate_v3_v3(tvec, rv3d->ofs);
- vod->init.zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL);
+ vod->init.zfac = ED_view3d_calc_zfac(rv3d, tvec);
}
vod->reverse = 1.0f;
@@ -544,26 +544,24 @@ static void axis_set_view(bContext *C,
void viewmove_apply(ViewOpsData *vod, int x, int y)
{
- if (ED_view3d_offset_lock_check(vod->v3d, vod->rv3d)) {
- vod->rv3d->ofs_lock[0] -= ((vod->prev.event_xy[0] - x) * 2.0f) / (float)vod->region->winx;
- vod->rv3d->ofs_lock[1] -= ((vod->prev.event_xy[1] - y) * 2.0f) / (float)vod->region->winy;
+ const float event_ofs[2] = {
+ vod->prev.event_xy[0] - x,
+ vod->prev.event_xy[1] - y,
+ };
+
+ if ((vod->rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) {
+ ED_view3d_camera_view_pan(vod->region, event_ofs);
}
- else if ((vod->rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) {
- const float zoomfac = BKE_screen_view3d_zoom_to_fac(vod->rv3d->camzoom) * 2.0f;
- vod->rv3d->camdx += (vod->prev.event_xy[0] - x) / (vod->region->winx * zoomfac);
- vod->rv3d->camdy += (vod->prev.event_xy[1] - y) / (vod->region->winy * zoomfac);
- CLAMP(vod->rv3d->camdx, -1.0f, 1.0f);
- CLAMP(vod->rv3d->camdy, -1.0f, 1.0f);
+ else if (ED_view3d_offset_lock_check(vod->v3d, vod->rv3d)) {
+ vod->rv3d->ofs_lock[0] -= (event_ofs[0] * 2.0f) / (float)vod->region->winx;
+ vod->rv3d->ofs_lock[1] -= (event_ofs[1] * 2.0f) / (float)vod->region->winy;
}
else {
float dvec[3];
- float mval_f[2];
- mval_f[0] = x - vod->prev.event_xy[0];
- mval_f[1] = y - vod->prev.event_xy[1];
- ED_view3d_win_to_delta(vod->region, mval_f, dvec, vod->init.zfac);
+ ED_view3d_win_to_delta(vod->region, event_ofs, vod->init.zfac, dvec);
- add_v3_v3(vod->rv3d->ofs, dvec);
+ sub_v3_v3(vod->rv3d->ofs, dvec);
if (RV3D_LOCK_FLAGS(vod->rv3d) & RV3D_BOXVIEW) {
view3d_boxview_sync(vod->area, vod->region);
diff --git a/source/blender/editors/space_view3d/view3d_navigate_dolly.c b/source/blender/editors/space_view3d/view3d_navigate_dolly.c
index 06b616e71da..7b6b119294d 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_dolly.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_dolly.c
@@ -50,9 +50,12 @@ void viewdolly_modal_keymap(wmKeyConfig *keyconf)
/* disabled mode switching for now, can re-implement better, later on */
#if 0
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
- WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
- WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
+ WM_modalkeymap_add_item(
+ keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, KM_ANY, VIEWROT_MODAL_SWITCH_ROTATE);
+ WM_modalkeymap_add_item(
+ keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, KM_ANY, VIEWROT_MODAL_SWITCH_ROTATE);
+ WM_modalkeymap_add_item(
+ keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, KM_ANY, VIEWROT_MODAL_SWITCH_MOVE);
#endif
/* assign map to operators */
diff --git a/source/blender/editors/space_view3d/view3d_navigate_move.c b/source/blender/editors/space_view3d/view3d_navigate_move.c
index d2fd505a703..071643e9314 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_move.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_move.c
@@ -43,8 +43,8 @@ void viewmove_modal_keymap(wmKeyConfig *keyconf)
keymap = WM_modalkeymap_ensure(keyconf, "View3D Move Modal", modal_items);
/* items for modal map */
- WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
- WM_modalkeymap_add_item(keymap, EVT_ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, KM_ANY, VIEW_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, EVT_ESCKEY, KM_PRESS, KM_ANY, 0, KM_ANY, VIEW_MODAL_CONFIRM);
/* disabled mode switching for now, can re-implement better, later on */
#if 0
diff --git a/source/blender/editors/space_view3d/view3d_navigate_ndof.c b/source/blender/editors/space_view3d/view3d_navigate_ndof.c
index ced8eca710b..1ce9bdcb211 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_ndof.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_ndof.c
@@ -48,7 +48,7 @@ static float view3d_ndof_pan_speed_calc_ex(RegionView3D *rv3d, const float depth
float speed = rv3d->pixsize * NDOF_PIXELS_PER_SECOND;
if (rv3d->is_persp) {
- speed *= ED_view3d_calc_zfac(rv3d, depth_pt, NULL);
+ speed *= ED_view3d_calc_zfac(rv3d, depth_pt);
}
return speed;
@@ -347,6 +347,70 @@ void view3d_ndof_fly(const wmNDOFMotionData *ndof,
/** \} */
/* -------------------------------------------------------------------- */
+/** \name NDOF Camera View Support
+ * \{ */
+
+/**
+ * 2D orthographic style NDOF navigation within the camera view.
+ * Support navigating the camera view instead of leaving the camera-view and navigating in 3D.
+ */
+static int view3d_ndof_cameraview_pan_zoom(bContext *C, const wmEvent *event)
+{
+ const wmNDOFMotionData *ndof = event->customdata;
+ View3D *v3d = CTX_wm_view3d(C);
+ ARegion *region = CTX_wm_region(C);
+ RegionView3D *rv3d = region->regiondata;
+
+ ED_view3d_smooth_view_force_finish(C, v3d, region);
+
+ if ((v3d->camera && (rv3d->persp == RV3D_CAMOB) && (v3d->flag2 & V3D_LOCK_CAMERA) == 0)) {
+ /* pass */
+ }
+ else {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ const bool has_translate = !is_zero_v2(ndof->tvec);
+ const bool has_zoom = ndof->tvec[2] != 0.0f;
+
+ /* NOTE(@campbellbarton): In principle rotating could pass through to regular
+ * non-camera NDOF behavior (exiting the camera-view and rotating).
+ * Disabled this block since in practice it's difficult to control NDOF devices
+ * to perform some rotation with absolutely no translation. Causing rotation to
+ * randomly exit from the user perspective. Adjusting the dead-zone could avoid
+ * the motion feeling *glitchy* although in my own tests even then it didn't work reliably.
+ * Leave rotating out of camera-view disabled unless it can be made to work reliably. */
+ if (!(has_translate || has_zoom)) {
+ // return OPERATOR_PASS_THROUGH;
+ }
+
+ bool changed = false;
+
+ if (has_translate) {
+ const float speed = ndof->dt * NDOF_PIXELS_PER_SECOND;
+ float event_ofs[2] = {ndof->tvec[0] * speed, ndof->tvec[1] * speed};
+ if (ED_view3d_camera_view_pan(region, event_ofs)) {
+ changed = true;
+ }
+ }
+
+ if (has_zoom) {
+ const float scale = 1.0f + (ndof->dt * ndof->tvec[2]);
+ if (ED_view3d_camera_view_zoom_scale(rv3d, scale)) {
+ changed = true;
+ }
+ }
+
+ if (changed) {
+ ED_region_tag_redraw(region);
+ return OPERATOR_FINISHED;
+ }
+ return OPERATOR_CANCELLED;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name NDOF Orbit/Translate Operator
* \{ */
@@ -436,6 +500,13 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
return OPERATOR_CANCELLED;
}
+ if (U.ndof_flag & NDOF_CAMERA_PAN_ZOOM) {
+ const int camera_retval = view3d_ndof_cameraview_pan_zoom(C, event);
+ if (camera_retval != OPERATOR_PASS_THROUGH) {
+ return camera_retval;
+ }
+ }
+
const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ViewOpsData *vod;
View3D *v3d;
@@ -550,6 +621,13 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *e
return OPERATOR_CANCELLED;
}
+ if (U.ndof_flag & NDOF_CAMERA_PAN_ZOOM) {
+ const int camera_retval = view3d_ndof_cameraview_pan_zoom(C, event);
+ if (camera_retval != OPERATOR_PASS_THROUGH) {
+ return camera_retval;
+ }
+ }
+
const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
diff --git a/source/blender/editors/space_view3d/view3d_navigate_roll.c b/source/blender/editors/space_view3d/view3d_navigate_roll.c
index 56bd9c93216..9c070fb0341 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_roll.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_roll.c
@@ -24,8 +24,17 @@
/** \name View Roll Operator
* \{ */
-static void view_roll_angle(
- ARegion *region, float quat[4], const float orig_quat[4], const float dvec[3], float angle)
+/**
+ * \param use_axis_view: When true, keep axis-aligned orthographic views
+ * (when rotating in 90 degree increments). While this may seem obscure some NDOF
+ * devices have key shortcuts to do this (see #NDOF_BUTTON_ROLL_CW & #NDOF_BUTTON_ROLL_CCW).
+ */
+static void view_roll_angle(ARegion *region,
+ float quat[4],
+ const float orig_quat[4],
+ const float dvec[3],
+ float angle,
+ bool use_axis_view)
{
RegionView3D *rv3d = region->regiondata;
float quat_mul[4];
@@ -38,7 +47,16 @@ static void view_roll_angle(
/* avoid precision loss over time */
normalize_qt(quat);
- rv3d->view = RV3D_VIEW_USER;
+ if (use_axis_view && RV3D_VIEW_IS_AXIS(rv3d->view) && (fabsf(angle) == (float)M_PI_2)) {
+ if (ED_view3d_quat_to_axis_view(quat, 0.01f, &rv3d->view, &rv3d->view_axis_roll)) {
+ if (rv3d->view != RV3D_VIEW_USER) {
+ ED_view3d_quat_from_axis_view(rv3d->view, rv3d->view_axis_roll, quat_mul);
+ }
+ }
+ }
+ else {
+ rv3d->view = RV3D_VIEW_USER;
+ }
}
static void viewroll_apply(ViewOpsData *vod, int x, int y)
@@ -46,7 +64,8 @@ static void viewroll_apply(ViewOpsData *vod, int x, int y)
float angle = BLI_dial_angle(vod->init.dial, (const float[2]){x, y});
if (angle != 0.0f) {
- view_roll_angle(vod->region, vod->rv3d->viewquat, vod->init.quat, vod->init.mousevec, angle);
+ view_roll_angle(
+ vod->region, vod->rv3d->viewquat, vod->init.quat, vod->init.mousevec, angle, false);
}
if (vod->use_dyn_ofs) {
@@ -169,7 +188,7 @@ static int viewroll_exec(bContext *C, wmOperator *op)
normalize_v3_v3(mousevec, rv3d->viewinv[2]);
negate_v3(mousevec);
- view_roll_angle(region, quat_new, rv3d->viewquat, mousevec, angle);
+ view_roll_angle(region, quat_new, rv3d->viewquat, mousevec, angle, true);
const float *dyn_ofs_pt = NULL;
float dyn_ofs[3];
diff --git a/source/blender/editors/space_view3d/view3d_navigate_rotate.c b/source/blender/editors/space_view3d/view3d_navigate_rotate.c
index 774a8983c67..11de5463cdb 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_rotate.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_rotate.c
@@ -383,7 +383,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int event_xy[2];
if (event->type == MOUSEPAN) {
- if (event->is_direction_inverted) {
+ if (event->flag & WM_EVENT_SCROLL_INVERT) {
event_xy[0] = 2 * event->xy[0] - event->prev_xy[0];
event_xy[1] = 2 * event->xy[1] - event->prev_xy[1];
}
diff --git a/source/blender/editors/space_view3d/view3d_navigate_zoom.c b/source/blender/editors/space_view3d/view3d_navigate_zoom.c
index 8eb8fffaa31..5f6f9fde324 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_zoom.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_zoom.c
@@ -125,18 +125,18 @@ static void view_zoom_to_window_xy_3d(ARegion *region, float dfac, const int zoo
float dvec[3];
float tvec[3];
float tpos[3];
- float mval_f[2];
+ float xy_delta[2];
float zfac;
negate_v3_v3(tpos, rv3d->ofs);
- mval_f[0] = (float)(((zoom_xy[0] - region->winrct.xmin) * 2) - region->winx) / 2.0f;
- mval_f[1] = (float)(((zoom_xy[1] - region->winrct.ymin) * 2) - region->winy) / 2.0f;
+ xy_delta[0] = (float)(((zoom_xy[0] - region->winrct.xmin) * 2) - region->winx) / 2.0f;
+ xy_delta[1] = (float)(((zoom_xy[1] - region->winrct.ymin) * 2) - region->winy) / 2.0f;
/* Project cursor position into 3D space */
- zfac = ED_view3d_calc_zfac(rv3d, tpos, NULL);
- ED_view3d_win_to_delta(region, mval_f, dvec, zfac);
+ zfac = ED_view3d_calc_zfac(rv3d, tpos);
+ ED_view3d_win_to_delta(region, xy_delta, zfac, dvec);
/* Calculate view target position for dolly */
add_v3_v3v3(tvec, tpos, dvec);
diff --git a/source/blender/editors/space_view3d/view3d_navigate_zoom_border.c b/source/blender/editors/space_view3d/view3d_navigate_zoom_border.c
index 4e909151ce4..f834efe4a7b 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_zoom_border.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_zoom_border.c
@@ -125,7 +125,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
negate_v3_v3(new_ofs, p);
}
else {
- float mval_f[2];
+ float xy_delta[2];
float zfac;
/* We can't use the depth, fallback to the old way that doesn't set the center depth */
@@ -134,12 +134,12 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
{
float tvec[3];
negate_v3_v3(tvec, new_ofs);
- zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL);
+ zfac = ED_view3d_calc_zfac(rv3d, tvec);
}
- mval_f[0] = (rect.xmin + rect.xmax - vb[0]) / 2.0f;
- mval_f[1] = (rect.ymin + rect.ymax - vb[1]) / 2.0f;
- ED_view3d_win_to_delta(region, mval_f, dvec, zfac);
+ xy_delta[0] = (rect.xmin + rect.xmax - vb[0]) / 2.0f;
+ xy_delta[1] = (rect.ymin + rect.ymax - vb[1]) / 2.0f;
+ ED_view3d_win_to_delta(region, xy_delta, zfac, dvec);
/* center the view to the center of the rectangle */
sub_v3_v3(new_ofs, dvec);
}
diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c
index 06b848571d8..98fb914cda9 100644
--- a/source/blender/editors/space_view3d/view3d_placement.c
+++ b/source/blender/editors/space_view3d/view3d_placement.c
@@ -727,6 +727,17 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
V3DSnapCursorState *snap_state_new = ED_view3d_cursor_snap_active();
if (snap_state_new) {
ipd->snap_state = snap_state = snap_state_new;
+
+ /* For drag events, update the location since it will be set from the drag-start.
+ * This is needed as cursor-drawing doesn't deal with drag events and will use
+ * the current cursor location instead of the drag-start. */
+ if (event->val == KM_CLICK_DRAG) {
+ /* Set this flag so snapping always updated. */
+ int flag_orig = snap_state_new->flag;
+ snap_state_new->flag |= V3D_SNAPCURSOR_TOGGLE_ALWAYS_TRUE;
+ ED_view3d_cursor_snap_data_get(snap_state_new, C, event->mval[0], event->mval[1]);
+ snap_state_new->flag = flag_orig;
+ }
}
snap_state->draw_point = true;
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index 2cf9ac0a52e..85d239507ce 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -276,7 +276,7 @@ float ED_view3d_pixel_size_no_ui_scale(const RegionView3D *rv3d, const float co[
return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize;
}
-float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_flip)
+float ED_view3d_calc_zfac_ex(const RegionView3D *rv3d, const float co[3], bool *r_flip)
{
float zfac = mul_project_m4_v3_zfac(rv3d->persmat, co);
@@ -299,10 +299,15 @@ float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_f
return zfac;
}
+float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3])
+{
+ return ED_view3d_calc_zfac_ex(rv3d, co, NULL);
+}
+
float ED_view3d_calc_depth_for_comparison(const RegionView3D *rv3d, const float co[3])
{
if (rv3d->is_persp) {
- return ED_view3d_calc_zfac(rv3d, co, NULL);
+ return ED_view3d_calc_zfac(rv3d, co);
}
return -dot_v3v3(rv3d->viewinv[2], co);
}
@@ -436,8 +441,8 @@ bool view3d_get_view_aligned_coordinate(ARegion *region,
if (ret == V3D_PROJ_RET_OK) {
const float mval_f[2] = {(float)(mval_cpy[0] - mval[0]), (float)(mval_cpy[1] - mval[1])};
- const float zfac = ED_view3d_calc_zfac(rv3d, fp, NULL);
- ED_view3d_win_to_delta(region, mval_f, dvec, zfac);
+ const float zfac = ED_view3d_calc_zfac(rv3d, fp);
+ ED_view3d_win_to_delta(region, mval_f, zfac, dvec);
sub_v3_v3(fp, dvec);
return true;
@@ -584,57 +589,57 @@ bool ED_view3d_win_to_3d_on_plane_with_fallback(const ARegion *region,
}
void ED_view3d_win_to_delta(const ARegion *region,
- const float mval[2],
- float out[3],
- const float zfac)
+ const float xy_delta[2],
+ const float zfac,
+ float r_out[3])
{
RegionView3D *rv3d = region->regiondata;
float dx, dy;
- dx = 2.0f * mval[0] * zfac / region->winx;
- dy = 2.0f * mval[1] * zfac / region->winy;
+ dx = 2.0f * xy_delta[0] * zfac / region->winx;
+ dy = 2.0f * xy_delta[1] * zfac / region->winy;
- out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy);
- out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy);
- out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy);
+ r_out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy);
+ r_out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy);
+ r_out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy);
}
-void ED_view3d_win_to_origin(const ARegion *region, const float mval[2], float out[3])
+void ED_view3d_win_to_origin(const ARegion *region, const float mval[2], float r_out[3])
{
RegionView3D *rv3d = region->regiondata;
if (rv3d->is_persp) {
- copy_v3_v3(out, rv3d->viewinv[3]);
+ copy_v3_v3(r_out, rv3d->viewinv[3]);
}
else {
- out[0] = 2.0f * mval[0] / region->winx - 1.0f;
- out[1] = 2.0f * mval[1] / region->winy - 1.0f;
+ r_out[0] = 2.0f * mval[0] / region->winx - 1.0f;
+ r_out[1] = 2.0f * mval[1] / region->winy - 1.0f;
if (rv3d->persp == RV3D_CAMOB) {
- out[2] = -1.0f;
+ r_out[2] = -1.0f;
}
else {
- out[2] = 0.0f;
+ r_out[2] = 0.0f;
}
- mul_project_m4_v3(rv3d->persinv, out);
+ mul_project_m4_v3(rv3d->persinv, r_out);
}
}
-void ED_view3d_win_to_vector(const ARegion *region, const float mval[2], float out[3])
+void ED_view3d_win_to_vector(const ARegion *region, const float mval[2], float r_out[3])
{
RegionView3D *rv3d = region->regiondata;
if (rv3d->is_persp) {
- out[0] = 2.0f * (mval[0] / region->winx) - 1.0f;
- out[1] = 2.0f * (mval[1] / region->winy) - 1.0f;
- out[2] = -0.5f;
- mul_project_m4_v3(rv3d->persinv, out);
- sub_v3_v3(out, rv3d->viewinv[3]);
+ r_out[0] = 2.0f * (mval[0] / region->winx) - 1.0f;
+ r_out[1] = 2.0f * (mval[1] / region->winy) - 1.0f;
+ r_out[2] = -0.5f;
+ mul_project_m4_v3(rv3d->persinv, r_out);
+ sub_v3_v3(r_out, rv3d->viewinv[3]);
}
else {
- negate_v3_v3(out, rv3d->viewinv[2]);
+ negate_v3_v3(r_out, rv3d->viewinv[2]);
}
- normalize_v3(out);
+ normalize_v3(r_out);
}
bool ED_view3d_win_to_segment_clipped(struct Depsgraph *depsgraph,
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index f08c53fff47..e380a08dcc7 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -1313,7 +1313,7 @@ static bool view3d_lasso_select(bContext *C,
case OB_MESH:
changed = do_lasso_select_mesh(vc, wm_userdata, mcoords, mcoords_len, sel_op);
break;
- case OB_CURVE:
+ case OB_CURVES_LEGACY:
case OB_SURF:
changed = do_lasso_select_curve(vc, mcoords, mcoords_len, sel_op);
break;
@@ -2695,7 +2695,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
retval = ED_lattice_deselect_all_multi(C);
}
}
- else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
retval = ED_curve_editnurb_select_pick(C, location, extend, deselect, toggle);
if (!retval && deselect_all) {
retval = ED_curve_deselect_all_multi(C);
@@ -3586,7 +3586,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
}
break;
- case OB_CURVE:
+ case OB_CURVES_LEGACY:
case OB_SURF:
changed = do_nurbs_box_select(&vc, &rect, sel_op);
if (changed) {
@@ -4342,7 +4342,7 @@ static bool obedit_circle_select(bContext *C,
case OB_MESH:
changed = mesh_circle_select(vc, wm_userdata, sel_op, mval, rad);
break;
- case OB_CURVE:
+ case OB_CURVES_LEGACY:
case OB_SURF:
changed = nurbscurve_circle_select(vc, sel_op, mval, rad);
break;
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index 8a219cd96d1..3e788f2d643 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -510,6 +510,39 @@ bool ED_view3d_persp_ensure(const Depsgraph *depsgraph, View3D *v3d, ARegion *re
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Camera View Utilities
+ *
+ * Utilities for manipulating the camera-view.
+ * \{ */
+
+bool ED_view3d_camera_view_zoom_scale(RegionView3D *rv3d, const float scale)
+{
+ const float camzoom_init = rv3d->camzoom;
+ float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
+ /* Clamp both before and after conversion to prevent NAN on negative values. */
+
+ zoomfac = zoomfac * scale;
+ CLAMP(zoomfac, RV3D_CAMZOOM_MIN_FACTOR, RV3D_CAMZOOM_MAX_FACTOR);
+ rv3d->camzoom = BKE_screen_view3d_zoom_from_fac(zoomfac);
+ CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
+ return (rv3d->camzoom != camzoom_init);
+}
+
+bool ED_view3d_camera_view_pan(ARegion *region, const float event_ofs[2])
+{
+ RegionView3D *rv3d = region->regiondata;
+ const float camdxy_init[2] = {rv3d->camdx, rv3d->camdy};
+ const float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom) * 2.0f;
+ rv3d->camdx += event_ofs[0] / (region->winx * zoomfac);
+ rv3d->camdy += event_ofs[1] / (region->winy * zoomfac);
+ CLAMP(rv3d->camdx, -1.0f, 1.0f);
+ CLAMP(rv3d->camdy, -1.0f, 1.0f);
+ return (camdxy_init[0] != rv3d->camdx) || (camdxy_init[1] != rv3d->camdy);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Camera Lock API
*
* Lock the camera to the 3D Viewport, allowing view manipulation to transform the camera.
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 3bcc1b2968e..fd01f708ed2 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -177,8 +177,8 @@ void convertViewVec(TransInfo *t, float r_vec[3], double dx, double dy)
r_vec[1] = dy;
}
else {
- const float mval_f[2] = {(float)dx, (float)dy};
- ED_view3d_win_to_delta(t->region, mval_f, r_vec, t->zfac);
+ const float xy_delta[2] = {(float)dx, (float)dy};
+ ED_view3d_win_to_delta(t->region, xy_delta, t->zfac, r_vec);
}
}
else if (t->spacetype == SPACE_IMAGE) {
@@ -1150,10 +1150,10 @@ int transformEvent(TransInfo *t, const wmEvent *event)
else if (event->val == KM_PRESS) {
switch (event->type) {
case EVT_CKEY:
- if (event->is_repeat) {
+ if (event->flag & WM_EVENT_IS_REPEAT) {
break;
}
- if (event->alt) {
+ if (event->modifier & KM_ALT) {
if (!(t->options & CTX_NO_PET)) {
t->flag ^= T_PROP_CONNECTED;
sort_trans_data_dist(t);
@@ -1164,10 +1164,10 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
break;
case EVT_OKEY:
- if (event->is_repeat) {
+ if (event->flag & WM_EVENT_IS_REPEAT) {
break;
}
- if (t->flag & T_PROP_EDIT && event->shift) {
+ if ((t->flag & T_PROP_EDIT) && (event->modifier & KM_SHIFT)) {
t->prop_mode = (t->prop_mode + 1) % PROP_MODE_MAX;
calculatePropRatio(t);
t->redraw |= TREDRAW_HARD;
@@ -1175,7 +1175,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
break;
case EVT_PADPLUSKEY:
- if (event->alt && t->flag & T_PROP_EDIT) {
+ if ((event->modifier & KM_ALT) && (t->flag & T_PROP_EDIT)) {
t->prop_size *= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO) {
t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->clip_end);
@@ -1186,7 +1186,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
break;
case EVT_PADMINUS:
- if (event->alt && t->flag & T_PROP_EDIT) {
+ if ((event->modifier & KM_ALT) && (t->flag & T_PROP_EDIT)) {
t->prop_size /= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
calculatePropRatio(t);
t->redraw = TREDRAW_HARD;
@@ -1202,7 +1202,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
break;
case EVT_NKEY:
- if (event->is_repeat) {
+ if (event->flag & WM_EVENT_IS_REPEAT) {
break;
}
if (ELEM(t->mode, TFM_ROTATION)) {
@@ -1697,7 +1697,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
/* Needed to translate tweak events to mouse buttons. */
t->launch_event = event ? WM_userdef_event_type_from_keymap_type(event->type) : -1;
- t->is_launch_event_tweak = event ? ISTWEAK(event->type) : false;
+ t->is_launch_event_drag = event ? (event->val == KM_CLICK_DRAG) : false;
/* XXX Remove this when wm_operator_call_internal doesn't use window->eventstate
* (which can have type = 0) */
@@ -1780,10 +1780,12 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
}
if (kmi->propvalue == TFM_MODAL_SNAP_INV_ON && kmi->val == KM_PRESS) {
- if ((ELEM(kmi->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY) && event->ctrl) ||
- (ELEM(kmi->type, EVT_LEFTSHIFTKEY, EVT_RIGHTSHIFTKEY) && event->shift) ||
- (ELEM(kmi->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY) && event->alt) ||
- ((kmi->type == EVT_OSKEY) && event->oskey)) {
+ if ((ELEM(kmi->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY) &&
+ (event->modifier & KM_CTRL)) ||
+ (ELEM(kmi->type, EVT_LEFTSHIFTKEY, EVT_RIGHTSHIFTKEY) &&
+ (event->modifier & KM_SHIFT)) ||
+ (ELEM(kmi->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY) && (event->modifier & KM_ALT)) ||
+ ((kmi->type == EVT_OSKEY) && (event->modifier & KM_OSKEY))) {
t->modifiers |= MOD_SNAP_INVERT;
}
break;
@@ -1967,7 +1969,7 @@ bool checkUseAxisMatrix(TransInfo *t)
/* currently only checks for editmode */
if (t->flag & T_EDIT) {
if ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
- (ELEM(t->obedit_type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE))) {
+ (ELEM(t->obedit_type, OB_MESH, OB_CURVES_LEGACY, OB_MBALL, OB_ARMATURE))) {
/* not all editmode supports axis-matrix */
return true;
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 757c11f1179..3ee5868d5be 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -592,9 +592,11 @@ typedef struct TransInfo {
/*************** NEW STUFF *********************/
/** event type used to launch transform. */
short launch_event;
- /** Is the actual launch event a tweak event? (launch_event above is set to the corresponding
- * mouse button then.) */
- bool is_launch_event_tweak;
+ /**
+ * Is the actual launch event a drag event?
+ * (`launch_event` is set to the corresponding mouse button then.)
+ */
+ bool is_launch_event_drag;
bool is_orient_default_overwrite;
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 64ef170a13f..81b35e4539b 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -1041,8 +1041,7 @@ static void setNearestAxis3d(TransInfo *t)
* and to overflow the short integers.
* The formula used is a bit stupid, just a simplification of the subtraction
* of two 2D points 30 pixels apart (that's the last factor in the formula) after
- * projecting them with ED_view3d_win_to_delta and then get the length of that vector.
- */
+ * projecting them with #ED_view3d_win_to_delta and then get the length of that vector. */
zfac = mul_project_m4_v3_zfac(t->persmat, t->center_global);
zfac = len_v3(t->persinv[0]) * 2.0f / t->region->winx * zfac * 30.0f;
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index 95b810daeaf..4a2169b381e 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -1040,7 +1040,7 @@ static void init_proportional_edit(TransInfo *t)
/* Already calculated by uv_set_connectivity_distance. */
}
else if (convert_type == TC_CURVE_VERTS) {
- BLI_assert(t->obedit_type == OB_CURVE);
+ BLI_assert(t->obedit_type == OB_CURVES_LEGACY);
set_prop_dist(t, false);
}
else {
@@ -1049,7 +1049,7 @@ static void init_proportional_edit(TransInfo *t)
sort_trans_data_dist(t);
}
- else if (ELEM(t->obedit_type, OB_CURVE)) {
+ else if (ELEM(t->obedit_type, OB_CURVES_LEGACY)) {
/* Needed because bezier handles can be partially selected
* and are still added into transform data. */
sort_trans_data_selected_first(t);
@@ -1286,7 +1286,7 @@ static eTConvertType convert_type_get(const TransInfo *t, Object **r_obj_armatur
convert_type = TC_MESH_VERTS;
}
}
- else if (ELEM(t->obedit_type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(t->obedit_type, OB_CURVES_LEGACY, OB_SURF)) {
convert_type = TC_CURVE_VERTS;
}
else if (t->obedit_type == OB_LATTICE) {
diff --git a/source/blender/editors/transform/transform_convert_graph.c b/source/blender/editors/transform/transform_convert_graph.c
index 608fd59c8b7..54222fbb117 100644
--- a/source/blender/editors/transform/transform_convert_graph.c
+++ b/source/blender/editors/transform/transform_convert_graph.c
@@ -161,7 +161,7 @@ static void graph_bezt_get_transform_selection(const TransInfo *t,
bool left = use_handle ? ((bezt->f1 & SELECT) != 0) : key;
bool right = use_handle ? ((bezt->f3 & SELECT) != 0) : key;
- if (use_handle && t->is_launch_event_tweak) {
+ if (use_handle && t->is_launch_event_drag) {
if (sipo->runtime.flag & SIPO_RUNTIME_FLAG_TWEAK_HANDLES_LEFT) {
key = right = false;
}
diff --git a/source/blender/editors/transform/transform_convert_object_texspace.c b/source/blender/editors/transform/transform_convert_object_texspace.c
index e12d0db8758..763af1f3384 100644
--- a/source/blender/editors/transform/transform_convert_object_texspace.c
+++ b/source/blender/editors/transform/transform_convert_object_texspace.c
@@ -44,7 +44,7 @@ void createTransTexspace(TransInfo *t)
}
id = ob->data;
- if (id == NULL || !ELEM(GS(id->name), ID_ME, ID_CU, ID_MB)) {
+ if (id == NULL || !ELEM(GS(id->name), ID_ME, ID_CU_LEGACY, ID_MB)) {
BKE_report(t->reports, RPT_ERROR, "Unsupported object type for text-space transform");
return;
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 1d86a8f9413..8987325145c 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -731,7 +731,8 @@ void postTrans(bContext *C, TransInfo *t)
if (t->data_len_all != 0) {
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
/* free data malloced per trans-data */
- if (ELEM(t->obedit_type, OB_CURVE, OB_SURF, OB_GPENCIL) || (t->spacetype == SPACE_GRAPH)) {
+ if (ELEM(t->obedit_type, OB_CURVES_LEGACY, OB_SURF, OB_GPENCIL) ||
+ (t->spacetype == SPACE_GRAPH)) {
TransData *td = tc->data;
for (int a = 0; a < tc->data_len; a++, td++) {
if (td->flag & TD_BEZTRIPLE) {
@@ -1145,7 +1146,7 @@ void calculateCenter(TransInfo *t)
projectFloatView(t, axis, t->center2d);
- /* rotate only needs correct 2d center, grab needs ED_view3d_calc_zfac() value */
+ /* Rotate only needs correct 2d center, grab needs #ED_view3d_calc_zfac() value. */
if (t->mode == TFM_TRANSLATION) {
copy_v3_v3(t->center_global, axis);
}
@@ -1154,17 +1155,16 @@ void calculateCenter(TransInfo *t)
}
if (t->spacetype == SPACE_VIEW3D) {
- /* ED_view3d_calc_zfac() defines a factor for perspective depth correction,
- * used in ED_view3d_win_to_delta() */
+ /* #ED_view3d_calc_zfac() defines a factor for perspective depth correction,
+ * used in #ED_view3d_win_to_delta(). */
- /* zfac is only used convertViewVec only in cases operator was invoked in RGN_TYPE_WINDOW
- * and never used in other cases.
+ /* NOTE: `t->zfac` is only used #convertViewVec only in cases operator was invoked in
+ * #RGN_TYPE_WINDOW and never used in other cases.
*
- * We need special case here as well, since ED_view3d_calc_zfac will crash when called
- * for a region different from RGN_TYPE_WINDOW.
- */
+ * We need special case here as well, since #ED_view3d_calc_zfac will crash when called
+ * for a region different from #RGN_TYPE_WINDOW. */
if (t->region->regiontype == RGN_TYPE_WINDOW) {
- t->zfac = ED_view3d_calc_zfac(t->region->regiondata, t->center_global, NULL);
+ t->zfac = ED_view3d_calc_zfac(t->region->regiondata, t->center_global);
}
else {
t->zfac = 0.0f;
diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c
index d2b2d2f116e..da601328192 100644
--- a/source/blender/editors/transform/transform_gizmo_2d.c
+++ b/source/blender/editors/transform/transform_gizmo_2d.c
@@ -669,6 +669,7 @@ static void gizmo2d_xform_invoke_prepare(const bContext *C,
float c[3] = {mid[0], mid[1], 0.0f};
float orient_matrix[3][3];
+ unit_m3(orient_matrix);
ScrArea *area = CTX_wm_area(C);
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index 7e121a717aa..f07fadb7fc1 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -816,7 +816,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
}
FOREACH_EDIT_OBJECT_END();
}
- else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
FOREACH_EDIT_OBJECT_BEGIN (ob_iter, use_mat_local) {
Curve *cu = ob_iter->data;
Nurb *nu;
@@ -1869,7 +1869,7 @@ static void WIDGETGROUP_gizmo_invoke_prepare(const bContext *C,
if (axis != -1) {
wmWindow *win = CTX_wm_window(C);
/* Swap single axis for two-axis constraint. */
- bool flip = win->eventstate->shift;
+ bool flip = (win->eventstate->modifier & KM_SHIFT) != 0;
BLI_assert(axis_idx != -1);
const short axis_type = gizmo_get_axis_type(axis_idx);
if (axis_type != MAN_AXES_ROTATE) {
diff --git a/source/blender/editors/transform/transform_gizmo_extrude_3d.c b/source/blender/editors/transform/transform_gizmo_extrude_3d.c
index 6873ea862ce..f6f43f867ae 100644
--- a/source/blender/editors/transform/transform_gizmo_extrude_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_extrude_3d.c
@@ -153,7 +153,7 @@ static void gizmo_mesh_extrude_setup(const bContext *C, wmGizmoGroup *gzgroup)
op_idname = "ARMATURE_OT_extrude_move";
ggd->normal_axis = 1;
}
- else if (obact->type == OB_CURVE) {
+ else if (obact->type == OB_CURVES_LEGACY) {
op_idname = "CURVE_OT_extrude_move";
ggd->normal_axis = 2;
}
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index b6c4002b1c7..6162dfc9bb5 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -57,7 +57,7 @@ bool transdata_check_local_center(const TransInfo *t, short around)
return ((around == V3D_AROUND_LOCAL_ORIGINS) &&
((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)) ||
+ (ELEM(t->obedit_type, OB_MESH, OB_CURVES_LEGACY, OB_MBALL, OB_ARMATURE, OB_GPENCIL)) ||
(t->spacetype == SPACE_GRAPH) ||
(t->options & (CTX_MOVIECLIP | CTX_MASK | CTX_PAINT_CURVE | CTX_SEQUENCER_IMAGE))));
}
diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c
index 0afc527d4a8..77c5707d814 100644
--- a/source/blender/editors/transform/transform_mode_vert_slide.c
+++ b/source/blender/editors/transform/transform_mode_vert_slide.c
@@ -146,9 +146,9 @@ static void calcVertSlideMouseActiveEdges(struct TransInfo *t, const int mval[2]
* by finding the closest edge in local-space.
* However this skews the outcome with non-uniform-scale. */
- /* first get the direction of the original mouse position */
+ /* First get the direction of the original mouse position. */
sub_v2_v2v2(dir, imval_fl, mval_fl);
- ED_view3d_win_to_delta(t->region, dir, dir, t->zfac);
+ ED_view3d_win_to_delta(t->region, dir, t->zfac, dir);
normalize_v3(dir);
for (i = 0, sv = sld->sv; i < sld->totsv; i++, sv++) {
@@ -425,18 +425,18 @@ void drawVertSlide(TransInfo *t)
/* direction from active vertex! */
if ((t->mval[0] != t->mouse.imval[0]) || (t->mval[1] != t->mouse.imval[1])) {
float zfac;
- float mval_ofs[2];
+ float xy_delta[2];
float co_orig_3d[3];
float co_dest_3d[3];
- mval_ofs[0] = t->mval[0] - t->mouse.imval[0];
- mval_ofs[1] = t->mval[1] - t->mouse.imval[1];
+ xy_delta[0] = t->mval[0] - t->mouse.imval[0];
+ xy_delta[1] = t->mval[1] - t->mouse.imval[1];
mul_v3_m4v3(
co_orig_3d, TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat, curr_sv->co_orig_3d);
- zfac = ED_view3d_calc_zfac(t->region->regiondata, co_orig_3d, NULL);
+ zfac = ED_view3d_calc_zfac(t->region->regiondata, co_orig_3d);
- ED_view3d_win_to_delta(t->region, mval_ofs, co_dest_3d, zfac);
+ ED_view3d_win_to_delta(t->region, xy_delta, zfac, co_dest_3d);
invert_m4_m4(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->imat,
TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 3722e83e451..936aca7d2e0 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -628,7 +628,7 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
"Proportional Falloff",
"Falloff type for proportional editing mode");
/* Abusing id_curve :/ */
- RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE);
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE_LEGACY);
RNA_def_float(ot->srna,
"proportional_size",
1,
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 6ca61d415ea..c0d943e17ee 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -350,7 +350,7 @@ bool BIF_createTransformOrientation(bContext *C,
else if (obedit->type == OB_ARMATURE) {
ts = createBoneSpace(C, reports, name, overwrite);
}
- else if (obedit->type == OB_CURVE) {
+ else if (obedit->type == OB_CURVES_LEGACY) {
ts = createCurveSpace(C, reports, name, overwrite);
}
}
@@ -984,7 +984,7 @@ int getTransformOrientation_ex(ViewLayer *view_layer,
negate_v3(plane);
} /* end editmesh */
- else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
Curve *cu = obedit->data;
Nurb *nu = NULL;
int a;
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index ce0cf3aa6cb..2f3c021ba38 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -86,7 +86,7 @@ int BIF_snappingSupported(Object *obedit)
int status = 0;
/* only support object mesh, armature, curves */
- if (obedit == NULL || ELEM(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE, OB_MBALL)) {
+ if (obedit == NULL || ELEM(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVES_LEGACY, OB_LATTICE, OB_MBALL)) {
status = 1;
}
@@ -308,7 +308,8 @@ eRedrawFlag handleSnapping(TransInfo *t, const wmEvent *event)
eRedrawFlag status = TREDRAW_NOTHING;
#if 0 /* XXX need a proper selector for all snap mode */
- if (BIF_snappingSupported(t->obedit) && event->type == TABKEY && event->shift) {
+ if (BIF_snappingSupported(t->obedit) && (event->type == EVT_TABKEY) &&
+ (event->modifier & KM_SHIFT)) {
/* toggle snap and reinit */
t->settings->snap_flag ^= SCE_SNAP;
initSnapping(t, NULL);
@@ -583,7 +584,7 @@ static short snap_mode_from_scene(TransInfo *t)
/* All obedit types will match. */
const int obedit_type = t->obedit_type;
if ((t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR | CTX_OBMODE_XFORM_OBDATA)) ||
- ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE, OB_MBALL, -1)) {
+ ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVES_LEGACY, OB_LATTICE, OB_MBALL, -1)) {
r_snap_mode = ts->snap_mode;
if ((r_snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) &&
(t->mode == TFM_TRANSLATION)) {
@@ -617,7 +618,7 @@ static short snap_select_type_get(TransInfo *t)
* When we're moving the origins, allow snapping onto our own geometry (see T69132). */
}
else if ((obedit_type != -1) &&
- ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE, OB_MBALL)) {
+ ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVES_LEGACY, OB_LATTICE, OB_MBALL)) {
/* Edit mode */
/* Temporary limited to edit mode meshes, armature, curves, metaballs. */
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index ca6940040b2..8b7133892ff 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -477,7 +477,7 @@ static void iter_snap_objects(SnapObjectContext *sctx,
}
}
else if (snap_select == SNAP_NOT_SELECTED) {
- if (is_object_active && !(base->object->mode & OB_MODE_OBJECT)) {
+ if (is_object_active && base->object->mode != OB_MODE_OBJECT) {
/* Pass. Consider the selection of elements being edited. */
}
else if ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) {
@@ -1054,7 +1054,7 @@ static void raycast_obj_fn(SnapObjectContext *sctx,
dt->r_hit_list);
break;
}
- case OB_CURVE:
+ case OB_CURVES_LEGACY:
case OB_SURF:
case OB_FONT: {
if (!is_object_active) {
@@ -2743,7 +2743,7 @@ static void snap_obj_fn(SnapObjectContext *sctx,
dt->r_no,
dt->r_index);
break;
- case OB_CURVE:
+ case OB_CURVES_LEGACY:
retval = snapCurve(
sctx, params, ob_eval, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index);
break; /* Use ATTR_FALLTHROUGH if we want to snap to the generated mesh. */
@@ -3117,7 +3117,7 @@ static short transform_snap_context_project_view3d_mixed_impl(
sctx->runtime.has_occlusion_plane = false;
/* By convention we only snap to the original elements of a curve. */
- if (has_hit && ob_eval->type != OB_CURVE) {
+ if (has_hit && ob_eval->type != OB_CURVES_LEGACY) {
/* Compute the new clip_pane but do not add it yet. */
float new_clipplane[4];
BLI_ASSERT_UNIT_V3(no);
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index 2300e664dfa..7b4551fdb0c 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -40,6 +40,7 @@ set(SRC
../include/ED_clip.h
../include/ED_curve.h
../include/ED_curves.h
+ ../include/ED_curves_sculpt.h
../include/ED_datafiles.h
../include/ED_file_indexer.h
../include/ED_fileselect.h
diff --git a/source/blender/editors/util/ed_transverts.c b/source/blender/editors/util/ed_transverts.c
index 0523a58825e..c1e093d5555 100644
--- a/source/blender/editors/util/ed_transverts.c
+++ b/source/blender/editors/util/ed_transverts.c
@@ -45,7 +45,7 @@ void ED_transverts_update_obedit(TransVertStore *tvs, Object *obedit)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BM_mesh_normals_update(em->bm);
}
- else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
Curve *cu = obedit->data;
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
Nurb *nu = nurbs->first;
@@ -181,7 +181,8 @@ static void set_mapped_co(void *vuserdata, int index, const float co[3], const f
bool ED_transverts_check_obedit(const Object *obedit)
{
- return (ELEM(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL));
+ return (
+ ELEM(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVES_LEGACY, OB_MBALL));
}
void ED_transverts_create_from_obedit(TransVertStore *tvs, const Object *obedit, const int mode)
@@ -351,7 +352,7 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, const Object *obedit,
}
}
}
- else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) {
Curve *cu = obedit->data;
int totmalloc = 0;
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 15fe944be49..32d405df841 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -306,7 +306,7 @@ bool ED_editors_flush_edits(Main *bmain)
/* ***** XXX: functions are using old blender names, cleanup later ***** */
void apply_keyb_grid(
- int shift, int ctrl, float *val, float fac1, float fac2, float fac3, int invert)
+ bool shift, bool ctrl, float *val, float fac1, float fac2, float fac3, int invert)
{
/* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
if (invert) {
diff --git a/source/blender/editors/util/ed_util_ops.cc b/source/blender/editors/util/ed_util_ops.cc
index 014944da916..25deacbcdd1 100644
--- a/source/blender/editors/util/ed_util_ops.cc
+++ b/source/blender/editors/util/ed_util_ops.cc
@@ -226,7 +226,7 @@ static int lib_id_fake_user_toggle_exec(bContext *C, wmOperator *op)
ID *id = (ID *)idptr.data;
- if ((id->lib != nullptr) || (ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS))) {
+ if (ID_IS_LINKED(id) || (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;
}
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index 3bf226f6ba1..be6ac6e13e6 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -321,7 +321,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
if (U.flag & USER_FLAG_NUMINPUT_ADVANCED)
#endif
{
- if ((event->ctrl == 0) && (event->alt == 0) && (event->ascii != '\0') &&
+ if (((event->modifier & (KM_CTRL | KM_ALT)) == 0) && (event->ascii != '\0') &&
strchr("01234567890@%^&*-+/{}()[]<>.|", event->ascii)) {
if (!(n->flag & NUM_EDIT_FULL)) {
n->flag |= NUM_EDITED;
@@ -339,7 +339,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
n->val_flag[idx] |= NUM_EDITED;
return true;
}
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
n->flag &= ~NUM_EDIT_FULL;
return true;
}
@@ -375,7 +375,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
updated = true;
break;
}
- else if (event->shift || !n->str[0]) {
+ else if ((event->modifier & KM_SHIFT) || !n->str[0]) {
n->val[idx] = n->val_org[idx];
n->val_flag[idx] &= ~NUM_EDITED;
n->str[0] = '\0';
@@ -390,7 +390,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
case EVT_DELKEY:
if ((n->val_flag[idx] & NUM_EDITED) && n->str[0]) {
int t_cur = cur = n->str_cur;
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
mode = STRCUR_JUMP_DELIM;
}
BLI_str_cursor_step_utf8(n->str, strlen(n->str), &t_cur, dir, mode, true);
@@ -416,7 +416,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
ATTR_FALLTHROUGH;
case EVT_RIGHTARROWKEY:
cur = n->str_cur;
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
mode = STRCUR_JUMP_DELIM;
}
BLI_str_cursor_step_utf8(n->str, strlen(n->str), &cur, dir, mode, true);
@@ -442,7 +442,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
n->val_flag[idx] &= ~(NUM_NEGATE | NUM_INVERSE);
#endif
- idx = (idx + idx_max + (event->ctrl ? 0 : 2)) % (idx_max + 1);
+ idx = (idx + idx_max + ((event->modifier & KM_CTRL) ? 0 : 2)) % (idx_max + 1);
n->idx = idx;
if (n->val_flag[idx] & NUM_EDITED) {
value_to_editstr(n, idx);
@@ -470,7 +470,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
n->val_flag[idx] |= NUM_EDITED;
return true;
}
- else if (event->ctrl) {
+ else if (event->modifier & KM_CTRL) {
n->flag &= ~NUM_EDIT_FULL;
return true;
}
@@ -480,28 +480,28 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
#ifdef USE_FAKE_EDIT
case EVT_PADMINUS:
case EVT_MINUSKEY:
- if (event->ctrl || !(n->flag & NUM_EDIT_FULL)) {
+ if ((event->modifier & KM_CTRL) || !(n->flag & NUM_EDIT_FULL)) {
n->val_flag[idx] ^= NUM_NEGATE;
updated = true;
}
break;
case EVT_PADSLASHKEY:
case EVT_SLASHKEY:
- if (event->ctrl || !(n->flag & NUM_EDIT_FULL)) {
+ if ((event->modifier & KM_CTRL) || !(n->flag & NUM_EDIT_FULL)) {
n->val_flag[idx] ^= NUM_INVERSE;
updated = true;
}
break;
#endif
case EVT_CKEY:
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
/* Copy current `str` to the copy/paste buffer. */
WM_clipboard_text_set(n->str, 0);
updated = true;
}
break;
case EVT_VKEY:
- if (event->ctrl) {
+ if (event->modifier & KM_CTRL) {
/* extract the first line from the clipboard */
int pbuf_len;
char *pbuf = WM_clipboard_text_get_firstline(false, &pbuf_len);
@@ -531,7 +531,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
/* Up to this point, if we have a ctrl modifier, skip.
* This allows to still access most of modals' shortcuts even in numinput mode.
*/
- if (!updated && event->ctrl) {
+ if (!updated && (event->modifier & KM_CTRL)) {
return false;
}
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 91b29049ecf..c0d0fe95c8c 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -2598,7 +2598,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* Increase limit */
case EVT_PADPLUSKEY:
case WHEELUPMOUSE:
- if (event->val == KM_PRESS && event->alt) {
+ if ((event->val == KM_PRESS) && (event->modifier & KM_ALT)) {
ssc->limit_dist += 0.01f;
if (!stitch_process_data(ssc, active_state, scene, false)) {
stitch_cancel(C, op);
@@ -2612,7 +2612,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* Decrease limit */
case EVT_PADMINUS:
case WHEELDOWNMOUSE:
- if (event->val == KM_PRESS && event->alt) {
+ if ((event->val == KM_PRESS) && (event->modifier & KM_ALT)) {
ssc->limit_dist -= 0.01f;
ssc->limit_dist = MAX2(0.01f, ssc->limit_dist);
if (!stitch_process_data(ssc, active_state, scene, false)) {
@@ -2673,7 +2673,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* Select geometry */
case RIGHTMOUSE:
- if (!event->shift) {
+ if ((event->modifier & KM_SHIFT) == 0) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}