43 const float w = 1.0f /
float(face_verts.
size());
47 center += vert_positions[face_verts[i]] *
w;
54 if (face_verts.
size() == 3) {
57 vert_positions[face_verts[0]],
58 vert_positions[face_verts[1]],
59 vert_positions[face_verts[2]]);
62 if (face_verts.
size() == 4) {
65 vert_positions[face_verts[0]],
66 vert_positions[face_verts[1]],
67 vert_positions[face_verts[2]],
68 vert_positions[face_verts[3]]);
76 if (face_verts.
size() == 3) {
78 vert_positions[face_verts[1]],
79 vert_positions[face_verts[2]]);
83 coords[i] = vert_positions[face_verts[i]];
94 const Span<int> corner_verts = mesh->corner_verts();
96 float total_area = 0.0f;
97 for (
const int i : faces.index_range()) {
105 const float (*positions)[3],
108 const float *v_pivot, *v_step1;
109 float total_volume = 0.0f;
113 v_pivot = positions[face_verts[0]];
114 v_step1 = positions[face_verts[1]];
116 for (
int i = 2; i < face_size; i++) {
117 const float *v_step2 = positions[face_verts[i]];
122 total_volume += tetra_volume;
130 for (
uint j = 0; j < 3; j++) {
131 r_cent[j] += tetra_volume * (v_pivot[j] + v_step1[j] + v_step2[j]);
149 const float3 &reference_center,
153 float v_pivot[3], v_step1[3];
154 float total_volume = 0.0f;
156 sub_v3_v3v3(v_pivot, positions[face_verts[0]], reference_center);
157 sub_v3_v3v3(v_step1, positions[face_verts[1]], reference_center);
158 for (
int i = 2; i < face_verts.
size(); i++) {
160 sub_v3_v3v3(v_step2, positions[face_verts[i]], reference_center);
162 total_volume += tetra_volume;
163 for (
uint j = 0; j < 3; j++) {
164 r_cent[j] += tetra_volume * (v_pivot[j] + v_step1[j] + v_step2[j]);
181 float total_area = 0.0f;
182 float v1[3],
v2[3], v3[3], tri_cent[3];
191 for (
int i = 2; i < face_verts.
size(); i++) {
195 total_area += tri_area;
215 int i_this = face_verts.
size() - 1;
219 nor_prev, vert_positions[face_verts[i_this - 1]], vert_positions[face_verts[i_this]]);
222 while (i_next < face_verts.
size()) {
223 sub_v3_v3v3(nor_next, vert_positions[face_verts[i_this]], vert_positions[face_verts[i_next]]);
246 for (
const int i : positions.index_range()) {
250 if (mesh->verts_num) {
251 mul_v3_fl(r_cent, 1.0f /
float(mesh->verts_num));
253 return (mesh->verts_num != 0);
261 const Span<int> corner_verts = mesh->corner_verts();
263 for (
const int i : faces.index_range()) {
264 for (
const int vert : corner_verts.
slice(faces[i])) {
267 tot += faces[i].size();
270 if (mesh->faces_num) {
273 return (mesh->faces_num != 0);
279 float total_area = 0.0f;
283 const Span<int> corner_verts = mesh->corner_verts();
288 for (
const int i : faces.index_range()) {
290 positions, corner_verts.
slice(faces[i]), face_cent);
293 total_area += face_area;
296 if (mesh->faces_num) {
305 return (mesh->faces_num != 0);
311 float total_volume = 0.0f;
315 const Span<int> corner_verts = mesh->corner_verts();
324 for (
const int i : faces.index_range()) {
326 positions, corner_verts.
slice(faces[i]), init_cent, face_cent);
330 total_volume += face_volume;
333 if (total_volume != 0.0f) {
343 return init_cent_result;
346 return (mesh->faces_num != 0);
359 const int *corner_verts,
365 if (corner_tris_num == 0) {
369 float totweight = 0.0f;
371 for (i = 0; i < corner_tris_num; i++) {
372 const float *v1 = positions[corner_verts[corner_tris[i][0]]];
373 const float *
v2 = positions[corner_verts[corner_tris[i][1]]];
374 const float *v3 = positions[corner_verts[corner_tris[i][2]]];
383 if (totweight == 0.0f) {
387 mul_v3_fl(r_center, 1.0f / (3.0f * totweight));
393 const int mverts_num,
395 const int corner_tris_num,
396 const int *corner_verts,
411 if (corner_tris_num == 0) {
416 vert_positions, mverts_num, corner_tris, corner_tris_num, corner_verts, center))
423 for (i = 0; i < corner_tris_num; i++) {
424 const float *v1 = vert_positions[corner_verts[corner_tris[i][0]]];
425 const float *
v2 = vert_positions[corner_verts[corner_tris[i][1]]];
426 const float *v3 = vert_positions[corner_verts[corner_tris[i][2]]];
446 *r_volume =
fabsf(totvol);
452 if (totvol != 0.0f) {
453 mul_v3_fl(r_center, (1.0f / 3.0f) / totvol);
473 for (
int x = 0; x < sides; x++) {
476 for (
int y = 0; y <
x; y++) {
477 co_a = co[y * sides +
x];
478 co_b = co[x * sides +
y];
481 std::swap(co_a[0], co_a[1]);
482 std::swap(co_b[0], co_b[1]);
484 if (use_loop_mdisp_flip) {
490 co_a = co[x * sides +
x];
492 std::swap(co_a[0], co_a[1]);
494 if (use_loop_mdisp_flip) {
514 for (const int i : range) {
515 hide_edge[i] = hide_vert[edges[i][0]] || hide_vert[edges[i][1]];
526 threading::parallel_for(faces.index_range(), 4096, [&](
const IndexRange range) {
527 for (const int i : range) {
528 const Span<int> face_verts = corner_verts.slice(faces[i]);
529 hide_poly[i] = std::any_of(
530 face_verts.begin(), face_verts.end(), [&](const int vert) { return hide_vert[vert]; });
539 const VArray<bool> hide_vert = *attributes.lookup_or_default<
bool>(
540 ".hide_vert", AttrDomain::Point,
false);
542 attributes.remove(
".hide_edge");
543 attributes.remove(
".hide_poly");
549 ".hide_edge", AttrDomain::Edge);
551 ".hide_poly", AttrDomain::Face);
564 const VArray<bool> hide_poly = *attributes.lookup_or_default<
bool>(
565 ".hide_poly", AttrDomain::Face,
false);
567 attributes.remove(
".hide_vert");
568 attributes.remove(
".hide_edge");
573 const Span<int> corner_verts = mesh.corner_verts();
574 const Span<int> corner_edges = mesh.corner_edges();
576 ".hide_vert", AttrDomain::Point);
578 ".hide_edge", AttrDomain::Edge);
581 threading::parallel_for(faces.index_range(), 1024, [&](
const IndexRange range) {
582 for (const int i : range) {
583 if (hide_poly_span[i]) {
584 hide_vert.span.fill_indices(corner_verts.slice(faces[i]), true);
585 hide_edge.span.fill_indices(corner_edges.slice(faces[i]), true);
590 threading::parallel_for(faces.index_range(), 1024, [&](
const IndexRange range) {
591 for (const int i : range) {
592 if (!hide_poly_span[i]) {
593 hide_vert.span.fill_indices(corner_verts.slice(faces[i]), false);
594 hide_edge.span.fill_indices(corner_edges.slice(faces[i]), false);
612 const VArray<bool> select_poly = *attributes.lookup_or_default<
bool>(
613 ".select_poly", AttrDomain::Face,
false);
615 attributes.remove(
".select_vert");
616 attributes.remove(
".select_edge");
620 ".select_vert", AttrDomain::Point);
622 ".select_edge", AttrDomain::Edge);
626 array_utils::copy(*attributes.lookup_or_default<
bool>(
".select_poly", AttrDomain::Point,
false),
628 array_utils::copy(*attributes.lookup_or_default<
bool>(
".select_poly", AttrDomain::Edge,
false),
632 select_edge.finish();
638 const VArray<bool> select_vert = *attributes.lookup_or_default<
bool>(
639 ".select_vert", AttrDomain::Point,
false);
641 attributes.remove(
".select_edge");
642 attributes.remove(
".select_poly");
646 ".select_edge", AttrDomain::Edge);
648 ".select_poly", AttrDomain::Face);
651 const VArray<bool> hide_edge = *attributes.lookup_or_default<
bool>(
652 ".hide_edge", AttrDomain::Edge,
false);
654 *attributes.lookup_or_default<
bool>(
".select_vert", AttrDomain::Edge,
false),
655 IndexMask::from_bools(hide_edge, memory).complement(hide_edge.
index_range(), memory),
660 const VArray<bool> hide_poly = *attributes.lookup_or_default<
bool>(
661 ".hide_poly", AttrDomain::Face,
false);
663 *attributes.lookup_or_default<
bool>(
".select_vert", AttrDomain::Face,
false),
664 IndexMask::from_bools(hide_poly, memory).complement(hide_poly.
index_range(), memory),
668 select_poly.finish();
674 const VArray<bool> select_edge = *attributes.lookup_or_default<
bool>(
675 ".select_edge", AttrDomain::Point,
false);
677 attributes.remove(
".select_vert");
678 attributes.remove(
".select_poly");
682 ".select_vert", AttrDomain::Point);
684 ".select_poly", AttrDomain::Face);
687 const VArray<bool> hide_vert = *attributes.lookup_or_default<
bool>(
688 ".hide_vert", AttrDomain::Point,
false);
690 *attributes.lookup_or_default<
bool>(
".select_edge", AttrDomain::Point,
false),
691 IndexMask::from_bools(hide_vert, memory).complement(hide_vert.
index_range(), memory),
696 const VArray<bool> hide_poly = *attributes.lookup_or_default<
bool>(
697 ".hide_poly", AttrDomain::Face,
false);
699 *attributes.lookup_or_default<
bool>(
".select_edge", AttrDomain::Face,
false),
700 IndexMask::from_bools(hide_poly, memory).complement(hide_poly.
index_range(), memory),
704 select_poly.finish();
717 const int *corner_verts,
720 const float (*vert_cos_src)[3],
721 const float (*vert_cos_dst)[3],
723 const float (*vert_cos_org)[3],
724 float (*vert_cos_new)[3])
728 int *vert_accum = (
int *)
MEM_calloc_arrayN(
size_t(totvert),
sizeof(*vert_accum), __func__);
730 memset(vert_cos_new,
'\0',
sizeof(*vert_cos_new) *
size_t(totvert));
732 for (
const int i : faces.index_range()) {
734 const int *face_verts = &corner_verts[face.start()];
736 for (
int j = 0; j < face.size(); j++) {
737 const int v_prev = face_verts[(face.size() + (j - 1)) % face.size()];
738 const int v_curr = face_verts[j];
739 const int v_next = face_verts[(j + 1) % face.size()];
744 vert_cos_dst[v_curr],
745 vert_cos_org[v_prev],
746 vert_cos_org[v_curr],
747 vert_cos_org[v_next],
748 vert_cos_src[v_prev],
749 vert_cos_src[v_curr],
750 vert_cos_src[v_next]);
753 vert_accum[v_curr] += 1;
757 for (
int i = 0; i < totvert; i++) {
759 mul_v3_fl(vert_cos_new[i], 1.0f /
float(vert_accum[i]));
float area_poly_v3(const float verts[][3], unsigned int nr)
void transform_point_by_tri_v3(float pt_tar[3], float const pt_src[3], const float tri_tar_p1[3], const float tri_tar_p2[3], const float tri_tar_p3[3], const float tri_src_p1[3], const float tri_src_p2[3], const float tri_src_p3[3])
float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3])
float volume_tri_tetrahedron_signed_v3_6x(const float v1[3], const float v2[3], const float v3[3])
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
float volume_tetrahedron_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
void mid_v3_v3v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
bool is_finite_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void swap_v3_v3(float a[3], float b[3])
MINLINE void zero_v3(float r[3])
float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3])
#define UNUSED_FUNCTION(x)
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
IndexRange index_range() const
T get_internal_single() const
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void BKE_mesh_calc_relative_deform(const int *face_offsets, const int faces_num, const int *corner_verts, const int totvert, const float(*vert_cos_src)[3], const float(*vert_cos_dst)[3], const float(*vert_cos_org)[3], float(*vert_cos_new)[3])
bool BKE_mesh_center_of_surface(const Mesh *mesh, float r_cent[3])
void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip)
void BKE_mesh_calc_volume(const float(*vert_positions)[3], const int mverts_num, const blender::int3 *corner_tris, const int corner_tris_num, const int *corner_verts, float *r_volume, float r_center[3])
static float UNUSED_FUNCTION mesh_calc_face_volume_centroid(const int *face_verts, const int face_size, const float(*positions)[3], float r_cent[3])
float BKE_mesh_calc_area(const Mesh *mesh)
static bool mesh_calc_center_centroid_ex(const float(*positions)[3], int, const blender::int3 *corner_tris, int corner_tris_num, const int *corner_verts, float r_center[3])
bool BKE_mesh_center_median(const Mesh *mesh, float r_cent[3])
bool BKE_mesh_center_median_from_faces(const Mesh *mesh, float r_cent[3])
bool BKE_mesh_center_of_volume(const Mesh *mesh, float r_cent[3])
void face_angles_calc(Span< float3 > vert_positions, Span< int > face_verts, MutableSpan< float > angles)
float3 face_normal_calc(Span< float3 > vert_positions, Span< int > face_verts)
static float3 face_center_calc_ngon(const Span< float3 > vert_positions, const Span< int > face_verts)
float face_area_calc(Span< float3 > vert_positions, Span< int > face_verts)
static float face_area_centroid_calc(const Span< float3 > positions, const Span< int > face_verts, float r_cent[3])
float3 face_center_calc(Span< float3 > vert_positions, Span< int > face_verts)
static float mesh_calc_face_volume_centroid_with_reference_center(const Span< float3 > positions, const Span< int > face_verts, const float3 &reference_center, float r_cent[3])
void mesh_select_vert_flush(Mesh &mesh)
void mesh_face_hide_from_vert(OffsetIndices< int > faces, Span< int > corner_verts, Span< bool > hide_vert, MutableSpan< bool > hide_poly)
void mesh_hide_vert_flush(Mesh &mesh)
void mesh_hide_face_flush(Mesh &mesh)
void mesh_select_edge_flush(Mesh &mesh)
void mesh_edge_hide_from_vert(Span< int2 > edges, Span< bool > hide_vert, MutableSpan< bool > hide_edge)
void mesh_select_face_flush(Mesh &mesh)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
MutableVArraySpan< T > span