Add some more broken code. See scratch.rs for what does work.

This commit is contained in:
Chris Hodapp 2020-03-14 12:10:51 -04:00
parent 4df6b8442c
commit 75025fb79b
4 changed files with 200 additions and 30 deletions

View File

@ -1,3 +1,4 @@
use std::rc::Rc;
use nalgebra::*; use nalgebra::*;
//pub mod examples; //pub mod examples;
@ -5,15 +6,12 @@ use crate::openmesh::{OpenMesh, Tag, Mat4, Vertex, vertex, transform};
use crate::rule::{Rule, RuleEval, Child}; use crate::rule::{Rule, RuleEval, Child};
use crate::prim; use crate::prim;
use crate::util; use crate::util;
use crate::scratch;
fn recurRule<A: Fn () -> RuleEval>(f: A) -> Rule { /*
Rule { #[derive(Copy, Clone)]
eval: Box::new(f),
}
}
struct CurveHorn { struct CurveHorn {
seed: Vec<Vertex>, seed: [Vertex; 4],
id_xform: Mat4, id_xform: Mat4,
flip180: Mat4, flip180: Mat4,
incr: Mat4, incr: Mat4,
@ -21,10 +19,29 @@ struct CurveHorn {
impl CurveHorn { impl CurveHorn {
fn test_thing(&self) {
let f: Box<dyn Fn() -> RuleEval> = Box::new(move || self.do_nothing());
println!("{:p}", f);
}
fn do_nothing(&self) -> RuleEval {
RuleEval {
geom: prim::empty_mesh(),
final_geom: prim::empty_mesh(),
children: vec![
Child {
rule: Rule { eval: Box::new(move || self.do_nothing()) },
xf: self.id_xform,
vmap: vec![0,1,2,3],
},
],
}
}
fn init() -> Rule { fn init() -> Rule {
let y = &Vector3::y_axis(); let y = &Vector3::y_axis();
let c = CurveHorn { let c = CurveHorn {
seed: vec![ seed: [
vertex(-0.5, -0.5, 0.0), vertex(-0.5, -0.5, 0.0),
vertex(-0.5, 0.5, 0.0), vertex(-0.5, 0.5, 0.0),
vertex( 0.5, 0.5, 0.0), vertex( 0.5, 0.5, 0.0),
@ -38,24 +55,24 @@ impl CurveHorn {
Matrix4::new_scaling(0.95) * Matrix4::new_scaling(0.95) *
geometry::Translation3::new(0.0, 0.0, 0.2).to_homogeneous(), geometry::Translation3::new(0.0, 0.0, 0.2).to_homogeneous(),
}; };
recurRule(|| c.start()) Rule { eval: Box::new(move || c.do_nothing()) }
}
} }
fn start(&self) -> RuleEval { fn start(&self) -> RuleEval {
RuleEval { RuleEval {
geom: OpenMesh { geom: OpenMesh {
verts: self.seed.clone(), verts: self.seed.to_vec(),
faces: vec![], faces: vec![],
}, },
final_geom: prim::empty_mesh(), final_geom: prim::empty_mesh(),
children: vec![ children: vec![
Child { Child {
rule: recurRule(|| self.recur()), rule: Rule { eval: Box::new(move || self.recur()) },
xf: self.id_xform, xf: self.id_xform,
vmap: vec![0,1,2,3], vmap: vec![0,1,2,3],
}, },
Child { Child {
rule: recurRule(|| self.recur()), rule: Rule { eval: Box::new(move || self.recur()) },
xf: self.flip180, xf: self.flip180,
vmap: vec![3,2,1,0], vmap: vec![3,2,1,0],
}, },
@ -101,7 +118,7 @@ impl CurveHorn {
final_geom: final_geom, final_geom: final_geom,
children: vec![ children: vec![
Child { Child {
rule: recurRule(|| self.recur()), rule: Rule { eval: Box::new(move || self.recur()) },
xf: self.incr, xf: self.incr,
vmap: vec![0,1,2,3], vmap: vec![0,1,2,3],
}, },
@ -117,7 +134,7 @@ impl CubeThing {
fn init() -> Rule { fn init() -> Rule {
let c = CubeThing {}; let c = CubeThing {};
recurRule(|| c.rec()) Rule { eval: Box::new(|| c.rec()) }
} }
fn rec(&self) -> RuleEval { fn rec(&self) -> RuleEval {
@ -145,7 +162,7 @@ impl CubeThing {
Matrix4::new_scaling(0.5) * Matrix4::new_scaling(0.5) *
geometry::Translation3::new(6.0, 0.0, 0.0).to_homogeneous(); geometry::Translation3::new(6.0, 0.0, 0.0).to_homogeneous();
Child { Child {
rule: recurRule(|| self.rec()), rule: Rule { eval: Box::new(|| self.rec()) },
xf: m, xf: m,
vmap: vec![], vmap: vec![],
} }
@ -166,7 +183,7 @@ impl RamHorn {
fn init() -> Rule { fn init() -> Rule {
let r = RamHorn{}; let r = RamHorn{};
recurRule(|| r.start()) Rule { eval: Box::new(|| r.start()) }
} }
// Conversion from Python & automata_scratch // Conversion from Python & automata_scratch
@ -226,22 +243,22 @@ impl RamHorn {
final_geom: prim::empty_mesh(), final_geom: prim::empty_mesh(),
children: vec![ children: vec![
Child { Child {
rule: recurRule(|| self.ram_horn()), rule: Rule { eval: Box::new(|| self.ram_horn()) },
xf: opening_xform(0.0), xf: opening_xform(0.0),
vmap: vec![5,2,6,8], vmap: vec![5,2,6,8],
}, },
Child { Child {
rule: recurRule(|| self.ram_horn()), rule: Rule { eval: Box::new(|| self.ram_horn()) },
xf: opening_xform(1.0), xf: opening_xform(1.0),
vmap: vec![4,1,5,8], vmap: vec![4,1,5,8],
}, },
Child { Child {
rule: recurRule(|| self.ram_horn()), rule: Rule { eval: Box::new(|| self.ram_horn()) },
xf: opening_xform(2.0), xf: opening_xform(2.0),
vmap: vec![7,0,4,8], vmap: vec![7,0,4,8],
}, },
Child { Child {
rule: recurRule(|| self.ram_horn()), rule: Rule { eval: Box::new(|| self.ram_horn()) },
xf: opening_xform(3.0), xf: opening_xform(3.0),
vmap: vec![6,3,7,8], vmap: vec![6,3,7,8],
}, },
@ -288,7 +305,7 @@ impl RamHorn {
final_geom: final_geom, final_geom: final_geom,
children: vec![ children: vec![
Child { Child {
rule: recurRule(|| self.ram_horn()), rule: Rule { eval: Box::new(|| self.ram_horn()) },
xf: incr, xf: incr,
vmap: vec![0,1,2,3], vmap: vec![0,1,2,3],
}, },
@ -327,7 +344,7 @@ impl Twist {
seed_sub: seed_sub, seed_sub: seed_sub,
subdiv: subdiv, subdiv: subdiv,
}; };
recurRule(|| t.start()) Rule { eval: Box::new(|| t.start()) }
} }
// 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
@ -348,7 +365,7 @@ impl Twist {
let children: Vec<Child> = (0..self.count).map(|i| { let children: Vec<Child> = (0..self.count).map(|i| {
let xf = xform(i); let xf = xform(i);
Child { Child {
rule: recurRule(|| self.recur()), rule: Rule { eval: Box::new(|| self.recur()) },
xf: xf, xf: xf,
vmap: ((n+1)*i..(n+1)*(i+self.count)).collect(), // N.B. vmap: ((n+1)*i..(n+1)*(i+self.count)).collect(), // N.B.
// note n+1, not n. the +1 is for the centroid below // note n+1, not n. the +1 is for the centroid below
@ -392,7 +409,7 @@ impl Twist {
final_geom: OpenMesh { verts: vec![vc], faces }, final_geom: OpenMesh { verts: vec![vc], faces },
children: vec![ children: vec![
Child { Child {
rule: recurRule(|| self.recur()), rule: Rule { eval: Box::new(move || self.recur()) },
xf: incr, xf: incr,
vmap: (0..n).collect(), vmap: (0..n).collect(),
}, },
@ -400,9 +417,11 @@ impl Twist {
} }
} }
} }
*/
pub fn main() { pub fn main() {
/*
{ {
let vs = vec![ let vs = vec![
vertex(-0.5, 0.0, -0.5), vertex(-0.5, 0.0, -0.5),
@ -432,6 +451,7 @@ pub fn main() {
println!("Writing {}...", fname); println!("Writing {}...", fname);
mesh.write_stl_file(&fname).unwrap(); mesh.write_stl_file(&fname).unwrap();
} }
*/
/* /*
run_test(CubeThing::init(), Rule { eval: CubeThing::rec }, 3, "cube_thing"); run_test(CubeThing::init(), Rule { eval: CubeThing::rec }, 3, "cube_thing");
@ -443,15 +463,41 @@ pub fn main() {
run_test(Twist::init(), Rule { eval: Twist::start }, 200, "twist"); run_test(Twist::init(), Rule { eval: Twist::start }, 200, "twist");
*/ */
run_test_iter(CubeThing::init(), 3, "cube_thing2"); //run_test_iter(CubeThing::init(), 3, "cube_thing2");
run_test_iter(CurveHorn::init(), 100, "curve_horn2_iter"); //run_test_iter(CurveHorn::init(), 100, "curve_horn2_iter");
run_test_iter(RamHorn::init(), 100, "ram_horn2"); //run_test_iter(RamHorn::init(), 100, "ram_horn2");
// TODO: If I increase the above from 100 to ~150, Blender reports // TODO: If I increase the above from 100 to ~150, Blender reports
// that the very tips are non-manifold. I am wondering if this is // that the very tips are non-manifold. I am wondering if this is
// some sort of numerical precision issue. // some sort of numerical precision issue.
run_test_iter(Twist::init(1.0, 2), 100, "twist"); //run_test_iter(Twist::init(1.0, 2), 100, "twist");
// This is a stress test: // This is a stress test:
// let f = 20; // let f = 20;
// run_test_iter(Twist::init(f as f32, 32), 100*f, "twist2"); // run_test_iter(Twist::init(f as f32, 32), 100*f, "twist2");
{
let a = vec![1,2,3];
let c = move || {
println!("c: a={:?}", a);
};
let r: Rc<dyn Fn()> = Rc::new(c);
// But this will fail at the function calls below:
//let r: Rc<dyn FnOnce()> = Rc::new(c);
let r2 = r.clone();
println!("strong_count={}", Rc::strong_count(&r2));
println!("weak_count={}", Rc::weak_count(&r2));
r2();
r();
let a2 = vec![1,2,3];
let c2 = move || {
println!("c2: a2={:?}", a2);
};
let b: Box<dyn FnOnce()> = Box::new(c2);
b();
}
} }

View File

@ -1,3 +1,4 @@
pub mod scratch;
pub mod examples; pub mod examples;
pub mod openmesh; pub mod openmesh;
pub mod rule; pub mod rule;

View File

@ -13,6 +13,9 @@ pub struct Rule {
// 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?
// The above looks like it is going to require a lifetime parameter
// regardless, in which case I don't really need Box.
/// `RuleEval` 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

120
src/scratch.rs Normal file
View File

@ -0,0 +1,120 @@
use std::rc::Rc;
/*
struct R<'a> {
b: &'a dyn Fn() -> R<'a>,
}
#[derive(Copy, Clone)]
struct Foo {}
impl<'a> Foo {
// These are valid, but not especially useful (if I am
// transferring ownership then I cannot have any branching):
fn fn1(self) -> R<'a> {
R { b: & move || self.fn1() }
}
fn fn2(self) -> R<'a> {
R { b: &|| self.fn2() }
}
}
*/
// Below (using box instead of a trait object) follows similar rules:
struct S<'a> {
b: Box<dyn Fn() -> S<'a>>,
}
#[derive(Copy, Clone)]
struct Foo2 {}
impl<'a> Foo2 {
fn fn1(self) -> S<'a> {
S { b: Box::new(move || self.fn1()) }
}
// Not valid (error[E0373]: closure may outlive the current
// function, but it borrows `self`, which is owned by the current
// function):
//fn fn2(self) -> S<'a> {
// S { b: Box::new(|| self.fn2()) }
//}
// Not valid:
//fn fn3(&self) -> S<'a> {
// S { b: Box::new(move || self.fn3()) }
//}
// Not valid:
//fn fn4(&self) -> S<'a> {
// S { b: Box::new(|| self.fn4()) }
//}
}
struct T<'a> {
b: Rc<dyn Fn() -> T<'a> + 'a>,
}
#[derive(Copy, Clone)]
struct Foo3 {}
impl<'a> Foo3 {
fn fn1(self) -> T<'a> {
T { b: Rc::new(move || self.fn1()) }
}
// Not valid (E0373):
//fn fn2(self) -> T<'a> {
// T { b: Rc::new(|| self.fn2()) }
//}
// Not valid:
//fn fn3(&self) -> T<'a> {
// T { b: Rc::new(move || self.fn3()) }
//}
// Not valid:
//fn fn4(&self) -> T<'a> {
// T { b: Rc::new(|| self.fn4()) }
//}
// But this is now valid because T can be cloned:
fn fn5(self) -> (T<'a>, T<'a>) {
let p = Rc::new(move || self.fn1());
let p2 = p.clone();
(T { b: p }, T { b: p2 })
}
}
// Further, this is now valid too (lifetimes removed):
struct U {
b: Rc<dyn Fn() -> U>,
}
#[derive(Copy, Clone)]
struct Foo4 {}
impl Foo4 {
fn fn1(self) -> U {
U { b: Rc::new(move || self.fn1()) }
}
fn fn5(self) -> (U, U) {
let p = Rc::new(move || self.fn1());
let p2 = p.clone();
(U { b: p }, U { b: p2 })
}
}
// I can get rid of Copy/Clone if I use FnOnce:
struct V {
b: Rc<dyn FnOnce() -> V>,
}
struct Foo5 {}
impl Foo5 {
fn fn1(self) -> V {
V { b: Rc::new(move || self.fn1()) }
}
fn fn2(self) -> (V, V) {
let p = Rc::new(move || self.fn1());
let p2 = p.clone();
(V { b: p }, V { b: p2 })
}
// and then either kind is fine:
fn fn3(self) -> V {
V { b: Rc::new(|| self.fn3()) }
}
fn fn4(self) -> (V, V) {
let p = Rc::new(|| self.fn3());
let p2 = p.clone();
(V { b: p }, V { b: p2 })
// but this confuses me a bit. doesn't this then let me call
// an FnOnce... more than once?
}
}