Blender  V3.3
mesh_sample.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include "BKE_attribute_math.hh"
4 #include "BKE_bvhutils.h"
5 #include "BKE_mesh_runtime.h"
6 #include "BKE_mesh_sample.hh"
7 
8 #include "DNA_mesh_types.h"
9 #include "DNA_meshdata_types.h"
10 
11 #include "BLI_rand.hh"
12 
14 
15 template<typename T>
17  const Span<int> looptri_indices,
18  const Span<float3> bary_coords,
19  const VArray<T> &data_in,
20  const IndexMask mask,
21  const MutableSpan<T> data_out)
22 {
25 
26  for (const int i : mask) {
27  const int looptri_index = looptri_indices[i];
28  const MLoopTri &looptri = looptris[looptri_index];
29  const float3 &bary_coord = bary_coords[i];
30 
31  const int v0_index = mesh.mloop[looptri.tri[0]].v;
32  const int v1_index = mesh.mloop[looptri.tri[1]].v;
33  const int v2_index = mesh.mloop[looptri.tri[2]].v;
34 
35  const T v0 = data_in[v0_index];
36  const T v1 = data_in[v1_index];
37  const T v2 = data_in[v2_index];
38 
39  const T interpolated_value = attribute_math::mix3(bary_coord, v0, v1, v2);
40  data_out[i] = interpolated_value;
41  }
42 }
43 
45  const Span<int> looptri_indices,
46  const Span<float3> bary_coords,
47  const GVArray &data_in,
48  const IndexMask mask,
49  const GMutableSpan data_out)
50 {
51  BLI_assert(data_in.size() == mesh.totvert);
52  BLI_assert(data_in.type() == data_out.type());
53 
54  const CPPType &type = data_in.type();
56  using T = decltype(dummy);
57  sample_point_attribute<T>(
58  mesh, looptri_indices, bary_coords, data_in.typed<T>(), mask, data_out.typed<T>());
59  });
60 }
61 
62 template<typename T>
64  const Span<int> looptri_indices,
65  const Span<float3> bary_coords,
66  const VArray<T> &data_in,
67  const IndexMask mask,
68  const MutableSpan<T> data_out)
69 {
72 
73  for (const int i : mask) {
74  const int looptri_index = looptri_indices[i];
75  const MLoopTri &looptri = looptris[looptri_index];
76  const float3 &bary_coord = bary_coords[i];
77 
78  const int loop_index_0 = looptri.tri[0];
79  const int loop_index_1 = looptri.tri[1];
80  const int loop_index_2 = looptri.tri[2];
81 
82  const T v0 = data_in[loop_index_0];
83  const T v1 = data_in[loop_index_1];
84  const T v2 = data_in[loop_index_2];
85 
86  const T interpolated_value = attribute_math::mix3(bary_coord, v0, v1, v2);
87  data_out[i] = interpolated_value;
88  }
89 }
90 
92  const Span<int> looptri_indices,
93  const Span<float3> bary_coords,
94  const GVArray &data_in,
95  const IndexMask mask,
96  const GMutableSpan data_out)
97 {
98  BLI_assert(data_in.size() == mesh.totloop);
99  BLI_assert(data_in.type() == data_out.type());
100 
101  const CPPType &type = data_in.type();
103  using T = decltype(dummy);
104  sample_corner_attribute<T>(
105  mesh, looptri_indices, bary_coords, data_in.typed<T>(), mask, data_out.typed<T>());
106  });
107 }
108 
109 template<typename T>
111  const Span<int> looptri_indices,
112  const VArray<T> &data_in,
113  const IndexMask mask,
114  const MutableSpan<T> data_out)
115 {
118 
119  for (const int i : mask) {
120  const int looptri_index = looptri_indices[i];
121  const MLoopTri &looptri = looptris[looptri_index];
122  const int poly_index = looptri.poly;
123  data_out[i] = data_in[poly_index];
124  }
125 }
126 
128  const Span<int> looptri_indices,
129  const GVArray &data_in,
130  const IndexMask mask,
131  const GMutableSpan data_out)
132 {
133  BLI_assert(data_in.size() == mesh.totpoly);
134  BLI_assert(data_in.type() == data_out.type());
135 
136  const CPPType &type = data_in.type();
138  using T = decltype(dummy);
139  sample_face_attribute<T>(mesh, looptri_indices, data_in.typed<T>(), mask, data_out.typed<T>());
140  });
141 }
142 
144  const IndexMask mask,
145  const Span<float3> positions,
146  const Span<int> looptri_indices)
147  : mesh_(mesh), mask_(mask), positions_(positions), looptri_indices_(looptri_indices)
148 {
149  BLI_assert(positions.size() == looptri_indices.size());
150 }
151 
153 {
154  if (!bary_coords_.is_empty()) {
155  BLI_assert(bary_coords_.size() >= mask_.min_array_size());
156  return bary_coords_;
157  }
158  bary_coords_.reinitialize(mask_.min_array_size());
159 
160  const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh_),
162 
163  for (const int i : mask_) {
164  const int looptri_index = looptri_indices_[i];
165  const MLoopTri &looptri = looptris[looptri_index];
166 
167  const int v0_index = mesh_->mloop[looptri.tri[0]].v;
168  const int v1_index = mesh_->mloop[looptri.tri[1]].v;
169  const int v2_index = mesh_->mloop[looptri.tri[2]].v;
170 
171  interp_weights_tri_v3(bary_coords_[i],
172  mesh_->mvert[v0_index].co,
173  mesh_->mvert[v1_index].co,
174  mesh_->mvert[v2_index].co,
175  positions_[i]);
176  }
177  return bary_coords_;
178 }
179 
181 {
182  if (!nearest_weights_.is_empty()) {
183  BLI_assert(nearest_weights_.size() >= mask_.min_array_size());
184  return nearest_weights_;
185  }
186  nearest_weights_.reinitialize(mask_.min_array_size());
187 
188  const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh_),
190 
191  for (const int i : mask_) {
192  const int looptri_index = looptri_indices_[i];
193  const MLoopTri &looptri = looptris[looptri_index];
194 
195  const int v0_index = mesh_->mloop[looptri.tri[0]].v;
196  const int v1_index = mesh_->mloop[looptri.tri[1]].v;
197  const int v2_index = mesh_->mloop[looptri.tri[2]].v;
198 
199  const float d0 = len_squared_v3v3(positions_[i], mesh_->mvert[v0_index].co);
200  const float d1 = len_squared_v3v3(positions_[i], mesh_->mvert[v1_index].co);
201  const float d2 = len_squared_v3v3(positions_[i], mesh_->mvert[v2_index].co);
202 
203  nearest_weights_[i] = MIN3_PAIR(d0, d1, d2, float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
204  }
205  return nearest_weights_;
206 }
207 
209  const eAttrDomain domain,
210  const eAttributeMapMode mode,
211  const GMutableSpan dst)
212 {
213  if (src.is_empty() || dst.is_empty()) {
214  return;
215  }
216 
217  /* Compute barycentric coordinates only when they are needed. */
218  Span<float3> weights;
219  if (ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) {
220  switch (mode) {
222  weights = ensure_barycentric_coords();
223  break;
225  weights = ensure_nearest_weights();
226  break;
227  }
228  }
229 
230  /* Interpolate the source attributes on the surface. */
231  switch (domain) {
232  case ATTR_DOMAIN_POINT: {
233  sample_point_attribute(*mesh_, looptri_indices_, weights, src, mask_, dst);
234  break;
235  }
236  case ATTR_DOMAIN_FACE: {
237  sample_face_attribute(*mesh_, looptri_indices_, src, mask_, dst);
238  break;
239  }
240  case ATTR_DOMAIN_CORNER: {
241  sample_corner_attribute(*mesh_, looptri_indices_, weights, src, mask_, dst);
242  break;
243  }
244  case ATTR_DOMAIN_EDGE: {
245  /* Not yet supported. */
246  break;
247  }
248  default: {
250  break;
251  }
252  }
253 }
254 
256  GSpanAttributeWriter &dst_attribute,
257  eAttributeMapMode mode)
258 {
259  if (src_attribute && dst_attribute) {
260  this->sample_data(src_attribute.varray, src_attribute.domain, mode, dst_attribute.span);
261  }
262 }
263 
265  const Mesh &mesh,
266  const Span<int> looptri_indices_to_sample,
267  const float3 &sample_pos,
268  const float sample_radius,
269  const float approximate_density,
270  Vector<float3> &r_bary_coords,
271  Vector<int> &r_looptri_indices,
272  Vector<float3> &r_positions)
273 {
276 
277  const float sample_radius_sq = pow2f(sample_radius);
278  const float sample_plane_area = M_PI * sample_radius_sq;
279  /* Used for switching between two triangle sampling strategies. */
280  const float area_threshold = sample_plane_area;
281 
282  const int old_num = r_bary_coords.size();
283 
284  for (const int looptri_index : looptri_indices_to_sample) {
285  const MLoopTri &looptri = looptris[looptri_index];
286 
287  const float3 &v0 = mesh.mvert[mesh.mloop[looptri.tri[0]].v].co;
288  const float3 &v1 = mesh.mvert[mesh.mloop[looptri.tri[1]].v].co;
289  const float3 &v2 = mesh.mvert[mesh.mloop[looptri.tri[2]].v].co;
290 
291  const float looptri_area = area_tri_v3(v0, v1, v2);
292 
293  if (looptri_area < area_threshold) {
294  /* The triangle is small compared to the sample radius. Sample by generating random
295  * barycentric coordinates. */
296  const int amount = rng.round_probabilistic(approximate_density * looptri_area);
297  for ([[maybe_unused]] const int i : IndexRange(amount)) {
298  const float3 bary_coord = rng.get_barycentric_coordinates();
299  const float3 point_pos = attribute_math::mix3(bary_coord, v0, v1, v2);
300  const float dist_to_sample_sq = math::distance_squared(point_pos, sample_pos);
301  if (dist_to_sample_sq > sample_radius_sq) {
302  continue;
303  }
304 
305  r_bary_coords.append(bary_coord);
306  r_looptri_indices.append(looptri_index);
307  r_positions.append(point_pos);
308  }
309  }
310  else {
311  /* The triangle is large compared to the sample radius. Sample by generating random points
312  * on the triangle plane within the sample radius. */
313  float3 normal;
314  normal_tri_v3(normal, v0, v1, v2);
315 
316  float3 sample_pos_proj = sample_pos;
317  project_v3_plane(sample_pos_proj, normal, v0);
318 
319  const float proj_distance_sq = math::distance_squared(sample_pos_proj, sample_pos);
320  const float sample_radius_factor_sq = 1.0f -
321  std::min(1.0f, proj_distance_sq / sample_radius_sq);
322  const float radius_proj_sq = sample_radius_sq * sample_radius_factor_sq;
323  const float radius_proj = std::sqrt(radius_proj_sq);
324  const float circle_area = M_PI * radius_proj_sq;
325 
326  const int amount = rng.round_probabilistic(approximate_density * circle_area);
327 
328  const float3 axis_1 = math::normalize(v1 - v0) * radius_proj;
329  const float3 axis_2 = math::normalize(math::cross(axis_1, math::cross(axis_1, v2 - v0))) *
330  radius_proj;
331 
332  for ([[maybe_unused]] const int i : IndexRange(amount)) {
333  const float r = std::sqrt(rng.get_float());
334  const float angle = rng.get_float() * 2.0f * M_PI;
335  const float x = r * std::cos(angle);
336  const float y = r * std::sin(angle);
337  const float3 point_pos = sample_pos_proj + axis_1 * x + axis_2 * y;
338  if (!isect_point_tri_prism_v3(point_pos, v0, v1, v2)) {
339  /* Sampled point is not in the triangle. */
340  continue;
341  }
342 
343  float3 bary_coord;
344  interp_weights_tri_v3(bary_coord, v0, v1, v2, point_pos);
345 
346  r_bary_coords.append(bary_coord);
347  r_looptri_indices.append(looptri_index);
348  r_positions.append(point_pos);
349  }
350  }
351  }
352  return r_bary_coords.size() - old_num;
353 }
354 
357  const Mesh &mesh,
358  BVHTreeFromMesh &mesh_bvhtree,
359  const float2 &sample_pos_re,
360  const float sample_radius_re,
361  const FunctionRef<void(const float2 &pos_re, float3 &r_start, float3 &r_end)>
362  region_position_to_ray,
363  const bool front_face_only,
364  const int tries_num,
365  const int max_points,
366  Vector<float3> &r_bary_coords,
367  Vector<int> &r_looptri_indices,
368  Vector<float3> &r_positions)
369 {
372 
373  int point_count = 0;
374  for ([[maybe_unused]] const int _ : IndexRange(tries_num)) {
375  if (point_count == max_points) {
376  break;
377  }
378 
379  const float r = sample_radius_re * std::sqrt(rng.get_float());
380  const float angle = rng.get_float() * 2.0f * M_PI;
381  float3 ray_start, ray_end;
382  const float2 pos_re = sample_pos_re + r * float2(std::cos(angle), std::sin(angle));
383  region_position_to_ray(pos_re, ray_start, ray_end);
384  const float3 ray_direction = math::normalize(ray_end - ray_start);
385 
386  BVHTreeRayHit ray_hit;
387  ray_hit.dist = FLT_MAX;
388  ray_hit.index = -1;
389  BLI_bvhtree_ray_cast(mesh_bvhtree.tree,
390  ray_start,
391  ray_direction,
392  0.0f,
393  &ray_hit,
394  mesh_bvhtree.raycast_callback,
395  &mesh_bvhtree);
396 
397  if (ray_hit.index == -1) {
398  continue;
399  }
400 
401  if (front_face_only) {
402  const float3 normal = ray_hit.no;
403  if (math::dot(ray_direction, normal) >= 0.0f) {
404  continue;
405  }
406  }
407 
408  const int looptri_index = ray_hit.index;
409  const float3 pos = ray_hit.co;
410 
411  const float3 bary_coords = compute_bary_coord_in_triangle(mesh, looptris[looptri_index], pos);
412 
413  r_positions.append(pos);
414  r_bary_coords.append(bary_coords);
415  r_looptri_indices.append(looptri_index);
416  point_count++;
417  }
418  return point_count;
419 }
420 
422  const MLoopTri &looptri,
423  const float3 &position)
424 {
425  const float3 &v0 = mesh.mvert[mesh.mloop[looptri.tri[0]].v].co;
426  const float3 &v1 = mesh.mvert[mesh.mloop[looptri.tri[1]].v].co;
427  const float3 &v2 = mesh.mvert[mesh.mloop[looptri.tri[2]].v].co;
428  float3 bary_coords;
429  interp_weights_tri_v3(bary_coords, v0, v1, v2, position);
430  return bary_coords;
431 }
432 
433 } // namespace blender::bke::mesh_surface_sample
eAttrDomain
Definition: BKE_attribute.h:25
@ ATTR_DOMAIN_POINT
Definition: BKE_attribute.h:27
@ ATTR_DOMAIN_FACE
Definition: BKE_attribute.h:29
@ ATTR_DOMAIN_CORNER
Definition: BKE_attribute.h:30
@ ATTR_DOMAIN_EDGE
Definition: BKE_attribute.h:28
const struct MLoopTri * BKE_mesh_runtime_looptri_ensure(const struct Mesh *mesh)
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh)
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_NOINLINE
sqrt(x)+1/max(0
int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
Definition: BLI_kdopbvh.c:1942
MINLINE float pow2f(float x)
#define M_PI
Definition: BLI_math_base.h:20
void interp_weights_tri_v3(float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3])
Definition: math_geom.c:3603
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:92
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:33
bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:3380
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3])
Definition: math_vector.c:668
#define ELEM(...)
#define MIN3_PAIR(cmp_a, cmp_b, cmp_c, ret_a, ret_b, ret_c)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
ATTR_WARN_UNUSED_RESULT const BMVert * v2
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
const CPPType & type() const
MutableSpan< T > typed() const
const CPPType & type() const
VArray< T > typed() const
int64_t min_array_size() const
int round_probabilistic(float x)
Definition: rand.cc:377
constexpr int64_t size() const
Definition: BLI_span.hh:240
int64_t size() const
Definition: BLI_vector.hh:694
void append(const T &value)
Definition: BLI_vector.hh:433
void sample_data(const GVArray &src, eAttrDomain domain, eAttributeMapMode mode, const GMutableSpan dst)
Definition: mesh_sample.cc:208
void sample_attribute(const GAttributeReader &src_attribute, GSpanAttributeWriter &dst_attribute, eAttributeMapMode mode)
Definition: mesh_sample.cc:255
MeshAttributeInterpolator(const Mesh *mesh, const IndexMask mask, const Span< float3 > positions, const Span< int > looptri_indices)
Definition: mesh_sample.cc:143
SyclQueue void void * src
uint pos
IconTextureDrawCall normal
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
#define T
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:319
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:311
T mix3(const float3 &weights, const T &v0, const T &v1, const T &v2)
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
void sample_face_attribute(const Mesh &mesh, Span< int > looptri_indices, const GVArray &data_in, const IndexMask mask, GMutableSpan data_out)
Definition: mesh_sample.cc:127
float3 compute_bary_coord_in_triangle(const Mesh &mesh, const MLoopTri &looptri, const float3 &position)
Definition: mesh_sample.cc:421
void sample_point_attribute(const Mesh &mesh, Span< int > looptri_indices, Span< float3 > bary_coords, const GVArray &data_in, const IndexMask mask, GMutableSpan data_out)
Definition: mesh_sample.cc:44
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)
Definition: mesh_sample.cc:264
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)
void sample_corner_attribute(const Mesh &mesh, Span< int > looptri_indices, Span< float3 > bary_coords, const GVArray &data_in, const IndexMask mask, GMutableSpan data_out)
Definition: mesh_sample.cc:91
T distance_squared(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
T dot(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
vec_base< T, 3 > cross(const vec_base< T, 3 > &a, const vec_base< T, 3 > &b)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
vec_base< float, 3 > float3
vec_base< float, 2 > float2
MutableSpan< float3 > positions
#define min(a, b)
Definition: sort.c:35
BVHTree_RayCastCallback raycast_callback
Definition: BKE_bvhutils.h:54
struct BVHTree * tree
Definition: BKE_bvhutils.h:50
float co[3]
Definition: BLI_kdopbvh.h:68
float no[3]
Definition: BLI_kdopbvh.h:70
unsigned int poly
unsigned int tri[3]
unsigned int v
float co[3]
struct MVert * mvert
int totvert
struct MLoop * mloop
int totpoly
int totloop