cad-editor/docs/tessellation.md

98 lines
6.5 KiB
Markdown
Raw Normal View History

perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
# Entity tessellation paths
How each acadrust `EntityType` becomes drawable geometry in OpenCADStudio.
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
There are **three ways** an entity gets there, and they must not be conflated:
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
1. **Kernel B-rep mesh** — the ACIS document is lifted into a cadkernel `Body`
and each face triangulated in its own surface's parameter space. The only
path that produces filled *mesh* triangles from analytic surfaces.
2. **Curve-sampled** — the entity's geometry is read through
`entities::curve::entity_curve`, which is where each type's curve is defined
once, and tessellated to a chord tolerance. Output is a polyline; no surface
is involved.
3. **Direct** — points, segments or triangles emitted straight from the
entity's own fields.
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
The distinction between (2) and (3) is worth keeping because (2) is a single
definition shared with everything else that needs an entity's geometry — snap
candidates, EXTRUDE and REVOLVE profiles, hatch boundaries, clip outlines. A
circle drawn on screen and a circle handed to the Model tab come from the same
place and cannot disagree.
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
Entry points: `src/scene/convert/tess.rs` (`tessellate_entity`, the per-entity
dispatcher) → `src/scene/convert/tessellate.rs` (`tessellate`, the
`RenderObject` router), `src/entities/curve.rs` (curve definitions and
sampling) and `src/scene/convert/curve_tol.rs` (the per-frame chord tolerance).
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
## Summary
| Path | Entities |
|---|---|
| **Kernel B-rep mesh** (lift → per-face triangulation, with a direct per-surface fallback) | `Solid3D`, `Region`, `Body`, `Surface` |
| **Curve-sampled** (`entity_curve` → chord-tolerance tessellation) | `Line`, `Arc`, `Circle`, `Ellipse`, `Spline`, `LwPolyline`, `Polyline`, `Polyline2D`, `Polyline3D`*non-thick variants only* |
| **Direct** (segments/triangles emitted straight) | everything else |
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
> The Model/Design-tab primitives (BOX, SPHERE, CYLINDER, CONE, WEDGE, TORUS,
> PYRAMID, EXTRUDE, REVOLVE) are true kernel B-reps too, cached on the Scene as
> `Body` and meshed the same way — but they are created as `Solid3D`
> placeholders carrying that body, not as their own `EntityType`. SWEEP and
> LOFT produce a mesh only, with no B-rep behind it.
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
ACIS solids dispatch through `solid3d_tess::tessellate_acis`, which lifts the
document into the kernel first (`acis_kernel::tessellate_sat`) and falls back
to a bespoke per-surface LOD sampler (`tessellate_sat_lods`) when the kernel
cannot express a face — so their path is **kernel-with-direct-fallback**. The
fallback is not silent: a mesh whose faces did not all lift is marked
incomplete, because one missing wall looks exactly like a finished solid.
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
Curved-surface tessellation density is radius-relative (`CURVE_REL_TOL`, a
fraction of the surface radius) so a cylinder's facet count matches the
circle/arc wire tessellation instead of exploding on large radii.
## Full table
| Entity | Output | Path | Notes |
|---|---|---|---|
| Arc | wire | curve-sampled | non-thick: sampled from the arc's own curve; thick: direct `Lines` plus the swept wall |
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
| AttributeDefinition | wire | direct | routes through the Text/MText LFF glyph stroke pipeline |
| AttributeEntity | wire | direct | same as AttributeDefinition; values supplied per Insert |
| Block | none | n/a | block-definition sentinel; not tessellated (referenced via Insert) |
| BlockEnd | none | n/a | block-definition end marker; no output |
| Body | mesh | kernel-with-direct-fallback | 3D ACIS body lifted into a kernel `Body`; fallback per-surface sampler |
| Circle | wire | curve-sampled | non-thick: sampled from the circle's own curve; thick: direct `Lines` |
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
| Dimension | wire | direct | baked-block path recurses on `D###` sub-entities; synthesis path emits lines/arrows/LFF text |
| Ellipse | wire | curve-sampled | sampled from the ellipse's own curve |
| Face3D | both | direct | edge `Lines` + direct fan-triangulated `fill_tris`; no B-rep |
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
| Hatch | both | direct | boundary outline not emitted to the wire set (#131 OOM); fill rasterized on GPU |
| Insert | wire | direct | expands block children and tessellates each via its own path; XCLIP filter applied |
| Leader | wire | direct | leader path + arrowhead + landing, direct `Lines` |
| Line | wire | curve-sampled | non-thick: its two ends; thick: direct `Lines` plus the swept wall |
| LwPolyline | wire | curve-sampled | `plinegen` true: sampled from its own curve, bulges kept as arcs; else direct `SegmentedLines` |
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
| Mesh | both | direct | SubD mesh: edge `Lines` + direct fan-triangulated `fill_tris` |
| MLine | wire | direct | spine + offset lines + caps, direct `Lines` |
| MText | wire | direct | wrap-aware multi-line LFF glyph layout; inline formatting codes |
| MultiLeader | wire | direct | leader + landing + LFF text + frame + fill |
| Ole2Frame | wire | direct | bounding rectangle + diagonal cross |
| Point | wire | direct | a position → dot or cross marker sized by PDSIZE |
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
| PolyfaceMesh | both | direct | face list: closed-polyline edges + direct fan-triangulated `fill_tris` |
| PolygonMesh | both | direct | M×N grid wireframe + direct fan-triangulated `fill_tris` |
| Polyline | wire | curve-sampled | heavy 3D polyline; sampled from its own curve, bulges kept as arcs |
| Polyline2D | wire | curve-sampled | 2D polyline with bulge; sampled from its own curve |
| Polyline3D | wire | curve-sampled | straight edges, no bulge or thickness |
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
| RasterImage | wire | direct | boundary rectangle / clipping polygon |
| Ray | wire | direct | two-point `[base, base + dir×1e6]`, no sampling |
| Region | mesh | kernel-with-direct-fallback | 2D planar ACIS body; same kernel path as Solid3D |
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
| Seqend | none | n/a | vertex-sequence terminator sentinel; no output |
| Shape | wire | direct | small diamond marker at the insertion point |
| Solid | wire | direct | 2D SOLID: four quad edges as direct `Lines` |
| Solid3D | mesh | kernel-with-direct-fallback | 3DSOLID: parse SAT/SAB → lift into a kernel `Body`; fallback sampler |
| Spline | wire | curve-sampled | NURBS sampled through the kernel's space curve, refined where it bends |
perf(render): batch solid meshes, fix per-pick freezes on heavy 3D models Opening / navigating a heavy 3D DWG (e.g. a BIM model with ~10k ACIS solids) was effectively frozen. Several independent costs, all addressed here: - Face3D edge/fill buffers were re-uploaded on every camera move (keyed on camera_generation). They are world-space and selection-independent, so gate them on (geometry_epoch, fill_mode) instead — a pan no longer re-walks every wire. - Solid meshes were drawn one buffer + one draw call per solid (~10k draws/ frame), which strangled the GPU front end. Concatenate every solid's LOD0 into a few large buffers (split only to stay under the 256 MB buffer cap) and draw the whole set in a handful of calls. Built once per geometry epoch, so selection / hover never re-pack it. - Selection / hover highlight is now a small tinted overlay of just the picked solids, drawn last with an Always-depth pipeline so it shows on top even when the solid is occluded — instead of re-tinting and re-uploading all meshes. - Hover / pick hit-testing scanned every triangle of every solid each move (seconds on a heavy model). Add a 3D-AABB screen-rect broad phase (MeshLodSet now carries z_aabb) and reuse the renderer's cached expanded mesh set, so picking is O(solids) cheap projections plus the few solids actually under the cursor. - Block-internal hatch hit-testing exploded every INSERT on every hover. Cache the result per geometry epoch and skip blocks that contain no hatch. - Curved-surface (cone/sphere/torus) tessellation tolerance is now radius- relative (CURVE_REL_TOL) so a cylinder's facet count is size-independent and matches the circle/arc wire tessellation, instead of exploding on large radii. Also adds docs/tessellation.md mapping every EntityType to its tessellation path (truck B-rep vs truck curve topology vs direct). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 22:46:29 +03:00
| Table | both | direct | cell fills (`fill_tris`) + LFF cell text + grid lines |
| Text | wire | direct | LFF-font stroked glyph polylines |
| Tolerance | wire | direct | feature-control frame grid + per-cell LFF symbols |
| Underlay | wire | direct | boundary rectangle of the PDF/DWF reference |
| Unknown | none | n/a | unrecognized-entity sentinel; no output |
| Viewport | wire | direct | content-viewport frame rectangle (sheet viewport skipped) |
| Wipeout | wire | direct | boundary rectangle / clipping polygon |
| XLine | wire | direct | three-point infinite line, no sampling |