Refactor & almost eliminate tri_mesh; cube_thing_rule working
This commit is contained in:
parent
9e92a469b8
commit
2b6ca70d40
@ -1,7 +1,7 @@
|
|||||||
- `curve_horn_*`: actually *combine* geometry properly.
|
- `curve_horn_*`: actually *combine* geometry properly.
|
||||||
|
|
||||||
- https://docs.rs/nalgebra/0.19.0/nalgebra/geometry/index.html - try
|
- Why is MeshBuilder so slow? Am I certain I'm not giving it a lot of
|
||||||
some other transformations from here (with to_homogeneous)
|
redundant geometry?
|
||||||
|
|
||||||
- Look at everything in README.md in automata_scratch.
|
- Look at everything in README.md in automata_scratch.
|
||||||
- Implement some of the tougher examples from the above too, e.g. the
|
- Implement some of the tougher examples from the above too, e.g. the
|
||||||
|
|||||||
110
src/main.rs
110
src/main.rs
@ -46,6 +46,20 @@ impl OpenMesh {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_trimesh(&self) -> Result<tm::Mesh, tri_mesh::mesh_builder::Error> {
|
||||||
|
let mut v: Vec<f64> = vec![0.0; self.verts.len() * 3];
|
||||||
|
println!("DEBUG: to_trimesh() iterating...");
|
||||||
|
for (i, vert) in self.verts.iter().enumerate() {
|
||||||
|
v[3*i] = vert[0].into();
|
||||||
|
v[3*i+1] = vert[1].into();
|
||||||
|
v[3*i+2] = vert[2].into();
|
||||||
|
}
|
||||||
|
let faces: Vec<u32> = self.faces.iter().map(|f| *f as _).collect();
|
||||||
|
println!("DEBUG: to_trimesh() calling MeshBuilder. faces.len()={}, v.len()={}...", faces.len(), v.len());
|
||||||
|
tm::MeshBuilder::new().with_indices(faces).with_positions(v).build()
|
||||||
|
}
|
||||||
|
// TODO: Why is this the slow part?
|
||||||
|
|
||||||
fn connect_single(&self, other: &OpenMesh) -> OpenMesh {
|
fn connect_single(&self, other: &OpenMesh) -> OpenMesh {
|
||||||
|
|
||||||
// Imagine connecting two pieces of pipe together. We are
|
// Imagine connecting two pieces of pipe together. We are
|
||||||
@ -83,20 +97,14 @@ impl OpenMesh {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_trimesh(&self) -> Result<tm::Mesh, tri_mesh::mesh_builder::Error> {
|
|
||||||
let mut v: Vec<f64> = vec![0.0; self.verts.len() * 3];
|
|
||||||
for (i, vert) in self.verts.iter().enumerate() {
|
|
||||||
v[3*i] = vert[0].into();
|
|
||||||
v[3*i+1] = vert[1].into();
|
|
||||||
v[3*i+2] = vert[2].into();
|
|
||||||
}
|
|
||||||
let faces: Vec<u32> = self.faces.iter().map(|f| *f as _).collect();
|
|
||||||
tm::MeshBuilder::new().with_indices(faces).with_positions(v).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just assume this is broken
|
// Just assume this is broken
|
||||||
fn connect(&self, others: &Vec<OpenMesh>) -> OpenMesh {
|
fn connect(&self, others: &Vec<OpenMesh>) -> OpenMesh {
|
||||||
|
|
||||||
|
if others.len() > 1 && self.idxs_exit.len() > 0 {
|
||||||
|
panic!("connect() is implemented for only one mesh if exit groups are present")
|
||||||
|
}
|
||||||
|
|
||||||
|
if false {
|
||||||
let mut v: Vec<Vertex> = vec![vertex(0.0,0.0,0.0); self.verts.len()];
|
let mut v: Vec<Vertex> = vec![vertex(0.0,0.0,0.0); self.verts.len()];
|
||||||
// Start out by cloning just entrance & body vertices:
|
// Start out by cloning just entrance & body vertices:
|
||||||
v.copy_from_slice(&self.verts[0..self.idxs_body.1]);
|
v.copy_from_slice(&self.verts[0..self.idxs_body.1]);
|
||||||
@ -142,30 +150,36 @@ impl OpenMesh {
|
|||||||
idxs_body: self.idxs_body.clone(), // TODO
|
idxs_body: self.idxs_body.clone(), // TODO
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is wrong, but close enough for now;
|
||||||
|
let mut mesh = self.clone();
|
||||||
|
for other in others {
|
||||||
|
mesh = mesh.connect_single(&other);
|
||||||
|
}
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Does OpenMesh subsume both 'geom' and 'seeds' in RuleStep?
|
|
||||||
// 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?
|
||||||
|
|
||||||
enum Rule {
|
enum Rule {
|
||||||
// Produce geometry, and possibly recurse further:
|
// Produce geometry, and possibly recurse further:
|
||||||
Recurse(fn () -> Vec<RuleStep>),
|
Recurse(fn () -> RuleStep),
|
||||||
// Stop recursing here:
|
// Stop recursing here:
|
||||||
EmptyRule,
|
EmptyRule,
|
||||||
}
|
}
|
||||||
// TODO: Rename rules?
|
// TODO: Rename rules?
|
||||||
|
// TODO: It may be possible to have just a 'static' rule that requires
|
||||||
|
// no function call.
|
||||||
|
|
||||||
struct RuleStep {
|
struct RuleStep {
|
||||||
// The geometry generated by this rule on its own - and none of
|
// The geometry generated by this rule on its own (not by any of
|
||||||
// the child rules.
|
// the child rules).
|
||||||
geom: OpenMesh,
|
geom: OpenMesh,
|
||||||
|
|
||||||
// The next rule to run. If EmptyRule, then stop here (and
|
// Child rules, paired with the transform that will be applied to
|
||||||
// 'xform' is irrelevant).
|
// all of their geometry
|
||||||
rule: Box<Rule>,
|
children: Vec<(Rule, Matrix4<f32>)>,
|
||||||
// The transformation to apply to geometry generated by 'rule' and
|
|
||||||
// any child rules.
|
|
||||||
xform: Matrix4<f32>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// is there a better way to do this?
|
// is there a better way to do this?
|
||||||
@ -361,7 +375,7 @@ fn cube() -> OpenMesh {
|
|||||||
}.transform(geometry::Translation3::new(-0.5, -0.5, -0.5).to_homogeneous())
|
}.transform(geometry::Translation3::new(-0.5, -0.5, -0.5).to_homogeneous())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cube_thing_rule() -> Vec<RuleStep> {
|
fn cube_thing_rule() -> RuleStep {
|
||||||
|
|
||||||
let mesh = cube();
|
let mesh = cube();
|
||||||
|
|
||||||
@ -381,18 +395,20 @@ fn cube_thing_rule() -> Vec<RuleStep> {
|
|||||||
geometry::Rotation3::from_axis_angle(z, -qtr).to_homogeneous(),
|
geometry::Rotation3::from_axis_angle(z, -qtr).to_homogeneous(),
|
||||||
];
|
];
|
||||||
|
|
||||||
let gen_rulestep = |rot: &Matrix4<f32>| -> RuleStep {
|
let gen_rulestep = |rot: &Matrix4<f32>| -> (Rule, Matrix4<f32>) {
|
||||||
let m: Matrix4<f32> = rot *
|
let m: Matrix4<f32> = rot *
|
||||||
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();
|
||||||
let r = Rule::Recurse(cube_thing_rule);
|
(Rule::Recurse(cube_thing_rule), m)
|
||||||
|
|
||||||
let m2 = mesh.transform(m);
|
|
||||||
RuleStep { geom: m2, rule: Box::new(r), xform: m }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
turns.iter().map(gen_rulestep).collect()
|
RuleStep {
|
||||||
|
geom: mesh,
|
||||||
|
children: turns.iter().map(gen_rulestep).collect(),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// TODO: This doesn't produce a central cube; it's like it's half an
|
||||||
|
// iteration off.
|
||||||
|
|
||||||
// Have I any need of this after making OpenMesh?
|
// Have I any need of this after making OpenMesh?
|
||||||
/*
|
/*
|
||||||
@ -473,38 +489,34 @@ impl<'a> Iterator for MeshBound<'a> {
|
|||||||
|
|
||||||
fn rule_to_mesh(rule: &Rule, iters_left: u32) -> (OpenMesh, u32) {
|
fn rule_to_mesh(rule: &Rule, iters_left: u32) -> (OpenMesh, u32) {
|
||||||
|
|
||||||
let mut mesh = empty_mesh();
|
|
||||||
|
|
||||||
let mut nodes: u32 = 1;
|
let mut nodes: u32 = 1;
|
||||||
|
|
||||||
if iters_left <= 0 {
|
if iters_left <= 0 {
|
||||||
return (mesh, nodes);
|
return (empty_mesh(), nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
match rule {
|
match rule {
|
||||||
Rule::Recurse(func) => {
|
Rule::Recurse(f) => {
|
||||||
for step in func() {
|
let rs: RuleStep = f();
|
||||||
let subrule: Rule = *step.rule;
|
|
||||||
let subxform: Matrix4<f32> = step.xform;
|
|
||||||
let geom: OpenMesh = step.geom;
|
|
||||||
|
|
||||||
mesh = mesh.connect_single(&geom);
|
// Get sub-geometry (from child rules) and transform it:
|
||||||
|
let subgeom: Vec<(OpenMesh, Matrix4<f32>, u32)> = rs.children.iter().map(|(subrule, subxform)| {
|
||||||
|
let (m,n) = rule_to_mesh(subrule, iters_left - 1);
|
||||||
|
(m, *subxform, n)
|
||||||
|
}).collect();
|
||||||
|
|
||||||
let (mut submesh, subnodes) = rule_to_mesh(
|
// Tally up node count:
|
||||||
&subrule, iters_left - 1);
|
subgeom.iter().for_each(|(_,_,n)| nodes += n);
|
||||||
|
|
||||||
submesh = submesh.transform(subxform);
|
let g: Vec<OpenMesh> = subgeom.iter().map(|(m,x,_)| m.transform(*x)).collect();
|
||||||
|
|
||||||
nodes += subnodes;
|
// Connect geometry from this rule (not child rules):
|
||||||
|
return (rs.geom.connect(&g), nodes);
|
||||||
mesh = mesh.connect_single(&submesh);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Rule::EmptyRule => {
|
Rule::EmptyRule => {
|
||||||
// do nothing
|
return (empty_mesh(), nodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(mesh, nodes)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -570,9 +582,10 @@ fn main() {
|
|||||||
|
|
||||||
let r = Rule::Recurse(cube_thing_rule);
|
let r = Rule::Recurse(cube_thing_rule);
|
||||||
|
|
||||||
let max_iters = 2;
|
let max_iters = 4;
|
||||||
println!("Running rules...");
|
println!("Running rules...");
|
||||||
let (cubemesh_, nodes) = rule_to_mesh(&r, max_iters);
|
let (cubemesh_, nodes) = rule_to_mesh(&r, max_iters);
|
||||||
|
println!("Converting mesh...");
|
||||||
let cubemesh = cubemesh_.to_trimesh().unwrap();
|
let cubemesh = cubemesh_.to_trimesh().unwrap();
|
||||||
println!("Collected {} nodes, produced {} faces, {} vertices",
|
println!("Collected {} nodes, produced {} faces, {} vertices",
|
||||||
nodes, cubemesh.no_faces(), cubemesh.no_vertices());
|
nodes, cubemesh.no_faces(), cubemesh.no_vertices());
|
||||||
@ -591,7 +604,4 @@ fn main() {
|
|||||||
s
|
s
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
// TEMP (while I figure shit out)
|
|
||||||
println!("DEBUG-------------------------------");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user