2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2011 Blender Foundation.
19 * All rights reserved.
21 * ***** END GPL LICENSE BLOCK *****
24 /** \file blender/blenkernel/intern/mesh_validate.c
34 #include "DNA_mesh_types.h"
35 #include "DNA_meshdata_types.h"
36 #include "DNA_object_types.h"
38 #include "BLI_sys_types.h"
40 #include "BLI_utildefines.h"
41 #include "BLI_edgehash.h"
42 #include "BLI_math_base.h"
43 #include "BLI_math_vector.h"
45 #include "BKE_deform.h"
48 #include "DEG_depsgraph.h"
50 #include "MEM_guardedalloc.h"
52 /* loop v/e are unsigned, so using max uint_32 value as invalid marker... */
53 #define INVALID_LOOP_EDGE_MARKER 4294967295u
56 /** \name Internal functions
64 typedef struct SortFace {
69 /* Used to detect polys (faces) using exactly the same vertices. */
70 /* Used to detect loops used by no (disjoint) or more than one (intersect) polys. */
71 typedef struct SortPoly {
76 bool invalid; /* Poly index. */
79 static void edge_store_assign(uint32_t verts[2], const uint32_t v1, const uint32_t v2)
91 static void edge_store_from_mface_quad(EdgeUUID es[4], MFace *mf)
93 edge_store_assign(es[0].verts, mf->v1, mf->v2);
94 edge_store_assign(es[1].verts, mf->v2, mf->v3);
95 edge_store_assign(es[2].verts, mf->v3, mf->v4);
96 edge_store_assign(es[3].verts, mf->v4, mf->v1);
99 static void edge_store_from_mface_tri(EdgeUUID es[4], MFace *mf)
101 edge_store_assign(es[0].verts, mf->v1, mf->v2);
102 edge_store_assign(es[1].verts, mf->v2, mf->v3);
103 edge_store_assign(es[2].verts, mf->v3, mf->v1);
104 es[3].verts[0] = es[3].verts[1] = UINT_MAX;
107 static int int64_cmp(const void *v1, const void *v2)
109 const int64_t x1 = *(const int64_t *)v1;
110 const int64_t x2 = *(const int64_t *)v2;
122 static int search_face_cmp(const void *v1, const void *v2)
124 const SortFace *sfa = v1, *sfb = v2;
126 if (sfa->es[0].edval > sfb->es[0].edval) {
129 else if (sfa->es[0].edval < sfb->es[0].edval) {
133 else if (sfa->es[1].edval > sfb->es[1].edval) {
136 else if (sfa->es[1].edval < sfb->es[1].edval) {
140 else if (sfa->es[2].edval > sfb->es[2].edval) {
143 else if (sfa->es[2].edval < sfb->es[2].edval) {
147 else if (sfa->es[3].edval > sfb->es[3].edval) {
150 else if (sfa->es[3].edval < sfb->es[3].edval) {
157 /* TODO check there is not some standard define of this somewhere! */
158 static int int_cmp(const void *v1, const void *v2)
160 return *(int *)v1 > *(int *)v2 ? 1 : *(int *)v1 < *(int *)v2 ? -1 : 0;
163 static int search_poly_cmp(const void *v1, const void *v2)
165 const SortPoly *sp1 = v1, *sp2 = v2;
166 const int max_idx = sp1->numverts > sp2->numverts ? sp2->numverts : sp1->numverts;
169 /* Reject all invalid polys at end of list! */
170 if (sp1->invalid || sp2->invalid)
171 return sp1->invalid ? (sp2->invalid ? 0 : 1) : -1;
172 /* Else, sort on first non-equal verts (remember verts of valid polys are sorted). */
173 for (idx = 0; idx < max_idx; idx++) {
174 const int v1_i = sp1->verts[idx];
175 const int v2_i = sp2->verts[idx];
177 return (v1_i > v2_i) ? 1 : -1;
180 return sp1->numverts > sp2->numverts ? 1 : sp1->numverts < sp2->numverts ? -1 : 0;
183 static int search_polyloop_cmp(const void *v1, const void *v2)
185 const SortPoly *sp1 = v1, *sp2 = v2;
187 /* Reject all invalid polys at end of list! */
188 if (sp1->invalid || sp2->invalid)
189 return sp1->invalid && sp2->invalid ? 0 : sp1->invalid ? 1 : -1;
190 /* Else, sort on loopstart. */
191 return sp1->loopstart > sp2->loopstart ? 1 : sp1->loopstart < sp2->loopstart ? -1 : 0;
197 /* -------------------------------------------------------------------- */
199 /** \name Mesh Validation
202 #define PRINT_MSG(...) (void) \
204 ((do_verbose) ? printf(__VA_ARGS__) : 0))
206 #define PRINT_ERR(...) (void) \
208 ((do_verbose) ? printf(__VA_ARGS__) : 0))
211 * Validate the mesh, \a do_fixes requires \a mesh to be non-null.
213 * \return false if no changes needed to be made.
215 bool BKE_mesh_validate_arrays(
217 MVert *mverts, unsigned int totvert,
218 MEdge *medges, unsigned int totedge,
219 MFace *mfaces, unsigned int totface,
220 MLoop *mloops, unsigned int totloop,
221 MPoly *mpolys, unsigned int totpoly,
222 MDeformVert *dverts, /* assume totvert length */
223 const bool do_verbose, const bool do_fixes,
226 # define REMOVE_EDGE_TAG(_me) { _me->v2 = _me->v1; free_flag.edges = do_fixes; } (void)0
227 # define IS_REMOVED_EDGE(_me) (_me->v2 == _me->v1)
229 # define REMOVE_LOOP_TAG(_ml) { _ml->e = INVALID_LOOP_EDGE_MARKER; free_flag.polyloops = do_fixes; } (void)0
230 # define REMOVE_POLY_TAG(_mp) { _mp->totloop *= -1; free_flag.polyloops = do_fixes; } (void)0
239 bool is_valid = true;
244 int verts_weight : 1;
254 /* This regroups loops and polys! */
268 EdgeHash *edge_hash = BLI_edgehash_new_ex(__func__, totedge);
270 BLI_assert(!(do_fixes && mesh == NULL));
272 fix_flag.as_flag = 0;
273 free_flag.as_flag = 0;
274 recalc_flag.as_flag = 0;
276 PRINT_MSG("%s: verts(%u), edges(%u), loops(%u), polygons(%u)\n",
277 __func__, totvert, totedge, totloop, totpoly);
279 if (totedge == 0 && totpoly != 0) {
280 PRINT_ERR("\tLogical error, %u polygons and 0 edges\n", totpoly);
281 recalc_flag.edges = do_fixes;
284 for (i = 0; i < totvert; i++, mv++) {
285 bool fix_normal = true;
287 for (j = 0; j < 3; j++) {
288 if (!isfinite(mv->co[j])) {
289 PRINT_ERR("\tVertex %u: has invalid coordinate\n", i);
294 fix_flag.verts = true;
303 PRINT_ERR("\tVertex %u: has zero normal, assuming Z-up normal\n", i);
305 mv->no[2] = SHRT_MAX;
306 fix_flag.verts = true;
311 for (i = 0, me = medges; i < totedge; i++, me++) {
314 if (me->v1 == me->v2) {
315 PRINT_ERR("\tEdge %u: has matching verts, both %u\n", i, me->v1);
318 if (me->v1 >= totvert) {
319 PRINT_ERR("\tEdge %u: v1 index out of range, %u\n", i, me->v1);
322 if (me->v2 >= totvert) {
323 PRINT_ERR("\tEdge %u: v2 index out of range, %u\n", i, me->v2);
327 if ((me->v1 != me->v2) && BLI_edgehash_haskey(edge_hash, me->v1, me->v2)) {
328 PRINT_ERR("\tEdge %u: is a duplicate of %d\n", i,
329 POINTER_AS_INT(BLI_edgehash_lookup(edge_hash, me->v1, me->v2)));
333 if (remove == false) {
334 if (me->v1 != me->v2) {
335 BLI_edgehash_insert(edge_hash, me->v1, me->v2, POINTER_FROM_INT(i));
343 if (mfaces && !mpolys) {
344 # define REMOVE_FACE_TAG(_mf) { _mf->v3 = 0; free_flag.faces = do_fixes; } (void)0
345 # define CHECK_FACE_VERT_INDEX(a, b) \
346 if (mf->a == mf->b) { \
347 PRINT_ERR(" face %u: verts invalid, " STRINGIFY(a) "/" STRINGIFY(b) " both %u\n", i, mf->a); \
350 # define CHECK_FACE_EDGE(a, b) \
351 if (!BLI_edgehash_haskey(edge_hash, mf->a, mf->b)) { \
352 PRINT_ERR(" face %u: edge " STRINGIFY(a) "/" STRINGIFY(b) \
353 " (%u,%u) is missing edge data\n", i, mf->a, mf->b); \
354 recalc_flag.edges = do_fixes; \
360 SortFace *sort_faces = MEM_callocN(sizeof(SortFace) * totface, "search faces");
363 unsigned int totsortface = 0;
365 PRINT_ERR("No Polys, only tessellated Faces\n");
367 for (i = 0, mf = mfaces, sf = sort_faces; i < totface; i++, mf++) {
372 fidx = mf->v4 ? 3 : 2;
374 fv[fidx] = *(&(mf->v1) + fidx);
375 if (fv[fidx] >= totvert) {
376 PRINT_ERR("\tFace %u: 'v%d' index out of range, %u\n", i, fidx + 1, fv[fidx]);
381 if (remove == false) {
383 CHECK_FACE_VERT_INDEX(v1, v2);
384 CHECK_FACE_VERT_INDEX(v1, v3);
385 CHECK_FACE_VERT_INDEX(v1, v4);
387 CHECK_FACE_VERT_INDEX(v2, v3);
388 CHECK_FACE_VERT_INDEX(v2, v4);
390 CHECK_FACE_VERT_INDEX(v3, v4);
393 CHECK_FACE_VERT_INDEX(v1, v2);
394 CHECK_FACE_VERT_INDEX(v1, v3);
396 CHECK_FACE_VERT_INDEX(v2, v3);
399 if (remove == false) {
402 CHECK_FACE_EDGE(v1, v2);
403 CHECK_FACE_EDGE(v2, v3);
404 CHECK_FACE_EDGE(v3, v4);
405 CHECK_FACE_EDGE(v4, v1);
408 CHECK_FACE_EDGE(v1, v2);
409 CHECK_FACE_EDGE(v2, v3);
410 CHECK_FACE_EDGE(v3, v1);
417 edge_store_from_mface_quad(sf->es, mf);
419 qsort(sf->es, 4, sizeof(int64_t), int64_cmp);
422 edge_store_from_mface_tri(sf->es, mf);
423 qsort(sf->es, 3, sizeof(int64_t), int64_cmp);
436 qsort(sort_faces, totsortface, sizeof(SortFace), search_face_cmp);
442 for (i = 1; i < totsortface; i++, sf++) {
445 /* on a valid mesh, code below will never run */
446 if (memcmp(sf->es, sf_prev->es, sizeof(sf_prev->es)) == 0) {
447 mf = mfaces + sf->index;
450 mf_prev = mfaces + sf_prev->index;
453 PRINT_ERR("\tFace %u & %u: are duplicates (%u,%u,%u,%u) (%u,%u,%u,%u)\n",
454 sf->index, sf_prev->index, mf->v1, mf->v2, mf->v3, mf->v4,
455 mf_prev->v1, mf_prev->v2, mf_prev->v3, mf_prev->v4);
458 PRINT_ERR("\tFace %u & %u: are duplicates (%u,%u,%u) (%u,%u,%u)\n",
459 sf->index, sf_prev->index, mf->v1, mf->v2, mf->v3,
460 mf_prev->v1, mf_prev->v2, mf_prev->v3);
475 MEM_freeN(sort_faces);
477 # undef REMOVE_FACE_TAG
478 # undef CHECK_FACE_VERT_INDEX
479 # undef CHECK_FACE_EDGE
482 /* Checking loops and polys is a bit tricky, as they are quite intricate...
485 * - a valid loopstart value.
486 * - a valid totloop value (>= 3 and loopstart+totloop < me.totloop).
490 * - a valid e value (corresponding to the edge it defines with the next loop in poly).
492 * Also, loops not used by polys can be discarded.
493 * And "intersecting" loops (i.e. loops used by more than one poly) are invalid,
494 * so be sure to leave at most one poly per loop!
497 SortPoly *sort_polys = MEM_callocN(sizeof(SortPoly) * totpoly, "mesh validate's sort_polys");
498 SortPoly *prev_sp, *sp = sort_polys;
501 for (i = 0, mp = mpolys; i < totpoly; i++, mp++, sp++) {
504 if (mp->loopstart < 0 || mp->totloop < 3) {
505 /* Invalid loop data. */
506 PRINT_ERR("\tPoly %u is invalid (loopstart: %d, totloop: %d)\n",
507 sp->index, mp->loopstart, mp->totloop);
510 else if (mp->loopstart + mp->totloop > totloop) {
511 /* Invalid loop data. */
512 PRINT_ERR("\tPoly %u uses loops out of range (loopstart: %d, loopend: %d, max nbr of loops: %u)\n",
513 sp->index, mp->loopstart, mp->loopstart + mp->totloop - 1, totloop - 1);
517 /* Poly itself is valid, for now. */
518 int v1, v2; /* v1 is prev loop vert idx, v2 is current loop one. */
520 sp->verts = v = MEM_mallocN(sizeof(int) * mp->totloop, "Vert idx of SortPoly");
521 sp->numverts = mp->totloop;
522 sp->loopstart = mp->loopstart;
524 /* Ideally we would only have to do that once on all vertices before we start checking each poly, but
525 * several polys can use same vert, so we have to ensure here all verts of current poly are cleared. */
526 for (j = 0, ml = &mloops[sp->loopstart]; j < mp->totloop; j++, ml++) {
527 if (ml->v < totvert) {
528 mverts[ml->v].flag &= ~ME_VERT_TMP_TAG;
532 /* Test all poly's loops' vert idx. */
533 for (j = 0, ml = &mloops[sp->loopstart]; j < mp->totloop; j++, ml++, v++) {
534 if (ml->v >= totvert) {
535 /* Invalid vert idx. */
536 PRINT_ERR("\tLoop %u has invalid vert reference (%u)\n", sp->loopstart + j, ml->v);
539 else if (mverts[ml->v].flag & ME_VERT_TMP_TAG) {
540 PRINT_ERR("\tPoly %u has duplicated vert reference at corner (%u)\n", i, j);
544 mverts[ml->v].flag |= ME_VERT_TMP_TAG;
552 /* Test all poly's loops. */
553 for (j = 0, ml = &mloops[sp->loopstart]; j < mp->totloop; j++, ml++) {
555 v2 = mloops[sp->loopstart + (j + 1) % mp->totloop].v;
556 if (!BLI_edgehash_haskey(edge_hash, v1, v2)) {
557 /* Edge not existing. */
558 PRINT_ERR("\tPoly %u needs missing edge (%d, %d)\n", sp->index, v1, v2);
560 recalc_flag.edges = true;
564 else if (ml->e >= totedge) {
566 * We already know from previous text that a valid edge exists, use it (if allowed)! */
569 ml->e = POINTER_AS_INT(BLI_edgehash_lookup(edge_hash, v1, v2));
570 fix_flag.loops_edge = true;
571 PRINT_ERR("\tLoop %u has invalid edge reference (%d), fixed using edge %u\n",
572 sp->loopstart + j, prev_e, ml->e);
575 PRINT_ERR("\tLoop %u has invalid edge reference (%u)\n", sp->loopstart + j, ml->e);
581 if (IS_REMOVED_EDGE(me) || !((me->v1 == v1 && me->v2 == v2) || (me->v1 == v2 && me->v2 == v1))) {
582 /* The pointed edge is invalid (tagged as removed, or vert idx mismatch),
583 * and we already know from previous test that a valid one exists, use it (if allowed)! */
586 ml->e = POINTER_AS_INT(BLI_edgehash_lookup(edge_hash, v1, v2));
587 fix_flag.loops_edge = true;
588 PRINT_ERR("\tPoly %u has invalid edge reference (%d, is_removed: %d), fixed using edge %u\n",
589 sp->index, prev_e, IS_REMOVED_EDGE(me), ml->e);
592 PRINT_ERR("\tPoly %u has invalid edge reference (%u)\n", sp->index, ml->e);
600 /* Needed for checking polys using same verts below. */
601 qsort(sp->verts, sp->numverts, sizeof(int), int_cmp);
606 /* Second check pass, testing polys using the same verts. */
607 qsort(sort_polys, totpoly, sizeof(SortPoly), search_poly_cmp);
608 sp = prev_sp = sort_polys;
611 for (i = 1; i < totpoly; i++, sp++) {
612 int p1_nv = sp->numverts, p2_nv = prev_sp->numverts;
613 const int *p1_v = sp->verts, *p2_v = prev_sp->verts;
616 /* break, because all known invalid polys have been put at the end by qsort with search_poly_cmp. */
620 /* Test same polys. */
621 if ((p1_nv == p2_nv) && (memcmp(p1_v, p2_v, p1_nv * sizeof(*p1_v)) == 0)) {
623 PRINT_ERR("\tPolys %u and %u use same vertices (%d",
624 prev_sp->index, sp->index, *p1_v);
625 for (j = 1; j < p1_nv; j++)
626 PRINT_ERR(", %d", p1_v[j]);
627 PRINT_ERR("), considering poly %u as invalid.\n", sp->index);
639 /* Third check pass, testing loops used by none or more than one poly. */
640 qsort(sort_polys, totpoly, sizeof(SortPoly), search_polyloop_cmp);
644 for (i = 0; i < totpoly; i++, sp++) {
645 /* Free this now, we don't need it anymore, and avoid us another loop! */
647 MEM_freeN(sp->verts);
649 /* Note above prev_sp: in following code, we make sure it is always valid poly (or NULL). */
652 REMOVE_POLY_TAG((&mpolys[sp->index]));
653 /* DO NOT REMOVE ITS LOOPS!!!
654 * As already invalid polys are at the end of the SortPoly list, the loops they
655 * were the only users have already been tagged as "to remove" during previous
656 * iterations, and we don't want to remove some loops that may be used by
657 * another valid poly! */
660 /* Test loops users. */
663 if (prev_end < sp->loopstart) {
664 for (j = prev_end, ml = &mloops[prev_end]; j < sp->loopstart; j++, ml++) {
665 PRINT_ERR("\tLoop %u is unused.\n", j);
669 prev_end = sp->loopstart + sp->numverts;
672 /* Multi-used loops. */
673 else if (prev_end > sp->loopstart) {
674 PRINT_ERR("\tPolys %u and %u share loops from %d to %d, considering poly %u as invalid.\n",
675 prev_sp->index, sp->index, sp->loopstart, prev_end, sp->index);
677 REMOVE_POLY_TAG((&mpolys[sp->index]));
678 /* DO NOT REMOVE ITS LOOPS!!!
679 * They might be used by some next, valid poly!
680 * Just not updating prev_end/prev_sp vars is enough to ensure the loops
681 * effectively no more needed will be marked as "to be removed"! */
685 prev_end = sp->loopstart + sp->numverts;
690 /* We may have some remaining unused loops to get rid of! */
691 if (prev_end < totloop) {
692 for (j = prev_end, ml = &mloops[prev_end]; j < totloop; j++, ml++) {
693 PRINT_ERR("\tLoop %u is unused.\n", j);
699 MEM_freeN(sort_polys);
702 BLI_edgehash_free(edge_hash, NULL);
704 /* fix deform verts */
707 for (i = 0, dv = dverts; i < totvert; i++, dv++) {
710 for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) {
711 /* note, greater than max defgroups is accounted for in our code, but not < 0 */
712 if (!isfinite(dw->weight)) {
713 PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight);
716 fix_flag.verts_weight = true;
719 else if (dw->weight < 0.0f || dw->weight > 1.0f) {
720 PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight);
722 CLAMP(dw->weight, 0.0f, 1.0f);
723 fix_flag.verts_weight = true;
727 if (dw->def_nr < 0) {
728 PRINT_ERR("\tVertex deform %u, has invalid group %d\n", i, dw->def_nr);
730 defvert_remove_group(dv, dw);
731 fix_flag.verts_weight = true;
734 /* re-allocated, the new values compensate for stepping
735 * within the for loop and may not be valid */
740 else { /* all freed */
749 # undef REMOVE_EDGE_TAG
750 # undef IS_REMOVED_EDGE
751 # undef REMOVE_LOOP_TAG
752 # undef REMOVE_POLY_TAG
755 if (free_flag.faces) {
756 BKE_mesh_strip_loose_faces(mesh);
759 if (free_flag.polyloops) {
760 BKE_mesh_strip_loose_polysloops(mesh);
763 if (free_flag.edges) {
764 BKE_mesh_strip_loose_edges(mesh);
767 if (recalc_flag.edges) {
768 BKE_mesh_calc_edges(mesh, true, false);
772 if (mesh && mesh->mselect) {
775 for (i = 0, msel = mesh->mselect; i < mesh->totselect; i++, msel++) {
778 if (msel->index < 0) {
779 PRINT_ERR("\tMesh select element %u type %d index is negative, "
780 "resetting selection stack.\n", i, msel->type);
781 free_flag.mselect = do_fixes;
785 switch (msel->type) {
787 tot_elem = mesh->totvert;
790 tot_elem = mesh->totedge;
793 tot_elem = mesh->totface;
797 if (msel->index > tot_elem) {
798 PRINT_ERR("\tMesh select element %u type %d index %d is larger than data array size %d, "
799 "resetting selection stack.\n", i, msel->type, msel->index, tot_elem);
801 free_flag.mselect = do_fixes;
806 if (free_flag.mselect) {
807 MEM_freeN(mesh->mselect);
808 mesh->mselect = NULL;
813 PRINT_MSG("%s: finished\n\n", __func__);
815 *r_changed = (fix_flag.as_flag || free_flag.as_flag || recalc_flag.as_flag);
817 BLI_assert((*r_changed == false) || (do_fixes == true));
822 static bool mesh_validate_customdata(
823 CustomData *data, CustomDataMask mask, const uint totitems,
824 const bool do_verbose, const bool do_fixes,
827 bool is_valid = true;
828 bool has_fixes = false;
831 PRINT_MSG("%s: Checking %d CD layers...\n", __func__, data->totlayer);
833 while (i < data->totlayer) {
834 CustomDataLayer *layer = &data->layers[i];
837 if (CustomData_layertype_is_singleton(layer->type)) {
838 const int layer_tot = CustomData_number_of_layers(data, layer->type);
840 PRINT_ERR("\tCustomDataLayer type %d is a singleton, found %d in Mesh structure\n",
841 layer->type, layer_tot);
847 CustomDataMask layer_typemask = CD_TYPE_AS_MASK(layer->type);
848 if ((layer_typemask & mask) == 0) {
849 PRINT_ERR("\tCustomDataLayer type %d which isn't in the mask\n",
857 CustomData_free_layer(data, layer->type, 0, i);
863 if (CustomData_layer_validate(layer, totitems, do_fixes)) {
864 PRINT_ERR("\tCustomDataLayer type %d has some invalid data\n", layer->type);
865 has_fixes = do_fixes;
871 PRINT_MSG("%s: Finished (is_valid=%d)\n\n", __func__, (int)!has_fixes);
873 *r_change = has_fixes;
881 bool BKE_mesh_validate_all_customdata(
882 CustomData *vdata, const uint totvert,
883 CustomData *edata, const uint totedge,
884 CustomData *ldata, const uint totloop,
885 CustomData *pdata, const uint totpoly,
886 const bool check_meshmask,
887 const bool do_verbose, const bool do_fixes,
890 bool is_valid = true;
891 bool is_change_v, is_change_e, is_change_l, is_change_p;
892 int tot_uvloop, tot_vcolloop;
893 CustomDataMask mask = check_meshmask ? CD_MASK_MESH : 0;
895 is_valid &= mesh_validate_customdata(vdata, mask, totvert, do_verbose, do_fixes, &is_change_v);
896 is_valid &= mesh_validate_customdata(edata, mask, totedge, do_verbose, do_fixes, &is_change_e);
897 is_valid &= mesh_validate_customdata(ldata, mask, totloop, do_verbose, do_fixes, &is_change_l);
898 is_valid &= mesh_validate_customdata(pdata, mask, totpoly, do_verbose, do_fixes, &is_change_p);
900 tot_uvloop = CustomData_number_of_layers(ldata, CD_MLOOPUV);
901 tot_vcolloop = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
902 if (tot_uvloop > MAX_MTFACE) {
903 PRINT_ERR("\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
904 MAX_MTFACE, tot_uvloop - MAX_MTFACE);
906 if (tot_vcolloop > MAX_MCOL) {
907 PRINT_ERR("\tMore VCol layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
908 MAX_MCOL, tot_vcolloop - MAX_MCOL);
911 /* check indices of clone/stencil */
912 if (do_fixes && CustomData_get_clone_layer(ldata, CD_MLOOPUV) >= tot_uvloop) {
913 CustomData_set_layer_clone(ldata, CD_MLOOPUV, 0);
916 if (do_fixes && CustomData_get_stencil_layer(ldata, CD_MLOOPUV) >= tot_uvloop) {
917 CustomData_set_layer_stencil(ldata, CD_MLOOPUV, 0);
921 *r_change = (is_change_v || is_change_e || is_change_l || is_change_p);
927 * Validates and corrects a Mesh.
929 * \returns true if a change is made.
931 bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_mask)
933 bool is_valid = true;
937 printf("MESH: %s\n", me->id.name + 2);
940 is_valid &= BKE_mesh_validate_all_customdata(
941 &me->vdata, me->totvert,
942 &me->edata, me->totedge,
943 &me->ldata, me->totloop,
944 &me->pdata, me->totpoly,
949 is_valid &= BKE_mesh_validate_arrays(
951 me->mvert, me->totvert,
952 me->medge, me->totedge,
953 me->mface, me->totface,
954 me->mloop, me->totloop,
955 me->mpoly, me->totpoly,
961 DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
970 * Checks if a Mesh is valid without any modification. This is always verbose.
972 * \see #DM_is_valid to call on derived meshes
976 bool BKE_mesh_is_valid(Mesh *me)
978 const bool do_verbose = true;
979 const bool do_fixes = false;
981 bool is_valid = true;
984 is_valid &= BKE_mesh_validate_all_customdata(
985 &me->vdata, me->totvert,
986 &me->edata, me->totedge,
987 &me->ldata, me->totloop,
988 &me->pdata, me->totpoly,
989 false, /* setting mask here isn't useful, gives false positives */
990 do_verbose, do_fixes, &changed);
992 is_valid &= BKE_mesh_validate_arrays(
994 me->mvert, me->totvert,
995 me->medge, me->totedge,
996 me->mface, me->totface,
997 me->mloop, me->totloop,
998 me->mpoly, me->totpoly,
1000 do_verbose, do_fixes,
1003 BLI_assert(changed == false);
1009 * Check all material indices of polygons are valid, invalid ones are set to 0.
1010 * \returns is_valid.
1012 bool BKE_mesh_validate_material_indices(Mesh *me)
1015 const int max_idx = max_ii(0, me->totcol - 1);
1016 const int totpoly = me->totpoly;
1018 bool is_valid = true;
1020 for (mp = me->mpoly, i = 0; i < totpoly; i++, mp++) {
1021 if (mp->mat_nr > max_idx) {
1028 DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
1039 /* -------------------------------------------------------------------- */
1041 /** \name Mesh Stripping (removing invalid data)
1044 /* We need to keep this for edge creation (for now?), and some old readfile code... */
1045 void BKE_mesh_strip_loose_faces(Mesh *me)
1050 for (a = b = 0, f = me->mface; a < me->totface; a++, f++) {
1053 memcpy(&me->mface[b], f, sizeof(me->mface[b]));
1054 CustomData_copy_data(&me->fdata, &me->fdata, a, b, 1);
1060 CustomData_free_elem(&me->fdata, b, a - b);
1065 /* Works on both loops and polys! */
1066 /* Note: It won't try to guess which loops of an invalid poly to remove!
1067 * this is the work of the caller, to mark those loops...
1068 * See e.g. BKE_mesh_validate_arrays(). */
1069 void BKE_mesh_strip_loose_polysloops(Mesh *me)
1074 /* New loops idx! */
1075 int *new_idx = MEM_mallocN(sizeof(int) * me->totloop, __func__);
1077 for (a = b = 0, p = me->mpoly; a < me->totpoly; a++, p++) {
1078 bool invalid = false;
1079 int i = p->loopstart;
1080 int stop = i + p->totloop;
1082 if (stop > me->totloop || stop < i) {
1088 /* If one of the poly's loops is invalid, the whole poly is invalid! */
1090 if (l->e == INVALID_LOOP_EDGE_MARKER) {
1097 if (p->totloop >= 3 && !invalid) {
1099 memcpy(&me->mpoly[b], p, sizeof(me->mpoly[b]));
1100 CustomData_copy_data(&me->pdata, &me->pdata, a, b, 1);
1106 CustomData_free_elem(&me->pdata, b, a - b);
1110 /* And now, get rid of invalid loops. */
1111 for (a = b = 0, l = me->mloop; a < me->totloop; a++, l++) {
1112 if (l->e != INVALID_LOOP_EDGE_MARKER) {
1114 memcpy(&me->mloop[b], l, sizeof(me->mloop[b]));
1115 CustomData_copy_data(&me->ldata, &me->ldata, a, b, 1);
1121 /* XXX Theoretically, we should be able to not do this, as no remaining poly
1122 * should use any stripped loop. But for security's sake... */
1127 CustomData_free_elem(&me->ldata, b, a - b);
1131 /* And now, update polys' start loop index. */
1132 /* Note: At this point, there should never be any poly using a striped loop! */
1133 for (a = 0, p = me->mpoly; a < me->totpoly; a++, p++) {
1134 p->loopstart = new_idx[p->loopstart];
1140 void BKE_mesh_strip_loose_edges(Mesh *me)
1145 unsigned int *new_idx = MEM_mallocN(sizeof(int) * me->totedge, __func__);
1147 for (a = b = 0, e = me->medge; a < me->totedge; a++, e++) {
1148 if (e->v1 != e->v2) {
1150 memcpy(&me->medge[b], e, sizeof(me->medge[b]));
1151 CustomData_copy_data(&me->edata, &me->edata, a, b, 1);
1157 new_idx[a] = INVALID_LOOP_EDGE_MARKER;
1161 CustomData_free_elem(&me->edata, b, a - b);
1165 /* And now, update loops' edge indices. */
1166 /* XXX We hope no loop was pointing to a striped edge!
1167 * Else, its e will be set to INVALID_LOOP_EDGE_MARKER :/ */
1168 for (a = 0, l = me->mloop; a < me->totloop; a++, l++) {
1169 l->e = new_idx[l->e];
1178 /* -------------------------------------------------------------------- */
1180 /** \name Mesh Edge Calculation
1183 /* make edges in a Mesh, for outside of editmode */
1186 unsigned int v1, v2;
1187 char is_loose, is_draw;
1190 /* edges have to be added with lowest index first for sorting */
1191 static void to_edgesort(
1192 struct EdgeSort *ed,
1193 unsigned int v1, unsigned int v2,
1194 char is_loose, short is_draw)
1197 ed->v1 = v1; ed->v2 = v2;
1200 ed->v1 = v2; ed->v2 = v1;
1202 ed->is_loose = is_loose;
1203 ed->is_draw = is_draw;
1206 static int vergedgesort(const void *v1, const void *v2)
1208 const struct EdgeSort *x1 = v1, *x2 = v2;
1210 if (x1->v1 > x2->v1) return 1;
1211 else if (x1->v1 < x2->v1) return -1;
1212 else if (x1->v2 > x2->v2) return 1;
1213 else if (x1->v2 < x2->v2) return -1;
1219 /* Create edges based on known verts and faces,
1220 * this function is only used when loading very old blend files */
1222 static void mesh_calc_edges_mdata(
1223 MVert *UNUSED(allvert), MFace *allface, MLoop *allloop,
1224 MPoly *allpoly, int UNUSED(totvert), int totface, int UNUSED(totloop), int totpoly,
1226 MEdge **r_medge, int *r_totedge)
1232 struct EdgeSort *edsort, *ed;
1234 unsigned int totedge_final = 0;
1235 unsigned int edge_index;
1237 /* we put all edges in array, sort them, and detect doubles that way */
1239 for (a = totface, mface = allface; a > 0; a--, mface++) {
1240 if (mface->v4) totedge += 4;
1241 else if (mface->v3) totedge += 3;
1246 /* flag that mesh has edges */
1247 (*r_medge) = MEM_callocN(0, __func__);
1252 ed = edsort = MEM_mallocN(totedge * sizeof(struct EdgeSort), "EdgeSort");
1254 for (a = totface, mface = allface; a > 0; a--, mface++) {
1255 to_edgesort(ed++, mface->v1, mface->v2, !mface->v3, mface->edcode & ME_V1V2);
1257 to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
1258 to_edgesort(ed++, mface->v3, mface->v4, 0, mface->edcode & ME_V3V4);
1259 to_edgesort(ed++, mface->v4, mface->v1, 0, mface->edcode & ME_V4V1);
1261 else if (mface->v3) {
1262 to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
1263 to_edgesort(ed++, mface->v3, mface->v1, 0, mface->edcode & ME_V3V1);
1267 qsort(edsort, totedge, sizeof(struct EdgeSort), vergedgesort);
1269 /* count final amount */
1270 for (a = totedge, ed = edsort; a > 1; a--, ed++) {
1271 /* edge is unique when it differs from next edge, or is last */
1272 if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) totedge_final++;
1276 medge = MEM_callocN(sizeof(MEdge) * totedge_final, __func__);
1278 for (a = totedge, med = medge, ed = edsort; a > 1; a--, ed++) {
1279 /* edge is unique when it differs from next edge, or is last */
1280 if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) {
1283 if (use_old == false || ed->is_draw) med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1284 if (ed->is_loose) med->flag |= ME_LOOSEEDGE;
1286 /* order is swapped so extruding this edge as a surface wont flip face normals
1287 * with cyclic curves */
1288 if (ed->v1 + 1 != ed->v2) {
1289 SWAP(unsigned int, med->v1, med->v2);
1294 /* equal edge, we merge the drawflag */
1295 (ed + 1)->is_draw |= ed->is_draw;
1301 med->flag = ME_EDGEDRAW;
1302 if (ed->is_loose) med->flag |= ME_LOOSEEDGE;
1303 med->flag |= ME_EDGERENDER;
1307 /* set edge members of mloops */
1308 hash = BLI_edgehash_new_ex(__func__, totedge_final);
1309 for (edge_index = 0, med = medge; edge_index < totedge_final; edge_index++, med++) {
1310 BLI_edgehash_insert(hash, med->v1, med->v2, POINTER_FROM_UINT(edge_index));
1314 for (a = 0; a < totpoly; a++, mpoly++) {
1315 MLoop *ml, *ml_next;
1316 int i = mpoly->totloop;
1318 ml_next = allloop + mpoly->loopstart; /* first loop */
1319 ml = &ml_next[i - 1]; /* last loop */
1322 ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(hash, ml->v, ml_next->v));
1328 BLI_edgehash_free(hash, NULL);
1331 *r_totedge = totedge_final;
1335 * If the mesh is from a very old blender version,
1336 * convert mface->edcode to edge drawflags
1338 void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
1343 mesh_calc_edges_mdata(
1344 me->mvert, me->mface, me->mloop, me->mpoly,
1345 me->totvert, me->totface, me->totloop, me->totpoly,
1346 use_old, &medge, &totedge);
1349 /* flag that mesh has edges */
1355 medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, totedge);
1357 me->totedge = totedge;
1359 BKE_mesh_strip_loose_faces(me);
1364 * Calculate edges from polygons
1366 * \param mesh: The mesh to add edges into
1367 * \param update: When true create new edges co-exist
1369 void BKE_mesh_calc_edges(Mesh *mesh, bool update, const bool select)
1372 EdgeHashIterator *ehi;
1374 MEdge *med, *med_orig;
1376 unsigned int eh_reserve;
1377 int i, totedge, totpoly = mesh->totpoly;
1379 /* select for newly created meshes which are selected [#25595] */
1380 const short ed_flag = (ME_EDGEDRAW | ME_EDGERENDER) | (select ? SELECT : 0);
1382 if (mesh->totedge == 0)
1385 eh_reserve = max_ii(update ? mesh->totedge : 0, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totpoly));
1386 eh = BLI_edgehash_new_ex(__func__, eh_reserve);
1389 /* assume existing edges are valid
1390 * useful when adding more faces and generating edges from them */
1392 for (i = 0; i < mesh->totedge; i++, med++)
1393 BLI_edgehash_insert(eh, med->v1, med->v2, med);
1396 /* mesh loops (bmesh only) */
1397 for (mp = mesh->mpoly, i = 0; i < totpoly; mp++, i++) {
1398 MLoop *l = &mesh->mloop[mp->loopstart];
1399 int j, v_prev = (l + (mp->totloop - 1))->v;
1400 for (j = 0; j < mp->totloop; j++, l++) {
1401 if (v_prev != l->v) {
1403 if (!BLI_edgehash_ensure_p(eh, v_prev, l->v, &val_p)) {
1411 totedge = BLI_edgehash_len(eh);
1413 /* write new edges into a temporary CustomData */
1414 CustomData_reset(&edata);
1415 CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
1417 med = CustomData_get_layer(&edata, CD_MEDGE);
1418 for (ehi = BLI_edgehashIterator_new(eh), i = 0;
1419 BLI_edgehashIterator_isDone(ehi) == false;
1420 BLI_edgehashIterator_step(ehi), ++i, ++med)
1422 if (update && (med_orig = BLI_edgehashIterator_getValue(ehi))) {
1423 *med = *med_orig; /* copy from the original */
1426 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
1427 med->flag = ed_flag;
1430 /* store the new edge index in the hash value */
1431 BLI_edgehashIterator_setValue(ehi, POINTER_FROM_INT(i));
1433 BLI_edgehashIterator_free(ehi);
1435 if (mesh->totpoly) {
1436 /* second pass, iterate through all loops again and assign
1437 * the newly created edges to them. */
1438 for (mp = mesh->mpoly, i = 0; i < mesh->totpoly; mp++, i++) {
1439 MLoop *l = &mesh->mloop[mp->loopstart];
1440 MLoop *l_prev = (l + (mp->totloop - 1));
1442 for (j = 0; j < mp->totloop; j++, l++) {
1443 /* lookup hashed edge index */
1444 med_index = POINTER_AS_INT(BLI_edgehash_lookup(eh, l_prev->v, l->v));
1445 l_prev->e = med_index;
1451 /* free old CustomData and assign new one */
1452 CustomData_free(&mesh->edata, mesh->totedge);
1453 mesh->edata = edata;
1454 mesh->totedge = totedge;
1456 mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE);
1458 BLI_edgehash_free(eh, NULL);
1461 void BKE_mesh_calc_edges_loose(Mesh *mesh)
1463 MEdge *med = mesh->medge;
1464 for (int i = 0; i < mesh->totedge; i++, med++) {
1465 med->flag |= ME_LOOSEEDGE;
1467 MLoop *ml = mesh->mloop;
1468 for (int i = 0; i < mesh->totloop; i++, ml++) {
1469 mesh->medge[ml->e].flag &= ~ME_LOOSEEDGE;
1474 * Calculate/create edges from tessface data
1476 * \param mesh: The mesh to add edges into
1479 void BKE_mesh_calc_edges_tessface(Mesh *mesh)
1481 CustomData edgeData;
1482 EdgeSetIterator *ehi;
1483 MFace *mf = mesh->mface;
1486 int i, *index, numEdges, numFaces = mesh->totface;
1488 eh = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(numFaces));
1490 for (i = 0; i < numFaces; i++, mf++) {
1491 BLI_edgeset_add(eh, mf->v1, mf->v2);
1492 BLI_edgeset_add(eh, mf->v2, mf->v3);
1495 BLI_edgeset_add(eh, mf->v3, mf->v4);
1496 BLI_edgeset_add(eh, mf->v4, mf->v1);
1499 BLI_edgeset_add(eh, mf->v3, mf->v1);
1503 numEdges = BLI_edgeset_len(eh);
1505 /* write new edges into a temporary CustomData */
1506 CustomData_reset(&edgeData);
1507 CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1508 CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1510 med = CustomData_get_layer(&edgeData, CD_MEDGE);
1511 index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
1513 for (ehi = BLI_edgesetIterator_new(eh), i = 0;
1514 BLI_edgesetIterator_isDone(ehi) == false;
1515 BLI_edgesetIterator_step(ehi), i++, med++, index++)
1517 BLI_edgesetIterator_getKey(ehi, &med->v1, &med->v2);
1519 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1520 *index = ORIGINDEX_NONE;
1522 BLI_edgesetIterator_free(ehi);
1524 /* free old CustomData and assign new one */
1525 CustomData_free(&mesh->edata, mesh->totedge);
1526 mesh->edata = edgeData;
1527 mesh->totedge = numEdges;
1529 mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE);
1531 BLI_edgeset_free(eh);