Table of Contents

Cutter Panel

Overview

The key component is ICutter. A tool carries at most one cutter, and two concrete types answer to that interface: MillingCutter and FreeformRemover. This panel is where the type is chosen, and it holds the cutter's own General fields.

It is the panel of the Cutter node, one of the roots of the picked tool's Control Tree on the Tool House Page: the node toolhouse/tool-{toolId}/cutter, reached at /tool-house/<toolId>/cutter under the page route /tool-house/:toolId?/:node*. Selecting it shows this panel in the editor column, under the breadcrumb Tool #N / Cutter.

Layout

Web Layout

  • Cutter Node Panel
    • Object Management Menu Button — the whole cutter as a .Cutter file: Load (opening on Resource/Cutter under the Admin root), Save As, Copy, Paste and XML Mode; disabled while the pace player is locked
    • Title Label — Cutter
    • Cutter Type Selector — Milling Cutter / Freeform Remover / None; Freeform Remover is enabled only on a tool that already carries one
    • Milling Cutter branch, rendered only while the type is Milling Cutter
      • Integral Mode Selector — Solid End / Insert End, rendered only while Show Physics Options is on
      • Shank Mass Input Field (g) — an estimate hint under it while the mass is evaluated, a return-to-estimate button in its append slot while the mass is a held value
      • Hone Radius Input Field (um)
      • Relief Angle Input Field (deg)
      • Sections Hint Caption, toolhouse.cutter.sectionsHint — says the flute profile, contours and upper beam are edited via the child items in the Control Tree, that material, inner beam and optimization join them while Show Physics Options is on, and the insert on an insert cutter
    • Freeform Remover branch — one caption, toolhouse.cutter.freeformRemoverUnavailable, saying the editor is not available here
    • No-cutter branch — two hints: toolhouse.cutter.noCutterHint, inviting the reader to pick Milling Cutter, and toolhouse.cutter.loadHint, pointing at the menu's Load and the shipped cutters under Resource/Cutter

The selector's value is the cutterType the tool detail reports, and none of the three branches renders until that first read answers.

The three numeric fields and, while Show Physics Options is on, the Integral Mode selector above them are the cutter's General fields, and they sit here under the Metadata-on-container convention — a container's own General fields are edited on the container's panel instead of in a General child. The three numeric fields are plain, always-editable inputs, one label each, and each commits alone through the general endpoint, which takes any of shankMass_g, honeRadius_um, reliefAngle_deg and shankMassAssignmentMode and leaves a field it does not receive unchanged. A blanked box commits nothing, so clearing a field never writes a zero; a commit the server refuses (a zero or negative mass) is reported in a toast and followed by a re-read of the tool, so the box returns to the value the server holds instead of keeping the refused number, and an Infinity or NaN entry — which JSON would carry as null, the endpoint's “leave it” — is refused in the panel the same way before anything is sent. Every accepted commit is followed by the same re-read, so the field's state is what the server reports, never a local assumption.

Shank Mass has two states, read from the shankMassAssignmentMode the tool detail reports beside the mass. While it is EvaluateByVolume the field shows the server's estimate from the beam volume and the shank material, with a hint under the field saying so; a typed mass commits as a held value — the server switches the cutter to Custom, which is what carries the number through the cache clears every edit runs and through the project's save and reload. While it is Custom the field's append slot holds a return-to-estimate button, which sends shankMassAssignmentMode: "EvaluateByVolume" alone and re-reads the tool. Sending only the edited field matters here: re-sending the displayed estimate beside a hone-radius edit would freeze it as a held value. A mass beside EvaluateByVolume, or a mass that is not a positive finite number, is refused with 400.

Integral Mode is the one physics-only field here: an insert-end cutter differs from a solid-end one in the mass and thermal models and in the beam the deflection and yielding-stress physics read — a solid-end cutter is one piece of its flute material, so its beam is the flute material and its shank material is a mirror of it; an insert-end cutter's beam is the body its inserts sit on, the shank material. It commits alone to the cutter's integral-mode endpoint, which answers with the whole cutter DTO; the panel takes its fields from that answer, clears the tool cache and emits a structure change for its own node, because the Insert node grows only under an Insert End cutter. Switching to Solid End makes the shank material mirror a set flute material again, loading a project does the same for every solid-end cutter it holds, and the shank-material endpoints refuse a solid-end cutter.

