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.cc136
1 files changed, 83 insertions, 53 deletions
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc
index 2841a19d677..bd0bbad3bb8 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc
@@ -35,6 +35,8 @@
#include "ED_screen.h"
#include "ED_view3d.h"
+#include "WM_api.h"
+
/**
* The code below uses a suffix naming convention to indicate the coordinate space:
* cu: Local space of the curves object that is being edited.
@@ -117,56 +119,71 @@ struct DeleteOperationExecutor {
}
}
+ Array<bool> curves_to_delete(curves_->curves_num(), false);
if (falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
- this->delete_projected();
+ this->delete_projected_with_symmetry(curves_to_delete);
}
else if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) {
- this->delete_spherical();
+ this->delete_spherical_with_symmetry(curves_to_delete);
}
else {
BLI_assert_unreachable();
}
+ Vector<int64_t> indices;
+ const IndexMask mask = index_mask_ops::find_indices_based_on_predicate(
+ curves_->curves_range(), 4096, indices, [&](const int curve_i) {
+ return curves_to_delete[curve_i];
+ });
+
+ curves_->remove_curves(mask);
+
DEG_id_tag_update(&curves_id_->id, ID_RECALC_GEOMETRY);
+ WM_main_add_notifier(NC_GEOM | ND_DATA, &curves_id_->id);
ED_region_tag_redraw(region_);
}
- void delete_projected()
+ void delete_projected_with_symmetry(MutableSpan<bool> curves_to_delete)
+ {
+ const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
+ eCurvesSymmetryType(curves_id_->symmetry));
+ for (const float4x4 &brush_transform : symmetry_brush_transforms) {
+ this->delete_projected(curves_to_delete, brush_transform);
+ }
+ }
+
+ void delete_projected(MutableSpan<bool> curves_to_delete, const float4x4 &brush_transform)
{
+ const float4x4 brush_transform_inv = brush_transform.inverted();
+
float4x4 projection;
ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values);
Span<float3> positions_cu = curves_->positions();
- /* 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_->points_for_curve(curve_i);
- for (const int segment_i : IndexRange(point_range.size() - 1)) {
- const float3 pos1_cu = positions_cu[point_range[segment_i]];
- const float3 pos2_cu = positions_cu[point_range[segment_i + 1]];
-
- float2 pos1_re, pos2_re;
- 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_) {
- return true;
- }
+ 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);
+ for (const int segment_i : IndexRange(points.size() - 1)) {
+ const float3 pos1_cu = brush_transform_inv * positions_cu[points[segment_i]];
+ const float3 pos2_cu = brush_transform_inv * positions_cu[points[segment_i + 1]];
+
+ float2 pos1_re, pos2_re;
+ 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_) {
+ curves_to_delete[curve_i] = true;
+ break;
}
- return false;
- });
-
- curves_->remove_curves(curves_to_remove);
+ }
+ }
+ });
}
- void delete_spherical()
+ void delete_spherical_with_symmetry(MutableSpan<bool> curves_to_delete)
{
- Span<float3> positions_cu = curves_->positions();
-
float4x4 projection;
ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values);
@@ -184,35 +201,48 @@ struct DeleteOperationExecutor {
const float3 brush_start_cu = world_to_curves_mat_ * brush_start_wo;
const float3 brush_end_cu = world_to_curves_mat_ * brush_end_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(
+ curves_to_delete, brush_transform * brush_start_cu, brush_transform * brush_end_cu);
+ }
+ }
+
+ void delete_spherical(MutableSpan<bool> curves_to_delete,
+ const float3 &brush_start_cu,
+ const float3 &brush_end_cu)
+ {
+ Span<float3> positions_cu = curves_->positions();
+
const float brush_radius_cu = self_->brush_3d_.radius_cu;
const float brush_radius_sq_cu = pow2f(brush_radius_cu);
- 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 points = curves_->points_for_curve(curve_i);
- for (const int segment_i : IndexRange(points.size() - 1)) {
- const float3 pos1_cu = positions_cu[points[segment_i]];
- const float3 pos2_cu = positions_cu[points[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) {
- continue;
- }
- return true;
+ 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);
+ for (const int segment_i : IndexRange(points.size() - 1)) {
+ const float3 pos1_cu = positions_cu[points[segment_i]];
+ const float3 pos2_cu = positions_cu[points[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) {
+ continue;
}
- return false;
- });
-
- curves_->remove_curves(curves_to_remove);
+ curves_to_delete[curve_i] = true;
+ break;
+ }
+ }
+ });
}
void initialize_spherical_brush_reference_point()