From 8d35c7bf1db00ced7cfe039015bc5ba2cca650d0 Mon Sep 17 00:00:00 2001 From: Chris Hodapp Date: Mon, 25 May 2020 09:20:46 -0400 Subject: [PATCH] Add a check function to DCELMesh --- src/dcel.rs | 110 ++++++++++++++++++++++++++++++++++++++++++++++-- src/examples.rs | 2 + 2 files changed, 109 insertions(+), 3 deletions(-) diff --git a/src/dcel.rs b/src/dcel.rs index e9b951b..4c51f21 100644 --- a/src/dcel.rs +++ b/src/dcel.rs @@ -72,7 +72,7 @@ impl fmt::Display for DCELMesh { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let v_strs: Vec = self.verts.iter().enumerate().map(|(i,v)| { - format!("v{}={:?}", i, v.v) + format!("v{}=e{} {:?}", i, v.halfedge, v.v) }).collect(); let v_str = v_strs.join(","); @@ -111,6 +111,110 @@ impl DCELMesh { } } + /// Runs various checks on the mesh. This will return true if the mesh + /// looks okay, and otherwise false. It will print messages as it + /// runs. + pub fn check(&self) -> bool { + let mut pass = true; + + if self.num_halfedges != self.halfedges.len() { + pass = false; + println!("self.num_halfedges={} != self.halfedges.len()={}", + self.num_halfedges, self.halfedges.len()); + } else { + println!("self.num_halfedges matches self.halfedges.len()"); + } + + if self.num_faces != self.faces.len() { + pass = false; + println!("self.faces={} != self.faces.len()={}", + self.num_faces, self.faces.len()); + } else { + println!("self.num_faces matches self.faces.len()"); + } + + if self.num_verts != self.verts.len() { + pass = false; + println!("self.verts={} != self.verts.len()={}", + self.num_verts, self.verts.len()); + } else { + println!("self.num_verts matches self.verts.len()"); + } + + for (i,v) in self.verts.iter().enumerate() { + if v.halfedge >= self.halfedges.len() { + println!("Vertex {}: halfedge index {} out of range", + i, v.halfedge); + pass = false; + } + if self.halfedges[v.halfedge].vert != i { + println!("Vertex {} names halfedge {}, which has a different origin vertex ({})", + i, v.halfedge, self.halfedges[v.halfedge].vert); + } + } + + for (i,edge) in self.halfedges.iter().enumerate() { + if edge.vert >= self.verts.len() { + println!("Halfedge {}: vertex index {} out of range", i, edge.vert); + pass = false; + } + if edge.has_twin { + let twin = &self.halfedges[edge.twin_halfedge]; + if !twin.has_twin { + println!("Halfedge {}: twin {} says it has no twin", + i, edge.twin_halfedge); + pass = false; + } else if i != twin.twin_halfedge { + println!("Halfedge {} has twin {}, but reverse isn't true", + i, edge.twin_halfedge); + pass = false; + } + } + let p = edge.prev_halfedge; + if p >= self.halfedges.len() { + println!("Halfedge {}: previous halfedge index {} out of range", + i, p); + pass = false; + } + let n = edge.next_halfedge; + if p >= self.halfedges.len() { + println!("Halfedge {}: next halfedge index {} out of range", + i, n); + pass = false; + } + let pn = self.halfedges[p].next_halfedge; + if pn != i { + println!("Halfedge {}: previous halfedge {} has next halfedge of {}, not {}", + i, p, pn, i); + pass = false; + } + let np = self.halfedges[n].prev_halfedge; + if np != i { + println!("Halfedge {}: next halfedge {} has previous halfedge of {}, not {}", + i, n, np, i); + pass = false; + } + // TODO: Check that following prev always leads back to start + // likewise following next + } + + for (i,face) in self.faces.iter().enumerate() { + if face.halfedge >= self.halfedges.len() { + println!("Face {}: halfedge index {} out of range", + i, face.halfedge); + pass = false; + } + let face2 = self.halfedges[face.halfedge].face; + if i != face2 { + println!("Face {} gives boundary halfedge {}, which gives different face ({})", + i, face.halfedge, face2); + pass = false; + } + } + + pass + } + pub fn face_to_halfedges(&self, face_idx: usize) -> Vec { let mut edges: Vec = vec![]; let start_idx = self.faces[face_idx].halfedge; @@ -212,10 +316,10 @@ impl DCELMesh { self.num_halfedges += 3; - // Since the 2nd halfedge we inserted (e_n + 1) has origin v_n: + // Since the 2nd halfedge we inserted (e_n + 2) has origin v_n: self.verts.push(DCELVertex { v: vert, - halfedge: e_n + 1, + halfedge: e_n + 2, }); self.num_verts += 1; diff --git a/src/examples.rs b/src/examples.rs index 94e8619..d882c26 100644 --- a/src/examples.rs +++ b/src/examples.rs @@ -1288,7 +1288,9 @@ pub fn test_dcel(fname: &str) { vertex(-0.5, 0.5, 0.0), vertex( 0.5, 0.5, 0.0), ]); + mesh.check(); let f2 = mesh.add_face_twin1(mesh.faces[f1].halfedge, vertex(0.0, 0.0, 1.0)); + mesh.check(); let vl1 = mesh.face_to_verts(f1); println!("verts = {:?}", vl1);