Files
FreeCADWasmDev/docs/current/PART_PRIMITIVES_PROJECTION_PROGRESS.md

17 KiB

Primitives and Projection Checkpoint

Latest Continuation: 2026-09-17 17:57 UTC

Batch 4aa3ea5e85f9c4b3e4412ba2; both selected commands remain incomplete. This continuation completes primitive subelement vertex snapping. Earlier requirements and deferred cases below remain in force except where explicitly superseded by the verified behavior here.

  • DocumentProbe.cpp now serializes unique OCCT vertices from the existing transformed display shape when builder geometry is requested. Vertices retain native precision and world placement. The document facade validates finite triples and agreement with the native topology count.
  • The mounted primitive task passes these coordinates into the existing Three.js view. Its optional vertex picker uses a 10 CSS pixel radius and mesh occlusion checks, returns the exact native point, and consumes misses without changing the draft primitive or its name. Surface picking remains independently usable. Callback refs avoid rebuilding the scene when arming/disarming a pick.
  • Extended tools/part-circle-vertex-picking-business-cases.mjs: a plane rotated 90 degrees and translated 4 mm exposes four expected world vertices; desktop and mobile clicks offset by 3 pixels snap to the exact vertices. Face-interior clicks keep the gate armed and fields unchanged. Creating the arc asserts radius sqrt(200), a 180-degree interval, native endpoints, valid topology, no pre-create document/history changes, and atomic undo/redo.
  • Existing standalone vertex, surface pick, cancel, OPFS/FCStd, desktop/mobile canvas pixel and layout assertions remain executable and completed.

Validation:

  • web/node_modules/.bin/tsc --noEmit -p web/tsconfig.json passed.
  • Focused FreeCADWebDocumentProbe build passed using python3 tools/build_web_module_artifacts.py --target FreeCADWebDocumentProbe --jobs 8 --timeout 240.
  • node web/tools/sync-assets.mjs copied three files, skipped 101, and updated the manifest in 3.549 s. Existing server at http://127.0.0.1:5180 was reused.
  • Combined unchanged runner invocation for both selected IDs produced business-evidence/32e5a354bbd763bd5df41ad4-20260917T175628274821.json in 21.338 s. Projection completed five assertions, including native linked geometry/recompute/FCStd and mounted desktop/mobile cases, with no case error. Primitive failed only in the new test's comparison of create versus read response metadata (createdObject versus attachmentEditing). Fixed the new fixture to capture its baseline with a read; no old assertion was relaxed.
  • Isolated runner invocation python3 tools/run_business_acceptance.py --module Part --ids Part:desktop:Part_Primitives --reuse produced business-evidence/13fb362e5bcf598a7f1f90a6-20260917T175702364139.json in 15.127 s. All four recorded scenario groups passed, browser and cleanup completed. Native browser load took 2.391 s; the new subelement stage took 2.487 s. The runner correctly returns acceptance_incomplete, exit 1, zero completed commands, because the remaining requirements are explicit.
  • Screenshots and detailed results: part-circle-vertex-picking-business/2026-09-17T17-56-47-560Z/. subelement-vertices.png and mobile-canvas.png were visually inspected and show the native arc/plane and vertex geometry. No blank viewport was observed.

Next work:

  1. Primitives: desktop location picking, expression binding and task lifecycle. Reuse completed three-point circle, vertex/surface picking, all sixteen primitive types, placement/container and cylinder skew implementations.
  2. Projection: task activation/live preview transaction, commit on accept, rollback on reject, and viewport face/edge/wire selection gates. Its existing linked-object workflow completed again after this native snapshot change.
  3. Preserve all deferred legacy scenario lists. This focused turn did not rerun every primitive type or every projection mode. Mesh occlusion is implemented for snapping; a dedicated overlapping-solids occlusion fixture remains useful. Arbitrary nested/scaled-link vertex snapping was not separately exercised.

