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(Mesh *mesh,
216 MVert *mverts, unsigned int totvert,
217 MEdge *medges, unsigned int totedge,
218 MFace *mfaces, unsigned int totface,
219 MLoop *mloops, unsigned int totloop,
220 MPoly *mpolys, unsigned int totpoly,
221 MDeformVert *dverts, /* assume totvert length */
222 const bool do_verbose, const bool do_fixes,
225 # define REMOVE_EDGE_TAG(_me) { _me->v2 = _me->v1; free_flag.edges = do_fixes; } (void)0
226 # define IS_REMOVED_EDGE(_me) (_me->v2 == _me->v1)
228 # define REMOVE_LOOP_TAG(_ml) { _ml->e = INVALID_LOOP_EDGE_MARKER; free_flag.polyloops = do_fixes; } (void)0
229 # define REMOVE_POLY_TAG(_mp) { _mp->totloop *= -1; free_flag.polyloops = do_fixes; } (void)0
238 bool is_valid = true;
243 int verts_weight : 1;
253 /* This regroups loops and polys! */
267 EdgeHash *edge_hash = BLI_edgehash_new_ex(__func__, totedge);
269 BLI_assert(!(do_fixes && mesh == NULL));
271 fix_flag.as_flag = 0;
272 free_flag.as_flag = 0;
273 recalc_flag.as_flag = 0;
275 PRINT_MSG("%s: verts(%u), edges(%u), loops(%u), polygons(%u)\n",
276 __func__, totvert, totedge, totloop, totpoly);
278 if (totedge == 0 && totpoly != 0) {
279 PRINT_ERR("\tLogical error, %u polygons and 0 edges\n", totpoly);
280 recalc_flag.edges = do_fixes;
283 for (i = 0; i < totvert; i++, mv++) {
284 bool fix_normal = true;
286 for (j = 0; j < 3; j++) {
287 if (!finite(mv->co[j])) {
288 PRINT_ERR("\tVertex %u: has invalid coordinate\n", i);
293 fix_flag.verts = true;
302 PRINT_ERR("\tVertex %u: has zero normal, assuming Z-up normal\n", i);
304 mv->no[2] = SHRT_MAX;
305 fix_flag.verts = true;
310 for (i = 0, me = medges; i < totedge; i++, me++) {
313 if (me->v1 == me->v2) {
314 PRINT_ERR("\tEdge %u: has matching verts, both %u\n", i, me->v1);
317 if (me->v1 >= totvert) {
318 PRINT_ERR("\tEdge %u: v1 index out of range, %u\n", i, me->v1);
321 if (me->v2 >= totvert) {
322 PRINT_ERR("\tEdge %u: v2 index out of range, %u\n", i, me->v2);
326 if ((me->v1 != me->v2) && BLI_edgehash_haskey(edge_hash, me->v1, me->v2)) {
327 PRINT_ERR("\tEdge %u: is a duplicate of %d\n", i,
328 GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, me->v1, me->v2)));
332 if (remove == false) {
333 if (me->v1 != me->v2) {
334 BLI_edgehash_insert(edge_hash, me->v1, me->v2, SET_INT_IN_POINTER(i));
342 if (mfaces && !mpolys) {
343 # define REMOVE_FACE_TAG(_mf) { _mf->v3 = 0; free_flag.faces = do_fixes; } (void)0
344 # define CHECK_FACE_VERT_INDEX(a, b) \
345 if (mf->a == mf->b) { \
346 PRINT_ERR(" face %u: verts invalid, " STRINGIFY(a) "/" STRINGIFY(b) " both %u\n", i, mf->a); \
349 # define CHECK_FACE_EDGE(a, b) \
350 if (!BLI_edgehash_haskey(edge_hash, mf->a, mf->b)) { \
351 PRINT_ERR(" face %u: edge " STRINGIFY(a) "/" STRINGIFY(b) \
352 " (%u,%u) is missing edge data\n", i, mf->a, mf->b); \
353 recalc_flag.edges = do_fixes; \
359 SortFace *sort_faces = MEM_callocN(sizeof(SortFace) * totface, "search faces");
362 unsigned int totsortface = 0;
364 PRINT_ERR("No Polys, only tesselated Faces\n");
366 for (i = 0, mf = mfaces, sf = sort_faces; i < totface; i++, mf++) {
371 fidx = mf->v4 ? 3 : 2;
373 fv[fidx] = *(&(mf->v1) + fidx);
374 if (fv[fidx] >= totvert) {
375 PRINT_ERR("\tFace %u: 'v%d' index out of range, %u\n", i, fidx + 1, fv[fidx]);
380 if (remove == false) {
382 CHECK_FACE_VERT_INDEX(v1, v2);
383 CHECK_FACE_VERT_INDEX(v1, v3);
384 CHECK_FACE_VERT_INDEX(v1, v4);
386 CHECK_FACE_VERT_INDEX(v2, v3);
387 CHECK_FACE_VERT_INDEX(v2, v4);
389 CHECK_FACE_VERT_INDEX(v3, v4);
392 CHECK_FACE_VERT_INDEX(v1, v2);
393 CHECK_FACE_VERT_INDEX(v1, v3);
395 CHECK_FACE_VERT_INDEX(v2, v3);
398 if (remove == false) {
401 CHECK_FACE_EDGE(v1, v2);
402 CHECK_FACE_EDGE(v2, v3);
403 CHECK_FACE_EDGE(v3, v4);
404 CHECK_FACE_EDGE(v4, v1);
407 CHECK_FACE_EDGE(v1, v2);
408 CHECK_FACE_EDGE(v2, v3);
409 CHECK_FACE_EDGE(v3, v1);
416 edge_store_from_mface_quad(sf->es, mf);
418 qsort(sf->es, 4, sizeof(int64_t), int64_cmp);
421 edge_store_from_mface_tri(sf->es, mf);
422 qsort(sf->es, 3, sizeof(int64_t), int64_cmp);
435 qsort(sort_faces, totsortface, sizeof(SortFace), search_face_cmp);
441 for (i = 1; i < totsortface; i++, sf++) {
444 /* on a valid mesh, code below will never run */
445 if (memcmp(sf->es, sf_prev->es, sizeof(sf_prev->es)) == 0) {
446 mf = mfaces + sf->index;
449 mf_prev = mfaces + sf_prev->index;
452 PRINT_ERR("\tFace %u & %u: are duplicates (%u,%u,%u,%u) (%u,%u,%u,%u)\n",
453 sf->index, sf_prev->index, mf->v1, mf->v2, mf->v3, mf->v4,
454 mf_prev->v1, mf_prev->v2, mf_prev->v3, mf_prev->v4);
457 PRINT_ERR("\tFace %u & %u: are duplicates (%u,%u,%u) (%u,%u,%u)\n",
458 sf->index, sf_prev->index, mf->v1, mf->v2, mf->v3,
459 mf_prev->v1, mf_prev->v2, mf_prev->v3);
474 MEM_freeN(sort_faces);
476 # undef REMOVE_FACE_TAG
477 # undef CHECK_FACE_VERT_INDEX
478 # undef CHECK_FACE_EDGE
481 /* Checking loops and polys is a bit tricky, as they are quite intricate...
484 * - a valid loopstart value.
485 * - a valid totloop value (>= 3 and loopstart+totloop < me.totloop).
489 * - a valid e value (corresponding to the edge it defines with the next loop in poly).
491 * Also, loops not used by polys can be discarded.
492 * And "intersecting" loops (i.e. loops used by more than one poly) are invalid,
493 * so be sure to leave at most one poly per loop!
496 SortPoly *sort_polys = MEM_callocN(sizeof(SortPoly) * totpoly, "mesh validate's sort_polys");
497 SortPoly *prev_sp, *sp = sort_polys;
500 for (i = 0, mp = mpolys; i < totpoly; i++, mp++, sp++) {
503 if (mp->loopstart < 0 || mp->totloop < 3) {
504 /* Invalid loop data. */
505 PRINT_ERR("\tPoly %u is invalid (loopstart: %d, totloop: %d)\n",
506 sp->index, mp->loopstart, mp->totloop);
509 else if (mp->loopstart + mp->totloop > totloop) {
510 /* Invalid loop data. */
511 PRINT_ERR("\tPoly %u uses loops out of range (loopstart: %d, loopend: %d, max nbr of loops: %u)\n",
512 sp->index, mp->loopstart, mp->loopstart + mp->totloop - 1, totloop - 1);
516 /* Poly itself is valid, for now. */
517 int v1, v2; /* v1 is prev loop vert idx, v2 is current loop one. */
519 sp->verts = v = MEM_mallocN(sizeof(int) * mp->totloop, "Vert idx of SortPoly");
520 sp->numverts = mp->totloop;
521 sp->loopstart = mp->loopstart;
523 /* Ideally we would only have to do that once on all vertices before we start checking each poly, but
524 * several polys can use same vert, so we have to ensure here all verts of current poly are cleared. */
525 for (j = 0, ml = &mloops[sp->loopstart]; j < mp->totloop; j++, ml++) {
526 if (ml->v < totvert) {
527 mverts[ml->v].flag &= ~ME_VERT_TMP_TAG;
531 /* Test all poly's loops' vert idx. */
532 for (j = 0, ml = &mloops[sp->loopstart]; j < mp->totloop; j++, ml++, v++) {
533 if (ml->v >= totvert) {
534 /* Invalid vert idx. */
535 PRINT_ERR("\tLoop %u has invalid vert reference (%u)\n", sp->loopstart + j, ml->v);
538 else if (mverts[ml->v].flag & ME_VERT_TMP_TAG) {
539 PRINT_ERR("\tPoly %u has duplicated vert reference at corner (%u)\n", i, j);
543 mverts[ml->v].flag |= ME_VERT_TMP_TAG;
551 /* Test all poly's loops. */
552 for (j = 0, ml = &mloops[sp->loopstart]; j < mp->totloop; j++, ml++) {
554 v2 = mloops[sp->loopstart + (j + 1) % mp->totloop].v;
555 if (!BLI_edgehash_haskey(edge_hash, v1, v2)) {
556 /* Edge not existing. */
557 PRINT_ERR("\tPoly %u needs missing edge (%d, %d)\n", sp->index, v1, v2);
559 recalc_flag.edges = true;
563 else if (ml->e >= totedge) {
565 * We already know from previous text that a valid edge exists, use it (if allowed)! */
568 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, v1, v2));
569 fix_flag.loops_edge = true;
570 PRINT_ERR("\tLoop %u has invalid edge reference (%d), fixed using edge %u\n",
571 sp->loopstart + j, prev_e, ml->e);
574 PRINT_ERR("\tLoop %u has invalid edge reference (%u)\n", sp->loopstart + j, ml->e);
580 if (IS_REMOVED_EDGE(me) || !((me->v1 == v1 && me->v2 == v2) || (me->v1 == v2 && me->v2 == v1))) {
581 /* The pointed edge is invalid (tagged as removed, or vert idx mismatch),
582 * and we already know from previous test that a valid one exists, use it (if allowed)! */
585 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, v1, v2));
586 fix_flag.loops_edge = true;
587 PRINT_ERR("\tPoly %u has invalid edge reference (%d), fixed using edge %u\n",
588 sp->index, prev_e, ml->e);
591 PRINT_ERR("\tPoly %u has invalid edge reference (%u)\n", sp->index, ml->e);
599 /* Needed for checking polys using same verts below. */
600 qsort(sp->verts, sp->numverts, sizeof(int), int_cmp);
605 /* Second check pass, testing polys using the same verts. */
606 qsort(sort_polys, totpoly, sizeof(SortPoly), search_poly_cmp);
607 sp = prev_sp = sort_polys;
610 for (i = 1; i < totpoly; i++, sp++) {
611 int p1_nv = sp->numverts, p2_nv = prev_sp->numverts;
612 const int *p1_v = sp->verts, *p2_v = prev_sp->verts;
615 /* break, because all known invalid polys have been put at the end by qsort with search_poly_cmp. */
619 /* Test same polys. */
622 bool p1_sub = true, p2_sub = true;
624 /* NOTE: This performs a sub-set test. */
625 /* XXX This (and the sort of verts list) is better than systematic
626 * search of all verts of one list into the other if lists have
627 * a fair amount of elements.
628 * Not sure however it's worth it in this case?
629 * But as we also need sorted vert list to check verts multi-used
630 * (in first pass of checks)... */
631 /* XXX If we consider only "equal" polys (i.e. using exactly same set of verts)
632 * as invalid, better to replace this by a simple memory cmp... */
633 while ((p1_nv && p2_nv) && (p1_sub || p2_sub)) {
640 else if (*p2_v < *p1_v) {
647 /* Equality, both next verts. */
656 else if (p2_nv && p2_sub)
659 if (p1_sub && p2_sub) {
660 PRINT("\tPolys %u and %u use same vertices, considering poly %u as invalid.\n",
661 prev_sp->index, sp->index, sp->index);
664 /* XXX In fact, these might be valid? :/ */
666 PRINT("\t%u is a sub-poly of %u, considering it as invalid.\n", sp->index, prev_sp->index);
670 PRINT("\t%u is a sub-poly of %u, considering it as invalid.\n", prev_sp->index, sp->index);
671 prev_sp->invalid = true;
672 prev_sp = sp; /* sp is new reference poly. */
676 if ((p1_nv == p2_nv) && (memcmp(p1_v, p2_v, p1_nv * sizeof(*p1_v)) == 0)) {
678 PRINT_ERR("\tPolys %u and %u use same vertices (%d",
679 prev_sp->index, sp->index, *p1_v);
680 for (j = 1; j < p1_nv; j++)
681 PRINT_ERR(", %d", p1_v[j]);
682 PRINT_ERR("), considering poly %u as invalid.\n", sp->index);
695 /* Third check pass, testing loops used by none or more than one poly. */
696 qsort(sort_polys, totpoly, sizeof(SortPoly), search_polyloop_cmp);
700 for (i = 0; i < totpoly; i++, sp++) {
701 /* Free this now, we don't need it anymore, and avoid us another loop! */
703 MEM_freeN(sp->verts);
705 /* Note above prev_sp: in following code, we make sure it is always valid poly (or NULL). */
708 REMOVE_POLY_TAG((&mpolys[sp->index]));
709 /* DO NOT REMOVE ITS LOOPS!!!
710 * As already invalid polys are at the end of the SortPoly list, the loops they
711 * were the only users have already been tagged as "to remove" during previous
712 * iterations, and we don't want to remove some loops that may be used by
713 * another valid poly! */
716 /* Test loops users. */
719 if (prev_end < sp->loopstart) {
720 for (j = prev_end, ml = &mloops[prev_end]; j < sp->loopstart; j++, ml++) {
721 PRINT_ERR("\tLoop %u is unused.\n", j);
725 prev_end = sp->loopstart + sp->numverts;
728 /* Multi-used loops. */
729 else if (prev_end > sp->loopstart) {
730 PRINT_ERR("\tPolys %u and %u share loops from %d to %d, considering poly %u as invalid.\n",
731 prev_sp->index, sp->index, sp->loopstart, prev_end, sp->index);
733 REMOVE_POLY_TAG((&mpolys[sp->index]));
734 /* DO NOT REMOVE ITS LOOPS!!!
735 * They might be used by some next, valid poly!
736 * Just not updating prev_end/prev_sp vars is enough to ensure the loops
737 * effectively no more needed will be marked as "to be removed"! */
741 prev_end = sp->loopstart + sp->numverts;
746 /* We may have some remaining unused loops to get rid of! */
747 if (prev_end < totloop) {
748 for (j = prev_end, ml = &mloops[prev_end]; j < totloop; j++, ml++) {
749 PRINT_ERR("\tLoop %u is unused.\n", j);
755 MEM_freeN(sort_polys);
758 BLI_edgehash_free(edge_hash, NULL);
760 /* fix deform verts */
763 for (i = 0, dv = dverts; i < totvert; i++, dv++) {
766 for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) {
767 /* note, greater than max defgroups is accounted for in our code, but not < 0 */
768 if (!finite(dw->weight)) {
769 PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight);
772 fix_flag.verts_weight = true;
775 else if (dw->weight < 0.0f || dw->weight > 1.0f) {
776 PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight);
778 CLAMP(dw->weight, 0.0f, 1.0f);
779 fix_flag.verts_weight = true;
783 if (dw->def_nr < 0) {
784 PRINT_ERR("\tVertex deform %u, has invalid group %d\n", i, dw->def_nr);
786 defvert_remove_group(dv, dw);
787 fix_flag.verts_weight = true;
790 /* re-allocated, the new values compensate for stepping
791 * within the for loop and may not be valid */
796 else { /* all freed */
805 # undef REMOVE_EDGE_TAG
806 # undef IS_REMOVED_EDGE
807 # undef REMOVE_LOOP_TAG
808 # undef REMOVE_POLY_TAG
811 if (free_flag.faces) {
812 BKE_mesh_strip_loose_faces(mesh);
815 if (free_flag.polyloops) {
816 BKE_mesh_strip_loose_polysloops(mesh);
819 if (free_flag.edges) {
820 BKE_mesh_strip_loose_edges(mesh);
823 if (recalc_flag.edges) {
824 BKE_mesh_calc_edges(mesh, true, false);
828 if (mesh && mesh->mselect) {
831 for (i = 0, msel = mesh->mselect; i < mesh->totselect; i++, msel++) {
834 if (msel->index < 0) {
835 PRINT_ERR("\tMesh select element %u type %d index is negative, "
836 "resetting selection stack.\n", i, msel->type);
837 free_flag.mselect = do_fixes;
841 switch (msel->type) {
843 tot_elem = mesh->totvert;
846 tot_elem = mesh->totedge;
849 tot_elem = mesh->totface;
853 if (msel->index > tot_elem) {
854 PRINT_ERR("\tMesh select element %u type %d index %d is larger than data array size %d, "
855 "resetting selection stack.\n", i, msel->type, msel->index, tot_elem);
857 free_flag.mselect = do_fixes;
862 if (free_flag.mselect) {
863 MEM_freeN(mesh->mselect);
864 mesh->mselect = NULL;
869 PRINT_MSG("%s: finished\n\n", __func__);
871 *r_changed = (fix_flag.as_flag || free_flag.as_flag || recalc_flag.as_flag);
873 BLI_assert((*r_changed == false) || (do_fixes == true));
878 static bool mesh_validate_customdata(CustomData *data, CustomDataMask mask,
879 const bool do_verbose, const bool do_fixes,
882 bool is_valid = true;
883 bool has_fixes = false;
886 PRINT_MSG("%s: Checking %d CD layers...\n", __func__, data->totlayer);
888 while (i < data->totlayer) {
889 CustomDataLayer *layer = &data->layers[i];
892 if (CustomData_layertype_is_singleton(layer->type)) {
893 const int layer_tot = CustomData_number_of_layers(data, layer->type);
895 PRINT_ERR("\tCustomDataLayer type %d is a singleton, found %d in Mesh structure\n",
896 layer->type, layer_tot);
902 CustomDataMask layer_typemask = CD_TYPE_AS_MASK(layer->type);
903 if ((layer_typemask & mask) == 0) {
904 PRINT_ERR("\tCustomDataLayer type %d which isn't in the mask\n",
912 CustomData_free_layer(data, layer->type, 0, i);
921 PRINT_MSG("%s: Finished (is_valid=%d)\n\n", __func__, (int)!has_fixes);
923 *r_change = has_fixes;
931 bool BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata,
932 CustomData *ldata, CustomData *pdata,
933 const bool check_meshmask,
934 const bool do_verbose, const bool do_fixes,
937 bool is_valid = true;
938 bool is_change_v, is_change_e, is_change_l, is_change_p;
939 int tot_texpoly, tot_uvloop, tot_vcolloop;
940 CustomDataMask mask = check_meshmask ? CD_MASK_MESH : 0;
942 is_valid &= mesh_validate_customdata(vdata, mask, do_verbose, do_fixes, &is_change_v);
943 is_valid &= mesh_validate_customdata(edata, mask, do_verbose, do_fixes, &is_change_e);
944 is_valid &= mesh_validate_customdata(ldata, mask, do_verbose, do_fixes, &is_change_l);
945 is_valid &= mesh_validate_customdata(pdata, mask, do_verbose, do_fixes, &is_change_p);
947 tot_texpoly = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
948 tot_uvloop = CustomData_number_of_layers(ldata, CD_MLOOPUV);
949 tot_vcolloop = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
950 if (tot_texpoly != tot_uvloop) {
951 PRINT_ERR("\tCustomDataLayer mismatch, tot_texpoly(%d), tot_uvloop(%d)\n",
952 tot_texpoly, tot_uvloop);
954 if (tot_texpoly > MAX_MTFACE) {
955 PRINT_ERR("\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
956 MAX_MTFACE, tot_texpoly - MAX_MTFACE);
958 if (tot_uvloop > MAX_MTFACE) {
959 PRINT_ERR("\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
960 MAX_MTFACE, tot_uvloop - MAX_MTFACE);
962 if (tot_vcolloop > MAX_MCOL) {
963 PRINT_ERR("\tMore VCol layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
964 MAX_MCOL, tot_vcolloop - MAX_MCOL);
967 /* check indices of clone/stencil */
968 if (do_fixes && CustomData_get_clone_layer(pdata, CD_MTEXPOLY) >= tot_texpoly) {
969 CustomData_set_layer_clone(pdata, CD_MTEXPOLY, 0);
972 if (do_fixes && CustomData_get_clone_layer(ldata, CD_MLOOPUV) >= tot_uvloop) {
973 CustomData_set_layer_clone(ldata, CD_MLOOPUV, 0);
976 if (do_fixes && CustomData_get_stencil_layer(pdata, CD_MTEXPOLY) >= tot_texpoly) {
977 CustomData_set_layer_stencil(pdata, CD_MTEXPOLY, 0);
980 if (do_fixes && CustomData_get_stencil_layer(ldata, CD_MLOOPUV) >= tot_uvloop) {
981 CustomData_set_layer_stencil(ldata, CD_MLOOPUV, 0);
985 *r_change = (is_change_v || is_change_e || is_change_l || is_change_p);
991 * \see #DM_is_valid to call on derived meshes
993 * \returns true if a change is made.
995 int BKE_mesh_validate(Mesh *me, const int do_verbose, const int cddata_check_mask)
997 bool is_valid = true;
1001 printf("MESH: %s\n", me->id.name + 2);
1004 is_valid &= BKE_mesh_validate_all_customdata(
1005 &me->vdata, &me->edata, &me->ldata, &me->pdata,
1010 is_valid &= BKE_mesh_validate_arrays(
1012 me->mvert, me->totvert,
1013 me->medge, me->totedge,
1014 me->mface, me->totface,
1015 me->mloop, me->totloop,
1016 me->mpoly, me->totpoly,
1022 DAG_id_tag_update(&me->id, OB_RECALC_DATA);
1031 * Duplicate of BM_mesh_cd_validate() for Mesh data.
1033 void BKE_mesh_cd_validate(Mesh *me)
1035 int totlayer_mtex = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
1036 int totlayer_uv = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
1037 int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
1038 int mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY);
1039 int uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV);
1042 /* XXX For now, do not delete those, just warn they are not really usable. */
1043 if (UNLIKELY(totlayer_mtex > MAX_MTFACE)) {
1044 printf("WARNING! More UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
1045 MAX_MTFACE, totlayer_mtex - MAX_MTFACE);
1047 if (UNLIKELY(totlayer_uv > MAX_MTFACE)) {
1048 printf("WARNING! More UV layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
1049 MAX_MTFACE, totlayer_uv - MAX_MTFACE);
1051 if (UNLIKELY(totlayer_mcol > MAX_MCOL)) {
1052 printf("WARNING! More VCol layers than %d allowed, %d last ones won't be available for render, shaders, etc.\n",
1053 MAX_MCOL, totlayer_mcol - MAX_MCOL);
1056 if (LIKELY(totlayer_mtex == totlayer_uv)) {
1059 else if (totlayer_mtex < totlayer_uv) {
1061 const char *from_name = me->ldata.layers[uv_index + totlayer_mtex].name;
1062 CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, from_name);
1063 CustomData_set_layer_unique_name(&me->pdata, totlayer_mtex);
1064 } while (totlayer_uv != ++totlayer_mtex);
1065 mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY);
1067 else if (totlayer_uv < totlayer_mtex) {
1069 const char *from_name = me->pdata.layers[mtex_index + totlayer_uv].name;
1070 CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, from_name);
1071 CustomData_set_layer_unique_name(&me->ldata, totlayer_uv);
1072 } while (totlayer_mtex != ++totlayer_uv);
1073 uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV);
1076 BLI_assert(totlayer_mtex == totlayer_uv);
1078 /* Check uv/tex names match as well!!! */
1079 for (i = 0; i < totlayer_mtex; i++, mtex_index++, uv_index++) {
1080 const char *name_src = me->pdata.layers[mtex_index].name;
1081 const char *name_dst = me->ldata.layers[uv_index].name;
1082 if (!STREQ(name_src, name_dst)) {
1083 BKE_mesh_uv_cdlayer_rename_index(me, mtex_index, uv_index, -1, name_src, false);
1089 * Check all material indices of polygons are valid, invalid ones are set to 0.
1090 * \returns is_valid.
1092 int BKE_mesh_validate_material_indices(Mesh *me)
1095 const int max_idx = max_ii(0, me->totcol - 1);
1096 const int totpoly = me->totpoly;
1098 bool is_valid = true;
1100 for (mp = me->mpoly, i = 0; i < totpoly; i++, mp++) {
1101 if (mp->mat_nr > max_idx) {
1108 DAG_id_tag_update(&me->id, OB_RECALC_DATA);
1119 /* -------------------------------------------------------------------- */
1121 /** \name Mesh Stripping (removing invalid data)
1124 /* We need to keep this for edge creation (for now?), and some old readfile code... */
1125 void BKE_mesh_strip_loose_faces(Mesh *me)
1130 for (a = b = 0, f = me->mface; a < me->totface; a++, f++) {
1133 memcpy(&me->mface[b], f, sizeof(me->mface[b]));
1134 CustomData_copy_data(&me->fdata, &me->fdata, a, b, 1);
1140 CustomData_free_elem(&me->fdata, b, a - b);
1145 /* Works on both loops and polys! */
1146 /* Note: It won't try to guess which loops of an invalid poly to remove!
1147 * this is the work of the caller, to mark those loops...
1148 * See e.g. BKE_mesh_validate_arrays(). */
1149 void BKE_mesh_strip_loose_polysloops(Mesh *me)
1154 /* New loops idx! */
1155 int *new_idx = MEM_mallocN(sizeof(int) * me->totloop, __func__);
1157 for (a = b = 0, p = me->mpoly; a < me->totpoly; a++, p++) {
1158 bool invalid = false;
1159 int i = p->loopstart;
1160 int stop = i + p->totloop;
1162 if (stop > me->totloop || stop < i) {
1168 /* If one of the poly's loops is invalid, the whole poly is invalid! */
1170 if (l->e == INVALID_LOOP_EDGE_MARKER) {
1177 if (p->totloop >= 3 && !invalid) {
1179 memcpy(&me->mpoly[b], p, sizeof(me->mpoly[b]));
1180 CustomData_copy_data(&me->pdata, &me->pdata, a, b, 1);
1186 CustomData_free_elem(&me->pdata, b, a - b);
1190 /* And now, get rid of invalid loops. */
1191 for (a = b = 0, l = me->mloop; a < me->totloop; a++, l++) {
1192 if (l->e != INVALID_LOOP_EDGE_MARKER) {
1194 memcpy(&me->mloop[b], l, sizeof(me->mloop[b]));
1195 CustomData_copy_data(&me->ldata, &me->ldata, a, b, 1);
1201 /* XXX Theoretically, we should be able to not do this, as no remaining poly
1202 * should use any stripped loop. But for security's sake... */
1207 CustomData_free_elem(&me->ldata, b, a - b);
1211 /* And now, update polys' start loop index. */
1212 /* Note: At this point, there should never be any poly using a striped loop! */
1213 for (a = 0, p = me->mpoly; a < me->totpoly; a++, p++) {
1214 p->loopstart = new_idx[p->loopstart];
1220 void BKE_mesh_strip_loose_edges(Mesh *me)
1225 unsigned int *new_idx = MEM_mallocN(sizeof(int) * me->totedge, __func__);
1227 for (a = b = 0, e = me->medge; a < me->totedge; a++, e++) {
1228 if (e->v1 != e->v2) {
1230 memcpy(&me->medge[b], e, sizeof(me->medge[b]));
1231 CustomData_copy_data(&me->edata, &me->edata, a, b, 1);
1237 new_idx[a] = INVALID_LOOP_EDGE_MARKER;
1241 CustomData_free_elem(&me->edata, b, a - b);
1245 /* And now, update loops' edge indices. */
1246 /* XXX We hope no loop was pointing to a striped edge!
1247 * Else, its e will be set to INVALID_LOOP_EDGE_MARKER :/ */
1248 for (a = 0, l = me->mloop; a < me->totloop; a++, l++) {
1249 l->e = new_idx[l->e];
1258 /* -------------------------------------------------------------------- */
1260 /** \name Mesh Edge Calculation
1263 /* make edges in a Mesh, for outside of editmode */
1266 unsigned int v1, v2;
1267 char is_loose, is_draw;
1270 /* edges have to be added with lowest index first for sorting */
1271 static void to_edgesort(struct EdgeSort *ed,
1272 unsigned int v1, unsigned int v2,
1273 char is_loose, short is_draw)
1276 ed->v1 = v1; ed->v2 = v2;
1279 ed->v1 = v2; ed->v2 = v1;
1281 ed->is_loose = is_loose;
1282 ed->is_draw = is_draw;
1285 static int vergedgesort(const void *v1, const void *v2)
1287 const struct EdgeSort *x1 = v1, *x2 = v2;
1289 if (x1->v1 > x2->v1) return 1;
1290 else if (x1->v1 < x2->v1) return -1;
1291 else if (x1->v2 > x2->v2) return 1;
1292 else if (x1->v2 < x2->v2) return -1;
1298 /* Create edges based on known verts and faces,
1299 * this function is only used when loading very old blend files */
1301 static void mesh_calc_edges_mdata(
1302 MVert *UNUSED(allvert), MFace *allface, MLoop *allloop,
1303 MPoly *allpoly, int UNUSED(totvert), int totface, int UNUSED(totloop), int totpoly,
1305 MEdge **r_medge, int *r_totedge)
1311 struct EdgeSort *edsort, *ed;
1313 unsigned int totedge_final = 0;
1314 unsigned int edge_index;
1316 /* we put all edges in array, sort them, and detect doubles that way */
1318 for (a = totface, mface = allface; a > 0; a--, mface++) {
1319 if (mface->v4) totedge += 4;
1320 else if (mface->v3) totedge += 3;
1325 /* flag that mesh has edges */
1326 (*r_medge) = MEM_callocN(0, __func__);
1331 ed = edsort = MEM_mallocN(totedge * sizeof(struct EdgeSort), "EdgeSort");
1333 for (a = totface, mface = allface; a > 0; a--, mface++) {
1334 to_edgesort(ed++, mface->v1, mface->v2, !mface->v3, mface->edcode & ME_V1V2);
1336 to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
1337 to_edgesort(ed++, mface->v3, mface->v4, 0, mface->edcode & ME_V3V4);
1338 to_edgesort(ed++, mface->v4, mface->v1, 0, mface->edcode & ME_V4V1);
1340 else if (mface->v3) {
1341 to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
1342 to_edgesort(ed++, mface->v3, mface->v1, 0, mface->edcode & ME_V3V1);
1346 qsort(edsort, totedge, sizeof(struct EdgeSort), vergedgesort);
1348 /* count final amount */
1349 for (a = totedge, ed = edsort; a > 1; a--, ed++) {
1350 /* edge is unique when it differs from next edge, or is last */
1351 if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) totedge_final++;
1355 medge = MEM_callocN(sizeof(MEdge) * totedge_final, __func__);
1357 for (a = totedge, med = medge, ed = edsort; a > 1; a--, ed++) {
1358 /* edge is unique when it differs from next edge, or is last */
1359 if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) {
1362 if (use_old == false || ed->is_draw) med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1363 if (ed->is_loose) med->flag |= ME_LOOSEEDGE;
1365 /* order is swapped so extruding this edge as a surface wont flip face normals
1366 * with cyclic curves */
1367 if (ed->v1 + 1 != ed->v2) {
1368 SWAP(unsigned int, med->v1, med->v2);
1373 /* equal edge, we merge the drawflag */
1374 (ed + 1)->is_draw |= ed->is_draw;
1380 med->flag = ME_EDGEDRAW;
1381 if (ed->is_loose) med->flag |= ME_LOOSEEDGE;
1382 med->flag |= ME_EDGERENDER;
1386 /* set edge members of mloops */
1387 hash = BLI_edgehash_new_ex(__func__, totedge_final);
1388 for (edge_index = 0, med = medge; edge_index < totedge_final; edge_index++, med++) {
1389 BLI_edgehash_insert(hash, med->v1, med->v2, SET_UINT_IN_POINTER(edge_index));
1393 for (a = 0; a < totpoly; a++, mpoly++) {
1394 MLoop *ml, *ml_next;
1395 int i = mpoly->totloop;
1397 ml_next = allloop + mpoly->loopstart; /* first loop */
1398 ml = &ml_next[i - 1]; /* last loop */
1401 ml->e = GET_UINT_FROM_POINTER(BLI_edgehash_lookup(hash, ml->v, ml_next->v));
1407 BLI_edgehash_free(hash, NULL);
1410 *r_totedge = totedge_final;
1414 * If the mesh is from a very old blender version,
1415 * convert mface->edcode to edge drawflags
1417 void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
1422 mesh_calc_edges_mdata(me->mvert, me->mface, me->mloop, me->mpoly,
1423 me->totvert, me->totface, me->totloop, me->totpoly,
1424 use_old, &medge, &totedge);
1427 /* flag that mesh has edges */
1433 medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, totedge);
1435 me->totedge = totedge;
1437 BKE_mesh_strip_loose_faces(me);
1442 * Calculate edges from polygons
1444 * \param mesh The mesh to add edges into
1445 * \param update When true create new edges co-exist
1447 void BKE_mesh_calc_edges(Mesh *mesh, bool update, const bool select)
1450 EdgeHashIterator *ehi;
1452 MEdge *med, *med_orig;
1454 unsigned int eh_reserve;
1455 int i, totedge, totpoly = mesh->totpoly;
1457 /* select for newly created meshes which are selected [#25595] */
1458 const short ed_flag = (ME_EDGEDRAW | ME_EDGERENDER) | (select ? SELECT : 0);
1460 if (mesh->totedge == 0)
1463 eh_reserve = max_ii(update ? mesh->totedge : 0, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totpoly));
1464 eh = BLI_edgehash_new_ex(__func__, eh_reserve);
1467 /* assume existing edges are valid
1468 * useful when adding more faces and generating edges from them */
1470 for (i = 0; i < mesh->totedge; i++, med++)
1471 BLI_edgehash_insert(eh, med->v1, med->v2, med);
1474 /* mesh loops (bmesh only) */
1475 for (mp = mesh->mpoly, i = 0; i < totpoly; mp++, i++) {
1476 MLoop *l = &mesh->mloop[mp->loopstart];
1477 int j, v_prev = (l + (mp->totloop - 1))->v;
1478 for (j = 0; j < mp->totloop; j++, l++) {
1479 if (v_prev != l->v) {
1481 if (!BLI_edgehash_ensure_p(eh, v_prev, l->v, &val_p)) {
1489 totedge = BLI_edgehash_size(eh);
1491 /* write new edges into a temporary CustomData */
1492 CustomData_reset(&edata);
1493 CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
1495 med = CustomData_get_layer(&edata, CD_MEDGE);
1496 for (ehi = BLI_edgehashIterator_new(eh), i = 0;
1497 BLI_edgehashIterator_isDone(ehi) == false;
1498 BLI_edgehashIterator_step(ehi), ++i, ++med)
1500 if (update && (med_orig = BLI_edgehashIterator_getValue(ehi))) {
1501 *med = *med_orig; /* copy from the original */
1504 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
1505 med->flag = ed_flag;
1508 /* store the new edge index in the hash value */
1509 BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
1511 BLI_edgehashIterator_free(ehi);
1513 if (mesh->totpoly) {
1514 /* second pass, iterate through all loops again and assign
1515 * the newly created edges to them. */
1516 for (mp = mesh->mpoly, i = 0; i < mesh->totpoly; mp++, i++) {
1517 MLoop *l = &mesh->mloop[mp->loopstart];
1518 MLoop *l_prev = (l + (mp->totloop - 1));
1520 for (j = 0; j < mp->totloop; j++, l++) {
1521 /* lookup hashed edge index */
1522 med_index = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, l_prev->v, l->v));
1523 l_prev->e = med_index;
1529 /* free old CustomData and assign new one */
1530 CustomData_free(&mesh->edata, mesh->totedge);
1531 mesh->edata = edata;
1532 mesh->totedge = totedge;
1534 mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE);
1536 BLI_edgehash_free(eh, NULL);