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/sculpt_paint/curves_sculpt_delete.cc')
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_delete.cc76
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;
}