No acceptance machinery, contract, verifier, proof requirements, passing status or coverage tag was edited. docs/business-acceptance/Part.json still matches the supplied packet hash 86146084d148d0fa402a8af92d00f5cc5fff0fed08985a649c17567d75faf084. No IFC implementation or claim was made; the IFC semantic export contract stays in force. No full-parity/API gate, deployment, push or external message occurred.

Current implementation hashes:

File SHA-256
DocumentProbe.cpp d09993d329e8c2683ba6a58ae1fde7af3999229d8c511280f780c7ba23842d1d
part-document-facade.ts 7ee5d7193f3d698b392acb0b27bf7565c0b63f476ac1fc9972b23c9b3a01289d
openscad-desktop-view.tsx f0fe640b02c9d7a2caa5002876205960b090e18657354cd1ddece451977a8126
part-primitives-task.tsx 160d64713b89ba4ea75a6e965267c3d64b09a6914f83cbb8eae242c42aa33d5f
part-circle-vertex-picking-business-cases.mjs dcbddef086cc311f3c176ebb071fb60a369cf30fdecf03ce1bf8f3050ed68bff
FreeCADWebDocumentProbe.wasm e5721f7be1c7146b76711148150887c1ec58974fc5b28b33f370f9edbe31d6c0

Earlier Checkpoints

Primitive continuation at 11:07 UTC: Cylinder skew is now implemented with nine completed new scenario groups. Keep the container/link work below; next primitive gaps are three-point circle picking, location/expression UI and live task lifecycle. Full command acceptance remains incomplete.

Latest Continuation: 2026-09-17 10:51 UTC

Batch 4aa3ea5e85f9c4b3e4412ba2 remains incomplete for both selected IDs. This update supersedes the historical placement/container and linked-object gaps below only to the extent of the concrete checks described here. All other original and supplemental requirements remain in force.

Implemented and Reused

  • Reused the mounted primitive/projection tasks, Part adapter, document facade, existing OCCT geometry and FreeCADWebDocumentProbe owner. No dispatcher or frontend application changes were needed.
  • Fixed DocumentProbe.cpp snapshot serialization: linked objects now resolve through Part::Feature::getTopoShape(ResolveLink | Transform) and expose native topology, edge samples and face meshes while retaining App::Link identity. This fixes the actual browser SupportLink selector timeout.
  • Feature display shapes apply the official GeoFeature::getGlobalPlacement parent transform, removing the already-applied local placement before composition. Mesh positions/normals/bounds, edge samples and vertex markers now share world placement. Editable feature placement stays local.
  • Extended tools/part-primitive-container-business-cases.mjs with translated and rotated nested Parts, root-object invariance, local rotation/translation, analytic mesh/edge/point coordinates, FCStd reopen, browser OPFS/history, desktop/mobile canvas pixels and orbit movement.
  • Extended tools/part-linked-projection-business-cases.mjs with link snapshot topology/mesh assertions, actual mounted support/source selection and native projection, plus desktop/mobile render and selector bounds checks. Existing link recompute, invalid-subelement rollback and FCStd assertions remain.

Build and Attributable Evidence

  • Focused build succeeded: python3 tools/build_web_module_artifacts.py --target FreeCADWebDocumentProbe --jobs 8 --timeout 240 (one target passed).
  • node web/tools/sync-assets.mjs completed in 3.481 seconds: three files copied, 101 skipped; JS/WASM/worker artifacts and manifest synchronized.
  • Ran python3 tools/run_business_acceptance.py --module Part --ids Part:desktop:Part_Primitives Part:desktop:Part_ProjectionOnSurface --reuse. Current report: business-evidence/32e5a354bbd763bd5df41ad4-20260917T105057732115.json. Runtime 30.248 seconds; all eight recorded case assertions passed, both browser stages completed, no case errors. Both case statuses deliberately remain not_implemented; runner reports acceptance_incomplete, zero passed commands, exit 1. Do not convert assertion success into command completion.
  • Current primitive detail and screenshots: part-primitive-container-business/2026-09-17T10-50-27-795Z/. Native load 0.409 s; native cases through cleanup 11.543 s; browser stage 7.497 s. Native cleanup completed before browser startup.
  • Current projection detail and screenshots: part-linked-projection-business/2026-09-17T10-50-50-843Z/. Native load 0.384 s; linked create through native cleanup 0.575 s; browser stage 3.197 s. Desktop/mobile screenshots for both workflows were inspected.
  • Baseline failure retained in business-evidence/32e5a354bbd763bd5df41ad4-20260917T104612942596.json: projection could not select SupportLink because snapshots lacked topology. Do not replay this unchanged baseline.
  • Scoped git diff --check passed. Acceptance contract, verifier, runner, proof requirements, coverage tags and passing statuses were not edited. docs/business-acceptance/Part.json still hashes to f0fd2e6fd7e90f2f4c8cbb72b0f4cb1496e6cea76db149e3777707782816ac04.

