49using blender::bke::CurvesGeometry;
144 const Span<float> segment_lengths =
self_->constraint_solver_.segment_lengths();
147 for (
const int curve_i : segment) {
148 const IndexRange points = points_by_curve[curve_i];
150 self_->curve_lengths_[curve_i] = std::accumulate(lengths.
begin(), lengths.
end(), 0.0f);
190 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
207 const float brush_radius_sq_re =
pow2f(brush_radius_re);
210 *
brush_->curves_sculpt_settings->curve_parameter_falloff;
213 const Span<float> segment_lengths =
self_->constraint_solver_.segment_lengths();
216 for (
const int curve_i : segment) {
217 bool curve_changed =
false;
218 const IndexRange points = points_by_curve[curve_i];
220 const float total_length =
self_->curve_lengths_[curve_i];
222 float current_length = 0.0f;
223 for (
const int point_i : points.
drop_front(1)) {
224 current_length += segment_lengths[point_i - 1];
231 ctx_.region, old_symm_pos_cu, projection);
235 if (distance_to_brush_sq_re > brush_radius_sq_re) {
240 const float distance_to_brush_re = std::sqrt(distance_to_brush_sq_re);
243 brush_, distance_to_brush_re, brush_radius_re);
244 const float curve_parameter = current_length * total_length_inv;
246 &curve_parameter_falloff_mapping, 0, curve_parameter);
248 const float weight =
brush_strength_ * curve_falloff * radius_falloff *
264 const float3 translation_eval = new_pos_cu - old_pos_cu;
266 point_i, translation_eval);
267 positions_cu_orig[point_i] += translation_orig;
269 curve_changed =
true;
272 r_changed_curves[curve_i] =
true;
283 float3 brush_start_wo, brush_end_wo;
304 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
313 const float3 &brush_start_cu,
314 const float3 &brush_end_cu,
315 const float brush_radius_cu)
318 const float brush_radius_sq_cu =
pow2f(brush_radius_cu);
319 const float3 brush_diff_cu = brush_end_cu - brush_start_cu;
322 *
brush_->curves_sculpt_settings->curve_parameter_falloff;
328 const Span<float> segment_lengths =
self_->constraint_solver_.segment_lengths();
331 for (
const int curve_i : segment) {
332 bool curve_changed =
false;
333 const IndexRange points = points_by_curve[curve_i];
335 const float total_length =
self_->curve_lengths_[curve_i];
337 float current_length = 0.0f;
338 for (
const int point_i : points.
drop_front(1)) {
339 current_length += segment_lengths[point_i - 1];
345 pos_old_cu, brush_start_cu, brush_end_cu);
346 if (distance_to_brush_sq_cu > brush_radius_sq_cu) {
351 const float distance_to_brush_cu = std::sqrt(distance_to_brush_sq_cu);
355 brush_, distance_to_brush_cu, brush_radius_cu);
356 const float curve_parameter = current_length * total_length_inv;
358 &curve_parameter_falloff_mapping, 0, curve_parameter);
360 const float weight =
brush_strength_ * curve_falloff * radius_falloff *
363 const float3 translation_eval_cu = weight * brush_diff_cu;
365 point_i, translation_eval_cu);
368 positions_cu[point_i] += translation_orig_cu;
369 curve_changed =
true;
372 r_changed_curves[curve_i] =
true;
390 if (brush_3d.has_value()) {
391 self_->brush_3d_ = *brush_3d;
402 executor.
execute(*
this,
C, stroke_extension);
407 return std::make_unique<CombOperation>();
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)
Object * CTX_data_active_object(const bContext *C)
Low-level operations for curves.
const Brush * BKE_paint_brush_for_read(const Paint *paint)
#define BLI_assert_unreachable()
MINLINE float pow2f(float x)
float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[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
Object is a sort of wrapper for general info.
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)
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
constexpr IndexRange drop_back(int64_t n) const
constexpr IndexRange drop_front(int64_t n) const
constexpr Span slice(int64_t start, int64_t size) const
constexpr const T * end() const
constexpr const T * begin() const
void on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) override
friend struct CombOperationExecutor
GeometryDeformation get_evaluated_curves_deformation(const Object *ob_eval, const Object &ob_orig)
IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves, IndexMaskMemory &memory)
std::unique_ptr< CurvesSculptStrokeOperation > new_comb_operation()
void remember_stroke_position(Scene &scene, const float3 &brush_position_wo)
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)
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)
CartesianBasis invert(const CartesianBasis &basis)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
MatBase< float, 4, 4 > float4x4
VecBase< float, 2 > float2
VecBase< float, 3 > float3
VArray< float > point_factors_
void comb_spherical_with_symmetry(MutableSpan< bool > r_changed_curves)
CombOperationExecutor(const bContext &C)
void initialize_spherical_brush_reference_point()
void comb_projected_with_symmetry(MutableSpan< bool > r_changed_curves)
IndexMask curve_selection_
float brush_radius_factor_
void comb_projected(MutableSpan< bool > r_changed_curves, const float4x4 &brush_transform)
IndexMaskMemory selected_curve_memory_
float brush_radius_base_re_
void comb_spherical(MutableSpan< bool > r_changed_curves, const float3 &brush_start_cu, const float3 &brush_end_cu, const float brush_radius_cu)
float2 brush_pos_prev_re_
CurvesGeometry * curves_orig_
CurvesSculptCommonContext ctx_
const CurvesSculpt * curves_sculpt_
void execute(CombOperation &self, const bContext &C, const StrokeExtension &stroke_extension)
float2 brush_pos_diff_re_
CurvesSurfaceTransforms transforms_
void initialize(const bke::CurvesGeometry &curves, const IndexMask &curve_selection, const bool use_surface_collision, const float surface_collision_distance)
void WM_main_add_notifier(uint type, void *reference)