Change name of 'vmap' to 'arg_vals' to fit with MeshFunc
This commit is contained in:
parent
ce3ca34b70
commit
b7da8bea41
12
README.md
12
README.md
@ -6,18 +6,8 @@
|
|||||||
transformations so that I'm actually constructing things to be
|
transformations so that I'm actually constructing things to be
|
||||||
correct instead of just throwing shit at the wall.
|
correct instead of just throwing shit at the wall.
|
||||||
See my "Composing Transformations" link in log.org.
|
See my "Composing Transformations" link in log.org.
|
||||||
- My "Barbs" example revealed another pesky limitation: a parent vertex
|
|
||||||
cannot refer to a parent vertex of the parent itself. This came up
|
|
||||||
because I had a rule inheriting 4 vertices (one side of a cube), and
|
|
||||||
creating 4 new vertices (the opposite side of a cube). I wanted its
|
|
||||||
child rules to be able to create faces that had 2 vertices of the
|
|
||||||
parent and 2 vertices that the parent inherited (basically grandparent
|
|
||||||
vertices) - think of one of the remaining 4 sides of the cube. I have
|
|
||||||
no way to do this and no easy workarounds I can see, given that the
|
|
||||||
rule does not have access to the exact vertex positions (so just making
|
|
||||||
new vertices that are 'close' and connecting them isn't an option).
|
|
||||||
- Adaptive subdivision - which means having to generalize past some
|
- Adaptive subdivision - which means having to generalize past some
|
||||||
`vmap` stuff.
|
`arg_vals` stuff.
|
||||||
- Try some non-deterministic examples.
|
- Try some non-deterministic examples.
|
||||||
- Get identical or near-identical meshes to `ramhorn_branch` from
|
- Get identical or near-identical meshes to `ramhorn_branch` from
|
||||||
Python. (Should just be a matter of tweaking parameters.)
|
Python. (Should just be a matter of tweaking parameters.)
|
||||||
|
|||||||
@ -39,7 +39,7 @@ pub fn cube_thing() -> Rule<()> {
|
|||||||
children: xforms.map(move |xf| Child {
|
children: xforms.map(move |xf| Child {
|
||||||
rule: self_.clone(),
|
rule: self_.clone(),
|
||||||
xf: xf,
|
xf: xf,
|
||||||
vmap: vec![],
|
arg_vals: vec![],
|
||||||
}).collect(),
|
}).collect(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -85,7 +85,7 @@ pub fn barbs() -> Rule<()> {
|
|||||||
Child {
|
Child {
|
||||||
rule: self_.clone(),
|
rule: self_.clone(),
|
||||||
xf: barb_incr,
|
xf: barb_incr,
|
||||||
vmap: (0..n).collect(),
|
arg_vals: (0..n).collect(),
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -128,27 +128,27 @@ pub fn barbs() -> Rule<()> {
|
|||||||
Child {
|
Child {
|
||||||
rule: self_.clone(),
|
rule: self_.clone(),
|
||||||
xf: main_incr,
|
xf: main_incr,
|
||||||
vmap: (0..n).collect(),
|
arg_vals: (0..n).collect(),
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: barb_.clone(), ctxt: () }),
|
rule: Rc::new(Rule { eval: barb_.clone(), ctxt: () }),
|
||||||
xf: main_barb_trans(0),
|
xf: main_barb_trans(0),
|
||||||
vmap: vec![b0 + 0, b0 + 1, a0 + 1, a0 + 0],
|
arg_vals: vec![b0 + 0, b0 + 1, a0 + 1, a0 + 0],
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: barb_.clone(), ctxt: () }),
|
rule: Rc::new(Rule { eval: barb_.clone(), ctxt: () }),
|
||||||
xf: main_barb_trans(1),
|
xf: main_barb_trans(1),
|
||||||
vmap: vec![b0 + 1, b0 + 2, a0 + 2, a0 + 1],
|
arg_vals: vec![b0 + 1, b0 + 2, a0 + 2, a0 + 1],
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: barb_.clone(), ctxt: () }),
|
rule: Rc::new(Rule { eval: barb_.clone(), ctxt: () }),
|
||||||
xf: main_barb_trans(2),
|
xf: main_barb_trans(2),
|
||||||
vmap: vec![b0 + 2, b0 + 3, a0 + 3, a0 + 2],
|
arg_vals: vec![b0 + 2, b0 + 3, a0 + 3, a0 + 2],
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: barb_.clone(), ctxt: () }),
|
rule: Rc::new(Rule { eval: barb_.clone(), ctxt: () }),
|
||||||
xf: main_barb_trans(3),
|
xf: main_barb_trans(3),
|
||||||
vmap: vec![b0 + 3, b0 + 0, a0 + 0, a0 + 3],
|
arg_vals: vec![b0 + 3, b0 + 0, a0 + 0, a0 + 3],
|
||||||
},
|
},
|
||||||
// TODO: Factor out repetition
|
// TODO: Factor out repetition
|
||||||
],
|
],
|
||||||
@ -171,7 +171,7 @@ pub fn barbs() -> Rule<()> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: main_.clone(), ctxt: () }),
|
rule: Rc::new(Rule { eval: main_.clone(), ctxt: () }),
|
||||||
xf: Transform::new(),
|
xf: Transform::new(),
|
||||||
vmap: (0..n).collect(),
|
arg_vals: (0..n).collect(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -233,7 +233,7 @@ pub fn twist(f: f32, subdiv: usize) -> Rule<()> {
|
|||||||
Child {
|
Child {
|
||||||
rule: self_.clone(),
|
rule: self_.clone(),
|
||||||
xf: incr,
|
xf: incr,
|
||||||
vmap: (0..n).collect(),
|
arg_vals: (0..n).collect(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -254,7 +254,7 @@ pub fn twist(f: f32, subdiv: usize) -> Rule<()> {
|
|||||||
rule: Rc::new(Rule { eval: (recur.clone())(incr), ctxt: () }),
|
rule: Rc::new(Rule { eval: (recur.clone())(incr), ctxt: () }),
|
||||||
// TODO: Cleanliness fix - can macros clean up above?
|
// TODO: Cleanliness fix - can macros clean up above?
|
||||||
xf: xform,
|
xf: xform,
|
||||||
vmap: (0..(n+1)).collect(),
|
arg_vals: (0..(n+1)).collect(),
|
||||||
// N.B. n+1, not n. the +1 is for the centroid below.
|
// N.B. n+1, not n. the +1 is for the centroid below.
|
||||||
};
|
};
|
||||||
let mut vs = xform.transform(&seed);
|
let mut vs = xform.transform(&seed);
|
||||||
@ -334,7 +334,7 @@ pub fn nest_spiral_2() -> Rule<NestSpiral2Ctxt> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(next_rule),
|
rule: Rc::new(next_rule),
|
||||||
xf: Transform::new(),
|
xf: Transform::new(),
|
||||||
vmap: (0..n2).collect(),
|
arg_vals: (0..n2).collect(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -346,7 +346,7 @@ pub fn nest_spiral_2() -> Rule<NestSpiral2Ctxt> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(next_rule),
|
rule: Rc::new(next_rule),
|
||||||
xf: Transform::new(),
|
xf: Transform::new(),
|
||||||
vmap: (0..n).collect(),
|
arg_vals: (0..n).collect(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -372,7 +372,7 @@ pub fn nest_spiral_2() -> Rule<NestSpiral2Ctxt> {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
xf: Transform::new(),
|
xf: Transform::new(),
|
||||||
vmap: vec![], // no parent vertices
|
arg_vals: vec![], // no parent vertices
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -463,7 +463,7 @@ pub fn twisty_torus() -> Rule<TorusCtxt> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(next_rule),
|
rule: Rc::new(next_rule),
|
||||||
xf: Transform::new(),
|
xf: Transform::new(),
|
||||||
vmap: (0..n2).collect(),
|
arg_vals: (0..n2).collect(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -475,7 +475,7 @@ pub fn twisty_torus() -> Rule<TorusCtxt> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(next_rule),
|
rule: Rc::new(next_rule),
|
||||||
xf: Transform::new(),
|
xf: Transform::new(),
|
||||||
vmap: (0..n).collect(),
|
arg_vals: (0..n).collect(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -538,7 +538,7 @@ pub fn twisty_torus_hardcode() -> Rule<()> {
|
|||||||
Child {
|
Child {
|
||||||
rule: self_.clone(),
|
rule: self_.clone(),
|
||||||
xf: incr,
|
xf: incr,
|
||||||
vmap: (0..n).collect(),
|
arg_vals: (0..n).collect(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -557,7 +557,7 @@ pub fn twisty_torus_hardcode() -> Rule<()> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: Rc::new(recur.clone()), ctxt: () }),
|
rule: Rc::new(Rule { eval: Rc::new(recur.clone()), ctxt: () }),
|
||||||
xf: incr,
|
xf: incr,
|
||||||
vmap: (0..n2).collect(),
|
arg_vals: (0..n2).collect(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -633,7 +633,7 @@ pub fn wind_chime_mistake_thing() -> Rule<WindChimeCtxt> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(next_rule),
|
rule: Rc::new(next_rule),
|
||||||
xf: Transform::new(),
|
xf: Transform::new(),
|
||||||
vmap: (0..n2).collect(),
|
arg_vals: (0..n2).collect(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -645,7 +645,7 @@ pub fn wind_chime_mistake_thing() -> Rule<WindChimeCtxt> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(next_rule),
|
rule: Rc::new(next_rule),
|
||||||
xf: Transform::new(),
|
xf: Transform::new(),
|
||||||
vmap: (0..n).collect(),
|
arg_vals: (0..n).collect(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -712,7 +712,7 @@ pub fn ramhorn() -> Rule<()> {
|
|||||||
Child {
|
Child {
|
||||||
rule: self_.clone(),
|
rule: self_.clone(),
|
||||||
xf: incr,
|
xf: incr,
|
||||||
vmap: vec![0,1,2,3],
|
arg_vals: vec![0,1,2,3],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -779,22 +779,22 @@ pub fn ramhorn() -> Rule<()> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: Rc::new(recur.clone()), ctxt: () }),
|
rule: Rc::new(Rule { eval: Rc::new(recur.clone()), ctxt: () }),
|
||||||
xf: opening_xform(0.0),
|
xf: opening_xform(0.0),
|
||||||
vmap: vec![5,2,6,8],
|
arg_vals: vec![5,2,6,8],
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: Rc::new(recur.clone()), ctxt: () }),
|
rule: Rc::new(Rule { eval: Rc::new(recur.clone()), ctxt: () }),
|
||||||
xf: opening_xform(1.0),
|
xf: opening_xform(1.0),
|
||||||
vmap: vec![4,1,5,8],
|
arg_vals: vec![4,1,5,8],
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: Rc::new(recur.clone()), ctxt: () }),
|
rule: Rc::new(Rule { eval: Rc::new(recur.clone()), ctxt: () }),
|
||||||
xf: opening_xform(2.0),
|
xf: opening_xform(2.0),
|
||||||
vmap: vec![7,0,4,8],
|
arg_vals: vec![7,0,4,8],
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: Rc::new(recur.clone()), ctxt: () }),
|
rule: Rc::new(Rule { eval: Rc::new(recur.clone()), ctxt: () }),
|
||||||
xf: opening_xform(3.0),
|
xf: opening_xform(3.0),
|
||||||
vmap: vec![6,3,7,8],
|
arg_vals: vec![6,3,7,8],
|
||||||
},
|
},
|
||||||
// TODO: These vertex mappings appear to be right.
|
// TODO: These vertex mappings appear to be right.
|
||||||
// Explain *why* they are right.
|
// Explain *why* they are right.
|
||||||
@ -893,22 +893,22 @@ pub fn ramhorn_branch(depth: usize, f: f32) -> Rule<RamHornCtxt> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
||||||
xf: opening_xform(0.0),
|
xf: opening_xform(0.0),
|
||||||
vmap: vec![5,2,6,8],
|
arg_vals: vec![5,2,6,8],
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
||||||
xf: opening_xform(1.0),
|
xf: opening_xform(1.0),
|
||||||
vmap: vec![4,1,5,8],
|
arg_vals: vec![4,1,5,8],
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
||||||
xf: opening_xform(2.0),
|
xf: opening_xform(2.0),
|
||||||
vmap: vec![7,0,4,8],
|
arg_vals: vec![7,0,4,8],
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
||||||
xf: opening_xform(3.0),
|
xf: opening_xform(3.0),
|
||||||
vmap: vec![6,3,7,8],
|
arg_vals: vec![6,3,7,8],
|
||||||
},
|
},
|
||||||
// TODO: These vertex mappings appear to be right.
|
// TODO: These vertex mappings appear to be right.
|
||||||
// Explain *why* they are right.
|
// Explain *why* they are right.
|
||||||
@ -940,7 +940,7 @@ pub fn ramhorn_branch(depth: usize, f: f32) -> Rule<RamHornCtxt> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(next_rule),
|
rule: Rc::new(next_rule),
|
||||||
xf: incr,
|
xf: incr,
|
||||||
vmap: vec![0,1,2,3],
|
arg_vals: vec![0,1,2,3],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -970,7 +970,7 @@ pub fn ramhorn_branch(depth: usize, f: f32) -> Rule<RamHornCtxt> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: Rc::new(trans.clone()), ctxt: self_.ctxt }),
|
rule: Rc::new(Rule { eval: Rc::new(trans.clone()), ctxt: self_.ctxt }),
|
||||||
xf: Transform::new(),
|
xf: Transform::new(),
|
||||||
vmap: vec![0,1,2,3],
|
arg_vals: vec![0,1,2,3],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -1066,22 +1066,22 @@ pub fn ramhorn_branch_random(depth: usize, f: f32) -> Rule<RamHornCtxt2> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
||||||
xf: opening_xform(0.0),
|
xf: opening_xform(0.0),
|
||||||
vmap: vec![5,2,6,8],
|
arg_vals: vec![5,2,6,8],
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
||||||
xf: opening_xform(1.0),
|
xf: opening_xform(1.0),
|
||||||
vmap: vec![4,1,5,8],
|
arg_vals: vec![4,1,5,8],
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
||||||
xf: opening_xform(2.0),
|
xf: opening_xform(2.0),
|
||||||
vmap: vec![7,0,4,8],
|
arg_vals: vec![7,0,4,8],
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
rule: Rc::new(Rule { eval: recur.clone(), ctxt }),
|
||||||
xf: opening_xform(3.0),
|
xf: opening_xform(3.0),
|
||||||
vmap: vec![6,3,7,8],
|
arg_vals: vec![6,3,7,8],
|
||||||
},
|
},
|
||||||
// TODO: These vertex mappings appear to be right.
|
// TODO: These vertex mappings appear to be right.
|
||||||
// Explain *why* they are right.
|
// Explain *why* they are right.
|
||||||
@ -1114,7 +1114,7 @@ pub fn ramhorn_branch_random(depth: usize, f: f32) -> Rule<RamHornCtxt2> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(next_rule),
|
rule: Rc::new(next_rule),
|
||||||
xf: incr,
|
xf: incr,
|
||||||
vmap: vec![0,1,2,3],
|
arg_vals: vec![0,1,2,3],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -1144,7 +1144,7 @@ pub fn ramhorn_branch_random(depth: usize, f: f32) -> Rule<RamHornCtxt2> {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rc::new(Rule { eval: Rc::new(trans.clone()), ctxt: self_.ctxt }),
|
rule: Rc::new(Rule { eval: Rc::new(trans.clone()), ctxt: self_.ctxt }),
|
||||||
xf: Transform::new(),
|
xf: Transform::new(),
|
||||||
vmap: vec![0,1,2,3],
|
arg_vals: vec![0,1,2,3],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -1178,7 +1178,7 @@ impl CurveHorn {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rule { eval: Rc::new(move || self.do_nothing()) },
|
rule: Rule { eval: Rc::new(move || self.do_nothing()) },
|
||||||
xf: self.id_xform,
|
xf: self.id_xform,
|
||||||
vmap: vec![0,1,2,3],
|
arg_vals: vec![0,1,2,3],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -1215,12 +1215,12 @@ impl CurveHorn {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rule { eval: Rc::new(move || self.recur()) },
|
rule: Rule { eval: Rc::new(move || self.recur()) },
|
||||||
xf: self.id_xform,
|
xf: self.id_xform,
|
||||||
vmap: vec![0,1,2,3],
|
arg_vals: vec![0,1,2,3],
|
||||||
},
|
},
|
||||||
Child {
|
Child {
|
||||||
rule: Rule { eval: Rc::new(move || self.recur()) },
|
rule: Rule { eval: Rc::new(move || self.recur()) },
|
||||||
xf: self.flip180,
|
xf: self.flip180,
|
||||||
vmap: vec![3,2,1,0],
|
arg_vals: vec![3,2,1,0],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -1266,7 +1266,7 @@ impl CurveHorn {
|
|||||||
Child {
|
Child {
|
||||||
rule: Rule { eval: Rc::new(move || self.recur()) },
|
rule: Rule { eval: Rc::new(move || self.recur()) },
|
||||||
xf: self.incr,
|
xf: self.incr,
|
||||||
vmap: vec![0,1,2,3],
|
arg_vals: vec![0,1,2,3],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/mesh.rs
17
src/mesh.rs
@ -74,8 +74,11 @@ impl Mesh {
|
|||||||
pub enum VertexUnion {
|
pub enum VertexUnion {
|
||||||
/// A concrete vertex.
|
/// A concrete vertex.
|
||||||
Vertex(Vertex),
|
Vertex(Vertex),
|
||||||
/// An 'unbound' vertex - something like an argument to a function with
|
/// A vertex argument - something like an argument to a function with
|
||||||
/// the given positional index.
|
/// the given positional index.
|
||||||
|
///
|
||||||
|
/// The job of `MeshFunc.connect` is to bind these arguments to concrete
|
||||||
|
/// vertices.
|
||||||
Arg(usize),
|
Arg(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,13 +158,15 @@ impl MeshFunc {
|
|||||||
|
|
||||||
/// Treat this mesh as a 'parent' mesh to connect with any number
|
/// Treat this mesh as a 'parent' mesh to connect with any number
|
||||||
/// of 'child' meshes, all of them paired with their respective
|
/// of 'child' meshes, all of them paired with their respective
|
||||||
/// parent vertex mappings. This returns a tuple of (new mesh,
|
/// vertex argument values (i.e. `arg_vals` from `Child`).
|
||||||
/// offsets), where 'offsets' gives the offset of where child
|
/// This returns a tuple of (new mesh, offsets), where 'offsets'
|
||||||
/// meshes were shifted in the new mesh.
|
/// gives the offset of where child meshes were shifted in the new
|
||||||
|
/// mesh.
|
||||||
///
|
///
|
||||||
/// 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 order to adjust
|
||||||
/// adjusting a parent vertex mapping, like 'vmap' of Rule::Child.
|
/// references to vertices of a mesh in 'children' - such as
|
||||||
|
/// 'arg_vals' of `rule::Child`.
|
||||||
pub fn connect<T, U>(&self, children: T) -> (MeshFunc, Vec<usize>)
|
pub fn connect<T, U>(&self, children: T) -> (MeshFunc, Vec<usize>)
|
||||||
where U: Borrow<MeshFunc>,
|
where U: Borrow<MeshFunc>,
|
||||||
T: IntoIterator<Item = (U, Vec<usize>)>
|
T: IntoIterator<Item = (U, Vec<usize>)>
|
||||||
|
|||||||
55
src/rule.rs
55
src/rule.rs
@ -46,6 +46,8 @@ 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.
|
||||||
|
/// (TODO: Does this make sense? Nowhere else do I treat Arg(n) as
|
||||||
|
/// an index - it's always a positional argument.)
|
||||||
pub final_geom: Rc<MeshFunc>,
|
pub final_geom: Rc<MeshFunc>,
|
||||||
|
|
||||||
/// The child invocations (used if recursion continues). The
|
/// The child invocations (used if recursion continues). The
|
||||||
@ -67,12 +69,15 @@ pub struct Child<S> {
|
|||||||
/// as all sub-geometry produced recursively).
|
/// as all sub-geometry produced recursively).
|
||||||
pub xf: Transform,
|
pub xf: Transform,
|
||||||
|
|
||||||
/// The parent vertex mapping: a mapping to apply to turn a
|
/// The 'argument values' to apply to vertex arguments of a `MeshFunc`
|
||||||
/// Tag::Parent vertex reference into a vertex index of the parent
|
/// from `geom` and `final_geom` that `rule` produces when evaluated.
|
||||||
/// mesh. That is, if `rule` produces a `MeshFunc` with a face
|
/// The values of this are treated as indices into the parent
|
||||||
/// of `Tag::Parent(n)`, this will correspond to index `vmap[n]`
|
/// `RuleEval` that produced this `Child`.
|
||||||
/// in the parent mesh.
|
///
|
||||||
pub vmap: Vec<usize>,
|
/// In specific: if `arg_vals[i] = j` and `rule` produces some `geom` or
|
||||||
|
/// `final_geom`, then any vertex of `VertexUnion::Arg(i)` will be mapped
|
||||||
|
/// to `geom.verts[j]` in the *parent* geometry.
|
||||||
|
pub arg_vals: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Rule<S> {
|
impl<S> Rule<S> {
|
||||||
@ -88,7 +93,7 @@ impl<S> Rule<S> {
|
|||||||
if iters_left <= 0 {
|
if iters_left <= 0 {
|
||||||
return ((*rs.final_geom).clone(), 1);
|
return ((*rs.final_geom).clone(), 1);
|
||||||
// TODO: This is probably wrong because of the way that
|
// TODO: This is probably wrong because of the way that
|
||||||
// sub.vmap is used below. final_geom is not supposed to
|
// sub.arg_vals is used below. final_geom is not supposed to
|
||||||
// have any vertex mapping applied.
|
// have any vertex mapping applied.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +108,7 @@ impl<S> Rule<S> {
|
|||||||
|
|
||||||
let m2 = submesh.transform(&sub.xf);
|
let m2 = submesh.transform(&sub.xf);
|
||||||
|
|
||||||
(m2, sub.vmap.clone())
|
(m2, sub.arg_vals.clone())
|
||||||
// TODO: Fix clone?
|
// TODO: Fix clone?
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
@ -181,8 +186,8 @@ impl<S> Rule<S> {
|
|||||||
// geometry properly:
|
// geometry properly:
|
||||||
let final_geom = eval.final_geom.transform(&xf);
|
let final_geom = eval.final_geom.transform(&xf);
|
||||||
// TODO: Fix the awful hack below. I do this only to
|
// TODO: Fix the awful hack below. I do this only to
|
||||||
// generate an identity mapping for vmap when I don't
|
// generate an identity mapping for arg_vals when I don't
|
||||||
// actually need vmap.
|
// actually need arg_vals.
|
||||||
let m = {
|
let m = {
|
||||||
let mut m_ = 0;
|
let mut m_ = 0;
|
||||||
for v in &final_geom.verts {
|
for v in &final_geom.verts {
|
||||||
@ -197,10 +202,10 @@ impl<S> Rule<S> {
|
|||||||
}
|
}
|
||||||
m_ + 1
|
m_ + 1
|
||||||
};
|
};
|
||||||
let vmap: Vec<usize> = (0..m).collect();
|
let arg_vals: Vec<usize> = (0..m).collect();
|
||||||
let (geom2, _) = new_geom.connect(vec![(final_geom, vmap)]);
|
let (geom2, _) = new_geom.connect(vec![(final_geom, arg_vals)]);
|
||||||
|
|
||||||
geom = geom.connect(vec![(geom2, child.vmap.clone())]).0;
|
geom = geom.connect(vec![(geom2, child.arg_vals.clone())]).0;
|
||||||
// TODO: Fix clone?
|
// TODO: Fix clone?
|
||||||
|
|
||||||
// If we end recursion on one child, we must end it
|
// If we end recursion on one child, we must end it
|
||||||
@ -216,23 +221,19 @@ impl<S> Rule<S> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (g, offsets) = geom.connect(vec![(new_geom, child.vmap.clone())]);
|
let (g, offsets) = geom.connect(vec![(new_geom, child.arg_vals.clone())]);
|
||||||
geom = g;
|
geom = g;
|
||||||
|
|
||||||
// 'new_geom' may itself be parent geometry for
|
// 'eval.children' may contain (via 'arg_vals') references to
|
||||||
// 'eval.children' (via Tag::Parent), and vmap is there to
|
// indices of 'new_geom'. However, we don't connect() to
|
||||||
// resolve Tag::Parent references to the right vertices in
|
// 'new_geom', but to the global geometry we just merged it
|
||||||
// 'new_geom'.
|
// into. To account for this, we must shift 'arg_vals' by
|
||||||
//
|
// the offset that 'geom.connect' gave us.
|
||||||
// However, we connect() on the global geometry which we
|
|
||||||
// merged 'new_geom' into, not 'new_geom' directly. To
|
|
||||||
// account for this, we must shift vmap by the offset that
|
|
||||||
// 'geom.connect' gave us:
|
|
||||||
let off = offsets[0];
|
let off = offsets[0];
|
||||||
// (We pass a one-element vector to geom.connect() above
|
// (We pass a one-element vector to geom.connect() above
|
||||||
// so offsets always has just one element.)
|
// so offsets always has just one element.)
|
||||||
for child in eval.children.iter_mut() {
|
for child in eval.children.iter_mut() {
|
||||||
child.vmap = child.vmap.iter().map(|n| n + off).collect();
|
child.arg_vals = child.arg_vals.iter().map(|n| n + off).collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're done evaluating this rule, so increment 'next'.
|
// We're done evaluating this rule, so increment 'next'.
|
||||||
@ -263,7 +264,7 @@ impl<S> Rule<S> {
|
|||||||
|
|
||||||
impl<S> RuleEval<S> {
|
impl<S> RuleEval<S> {
|
||||||
/// Turn an iterator of (MeshFunc, 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 `arg_vals` 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.)
|
||||||
@ -274,13 +275,13 @@ impl<S> RuleEval<S> {
|
|||||||
let (meshes, children): (Vec<_>, Vec<_>) = m.into_iter().unzip();
|
let (meshes, children): (Vec<_>, Vec<_>) = m.into_iter().unzip();
|
||||||
let (mesh, offsets) = MeshFunc::append(meshes);
|
let (mesh, offsets) = MeshFunc::append(meshes);
|
||||||
|
|
||||||
// Patch up vmap in each child, and copy everything else:
|
// Patch up arg_vals 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)| {
|
||||||
Child {
|
Child {
|
||||||
rule: c.rule.clone(),
|
rule: c.rule.clone(),
|
||||||
xf: c.xf.clone(),
|
xf: c.xf.clone(),
|
||||||
// simply add offset:
|
// simply add offset:
|
||||||
vmap: c.vmap.iter().map(|i| i + off).collect(),
|
arg_vals: c.arg_vals.iter().map(|i| i + off).collect(),
|
||||||
}
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user