Line data Source code
1 : """
2 : isconsistent = checkmesh(mesh[, silent=false)
3 :
4 : Apply consistency checks on `mesh`, print report unless `silent==true`.
5 : """
6 12 : function checkmesh(mesh::Mesh; silent::Bool = false)
7 12 : silent || @info "CHECK Mesh nv=$(nv(mesh)), nf=$(nf(mesh)), ne=$(ne(mesh))"
8 :
9 12 : silent || @info "Check vertex -- half-edge"
10 6 : _check_vh(mesh) || return false
11 :
12 12 : silent || @info "Check face loops"
13 6 : _check_faces(mesh) || return false
14 :
15 12 : silent || @info "Check face -- half-edge"
16 6 : _check_fh(mesh) || return false
17 :
18 : # @debug "boundary: $(hasboundary(mesh)), isolated: $(hasisolatedvertices(mesh))"
19 12 : silent || @debug "manifold: $(ismanifold(mesh))"
20 12 : silent || @debug "triangulation: $(istrianglemesh(mesh)), quad mesh: $(isquadmesh(mesh))"
21 12 : silent || @debug "contiguous v:$(iscontiguous(mesh, VHnd)), f:$(iscontiguous(mesh, FHnd)), e:$(iscontiguous(mesh, EHnd))"
22 :
23 6 : silent || @info "PASSED All checks"
24 :
25 0 : true
26 : end
27 :
28 :
29 6 : function _check_vh(mesh)
30 12 : for v in vertices(mesh)
31 24 : h = halfedge(mesh, v)
32 24 : (h == NoH) && continue
33 16 : if source(mesh, h) != v
34 0 : @warn "$v -> $h"
35 0 : return false
36 : end
37 42 : end
38 :
39 10 : for h2 in halfedges(mesh)
40 20 : for h in h2
41 40 : v = source(mesh, h)
42 72 : if h ∉ star(mesh, v)
43 0 : @warn "star $v misses $h"
44 0 : return false
45 : end
46 60 : end
47 20 : end
48 :
49 0 : true
50 : end
51 :
52 6 : function _check_faces(mesh)
53 10 : for f in faces(mesh)
54 8 : h = halfedge(mesh, f)
55 8 : _check_face(next, mesh, h) || return false
56 8 : _check_face(prev, mesh, h) || return false
57 8 : end
58 :
59 0 : true
60 : end
61 :
62 16 : function _check_face(f::Function, mesh, h)
63 16 : h0 = h
64 16 : h = f(mesh, h)
65 16 : for _ in 1:100
66 48 : (h == h0) && return true
67 32 : h = f(mesh, h)
68 64 : end
69 0 : @warn "loop $f"
70 0 : false
71 : end
72 :
73 6 : function _check_fh(mesh)
74 10 : for f in faces(mesh)
75 8 : h = halfedge(mesh, f)
76 :
77 8 : if face(mesh, h) != f
78 0 : @warn "$f -> $h"
79 0 : return false
80 : end
81 12 : end
82 :
83 10 : for h2 in halfedges(mesh)
84 20 : for h in h2
85 40 : f = face(mesh, h)
86 40 : (f == NoF) && continue
87 :
88 48 : if h ∉ halfedges(mesh, f)
89 0 : @warn "halfedges $f misses $h"
90 0 : return false
91 : end
92 60 : end
93 20 : end
94 :
95 0 : true
96 : end
|