Current fingerprints (full input/artifact hashes also retained in case reports):

File SHA-256
DocumentProbe.cpp 968b3acd508837e35cf59421c5ae3cd37fbfb3df665580be2aa240d621470e9b
part-primitive-container-business-cases.mjs 9bea0d5695703ae9a0622aedc4cb9ad4de8c87128e8cc91f7c13b23fc1e3d453
part-linked-projection-business-cases.mjs b772bfb1bd02a1472ccb3922e69edf0e631d07fb5bdaf2a793c543e9b2d2fd0f
FreeCADWebDocumentProbe.wasm b54714854c49f805eeee4b788c5b7921a0c53788a1a4918ac2c3295c8ee4439f

Next Work

  1. Projection still needs a desktop preview transaction spanning task activation, live updates, accept/commit and reject/rollback, plus viewport subelement selection gates. Start at PartProjectionDocument.h, the native document transaction lifecycle, executePartProjectionDesktop and the mounted task. The linked-object selector failure is fixed; do not implement it again.
  2. Primitives still need cylinder skew, circle from three points, desktop expression binding and live task-lifecycle behavior. Sixteen primitive types, placement and active-container membership/display already have implementations and executable cases; reuse them.
  3. Current focused cases preserve their explicit deferred legacy case lists. This run did not rerun every primitive type, every projection mode or arbitrary nested/scaled links. Retain all prior cases and original requirements when completing the commands; no full-parity/API gate is authorized.
  4. The packet's preflight still lists these commands as missing coverage. Do not edit the contract or add coverage labels to bypass the remaining behavior. Implement the next missing behavior, then invoke the unchanged acceptance runner for attributable evidence against stable files.

Reuse the running local server at http://127.0.0.1:5180; no new server was started. No IFC behavior, contract or verifier was changed, and no IFC semantic claim is made. No deployment, push or external message occurred.

Earlier Checkpoint (Retained)

Primitive status is superseded by Helix and Spiral progress: all sixteen types are exposed; continue with placement/container and remaining task interactions, not the historical missing-type list below. Preserve the earlier evidence without replaying its completed cases.

Batch 4aa3ea5e85f9c4b3e4412ba2, 2026-09-17. Selected: Part:desktop:Part_Primitives and Part:desktop:Part_ProjectionOnSurface. Both remain incomplete.

Delivered This Turn

  • Added the mounted Projection task's Use camera direction button. It reads the current viewport camera direction, including after orbit interaction, into the existing direction fields. Apply continues through the existing Part adapter, document facade, Worker and native Part::ProjectOnSurface geometry route.
  • Added an optional direction callback to web/src/openscad-desktop-view.tsx, using a ref so observing camera movement does not rebuild the scene. The task consumes it in web/src/part-projection-task.tsx.
  • Desktop source semantics: DlgProjectionOnSurface.cpp, DlgProjectOnSurface::onGetCurrentCamDirClicked around line 1406 transforms camera-local (0,0,-1) and sets Direction. Existing axis buttons remain intact.
  • Extended tools/part-projection-business-cases.mjs with actual camera orbit interaction, analytic cylindrical-support edge projection, radius-driven recomputation, FCStd reopen and subsequent radius edit, and indirect source and support cycle rejection through two dependent compounds.
  • Curved fixture checks one valid edge, length 3, y=3, z endpoints 2 and 5, x=sqrt(radius^2-9) for radii 5, 6 and 7, and exact native projection links. Cycle cases require an explicit cycle error and unchanged document snapshots, geometry, links, undo history and second document.
  • Existing DocumentProbe WASM was reused. No native build or artifact sync was necessary. No acceptance contract, runner, verifier, proof requirements or passing status was modified; no coverage tags were added.

