control gear params from the UI
This commit is contained in:
parent
f35ca37cae
commit
f5d578ccf3
|
|
@ -23,11 +23,11 @@ impl BevelGearDesc {
|
|||
}
|
||||
}
|
||||
|
||||
fn pitch_radius(&self) -> f32 {
|
||||
pub fn pitch_radius(&self) -> f32 {
|
||||
0.5 * self.teeth as f32
|
||||
}
|
||||
|
||||
fn pitch_distance(&self) -> f32 {
|
||||
pub fn pitch_distance(&self) -> f32 {
|
||||
self.pitch_radius() / self.cone_halfangle.tan()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
26
src/lib.rs
26
src/lib.rs
|
|
@ -10,6 +10,22 @@ mod render;
|
|||
|
||||
const BACKGROUND: Vec4 = vec4(0.00, 0.39, 0.52, 1.00);
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct ResetArgs {
|
||||
pub tooth: u32,
|
||||
pub cone_halfangle: f32,
|
||||
}
|
||||
|
||||
impl Default for ResetArgs {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
tooth: 24,
|
||||
cone_halfangle: std::f32::consts::FRAC_PI_4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct RedrawArgs {
|
||||
|
|
@ -72,7 +88,7 @@ fn color_to_wgpu(color: Vec4) -> wgpu::Color {
|
|||
}
|
||||
|
||||
impl Core {
|
||||
pub fn new(gpu: Gpu, pixel_size: UVec2) -> Self {
|
||||
pub fn new(gpu: Gpu, pixel_size: UVec2, args: &ResetArgs) -> Self {
|
||||
let Gpu {
|
||||
device,
|
||||
queue,
|
||||
|
|
@ -100,14 +116,14 @@ impl Core {
|
|||
|
||||
let bevel_gear_desc = bevel_gear::BevelGearDesc {
|
||||
profile: Default::default(),
|
||||
teeth: 24,
|
||||
cone_halfangle: 0.5,
|
||||
teeth: args.tooth,
|
||||
cone_halfangle: args.cone_halfangle,
|
||||
};
|
||||
let bevel_gear_mesh = bevel_gear::make_mesh(
|
||||
&bevel_gear_desc,
|
||||
&bevel_gear::BevelGearVisual {
|
||||
inner_distance: 8.0,
|
||||
outer_distance: 12.0,
|
||||
inner_distance: bevel_gear_desc.pitch_distance() - 4.0,
|
||||
outer_distance: bevel_gear_desc.pitch_distance(),
|
||||
},
|
||||
&bevel_gear::BevelGearShape::new_blank(&bevel_gear_desc, 60),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use gear_cutter::{Core, RedrawArgs, init_gpu_inner};
|
||||
use gear_cutter::{Core, RedrawArgs, ResetArgs, init_gpu_inner};
|
||||
use glam::uvec2;
|
||||
use winit::{
|
||||
application::ApplicationHandler,
|
||||
|
|
@ -26,7 +26,7 @@ impl MainWindow {
|
|||
instance.create_surface(Arc::clone(&window))
|
||||
}))
|
||||
.unwrap();
|
||||
let core = Core::new(gpu, uvec2(1, 1));
|
||||
let core = Core::new(gpu, uvec2(1, 1), &ResetArgs::default());
|
||||
Self { window, core }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@ BoxCore& BoxCore::operator=(BoxCore&& b) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
BoxCore BoxCore::from_xcb(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height) {
|
||||
BoxCore BoxCore::from_xcb(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height, const ResetArgs& args) {
|
||||
if (!connection)
|
||||
throw std::logic_error("attempt to use a null connection");
|
||||
if (!window)
|
||||
throw std::logic_error("attempt to use a null window");
|
||||
BoxCore out;
|
||||
out.ptr.ptr = ffi::rt4_viewport_create(connection, window, width, height);
|
||||
out.ptr.ptr = ffi::rt4_viewport_create(connection, window, width, height, &args);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
struct xcb_connection_t;
|
||||
|
||||
using ffi::ResetArgs;
|
||||
using ffi::RedrawArgs;
|
||||
|
||||
class MutCore {
|
||||
|
|
@ -36,7 +37,7 @@ public:
|
|||
|
||||
void reset();
|
||||
|
||||
static BoxCore from_xcb(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height);
|
||||
static BoxCore from_xcb(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height, const ResetArgs& args);
|
||||
|
||||
private:
|
||||
MutCore ptr;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{ffi::c_void, num::NonZero, ptr::NonNull};
|
||||
|
||||
use gear_cutter::{Core, RedrawArgs, init_gpu_inner};
|
||||
use gear_cutter::{Core, RedrawArgs, ResetArgs, init_gpu_inner};
|
||||
use glam::{UVec2, uvec2};
|
||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle, XcbDisplayHandle, XcbWindowHandle};
|
||||
|
||||
|
|
@ -8,6 +8,7 @@ unsafe fn create_viewport(
|
|||
display: impl Into<RawDisplayHandle>,
|
||||
window: impl Into<RawWindowHandle>,
|
||||
size: UVec2,
|
||||
args: &ResetArgs,
|
||||
) -> Box<Core> {
|
||||
let target = wgpu::SurfaceTargetUnsafe::RawHandle {
|
||||
raw_display_handle: display.into(),
|
||||
|
|
@ -17,7 +18,7 @@ unsafe fn create_viewport(
|
|||
instance.create_surface_unsafe(target)
|
||||
}))
|
||||
.unwrap();
|
||||
Box::new(Core::new(gpu, size))
|
||||
Box::new(Core::new(gpu, size, args))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
|
|
@ -26,10 +27,11 @@ unsafe extern "C" fn rt4_viewport_create(
|
|||
window: NonZero<u32>,
|
||||
width: u32,
|
||||
height: u32,
|
||||
args: &ResetArgs,
|
||||
) -> Box<Core> {
|
||||
let display = XcbDisplayHandle::new(Some(connection), 0);
|
||||
let window = XcbWindowHandle::new(window);
|
||||
unsafe { create_viewport(display, window, uvec2(width, height)) }
|
||||
unsafe { create_viewport(display, window, uvec2(width, height), args) }
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
|
|
|
|||
|
|
@ -6,13 +6,38 @@ GearCutter::GearCutter(QWidget* parent)
|
|||
: QMainWindow(parent),
|
||||
m_ui(new Ui::MainWindow) {
|
||||
m_ui->setupUi(this);
|
||||
updateParams();
|
||||
updateView();
|
||||
}
|
||||
|
||||
GearCutter::~GearCutter() = default;
|
||||
|
||||
void GearCutter::updateParams() {
|
||||
const std::uint32_t tooth = m_ui->bevTooth->value();
|
||||
const std::uint32_t mate_tooth = m_ui->bevMateTooth->value();
|
||||
const float shaft_angle = qDegreesToRadians((float)m_ui->bevShaftAngle->value());
|
||||
|
||||
const float r_gear = 0.5f * tooth;
|
||||
const float r_mate = 0.5f * mate_tooth;
|
||||
const float s = std::sin(shaft_angle);
|
||||
const float c = std::cos(shaft_angle);
|
||||
const float x_mate = s * r_mate;
|
||||
const float y_mate = r_gear + c * r_mate;
|
||||
const float h_gear = x_mate + y_mate * c / s;
|
||||
const float cone_halfangle = std::atan2(r_gear, h_gear);
|
||||
|
||||
m_ui->bevAngle->setValue(qRadiansToDegrees(cone_halfangle));
|
||||
m_ui->bevMateAngle->setValue(qRadiansToDegrees(shaft_angle - cone_halfangle));
|
||||
|
||||
const ResetArgs args{
|
||||
.tooth = tooth,
|
||||
.cone_halfangle = cone_halfangle,
|
||||
};
|
||||
m_ui->viewport->setParams(args);
|
||||
}
|
||||
|
||||
void GearCutter::updateView() {
|
||||
RedrawArgs args{
|
||||
const RedrawArgs args{
|
||||
.cam_yaw = qDegreesToRadians((float)m_ui->camYaw->value()),
|
||||
.cam_pitch = qDegreesToRadians((float)m_ui->camPitch->value()),
|
||||
.cam_view_y = (float)m_ui->camFoVLin->value(),
|
||||
|
|
@ -21,9 +46,4 @@ void GearCutter::updateView() {
|
|||
m_ui->viewport->setView(args);
|
||||
}
|
||||
|
||||
void GearCutter::updateViewIf(bool update) {
|
||||
if (update)
|
||||
updateView();
|
||||
}
|
||||
|
||||
#include "moc_main_window.cpp"
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ public:
|
|||
~GearCutter() override;
|
||||
|
||||
public slots:
|
||||
void updateParams();
|
||||
void updateView();
|
||||
void updateViewIf(bool update); // for radio buttons
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Ui::MainWindow> m_ui;
|
||||
|
|
|
|||
|
|
@ -26,14 +26,14 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1600</width>
|
||||
<height>34</height>
|
||||
<height>33</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<widget class="QDockWidget" name="dockWidget">
|
||||
<property name="features">
|
||||
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
|
||||
<set>QDockWidget::DockWidgetFeature::DockWidgetFloatable|QDockWidget::DockWidgetFeature::DockWidgetMovable</set>
|
||||
</property>
|
||||
<attribute name="dockWidgetArea">
|
||||
<number>2</number>
|
||||
|
|
@ -159,10 +159,152 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Bevel gear</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Tooth</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="bevTooth">
|
||||
<property name="minimum">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Cone half-angle</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="bevAngle">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> °</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>15.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>90.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>5.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>90.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Mate tooth</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="bevMateTooth">
|
||||
<property name="minimum">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>32</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Mate half-angle</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="bevMateAngle">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> °</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>90.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>5.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Shaft angle</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="bevShaftAngle">
|
||||
<property name="suffix">
|
||||
<string> °</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>15.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>150.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>5.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>90.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -184,6 +326,17 @@
|
|||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>camYaw</tabstop>
|
||||
<tabstop>camPitch</tabstop>
|
||||
<tabstop>camFoVLin</tabstop>
|
||||
<tabstop>camFoVAng</tabstop>
|
||||
<tabstop>bevTooth</tabstop>
|
||||
<tabstop>bevAngle</tabstop>
|
||||
<tabstop>bevMateTooth</tabstop>
|
||||
<tabstop>bevMateAngle</tabstop>
|
||||
<tabstop>bevShaftAngle</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
|
|
@ -250,9 +403,57 @@
|
|||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>bevTooth</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>updateParams()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>1557</x>
|
||||
<y>431</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>1464</x>
|
||||
<y>488</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>bevMateTooth</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>updateParams()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>1509</x>
|
||||
<y>556</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>1462</x>
|
||||
<y>561</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>bevShaftAngle</sender>
|
||||
<signal>valueChanged(double)</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>updateParams()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>1489</x>
|
||||
<y>681</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>1461</x>
|
||||
<y>689</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>updateView()</slot>
|
||||
<slot>updateViewIf(bool)</slot>
|
||||
<slot>updateParams()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,12 @@ Viewport::Viewport(QWidget* parent, Qt::WindowFlags f)
|
|||
|
||||
Viewport::~Viewport() = default;
|
||||
|
||||
void Viewport::setParams(ResetArgs new_args) {
|
||||
setup = new_args;
|
||||
recreate();
|
||||
update();
|
||||
}
|
||||
|
||||
void Viewport::setView(RedrawArgs new_args) {
|
||||
args = new_args;
|
||||
update();
|
||||
|
|
@ -63,7 +69,7 @@ void Viewport::recreate() try {
|
|||
|
||||
const QSize device_size = size() * devicePixelRatio();
|
||||
core.reset();
|
||||
core = BoxCore::from_xcb(xcb_connection, x11_window, device_size.width(), device_size.height());
|
||||
core = BoxCore::from_xcb(xcb_connection, x11_window, device_size.width(), device_size.height(), setup);
|
||||
} catch (const std::exception& e) {
|
||||
fprintf(stderr, "failed to recreate the viewport: %s", e.what());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ public:
|
|||
~Viewport() override;
|
||||
QPaintEngine* paintEngine() const override;
|
||||
|
||||
void setParams(ResetArgs new_args);
|
||||
void setView(RedrawArgs new_args);
|
||||
|
||||
protected:
|
||||
|
|
@ -21,6 +22,7 @@ protected:
|
|||
|
||||
private:
|
||||
BoxCore core;
|
||||
ResetArgs setup = {};
|
||||
RedrawArgs args = {};
|
||||
|
||||
void recreate();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user