Commit graph cad-editor/src/scene/solid3d_tess.rs
Author SHA1 Message Date
Hakan Seven
8c08ae104a perf(scene): multi-resolution mesh LOD (Phase 3.4)
ACIS SAT entities (Solid3D / Region / Body) were tessellated at one
fixed sampling density (CIRC_SEGS=48, GRID_U=32, GRID_V=16) regardless
of how far they were from the camera. Distant solids paid the full
triangle bill for fragments that mostly resolved to sub-pixel size.

Generate three pre-built LODs per entity at load time:

  * LOD 0 (HIGH)  — 48/32/16 segments. Use above 200 px projected diag.
  * LOD 1 (MID)   — 24/16/8.  Use 50–200 px.
  * LOD 2 (LOW)   — 12/8/4.   Use below 50 px.

Tessellation cost is paid 3× on load (cheap — typical files have few
solids). Render picks per-frame via `compute_mesh_lod` from each mesh's
`world_aabb` projected diagonal. When a level is missing (e.g. a solid
entity that only emits LOD 0), the selector walks down to the nearest
available slot.

API ripples:
  * New `LodConfig` (HIGH/MID/LOW) drives `tess_sat`, `tess_cone_face`,
    `tess_sphere_face`, `tess_torus_face`.
  * `tessellate_solid3d / _region / _body` now return `MeshLodSet`.
  * `MeshLodSet { lods: Vec<MeshModel>, world_aabb }` + `from_single`
    constructor so interactive truck-based commands (BOX/CYLINDER/etc.)
    that only generate one tessellation stay one-line.
  * GPU side gets `MeshLodGpu { lods: Vec<MeshGpu>, world_aabb }` and
    a `mesh_lod_levels` per-frame index vector.
  * STL/STEP export pulls slot 0 explicitly so the on-disk geometry
    isn't downgraded by the view-dependent ladder.

Background-thread lazy generation (per the roadmap) is deferred — the
synchronous eager build is fine for typical CAD files. Switch to a
queue + background tessellator when files with hundreds of solids
become a load-time bottleneck.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 23:30:13 +03:00
Hakan
ca07268c7c cargo fmt 2026-05-12 10:36:15 +03:00
Hakan Seven
27aca41dd1 feat: plinegen + SAB parsing for Solid3D/Region/Body
LwPolyline PLINEGEN=0 (DXF default): emit SegmentedLines with NaN
separators between vertex-to-vertex segments; wire_gpu resets
arc-length to 0 after each NaN so linetype pattern restarts per vertex.
PLINEGEN=1: existing Contour path unchanged (continuous pattern).
WireModel gains plinegen field propagated through tessellate pipeline.

Solid3D/Region/Body: call SabReader::read() when parse_sat() returns
None due to binary SAB format (DWG files / newer AutoCAD exports).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 06:55:28 +03:00
Hakan Seven
5cf7a19ca8 feat: Region and Body entity tessellation + render
Refactors solid3d_tess to share tessellate_sat() across Solid3D,
Region (2D planar ACIS body), and Body (3D ACIS body).
populate_meshes_from_document() and add_entity() now tessellate
all three entity types into GPU MeshModels when ACIS SAT data
is available.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 18:37:24 +03:00
Hakan Seven
a99115bda5 feat: Solid3D (3DSOLID) ACIS tessellation
Parse SAT geometry directly into GPU MeshModel without going through
the truck B-rep pipeline:
  • plane-surface faces  → fan-triangulate the coedge-loop polygon
  • cone-surface faces   → parametric grid (handles cylinders and cones)
  • sphere-surface faces → UV sphere grid (GRID_U × GRID_V)
  • torus-surface faces  → UV torus grid

Scene integration:
  • add_entity(): tessellates Solid3D on insert, stores in scene.meshes
  • erase_entities(): removes mesh from scene.meshes on delete
  • populate_meshes_from_document(): rebuilds all meshes on file load
    and undo/redo (called alongside populate_hatches/images)

ROADMAP updated: Solid3D tessellation marked ✅ in sections 2.12, 14.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 19:11:24 +03:00