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"
46 #include "BKE_depsgraph.h"
47 #include "BKE_DerivedMesh.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. */
623 bool p1_sub = true, p2_sub = true;
625 /* NOTE: This performs a sub-set test. */
626 /* XXX This (and the sort of verts list) is better than systematic
627 * search of all verts of one list into the other if lists have
628 * a fair amount of elements.
629 * Not sure however it's worth it in this case?
630 * But as we also need sorted vert list to check verts multi-used
631 * (in first pass of checks)... */
632 /* XXX If we consider only "equal" polys (i.e. using exactly same set of verts)
633 * as invalid, better to replace this by a simple memory cmp... */
634 while ((p1_nv && p2_nv) && (p1_sub || p2_sub)) {
641 else if (*p2_v < *p1_v) {
648 /* Equality, both next verts. */
657 else if (p2_nv && p2_sub)
660 if (p1_sub && p2_sub) {
661 PRINT("\tPolys %u and %u use same vertices, considering poly %u as invalid.\n",
662 prev_sp->index, sp->index, sp->index);
665 /* XXX In fact, these might be valid? :/ */
667 PRINT("\t%u is a sub-poly of %u, considering it as invalid.\n", sp->index, prev_sp->index);
671 PRINT("\t%u is a sub-poly of %u, considering it as invalid.\n", prev_sp->index, sp->index);
672 prev_sp->invalid = true;
673 prev_sp = sp; /* sp is new reference poly. */
677 if ((p1_nv == p2_nv) && (memcmp(p1_v, p2_v, p1_nv * sizeof(*p1_v)) == 0)) {
679 PRINT_ERR("\tPolys %u and %u use same vertices (%d",
680 prev_sp->index, sp->index, *p1_v);
681 for (j = 1; j < p1_nv; j++)
682 PRINT_ERR(", %d", p1_v[j]);
683 PRINT_ERR("), considering poly %u as invalid.\n", sp->index);
696 /* Third check pass, testing loops used by none or more than one poly. */
697 qsort(sort_polys, totpoly, sizeof(SortPoly), search_polyloop_cmp);
701 for (i = 0; i < totpoly; i++, sp++) {
702 /* Free this now, we don't need it anymore, and avoid us another loop! */
704 MEM_freeN(sp->verts);
706 /* Note above prev_sp: in following code, we make sure it is always valid poly (or NULL). */
709 REMOVE_POLY_TAG((&mpolys[sp->index]));
710 /* DO NOT REMOVE ITS LOOPS!!!
711 * As already invalid polys are at the end of the SortPoly list, the loops they
712 * were the only users have already been tagged as "to remove" during previous
713 * iterations, and we don't want to remove some loops that may be used by
714 * another valid poly! */
717 /* Test loops users. */
720 if (prev_end < sp->loopstart) {
721 for (j = prev_end, ml = &mloops[prev_end]; j < sp->loopstart; j++, ml++) {
722 PRINT_ERR("\tLoop %u is unused.\n", j);
726 prev_end = sp->loopstart + sp->numverts;
729 /* Multi-used loops. */
730 else if (prev_end > sp->loopstart) {
731 PRINT_ERR("\tPolys %u and %u share loops from %d to %d, considering poly %u as invalid.\n",
732 prev_sp->index, sp->index, sp->loopstart, prev_end, sp->index);
734 REMOVE_POLY_TAG((&mpolys[sp->index]));
735 /* DO NOT REMOVE ITS LOOPS!!!
736 * They might be used by some next, valid poly!
737 * Just not updating prev_end/prev_sp vars is enough to ensure the loops
738 * effectively no more needed will be marked as "to be removed"! */
742 prev_end = sp->loopstart + sp->numverts;
747 /* We may have some remaining unused loops to get rid of! */
748 if (prev_end < totloop) {
749 for (j = prev_end, ml = &mloops[prev_end]; j < totloop; j++, ml++) {
750 PRINT_ERR("\tLoop %u is unused.\n", j);
756 MEM_freeN(sort_polys);
759 BLI_edgehash_free(edge_hash, NULL);
761 /* fix deform verts */
764 for (i = 0, dv = dverts; i < totvert; i++, dv++) {
767 for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) {
768 /* note, greater than max defgroups is accounted for in our code, but not < 0 */
769 if (!isfinite(dw->weight)) {
770 PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight);
773 fix_flag.verts_weight = true;
776 else if (dw->weight < 0.0f || dw->weight > 1.0f) {
777 PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight);
779 CLAMP(dw->weight, 0.0f, 1.0f);
780 fix_flag.verts_weight = true;
784 if (dw->def_nr < 0) {
785 PRINT_ERR("\tVertex deform %u, has invalid group %d\n", i, dw->def_nr);
787 defvert_remove_group(dv, dw);
788 fix_flag.verts_weight = true;
791 /* re-allocated, the new values compensate for stepping
792 * within the for loop and may not be valid */
797 else { /* all freed */
806 # undef REMOVE_EDGE_TAG
807 # undef IS_REMOVED_EDGE
808 # undef REMOVE_LOOP_TAG
809 # undef REMOVE_POLY_TAG
812 if (free_flag.faces) {
813 BKE_mesh_strip_loose_faces(mesh);
816 if (free_flag.polyloops) {
817 BKE_mesh_strip_loose_polysloops(mesh);
820 if (free_flag.edges) {
821 BKE_mesh_strip_loose_edges(mesh);
824 if (recalc_flag.edges) {
825 BKE_mesh_calc_edges(mesh, true, false);
829 if (mesh && mesh->mselect) {
832 for (i = 0, msel = mesh->mselect; i < mesh->totselect; i++, msel++) {
835 if (msel->index < 0) {
836 PRINT_ERR("\tMesh select element %u type %d index is negative, "
837 "resetting selection stack.\n", i, msel->type);
838 free_flag.mselect = do_fixes;
842 switch (msel->type) {
844 tot_elem = mesh->totvert;
847 tot_elem = mesh->totedge;
850 tot_elem = mesh->totface;
854 if (msel->index > tot_elem) {
855 PRINT_ERR("\tMesh select element %u type %d index %d is larger than data array size %d, "
856 "resetting selection stack.\n", i, msel->type, msel->index, tot_elem);
858 free_flag.mselect = do_fixes;
863 if (free_flag.mselect) {
864 MEM_freeN(mesh->mselect);
865 mesh->mselect = NULL;
870 PRINT_MSG("%s: finished\n\n", __func__);
872 *r_changed = (fix_flag.as_flag || free_flag.as_flag || recalc_flag.as_flag);
874 BLI_assert((*r_changed == false) || (do_fixes == true));
879 static bool mesh_validate_customdata(
880 CustomData *data, CustomDataMask mask,
881 const bool do_verbose, const bool do_fixes,
884 bool is_valid = true;
885 bool has_fixes = false;
888 PRINT_MSG("%s: Checking %d CD layers...\n", __func__, data->totlayer);
890 while (i < data->totlayer) {
891 CustomDataLayer *layer = &data->layers[i];
894 if (CustomData_layertype_is_singleton(layer->type)) {
895 const int layer_tot = CustomData_number_of_layers(data, layer->type);
897 PRINT_ERR("\tCustomDataLayer type %d is a singleton, found %d in Mesh structure\n",
898 layer->type, layer_tot);
904 CustomDataMask layer_typemask = CD_TYPE_AS_MASK(layer->type);
905 if ((layer_typemask & mask) == 0) {
906 PRINT_ERR("\tCustomDataLayer type %d which isn't in the mask\n",
914 CustomData_free_layer(data, layer->type, 0, i);
923 PRINT_MSG("%s: Finished (is_valid=%d)\n\n", __func__, (int)!has_fixes);
925 *r_change = has_fixes;
933 bool BKE_mesh_validate_all_customdata(
934 CustomData *vdata, CustomData *edata,
935 CustomData *ldata, CustomData *pdata,
936 const bool check_meshmask,
937 const bool do_verbose, const bool do_fixes,
940 bool is_valid = true;
941 bool is_change_v, is_change_e, is_change_l, is_change_p;
942 int tot_texpoly, tot_uvloop, tot_vcolloop;
943 CustomDataMask mask = check_meshmask ? CD_MASK_MESH : 0;
945 is_valid &= mesh_validate_customdata(vdata, mask, do_verbose, do_fixes, &is_change_v);
946 is_valid &= mesh_validate_customdata(edata, mask, do_verbose, do_fixes, &is_change_e);
947 is_valid &= mesh_validate_customdata(ldata, mask, do_verbose, do_fixes, &is_change_l);
948 is_valid &= mesh_validate_customdata(pdata, mask, do_verbose, do_fixes, &is_change_p);
950 tot_texpoly = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
951 tot_uvloop = CustomData_number_of_layers(ldata, CD_MLOOPUV);
952 tot_vcolloop = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
953 if (tot_texpoly != tot_uvloop) {
954 PRINT_ERR("\tCustomDataLayer mismatch, tot_texpoly(%d), tot_uvloop(%d)\n",
955 tot_texpoly, tot_uvloop);
957 if (tot_texpoly > MAX_MTFACE) {
958 PRINT_ERR("\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
959 MAX_MTFACE, tot_texpoly - MAX_MTFACE);
961 if (tot_uvloop > MAX_MTFACE) {
962 PRINT_ERR("\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
963 MAX_MTFACE, tot_uvloop - MAX_MTFACE);
965 if (tot_vcolloop > MAX_MCOL) {
966 PRINT_ERR("\tMore VCol layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
967 MAX_MCOL, tot_vcolloop - MAX_MCOL);
970 /* check indices of clone/stencil */
971 if (do_fixes && CustomData_get_clone_layer(pdata, CD_MTEXPOLY) >= tot_texpoly) {
972 CustomData_set_layer_clone(pdata, CD_MTEXPOLY, 0);
975 if (do_fixes && CustomData_get_clone_layer(ldata, CD_MLOOPUV) >= tot_uvloop) {
976 CustomData_set_layer_clone(ldata, CD_MLOOPUV, 0);
979 if (do_fixes && CustomData_get_stencil_layer(pdata, CD_MTEXPOLY) >= tot_texpoly) {
980 CustomData_set_layer_stencil(pdata, CD_MTEXPOLY, 0);
983 if (do_fixes && CustomData_get_stencil_layer(ldata, CD_MLOOPUV) >= tot_uvloop) {
984 CustomData_set_layer_stencil(ldata, CD_MLOOPUV, 0);
988 *r_change = (is_change_v || is_change_e || is_change_l || is_change_p);
994 * \see #DM_is_valid to call on derived meshes
996 * \returns true if a change is made.
998 bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_mask)
1000 bool is_valid = true;
1004 printf("MESH: %s\n", me->id.name + 2);
1007 is_valid &= BKE_mesh_validate_all_customdata(
1008 &me->vdata, &me->edata, &me->ldata, &me->pdata,
1013 is_valid &= BKE_mesh_validate_arrays(
1015 me->mvert, me->totvert,
1016 me->medge, me->totedge,
1017 me->mface, me->totface,
1018 me->mloop, me->totloop,
1019 me->mpoly, me->totpoly,
1025 DAG_id_tag_update(&me->id, OB_RECALC_DATA);
1034 * Duplicate of BM_mesh_cd_validate() for Mesh data.
1036 void BKE_mesh_cd_validate(Mesh *me)
1038 int totlayer_mtex = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
1039 int totlayer_uv = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
1040 int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
1041 int mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY);
1042 int uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV);
1045 /* XXX For now, do not delete those, just warn they are not really usable. */
1046 if (UNLIKELY(totlayer_mtex > MAX_MTFACE)) {
1047 printf("WARNING! More UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
1048 MAX_MTFACE, totlayer_mtex - MAX_MTFACE);
1050 if (UNLIKELY(totlayer_uv > MAX_MTFACE)) {
1051 printf("WARNING! More UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
1052 MAX_MTFACE, totlayer_uv - MAX_MTFACE);
1054 if (UNLIKELY(totlayer_mcol > MAX_MCOL)) {
1055 printf("WARNING! More VCol layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
1056 MAX_MCOL, totlayer_mcol - MAX_MCOL);
1059 if (LIKELY(totlayer_mtex == totlayer_uv)) {
1062 else if (totlayer_mtex < totlayer_uv) {
1064 const char *from_name = me->ldata.layers[uv_index + totlayer_mtex].name;
1065 CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, from_name);
1066 CustomData_set_layer_unique_name(&me->pdata, totlayer_mtex);
1067 } while (totlayer_uv != ++totlayer_mtex);
1068 mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY);
1070 else if (totlayer_uv < totlayer_mtex) {
1072 const char *from_name = me->pdata.layers[mtex_index + totlayer_uv].name;
1073 CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, from_name);
1074 CustomData_set_layer_unique_name(&me->ldata, totlayer_uv);
1075 } while (totlayer_mtex != ++totlayer_uv);
1076 uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV);
1079 BLI_assert(totlayer_mtex == totlayer_uv);
1081 /* Check uv/tex names match as well!!! */
1082 for (i = 0; i < totlayer_mtex; i++, mtex_index++, uv_index++) {
1083 const char *name_src = me->pdata.layers[mtex_index].name;
1084 const char *name_dst = me->ldata.layers[uv_index].name;
1085 if (!STREQ(name_src, name_dst)) {
1086 BKE_mesh_uv_cdlayer_rename_index(me, mtex_index, uv_index, -1, name_src, false);
1092 * Check all material indices of polygons are valid, invalid ones are set to 0.
1093 * \returns is_valid.
1095 bool BKE_mesh_validate_material_indices(Mesh *me)
1098 const int max_idx = max_ii(0, me->totcol - 1);
1099 const int totpoly = me->totpoly;
1101 bool is_valid = true;
1103 for (mp = me->mpoly, i = 0; i < totpoly; i++, mp++) {
1104 if (mp->mat_nr > max_idx) {
1111 DAG_id_tag_update(&me->id, OB_RECALC_DATA);
1122 /* -------------------------------------------------------------------- */
1124 /** \name Mesh Stripping (removing invalid data)
1127 /* We need to keep this for edge creation (for now?), and some old readfile code... */
1128 void BKE_mesh_strip_loose_faces(Mesh *me)
1133 for (a = b = 0, f = me->mface; a < me->totface; a++, f++) {
1136 memcpy(&me->mface[b], f, sizeof(me->mface[b]));
1137 CustomData_copy_data(&me->fdata, &me->fdata, a, b, 1);
1143 CustomData_free_elem(&me->fdata, b, a - b);
1148 /* Works on both loops and polys! */
1149 /* Note: It won't try to guess which loops of an invalid poly to remove!
1150 * this is the work of the caller, to mark those loops...
1151 * See e.g. BKE_mesh_validate_arrays(). */
1152 void BKE_mesh_strip_loose_polysloops(Mesh *me)
1157 /* New loops idx! */
1158 int *new_idx = MEM_mallocN(sizeof(int) * me->totloop, __func__);
1160 for (a = b = 0, p = me->mpoly; a < me->totpoly; a++, p++) {
1161 bool invalid = false;
1162 int i = p->loopstart;
1163 int stop = i + p->totloop;
1165 if (stop > me->totloop || stop < i) {
1171 /* If one of the poly's loops is invalid, the whole poly is invalid! */
1173 if (l->e == INVALID_LOOP_EDGE_MARKER) {
1180 if (p->totloop >= 3 && !invalid) {
1182 memcpy(&me->mpoly[b], p, sizeof(me->mpoly[b]));
1183 CustomData_copy_data(&me->pdata, &me->pdata, a, b, 1);
1189 CustomData_free_elem(&me->pdata, b, a - b);
1193 /* And now, get rid of invalid loops. */
1194 for (a = b = 0, l = me->mloop; a < me->totloop; a++, l++) {
1195 if (l->e != INVALID_LOOP_EDGE_MARKER) {
1197 memcpy(&me->mloop[b], l, sizeof(me->mloop[b]));
1198 CustomData_copy_data(&me->ldata, &me->ldata, a, b, 1);
1204 /* XXX Theoretically, we should be able to not do this, as no remaining poly
1205 * should use any stripped loop. But for security's sake... */
1210 CustomData_free_elem(&me->ldata, b, a - b);
1214 /* And now, update polys' start loop index. */
1215 /* Note: At this point, there should never be any poly using a striped loop! */
1216 for (a = 0, p = me->mpoly; a < me->totpoly; a++, p++) {
1217 p->loopstart = new_idx[p->loopstart];
1223 void BKE_mesh_strip_loose_edges(Mesh *me)
1228 unsigned int *new_idx = MEM_mallocN(sizeof(int) * me->totedge, __func__);
1230 for (a = b = 0, e = me->medge; a < me->totedge; a++, e++) {
1231 if (e->v1 != e->v2) {
1233 memcpy(&me->medge[b], e, sizeof(me->medge[b]));
1234 CustomData_copy_data(&me->edata, &me->edata, a, b, 1);
1240 new_idx[a] = INVALID_LOOP_EDGE_MARKER;
1244 CustomData_free_elem(&me->edata, b, a - b);
1248 /* And now, update loops' edge indices. */
1249 /* XXX We hope no loop was pointing to a striped edge!
1250 * Else, its e will be set to INVALID_LOOP_EDGE_MARKER :/ */
1251 for (a = 0, l = me->mloop; a < me->totloop; a++, l++) {
1252 l->e = new_idx[l->e];
1261 /* -------------------------------------------------------------------- */
1263 /** \name Mesh Edge Calculation
1266 /* make edges in a Mesh, for outside of editmode */
1269 unsigned int v1, v2;
1270 char is_loose, is_draw;
1273 /* edges have to be added with lowest index first for sorting */
1274 static void to_edgesort(
1275 struct EdgeSort *ed,
1276 unsigned int v1, unsigned int v2,
1277 char is_loose, short is_draw)
1280 ed->v1 = v1; ed->v2 = v2;
1283 ed->v1 = v2; ed->v2 = v1;
1285 ed->is_loose = is_loose;
1286 ed->is_draw = is_draw;
1289 static int vergedgesort(const void *v1, const void *v2)
1291 const struct EdgeSort *x1 = v1, *x2 = v2;
1293 if (x1->v1 > x2->v1) return 1;
1294 else if (x1->v1 < x2->v1) return -1;
1295 else if (x1->v2 > x2->v2) return 1;
1296 else if (x1->v2 < x2->v2) return -1;
1302 /* Create edges based on known verts and faces,
1303 * this function is only used when loading very old blend files */
1305 static void mesh_calc_edges_mdata(
1306 MVert *UNUSED(allvert), MFace *allface, MLoop *allloop,
1307 MPoly *allpoly, int UNUSED(totvert), int totface, int UNUSED(totloop), int totpoly,
1309 MEdge **r_medge, int *r_totedge)
1315 struct EdgeSort *edsort, *ed;
1317 unsigned int totedge_final = 0;
1318 unsigned int edge_index;
1320 /* we put all edges in array, sort them, and detect doubles that way */
1322 for (a = totface, mface = allface; a > 0; a--, mface++) {
1323 if (mface->v4) totedge += 4;
1324 else if (mface->v3) totedge += 3;
1329 /* flag that mesh has edges */
1330 (*r_medge) = MEM_callocN(0, __func__);
1335 ed = edsort = MEM_mallocN(totedge * sizeof(struct EdgeSort), "EdgeSort");
1337 for (a = totface, mface = allface; a > 0; a--, mface++) {
1338 to_edgesort(ed++, mface->v1, mface->v2, !mface->v3, mface->edcode & ME_V1V2);
1340 to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
1341 to_edgesort(ed++, mface->v3, mface->v4, 0, mface->edcode & ME_V3V4);
1342 to_edgesort(ed++, mface->v4, mface->v1, 0, mface->edcode & ME_V4V1);
1344 else if (mface->v3) {
1345 to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
1346 to_edgesort(ed++, mface->v3, mface->v1, 0, mface->edcode & ME_V3V1);
1350 qsort(edsort, totedge, sizeof(struct EdgeSort), vergedgesort);
1352 /* count final amount */
1353 for (a = totedge, ed = edsort; a > 1; a--, ed++) {
1354 /* edge is unique when it differs from next edge, or is last */
1355 if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) totedge_final++;
1359 medge = MEM_callocN(sizeof(MEdge) * totedge_final, __func__);
1361 for (a = totedge, med = medge, ed = edsort; a > 1; a--, ed++) {
1362 /* edge is unique when it differs from next edge, or is last */
1363 if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) {
1366 if (use_old == false || ed->is_draw) med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1367 if (ed->is_loose) med->flag |= ME_LOOSEEDGE;
1369 /* order is swapped so extruding this edge as a surface wont flip face normals
1370 * with cyclic curves */
1371 if (ed->v1 + 1 != ed->v2) {
1372 SWAP(unsigned int, med->v1, med->v2);
1377 /* equal edge, we merge the drawflag */
1378 (ed + 1)->is_draw |= ed->is_draw;
1384 med->flag = ME_EDGEDRAW;
1385 if (ed->is_loose) med->flag |= ME_LOOSEEDGE;
1386 med->flag |= ME_EDGERENDER;
1390 /* set edge members of mloops */
1391 hash = BLI_edgehash_new_ex(__func__, totedge_final);
1392 for (edge_index = 0, med = medge; edge_index < totedge_final; edge_index++, med++) {
1393 BLI_edgehash_insert(hash, med->v1, med->v2, POINTER_FROM_UINT(edge_index));
1397 for (a = 0; a < totpoly; a++, mpoly++) {
1398 MLoop *ml, *ml_next;
1399 int i = mpoly->totloop;
1401 ml_next = allloop + mpoly->loopstart; /* first loop */
1402 ml = &ml_next[i - 1]; /* last loop */
1405 ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(hash, ml->v, ml_next->v));
1411 BLI_edgehash_free(hash, NULL);
1414 *r_totedge = totedge_final;
1418 * If the mesh is from a very old blender version,
1419 * convert mface->edcode to edge drawflags
1421 void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
1426 mesh_calc_edges_mdata(
1427 me->mvert, me->mface, me->mloop, me->mpoly,
1428 me->totvert, me->totface, me->totloop, me->totpoly,
1429 use_old, &medge, &totedge);
1432 /* flag that mesh has edges */
1438 medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, totedge);
1440 me->totedge = totedge;
1442 BKE_mesh_strip_loose_faces(me);
1447 * Calculate edges from polygons
1449 * \param mesh: The mesh to add edges into
1450 * \param update: When true create new edges co-exist
1452 void BKE_mesh_calc_edges(Mesh *mesh, bool update, const bool select)
1455 EdgeHashIterator *ehi;
1457 MEdge *med, *med_orig;
1459 unsigned int eh_reserve;
1460 int i, totedge, totpoly = mesh->totpoly;
1462 /* select for newly created meshes which are selected [#25595] */
1463 const short ed_flag = (ME_EDGEDRAW | ME_EDGERENDER) | (select ? SELECT : 0);
1465 if (mesh->totedge == 0)
1468 eh_reserve = max_ii(update ? mesh->totedge : 0, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totpoly));
1469 eh = BLI_edgehash_new_ex(__func__, eh_reserve);
1472 /* assume existing edges are valid
1473 * useful when adding more faces and generating edges from them */
1475 for (i = 0; i < mesh->totedge; i++, med++)
1476 BLI_edgehash_insert(eh, med->v1, med->v2, med);
1479 /* mesh loops (bmesh only) */
1480 for (mp = mesh->mpoly, i = 0; i < totpoly; mp++, i++) {
1481 MLoop *l = &mesh->mloop[mp->loopstart];
1482 int j, v_prev = (l + (mp->totloop - 1))->v;
1483 for (j = 0; j < mp->totloop; j++, l++) {
1484 if (v_prev != l->v) {
1486 if (!BLI_edgehash_ensure_p(eh, v_prev, l->v, &val_p)) {
1494 totedge = BLI_edgehash_len(eh);
1496 /* write new edges into a temporary CustomData */
1497 CustomData_reset(&edata);
1498 CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
1500 med = CustomData_get_layer(&edata, CD_MEDGE);
1501 for (ehi = BLI_edgehashIterator_new(eh), i = 0;
1502 BLI_edgehashIterator_isDone(ehi) == false;
1503 BLI_edgehashIterator_step(ehi), ++i, ++med)
1505 if (update && (med_orig = BLI_edgehashIterator_getValue(ehi))) {
1506 *med = *med_orig; /* copy from the original */
1509 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
1510 med->flag = ed_flag;
1513 /* store the new edge index in the hash value */
1514 BLI_edgehashIterator_setValue(ehi, POINTER_FROM_INT(i));
1516 BLI_edgehashIterator_free(ehi);
1518 if (mesh->totpoly) {
1519 /* second pass, iterate through all loops again and assign
1520 * the newly created edges to them. */
1521 for (mp = mesh->mpoly, i = 0; i < mesh->totpoly; mp++, i++) {
1522 MLoop *l = &mesh->mloop[mp->loopstart];
1523 MLoop *l_prev = (l + (mp->totloop - 1));
1525 for (j = 0; j < mp->totloop; j++, l++) {
1526 /* lookup hashed edge index */
1527 med_index = POINTER_AS_INT(BLI_edgehash_lookup(eh, l_prev->v, l->v));
1528 l_prev->e = med_index;
1534 /* free old CustomData and assign new one */
1535 CustomData_free(&mesh->edata, mesh->totedge);
1536 mesh->edata = edata;
1537 mesh->totedge = totedge;
1539 mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE);
1541 BLI_edgehash_free(eh, NULL);