Fixed the bug for real. I think. Still needs cleanup...

This commit is contained in:
Chris Hodapp 2020-10-03 10:04:12 -04:00
parent 0f3c550726
commit bd7a3fdd58
2 changed files with 19 additions and 19 deletions

View File

@ -155,15 +155,11 @@ 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
/// vertex argument values (i.e. `arg_vals` from `Child`). /// vertex argument values (i.e. `arg_vals` from `Child`).
/// This returns a tuple of (new mesh, offsets), where 'offsets' /// This returns a tuple of (new mesh, new `arg_vals`), where
/// gives the offset of where child meshes were shifted in the new /// `arg_vals[i]` gives the remapped value of `children[i].arg_vals`
/// mesh. /// which accounts for where the referenced vertices were moved to.
/// /// (TODO: That definition is wrong; explain it right.)
/// That is, the vertices of 'children[i]' begin at vertex pub fn connect<T, U>(&self, children: T) -> (MeshFunc, Vec<Vec<usize>>)
/// 'offset[i]' of the new mesh. This is needed in order to adjust
/// 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>)
where U: Borrow<MeshFunc>, where U: Borrow<MeshFunc>,
T: IntoIterator<Item=(U, Vec<usize>)> T: IntoIterator<Item=(U, Vec<usize>)>
{ {
@ -174,7 +170,7 @@ impl MeshFunc {
let mut verts: Vec<VertexUnion> = self.verts.clone(); let mut verts: Vec<VertexUnion> = self.verts.clone();
let mut faces = self.faces.clone(); let mut faces = self.faces.clone();
let mut offsets: Vec<usize> = vec![]; let mut offsets: Vec<Vec<usize>> = vec![];
println!("DEBUG: start verts={:?}", verts); println!("DEBUG: start verts={:?}", verts);
@ -193,6 +189,7 @@ impl MeshFunc {
verts.extend(child.verts.iter().enumerate().filter_map(|(i,v)| { verts.extend(child.verts.iter().enumerate().filter_map(|(i,v)| {
match v { match v {
VertexUnion::Vertex(_) => { VertexUnion::Vertex(_) => {
println!("placing child vert {} at {}", i, offset + j);
remap[i] = j; remap[i] = j;
j += 1; j += 1;
Some(v.clone()) Some(v.clone())
@ -222,7 +219,7 @@ impl MeshFunc {
println!("DEBUG: offset={} mapping={:?}", offset, mapping); println!("DEBUG: offset={} mapping={:?}", offset, mapping);
println!("DEBUG: remap={:?}", remap); println!("DEBUG: remap={:?}", remap);
// All faces need copied, but if if the index was to // All faces need copied, but if the index was to
// a concrete vertex, then it needs shifted by 'offset'; // a concrete vertex, then it needs shifted by 'offset';
// if an argument, it needs remapped. // if an argument, it needs remapped.
faces.extend(child.faces.iter().enumerate().map(|(i,n)| { faces.extend(child.faces.iter().enumerate().map(|(i,n)| {
@ -230,14 +227,15 @@ impl MeshFunc {
VertexUnion::Vertex(_) => remap[*n] + offset, VertexUnion::Vertex(_) => remap[*n] + offset,
VertexUnion::Arg(m) => mapping[m], VertexUnion::Arg(m) => mapping[m],
}; };
println!("face at i={} (n={}): new f={}, {} verts; vert={:?}", i, n, f, verts.len(), child.verts[*n]); println!("face at i={} (n={}): new f={}, {} verts; vert={:?} -> {:?}", i, n, f, verts.len(), child.verts[*n], verts[f]);
if f >= verts.len() { if f >= verts.len() {
panic!("face >= num_verts") panic!("face >= num_verts")
} }
f f
})); }));
offsets.push(offset); let o2 = remap.iter().map(|n| n + offset).collect();
offsets.push(o2);
} }
let m = MeshFunc { let m = MeshFunc {

View File

@ -271,19 +271,21 @@ impl<S> Rule<S> {
continue; continue;
} }
let (g, offsets) = geom.connect(vec![(new_geom, child.arg_vals.clone())]); let (g, remaps) = geom.connect(vec![(new_geom, child.arg_vals.clone())]);
geom = g; geom = g;
// 'eval.children' may contain (via 'arg_vals') references to // 'eval.children' may contain (via 'arg_vals') references to
// indices of 'new_geom'. However, we don't connect() to // indices of 'new_geom'. However, we don't connect() to
// 'new_geom', but to the global geometry we just merged it // 'new_geom', but to the global geometry we just merged it
// into. To account for this, we must shift 'arg_vals' by // into. To account for this, we must remap 'arg_vals' by the
// the offset that 'geom.connect' gave us. // mapping connect() gave us:
let off = offsets[0]; let remap = &remaps[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 remaps always has just one element.)
for child in eval.children.iter_mut() { for child in eval.children.iter_mut() {
child.arg_vals = child.arg_vals.iter().map(|n| n + off).collect(); println!("DEBUG: got shifting child.arg_vals={:?}", child.arg_vals);
child.arg_vals = child.arg_vals.iter().map(|n| remap[*n]).collect();
println!("DEBUG: new child.arg_vals={:?}", child.arg_vals);
} }
// We're done evaluating this rule, so increment 'next'. // We're done evaluating this rule, so increment 'next'.