diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc index 6386328326a..a7f4ff724fe 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc @@ -6,6 +6,7 @@ #include "curves_sculpt_intern.hh" +#include "BLI_bounds.hh" #include "BLI_kdtree.h" #include "BLI_math_geom.h" #include "BLI_math_matrix.hh" @@ -239,6 +240,14 @@ struct AddOperationExecutor { add_outputs.new_curves_range)); selection.finish(); } + if (U.uiflag & USER_ORBIT_SELECTION) { + if (const std::optional> center_cu = bounds::min_max( + curves_orig_->positions().slice(add_outputs.new_points_range))) + { + remember_stroke_position( + *ctx_.scene, math::transform_point(transforms_.curves_to_world, center_cu->center())); + } + } if (add_outputs.uv_error) { report_invalid_uv_map(stroke_extension.reports); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc index 323b4f59f09..2c7ebfc840b 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc @@ -346,6 +346,14 @@ Vector get_symmetry_brush_transforms(const eCurvesSymmetryType symmetr return matrices; } +void remember_stroke_position(Scene &scene, const float3 &brush_position_wo) +{ + UnifiedPaintSettings &ups = scene.toolsettings->unified_paint_settings; + copy_v3_v3(ups.average_stroke_accum, brush_position_wo); + ups.average_stroke_counter = 1; + ups.last_stroke_valid = true; +} + float transform_brush_radius(const float4x4 &transform, const float3 &brush_position, const float old_radius) diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc index b10096e2b5f..2b7956bf7c3 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc @@ -137,7 +137,7 @@ struct CombOperationExecutor { brush_pos_diff_re_ = brush_pos_re_ - brush_pos_prev_re_; if (stroke_extension.is_first) { - if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { + if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE || (U.uiflag & USER_ORBIT_SELECTION)) { this->initialize_spherical_brush_reference_point(); } self_->constraint_solver_.initialize( @@ -392,6 +392,9 @@ struct CombOperationExecutor { brush_radius_base_re_); if (brush_3d.has_value()) { self_->brush_3d_ = *brush_3d; + remember_stroke_position( + *ctx_.scene, + math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu)); } } }; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc index 6108462df2c..855d4ac077f 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc @@ -106,7 +106,7 @@ struct DeleteOperationExecutor { const eBrushFalloffShape falloff_shape = eBrushFalloffShape(brush_->falloff_shape); if (stroke_extension.is_first) { - if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { + if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE || (U.uiflag & USER_ORBIT_SELECTION)) { this->initialize_spherical_brush_reference_point(); } const bke::crazyspace::GeometryDeformation deformation = @@ -261,6 +261,9 @@ struct DeleteOperationExecutor { brush_radius_base_re_); if (brush_3d.has_value()) { self_->brush_3d_ = *brush_3d; + remember_stroke_position( + *ctx_.scene, + math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu)); } } }; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc index 42e8ac27382..791c51b1129 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc @@ -16,6 +16,7 @@ #include "BKE_object.hh" #include "BKE_paint.hh" #include "BKE_report.hh" +#include "BLI_bounds.hh" #include "ED_screen.hh" #include "ED_view3d.hh" @@ -287,6 +288,14 @@ struct DensityAddOperationExecutor { add_outputs.new_curves_range)); selection.finish(); } + if (U.uiflag & USER_ORBIT_SELECTION) { + if (const std::optional> center_cu = bounds::min_max( + curves_orig_->positions().slice(add_outputs.new_points_range))) + { + remember_stroke_position( + *ctx_.scene, math::transform_point(transforms_.curves_to_world, center_cu->center())); + } + } if (add_outputs.uv_error) { report_invalid_uv_map(stroke_extension.reports); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc index f82dd7611d9..6f31e7ce98a 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc @@ -290,7 +290,7 @@ struct CurvesEffectOperationExecutor { brush_pos_end_re_ = stroke_extension.mouse_position; if (stroke_extension.is_first) { - if (falloff_shape_ == PAINT_FALLOFF_SHAPE_SPHERE) { + if (falloff_shape_ == PAINT_FALLOFF_SHAPE_SPHERE || (U.flag & USER_ORBIT_SELECTION)) { if (std::optional brush_3d = sample_curves_3d_brush( *ctx_.depsgraph, *ctx_.region, @@ -301,6 +301,9 @@ struct CurvesEffectOperationExecutor { brush_radius_base_re_)) { self.brush_3d_ = *brush_3d; + remember_stroke_position( + *ctx_.scene, + math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu)); } } diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh index bc9f82e3426..49c715e5384 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh @@ -92,6 +92,12 @@ std::optional sample_curves_3d_brush(const Depsgraph &depsgraph, const float2 &brush_pos_re, const float brush_radius_re); +/** + * Updates the position of the stroke so that it can be used by the orbit-around-selection + * navigation method. + */ +void remember_stroke_position(Scene &scene, const float3 &brush_position_wo); + Vector get_symmetry_brush_transforms(eCurvesSymmetryType symmetry); bke::SpanAttributeWriter float_selection_ensure(Curves &curves_id); @@ -117,7 +123,7 @@ void move_last_point_and_resample(MoveAndResampleBuffers &buffer, class CurvesSculptCommonContext { public: const Depsgraph *depsgraph = nullptr; - const Scene *scene = nullptr; + Scene *scene = nullptr; ARegion *region = nullptr; const View3D *v3d = nullptr; RegionView3D *rv3d = nullptr; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc b/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc index 2328dcd01a1..29cafacdf58 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc @@ -112,7 +112,7 @@ struct PinchOperationExecutor { const eBrushFalloffShape falloff_shape = eBrushFalloffShape(brush_->falloff_shape); if (stroke_extension.is_first) { - if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { + if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE || (U.uiflag & USER_ORBIT_SELECTION)) { self_->brush_3d_ = *sample_curves_3d_brush(*ctx_.depsgraph, *ctx_.region, *ctx_.v3d, @@ -120,6 +120,9 @@ struct PinchOperationExecutor { *object_, brush_pos_re_, brush_radius_base_re_); + remember_stroke_position( + *ctx_.scene, + math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu)); } self_->constraint_solver_.initialize( diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc index cfc4e8cc286..04b5b623c6a 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc @@ -121,7 +121,7 @@ struct PuffOperationExecutor { surface_bvh_ = surface_->bvh_corner_tris(); if (stroke_extension.is_first) { - if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { + if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE || (U.uiflag & USER_ORBIT_SELECTION)) { self.brush_3d_ = *sample_curves_3d_brush(*ctx_.depsgraph, *ctx_.region, *ctx_.v3d, @@ -129,6 +129,9 @@ struct PuffOperationExecutor { *object_, brush_pos_re_, brush_radius_base_re_); + remember_stroke_position( + *ctx_.scene, + math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu)); } self_->constraint_solver_.initialize( diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc b/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc index 8590cd34489..39b64daa1b5 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc @@ -115,7 +115,7 @@ struct SelectionPaintOperationExecutor { selection_goal_ = self_->use_select_ ? 1.0f : 0.0f; if (stroke_extension.is_first) { - if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { + if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE || (U.uiflag & USER_ORBIT_SELECTION)) { this->initialize_spherical_brush_reference_point(); } } @@ -377,6 +377,9 @@ struct SelectionPaintOperationExecutor { brush_radius_base_re_); if (brush_3d.has_value()) { self_->brush_3d_ = *brush_3d; + remember_stroke_position( + *ctx_.scene, + math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu)); } } }; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc index 4af181177c4..e654015bfe0 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc @@ -239,6 +239,9 @@ struct SlideOperationExecutor { if (!brush_3d.has_value()) { return; } + remember_stroke_position( + *ctx_.scene, math::transform_point(transforms_.curves_to_world, brush_3d->position_cu)); + const ReverseUVSampler reverse_uv_sampler_orig{surface_uv_map_orig_, surface_corner_tris_orig_}; for (const float4x4 &brush_transform : brush_transforms) { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc b/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc index 711c155311d..4a2f1f956c4 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc @@ -87,7 +87,7 @@ struct SmoothOperationExecutor { const eBrushFalloffShape falloff_shape = eBrushFalloffShape(brush_->falloff_shape); if (stroke_extension.is_first) { - if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { + if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE || (U.uiflag & USER_ORBIT_SELECTION)) { self.brush_3d_ = *sample_curves_3d_brush(*ctx_.depsgraph, *ctx_.region, *ctx_.v3d, @@ -95,6 +95,9 @@ struct SmoothOperationExecutor { *object_, brush_pos_re_, brush_radius_base_re_); + remember_stroke_position( + *ctx_.scene, + math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu)); } } diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc index 54dbe60f064..556df6148c6 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc @@ -129,7 +129,7 @@ struct SnakeHookOperatorExecutor { brush_pos_diff_re_ = brush_pos_re_ - brush_pos_prev_re_; if (stroke_extension.is_first) { - if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { + if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE || (U.uiflag & USER_ORBIT_SELECTION)) { std::optional brush_3d = sample_curves_3d_brush(*ctx_.depsgraph, *ctx_.region, *ctx_.v3d, @@ -139,6 +139,9 @@ struct SnakeHookOperatorExecutor { brush_radius_base_re_); if (brush_3d.has_value()) { self_->brush_3d_ = *brush_3d; + remember_stroke_position( + *ctx_.scene, + math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu)); } } return; diff --git a/source/blender/editors/space_view3d/view3d_navigate.cc b/source/blender/editors/space_view3d/view3d_navigate.cc index 4bba2d970e1..1efe14b2885 100644 --- a/source/blender/editors/space_view3d/view3d_navigate.cc +++ b/source/blender/editors/space_view3d/view3d_navigate.cc @@ -801,6 +801,10 @@ bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3]) BKE_paint_stroke_get_average(scene, ob_act_eval, lastofs); is_set = true; } + else if (ob_act && (ob_act->mode & OB_MODE_SCULPT_CURVES)) { + BKE_paint_stroke_get_average(scene, ob_act_eval, lastofs); + is_set = true; + } else if (ob_act && (ob_act->mode & OB_MODE_EDIT) && (ob_act->type == OB_FONT)) { Curve *cu = static_cast(ob_act_eval->data); EditFont *ef = cu->editfont;