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:
authorJacques Lucke <jacques@blender.org>2022-06-20 17:27:42 +0300
committerJacques Lucke <jacques@blender.org>2022-06-20 17:27:57 +0300
commitd2e4bd79950f4e600f9e90ae7b58104be8b13801 (patch)
tree7038fac630755a917ae5c25bc9f8123e730ddc6a /source/blender
parentaf983a3eef495e14a24c2063f743765d988d27d3 (diff)
Curves: extract surface brush sampling into separate function
This functionality will also be necessary in the Density brush.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_add.cc78
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_brush.cc59
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_intern.hh21
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 &region,
+ 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, &region, &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,
+ &region,
+ &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 &region,
+ 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