Commit Graph
52 Commits
Author SHA1 Message Date
Hakan SevenandClaude Opus 5.5 2e47e1fa95 chore: pin opencadcodec ad16215, opencadkernel 1e02630
Brings in the DWFFRAME/DGNFRAME header variables (codec #63) and robust 2D tangency plus ellipse-circle intersection (kernel #68). Pins opencadcodec ad16215, opencadkernel 1e02630, opencadgraph 7ef5ae4.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-28 13:45:11 +03:00
Hakan SevenandClaude Opus 5.5 df2778f466 chore: pin opencadcodec a35f43e (R13/R14 layers plottable)
Brings in bounded object storage on DWG import (#62) and R13/R14 LAYER
records reading as plottable. Pins opencadcodec a35f43e, opencadkernel
ee41029, opencadgraph 8b8c7f3.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-28 10:13:04 +03:00
Hakan SevenandClaude Opus 5.5 b7498b176c chore: pin opencadcodec 42b44d2 (DXF saves polar stretch actions)
Pins opencadcodec 42b44d2, opencadkernel 4e67cd7, opencadgraph d89a9c5.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 13:04:21 +03:00
Hakan SevenandClaude Opus 5.5 315df5cd47 chore: pin opencadcodec 4f7bd51 (merlinnot codec fixes #56-#61)
Brings in: unchanged ACSH extrusion history and DIMASSOC records kept
byte for byte; native dynamic-action field layouts corrected; evaluation
graph expressions written as owned; evaluated block metadata copy;
source class numbers kept on same-version legacy saves; explicit block
attribute flags kept.

The dynamic-action model now names its fields after their native
meaning, so the object summaries read parameter ids, the move offsets'
distance multiplier and the lookup table's columns. The empty
PropertiesTable variant is gone; such tables stay opaque objects.

Pins opencadcodec 4f7bd51, opencadkernel 8186605, opencadgraph 048c9c5.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 07:11:40 +03:00
Hakan SevenandClaude Opus 5.5 89512c2f20 fix(text): no stroke-font tracking after big-font and fallback glyphs (#1470)
Every glyph advanced by the face's letter spacing, including CJK glyphs a
style's big font or the TrueType fallback supplies. Their advances already
carry the gap (big font) or side bearings (TrueType), so with an LFF primary
such as iso each ideograph took 1.33 heights instead of one.
Face::spacing_after(ch) gives the tracking only to glyphs the stroke font
draws itself; every layout path uses it.

The 1.8-height widths in the report were the TEXT bounds estimate counting
UTF-8 bytes; opencadcodec 1109d52 counts characters.

Pins opencadcodec 1109d52, opencadkernel 8a246b0, opencadgraph 3c4af1c.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-25 21:27:17 +03:00
Hakan SevenandClaude Opus 5.5 fdc01e13c8 fix(render): show Inventor drawing views, each in its own viewport (#1285)
Inventor DWG exports place every sheet block with AcIdBlockReference,
which the codec skipped, so these drawings opened blank. opencadcodec
7c20aa7 decodes it as an INSERT and keeps the viewport each model-space
view reference is bound to.

Those view blocks overlap in model space, so a content viewport now also
hides model-space references bound to a different viewport. The handles
join the viewport's frozen-layer set (entity and layer handles never
collide), which the wire and render-graph visibility checks and every
per-viewport cache key already use.

Pins opencadcodec 7c20aa7, opencadkernel d71a828, opencadgraph 1543a5a.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-25 19:48:36 +03:00
Hakan SevenandClaude Opus 5.5 857f2f2e58 feat(graph): save and open node graphs as .ocg files
The graph panel gets New, Open and Save. A .ocg file is JSON holding the
graph (nodes, parameters, links), the canvas (positions, open sections,
pan, zoom) and each object node's entity handles, plus the fingerprint
GUID of the drawing those entities live in. On open, handles are reused
only in that same drawing and only while the entity is still the node's
kind; otherwise evaluation creates new entities, so a graph opened in
another drawing never takes over unrelated objects. A drawing without a
fingerprint gets one when its graph is first saved.

Pins opencadcodec d6d534f (DXF now writes $FINGERPRINTGUID and
$VERSIONGUID), opencadkernel 5d9e921 and opencadgraph 5c9b004 (graph
JSON round trip).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-25 08:14:56 +03:00
Hakan SevenandClaude Opus 5.5 f537aff75c feat: node graph overlay; move to opencadcodec/opencadkernel/opencadgraph
The codec and kernel repositories and crates are renamed opencadcodec and
opencadkernel. Inside OCS they are depended on under short keys, so code
reads `codec::`, `kernel::` and the new `graph::` (opencadgraph, the node
graph engine). File-format and protocol spellings stay as they were: the
ACIS product id `acadrust`, the ACADRUST_* switches and the plugin
version keys `acadrust_version` / `acadrust_source`.

A button left of MCP on the command line opens a translucent node graph
over the viewport, with a palette of object, input, math, logic, list,
text and geometry nodes added by click or drag. An object node owns
drawing entities and its rows are the Properties panel's own rows for
them: the single-object page is extracted from refresh_properties as
entity_property_sections, values use the control protocol's
property_json, and writes go through set_property_value with a property
target override, so the panel, MCP and the graph share one read/write
path. A list reaching an object row makes one entity per element. Each
graph action is one undo step; the canvas pans and zooms.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-25 07:34:23 +03:00
Hakan SevenandClaude Opus 5.5 6d9365ea88 fix(xclip): follow-ups to the XCLIP merge
- An inverted clip's roundtrip record goes in the filter's extension
  dictionary through the codec's own API (ensure_extension_dictionary /
  xrecord / extension_dictionary_handle) instead of a scan of every
  object, which the renderer ran for each clipped reference.
- Pin cadcodec 1c3be0c (the DXF writer now links a spatial filter's
  extension dictionary, so that record is not left unreferenced) and
  cadkernel deb529b; plugin crates and the Python plugin lock follow.
- The XCLIP boundary preview stays f64.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-24 23:46:50 +03:00
Hakan SevenandClaude Opus 5.5 d5016c7044 fix(pdf): follow-ups to the PDF underlay merge
- Pin cadcodec upstream at d290dbe (the merged underlay change) and
  cadkernel at 4134ae3, which follows it; drop the fork patch, move the
  plugin-API and web-worker crates and the Python plugin lock to the same
  codec so one copy is built.
- "Import as block" with raster images left IMAGE entities without an
  image definition: block definition now creates it like add_entity does,
  through one shared helper.
- The three preview outlines (attach frame, clip boundary, import area)
  stay f64 instead of casting world points to f32.
- Page size / total / PDF scale entries use the catalog's positional
  placeholder; the bare {name} form failed to format in 20 locales.
- The Underlay Layers bulb is the SVG layer icon, not a text glyph.
- PDF dialogs use the shared dialog buttons and radios.
- Options opened from a PDF dialog clears its saved state on return.
- Paper-space underlay background reuses the model block handle already
  resolved; dead `let _ = i` lines and a misplaced doc comment removed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-24 23:24:51 +03:00
Hakan SevenandClaude Opus 5.5 a479dd11d1 chore: pin cadcodec at dd1d7bf and cadkernel at 6eae7c9
Brings in the DXF round-trip fixes merged as cadcodec #48 and #51 and the
block-definition fixes for cadcodec issues #49 and #52. cadkernel moved to
the same codec revision first, so the graph keeps a single acadrust. The
Python plugin, which is outside the workspace, has its own lock moved too:
its staging script requires the plugin and the host to share one acadrust
source.

The canaries that asserted the old wrong results were flipped against the
real-IPC audits, all 60 of which pass with the plugin built: Helix, Light,
Underlay, ViewBorder and SectionSymbol now round-trip through DXF, as do the
text style flags, the dimension style's text style name, the block
description, the table's merged ranges and the leader's annotation link and
vectors. Those five kinds move to Complete in the coverage ledger.

Two narrower gaps stay pinned. The ATTDEF writer emits no group 280, so
`lock_position` is still lost on a DXF save; every other field now
survives. A true-colour leader `override_color` cannot be held by DXF group
77, which takes an ACI index, and the DWG writer does not store it.

Behaviour change for users: a text style's oblique angle is now written to
DXF in degrees, as the format defines it. DXF files written by earlier
versions carry radians there and reopen with a much smaller slant.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-23 17:49:34 +03:00
Felix RiestraandClaude Sonnet 5 8f68006bea docs: make the change ready for upstream review
Remove personal names, local paths and fork-only process notes from code comments,
docs and the plugin manifest (repository now points at the upstream project), and
drop the handoff section from the plan.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 22:35:09 +02:00
Felix RiestraandClaude Sonnet 5 d2c2ef178b docs: record cadcodec PR #51 for the text and dimension style DXF fixes
Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 18:55:42 +02:00
Felix RiestraandClaude Sonnet 5 2ed41586de feat: SCRIPTCOMMANDS setting to turn script-driven commands off
A saved user preference (on by default) toggled by the SCRIPTCOMMANDS command
gates HostApi::run_command; Cancel stays allowed so a waiting command is never
stranded. The runner refuses the SCRIPTCOMMANDS command itself, so a script
cannot change it. Documents why no helper-thread or stack-growing dependency was
added: native builds link with at least 8 MiB, the nesting depth is fixed, and the
deepest step found needs 2 to 4 MiB in a debug build.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 18:48:27 +02:00
Felix RiestraandClaude Sonnet 5 a25ae4f8c0 chore: clear compiler warnings introduced by the Python host work
Drop two unneeded mut bindings in tests and mark the generated dict/enum
converters allow(dead_code), since a kind can leave one unused.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 18:31:23 +02:00
Felix RiestraandClaude Sonnet 5 8eb85dab8d docs: final review pass over the Python host documentation
Rewrite the host-model design note for the current architecture (entities, tables,
commands, nested validation, known limits), refresh the plan's current-state header,
the ledger and gaps-doc status lines (cadcodec PR #48), the README status and the
superseded ocs.command notes, and drop dangling references to a sibling project that
is not in this repository.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 18:27:59 +02:00
Felix RiestraandClaude Sonnet 5 b180dce1a1 feat(python): PEDIT polyline wrappers and path/3-D arrays
polyline_close/open/width/reverse/join (a line or arc is turned into a polyline
first), array_path and array_3d, written against observed prompts and checked
for exact geometry in the real-IPC audit. Polylines default their pick point to
the first vertex. The audit runs on a large-stack thread because PEDIT's
line-to-polyline step needs more than a test thread's 2 MiB in a debug build.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 17:57:58 +02:00
Felix RiestraandClaude Sonnet 5 81251d9cf3 fix(python): validate nested input (vertices, edges) instead of defaulting silently
The generated dict-to-struct conversions for nested records defaulted every
absent field and ignored unknown keys, so an LwPolyline built from
{'x': .., 'y': ..} vertices became zero-coordinate vertices. They now refuse an
unknown key (naming the keys the record takes) and a manifest list,
required_struct_fields, enforces the fields that define a nested record's
geometry (vertex locations, hatch edge ends and centres, section symbol points).
Regression test over real IPC; every existing lifecycle audit still passes.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 17:42:35 +02:00
Felix RiestraandClaude Sonnet 5 360dd853ed feat(python): chamfer, arrays, explode, join, break, stretch and lengthen wrappers
Each is written against the prompt sequence observed in the exploration harness
and checked for exact geometry in the real-IPC audit. HATCH is left to
create_entity because its command needs an interactive boundary pick.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 17:34:18 +02:00
Felix RiestraandClaude Sonnet 5 1b1785eefb feat(python): command runner and modify wrappers (doc.command, doc.modify)
HostApi::run_command drives the real OCS command through the same primitives
the automation channel uses, synchronously on the host thread: run a line,
start a command and answer point/text/token/entity/selection/enter prompts, or
cancel (closing anything the command opened). Refused while another command is
active, for a denylist (QUIT, NEW, OPEN, SAVE*, PY_* ...) and off the active tab.
Python: doc.command, doc.start_command and doc.modify (offset, trim, extend,
fillet, move, copy, rotate, scale, mirror, erase). Real-IPC audit checks exact
geometry for every wrapper plus guards and undo; IPC and Python unit tests; docs.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 17:25:05 +02:00
Felix RiestraandClaude Sonnet 5 795aa922b4 feat(python): linetypes and layouts (doc.linetypes, doc.layouts)
TableOperation gains simple-linetype create/modify/rename/delete (standard names
taken, rename follows layers and entities, guarded delete) and paper-space
layout create/rename/delete/set-current/set-page (default page setup and sheet
viewport, the application's own layout switch, Model protected). CTAB now reports
the current layout. Real-IPC audit with DWG/DXF persistence and undo, IPC and
Python unit tests, docs.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 17:05:48 +02:00
Felix RiestraandClaude Sonnet 5 b1edc9f578 feat(python): block contents (create_entity(..., block=))
BlockEntityAdd adds a validated entity to a block definition (owner set by the
host, same validation as a model-space entity, self-nesting inserts refused),
reusing the scene's block-editor routing. Deleting a block member now also
drops its handle from the block record. Real-IPC audit with an attribute
definition inside a block, DWG/DXF persistence and undo; IPC and Python unit
tests; docs.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 16:54:30 +02:00
Felix RiestraandClaude Sonnet 5 8d20d280fe feat(python): block definitions (doc.blocks)
TableOperation gains BlockCreate (copy entities into a definition shifted by the
base point, optionally erasing originals), BlockModify, BlockRename (inserts
follow) and BlockDelete (refused while referenced; removes members, markers and
orphaned draw-order tables). Real-IPC audit with DWG/DXF persistence and undo,
IPC and Python unit tests, docs; the DXF loss of the block description is pinned
by a canary.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 16:28:03 +02:00
Felix RiestraandClaude Sonnet 5 aaea15e4ef feat(python): text and dimension styles (doc.text_styles, doc.dim_styles)
Extends TableOperation with text style create/modify, dimension style
create/modify (DimStyle fields as a validated JSON object), rename, delete and
set-current. Reuses OCS's style in-use scan and reference-following rename
(four style_ops methods widened to pub(super)); a renamed text style also
updates dimension styles that name it. Real-IPC audit with DWG/DXF persistence
and undo, IPC and Python unit tests, docs. Four cadcodec findings are pinned by
canaries.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 16:18:22 +02:00
Felix RiestraandClaude Sonnet 5 b7b6e2cef5 feat(python): validated, undoable layer table (doc.layers)
Adds the additive v7 TableOperation request and HostApi::table_operation for
layer create/modify/rename/delete/set-current. Refusals are decided before the
undo step is recorded. Python wrapper, real-IPC audit with DWG/DXF persistence,
IPC round-trip test, Python unit test and docs.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-21 16:00:26 +02:00
Felix RiestraandClaude Sonnet 5 6e2e073e29 Complete Viewport: layout-tab canvas oracle, unique ids, derived scale
The shared driver now activates the layout that owns a viewport and requires
a drawn frame. The host assigns a unique id of at least 2 and derives
custom_scale as height / view_height on every scripted create or edit, as
MVIEW does, so custom_scale is read-only. A control showed the default id 0
is not invisible, so the id matters for uniqueness.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 18:53:32 +02:00
Felix RiestraandClaude Sonnet 5 5e6a830782 Complete Ole2Frame: embed a picture file from a script
EmbedPicture builds the frame with OCS's own EmbeddedImage and
build_embedded_ole, so the opaque storage is never scripted. PNG, JPEG and
BMP are stored as read and other formats are re-encoded as PNG. The lifecycle
test now creates through Python; a new test covers formats, aspect, origin,
layer and refusals.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 18:12:31 +02:00
Felix RiestraandClaude Sonnet 5 942222c381 Map SectionSymbol, the last unmapped kind
points is canonical; the host derives the point counts and refreshes the
end/tick/label projections with sync_display_fields when it changes, and
validates that style and view-representation references are existing class
objects. The lifecycle test passes every gate in DWG; DXF reopens the symbol
as an unknown entity because cadcodec dispatches SECTIONLINE only inside
blocks (pinned by a canary and already in the cadcodec write-up).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 18:05:38 +02:00
Felix RiestraandClaude Sonnet 5 5a39052397 Add kernel booleans: union, subtract and intersect for Solid3D
SolidOperation::Boolean runs synchronously, surfaces the kernel's refusal
with a plain reason and leaves the operands untouched, consumes them on
success unless keep_operands, and records one undo step. The lifecycle test
uses planar boxes with exact volumes and covers chaining, refusals, both
formats and undo; an ignored test shows a curved refusal reaching the script.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 17:58:38 +02:00
Felix RiestraandClaude Sonnet 5 9cd6653a58 Complete Surface: plane surfaces, extrusions, isolines and moves
Adds SurfaceFromProfile and Extrude kernel operations (doc.solids.surface and
doc.solids.extrude), accepts surfaces in Transform, and maps Surface with
editable isolines. Fixes a real bug found by the test: the surface kind field
overwrote the entity-type kind key in Python dicts, so it is exposed as
surface_kind, with a catalog test guarding against name collisions.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 17:47:22 +02:00
Felix RiestraandClaude Sonnet 5 918351f264 Fix create_entity for a schema without property rows; test tuple coercion
The Python unit test's fake host omits the properties list the real host
always supplies. The coercion tolerates its absence, and a new test covers
tuples for point properties and lists of them. The previous commit slipped
past the Python tests because the gate did not include them.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 17:38:31 +02:00
Felix RiestraandClaude Sonnet 5 c731d3a9a4 Complete Region: create from a profile, plus tuple and int friendliness
RegionFromProfile reuses the REGION command's kernel calls; doc.solids.region
exposes it with layer and delete_source options. The lifecycle test builds
regions from real circle and polyline entities and covers refusals, a move,
both formats and undo. create_entity now accepts coordinate tuples for point
properties and every generated float setter accepts Python ints.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 17:37:10 +02:00
Felix RiestraandClaude Sonnet 5 04cd9e462d Add kernel solid operations and complete Solid3D (create and rigid move)
An additive HostApi::solid_operation builds cadkernel primitives and applies
rigid transforms, verifying each result lifts back losslessly and refusing a
payload it cannot lift. Exposed as doc.solids in Python; Solid3D, Body and
Region are mapped read-only with the opaque payload preserved. The lifecycle
test passes through the real runner with analytic volumes and exact extents as
oracles, DWG and DXF reopen with re-edit, and undo restores exactly.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 17:29:06 +02:00
Felix RiestraandClaude Sonnet 5 e583da83db Map Ole2Frame as update-only with the embedded object preserved
Frame corners and the aspect lock are scriptable; the opaque storage and
envelope are excluded and refused on edit. The audit embeds a real PNG
through OCS's own builder and proves it survives DWG and DXF byte-for-byte.
Python creation stays a follow-up.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 16:43:25 +02:00
Felix RiestraandClaude Sonnet 5 eb22de636b Decide Insert and Polyline: Insert creatable by block name, Polyline update-only
Insert can be created by naming an existing ordinary block; the host refuses
unknown blocks, model/paper space and containment cycles, and keeps legacy
inserts of missing blocks editable. The legacy Polyline is update-only with a
hint toward Polyline2D and Polyline3D because both writers convert it on
save. The generator gains update_only_message.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 16:14:02 +02:00
Felix RiestraandClaude Sonnet 5 bfb5e7576b Merge origin/main into plugin/host-model-api
Picks up cadcodec 5b682ed and cadkernel 6f046af and the plotstyle
layer-usage speedup. The adapter's Cargo.lock now resolves acadrust to
5b682ed. All host, API and adapter tests pass and no acadrust canary
assertion tripped.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 15:29:55 +02:00
Felix RiestraandClaude Sonnet 5 12b0823e76 Map Light; record SectionSymbol as blocked
Light placement, intensity, colour, attenuation and shadow fields are
writable with host validation. staged_python_light_lifecycle_over_real_ipc
passes every gate except DXF cast_shadows, pinned by a canary.
SectionSymbol is recorded as blocked: it needs host-created style and view
representation objects and its raw point counts have no documented
derivation.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 15:18:13 +02:00
Felix RiestraandClaude Sonnet 5 21ce4b0e2b Map ViewBorder in the Python host model; record DXF kind blocker
Bounds, scale and rotation are writable with viewport and scale reference
rules. staged_python_view_border_lifecycle_over_real_ipc passes every gate
in DWG; a DXF DRAWINGVIEW reopens as an opaque entity, pinned by a canary.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 15:13:23 +02:00
Felix RiestraandClaude Sonnet 5 9075e53511 Map Viewport in the Python host model
Curated view fields are writable; the owner must be a paper-space block and
frozen layers must exist. staged_python_viewport_lifecycle_over_real_ipc
passes every gate except a paper-space canvas oracle, so the kind is
recorded as integration-tested.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 15:09:23 +02:00
Felix RiestraandClaude Sonnet 5 2e4d77dc09 Map Underlay in the Python host model; record DXF rotation blocker
Scripts place an underlay against an existing UnderlayDefinition; the host
checks that the definition exists and matches the underlay type.
staged_python_underlay_lifecycle_over_real_ipc passes every gate except DXF
persistence: acadrust's reader returns the degree-valued rotation
unconverted and repeated saves compound it. Pinned by canary expectations.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 15:05:11 +02:00
Felix RiestraandClaude Sonnet 5 96e3b54f08 Complete Wipeout host model coverage
Maps the placement, display and clip-boundary fields with rectangular and
polygonal clip validation. staged_python_wipeout_lifecycle_over_real_ipc
passes the full gate including DWG and DXF reopen with re-edit.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 15:00:04 +02:00
Felix RiestraandClaude Sonnet 5 7f65d6d373 Map RasterImage with host-created image definitions
Scripts name an image file; the host reads its pixel size, creates and links
the ImageDefinition and derives size and the default clip boundary.
staged_python_raster_image_lifecycle_over_real_ipc passes every gate in OCS
with a real PNG. ACAD_IMAGE_DICT and reactor linkage are not created, so the
kind is recorded as integration-tested.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:55:29 +02:00
Felix RiestraandClaude Sonnet 5 d4c2520907 Map Helix in the Python host model; record DXF handedness blocker
The host rebuilds the derived spline from the generating parameters on
scripted create/edit. staged_python_helix_lifecycle_over_real_ipc passes
every gate except DXF handedness, which acadrust's reader never applies;
the gap is pinned by a canary via per-format expectations in the shared
mesh lifecycle driver.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:48:44 +02:00
Felix RiestraandClaude Sonnet 5 b97d74efa4 Complete PolygonMesh, PolyfaceMesh and Mesh host model coverage
Maps all three mesh kinds with host validation of grid counts, face indices
and edge topology, and skips sub-record common data in the generator.
A shared run_mesh_lifecycle driver passes the full gate for each kind,
including DWG and DXF reopen with re-edit.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:42:42 +02:00
Felix RiestraandClaude Sonnet 5 0206c7c30b Complete Table host model coverage
Maps rows, columns, merged ranges, style and placement through the generic
generator (now with tuple and usize support), adds grid/merge/reference
validation, and keeps DXF cell merge dimensions in step with merged_ranges.
staged_python_table_lifecycle_over_real_ipc passes the full gate including
DWG and DXF reopen.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:36:12 +02:00
Felix RiestraandClaude Sonnet 5 b3f5388208 Complete MultiLeader host model coverage
Extends the adapter generator (Color, LineWeight, mixed unit/payload enums,
fixed float arrays, bitflags-2 newtypes, keep_types override) and maps
MultiLeader with a merge-style context patch, host validation and
reference checks. staged_python_multileader_lifecycle_over_real_ipc passes
the full gate including DWG and DXF reopen.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:27:43 +02:00
Felix RiestraandClaude Sonnet 5 22f9c20fe8 Support Color in the Python adapter generator; map Leader.override_color
Color converts as {'kind': ByLayer|None|ByBlock|Index|Rgb, 'value': ...}.
Leader.override_color is now writable; neither DWG nor DXF stores it, which
is recorded as a fourth persistence blocker with a canary assertion.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:18:12 +02:00
Felix RiestraandClaude Sonnet 5 6b4c86fd7a Complete Dimension host model coverage for all nine subtypes
Adds a hand-written flat Dimension model to the adapter (manifest
manual_kinds hook) and a synthetic-property section to the host coverage
policy. The host derives actual_measurement and the base definition point on
scripted create/edit. staged_python_dimension_lifecycle_over_real_ipc passes
the full gate for every subtype including DWG and DXF reopen. Python ints are
now accepted for coordinates and angles.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:15:03 +02:00
Felix RiestraandClaude Sonnet 5 a86d5bc727 Complete MLine host model coverage
Maps vertices, flags, justification, normal, scale and style with host
validation and MLineStyle binding. The host recomputes vertex direction,
miter and element parameters on scripted create/edit, so scripts only supply
positions. staged_python_mline_lifecycle_over_real_ipc passes the full gate
including DWG and DXF reopen.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:02:40 +02:00
Felix RiestraandClaude Sonnet 5 ec10bdbc48 Map Leader in the Python host model; record acadrust W blockers
Adds Leader validation and annotation/dimension-style reference checks to
ocs_plugin_api, maps 15 writable and 5 read-only fields in the adapter, and
adds staged_python_leader_lifecycle_over_real_ipc covering C/R/E/D/U/I/V/P.
The W gate stays open: acadrust's DXF writer omits the annotation handle and
DXF reads drop annotation_offset; DWG R2010+ does not store text size or the
hookline flag. Each gap is pinned by a canary assertion.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 11:12:27 +02:00