Fixed another bug in connect()

This commit is contained in:
Chris Hodapp 2020-02-16 17:37:51 -05:00
parent d3e2f4f83c
commit 3eb8d12e03
2 changed files with 38 additions and 90 deletions

View File

@ -2,13 +2,10 @@
## Highest priority: ## Highest priority:
- Fix my new ADTs for meshes. It's working for the cube example
(which doesn't touch exit groups/exit vertices) but not for the
`curve_horn_*` one.
- Fix `OpenMesh.connect()`.
- Continue converting `curve_horn_*`. - Continue converting `curve_horn_*`.
- Consider trampolining to_mesh. My call stack seems needlessly deep - Consider trampolining `to_mesh`. My call stack seems needlessly
in spots. deep in spots. Can I make tail-recursive?
-
## Important: ## Important:

View File

@ -86,9 +86,9 @@ impl OpenMesh {
fn connect(&self, others: &Vec<OpenMesh>) -> OpenMesh { fn connect(&self, others: &Vec<OpenMesh>) -> OpenMesh {
println!("DEBUG: connect(), self has {} exit groups, others have {:?}", //println!("DEBUG: connect(), self has {} exit groups, others have {:?}",
self.exit_groups.len(), others.iter().map(|o| o.exit_groups.len()).collect::<Vec<usize>>()); // self.exit_groups.len(), others.iter().map(|o| o.exit_groups.len()).collect::<Vec<usize>>());
println!("DEBUG: connect(), self: verts.len()={} faces.len()={} max face={}", self.verts.len(), self.faces.len(), self.faces.iter().map(|f| match f { Tag::Body(n) => n, Tag::Exit(_,n) => n }).max().unwrap()); //println!("DEBUG: connect(), self: verts.len()={} faces.len()={} max face={}", self.verts.len(), self.faces.len(), self.faces.iter().map(|f| match f { Tag::Body(n) => n, Tag::Exit(_,n) => n }).max().unwrap());
// Copy body vertices & faces: // Copy body vertices & faces:
let mut verts: Vec<Vertex> = self.verts.clone(); let mut verts: Vec<Vertex> = self.verts.clone();
@ -101,9 +101,10 @@ impl OpenMesh {
let mut offsets: Vec<usize> = vec![0; others.len()]; let mut offsets: Vec<usize> = vec![0; others.len()];
for (i,other) in others.iter().enumerate() { for (i,other) in others.iter().enumerate() {
let max_ = other.faces.iter().map(|f| match f { Tag::Body(n) => n, Tag::Exit(_,n) => n }).max().unwrap_or(&0); //let max_ = other.faces.iter().map(|f| match f { Tag::Body(n) => n, Tag::Exit(_,n) => n }).max().unwrap_or(&0);
println!("DEBUG: connect(), other[{}]: verts.len()={} faces.len()={} max face={}", i, other.verts.len(), other.faces.len(), max_); //println!("DEBUG: connect(), other[{}]: verts.len()={} faces.len()={} max face={}", i, other.verts.len(), other.faces.len(), max_);
println!("DEBUG: start body_offset={}", body_offset); //println!("DEBUG: start body_offset={}", body_offset);
//println!("DEBUG: start exit_offset={}", exit_offset);
// Append body vertices & exit vertices directly: // Append body vertices & exit vertices directly:
verts.append(&mut other.verts.clone()); verts.append(&mut other.verts.clone());
@ -120,16 +121,20 @@ impl OpenMesh {
} }
exit_groups.append(&mut other.exit_groups.clone()); exit_groups.append(&mut other.exit_groups.clone());
offsets[i] = body_offset;
// Increase offsets by the number of elements we appended: // Increase offsets by the number of elements we appended:
body_offset += other.verts.len(); body_offset += other.verts.len();
offsets[i] = body_offset;
println!("DEBUG: end body_offset={}", body_offset); //println!("DEBUG: end body_offset={}", body_offset);
//println!("DEBUG: end exit_offset={}", exit_offset);
} }
//println!("DEBUG: offsets={:?}", offsets);
// All of the Exit face indices from 'self' need to be // All of the Exit face indices from 'self' need to be
// modified to refer to Body vertices of something in // modified to refer to Body vertices of something in
// 'others': // 'others':
//println!("DEBUG: initial faces={:?}", faces);
for i in 0..faces.len() { for i in 0..faces.len() {
match faces[i] { match faces[i] {
Tag::Exit(g, n) => { Tag::Exit(g, n) => {
@ -138,6 +143,7 @@ impl OpenMesh {
_ => { }, _ => { },
}; };
} }
//println!("DEBUG: final faces={:?}", faces);
let m = OpenMesh { let m = OpenMesh {
verts: verts, verts: verts,
@ -146,8 +152,8 @@ impl OpenMesh {
}; };
// TODO: Why is this still ending up with Exit faces despite my loop above? // TODO: Why is this still ending up with Exit faces despite my loop above?
println!("Returning mesh with verts.len()={} faces.len()={} max face={}", m.verts.len(), m.faces.len(), m.faces.iter().map(|f| match f { Tag::Body(n) => n, Tag::Exit(_,n) => n }).max().unwrap()); //println!("DEBUG: Returning mesh with verts.len()={} faces.len()={} max face={}", m.verts.len(), m.faces.len(), m.faces.iter().map(|f| match f { Tag::Body(n) => n, Tag::Exit(_,n) => n }).max().unwrap());
println!("Returning: {:?}", m); //println!("Returning: {:?}", m);
return m; return m;
} }
} }
@ -322,29 +328,27 @@ fn curve_horn_thing_rule() -> RuleStep {
Matrix4::new_scaling(0.95) * Matrix4::new_scaling(0.95) *
geometry::Translation3::new(0.0, 0.0, 0.2).to_homogeneous(); geometry::Translation3::new(0.0, 0.0, 0.2).to_homogeneous();
let mut verts = vec![ let verts = vec![
vertex(-0.5, -0.5, 0.0), vertex(-0.5, -0.5, 0.0),
vertex(0.5, -0.5, 0.0), vertex(0.5, -0.5, 0.0),
vertex(-0.5, 0.5, 0.0), vertex(-0.5, 0.5, 0.0),
vertex(0.5, 0.5, 0.0), vertex(0.5, 0.5, 0.0),
]; ];
let mut v2: Vec<Vertex> = verts.iter().map(|v| m * v).collect(); let final_verts: Vec<Vertex> = verts.iter().map(|v| m * v).collect();
let final_verts: Vec<Vertex> = v2.clone();
verts.append(&mut v2);
let geom = OpenMesh { let geom = OpenMesh {
verts: verts, verts: verts,
faces: vec![ faces: vec![
// Endcaps purposely left off for now. // Endcaps purposely left off for now.
// TODO: I should really generate these, not hard-code them. // TODO: I should really generate these, not hard-code them.
Tag::Body(1), Tag::Exit(0, 7), Tag::Exit(0, 5), Tag::Body(1), Tag::Exit(0, 3), Tag::Exit(0, 1),
Tag::Body(1), Tag::Body(3), Tag::Exit(0, 7), Tag::Body(1), Tag::Body(3), Tag::Exit(0, 3),
Tag::Exit(0, 4), Tag::Body(2), Tag::Body(0), Tag::Exit(0, 0), Tag::Body(2), Tag::Body(0),
Tag::Exit(0, 4), Tag::Exit(0, 6), Tag::Body(2), Tag::Exit(0, 0), Tag::Exit(0, 2), Tag::Body(2),
Tag::Body(2), Tag::Exit(0, 7), Tag::Body(3), Tag::Body(2), Tag::Exit(0, 3), Tag::Body(3),
Tag::Body(2), Tag::Exit(0, 6), Tag::Exit(0, 7), Tag::Body(2), Tag::Exit(0, 2), Tag::Exit(0, 3),
Tag::Body(0), Tag::Body(1), Tag::Exit(0, 5), Tag::Body(0), Tag::Body(1), Tag::Exit(0, 1),
Tag::Body(0), Tag::Exit(0, 5), Tag::Exit(0, 4), Tag::Body(0), Tag::Exit(0, 1), Tag::Exit(0, 0),
], ],
exit_groups: vec![4], exit_groups: vec![4],
}; };
@ -427,68 +431,15 @@ fn cube_thing_rule() -> RuleStep {
fn main() { fn main() {
// Below is so far my only example that uses entrance/exit groups: let run_test = |r: Rule, iters, name| {
/* println!("Running {}...", name);
println!("DEBUG-------------------------------"); let (mesh, nodes) = r.to_mesh(iters);
let m = OpenMesh { println!("Merged {} nodes", nodes);
verts: vec![ let fname = format!("{}.stl", name);
vertex(0.0, 0.0, 0.0), println!("Writing {}...", fname);
vertex(1.0, 0.0, 0.0), mesh.write_stl_file(&fname).unwrap();
vertex(0.0, 1.0, 0.0),
vertex(1.0, 1.0, 0.0),
],
faces: vec![
Tag::Body(1), Tag::Exit(0,3), Tag::Exit(0,1),
Tag::Body(1), Tag::Body(3), Tag::Exit(0,3),
Tag::Exit(0,0), Tag::Body(2), Tag::Body(0),
Tag::Exit(0,0), Tag::Exit(0,2), Tag::Body(2),
Tag::Body(2), Tag::Exit(0,3), Tag::Body(3),
Tag::Body(2), Tag::Exit(0,2), Tag::Exit(0,3),
Tag::Body(0), Tag::Body(1), Tag::Exit(0,1),
Tag::Body(0), Tag::Exit(0,1), Tag::Exit(0,0),
],
exit_groups: vec![4],
}; };
let xform = geometry::Translation3::new(0.0, 0.0, 1.0).to_homogeneous(); run_test(Rule::Recurse(cube_thing_rule), 3, "cube_thing");
let m2 = m.transform(xform); run_test(Rule::Recurse(curve_horn_thing_rule), 100, "curve_horn_thing");
let m3 = m.connect(&vec![m2.clone()]);
let m4 = m3.connect(&vec![m2.transform(xform)]);
println!("m4 = {:?}", m4);
m.write_stl_file("openmesh_cube.obj").unwrap();
m2.write_stl_file("openmesh_cube2.obj").unwrap();
m3.write_stl_file("openmesh_cube3.obj").unwrap();
{
let count = 10;
let mut mesh = m.clone();
let mut inc = m.clone();
for _ in 0..count {
inc = inc.transform(xform);
mesh = mesh.connect(&vec![inc.clone()]);
}
}
*/
{
let r = Rule::Recurse(cube_thing_rule);
let max_iters = 3;
println!("Running cube_thing_rule...");
let (cubemesh, nodes) = r.to_mesh(max_iters);
println!("Merged {} nodes", nodes);
println!("Writing STL...");
cubemesh.write_stl_file("cubemesh.stl").unwrap();
}
{
let r = Rule::Recurse(curve_horn_thing_rule);
let max_iters = 50;
println!("Running curve_horn_thing_rule...");
let (cubemesh, nodes) = r.to_mesh(max_iters);
//println!("cubemesh={:?}", cubemesh);
println!("Merged {} nodes", nodes);
println!("Writing STL...");
cubemesh.write_stl_file("curve_horn_thing.stl").unwrap();
}
} }