154 return curve_weights[curve_i] > 0.0f;
157 this->
puff(curves_mask, curve_weights);
171 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
184 const float brush_radius_sq_re =
pow2f(brush_radius_re);
191 const IndexRange points = points_by_curve[curve_i];
193 deformation.positions[points[0]]);
195 float max_weight = 0.0f;
196 for (
const int point_i : points.drop_front(1)) {
198 deformation.positions[point_i]);
204 if (dist_to_brush_sq_re > brush_radius_sq_re) {
208 const float dist_to_brush_re = std::sqrt(dist_to_brush_sq_re);
210 brush_, dist_to_brush_re, brush_radius_re);
231 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
238 const float brush_radius_cu,
241 const float brush_radius_sq_cu =
pow2f(brush_radius_cu);
248 const IndexRange points = points_by_curve[curve_i];
249 float max_weight = 0.0f;
250 for (
const int point_i : points.drop_front(1)) {
251 const float3 &prev_pos_cu = deformation.positions[point_i - 1];
252 const float3 &pos_cu = deformation.positions[point_i];
254 brush_pos_cu, prev_pos_cu, pos_cu);
255 if (dist_to_brush_sq_cu > brush_radius_sq_cu) {
259 const float dist_to_brush_cu = std::sqrt(dist_to_brush_sq_cu);
261 brush_, dist_to_brush_cu, brush_radius_cu);
275 for (
const int curve_i : segment) {
276 const IndexRange points = points_by_curve[curve_i];
277 const int first_point_i = points[0];
278 const float3 first_pos_cu = positions_cu[first_point_i];
293 const float3 closest_pos_su = nearest.co;
304 accumulated_lengths_cu.
resize(points.size() - 1);
306 positions_cu.
slice(points),
false, accumulated_lengths_cu);
311 const int point_i = points[i];
312 const float3 old_pos_cu = positions_cu[point_i];
315 const float length_param_cu = accumulated_lengths_cu[i - 1];
316 const float3 goal_pos_cu = first_pos_cu + length_param_cu * normal_cu;
319 curve_weights[curve_i];
324 const float old_dist_to_root_cu =
math::distance(old_pos_cu, first_pos_cu);
325 const float new_dist_to_root_cu =
math::distance(new_pos_cu, first_pos_cu);
326 if (new_dist_to_root_cu < old_dist_to_root_cu) {
328 new_pos_cu += (old_dist_to_root_cu - new_dist_to_root_cu) * offset;
331 positions_cu[point_i] = new_pos_cu;
341 executor.
execute(*
this, C, stroke_extension);
346 return std::make_unique<PuffOperation>();
int BKE_brush_size_get(const Scene *scene, const Brush *brush)
float BKE_brush_curve_strength(eBrushCurvePreset preset, const CurveMapping *cumap, float distance, float brush_radius)
void free_bvhtree_from_mesh(BVHTreeFromMesh *data)
BVHTree * BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data, const Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
@ BVHTREE_FROM_CORNER_TRIS
Object * CTX_data_active_object(const bContext *C)
const Brush * BKE_paint_brush_for_read(const Paint *paint)
#define BLI_assert_unreachable()
int BLI_bvhtree_find_nearest(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
MINLINE float pow2f(float x)
float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3])
void interp_weights_tri_v3(float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3])
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
#define BLI_SCOPED_DEFER(function_to_defer)
void DEG_id_tag_update(ID *id, unsigned int flags)
@ PAINT_FALLOFF_SHAPE_SPHERE
@ PAINT_FALLOFF_SHAPE_TUBE
@ CV_SCULPT_COLLISION_ENABLED
void ED_region_tag_redraw(ARegion *region)
blender::float2 ED_view3d_project_float_v2_m4(const ARegion *region, const float co[3], const blender::float4x4 &mat)
void ED_view3d_win_to_3d(const View3D *v3d, const ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
blender::float4x4 ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, const Object *ob)
constexpr IndexRange drop_front(int64_t n) const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
void resize(const int64_t new_size)
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
MutableSpan< float3 > positions_for_write()
OffsetIndices< int > points_by_curve() const
void tag_positions_changed()
AttributeAccessor attributes() const
const Depsgraph * depsgraph
void on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) override
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
void foreach_index(Fn &&fn) const
GeometryDeformation get_evaluated_curves_deformation(const Object *ob_eval, const Object &ob_orig)
IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves, IndexMaskMemory &memory)
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)
void report_missing_surface(ReportList *reports)
float brush_strength_get(const Scene &scene, const Brush &brush, const StrokeExtension &stroke_extension)
Vector< float4x4 > get_symmetry_brush_transforms(const eCurvesSymmetryType symmetry)
std::unique_ptr< CurvesSculptStrokeOperation > new_puff_operation()
float brush_radius_factor(const Brush &brush, const StrokeExtension &stroke_extension)
float3 compute_surface_point_normal(const int3 &tri, const float3 &bary_coord, Span< float3 > corner_normals)
void accumulate_lengths(const Span< T > values, const bool cyclic, MutableSpan< float > lengths)
T distance(const T &a, const T &b)
CartesianBasis invert(const CartesianBasis &basis)
T interpolate(const T &a, const T &b, const FactorT &t)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
void max_inplace(T &a, const T &b)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
BVHTree_NearestPointCallback nearest_callback
struct ToolSettings * toolsettings
void solve_step(bke::CurvesGeometry &curves, const IndexMask &curve_selection, const Mesh *surface, const CurvesSurfaceTransforms &transforms)
void initialize(const bke::CurvesGeometry &curves, const IndexMask &curve_selection, const bool use_surface_collision)
void execute(PuffOperation &self, const bContext &C, const StrokeExtension &stroke_extension)
PuffOperationExecutor(const bContext &C)
void find_curve_weights_projected_with_symmetry(MutableSpan< float > r_curve_weights)
float brush_radius_factor_
CurvesSculptCommonContext ctx_
Span< int > surface_corner_verts_
Span< float3 > surface_positions_
Span< int3 > surface_corner_tris_
void find_curves_weights_spherical_with_symmetry(MutableSpan< float > r_curve_weights)
const Object * surface_ob_
void puff(const IndexMask &selection, const Span< float > curve_weights)
const CurvesSculpt * curves_sculpt_
Span< float3 > corner_normals_su_
IndexMask curve_selection_
IndexMaskMemory selected_curve_memory_
void find_curves_weights_spherical(const float3 &brush_pos_cu, const float brush_radius_cu, MutableSpan< float > r_curve_weights)
VArray< float > point_factors_
CurvesSurfaceTransforms transforms_
float brush_radius_base_re_
void find_curve_weights_projected(const float4x4 &brush_transform, MutableSpan< float > r_curve_weights)
BVHTreeFromMesh surface_bvh_
void WM_main_add_notifier(uint type, void *reference)