From f880de181e32d69e9561ff20abc876f8421ba433 Mon Sep 17 00:00:00 2001 From: numzero Date: Mon, 20 Jul 2026 14:29:37 +0300 Subject: [PATCH] add ui to select mode --- src/lib.rs | 16 +++- src/mesh.rs | 12 ++- ui/src/api.hxx | 10 +++ ui/src/main_window.cxx | 23 ++++++ ui/src/main_window.hxx | 1 + ui/src/main_window.ui | 169 +++++++++++++++++++++++++++++++++++++++-- 6 files changed, 223 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 01eba7b..389581e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,24 +9,38 @@ mod render; const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth16Unorm; const OUTPUT_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb; +#[derive(Debug, Clone, Copy)] +#[repr(u32)] +pub enum Mode { + Solid, + Shell, + Mesh, +} + #[derive(Debug, Clone, Copy)] #[repr(C)] pub struct ShapeArgs { + pub mode: Mode, pub sides: u32, pub layers_up: u32, pub layers_down: u32, pub base_diameter: f32, pub height: f32, + pub thickness: f32, + pub line_width: f32, } impl Default for ShapeArgs { fn default() -> Self { Self { + mode: Mode::Shell, sides: 24, layers_up: 6, layers_down: 6, base_diameter: 36.0, height: 120.0, + thickness: 1.6, + line_width: 3.0, } } } @@ -96,7 +110,7 @@ impl Core { } fn render(&self, output: &wgpu::Texture, args: &RedrawArgs) { - let mesh = mesh::cup(&args.shape); + let mesh = mesh::make(&args.shape); let mesh = faceted_mesh(&mesh); let mesh = render::Mesh::new(&self.device, &mesh); diff --git a/src/mesh.rs b/src/mesh.rs index a9ba76a..9f62c6f 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -4,7 +4,7 @@ use glam::{Mat2, Vec3, Vec3Swizzles, vec2, vec3}; pub type Face = [usize; 3]; -#[derive(Clone)] +#[derive(Clone, Default)] pub struct Mesh { pub vertices: Vec, pub faces: Vec, @@ -109,7 +109,7 @@ pub fn solid(shape: &crate::ShapeArgs) -> Mesh { pub fn cup(shape: &crate::ShapeArgs) -> Mesh { let sides = shape.sides as usize; - let thickness = 1.6; + let thickness = shape.thickness; let mut outer = shell(shape); let shell_vs = outer.vertices.len(); @@ -141,3 +141,11 @@ pub fn cup(shape: &crate::ShapeArgs) -> Mesh { 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 + } +} diff --git a/ui/src/api.hxx b/ui/src/api.hxx index 74db20b..56aecb5 100644 --- a/ui/src/api.hxx +++ b/ui/src/api.hxx @@ -11,12 +11,21 @@ struct alignas(16) Vec4 { namespace ffi { struct Core; +enum class Mode: std::uint32_t { + Solid, + Shell, + Mesh, +}; + struct ShapeArgs { + Mode mode; std::uint32_t sides; std::uint32_t layers_up; std::uint32_t layers_down; float base_diameter; float height; + float thickness; + float line_width; }; struct RedrawArgs { @@ -29,6 +38,7 @@ struct RedrawArgs { }; } // namespace ffi +using ffi::Mode; using ffi::ShapeArgs; using ffi::RedrawArgs; diff --git a/ui/src/main_window.cxx b/ui/src/main_window.cxx index 245db4d..91b312d 100644 --- a/ui/src/main_window.cxx +++ b/ui/src/main_window.cxx @@ -6,22 +6,45 @@ Hyperboloid::Hyperboloid(QWidget* parent) : QMainWindow(parent), m_ui(new Ui::MainWindow) { m_ui->setupUi(this); + m_ui->mode->setId(m_ui->modeSolid, (int)Mode::Solid); + m_ui->mode->setId(m_ui->modeShell, (int)Mode::Shell); + m_ui->mode->setId(m_ui->modeMesh, (int)Mode::Mesh); + updateModeUi(); updateView(); } Hyperboloid::~Hyperboloid() = default; +void Hyperboloid::updateModeUi() { + const auto mode = (Mode)m_ui->mode->checkedId(); + bool has_thickness = false; + bool has_line_width = false; + switch (mode) { + case Mode::Mesh: + has_line_width = true; + case Mode::Shell: + has_thickness = true; + case Mode::Solid: + ; + } + m_ui->thickness->setEnabled(has_thickness); + m_ui->lineWidth->setEnabled(has_line_width); +} + void Hyperboloid::updateView() { const int max_layers = (m_ui->sides->value() - 1) / 2; m_ui->layersUp->setMaximum(max_layers); m_ui->layersDown->setMaximum(max_layers); const auto color = m_ui->inBackground->color(); const ShapeArgs shape { + .mode = (Mode)m_ui->mode->checkedId(), .sides = (std::uint32_t)m_ui->sides->value(), .layers_up = (std::uint32_t)m_ui->layersUp->value(), .layers_down = (std::uint32_t)m_ui->layersDown->value(), .base_diameter = (float)m_ui->dia->value(), .height = (float)m_ui->height->value(), + .thickness = (float)m_ui->thickness->value(), + .line_width = (float)m_ui->lineWidth->value(), }; const RedrawArgs args{ .shape = shape, diff --git a/ui/src/main_window.hxx b/ui/src/main_window.hxx index c2ee61e..5614d9c 100644 --- a/ui/src/main_window.hxx +++ b/ui/src/main_window.hxx @@ -15,6 +15,7 @@ public: ~Hyperboloid() override; public slots: + void updateModeUi(); void updateView(); void updateViewIf(bool update); // for radio buttons diff --git a/ui/src/main_window.ui b/ui/src/main_window.ui index 66825a7..e5c3b28 100644 --- a/ui/src/main_window.ui +++ b/ui/src/main_window.ui @@ -257,6 +257,97 @@ + + + + Mode + + + + + + Solid + + + mode + + + + + + + Shell + + + true + + + mode + + + + + + + Mesh + + + mode + + + + + + + Thickness + + + + + + + mm + + + 0.100000000000000 + + + 10.000000000000000 + + + QAbstractSpinBox::StepType::AdaptiveDecimalStepType + + + 1.600000000000000 + + + + + + + Line width + + + + + + + mm + + + 0.100000000000000 + + + 50.000000000000000 + + + 3.000000000000000 + + + + + + @@ -324,7 +415,7 @@ 1585 - 803 + 1036 799 @@ -435,8 +526,8 @@ updateView() - 1472 - 611 + 1585 + 620 1446 @@ -451,8 +542,8 @@ updateView() - 1476 - 686 + 1585 + 682 1446 @@ -460,9 +551,77 @@ + + thickness + valueChanged(double) + MainWindow + updateView() + + + 1495 + 852 + + + 1459 + 855 + + + + + lineWidth + valueChanged(double) + MainWindow + updateView() + + + 1495 + 915 + + + 1461 + 913 + + + + + mode + buttonClicked(QAbstractButton*) + MainWindow + updateView() + + + -1 + -1 + + + 799 + 599 + + + + + mode + buttonClicked(QAbstractButton*) + MainWindow + updateModeUi() + + + -1 + -1 + + + 799 + 599 + + + updateView() updateViewIf(bool) + updateModeUi() + + +