Blender  V3.3
Classes | Macros | Variables
mesh_validate.cc File Reference
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "CLG_log.h"
#include "BLI_bitmap.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "BLI_sys_types.h"
#include "BLI_edgehash.h"
#include "BLI_math_base.h"
#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
#include "DEG_depsgraph.h"
#include "MEM_guardedalloc.h"

Go to the source code of this file.

Classes

union  EdgeUUID
 
struct  SortFace
 
struct  SortPoly
 
struct  EdgeSort
 

Macros

#define INVALID_LOOP_EDGE_MARKER   4294967295u
 
#define REMOVE_EDGE_TAG(_me)
 
#define IS_REMOVED_EDGE(_me)   (_me->v2 == _me->v1)
 
#define REMOVE_LOOP_TAG(_ml)
 
#define REMOVE_POLY_TAG(_mp)
 
#define REMOVE_FACE_TAG(_mf)
 
#define CHECK_FACE_VERT_INDEX(a, b)
 
#define CHECK_FACE_EDGE(a, b)
 

Functions

Internal functions
static void edge_store_assign (uint32_t verts[2], const uint32_t v1, const uint32_t v2)
 
static void edge_store_from_mface_quad (EdgeUUID es[4], MFace *mf)
 
static void edge_store_from_mface_tri (EdgeUUID es[4], MFace *mf)
 
static int int64_cmp (const void *v1, const void *v2)
 
static int search_face_cmp (const void *v1, const void *v2)
 
static int int_cmp (const void *v1, const void *v2)
 
static int search_poly_cmp (const void *v1, const void *v2)
 
static int search_polyloop_cmp (const void *v1, const void *v2)
 
Mesh Stripping (removing invalid data)
void BKE_mesh_strip_loose_faces (Mesh *me)
 
void BKE_mesh_strip_loose_polysloops (Mesh *me)
 
void BKE_mesh_strip_loose_edges (Mesh *me)
 
Mesh Edge Calculation
static void to_edgesort (struct EdgeSort *ed, uint v1, uint v2, char is_loose, short is_draw)
 
static int vergedgesort (const void *v1, const void *v2)
 
static void mesh_calc_edges_mdata (MVert *UNUSED(allvert), MFace *allface, MLoop *allloop, MPoly *allpoly, int UNUSED(totvert), int totface, int UNUSED(totloop), int totpoly, const bool use_old, MEdge **r_medge, int *r_totedge)
 
void BKE_mesh_calc_edges_legacy (Mesh *me, const bool use_old)
 
void BKE_mesh_calc_edges_loose (Mesh *mesh)
 
void BKE_mesh_calc_edges_tessface (Mesh *mesh)
 

Variables

static CLG_LogRef LOG = {"bke.mesh"}
 

Mesh Validation

#define PRINT_MSG(...)
 
#define PRINT_ERR(...)
 
bool BKE_mesh_validate_arrays (Mesh *mesh, MVert *mverts, uint totvert, MEdge *medges, uint totedge, MFace *mfaces, uint totface, MLoop *mloops, uint totloop, MPoly *mpolys, uint totpoly, MDeformVert *dverts, const bool do_verbose, const bool do_fixes, bool *r_changed)
 
static bool mesh_validate_customdata (CustomData *data, eCustomDataMask mask, const uint totitems, const bool do_verbose, const bool do_fixes, bool *r_change)
 
bool BKE_mesh_validate_all_customdata (CustomData *vdata, const uint totvert, CustomData *edata, const uint totedge, CustomData *ldata, const uint totloop, CustomData *pdata, const uint totpoly, const bool check_meshmask, const bool do_verbose, const bool do_fixes, bool *r_change)
 
bool BKE_mesh_validate (Mesh *me, const bool do_verbose, const bool cddata_check_mask)
 
bool BKE_mesh_is_valid (Mesh *me)
 
bool BKE_mesh_validate_material_indices (Mesh *me)
 

Macro Definition Documentation

◆ CHECK_FACE_EDGE

