Updated some more docs
This commit is contained in:
parent
751df8274f
commit
00a766bd24
@ -4,8 +4,9 @@ use nalgebra::*;
|
||||
use std::fs::OpenOptions;
|
||||
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>;
|
||||
/// A type for homogeneous transforms
|
||||
pub type Mat4 = Matrix4<f32>;
|
||||
|
||||
/// Initializes a vertex:
|
||||
@ -13,23 +14,32 @@ pub fn vertex(x: f32, y: f32, z: f32) -> Vertex {
|
||||
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)]
|
||||
pub enum Tag {
|
||||
Body(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)]
|
||||
pub struct OpenMesh {
|
||||
// Vertices (in homogeneous coordinates).
|
||||
/// Vertices of mesh
|
||||
pub verts: Vec<Vertex>,
|
||||
// Triangles, taken as every 3 values, treated each as indices
|
||||
// into 'verts':
|
||||
/// Indices of triangles (taken as every 3 values). `Tag::Body`
|
||||
/// 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>,
|
||||
}
|
||||
|
||||
impl OpenMesh {
|
||||
|
||||
/// Returns a new `OpenMesh` whose vertices have been transformed.
|
||||
pub fn transform(&self, xfm: &Mat4) -> OpenMesh {
|
||||
OpenMesh {
|
||||
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<()> {
|
||||
let mut file = OpenOptions::new().write(true).create(true).truncate(true).open(fname)?;
|
||||
self.write_stl(&mut file)
|
||||
@ -84,25 +96,29 @@ impl OpenMesh {
|
||||
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
|
||||
|
||||
// Copy body vertices & faces:
|
||||
let mut verts: Vec<Vertex> = self.verts.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
|
||||
// which we're appending everything in 'other.verts' -
|
||||
// thus, the offset we shift all indices in 'others' by.
|
||||
// which we're appending everything in 'child.verts' -
|
||||
// thus, the offset we shift all indices in 'children' by.
|
||||
let body_offset = verts.len();
|
||||
|
||||
// Copy all vertices from 'other':
|
||||
verts.append(&mut other.verts.clone());
|
||||
// Copy all vertices from 'child':
|
||||
verts.append(&mut child.verts.clone());
|
||||
|
||||
// Append its faces:
|
||||
faces.extend(other.faces.iter().map(|t| {
|
||||
faces.extend(child.faces.iter().map(|t| {
|
||||
match t {
|
||||
// Apply aforementioned shift to its body vertices:
|
||||
Tag::Body(n) => Tag::Body(n + body_offset),
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use nalgebra::*;
|
||||
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 {
|
||||
OpenMesh {
|
||||
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 {
|
||||
OpenMesh {
|
||||
verts: vec![
|
||||
|
||||
@ -59,10 +59,11 @@ pub struct Child {
|
||||
/// as all sub-geometry produced recursively).
|
||||
pub xf: Mat4,
|
||||
|
||||
/// The mapping to apply to turn a Tag::Parent vertex reference
|
||||
/// into a vertex index of the parent mesh. That is, if `rule`
|
||||
/// produces an `OpenMesh` with a face of `Tag::Parent(n)`, this
|
||||
/// will correspond to index `vmap[n]` in the parent mesh.
|
||||
/// The parent vertex mapping: a mapping to apply to turn a
|
||||
/// Tag::Parent vertex reference into a vertex index of the parent
|
||||
/// mesh. That is, if `rule` produces an `OpenMesh` with a face
|
||||
/// of `Tag::Parent(n)`, this will correspond to index `vmap[n]`
|
||||
/// in the parent mesh.
|
||||
pub vmap: Vec<usize>,
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user