Table of Contents

Mechanism Builder Page

The Mechanism Builder page edits a standalone GeneralMechanism — its anchor topology, per-branch ITransformer, and per-anchor optional geometry inside a Solid. Unlike the project-scoped editors (Fixture / Workpiece / ToolHouse / Spindle Capability), this page is user-scoped — no project needs to be loaded.

Layout

  • Mechanism Builder Page
    • Three Fixed Columns — equal width, separated by 1px borders, none of them draggable. Every column keeps its header pinned; the graph and the editor cards scroll inside their own region below it.
    • Column 1: Graph
      • Title + File Menu + Add Anchor Button.
        • File Menu
          • New — discards the current mechanism and starts an empty one with a root anchor.
          • Load… — opens the server file picker (Admin / Project / Resource) filtered to *.GeneralMechanism / *.general-mech / *.xml; the backend parses the picked file in place and records its directory so ReLoad can re-read it. .GeneralMechanism is the canonical spelling — GeneralMechanism.XName, what this page's Save As writes and what the shipped mechanism inside the Table-B1.default package is named; .general-mech is the older hand-authored spelling case files still carry. The filter is display-only either way, since the backend dispatches on the parsed root element and parses whatever is picked.
          • ReLoad — re-parses the file last loaded (disabled until a file has been loaded). The entry is spelled ReLoad, with the second capital.
          • Save As General Mechanism — writes a .GeneralMechanism XML to the picked server location and retargets ReLoad at it.
          • Save As Machine Tool — wraps the mechanism in a GeneralXyzabcMachineTool and writes a .MachineTool XML to the picked server location, leaving the open-mechanism pointer where it is. The envelope is the Xyzabc machine tool; the menu entry names neither that nor the file type.
        • Add Anchor — creates a standalone anchor, connected to nothing, and selects it.
      • File Line — the loaded file's relative path, or an “unsaved” caption while the mechanism has no file.
      • Graph — mermaid diagram of anchors (nodes) + branches (edges), scrolling inside its own region; node / edge click selects. The selected anchor is filled green and the selected branch's edge is stroked green.
    • Column 2: Selected Item Editor — content depends on selection:
      • Anchor selected: header with a Root badge on the root anchor, an Extend button, and a delete button (double-click; absent on the root).
        • Identity Card — the anchor's Guid, an inline name field (debounced), and an “Add Branch” select that connects this anchor to the picked one.
        • Geometry Card — a Geometry checkbox attaches or removes the anchor's Solid, and a badge shows the current geometry type. While attached the card carries a display-colour control and mounts the geometry editor over five kinds: Box3d, Cylindroid, StlFile, TransformationGeom and GeomCombination. CubeTreeFile and ExtendedCylinder are absent because the backend's create-geom does not construct them. TransformationGeom still exposes its own inner geometry and inner transformer through the nested editor.
      • Branch selected: header with a delete button (double-click).
        • Identity Card — the branch's Guid, an inline name field (debounced), and the fletch → arrow anchor chips naming the two anchors it joins.
        • Transformer Card — Transformer Select Panel (7 transformer kinds).
    • Column 3: Display — RenderingCanvas Tool Bar, a rendering / disconnected badge, and RenderingCanvas bound to DelegateFuncDisplayee(() => MechService.GeneralMechanism as IDisplayee).
    • Server File Picker — one FileExplorerDialog shared by Load and both Save As actions.

Behavior

  • New-anchor auto-naming. Newly-created anchors receive placeholder names (NewAnchor-001, NewAnchor-002, …) — the first NewAnchor-{i:000} no descendant anchor already carries. Inline rename is debounced 400 ms.
  • Extend. The anchor editor's Extend button creates a new anchor and the branch from the selected one to it in a single call, then selects the new anchor. This is the normal way a chain grows; Add Anchor leaves the new anchor unconnected.
  • Branch add filter. The “Add Branch” select inside the anchor editor filters out the selected anchor itself and anchors already directly connected, in either direction. A new branch starts on NoTransform.
  • Root protection. The root anchor cannot be deleted; double-click delete on any other anchor works.
  • Branch transformer swap. TransformerSelectPanel uses a parent-aware onCreate hook that calls POST /branch/{id}/update-transformer, so the new transformer takes effect on the next frame without a re-init round-trip. Same idiom as Fixture Page.
  • Geometry cache invalidation. Geometry edits POST to anchor/{id}/refresh-geom-cache, which triggers the same Solid.ClearCache() pattern used across the project.
  • Anchor display colour. The colour input authors an #rrggbb that persists inside the mechanism's <Solid> element, so every consumer of the file shows the same colour; a reset button drops the authored value and an “auto” badge marks the stable Guid-seeded fallback the 3D view otherwise renders with. Solid.Display reads the colour per frame, so the canvas follows without a cache refresh.
  • DelegateFuncDisplayee. The RenderingCanvas is wired through a delegate so edits render next frame without IndexService churn.

