Coordinate grid uses same scale as user's units (#7465)
Closes https://github.com/KittyCAD/engine/issues/3494. Thanks to @nadr0 for helping on the JS side. If users set their units, the grid will stop auto scaling, and instead will be set to 10 of whatever unit they used. If users set their units, and those units are metric, then it'll include a scale bar (see screenshot). Imperial units won't have that bar. This behaviour is configurable via settings. ## Limitations - The scale bar below the grid cannot be disabled in metric units, and cannot be enabled in imperial units <img width="1690" alt="Screenshot 2025-06-05 at 7 51 41 PM" src="https://github.com/user-attachments/assets/c597087c-f96d-4c30-95f4-b3d8ba2b5567" />
This commit is contained in:
@ -31,7 +31,7 @@ pub use state::{ExecState, MetaSettings};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
engine::EngineManager,
|
||||
engine::{EngineManager, GridScaleBehavior},
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
cache::{CacheInformation, CacheResult},
|
||||
@ -295,6 +295,8 @@ pub struct ExecutorSettings {
|
||||
/// This is the path to the current file being executed.
|
||||
/// We use this for preventing cyclic imports.
|
||||
pub current_file: Option<TypedPath>,
|
||||
/// Whether or not to automatically scale the grid when user zooms.
|
||||
pub fixed_size_grid: bool,
|
||||
}
|
||||
|
||||
impl Default for ExecutorSettings {
|
||||
@ -306,33 +308,34 @@ impl Default for ExecutorSettings {
|
||||
replay: None,
|
||||
project_directory: None,
|
||||
current_file: None,
|
||||
fixed_size_grid: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::settings::types::Configuration> for ExecutorSettings {
|
||||
fn from(config: crate::settings::types::Configuration) -> Self {
|
||||
Self::from(config.settings)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::settings::types::Settings> for ExecutorSettings {
|
||||
fn from(settings: crate::settings::types::Settings) -> Self {
|
||||
Self {
|
||||
highlight_edges: config.settings.modeling.highlight_edges.into(),
|
||||
enable_ssao: config.settings.modeling.enable_ssao.into(),
|
||||
show_grid: config.settings.modeling.show_scale_grid,
|
||||
highlight_edges: settings.modeling.highlight_edges.into(),
|
||||
enable_ssao: settings.modeling.enable_ssao.into(),
|
||||
show_grid: settings.modeling.show_scale_grid,
|
||||
replay: None,
|
||||
project_directory: None,
|
||||
current_file: None,
|
||||
fixed_size_grid: settings.app.fixed_size_grid,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::settings::types::project::ProjectConfiguration> for ExecutorSettings {
|
||||
fn from(config: crate::settings::types::project::ProjectConfiguration) -> Self {
|
||||
Self {
|
||||
highlight_edges: config.settings.modeling.highlight_edges.into(),
|
||||
enable_ssao: config.settings.modeling.enable_ssao.into(),
|
||||
show_grid: Default::default(),
|
||||
replay: None,
|
||||
project_directory: None,
|
||||
current_file: None,
|
||||
}
|
||||
Self::from(config.settings.modeling)
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,6 +348,7 @@ impl From<crate::settings::types::ModelingSettings> for ExecutorSettings {
|
||||
replay: None,
|
||||
project_directory: None,
|
||||
current_file: None,
|
||||
fixed_size_grid: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -358,6 +362,7 @@ impl From<crate::settings::types::project::ProjectModelingSettings> for Executor
|
||||
replay: None,
|
||||
project_directory: None,
|
||||
current_file: None,
|
||||
fixed_size_grid: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -497,6 +502,7 @@ impl ExecutorContext {
|
||||
replay: None,
|
||||
project_directory: None,
|
||||
current_file: None,
|
||||
fixed_size_grid: false,
|
||||
},
|
||||
None,
|
||||
engine_addr,
|
||||
@ -592,6 +598,18 @@ impl ExecutorContext {
|
||||
|
||||
pub async fn run_with_caching(&self, program: crate::Program) -> Result<ExecOutcome, KclErrorWithOutputs> {
|
||||
assert!(!self.is_mock());
|
||||
let grid_scale = if self.settings.fixed_size_grid {
|
||||
GridScaleBehavior::Fixed(
|
||||
program
|
||||
.meta_settings()
|
||||
.ok()
|
||||
.flatten()
|
||||
.map(|s| s.default_length_units)
|
||||
.map(kcmc::units::UnitLength::from),
|
||||
)
|
||||
} else {
|
||||
GridScaleBehavior::ScaleWithZoom
|
||||
};
|
||||
|
||||
let (program, exec_state, result) = match cache::read_old_ast().await {
|
||||
Some(mut cached_state) => {
|
||||
@ -618,6 +636,7 @@ impl ExecutorContext {
|
||||
&self.settings,
|
||||
Default::default(),
|
||||
&mut cached_state.main.exec_state.id_generator,
|
||||
grid_scale,
|
||||
)
|
||||
.await
|
||||
.is_err()
|
||||
@ -645,6 +664,7 @@ impl ExecutorContext {
|
||||
&self.settings,
|
||||
Default::default(),
|
||||
&mut cached_state.main.exec_state.id_generator,
|
||||
grid_scale,
|
||||
)
|
||||
.await
|
||||
.is_err()
|
||||
@ -689,6 +709,7 @@ impl ExecutorContext {
|
||||
&self.settings,
|
||||
Default::default(),
|
||||
&mut cached_state.main.exec_state.id_generator,
|
||||
grid_scale,
|
||||
)
|
||||
.await
|
||||
.is_ok()
|
||||
@ -1077,8 +1098,25 @@ impl ExecutorContext {
|
||||
let _stats = crate::log::LogPerfStats::new("Interpretation");
|
||||
|
||||
// Re-apply the settings, in case the cache was busted.
|
||||
let grid_scale = if self.settings.fixed_size_grid {
|
||||
GridScaleBehavior::Fixed(
|
||||
program
|
||||
.meta_settings()
|
||||
.ok()
|
||||
.flatten()
|
||||
.map(|s| s.default_length_units)
|
||||
.map(kcmc::units::UnitLength::from),
|
||||
)
|
||||
} else {
|
||||
GridScaleBehavior::ScaleWithZoom
|
||||
};
|
||||
self.engine
|
||||
.reapply_settings(&self.settings, Default::default(), exec_state.id_generator())
|
||||
.reapply_settings(
|
||||
&self.settings,
|
||||
Default::default(),
|
||||
exec_state.id_generator(),
|
||||
grid_scale,
|
||||
)
|
||||
.await
|
||||
.map_err(KclErrorWithOutputs::no_outputs)?;
|
||||
|
||||
|
Reference in New Issue
Block a user