Implements docs/dwg_constraint_compatibility_design.md's staged plan in
full: materializes the sketch-constraint set as acadrust's real
AssocNetwork/Assoc2dConstraintGroup object graph on save, additive to
the existing OCS_SKETCH_CONSTRAINTS XRecord, so files also carry
constraints AutoCAD/BricsCAD recognize as their own native objects
(per Hakan's request on the upstream project). Covers every
ConstraintKind, including AssocVariable wiring for named-parameter
driving values, and clears+rebuilds on each save.
DWG round-trips the full dependency chain; DXF only keeps the
constraint-group shell since acadrust's own DXF writer deliberately
omits AssocDependency-family objects. Both behaviors are covered by
tests and documented in the design doc's progress section, along with
two other implementation-time findings (skipping the NOD-anchored
top-level network, and the DWG writer's root-node/connections wire
format).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Hakan (upstream maintainer) asked for the sketch-constraint system to
persist using the constraint object model already exposed in acadrust/
cadcodec (Assoc2dConstraintGroup, AssocConstraintNode), so a file saved
by OpenCADStudio carries constraints AutoCAD/BricsCAD recognize as
their own native objects, not just an opaque custom XRecord blob.
Covers:
- The full ConstraintKind -> AssocConstraintNodeData mapping table,
grounded in build_constraint's actual refs shapes (the real contract,
not the doc comments).
- The geometry-node mapping for SketchRef (line/circle/arc/point
references) onto Line/BoundedLine/Circle/Arc/ImplicitPoint nodes.
- The AssocNetwork -> AssocAction -> Assoc2dConstraintGroup graph shape
actually needed, not just a flat data swap.
- A proposed additive persistence strategy: write both our own
OCS_SKETCH_CONSTRAINTS XRecord and the native graph, since our model
carries things (DrivingValue::Named) the native graph can't yet
losslessly express.
- Known gaps: Equal has no length/radius sub-kind split natively,
several AutoCAD constraint types we don't model at all, Tangent
involving an Arc (a pre-existing gap in the constraint system,
unrelated to DWG compatibility).
Three of five open questions are resolved against Autodesk's own
primary sources rather than left as inference: the ObjectARX 2012 SDK's
own C++ headers (mirrored on GitHub, Autodesk's own copyright notice
grants free use/distribution -- it's the SDK Autodesk publishes for
third-party interop) and Autodesk's live public ObjectARX reference
site. Confirmed: the associative network's dictionary key
("ACAD_ASSOCNETWORK"), the AcDb::ImplicitPointType enum settling how
SketchRef's point markers map to constraint geometry nodes, and that
AssocVariable's evaluator field can be left empty (Autodesk's own doc:
"the default evaluator for current acad version will be used"). Two
questions remain and need a real write-then-open test rather than more
reading: whether AutoCAD tolerates a partially-populated graph, and
DWG version gating on fields not yet checked.
Suggested staged approach: prove out Horizontal/Vertical on a single
Line first (sidesteps the value-dependency wiring), verify it opens
cleanly in real AutoCAD/BricsCAD or a DWG inspector, before writing
more of the graph on an unverified foundation. Design only -- no
implementation yet.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>