Extrude: a symmetric distance is the total thickness (#1260)

A symmetric solid extrude of 10 mm is now 10 mm thick, 5 mm each side of the sketch plane, and switching from One Side to Symmetric keeps the thickness entered. Under format 21 the extent records its convention; designs saved without it keep the per-side reading, so their geometry and parameters don't change. Fixes #1236.

Co-authored-by: Karl-VonRichter <Karl-VonRichter@users.noreply.github.com>
This commit is contained in:
Karl Von RichterandKarl-VonRichter authored and GitHub committed 2026-10-15 01:19:55 -04:00
1 parent faeeff1c64
commit 1ec33fcdc7
19 files changed
+323 -18

No files matched your search

+18 -6
View File
@@ -338,6 +338,16 @@ fn draw(app: &SolveApp, ui: &mut egui::Ui, painter: &egui::Painter, proj: &Proj,
_ => 1.0,
};
let symmetric = to_span.is_none() && matches!(d.kind, Kind::Extrude { direction: 2, .. });
let symmetric_scale = if symmetric {
d.extra
.get("convention")
.cloned()
.and_then(|v| serde_json::from_value::<solidcraft_engine::doc::ExtrudeConvention>(v).ok())
.unwrap_or(solidcraft_engine::doc::ExtrudeConvention::TotalDistance)
.symmetric_half_distance(1.0)
} else {
1.0
};
// Extrudes and moves go either way; radii and thicknesses stay positive.
let signed = matches!(
d.kind,
@@ -416,17 +426,19 @@ fn draw(app: &SolveApp, ui: &mut egui::Ui, painter: &egui::Painter, proj: &Proj,
if let (Some(n), Some(l)) = (dir, len.filter(|_| kind == ValueKind::Length)) {
let n = n * sign;
let baseline = to_span.map(f64::abs).unwrap_or(0.0);
let mut shown_value = format_len(l + baseline);
// Through All already supplies a reach per side; dragging switches to an entered distance.
let half = if all_span.is_some() { l } else { l * symmetric_scale };
let mut shown_value = format_len(half + baseline);
let original_shown = shown_value.clone();
let dragged = if to_span.is_some() { &mut shown_value } else { &mut *value };
if let Some(ts) = drag_arrow(ui, painter, proj, base, bs, n, l + baseline, signed, egui::Id::new("sc_manipulator"), half_height, dragged) {
if to_span.is_some()
let dragged = if to_span.is_some() || symmetric_scale != 1.0 { &mut shown_value } else { &mut *value };
if let Some(ts) = drag_arrow(ui, painter, proj, base, bs, n, half + baseline, signed, egui::Id::new("sc_manipulator"), half_height, dragged) {
if (to_span.is_some() || symmetric_scale != 1.0)
&& shown_value != original_shown
&& let Ok(v) = app.session.doc.eval(&shown_value, ValueKind::Length)
{
*value = format_len(v - baseline);
*value = format_len((v - baseline) / symmetric_scale);
}
if symmetric && let Some(bt) = proj.to_screen(base - n * l) {
if symmetric && let Some(bt) = proj.to_screen(base - n * half) {
arrow(painter, bs, bt, t.manipulator);
}
painter.circle(bs, 3.5, t.manipulator, Stroke::new(1.0, Color32::WHITE));