fix(draw): build entities in the world XY plane, not a stale Y-up swap (#54)
The pick/typed point is the world XY plane (z = elevation = 0), but several entity builders still mapped the screen point as if the world were Y-up (drawing in XZ), reading the constant elevation as the DXF Y. That collapsed shapes onto a single line — e.g. a revision cloud always came out as two horizontal lines regardless of the path drawn. Map the drawing-plane point straight through (x→x, y→y, z→elevation) in: revcloud, donut, mline, raster image, wipeout (polygonal + rectangular), table, attribute definition, and tolerance. Previews already used the correct pass-through, so they matched the cursor; only the committed geometry was wrong. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
12e5a4b744
commit
3e493969b6
8 changed files with 14 additions and 14 deletions
|
|
@ -118,7 +118,7 @@ impl CadCommand for TableCommand {
|
||||||
|
|
||||||
fn on_point(&mut self, pt: Vec3) -> CmdResult {
|
fn on_point(&mut self, pt: Vec3) -> CmdResult {
|
||||||
if let Step::Insertion { cols, rows } = self.step {
|
if let Step::Insertion { cols, rows } = self.step {
|
||||||
let ins = Vector3::new(pt.x as f64, pt.z as f64, pt.y as f64);
|
let ins = Vector3::new(pt.x as f64, pt.y as f64, pt.z as f64);
|
||||||
let table = TableBuilder::new(rows, cols)
|
let table = TableBuilder::new(rows, cols)
|
||||||
.at(ins)
|
.at(ins)
|
||||||
.row_height(ROW_HEIGHT)
|
.row_height(ROW_HEIGHT)
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ impl CadCommand for ToleranceCommand {
|
||||||
|
|
||||||
fn on_point(&mut self, pt: Vec3) -> CmdResult {
|
fn on_point(&mut self, pt: Vec3) -> CmdResult {
|
||||||
if let Step::Insertion { text } = &self.step {
|
if let Step::Insertion { text } = &self.step {
|
||||||
let ins = Vector3::new(pt.x as f64, pt.z as f64, pt.y as f64);
|
let ins = Vector3::new(pt.x as f64, pt.y as f64, pt.z as f64);
|
||||||
let tol = Tolerance::with_text(ins, text.clone());
|
let tol = Tolerance::with_text(ins, text.clone());
|
||||||
CmdResult::CommitAndExit(EntityType::Tolerance(tol))
|
CmdResult::CommitAndExit(EntityType::Tolerance(tol))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ impl CadCommand for AttdefCommand {
|
||||||
tag: tag.clone(),
|
tag: tag.clone(),
|
||||||
prompt: prompt.clone(),
|
prompt: prompt.clone(),
|
||||||
default_value: default.clone(),
|
default_value: default.clone(),
|
||||||
insertion_point: Vector3::new(pt.x as f64, pt.z as f64, pt.y as f64),
|
insertion_point: Vector3::new(pt.x as f64, pt.y as f64, pt.z as f64),
|
||||||
height: self.height,
|
height: self.height,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ impl CadCommand for DonutCommand {
|
||||||
fn on_point(&mut self, pt: Vec3) -> CmdResult {
|
fn on_point(&mut self, pt: Vec3) -> CmdResult {
|
||||||
match &self.state {
|
match &self.state {
|
||||||
DonutState::PlaceCenter => {
|
DonutState::PlaceCenter => {
|
||||||
let entity = make_donut(pt.x as f64, pt.z as f64, self.inner_r, self.outer_r);
|
let entity = make_donut(pt.x as f64, pt.y as f64, self.inner_r, self.outer_r);
|
||||||
// Keep command active so user can place more donuts.
|
// Keep command active so user can place more donuts.
|
||||||
CmdResult::CommitEntity(entity)
|
CmdResult::CommitEntity(entity)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ impl CadCommand for MlineCommand {
|
||||||
fn build_mline(pts: &[Vec3], scale: f64, closed: bool, style_name: &str) -> EntityType {
|
fn build_mline(pts: &[Vec3], scale: f64, closed: bool, style_name: &str) -> EntityType {
|
||||||
let verts: Vec<Vector3> = pts
|
let verts: Vec<Vector3> = pts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| Vector3::new(p.x as f64, p.z as f64, p.y as f64))
|
.map(|p| Vector3::new(p.x as f64, p.y as f64, p.z as f64))
|
||||||
.collect();
|
.collect();
|
||||||
let mut mline = if closed {
|
let mut mline = if closed {
|
||||||
MLine::closed_from_points(&verts)
|
MLine::closed_from_points(&verts)
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ impl ImageCommand {
|
||||||
let world_width = ((width_pt.x - origin.x) as f64).abs().max(0.001);
|
let world_width = ((width_pt.x - origin.x) as f64).abs().max(0.001);
|
||||||
let world_height = world_width / self.aspect();
|
let world_height = world_width / self.aspect();
|
||||||
|
|
||||||
let ins = Vector3::new(origin.x as f64, origin.z as f64, origin.y as f64);
|
let ins = Vector3::new(origin.x as f64, origin.y as f64, origin.z as f64);
|
||||||
|
|
||||||
let mut img = RasterImage::with_size(
|
let mut img = RasterImage::with_size(
|
||||||
&self.file_path,
|
&self.file_path,
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ fn make_revcloud(pts: &[Vec3], arc_len: f64) -> EntityType {
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
let p0 = pts[i];
|
let p0 = pts[i];
|
||||||
let p1 = pts[(i + 1) % n];
|
let p1 = pts[(i + 1) % n];
|
||||||
let seg_len = ((p1.x - p0.x).powi(2) + (p1.z - p0.z).powi(2)).sqrt() as f64;
|
let seg_len = ((p1.x - p0.x).powi(2) + (p1.y - p0.y).powi(2)).sqrt() as f64;
|
||||||
if seg_len < 1e-6 {
|
if seg_len < 1e-6 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -117,11 +117,11 @@ fn make_revcloud(pts: &[Vec3], arc_len: f64) -> EntityType {
|
||||||
// How many full arcs fit?
|
// How many full arcs fit?
|
||||||
let num_arcs = ((seg_len / arc_len).round() as usize).max(1);
|
let num_arcs = ((seg_len / arc_len).round() as usize).max(1);
|
||||||
let step_x = (p1.x - p0.x) as f64 / num_arcs as f64;
|
let step_x = (p1.x - p0.x) as f64 / num_arcs as f64;
|
||||||
let step_z = (p1.z - p0.z) as f64 / num_arcs as f64;
|
let step_y = (p1.y - p0.y) as f64 / num_arcs as f64;
|
||||||
|
|
||||||
for j in 0..num_arcs {
|
for j in 0..num_arcs {
|
||||||
let x = p0.x as f64 + step_x * j as f64;
|
let x = p0.x as f64 + step_x * j as f64;
|
||||||
let y = p0.z as f64 + step_z * j as f64; // DXF Y
|
let y = p0.y as f64 + step_y * j as f64; // DXF Y
|
||||||
let mut v = LwVertex::new(Vector2::new(x, y));
|
let mut v = LwVertex::new(Vector2::new(x, y));
|
||||||
v.bulge = bump_bulge;
|
v.bulge = bump_bulge;
|
||||||
vertices.push(v);
|
vertices.push(v);
|
||||||
|
|
|
||||||
|
|
@ -168,18 +168,18 @@ impl CadCommand for WipeoutCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_rect_wipeout(p1: Vec3, p2: Vec3) -> EntityType {
|
fn make_rect_wipeout(p1: Vec3, p2: Vec3) -> EntityType {
|
||||||
// Y-up world: X→DXF X, Z→DXF Y, Y→DXF Z
|
// Drawing plane is world XY (z = elevation).
|
||||||
let c1 = Vector3::new(p1.x.min(p2.x) as f64, p1.z.min(p2.z) as f64, p1.y as f64);
|
let c1 = Vector3::new(p1.x.min(p2.x) as f64, p1.y.min(p2.y) as f64, p1.z as f64);
|
||||||
let c2 = Vector3::new(p1.x.max(p2.x) as f64, p1.z.max(p2.z) as f64, p1.y as f64);
|
let c2 = Vector3::new(p1.x.max(p2.x) as f64, p1.y.max(p2.y) as f64, p1.z as f64);
|
||||||
EntityType::Wipeout(Wipeout::from_corners(c1, c2))
|
EntityType::Wipeout(Wipeout::from_corners(c1, c2))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_poly_wipeout(pts: &[Vec3]) -> EntityType {
|
fn make_poly_wipeout(pts: &[Vec3]) -> EntityType {
|
||||||
use acadrust::types::Vector2;
|
use acadrust::types::Vector2;
|
||||||
let z = pts[0].y as f64;
|
let z = pts[0].z as f64;
|
||||||
let verts: Vec<Vector2> = pts
|
let verts: Vec<Vector2> = pts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| Vector2::new(p.x as f64, p.z as f64))
|
.map(|p| Vector2::new(p.x as f64, p.y as f64))
|
||||||
.collect();
|
.collect();
|
||||||
EntityType::Wipeout(Wipeout::polygonal(&verts, z))
|
EntityType::Wipeout(Wipeout::polygonal(&verts, z))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue