25 mask.foreach_index([&](
const int i) {
26 const int3 &tri = corner_tris[tri_indices[i]];
28 src[corner_verts[tri[0]]],
29 src[corner_verts[tri[1]]],
30 src[corner_verts[tri[2]]]);
42 mask.foreach_index([&](
const int i) {
43 const int3 &tri = corner_tris[tri_indices[i]];
45 src[corner_verts[tri[0]]],
46 src[corner_verts[tri[1]]],
47 src[corner_verts[tri[2]]]);
64 using T =
decltype(dummy);
66 corner_verts, corner_tris, tri_indices, bary_coords, src.
typed<T>(), mask, dst.
typed<T>());
70template<
typename T,
bool check_indices = false>
78 mask.foreach_index([&](
const int i) {
79 if constexpr (check_indices) {
80 if (tri_indices[i] == -1) {
85 const int3 &tri = corner_tris[tri_indices[i]];
97 mask.foreach_index([&](
const int i) {
98 const int3 &tri = corner_tris[tri_indices[i]];
115 using T =
decltype(dummy);
117 corner_tris, tri_indices, bary_coords, src.
typed<T>(), mask, dst.
typed<T>());
128 mask.foreach_index([&](
const int i) {
129 const int tri_index = tri_indices[i];
130 const int face_index = tri_faces[tri_index];
131 dst[i] = src[face_index];
145 using T =
decltype(dummy);
150template<
bool check_indices = false>
159 mask.foreach_index([&](
const int i) {
160 if constexpr (check_indices) {
161 if (tri_indices[i] == -1) {
166 const int3 &tri = corner_tris[tri_indices[i]];
168 vert_positions, corner_verts, tri, sample_positions[i]);
172template<
bool check_indices = false>
181 mask.foreach_index([&](
const int i) {
182 if constexpr (check_indices) {
183 if (tri_indices[i] == -1) {
188 const int3 &tri = corner_tris[tri_indices[i]];
189 const std::array<float, 3> distances{
194 const int index = std::min_element(distances.begin(), distances.end()) - distances.begin();
195 const std::array<float3, 3> weights{
float3(1, 0, 0),
float3(0, 1, 0),
float3(0, 0, 1)};
196 bary_coords[i] = weights[index];
204 const float sample_radius,
205 const float approximate_density,
211 const Span<int> corner_verts = mesh.corner_verts();
212 const Span<int3> corner_tris = mesh.corner_tris();
214 const float sample_radius_sq =
pow2f(sample_radius);
215 const float sample_plane_area =
M_PI * sample_radius_sq;
217 const float area_threshold = sample_plane_area;
219 const int old_num = r_bary_coords.
size();
221 for (
const int tri_index : tris_to_sample) {
222 const int3 &tri = corner_tris[tri_index];
224 const float3 &v0 = positions[corner_verts[tri[0]]];
225 const float3 &v1 = positions[corner_verts[tri[1]]];
226 const float3 &
v2 = positions[corner_verts[tri[2]]];
230 if (corner_tri_area < area_threshold) {
234 for ([[maybe_unused]]
const int i :
IndexRange(amount)) {
238 if (dist_to_sample_sq > sample_radius_sq) {
242 r_bary_coords.
append(bary_coord);
243 r_tri_indices.
append(tri_index);
244 r_positions.
append(point_pos);
253 float3 sample_pos_proj = sample_pos;
257 const float sample_radius_factor_sq = 1.0f -
258 std::min(1.0f, proj_distance_sq / sample_radius_sq);
259 const float radius_proj_sq = sample_radius_sq * sample_radius_factor_sq;
260 const float radius_proj = std::sqrt(radius_proj_sq);
261 const float circle_area =
M_PI * radius_proj_sq;
269 for ([[maybe_unused]]
const int i :
IndexRange(amount)) {
270 const float r = std::sqrt(rng.
get_float());
272 const float x = r * std::cos(angle);
273 const float y = r * std::sin(angle);
274 const float3 point_pos = sample_pos_proj + axis_1 * x + axis_2 *
y;
283 r_bary_coords.
append(bary_coord);
284 r_tri_indices.
append(tri_index);
285 r_positions.
append(point_pos);
289 return r_bary_coords.
size() - old_num;
296 const float2 &sample_pos_re,
297 const float sample_radius_re,
299 region_position_to_ray,
300 const bool front_face_only,
302 const int max_points,
308 const Span<int> corner_verts = mesh.corner_verts();
309 const Span<int3> corner_tris = mesh.corner_tris();
312 for ([[maybe_unused]]
const int _ :
IndexRange(tries_num)) {
313 if (point_count == max_points) {
317 const float r = sample_radius_re * std::sqrt(rng.
get_float());
319 float3 ray_start, ray_end;
320 const float2 pos_re = sample_pos_re + r *
float2(std::cos(angle), std::sin(angle));
321 region_position_to_ray(pos_re, ray_start, ray_end);
335 if (ray_hit.
index == -1) {
339 if (front_face_only) {
341 if (
math::dot(ray_direction, normal) >= 0.0f) {
346 const int tri_index = ray_hit.
index;
350 positions, corner_verts, corner_tris[tri_index],
pos);
353 r_bary_coords.
append(bary_coords);
354 r_tri_indices.
append(tri_index);
365 const float3 &v0 = vert_positions[corner_verts[tri[0]]];
366 const float3 &v1 = vert_positions[corner_verts[tri[1]]];
367 const float3 &
v2 = vert_positions[corner_verts[tri[2]]];
374 : source_(std::move(geometry))
380 builder.single_input<
float3>(
"Position");
381 builder.single_input<
int>(
"Triangle Index");
382 builder.single_output<
float3>(
"Barycentric Weight");
387 vert_positions_ = mesh.vert_positions();
388 corner_verts_ = mesh.corner_verts();
389 corner_tris_ = mesh.corner_tris();
399 2,
"Barycentric Weight");
410 : source_(std::move(geometry))
416 builder.single_input<
float3>(
"Position");
417 builder.single_input<
int>(
"Triangle Index");
418 builder.single_output<
float3>(
"Barycentric Weight");
423 vert_positions_ = mesh.vert_positions();
424 corner_verts_ = mesh.corner_verts();
425 corner_tris_ = mesh.corner_tris();
435 2,
"Barycentric Weight");
446 : source_(std::move(geometry))
449 this->evaluate_source(std::move(src_field));
451 builder.single_input<
int>(
"Triangle Index");
452 builder.single_input<
float3>(
"Barycentric Weight");
453 builder.single_output(
"Value", source_data_->
type());
463 1,
"Barycentric Weight");
466 using T = decltype(dummy);
467 sample_corner_attribute<T, true>(corner_tris_,
470 source_data_->typed<T>(),
476void BaryWeightSampleFn::evaluate_source(
fn::GField src_field)
479 corner_tris_ = mesh.corner_tris();
485 const int domain_size = mesh.attributes().domain_size(domain_);
486 source_evaluator_ = std::make_unique<fn::FieldEvaluator>(*source_context_, domain_size);
487 source_evaluator_->add(std::move(src_field));
488 source_evaluator_->evaluate();
489 source_data_ = &source_evaluator_->get_evaluated(0);
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)
void interp_weights_tri_v3(float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3])
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3])
void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3])
ATTR_WARN_UNUSED_RESULT const BMVert * v2
const CPPType & type() const
MutableSpan< T > typed() const
const CPPType & type() const
VArray< T > typed() const
int round_probabilistic(float x)
float3 get_barycentric_coordinates()
void append(const T &value)
BaryWeightFromPositionFn(GeometrySet geometry)
void call(const IndexMask &mask, mf::Params params, mf::Context context) const
void call(const IndexMask &mask, mf::Params params, mf::Context context) const
BaryWeightSampleFn(GeometrySet geometry, fn::GField src_field)
CornerBaryWeightFromPositionFn(GeometrySet geometry)
void call(const IndexMask &mask, mf::Params params, mf::Context context) const
const Signature & signature() const
void set_signature(const Signature *signature)
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
T mix3(const float3 &weights, const T &v0, const T &v1, const T &v2)
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)
void sample_corner_normals(Span< int3 > corner_tris, Span< int > tri_indices, Span< float3 > bary_coords, Span< float3 > src, const IndexMask &mask, MutableSpan< float3 > dst)
void sample_point_attribute(Span< int > corner_verts, Span< int3 > corner_tris, Span< int > tri_indices, Span< float3 > bary_coords, const GVArray &src, const IndexMask &mask, GMutableSpan dst)
float3 compute_bary_coord_in_triangle(Span< float3 > vert_positions, Span< int > corner_verts, const int3 &corner_tri, const float3 &position)
static void sample_barycentric_weights(const Span< float3 > vert_positions, const Span< int > corner_verts, const Span< int3 > corner_tris, const Span< int > tri_indices, const Span< float3 > sample_positions, const IndexMask &mask, MutableSpan< float3 > bary_coords)
void sample_corner_attribute(Span< int3 > corner_tris, Span< int > tri_indices, Span< float3 > bary_coords, const GVArray &src, const IndexMask &mask, GMutableSpan dst)
static void sample_nearest_weights(const Span< float3 > vert_positions, const Span< int > corner_verts, const Span< int3 > corner_tris, const Span< int > tri_indices, const Span< float3 > sample_positions, const IndexMask &mask, MutableSpan< float3 > bary_coords)
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)
void sample_face_attribute(Span< int > corner_tri_faces, Span< int > tri_indices, const GVArray &src, const IndexMask &mask, GMutableSpan dst)
T sample_corner_attribute_with_bary_coords(const float3 &bary_weights, const int3 &corner_tri, const Span< T > corner_attribute)
void sample_point_normals(Span< int > corner_verts, Span< int3 > corner_tris, Span< int > tri_indices, Span< float3 > bary_coords, Span< float3 > src, IndexMask mask, MutableSpan< float3 > dst)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
AxisSigned cross(const AxisSigned a, const AxisSigned b)
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< float, 2 > float2
VecBase< float, 3 > float3
BVHTree_RayCastCallback raycast_callback
void ensure_owns_direct_data()
const Mesh * get_mesh() const