137 return curves_to_delete[curve_i];
144 for (
const IndexRange curves_range : ranges_to_keep) {
145 new_deformed_positions.
extend(
148 self_->deformed_positions_ = std::move(new_deformed_positions);
161 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
174 const float brush_radius_sq_re =
pow2f(brush_radius_re);
177 for (const int curve_i : curve_selection_.slice(range)) {
178 const IndexRange points = curves_->points_for_curve(curve_i);
179 if (points.size() == 1) {
180 const float3 pos_cu = brush_transform_inv * self_->deformed_positions_[points.first()];
182 ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.values);
184 if (math::distance_squared(brush_pos_re_, pos_re) <= brush_radius_sq_re) {
185 curves_to_delete[curve_i] = true;
190 for (const int segment_i : points.drop_back(1)) {
191 const float3 pos1_cu = brush_transform_inv * self_->deformed_positions_[segment_i];
192 const float3 pos2_cu = brush_transform_inv * self_->deformed_positions_[segment_i + 1];
194 float2 pos1_re, pos2_re;
195 ED_view3d_project_float_v2_m4(ctx_.region, pos1_cu, pos1_re, projection.values);
196 ED_view3d_project_float_v2_m4(ctx_.region, pos2_cu, pos2_re, projection.values);
198 const float dist_sq_re = dist_squared_to_line_segment_v2(
199 brush_pos_re_, pos1_re, pos2_re);
200 if (dist_sq_re <= brush_radius_sq_re) {
201 curves_to_delete[curve_i] = true;
217 transforms_.curves_to_world * self_->brush_3d_.position_cu,
220 const float3 brush_cu = transforms_.world_to_curves * brush_wo;
225 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
226 this->delete_spherical(brush_transform * brush_cu, curves_to_delete);
232 const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_;
233 const float brush_radius_sq_cu =
pow2f(brush_radius_cu);
236 for (const int curve_i : curve_selection_.slice(range)) {
237 const IndexRange points = curves_->points_for_curve(curve_i);
239 if (points.size() == 1) {
240 const float3 &pos_cu = self_->deformed_positions_[points.first()];
241 const float distance_sq_cu = math::distance_squared(pos_cu, brush_cu);
242 if (distance_sq_cu < brush_radius_sq_cu) {
243 curves_to_delete[curve_i] = true;
248 for (const int segment_i : points.drop_back(1)) {
249 const float3 &pos1_cu = self_->deformed_positions_[segment_i];
250 const float3 &pos2_cu = self_->deformed_positions_[segment_i + 1];
252 const float distance_sq_cu = dist_squared_to_line_segment_v3(brush_cu, pos1_cu, pos2_cu);
253 if (distance_sq_cu > brush_radius_sq_cu) {
256 curves_to_delete[curve_i] = true;
271 brush_radius_base_re_);
272 if (brush_3d.has_value()) {
273 self_->brush_3d_ = *brush_3d;
278 void DeleteOperation::on_stroke_extended(
const bContext &
C,
282 executor.execute(*
this,
C, stroke_extension);
287 return std::make_unique<DeleteOperation>();
int BKE_brush_size_get(const struct Scene *scene, const struct Brush *brush)
struct Object * CTX_data_active_object(const bContext *C)
Low-level operations for curves.
const struct Brush * BKE_paint_brush_for_read(const struct Paint *p)
#define BLI_assert_unreachable()
A KD-tree for nearest neighbor search.
MINLINE float pow2f(float x)
void DEG_id_tag_update(struct ID *id, int flag)
@ PAINT_FALLOFF_SHAPE_SPHERE
@ PAINT_FALLOFF_SHAPE_TUBE
struct CurvesGeometry CurvesGeometry
Object is a sort of wrapper for general info.
void ED_region_tag_redraw(struct ARegion *region)
void ED_view3d_ob_project_mat_get(const struct RegionView3D *v3d, const struct Object *ob, float r_pmat[4][4])
void ED_view3d_win_to_3d(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
Platform independent time functions.
Vector< IndexRange > extract_ranges_invert(const IndexRange full_range, Vector< int64_t > *r_skip_amounts=nullptr) const
IndexRange index_range() const
void extend(Span< T > array)
IndexRange curves_range() const
IndexRange points_for_curves(IndexRange curves) const
void remove_curves(IndexMask curves_to_delete)
static CurvesGeometry & wrap(::CurvesGeometry &dna_struct)
const Depsgraph * depsgraph
void on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) override
ccl_gpu_kernel_postfix int ccl_global int * indices
GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph, const Object &ob_orig)
std::optional< CurvesBrush3D > sample_curves_3d_brush(const Depsgraph &depsgraph, const ARegion ®ion, const View3D &v3d, const RegionView3D &rv3d, const Object &curves_object, const float2 &brush_pos_re, const float brush_radius_re)
std::unique_ptr< CurvesSculptStrokeOperation > new_delete_operation()
static IndexMask retrieve_selected_curves(const CurvesGeometry &curves, const eAttrDomain domain, Vector< int64_t > &r_indices)
Vector< float4x4 > get_symmetry_brush_transforms(const eCurvesSymmetryType symmetry)
float brush_radius_factor(const Brush &brush, const StrokeExtension &stroke_extension)
IndexMask find_indices_based_on_predicate(const IndexMask indices_to_check, const int64_t parallel_grain_size, Vector< int64_t > &r_indices, const Predicate &predicate)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
struct ToolSettings * toolsettings
Vector< int64_t > selected_curve_indices_
void delete_spherical(const float3 &brush_cu, MutableSpan< bool > curves_to_delete)
DeleteOperationExecutor(const bContext &C)
float brush_radius_base_re_
CurvesSurfaceTransforms transforms_
void execute(DeleteOperation &self, const bContext &C, const StrokeExtension &stroke_extension)
void delete_projected(const float4x4 &brush_transform, MutableSpan< bool > curves_to_delete)
const CurvesSculpt * curves_sculpt_
void delete_spherical_with_symmetry(MutableSpan< bool > curves_to_delete)
IndexMask curve_selection_
void initialize_spherical_brush_reference_point()
float brush_radius_factor_
CurvesSculptCommonContext ctx_
void delete_projected_with_symmetry(MutableSpan< bool > curves_to_delete)
float4x4 inverted() const
void WM_main_add_notifier(unsigned int type, void *reference)