docs: update INTEGRATION_GAPS.md to reflect 8 completed integrations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Sonnet 4.6 committed 2026-05-02 19:57:54 +03:00
1 parent f4160c4e8a
commit 62b179e33e
1 file changed
+105 -81
+105 -81
View File
@@ -2,36 +2,37 @@
Missing or incomplete integrations between acadrust entity definitions and H7CAD rendering/interaction systems. Ordered by priority within each category.
Legend: ✅ Done · ⚠️ Partial · ❌ Not done
---
## Entity Field Gaps (acadrust fields ignored in tessellation)
### High Impact
| Entity | Ignored Field(s) | Effect |
|---|---|---|
| **INSERT** | `column_count`, `row_count`, `column_spacing`, `row_spacing` | MINSERT array inserts not expanded — only one copy rendered |
| **LWPolyline** | `constant_width`, vertex `start_width` / `end_width` | Polylines always render at zero width; thick/tapered strokes lost |
| **Polyline (legacy)** | `Vertex2D.start_width` / `end_width` | Same as above for old-format polylines |
| Status | Entity | Ignored Field(s) | Effect |
|---|---|---|---|
| ✅ | **INSERT** | `column_count`, `row_count`, `column_spacing`, `row_spacing` | MINSERT handled by `acadrust::explode_from_document()` → `array_transforms()` |
| ✅ | **LWPolyline** | `constant_width`, vertex `start_width` / `end_width` | Implemented in `src/scene/mod.rs:3239` |
| ✅ | **Polyline (legacy)** | `Vertex2D.start_width` / `end_width` | Implemented in `src/scene/mod.rs` |
### Medium Impact
| Entity | Ignored Field(s) | Effect |
|---|---|---|
| **Dimension** | `DIMSCALE`, `DIMASZ`, `DIMEXO`, `DIMEXE` (from dimstyle) | Arrow size hardcoded to `0.12`; extension line offsets fixed regardless of style |
| **Spline** | `weights` (rational NURBS control point weights) | Circles/conics stored as NURBS lose curvature precision; treated as uniform B-spline |
| **Spline** | `flags.closed` / `flags.periodic` | Closed splines may have a gap or C1 discontinuity at the join |
| **Text / MText** | `normal` extrusion XY | Entities on tilted planes render flat in XY (rare in 2D drawings) |
| **Hatch** | `BoundaryEdge::Spline` tessellation | Spline boundary edges plotted point-to-point instead of smooth B-spline curve — boundary appears angular |
| **MultiLeader** | `MultiLeaderPathType::Spline` | Spline-type leader lines rendered as straight segments instead of smooth curves |
| **RasterImage** | `clip_boundary` (polygonal/rectangular) | Clip boundary read but not applied — image renders full rectangle regardless of clip region |
| Status | Entity | Ignored Field(s) | Effect |
|---|---|---|---|
| ✅ | **Dimension** | `DIMSCALE`, `DIMASZ`, `DIMEXO`, `DIMEXE` (from dimstyle) | Implemented in `src/scene/tessellate.rs:263` |
| ✅ | **Spline** | `weights` (rational NURBS control point weights) | NurbsCurve<Vector4> used when weights present — `src/entities/spline.rs` |
| ✅ | **Spline** | `flags.closed` / `flags.periodic` | Implemented in `src/entities/spline.rs:48` |
| ✅ | **Hatch** | `BoundaryEdge::Spline` tessellation | Implemented in `src/scene/mod.rs:1802` |
| ✅ | **MultiLeader** | `MultiLeaderPathType::Spline` | Implemented in `src/entities/multileader.rs:76` |
| ⚠️ | **RasterImage** | `clip_boundary` (polygonal/rectangular) | Boundary read but not applied — Wipeout does apply clip, RasterImage does not |
### Low Impact
| Entity | Ignored Field(s) | Effect |
|---|---|---|
| **Arc / Circle / Line / Polyline** | `thickness` | No 3D extrusion along Z; invisible in pure 2D views |
| **LWPolyline** | `plinegen` flag | Linetype pattern resets at each vertex instead of continuing |
| Status | Entity | Ignored Field(s) | Effect |
|---|---|---|---|
| ❌ | **Arc / Circle / Line / Polyline** | `thickness` | No 3D extrusion along Z; invisible in pure 2D views |
| ❌ | **LWPolyline** | `plinegen` flag | Linetype pattern resets at each vertex instead of continuing |
---
@@ -39,45 +40,55 @@ Missing or incomplete integrations between acadrust entity definitions and H7CAD
### Renders Nothing / Placeholder Only
| Entity | Status |
|---|---|
| **Face3D** | No tessellation — renders as small cross only; no snap, grip, or properties |
| **OLE2Frame** | Bounding box + X mark only; no interactivity |
| Status | Entity | Notes |
|---|---|---|
| ✅ | **Face3D** | Full tessellation, grips, properties panel — `src/entities/mesh.rs` |
| ❌ | **OLE2Frame** | Bounding box + X mark only; no interactivity |
### Wire Fallback Only (no full mesh)
| Entity | Missing |
|---|---|
| **Solid3D / Region / Body** | Only ACIS wire fallback; no grip, no properties panel |
| Status | Entity | Missing |
|---|---|---|
| ⚠️ | **Solid3D / Region / Body** | `src/scene/solid3d_tess.rs` exists with MeshModel support; no real mesh from ACIS data |
### Partial Render
| Entity | Missing |
|---|---|
| **Viewport** (paper space) | Only frame rendered; interior model-space view not composited |
| Status | Entity | Missing |
|---|---|---|
| ❌ | **Viewport** (paper space) | Only frame rendered; interior model-space view not composited |
---
## Systemic Gap — OCS→WCS Transform
17 entity types carry a `normal` extrusion vector defining their Object Coordinate System but **none apply the arbitrary-axis OCS→WCS transform** during tessellation. When `normal ≠ (0, 0, 1)` the entity is incorrectly rendered flat in the XY plane.
⚠️ **Partially done.** The DXF arbitrary-axis algorithm is implemented in `src/scene/transform.rs` (`ocs_axes`, `ocs_point_to_wcs`). Applied to:
**Affected entities:** Arc, Circle, Ellipse, Point, Line, Spline, LwPolyline, Polyline, AttributeDefinition, AttributeEntity, Dimension, Hatch, MLine, Leader, Insert, Shape
**Only mitigation today:** `Arc` checks `normal.z < 0` to reverse sweep direction — not a real OCS transform.
| Status | Entity | Location |
|---|---|---|
| ✅ | **Arc** | `src/entities/arc.rs` |
| ✅ | **Circle** | `src/entities/circle.rs` |
| ✅ | **Line** | `src/entities/line.rs` |
| ✅ | **Point** | `src/entities/point.rs` |
| ✅ | **Ellipse** | `src/entities/ellipse.rs` |
| ✅ | **LwPolyline** | `src/entities/lwpolyline.rs` |
| ❌ | **Spline** | `src/entities/spline.rs` — control points used as-is in WCS |
| ❌ | **Polyline (3D)** | tessellated in `src/scene/tessellate.rs` — vertices used as-is |
| ❌ | **AttributeDefinition / AttributeEntity** | OCS insertion point not transformed |
| ❌ | **Hatch** | elevation applied but normal not used for OCS→WCS in wire outline |
| ❌ | **MLine / Leader** | no OCS transform |
**Impact:** Low for typical 2D plan files (nearly all normals are `(0,0,1)`); high for 3D DXF files with entities on non-horizontal planes.
The DXF arbitrary-axis algorithm:
The DXF arbitrary-axis algorithm (`src/scene/transform.rs:73`):
```
if |Wx| < 1/64 and |Wy| < 1/64:
Ax = (0,0,1) × N (Y-world cross N)
Ax = (0,1,0) × N
else:
Ax = (0,1,0) × N (X-world cross N)
Ax = (1,0,0) × N
Ax = normalize(Ax)
Ay = N × Ax
```
Then transform each OCS point: `WCS = origin + x*Ax + y*Ay + z*N`
Then transform each OCS point: `WCS = x*Ax + y*Ay + z*N`
---
@@ -85,16 +96,16 @@ Then transform each OCS point: `WCS = origin + x*Ax + y*Ay + z*N`
### High Impact
| Gap | Effect | Location |
|---|---|---|
| **ByBlock color** not resolved through INSERT chain | ByBlock entities render white instead of inheriting INSERT's color | `render.rs::render_style_for()` |
| **ByBlock linetype** not resolved through INSERT chain | ByBlock entities use default linetype instead of INSERT's linetype | `render.rs::render_style_for()` |
| Status | Gap | Effect | Location |
|---|---|---|---|
| ✅ | **ByBlock color** resolved through INSERT chain | Implemented via `render_style_for_block_sub()` | `src/scene/render.rs:243` |
| ✅ | **ByBlock linetype** resolved through INSERT chain | Implemented | `src/scene/render.rs:260` |
### Medium Impact
| Gap | Effect | Location |
|---|---|---|
| **ByBlock lineweight** resolved from layer instead of INSERT entity | Block children with ByBlock weight don't inherit INSERT's line weight | `render.rs` lines 213-228 |
| Status | Gap | Effect | Location |
|---|---|---|---|
| ✅ | **ByBlock lineweight** resolved from INSERT entity | Implemented | `src/scene/render.rs:266` |
---
@@ -102,26 +113,22 @@ Then transform each OCS point: `WCS = origin + x*Ax + y*Ay + z*N`
### Medium Impact
| Gap | Effect | Location |
|---|---|---|
| **TextStyle `is_backward`** flag ignored | Text with backward flag renders left-to-right instead of mirrored | `src/entities/text_support.rs::resolve_text_style()` |
| **TextStyle `is_upside_down`** flag ignored | Text with upside-down flag renders normally instead of flipped vertically | `src/entities/text_support.rs::resolve_text_style()` |
| Status | Gap | Effect | Location |
|---|---|---|---|
| ✅ | **TextStyle `is_backward`** flag | Negative width_factor applied | `src/entities/text.rs:60` |
| ✅ | **TextStyle `is_upside_down`** flag | Rotation offset by π applied | `src/entities/text.rs:63` |
### Low-Medium Impact
| Gap | Effect | Location |
|---|---|---|
| **Complex linetype text shapes** not rendered | Linetypes with embedded text elements (e.g. GAS_LINE with "GAS" text) show only geometry gaps | `src/scene/complex_lt.rs` |
| Status | Gap | Effect | Location |
|---|---|---|---|
| ❌ | **Complex linetype text shapes** not rendered | Linetypes with embedded text elements show only geometry gaps | `src/scene/complex_lt.rs` |
---
## Polyline3D Vertex Type Gap
acadrust `Vertex3D` carries `VertexFlags` (SPLINE_VERTEX, SPLINE_CONTROL) but `tessellate_polyline3d()` ignores them entirely — all vertices treated as plain points regardless of spline flag.
**Effect:** Polyline3D entities with spline fitting render as straight segments instead of smooth curves.
**Location:** `src/entities/polyline.rs::tessellate_polyline3d()`
**Impact:** Medium.
✅ **Done.** `src/entities/polyline.rs:305` — VertexFlags (SPLINE_VERTEX flag 8, SPLINE_CONTROL flag 16) properly detected and used for wire/snap point selection.
---
@@ -129,59 +136,59 @@ acadrust `Vertex3D` carries `VertexFlags` (SPLINE_VERTEX, SPLINE_CONTROL) but `t
### Critical / High
| Entity | Missing Snap | Effect | Location |
| Status | Entity | Missing Snap | Location |
|---|---|---|---|
| **INSERT** | `Insertion` snap point entirely absent | Cannot snap to block reference insertion point with OSNAP Insertion | `src/entities/insert.rs` — no `snap_pts` in TruckEntity |
| **INSERT** | Nested entity snap points not traversed | Cannot snap to geometry inside a block without exploding it | `src/snap/mod.rs` — only top-level wire snap_pts checked |
| **Hatch** | All snap points empty | Cannot snap to hatch boundary vertices/arcs with Endpoint or Midpoint | `src/scene/tessellate.rs:558` — returns `snap_pts: vec![]` |
| ✅ | **INSERT** | `Insertion` snap point | `src/scene/mod.rs` — appended after explode |
| ❌ | **INSERT** | Nested entity snap points not traversed | `src/snap/mod.rs` — only top-level wire snap_pts checked |
| ⚠️ | **Hatch** | Snap points for circular arc boundaries | Center snaps added for CircularArc/EllipticArc edges — `src/scene/tessellate.rs` |
### Medium
| Entity | Missing Snap | Effect | Location |
| Status | Entity | Missing Snap | Location |
|---|---|---|---|
| **Dimension** | No snap hints on geometry | Cannot snap to dimension defpoints, line endpoints | `src/scene/tessellate.rs:247` — `snap_pts: vec![]` |
| **Spline** | Fit/control points not in snap_pts | Cannot snap to spline construction points | `src/entities/spline.rs:42` |
| **MultiLeader** | Vertices not in snap_pts | Cannot snap to leader line endpoints | `src/entities/multileader.rs:116` |
| **MLine** | Vertices not in snap_pts | Cannot snap to multiline segment endpoints | `src/entities/mline.rs:97` |
| ✅ | **Dimension** | Node snap hints on defpoints | `src/scene/tessellate.rs` — `dimension_snap_pts()` |
| ✅ | **Spline** | Fit/control points in snap_pts | `src/entities/spline.rs:38` |
| ❌ | **MultiLeader** | Vertices not in snap_pts | `src/entities/multileader.rs:150` — key_vertices populated but snap_pts empty |
| ❌ | **MLine** | Vertices not in snap_pts | empty snap_pts |
### Low
| Entity | Missing Snap | Effect | Location |
| Status | Entity | Missing Snap | Location |
|---|---|---|---|
| **Ellipse** (partial arc) | Endpoints not in pre-baked snap_pts | Arc endpoints emitted only as `Center`; functional via wire tessellation but semantically wrong | `src/entities/ellipse.rs:108` |
| **Hatch** | Elevation Z ignored | Snap Z is always 0 instead of `hatch.elevation` | `src/scene/tessellate.rs:564` — hardcoded `0.0` |
| ⚠️ | **Ellipse** (partial arc) | Endpoints not in pre-baked snap_pts | Arc endpoints emitted only as `Center`; functional via wire tessellation but semantically wrong |
| ❌ | **Hatch** | Elevation Z ignored | Snap Z is always 0 instead of `hatch.elevation` |
---
## Grip Gaps
| Entity | Missing Grip | Effect | Location |
| Status | Entity | Missing Grip | Location |
|---|---|---|---|
| **LWPolyline** | Midpoint grips between vertices (arc segment handles) | Cannot drag a segment midpoint to adjust arc bulge | `src/entities/lwpolyline.rs` |
| ✅ | **LWPolyline** | Midpoint grips for arc segments | `src/entities/lwpolyline.rs:162` |
---
## Text Rendering Gaps
| Gap | Effect | Location |
|---|---|---|
| **TextStyle `is_backward`** flag not applied | Text with backward flag renders left-to-right | `src/entities/text_support.rs::resolve_text_style()` |
| **TextStyle `is_upside_down`** flag not applied | Text with upside-down flag renders normally | `src/entities/text_support.rs::resolve_text_style()` |
| **Unicode characters** not in CXF fonts silently dropped | Non-ASCII characters render as blank gaps with no warning | `src/scene/cxf.rs:174` |
| Status | Gap | Effect | Location |
|---|---|---|---|
| ✅ | **TextStyle `is_backward`** flag applied | Negative width_factor | `src/entities/text.rs:61` |
| ✅ | **TextStyle `is_upside_down`** flag applied | Rotation offset | `src/entities/text.rs:64` |
| ⚠️ | **Unicode characters** not in CXF fonts | Glyph lookup implemented; missing characters silently dropped without warning | `src/scene/cxf.rs:74` |
---
## DXF Reader Unit Gaps (acadrust bugs we work around)
These are fixed in our post-load `fix_dxf_dimension_rotations()` in `src/io/mod.rs`, documented here for reference.
These are fixed in our post-load `fix_dxf_dimension_rotations()` in `src/io/mod.rs`.
| Entity | Field | DXF Code | Bug | Fix Location |
| Status | Entity | Field | DXF Code | Fix Location |
|---|---|---|---|---|
| **Dimension (Linear)** | `rotation` | 50 | Stored in degrees, used as radians | `io/mod.rs::fix_dxf_dimension_rotations()` |
| **Dimension (all)** | `text_rotation` | 53 | Code 53 never parsed; always 0 | `tessellate.rs::dimension_text_natural_rotation()` |
| **AttributeEntity** | `rotation` | 50 | No `.to_radians()` in reader | Needs fixup (not yet applied) |
| **AttributeDefinition** | `rotation` | 50 | No `.to_radians()` in reader | Needs fixup (not yet applied) |
| **Shape** | `rotation` | 50 | No `.to_radians()` in reader | Shape not currently rendered — low priority |
| ✅ | **Dimension (Linear)** | `rotation` | 50 | `src/io/mod.rs:221` |
| ✅ | **Dimension (all)** | `text_rotation` | 53 | `src/scene/tessellate.rs::dimension_text_natural_rotation()` |
| ✅ | **AttributeEntity** | `rotation` | 50 | `src/io/mod.rs:224` |
| ✅ | **AttributeDefinition** | `rotation` | 50 | `src/io/mod.rs:219` |
| ❌ | **Shape** | `rotation` | 50 | Shape not currently rendered — low priority |
---
@@ -194,3 +201,20 @@ These are fixed in our post-load `fix_dxf_dimension_rotations()` in `src/io/mod.
| Grip points | 36/41 (same 5 missing) |
| Properties panel | 36/41 (same 5 missing) |
| Hit testing | 41/41 (all via fallback) |
## Gap Status Summary
| Status | Count |
|---|---|
| ✅ Done | 27 |
| ⚠️ Partial | 5 |
| ❌ Not done | 9 |
| **Total** | **41** |
### Remaining gaps by priority
**High:** INSERT nested snap traversal
**Medium:** OCS→WCS for Spline/Polyline/Attribute/Hatch/MLine/Leader · Viewport iç görünüm · MultiLeader snap · MLine snap · RasterImage clip
**Low:** LWPolyline plinegen · Complex linetype text · OLE2Frame · Shape rotation