forked from 1b-agent/opencadstudio-upstream
feat(ucs): integrate coordinate systems
Route coordinate input, geometry creation, transforms, properties,\nviews, and viewport persistence through a shared working plane.\n\nRefs #484
This commit is contained in:
1 parent
b1d55c6a7e
commit
657d023fb7
61 files changed
+2218
-747
No files matched your search
+25
-32
@@ -257,11 +257,22 @@ impl DocumentTab {
|
||||
/// is identity (plain WCS).
|
||||
pub(super) fn model_ucs_from_header(&self) -> Option<Ucs> {
|
||||
let h = &self.scene.document.header;
|
||||
let mut u = Ucs::new(h.model_space_ucs_name.clone());
|
||||
let mut u = if h.model_space_ucs_name.is_empty() {
|
||||
Ucs::new("*ACTIVE*")
|
||||
} else {
|
||||
self.scene
|
||||
.document
|
||||
.ucss
|
||||
.get(&h.model_space_ucs_name)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| Ucs::new(h.model_space_ucs_name.clone()))
|
||||
};
|
||||
u.origin = h.model_space_ucs_origin;
|
||||
u.x_axis = h.model_space_ucs_x_axis;
|
||||
u.y_axis = h.model_space_ucs_y_axis;
|
||||
if super::helpers::UcsXform::from_ucs(&u).is_identity() {
|
||||
if h.model_space_ucs_name.is_empty()
|
||||
&& super::helpers::UcsXform::from_ucs(&u).is_identity()
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(u)
|
||||
@@ -278,11 +289,21 @@ impl DocumentTab {
|
||||
if !vp.ucs_per_viewport {
|
||||
return None;
|
||||
}
|
||||
let mut u = Ucs::new("*VPUCS*");
|
||||
let mut u = if vp.ucs_handle.is_null() {
|
||||
Ucs::new("*VPUCS*")
|
||||
} else {
|
||||
self.scene
|
||||
.document
|
||||
.ucss
|
||||
.iter()
|
||||
.find(|ucs| ucs.handle == vp.ucs_handle)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| Ucs::new("*VPUCS*"))
|
||||
};
|
||||
u.origin = vp.ucs_origin;
|
||||
u.x_axis = vp.ucs_x_axis;
|
||||
u.y_axis = vp.ucs_y_axis;
|
||||
if super::helpers::UcsXform::from_ucs(&u).is_identity() {
|
||||
if vp.ucs_handle.is_null() && super::helpers::UcsXform::from_ucs(&u).is_identity() {
|
||||
None
|
||||
} else {
|
||||
Some(u)
|
||||
@@ -369,34 +390,6 @@ impl DocumentTab {
|
||||
self.scene.viewcube_ucs = self.ucs_xform().rotation_mat();
|
||||
}
|
||||
|
||||
/// UCS→render(wire)-space affine for commands that build axis-aligned
|
||||
/// geometry. Columns are the UCS axes; translation is the UCS origin in wire
|
||||
/// space. Identity outside model space (no UCS there).
|
||||
pub(super) fn ucs_wire_affine(&self) -> glam::Mat4 {
|
||||
if !self.editing_model_space() {
|
||||
return glam::Mat4::IDENTITY;
|
||||
}
|
||||
let (o, x, y, z) = self.ucs_xform().axes();
|
||||
let origin = glam::Vec3::new(o.x as f32, o.y as f32, o.z as f32);
|
||||
glam::Mat4::from_cols(
|
||||
x.as_vec3().extend(0.0),
|
||||
y.as_vec3().extend(0.0),
|
||||
z.as_vec3().extend(0.0),
|
||||
origin.extend(1.0),
|
||||
)
|
||||
}
|
||||
|
||||
/// World-space rotation angle (radians) of the active UCS X axis — the
|
||||
/// default rotation for new text-bearing objects so their text aligns to
|
||||
/// the user's coordinate system. Zero outside model space / with no UCS.
|
||||
pub(super) fn ucs_rotation_angle(&self) -> f64 {
|
||||
if !self.editing_model_space() {
|
||||
return 0.0;
|
||||
}
|
||||
let (_, x, ..) = self.ucs_xform().axes();
|
||||
(x.y as f64).atan2(x.x as f64)
|
||||
}
|
||||
|
||||
/// Grid origin (render/wire space) and UCS→world rotation for grid snap and
|
||||
/// the grid overlay. Identity / origin-at-zero outside model space.
|
||||
pub(super) fn ucs_grid_basis(&self) -> (glam::Vec3, glam::Mat4) {
|
||||
|
||||
Reference in new issue
Block a user