diff --git a/src/main.rs b/src/main.rs index 91b0978..62ec691 100644 --- a/src/main.rs +++ b/src/main.rs @@ -85,85 +85,46 @@ fn curve_horn_thing_rule(v: Vec) -> Vec { mesh.apply_transformation(m); // TODO: Fix this horrible code below that is seemingly - // correct, but should not be run on every single iteration. - let bounds: Vec<(HalfEdgeID, HalfEdgeID)> = MeshBound::new(&seed).unwrap().zip(MeshBound::new(&mesh).unwrap()).collect(); + // correct, but shouldn't be run on every rule iteration! - // 'bounds' now has pairs of half-edges which walk the outside - // boundaries of each mesh, and should be connected together. - // They come from different meshes, so handle accordingly. - - // Put all vertices together (though we may not need them all, - // only the ones 'bounds' touches - TODO): - let mut pos = seed.positions_buffer(); - pos.append(&mut mesh.positions_buffer()); - // 2 faces per 'bounds' element, 3 vertices per face: - let mut indices: Vec = vec![0; 2 * bounds.len() * 3]; + // Collect together all the vertices from the boundaries of + // 'seed' and 'mesh': + let edge2vert = |m: &Mesh, e: HalfEdgeID| { + let v = m.edge_positions(e).0; + vec![v.x, v.y, v.z] + }; + let i1 = MeshBound::new(&seed).unwrap().flat_map(|id| edge2vert(&seed, id)); + let i2 = MeshBound::new(&mesh).unwrap().flat_map(|id| edge2vert(&mesh, id)); + let verts: Vec = i1.chain(i2).collect(); + println!("verts = {:?}", verts); - struct VID { val: usize } - fn vertex_id_to_u32(v: VertexID) -> u32 { - let v: VID = unsafe { std::mem::transmute(v) }; - u32::try_from(v.val).unwrap() + // We need 3 indices per face, 2 faces per (boundary) vertex: + let num_verts = seed.no_vertices(); + let mut idxs: Vec = vec![0; 2 * num_verts * 3]; + for i in 0..num_verts { + let a1: u32 = i as _; + let a2: u32 = ((i + 1) % num_verts) as _; + let b1: u32 = (i + num_verts) as _; + let b2: u32 = (((i + 1) % num_verts) + num_verts) as _; + // Connect vertices into faces with a zig-zag pattern + // (mind the winding order). First face: + idxs[6*i + 0] = a1; + idxs[6*i + 1] = a2; + idxs[6*i + 2] = b1; + println!("vert {}, face 1: ({}, {}, {})", i, a1, a2, b1); + // Second face: + idxs[6*i + 3] = b1; + idxs[6*i + 4] = a2; + idxs[6*i + 5] = b2; + println!("vert {}, face 2: ({}, {}, {})", i, b1, a2, b2); } - // MeshBuilder requires u32 indices. My vertices are - // VertexID, which is just usize under the hood. I am open to - // other suggestions. - fn vertex_id_to_usize(v: VertexID) -> usize { - let v: VID = unsafe { std::mem::transmute(v) }; - v.val - } - - let offset = u32::try_from(seed.no_vertices()).unwrap(); + // TODO: Something is still not quite right there. - for (i,(e1,e2)) in bounds.iter().enumerate() { - let (v1a_, v1b_) = seed.edge_vertices(*e1); - let (v2a_, v2b_) = mesh.edge_vertices(*e2); - let v1a = vertex_id_to_u32(v1a_); - let v1b = vertex_id_to_u32(v1b_); - let v2a = vertex_id_to_u32(v2a_); - let v2b = vertex_id_to_u32(v2b_); - - let v1a_d = vertex_id_to_usize(v1a_); - let v1b_d = vertex_id_to_usize(v1b_); - let v2a_d = vertex_id_to_usize(v2a_) + seed.no_vertices(); - let v2b_d = vertex_id_to_usize(v2b_) + seed.no_vertices(); - - println!("DEBUG: i={} e1={} ({}-{}) e2={} ({}-{})", i, e1, v1a, v1b, e2, v2a, v2b); - // TODO: Figure out why I am seeing two different things - // for e1 here with pos vs. seed.edge_positions: - println!("DEBUG: i={} e1: ({},{},{}) to ({},{},{})", - i, pos[3*v1a_d], pos[3*v1a_d+1], pos[3*v1a_d+2], - pos[3*v1b_d], pos[3*v1b_d+1], pos[3*v1b_d+2]); - println!("DEBUG: e1, {:?}", seed.edge_positions(*e1)); - // and for e2 here: - println!("DEBUG: i={} e2: ({},{},{}) to ({},{},{})", - i, pos[3*v2a_d], pos[3*v2a_d+1], pos[3*v2a_d+2], - pos[3*v2b_d], pos[3*v2b_d+1], pos[3*v2b_d+2]); - println!("DEBUG: e2, {:?}", mesh.edge_positions(*e2)); - // First triangle: - indices[6*i + 0] = v1a; - indices[6*i + 1] = v1b; - indices[6*i + 2] = offset + v2a; - // Second triangle: - indices[6*i + 3] = offset + v2a; - indices[6*i + 4] = v1b; - indices[6*i + 5] = offset + v2b; - println!("DEBUG: i={} ({}, {}, {}) and ({}, {}, {})", i, v1a, v1b, offset + v2a, offset + v2a, v1b, offset + v2b); - } - // TODO: This is *still* connecting wrong somehow. - - // positions_buffer just calls vertex_iter() and - // vertex_position anyway, so why not just access directly? - // The only thing that matters with my own indices is that - // they be u32 and they point to the right vertex (and I can - // choose the vertices). - - // So maybe... - // - Assemble vertices just from 'bounds'. - // - Disregard positions_buffer completely. I don't need it. - // - Set 'indices' based on what I know about how 'bounds' was - // constructed. - - let joined = match MeshBuilder::new().with_positions(pos).with_indices(indices).build() { + let joined = match MeshBuilder::new(). + with_positions(verts). + with_indices(idxs). + build() + { Ok(m) => m, Err(error) => { panic!("Error building mesh: {:?}", error) @@ -292,7 +253,7 @@ impl<'a> Iterator for MeshBound<'a> { // We have returned back to start: self.done = true; } - println!("DEBUG: MeshBound: edge {} is {:?}", halfedge_id, self.m.edge_positions(halfedge_id)); + //println!("DEBUG: MeshBound: edge {} is {:?}", halfedge_id, self.m.edge_positions(halfedge_id)); return Some(halfedge_id); } } @@ -420,7 +381,7 @@ fn main() { } println!("DEBUG-------------------------------"); - let (mesh, nodes) = rule_to_mesh(&r2, vec![seed], 5); + let (mesh, nodes) = rule_to_mesh(&r2, vec![seed], 75); println!("Collected {} nodes, produced {} faces, {} vertices", nodes, mesh.no_faces(), mesh.no_vertices()); println!("Writing OBJ...");