24 mask.foreach_index([&](
const int i) {
25 const int3 &tri = corner_tris[tri_indices[
i]];
27 src[corner_verts[tri[0]]],
28 src[corner_verts[tri[1]]],
29 src[corner_verts[tri[2]]]);
41 mask.foreach_index([&](
const int i) {
42 const int3 &tri = corner_tris[tri_indices[
i]];
44 src[corner_verts[tri[0]]],
45 src[corner_verts[tri[1]]],
46 src[corner_verts[tri[2]]]);
63 using T =
decltype(dummy);
65 corner_verts, corner_tris, tri_indices, bary_coords, src.
typed<
T>(),
mask, dst.
typed<
T>());
69template<
typename T,
bool check_indices = false>
77 mask.foreach_index([&](
const int i) {
78 if constexpr (check_indices) {
79 if (tri_indices[
i] == -1) {
84 const int3 &tri = corner_tris[tri_indices[
i]];
96 mask.foreach_index([&](
const int i) {
97 const int3 &tri = corner_tris[tri_indices[
i]];
114 using T =
decltype(dummy);
116 corner_tris, tri_indices, bary_coords, src.
typed<
T>(),
mask, dst.
typed<
T>());
127 mask.foreach_index([&](
const int i) {
128 const int tri_index = tri_indices[
i];
129 const int face_index = tri_faces[tri_index];
130 dst[
i] = src[face_index];
144 using T =
decltype(dummy);
149template<
bool check_indices = false>
158 mask.foreach_index([&](
const int i) {
159 if constexpr (check_indices) {
160 if (tri_indices[
i] == -1) {
165 const int3 &tri = corner_tris[tri_indices[
i]];
167 vert_positions, corner_verts, tri, sample_positions[
i]);
171template<
bool check_indices = false>
180 mask.foreach_index([&](
const int i) {
181 if constexpr (check_indices) {
182 if (tri_indices[
i] == -1) {
187 const int3 &tri = corner_tris[tri_indices[
i]];
188 const std::array<float, 3> distances{
193 const int index = std::min_element(distances.begin(), distances.end()) - distances.
begin();
194 const std::array<float3, 3> weights{
float3(1, 0, 0),
float3(0, 1, 0),
float3(0, 0, 1)};
195 bary_coords[
i] = weights[index];
203 const float sample_radius,
204 const float approximate_density,
213 const float sample_radius_sq =
pow2f(sample_radius);
214 const float sample_plane_area =
M_PI * sample_radius_sq;
216 const float area_threshold = sample_plane_area;
218 const int old_num = r_bary_coords.
size();
220 for (
const int tri_index : tris_to_sample) {
221 const int3 &tri = corner_tris[tri_index];
223 const float3 &v0 = positions[corner_verts[tri[0]]];
224 const float3 &v1 = positions[corner_verts[tri[1]]];
225 const float3 &
v2 = positions[corner_verts[tri[2]]];
229 if (corner_tri_area < area_threshold) {
233 for ([[maybe_unused]]
const int i :
IndexRange(amount)) {
237 if (dist_to_sample_sq > sample_radius_sq) {
241 r_bary_coords.
append(bary_coord);
242 r_tri_indices.
append(tri_index);
243 r_positions.
append(point_pos);
252 float3 sample_pos_proj = sample_pos;
256 const float sample_radius_factor_sq = 1.0f -
257 std::min(1.0f, proj_distance_sq / sample_radius_sq);
258 const float radius_proj_sq = sample_radius_sq * sample_radius_factor_sq;
259 const float radius_proj = std::sqrt(radius_proj_sq);
260 const float circle_area =
M_PI * radius_proj_sq;
268 for ([[maybe_unused]]
const int i :
IndexRange(amount)) {
269 const float r = std::sqrt(rng.
get_float());
271 const float x = r * std::cos(
angle);
272 const float y = r * std::sin(
angle);
273 const float3 point_pos = sample_pos_proj + axis_1 *
x + axis_2 *
y;
282 r_bary_coords.
append(bary_coord);
283 r_tri_indices.
append(tri_index);
284 r_positions.
append(point_pos);
288 return r_bary_coords.
size() - old_num;
295 const float2 &sample_pos_re,
296 const float sample_radius_re,
298 region_position_to_ray,
299 const bool front_face_only,
301 const int max_points,
311 for ([[maybe_unused]]
const int _ :
IndexRange(tries_num)) {
312 if (point_count == max_points) {
316 const float r = sample_radius_re * std::sqrt(rng.
get_float());
318 float3 ray_start, ray_end;
320 region_position_to_ray(pos_re, ray_start, ray_end);
334 if (ray_hit.
index == -1) {
338 if (front_face_only) {
340 if (
math::dot(ray_direction, normal) >= 0.0f) {
345 const int tri_index = ray_hit.
index;
349 positions, corner_verts, corner_tris[tri_index],
pos);
352 r_bary_coords.
append(bary_coords);
353 r_tri_indices.
append(tri_index);
364 const float3 &v0 = vert_positions[corner_verts[tri[0]]];
365 const float3 &v1 = vert_positions[corner_verts[tri[1]]];
366 const float3 &
v2 = vert_positions[corner_verts[tri[2]]];
375 source_.ensure_owns_direct_data();
376 static const mf::Signature
signature = []() {
378 mf::SignatureBuilder builder{
"Bary Weight from Position",
signature};
379 builder.single_input<
float3>(
"Position");
380 builder.single_input<
int>(
"Triangle Index");
381 builder.single_output<
float3>(
"Barycentric Weight");
385 const Mesh &
mesh = *source_.get_mesh();
386 vert_positions_ =
mesh.vert_positions();
387 corner_verts_ =
mesh.corner_verts();
388 corner_tris_ =
mesh.corner_tris();
398 2,
"Barycentric Weight");
411 source_.ensure_owns_direct_data();
412 static const mf::Signature
signature = []() {
414 mf::SignatureBuilder builder{
"Nearest Weight from Position",
signature};
415 builder.single_input<
float3>(
"Position");
416 builder.single_input<
int>(
"Triangle Index");
417 builder.single_output<
float3>(
"Barycentric Weight");
421 const Mesh &
mesh = *source_.get_mesh();
422 vert_positions_ =
mesh.vert_positions();
423 corner_verts_ =
mesh.corner_verts();
424 corner_tris_ =
mesh.corner_tris();
434 2,
"Barycentric Weight");
447 source_.ensure_owns_direct_data();
448 this->evaluate_source(std::move(src_field));
449 mf::SignatureBuilder builder{
"Sample Barycentric Triangles", signature_};
450 builder.single_input<
int>(
"Triangle Index");
451 builder.single_input<
float3>(
"Barycentric Weight");
452 builder.single_output(
"Value", source_data_->type());
462 1,
"Barycentric Weight");
465 using T = decltype(dummy);
466 sample_corner_attribute<T, true>(corner_tris_,
469 source_data_->typed<T>(),
475void BaryWeightSampleFn::evaluate_source(
fn::GField src_field)
478 corner_tris_ =
mesh.corner_tris();
484 const int domain_size =
mesh.attributes().domain_size(domain_);
485 source_evaluator_ = std::make_unique<fn::FieldEvaluator>(*source_context_, domain_size);
486 source_evaluator_->add(std::move(src_field));
487 source_evaluator_->evaluate();
488 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])
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
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()
constexpr const T * begin() const
void append(const T &value)
void call(const IndexMask &mask, mf::Params params, mf::Context context) const override
BaryWeightFromPositionFn(GeometrySet geometry)
void call(const IndexMask &mask, mf::Params params, mf::Context context) const override
BaryWeightSampleFn(GeometrySet geometry, fn::GField src_field)
void call(const IndexMask &mask, mf::Params params, mf::Context context) const override
CornerBaryWeightFromPositionFn(GeometrySet geometry)
const Signature & signature() const
void set_signature(const Signature *signature)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
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_projected(RandomNumberGenerator &rng, const Mesh &mesh, bke::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)
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)
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< int32_t, 3 > int3
VecBase< float, 3 > float3
BVHTree_RayCastCallback raycast_callback
const Mesh * get_mesh() const