Attributable Execution

Both isolated commands used python3 tools/run_business_acceptance.py --module Part --ids <ID> --reuse. Each returned acceptance_incomplete, exit 1, with the case result not_implemented because the explicit remaining requirements below are still open. Neither command is counted as passed.

Command Assertions Seconds Evidence in docs/current/business-evidence
Part_ProjectionOnSurface 34 passed, 0 failed 21.576 7eb5ff3f52f792bd7cf89e8e-20260917T070842519089.json
Part_Primitives 31 passed, 0 failed 78.753 13fb362e5bcf598a7f1f90a6-20260917T071048395612.json

Both reached browser-complete and cleanup-complete. Projection native load took about 0.404 s, native projection through curved/persistence checks about 8.532 s, and browser work about 9.029 s. Primitive native load took about 0.409 s, native fixture/history/persistence work about 31.476 s, and browser work about 45 s.

Projection screenshots at widths 1440 and 390 were generated with canvas-pixel and overflow assertions and visually inspected. They are under docs/current/part-projection-business/2026-09-17T07-08-21-248Z/. They show the native support, source and extruded projection without overlap.

TypeScript passed with web/node_modules/.bin/tsc --noEmit -p web/tsconfig.json. Scoped git diff --check passed.

The first combined baseline run was invalidated by source edits made while it was running; do not use it as current evidence. The first isolated Projection run failed at the existing exact FCStd object comparison after the newly added curved fixture caused normal remeshing roundoff/reordering. That failure remains in 7eb5ff3f52f792bd7cf89e8e-20260917T070716119724.json. The new curved fixture was moved after the unchanged original persistence assertions and given its own analytic persistence and dependency assertions. Existing assertions were not relaxed or removed. The subsequent stable run above completed all assertions.

Remaining Work and Next Anchors

Projection:

  • Desktop preview transaction: create on task activation, recompute live edits, commit on accept, and abort all task edits on reject. Current Apply commits separate edits; Close does not implement desktop preview rollback.
  • Viewport subelement selection gates. Current controls select named topology; viewport picking selects objects only.
  • Linked-object projection behavior and executable cases. Current native PartProjectionDocument.h resolver requires Part::Feature even though shape extraction uses ResolveLink. Desktop FeatureProjectOnSurface.cpp getSupportFace also requests Part::Feature; examine actual link semantics before changing either owner. No link support was claimed this turn.

Primitives:

  • Prism, Wedge, Helix, Spiral, Circle, Ellipse, Polygon, Line and Vertex.
  • Placement/orientation and active-container semantics.
  • Existing Plane, Box, Cylinder, Cone, Sphere, Torus and Ellipsoid workflows passed their current cases; do not rebuild or recreate these implementations.
  • Relevant anchors: DocumentProbe.cpp primitiveProperties around line 170, setPrimitive validation/property assignment around line 1328; part-document-facade.ts PART_PRIMITIVE_FIELDS and validation around line 363; part-primitives-task.tsx defaults/type picker; adapter executePartPrimitivesDesktop around line 739; runPrimitiveTaskCases in tools/part-primitive-business-cases.mjs around line 26.

Continue by implementing a missing behavior above, then run only the affected isolated acceptance case against stable files. Do not replay unchanged cases to refresh timestamps. Preserve all original and supplemental requirements, including docs/current/IFC_SEMANTIC_EXPORT_CONTRACT.md; no IFC work or semantic completion was claimed here. No full-parity/API gate, deployment, push or message to others was performed.

Existing local server reused: http://127.0.0.1:5180. Projection task: /workbench.html?module=Part&command=Part_ProjectionOnSurface.