diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/curves_sculpt_comb.cc')
-rw-r--r-- | source/blender/editors/sculpt_paint/curves_sculpt_comb.cc | 117 |
1 files changed, 50 insertions, 67 deletions
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc index 1fcab2290e8..449f1786167 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc @@ -78,11 +78,7 @@ class CombOperation : public CurvesSculptStrokeOperation { */ struct CombOperationExecutor { CombOperation *self_ = nullptr; - const Depsgraph *depsgraph_ = nullptr; - const Scene *scene_ = nullptr; - ARegion *region_ = nullptr; - const View3D *v3d_ = nullptr; - const RegionView3D *rv3d_ = nullptr; + CurvesSculptCommonContext ctx_; const CurvesSculpt *curves_sculpt_ = nullptr; const Brush *brush_ = nullptr; @@ -96,21 +92,19 @@ struct CombOperationExecutor { Curves *curves_id_ = nullptr; CurvesGeometry *curves_ = nullptr; - const Object *surface_ob_ = nullptr; - const Mesh *surface_ = nullptr; - Span<MLoopTri> surface_looptris_; + VArray<float> point_factors_; + Vector<int64_t> selected_curve_indices_; + IndexMask curve_selection_; float2 brush_pos_prev_re_; float2 brush_pos_re_; float2 brush_pos_diff_re_; - float brush_pos_diff_length_re_; - float4x4 curves_to_world_mat_; - float4x4 world_to_curves_mat_; - float4x4 surface_to_world_mat_; - float4x4 world_to_surface_mat_; + CurvesSurfaceTransforms transforms_; - BVHTreeFromMesh surface_bvh_; + CombOperationExecutor(const bContext &C) : ctx_(C) + { + } void execute(CombOperation &self, const bContext &C, const StrokeExtension &stroke_extension) { @@ -118,21 +112,13 @@ struct CombOperationExecutor { BLI_SCOPED_DEFER([&]() { self_->brush_pos_last_re_ = stroke_extension.mouse_position; }); - depsgraph_ = CTX_data_depsgraph_pointer(&C); - scene_ = CTX_data_scene(&C); object_ = CTX_data_active_object(&C); - region_ = CTX_wm_region(&C); - v3d_ = CTX_wm_view3d(&C); - rv3d_ = CTX_wm_region_view3d(&C); - curves_sculpt_ = scene_->toolsettings->curves_sculpt; + curves_sculpt_ = ctx_.scene->toolsettings->curves_sculpt; brush_ = BKE_paint_brush_for_read(&curves_sculpt_->paint); - brush_radius_base_re_ = BKE_brush_size_get(scene_, brush_); + brush_radius_base_re_ = BKE_brush_size_get(ctx_.scene, brush_); brush_radius_factor_ = brush_radius_factor(*brush_, stroke_extension); - brush_strength_ = brush_strength_get(*scene_, *brush_, stroke_extension); - - curves_to_world_mat_ = object_->obmat; - world_to_curves_mat_ = curves_to_world_mat_.inverted(); + brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension); falloff_shape_ = static_cast<eBrushFalloffShape>(brush_->falloff_shape); @@ -142,26 +128,14 @@ struct CombOperationExecutor { return; } + transforms_ = CurvesSurfaceTransforms(*object_, curves_id_->surface); + + point_factors_ = get_point_selection(*curves_id_); + curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_); + brush_pos_prev_re_ = self_->brush_pos_last_re_; brush_pos_re_ = stroke_extension.mouse_position; brush_pos_diff_re_ = brush_pos_re_ - brush_pos_prev_re_; - brush_pos_diff_length_re_ = math::length(brush_pos_diff_re_); - - surface_ob_ = curves_id_->surface; - if (surface_ob_ != nullptr) { - surface_ = static_cast<const Mesh *>(surface_ob_->data); - surface_looptris_ = {BKE_mesh_runtime_looptri_ensure(surface_), - BKE_mesh_runtime_looptri_len(surface_)}; - surface_to_world_mat_ = surface_ob_->obmat; - world_to_surface_mat_ = surface_to_world_mat_.inverted(); - BKE_bvhtree_from_mesh_get(&surface_bvh_, surface_, BVHTREE_FROM_LOOPTRI, 2); - } - - BLI_SCOPED_DEFER([&]() { - if (surface_ob_ != nullptr) { - free_bvhtree_from_mesh(&surface_bvh_); - } - }); if (stroke_extension.is_first) { if (falloff_shape_ == PAINT_FALLOFF_SHAPE_SPHERE) { @@ -189,7 +163,7 @@ struct CombOperationExecutor { curves_->tag_positions_changed(); 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_); + ED_region_tag_redraw(ctx_.region); } /** @@ -212,14 +186,14 @@ struct CombOperationExecutor { MutableSpan<float3> positions_cu = curves_->positions_for_write(); float4x4 projection; - ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); + ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); 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(), 256, [&](const IndexRange curves_range) { + threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { Vector<int> &local_changed_curves = r_changed_curves.local(); - for (const int curve_i : curves_range) { + for (const int curve_i : curve_selection_.slice(range)) { bool curve_changed = false; const IndexRange points = curves_->points_for_curve(curve_i); for (const int point_i : points.drop_front(1)) { @@ -227,7 +201,7 @@ struct CombOperationExecutor { /* Find the position of the point in screen space. */ float2 old_pos_re; - ED_view3d_project_float_v2_m4(region_, old_pos_cu, old_pos_re, projection.values); + ED_view3d_project_float_v2_m4(ctx_.region, old_pos_cu, old_pos_re, projection.values); const float distance_to_brush_sq_re = dist_squared_to_line_segment_v2( old_pos_re, brush_pos_prev_re_, brush_pos_re_); @@ -241,15 +215,19 @@ struct CombOperationExecutor { const float radius_falloff = BKE_brush_curve_strength( brush_, distance_to_brush_re, brush_radius_re); /* Combine the falloff and brush strength. */ - const float weight = brush_strength_ * radius_falloff; + const float weight = brush_strength_ * radius_falloff * point_factors_[point_i]; - /* Offset the old point position in screen space and transform it back into 3D space. */ + /* Offset the old point position in screen space and transform it back into 3D space. + */ const float2 new_position_re = old_pos_re + brush_pos_diff_re_ * weight; float3 new_position_wo; - ED_view3d_win_to_3d( - v3d_, region_, curves_to_world_mat_ * old_pos_cu, new_position_re, new_position_wo); + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, + transforms_.curves_to_world * old_pos_cu, + new_position_re, + new_position_wo); const float3 new_position_cu = brush_transform * - (world_to_curves_mat_ * new_position_wo); + (transforms_.world_to_curves * new_position_wo); positions_cu[point_i] = new_position_cu; curve_changed = true; @@ -267,21 +245,21 @@ struct CombOperationExecutor { void comb_spherical_with_symmetry(EnumerableThreadSpecific<Vector<int>> &r_changed_curves) { float4x4 projection; - ED_view3d_ob_project_mat_get(rv3d_, object_, projection.values); + ED_view3d_ob_project_mat_get(ctx_.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, + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, + transforms_.curves_to_world * self_->brush_3d_.position_cu, brush_pos_prev_re_, brush_start_wo); - ED_view3d_win_to_3d(v3d_, - region_, - curves_to_world_mat_ * self_->brush_3d_.position_cu, + ED_view3d_win_to_3d(ctx_.v3d, + ctx_.region, + transforms_.curves_to_world * 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; + const float3 brush_start_cu = transforms_.world_to_curves * brush_start_wo; + const float3 brush_end_cu = transforms_.world_to_curves * brush_end_wo; const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_; @@ -304,9 +282,9 @@ struct CombOperationExecutor { const float brush_radius_sq_cu = pow2f(brush_radius_cu); const float3 brush_diff_cu = brush_end_cu - brush_start_cu; - threading::parallel_for(curves_->curves_range(), 256, [&](const IndexRange curves_range) { + threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { Vector<int> &local_changed_curves = r_changed_curves.local(); - for (const int curve_i : curves_range) { + for (const int curve_i : curve_selection_.slice(range)) { bool curve_changed = false; const IndexRange points = curves_->points_for_curve(curve_i); for (const int point_i : points.drop_front(1)) { @@ -326,7 +304,7 @@ struct CombOperationExecutor { const float radius_falloff = BKE_brush_curve_strength( brush_, distance_to_brush_cu, brush_radius_cu); /* Combine the falloff and brush strength. */ - const float weight = brush_strength_ * radius_falloff; + const float weight = brush_strength_ * radius_falloff * point_factors_[point_i]; /* Update the point position. */ positions_cu[point_i] = pos_old_cu + weight * brush_diff_cu; @@ -344,8 +322,13 @@ struct CombOperationExecutor { */ 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_base_re_); + std::optional<CurvesBrush3D> brush_3d = sample_curves_3d_brush(*ctx_.depsgraph, + *ctx_.region, + *ctx_.v3d, + *ctx_.rv3d, + *object_, + brush_pos_re_, + brush_radius_base_re_); if (brush_3d.has_value()) { self_->brush_3d_ = *brush_3d; } @@ -399,7 +382,7 @@ struct CombOperationExecutor { void CombOperation::on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) { - CombOperationExecutor executor; + CombOperationExecutor executor{C}; executor.execute(*this, C, stroke_extension); } |