64 KDTree_3d *curve_roots_kdtree_ =
nullptr;
71 if (curve_roots_kdtree_ !=
nullptr) {
72 BLI_kdtree_3d_free(curve_roots_kdtree_);
128 Mesh &surface_orig = *
static_cast<Mesh *
>(surface_ob_orig.
data);
129 if (surface_orig.
totpoly == 0) {
222 add_inputs.
uvs = sampled_uvs;
233 add_inputs.
surface = &surface_orig;
259 float3 ray_start_wo, ray_end_wo;
268 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
275 const float3 &ray_start_su,
281 ray_hit.
dist = FLT_MAX;
291 if (ray_hit.
index == -1) {
295 const int looptri_index = ray_hit.
index;
297 const float3 brush_pos_su = ray_hit.
co;
313 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
322 const int old_amount = r_sampled_uvs.
size();
323 const int max_iterations = 100;
324 int current_iteration = 0;
326 if (current_iteration++ >= max_iterations) {
333 const int missing_amount =
add_amount_ + old_amount - r_sampled_uvs.
size();
376 if (!brush_3d.has_value()) {
380 float3 view_ray_start_wo, view_ray_end_wo;
394 for (
const float4x4 &brush_transform : symmetry_brush_transforms) {
401 transform, brush_3d->position_cu, brush_3d->radius_cu);
403 this->
sample_spherical(rng, r_sampled_uvs, brush_pos_su, brush_radius_su, view_direction_su);
409 const float3 &brush_pos_su,
410 const float brush_radius_su,
411 const float3 &view_direction_su)
413 const float brush_radius_sq_su =
pow2f(brush_radius_su);
418 BLI_bvhtree_range_query_cpp(
429 if (
math::dot(normal_su, view_direction_su) >= 0.0f) {
432 selected_looptri_indices.
append(index);
436 BLI_bvhtree_range_query_cpp(
441 selected_looptri_indices.
append(index);
448 const float brush_plane_area_su =
M_PI * brush_radius_sq_su;
449 const float approximate_density_su =
add_amount_ / brush_plane_area_su;
452 const int max_iterations = 5;
453 int current_iteration = 0;
455 const int old_amount = r_sampled_uvs.
size();
457 if (current_iteration++ >= max_iterations) {
466 selected_looptri_indices,
469 approximate_density_su,
489 if (
self_->curve_roots_kdtree_ ==
nullptr) {
494 BLI_kdtree_3d_insert(
self_->curve_roots_kdtree_, curve_i, root_pos_cu);
496 BLI_kdtree_3d_balance(
self_->curve_roots_kdtree_);
504 executor.execute(*
this,
C, stroke_extension);
509 return std::make_unique<AddOperation>();
void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
BVHTree * BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, const struct Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
struct Object * CTX_data_active_object(const bContext *C)
Low-level operations for curves.
Low-level operations for curves.
bool CustomData_has_layer(const struct CustomData *data, int type)
void * CustomData_get_layer(const struct CustomData *data, int type)
void BKE_mesh_calc_normals_split(struct Mesh *mesh)
const struct MLoopTri * BKE_mesh_runtime_looptri_ensure(const struct Mesh *mesh)
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh)
General operations, lookup, etc. for blender objects.
struct Mesh * BKE_object_get_evaluated_mesh(const struct Object *object)
const struct Brush * BKE_paint_brush_for_read(const struct Paint *p)
#define BLI_assert_unreachable()
int BLI_bvhtree_ray_cast(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)
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
#define BLI_SCOPED_DEFER(function_to_defer)
void DEG_id_tag_update(struct ID *id, int flag)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ PAINT_FALLOFF_SHAPE_SPHERE
@ PAINT_FALLOFF_SHAPE_TUBE
@ BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_POINT_COUNT
@ BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_LENGTH
@ BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_SHAPE
struct CurvesGeometry CurvesGeometry
Object is a sort of wrapper for general info.
void ED_region_tag_redraw(struct ARegion *region)
bool ED_view3d_win_to_segment_clipped(const struct Depsgraph *depsgraph, const struct ARegion *region, const struct View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_end[3], bool do_clip_planes)
Platform independent time functions.
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
constexpr bool is_empty() const
void remove_and_reorder(const int64_t index)
void append(const T &value)
GAttributeReader lookup(const AttributeIDRef &attribute_id) const
IndexRange curves_range() const
Span< int > offsets() const
static CurvesGeometry & wrap(::CurvesGeometry &dna_struct)
Span< float3 > positions() const
void on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) override
const Depsgraph * depsgraph
float3 compute_bary_coord_in_triangle(const Mesh &mesh, const MLoopTri &looptri, const float3 &position)
T sample_corner_attrribute_with_bary_coords(const float3 &bary_weights, const MLoopTri &looptri, const Span< T > corner_attribute)
int sample_surface_points_spherical(RandomNumberGenerator &rng, const Mesh &mesh, Span< int > looptri_indices_to_sample, const float3 &sample_pos, float sample_radius, float approximate_density, Vector< float3 > &r_bary_coords, Vector< int > &r_looptri_indices, Vector< float3 > &r_positions)
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_looptri_indices, Vector< float3 > &r_positions)
AttributeAccessor mesh_attributes(const Mesh &mesh)
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)
T dot(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
vec_base< T, Size > normalize(const vec_base< T, Size > &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)
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_
const CurvesSculpt * curves_sculpt_
void execute(AddOperation &self, const bContext &C, const StrokeExtension &stroke_extension)
Span< MLoopTri > surface_looptris_eval_
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)
double PIL_check_seconds_timer(void)
void WM_main_add_notifier(unsigned int type, void *reference)