Twist: closed beginning & end properly.
Yes, it checks out as a manifold mesh too.
This commit is contained in:
parent
84b7bd0b21
commit
9746adf39c
@ -303,12 +303,13 @@ impl Twist {
|
||||
|
||||
pub fn init() -> (Twist, Rule<Twist>) {
|
||||
let subdiv = 2;
|
||||
let xf = geometry::Rotation3::from_axis_angle(&Vector3::x_axis(), -0.7).to_homogeneous();
|
||||
let seed = vec![
|
||||
vertex(-0.5, 0.0, -0.5),
|
||||
vertex( 0.5, 0.0, -0.5),
|
||||
vertex( 0.5, 0.0, 0.5),
|
||||
vertex(-0.5, 0.0, 0.5),
|
||||
];
|
||||
].iter().map(|v| xf * v).collect();
|
||||
let seed_sub = util::subdivide_cycle(&seed, subdiv);
|
||||
let t = Twist {
|
||||
dx0: 2.0,
|
||||
@ -342,23 +343,23 @@ impl Twist {
|
||||
Child {
|
||||
rule: Rule { eval: Self::recur },
|
||||
xf: xf,
|
||||
vmap: (n*i..n*(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
|
||||
}
|
||||
}).collect();
|
||||
|
||||
// Use byproducts of this to make 'count' copies of 'seed' with
|
||||
// this same transform:
|
||||
let mut verts = vec![];
|
||||
for child in &children {
|
||||
verts.extend(self.seed_sub.iter().map(|v| child.xf * v));
|
||||
}
|
||||
let meshes = children.iter().map(|child| {
|
||||
let mut vs = self.seed_sub.iter().map(|v| child.xf * v).collect();
|
||||
// and in the process, generate faces for these seeds:
|
||||
let (centroid, f) = util::connect_convex(&vs, false);
|
||||
vs.push(centroid);
|
||||
OpenMesh { verts: vs, faces: f }
|
||||
});
|
||||
|
||||
RuleEval {
|
||||
geom: OpenMesh {
|
||||
verts: verts,
|
||||
faces: vec![],
|
||||
// TODO: Close these initial faces off
|
||||
},
|
||||
geom: OpenMesh::append(meshes),
|
||||
final_geom: prim::empty_mesh(),
|
||||
children: children,
|
||||
}
|
||||
@ -374,12 +375,14 @@ impl Twist {
|
||||
let seed_sub = util::subdivide_cycle(&seed_orig, self.subdiv);
|
||||
let n = seed_sub.len();
|
||||
|
||||
let (vc, faces) = util::connect_convex(&seed_sub, true);
|
||||
|
||||
RuleEval {
|
||||
geom: OpenMesh {
|
||||
verts: seed_sub,
|
||||
faces: util::parallel_zigzag_faces(n),
|
||||
},
|
||||
final_geom: prim::empty_mesh(), // TODO: Close properly
|
||||
final_geom: OpenMesh { verts: vec![vc], faces },
|
||||
children: vec![
|
||||
Child {
|
||||
rule: Rule { eval: Self::recur },
|
||||
@ -439,5 +442,5 @@ pub fn main() {
|
||||
// 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
|
||||
// some sort of numerical precision issue.
|
||||
run_test_iter(Twist::init(), 200, "twist2");
|
||||
run_test_iter(Twist::init(), 100, "twist2");
|
||||
}
|
||||
|
||||
@ -39,6 +39,31 @@ pub struct OpenMesh {
|
||||
|
||||
impl OpenMesh {
|
||||
|
||||
pub fn append<T>(meshes: T) -> OpenMesh
|
||||
where T: IntoIterator<Item = OpenMesh>
|
||||
{
|
||||
let mut v: Vec<Vertex> = vec![];
|
||||
let mut f: Vec<Tag> = vec![];
|
||||
for mesh in meshes {
|
||||
// Position in 'verts' at which we're appending
|
||||
// mesh.verts, which we need to know to shift indices:
|
||||
let offset = v.len();
|
||||
|
||||
// Copy all vertices:
|
||||
v.append(&mut mesh.verts.clone());
|
||||
// Append its faces, applying offset:
|
||||
f.extend(mesh.faces.iter().map(|t| {
|
||||
match t {
|
||||
Tag::Body(n) => Tag::Body(n + offset),
|
||||
Tag::Parent(_) => panic!("Cannot append() if mesh has parent references!"),
|
||||
// TODO: Handle the above
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
OpenMesh { verts: v, faces: f }
|
||||
}
|
||||
|
||||
/// Returns a new `OpenMesh` whose vertices have been transformed.
|
||||
pub fn transform(&self, xfm: &Mat4) -> OpenMesh {
|
||||
OpenMesh {
|
||||
|
||||
@ -151,6 +151,12 @@ impl<A> Rule<A> {
|
||||
let s = &mut stack[n-1];
|
||||
let depth = s.depth;
|
||||
|
||||
if s.rules.is_empty() {
|
||||
stack.pop();
|
||||
n -= 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Evaluate the rule:
|
||||
let child = &s.rules[s.next];
|
||||
let mut eval = (child.rule.eval)(arg);
|
||||
|
||||
26
src/util.rs
26
src/util.rs
@ -29,3 +29,29 @@ pub fn parallel_zigzag_faces(count: usize) -> Vec<Tag> {
|
||||
]
|
||||
}).flatten().collect()
|
||||
}
|
||||
|
||||
pub fn connect_convex(verts: &Vec<Vertex>, as_parent: bool) -> (Vertex, Vec<Tag>) {
|
||||
let n = verts.len();
|
||||
let mut centroid = Vertex::new(0.0, 0.0, 0.0, 0.0);
|
||||
for v in verts {
|
||||
centroid += v;
|
||||
}
|
||||
centroid /= n as f32;
|
||||
|
||||
let faces: Vec<Tag> = {
|
||||
if as_parent {
|
||||
(0..n).map(|f1| {
|
||||
let f2 = (f1 + 1) % n;
|
||||
vec![Tag::Parent(f2), Tag::Parent(f1), Tag::Body(0)]
|
||||
}).flatten().collect()
|
||||
} else {
|
||||
(0..n).map(|f1| {
|
||||
let f2 = (f1 + 1) % n;
|
||||
// n is used for new center vertex
|
||||
vec![Tag::Body(f1), Tag::Body(f2), Tag::Body(n)]
|
||||
}).flatten().collect()
|
||||
}
|
||||
};
|
||||
|
||||
(centroid, faces)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user