Commit Graph
3 Commits
Author SHA1 Message Date
Umut CANandClaude Opus 5.5 cdff63fce0 fix(understand): a DWG the operator has open is exported as it stands, never closed
On the live engine, take_snapshot read a .dwg path by calling
Documents.Open(path, read-only), exporting and then Close(False) on what
Open returned. If the operator already had that drawing open, that was
their document, and closing it unsaved could throw away unsaved work.
drawing_understand, drawing_scale_check, drawing_diff and the takeoffs all
read a path through this function.

The review of drawing_diff raised the risk and did not probe it live, to
avoid a modal dialog on the shared AutoCAD. The fix makes the question
moot: the path is looked up among the open documents first, case-blind as
Windows paths are, and an open drawing is exported as it stands (unsaved
edits included) and left open. Only a document opened here is closed here.
The new test, against the fake that behaves as measured, fails on the old
code with an open and a close in the log.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
2026-09-24 12:24:02 +03:00
Umut CANandClaude Opus 5.5 efa1ea8182 fix(understand): a truncated DXF is refused by the snapshot, not left hanging
ezdxf's tag reader raises StopIteration on a file that ends early, for example
after an interrupted save or a partial copy. read_snapshot caught only OSError
and DXFError, so the StopIteration escaped. asyncio.to_thread cannot hand
StopIteration back to an awaiting caller, so every track H tool reading such
a file would have hung instead of refusing it.

The review of drawing_diff found this in its own reader. The snapshot now
does the same: every parse or walk failure except MemoryError becomes the
existing "is not a readable DXF file" refusal. A new test checks this both
directly and through a worker thread with a 10 s timeout. It failed with
StopIteration before this change and passes after it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
2026-09-24 12:22:23 +03:00
Umut CANandClaude Opus 5.5 9ab0ae1773 feat(understand): the snapshot, the vocabulary and the label parsers; MAX_DXF_BYTES 512 MB; the office extra
Track H's foundation, landed on main before its three groups branch.

- engineering/understand/snapshot.py: one bulk read of a drawing into frozen
  WCS records (OCS translated through backends/ocs.py, text decoded, an
  INSERT boxed by its block geometry without its attribute texts). A DXF is
  read with ezdxf after the size check; the headless engine's document is
  read under its own lock; the live engine exports the active document with
  Document.Export(<tmp>/snap, "DXF", <set of all>) - never renamed, deleted
  afterwards - and a DWG is opened read-only, exported and closed. Measured on
  AutoCAD 2026: ".dxf" is refused with Invalid argument, the file lands as
  snap.DXF, model space, paper space and unused block definitions all reach
  it, and the selection set does not narrow a DXF export.
- engineering/understand/labels.py: %%c, \U+2205, the U+2300 sign, o-stroke
  and MTEXT format runs all read as one diameter spelling; sizes are kept as
  drawn and never equated; Cyrillic look-alike capitals fold into Latin tags;
  panels, wiring callouts and electrical data (kW, phases, volts, N, VFD) in
  EN / TR / RU / NL / DE. A power that is not written stays None.
- engineering/understand/vocab.py: layer classification with a confidence and
  the deciding keyword, supply / return words, room labels and block kinds in
  five languages. A CIP layer without a direction word is not guessed.
- MAX_DXF_BYTES defaults to 512 MB (a real layout was 188 MB); the refusal
  names the size and the variable. New `office` extra (openpyxl), also in
  `full`; uv.lock regenerated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
2026-09-24 11:38:59 +03:00