Updated some more docs

This commit is contained in:
hodapp 2020-02-22 13:43:55 -05:00
parent 751df8274f
commit 00a766bd24
3 changed files with 36 additions and 18 deletions

View File

@ -4,8 +4,9 @@ use nalgebra::*;
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::io; use std::io;
/// A type for custom mesh vertices. Initialize with [vertex][self::vertex]. /// A type for mesh vertices. Initialize with [vertex][self::vertex].
pub type Vertex = Vector4<f32>; pub type Vertex = Vector4<f32>;
/// A type for homogeneous transforms
pub type Mat4 = Matrix4<f32>; pub type Mat4 = Matrix4<f32>;
/// Initializes a vertex: /// Initializes a vertex:
@ -13,23 +14,32 @@ pub fn vertex(x: f32, y: f32, z: f32) -> Vertex {
Vertex::new(x, y, z, 1.0) Vertex::new(x, y, z, 1.0)
} }
/// A type for a 'tagged' vertex index referring either to an index of
/// a mesh, or of its parent.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Tag { pub enum Tag {
Body(usize), Body(usize),
Parent(usize), Parent(usize),
} }
// TODO: This is clumsy. Can I do this some other way, or at least
// phrase it better?
/// A face-vertex mesh whose faces indices can refer either to its own
/// vertices, or to some 'parent' mesh.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct OpenMesh { pub struct OpenMesh {
// Vertices (in homogeneous coordinates). /// Vertices of mesh
pub verts: Vec<Vertex>, pub verts: Vec<Vertex>,
// Triangles, taken as every 3 values, treated each as indices /// Indices of triangles (taken as every 3 values). `Tag::Body`
// into 'verts': /// indices correspond to `verts`, while `Tag::Parent` indices
/// correspond to some parent mesh that must eventually be given
/// to complete this mesh.
pub faces: Vec<Tag>, pub faces: Vec<Tag>,
} }
impl OpenMesh { impl OpenMesh {
/// Returns a new `OpenMesh` whose vertices have been transformed.
pub fn transform(&self, xfm: &Mat4) -> OpenMesh { pub fn transform(&self, xfm: &Mat4) -> OpenMesh {
OpenMesh { OpenMesh {
verts: self.verts.iter().map(|v| xfm * v).collect(), verts: self.verts.iter().map(|v| xfm * v).collect(),
@ -39,6 +49,8 @@ impl OpenMesh {
} }
} }
/// Write this mesh as an STL file. This will fail if any element
/// of `faces` is `Tag::Parent`.
pub fn write_stl_file(&self, fname: &str) -> io::Result<()> { pub fn write_stl_file(&self, fname: &str) -> io::Result<()> {
let mut file = OpenOptions::new().write(true).create(true).truncate(true).open(fname)?; let mut file = OpenOptions::new().write(true).create(true).truncate(true).open(fname)?;
self.write_stl(&mut file) self.write_stl(&mut file)
@ -84,25 +96,29 @@ impl OpenMesh {
stl_io::write_stl(writer, triangles.iter()) stl_io::write_stl(writer, triangles.iter())
} }
pub fn connect(&self, others: &Vec<(OpenMesh, &Vec<usize>)>) -> OpenMesh { /// Treat this mesh as a 'parent' mesh to connect with any number
/// of 'child' meshes, all of them paired with their respective
/// parent vertex mappings. This returns a new mesh.
pub fn connect(&self, children: &Vec<(OpenMesh, &Vec<usize>)>) -> OpenMesh {
// TODO: Clean up this description a bit
// TODO: Clean up Vec<usize> stuff // TODO: Clean up Vec<usize> stuff
// Copy body vertices & faces: // Copy body vertices & faces:
let mut verts: Vec<Vertex> = self.verts.clone(); let mut verts: Vec<Vertex> = self.verts.clone();
let mut faces = self.faces.clone(); let mut faces = self.faces.clone();
for (other,mapping) in others { for (child,mapping) in children {
// body_offset corresponds to the position in 'verts' at // body_offset corresponds to the position in 'verts' at
// which we're appending everything in 'other.verts' - // which we're appending everything in 'child.verts' -
// thus, the offset we shift all indices in 'others' by. // thus, the offset we shift all indices in 'children' by.
let body_offset = verts.len(); let body_offset = verts.len();
// Copy all vertices from 'other': // Copy all vertices from 'child':
verts.append(&mut other.verts.clone()); verts.append(&mut child.verts.clone());
// Append its faces: // Append its faces:
faces.extend(other.faces.iter().map(|t| { faces.extend(child.faces.iter().map(|t| {
match t { match t {
// Apply aforementioned shift to its body vertices: // Apply aforementioned shift to its body vertices:
Tag::Body(n) => Tag::Body(n + body_offset), Tag::Body(n) => Tag::Body(n + body_offset),

View File

@ -1,7 +1,7 @@
use nalgebra::*; use nalgebra::*;
use crate::openmesh::{OpenMesh, Tag, vertex}; use crate::openmesh::{OpenMesh, Tag, vertex};
// is there a better way to do this? /// Returns an empty mesh (no vertices, no faces).
pub fn empty_mesh() -> OpenMesh { pub fn empty_mesh() -> OpenMesh {
OpenMesh { OpenMesh {
verts: vec![], verts: vec![],
@ -9,6 +9,7 @@ pub fn empty_mesh() -> OpenMesh {
} }
} }
/// Returns a cube of sidelength one centered at (0,0,0).
pub fn cube() -> OpenMesh { pub fn cube() -> OpenMesh {
OpenMesh { OpenMesh {
verts: vec![ verts: vec![

View File

@ -59,10 +59,11 @@ pub struct Child {
/// as all sub-geometry produced recursively). /// as all sub-geometry produced recursively).
pub xf: Mat4, pub xf: Mat4,
/// The mapping to apply to turn a Tag::Parent vertex reference /// The parent vertex mapping: a mapping to apply to turn a
/// into a vertex index of the parent mesh. That is, if `rule` /// Tag::Parent vertex reference into a vertex index of the parent
/// produces an `OpenMesh` with a face of `Tag::Parent(n)`, this /// mesh. That is, if `rule` produces an `OpenMesh` with a face
/// will correspond to index `vmap[n]` in the parent mesh. /// of `Tag::Parent(n)`, this will correspond to index `vmap[n]`
/// in the parent mesh.
pub vmap: Vec<usize>, pub vmap: Vec<usize>,
} }