Skip to content

v0.55.1 — Per-triangle highlight overlay (closes #25)

Choose a tag to compare

@gsdali gsdali released this 03 May 06:41
· 59 commits to main since this release

Closes #25. Per-sub-shape highlight overlay — replaces the v0.1 OCCTSwiftAIS cheap-route pattern with a renderer-side per-triangle style buffer + dedicated render pass.

What's new

// Empty (default) — no behavioural change.
var body = ViewportBody.box(id: "part")

// Highlight specific triangles by writing per-triangle styles.
body.triangleStyles = (0..<body.indices.count / 3).map { idx in
    isFaceTriangle(idx, faceID: selectedFace)
        ? TriangleStyle(color: SIMD4<Float>(0.1, 0.5, 1.0, 0.5))
        : .none
}

TriangleStyle is a single SIMD4<Float> color (16 bytes per triangle). Zero-alpha entries skip the highlight pass.

Why this beats the v0.1 cheap route

  • No silhouette flicker. Identical geometry depth-tests cleanly with .lessEqual instead of needing the bbox-diagonal nudge along normals.
  • No vertex-data churn. Selection / hover state changes flip per-triangle alpha; no overlay body to spawn or kill on every selection change.
  • No body-count blow-up. Style buffer scales with triangle count, not with selection count.
  • Hover + multi-select for free. Per-triangle style means hover at low alpha and primary selection at higher alpha can coexist on the same body without spawning N overlay bodies.

Renderer changes

  • New triangle_highlight MTL pipeline + highlight_vertex / highlight_fragment MSL shaders.
  • Per-body triangleStyleBuffer: MTLBuffer? cached alongside the existing vertex / index / edge buffers; built only when triangleStyles is populated, nil otherwise.
  • New render pass inserted between the shaded pass and the selection-outline pass.
  • New highlightDepthState (.lessEqual + depth-write disabled) so identical-position highlights win the depth tie without disturbing depth state for subsequent passes.
  • Fragment shader indexes the style buffer by [[primitive_id]]; discards triangles with alpha == 0.

Tests

4 new tests in TriangleStyleTests:

  • TriangleStyle.none is transparent
  • Default-constructed TriangleStyle equals .none
  • ViewportBody default triangleStyles is empty
  • ViewportBody round-trips a non-empty styles array

All 50 viewport tests pass.

Driver

OCCTSwiftAIS v0.6+ will adopt this and drop its makeFaceOverlay(...) cheap-route helper. Body-level selection still routes through viewport.selectedBodyIDs (already works).

Pin

.package(url: "https://github.com/gsdali/OCCTSwiftViewport.git", from: "0.55.1"),

Pure additive: existing call sites keep working with triangleStyles defaulting to [].