Liking cljdoc? Tell your friends :D

Concavity validation

The regression suite in test/main/plexus/concavity_test.cljc runs on both JVM and JavaScript/WASM, using the same published geometry dependencies.

Verified: 56 JVM tests / 295 assertions and 48 JavaScript tests / 276 assertions, with no failures or errors. Advanced JavaScript compilation reports no warnings.

Cases and results

Reference surfaceChecksResult
V-valley with a 90-degree inward creaseAnalytic endpoint and heading, diagonal sideways/forward travel, arc length, reversal, 1/17/113 sampling stepsNavigation passes
0.2-unit-wide connected trenchDescend one wall, traverse the floor, ascend the facing wall; reverse the routeFollows topology without jumping across the gap
Spherical Boolean-cut bowlWalk from the bottom up the wall; positive, zero, and negative depth; spacing 1 and 0.1Sweeps pass clearance and transverse-intersection checks
Torus starting at its concave inner wallWalk through changing curvature; positive, zero, and negative depth; spacing 1 and 0.1Sweeps pass clearance and transverse-intersection checks
V-valley swept at depth 0 or +0.5A 0.2 × 0.2 profile across the sharp inward creaseRejected with :surface-sweep-fold
V-valley swept at depth −0.5Same profile on the outside of this turnPasses the tested intersection and containment checks
Bowl with depth 11, exceeding its radiusOffset path folds past the curvature centerRejected with :surface-sweep-fold

For the bowl and torus, the profile is 0.2 × 0.2 units, depth is −0.5, 0, or +0.5, and lengths are 8 and 12 respectively. At positive depth the generated solid has less than 1e−6 cubic units of intersection with its reference solid. At negative depth it has less than 1e−6 cubic units outside it. At zero depth it straddles the reference surface. Inside plus outside volume agrees with total volume within 1e−5 cubic units. These clearances are specific to these fixtures and dimensions.

Navigation checks use known endpoints where available, measured polyline length, reverse paths, triangle barycentric coordinates, and unit tangent headings. The bowl also checks continuity of interpolated normals across physical edges and alignment with its independently known inward radial direction.

Failure found and corrected

The original sweep used discontinuous face normals. At sharp inward corners its centerline was correct, but the loft could self-intersect. Native Manifold status still returned :NoError. Increasing the number of samples did not resolve it. Closely spaced stations could also invert small parts of a profile near edges of otherwise smooth meshes.

The regression suite deliberately reconstructs an unchecked bad valley loft. It asserts that native status succeeds while a separate triangle-intersection checker detects transverse intersections. The guarded DSL rejects that sweep, including when called through SCI source macros; operation and source-expression metadata survive the error.

The correction uses angle-weighted frame normals within smooth physical face fans, preserving creases over 60 degrees. Before lofting, it checks progression of every profile vertex relative to both neighboring sweep directions. In smooth regions, nearby stations that would fold can be coalesced, bounded by twice the requested spacing. Sharp folds and unrecoverable collapses are rejected rather than silently returned as geometry. Navigation samples and endpoints are retained.

Scope of the geometric validation

The independent checker tests segment/triangle intersections on nonadjacent output triangles, with bounding-box rejection. It detects transverse crossings; it is not an exhaustive proof against all coplanar overlaps, contacts at shared vertices, or arbitrarily small numerical defects. Native topology/status checks and Boolean volume/clearance checks complement it.

The runtime guard checks local sweep inversion. It does not detect collisions between distant parts of a path or with unrelated geometry, and it does not create mitered or rounded joins at sharp creases. A surrounding loft that changes profiles needs its own geometric review. Profiles still remain rigid across their width. The passing fixtures do not imply every concave surface, profile size, or depth is safe.

Reproduce

clojure -M:dev:test:sci
clojure -M:cljs scripts/prepare-cljs.clj
clojure -M:cljs -m shadow.cljs.devtools.cli release test
node target/cljs-tests.js
clojure -M:dev src/examples/surface_concavity.clj

The example writes target/surface-concave-bowl.glb and target/surface-concave-torus.glb. Orange geometry is the generated sweep; gray geometry is the reference surface.

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close