forked from 1b-agent/opencadstudio-upstream
fix: dimension line geometry and DXF rotation unit mismatch
append_linear_dimension() applied the same perp offset to both d1 and d2, but only d2 is guaranteed to be at the definition_point level; d1 must be projected independently onto the dimension line, otherwise non-collinear first/second points produce a parallelogram instead of a rectangle. Fix: compute dim_line_pos = def.dot(perp) and project each endpoint separately so the dimension line is always parallel to axis. Additionally, the acadrust DXF reader stores LinearDimension.rotation from group code 50 (degrees) without converting to radians, while DWG and our own annotation commands store it in radians. Add a post-load fixup in load_file() that converts the rotation to radians for DXF files so tessellation can call cos/sin uniformly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
2255dc5176
commit
19bb846c50
2 files changed
+25
-7
No files matched your search
+22
-4
@@ -11,6 +11,7 @@ pub mod step;
|
||||
pub mod stl;
|
||||
pub mod xref;
|
||||
|
||||
use acadrust::entities::{Dimension, EntityType};
|
||||
use acadrust::io::dwg::DwgReader;
|
||||
use acadrust::{CadDocument, DwgWriter, DxfReader, DxfWriter};
|
||||
use std::path::{Path, PathBuf};
|
||||
@@ -60,10 +61,14 @@ pub fn load_file(path: &Path) -> Result<CadDocument, String> {
|
||||
let mut reader = DwgReader::from_file(path).map_err(|e| e.to_string())?;
|
||||
reader.read().map_err(|e| e.to_string())
|
||||
}
|
||||
"dxf" => DxfReader::from_file(path)
|
||||
.map_err(|e| e.to_string())?
|
||||
.read()
|
||||
.map_err(|e| e.to_string()),
|
||||
"dxf" => {
|
||||
let mut doc = DxfReader::from_file(path)
|
||||
.map_err(|e| e.to_string())?
|
||||
.read()
|
||||
.map_err(|e| e.to_string())?;
|
||||
fix_dxf_dimension_rotations(&mut doc);
|
||||
Ok(doc)
|
||||
}
|
||||
_ => Err(format!("Unsupported file format: .{ext}")),
|
||||
}
|
||||
}
|
||||
@@ -162,3 +167,16 @@ pub fn save_dxf(doc: &CadDocument, path: &Path) -> Result<(), String> {
|
||||
.write_to_file(path)
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
// ── DXF post-load fixups ──────────────────────────────────────────────────
|
||||
|
||||
/// The acadrust DXF reader stores LinearDimension.rotation directly from DXF
|
||||
/// group code 50, which is in degrees. DWG and our own dimension-creation code
|
||||
/// store it in radians. Convert so tessellation can call cos/sin uniformly.
|
||||
fn fix_dxf_dimension_rotations(doc: &mut CadDocument) {
|
||||
for entity in doc.entities_mut() {
|
||||
if let EntityType::Dimension(Dimension::Linear(d)) = entity {
|
||||
d.rotation = d.rotation.to_radians();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -707,9 +707,9 @@ fn append_linear_dimension(
|
||||
axis: Vec3,
|
||||
) {
|
||||
let perp = Vec3::new(-axis.y, axis.x, 0.0);
|
||||
let offset = (def - first).dot(perp);
|
||||
let d1 = first + perp * offset;
|
||||
let d2 = second + perp * offset;
|
||||
let dim_line_pos = def.dot(perp);
|
||||
let d1 = first + perp * (dim_line_pos - first.dot(perp));
|
||||
let d2 = second + perp * (dim_line_pos - second.dot(perp));
|
||||
add_segment(points, first, d1);
|
||||
add_segment(points, second, d2);
|
||||
add_segment(points, d1, d2);
|
||||
|
||||
Reference in new issue
Block a user