52 const float3 &ray_start_cu,
54 const float brush_radius_re,
61 const float brush_inner_radius_re = std::min<float>(brush_radius_re,
float(
UI_UNIT_X) / 3.0f);
62 const float brush_inner_radius_sq_re =
pow2f(brush_inner_radius_re);
72 if (
b.distance_sq_re <= brush_inner_radius_sq_re) {
73 if (a.distance_sq_re > brush_inner_radius_sq_re) {
77 if (
b.depth_sq_cu < a.depth_sq_cu) {
82 else if (
b.distance_sq_re < a.distance_sq_re) {
90 if (is_better_candidate(a,
b)) {
95 const OffsetIndices points_by_curve = curves.points_by_curve();
98 curves.curves_range(),
104 for (
const int curve_i : curves_range) {
105 const IndexRange points = points_by_curve[curve_i];
107 if (points.size() == 1) {
108 const float3 &pos_cu = positions[points.first()];
111 if (depth_sq_cu > max_depth_sq_cu) {
122 update_if_better(best_candidate, candidate);
126 for (
const int segment_i : points.drop_back(1)) {
127 const float3 &p1_cu = positions[segment_i];
128 const float3 &p2_cu = positions[segment_i + 1];
135 closest_re, brush_pos_re, p1_re, p2_re);
139 if (depth_sq_cu > max_depth_sq_cu) {
153 update_if_better(best_candidate, candidate);
156 return best_candidate;
159 return is_better_candidate(a,
b) ?
b : a;
174 const Object &curves_object,
175 const float2 &brush_pos_re,
176 const float brush_radius_re)
183 float3 center_ray_start_wo, center_ray_end_wo;
185 &
depsgraph, ®ion, &v3d, brush_pos_re, center_ray_start_wo, center_ray_end_wo,
true);
188 if (surface_object_eval !=
nullptr) {
189 const float4x4 surface_to_world_mat(surface_object->object_to_world().ptr());
198 center_ray_start_wo);
201 center_ray_start_su);
205 center_ray_hit.
index = -1;
208 center_ray_direction_su,
213 if (center_ray_hit.
index >= 0) {
214 const float3 hit_position_su = center_ray_hit.
co;
218 center_ray_end_su = hit_position_su;
224 const float4x4 &curves_to_world_mat = curves_object.object_to_world();
228 center_ray_start_wo);
242 deformation.positions);
243 if (!brush_position_optional_cu.has_value()) {
247 const float3 brush_position_cu = *brush_position_optional_cu;
250 float3 radius_ray_start_wo, radius_ray_end_wo;
254 brush_pos_re +
float2(brush_radius_re, 0.0f),
259 radius_ray_start_wo);
274 const float2 &brush_pos_re,
275 const float brush_radius_re)
277 float3 brush_ray_start_wo, brush_ray_end_wo;
279 &
depsgraph, ®ion, &v3d, brush_pos_re, brush_ray_start_wo, brush_ray_end_wo,
true);
292 brush_ray_direction_su,
296 const_cast<void *
>(
static_cast<const void *
>(&surface_bvh)));
297 if (ray_hit.
index == -1) {
301 float3 brush_radius_ray_start_wo, brush_radius_ray_end_wo;
305 brush_pos_re +
float2(brush_radius_re, 0),
306 brush_radius_ray_start_wo,
307 brush_radius_ray_end_wo,
310 brush_radius_ray_start_wo);
312 brush_radius_ray_end_wo);
314 const float3 brush_pos_su = ray_hit.
co;
317 brush_pos_cu, brush_radius_ray_start_cu, brush_radius_ray_end_cu);
326 if (symmetry & type) {
327 static std::array<float, 2> values = {1.0f, -1.0f};
330 static std::array<float, 1> values = {1.0f};
338 matrix.ptr()[0][0] =
x;
339 matrix.ptr()[1][1] =
y;
340 matrix.ptr()[2][2] =
z;
350 const float3 &brush_position,
351 const float old_radius)
353 const float3 offset_position = brush_position +
float3(old_radius, 0.0f, 0.0f);
361 const float3 &new_last_position)
370 const float new_last_segment_length =
math::distance(positions.last(1), new_last_position);
371 const float new_total_length = buffer.
orig_lengths.
last(1) + new_last_segment_length;
372 const float length_factor =
math::safe_divide(new_total_length, orig_total_length);
390 positions.last() = new_last_position;
434 const bool use_surface_collision)
436 use_surface_collision_ = use_surface_collision;
439 curves.points_by_curve(), curves.positions(), curve_selection, segment_lengths_);
440 if (use_surface_collision_) {
441 start_positions_ = curves.positions();
450 if (use_surface_collision_ && surface !=
nullptr) {
452 curves.points_by_curve(),
458 curves.positions_for_write());
459 start_positions_ = curves.positions();
463 curves.points_by_curve(), curve_selection, segment_lengths_, curves.positions_for_write());
465 curves.tag_positions_changed();
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
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])
#define BLI_SCOPED_DEFER(function_to_defer)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
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)
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
void reinitialize(const int64_t new_size)
constexpr IndexRange drop_front(int64_t n) const
void append(const T &value)
const T & last(const int64_t n=0) const
IndexRange index_range() const
void resize(const int64_t new_size)
const Depsgraph * depsgraph
CurvesSculptCommonContext(const bContext &C)
local_group_size(16, 16) .push_constant(Type b
const Depsgraph * depsgraph
GeometryDeformation get_evaluated_curves_deformation(const Object *ob_eval, const Object &ob_orig)
std::optional< CurvesBrush3D > sample_curves_surface_3d_brush(const Depsgraph &depsgraph, const ARegion ®ion, const View3D &v3d, const CurvesSurfaceTransforms &transforms, const BVHTreeFromMesh &surface_bvh, const float2 &brush_pos_re, const float brush_radius_re)
void report_invalid_uv_map(ReportList *reports)
void report_empty_evaluated_surface(ReportList *reports)
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)
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_constraints(OffsetIndices< int > points_by_curve, const IndexMask &curve_selection, Span< float > segment_lenghts, MutableSpan< float3 > positions)
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)
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)
VecBase< float, 2 > float2
VecBase< float, 3 > float3
BVHTree_RayCastCallback raycast_callback
static MatBase identity()
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)
Vector< float3 > new_positions
Vector< int > sample_indices
Vector< float > orig_lengths
Vector< float > new_lengths
Vector< float > sample_factors