forked from 1b-agent/opencadstudio-upstream
fix: correct arc sweep direction for reversed normals and mirrored blocks
- Arc rendering now respects the normal vector: when normal.z < 0 the midpoint is placed on the clockwise side so the curve sweeps the right way - Removed spurious .to_radians() / .to_degrees() round-trips in arc.rs (angles are already stored in the unit the trig functions expect) - apply_grip and apply_transform use consistent angle units - normalize_insert_entity no longer converts arc angles; the old conversion was only needed by the now-removed .to_radians() call in to_truck - Added fix_mirrored_arc: swaps arc start/end angles when the INSERT has a mirrored scale (x_scale * y_scale < 0) so exploded arcs curve correctly Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
1 parent
a255b99863
commit
e2f5715de8
3 files changed
+47
-30
No files matched your search
@@ -49,11 +49,14 @@ pub fn explode_entity(entity: &EntityType, document: &CadDocument) -> Vec<Entity
|
||||
EntityType::Polyline2D(p) => explode_polyline2d(p),
|
||||
EntityType::Polyline(p) => explode_polyline(p),
|
||||
EntityType::Polyline3D(p) => explode_polyline3d(p),
|
||||
EntityType::Insert(ins) => ins
|
||||
.explode_from_document(document)
|
||||
.into_iter()
|
||||
.map(normalize_insert_entity)
|
||||
.collect(),
|
||||
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::MLine(ml) => explode_mline(ml),
|
||||
EntityType::Dimension(dim) => explode_dimension(dim),
|
||||
_ => vec![],
|
||||
@@ -140,10 +143,6 @@ fn explode_polyline2d(p: &Polyline2D) -> Vec<EntityType> {
|
||||
|
||||
pub fn normalize_insert_entity(mut entity: EntityType) -> EntityType {
|
||||
match &mut entity {
|
||||
EntityType::Arc(arc) => {
|
||||
arc.start_angle = arc.start_angle.to_degrees();
|
||||
arc.end_angle = arc.end_angle.to_degrees();
|
||||
}
|
||||
EntityType::Ellipse(ell) => {
|
||||
let major_len = ell.major_axis_length();
|
||||
let full_span = {
|
||||
@@ -170,14 +169,26 @@ pub fn normalize_insert_entity(mut entity: EntityType) -> EntityType {
|
||||
entity
|
||||
}
|
||||
|
||||
pub fn normalize_entity_for_block(mut entity: EntityType) -> EntityType {
|
||||
if let EntityType::Arc(arc) = &mut entity {
|
||||
arc.start_angle = arc.start_angle.to_radians();
|
||||
arc.end_angle = arc.end_angle.to_radians();
|
||||
}
|
||||
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<EntityType> {
|
||||
let n = p.vertices.len();
|
||||
if n < 2 {
|
||||
|
||||
Reference in new issue
Block a user