58using bke::CurvesGeometry;
63 KDTree_3d *curve_roots_kdtree_ =
nullptr;
70 if (curve_roots_kdtree_ !=
nullptr) {
71 BLI_kdtree_3d_free(curve_roots_kdtree_);
127 const Mesh &surface_orig = *
static_cast<const Mesh *
>(surface_ob_orig.
data);
202 const Span<int3> surface_corner_tris_orig = surface_orig.corner_tris();
203 const Span<float3> corner_normals_su = surface_orig.corner_normals();
207 add_inputs.
uvs = sampled_uvs;
223 add_inputs.
surface = &surface_orig;
258 float3 ray_start_wo, ray_end_wo;
267 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
276 const float3 &ray_start_su,
292 if (ray_hit.
index == -1) {
296 const int tri_index = ray_hit.
index;
298 const float3 brush_pos_su = ray_hit.
co;
314 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
323 const int old_amount = r_sampled_uvs.
size();
324 const int max_iterations = 100;
325 int current_iteration = 0;
327 if (current_iteration++ >= max_iterations) {
334 const int missing_amount =
add_amount_ + old_amount - r_sampled_uvs.
size();
379 if (!brush_3d.has_value()) {
383 float3 view_ray_start_wo, view_ray_end_wo;
399 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
407 transform, brush_3d->position_cu, brush_3d->radius_cu);
409 this->
sample_spherical(rng, r_sampled_uvs, brush_pos_su, brush_radius_su, view_direction_su);
415 const float3 &brush_pos_su,
416 const float brush_radius_su,
417 const float3 &view_direction_su)
419 const float brush_radius_sq_su =
pow2f(brush_radius_su);
424 BLI_bvhtree_range_query_cpp(
428 [&](
const int index,
const float3 & ,
const float ) {
429 const int3 &tri = surface_corner_tris_eval_[index];
430 const float3 &v0_su = surface_positions_eval_[surface_corner_verts_eval_[tri[0]]];
431 const float3 &v1_su = surface_positions_eval_[surface_corner_verts_eval_[tri[1]]];
432 const float3 &v2_su = surface_positions_eval_[surface_corner_verts_eval_[tri[2]]];
434 normal_tri_v3(normal_su, v0_su, v1_su, v2_su);
435 if (math::dot(normal_su, view_direction_su) >= 0.0f) {
438 selected_tri_indices.
append(index);
442 BLI_bvhtree_range_query_cpp(
446 [&](
const int index,
const float3 & ,
const float ) {
447 selected_tri_indices.append(index);
454 const float brush_plane_area_su =
M_PI * brush_radius_sq_su;
455 const float approximate_density_su =
add_amount_ / brush_plane_area_su;
458 const int max_iterations = 5;
459 int current_iteration = 0;
461 const int old_amount = r_sampled_uvs.size();
462 while (r_sampled_uvs.size() < old_amount +
add_amount_) {
463 if (current_iteration++ >= max_iterations) {
472 selected_tri_indices,
475 approximate_density_su,
482 r_sampled_uvs.append(uv);
487 while (r_sampled_uvs.size() > old_amount +
add_amount_) {
488 const int index_to_remove = rng.get_int32(
add_amount_) + old_amount;
489 r_sampled_uvs.remove_and_reorder(index_to_remove);
495 if (self_->curve_roots_kdtree_ ==
nullptr) {
496 self_->curve_roots_kdtree_ = BLI_kdtree_3d_new(curves_orig_->
curves_num());
499 for (
const int curve_i : curves_orig_->
curves_range()) {
500 BLI_kdtree_3d_insert(self_->curve_roots_kdtree_, curve_i, positions[offsets[curve_i]]);
502 BLI_kdtree_3d_balance(self_->curve_roots_kdtree_);
510 executor.
execute(*
this, C, stroke_extension);
515 return std::make_unique<AddOperation>();
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)
Low-level operations for curves.
Low-level operations for curves.
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
const Brush * BKE_paint_brush_for_read(const Paint *paint)
#define BLI_assert_unreachable()
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)
A KD-tree for nearest neighbor search.
MINLINE float pow2f(float x)
#define BLI_SCOPED_DEFER(function_to_defer)
void DEG_id_tag_update(ID *id, unsigned int flags)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ PAINT_FALLOFF_SHAPE_SPHERE
@ PAINT_FALLOFF_SHAPE_TUBE
@ BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_POINT_COUNT
@ BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_RADIUS
@ BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_LENGTH
@ BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_SHAPE
Object is a sort of wrapper for general info.
void ED_region_tag_redraw(ARegion *region)
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)
static RandomNumberGenerator from_random_seed()
constexpr bool is_empty() const
void append(const T &value)
bool contains(const StringRef attribute_id) const
IndexRange curves_range() const
MutableAttributeAccessor attributes_for_write()
Span< int > offsets() const
Span< float3 > positions() const
AttributeAccessor attributes() const
void on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) override
const Depsgraph * depsgraph
int sample_surface_points_spherical(RandomNumberGenerator &rng, const Mesh &mesh, Span< int > tris_to_sample, const float3 &sample_pos, float sample_radius, float approximate_density, Vector< float3 > &r_bary_coords, Vector< int > &r_tri_indices, Vector< float3 > &r_positions)
float3 compute_bary_coord_in_triangle(Span< float3 > vert_positions, Span< int > corner_verts, const int3 &corner_tri, const float3 &position)
int sample_surface_points_projected(RandomNumberGenerator &rng, const Mesh &mesh, BVHTreeFromMesh &mesh_bvhtree, const float2 &sample_pos_re, float sample_radius_re, FunctionRef< void(const float2 &pos_re, float3 &r_start, float3 &r_end)> region_position_to_ray, bool front_face_only, int tries_num, int max_points, Vector< float3 > &r_bary_coords, Vector< int > &r_tri_indices, Vector< float3 > &r_positions)
T sample_corner_attribute_with_bary_coords(const float3 &bary_weights, const int3 &corner_tri, const Span< T > corner_attribute)
void fill_selection_true(GMutableSpan selection)
std::unique_ptr< CurvesSculptStrokeOperation > new_add_operation()
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)
float brush_radius_get(const Scene &scene, const Brush &brush, const StrokeExtension &stroke_extension)
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)
Vector< float4x4 > get_symmetry_brush_transforms(const eCurvesSymmetryType symmetry)
float transform_brush_radius(const float4x4 &transform, const float3 &brush_position, const float old_radius)
AddCurvesOnMeshOutputs add_curves_on_mesh(bke::CurvesGeometry &curves, const AddCurvesOnMeshInputs &inputs)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
BVHTree_RayCastCallback raycast_callback
struct BrushCurvesSculptSettings * curves_sculpt_settings
struct ToolSettings * toolsettings
void ensure_curve_roots_kdtree()
void sample_spherical_with_symmetry(RandomNumberGenerator &rng, Vector< float2 > &r_sampled_uvs)
CurvesSculptCommonContext ctx_
void sample_in_center_with_symmetry(Vector< float2 > &r_sampled_uvs)
Span< float3 > surface_positions_eval_
Span< int3 > surface_corner_tris_eval_
CurvesSurfaceTransforms transforms_
void sample_projected_with_symmetry(RandomNumberGenerator &rng, Vector< float2 > &r_sampled_uvs)
Object * surface_ob_eval_
void sample_in_center(Vector< float2 > &r_sampled_uvs, const float3 &ray_start_su, const float3 &ray_end_su)
VArraySpan< float2 > surface_uv_map_eval_
BVHTreeFromMesh surface_bvh_eval_
CurvesGeometry * curves_orig_
const BrushCurvesSculptSettings * brush_settings_
Span< int > surface_corner_verts_eval_
const CurvesSculpt * curves_sculpt_
void execute(AddOperation &self, const bContext &C, const StrokeExtension &stroke_extension)
void sample_spherical(RandomNumberGenerator &rng, Vector< float2 > &r_sampled_uvs, const float3 &brush_pos_su, const float brush_radius_su, const float3 &view_direction_su)
void sample_projected(RandomNumberGenerator &rng, Vector< float2 > &r_sampled_uvs, const float4x4 &brush_transform)
AddOperationExecutor(const bContext &C)
IndexRange new_points_range
IndexRange new_curves_range
void WM_main_add_notifier(uint type, void *reference)