diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/curves_sculpt_delete.cc')
-rw-r--r-- | source/blender/editors/sculpt_paint/curves_sculpt_delete.cc | 76 |
1 files changed, 40 insertions, 36 deletions
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc index 9446f38891e..323e99df099 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc @@ -50,8 +50,6 @@ using blender::bke::CurvesGeometry; class DeleteOperation : public CurvesSculptStrokeOperation { private: - float2 brush_pos_prev_re_; - CurvesBrush3D brush_3d_; friend struct DeleteOperationExecutor; @@ -74,17 +72,16 @@ struct DeleteOperationExecutor { const CurvesSculpt *curves_sculpt_ = nullptr; const Brush *brush_ = nullptr; - float brush_radius_re_; + float brush_radius_base_re_; + float brush_radius_factor_; float2 brush_pos_re_; - float2 brush_pos_prev_re_; float4x4 curves_to_world_mat_; float4x4 world_to_curves_mat_; void execute(DeleteOperation &self, const bContext &C, const StrokeExtension &stroke_extension) { - BLI_SCOPED_DEFER([&]() { self.brush_pos_prev_re_ = stroke_extension.mouse_position; }); self_ = &self; depsgraph_ = CTX_data_depsgraph_pointer(&C); @@ -99,11 +96,10 @@ struct DeleteOperationExecutor { curves_sculpt_ = scene_->toolsettings->curves_sculpt; brush_ = BKE_paint_brush_for_read(&curves_sculpt_->paint); - brush_radius_re_ = BKE_brush_size_get(scene_, brush_); + brush_radius_base_re_ = BKE_brush_size_get(scene_, brush_); + brush_radius_factor_ = brush_radius_factor(*brush_, stroke_extension); brush_pos_re_ = stroke_extension.mouse_position; - brush_pos_prev_re_ = stroke_extension.is_first ? stroke_extension.mouse_position : - self.brush_pos_prev_re_; curves_to_world_mat_ = object_->obmat; world_to_curves_mat_ = curves_to_world_mat_.inverted(); @@ -159,9 +155,23 @@ struct DeleteOperationExecutor { Span<float3> positions_cu = curves_->positions(); + const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_; + const float brush_radius_sq_re = pow2f(brush_radius_re); + threading::parallel_for(curves_->curves_range(), 512, [&](IndexRange curve_range) { for (const int curve_i : curve_range) { const IndexRange points = curves_->points_for_curve(curve_i); + if (points.size() == 1) { + const float3 pos_cu = brush_transform_inv * positions_cu[points.first()]; + float2 pos_re; + ED_view3d_project_float_v2_m4(region_, pos_cu, pos_re, projection.values); + + if (math::distance_squared(brush_pos_re_, pos_re) <= brush_radius_sq_re) { + curves_to_delete[curve_i] = true; + } + continue; + } + for (const int segment_i : points.drop_back(1)) { const float3 pos1_cu = brush_transform_inv * positions_cu[segment_i]; const float3 pos2_cu = brush_transform_inv * positions_cu[segment_i + 1]; @@ -170,8 +180,9 @@ struct DeleteOperationExecutor { ED_view3d_project_float_v2_m4(region_, pos1_cu, pos1_re, projection.values); ED_view3d_project_float_v2_m4(region_, pos2_cu, pos2_re, projection.values); - const float dist = dist_seg_seg_v2(pos1_re, pos2_re, brush_pos_prev_re_, brush_pos_re_); - if (dist <= brush_radius_re_) { + const float dist_sq_re = dist_squared_to_line_segment_v2( + brush_pos_re_, pos1_re, pos2_re); + if (dist_sq_re <= brush_radius_sq_re) { curves_to_delete[curve_i] = true; break; } @@ -185,55 +196,48 @@ struct DeleteOperationExecutor { float4x4 projection; ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); - float3 brush_start_wo, brush_end_wo; - ED_view3d_win_to_3d(v3d_, - region_, - curves_to_world_mat_ * self_->brush_3d_.position_cu, - brush_pos_prev_re_, - brush_start_wo); + float3 brush_wo; ED_view3d_win_to_3d(v3d_, region_, curves_to_world_mat_ * self_->brush_3d_.position_cu, brush_pos_re_, - brush_end_wo); - const float3 brush_start_cu = world_to_curves_mat_ * brush_start_wo; - const float3 brush_end_cu = world_to_curves_mat_ * brush_end_wo; + brush_wo); + const float3 brush_cu = world_to_curves_mat_ * brush_wo; const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms( eCurvesSymmetryType(curves_id_->symmetry)); for (const float4x4 &brush_transform : symmetry_brush_transforms) { - this->delete_spherical( - brush_transform * brush_start_cu, brush_transform * brush_end_cu, curves_to_delete); + this->delete_spherical(brush_transform * brush_cu, curves_to_delete); } } - void delete_spherical(const float3 &brush_start_cu, - const float3 &brush_end_cu, - MutableSpan<bool> curves_to_delete) + void delete_spherical(const float3 &brush_cu, MutableSpan<bool> curves_to_delete) { Span<float3> positions_cu = curves_->positions(); - const float brush_radius_cu = self_->brush_3d_.radius_cu; + const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_; const float brush_radius_sq_cu = pow2f(brush_radius_cu); threading::parallel_for(curves_->curves_range(), 512, [&](IndexRange curve_range) { for (const int curve_i : curve_range) { const IndexRange points = curves_->points_for_curve(curve_i); + + if (points.size() == 1) { + const float3 &pos_cu = positions_cu[points.first()]; + const float distance_sq_cu = math::distance_squared(pos_cu, brush_cu); + if (distance_sq_cu < brush_radius_sq_cu) { + curves_to_delete[curve_i] = true; + } + continue; + } + for (const int segment_i : points.drop_back(1)) { const float3 &pos1_cu = positions_cu[segment_i]; const float3 &pos2_cu = positions_cu[segment_i + 1]; - float3 closest_segment_cu, closest_brush_cu; - isect_seg_seg_v3(pos1_cu, - pos2_cu, - brush_start_cu, - brush_end_cu, - closest_segment_cu, - closest_brush_cu); - const float distance_to_brush_sq_cu = math::distance_squared(closest_segment_cu, - closest_brush_cu); - if (distance_to_brush_sq_cu > brush_radius_sq_cu) { + const float distance_sq_cu = dist_squared_to_line_segment_v3(brush_cu, pos1_cu, pos2_cu); + if (distance_sq_cu > brush_radius_sq_cu) { continue; } curves_to_delete[curve_i] = true; @@ -246,7 +250,7 @@ struct DeleteOperationExecutor { void initialize_spherical_brush_reference_point() { std::optional<CurvesBrush3D> brush_3d = sample_curves_3d_brush( - *depsgraph_, *region_, *v3d_, *rv3d_, *object_, brush_pos_re_, brush_radius_re_); + *depsgraph_, *region_, *v3d_, *rv3d_, *object_, brush_pos_re_, brush_radius_base_re_); if (brush_3d.has_value()) { self_->brush_3d_ = *brush_3d; } |