Geometry Management Panel
The geometry switchboard is one control: a kind picker over the kinds its host allows, and — unless the host asked for the picker alone — the picked kind's editor beneath it. On the web it binds a key into the shared object store, not an object, and every Control-Tree Geometry slot is this same control in selector-only mode.
Layout
Web: a geometry-type dropdown; a separator, drawn only while a kind is active; then that kind's editor. Picking a kind commits immediately — there is no Apply button. In selector-only mode everything below the dropdown is dropped, which is the form each Geometry slot node shows.
Desktop: a combo box on the left of a head line with a Convert menu on its right, over a bordered content presenter that hosts the kind's own control.
What It Binds
The web panel has no target-geometry property. It takes a modelKey naming the object it edits and
mutates what sits behind that key; a host that also owns the field holding the geometry passes an
onCreate hook, so switching the kind rebinds the host's field rather than just the key. The
desktop panel is the one that exchanges an IStlSource directly, through a getter and
setter pair its host supplies.
Each host's field type decides which kinds it may offer; whether the kind survives a save decides
which of those it does. A fixture's geometry and a transformation geometry's inner geometry are
IGetStl; a workpiece's initial geometry is an IMakeXmlSource, which is why the
cube-tree file — which is not an IGetStl — reaches that picker and no other.
Type compatibility alone is not sufficient, and ExtendedCylinder is the case that
shows it. It is an IMakeXmlSource, so the workpiece's raw slot could hold one and once did — but
its start section is supplied by a host at run time and is not serialized, so a saved project
reloaded it with a zero-radius start and the shape degenerated. The kind is now offered by the one
host that wires that source, the cutter's upper beam.
Reach
The picker's own default is six of the seven kinds: Box3d, Cylindroid, StlFile, TransformationGeom, GeomCombination and CubeTreeFile. ExtendedCylinder is in the kind map but out of that default: a host that can wire its start section names it explicitly. Nothing is hidden by a flag on the web.
The default is a guard rail, not a shipped list. Every host passes its own whitelist — the five Control-Tree Geometry slots from the node context, the four inline hosts as a constant — so no shipped surface renders the default at all, and the whitelist is what really decides reach.
| Host | Kinds offered |
|---|---|
| Fixture geometry, mechanism anchor, a transformation geometry's inner geometry, a combination child | the five container kinds — Box3d, Cylindroid, StlFile, TransformationGeom, GeomCombination |
| Workpiece raw geometry | six — the five container kinds plus CubeTreeFile |
| Workpiece target geometry | four |
| Cutter upper beam | six — Cylindroid, ExtendedCylinder, TransformationGeom, StlFile, Box3d, GeomCombination |
A null geometry is a legal state of the model, but the web picker offers its None (unset) entry
only when the host asks for it: the three General Setup slots and a transformation geometry's inner
geometry do, while the mechanism anchor, the cutter upper beam and combination children do not, so
those pickers cannot clear the slot. Clearing goes through the host's create hook with the literal
kind None, which the container-aware endpoints map to null. The desktop combo always lists a
None item.
Converting Is Desktop-Only
Wrapping an existing geometry into a TransformationGeom — and extracting it back out — exists only in the desktop client, as items in the Convert menu rather than as buttons. The Convert to Transformation item re-titles itself Extract from Transformation when the current geometry already is one; the combination item behaves the same way, and its extract is offered only when the combination holds exactly one child. Three code-behind properties can hide the menu and each of its two items, but no shipped host sets any of them.
The web has no equivalent, and the difference is not cosmetic. Picking TransformationGeom in
the picker creates a new, empty one and discards the geometry that was there — it does not wrap it.
In the Control Tree
Geometry is a slot item type. Its child builder probes the slot's key for the type behind it and,
when that type is a known kind, grows exactly one child node of that kind bound to the same key
— so the slot node carries the picker and its single child carries the editor. Five kinds resolve to
the shared sole-editor panel; TransformationGeom and GeomCombination instead map to panels of
their own, because they grow further slot children rather than hosting one editor. The two
file-backed kinds compose the referenced file into their node label.
Source Code Path
See HiNC App Anatomy for git repository links.
HiNC-2025-webservice (Quasar CLI SPA):
wwwroot-src/src/components/geom/GeometryEditor.vue— the switchboard: the kind picker over the allowed kinds, the opt-in unset entry, the immediate commit through the create hook, and the active kind's editor.wwwroot-src/src/components/geom/geometryEditors.ts— the single kind → editor map both this picker and the Control Tree's sole-editor panel resolve through.wwwroot-src/src/components/controlTree/GeometrySlotPanel.vue— the slot node's panel: this switchboard in selector-only mode, fed its allowed kinds, its unset flag and its create hook from the node.wwwroot-src/src/components/controlTree/SoleEditorPanel.vue— the kind child's panel.wwwroot-src/src/components/controlTree/itemTypes.ts— registersGeometryas a slot type with its child builder, registers each kind against its panel, and holds both the container-kind list and the file-backed node labels.wwwroot-src/src/components/controlTree/useControlTreeHost.ts— the three General Setup Geometry slots and their per-host kind whitelists.wwwroot-src/src/pages/MechBuilderPage.vueandwwwroot-src/src/components/toolhouse/UpperBeamDiv.vue— the two inline, non-tree hosts.wwwroot-src/src/api/index-service.ts— the type probe the picker calls to discover which kind is currently behind the key.wwwroot-src/src/api/geometry.ts— the kind union, the create dispatcher and its per-kind endpoint map, and every per-kind call.wwwroot-src/src/api/fixture.ts,wwwroot-src/src/api/workpiece.ts,wwwroot-src/src/api/toolHouse.tsandwwwroot-src/src/api/generalMechanism.ts— the container-aware create wrappers each host's hook posts through.wwwroot-src/src/i18n/en/common.tsandwwwroot-src/src/i18n/en/geom.ts— the picker's label and its unset and empty-state strings. Geometry type names are deliberately not translated.- The seven per-kind controllers under
Geom/—Geom/Box3dController.cs,Geom/CylindroidController.cs,Geom/ExtendedCylinderController.cs,Geom/StlFileController.cs,Geom/CubeTreeFileController.cs,Geom/TransformationGeomController.csandGeom/GeomCombinationController.cs— each at/api/{Kind}/*. There is no single geometry controller and no geometry hub. Common/IndexController.cs— the type probe at/api/Index/GetType.Common/IndexService.cs— the keyed object store all of the above read and write. There is no per-panel session object.Mech/FixtureController.cs,Mech/WorkpieceController.cs,Mech/CutterController.csandMech/MechBuilder/GeneralMechanismController.cs— the container-aware create endpoints that set the host's own field, and the ones that acceptNoneand store null.
See Also
- Mechanism Builder Page — embeds this control under its anchor editor
- Box3d Control — the kind editors this switchboard resolves
- Cylindroid Control — the same, for a solid of revolution
- Extended Cylinder Panel — the same, and the kind exactly one host offers
- STL File Control — the same, for an STL reference
- Meshed Geometry Panel — the same, for a voxel cube tree
- Transformation Geometry Control — the container kind this panel can wrap into on the desktop client
- Geometry Combination Control — the other container kind, whose every child embeds this panel again