diff options
author | Jacques Lucke <jacques@blender.org> | 2022-06-20 17:27:42 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2022-06-20 17:27:57 +0300 |
commit | d2e4bd79950f4e600f9e90ae7b58104be8b13801 (patch) | |
tree | 7038fac630755a917ae5c25bc9f8123e730ddc6a /source/blender/editors | |
parent | af983a3eef495e14a24c2063f743765d988d27d3 (diff) |
Curves: extract surface brush sampling into separate function
This functionality will also be necessary in the Density brush.
Diffstat (limited to 'source/blender/editors')
3 files changed, 106 insertions, 52 deletions
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc index 7469c69e40b..bac03de77e7 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc @@ -334,73 +334,47 @@ struct AddOperationExecutor { */ void sample_spherical_with_symmetry(RandomNumberGenerator &rng, AddedPoints &r_added_points) { - /* Find ray that starts in the center of the brush. */ - float3 brush_ray_start_wo, brush_ray_end_wo; - ED_view3d_win_to_segment_clipped(ctx_.depsgraph, - ctx_.region, - ctx_.v3d, - brush_pos_re_, - brush_ray_start_wo, - brush_ray_end_wo, - true); - const float3 brush_ray_start_cu = transforms_.world_to_curves * brush_ray_start_wo; - const float3 brush_ray_end_cu = transforms_.world_to_curves * brush_ray_end_wo; + const std::optional<CurvesBrush3D> brush_3d = sample_curves_surface_3d_brush(*ctx_.depsgraph, + *ctx_.region, + *ctx_.v3d, + transforms_, + surface_bvh_, + brush_pos_re_, + brush_radius_re_); + if (!brush_3d.has_value()) { + return; + } - /* Find ray that starts on the boundary of the brush. That is used to compute the brush radius - * in 3D. */ - float3 brush_radius_ray_start_wo, brush_radius_ray_end_wo; + float3 view_ray_start_wo, view_ray_end_wo; ED_view3d_win_to_segment_clipped(ctx_.depsgraph, ctx_.region, ctx_.v3d, - brush_pos_re_ + float2(brush_radius_re_, 0), - brush_radius_ray_start_wo, - brush_radius_ray_end_wo, + brush_pos_re_, + view_ray_start_wo, + view_ray_end_wo, true); - const float3 brush_radius_ray_start_cu = transforms_.world_to_curves * - brush_radius_ray_start_wo; - const float3 brush_radius_ray_end_cu = transforms_.world_to_curves * brush_radius_ray_end_wo; + const float3 view_direction_su = math::normalize( + transforms_.world_to_surface * view_ray_end_wo - + transforms_.world_to_surface * view_ray_start_wo); const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms( eCurvesSymmetryType(curves_id_->symmetry)); for (const float4x4 &brush_transform : symmetry_brush_transforms) { const float4x4 transform = transforms_.curves_to_surface * brush_transform; - this->sample_spherical(rng, - r_added_points, - transform * brush_ray_start_cu, - transform * brush_ray_end_cu, - transform * brush_radius_ray_start_cu, - transform * brush_radius_ray_end_cu); + const float3 brush_pos_su = transform * brush_3d->position_cu; + const float brush_radius_su = transform_brush_radius( + transform, brush_3d->position_cu, brush_3d->radius_cu); + this->sample_spherical( + rng, r_added_points, brush_pos_su, brush_radius_su, view_direction_su); } } void sample_spherical(RandomNumberGenerator &rng, AddedPoints &r_added_points, - const float3 &brush_ray_start_su, - const float3 &brush_ray_end_su, - const float3 &brush_radius_ray_start_su, - const float3 &brush_radius_ray_end_su) + const float3 &brush_pos_su, + const float brush_radius_su, + const float3 &view_direction_su) { - const float3 brush_ray_direction_su = math::normalize(brush_ray_end_su - brush_ray_start_su); - - BVHTreeRayHit ray_hit; - ray_hit.dist = FLT_MAX; - ray_hit.index = -1; - BLI_bvhtree_ray_cast(surface_bvh_.tree, - brush_ray_start_su, - brush_ray_direction_su, - 0.0f, - &ray_hit, - surface_bvh_.raycast_callback, - &surface_bvh_); - - if (ray_hit.index == -1) { - return; - } - - /* Compute brush radius. */ - const float3 brush_pos_su = ray_hit.co; - const float brush_radius_su = dist_to_line_v3( - brush_pos_su, brush_radius_ray_start_su, brush_radius_ray_end_su); const float brush_radius_sq_su = pow2f(brush_radius_su); /* Find surface triangles within brush radius. */ @@ -417,7 +391,7 @@ struct AddOperationExecutor { const float3 v2_su = surface_->mvert[surface_->mloop[looptri.tri[2]].v].co; float3 normal_su; normal_tri_v3(normal_su, v0_su, v1_su, v2_su); - if (math::dot(normal_su, brush_ray_direction_su) >= 0.0f) { + if (math::dot(normal_su, view_direction_su) >= 0.0f) { return; } looptri_indices.append(index); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc index 5955c349eae..8c6ef34ef26 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc @@ -256,6 +256,55 @@ std::optional<CurvesBrush3D> sample_curves_3d_brush(const Depsgraph &depsgraph, return brush_3d; } +std::optional<CurvesBrush3D> sample_curves_surface_3d_brush( + const Depsgraph &depsgraph, + const ARegion ®ion, + const View3D &v3d, + const CurvesSculptTransforms &transforms, + const BVHTreeFromMesh &surface_bvh, + const float2 &brush_pos_re, + const float brush_radius_re) +{ + float3 brush_ray_start_wo, brush_ray_end_wo; + ED_view3d_win_to_segment_clipped( + &depsgraph, ®ion, &v3d, brush_pos_re, brush_ray_start_wo, brush_ray_end_wo, true); + const float3 brush_ray_start_su = transforms.world_to_surface * brush_ray_start_wo; + const float3 brush_ray_end_su = transforms.world_to_surface * brush_ray_end_wo; + + const float3 brush_ray_direction_su = math::normalize(brush_ray_end_su - brush_ray_start_su); + + BVHTreeRayHit ray_hit; + ray_hit.dist = FLT_MAX; + ray_hit.index = -1; + BLI_bvhtree_ray_cast(surface_bvh.tree, + brush_ray_start_su, + brush_ray_direction_su, + 0.0f, + &ray_hit, + surface_bvh.raycast_callback, + const_cast<void *>(static_cast<const void *>(&surface_bvh))); + if (ray_hit.index == -1) { + return std::nullopt; + } + + float3 brush_radius_ray_start_wo, brush_radius_ray_end_wo; + ED_view3d_win_to_segment_clipped(&depsgraph, + ®ion, + &v3d, + brush_pos_re + float2(brush_radius_re, 0), + brush_radius_ray_start_wo, + brush_radius_ray_end_wo, + true); + const float3 brush_radius_ray_start_cu = transforms.world_to_curves * brush_radius_ray_start_wo; + const float3 brush_radius_ray_end_cu = transforms.world_to_curves * brush_radius_ray_end_wo; + + const float3 brush_pos_su = ray_hit.co; + const float3 brush_pos_cu = transforms.surface_to_curves * brush_pos_su; + const float brush_radius_cu = dist_to_line_v3( + brush_pos_cu, brush_radius_ray_start_cu, brush_radius_ray_end_cu); + return CurvesBrush3D{brush_pos_cu, brush_radius_cu}; +} + Vector<float4x4> get_symmetry_brush_transforms(const eCurvesSymmetryType symmetry) { Vector<float4x4> matrices; @@ -284,6 +333,16 @@ Vector<float4x4> get_symmetry_brush_transforms(const eCurvesSymmetryType symmetr return matrices; } +float transform_brush_radius(const float4x4 &transform, + const float3 &brush_position, + const float old_radius) +{ + const float3 offset_position = brush_position + float3(old_radius, 0.0f, 0.0f); + const float3 new_position = transform * brush_position; + const float3 new_offset_position = transform * offset_position; + return math::distance(new_position, new_offset_position); +} + void move_last_point_and_resample(MutableSpan<float3> positions, const float3 &new_last_position) { /* Find the accumulated length of each point in the original curve, diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh index ce84d94fbd5..ad3871bee45 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh @@ -21,6 +21,7 @@ struct View3D; struct Object; struct Brush; struct Scene; +struct BVHTreeFromMesh; namespace blender::ed::sculpt_paint { @@ -60,6 +61,13 @@ std::unique_ptr<CurvesSculptStrokeOperation> new_grow_shrink_operation( const BrushStrokeMode brush_mode, const bContext &C); std::unique_ptr<CurvesSculptStrokeOperation> new_selection_paint_operation( const BrushStrokeMode brush_mode, const bContext &C); +std::unique_ptr<CurvesSculptStrokeOperation> new_pinch_operation(const BrushStrokeMode brush_mode, + const bContext &C); +std::unique_ptr<CurvesSculptStrokeOperation> new_smooth_operation(); +std::unique_ptr<CurvesSculptStrokeOperation> new_puff_operation(); +std::unique_ptr<CurvesSculptStrokeOperation> new_density_operation( + const BrushStrokeMode brush_mode, const bContext &C); +std::unique_ptr<CurvesSculptStrokeOperation> new_slide_operation(); struct CurvesBrush3D { float3 position_cu; @@ -121,4 +129,17 @@ struct CurvesSculptTransforms { CurvesSculptTransforms(const Object &curves_ob, const Object *surface_ob); }; +std::optional<CurvesBrush3D> sample_curves_surface_3d_brush( + const Depsgraph &depsgraph, + const ARegion ®ion, + const View3D &v3d, + const CurvesSculptTransforms &transforms, + const BVHTreeFromMesh &surface_bvh, + const float2 &brush_pos_re, + const float brush_radius_re); + +float transform_brush_radius(const float4x4 &transform, + const float3 &brush_position, + const float old_radius); + } // namespace blender::ed::sculpt_paint |