From 200f10fd25df35576bccfa0768b8a3179e0a3fd1 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Tue, 12 May 2026 22:04:12 +0300 Subject: [PATCH] fix(explode): correct arc/ellipse direction in mirrored INSERT blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrored INSERTs reverse OCS handedness, but acadrust's explode used to keep the original normal — making CCW-around-normal arcs and ellipses sweep the wrong way. The fix lives in acadrust 7c711e9, which flips the new normal when det < 0 and reprojects center/major_axis/angles into the new OCS. H7CAD's fix_mirrored_arc workaround is no longer needed. --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/modules/home/modify/explode.rs | 29 +++++------------------------ src/scene/mod.rs | 2 -- 4 files changed, 7 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 448c75dac..b5e893e0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" [[package]] name = "acadrust" version = "0.3.4" -source = "git+https://github.com/hakanaktt/acadrust#4025fd212880dfaa9bcb8b0a52b0bc2b3d2d4415" +source = "git+https://github.com/HakanSeven12/acadrust?rev=7c711e9#7c711e9d4bb8fd7e21ea449e335cee9da24d37de" dependencies = [ "ahash", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index f8a64291f..797b2c154 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,4 +23,4 @@ rayon = "1" windows-sys = { version = "0.59", features = ["Win32_UI_Shell", "Win32_UI_WindowsAndMessaging"] } [patch.crates-io] -acadrust = { git = "https://github.com/hakanaktt/acadrust" } +acadrust = { git = "https://github.com/HakanSeven12/acadrust", rev = "7c711e9" } diff --git a/src/modules/home/modify/explode.rs b/src/modules/home/modify/explode.rs index 112767766..230bbd22c 100644 --- a/src/modules/home/modify/explode.rs +++ b/src/modules/home/modify/explode.rs @@ -49,14 +49,11 @@ pub fn explode_entity(entity: &EntityType, document: &CadDocument) -> Vec explode_polyline2d(p), EntityType::Polyline(p) => explode_polyline(p), EntityType::Polyline3D(p) => explode_polyline3d(p), - EntityType::Insert(ins) => { - let is_mirrored = ins.x_scale() * ins.y_scale() < 0.0; - ins.explode_from_document(document) - .into_iter() - .map(normalize_insert_entity) - .map(|sub| fix_mirrored_arc(sub, is_mirrored)) - .collect() - } + EntityType::Insert(ins) => ins + .explode_from_document(document) + .into_iter() + .map(normalize_insert_entity) + .collect(), EntityType::MLine(ml) => explode_mline(ml), EntityType::Dimension(dim) => explode_dimension(dim), _ => vec![], @@ -173,22 +170,6 @@ pub fn normalize_entity_for_block(entity: EntityType) -> EntityType { entity } -/// Swap arc start/end angles when the INSERT that produced the entity was -/// mirrored (exactly one of x_scale / y_scale is negative). The acadrust -/// explode recalculates endpoint positions correctly but does not reverse the -/// sweep direction, so the arc would otherwise curve the wrong way. -pub fn fix_mirrored_arc(entity: EntityType, is_mirrored: bool) -> EntityType { - if !is_mirrored { - return entity; - } - if let EntityType::Arc(mut arc) = entity { - std::mem::swap(&mut arc.start_angle, &mut arc.end_angle); - EntityType::Arc(arc) - } else { - entity - } -} - fn explode_lwpolyline(p: &LwPolyline) -> Vec { let n = p.vertices.len(); if n < 2 { diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 5e9147fb1..d70310f4a 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -3788,7 +3788,6 @@ fn tessellate_entity( } if let EntityType::Insert(ins) = e { - let is_mirrored = ins.x_scale() * ins.y_scale() < 0.0; // Resolve the INSERT's own style so ByBlock sub-entities can inherit it. let (ins_color, ins_pat_len, ins_pat, ins_lw_px, _) = render::render_style_for(document, e); let ins_color = render::adapt_to_bg(ins_color, bg_color); @@ -3797,7 +3796,6 @@ fn tessellate_entity( .iter() .cloned() .map(crate::modules::home::modify::explode::normalize_insert_entity) - .map(|sub| crate::modules::home::modify::explode::fix_mirrored_arc(sub, is_mirrored)) .flat_map(|sub| { let (sub_color, sub_pattern_length, sub_pattern, sub_line_weight_px, sub_aci) = render::render_style_for_block_sub(