111 this->
smooth(point_smooth_factors);
122 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
133 const float brush_radius_sq_re =
pow2f(brush_radius_re);
142 for (const int curve_i : curve_selection_.slice(range)) {
143 const IndexRange points = curves_->points_for_curve(curve_i);
144 for (const int point_i : points) {
145 const float3 &pos_cu = brush_transform_inv * deformation.positions[point_i];
147 ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.values);
148 const float dist_to_brush_sq_re = math::distance_squared(pos_re, brush_pos_re_);
149 if (dist_to_brush_sq_re > brush_radius_sq_re) {
153 const float dist_to_brush_re = std::sqrt(dist_to_brush_sq_re);
154 const float radius_falloff = BKE_brush_curve_strength(
155 brush_, dist_to_brush_re, brush_radius_re);
158 const float weight_factor = 0.1f;
159 const float weight = weight_factor * brush_strength_ * radius_falloff *
160 point_factors_[point_i];
161 math::max_inplace(r_point_smooth_factors[point_i], weight);
175 transforms_.curves_to_world * self_->brush_3d_.position_cu,
178 const float3 brush_pos_cu = transforms_.world_to_curves * brush_pos_wo;
179 const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_;
183 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
184 this->find_spherical_smooth_factors(
185 brush_transform * brush_pos_cu, brush_radius_cu, r_point_smooth_factors);
190 const float brush_radius_cu,
193 const float brush_radius_sq_cu =
pow2f(brush_radius_cu);
198 for (const int curve_i : curve_selection_.slice(range)) {
199 const IndexRange points = curves_->points_for_curve(curve_i);
200 for (const int point_i : points) {
201 const float3 &pos_cu = deformation.positions[point_i];
202 const float dist_to_brush_sq_cu = math::distance_squared(pos_cu, brush_pos_cu);
203 if (dist_to_brush_sq_cu > brush_radius_sq_cu) {
207 const float dist_to_brush_cu = std::sqrt(dist_to_brush_sq_cu);
208 const float radius_falloff = BKE_brush_curve_strength(
209 brush_, dist_to_brush_cu, brush_radius_cu);
212 const float weight_factor = 0.1f;
213 const float weight = weight_factor * brush_strength_ * radius_falloff *
214 point_factors_[point_i];
215 math::max_inplace(r_point_smooth_factors[point_i], weight);
225 Vector<float3> old_positions;
226 for (const int curve_i : curve_selection_.slice(range)) {
227 const IndexRange points = curves_->points_for_curve(curve_i);
228 old_positions.clear();
229 old_positions.extend(positions.slice(points));
230 for (const int i : IndexRange(points.size()).drop_front(1).drop_back(1)) {
231 const int point_i = points[i];
232 const float smooth_factor = point_smooth_factors[point_i];
233 if (smooth_factor == 0.0f) {
237 const float3 old_pos = old_positions[i];
238 const float3 &prev_pos = old_positions[i - 1];
239 const float3 &next_pos = old_positions[i + 1];
240 const float3 goal_pos = math::midpoint(prev_pos, next_pos);
241 const float3 new_pos = math::interpolate(old_pos, goal_pos, smooth_factor);
242 positions[point_i] = new_pos;
249 void SmoothOperation::on_stroke_extended(
const bContext &
C,
253 executor.execute(*
this,
C, stroke_extension);
258 return std::make_unique<SmoothOperation>();
int BKE_brush_size_get(const struct Scene *scene, const struct Brush *brush)
struct Object * CTX_data_active_object(const bContext *C)
const struct Brush * BKE_paint_brush_for_read(const struct Paint *p)
#define BLI_assert_unreachable()
MINLINE float pow2f(float x)
void DEG_id_tag_update(struct ID *id, int flag)
@ PAINT_FALLOFF_SHAPE_SPHERE
@ PAINT_FALLOFF_SHAPE_TUBE
void ED_region_tag_redraw(struct ARegion *region)
void ED_view3d_ob_project_mat_get(const struct RegionView3D *v3d, const struct Object *ob, float r_pmat[4][4])
void ED_view3d_win_to_3d(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
IndexRange index_range() const
static CurvesGeometry & wrap(::CurvesGeometry &dna_struct)
void tag_positions_changed()
const Depsgraph * depsgraph
void on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) override
GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph, const Object &ob_orig)
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)
VArray< float > get_point_selection(const Curves &curves_id)
std::unique_ptr< CurvesSculptStrokeOperation > new_smooth_operation()
static IndexMask retrieve_selected_curves(const CurvesGeometry &curves, const eAttrDomain domain, Vector< int64_t > &r_indices)
float brush_strength_get(const Scene &scene, const Brush &brush, const StrokeExtension &stroke_extension)
Vector< float4x4 > get_symmetry_brush_transforms(const eCurvesSymmetryType symmetry)
float brush_radius_factor(const Brush &brush, const StrokeExtension &stroke_extension)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
MutableSpan< float3 > positions
struct ToolSettings * toolsettings
void find_spherical_smooth_factors(const float3 &brush_pos_cu, const float brush_radius_cu, MutableSpan< float > r_point_smooth_factors)
void find_projected_smooth_factors(const float4x4 &brush_transform, MutableSpan< float > r_point_smooth_factors)
VArray< float > point_factors_
float brush_radius_base_re_
const CurvesSculpt * curves_sculpt_
IndexMask curve_selection_
CurvesSculptCommonContext ctx_
CurvesSurfaceTransforms transforms_
Vector< int64_t > selected_curve_indices_
void smooth(const Span< float > point_smooth_factors)
void execute(SmoothOperation &self, const bContext &C, const StrokeExtension &stroke_extension)
void find_spherical_smooth_factors_with_symmetry(MutableSpan< float > r_point_smooth_factors)
SmoothOperationExecutor(const bContext &C)
float brush_radius_factor_
void find_projected_smooth_factors_with_symmetry(MutableSpan< float > r_point_smooth_factors)
float4x4 inverted() const
void WM_main_add_notifier(unsigned int type, void *reference)