#define CHECK_FACE_EDGE (   a,
 
)
Value:
if (!BLI_edgehash_haskey(edge_hash, mf->a, mf->b)) { \
PRINT_ERR(" face %u: edge " STRINGIFY(a) "/" STRINGIFY(b) " (%u,%u) is missing edge data", \
i, \
mf->a, \
mf->b); \
recalc_flag.edges = do_fixes; \
} \
(void)0
bool BLI_edgehash_haskey(const EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:363
#define STRINGIFY(x)
SyclQueue void void size_t num_bytes void
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken b("b", pxr::TfToken::Immortal)

◆ CHECK_FACE_VERT_INDEX

#define CHECK_FACE_VERT_INDEX (   a,
 
)
Value:
if (mf->a == mf->b) { \
PRINT_ERR(" face %u: verts invalid, " STRINGIFY(a) "/" STRINGIFY(b) " both %u", i, mf->a); \
remove = do_fixes; \
} \
(void)0

◆ INVALID_LOOP_EDGE_MARKER

#define INVALID_LOOP_EDGE_MARKER   4294967295u

Definition at line 36 of file mesh_validate.cc.

◆ IS_REMOVED_EDGE

#define IS_REMOVED_EDGE (   _me)    (_me->v2 == _me->v1)

◆ PRINT_ERR

#define PRINT_ERR (   ...)
Value:
do { \
is_valid = false; \
if (do_verbose) { \
CLOG_ERROR(&LOG, __VA_ARGS__); \
} \
} while (0)
static CLG_LogRef LOG

Definition at line 195 of file mesh_validate.cc.

◆ PRINT_MSG

#define PRINT_MSG (   ...)
Value:
if (do_verbose) { \
CLOG_INFO(&LOG, 1, __VA_ARGS__); \
} \
((void)0)

Definition at line 189 of file mesh_validate.cc.

◆ REMOVE_EDGE_TAG

#define REMOVE_EDGE_TAG (   _me)
Value:
{ \
_me->v2 = _me->v1; \
free_flag.edges = do_fixes; \
} \
(void)0

◆ REMOVE_FACE_TAG

#define REMOVE_FACE_TAG (   _mf)
Value:
{ \
_mf->v3 = 0; \
free_flag.faces = do_fixes; \
} \
(void)0

◆ REMOVE_LOOP_TAG

#define REMOVE_LOOP_TAG (   _ml)
Value:
{ \
free_flag.polyloops = do_fixes; \
} \
(void)0
#define INVALID_LOOP_EDGE_MARKER

◆ REMOVE_POLY_TAG

#define REMOVE_POLY_TAG (   _mp)
Value:
{ \
_mp->totloop *= -1; \
free_flag.polyloops = do_fixes; \
} \
(void)0

Function Documentation

◆ BKE_mesh_calc_edges_legacy()

void BKE_mesh_calc_edges_legacy ( struct Mesh me,
bool  use_old 
)

◆ BKE_mesh_calc_edges_loose()

void BKE_mesh_calc_edges_loose ( Mesh mesh)

◆ BKE_mesh_calc_edges_tessface()

void BKE_mesh_calc_edges_tessface ( struct Mesh mesh)

◆ BKE_mesh_is_valid()

bool BKE_mesh_is_valid ( struct Mesh me)

◆ BKE_mesh_strip_loose_edges()

void BKE_mesh_strip_loose_edges ( Mesh me)

◆ BKE_mesh_strip_loose_faces()

void BKE_mesh_strip_loose_faces ( Mesh me)

◆ BKE_mesh_strip_loose_polysloops()

void BKE_mesh_strip_loose_polysloops ( struct Mesh me)

Works on both loops and polys!

Note
It won't try to guess which loops of an invalid poly to remove! this is the work of the caller, to mark those loops. See e.g. BKE_mesh_validate_arrays().

Definition at line 1184 of file mesh_validate.cc.

References Freestyle::a, usdtokens::b(), CustomData_copy_data(), CustomData_free_elem(), BMLoop::e, INVALID_LOOP_EDGE_MARKER, l, Mesh::ldata, MPoly::loopstart, MEM_freeN, MEM_mallocN, Mesh::mloop, Mesh::mpoly, Mesh::pdata, Mesh::totloop, MPoly::totloop, and Mesh::totpoly.

