fix(task-14): polyline bulges leave the backends in WCS, so a mirrored arc reads on its true side
The per-vertex `bulges` list was handed out in the entity's own frame next
to `points` that had been translated to WCS. A mirrored LWPOLYLINE
(extrusion / Normal -Z, what `entity_mirror` produces) is a reflection,
which reverses every arc's sense, so the reader tested endpoints against
the arc's mirror image: a line ending on the true apex dangled, a line
ending on empty paper made a junction, and `length` (frame-invariant)
said nothing. Both engines had it — ezdxf emitted `get_points("xyb")`
raw, COM returned `GetBulge` raw after reflecting `Coordinates`.
`ocs.wcs_bulge(extrusion, bulge)` now negates the sign for a left-handed
frame (the same rule `wcs_arc_angles` applies to an ARC's endpoints) and
both `_entity_info` paths route bulges through it whenever they translate
the points. Fenced by an end-to-end mirrored-pipe graph test, the COM
`_entity_info` fake with Normal -Z, and a boundary-level OCS test.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
co-authored by
Claude Opus 5
parent
8fcd587b5b
commit
8b6f355c3d
@@ -815,8 +815,13 @@ def _entity_info_dxf(ent) -> EntityInfo:
|
||||
props["length"] = round(_length, 6)
|
||||
# The bulge of the segment leaving each vertex (DXF convention), so
|
||||
# a reader that walks `points` can test against the arc the drawing
|
||||
# holds instead of the chord it does not. Parallel to `points`.
|
||||
props["bulges"] = [b for _x, _y, b in _verts]
|
||||
# holds instead of the chord it does not. Parallel to `points`, and
|
||||
# in the same frame as them: a mirrored polyline's frame is a
|
||||
# reflection, which reverses every arc's sense, so the stored sign
|
||||
# next to translated points would describe the arc's mirror image.
|
||||
props["bulges"] = [
|
||||
ocs.wcs_bulge(extrusion, b) if needs_ocs else b for _x, _y, b in _verts
|
||||
]
|
||||
if ent.closed:
|
||||
props["area"] = round(_area, 6)
|
||||
elif ent_type == "TEXT":
|
||||
|
||||
Reference in New Issue
Block a user