Repository navigation
OpenGeometry 3.0.0 - #25
Open
aka-blackboots wants to merge 211 commits into
Open
aka-blackboots wants to merge 211 commits into
aka-blackboots wants to merge 211 commits into
Conversation
Restructure the 2.5 kernel and Three.js SDK to the planned layer tree and enforce the coding standards mechanically, with behaviour proven unchanged: the debug kernel snapshot (461 cases), the SDK snapshot and the API surface are byte-identical to the Phase A baseline, the parity oracle output equals its fixtures, and every gate passes on a clean rebuild. Kernel: one-way layer order, curated public API (776 to 322 paths), every non-test function at most 80 lines and 7 parameters, shared helpers consolidated, tests/source_rules with frozen one-way exception lists, a test-support crate, string errors typed. SDK: split into dto, kernel, world-graph, rendering, marks, bodies, picking, export and runtime modules behind a 63-line facade; strict tsconfig, typed ESLint with layer rules, source, cycle and duplicate checks, a testing entry, and the scripts and browser tests in their planned homes.
npm run check runs every Rust and SDK gate from main-v2.5 in a fixed order, logs each step to .check/<step>.log, keeps going past failures and exits non-zero with the failed step names. check:full adds the Playwright runs on three 0.168 and 0.184. --only and --from pick a subset.
…orted Covers --only, --from, --skip, the empty selection, unknown names and missing values, the test:wasm rename, and the performance and browser flake classifier, before verify.mjs exports them.
Clippy gets its own target dir so cargo re-lints only what changed without touching sources. A rotated20BooleanMs regression is retried twice and the memory disposal browser test is repeated five times before either counts as a failure; any other regressed metric is marked INVESTIGATE. Browser ports, Playwright output and vite caches follow OG_PW_PORT_BASE and the three version, so the 168 and 184 runs overlap. Step selection gains --skip, fails on empty selections and bad arguments with one line, and verify.mjs runs steps only as the entry script so its pure functions are testable.
… STEP Finding O:orc-1: batch subtraction had no oracle. These tests replay a batch-matrix fixture corpus recorded from main; they fail until the oracle writes it. The STEP matrix loop becomes one helper shared by the boolean and batch matrices.
Finding O:orc-1: subtract_planar_cutters had no oracle. The traced copy now records subtract_planar_cutters and its batch handlers, and a batch module rebuilds the snapshot's batch scenes (13 entries, 4 ordered scenes and the staged mixed scene in both orders, 23 rows) with main's builders, writing each row's result, handlers and STEP files to batch-matrix/, plus a serial fallback row for non-mixed coverage gaps. The STEP writer moves to write.rs so matrix and batch share it; matrix output is unchanged. Five helpers repeat the snapshot's across kernels and get allowed duplicate groups.
…ode per context Retires the frozen operations->world_graph upward imports and module cycle, and adds tests that SingularParameterization takes the code of its graph context and that every OperationError keeps its code and message as a GraphError. Both fail until OperationError and ErrorContext exist.
…form The five boolean .tess.json files are never read and no matrix or batch row has a tessellation fixture, so a regression in the ported trimmed-face refinement goes unnoticed. Main numbers refinement midpoints from a HashSet, so the comparison is made over an order-free canonical form built in test-support. The batch fixture listing moves to tests/parity/support.rs so the new test shares it.
The standards review of W-B1 found batch.rs sitting beside batch/, which breaks the mod.rs convention for directory modules, and parts.rs exposing upright, arc and Part's fields wider than their only users in parts.rs need. scene and ordered now sit below their last caller, and four duplicate-group reasons name the snapshot helpers as general fixtures rather than batch-only ones. No output changes.
operations no longer imports world_graph: creating steps return OperationError, which world_graph converts into GraphError with the same code, message and null details. CreatingOperation and ModifyingOperation move into world_graph, and operands.rs keeps its own invalid(). SingularParameterization now reports InvalidGeometry, and every graph entry point rewrites it by ErrorContext (Create/Rebuild to InvalidParameter, Transform to InvalidTransform). The frozen upward imports and the operations<->world_graph cycle are retired; the sweep line_edge duplicate pair is re-keyed and its merge deferred to the debt note.
…sults The oracle now tessellates every boolean fixture and every matrix and batch row whose result holds a BRep with main and with traced, asserts the two agree in an order-free canonical form, and writes it under tessellation/. Main numbers refinement midpoints from a HashSet, so vertex numbering is not stable across runs; the canonical form sorts vertices, triangles and outline segments so the fixtures are. The canonical helpers exist once per kernel, recorded as allowed duplicate groups.
The fixture-reading one-liner existed twice in the parity tests; it now lives once in support.rs beside parity_fixtures, both pub(super) like every other test-crate support module. The oracle's canonical.rs lists its steps below their caller in call order and separates every function with a blank line.
The standards verifier found invalid declared pub(super), which from operations/mod.rs is crate-wide, while its only callers are descendants of operations; private is the narrowest visibility that compiles. The blank line in sweep/mod.rs was left by the removed world_graph import.
86a80b4 removed a blank line in sweep/mod.rs, moving line_edge from line 270 to 269; the allowlist member now matches what check:duplicates reports. Hash, count and reason are unchanged.
The blank line added before canonical_vertices moved the later canonical functions down one line; the allowlist members now name the lines the duplicate check reports.
Pins D6 (a name over 4 KiB is LimitExceeded, empty stays InvalidParameter), D7 (the exportStep node list is exempt from the 64 KiB params cap, capped at 100,000 ids, ids over 1,024 chars are InvalidParameter) and the export of a Body's children in stored order. params.rs moves to params/mod.rs so its tests sit beside it.
Pins typed ErrorDetails on GraphError: every GeometryError variant keeps its code in every context, a failing chained operate names its handlers, tool index and og_ids, a failing multi-body export names the body, and the bindings DTO keeps the error JSON byte-identical. Retires the frozen serde_json entries on world_graph/error.rs.
expand_export now walks every node's children depth-first in stored order, so Solids parented under a Body are exported and Wires or Sheets under it are reported in skipped (S:step-4). A name over 4 KiB is LimitExceeded, separate from the InvalidParameter option faults (D6). exportStep reads its node list through params::nodes, which is exempt from the 64 KiB params cap, caps the list at 100,000 ids without allocating the extra one and rejects ids over 1,024 chars as it reads (D7).
…ar sweep seams stay bitwise watertight The validity test named 20 of the 28 verdict fixtures and skipped arc, circle, cuboid and the five builder-box and builder-sphere-cut pairs. Looping over every verdict file in the folder keeps new fixtures from being skipped. Refinement midpoints on the circular L-path sweep reuse the boundary sample they coincide with in uv; evaluating the surface there instead leaves seam edges that differ in the last bits and break bitwise watertightness. No parity fixture reaches the reuse, so it stays and this test pins it.
GraphError::Code now carries ErrorDetails instead of a serde_json Value, so error.rs leaves the frozen serde_json lists. Operate failures raised by the boolean handlers keep the handlers recorded so far, the failing tool's index and the operand og_ids; multi-body STEP export failures in preflight or emission name the failing body. The bindings build the error JSON through ErrorDto with unchanged bytes, and the snapshot tool records every GraphError as the same code/details/message JSON.
…gates need The golden file hashes case records, handler listings and extra texts, so 'record text' was too narrow. CI runs on Ubuntu and macOS and compares on neither. The release step said 'locally', but the comparisons it relies on run only with CI unset, and two of them only on a machine with a golden file for its target and a timings block.
A line-and-arc Profile wire and a partial Arc wire, accepted as extrude profiles and holes so extrude reaches the arc-edged builder. Fixes the offset circular hole that was refused (the probe left the outer seam) and gives InvalidParameter for a hole that encloses the profile. SDK constants and types, golden scenes, an Unreleased migration entry and README rows.
The 2.0.18 helper moves to tests/node and the growth test is rewritten against the world-graph create calls. It counts 737 growth steps for 5,000 kept cuboids (19 to 982 pages), which decides that the memory module of OPE-17 is needed. Recorded numbers are compared only off CI.
body.getWorldBrep() returns the BRep placed by the node's world transform, read-only, with the shape id and revision kept so it matches getBrep() for an unmoved body. body.faceNormalAt(faceId, point) returns the body-local normal with the face sense applied; an unknown face is InvalidParameter. Migration entry and README rows.
OG_PRIMITIVE_CYLINDER_SECTOR builds a solid sector through the existing builder at the plane frame; a zero, non-finite or full-turn sweep and sizes at or below four geometric tolerances are InvalidParameter. SDK constant and type, golden scenes, migration entry and README row.
The 2.0.18 allocator as the root module memory: on wasm32, after a growth, it reserves one eighth of the memory between 1 MiB and 64 MiB, and stops after a refused reserve. 5,000 kept cuboids now grow the memory 22 times instead of 737. The layer list gains the memory line; the node tests port the 2.0.18 limit and worst-case tests, and the section reader is checked against the engine's import list.
A sweep with caps: false builds an open-ended Sheet body: the graph accepts a faces-without-solids result as a Sheet for that sweep only, and refuses it for a Solid request with BodyTypeMismatch. caps defaults to true, so a capped sweep is unchanged; the golden moves only by the Sweep label. The SDK gets the Sheet class and the Sheet body type. STEP export refuses a Sheet with InvalidOperand, as for a Wire.
OG_PRIMITIVE_POLYHEDRON builds a closed solid from the app's points and planar face rings. The builder checks planarity within the geometric tolerance, that each edge is used twice in opposite directions, outward winding, one shell, manifold vertices and unused or repeated points, and exits through validate(); every refusal is InvalidParameter or InvalidTopology. A polyhedron reaches the planar boolean handlers, so a hip roof minus a chimney and a wall minus a roof cut exactly. SDK constant and type, golden scenes, migration entry and README row.
…E-5) The 2.0.17 and 2.0.18 region-boolean fixes, carried into geom2d: endpoints weld by distance instead of a grid key, the probe is bounded by the clearance to other edges, a hole goes to the smallest containing ring, a ring is degenerate when its area is below eps times half its perimeter, and an open chain or an orphan hole is an error. The planar boolean handlers map it to InvalidTopology. No stored result moves: the fixes change decisions the existing scenes never reach.
An arc segment in a sweep path builds exact bend faces: cylinder, annular plane and cone faces for each polygon profile edge, and two half-torus faces for a circle profile, all with exact pcurves. Floorkit's 0.4 x 0.25 m duct elbow and a round pipe elbow build as one arc and export to STEP. Joints at an arc must be tangent within 1e-9 rad, otherwise InvalidParameter; arcs above half a turn split into equal bends; the bend radius must clear the profile reach by four geometric tolerances; the overlap and mitre-span rules are unchanged; caps: false gives an open elbow Sheet. A sweep without arcs is byte-identical. One commit, because the face code alone is unwired and would fail the dead-code check.
The curved region boolean welds endpoints by distance with the clearance rule of OPE-5 instead of the quant grid key, in all three places that used it. The winding wraps a travel just below a full turn, so a point on an arc's seam ray winds once, and an arc end meeting a line is counted once. An orphan hole is now InvalidTopology instead of being dropped. No stored result moves.
OpenGeometry.exportIfcBody(body) returns the 2.0.18 V2 exchange body, read-only like STEP export: the world-placed BRep in Z-up metres, 27 IFC entity types, CSG with IfcBooleanResult for cavities, and the 2.0.18 refusals. Its output equals 2.0.18 byte for byte on all 50 exportable fixture and matrix bodies, recorded from the 2.0.18 crate as stored cases. A Wire or Sheet is InvalidOperand. STEP export is unchanged: its Z-up similarity and body placement are shared, not copied.
A closed path closes its last joint by the mitre rule and has no caps; a straight closing joint is a perpendicular section. Also repairs the IFC example fences in MIGRATION.md.
… widened tube (OPE-12) A refused span is cleared only when a padded three-sample box of each piece misses the trim boxes; a correction that fails in its tube is retried once in a tube widened per axis and accepted only near its anchor segment.
booleanRegions2D and booleanCurvedRegions2D take and return the 2.0 wire format, with OG_REGION_TOLERANCE and the exported region types; the SDK refuses a bad operation, a non-list operand and unknown planar fields before the kernel sees them.
…n (OPE-12) The generic band handler gains a chain path for a cutter whose sides cross the wall's two faces once each, as an arched profile does. The open pieces join at the cutter's corner edges, a band face's seam turns away from the opening, and every case it cannot cut is a CoverageGap. The vertical-arc probes take their reach from the nearest boundary.
offset_ring_variable subtracts an exact stadium per edge from the ring and its holes, drops a convex corner's redundant cap where nothing else is near, refuses a self-crossing ring, and keeps an edge too short to clip as one disk; OGWorldGraph.offsetRingVariable binds it.
…otch (OPE-20) The band chain path takes a cutter that crosses both wall faces and the bottom cap, or whose sill touches the cap within 4 geometric tolerances: each wall face gets an open notch spliced into its outer loop and the cap is cut through. Every other case stays a CoverageGap.
…nds by their centre (OPE-8) Every curve pair also offers the curves' ends that lie on both, crowded pieces are probed away from the other curve, duplicate pieces match by ends and middle within tolerance, and an arc end snapped onto a ray counts by the side its centre lies on.
…(OPE-8) offset_polyline_regions unions exact segment rectangles with mitre or bevel wedges; offset_path ports 2.0's one-sided offset at its own tolerance; both are bound on OGWorldGraph. The curved boolean now looks only at pieces whose padded bounding boxes can meet, with the same output.
…ng pieces (OPE-26)
…a clipped stair waist tessellates (OPE-25)
… tests (OPE-22, OPE-23)
Every file main changed is a 2.0 file that the 3.0 tree deletes or replaces, so the 3.0 side is kept for each one. - 533710f (2.0.17) and the 2D region fixes of cba5c0a are in geom2d (OPE-5, OPE-6); their tests moved into the crate. - The memory work of cba5c0a is the memory module (OPE-16, OPE-17). - The tessellation cache and accuracy rule of cba5c0a do not apply to the 3.0 tessellator. - 46de326 (#28), the exact cylinder minus an oblique half-space cuboid, is not in 3.0 yet; tracked as OPE-33. - The root package.json keeps the 3.0 workspace form; the version lives in main/package.json.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The new kernel, released as 3.0.0. It replaces the 2.0 code with a B-rep kernel in Rust and WebAssembly and a new TypeScript SDK for Three.js. Code written for 2.0 must change:
MIGRATION.mdshows how.What 3.0.0 adds on top of the new kernel:
The 2.0.17 and 2.0.18 fixes from
mainare carried into the new code.main's #28 (an exact cylinder cut by an oblique box face) is not in 3.0 yet: such a cut stops with aCoverageGaperror, not a wrong result.Checks:
npm run check:fullpasses.