Equipment Topology Column
The Topology column is the Equipment page's fourth column: the whole authored equipment — machine tool, fixture, workpiece and tool — drawn as one anchor / branch graph, with an editor card below it for whichever anchor, branch or assembly is picked. It is where a part's anchors, branches, transformers and solids are authored; the Control Tree's three mechanism items only bind roles — which of a part's own anchors and branches play its Table Mount, its Geometry Anchor, its Axis X — and a role armed there is bound by clicking its element in this graph. It has one surface:
- the rightmost column of the Equipment page (
/equipment), titled Topology. It carries no?tree=id of its own: the graph is not a Control-Tree branch, and a part's cluster in it is a shortcut to that part's tree item.
The column order is TREE | EDITOR | CANVAS | TOPOLOGY, one column-toggle button each in the menu
bar's column-button row — the fourth button, titled “Toggle the Topology column”. Its first-run
visibility follows the window — shown on one at least 1280 px wide, hidden on a narrower one — and
is stored with the rest of the device-local view preferences at their next write; a stored bit wins
whatever the window is afterwards. Its width is device-local (the topologyColPx view preference,
default 420 px) and it is pinned to 0 px rather than unmounted while hidden, so the graph keeps its
selection and scroll.
When the canvas is hidden and the Topology column shown, the column takes the canvas's width.
- Key Model:
- SetupEquipment — the authored equipment face (SetupEquipment), whose parts and attachments the graph draws and every edit lands on in place.
- GeneralXyzabcMachineTool, Fixture,
Workpiece — the three editable parts. Each owns an assembly
(
Asmb,Root,AnchorToSolid) and names its roles as settable anchor or branch properties: the machine's TableMount, ToolMount, AxisX …AxisCand Spindle; the fixture's TableMount, WorkpieceMount and GeomAnchor; the workpiece's FixtureMount, ProgramZeroAnchor and GeomAnchor. A transformer lives on a branch —Branch.Get(fixture.GeomAnchor, fixture.TableMount).Transformer— never on the part. - Asmb, Anchor, Branch — the topology primitives every cluster, node and edge of the graph stands for.
- IsErrorTerm — the error-term mark, which the Error term option
on the card of an axis's or the spindle's branch sets on the branch it inserts just before that
one, the role's error term: the controller solves on a copy of the machine in which every
marked branch is
NoTransform, and the machine runs with the marked branches while the project's error-term switch is on (see Error-Term Branches).
- Assistant Model:
- Rewire — rebuilds the attachment branches between the parts whole after every edit; the worktable attachment carries TableToComp.
- NotifySetupEquipmentEdited — lets the runtime face, its solver and axis configuration follow the authored edit.
- EnableErrorTerms — the project's error-term switch, set on the Machine Tool item and carried by the graph; a write is a setup edit the runtime face follows like any other.
Layout
Title Bar
- Refresh — an icon button (tooltip Refresh) at the right end of the column's title bar, spinning while a pull is in flight and disabled while an edit is; re-pulls the graph and every part's roles.
Armed-Role Strip
A strip between the title bar and the graph, shown only while a role is armed on a Roles panel: a chip reading "Pick {element} in the {owner} to bind {role}.", removable to disarm.
Graph
The graph is drawn by the graph view MechBuilderGraph.vue, whose name is historical. Every
assembly with an anchor somewhere below it is a cluster titled with the assembly's name, nested as
the assemblies nest: the equipment's own assembly (SetupEquipment) outermost and untagged, one
cluster per part inside it — the part's key assembly, its title tagged Machine Tool,
Fixture, Workpiece or Tool — and a part's sub-assemblies inside that. Above the graph
sits the graph view's own toolbar — the flow direction (top-down or left-to-right), zoom out, the
scale (a click returns to actual size), zoom in and fit to width — and the graph scrolls in its own
region, which a drag pans once the graph overflows it. A height divider under the graph sets its
height (the device-local topologyGraphPx view preference, default 320 px); the editor card below
it takes the rest.
- The tool is not edited here: its cluster holds only its assembly clusters and the anchor its attachment reaches, never its own anchors and branches.
- An anchor bound to a role carries a badge under its label naming the part and the role in the UI language — Fixture · Table Mount, Machine Tool · Tool Mount — and an outlined node style; a branch bound to an axis or the spindle carries its badge too (Machine Tool · Axis X). The badges are gathered from every part, not only from the part the element belongs to, so an element more than one part points at shows one badge per part.
- A part's own branch is a solid edge and an attachment between parts a dotted one. An edge is
labelled
name (transformer type), the transformer type alone when the branch has no name, and Attachment when it has neither. - A branch marked as an error term is a thick edge with an orange badge in its label reading
Error term. While the project's error-term switch is off, the badge is outlined and reads
Error term (not in effect), and the edge stays thick. The mark never colours the edge, so a
selected marked branch takes the selection's colours like any other. The graph carries the switch
(
errorTermsEnabled), so every pull draws the badges in its current state. - Clicking an anchor selects it and opens the anchor editor; clicking a branch selects it and opens the branch editor; clicking a cluster selects that assembly and — when it belongs to the machine tool, fixture or workpiece — moves the Control Tree to that part's mechanism item, so its Roles panel sits beside the graph. The three selections are mutually exclusive.
- With no project open the graph area reads “Open a project to see its equipment topology.”
Editor Card — Anchor
Header: the title Anchor, a Root badge on the part's root anchor, an owner chip (Machine Tool /
Fixture / Workpiece / Tool / Equipment); below it, one badge per role bound to the anchor — the same
text the graph draws, with the language-neutral form the REST graph carries (Fixture-TableMount) as its tooltip.
- On an editable owner (a machine tool that is a GeneralXyzabcMachineTool,
the fixture, the workpiece):
- Name — renamed on Enter or when the field is left, never while typing.
- Extend — a new anchor linked from this one by a
NoTransformbranch; the new anchor becomes the selection. - Delete — the trash button, on a double-click; not offered on the root anchor. A role bound to the anchor, or an axis or spindle role bound to a branch the deletion takes with it, is unbound first and named in a toast ("Unbound roles: …").
- Add Branch — a select over the part's other anchors not already joined to this one in either
direction; picking one creates a
NoTransformbranch from this anchor to it. - Geometry — a checkbox that hangs a solid on the anchor or removes it, and while enabled a type
badge (the kind, or Transformed {kind}), the display-colour swatch (an authored colour
beside a reset button, or the automatic one marked auto) and the
Geometry Editor over the solid's geometry. The editor's kind
picker offers
Box3d,Cylindroid,StlFileandGeomCombination, and no None entry; beneath it the Transform picker puts a transform on the picked geometry in place, and the transformer's editor follows the geometry's. A freshly enabled solid holds an empty wrapper, which the card reads as no kind picked yet. The section is not offered on the workpiece at all, whose anchors carry no solids. On the fixture's Geometry Anchor the checkbox cannot be cleared (the server refusesdisable-geomand the box snaps back with a toast), and with no None in the picker that solid's geometry can be switched to another kind here but emptied only over HTTP (create-geom?geometryType=None).
- On a non-editable owner (the tool, or a
ClMillingDevicemachine) the card shows only “{type} is shown here but not editable.”
Editor Card — Branch
Header: the title Branch, the owner chip, an Attachment chip on a branch between parts, an Error term chip on a marked branch, and the badge of an axis or spindle role bound to the branch, on its own row below.
- Name (editable on a part's own branch only; disabled on an attachment, which is named by its role
pair), the two endpoint chips (fletch → arrow anchor), the current transformer type, and, under
Transformer, the transformer editor: the shared
Transformer Select Panel switchboard, which swaps the branch's
transformer as soon as a kind is picked and re-posts an inner-value edit so the canvas follows.
On a marked branch it offers the static kinds only —
StaticTranslation,StaticRotation,StaticFreeform,GeneralTransformandNoTransform— the kinds the server takes there. - The Error term chip is orange, titled “The controller solves without this branch; the machine runs with it.” While the project's error-term switch is off it is grey, reads Error term (not in effect) and is titled “The project's error terms are switched off on the Machine Tool item: the machine runs without this branch's value as well.”
- Error term — a toggle below the Transformer section on the card of a machine-tool branch
bound to an axis (Axis X … Axis C) or the Spindle — the role card — and on no other card; a
branch a file binds to two of these roles carries it for the first. Its tooltip reads “Add an
error of the real machine to this role: a branch of its own, just before this one, carries it.
The controller solves machine coordinates without it, and the machine runs with it while the
project's error terms are on. Switched off, the error term is taken out again.” The toggle reads
the role's error term from the roles (
errorTermBranchGuid). Switched on, it postsroles/machine-tool/{role}/error-term, which inserts the error term and rebuilds the role's branch from the error term's anchor; switched off, it sendsDELETEto the same route, which takes the error term out and rebuilds the branch from its old start anchor (see Behavior). Either way the branch comes back under a new guid: the column re-pulls the graph and the roles and selects the rebuilt branch, so the card stays on the role. The option waits until the press on it has delivered its click before it queues, so a name typed into the card and left by that press is committed first, on the branch it was typed for; a name or transformer commit queued behind the rebuild follows the branch to its new guid, and a value commit for an error term taken out meanwhile is dropped. A refusal shows as a notification and leaves the toggle as the roles have it. - While the role has an error term, a chip beside the option reads Error term, titled "The
controller solves without the error term of {role}; the machine runs with it.", or, while the
project's error-term switch is off, Error term (not in effect), grey, titled “The project's
error terms are switched off on the Machine Tool item: the machine runs without the error term of
{role} as well.” Below the option sit the two anchors the error term joins (fletch → arrow) and
the error term's own Transformer Select Panel, which offers the static kinds only: a kind picked
there is put on the error term (
update-transformeron its guid), and a value edit re-posts the error term's key, so the error is edited without leaving the role card. The anchors and the editor show only while the graph agrees with the roles — the error term ends at the branch's fletch — since a bind on a Roles panel adopts its answer before the graph is re-pulled. - On the error term's own card — the marked branch that stands as an axis's or the spindle's error term — a line under the transformer type reads "This branch is the error term of {role}; it is added and removed on the card of {role}.", shown, like the role card's editor, while the graph agrees with the roles. That card has no option and no Clear mark; its Transformer section edits the same value as the role card.
- A mark no role owns — on a fixture's or a workpiece's branch, on a branch that plays an axis or
the spindle, or on a branch of the machine tool that stands in no error term's place (see
Behavior) — is one a hand-edited file brought in or a later edit left behind. Under
the transformer type, the card gives the part's Roles-panel finding about the branch, which the
chip's title repeats:
ErrorTermRoleon a branch that plays a role, otherwise the finding whose args name the branch by its guid (branchGuid), orErrorTermNotOnRolewhen none does. Below it, Clear mark — tooltip “Take the error-term mark off this branch; its transformer stays as it is.” — postsfalseto the branch'serror-termroute and re-pulls the graph. AClMillingDevicemachine's marked branch, which this column cannot clear, gets neither. - The worktable attachment — the machine's table end into the fixture's Table Mount, or into
the workpiece's Fixture Mount when the project has no fixture — is the one attachment with an
editable transformer: the equipment's
TableToComp, edited under ownerequipment. Every other attachment shows “Only the worktable attachment carries an editable transformer; the other attachments follow their roles.” - Delete (double-click) on a part's own branch; an axis or the spindle bound to it is unbound first and toasted.
- A branch of a non-editable part (a
ClMillingDevicemachine) shows only “{type} is shown here but not editable.”
Editor Card — Assembly
Clicking a cluster shows the card headed Mechanism, with the owner chip of the part the assembly belongs to.
- On an editable part (the machine tool, fixture or workpiece): a Name field that renames the assembly — on Enter or when the field is left; the server refuses a name carrying the path separator, one that opens like a GUID segment, and one a sibling assembly already carries — then the part's runtime type, “Roles are bound on this part's item in the Control Tree.” and an Open roles button that selects that item.
- On any other assembly (the tool's, the equipment's own, a
ClMillingDevicemachine's): the assembly's name as plain text, the type line and “{type} is shown here but not editable.”
Roles Panel (on the Control Tree)
Each of the three mechanism root panels — Machine Tool, Fixture,
Workpiece — ends with the Roles panel, titled Roles: one row per role, with
the role's label, a caption naming its kind (anchor or branch), “required” where the part needs
it, and “needs {transformer type}” on a branch role; a clearable select over the part's own
anchors or branches, leaving out the branches marked as error terms (a role bound outside the
part, or to a marked branch, is listed by name at the top so the select can show it); and the arm
button, a target icon whose tooltip reads “Pick on the graph” (lit while its role is armed). Below
the list, the server's checks — or “All checks pass.” A part the project has not mounted shows
“Not mounted.” instead of the rows, and a part whose type has no editable roles (a
ClMillingDevice machine) “{type} has no editable roles.”
| Part | Roles | Kind | Note |
|---|---|---|---|
| Machine tool | Table Mount, Tool Mount | anchor | required |
| Machine tool | Axis X, Axis Y, Axis Z | branch | optional; needs DynamicTranslation |
| Machine tool | Axis A, Axis B, Axis C | branch | optional; needs DynamicRotation |
| Machine tool | Spindle | branch | optional; needs DynamicRotation |
| Fixture | Table Mount, Workpiece Mount, Geometry Anchor | anchor | required |
| Workpiece | Fixture Mount, Program-Zero Anchor, Geometry Anchor | anchor | required |
| Check | Meaning |
|---|---|
Unbound |
Not bound; the mechanism needs this role. |
NotOwn |
Bound to an element outside this mechanism's own assembly. |
Duplicate |
The same element also plays {other}. |
NotReachable |
No branch chain leads from the root anchor to this anchor. |
AxisTransformerMismatch |
Needs a {expected} branch; the bound branch carries {actual}. |
AxisOffChain |
The branch is not on the chain between the table mount and the tool mount. |
SpindleOffToolAxis |
The spindle's rotation does not run along the tool mount's Z axis through its origin; turning it swings the tool around. |
ErrorTermRole |
The bound branch is marked as an error term; a role's branch cannot be one. Clear its mark in the Topology column, then add the error term on the branch's card. |
ErrorTermDynamic |
The error term {branch} carries {actual}; an error term carries a static transformer only. Change its transformer type to a static one, or clear its mark in the Topology column. |
ErrorTermOnToolAxis |
The error term {branch} lies between the spindle and the tool mount, which makes the spindle read as off the tool axis. Clear its mark, and add the spindle housing's error on the spindle branch's card. |
ErrorTermNotOnRole |
The branch {branch} is marked as an error term, but it is no axis's or spindle's: error terms are added on the cards of the machine tool's axis and spindle branches. Clear its mark in the Topology column. |
A finding is printed after the label of the role it is about ("Table Mount: Not bound; …").
A marked branch is reported by the first of the four error-term checks that fits, in the order of
the table, and by no other: ErrorTermRole under each role the branch plays; for any other marked
branch of the machine tool, ErrorTermDynamic when its kind is not static, wherever it lies, then
ErrorTermOnToolAxis, under Spindle, when it lies on the chain from the spindle branch to the
tool mount — the branch reaching the tool mount included, and even when it stands just before an
axis — and ErrorTermNotOnRole when it stands in no error term's place (see
Behavior); on a fixture or a workpiece, ErrorTermNotOnRole for every marked
branch. ErrorTermDynamic and ErrorTermNotOnRole are about no role, so the panel prints them
alone. {branch} is the marked branch's name, or its two anchors' names as fletch--->arrow when
it has none; the findings of the last three also carry the branch's guid as branchGuid in their
args, by which the branch card finds the finding about its branch. The chain from the spindle
branch to the tool mount is followed in either direction: with the Tool Mount bound to an anchor
on the table side, it runs back through the root, and a mark it passes is ErrorTermOnToolAxis's.
While any marked branch lies on that chain, SpindleOffToolAxis is not reported: the error would
skew that reading. An error term in its place off that chain is reported by none of the four; they
report a mark that a file or a script brought in, or one a later edit left where no role owns it
or moved onto that chain. ErrorTermRole also stops every run at its start with an
ErrorTermRoleException naming the role and the branch, until the mark is cleared or
another branch is bound.
Canvas Display Option
The shared Equipment canvas's Display Options dropdown carries a Role Anchors flag in its
Anchors group (show-role-anchors, off by default): it draws the axes of every bound role anchor —
the machine's two mounts, the fixture's three anchors, the workpiece's three — independently of the
per-anchor flags. An anchor the machine does not reach is not placed and draws nothing.
Behavior
- Arm and pick. The arm button on a Roles row arms that role (the chip appears in a strip above the graph), and a second click on it disarms. The next click on a graph element of the same kind that belongs to the same part binds it, toasts "{role} bound.", disarms and refreshes; an element of the wrong kind repeats the armed hint, and an element of another part toasts “That element belongs to another part; pick one from the part that owns the role.” and leaves the role armed. The select on the row binds without arming; clearing it unbinds. A refused bind leaves the select on the bound element.
- Adding and removing an error term. The role card's Error term option posts
roles/machine-tool/{role}/error-termto add the role's error term, and sendsDELETEto the same route to remove it. Adding is one edit, settled once. With F → A the role's branch, the server makes an anchor E in the assembly A sits in and the error term F → E, both named by the branch's name witherrappended (Xerr) — A's name when the branch has none, the role key when neither has one; a name that would not stay addressable is passed over, and a name an anchor of the machine carries already takes a three-digit counter (Xerr001). The error term carries aStaticRotationof 0° about Z, which leaves the machine as it was until a value is written, and is marked. A branch's ends are fixed, so the role's branch is rebuilt: a new branch E → A takes the old one's transformer object, its name, its mark and every role bound to it, under a new guid, and the old one is detached; a step that fails takes the others back. Removing is the way back: a new branch F → A takes E → A's transformer object, name, mark and roles, again under a new guid, and E → A, the error term and E go. Added and then removed, an error term leaves the machine file as it was but for that branch's guid when the branch is the only one out of its start anchor; when another branch leaves that anchor too, the rebuilt branch becomes the last one out of it, so the file's branch elements can also come in another order, the topology the same. - Adding is refused (409), checked in this order, on a role of the fixture or the workpiece
(
ErrorTermOutsideMachine), on a mount (ErrorTermRoleNotAxis), on an axis or the spindle bound to no branch of the machine (ErrorTermRoleUnbound), on a role whose own branch is marked, which only a file leaves (ErrorTermRoleMarked), on a role that has an error term already (ErrorTermExists) and on a role whose branch lies between the spindle branch and the tool mount, where the branch before it would lie too (ErrorTermOnToolAxis). Removing meets the first three, thenErrorTermAbsentwhen no error term stands before the role's branch — a marked branch there out of its place is none — andErrorTermBypasswhen a branch from the error term's start anchor to the role branch's end anchor stands beside it, so the role's branch could not go back there. A role key the part does not have is 404RoleNotFound. - Where an error term stands. One rule decides it, and the roles'
errorTermBranchGuid, the Roles panel's checks, both error-term routes of a role and the mark route all read it: a branch F → E stands in the place of the error term of the axis or the spindle whose branch E → A follows it when F → E is one of the machine's own branches, plays no role, carries a static kind and is the only branch into E, and E is an anchor of its own — not the root, playing no role, hanging no solid — from which nothing goes but that role's branch; marked, it is that role's error term. Why an error term goes there is in Where an Error Term Goes. A segment split into that shape by hand, its branch before the axis marked, reads as that axis's error term, and the axis's role card removes it like one it added. - The mark route. A branch's
error-termclears its mark (false), or sets one (true) only where the branch stands in an error term's place, so a script can compare a play with its error terms cleared against one with them marked. Clearing is never refused on the machine tool, the fixture or the workpiece; aClMillingDevicemachine is not editable here (409MechanismNotEditable), so a mark its file carries cannot be cleared in this column. Marking is refused (409), checked in this order, on a branch of the fixture or the workpiece (ErrorTermOutsideMachine: error terms belong to the machine tool), on a branch that plays an axis or the spindle (ErrorTermOnRole: the role would drop out of the controller's model), on a branch whose transformer is not a static kind (ErrorTermDynamic), on a branch between the spindle branch and the tool mount (ErrorTermOnToolAxis: the spindle would read as off the tool axis) and on a branch that stands in no error term's place (ErrorTermNotOnRole). Posting the value the branch already holds answers the branch and changes nothing: no rewire, nothing for the runtime face to follow. - The place is held only when an error term is added or a mark is set. A later edit — a role rebound or unbound, the role's branch deleted, the error term's anchor given a solid or bound as a mount, a branch added into or out of that anchor, the spindle or the Tool Mount rebound so that the chain between them passes a mark — is not refused, and the Roles panel reports the mark it leaves where no role owns it or on that chain. A mark no role owns shows on its branch's card with Clear mark.
- Two rules hold at every later edit. Binding an axis or the spindle to a marked branch is
refused (409
RoleOnErrorTerm), and so isupdate-transformerputting a kind that is not static on a marked branch (409ErrorTermDynamic). - After every edit — a bind, a rename, an anchor or branch created or deleted, a transformer
swapped, a solid hung, an error term added or removed, a mark set or cleared — the server
rewires the equipment's attachments
(Rewire), regenerates the
machine's collision pairs when the machine auto-generates them and both its mounts are bound,
and notifies the project so the runtime face follows; the canvas redraws on its next frame. The
attachment branches are re-minted by every rewire, so the column re-pulls the graph and the
roles (
reinitializeMechanism/refreshTopologyon the Control-Tree host) rather than patching them; a selected worktable attachment follows its new guid, and so does a role's branch that adding or removing its error term rebuilt. Calls that leave the topology unchanged — has-geom, geom-type, the rgb read and write, refresh-geom-cache, index-transformer — settle nothing; index-geom does so only when it hung a new solid, and a branch'serror-termonly when the mark changed. - An in-place value edit inside the branch card's transformer editor, or the role card's
error-term editor, re-posts
update-transformerwith the same key, so the object the switchboard produced is the one installed on the branch when the redraw happens; inside the anchor card's geometry editor it postsrefresh-geom-cache, so the runtime face — which shares the solid instance — re-triangulates. Either then refreshes the graph; a geometry kind switch is structural and goes through the host's re-pull instead. Re-posting the branch's own object is never refused;update-transformerrefuses a transformer object that another branch of the equipment already carries (409TransformerInUse), on the worktable attachment's route too. - While a play is live — the pace player locked (
RunningorPaused), or a play a host request drives directly on the session shell (POST /api/SessionShell/PlayNcFileand its siblings) in flight — the machine tool's and the fixture's solids are read-only. The runtime face does not copy them: it draws the very instances this column edits and checks collisions against them, so a run reads them as it plays. Those instances stay the run's until the next session boundary: a machine tool or a fixture swapped during a run (/api/mech/machine-tool/load,…/updateor…/create,/api/Fixture/UpdateFixture, none of them refused), or an anchor deleted with its solid, leaves the run on the old solids, and a write under them is refused too.enable-geom,disable-geom,create-geom,set-geom-transform,refresh-geom-cacheandPOST …/rgbanswer 409SolidEditRefusedWhileRunningbefore the action runs, so a refused request changes nothing;index-geomanswers the same on an anchor that has no solid yet, before it hangs one. The generic geometry and transformer editors (/api/Box3d,/api/TransformationGeom,/api/StaticTranslation, …) refuse a write the same way when its key names an object that is, or hangs under, one of those solids; every other object they serve — a workpiece's geometry, a tool's, a branch's transformer — passes. The Equipment page shows the refusal's own message in a banner while the execution status readsRunningorPaused, with a Stop and a Reset button, and covers or disables nothing: a write sent all the same is refused and shown as a notification. A direct play on the session shell raises the session'sIsRunningNcLinesand leaves the player idle, so the status reads neitherRunningnorPausedand no banner shows: a write during it is refused with the notification alone. The rest of the column — anchors, branches and their transformers, roles, error terms, renames, deletes — stays open during a run: it edits a face the runtime copies, and what it changes takes effect at the next session boundary. - Edits are serialised on one promise chain; while one is in flight — the column's own, or a bind from a Roles panel's select — the graph ignores clicks; the title bar's Refresh and the card's Extend, Delete, Add Branch select, Geometry checkbox, colour controls, Error term option and Clear mark are disabled, and so are the Roles panels' selects and arm buttons. The transformer and geometry editors in the card are not gated: a kind switch in either queues behind the edit in flight. The name fields stay editable too: a rename committed meanwhile queues behind the edit in flight. The state — graph, roles, selection, armed role — is one module singleton shared by the column and the three Roles panels, so the Control-Tree host's own refresh after Load / Paste / New on a mechanism item updates the column too.
- The column pulls the graph and the roles when it mounts, which it does even while hidden, since a hidden column is pinned to 0 px rather than unmounted. A pull the column wants while hidden — its state emptied under it — waits until it is shown on the active page; the host's re-pulls after a bind or a Load / Paste / New run either way. A no-project 404 is an empty state, not an error.
HTTP Surface
Everything is under api/mech/equipment-topology. Owners are machine-tool, fixture and
workpiece; equipment is accepted only by the two branch-transformer routes, and only for the
worktable attachment. A POST body is JSON.
| Route | Does |
|---|---|
GET graph?toolInternals= |
The whole equipment as one graph; toolInternals=true adds the tool's own anchors and branches (the page never asks for them); each branch carries isErrorTerm, and the graph the project's error-term switch as errorTermsEnabled |
GET error-terms, PUT error-terms body true / false |
The project's error-term switch as a bare JSON boolean; PUT answers the value written |
GET roles, GET roles/{owner} |
The roles of every part / one part, with candidates and checks; an axis's or the spindle's role names its error term as errorTermBranchGuid (empty when it has none, and on every other role) |
POST roles/{owner}/{role} body { "guid": "…" } |
Binds the role to the part's own element; an empty guid unbinds; answers the part's roles |
POST roles/{owner}/{role}/error-term |
Adds the error term of an axis or the spindle: a new anchor and a marked StaticRotation of 0° just before the role's branch, which is rebuilt from the new anchor under a new guid; answers { role, anchor, errorTerm, branch } — the new anchor, the error term and the rebuilt branch |
DELETE roles/{owner}/{role}/error-term |
Removes it: the role's branch is rebuilt from the error term's start anchor under a new guid, and the error term and its anchor go; answers the rebuilt branch |
POST {owner}/asmb/{id}/rename body { "name": "…" } |
Renames the part's key assembly or one below it; 400 for a name carrying the path separator, opening like a GUID segment, or worn by a sibling assembly |
POST {owner}/anchor/new?name= |
A stand-alone anchor in the part's key assembly |
POST {owner}/anchor/extend-from/{id} |
A new anchor downstream of {id} on a NoTransform branch |
POST {owner}/anchor/{id}/rename body { "name": "…" } |
Renames |
DELETE {owner}/anchor/{id} |
Deletes the anchor and its branches; answers { success, unboundRoles }; the root is refused |
POST {owner}/branch body { "fletchAnchorGuid", "arrowAnchorGuid" } |
A NoTransform branch between two anchors of the part |
POST {owner}/branch/{id}/rename |
Renames |
POST {owner}/branch/{id}/error-term body { "value": false } |
Clears the branch's error-term mark; true sets one, only where the branch stands in an error term's place; answers the branch with its isErrorTerm; the value the branch already holds answers it unchanged and settles nothing; 400 for a body without value |
DELETE {owner}/branch/{id} |
Deletes; answers unboundRoles |
POST {owner}/branch/{id}/index-transformer |
Indexes the branch's transformer; answers its key |
POST {owner}/branch/{id}/update-transformer?transformerKey= |
Swaps the branch's transformer to the indexed one; answers the canonical key |
GET {owner}/anchor/{id}/has-geom, GET …/geom-type, GET …/rgb |
The anchor solid's presence, geometry type name (or None), display colour |
POST {owner}/anchor/{id}/enable-geom, …/disable-geom |
Hangs a solid holding an empty TransformationGeom (an existing solid is kept), which the card presents as a slot with no kind yet / removes it |
POST {owner}/anchor/{id}/index-geom |
Indexes the solid's geometry for the editor, hanging a solid first when there is none; answers the key |
POST {owner}/anchor/{id}/create-geom?geometryType= |
A fresh geometry of that kind on the solid (None clears it) |
POST {owner}/anchor/{id}/set-geom-transform?transformerType= |
Wraps the solid's geometry in a TransformationGeom of that transformer kind, swaps the transformer, or with None unwraps it — in place, the authored geometry kept; what the card's Transform picker posts; 409 on an anchor without a solid or a solid holding nothing |
POST {owner}/anchor/{id}/refresh-geom-cache |
Clears the solid's cached triangulation after an in-place edit |
POST {owner}/anchor/{id}/rgb?rgb= |
Authors the display colour (#rrggbb; empty clears) |
While a play is live — the pace player locked (Running or Paused), or a play a host request
drives directly on the session shell in flight — enable-geom, disable-geom, create-geom,
set-geom-transform, refresh-geom-cache and POST …/rgb answer 409
SolidEditRefusedWhileRunning, and so does index-geom on an anchor that has no solid yet; every
other route of the table stays open (see Behavior).
IndexService keys: a branch transformer is equipment-topology.<owner>.branch.<guid>.transformer,
an anchor solid's geometry equipment-topology.<owner>.anchor.<guid>.geom (the guid written without
hyphens in both); the worktable attachment's is equipment-topology.equipment.table-to-comp.
| Status | code |
When |
|---|---|---|
| 404 | NoProjectLoaded |
No project, or no authored equipment |
| 400 | UnknownOwner |
An owner other than the three parts (tool included) |
| 404 | MechanismNotFound |
The owner names a part the project has not mounted |
| 409 | MechanismNotEditable |
The machine tool is a ClMillingDevice |
| 404 | RoleNotFound |
The part has no role of that key |
| 409 | RoleElementTaken |
The element already plays another role of the same part |
| 409 | AxisTransformerMismatch |
An axis or the spindle given a branch of the wrong kind, or its bound branch given the wrong transformer |
| 409 | MechanismRefused |
The part's own rule: a role takes only an element of its assembly |
| 400 | — | A branch's error-term with no body, or a body without value |
| 409 | ErrorTermOutsideMachine |
Adding or removing the error term of a fixture's or a workpiece's role, or marking a branch of the fixture or the workpiece |
| 409 | ErrorTermRoleNotAxis |
Adding or removing the error term of a mount |
| 409 | ErrorTermRoleUnbound |
Adding or removing the error term of an axis or the spindle bound to no branch of the machine tool |
| 409 | ErrorTermRoleMarked |
Adding the error term of a role whose own branch is marked as an error term |
| 409 | ErrorTermExists |
Adding the error term of a role that has one |
| 409 | ErrorTermAbsent |
Removing the error term of a role that has none |
| 409 | ErrorTermBypass |
Removing an error term while a branch from its start anchor to the role branch's end anchor stands beside it; args role, fletch and arrow, the two anchors by name |
| 409 | ErrorTermOnRole |
Marking a branch that plays an axis or the spindle |
| 409 | ErrorTermDynamic |
Marking a branch whose transformer is not a static kind, or update-transformer putting such a kind on a marked branch |
| 409 | ErrorTermOnToolAxis |
Adding the error term of a role whose branch lies between the spindle branch and the tool mount, or marking a branch there |
| 409 | ErrorTermNotOnRole |
Marking a branch that stands in no error term's place |
| 409 | RoleOnErrorTerm |
Binding an axis or the spindle to a branch marked as an error term |
| 409 | TransformerInUse |
update-transformer given a transformer object another branch of the equipment carries, the worktable attachment's route included; never the branch's own object re-posted |
| 409 | SolidsNotAllowed |
enable-geom, disable-geom, index-geom or create-geom on the workpiece (its read routes answer as for an anchor with no solid) |
| 409 | SolidEditRefusedWhileRunning |
enable-geom, disable-geom, create-geom, set-geom-transform, refresh-geom-cache or POST …/rgb while a play is live — the pace player locked (Running or Paused), or a play a host request drives directly on the session shell in flight — answered by a filter before any check of the route's own, so it then answers in place of UnknownOwner, MechanismNotFound, MechanismNotEditable, AnchorNotFound, SolidsNotAllowed or GeomAnchorKeepsItsSolid; and index-geom on an anchor without a solid then (it would hang one), answered in the action once the owner and the anchor resolve, so UnknownOwner, MechanismNotFound, MechanismNotEditable and AnchorNotFound come first and the workpiece still answers SolidsNotAllowed; at the same moments, a write of the generic geometry and transformer editors (/api/Box3d, /api/StaticTranslation, …) to an object that is, or hangs under, a solid of the machine tool or the fixture, on the authored face or on the runtime face, which keeps a swapped part's or a deleted anchor's solids until the next session boundary |
| 404 | AsmbNotFound |
An assembly guid outside the part's key assembly |
| 404 | AnchorNotFound |
An anchor guid outside the part's key assembly |
| 404 | BranchNotFound |
A branch guid outside the part's key assembly, or, under owner equipment, a guid that names no branch of the equipment |
| 409 | AttachmentFixed |
Owner equipment on any branch other than the worktable attachment (another attachment, or a part's own branch) |
| 409 | GeomAnchorKeepsItsSolid |
disable-geom on the fixture's Geometry Anchor |
Adding a role's error term meets ErrorTermOutsideMachine, ErrorTermRoleNotAxis,
ErrorTermRoleUnbound, ErrorTermRoleMarked, ErrorTermExists and ErrorTermOnToolAxis in that
order; removing it meets the first three, then ErrorTermAbsent and ErrorTermBypass. Marking a
branch meets ErrorTermOutsideMachine, ErrorTermOnRole, ErrorTermDynamic,
ErrorTermOnToolAxis and ErrorTermNotOnRole in that order; clearing a mark meets none of them.
Both error-term routes of a role rebuild the role's branch under a new guid, so a caller that kept
the old guid re-reads the roles or takes the answer's: the old one answers 404 BranchNotFound.
Where the English message names a role, it prints the raw role key
(AxisX, Spindle, TableMount); every other interface language shows the role's label in its
place.
The program-zero alignment stays on the Controller:
POST /api/Controller/iso-coordinate-table/{index}/align-workpiece-program-zero and
POST /api/Controller/iso-coordinate-table/revert-align-workpiece-program-zero rewrite the
transformer of the fixture branch that leads from its Geometry Anchor straight to its Table Mount.
Default Topology
A part built by CreateDefault — which is also the shape every legacy-form file loads onto — is what
the graph shows on a fresh project. Fixture: the root is the Geometry Anchor, carrying the fixture's
solid, with one NoTransform branch to the Table Mount and one to the Workpiece Mount, each
branch named after the mount it reaches. Workpiece: the root is the Fixture Mount; from the
Geometry Anchor one zero StaticTranslation branch leads to the Fixture Mount and one to the
Program-Zero Anchor, each named after the anchor it reaches. A mission script addresses the same
branches: once the fixture's table branch carries a StaticTranslation (the program-zero
alignment writes one; the default shape's is NoTransform),
(Branch.Get(Fixture.GeomAnchor, Fixture.TableMount).Transformer as StaticTranslation).Trans += new vec3d_t(0, 0, …);,
and Branch.Get(Workpiece.GeomAnchor, Workpiece.ProgramZeroAnchor).Transformer = transform;.
Source Code Path
See HiNC App Anatomy for git repository links.
Web Application
HiNC-2025-webservice (Quasar CLI SPA):
wwwroot-src/src/components/mech/EquipmentTopologyPanel.vue— the column: the Refresh button it teleports onto the title bar, the armed-role strip, the graph, the height divider and the editor card, addressed by owner; the arm-and-pick bind; the serialised edit chain and the post-edit refresh; the role card's Error term option, its chip, and its error term's anchors and editor, with the map of rebuilt guids the selection and the queued commits follow; the error term's own card; a misplaced mark's finding and Clear mark; the marked branch's chip.wwwroot-src/src/components/mech/MechanismRolesPanel.vue— the Roles panel a mechanism root panel ends with: the rows, the candidate selects, the arm buttons and the checks list, a finding about no role printed alone.wwwroot-src/src/components/mech/MechBuilderGraph.vue— the graph view, its name historical: nested assembly clusters, role badges, dotted attachment edges, thick error-term edges and their badges, and the anchor / branch / cluster click delegation; the direction, zoom and fit-width toolbar, drag-to-pan, and the scroll a redraw keeps. Mermaid is dynamic-imported on first draw, and every label is emitted quoted, which the parser requires for CJK text.wwwroot-src/src/composables/useEquipmentTopology.ts— the module singleton: the graph and roles, the exclusive selection, the armed role, the refresh epoch and the worktable-attachment test.wwwroot-src/src/api/equipmentTopology.ts— typed client forapi/mech/equipment-topology: the owner types, the graph and roles DTOs (a role'serrorTermBranchGuid,RoleErrorTermDto), and one function per route —addRoleErrorTerm/removeRoleErrorTermfor a role's error term andsetBranchErrorTermfor a branch's mark among them.wwwroot-src/src/components/controlTree/useControlTreeHost.ts—reinitializeMechanism/refreshTopology: the re-pull after a bind, an edit, or a Load / Paste / New on a mechanism item; and the topology reset in the equipment host's setup, once per project epoch, before the column mounts and pulls.wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue— mounts the Roles panel at the end of each of the three inline mechanism root panels, and on the machine tool's the Enable Error Terms switch above it, which re-pulls the graph after every write.wwwroot-src/src/pages/EquipmentPage.vue— the four-column host: the reversed pixel splitter that gives the column its own width, the canvas-hidden hand-over, and the column's title bar with the controls container the panel's Refresh button lands in; and the player-locked banner (solid-edit-locked-banner), shown while the status isRunningorPausedwith the refusal's own sentence and a Stop and a Reset button.wwwroot-src/src/components/AppMenuBar.vue— the column-button row, whose fourth button on this page toggles the column.wwwroot-src/src/composables/useViewPrefs.ts— thetopologycolumn bit, its window-width first-run default,topologyColPx, andtopologyGraphPx, the graph's height above the card.wwwroot-src/src/router/treeRoutes.ts— the retired-slot hop: a legacy?tree=link into a mechanism item's former child ids lands on that item.wwwroot-src/src/components/topo/TransformerSelectPanel.vueandwwwroot-src/src/components/geom/GeometryEditor.vue— the switchboards the branch and anchor cards mount.wwwroot-src/src/components/mech/EquipmentSetupPanel.vueandwwwroot-src/src/api/equipmentSetup.ts— the Role Anchors flag on the shared canvas's Display Options.wwwroot-src/src/i18n/en/mech.ts— thetopology.*androles.*labels, and the canvas flag; the error-term option, the chips, the error term's own line and Clear mark undertopology.errorTerm.*, the checks underroles.check.*.wwwroot-src/src/api/http.ts— the coded errors: outside English, a refusal's message is rendered in the interface language with role and owner labels in place of the raw keys;SolidEditRefusedWhileRunningmaps ontoapiErrors.solidEditRefusedWhileRunning, the banner's text too.wwwroot-src/src/i18n/en/apiErrors.ts—solidEditRefusedWhileRunning, the refusal's sentence, one file per interface language beside it.Mech/Topology/EquipmentTopologyController.cs— the REST surface: owner resolution, the graph and roles reads, the anchor / branch / solid routes, a role's error term added and removed (RoleErrorTermDto), the error-term mark and the project's error-term switch, the worktable-attachment gate, and the after-edit settle (rewire, collision pairs, notify).Mech/Topology/EquipmentRoles.cs— the per-part role table,Describe(roles, candidates, checks, each axis's and the spindle's error term), the eleven checks,Bindwith its three refusals,Unbindbefore a delete,ErrorTermRoleOf(where an error term stands) andErrorTermOf,AddErrorTermProblemandRemoveErrorTermProblemwith the refusals of adding and removing an error term,ErrorTermNameandNewErrorTermTransformer(the inserted anchor's name and the error term's first value),Rebinder(the roles re-pointed onto a rebuilt branch),ErrorTermProblemwith the five refusals of a mark, and the transformer guard (AxisTransformerMismatch,ErrorTermDynamic,TransformerInUse).Mech/Topology/TopologyEditService.cs— anchor / branch CRUD,InsertUpstream/RemoveUpstream(an anchor and a branch put in front of a branch or taken out, the branch rebuilt) andFreeAnchorName, the error-term mark, transformer indexing and swap, solid enable / index / create / type / cache / colour on any mechanism, built per request by the controller above with theequipment-topology.<owner>key prefix.Mech/Topology/TopologyGraphDto.csandMech/Topology/TopologyGraphBuilder.cs— the graph DTO (assemblies, anchors, branches with their error-term marks, root anchor id, mechanisms, the error-term switch) and how owners, attachments and the tool-internals cut are decided.Mech/Topology/EquipmentSolids.cs— the solids the runtime face shares with the authored one, every solid on the machine tool's and the fixture's anchors, read on both faces, since the runtime one keeps a swapped part's or a deleted anchor's solids until the next session boundary; andHold, whether an object is one of them or hangs under one — a solid's geometry, aTransformationGeom's geometry and transformer, aGeomCombination's items, aStackTransformer's stack, aGeneralTransform's translation and rotation — compared by reference. Each dictionary is read as a snapshot; a walk torn by a write on another thread is tried again, three attempts in all, and one that never completes holds.Common/ApiError.cs— the error codes above.Common/RefuseWhilePlayerLockedAttribute.cs— the tool house's player-lock filter, givenPlayerLockedEdit.Solidson the six solid routes: there it answers 409SolidEditRefusedWhileRunningwhile the solids are locked, before the action runs.SolidsLocked, the test it reads then — and the oneindex-geomreads in its action — isStepNotBuiltYet.IsLocked; the tool house's own refusal keeps the player's lock alone.Common/RefuseSolidEditWhilePlayerLockedAttribute.cs— the filter on the generic geometry and transformer editors, every controller underGeom/andMech/Topo/: while the solids are locked (SolidsLocked, above), a non-GET action whose index key names an objectEquipmentSolids.Holdholds answers 409SolidEditRefusedWhileRunning; the index-only POSTs marked[AllowWhilePlayerLocked]pass, but forTransformationGeom/IndexTransformeron a wrapper under those solids that has no transformer yet, whose one write — aNoTransformon the null field — is refused the same way.Execution/StepNotBuiltYet.cs—IsLocked, the solids' lock: the pace player locked, or the session'sIsRunningNcLinesraised by a play a host request drives directly on the session shell (POST /api/SessionShell/PlayNcFileand its siblings), which leaves the player idle, so the execution status reads neitherRunningnorPaused.Disp/EquipmentSetupDisplayeeConfig.cs,Disp/EquipmentSetupDisplayee.csandMech/EquipmentSetupDisplayController.cs—ShowRoleAnchors: the persisted flag, the drawing, and itsshow-role-anchors/{renderingConnectionId}endpoint.Controller/ControllerController.cs— the align / revert-align endpoints that write the fixture's table branch.
HiAPI Engine
HiMech/NcMech/Xyzabc/GeneralXyzabcMachineTool.cs— the machine's own topology and roles:TableMount,ToolMount,AxisX…AxisC,Spindle.HiMech/NcMech/Fixtures/Fixture.cs— the fixture's assembly, its three anchor roles,Solid/Geomon the Geometry Anchor,HangSolidandCreateDefault.HiMech/NcMech/Workpieces/Workpiece.cs— the workpiece's assembly, its three anchor roles andCreateDefault.HiMech/Machining/MachiningEquipmentUtils/EquipmentWiring.cs—Rewire: the attachment branches detached and re-attached whole from the parts' current roles.HiMech/Machining/MachiningEquipmentUtils/MachiningEquipmentUtil.cs—TryAlignWorkpieceProgramZeroToIso, the alignment the Controller endpoints call.HiMech/Mech/Topo/Branch.cs—IsErrorTerm, the mark, and theIsErrorTermattribute a machine or project file carries on a marked branch.HiMech/Mech/MachiningChainUtil.cs—RequireRoleBranchesNotErrorTerm, the refusal by name a run meets at its start when a role branch is marked.HiNc/MachiningProcs/LocalProjectService.cs—EnableErrorTerms, the project's switch theerror-termsroutes read and write: a write is a setup edit, and while the switch is off the runtime face takes every marked branch asNoTransform.
See Also
- Equipment Page — the page this column belongs to
- Machine Tool — the part whose mounts and axes are bound on its root panel and authored here
- Fixture — the part whose Geometry Anchor carries a solid and whose table branch the program-zero alignment writes
- Workpiece — the part whose anchors carry no solids, and whose Program-Zero Anchor a script addresses through this graph
- Transformer Select Panel — the switchboard the branch card mounts, and the parent-aware swap it performs
- Geometry Editor — the switchboard the anchor card mounts over the anchor solid's geometry
- Control Tree — the host whose
reinitializeMechanismre-pulls this column after an edit, and whose mechanism items a cluster click selects - Tree Ids and Routes — why this column has no
?tree=id, and the hop that lands retired mechanism child ids on their item - Main Panel — the menu bar whose last column toggle on this page shows and hides the column
- Anchors and Roles — the end-user placement task done through this column and the Roles panels
- Object Store (IndexService) — the keyed store the branch transformers and anchor geometries are edited through
- Driving the Web Service over HTTP — the same routes driven by a script