Files
OneCAD-Simulation/docs/meshing/corpus.md
T
5afd1addb9 Structured hex: extrude, revolve, sweep and mapped all-hex meshing (M5) (#40)
* Structured hex meshing: multi-level extrude and revolve, one-to-one sweep, mapped blocks (M5)

modelcraft_mesh::hex::hex_mesh meshes a face-tagged boundary surface with
hexahedra by the first structured method that fits: a straight or
rotational multi-level sweep (imprinted cross-section arrangement, cuts at
reflex corners, mapped/annulus/free regions), a one-to-one sweep through
rings of linking faces (least-squares affine layers with residual
correction), or a mapped logical cube (trivariate transfinite
interpolation). Interval assignment couples shared curves; boundary quads
carry B-rep face tags; the certified validity gate, a tiling check and a
fidelity check guard the output; hex20 mid-edge nodes go onto the faces.
Shape::face_surfaces exposes the analytic face surfaces; the corpus runner
gets a structured hex column.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* mesh.hex.generate: structured hex meshing as a command

Meshes one body, every body of the open design or an imported surface,
replaces the mesh, tags element faces with the B-rep faces (so sets by
geometry resolve) and reports per body the method, counts and quality.
The quality pass certifies each element once and feeds the validity gate
(quality::validity_gate_checks). Shape::size gives the cached body size
for defaults instead of a full measure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* Hex: disk O-grids, convex interval cost, early size guard, hex20 corpus column

Smooth single-loop sections (cylinders, tori, vases) get a butterfly O-grid
instead of the free mesher; interval assignment raises counts by the
squared relative error so equal sides share increments evenly; a mesh far
beyond the element limit is refused before any work and mapped limits are
no longer swallowed. The corpus reports hex8 and hex20 quality.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* Catalogue: structured hex commands ready (mesh.hex.sweep, mesh.hex.mapped, mesh.hex.generate)

mesh.hex.sweep and mesh.hex.mapped run mesh.hex.generate with the sweeping
methods or the mapped one; mesh.hex.generate is the sweep entry's related
command. The planned M6 octree entry moves to mesh.hex.octree (its icon
renamed with it). docs/features.md regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* Docs: structured hex literature (B8), architecture, roadmap, parity; corpus hex column

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* Hex: simplify review fixes

Prepare each sweep frame's cross-section once (arrangement, cuts, fill)
and reuse it across refinement retries; candidate frames come from one
setup pass. Edge triangles come from the feature edges, layer counts go
through size::edge_divisions, sweep residual weights are computed once
per node, flux shape functions live on the stack, and the arrangement's
exact side test and distances serve the region probe. The engine takes
the boundary options mesh.tet.generate takes and names unnamed faces by
index like it; the corpus hex20 run reuses the winning method; the
mapped entry lists mesh.hex.generate too; the octree icon is redrawn
under its new id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* Regenerate docs/features.md and docs/meshing/corpus.md after rebasing

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* Regenerate docs/features.md and docs/meshing/corpus.md after rebasing onto main

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* Regenerate docs/features.md and docs/meshing/corpus.md after rebasing onto main

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* Regenerate docs/features.md and docs/meshing/corpus.md after rebasing onto main

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* Regenerate docs/features.md after rebasing onto main

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* Regenerate docs/features.md after rebasing onto main

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* Regenerate docs/features.md after rebasing onto main

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

---------

Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 22:25:50 -04:00

10 KiB
Raw Blame History

Meshing test corpus

Generated by cargo xtask corpus; do not edit. The parts are our own: SolidCraft recipes in tests/corpus/<name>/recipe.json and analytic shapes generated in code (crates/testkit/src/corpus.rs). Each run rebuilds every part, tessellates it at a chordal tolerance of 1e-3 of its bounding-box diagonal and runs every stage on it. Times are wall clock on the machine that ran it; every other column is deterministic.

Results

part categories bodies faces triangles tol. mm build ms enclosed mm³ SolidCraft mm³ rel. diff exact mm³ boundary genus feature edges check ms CDT tets Steiner cavities tet gate CDT ms hex hex elements hex8 min SJ hex20 min SJ hex ms
bent-tube sweepable, thin-wall, genus 1 18 4296 0.121 454 4213.1 4159.4 1.3e-2 4159.8 ok, 2148 vertices 1 268 11.5 15550 2338 0 pass 606 sweep 192 0.859 0.997 63
bolted-assembly assembly, blocky 3 22 284 0.117 206 33004.7 32999.0 1.7e-4 32998.9 ok, 144 vertices 0, 1, 1 104 0.7 690 181 0 pass 34 extrude 357 0.398 0.222 40
cross-cylinders boolean, sharp 1 10 1395 0.087 7920 32197.4 32357.8 -5.0e-3 32365.8 error: Cross: invalid boundary surface: 28 defects; triangles 142 and 184 are oriented inconsistently across edge 0–396 at (-15.488656021315903, 4.577998041166734, 7.853092194999726); triangles 184 and 239 are oriented inconsistently across edge 0–554 at (-18.75000000000002, 5.634596901641276, 7.632255089815496); edge 103–108 at (-0.16007784063084018, 0.03984236936862052, 9.998639270596865) is shared by 3 triangles; … error: Cross: invalid boundary surface: 28 defects; triangles 142 and 184 are oriented inconsistently across edge 0–396 at (-15.488656021315903, 4.577998041166734, 7.853092194999726); triangles 184 and 239 are oriented inconsistently across edge 0–554 at (-18.75000000000002, 5.634596901641276, 7.632255089815496); edge 103–108 at (-0.16007784063084018, 0.03984236936862052, 9.998639270596865) is shared by 3 triangles; … error: Cross: invalid boundary surface: 28 defects; triangles 142 and 184 are oriented inconsistently across edge 0–396 at (-15.488656021315903, 4.577998041166734, 7.853092194999726); triangles 184 and 239 are oriented inconsistently across edge 0–554 at (-18.75000000000002, 5.634596901641276, 7.632255089815496); edge 103–108 at (-0.16007784063084018, 0.03984236936862052, 9.998639270596865) is shared by 3 triangles; …
filleted-bracket fillet, genus, sweepable 1 13 540 0.088 388 32162.3 32145.0 5.4e-4 32144.8 ok, 268 vertices 2 135 1.4 5582 1613 0 pass 208 no: Bracket: not supported yet: no structured hex method fits this body (extrude: cylindrical face 8 is not parallel to the direction; sweep: from face 1: linking face 6 has 2 boundary loops (periodic or holed linking faces are not swept); from face 6: 5
i-beam sweepable, thin-wall 1 14 44 0.208 3 61600.0 61600.0 0.0e0 61600.0 ok, 24 vertices 0 36 0.1 94 24 0 pass 4 extrude 336 0.707 0.707 34
loft-transition organic 1 6 292 0.075 57 56390.2 56450.6 -1.1e-3 – ok, 148 vertices 0 40 0.7 1329 256 1 pass 38 sweep 2873 0.189 0.189 328
perforated-plate genus, thin-wall, sweepable 1 54 1644 0.144 273 26822.2 26764.6 2.2e-3 26764.2 ok, 776 vertices 24 828 4.8 33611 9798 0 pass 1345 extrude 467 0.304 0.033 98
pinhole-block small-feature, genus 1 38 4044 0.073 201 49919.4 49909.6 2.0e-4 49909.5 ok, 1992 vertices 16 1548 12.9 96411 30221 0 pass 8142 extrude 5236 0.408 0.392 735
rounded-box fillet 1 26 2540 0.054 235 23325.7 23340.5 -6.3e-4 23340.8 ok, 1272 vertices 0 216 8.4 11663 1916 0 pass 469 no: Box: not supported yet: no structured hex method fits this body (extrude: cylindrical face 8 is not parallel to the direction; sweep: from face 0: 12 faces are not on the sweep path; from face 5: 12 faces are not on the sweep path; revolve: plan 15
shallow-groove near-tangent, boolean 1 8 62 0.075 11 47795.2 47782.3 2.7e-4 47781.5 ok, 33 vertices 0 24 0.2 267 87 0 pass 13 extrude 1960 0.991 0.986 201
sharp-wedge sharp, thin-wall, sweepable 1 5 8 0.083 2 3200.0 3200.0 0.0e0 3200.0 ok, 6 vertices 0 9 0.0 11 3 0 pass 0 extrude 294 0.050 0.050 30
sphere-on-plate near-tangent, boolean 1 12 2826 0.098 974 69353.3 69509.0 -2.2e-3 69509.7 ok, 1415 vertices 0 124 7.2 4898 309 9 pass 260 no: Plate: not supported yet: no structured hex method fits this body (extrude: face 6 is curved across the direction; sweep: from face 0: 6 faces are not on the sweep path; from face 5: linking face 11 has 2 boundary loops (periodic or holed linking 11
spline-vase organic 1 11 3890 0.106 226 94891.2 94948.5 -6.0e-4 – ok, 1947 vertices 0 243 9.0 12461 1512 0 pass 456 sweep 4554 0.649 0.649 547
stepped-block blocky, sharp 1 14 96 0.078 264 47000.0 47000.0 0.0e0 47000.0 ok, 48 vertices 1 60 0.4 223 41 0 pass 7 extrude 1416 0.999 0.999 142
thin-ribs thin-wall, blocky 1 26 92 0.119 1004 32000.0 32000.0 -4.5e-16 32000.0 ok, 48 vertices 0 72 0.6 171 33 0 pass 8 extrude 777 0.844 0.844 100
thin-wall-enclosure thin-wall, blocky 1 11 36 0.108 340 15564.0 15564.0 0.0e0 15564.0 ok, 20 vertices 0 28 0.2 191 47 2 pass 11 extrude 894 0.297 0.297 112
analytic-sphere analytic 1 6 2784 0.069 719 33353.4 33507.9 -4.6e-3 33510.3 ok, 1394 vertices 0 96 12.6 4211 58 0 pass 440 no: Sphere: not supported yet: no structured hex method fits this body (extrude: no direction to try; sweep: no planar face to sweep from; revolve: no axis to try; mapped: meshing failed: meshing failed: mesh validity gate: 8 inverted or degenerate ele 31
analytic-torus analytic, genus 1 6 7230 0.109 944 37644.1 37893.7 -6.6e-3 37899.3 ok, 3615 vertices 1 180 25.6 19790 466 0 pass 1412 revolve 1134 0.706 0.706 280
analytic-cylinder analytic, sweepable 1 4 1004 0.049 190 12533.1 12564.7 -2.5e-3 12566.4 ok, 504 vertices 0 106 3.4 7437 1568 0 pass 452 extrude 3200 0.707 0.707 585
analytic-pipe analytic, genus, sweepable 1 6 1448 0.104 336 94150.9 94238.0 -9.3e-4 94247.8 ok, 724 vertices 1 220 9.0 6238 1340 0 pass 479 extrude 1288 0.998 0.998 290
analytic-plate-hole analytic, genus, sweepable 1 8 112 0.224 231 98449.1 98429.5 2.0e-4 98429.2 ok, 56 vertices 1 62 0.9 1868 543 0 pass 72 extrude 321 0.320 0.142 55

Categories

category stresses parts
thin-wall walls thin against the part's size 6
small-feature features much smaller than the part 1
fillet blends between faces 2
genus through holes (genus > 0) 7
sharp sharp edges and acute dihedral angles 3
near-tangent faces meeting at a shallow angle 2
boolean intersection curves from booleans 3
sweepable extrusions and sweeps (one-to-one sweep meshing) 8
blocky axis-aligned blocks (polycube-friendly) 4
organic free-form, lofted or revolved spline surfaces 2
assembly several bodies placed by component transforms 1
analytic closed-form geometry for solver verification 5

Parts

  • bent-tube: A 10 mm tube with a 1 mm wall, bent through R30: a thin-walled sweep along a line-arc-line path.
  • bolted-assembly: A base plate with a clamp block component placed twice, once turned 90 degrees: bodies placed by component transforms.
  • cross-cylinders: Two orthogonal R10 cylinders joined: equal radii, so the intersection curves cross at two singular points.
  • filleted-bracket: An 8 mm L-bracket with an R6 inside fillet and a hole through each leg: a blend beside holes.
  • i-beam: A 200 mm I-beam with 3 mm flanges and a 2 mm web: a long sweepable prism with thin walls.
  • loft-transition: A 40 mm square lofted to an R15 circle 50 mm above: a ruled free-form surface between unlike sections.
  • perforated-plate: A 3 mm plate perforated by a 6 x 4 grid of 6 mm holes: genus 24 in a thin sheet.
  • pinhole-block: A 50 mm block drilled through by sixteen 0.6 mm pinholes: features 80 times smaller than the part, genus 16.
  • rounded-box: A 40 x 30 x 20 box with every edge rounded R3: cylinder and sphere blends meeting at the corners.
  • shallow-groove: A block with a 0.5 mm deep groove cut by an R30 cylinder: groove walls 10 degrees off the top face.
  • sharp-wedge: A wedge whose faces meet at under 3 degrees: a sharp edge with a needle-thin cross-section.
  • sphere-on-plate: A sphere sunk 0.1 mm into a plate: the faces meet at under 6 degrees around a 2 mm circle.
  • spline-vase: A vase revolved from a spline profile: doubly curved faces of varying curvature around a closed axis.
  • stepped-block: Three stacked blocks with a slot cut through the base: axis-aligned steps for polycube and octree meshers.
  • thin-ribs: A 4 mm plate carrying five 0.8 mm ribs 20 mm tall: thin walls standing on a thicker base.
  • thin-wall-enclosure: An 80 x 60 x 40 box shelled to 1 mm walls, open on top: thin walls over a large span.
  • analytic-sphere: Sphere r 20: curvature everywhere, no edges.
  • analytic-torus: Torus 30/8: genus 1 with doubly curved faces and no edges.
  • analytic-cylinder: Cylinder r 10, h 40: the round bar of beam and torsion checks.
  • analytic-pipe: Thick-walled pipe 20/30, length 60: the Lamé cylinder.
  • analytic-plate-hole: Plate 200 x 100 x 5 with a 20 mm hole: the Kirsch plate.