diff --git a/Cargo.lock b/Cargo.lock
index 96a81a8..c5f3464 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -381,6 +381,12 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
+[[package]]
+name = "either"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d"
+
[[package]]
name = "equivalent"
version = "1.0.2"
@@ -629,6 +635,7 @@ version = "0.1.0"
dependencies = [
"bytemuck",
"glam",
+ "itertools",
"pollster",
"wgpu",
"winit",
@@ -656,6 +663,15 @@ dependencies = [
"hashbrown 0.16.1",
]
+[[package]]
+name = "itertools"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc"
+dependencies = [
+ "either",
+]
+
[[package]]
name = "jni"
version = "0.21.1"
diff --git a/Cargo.toml b/Cargo.toml
index 2bc6a2a..ab81523 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,6 +20,7 @@ opt-level = 3
[dependencies]
bytemuck = { version = "1.25.2", features = ["derive"] }
glam = { version = "0.30.9", features = ["bytemuck"] }
+itertools = "0.15.0"
pollster = "0.4.0"
wgpu = "27.0.1"
winit = "0.30.12"
diff --git a/src/mesh.rs b/src/mesh.rs
index 9f62c6f..232804c 100644
--- a/src/mesh.rs
+++ b/src/mesh.rs
@@ -1,6 +1,7 @@
-use std::f32::consts::PI;
+use std::f32::consts::{FRAC_PI_3, PI};
use glam::{Mat2, Vec3, Vec3Swizzles, vec2, vec3};
+use itertools::Itertools;
pub type Face = [usize; 3];
@@ -93,16 +94,67 @@ pub fn shell(shape: &crate::ShapeArgs) -> Mesh {
}
pub fn solid(shape: &crate::ShapeArgs) -> Mesh {
- let sides = shape.sides as usize;
+ let r = shape.base_diameter / 2.0;
- let mut mesh = shell(shape);
+ let mut mesh = Mesh::default();
- let mut bottom = disc_faces(0, sides);
- flip_faces(&mut bottom);
- mesh.faces.extend(bottom);
-
- let top = disc_faces(mesh.vertices.len() - sides, sides);
- mesh.faces.extend(top);
+ let mut pts = Vec::new();
+ for a in 0..3 {
+ let angle = 2.0 * a as f32 * FRAC_PI_3;
+ let (y, x) = angle.sin_cos();
+ pts.push(vec2(x, y));
+ }
+ mesh.vertices
+ .extend(pts.iter().map(|pt| r * vec3(pt.x, pt.y, 0.0)));
+ mesh.faces.push([0, 2, 1]);
+ let n_layers = 4;
+ for layer in 1..n_layers {
+ let mut new_pts = Vec::new();
+ let z0 = 1.0 - 3.0f32.powf(-(layer - 1) as f32);
+ let z = 1.0 - 3.0f32.powf(-layer as f32);
+ for [a, b] in pts.iter().copied().circular_array_windows() {
+ let along = b - a;
+ let across = -along.perp();
+ let c = (2. * a + b) / 3.;
+ let d = (a + 2. * b) / 3.;
+ let mid = (a + b) / 2.;
+ let e = mid + across * (1.0f32 / 12.).sqrt();
+ new_pts.push(a);
+ new_pts.push(c);
+ new_pts.push(e);
+ new_pts.push(d);
+ let base = mesh.vertices.len();
+ mesh.vertices
+ .extend([a, mid, b].map(|pt| r * vec3(pt.x, pt.y, z0)));
+ mesh.vertices
+ .extend([a, c, e, d, b].map(|pt| r * vec3(pt.x, pt.y, z)));
+ mesh.faces.extend(
+ [
+ [0, 4, 3],
+ [0, 1, 4],
+ [1, 5, 4],
+ [1, 6, 5],
+ [1, 2, 6],
+ [2, 7, 6],
+ ]
+ .map(|face| face.map(|index| base + index)),
+ );
+ }
+ pts = new_pts;
+ }
+ {
+ let z0 = 1.0 - 3.0f32.powf(-(n_layers - 1) as f32);
+ let z = 1.0 - 3.0f32.powf(-n_layers as f32);
+ for [a, b] in pts.iter().copied().circular_array_windows() {
+ let base = mesh.vertices.len();
+ mesh.vertices
+ .extend([a, b].map(|pt| r * vec3(pt.x, pt.y, z0)));
+ mesh.vertices
+ .extend([a, b].map(|pt| r * vec3(pt.x, pt.y, z)));
+ mesh.faces
+ .extend([[0, 3, 2], [0, 1, 3]].map(|face| face.map(|index| base + index)));
+ }
+ }
mesh
}
@@ -143,9 +195,5 @@ pub fn cup(shape: &crate::ShapeArgs) -> Mesh {
}
pub fn make(shape: &crate::ShapeArgs) -> Mesh {
- match shape.mode {
- crate::Mode::Solid => solid(shape),
- crate::Mode::Shell => cup(shape),
- crate::Mode::Mesh => Default::default(), // TODO implement
- }
+ solid(shape)
}
diff --git a/ui/src/main_window.ui b/ui/src/main_window.ui
index a9b65b6..9a55045 100644
--- a/ui/src/main_window.ui
+++ b/ui/src/main_window.ui
@@ -221,13 +221,13 @@
4.000000000000000
- 100.000000000000000
+ 200.000000000000000
QAbstractSpinBox::StepType::AdaptiveDecimalStepType
- 36.000000000000000
+ 100.000000000000000