Skip to content

CSG Mesh Path

PHITS cell expressions are the geometry truth. The viewport mesh is generated inspection data and never a second geometry model.

Ownership

geometry.odin owns PHITS surfaces, cells, materials, expression terms, and geometry revision. It does not own render meshes.

csg_mesh.odin owns signed-distance evaluation, expression compilation, bounds, and Marching Cubes extraction. csg_mesh_cache.odin owns CPU/disk cache state; preview_mesh_job.odin owns asynchronous preview work; and cell_diagnostic_cache.odin owns cached cell diagnostics.

App_State owns the active CSG settings, cache, preview job, and diagnostic cache. editor_geometry.odin owns the shared cached mesh, diagnostic, bounds, and picking queries. renderer.odin, renderer_cells.odin, and renderer_preview.odin own GPU scene data and upload preparation. Cache identity includes cell identity, geometry revision, and CSG settings.

Expression semantics

cell_expression_signed_distance evaluates the same expression represented by the PHITS cell:

  • inside-surface terms use the surface signed distance;
  • outside-surface terms negate it;
  • outside-cell terms recursively evaluate the cutter cell and negate it; and
  • the cell distance is the maximum of the active constraints.

Raw PHITS cells remain preserved/exportable. They are meshed only when reduced to RAMAL-editable terms. Construction surfaces are not final-cell geometry.

Extraction path

csg_mesh_build_cell first emits exact planar faces for an untransformed RPP cell and for a closed RPP shell whose coextensive cutter slabs merge into one rectangular cavity. These meshes are independent of viewport quality. Other cells compile their expressions and #cell references once, sample a bounded signed-distance grid, and use the literal 256-case Marching Cubes table. That path uses a dense grid-edge cache, finite-difference normals from sampled values, and geometry/grid-normal checks for triangle rejection and orientation. PHITS TRCL transforms are reduced to the canonical affine mapping; surfaces are not baked into a separate model.

The active settings are resolution, complex_resolution, padding_fraction, and min_padding. Changing them clears the CPU cache and invalidates renderer CSG models. For multi-term RPP expressions, a thin axis is sampled more densely when a participating RPP feature would otherwise fall between slices, up to the selected resolution cap. This protects small features in expressions that cannot use the exact planar path while leaving the PHITS expression unchanged.

Current guarantees and limits

The current tests cover thin curved cuts, tangent curved cutters, nested #cell cutters, near-plane clipping, empty-volume rejection, and the converted source-head envelope's exact outer and inner RPP faces at every 36/48/72/96 viewport-quality preset. The exact path also rejects invalid/non-finite RPP bounds, non-coextensive cutter cross-sections, and real gaps between cutter slabs rather than merging them because the surrounding scene is large. The code also contains an opt-in cold-extraction benchmark:

RAMAL_CSG_BENCH=1 odin test . -define:ODIN_TEST_THREADS=1
RAMAL_CSG_BENCH=1 RAMAL_CSG_BENCH_EXTERIOR=1 odin test . -define:ODIN_TEST_THREADS=1

Open robustness work supported by the current extraction/tests is limited to extraction quality: more sliver and boundary stress cases, explicit saddle-case ambiguity handling, broader topology checks, adaptive sampling around sign changes, and keeping PHITS diagnostics/export rules aligned. These are robustness issues in the generated inspection mesh, not reasons to add another geometry truth source.

Resolved converted-head Cell 13 viewport failure

On 2026-08-27, converted-head envelope Cell 13 appeared smooth in Fast and Balanced but showed tilted diamond-shaped holes and serrated faces in High. The PHITS expression was valid; the defect was limited to the inspection mesh. Marching Cubes sampled the thin, coextensive cutter slabs at quality-dependent positions, so the visible approximation changed with resolution. After the exact planar RPP-shell path was added, the on-disk mesh cache could still serve the earlier High mesh because its representation identity had not changed.

The repair has two required parts:

  1. eligible RPP shells emit exact outer and inner planar faces, independent of viewport quality; and
  2. the disk-cache format identity is advanced whenever a mesh-representation change would make older cached geometry invalid.

Regression coverage requires the same exact converted-head shell at every 36/48/72/96 preset and separately rejects false cutter merges. If a future quality preset shows different topology, first determine whether the Cell used the exact or sampled path and whether a stale disk entry was loaded. Never modify the PHITS Cell expression to conceal a viewport-only defect.

Hard-cut rules

  • Do not restore primitive preview meshes as the final-cell view.
  • Do not pick final cells from construction-surface bounds.
  • Do not bypass expression exclusions or keep an old compatibility loader.
  • Keep construction surfaces as authoring aids and final regions on the CSG expression path.