Referenced by BKE_mesh_validate_arrays().

◆ BKE_mesh_validate()

bool BKE_mesh_validate ( struct Mesh me,
bool  do_verbose,
bool  cddata_check_mask 
)

◆ BKE_mesh_validate_all_customdata()

bool BKE_mesh_validate_all_customdata ( struct CustomData vdata,
uint  totvert,
struct CustomData edata,
uint  totedge,
struct CustomData ldata,
uint  totloop,
struct CustomData pdata,
uint  totpoly,
bool  check_meshmask,
bool  do_verbose,
bool  do_fixes,
bool r_change 
)

◆ BKE_mesh_validate_arrays()

bool BKE_mesh_validate_arrays ( struct Mesh me,
struct MVert mverts,
unsigned int  totvert,
struct MEdge medges,
unsigned int  totedge,
struct MFace mfaces,
unsigned int  totface,
struct MLoop mloops,
unsigned int  totloop,
struct MPoly mpolys,
unsigned int  totpoly,
struct MDeformVert dverts,
bool  do_verbose,
bool  do_fixes,
bool r_change 
)

Validate the mesh, do_fixes requires mesh to be non-null.

Returns
false if no changes needed to be made.

Vertex Normals

While zeroed normals are checked, these checks aren't comprehensive. Technically, to detect errors here a normal recalculation and comparison is necessary. However this function is mainly to prevent severe errors in geometry (invalid data that will crash Blender, or cause some features to behave incorrectly), not to detect subtle differences in the resulting normals which could be caused by importers that load normals (for example).

Definition at line 204 of file mesh_validate.cc.

References BKE_defvert_remove_group(), BKE_mesh_assert_normals_dirty_or_calculated(), BKE_mesh_calc_edges(), BKE_mesh_strip_loose_edges(), BKE_mesh_strip_loose_faces(), BKE_mesh_strip_loose_polysloops(), BKE_mesh_vertex_normals_are_dirty(), BKE_mesh_vertex_normals_ensure(), BLI_assert, BLI_BITMAP_DISABLE, BLI_BITMAP_ENABLE, BLI_BITMAP_NEW, BLI_BITMAP_TEST, BLI_edgehash_free(), BLI_edgehash_haskey(), BLI_edgehash_insert(), BLI_edgehash_lookup(), BLI_edgehash_new_ex(), CHECK_FACE_EDGE, CHECK_FACE_VERT_INDEX, CLAMP, MDeformWeight::def_nr, MDeformVert::dw, MLoop::e, edge_store_from_mface_quad(), edge_store_from_mface_tri(), SortFace::es, faces, float(), if(), SortFace::index, SortPoly::index, MSelect::index, int64_cmp(), int_cmp(), SortPoly::invalid, IS_REMOVED_EDGE, is_valid, is_zero_v3(), CCL_NAMESPACE_BEGIN::isfinite(), SortPoly::loopstart, ME_ESEL, ME_FSEL, ME_VSEL, MEM_callocN, MEM_freeN, MEM_mallocN, mesh, Mesh::mselect, normal, SortPoly::numverts, POINTER_AS_INT, POINTER_FROM_INT, PRINT_ERR, PRINT_MSG, blender::bke::attribute_accessor_functions::remove(), REMOVE_EDGE_TAG, REMOVE_FACE_TAG, REMOVE_LOOP_TAG, REMOVE_POLY_TAG, search_face_cmp(), search_poly_cmp(), search_polyloop_cmp(), Mesh::totedge, Mesh::totpoly, Mesh::totselect, Mesh::totvert, MSelect::type, v, MLoop::v, v1, MEdge::v1, MFace::v1, v2, MEdge::v2, MFace::v2, MFace::v3, MFace::v4, SortPoly::verts, verts, MDeformWeight::weight, and zero_v3().

Referenced by BKE_mesh_is_valid(), BKE_mesh_runtime_is_valid(), BKE_mesh_validate(), and blo_do_versions_290().

◆ BKE_mesh_validate_material_indices()

