Fixed a few more bugs in parametric_mesh. More remain...
This commit is contained in:
parent
39072e0c30
commit
6a3a19db21
18
src/dcel.rs
18
src/dcel.rs
@ -353,8 +353,9 @@ impl<V: Copy + std::fmt::Debug> DCELMesh<V> {
|
|||||||
let twin_halfedge = &self.halfedges[twin];
|
let twin_halfedge = &self.halfedges[twin];
|
||||||
let v1 = self.halfedges[twin_halfedge.next_halfedge].vert;
|
let v1 = self.halfedges[twin_halfedge.next_halfedge].vert;
|
||||||
let v2 = twin_halfedge.vert;
|
let v2 = twin_halfedge.vert;
|
||||||
|
// twin is: v2 -> v1
|
||||||
|
|
||||||
// Insert 'twin' half-edge first:
|
// Insert *its* twin, v1 -> v2, first:
|
||||||
self.halfedges.push(DCELHalfEdge {
|
self.halfedges.push(DCELHalfEdge {
|
||||||
vert: v1,
|
vert: v1,
|
||||||
face: f_n,
|
face: f_n,
|
||||||
@ -363,6 +364,11 @@ impl<V: Copy + std::fmt::Debug> DCELMesh<V> {
|
|||||||
next_halfedge: e_n + 1,
|
next_halfedge: e_n + 1,
|
||||||
prev_halfedge: e_n + 2,
|
prev_halfedge: e_n + 2,
|
||||||
});
|
});
|
||||||
|
// DEBUG
|
||||||
|
if self.halfedges[twin].has_twin {
|
||||||
|
panic!(format!("Trying to add twin to {}, which already has twin ({})",
|
||||||
|
twin, self.halfedges[twin].twin_halfedge));
|
||||||
|
}
|
||||||
self.halfedges[twin].has_twin = true;
|
self.halfedges[twin].has_twin = true;
|
||||||
self.halfedges[twin].twin_halfedge = e_n;
|
self.halfedges[twin].twin_halfedge = e_n;
|
||||||
self.halfedges.push(DCELHalfEdge {
|
self.halfedges.push(DCELHalfEdge {
|
||||||
@ -429,7 +435,6 @@ impl<V: Copy + std::fmt::Debug> DCELMesh<V> {
|
|||||||
|
|
||||||
// twin1 is: v1 -> v2, twin2 is: v3 -> v1.
|
// twin1 is: v1 -> v2, twin2 is: v3 -> v1.
|
||||||
// so the twin of twin1 must be: v2 -> v1
|
// so the twin of twin1 must be: v2 -> v1
|
||||||
// and the twin of twin2 must be: v1 -> v3
|
|
||||||
self.halfedges.push(DCELHalfEdge {
|
self.halfedges.push(DCELHalfEdge {
|
||||||
vert: v2,
|
vert: v2,
|
||||||
face: f_n,
|
face: f_n,
|
||||||
@ -440,24 +445,25 @@ impl<V: Copy + std::fmt::Debug> DCELMesh<V> {
|
|||||||
}); // index e_n
|
}); // index e_n
|
||||||
self.halfedges[twin1_idx].has_twin = true;
|
self.halfedges[twin1_idx].has_twin = true;
|
||||||
self.halfedges[twin1_idx].twin_halfedge = e_n;
|
self.halfedges[twin1_idx].twin_halfedge = e_n;
|
||||||
|
// and the twin of twin2 must be: v1 -> v3
|
||||||
self.halfedges.push(DCELHalfEdge {
|
self.halfedges.push(DCELHalfEdge {
|
||||||
vert: v3,
|
vert: v1,
|
||||||
face: f_n,
|
face: f_n,
|
||||||
has_twin: true,
|
has_twin: true,
|
||||||
twin_halfedge: twin2_idx,
|
twin_halfedge: twin2_idx,
|
||||||
next_halfedge: e_n + 2,
|
next_halfedge: e_n + 2,
|
||||||
prev_halfedge: e_n,
|
prev_halfedge: e_n,
|
||||||
}); // index e_n + 1
|
}); // index e_n + 1
|
||||||
|
self.halfedges[twin2_idx].has_twin = true;
|
||||||
|
self.halfedges[twin2_idx].twin_halfedge = e_n + 1;
|
||||||
self.halfedges.push(DCELHalfEdge {
|
self.halfedges.push(DCELHalfEdge {
|
||||||
vert: v1,
|
vert: v3,
|
||||||
face: f_n,
|
face: f_n,
|
||||||
has_twin: false,
|
has_twin: false,
|
||||||
twin_halfedge: 0,
|
twin_halfedge: 0,
|
||||||
next_halfedge: e_n,
|
next_halfedge: e_n,
|
||||||
prev_halfedge: e_n + 1,
|
prev_halfedge: e_n + 1,
|
||||||
}); // index e_n + 2
|
}); // index e_n + 2
|
||||||
self.halfedges[twin2_idx].has_twin = true;
|
|
||||||
self.halfedges[twin2_idx].twin_halfedge = e_n + 1;
|
|
||||||
self.num_halfedges += 3;
|
self.num_halfedges += 3;
|
||||||
|
|
||||||
// Finally, add the face (any halfedge is fine):
|
// Finally, add the face (any halfedge is fine):
|
||||||
|
|||||||
@ -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 = 16.0;
|
let t1 = 1.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).
|
||||||
|
|||||||
75
src/rule.rs
75
src/rule.rs
@ -432,7 +432,29 @@ pub fn parametric_mesh<F>(frame: Vec<Vertex>, f: F, t0: f32, t1: f32, max_err: f
|
|||||||
|
|
||||||
while !frontier.is_empty() {
|
while !frontier.is_empty() {
|
||||||
for (i, f) in frontier.iter().enumerate() {
|
for (i, f) in frontier.iter().enumerate() {
|
||||||
println!("DEBUG: frontier[{}]: vert={},{},{} t={} halfedges={:?}", i, f.vert.x, f.vert.y, f.vert.z, f.t, f.halfedges);
|
println!("DEBUG: frontier[{}]: vert={},{},{} vert_idx={:?} t={} halfedges={:?}", i, f.vert.x, f.vert.y, f.vert.z, f.vert_idx, f.t, f.halfedges);
|
||||||
|
match f.vert_idx {
|
||||||
|
Some(vert) => {
|
||||||
|
match f.halfedges[1] {
|
||||||
|
Some(idx) => {
|
||||||
|
if mesh.halfedges[idx].vert != vert {
|
||||||
|
println!(" Error: halfedge[1]={} starts at {}, should start at {}", idx, mesh.halfedges[idx].vert, vert);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => {},
|
||||||
|
};
|
||||||
|
match f.halfedges[0] {
|
||||||
|
Some(idx) => {
|
||||||
|
let v2 = mesh.halfedges[mesh.halfedges[idx].next_halfedge].vert;
|
||||||
|
if v2 != vert {
|
||||||
|
println!(" Error: halfedge[0]={} ends at {}, should start at {}", idx, v2, vert);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
None => {},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pick a vertex to advance.
|
// Pick a vertex to advance.
|
||||||
@ -457,7 +479,8 @@ pub fn parametric_mesh<F>(frame: Vec<Vertex>, f: F, t0: f32, t1: f32, max_err: f
|
|||||||
// the furthest we can go while remaining within 'err', i.e. when we
|
// the furthest we can go while remaining within 'err', i.e. when we
|
||||||
// make our connections we look at how far points on the *edges*
|
// make our connections we look at how far points on the *edges*
|
||||||
// diverge from the trajectory of the continuous transformation).
|
// diverge from the trajectory of the continuous transformation).
|
||||||
let mut dt = (t1 - t0) / 100.0;
|
//let mut dt = (t1 - t0) / 100.0;
|
||||||
|
let mut dt = (t1 - t0) / 10.0;
|
||||||
let vf = v.frame_vert;
|
let vf = v.frame_vert;
|
||||||
for iter in 0..0 /*100*/ { // DEBUG: Re-enable
|
for iter in 0..0 /*100*/ { // DEBUG: Re-enable
|
||||||
// Consider an edge from f(v.t)*vf to f(v.t + dt)*vf.
|
// Consider an edge from f(v.t)*vf to f(v.t + dt)*vf.
|
||||||
@ -502,50 +525,54 @@ pub fn parametric_mesh<F>(frame: Vec<Vertex>, f: F, t0: f32, t1: f32, max_err: f
|
|||||||
println!("l1={} l2={} l3={}", l1, l2, l3);
|
println!("l1={} l2={} l3={}", l1, l2, l3);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// 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.
|
||||||
let (f1, edges1) = match v.halfedges[0] {
|
|
||||||
|
// First face: connect 'prior' frontier vertex to 'v' & 'v_next'.
|
||||||
|
// 'f1' is that face, 'edge1' connects prior vertex and 'v_next'.
|
||||||
|
// 'edge_v_next' connects 'v_next' and 'v' (in that order!)
|
||||||
|
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 + n - 1) % n];
|
||||||
println!("DEBUG: add_face()");
|
println!("DEBUG: add_face()");
|
||||||
let (f1, edges1) = mesh.add_face([
|
let (f1, edges) = mesh.add_face([
|
||||||
VertSpec::New(v_next),
|
VertSpec::New(v_next), // edges[0]: v_next -> v
|
||||||
match v.vert_idx {
|
match v.vert_idx {
|
||||||
None => VertSpec::New(v.vert),
|
None => VertSpec::New(v.vert),
|
||||||
Some(idx) => VertSpec::Idx(idx),
|
Some(idx) => VertSpec::Idx(idx),
|
||||||
},
|
}, // edges[1]: v -> neighbor
|
||||||
match neighbor.vert_idx {
|
match neighbor.vert_idx {
|
||||||
None => VertSpec::New(neighbor.vert),
|
None => VertSpec::New(neighbor.vert),
|
||||||
Some(idx) => VertSpec::Idx(idx),
|
Some(idx) => VertSpec::Idx(idx),
|
||||||
},
|
}, // edges[2]: neighbor -> v_next
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if neighbor.vert_idx.is_none() {
|
if neighbor.vert_idx.is_none() {
|
||||||
// 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[edges1[2]].vert);
|
frontier[(i + n - 1) % n].vert_idx = Some(mesh.halfedges[edges[2]].vert);
|
||||||
// edges[2] is because this is the position of
|
|
||||||
// neighbor.vert_idx in add_face.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(f1, edges1)
|
(f1, edges[2], edges[0])
|
||||||
},
|
},
|
||||||
Some(edge_idx) => {
|
Some(edge_idx) => {
|
||||||
println!("DEBUG: add_face_twin1({},{})", edge_idx, v_next);
|
println!("DEBUG: add_face_twin1({},{})", edge_idx, v_next);
|
||||||
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
|
||||||
|
(f1, edges[1], edges[2])
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
println!("DEBUG: edges1={:?}", edges1);
|
println!("DEBUG: edge1={} edge_v_next={}", edge1, edge_v_next);
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
mesh.check();
|
mesh.check();
|
||||||
mesh.print();
|
mesh.print();
|
||||||
|
|
||||||
// edge2 should be: the half-edge connecting the 'neighbor' frontier
|
// edge2 should be: the half-edge connecting the 'next' frontier
|
||||||
// vertex to v_next
|
// vertex to 'v_next'
|
||||||
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,
|
||||||
@ -553,7 +580,7 @@ pub fn parametric_mesh<F>(frame: Vec<Vertex>, f: F, t0: f32, t1: f32, max_err: f
|
|||||||
// is edges1[0].
|
// is edges1[0].
|
||||||
None => {
|
None => {
|
||||||
let neighbor = &frontier[(i + 1) % n];
|
let neighbor = &frontier[(i + 1) % n];
|
||||||
let (f2, edges) = mesh.add_face_twin1(edges1[0], neighbor.vert);
|
let (f2, edges) = mesh.add_face_twin1(edge_v_next, neighbor.vert);
|
||||||
|
|
||||||
if neighbor.vert_idx.is_none() {
|
if neighbor.vert_idx.is_none() {
|
||||||
// Reasoning here is identical to "If neighbor.vert_idx
|
// Reasoning here is identical to "If neighbor.vert_idx
|
||||||
@ -564,8 +591,7 @@ pub fn parametric_mesh<F>(frame: Vec<Vertex>, f: F, t0: f32, t1: f32, max_err: f
|
|||||||
(f2, edges[1])
|
(f2, edges[1])
|
||||||
},
|
},
|
||||||
Some(edge_idx) => {
|
Some(edge_idx) => {
|
||||||
let (f2, edges) = mesh.add_face_twin2(edge_idx, edges1[2]);
|
let (f2, edges) = mesh.add_face_twin2(edge_v_next, edge1);
|
||||||
// TODO: Why edges1[2]?
|
|
||||||
(f2, edges[2])
|
(f2, edges[2])
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -591,11 +617,8 @@ pub fn parametric_mesh<F>(frame: Vec<Vertex>, f: F, t0: f32, t1: f32, max_err: f
|
|||||||
vert: v_next,
|
vert: v_next,
|
||||||
frame_vert: vf,
|
frame_vert: vf,
|
||||||
t: t,
|
t: t,
|
||||||
halfedges: [Some(edges1[2]), Some(edge2)],
|
halfedges: [Some(edge1), Some(edge2)],
|
||||||
// Note that edges1[2] *starts* at the new vertex, and
|
vert_idx: Some(mesh.halfedges[edge_v_next].vert),
|
||||||
// edge2 *ends* at it.
|
|
||||||
// DEBUG: The above comment is wrong, but why?
|
|
||||||
vert_idx: Some(mesh.halfedges[edges1[2]].vert),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -713,5 +736,5 @@ pub fn parametric_mesh<F>(frame: Vec<Vertex>, f: F, t0: f32, t1: f32, max_err: f
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
return Mesh { faces: vec![], verts: vec![] };
|
return dcel::convert_mesh(&mesh);
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user