From d8c60c32d49eada1af5eb3c97b70b319085c68ab Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Thu, 4 Jun 2026 11:03:03 +0300 Subject: [PATCH] fix(3d): revolve axis and OBJ import use the Z-up world, not stale Y-up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The truck B-rep pipeline is Z-up (solids extrude/raise along Z, profile wires convert pass-through), but two spots still assumed a Y-up world: - REVOLVE swapped the axis/origin to (x, z, y), so the revolve axis sat in the XZ plane while the profile sat in XY → wrong solid. Use the axis/origin straight through. - OBJ import kept Y-up coordinates as-is on the (now Z-up) viewport, so imported meshes lay on their side. Rotate +90° about X on import (positions + normals): (x, y, z) → (x, -z, y). EXTRUDE (sweep along +Z) and the box/cylinder primitives were already Z-up and unchanged. Co-Authored-By: Claude Opus 4.8 --- src/app/cmd_result.rs | 4 ++-- src/io/obj.rs | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/app/cmd_result.rs b/src/app/cmd_result.rs index f75a76436..32964ee82 100644 --- a/src/app/cmd_result.rs +++ b/src/app/cmd_result.rs @@ -1230,11 +1230,11 @@ impl OpenCADStudio { let wire = wire?; let origin = Point3::new( axis_start.x as f64, - axis_start.z as f64, axis_start.y as f64, + axis_start.z as f64, ); let dir = (axis_end - axis_start).normalize(); - let axis = TruckVec3::new(dir.x as f64, dir.z as f64, dir.y as f64); + let axis = TruckVec3::new(dir.x as f64, dir.y as f64, dir.z as f64); let shell = builder::rsweep( &wire, origin, diff --git a/src/io/obj.rs b/src/io/obj.rs index 0f56b2235..2e09d172c 100644 --- a/src/io/obj.rs +++ b/src/io/obj.rs @@ -27,14 +27,15 @@ pub fn parse_obj(src: &str, color: [f32; 4]) -> Option { "v" => { let vals: Vec = parts.filter_map(|s| s.parse().ok()).collect(); if vals.len() >= 3 { - // OBJ: Y-up right-handed. OpenCADStudio viewport is also Y-up → keep as-is. - positions.push([vals[0], vals[1], vals[2]]); + // OBJ is Y-up right-handed; OpenCADStudio's world is Z-up. + // Rotate +90° about X so OBJ Y→world Z (up): (x, y, z) → (x, -z, y). + positions.push([vals[0], -vals[2], vals[1]]); } } "vn" => { let vals: Vec = parts.filter_map(|s| s.parse().ok()).collect(); if vals.len() >= 3 { - normals_raw.push([vals[0], vals[1], vals[2]]); + normals_raw.push([vals[0], -vals[2], vals[1]]); } } "f" => {