OpenMesh struct now has trimesh export

This commit is contained in:
Chris Hodapp 2020-02-08 22:52:55 -05:00
parent 52bfd8fc6c
commit 2176f0c90e
2 changed files with 97 additions and 29 deletions

View File

@ -2,6 +2,7 @@
- https://docs.rs/nalgebra/0.19.0/nalgebra/geometry/struct.Translation.html#method.prepend_translation - - https://docs.rs/nalgebra/0.19.0/nalgebra/geometry/struct.Translation.html#method.prepend_translation -
see this for how to create Matrix4 from a translation see this for how to create Matrix4 from a translation
- Try a translation on an OpenMesh, and then try connect_single!
- Look at everything in README.md in automata_scratch. - Look at everything in README.md in automata_scratch.
- Implement some of the tougher examples from the above too, e.g. the - Implement some of the tougher examples from the above too, e.g. the

View File

@ -21,16 +21,16 @@ struct OpenMesh {
// into 'verts': // into 'verts':
faces: Vec<usize>, faces: Vec<usize>,
// A list of indices into verts, telling the index at which each // A list of indices into verts, telling the index at which each
// 'entrance' vertex loop begins. The loop implicitly ends where the // 'entrance' vertex group begins. The group implicitly ends
// next one begins, or if it is the last one, at idxs_body._1. // where the next one begins, or if it is the last group, at
// Thus, this has one element per vertex loop, and must go in // idxs_body._1. Thus, this has one element per vertex group, and
// ascending order. // must go in ascending order.
idxs_entrance: Vec<usize>, idxs_entrance: Vec<usize>,
// The same as idxs_entrance, but for 'exit' vertex loops. The final // The same as idxs_entrance, but for 'exit' vertex groups. The
// loop is taken as ending at the end of the list. // final loop is taken as ending at the end of the list.
idxs_exit: Vec<usize>, idxs_exit: Vec<usize>,
// The start and end (non-inclusive) of the 'body' vertices - // The start and end (non-inclusive) of the 'body' vertices -
// those that are neither an entrance nor an exit loop. // those that are neither an entrance nor an exit group.
idxs_body: (usize, usize), idxs_body: (usize, usize),
} }
// TODO: What is proper for an index, u32 or usize? // TODO: What is proper for an index, u32 or usize?
@ -47,10 +47,54 @@ impl OpenMesh {
} }
} }
fn connect_single(&self, other: &OpenMesh) -> OpenMesh {
let mut v: Vec<Vertex> = vec![vertex(0.0,0.0,0.0); self.verts.len()];
// Start out by cloning just entrance & body vertices:
v.copy_from_slice(&self.verts[0..self.idxs_body.1]);
let mut f = self.faces.clone();
// I already know what size v will be so I can pre-allocate
// and then just clone_from_slice to the proper locations
// We are offsetting all vertices in 'other' by everything
// else in 'v', so we need to account for this when we copy
// 'faces' (which has vector indices):
let offset = self.idxs_body.1;
f.extend(other.faces.iter().map(|f| *f + offset));
v.extend(other.verts.iter());
// The new exit groups are those in 'other', but likewise we
// need to shift these indices:
let idxs_exit = self.idxs_exit.iter().map(|f| *f + offset).collect();
// Body vertices start in the same place, but end where the
// body vertices in 'other' end (thus needing offset):
let idxs_body = (self.idxs_body.0, other.idxs_body.1 + offset);
OpenMesh {
verts: v,
faces: f,
idxs_entrance: self.idxs_entrance.clone(),
idxs_exit: idxs_exit,
idxs_body: idxs_body,
}
}
fn to_trimesh(&self) -> Result<Mesh, tri_mesh::mesh_builder::Error> {
let mut v: Vec<f64> = vec![0.0; self.verts.len() * 3];
for (i, vert) in self.verts.iter().enumerate() {
v[3*i] = vert[0].into();
v[3*i+1] = vert[1].into();
v[3*i+2] = vert[2].into();
}
let faces: Vec<u32> = self.faces.iter().map(|f| *f as _).collect();
MeshBuilder::new().with_indices(faces).with_positions(v).build()
}
// Just assume this is broken
fn connect(&self, others: &Vec<OpenMesh>) -> OpenMesh { fn connect(&self, others: &Vec<OpenMesh>) -> OpenMesh {
let mut v: Vec<Vertex> = vec![vertex(0.0,0.0,0.0); self.verts.len()];
// Start out by cloning just entrance & body vertices: // Start out by cloning just entrance & body vertices:
let mut v = self.verts[0..self.idxs_body.1].clone(); v.copy_from_slice(&self.verts[0..self.idxs_body.1]);
let mut f = self.faces.clone(); let mut f = self.faces.clone();
// TODO: Don't I need to patch up 'f'? self.faces refers to // TODO: Don't I need to patch up 'f'? self.faces refers to
// exit vertices which - if others.len() > 1 - need to be // exit vertices which - if others.len() > 1 - need to be
@ -58,32 +102,21 @@ impl OpenMesh {
// solely of an offset to all indices in a certain range. // solely of an offset to all indices in a certain range.
// //
// e.g. let idxs_exit be [e0, e1, e2, ... e_(n-1)] // e.g. let idxs_exit be [e0, e1, e2, ... e_(n-1)]
// indices in range [e0, e1-1] are for exit loop 0. // indices in range [e0, e1-1] are for exit group 0.
// indices in range [e1, e2-1] are for exit loop 1. // indices in range [e1, e2-1] are for exit group 1.
// indices in range [e2, e3-1] are for exit loop 2, etc. // indices in range [e2, e3-1] are for exit group 2, etc.
// //
// exit loop 0 requires no offset (we'll be putting entrance // exit group 0 requires no offset (we'll be putting entrance
// loop vertices of self.others[0] right over top of them). // group vertices of self.others[0] right over top of them).
// //
// exit loop 1 requires an offset of the number of entrace & // exit group 1 requires an offset of the number of entrace &
// body vertices of self.others[0] (because we have appended // body vertices of self.others[0] (because we have appended
// this all)... with some additional adjustment maybe? not // this all)... with some additional adjustment maybe? not
// sure. // sure.
// //
// exit loop 2 requires an offset of the same for // exit group 2 requires an offset of the same for
// self.others[0] and self.others[1]. // self.others[0] and self.others[1].
// one thing I'm missing: the above assumes one entrance loop
// for each element of 'others' but this might not be right.
// how do I know *which* entrance loop in 'others' goes with
// which exit loop of 'self'?
// if I enforce that each in 'others' can have only one
// entrance loop, and these match up 1:1 with exit loops, then
// this is much simpler but less flexible; it forbids multiple
// loops moving in tandem, and more complex things like
// joining forks.
for other in others { for other in others {
// We are offsetting all vertices in 'other' by everything // We are offsetting all vertices in 'other' by everything
// else in 'v', so we need to account for this when we // else in 'v', so we need to account for this when we
@ -93,13 +126,13 @@ impl OpenMesh {
f.extend(other.faces.iter().map(|f| *f + offset)); f.extend(other.faces.iter().map(|f| *f + offset));
} }
// - Connect up so that each of self's exit loops is an // - Connect up so that each of self's exit groups is an
// entrance loop from one of 'other' // entrance group from one of 'other'
return OpenMesh { return OpenMesh {
verts: v, verts: v,
faces: f, faces: f,
idxs_entrance: self.idxs_entrance.clone(), // TODO idxs_entrance: self.idxs_entrance.clone(),
idxs_exit: self.idxs_exit.clone(), // TODO idxs_exit: self.idxs_exit.clone(), // TODO
idxs_body: self.idxs_body.clone(), // TODO idxs_body: self.idxs_body.clone(), // TODO
}; };
@ -439,6 +472,40 @@ fn print_matrix(m: &Mat4) {
} }
fn main() { fn main() {
println!("DEBUG-------------------------------");
let m = OpenMesh {
verts: vec![
vertex(0.0, 0.0, 0.0),
vertex(1.0, 0.0, 0.0),
vertex(0.0, 1.0, 0.0),
vertex(1.0, 1.0, 0.0),
vertex(0.0, 0.0, 1.0),
vertex(1.0, 0.0, 1.0),
vertex(0.0, 1.0, 1.0),
vertex(1.0, 1.0, 1.0),
],
faces: vec![
0, 3, 1,
0, 2, 3,
1, 7, 5,
1, 3, 7,
5, 6, 4,
5, 7, 6,
4, 2, 0,
4, 6, 2,
2, 7, 3,
2, 6, 7,
0, 1, 5,
0, 5, 4,
],
idxs_entrance: vec![],
idxs_exit: vec![],
idxs_body: (0, 0),
};
let m_trimesh = m.to_trimesh().unwrap();
std::fs::write("openmesh_cube.obj", m_trimesh.parse_as_obj()).unwrap();
// Construct any mesh, this time, we will construct a simple icosahedron // Construct any mesh, this time, we will construct a simple icosahedron
let mesh = MeshBuilder::new().icosahedron().build().unwrap(); let mesh = MeshBuilder::new().icosahedron().build().unwrap();