Stick Tool Panel
The term stick is for not only milling, but other remover like electric discharge machining tool.
On the shipped web client the Stick Tool Panel is the Control Tree of one tool on the Tool House Page: picking a tool in that page's left list roots the tree at that tool, and the node selected in the tree fills the editor column beside it. The tree's roots are the tool's faces — General, Cutter, Holder, Clamping and Int. Holder — and the tool itself has no row, so the editor's header names the tool in front of the node, as in Tool #3 / Clamping.
The key model is MillingTool.
Layout
- Control Tree of the picked tool — its roots are the General node followed by the faces the
virtual tool container
toolhouse/tool-{toolId}grows; the container itself is never drawn as a row- General Node (
toolhouse/tool-{toolId}/general) — the first root, a leaf- Title Bar: Tool #N, with a Duplicate Button and a Delete Button (icon buttons; Delete asks for confirmation first)
- Tool ID TextField — the T-number; committing it renames the tool, and a number the house already holds is refused and the field snaps back
- Note TextField (editable)
- Abstract Note (auto) — read-only, auto-derived, with a one-click copy button
- Cutter Node (
…/cutter)- Cutter Panel — the cutter type selector; the section nodes it grows are the Cutter Branch
- Holder Node (
…/holder)- Holder Panel — the holder type selector; the section nodes it grows are the Holder Branch
- Clamping Node (
…/clamping) — a leaf- Exposed Cutter Height numeric field (mm)
- Preserved Distance (flute top → spindle nose) numeric field (mm)
- Formula caption (
ExposedCutterHeight=PreservedDistance+FluteHeight) - Setup Angle numeric field (deg), with a hint under it
- Int. Holder Node (
…/intelligent) — a leaf, grown only while Show Physics Options is on- Observation Location
- Reference Dropdown (
ObservationAnchorReference) — its options are theMillingToolAnchorReferencenames the server sends with the observation: None, Tool Tip, Holder Anchor, Spindle Mount - Z Relative to Reference numeric field (
RelativeHeightFromObservationAnchor_mm)
- Reference Dropdown (
- Holder Channels — one check box per channel the server offers, Mx / My / Mz (
ObservationChannels)
- Observation Location
- General Node (
General, Cutter, Holder and Clamping are roots for every tool. Int. Holder is grown only while the shell's Show Physics Options preference is on: its content is the observation point of the Smart Tool Holder that the sensor-moment mapping is computed about. With the preference off, neither the node nor the ring is shown. With it on and the reference not None, the canvases that draw the mounted tool — the Execution Page's and the Equipment Page's — draw a green observation ring at that point, sized from the outline of the tool at that height; the Tool House's own canvas does not draw it. Turning the preference off while Int. Holder is selected re-roots the tree and moves the selection to General.
Cutter and Holder are type-selector nodes: the type chosen decides which section nodes grow below them. The Cutter node grows sections only for a Milling Cutter, and the Holder node grows none for a tool whose holder type is None.
Object Management covers the whole house and the whole cutter, not the single tool: the
Object Management Menu Button heads the page's tool list
with file extension .MachiningToolHouse (load type Hi.Machining.MachiningToolHouse, HiMech), the
Cutter node's panel carries another for the tool's cutter (.Cutter), and the General node offers
Duplicate and Delete for the single tool. There is no per-tool object-management button; the identity fields — Tool ID, Note and the Abstract
Note — sit on the General node beside those two buttons.
One Tool, Not the House
The tree holds one tool, never the whole house, and that is a constraint of the server rather than a
layout choice. The holder index keys are per session, not per tool ({sessionKey}-HolderGeom,
{sessionKey}-HolderCylindroid, re-pointed on every read), so two tools' holder branches built at
once would both address the tool built last. The tools are therefore rows of the page's list rather
than rows of the tree — the Tool House root grows no children — and the host points the session and
the tool canvas at the picked tool (ensureToolSelected) before it builds that tool's faces. Each
per-tool panel in wwwroot-src/src/components/controlTree/toolhouse/ repeats the call when it
mounts.
Nodes and the URL
Every node id is a role path under toolhouse/tool-{toolId}, and the page's URL spells it as
/tool-house/<toolId>/<node path>: the tool number, then the selected node's id with its
toolhouse/tool-{toolId} prefix removed. The Clamping node of tool 3 is /tool-house/3/clamping,
and a node five levels down rides the URL whole, as in
/tool-house/3/cutter/contours/fluting/flute-0/side. toolNodePathOf and toolTreeId in
wwwroot-src/src/router/treeRoutes.ts convert between the id and the URL's two halves, and
routeForTreeId turns any Tool House id into this route without dropping a segment.
- The URL is the authority. A tool number with no node path,
/tool-house/3, selects General. A node path the tool does not grow is clamped to the deepest node along it that the tool does grow — or to General when not even its first segment is a root, as withintelligentwhile Show Physics Options is off — and the URL is rewritten to the node actually selected. A tool number the house does not hold lands on the house's first tool. - A bare
/tool-houselands on remembered state. The menu bar's Tool House switch links there, carrying no selection, so the page keeps the tool already shown — or, on a fresh load, takes the house's first tool — and opens the last node path selected on this page, which the browser keeps with the page's last selection (lastTreeIdsinwwwroot-src/src/composables/useViewPrefs.ts). An explicit URL always wins over that memory. - Picking another tool keeps the face. Each list row is a router link that rewrites only the tool number. The link carries the deepest node path asked for rather than the URL's clipped one, so a face one tool does not grow (flute 3 of a two-flute cutter) comes back on the next tool that grows it. A re-root adopts its selection only while the URL still names the tool it built, so two quick clicks in the list settle on the second tool.
- House changes go through the URL. Committing a new Tool ID, duplicating a tool, or adding one
with New Tool moves the URL to that tool's number, keeping the node path; deleting a tool re-roots
the tree at the house's first tool, and an Object Management load rebuilds the tree in place. This
is the
toolhousebranch of the host'sonNodeStructureChanged. - No
?tree=. The Tool House page never reads or writes the?tree=query. That query belongs to the Execution and Equipment pages, and a Tool House id arriving on either of them is redirected here byrouteForTreeId.
Note
The Exposed Cutter Height and Preserved Distance are directly related:
ExposedCutterHeight = PreservedDistance + FluteHeight, so each value changes when the other
is changed. Editing Preserved Distance commits PUT /api/ToolHouse/{id}/preserved-distance, whose
response carries the recomputed pair and fills both fields; editing Exposed Cutter Height commits
PUT /api/ToolHouse/{id}/exposed-height, which answers without a body, so the panel re-reads the
tool to pick up the new preserved distance.
Setup Angle is a third field on the same node, coupled to neither of those two: it is how far the
cutter is turned in the holder about the tool axis, and it commits on its own to
PUT /api/ToolHouse/{id}/setup-angle, whose body is a bare JSON number. Only the milling physics
reads it — the tool assembly and the canvas are not turned by it.
While the pace player is locked — a run in progress or paused — all three commits are refused with
409 ToolEditRefusedWhileRunning, as is every other tool-house edit; the page says so in a banner
with Stop and Reset, and the fields read as before.
Source Code Path
See HiNC App Anatomy for git repository links.
HiNC-2025-webservice (Quasar CLI SPA). The tool's faces are nodes of the shared Control Tree, rendered
by the same ControlTreePanel and PrimarySlavePanel pair as the Execution and Equipment pages:
wwwroot-src/src/components/controlTree/toolHouseItemTypes.ts— the Tool House ItemType registry:toolContainerNodemints the virtualtoolhouse/tool-{toolId}container (aToolNodewith no panel), whosebuildToolChildrengrows the Cutter, Holder and Clamping faces and, while Show Physics Options is on, Int. Holder;toolGeneralNodemints the General leaf, whoseToolGeneralitem type carriesToolNodePanel.ToolHouseRoothas nobuildChildren.wwwroot-src/src/components/controlTree/useControlTreeHost.ts— thetoolhousescope:buildToolHouseRootsbuilds the picked tool's container and lifts its children to the roots behind General,deepestBuiltIdclamps a node path to what the tool grows,toolLocationbuilds the list rows' links, and thetoolhousebranch ofonNodeStructureChangedsends a tool switch through the URL and re-seats the tree in place otherwise.wwwroot-src/src/router/treeRoutes.ts—toolNodePathOf/toolTreeId, the tree id ↔ URL halves, androuteForTreeId.wwwroot-src/src/router/routes.ts— the routetool-house/:toolId(\d+)?/:node(.*)*.wwwroot-src/src/pages/ToolHousePage.vue— renders the tree column (ControlTreePanel) and the editor column (PrimarySlavePanel) overuseControlTreeHost('toolhouse'), between the tool list and the tool canvas.wwwroot-src/src/components/controlTree/toolhouse/ToolNodePanel.vue— the General node: Tool ID / Note / read-only auto Abstract Note with copy, plus Duplicate and Delete.wwwroot-src/src/components/controlTree/toolhouse/ToolCutterPanel.vue— the Cutter node's type selector (Milling Cutter / Freeform Remover / None) plus a milling cutter's own fields.wwwroot-src/src/components/controlTree/toolhouse/ToolHolderPanel.vue— the Holder node's type selector (None / Cylindroid / Freeform) plus the holder's Name / Note / auto Abstract Note.wwwroot-src/src/components/controlTree/toolhouse/ToolClampingPanel.vue— the Clamping node and its two coupled fields, plus the independent Setup Angle.wwwroot-src/src/components/controlTree/toolhouse/ToolIntelligentPanel.vue— the Int. Holder node; a thin wrapper overwwwroot-src/src/components/toolhouse/IntelligentHolderDiv.vue, which holds the Observation Location controls.wwwroot-src/src/composables/useToolHouse.ts— the module-singleton state every tool-house panel is a thin view over: the tool list, the active tool, and the rendering connection id;ensureToolSelectedpoints the session and the canvas at one tool.Mech/ToolHouseController.cs—[Route("api/[controller]")], so/api/ToolHouse: the tool-level fields the General, Clamping and Int. Holder nodes edit —PUT /{id}/note | exposed-height | preserved-distance | setup-angle,GET/PUT /{id}/observation,POST DuplicateTool | RenameTool,DELETE DeleteTool— plus the Holder node'sPOST SetHolderTypeand the tool list'sPOST CreateTool. Every one of them answers 409ToolEditRefusedWhileRunningwhile the pace player is locked (a run in progress or paused);POST InitializeandPOST SelectTool, which only index, do not.Mech/CutterController.cs(/api/Cutter),Mech/CylindroidHolderController.cs(/api/CylindroidHolder) andMech/FreeformHolderController.cs(/api/FreeformHolder) — the server surface behind the Cutter and Holder nodes; the two holder controllers mint the per-session holder index keys. All three are read-only while the pace player is locked, the same 409; the cutter'sPOST /{id}/inner-beamandPOST /{id}/upper-beam, the holder controllers'POST Getand the freeform holder'sPOST IndexCurrentGeometry— the reads that only index — stay available.wwwroot-src/src/api/toolHouse.ts— the typed client for/api/ToolHouseand/api/Cutter;wwwroot-src/src/api/cylindroidHolder.tsandwwwroot-src/src/api/freeformHolder.tsare the two holder controllers' clients.
See Also
- Tool House Page — the page this tree sits in: its tool list, its four columns and its route
- Cutter Branch — the section nodes the Cutter node grows
- Holder Branch — the section nodes the Holder node grows
- Control Tree — the shared tree host whose
toolhousescope builds these roots