Allocate memory for efficiently.
This should generally improve rendering time.
This commit is contained in:
1 parent
8ba6d56512
commit
d84e78b29a
3 files changed
+41
-66
No files matched your search
+12
-38
@@ -23,14 +23,6 @@ fn new_triangle(p1: &Vertex, p2: &Vertex, p3: &Vertex) -> stl_io::Triangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// N steps around a circle, measured in radians.
|
|
||||||
fn radian_steps(steps: u32) -> Vec<f32> {
|
|
||||||
let counter = 0..steps;
|
|
||||||
let stepsize = std::f64::consts::TAU / steps as f64;
|
|
||||||
|
|
||||||
counter.map(|i| (i as f64 * stepsize) as f32).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Find a point on the cirle at a given angle (in radians).
|
/// Find a point on the cirle at a given angle (in radians).
|
||||||
fn vertex_on_circle(center: &Vertex, radius: f32, angle: f32) -> Vertex {
|
fn vertex_on_circle(center: &Vertex, radius: f32, angle: f32) -> Vertex {
|
||||||
let x = center[0] + (radius * angle.cos());
|
let x = center[0] + (radius * angle.cos());
|
||||||
@@ -41,10 +33,14 @@ fn vertex_on_circle(center: &Vertex, radius: f32, angle: f32) -> Vertex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn vertexes_on_circle(layer: &Layer, steps: u32) -> Vec<Vertex> {
|
fn vertexes_on_circle(layer: &Layer, steps: u32) -> Vec<Vertex> {
|
||||||
radian_steps(steps)
|
let mut result = Vec::with_capacity(steps as usize);
|
||||||
.iter()
|
let stepsize = std::f64::consts::TAU / steps as f64;
|
||||||
.map(|angle| vertex_on_circle(&layer.center, layer.radius, *angle))
|
|
||||||
.collect()
|
for i in 0..steps {
|
||||||
|
let angle = (i as f64 * stepsize) as f32;
|
||||||
|
result.push(vertex_on_circle(&layer.center, layer.radius, angle));
|
||||||
|
}
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tube_base(center: &Vertex, edge: &[Vertex]) -> Vec<Triangle> {
|
fn tube_base(center: &Vertex, edge: &[Vertex]) -> Vec<Triangle> {
|
||||||
@@ -88,13 +84,15 @@ pub fn render(layers: &Layers, resolution: f32) -> Vec<Triangle> {
|
|||||||
let circle_steps =
|
let circle_steps =
|
||||||
((layers.max_radius() * std::f32::consts::TAU) / resolution).max(64.0) as u32;
|
((layers.max_radius() * std::f32::consts::TAU) / resolution).max(64.0) as u32;
|
||||||
|
|
||||||
let mut layer_vertexes: Vec<Vec<Vertex>> = Vec::new();
|
let mut layer_vertexes: Vec<Vec<Vertex>> = Vec::with_capacity(layers.layers.len());
|
||||||
|
|
||||||
for layer in &layers.layers {
|
for layer in &layers.layers {
|
||||||
layer_vertexes.push(vertexes_on_circle(layer, circle_steps));
|
layer_vertexes.push(vertexes_on_circle(layer, circle_steps));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut result: Vec<Triangle> = Vec::new();
|
// Estimate triangle count: base + sides + top
|
||||||
|
let estimated_triangles = layers.layers.len() * circle_steps as usize * 2;
|
||||||
|
let mut result: Vec<Triangle> = Vec::with_capacity(estimated_triangles as usize);
|
||||||
|
|
||||||
result.append(&mut tube_base(&layers.base, &layer_vertexes[0]));
|
result.append(&mut tube_base(&layers.base, &layer_vertexes[0]));
|
||||||
for i in 0..layer_vertexes.len() - 1 {
|
for i in 0..layer_vertexes.len() - 1 {
|
||||||
@@ -137,30 +135,6 @@ mod tests {
|
|||||||
assert_eq!(tri_big.normal, Normal::new([0.0, 0.0, 18.0]));
|
assert_eq!(tri_big.normal, Normal::new([0.0, 0.0, 18.0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn radian_steps_basic() {
|
|
||||||
assert_eq!(radian_steps(0), []);
|
|
||||||
assert_eq!(radian_steps(1), [0.0]);
|
|
||||||
assert_eq!(radian_steps(2), [0.0, std::f32::consts::PI]);
|
|
||||||
assert_eq!(
|
|
||||||
radian_steps(3),
|
|
||||||
[
|
|
||||||
0.0,
|
|
||||||
std::f32::consts::PI * 2.0 / 3.0,
|
|
||||||
std::f32::consts::PI * 4.0 / 3.0
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
radian_steps(4),
|
|
||||||
[
|
|
||||||
0.0,
|
|
||||||
std::f32::consts::PI * 0.5,
|
|
||||||
std::f32::consts::PI,
|
|
||||||
std::f32::consts::PI * 1.5,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn validate_vec_vertex_relative_eq(val: &Vec<Vertex>, expected: &Vec<Vertex>) {
|
fn validate_vec_vertex_relative_eq(val: &Vec<Vertex>, expected: &Vec<Vertex>) {
|
||||||
let mut pass = true;
|
let mut pass = true;
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -35,7 +35,9 @@ fn generate_binary_stl(mushroom: mushroom::Mushroom) -> Vec<u8> {
|
|||||||
let mesh = render::render(&layers, 0.1);
|
let mesh = render::render(&layers, 0.1);
|
||||||
|
|
||||||
// Generate / return the byte array.
|
// Generate / return the byte array.
|
||||||
let mut binary_stl = Vec::<u8>::new();
|
// Estimate STL file size: ~80 bytes per triangle + 80 byte header
|
||||||
|
let estimated_size = mesh.len() * 80 + 80;
|
||||||
|
let mut binary_stl = Vec::<u8>::with_capacity(estimated_size);
|
||||||
stl_io::write_stl(&mut binary_stl, mesh.iter()).unwrap();
|
stl_io::write_stl(&mut binary_stl, mesh.iter()).unwrap();
|
||||||
binary_stl
|
binary_stl
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-27
@@ -6,33 +6,31 @@ use crate::mushroom::{CapStyle, Mushroom};
|
|||||||
fn stalk_layers(mushroom: &Mushroom, base: &Vertex, _resolution: f32) -> Vec<layers::Layer> {
|
fn stalk_layers(mushroom: &Mushroom, base: &Vertex, _resolution: f32) -> Vec<layers::Layer> {
|
||||||
let stalk_top = Vertex::new([base[0], base[1], base[2] + mushroom.stalk_h]);
|
let stalk_top = Vertex::new([base[0], base[1], base[2] + mushroom.stalk_h]);
|
||||||
|
|
||||||
[
|
let mut result = Vec::with_capacity(2);
|
||||||
layers::Layer {
|
result.push(layers::Layer {
|
||||||
center: *base,
|
center: *base,
|
||||||
radius: mushroom.stalk_r,
|
radius: mushroom.stalk_r,
|
||||||
},
|
});
|
||||||
layers::Layer {
|
result.push(layers::Layer {
|
||||||
center: stalk_top,
|
center: stalk_top,
|
||||||
radius: mushroom.stalk_r,
|
radius: mushroom.stalk_r,
|
||||||
},
|
});
|
||||||
]
|
result
|
||||||
.to_vec()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cap_layers_cylinder(mushroom: &Mushroom, base: &Vertex) -> Vec<layers::Layer> {
|
fn cap_layers_cylinder(mushroom: &Mushroom, base: &Vertex) -> Vec<layers::Layer> {
|
||||||
let top = Vertex::new([base[0], base[1], base[2] + mushroom.cap_h]);
|
let top = Vertex::new([base[0], base[1], base[2] + mushroom.cap_h]);
|
||||||
|
|
||||||
[
|
let mut result = Vec::with_capacity(2);
|
||||||
layers::Layer {
|
result.push(layers::Layer {
|
||||||
center: *base,
|
center: *base,
|
||||||
radius: mushroom.cap_r,
|
radius: mushroom.cap_r,
|
||||||
},
|
});
|
||||||
layers::Layer {
|
result.push(layers::Layer {
|
||||||
center: top,
|
center: top,
|
||||||
radius: mushroom.cap_r,
|
radius: mushroom.cap_r,
|
||||||
},
|
});
|
||||||
]
|
result
|
||||||
.to_vec()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cap_layers_dome(mushroom: &Mushroom, base: &Vertex, resolution: f32) -> Vec<layers::Layer> {
|
fn cap_layers_dome(mushroom: &Mushroom, base: &Vertex, resolution: f32) -> Vec<layers::Layer> {
|
||||||
@@ -129,11 +127,11 @@ pub fn mushroom(mushroom: &Mushroom, resolution: f32) -> layers::Layers {
|
|||||||
let base = Vertex::new([0.0, 0.0, 0.0]);
|
let base = Vertex::new([0.0, 0.0, 0.0]);
|
||||||
|
|
||||||
// Get layers for the stalk.
|
// Get layers for the stalk.
|
||||||
let mut stalk_layers = stalk_layers(mushroom, &base, resolution);
|
let stalk_layers = stalk_layers(mushroom, &base, resolution);
|
||||||
|
|
||||||
// Get layers for the cap.
|
// Get layers for the cap.
|
||||||
let cap_base = stalk_layers.last().unwrap().center;
|
let cap_base = stalk_layers.last().unwrap().center;
|
||||||
let mut cap_layers = cap_layers(mushroom, &cap_base, resolution);
|
let cap_layers = cap_layers(mushroom, &cap_base, resolution);
|
||||||
|
|
||||||
// The very top of the mushroom is directly above the top layer of the cap (or even with it)
|
// The very top of the mushroom is directly above the top layer of the cap (or even with it)
|
||||||
// at the exact height of the total mushroom.
|
// at the exact height of the total mushroom.
|
||||||
@@ -141,8 +139,9 @@ pub fn mushroom(mushroom: &Mushroom, resolution: f32) -> layers::Layers {
|
|||||||
let top = Vertex::new([cap_top[0], cap_top[1], base[2] + mushroom.height()]);
|
let top = Vertex::new([cap_top[0], cap_top[1], base[2] + mushroom.height()]);
|
||||||
|
|
||||||
// Assemble the final Layers object.
|
// Assemble the final Layers object.
|
||||||
let mut layers: Vec<layers::Layer> = Vec::new();
|
let growth = stalk_layers.len() + cap_layers.len();
|
||||||
layers.append(&mut stalk_layers);
|
let mut layers: Vec<layers::Layer> = Vec::with_capacity(growth);
|
||||||
layers.append(&mut cap_layers);
|
layers.extend(stalk_layers);
|
||||||
|
layers.extend(cap_layers);
|
||||||
layers::Layers { base, top, layers }
|
layers::Layers { base, top, layers }
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user