Scratch work
This commit is contained in:
parent
4c626f6358
commit
2dd056ad4a
@ -2,7 +2,7 @@ use nalgebra::*;
|
|||||||
//pub mod examples;
|
//pub mod examples;
|
||||||
|
|
||||||
use crate::openmesh::{OpenMesh, Tag, Mat4, Vertex, vertex};
|
use crate::openmesh::{OpenMesh, Tag, Mat4, Vertex, vertex};
|
||||||
use crate::rule::{Rule, RuleStep, Child};
|
use crate::rule::{Rule, RuleEval, Child};
|
||||||
use crate::prim;
|
use crate::prim;
|
||||||
use crate::util;
|
use crate::util;
|
||||||
|
|
||||||
@ -34,8 +34,8 @@ impl CurveHorn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> RuleStep<Self> {
|
fn start(&self) -> RuleEval<Self> {
|
||||||
RuleStep {
|
RuleEval {
|
||||||
geom: OpenMesh {
|
geom: OpenMesh {
|
||||||
verts: self.seed.clone(),
|
verts: self.seed.clone(),
|
||||||
faces: vec![],
|
faces: vec![],
|
||||||
@ -56,7 +56,7 @@ impl CurveHorn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recur(&self) -> RuleStep<Self> {
|
fn recur(&self) -> RuleEval<Self> {
|
||||||
|
|
||||||
let verts = self.seed.clone();
|
let verts = self.seed.clone();
|
||||||
let next_verts: Vec<Vertex> = verts.iter().map(|v| self.incr * v).collect();
|
let next_verts: Vec<Vertex> = verts.iter().map(|v| self.incr * v).collect();
|
||||||
@ -89,7 +89,7 @@ impl CurveHorn {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
RuleStep{
|
RuleEval{
|
||||||
geom: geom,
|
geom: geom,
|
||||||
final_geom: final_geom,
|
final_geom: final_geom,
|
||||||
children: vec![
|
children: vec![
|
||||||
@ -112,7 +112,7 @@ impl CubeThing {
|
|||||||
CubeThing {}
|
CubeThing {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rec(&self) -> RuleStep<Self> {
|
fn rec(&self) -> RuleEval<Self> {
|
||||||
|
|
||||||
let mesh = prim::cube();
|
let mesh = prim::cube();
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ impl CubeThing {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
RuleStep {
|
RuleEval {
|
||||||
geom: mesh,
|
geom: mesh,
|
||||||
final_geom: prim::empty_mesh(),
|
final_geom: prim::empty_mesh(),
|
||||||
children: turns.iter().map(gen_rulestep).collect(),
|
children: turns.iter().map(gen_rulestep).collect(),
|
||||||
@ -161,7 +161,7 @@ impl RamHorn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Conversion from Python & automata_scratch
|
// Conversion from Python & automata_scratch
|
||||||
fn start(&self) -> RuleStep<Self> {
|
fn start(&self) -> RuleEval<Self> {
|
||||||
let opening_xform = |i| {
|
let opening_xform = |i| {
|
||||||
let r = std::f32::consts::FRAC_PI_2 * i;
|
let r = std::f32::consts::FRAC_PI_2 * i;
|
||||||
((geometry::Rotation3::from_axis_angle(
|
((geometry::Rotation3::from_axis_angle(
|
||||||
@ -170,7 +170,7 @@ impl RamHorn {
|
|||||||
Matrix4::new_scaling(0.5) *
|
Matrix4::new_scaling(0.5) *
|
||||||
geometry::Translation3::new(0.0, 0.0, -1.0).to_homogeneous())
|
geometry::Translation3::new(0.0, 0.0, -1.0).to_homogeneous())
|
||||||
};
|
};
|
||||||
RuleStep {
|
RuleEval {
|
||||||
geom: OpenMesh {
|
geom: OpenMesh {
|
||||||
verts: vec![
|
verts: vec![
|
||||||
// 'Top' vertices:
|
// 'Top' vertices:
|
||||||
@ -242,7 +242,7 @@ impl RamHorn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ram_horn(&self) -> RuleStep<Self> {
|
fn ram_horn(&self) -> RuleEval<Self> {
|
||||||
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 = geometry::Translation3::new(0.0, 0.0, 0.8).to_homogeneous() *
|
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() *
|
||||||
@ -274,7 +274,7 @@ impl RamHorn {
|
|||||||
Tag::Parent(0), Tag::Parent(3), Tag::Parent(2),
|
Tag::Parent(0), Tag::Parent(3), Tag::Parent(2),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
RuleStep {
|
RuleEval {
|
||||||
geom: geom,
|
geom: geom,
|
||||||
final_geom: final_geom,
|
final_geom: final_geom,
|
||||||
children: vec![
|
children: vec![
|
||||||
@ -321,7 +321,7 @@ impl Twist {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Meant to be a copy of twist_from_gen from Python & automata_scratch
|
// Meant to be a copy of twist_from_gen from Python & automata_scratch
|
||||||
pub fn start(&self) -> RuleStep<Twist> {
|
pub fn start(&self) -> RuleEval<Twist> {
|
||||||
|
|
||||||
let n = self.seed.len();
|
let n = self.seed.len();
|
||||||
|
|
||||||
@ -351,7 +351,7 @@ impl Twist {
|
|||||||
verts.extend(self.seed_sub.iter().map(|v| child.xf * v));
|
verts.extend(self.seed_sub.iter().map(|v| child.xf * v));
|
||||||
}
|
}
|
||||||
|
|
||||||
RuleStep {
|
RuleEval {
|
||||||
geom: OpenMesh {
|
geom: OpenMesh {
|
||||||
verts: verts,
|
verts: verts,
|
||||||
faces: vec![],
|
faces: vec![],
|
||||||
@ -362,7 +362,7 @@ impl Twist {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recur(&self) -> RuleStep<Twist> {
|
pub fn recur(&self) -> RuleEval<Twist> {
|
||||||
let y = &Vector3::y_axis();
|
let y = &Vector3::y_axis();
|
||||||
let incr = geometry::Translation3::new(-self.dx0, 0.0, 0.0).to_homogeneous() *
|
let incr = geometry::Translation3::new(-self.dx0, 0.0, 0.0).to_homogeneous() *
|
||||||
geometry::Rotation3::from_axis_angle(y, self.ang).to_homogeneous() *
|
geometry::Rotation3::from_axis_angle(y, self.ang).to_homogeneous() *
|
||||||
@ -372,7 +372,7 @@ impl Twist {
|
|||||||
let seed_sub = util::subdivide_cycle(&seed_orig, self.subdiv);
|
let seed_sub = util::subdivide_cycle(&seed_orig, self.subdiv);
|
||||||
let n = seed_sub.len();
|
let n = seed_sub.len();
|
||||||
|
|
||||||
RuleStep {
|
RuleEval {
|
||||||
geom: OpenMesh {
|
geom: OpenMesh {
|
||||||
verts: seed_sub,
|
verts: seed_sub,
|
||||||
faces: util::parallel_zigzag_faces(n),
|
faces: util::parallel_zigzag_faces(n),
|
||||||
|
|||||||
108
src/rule.rs
108
src/rule.rs
@ -8,7 +8,7 @@ use crate::prim;
|
|||||||
/// geometry
|
/// geometry
|
||||||
pub enum Rule<A> {
|
pub enum Rule<A> {
|
||||||
/// Produce some geometry, and possibly recurse further.
|
/// Produce some geometry, and possibly recurse further.
|
||||||
Recurse(fn (&A) -> RuleStep<A>),
|
Recurse(fn (&A) -> RuleEval<A>),
|
||||||
/// Produce nothing and recurse no further.
|
/// Produce nothing and recurse no further.
|
||||||
EmptyRule,
|
EmptyRule,
|
||||||
}
|
}
|
||||||
@ -17,7 +17,7 @@ pub enum Rule<A> {
|
|||||||
// no function call.
|
// no function call.
|
||||||
// TODO: Do I benefit with Rc<Rule> below so Rule can be shared?
|
// TODO: Do I benefit with Rc<Rule> below so Rule can be shared?
|
||||||
|
|
||||||
/// `RuleStep` supplies the results of evaluating some `Rule` for one
|
/// `RuleEval` supplies the results of evaluating some `Rule` for one
|
||||||
/// iteration: it contains the geometry produced at this step
|
/// iteration: it contains the geometry produced at this step
|
||||||
/// (`geom`), and it tells what to do next depending on whether
|
/// (`geom`), and it tells what to do next depending on whether
|
||||||
/// recursion continues further, or is stopped here (due to hitting
|
/// recursion continues further, or is stopped here (due to hitting
|
||||||
@ -28,7 +28,7 @@ pub enum Rule<A> {
|
|||||||
/// - if recursion continues, the rules of `children` are evaluated,
|
/// - if recursion continues, the rules of `children` are evaluated,
|
||||||
/// and the resultant geometry is transformed and then connected with
|
/// and the resultant geometry is transformed and then connected with
|
||||||
/// `geom`.
|
/// `geom`.
|
||||||
pub struct RuleStep<A> {
|
pub struct RuleEval<A> {
|
||||||
/// The geometry generated at just this iteration
|
/// The geometry generated at just this iteration
|
||||||
pub geom: OpenMesh,
|
pub geom: OpenMesh,
|
||||||
|
|
||||||
@ -77,9 +77,9 @@ impl<A> Rule<A> {
|
|||||||
// rather than repeatedly transforming meshes, it stacks
|
// rather than repeatedly transforming meshes, it stacks
|
||||||
// transformations and then applies them all at once.
|
// transformations and then applies them all at once.
|
||||||
|
|
||||||
/// Convert this `Rule` to mesh data, recursively. `iters_left`
|
/// Convert this `Rule` to mesh data, recursively (depth first).
|
||||||
/// sets the maximum recursion depth. This returns (geometry,
|
/// `iters_left` sets the maximum recursion depth. This returns
|
||||||
/// number of rule evaluations).
|
/// (geometry, number of rule evaluations).
|
||||||
pub fn to_mesh(&self, arg: &A, iters_left: u32) -> (OpenMesh, u32) {
|
pub fn to_mesh(&self, arg: &A, iters_left: u32) -> (OpenMesh, u32) {
|
||||||
|
|
||||||
let mut evals: u32 = 1;
|
let mut evals: u32 = 1;
|
||||||
@ -87,7 +87,7 @@ impl<A> Rule<A> {
|
|||||||
if iters_left <= 0 {
|
if iters_left <= 0 {
|
||||||
match self {
|
match self {
|
||||||
Rule::Recurse(f) => {
|
Rule::Recurse(f) => {
|
||||||
let rs: RuleStep<A> = f(arg);
|
let rs: RuleEval<A> = f(arg);
|
||||||
return (rs.final_geom, 1);
|
return (rs.final_geom, 1);
|
||||||
}
|
}
|
||||||
Rule::EmptyRule => {
|
Rule::EmptyRule => {
|
||||||
@ -98,7 +98,7 @@ impl<A> Rule<A> {
|
|||||||
|
|
||||||
match self {
|
match self {
|
||||||
Rule::Recurse(f) => {
|
Rule::Recurse(f) => {
|
||||||
let rs: RuleStep<A> = f(arg);
|
let rs: RuleEval<A> = f(arg);
|
||||||
// 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.
|
||||||
|
|
||||||
@ -121,4 +121,96 @@ impl<A> Rule<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_mesh_iter(&self, arg: &A, max_depth: usize) -> (OpenMesh, u32) {
|
||||||
|
|
||||||
|
let mut geom = prim::empty_mesh();
|
||||||
|
let mut stack: Vec<(RuleEval<A>, usize)> = vec![];
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Rule::Recurse(f) => stack.push((f(arg), 0)),
|
||||||
|
Rule::EmptyRule => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let n = stack.len(); // TODO: Just keep a running total.
|
||||||
|
// We can increment/decrement as we push/pop.
|
||||||
|
let (eval, idx) = stack[n-1];
|
||||||
|
// note that:
|
||||||
|
// stack[n-2].children[idx] = eval (so to speak)
|
||||||
|
|
||||||
|
// I can't do the above. I can either...
|
||||||
|
// - Implement Copy for RuleEval.
|
||||||
|
// - push/pop all over the place and deal with the Option
|
||||||
|
// unpacking and the extra state-changes.
|
||||||
|
// - use something nicer than RuleEval?
|
||||||
|
|
||||||
|
// I can't borrow it because a mutable borrow is already
|
||||||
|
// done with the pop?
|
||||||
|
|
||||||
|
// I don't need to share geometry. I use geometry only
|
||||||
|
// once (though I may need to be careful on the rules with
|
||||||
|
// final_geom), though that's not yet implemented.
|
||||||
|
|
||||||
|
// Deriving automatically puts the Copy constraint on A,
|
||||||
|
// and I am not sure I want to deal with that - but I have
|
||||||
|
// to be able to copy Child regardless, thus Rule.
|
||||||
|
|
||||||
|
// Function pointers support Copy, so Rule is fine.
|
||||||
|
// Vectors by design do *not*.
|
||||||
|
|
||||||
|
// Seems a little bizarre that none of this affects
|
||||||
|
// recursive to_mesh... what am I doing differently?
|
||||||
|
|
||||||
|
// See if it is time to backtrack:
|
||||||
|
if n > max_depth || eval.children.is_empty() {
|
||||||
|
// This has no parents:
|
||||||
|
if n < 2 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backtrack:
|
||||||
|
stack.pop();
|
||||||
|
// TODO: Pop transform off of stack
|
||||||
|
|
||||||
|
// If possible, step to the next sibling:
|
||||||
|
let (parent, _) = &stack[n-2];
|
||||||
|
if (idx + 1) < parent.children.len() {
|
||||||
|
let sib = parent.children[idx + 1];
|
||||||
|
match sib.rule {
|
||||||
|
Rule::Recurse(f) => {
|
||||||
|
let eval_sib = f(arg);
|
||||||
|
stack.push((eval_sib, idx + 1));
|
||||||
|
// TODO: Push transform onto stack
|
||||||
|
// TODO: Append geometry
|
||||||
|
},
|
||||||
|
Rule::EmptyRule => {
|
||||||
|
// Nowhere to recurse further
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// Otherwise, try to recurse to first child:
|
||||||
|
let child = eval.children[0];
|
||||||
|
match child.rule {
|
||||||
|
Rule::Recurse(f) => {
|
||||||
|
let eval_child = f(arg);
|
||||||
|
stack.push((eval_child, 0));
|
||||||
|
// TODO: Push transform onto stack
|
||||||
|
// TODO: Append geometry
|
||||||
|
}
|
||||||
|
Rule::EmptyRule => {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Return right number
|
||||||
|
return (geom, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::openmesh::{OpenMesh, Tag, Mat4, Vertex, vertex};
|
use crate::openmesh::{Tag, Vertex};
|
||||||
use crate::rule::{Rule, RuleStep, Child};
|
//use crate::rule::{Rule, Child};
|
||||||
|
|
||||||
/// 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'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user