Add some more broken code. See scratch.rs for what does work.
This commit is contained in:
parent
4df6b8442c
commit
75025fb79b
104
src/examples.rs
104
src/examples.rs
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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
120
src/scratch.rs
Normal 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?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user