53 const float3 &ray_start_cu,
55 const float brush_radius_re,
62 const float brush_inner_radius_re = std::min<float>(brush_radius_re,
float(
UI_UNIT_X) / 3.0f);
63 const float brush_inner_radius_sq_re =
pow2f(brush_inner_radius_re);
73 if (
b.distance_sq_re <= brush_inner_radius_sq_re) {
91 if (is_better_candidate(a,
b)) {
105 for (
const int curve_i : curves_range) {
106 const IndexRange points = points_by_curve[curve_i];
108 if (points.
size() == 1) {
112 if (depth_sq_cu > max_depth_sq_cu) {
123 update_if_better(best_candidate, candidate);
127 for (
const int segment_i : points.
drop_back(1)) {
128 const float3 &p1_cu = positions[segment_i];
129 const float3 &p2_cu = positions[segment_i + 1];
136 closest_re, brush_pos_re, p1_re, p2_re);
140 if (depth_sq_cu > max_depth_sq_cu) {
154 update_if_better(best_candidate, candidate);
157 return best_candidate;
160 return is_better_candidate(a,
b) ?
b : a;
175 const Object &curves_object,
176 const float2 &brush_pos_re,
177 const float brush_radius_re)
184 float3 center_ray_start_wo, center_ray_end_wo;
186 &
depsgraph, ®ion, &v3d, brush_pos_re, center_ray_start_wo, center_ray_end_wo,
true);
189 if (surface_object_eval !=
nullptr) {
190 const float4x4 surface_to_world_mat(surface_object->object_to_world().ptr());
197 center_ray_start_wo);
200 center_ray_start_su);
204 center_ray_hit.
index = -1;
207 center_ray_direction_su,
212 if (center_ray_hit.
index >= 0) {
213 const float3 hit_position_su = center_ray_hit.
co;
217 center_ray_end_su = hit_position_su;
223 const float4x4 &curves_to_world_mat = curves_object.object_to_world();
227 center_ray_start_wo);
242 if (!brush_position_optional_cu.has_value()) {
246 const float3 brush_position_cu = *brush_position_optional_cu;
249 float3 radius_ray_start_wo, radius_ray_end_wo;
253 brush_pos_re +
float2(brush_radius_re, 0.0f),
258 radius_ray_start_wo);
273 const float2 &brush_pos_re,
274 const float brush_radius_re)
276 float3 brush_ray_start_wo, brush_ray_end_wo;
278 &
depsgraph, ®ion, &v3d, brush_pos_re, brush_ray_start_wo, brush_ray_end_wo,
true);
291 brush_ray_direction_su,
295 const_cast<void *
>(
static_cast<const void *
>(&surface_bvh)));
296 if (ray_hit.
index == -1) {
300 float3 brush_radius_ray_start_wo, brush_radius_ray_end_wo;
304 brush_pos_re +
float2(brush_radius_re, 0),
305 brush_radius_ray_start_wo,
306 brush_radius_ray_end_wo,
309 brush_radius_ray_start_wo);
311 brush_radius_ray_end_wo);
313 const float3 brush_pos_su = ray_hit.
co;
316 brush_pos_cu, brush_radius_ray_start_cu, brush_radius_ray_end_cu);
325 if (symmetry & type) {
326 static std::array<float, 2> values = {1.0f, -1.0f};
329 static std::array<float, 1> values = {1.0f};
337 matrix.
ptr()[0][0] =
x;
338 matrix.
ptr()[1][1] =
y;
339 matrix.
ptr()[2][2] =
z;
357 const float3 &brush_position,
358 const float old_radius)
360 const float3 offset_position = brush_position +
float3(old_radius, 0.0f, 0.0f);
368 const float3 &new_last_position)
377 const float new_last_segment_length =
math::distance(positions.
last(1), new_last_position);
378 const float new_total_length = buffer.
orig_lengths.
last(1) + new_last_segment_length;
379 const float length_factor =
math::safe_divide(new_total_length, orig_total_length);
397 positions.
last() = new_last_position;
441 const bool use_surface_collision,
442 const float surface_collision_distance)
444 use_surface_collision_ = use_surface_collision;
445 surface_collision_distance_ = surface_collision_distance;
446 segment_lengths_.reinitialize(
curves.points_num());
448 curves.points_by_curve(),
curves.positions(), curve_selection, segment_lengths_);
449 if (use_surface_collision_) {
450 start_positions_ =
curves.positions();
459 if (use_surface_collision_ && surface !=
nullptr) {
467 curves.positions_for_write(),
468 surface_collision_distance_);
469 start_positions_ =
curves.positions();
473 curves.points_by_curve(), curve_selection, segment_lengths_,
curves.positions_for_write());
475 curves.tag_positions_changed();
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
Low-level operations for curves.
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
void BKE_report(ReportList *reports, eReportType type, const char *message)
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
MINLINE float pow2f(float x)
float closest_to_line_segment_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3])
float closest_to_line_segment_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2])
float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
blender::float2 ED_view3d_project_float_v2_m4(const ARegion *region, const float co[3], const blender::float4x4 &mat)
blender::float4x4 ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, const Object *ob)
bool ED_view3d_win_to_segment_clipped(const Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_end[3], bool do_clip_planes)
BPy_StructRNA * depsgraph
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
const T & last(const int64_t n=0) const
IndexRange index_range() const
void resize(const int64_t new_size)
constexpr int64_t first() const
constexpr IndexRange drop_back(int64_t n) const
constexpr int64_t size() const
constexpr IndexRange drop_front(int64_t n) const
constexpr int64_t size() const
constexpr MutableSpan drop_back(const int64_t n) const
constexpr void copy_from(Span< T > values) const
constexpr T & last(const int64_t n=0) const
void append(const T &value)
void resize(const int64_t new_size)
const Depsgraph * depsgraph
CurvesSculptCommonContext(const bContext &C)
GeometryDeformation get_evaluated_curves_deformation(const Object *ob_eval, const Object &ob_orig)
void report_invalid_uv_map(ReportList *reports)
void report_empty_evaluated_surface(ReportList *reports)
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)
void report_missing_uv_map_on_original_surface(ReportList *reports)
void report_missing_uv_map_on_evaluated_surface(ReportList *reports)
void report_missing_surface(ReportList *reports)
std::optional< CurvesBrush3D > sample_curves_surface_3d_brush(const Depsgraph &depsgraph, const ARegion ®ion, const View3D &v3d, const CurvesSurfaceTransforms &transforms, const bke::BVHTreeFromMesh &surface_bvh, const float2 &brush_pos_re, const float brush_radius_re)
void report_empty_original_surface(ReportList *reports)
static std::optional< float3 > find_curves_brush_position(const CurvesGeometry &curves, const float3 &ray_start_cu, const float3 &ray_end_cu, const float brush_radius_re, const ARegion ®ion, const RegionView3D &rv3d, const Object &object, const Span< float3 > positions)
Vector< float4x4 > get_symmetry_brush_transforms(const eCurvesSymmetryType symmetry)
void move_last_point_and_resample(MoveAndResampleBuffers &buffer, MutableSpan< float3 > positions, const float3 &new_last_position)
float transform_brush_radius(const float4x4 &transform, const float3 &brush_position, const float old_radius)
void solve_length_and_collision_constraints(OffsetIndices< int > points_by_curve, const IndexMask &curve_selection, Span< float > segment_lengths, Span< float3 > start_positions, const Mesh &surface, const bke::CurvesSurfaceTransforms &transforms, MutableSpan< float3 > positions, const float surface_collision_distance)
void solve_length_constraints(OffsetIndices< int > points_by_curve, const IndexMask &curve_selection, Span< float > segment_lenghts, MutableSpan< float3 > positions)
void compute_segment_lengths(OffsetIndices< int > points_by_curve, Span< float3 > positions, const IndexMask &curve_selection, MutableSpan< float > r_segment_lengths)
int segments_num(const int points_num, const bool cyclic)
void accumulate_lengths(const Span< T > values, const bool cyclic, MutableSpan< float > lengths)
void sample_at_lengths(Span< float > accumulated_segment_lengths, Span< float > sample_lengths, MutableSpan< int > r_segment_indices, MutableSpan< float > r_factors)
void interpolate(const Span< T > src, const Span< int > indices, const Span< float > factors, MutableSpan< T > dst)
T safe_divide(const T &a, const T &b)
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)
T distance_squared(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
MatBase< float, 4, 4 > float4x4
VecBase< float, 2 > float2
VecBase< float, 3 > float3
static void init(bNodeTree *, bNode *node)
struct ToolSettings * toolsettings
float average_stroke_accum[3]
int average_stroke_counter
const c_style_mat & ptr() const
static MatBase identity()
BVHTree_RayCastCallback raycast_callback
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, const float surface_collision_distance)
Vector< float3 > new_positions
Vector< int > sample_indices
Vector< float > orig_lengths
Vector< float > new_lengths
Vector< float > sample_factors