The type also decides what grows below the node. A Milling Cutter grows the cutter's section nodes, in this order — Insert, Material, Flute Profile, Flute Contours, Inner Beam, Upper Beam, Optimization — whose role paths end in .../cutter/insert, .../cutter/material, .../cutter/profile, .../cutter/contours, .../cutter/inner-beam, .../cutter/upper-beam and .../cutter/opt. Insert, Material, Inner Beam and Optimization grow only while the Show Physics Options preference is on, and Insert only under an Insert End cutter; Flute Profile, Flute Contours and Upper Beam grow for every Milling Cutter. Selecting one shows that section's own panel in the editor column; see Milling Cutter Panel. A Freeform Remover or no cutter grows nothing, so the Cutter node is a leaf and the caption or hint is the whole surface; see Freeform Remover Panel. A URL naming a section the tool does not grow — /tool-house/<toolId>/cutter/profile on a tool without a Milling Cutter, or /tool-house/<toolId>/cutter/material while Show Physics Options is off — lands on the Cutter node, the deepest node the tool grows along that path, and the URL is rewritten to it.

The panel's Object Management Menu Button is bound to the whole cutter — the session's {sessionKey}-Cutter entry, file extension .Cutter, load type Hi.Milling.Cutters.MillingCutter, HiMech — as the one at the head of the page's tool list, on the Tool House Root Panel, is bound to the whole tool house (.MachiningToolHouse). A Load, Paste or XML apply only swaps that entry, so the panel then calls the cutter's install endpoint, which puts the entry's cutter on the tool: inline in the project, its material references dropped, a cutter that still belongs to another tool's assembly duplicated first, and anything but a cutter answered 409 with the entry put back on the tool's own cutter. Replacing a freeform remover asks first, as the type selector does. After an install or a type change the panel re-indexes the session's entries on its tool and remounts the menu, so Save As and XML Mode follow the cutter the tool holds; the canvas goes back to its home view after an install or a type change, since the zoom was set for the old cutter.

Features

Committing a type is one server call plus a cache clear. Milling Cutter calls EnsureCutter, which keeps the tool's existing MillingCutter and otherwise assigns a new one; None calls ClearCutter, which drops the tool's cutter altogether. On a tool holding a freeform remover either choice discards it, so the panel asks first and a Cancel sends nothing — see Freeform Remover Panel. The panel then clears the tool cache, re-reads the tool and emits a change, which redraws the canvas, and a structure change for its own node; the Control Tree rebuilds the Cutter branch in place, unfolds it and keeps the Cutter node selected, which is how the section nodes appear or disappear with the type.

Cache clearing is not a step the user performs. ICutter implements IClearCache, and every cutter endpoint that changes a field or a geometry clears the cache server-side before it answers: the field endpoints call ClearCache() on the milling cutter directly, while the ones that change flute or beam geometry go through the controller's resync hook, which clears the cache and re-aligns the tool's holder-to-cutter anchor transformer so the cutter is re-placed under the holder at its new height. On top of that the panels call clearToolCache(toolId), which clears the tool's cached solids and the holder's, so the tool canvas redraws. None of this happens while the pace player is locked — a run in progress or paused: the whole tool house is read-only then, the page's banner says so with a Stop and a Reset button, the editor column is covered, and a commit that gets through all the same is answered 409 ToolEditRefusedWhileRunning, shown as a toast.

Source Code Path

See HiNC App Anatomy for git repository links.