Source Code Path

See HiNC App Anatomy for git repository links.

HiNC-2025-webservice (Quasar CLI SPA):

  • wwwroot-src/src/pages/MechBuilderPage.vue — routed page at /util/mech-builder: File menu, the three columns, the anchor / branch editors, the display-colour control, the picker wiring and the canvas.
  • wwwroot-src/src/components/mech/MechBuilderGraph.vue — lazy mermaid loader + click-proxy onto mermaid node / edge DOM. Mermaid is dynamic-imported so the first bundle stays slim (~1 MB raw split into its own chunk); labels are emitted quoted, which the parser requires for CJK text.
  • wwwroot-src/src/components/widgets/FileExplorerDialog.vue — the server file picker behind Load and both Save As actions.
  • wwwroot-src/src/components/geom/GeometryEditor.vue — the geometry switchboard the anchor's Geometry card mounts.
  • wwwroot-src/src/components/topo/TransformerSelectPanel.vue — the branch transformer switchboard.
  • wwwroot-src/src/api/generalMechanism.ts — typed wrapper over /api/general-mechanism/*, including the three server-file operations and the anchor colour endpoints.
  • wwwroot-src/src/api/transformer.ts — the seven transformer kinds and their New endpoints.
  • wwwroot-src/src/api/geometry.tsGeometryKind, the union the anchor's allowed kinds are drawn from.
  • wwwroot-src/src/utils/path.tsstripDefaultMarker, which sheds the .default ownership marker from the name offered on save.
  • wwwroot-src/src/router/routes.ts/util/mech-builder entry (route name util-mech-builder).
  • wwwroot-src/src/components/AppMenuBar.vuePage → Mechanism Builder entry.
  • Mech/MechBuilder/GeneralMechanismService.cs — DI singleton that holds the current mechanism + last BaseDirectory + RelFile.
  • Mech/MechBuilder/GeneralMechanismController.cs/api/general-mechanism/* CRUD over anchors / branches / per-anchor geometry and colour; server-side Load, Reload and XML Save As for both GeneralMechanism and GeneralXyzabcMachineTool envelopes.
  • Mech/MechBuilder/GeneralMechanismDisplayController.cs/api/general-mechanism/display/* view init and the isometric reset-view.
  • Common/NamedRootResolver.cs — resolves the three named roots the picker offers.
  • Program.cs — registers GeneralMechanismService as a DI singleton.

IndexService Keys

The mechanism state is persistent across pages (unlike Fixture which re-initialises on mount), so mechanism keys are not registered with useCleanupHub. Stale keys are harmless; they are re-pointed on the next index-transformer / index-geom call.

  • general-mechanism.current — the mechanism itself (informational; DelegateFuncDisplayee bypasses IndexService at render time).
  • general-mechanism.branch.{guid:N}.transformer — stable per-branch transformer key used by TransformerSelectPanel.
  • general-mechanism.anchor.{guid:N}.geom — stable per-anchor key for whatever geometry the anchor's Solid holds, used by GeometryEditor. index-geom indexes that geometry without replacing it, so re-selecting an anchor leaves a non-TransformationGeom geometry intact.

File IO

Load and both Save As actions go through one server file picker — the File Explorer's dialog wrapper — over the three named roots AdminDirectory / ProjectDirectory / ResourceDir. The XML is read and written by the backend at the picked path; nothing travels through the browser. The picker opens on the root and folder of the last successful operation, starting at ResourceDir, where the shipped mechanism templates live, and a save offers the current file's name with the .default ownership marker stripped and the target extension forced (.GeneralMechanism or .MachineTool).

The File menu has New / Load… / ReLoad plus the two Save As entries; there is no plain “Save” that overwrites the last path. Saving a General Mechanism retargets ReLoad at the new file; saving a Machine Tool deliberately does not, because it is a separate file type that does not replace the open mechanism pointer.

See Also

  • Fixture Page — parent-aware onCreate transformer rebind pattern reused for Branch.
  • Transformers — the shared 7-transformer switchboard.
  • Geometry Management Control — embedded under the anchor editor.
  • Machine Tool — where a project's chain is loaded, replaced and previewed, next to this user-scoped builder.
  • File Explorer — the server-side browser this page's Load and Save As dialogs are built on.
  • Spindle Capability Page — the project-scoped editor with the same Load / Reload / Save As pattern.
  • Mechanism Builder (manual) — the end-user task: driving this editor, and what a machine chain built in it must be named.