bool BKE_mesh_validate_material_indices ( struct Mesh me)

Check all material indices of polygons are valid, invalid ones are set to 0.

Returns
True if the material indices are valid.

Definition at line 1133 of file mesh_validate.cc.

References DEG_id_tag_update(), Mesh::id, ID_RECALC_GEOMETRY_ALL_MODES, is_valid, MPoly::mat_nr, max_ii(), Mesh::mpoly, Mesh::totcol, and Mesh::totpoly.

◆ edge_store_assign()

static void edge_store_assign ( uint32_t  verts[2],
const uint32_t  v1,
const uint32_t  v2 
)
static

Definition at line 64 of file mesh_validate.cc.

References v1, v2, and verts.

Referenced by edge_store_from_mface_quad(), and edge_store_from_mface_tri().

◆ edge_store_from_mface_quad()

static void edge_store_from_mface_quad ( EdgeUUID  es[4],
MFace mf 
)
static

Definition at line 76 of file mesh_validate.cc.

References edge_store_assign(), MFace::v1, MFace::v2, MFace::v3, MFace::v4, and verts.

Referenced by BKE_mesh_validate_arrays().

◆ edge_store_from_mface_tri()

static void edge_store_from_mface_tri ( EdgeUUID  es[4],
MFace mf 
)
static

◆ int64_cmp()

static int int64_cmp ( const void v1,
const void v2 
)
static

Definition at line 92 of file mesh_validate.cc.

References v1, v2, and x2.

Referenced by BKE_mesh_validate_arrays().

◆ int_cmp()

static int int_cmp ( const void v1,
const void v2 
)
static

Definition at line 144 of file mesh_validate.cc.

References v1, and v2.

Referenced by BKE_mesh_validate_arrays().

◆ mesh_calc_edges_mdata()

static void mesh_calc_edges_mdata ( MVert UNUSEDallvert,
MFace allface,
MLoop allloop,
MPoly allpoly,
int   UNUSEDtotvert,
int  totface,
int   UNUSEDtotloop,
int  totpoly,
const bool  use_old,
MEdge **  r_medge,
int *  r_totedge 
)
static

◆ mesh_validate_customdata()

static bool mesh_validate_customdata ( CustomData data,
eCustomDataMask  mask,
const uint  totitems,
const bool  do_verbose,
const bool  do_fixes,
bool r_change 
)
static

◆ search_face_cmp()

static int search_face_cmp ( const void v1,
const void v2 
)
static

Definition at line 107 of file mesh_validate.cc.

References EdgeUUID::edval, SortFace::es, v1, and v2.

Referenced by BKE_mesh_validate_arrays().

◆ search_poly_cmp()

static int search_poly_cmp ( const void v1,
const void v2 
)
static

Definition at line 149 of file mesh_validate.cc.

References SortPoly::invalid, SortPoly::numverts, v1, v2, and SortPoly::verts.

Referenced by BKE_mesh_validate_arrays().

◆ search_polyloop_cmp()

static int search_polyloop_cmp ( const void v1,
const void v2 
)
static

Definition at line 170 of file mesh_validate.cc.

References SortPoly::invalid, SortPoly::loopstart, v1, and v2.

Referenced by BKE_mesh_validate_arrays().

◆ to_edgesort()

static void to_edgesort ( struct EdgeSort ed,
uint  v1,
uint  v2,
char  is_loose,
short  is_draw 
)
static

Definition at line 1304 of file mesh_validate.cc.

References EdgeSort::is_draw, EdgeSort::is_loose, EdgeSort::v1, v1, EdgeSort::v2, and v2.

Referenced by mesh_calc_edges_mdata().

◆ vergedgesort()

static int vergedgesort ( const void v1,
const void v2 
)
static

Definition at line 1318 of file mesh_validate.cc.

References EdgeSort::v1, v1, EdgeSort::v2, v2, and x2.

Referenced by mesh_calc_edges_mdata().

Variable Documentation

◆ LOG

CLG_LogRef LOG = {"bke.mesh"}
static

Definition at line 38 of file mesh_validate.cc.

Referenced by BKE_mesh_validate().