HiNC-2025-webservice (Quasar CLI SPA):

  • wwwroot-src/src/components/controlTree/toolhouse/ToolCutterPanel.vue — the Cutter node's panel: the cutter's Object Management menu, the Milling Cutter / Freeform Remover / None selector, the physics-only Integral Mode selector, the Shank Mass / Hone Radius / Relief Angle fields, the Freeform Remover caption and the two no-cutter hints. Commits a type change through ensureCutter or clearCutter followed by clearToolCache — behind a confirmation when it would discard a freeform remover — an integral-mode change through setIntegralMode, and a menu Load, Paste or XML apply through installCutter; re-indexes through the tool-house composable's reindexTool and sends the canvas home through refreshDisplay(true).
  • wwwroot-src/src/components/controlTree/toolHouseItemTypes.ts — registers this panel as the ToolCutter item type; its cutter child builder grows the section nodes only for a MillingCutter, gates Insert, Material, Inner Beam and Optimization on the Show Physics Options preference, and grows Insert only for an insert-end cutter.
  • wwwroot-src/src/components/controlTree/toolhouse/CutterSectionPanel.vue and wwwroot-src/src/components/controlTree/toolhouse/CutterContoursPanel.vue — the panels those section nodes render.
  • wwwroot-src/src/components/controlTree/useControlTreeHost.ts — the Control-Tree host in its toolhouse scope: rebuilds the Cutter branch on this panel's structure change, and clamps a URL naming a section the tool does not grow to the deepest node it does.
  • wwwroot-src/src/components/controlTree/toolhouse/ToolHouseRootPanel.vue — the head of the page's tool list, which carries the Object Management Menu Button for the whole tool house.
  • wwwroot-src/src/components/widgets/ObjectManagementMenuButton.vue — the reused object-management dropdown that root panel and this panel mount; every mounted instance shares one poll of the server's copied item.
  • wwwroot-src/src/components/widgets/NumericInput.vue — the shared numeric field behind the three General inputs; it commits on blur or Enter, flags an unparseable entry as an error without committing it, and hands nothing to the host when the value is unchanged — which is what keeps the return-to-estimate button, sitting in the field's own append slot so that pressing it blurs the input, from re-committing the displayed estimate as a held mass.
  • wwwroot-src/src/pages/ToolHousePage.vue — the routed page: the tool list, the Control Tree whose Cutter node this panel belongs to, the editor column that shows it, and the tool canvas; the route is /tool-house/:toolId?/:node*.
  • wwwroot-src/src/i18n/en/toolhouse.ts — the toolhouse.cutter.* strings this panel renders: cutterType, integralMode, solidEnd, insertEnd, shankMass, shankMassEvaluatedHint, shankMassEvaluate, honeRadius, reliefAngle, sectionsHint, freeformRemoverUnavailable, noCutterHint, loadHint, millingCutter, freeformRemover, and toolhouse.error.installCutter. The None option's label comes from common.options.none in wwwroot-src/src/i18n/en/common.ts.
  • wwwroot-src/src/api/toolHouse.ts — the typed wrapper: /api/ToolHouse for the house and the tool-level fields, /api/Cutter for every cutter mutation, plus ensureCutter, clearCutter, installCutter, setGeneral, setIntegralMode, clearToolCache and clearDisplayCache (with its home flag).
  • Mech/CutterController.cs — the cutter backend at /api/Cutter: EnsureCutter / ClearCutter (both drop the side file a replaced cutter was read from), POST /{id}/install?cutterKey= for the menu's loads, the shaper-profile, fluting, general, opt-limit, integral-mode and insert endpoints, the inner-beam and upper-beam endpoints and the material and coating-layer endpoints. Every field and geometry mutator clears the cutter cache before it answers, and answers 409 ToolEditRefusedWhileRunning instead while the pace player is locked — a run in progress or paused — so no cache is cleared under a run; GET /{id}/fluting/contours and the two POST reads, /{id}/inner-beam and /{id}/upper-beam, stay available.
  • Mech/CutterDtoBuilder.cs — the single source of truth for the read-side cutter DTO (integralMode, insert, innerBeam, general, shaperProfile, fluting, optLimit, material, and the messages a material load answers), shared by CutterController and the tool detail in ToolHouseController.
  • Mech/ToolHouseController.cs — the tool detail that this panel reads on mount: it reports the cutter's kind as hasCutter / cutterType and embeds that cutter DTO for a MillingCutter; plus the tool-cache clear the panel calls after every commit.

See Also

  • Cutter Branch — the folder this panel heads: the Cutter node and the nodes it grows
  • Milling Cutter Panel — the section nodes a Milling Cutter grows below this node
  • Freeform Remover Panel — the type selector's second option, shown on a tool that carries one and asked about before it is discarded