Possibly the actual actual bug fix
This commit is contained in:
parent
6a3a19db21
commit
41ea254537
30
src/dcel.rs
30
src/dcel.rs
@ -344,6 +344,20 @@ impl<V: Copy + std::fmt::Debug> DCELMesh<V> {
|
|||||||
pub fn add_face_twin1(&mut self, twin: usize, vert: V) -> (usize, [usize; 3]) {
|
pub fn add_face_twin1(&mut self, twin: usize, vert: V) -> (usize, [usize; 3]) {
|
||||||
// 'vert' will be at index v_n:
|
// 'vert' will be at index v_n:
|
||||||
let v_n = self.num_verts;
|
let v_n = self.num_verts;
|
||||||
|
// The half-edges will be at indices e_n, e_n+1, e_n+2:
|
||||||
|
let e_n = self.num_halfedges;
|
||||||
|
|
||||||
|
self.verts.push(DCELVertex {
|
||||||
|
v: vert,
|
||||||
|
halfedge: e_n + 2,
|
||||||
|
});
|
||||||
|
self.num_verts += 1;
|
||||||
|
self.add_face_twin1_ref(twin, v_n)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Like `add_face_twin1`, but for a vertex already present in the
|
||||||
|
/// mesh rather than a new one. All else is identical.
|
||||||
|
pub fn add_face_twin1_ref(&mut self, twin: usize, vert_idx: usize) -> (usize, [usize; 3]) {
|
||||||
// The face will be at index f_n:
|
// The face will be at index f_n:
|
||||||
let f_n = self.num_faces;
|
let f_n = self.num_faces;
|
||||||
// The half-edges will be at indices e_n, e_n+1, e_n+2:
|
// The half-edges will be at indices e_n, e_n+1, e_n+2:
|
||||||
@ -380,7 +394,7 @@ impl<V: Copy + std::fmt::Debug> DCELMesh<V> {
|
|||||||
prev_halfedge: e_n,
|
prev_halfedge: e_n,
|
||||||
});
|
});
|
||||||
self.halfedges.push(DCELHalfEdge {
|
self.halfedges.push(DCELHalfEdge {
|
||||||
vert: v_n,
|
vert: vert_idx,
|
||||||
face: f_n,
|
face: f_n,
|
||||||
has_twin: false,
|
has_twin: false,
|
||||||
twin_halfedge: 0,
|
twin_halfedge: 0,
|
||||||
@ -390,13 +404,6 @@ impl<V: Copy + std::fmt::Debug> DCELMesh<V> {
|
|||||||
|
|
||||||
self.num_halfedges += 3;
|
self.num_halfedges += 3;
|
||||||
|
|
||||||
// Since the 2nd halfedge we inserted (e_n + 2) has origin v_n:
|
|
||||||
self.verts.push(DCELVertex {
|
|
||||||
v: vert,
|
|
||||||
halfedge: e_n + 2,
|
|
||||||
});
|
|
||||||
self.num_verts += 1;
|
|
||||||
|
|
||||||
// Finally, add the face (any halfedge is fine):
|
// Finally, add the face (any halfedge is fine):
|
||||||
self.faces.push(DCELFace { halfedge: e_n });
|
self.faces.push(DCELFace { halfedge: e_n });
|
||||||
self.num_faces += 1;
|
self.num_faces += 1;
|
||||||
@ -412,8 +419,12 @@ impl<V: Copy + std::fmt::Debug> DCELMesh<V> {
|
|||||||
/// the next half-edge's twin will be twin2.
|
/// the next half-edge's twin will be twin2.
|
||||||
/// Also: halfedge `twin2_idx` must end at the vertex that starts
|
/// Also: halfedge `twin2_idx` must end at the vertex that starts
|
||||||
/// `twin1_idx`.
|
/// `twin1_idx`.
|
||||||
|
///
|
||||||
|
/// Returns (face index, halfedge indices). Halfedge indices begin
|
||||||
|
/// at the twin halfedge to twin1, then twin halfedge of
|
||||||
|
/// twin2, then the 'new' halfedge (which starts where twin2 starts,
|
||||||
|
/// and ends where twin1 ends).
|
||||||
pub fn add_face_twin2(&mut self, twin1_idx: usize, twin2_idx: usize) -> (usize, [usize; 3]) {
|
pub fn add_face_twin2(&mut self, twin1_idx: usize, twin2_idx: usize) -> (usize, [usize; 3]) {
|
||||||
println!("DEBUG: add_face_twin2({},{})", twin1_idx, twin2_idx);
|
|
||||||
// The face will be at index f_n:
|
// The face will be at index f_n:
|
||||||
let f_n = self.num_faces;
|
let f_n = self.num_faces;
|
||||||
// The half-edges will be at indices e_n, e_n+1, e_n+2:
|
// The half-edges will be at indices e_n, e_n+1, e_n+2:
|
||||||
@ -456,6 +467,7 @@ impl<V: Copy + std::fmt::Debug> DCELMesh<V> {
|
|||||||
}); // index e_n + 1
|
}); // index e_n + 1
|
||||||
self.halfedges[twin2_idx].has_twin = true;
|
self.halfedges[twin2_idx].has_twin = true;
|
||||||
self.halfedges[twin2_idx].twin_halfedge = e_n + 1;
|
self.halfedges[twin2_idx].twin_halfedge = e_n + 1;
|
||||||
|
// and final edge must be v3 -> v2:
|
||||||
self.halfedges.push(DCELHalfEdge {
|
self.halfedges.push(DCELHalfEdge {
|
||||||
vert: v3,
|
vert: v3,
|
||||||
face: f_n,
|
face: f_n,
|
||||||
|
|||||||
@ -1272,7 +1272,7 @@ pub fn test_parametric() -> Mesh {
|
|||||||
//let base_verts = util::subdivide_cycle(&base_verts, 16);
|
//let base_verts = util::subdivide_cycle(&base_verts, 16);
|
||||||
|
|
||||||
let t0 = 0.0;
|
let t0 = 0.0;
|
||||||
let t1 = 1.0;
|
let t1 = 50.0;
|
||||||
let xform = |t: f32| -> Transform {
|
let xform = |t: f32| -> Transform {
|
||||||
id().translate(0.0, 0.0, t/5.0)/*.
|
id().translate(0.0, 0.0, t/5.0)/*.
|
||||||
rotate(&Vector3::z_axis(), -t/2.0).
|
rotate(&Vector3::z_axis(), -t/2.0).
|
||||||
|
|||||||
63
src/rule.rs
63
src/rule.rs
@ -473,6 +473,10 @@ pub fn parametric_mesh<F>(frame: Vec<Vertex>, f: F, t0: f32, t1: f32, max_err: f
|
|||||||
// TODO: Fix boundary behavior here and make sure final topology
|
// TODO: Fix boundary behavior here and make sure final topology
|
||||||
// is right.
|
// is right.
|
||||||
|
|
||||||
|
// Indices (into 'frontier') of previous and next:
|
||||||
|
let i_prev = (i + n - 1) % n;
|
||||||
|
let i_next = (i + 1) % n;
|
||||||
|
|
||||||
println!("DEBUG: Moving frontier vertex {}, {:?} (t={}, frame_vert={:?})", i, v.vert, v.t, v.frame_vert);
|
println!("DEBUG: Moving frontier vertex {}, {:?} (t={}, frame_vert={:?})", i, v.vert, v.t, v.frame_vert);
|
||||||
|
|
||||||
// Move this vertex further along, i.e. t + dt. (dt is set by
|
// Move this vertex further along, i.e. t + dt. (dt is set by
|
||||||
@ -528,14 +532,17 @@ pub fn parametric_mesh<F>(frame: Vec<Vertex>, f: F, t0: f32, t1: f32, max_err: f
|
|||||||
// Add two faces to our mesh. They share two vertices, and thus
|
// Add two faces to our mesh. They share two vertices, and thus
|
||||||
// the boundary in between those vertices.
|
// the boundary in between those vertices.
|
||||||
|
|
||||||
// First face: connect 'prior' frontier vertex to 'v' & 'v_next'.
|
println!("DEBUG: Adding 1st face");
|
||||||
// 'f1' is that face, 'edge1' connects prior vertex and 'v_next'.
|
|
||||||
// 'edge_v_next' connects 'v_next' and 'v' (in that order!)
|
// First face: connect prior frontier vertex to 'v' & 'v_next'.
|
||||||
|
// f1 is that face,
|
||||||
|
// edge1 is: prior frontier vertex -> v_next.
|
||||||
|
// edge_v_next is: v_next -> v
|
||||||
let (f1, edge1, edge_v_next) = match v.halfedges[0] {
|
let (f1, edge1, edge_v_next) = match v.halfedges[0] {
|
||||||
// However, the way we add the face depends on whether we are
|
// However, the way we add the face depends on whether we are
|
||||||
// adding to an existing boundary or not:
|
// adding to an existing boundary or not:
|
||||||
None => {
|
None => {
|
||||||
let neighbor = &frontier[(i + n - 1) % n];
|
let neighbor = &frontier[i_prev];
|
||||||
println!("DEBUG: add_face()");
|
println!("DEBUG: add_face()");
|
||||||
let (f1, edges) = mesh.add_face([
|
let (f1, edges) = mesh.add_face([
|
||||||
VertSpec::New(v_next), // edges[0]: v_next -> v
|
VertSpec::New(v_next), // edges[0]: v_next -> v
|
||||||
@ -553,15 +560,18 @@ pub fn parametric_mesh<F>(frame: Vec<Vertex>, f: F, t0: f32, t1: f32, max_err: f
|
|||||||
// If neighbor.vert_idx is None, then we had to
|
// If neighbor.vert_idx is None, then we had to
|
||||||
// add its vertex to the mesh for the face we just
|
// add its vertex to the mesh for the face we just
|
||||||
// made - so mark it in the frontier:
|
// made - so mark it in the frontier:
|
||||||
frontier[(i + n - 1) % n].vert_idx = Some(mesh.halfedges[edges[2]].vert);
|
frontier[i_prev].vert_idx = Some(mesh.halfedges[edges[2]].vert);
|
||||||
}
|
}
|
||||||
|
|
||||||
(f1, edges[2], edges[0])
|
(f1, edges[2], edges[0])
|
||||||
},
|
},
|
||||||
Some(edge_idx) => {
|
Some(edge_idx) => {
|
||||||
println!("DEBUG: add_face_twin1({},{})", edge_idx, v_next);
|
// edge_idx is half-edge from prior frontier vertex to 'v'
|
||||||
|
println!("DEBUG: add_face_twin1({}, ({},{},{}))", edge_idx, v_next.x, v_next.y, v_next.z);
|
||||||
let (f1, edges) = mesh.add_face_twin1(edge_idx, v_next);
|
let (f1, edges) = mesh.add_face_twin1(edge_idx, v_next);
|
||||||
// Note the order of half-edges from add_face_twin1
|
// edges[0] is twin of edge_idx, thus v -> neighbor
|
||||||
|
// edges[1] is neighbor -> v_next
|
||||||
|
// edges[2] is v_next -> v
|
||||||
(f1, edges[1], edges[2])
|
(f1, edges[1], edges[2])
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -571,34 +581,55 @@ pub fn parametric_mesh<F>(frame: Vec<Vertex>, f: F, t0: f32, t1: f32, max_err: f
|
|||||||
mesh.check();
|
mesh.check();
|
||||||
mesh.print();
|
mesh.print();
|
||||||
|
|
||||||
// edge2 should be: the half-edge connecting the 'next' frontier
|
println!("DEBUG: Adding 2nd face");
|
||||||
// vertex to 'v_next'
|
// Second face: connect next frontier vertex to 'v' & 'v_next'.
|
||||||
|
// f2 is that face.
|
||||||
|
// edge2 is: v_next -> next frontier vertex
|
||||||
let (f2, edge2) = match v.halfedges[1] {
|
let (f2, edge2) = match v.halfedges[1] {
|
||||||
// Likewise, the way we add the second face depends on
|
// Likewise, the way we add the second face depends on
|
||||||
// the same (but for the other side). Regardless,
|
// the same (but for the other side). Regardless,
|
||||||
// they share the boundary between v_next and v.vert - which
|
// they share the boundary between v_next and v.vert - which
|
||||||
// is edges1[0].
|
// is edges1[0].
|
||||||
None => {
|
None => {
|
||||||
let neighbor = &frontier[(i + 1) % n];
|
let neighbor = &frontier[i_next];
|
||||||
let (f2, edges) = mesh.add_face_twin1(edge_v_next, neighbor.vert);
|
|
||||||
|
|
||||||
if neighbor.vert_idx.is_none() {
|
let (f2, edges) = match neighbor.vert_idx {
|
||||||
|
None => {
|
||||||
|
let v = neighbor.vert;
|
||||||
|
println!("DEBUG: add_face_twin1({}, ({},{},{}))", edge_v_next, v.x, v.y, v.z);
|
||||||
|
let (f2, edges) = mesh.add_face_twin1(edge_v_next, neighbor.vert);
|
||||||
// Reasoning here is identical to "If neighbor.vert_idx
|
// Reasoning here is identical to "If neighbor.vert_idx
|
||||||
// is None..." above:
|
// is None..." above:
|
||||||
frontier[(i + 1) % n].vert_idx = Some(mesh.halfedges[edges[2]].vert);
|
frontier[i_next].vert_idx = Some(mesh.halfedges[edges[2]].vert);
|
||||||
|
|
||||||
|
(f2, edges)
|
||||||
|
},
|
||||||
|
Some(vert_idx) => {
|
||||||
|
println!("DEBUG: add_face_twin1_ref({}, {})", edge_v_next, vert_idx);
|
||||||
|
mesh.add_face_twin1_ref(edge_v_next, vert_idx)
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
// For either branch:
|
||||||
|
// edges[0] is twin of edge_v_next, thus: v -> v_next
|
||||||
|
// edges[1] is: v_next -> neighbor
|
||||||
|
// egdes[2] is: neighbor -> v
|
||||||
|
|
||||||
(f2, edges[1])
|
(f2, edges[1])
|
||||||
},
|
},
|
||||||
Some(edge_idx) => {
|
Some(edge_idx) => {
|
||||||
let (f2, edges) = mesh.add_face_twin2(edge_v_next, edge1);
|
println!("DEBUG: add_face_twin2({}, {})", edge_idx, edge_v_next);
|
||||||
|
let (f2, edges) = mesh.add_face_twin2(edge_idx, edge_v_next);
|
||||||
|
// edges[0] is twin of edge_idx, thus: neighbor -> v
|
||||||
|
// edges[1] is twin of edge_v_next, thus: v -> v_next
|
||||||
|
// edges[2] is: v_next -> neighbor
|
||||||
|
println!("DEBUG: add_face_twin2 returned {:?}", edges);
|
||||||
(f2, edges[2])
|
(f2, edges[2])
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
println!("DEBUG: edge2={}", edge2);
|
println!("DEBUG: edge2={}", edge2);
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
println!("DEBUG: 2nd face");
|
println!("DEBUG: Added 2nd face");
|
||||||
mesh.check();
|
mesh.check();
|
||||||
mesh.print();
|
mesh.print();
|
||||||
|
|
||||||
@ -620,6 +651,8 @@ pub fn parametric_mesh<F>(frame: Vec<Vertex>, f: F, t0: f32, t1: f32, max_err: f
|
|||||||
halfedges: [Some(edge1), Some(edge2)],
|
halfedges: [Some(edge1), Some(edge2)],
|
||||||
vert_idx: Some(mesh.halfedges[edge_v_next].vert),
|
vert_idx: Some(mesh.halfedges[edge_v_next].vert),
|
||||||
};
|
};
|
||||||
|
frontier[i_prev].halfedges[1] = Some(edge1);
|
||||||
|
frontier[i_next].halfedges[0] = Some(edge2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Also add these faces to the stack of triangles to check for
|
// Also add these faces to the stack of triangles to check for
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user