One example is building and running, mostly
This commit is contained in:
parent
7626f1a089
commit
19988a0b35
@ -4,7 +4,8 @@ use nalgebra::*;
|
|||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
use crate::util;
|
use crate::util;
|
||||||
use crate::mesh::{Mesh, MeshTemplate};
|
use crate::util::VecExt;
|
||||||
|
use crate::mesh::{Mesh, MeshFunc, VertexUnion};
|
||||||
use crate::xform::{Transform, Vertex, vertex, Mat4};
|
use crate::xform::{Transform, Vertex, vertex, Mat4};
|
||||||
use crate::rule::{Rule, RuleFn, RuleEval, Child};
|
use crate::rule::{Rule, RuleFn, RuleEval, Child};
|
||||||
use crate::prim;
|
use crate::prim;
|
||||||
@ -45,15 +46,16 @@ pub fn cube_thing() -> Rule<()> {
|
|||||||
|
|
||||||
Rule { eval: Rc::new(rec), ctxt: () }
|
Rule { eval: Rc::new(rec), ctxt: () }
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub fn barbs() -> Rule<()> {
|
pub fn barbs() -> Rule<()> {
|
||||||
|
|
||||||
let (a0, a1);
|
let (b0, b1);
|
||||||
let base_verts: Vec<Vertex> = vec_indexed![
|
let base_verts: Vec<VertexUnion> = vec_indexed![
|
||||||
@a0: vertex(-0.5, -0.5, 0.0),
|
@b0: VertexUnion::Vertex(vertex(-0.5, -0.5, 0.0)),
|
||||||
vertex(-0.5, 0.5, 0.0),
|
VertexUnion::Vertex(vertex(-0.5, 0.5, 0.0)),
|
||||||
vertex( 0.5, 0.5, 0.0),
|
VertexUnion::Vertex(vertex( 0.5, 0.5, 0.0)),
|
||||||
@a1: vertex( 0.5, -0.5, 0.0),
|
@b1: VertexUnion::Vertex(vertex( 0.5, -0.5, 0.0)),
|
||||||
];
|
];
|
||||||
let n = base_verts.len();
|
let n = base_verts.len();
|
||||||
|
|
||||||
@ -64,19 +66,24 @@ pub fn barbs() -> Rule<()> {
|
|||||||
|
|
||||||
let b = base_verts.clone();
|
let b = base_verts.clone();
|
||||||
let barb = move |self_: Rc<Rule<()>>| -> RuleEval<()> {
|
let barb = move |self_: Rc<Rule<()>>| -> RuleEval<()> {
|
||||||
let next_verts = incr.transform(&b);
|
let mut next_verts = b.clone();
|
||||||
|
let (a0, a1) = next_verts.append_indexed(
|
||||||
|
&mut (0..4).map(|i| VertexUnion::Arg(i)).collect()
|
||||||
|
);
|
||||||
|
|
||||||
let geom = Rc::new(util::zigzag_to_parent(next_verts.clone(), a0..a1));
|
|
||||||
let (vc, faces) = util::connect_convex(&next_verts, true);
|
let geom = util::parallel_zigzag(next_verts.clone(), b0..b1, a0..a1);
|
||||||
|
/*let (vc, faces) = util::connect_convex(&next_verts, true);
|
||||||
let final_geom = Rc::new(OpenMesh {
|
let final_geom = Rc::new(OpenMesh {
|
||||||
verts: vec![vc],
|
verts: vec![vc],
|
||||||
alias_verts: vec![],
|
alias_verts: vec![],
|
||||||
faces: faces,
|
faces: faces,
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
RuleEval {
|
RuleEval {
|
||||||
geom: geom,
|
geom: Rc::new(geom.transform(&incr)),
|
||||||
final_geom: final_geom,
|
final_geom: Rc::new(prim::empty_meshfunc()), // TODO
|
||||||
children: vec![
|
children: vec![
|
||||||
Child {
|
Child {
|
||||||
rule: self_.clone(),
|
rule: self_.clone(),
|
||||||
@ -89,20 +96,24 @@ pub fn barbs() -> Rule<()> {
|
|||||||
|
|
||||||
let b = base_verts.clone();
|
let b = base_verts.clone();
|
||||||
let main = move |self_: Rc<Rule<()>>| -> RuleEval<()> {
|
let main = move |self_: Rc<Rule<()>>| -> RuleEval<()> {
|
||||||
let next_verts = incr.transform(&b);
|
let mut next_verts = b.clone();
|
||||||
|
let (a0, a1) = next_verts.append_indexed(
|
||||||
|
&mut (0..4).map(|i| VertexUnion::Arg(i)).collect()
|
||||||
|
);
|
||||||
|
|
||||||
// TODO: Once I start doing the barbs this will go away
|
// TODO: Once I start doing the barbs this will go away
|
||||||
let geom = Rc::new(util::zigzag_to_parent(next_verts.clone(), n));
|
let geom = util::parallel_zigzag(next_verts.clone(), b0..b1+1, a0..a1);
|
||||||
|
/*
|
||||||
let (vc, faces) = util::connect_convex(&next_verts, true);
|
let (vc, faces) = util::connect_convex(&next_verts, true);
|
||||||
let final_geom = Rc::new(OpenMesh {
|
let final_geom = Rc::new(MeshFunc {
|
||||||
verts: vec![vc],
|
verts: vec![vc],
|
||||||
alias_verts: vec![],
|
|
||||||
faces: faces,
|
faces: faces,
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
RuleEval {
|
RuleEval {
|
||||||
geom: geom,
|
geom: Rc::new(geom.transform(&incr)),
|
||||||
final_geom: final_geom,
|
final_geom: Rc::new(prim::empty_meshfunc()), // TODO
|
||||||
children: vec![
|
children: vec![
|
||||||
Child {
|
Child {
|
||||||
rule: self_.clone(),
|
rule: self_.clone(),
|
||||||
@ -116,15 +127,14 @@ pub fn barbs() -> Rule<()> {
|
|||||||
let main_ = Rc::new(main);
|
let main_ = Rc::new(main);
|
||||||
let base = move |self_: Rc<Rule<()>>| -> RuleEval<()> {
|
let base = move |self_: Rc<Rule<()>>| -> RuleEval<()> {
|
||||||
RuleEval {
|
RuleEval {
|
||||||
geom: Rc::new(OpenMesh {
|
geom: Rc::new(MeshFunc {
|
||||||
verts: base_verts.clone(),
|
verts: base_verts.clone(),
|
||||||
alias_verts: vec![],
|
|
||||||
faces: vec![
|
faces: vec![
|
||||||
0, 1, 2,
|
b0, b0 + 1, b0 + 2,
|
||||||
0, 1, 3,
|
b0, b0 + 2, b0 + 3,
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
final_geom: Rc::new(prim::empty_mesh()),
|
final_geom: Rc::new(prim::empty_meshfunc()),
|
||||||
children: vec![
|
children: vec![
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: main_.clone(), ctxt: () }),
|
rule: Rc::new(Rule { eval: main_.clone(), ctxt: () }),
|
||||||
@ -138,6 +148,7 @@ pub fn barbs() -> Rule<()> {
|
|||||||
Rule { eval: Rc::new(base), ctxt: () }
|
Rule { eval: Rc::new(base), ctxt: () }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// Meant to be a copy of twist_from_gen from Python &
|
// Meant to be a copy of twist_from_gen from Python &
|
||||||
// automata_scratch, but has since acquired a sort of life of its own
|
// automata_scratch, but has since acquired a sort of life of its own
|
||||||
pub fn twist(f: f32, subdiv: usize) -> Rule<()> {
|
pub fn twist(f: f32, subdiv: usize) -> Rule<()> {
|
||||||
|
|||||||
@ -36,7 +36,7 @@ mod tests {
|
|||||||
println!("Evaluated {} rules to {} verts", nodes, mesh.verts.len());
|
println!("Evaluated {} rules to {} verts", nodes, mesh.verts.len());
|
||||||
let fname = format!("{}.stl", name);
|
let fname = format!("{}.stl", name);
|
||||||
println!("Writing {}...", fname);
|
println!("Writing {}...", fname);
|
||||||
mesh.write_stl_file(&fname).unwrap();
|
mesh.to_mesh().write_stl_file(&fname).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -71,10 +71,12 @@ mod tests {
|
|||||||
fn cube_thing() {
|
fn cube_thing() {
|
||||||
run_test(examples::cube_thing(), 3, "cube_thing3", false);
|
run_test(examples::cube_thing(), 3, "cube_thing3", false);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn barbs() { run_test(examples::barbs(), 20, "barbs", false); }
|
fn barbs() { run_test(examples::barbs(), 20, "barbs", false); }
|
||||||
|
|
||||||
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
fn twist() {
|
fn twist() {
|
||||||
run_test(examples::twist(1.0, 2), 200, "screw", false);
|
run_test(examples::twist(1.0, 2), 200, "screw", false);
|
||||||
|
|||||||
53
src/mesh.rs
53
src/mesh.rs
@ -42,9 +42,9 @@ impl Mesh {
|
|||||||
|
|
||||||
// Turn every face into an stl_io::Triangle:
|
// Turn every face into an stl_io::Triangle:
|
||||||
for i in 0..num_faces {
|
for i in 0..num_faces {
|
||||||
let v0 = self.verts[3*i + 0].xyz();
|
let v0 = self.verts[self.faces[3*i + 0]].xyz();
|
||||||
let v1 = self.verts[3*i + 1].xyz();
|
let v1 = self.verts[self.faces[3*i + 1]].xyz();
|
||||||
let v2 = self.verts[3*i + 2].xyz();
|
let v2 = self.verts[self.faces[3*i + 2]].xyz();
|
||||||
|
|
||||||
let normal = (v1-v0).cross(&(v2-v0));
|
let normal = (v1-v0).cross(&(v2-v0));
|
||||||
|
|
||||||
@ -62,8 +62,8 @@ impl Mesh {
|
|||||||
stl_io::write_stl(writer, triangles.iter())
|
stl_io::write_stl(writer, triangles.iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_template(&self) -> MeshTemplate {
|
fn to_meshfunc(&self) -> MeshFunc {
|
||||||
MeshTemplate {
|
MeshFunc {
|
||||||
faces: self.faces.clone(),
|
faces: self.faces.clone(),
|
||||||
verts: self.verts.iter().map(|v| VertexUnion::Vertex(*v)).collect(),
|
verts: self.verts.iter().map(|v| VertexUnion::Vertex(*v)).collect(),
|
||||||
}
|
}
|
||||||
@ -72,10 +72,11 @@ impl Mesh {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum VertexUnion {
|
pub enum VertexUnion {
|
||||||
/// A concrete vertex
|
/// A concrete vertex.
|
||||||
Vertex(Vertex),
|
Vertex(Vertex),
|
||||||
/// An alias to some other vertex (by index)
|
/// An 'unbound' vertex - something like an argument to a function with
|
||||||
Alias(usize),
|
/// the given positional index.
|
||||||
|
Arg(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A face-vertex mesh whose vertices can either be concrete values
|
/// A face-vertex mesh whose vertices can either be concrete values
|
||||||
@ -84,7 +85,7 @@ pub enum VertexUnion {
|
|||||||
/// aliases are resolved to concrete vertices with a call like
|
/// aliases are resolved to concrete vertices with a call like
|
||||||
/// `connect()`.
|
/// `connect()`.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct MeshTemplate {
|
pub struct MeshFunc {
|
||||||
//
|
//
|
||||||
pub verts: Vec<VertexUnion>,
|
pub verts: Vec<VertexUnion>,
|
||||||
/// Indices of triangles (taken as every 3 values). Indices begin
|
/// Indices of triangles (taken as every 3 values). Indices begin
|
||||||
@ -95,11 +96,21 @@ pub struct MeshTemplate {
|
|||||||
pub faces: Vec<usize>,
|
pub faces: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MeshTemplate {
|
impl MeshFunc {
|
||||||
|
|
||||||
/// Returns a new `MeshTemplate` whose concrete vertices have
|
pub fn to_mesh(&self) -> Mesh {
|
||||||
|
Mesh {
|
||||||
|
faces: self.faces.clone(),
|
||||||
|
verts: self.verts.iter().map(|v| match *v {
|
||||||
|
VertexUnion::Vertex(v) => v,
|
||||||
|
VertexUnion::Arg(_) => panic!("Mesh still has vertex arguments!"),
|
||||||
|
}).collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new `MeshFunc` whose concrete vertices have
|
||||||
/// been transformed. Note that alias vertices are left untouched.
|
/// been transformed. Note that alias vertices are left untouched.
|
||||||
pub fn transform(&self, xfm: &Transform) -> MeshTemplate {
|
pub fn transform(&self, xfm: &Transform) -> MeshFunc {
|
||||||
let v = self.verts.iter().map(|v| {
|
let v = self.verts.iter().map(|v| {
|
||||||
match v {
|
match v {
|
||||||
VertexUnion::Vertex(v) => VertexUnion::Vertex(xfm.mtx * v),
|
VertexUnion::Vertex(v) => VertexUnion::Vertex(xfm.mtx * v),
|
||||||
@ -107,7 +118,7 @@ impl MeshTemplate {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
MeshTemplate {
|
MeshFunc {
|
||||||
verts: v.collect(),
|
verts: v.collect(),
|
||||||
faces: self.faces.clone(),
|
faces: self.faces.clone(),
|
||||||
}
|
}
|
||||||
@ -118,8 +129,8 @@ impl MeshTemplate {
|
|||||||
/// corresponding input mesh was shifted. That is, for the i'th
|
/// corresponding input mesh was shifted. That is, for the i'th
|
||||||
/// index in `meshes`, all of its triangle indices were shifted by
|
/// index in `meshes`, all of its triangle indices were shifted by
|
||||||
/// the i'th offset in the resultant mesh.
|
/// the i'th offset in the resultant mesh.
|
||||||
pub fn append<T, U>(meshes: T) -> (MeshTemplate, Vec<usize>)
|
pub fn append<T, U>(meshes: T) -> (MeshFunc, Vec<usize>)
|
||||||
where U: Borrow<MeshTemplate>,
|
where U: Borrow<MeshFunc>,
|
||||||
T: IntoIterator<Item = U>
|
T: IntoIterator<Item = U>
|
||||||
{
|
{
|
||||||
let mut offsets: Vec<usize> = vec![];
|
let mut offsets: Vec<usize> = vec![];
|
||||||
@ -139,7 +150,7 @@ impl MeshTemplate {
|
|||||||
f.extend(mesh.faces.iter().map(|n| n + offset));
|
f.extend(mesh.faces.iter().map(|n| n + offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
(MeshTemplate { verts: v, faces: f }, offsets)
|
(MeshFunc { verts: v, faces: f }, offsets)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Treat this mesh as a 'parent' mesh to connect with any number
|
/// Treat this mesh as a 'parent' mesh to connect with any number
|
||||||
@ -151,8 +162,8 @@ impl MeshTemplate {
|
|||||||
/// That is, the vertices of 'children[i]' begin at vertex
|
/// That is, the vertices of 'children[i]' begin at vertex
|
||||||
/// 'offset[i]' of the new mesh. This is needed in some cases for
|
/// 'offset[i]' of the new mesh. This is needed in some cases for
|
||||||
/// adjusting a parent vertex mapping, like 'vmap' of Rule::Child.
|
/// adjusting a parent vertex mapping, like 'vmap' of Rule::Child.
|
||||||
pub fn connect<T, U>(&self, children: T) -> (MeshTemplate, Vec<usize>)
|
pub fn connect<T, U>(&self, children: T) -> (MeshFunc, Vec<usize>)
|
||||||
where U: Borrow<MeshTemplate>,
|
where U: Borrow<MeshFunc>,
|
||||||
T: IntoIterator<Item = (U, Vec<usize>)>
|
T: IntoIterator<Item = (U, Vec<usize>)>
|
||||||
//pub fn connect(&self, children: &Vec<(OpenMesh, Vec<usize>)>) -> (OpenMesh, Vec<usize>)
|
//pub fn connect(&self, children: &Vec<(OpenMesh, Vec<usize>)>) -> (OpenMesh, Vec<usize>)
|
||||||
{
|
{
|
||||||
@ -178,7 +189,7 @@ impl MeshTemplate {
|
|||||||
verts.extend(child.verts.iter().filter_map(|v| {
|
verts.extend(child.verts.iter().filter_map(|v| {
|
||||||
match v {
|
match v {
|
||||||
VertexUnion::Vertex(_) => Some(v.clone()),
|
VertexUnion::Vertex(_) => Some(v.clone()),
|
||||||
VertexUnion::Alias(_) => None,
|
VertexUnion::Arg(_) => None,
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -188,14 +199,14 @@ impl MeshTemplate {
|
|||||||
faces.extend(child.faces.iter().map(|n|
|
faces.extend(child.faces.iter().map(|n|
|
||||||
match child.verts[*n] {
|
match child.verts[*n] {
|
||||||
VertexUnion::Vertex(_) => n + offset,
|
VertexUnion::Vertex(_) => n + offset,
|
||||||
VertexUnion::Alias(m) => mapping[m],
|
VertexUnion::Arg(m) => mapping[m],
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
offsets.push(offset);
|
offsets.push(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
let m = MeshTemplate {
|
let m = MeshFunc {
|
||||||
verts: verts,
|
verts: verts,
|
||||||
faces: faces,
|
faces: faces,
|
||||||
};
|
};
|
||||||
|
|||||||
10
src/prim.rs
10
src/prim.rs
@ -1,4 +1,4 @@
|
|||||||
use crate::mesh::{Mesh};
|
use crate::mesh::{Mesh, MeshFunc};
|
||||||
use crate::xform::{vertex, Transform};
|
use crate::xform::{vertex, Transform};
|
||||||
|
|
||||||
/// Returns an empty mesh (no vertices, no faces).
|
/// Returns an empty mesh (no vertices, no faces).
|
||||||
@ -9,6 +9,14 @@ pub fn empty_mesh() -> Mesh {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an empty MeshFn (no vertices, no faces, thus no args).
|
||||||
|
pub fn empty_meshfunc() -> MeshFunc {
|
||||||
|
MeshFunc {
|
||||||
|
verts: vec![],
|
||||||
|
faces: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a cube of sidelength one centered at (0,0,0).
|
/// Returns a cube of sidelength one centered at (0,0,0).
|
||||||
pub fn cube() -> Mesh {
|
pub fn cube() -> Mesh {
|
||||||
Mesh {
|
Mesh {
|
||||||
|
|||||||
24
src/rule.rs
24
src/rule.rs
@ -1,4 +1,4 @@
|
|||||||
use crate::mesh::{MeshTemplate, VertexUnion};
|
use crate::mesh::{MeshFunc, VertexUnion};
|
||||||
use crate::xform::{Transform};
|
use crate::xform::{Transform};
|
||||||
//use crate::prim;
|
//use crate::prim;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
@ -38,7 +38,7 @@ pub struct Rule<S> {
|
|||||||
/// `geom`.
|
/// `geom`.
|
||||||
pub struct RuleEval<S> {
|
pub struct RuleEval<S> {
|
||||||
/// The geometry generated at just this iteration
|
/// The geometry generated at just this iteration
|
||||||
pub geom: Rc<MeshTemplate>,
|
pub geom: Rc<MeshFunc>,
|
||||||
|
|
||||||
/// The "final" geometry that is merged with `geom` via
|
/// The "final" geometry that is merged with `geom` via
|
||||||
/// `connect()` in the event that recursion stops. This must be
|
/// `connect()` in the event that recursion stops. This must be
|
||||||
@ -46,7 +46,7 @@ pub struct RuleEval<S> {
|
|||||||
///
|
///
|
||||||
/// Parent vertex references will be resolved directly to `geom`
|
/// Parent vertex references will be resolved directly to `geom`
|
||||||
/// with no mapping.
|
/// with no mapping.
|
||||||
pub final_geom: Rc<MeshTemplate>,
|
pub final_geom: Rc<MeshFunc>,
|
||||||
|
|
||||||
/// The child invocations (used if recursion continues). The
|
/// The child invocations (used if recursion continues). The
|
||||||
/// 'parent' mesh, from the perspective of all geometry produced
|
/// 'parent' mesh, from the perspective of all geometry produced
|
||||||
@ -69,7 +69,7 @@ pub struct Child<S> {
|
|||||||
|
|
||||||
/// The parent vertex mapping: a mapping to apply to turn a
|
/// The parent vertex mapping: a mapping to apply to turn a
|
||||||
/// Tag::Parent vertex reference into a vertex index of the parent
|
/// Tag::Parent vertex reference into a vertex index of the parent
|
||||||
/// mesh. That is, if `rule` produces a `MeshTemplate` with a face
|
/// mesh. That is, if `rule` produces a `MeshFunc` with a face
|
||||||
/// of `Tag::Parent(n)`, this will correspond to index `vmap[n]`
|
/// of `Tag::Parent(n)`, this will correspond to index `vmap[n]`
|
||||||
/// in the parent mesh.
|
/// in the parent mesh.
|
||||||
pub vmap: Vec<usize>,
|
pub vmap: Vec<usize>,
|
||||||
@ -80,7 +80,7 @@ impl<S> Rule<S> {
|
|||||||
/// Convert this `Rule` to mesh data, recursively (depth first).
|
/// Convert this `Rule` to mesh data, recursively (depth first).
|
||||||
/// `iters_left` sets the maximum recursion depth. This returns
|
/// `iters_left` sets the maximum recursion depth. This returns
|
||||||
/// (geometry, number of rule evaluations).
|
/// (geometry, number of rule evaluations).
|
||||||
pub fn to_mesh(s: Rc<Rule<S>>, iters_left: usize) -> (MeshTemplate, usize) {
|
pub fn to_mesh(s: Rc<Rule<S>>, iters_left: usize) -> (MeshFunc, usize) {
|
||||||
|
|
||||||
let mut evals = 1;
|
let mut evals = 1;
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ impl<S> Rule<S> {
|
|||||||
// TODO: This logic is more or less right, but it
|
// TODO: This logic is more or less right, but it
|
||||||
// could perhaps use some un-tupling or something.
|
// could perhaps use some un-tupling or something.
|
||||||
|
|
||||||
let subgeom: Vec<(MeshTemplate, Vec<usize>)> = rs.children.iter().map(|sub| {
|
let subgeom: Vec<(MeshFunc, Vec<usize>)> = rs.children.iter().map(|sub| {
|
||||||
// Get sub-geometry (still un-transformed):
|
// Get sub-geometry (still un-transformed):
|
||||||
let (submesh, eval) = Rule::to_mesh(sub.rule.clone(), iters_left - 1);
|
let (submesh, eval) = Rule::to_mesh(sub.rule.clone(), iters_left - 1);
|
||||||
// Tally up eval count:
|
// Tally up eval count:
|
||||||
@ -114,7 +114,7 @@ impl<S> Rule<S> {
|
|||||||
/// This should be identical to to_mesh, but implemented
|
/// This should be identical to to_mesh, but implemented
|
||||||
/// iteratively with an explicit stack rather than with recursive
|
/// iteratively with an explicit stack rather than with recursive
|
||||||
/// function calls.
|
/// function calls.
|
||||||
pub fn to_mesh_iter(s: Rc<Rule<S>>, max_depth: usize) -> (MeshTemplate, usize) {
|
pub fn to_mesh_iter(s: Rc<Rule<S>>, max_depth: usize) -> (MeshFunc, usize) {
|
||||||
|
|
||||||
struct State<S> {
|
struct State<S> {
|
||||||
// The set of rules we're currently handling:
|
// The set of rules we're currently handling:
|
||||||
@ -187,7 +187,7 @@ impl<S> Rule<S> {
|
|||||||
let mut m_ = 0;
|
let mut m_ = 0;
|
||||||
for v in &final_geom.verts {
|
for v in &final_geom.verts {
|
||||||
match *v {
|
match *v {
|
||||||
VertexUnion::Alias(a) => {
|
VertexUnion::Arg(a) => {
|
||||||
if a > m_ {
|
if a > m_ {
|
||||||
m_ = a;
|
m_ = a;
|
||||||
}
|
}
|
||||||
@ -262,17 +262,17 @@ impl<S> Rule<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<S> RuleEval<S> {
|
impl<S> RuleEval<S> {
|
||||||
/// Turn an iterator of (MeshTemplate, Child) into a single RuleEval.
|
/// Turn an iterator of (MeshFunc, Child) into a single RuleEval.
|
||||||
/// All meshes are merged, and the `vmap` in each child has the
|
/// All meshes are merged, and the `vmap` in each child has the
|
||||||
/// correct offsets applied to account for this merge.
|
/// correct offsets applied to account for this merge.
|
||||||
///
|
///
|
||||||
/// (`final_geom` is passed through to the RuleEval unmodified.)
|
/// (`final_geom` is passed through to the RuleEval unmodified.)
|
||||||
pub fn from_pairs<T, U>(m: T, final_geom: MeshTemplate) -> RuleEval<S>
|
pub fn from_pairs<T, U>(m: T, final_geom: MeshFunc) -> RuleEval<S>
|
||||||
where U: Borrow<MeshTemplate>,
|
where U: Borrow<MeshFunc>,
|
||||||
T: IntoIterator<Item = (U, Child<S>)>
|
T: IntoIterator<Item = (U, Child<S>)>
|
||||||
{
|
{
|
||||||
let (meshes, children): (Vec<_>, Vec<_>) = m.into_iter().unzip();
|
let (meshes, children): (Vec<_>, Vec<_>) = m.into_iter().unzip();
|
||||||
let (mesh, offsets) = MeshTemplate::append(meshes);
|
let (mesh, offsets) = MeshFunc::append(meshes);
|
||||||
|
|
||||||
// Patch up vmap in each child, and copy everything else:
|
// Patch up vmap in each child, and copy everything else:
|
||||||
let children2: Vec<Child<S>> = children.iter().zip(offsets.iter()).map(|(c,off)| {
|
let children2: Vec<Child<S>> = children.iter().zip(offsets.iter()).map(|(c,off)| {
|
||||||
|
|||||||
21
src/util.rs
21
src/util.rs
@ -1,5 +1,5 @@
|
|||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use crate::mesh::{Mesh, MeshTemplate, VertexUnion};
|
use crate::mesh::{Mesh, MeshFunc, VertexUnion};
|
||||||
use crate::xform::{Vertex};
|
use crate::xform::{Vertex};
|
||||||
//use crate::rule::{Rule, Child};
|
//use crate::rule::{Rule, Child};
|
||||||
|
|
||||||
@ -19,6 +19,21 @@ macro_rules! vec_indexed {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait VecExt<T> {
|
||||||
|
fn append_indexed(&mut self, other: &mut Vec<T>) -> (usize, usize);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> VecExt<T> for Vec<T> {
|
||||||
|
// Like `append`, but returning `(a, b)` which give the range of
|
||||||
|
// elements just inserted.
|
||||||
|
fn append_indexed(&mut self, other: &mut Vec<T>) -> (usize, usize) {
|
||||||
|
let a = self.len();
|
||||||
|
self.append(other);
|
||||||
|
let b = self.len();
|
||||||
|
(a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Linearly subdivides a list of points that are to be treated as a
|
/// Linearly subdivides a list of points that are to be treated as a
|
||||||
/// cycle. This produces 'count' points for every element of 'p'
|
/// cycle. This produces 'count' points for every element of 'p'
|
||||||
/// (thus, the returned length will be `count*p.len()`).
|
/// (thus, the returned length will be `count*p.len()`).
|
||||||
@ -60,8 +75,8 @@ pub fn parallel_zigzag_faces(r1: Range<usize>, r2: Range<usize>) -> Vec<usize> {
|
|||||||
}).flatten().collect()
|
}).flatten().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zigzag_to_parent(verts: Vec<VertexUnion>, main: Range<usize>, parent: Range<usize>) -> MeshTemplate {
|
pub fn parallel_zigzag(verts: Vec<VertexUnion>, main: Range<usize>, parent: Range<usize>) -> MeshFunc {
|
||||||
MeshTemplate {
|
MeshFunc {
|
||||||
verts: verts,
|
verts: verts,
|
||||||
faces: parallel_zigzag_faces(main, parent),
|
faces: parallel_zigzag_faces(main, parent),
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user