Fixed ram_horn example, slight refactor on to_mesh

This commit is contained in:
Chris Hodapp 2020-02-22 08:26:27 -05:00
parent 436cb0bbc4
commit c594538644
4 changed files with 39 additions and 33 deletions

View File

@ -2,15 +2,15 @@
## Highest priority: ## Highest priority:
- See `ram_horn_*` and `curve_horn_*` TODOs: these are both solved by - Clean up my 'parent vertex mapping' thingy, *and* come up with
some sort of parent-vertex-mapping layer. The only other way around meaningful terms to discuss it.
this that I need is to require that rule functions exist in - Do transforms compose in the *reverse* of automata_scratch? This
explictly separate forms. appears to be the case.
- Consider trampolining `to_mesh`. My call stack seems needlessly
deep in spots. Can I make tail-recursive?
## Important but less critical: ## Important but less critical:
- Consider trampolining `to_mesh`. My call stack seems needlessly
deep in spots. Can I make tail-recursive?
- Grep for all TODOs in code, really. - Grep for all TODOs in code, really.
- 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

@ -119,11 +119,11 @@ fn cube_thing_rule() -> RuleStep {
// Conversion from Python & automata_scratch // Conversion from Python & automata_scratch
fn ram_horn_start() -> RuleStep { fn ram_horn_start() -> RuleStep {
let opening_xform = |i| { let opening_xform = |i| {
(geometry::Translation3::new(0.0, 0.0, -1.0).to_homogeneous() * ((geometry::Rotation3::from_axis_angle(
Matrix4::new_scaling(0.5) * &nalgebra::Vector3::z_axis(), i).to_homogeneous()) *
geometry::Translation3::new(0.25, 0.25, 1.0).to_homogeneous() * geometry::Translation3::new(0.25, 0.25, 1.0).to_homogeneous() *
geometry::Rotation3::from_axis_angle( Matrix4::new_scaling(0.5) *
&nalgebra::Vector3::z_axis(), i).to_homogeneous()) geometry::Translation3::new(0.0, 0.0, -1.0).to_homogeneous())
}; };
RuleStep { RuleStep {
geom: OpenMesh { geom: OpenMesh {
@ -171,19 +171,21 @@ fn ram_horn_start() -> RuleStep {
}, },
final_geom: prim::empty_mesh(), final_geom: prim::empty_mesh(),
children: vec![ children: vec![
(Rule::Recurse(ram_horn), opening_xform(0.0), vec![0,4,8,7]), (Rule::Recurse(ram_horn), opening_xform(0.0), vec![5,2,6,8]),
(Rule::Recurse(ram_horn), opening_xform(std::f32::consts::FRAC_PI_2), vec![1,5,8,4]), (Rule::Recurse(ram_horn), opening_xform(std::f32::consts::FRAC_PI_2), vec![4,1,5,8]),
(Rule::Recurse(ram_horn), opening_xform(std::f32::consts::FRAC_PI_2*2.0), vec![2,6,8,5]), (Rule::Recurse(ram_horn), opening_xform(std::f32::consts::FRAC_PI_2*2.0), vec![7,0,4,8]),
(Rule::Recurse(ram_horn), opening_xform(std::f32::consts::FRAC_PI_2*3.0), vec![3,7,8,6]), (Rule::Recurse(ram_horn), opening_xform(std::f32::consts::FRAC_PI_2*3.0), vec![6,3,7,8]),
// TODO: These vertex mappings appear to be right.
// Understand *why* they are right.
], ],
} }
} }
fn ram_horn() -> RuleStep { fn ram_horn() -> RuleStep {
let v = Unit::new_normalize(Vector3::new(-1.0, 0.0, 1.0)); let v = Unit::new_normalize(Vector3::new(-1.0, 0.0, 1.0));
let incr: Mat4 = Matrix4::new_scaling(0.9) * let incr: Mat4 = geometry::Translation3::new(0.0, 0.0, 0.8).to_homogeneous() *
geometry::Rotation3::from_axis_angle(&v, 0.3).to_homogeneous() * geometry::Rotation3::from_axis_angle(&v, 0.3).to_homogeneous() *
geometry::Translation3::new(0.0, 0.0, 0.8).to_homogeneous(); Matrix4::new_scaling(0.9);
let seed = vec![ let seed = vec![
vertex(-0.5, -0.5, 1.0), vertex(-0.5, -0.5, 1.0),
vertex(-0.5, 0.5, 1.0), vertex(-0.5, 0.5, 1.0),
@ -202,10 +204,6 @@ fn ram_horn() -> RuleStep {
Tag::Parent(3), Tag::Parent(2), Tag::Body(3), Tag::Parent(3), Tag::Parent(2), Tag::Body(3),
Tag::Body(0), Tag::Parent(3), Tag::Body(3), Tag::Body(0), Tag::Parent(3), Tag::Body(3),
Tag::Parent(0), Tag::Parent(3), Tag::Body(0), Tag::Parent(0), Tag::Parent(3), Tag::Body(0),
// TODO: These are correct once the recursion is already
// going - but they are wrong at the start! Note how I'm
// never using the 'midpoint' vertex from the parent,
// Tag::Parent(8).
], ],
}; };
let final_geom = OpenMesh { let final_geom = OpenMesh {
@ -238,6 +236,8 @@ pub fn main() {
}; };
run_test(Rule::Recurse(cube_thing_rule), 3, "cube_thing"); run_test(Rule::Recurse(cube_thing_rule), 3, "cube_thing");
// this can't work on its own because the resultant OpenMesh still
// has parent references:
//run_test(Rule::Recurse(curve_horn_thing_rule), 100, "curve_horn_thing"); //run_test(Rule::Recurse(curve_horn_thing_rule), 100, "curve_horn_thing");
run_test(Rule::Recurse(curve_horn_start), 100, "curve_horn2"); run_test(Rule::Recurse(curve_horn_start), 100, "curve_horn2");
run_test(Rule::Recurse(ram_horn_start), 200, "ram_horn"); run_test(Rule::Recurse(ram_horn_start), 200, "ram_horn");

View File

@ -84,7 +84,8 @@ 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 { pub fn connect(&self, others: &Vec<(OpenMesh, &Vec<usize>)>) -> OpenMesh {
// 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();

View File

@ -26,6 +26,9 @@ pub struct RuleStep {
// Child rules, paired with the transform that will be applied to // Child rules, paired with the transform that will be applied to
// all of their geometry and parent vertex mappings // all of their geometry and parent vertex mappings
pub children: Vec<(Rule, Mat4, Vec<usize>)>, pub children: Vec<(Rule, Mat4, Vec<usize>)>,
// TODO: Clean this up, perhaps change the tuple to something
// saner.
// TODO: Also, document & rename this more clearly.
} }
impl Rule { impl Rule {
@ -57,21 +60,23 @@ impl Rule {
match self { match self {
Rule::Recurse(f) => { Rule::Recurse(f) => {
let rs: RuleStep = f(); let rs: RuleStep = f();
// TODO: This logic is more or less right, but it
// could perhaps use some un-tupling or something.
// Get sub-geometry (from child rules) and transform it: let subgeom: Vec<(OpenMesh, &Vec<usize>)> = rs.children.iter().map(
let subgeom: Vec<(OpenMesh, Mat4, u32, Vec<usize>)> = rs.children.iter().map(|(subrule, subxform, mapping)| { |(subrule, subxform, vmap)| {
let (m,n) = subrule.to_mesh(iters_left - 1); // Get sub-geometry (still un-transformed):
(m, *subxform, n, mapping.clone()) let (submesh,n) = subrule.to_mesh(iters_left - 1);
}).collect(); // Tally up node count:
nodes += n;
// Tally up node count: let m2 = submesh.transform(*subxform);
subgeom.iter().for_each(|(_,_,n,_)| nodes += n);
let g: Vec<(OpenMesh, Vec<usize>)> = subgeom.iter().map(|(m,x,_,mv)| (m.transform(*x), mv.clone())).collect(); (m2, vmap)
// TODO: Not clone twice }).collect();
// Connect geometry from this rule (not child rules): // Connect geometry from this rule (not child rules):
return (rs.geom.connect(&g), nodes); return (rs.geom.connect(&subgeom), nodes);
} }
Rule::EmptyRule => { Rule::EmptyRule => {
return (prim::empty_mesh(), nodes); return (prim::empty_mesh(), nodes);