Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/curves_sculpt_delete.cc
| Show First 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | struct DeleteOperationExecutor { | ||||
| Curves *curves_id_ = nullptr; | Curves *curves_id_ = nullptr; | ||||
| CurvesGeometry *curves_ = nullptr; | CurvesGeometry *curves_ = nullptr; | ||||
| const CurvesSculpt *curves_sculpt_ = nullptr; | const CurvesSculpt *curves_sculpt_ = nullptr; | ||||
| const Brush *brush_ = nullptr; | const Brush *brush_ = nullptr; | ||||
| float brush_radius_re_; | float brush_radius_re_; | ||||
| float2 brush_pos_re_; | float2 brush_pos_re_; | ||||
| float2 brush_pos_prev_re_; | |||||
| float4x4 curves_to_world_mat_; | float4x4 curves_to_world_mat_; | ||||
| float4x4 world_to_curves_mat_; | float4x4 world_to_curves_mat_; | ||||
| void execute(DeleteOperation &self, const bContext &C, const StrokeExtension &stroke_extension) | 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; | self_ = &self; | ||||
| depsgraph_ = CTX_data_depsgraph_pointer(&C); | depsgraph_ = CTX_data_depsgraph_pointer(&C); | ||||
| scene_ = CTX_data_scene(&C); | scene_ = CTX_data_scene(&C); | ||||
| object_ = CTX_data_active_object(&C); | object_ = CTX_data_active_object(&C); | ||||
| region_ = CTX_wm_region(&C); | region_ = CTX_wm_region(&C); | ||||
| v3d_ = CTX_wm_view3d(&C); | v3d_ = CTX_wm_view3d(&C); | ||||
| rv3d_ = CTX_wm_region_view3d(&C); | rv3d_ = CTX_wm_region_view3d(&C); | ||||
| curves_id_ = static_cast<Curves *>(object_->data); | curves_id_ = static_cast<Curves *>(object_->data); | ||||
| curves_ = &CurvesGeometry::wrap(curves_id_->geometry); | curves_ = &CurvesGeometry::wrap(curves_id_->geometry); | ||||
| curves_sculpt_ = scene_->toolsettings->curves_sculpt; | curves_sculpt_ = scene_->toolsettings->curves_sculpt; | ||||
| brush_ = BKE_paint_brush_for_read(&curves_sculpt_->paint); | brush_ = BKE_paint_brush_for_read(&curves_sculpt_->paint); | ||||
| brush_radius_re_ = BKE_brush_size_get(scene_, brush_); | brush_radius_re_ = BKE_brush_size_get(scene_, brush_); | ||||
| brush_pos_re_ = stroke_extension.mouse_position; | 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; | curves_to_world_mat_ = object_->obmat; | ||||
| world_to_curves_mat_ = curves_to_world_mat_.inverted(); | world_to_curves_mat_ = curves_to_world_mat_.inverted(); | ||||
| const eBrushFalloffShape falloff_shape = static_cast<eBrushFalloffShape>( | const eBrushFalloffShape falloff_shape = static_cast<eBrushFalloffShape>( | ||||
| brush_->falloff_shape); | brush_->falloff_shape); | ||||
| if (stroke_extension.is_first) { | if (stroke_extension.is_first) { | ||||
| Show All 39 Lines | struct DeleteOperationExecutor { | ||||
| { | { | ||||
| const float4x4 brush_transform_inv = brush_transform.inverted(); | const float4x4 brush_transform_inv = brush_transform.inverted(); | ||||
| float4x4 projection; | float4x4 projection; | ||||
| ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); | ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); | ||||
| Span<float3> positions_cu = curves_->positions(); | Span<float3> positions_cu = curves_->positions(); | ||||
| const float brush_radius_sq_re = pow2f(brush_radius_re_); | |||||
| threading::parallel_for(curves_->curves_range(), 512, [&](IndexRange curve_range) { | threading::parallel_for(curves_->curves_range(), 512, [&](IndexRange curve_range) { | ||||
| for (const int curve_i : curve_range) { | for (const int curve_i : curve_range) { | ||||
| const IndexRange points = curves_->points_for_curve(curve_i); | const IndexRange points = curves_->points_for_curve(curve_i); | ||||
| for (const int segment_i : IndexRange(points.size() - 1)) { | for (const int segment_i : IndexRange(points.size() - 1)) { | ||||
| const float3 pos1_cu = brush_transform_inv * positions_cu[points[segment_i]]; | 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]]; | const float3 pos2_cu = brush_transform_inv * positions_cu[points[segment_i + 1]]; | ||||
| float2 pos1_re, pos2_re; | 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_, pos1_cu, pos1_re, projection.values); | ||||
| ED_view3d_project_float_v2_m4(region_, pos2_cu, pos2_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_); | const float dist_sq_re = dist_squared_to_line_segment_v3( | ||||
| if (dist <= brush_radius_re_) { | brush_pos_re_, pos1_re, pos2_re); | ||||
| if (dist_sq_re <= brush_radius_sq_re) { | |||||
JacquesLucke: Why is this using the 3d version of the function? | |||||
Done Inline ActionsCopy and paste, oops.. What do you think about having a BLI_math_geom.hh with distance_to_line_segment_sq(const T &segment_b, const T &segment_b, const T &point);? Should eliminate this mistake completely and work more nicely with C++ code. HooglyBoogly: Copy and paste, oops..
What do you think about having a `BLI_math_geom.hh` with… | |||||
Not Done Inline ActionsThat can be done separately. And I'd like to see a more clear plan for the naming of these functions. JacquesLucke: That can be done separately. And I'd like to see a more clear plan for the naming of these… | |||||
| curves_to_delete[curve_i] = true; | curves_to_delete[curve_i] = true; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| void delete_spherical_with_symmetry(MutableSpan<bool> curves_to_delete) | void delete_spherical_with_symmetry(MutableSpan<bool> curves_to_delete) | ||||
| { | { | ||||
| float4x4 projection; | float4x4 projection; | ||||
| ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); | ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); | ||||
| float3 brush_start_wo, brush_end_wo; | float3 brush_wo; | ||||
| ED_view3d_win_to_3d(v3d_, | |||||
| region_, | |||||
| curves_to_world_mat_ * self_->brush_3d_.position_cu, | |||||
| brush_pos_prev_re_, | |||||
| brush_start_wo); | |||||
| ED_view3d_win_to_3d(v3d_, | ED_view3d_win_to_3d(v3d_, | ||||
| region_, | region_, | ||||
| curves_to_world_mat_ * self_->brush_3d_.position_cu, | curves_to_world_mat_ * self_->brush_3d_.position_cu, | ||||
| brush_pos_re_, | brush_pos_re_, | ||||
| brush_end_wo); | brush_wo); | ||||
| const float3 brush_start_cu = world_to_curves_mat_ * brush_start_wo; | const float3 brush_cu = world_to_curves_mat_ * brush_wo; | ||||
| const float3 brush_end_cu = world_to_curves_mat_ * brush_end_wo; | |||||
| const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms( | const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms( | ||||
| eCurvesSymmetryType(curves_id_->symmetry)); | eCurvesSymmetryType(curves_id_->symmetry)); | ||||
| for (const float4x4 &brush_transform : symmetry_brush_transforms) { | for (const float4x4 &brush_transform : symmetry_brush_transforms) { | ||||
| this->delete_spherical( | this->delete_spherical(brush_transform * brush_cu, curves_to_delete); | ||||
| brush_transform * brush_start_cu, brush_transform * brush_end_cu, curves_to_delete); | |||||
| } | } | ||||
| } | } | ||||
| void delete_spherical(const float3 &brush_start_cu, | void delete_spherical(const float3 &brush_cu, MutableSpan<bool> curves_to_delete) | ||||
| const float3 &brush_end_cu, | |||||
| MutableSpan<bool> curves_to_delete) | |||||
| { | { | ||||
| Span<float3> positions_cu = curves_->positions(); | 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; | ||||
| const float brush_radius_sq_cu = pow2f(brush_radius_cu); | const float brush_radius_sq_cu = pow2f(brush_radius_cu); | ||||
| threading::parallel_for(curves_->curves_range(), 512, [&](IndexRange curve_range) { | threading::parallel_for(curves_->curves_range(), 512, [&](IndexRange curve_range) { | ||||
| for (const int curve_i : curve_range) { | for (const int curve_i : curve_range) { | ||||
| const IndexRange points = curves_->points_for_curve(curve_i); | const IndexRange points = curves_->points_for_curve(curve_i); | ||||
| for (const int segment_i : IndexRange(points.size() - 1)) { | for (const int segment_i : IndexRange(points.size() - 1)) { | ||||
| const float3 pos1_cu = positions_cu[points[segment_i]]; | const float3 pos1_cu = positions_cu[points[segment_i]]; | ||||
| const float3 pos2_cu = positions_cu[points[segment_i] + 1]; | const float3 pos2_cu = positions_cu[points[segment_i] + 1]; | ||||
| float3 closest_segment_cu, closest_brush_cu; | const float distance_sq_cu = dist_squared_to_line_segment_v3(brush_cu, pos1_cu, pos2_cu); | ||||
| isect_seg_seg_v3(pos1_cu, | if (distance_sq_cu > brush_radius_sq_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; | continue; | ||||
| } | } | ||||
| curves_to_delete[curve_i] = true; | curves_to_delete[curve_i] = true; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| Show All 24 Lines | |||||
Why is this using the 3d version of the function?