This commit is contained in:
2026-09-15 01:12:50 +08:00
parent 2db889ad89
commit 1a75503105
99 changed files with 4168 additions and 726 deletions
+8 -3
View File
@@ -1,8 +1,8 @@
{ {
"schemaVersion": 1, "schemaVersion": 1,
"engineVersion": "3.2.28.0", "engineVersion": "3.2.29.0",
"filesParsed": 1280, "filesParsed": 1282,
"siteCount": 365, "siteCount": 366,
"sites": [ "sites": [
{ {
"id": "AddTimeDataByFile--Start", "id": "AddTimeDataByFile--Start",
@@ -1099,6 +1099,11 @@
"template": "Physics is enabled and {0} steps touched the workpiece, but no touched step produced a physics result. Check that a tool is bound to the spindle, that the spindle rotates through the cuts (M03/M04), and that the workpiece cutting parameter is loaded. Force results are empty for the whole play; if the engagements were not built either (no tool, or spindle never rotating), milling-parameter training will skip every touched step.", "template": "Physics is enabled and {0} steps touched the workpiece, but no touched step produced a physics result. Check that a tool is bound to the spindle, that the spindle rotates through the cuts (M03/M04), and that the workpiece cutting parameter is loaded. Force results are empty for the whole play; if the engagements were not built either (no tool, or spindle never rotating), milling-parameter training will skip every touched step.",
"file": "HiMech/MachiningProcs/MachiningSession.cs" "file": "HiMech/MachiningProcs/MachiningSession.cs"
}, },
{
"id": "Play-RapidCut--Detected",
"template": "Rapid traverse at line {0} (from step {1}) removed {2} mm³ of stock over {3} steps, cutting depth up to {4} mm. On a real machine a rapid move through material breaks the tool or crashes the machine: check the approach clearance, the work offset, the tool length offset and the stock size. Set RapidCutVolumeThreshold_mm3 on the project to ignore grazing contact.",
"file": "HiMech/MachiningProcs/RapidCutMonitor.cs"
},
{ {
"id": "Play-YieldingStress--None", "id": "Play-YieldingStress--None",
"template": "Tool {0}: physics produced results but the yielding stress ratio could not be evaluated on any touched step (NaN). Check that the cutter is a milling cutter with a flute material, and that its beam geometry has sections outside the tip zone (a section counts only where its height above the tip exceeds its radius). The NcOpt yielding constraint is off for these tools.", "template": "Tool {0}: physics produced results but the yielding stress ratio could not be evaluated on any touched step (NaN). Check that the cutter is a milling cutter with a flute material, and that its beam geometry has sections outside the tip zone (a section counts only where its height above the tip exceeds its radius). The NcOpt yielding constraint is off for these tools.",
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+75 -75
View File
@@ -11,9 +11,9 @@
"dependencies": { "dependencies": {
"AvalonEdit": "6.3.0.90", "AvalonEdit": "6.3.0.90",
"FontAwesome.Sharp": "6.3.0", "FontAwesome.Sharp": "6.3.0",
"Hi.WpfPlus": "3.2.24", "Hi.WpfPlus": "3.2.25",
"HiNc": "3.2.25", "HiNc": "3.2.26",
"HiNc-Resource": "3.2.22", "HiNc-Resource": "3.2.23",
"Serilog.Extensions.Hosting": "10.0.0", "Serilog.Extensions.Hosting": "10.0.0",
"Serilog.Sinks.Console": "6.1.1", "Serilog.Sinks.Console": "6.1.1",
"Serilog.Sinks.File": "7.0.0", "Serilog.Sinks.File": "7.0.0",
@@ -1598,36 +1598,36 @@
} }
} }
}, },
"Hi.WpfPlus/3.2.24": { "Hi.WpfPlus/3.2.25": {
"dependencies": { "dependencies": {
"HiDisp": "3.2.31" "HiDisp": "3.2.32"
}, },
"runtime": { "runtime": {
"lib/net10.0-windows7.0/Hi.WpfPlus.dll": { "lib/net10.0-windows7.0/Hi.WpfPlus.dll": {
"assemblyVersion": "3.2.24.0", "assemblyVersion": "3.2.25.0",
"fileVersion": "3.2.24.0" "fileVersion": "3.2.25.0"
} }
} }
}, },
"HiCbtr/3.2.27": { "HiCbtr/3.2.28": {
"dependencies": { "dependencies": {
"HiDisp": "3.2.31" "HiDisp": "3.2.32"
}, },
"runtime": { "runtime": {
"lib/net10.0/HiCbtr.dll": { "lib/net10.0/HiCbtr.dll": {
"assemblyVersion": "3.2.27.0", "assemblyVersion": "3.2.28.0",
"fileVersion": "3.2.27.0" "fileVersion": "3.2.28.0"
} }
} }
}, },
"HiDisp/3.2.31": { "HiDisp/3.2.32": {
"dependencies": { "dependencies": {
"HiGeom": "3.2.24" "HiGeom": "3.2.25"
}, },
"runtime": { "runtime": {
"lib/net10.0/HiDisp.dll": { "lib/net10.0/HiDisp.dll": {
"assemblyVersion": "3.2.31.0", "assemblyVersion": "3.2.32.0",
"fileVersion": "3.2.31.0" "fileVersion": "3.2.32.0"
} }
}, },
"native": { "native": {
@@ -1645,15 +1645,15 @@
} }
} }
}, },
"HiGeom/3.2.24": { "HiGeom/3.2.25": {
"dependencies": { "dependencies": {
"MathNet.Numerics": "5.0.0", "MathNet.Numerics": "5.0.0",
"Microsoft.CodeAnalysis.Scripting.Common": "5.9.0" "Microsoft.CodeAnalysis.Scripting.Common": "5.9.0"
}, },
"runtime": { "runtime": {
"lib/net10.0/HiGeom.dll": { "lib/net10.0/HiGeom.dll": {
"assemblyVersion": "3.2.24.0", "assemblyVersion": "3.2.25.0",
"fileVersion": "3.2.24.0" "fileVersion": "3.2.25.0"
} }
}, },
"resources": { "resources": {
@@ -1665,27 +1665,27 @@
} }
} }
}, },
"HiLicense/3.2.24": { "HiLicense/3.2.25": {
"dependencies": { "dependencies": {
"HiGeom": "3.2.24" "HiGeom": "3.2.25"
}, },
"runtime": { "runtime": {
"lib/net10.0/HiLicense.dll": { "lib/net10.0/HiLicense.dll": {
"assemblyVersion": "3.2.24.0", "assemblyVersion": "3.2.25.0",
"fileVersion": "3.2.24.0" "fileVersion": "3.2.25.0"
} }
} }
}, },
"HiMech/3.2.28": { "HiMech/3.2.29": {
"dependencies": { "dependencies": {
"CommandLineParser": "2.9.1", "CommandLineParser": "2.9.1",
"HiCbtr": "3.2.27", "HiCbtr": "3.2.28",
"Microsoft.CodeAnalysis.CSharp.Scripting": "5.9.0" "Microsoft.CodeAnalysis.CSharp.Scripting": "5.9.0"
}, },
"runtime": { "runtime": {
"lib/net10.0/HiMech.dll": { "lib/net10.0/HiMech.dll": {
"assemblyVersion": "3.2.28.0", "assemblyVersion": "3.2.29.0",
"fileVersion": "3.2.28.0" "fileVersion": "3.2.29.0"
} }
}, },
"resources": { "resources": {
@@ -1694,19 +1694,19 @@
} }
} }
}, },
"HiNc/3.2.25": { "HiNc/3.2.26": {
"dependencies": { "dependencies": {
"Dapper": "2.1.79", "Dapper": "2.1.79",
"HiLicense": "3.2.24", "HiLicense": "3.2.25",
"HiMech": "3.2.28", "HiMech": "3.2.29",
"HiUniNc": "3.2.26", "HiUniNc": "3.2.27",
"Microsoft.Data.Sqlite": "10.0.9", "Microsoft.Data.Sqlite": "10.0.9",
"SQLitePCLRaw.bundle_e_sqlite3": "3.0.3" "SQLitePCLRaw.bundle_e_sqlite3": "3.0.3"
}, },
"runtime": { "runtime": {
"lib/net10.0/HiNc.dll": { "lib/net10.0/HiNc.dll": {
"assemblyVersion": "3.2.25.0", "assemblyVersion": "3.2.26.0",
"fileVersion": "3.2.25.0" "fileVersion": "3.2.26.0"
} }
}, },
"resources": { "resources": {
@@ -1718,22 +1718,22 @@
} }
} }
}, },
"HiNc-Resource/3.2.22": { "HiNc-Resource/3.2.23": {
"runtime": { "runtime": {
"lib/net10.0/HiNc-Resource.dll": { "lib/net10.0/HiNc-Resource.dll": {
"assemblyVersion": "3.2.22.0", "assemblyVersion": "3.2.23.0",
"fileVersion": "3.2.22.0" "fileVersion": "3.2.23.0"
} }
} }
}, },
"HiUniNc/3.2.26": { "HiUniNc/3.2.27": {
"dependencies": { "dependencies": {
"HiMech": "3.2.28" "HiMech": "3.2.29"
}, },
"runtime": { "runtime": {
"lib/net10.0/HiUniNc.dll": { "lib/net10.0/HiUniNc.dll": {
"assemblyVersion": "3.2.26.0", "assemblyVersion": "3.2.27.0",
"fileVersion": "3.2.26.0" "fileVersion": "3.2.27.0"
} }
} }
}, },
@@ -2117,68 +2117,68 @@
"path": "fontawesome.sharp/6.3.0", "path": "fontawesome.sharp/6.3.0",
"hashPath": "fontawesome.sharp.6.3.0.nupkg.sha512" "hashPath": "fontawesome.sharp.6.3.0.nupkg.sha512"
}, },
"Hi.WpfPlus/3.2.24": { "Hi.WpfPlus/3.2.25": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-wJGdZWt5bhN4i+1gHxAwijt5ugzZJa1yAiMRpiquS4Y9eaauJPZyTRb9mYFfqH7ketV1z6YI07XiXMKDWFXSxA==", "sha512": "sha512-8QBd9q0MGNFjTFuJS7TtWB+Zftpn0RJxIEzVQC+vQ/0FdqQIgLy0GEErsdpEqxO1cMFEbRLNtg7RPQG4gK9iHw==",
"path": "hi.wpfplus/3.2.24", "path": "hi.wpfplus/3.2.25",
"hashPath": "hi.wpfplus.3.2.24.nupkg.sha512" "hashPath": "hi.wpfplus.3.2.25.nupkg.sha512"
}, },
"HiCbtr/3.2.27": { "HiCbtr/3.2.28": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-R670R7hWJvDYWcHVfTb77cN+rrNI/aPcFeNf/I9RI5bn6vw5IBXYaPcHYEVFGIGI8Cc1cO72Asx8vLQZNix6yQ==", "sha512": "sha512-el7ZHL9Gq29dui9SK9M5SRLlt8RMNvYVW0AijNunyQODq+F2lqXbE9/i2P8MtvIzDLyTKqdaz4vkpcMpsAdx1g==",
"path": "hicbtr/3.2.27", "path": "hicbtr/3.2.28",
"hashPath": "hicbtr.3.2.27.nupkg.sha512" "hashPath": "hicbtr.3.2.28.nupkg.sha512"
}, },
"HiDisp/3.2.31": { "HiDisp/3.2.32": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-0MDxstmt9aatV8psR5t2dKmOjNsfgp5k1hnC/2i/f/U/nVfCYB3XawOSrF7p7PkUTUg5s6g4LD4RQLqNa6JglA==", "sha512": "sha512-LF2tEwpc+1vXSG+HxYDmOZ1FI5cD8mT2OILlKHeutjzucep3KjhigD09ftdptd98K2TnpBZk/TDKplrCbDxwXQ==",
"path": "hidisp/3.2.31", "path": "hidisp/3.2.32",
"hashPath": "hidisp.3.2.31.nupkg.sha512" "hashPath": "hidisp.3.2.32.nupkg.sha512"
}, },
"HiGeom/3.2.24": { "HiGeom/3.2.25": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-XgK3iHUfYJlqeGrc2ZYhAOXcFP5Izuhwm34J3cCID/iN6gYUsHR075TM4yyaoABvde+wkiRGp1/vb5FUavZ4MQ==", "sha512": "sha512-kDz6FPnxdDf7fIKUy7Ry6WUES17SbbrUZqxjrUko+wp+YMhQZePOT6/x7IqARfoHwMWQa4uyptz/uCqOKWfsvQ==",
"path": "higeom/3.2.24", "path": "higeom/3.2.25",
"hashPath": "higeom.3.2.24.nupkg.sha512" "hashPath": "higeom.3.2.25.nupkg.sha512"
}, },
"HiLicense/3.2.24": { "HiLicense/3.2.25": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-eYWwIRdk3Nz+tjbdgi5EgoWe1+g57A8RcMktZXQjuxFN8ja5flz6jmy0v4PiK/8oKbKA7HdloU0eCK3vB2FlPA==", "sha512": "sha512-a53li1WcSo6X3raacFoqVTrqM3TvQ/nQYLXBjlD3aFPneIsR8M32TO50f9wDYbeOIMlT90NjEnjrZHxIr+LHhw==",
"path": "hilicense/3.2.24", "path": "hilicense/3.2.25",
"hashPath": "hilicense.3.2.24.nupkg.sha512" "hashPath": "hilicense.3.2.25.nupkg.sha512"
}, },
"HiMech/3.2.28": { "HiMech/3.2.29": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-SxUofgDRrDdf44g3pKnWSs6LAQZJK7lDfFu9zKPBsnSx9LNwCzh9xN0d3nTCCj9SI0qVCKd1jcuugKlS7ERaRg==", "sha512": "sha512-gyrUo/YozRYciG43oHZLtRaXpmE3zhISgwk7Q8PiW4Bi5QAf/w7KNL3DKj+T18/3brv2owzTtQ7tT5K7myfUDQ==",
"path": "himech/3.2.28", "path": "himech/3.2.29",
"hashPath": "himech.3.2.28.nupkg.sha512" "hashPath": "himech.3.2.29.nupkg.sha512"
}, },
"HiNc/3.2.25": { "HiNc/3.2.26": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-TNDUQ35MFEjIP+SkbkR6WyCsOU4EjoyWFJBmBMAAvjCmOuk2zqAkWF/Z77pcfnRXnfAnfKnbgjkEV0K0l4BW1Q==", "sha512": "sha512-ClpKih2ipUdtoqcyWUzyk0MLkwMJhJ36uwcBUghHNBvm1ULaHSxEPWOK80/lXVadbchwVfPxL7+LRNs3QbJHuw==",
"path": "hinc/3.2.25", "path": "hinc/3.2.26",
"hashPath": "hinc.3.2.25.nupkg.sha512" "hashPath": "hinc.3.2.26.nupkg.sha512"
}, },
"HiNc-Resource/3.2.22": { "HiNc-Resource/3.2.23": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-HEWpSyOgRmmT1iXvv3Pzg8uMFoaYW0jmfQjqNrubEUigPJ8FwbAg6Yz1XaN7J5U59EP+jOWt65IN4SaXSNqGJA==", "sha512": "sha512-sP3Gacc91Gxst3mvC9S5+dcefFkFa/mRZMfashTHA7wmfPRy+xuYJAgUQw0NJs0Oz+qoc0GRE5BZm7IjSp1jvg==",
"path": "hinc-resource/3.2.22", "path": "hinc-resource/3.2.23",
"hashPath": "hinc-resource.3.2.22.nupkg.sha512" "hashPath": "hinc-resource.3.2.23.nupkg.sha512"
}, },
"HiUniNc/3.2.26": { "HiUniNc/3.2.27": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-dm4RYwFHbAZhkpAxNUNrrraq6gNndM6PWiBO0MBGnUi3nRWeL2GOFiV6k3LAWAIrVY6Ud6dQWwiWMl+q0X/4kw==", "sha512": "sha512-JrzVCUM2uu3Reul3VniFDEjPcoFpUvBph0p4yfmKWo2n0ae2emYKF8mixxntT2fzAawC5btqnzCEzDT1/uELeA==",
"path": "hiuninc/3.2.26", "path": "hiuninc/3.2.27",
"hashPath": "hiuninc.3.2.26.nupkg.sha512" "hashPath": "hiuninc.3.2.27.nupkg.sha512"
}, },
"MathNet.Numerics/5.0.0": { "MathNet.Numerics/5.0.0": {
"type": "package", "type": "package",
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"schemaVersion": 1, "schemaVersion": 1,
"engineVersion": "3.2.28.0", "engineVersion": "3.2.29.0",
"recordCount": 98, "recordCount": 98,
"records": [ "records": [
{ {
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -87,7 +87,7 @@
<article data-uid="Anatomy-ExecutionToolBar"> <article data-uid="Anatomy-ExecutionToolBar">
<h1 id="execution-tool-bar">Execution Tool Bar</h1> <h1 id="execution-tool-bar">Execution Tool Bar</h1>
<p>The transport controls for the run. In the web application they sit atop the <a href="index.html">Execution Page</a>'s primary editor panel, shown for the Execution root and every node under it, and this sole instance registers the F5F8 shortcuts.</p> <p>The transport controls for the run. In the web application they sit in the run header of the <a href="index.html">Execution Page</a>'s Control Tree pane — pinned above the tree, beside the run-state badge, on the Execution page only — and this sole instance registers the F5F8 shortcuts.</p>
<h2 id="layout">Layout</h2> <h2 id="layout">Layout</h2>
<ul> <ul>
<li><code>Execution Tool Bar</code> <li><code>Execution Tool Bar</code>
@@ -102,17 +102,19 @@
</ul> </ul>
</li> </li>
</ul> </ul>
<p>In the web application the status text moved out of the tool bar and onto the Execution tree item, which carries the run-state badge. The two single-advance buttons there share one <code>skip_next</code> icon and are separated by a letter drawn into the button's corner — <code>L</code> for the line button, <code>S</code> for the step button — rather than by colour; the tool-tips carry the key names.</p> <p>In the web application the status text is a run-state badge to the right of the button strip; the two share the Control Tree pane's run header, and when the tree column is narrowed the button strip scrolls while the badge keeps its width, so the run state is the last thing a resize hides. The two single-advance buttons share one <code>skip_next</code> icon and are separated by a letter drawn into the button's corner — <code>L</code> for the line button, <code>S</code> for the step button — rather than by colour; the tool-tips carry the key names.</p>
<h2 id="behavior">Behavior</h2> <h2 id="behavior">Behavior</h2>
<ul> <ul>
<li>The webservice watches <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> events to track <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_PacePlayer">PacePlayer</a> status changes.</li> <li>The webservice watches <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> events to track <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_PacePlayer">PacePlayer</a> status changes.</li>
<li>In the webservice, <code>ExecutionStatusService</code> subscribes to those events and broadcasts status changes over SignalR through <code>ExecutionStatusHub</code>.</li> <li>In the webservice, <code>ExecutionStatusService</code> subscribes to those events and broadcasts status changes over SignalR through <code>ExecutionStatusHub</code>.</li>
<li>The frequently used buttons carry hotkeys: Start / Resume, Pause, Run One Line and Run One Step. The app's tool-tips are the only place those key bindings are written down.</li> <li>The frequently used buttons carry hotkeys: Start / Resume, Pause, Run One Line and Run One Step. The app's tool-tips are the only place those key bindings are written down.</li>
<li>The background color of the <code>Status Text Field</code> follows the status: <li>The badge reads the status in lower case (<code>ready</code>, <code>running</code>, <code>paused</code>, <code>finished</code>, <code>no project</code>, <code>error</code>), and the background color of the <code>Status Text Field</code> follows it:
<ul> <ul>
<li>Warning style — Running</li> <li>Warning (amber) — Running</li>
<li>Secondary style — Paused, No Project</li> <li>Orange — Paused</li>
<li>Success style — Finished, Ready</li> <li>Positive (green) — Finished, Ready</li>
<li>Negative (red) — Error</li>
<li>Grey — No Project, and any status the client has no label for (its raw name is shown)</li>
</ul> </ul>
</li> </li>
</ul> </ul>
@@ -150,7 +152,7 @@
</tbody> </tbody>
</table> </table>
<p><strong>Neither single-advance button is enabled while the run is <code>Running</code></strong> — stepping is a <code>Ready</code>-or-<code>Paused</code> operation, so a moving run has to be paused before it can be stepped.</p> <p><strong>Neither single-advance button is enabled while the run is <code>Running</code></strong> — stepping is a <code>Ready</code>-or-<code>Paused</code> operation, so a moving run has to be paused before it can be stepped.</p>
<p>The F5F8 handler applies the same predicates before acting, and declines in two more cases: when the event target is an <code>input</code>, a <code>textarea</code> or a contenteditable element, and when the hosting page is deactivated. The second matters because the shell keep-alives the routed pages, so leaving the Execution route deactivates rather than unmounts this component; without the detach, F5 elsewhere in the app would drive the transport instead of reloading the browser. Every declined key falls through to the browser.</p> <p>The F5F8 handler applies the same predicates before acting, and declines in two more cases: when the event target is an <code>input</code>, a <code>textarea</code> or a contenteditable element, and when the hosting page is deactivated. The second matters because the shell keep-alives the routed pages, so leaving the Execution route deactivates rather than unmounts this component; without the detach, F5 elsewhere in the app would drive the transport instead of reloading the browser. Collapsing the Control Tree row does not detach it: the dock keeps the tree pane mounted through a collapse. Every declined key falls through to the browser.</p>
<div class="TIP"> <div class="TIP">
<h5>Tip</h5> <h5>Tip</h5>
<p>Use icons rather than text on the tool-bar buttons. Run One Line and Run One Step share an icon, so they need a second mark to tell them apart — this bar draws an <code>L</code> and an <code>S</code> in the button corner. The default colour is enough for the rest.</p> <p>Use icons rather than text on the tool-bar buttons. Run One Line and Run One Step share an icon, so they need a second mark to tell them apart — this bar draws an <code>L</code> and an <code>S</code> in the button corner. The default colour is enough for the rest.</p>
@@ -160,6 +162,9 @@
<p>HiNC-2025-webservice (Quasar CLI SPA):</p> <p>HiNC-2025-webservice (Quasar CLI SPA):</p>
<ul> <ul>
<li><code>wwwroot-src/src/components/execution/ExecutionToolBar.vue</code> — the buttons. All state and handlers come from the shared <code>useExecutionTransport</code> composable, so the component is pure markup.</li> <li><code>wwwroot-src/src/components/execution/ExecutionToolBar.vue</code> — the buttons. All state and handlers come from the shared <code>useExecutionTransport</code> composable, so the component is pure markup.</li>
<li><code>wwwroot-src/src/composables/useExecutionTransport.ts</code> — the enable rules, the API-calling handlers and the F5F8 listener; the shared reset-in-flight flag lives here.</li>
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the Control Tree pane; its run header mounts the bar beside the run-state badge on the Execution page only, with the badge unshrinkable and the button strip the part that scrolls.</li>
<li><code>wwwroot-src/src/utils/executionStatusPresent.ts</code> — the badge's label and color per status.</li>
<li><code>Execution/ExecutionController.cs</code><code>POST /api/Execution/start | pause | resume | run-line | run-step | stop | reset</code>, and <code>GET /api/Execution/status</code>.</li> <li><code>Execution/ExecutionController.cs</code><code>POST /api/Execution/start | pause | resume | run-line | run-step | stop | reset</code>, and <code>GET /api/Execution/status</code>.</li>
<li><code>Execution/ExecutionStatusHub.cs</code> + <code>Execution/ExecutionStatusService.cs</code> — the status broadcast.</li> <li><code>Execution/ExecutionStatusHub.cs</code> + <code>Execution/ExecutionStatusService.cs</code> — the status broadcast.</li>
</ul> </ul>
@@ -87,7 +87,7 @@
<article data-uid="Anatomy-Execution"> <article data-uid="Anatomy-Execution">
<h1 id="execution-page">Execution Page</h1> <h1 id="execution-page">Execution Page</h1>
<p>The Execution page is the run cockpit: the simulation plays here, and every panel on it reads the run. It is the app's landing route — <code>/</code> redirects to <code>/execution</code> — and its Control Tree, the <strong>Execution</strong> root with <strong>Mission</strong> and <strong>Program</strong> beneath it, rides the <code>?tree=</code> query, so <code>/execution?tree=execution/mission</code> deep-links the Mission editor.</p> <p>The Execution page is the run cockpit: the simulation plays here, and every panel on it reads the run. It is the app's landing route — <code>/</code> redirects to <code>/execution</code> — and its Control Tree — two roots, <strong>Mission</strong> above <strong>Program</strong> rides the <code>?tree=</code> query, so <code>/execution?tree=execution/mission</code> deep-links the Mission editor.</p>
<div class="NOTE"> <div class="NOTE">
<h5>Note</h5> <h5>Note</h5>
<p>The app says <strong>Execution</strong> throughout: the route <code>/execution</code>, the REST endpoints (<code>/api/Execution/*</code>), the status hub (<code>/executionStatusHub</code>) and the stored layout (<code>UserConfig.ExecutionDivConfig</code>). The HiAPI engine keeps its own library vocabulary — <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> <small>(API)</small> and <a class="xref" href="../../api/Hi.Common.PacePlayer.html">PacePlayer</a> <small>(API)</small> — which is a different codebase's naming, not an inconsistency here.</p> <p>The app says <strong>Execution</strong> throughout: the route <code>/execution</code>, the REST endpoints (<code>/api/Execution/*</code>), the status hub (<code>/executionStatusHub</code>) and the stored layout (<code>UserConfig.ExecutionDivConfig</code>). The HiAPI engine keeps its own library vocabulary — <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> <small>(API)</small> and <a class="xref" href="../../api/Hi.Common.PacePlayer.html">PacePlayer</a> <small>(API)</small> — which is a different codebase's naming, not an inconsistency here.</p>
@@ -101,16 +101,16 @@
<h2 id="layout">Layout</h2> <h2 id="layout">Layout</h2>
<p>Four columns, left to right. The two dock dividers are pixel-sized, so dragging one moves only that dock's edge while the flexible middle absorbs the change.</p> <p>Four columns, left to right. The two dock dividers are pixel-sized, so dragging one moves only that dock's edge while the flexible middle absorbs the change.</p>
<ul> <ul>
<li><strong>Left dock</strong> — the Control Tree over the primary editor panel for the selected tree node. The <a href="execution-tool-bar.html">Execution Tool Bar</a> — the transport buttons — sits atop that panel and is shown for the Execution root and every node under it.</li> <li><strong>Left dock</strong> — the Control Tree over the primary editor panel for the selected tree node. The tree pane opens with a run header pinned above its rows: the <a href="execution-tool-bar.html">Execution Tool Bar</a> — the transport buttons — with the live status badge to its right. The editor panel below holds the editor alone.</li>
<li><strong>Main</strong> — the <a class="xref" href="../../technique/rendering/rendering-canvas.html">RenderingCanvas</a> over the <a class="xref" href="../shell/session-message-panel.html">Session Message Panel</a>, stacked as collapsible panels with a draggable divider between them. The canvas panel's header adopts the <a class="xref" href="../widget/renderingcanvas-tool-bar.html">RenderingCanvas Tool Bar</a> and the <a href="execution-extended-renderingcanvas-tool-bar.html">Execution Extended RenderingCanvas Tool Bar</a>.</li> <li><strong>Main</strong> — the <a class="xref" href="../../technique/rendering/rendering-canvas.html">RenderingCanvas</a> over the <a class="xref" href="../shell/session-message-panel.html">Session Message Panel</a>, stacked as collapsible panels with a draggable divider between them. The canvas panel's header adopts the <a class="xref" href="../widget/renderingcanvas-tool-bar.html">RenderingCanvas Tool Bar</a> and the <a href="execution-extended-renderingcanvas-tool-bar.html">Execution Extended RenderingCanvas Tool Bar</a>.</li>
<li><strong>Strip Charts</strong> — the strip-chart group bar over the three <a href="strip-charts.html">Strip Charts</a>: Availability Chart, Surface Roughness Chart and Color Index Time Chart.</li> <li><strong>Strip Charts</strong> — the strip-chart group bar over the three <a href="strip-charts.html">Strip Charts</a>: Availability Chart, Surface Roughness Chart and Color Index Time Chart.</li>
<li><strong>Step Info</strong><em>Sentence Syntax</em> as its own region (an NC sentence need not map to any machining step, so it is not a member of the step-based panels), then the Step Info group bar, then <a href="selected-step-info-panel.html">Step Properties</a>, <em>CWE</em> (cutterworkpiece engagement) and the four <a href="cycle-line-charts.html">Cycle-Line Charts</a>.</li> <li><strong>Step Info</strong><em>Sentence Syntax</em> as its own region (an NC sentence need not map to any machining step, so it is not a member of the step-based panels), then the Step Info group bar, then <a href="selected-step-info-panel.html">Step Properties</a>, <em>CWE</em> (cutterworkpiece engagement) and the four <a href="cycle-line-charts.html">Cycle-Line Charts</a>.</li>
</ul> </ul>
<p>The four columns are toggled from the app menu bar; the panels inside them collapse in place from their own expansion headers. The canvas stays mounted while collapsed so its rendering connection survives, and its engine is paused rather than torn down. The page itself also stays mounted while the user is on another route: the shell wraps the router view in a <code>keep-alive</code> keyed on the project epoch, so navigating away pauses the canvas but keeps the page — and its connection — alive until the loaded project changes.</p> <p>The four columns are toggled from the app menu bar; the panels inside them collapse in place from their own expansion headers. The canvas stays mounted while collapsed so its rendering connection survives, and its engine is paused rather than torn down. The page itself also stays mounted while the user is on another route: the shell wraps the router view in a <code>keep-alive</code> keyed on the project epoch, so navigating away pauses the canvas but keeps the page — and its connection — alive until the loaded project changes.</p>
<h2 id="control-tree">Control Tree</h2> <h2 id="control-tree">Control Tree</h2>
<p>The page hosts an <code>execution</code>-scoped Control Tree: an <strong>Execution</strong> root with the <strong>Mission</strong> branch above the <strong>Program</strong> branch. Selecting a node fills the primary editor pane below the tree, and the <a href="execution-tool-bar.html">Execution Tool Bar</a> is mounted on top of that pane whenever the selected id is <code>execution</code> or starts with <code>execution/</code> — so the transport stays reachable from every node of this tree.</p> <p>The page hosts an <code>execution</code>-scoped Control Tree with two roots and no wrapper node over them: the <strong>Mission</strong> branch above the <strong>Program</strong> branch. Node ids keep the <code>execution/</code> prefix (<code>execution/mission</code>, <code>execution/program/…</code>) because that first segment is the page-scope key — <code>?tree=</code> routing and the remembered last selection hang off it — not a parent row; a bare <code>?tree=execution</code> resolves to <code>execution/mission</code>, and a URL with no <code>?tree=</code> lands on the remembered selection or, failing that, on Mission. Selecting a node fills the primary editor pane below the tree; that pane holds nothing but the selected node's editor.</p>
<p><strong>Execution root</strong> is the cockpit's home: a short orientation panel, because the controls it would otherwise hold live where they act — the transport on the primary pane's header, the panel switches on each panel's own expansion header, the column switches on the nav bar. The live run state rides the tree itself: the Execution tree item carries a status badge fed by <code>/executionStatusHub</code>.</p> <p><strong>Run header.</strong> The tree pane opens, on this page only, with a row pinned above the tree scroller: the <a href="execution-tool-bar.html">Execution Tool Bar</a> — the page's sole transport, which therefore owns the F5F8 shortcuts — and, to its right, the status badge fed by <code>/executionStatusHub</code>. It sits inside the pane rather than on the dock's expansion header because that header is shared with General Setup, which renders neither piece. The button strip is the only shrinkable child, so narrowing the tree column scrolls the buttons away while the badge stays in view; the dock keeps the tree row mounted while collapsed, so the transport and its shortcuts survive a collapsed row. The other controls the cockpit needs live where they act — the panel switches on each panel's own expansion header, the column switches on the app menu bar.</p>
<p><strong>Mission</strong> (<code>execution/mission</code>) is the editable command list a run executes — the project's <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> <small>(API)</small>, always a list, with nested lists read as sub-trees. Its ItemType registry supplies the tree checkbox that decides whether a command runs. The branch root is the entry-list editor — Add Command over a drag-reorderable row list with up / down / duplicate / delete — each command entry gets a control bar over that kind's own editor, and each of the kind's remaining setting groups becomes a section child of the command node. Every command type has its own page under <a href="mission/index.html">Mission</a>.</p> <p><strong>Mission</strong> (<code>execution/mission</code>) is the editable command list a run executes — the project's <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> <small>(API)</small>, always a list, with nested lists read as sub-trees. Its ItemType registry supplies the tree checkbox that decides whether a command runs. Every row-level structural op lives on the tree rows, not in a panel: each command row carries a drag handle and — revealed on hover and on the selected row — move up / move down / duplicate / delete; every list row, the Mission root included, carries an always-visible <strong>+</strong> (Add Command) that opens the command catalog and inserts the pick right after that list's focused command (the last selected or last added), else at the list's tail. The one panel-side insert is the Program File editor's <a href="mission/NcFileCommand-panel.html#multi-pick-fan-out">multi-pick fan-out</a>: each extra pick becomes a new Program File command right after that command in its own list, and the panel reports the insert range to the host, which treats it as a structural op like any row op — the same busy gate, the same carry-over of index-based ids onto the new siblings, the same rebuild scoped to the owning list. Dropping a dragged row on another command row's edge reorders it within its list or relocates it into the target row's list; dropping on a List row's middle band or on the Mission root row appends it into that list. The host runs all five ops through one path — a busy gate that holds tree selection, the checkboxes and further drags read-only while an op is in flight; the open editor's dirty-switch gate, which can refuse the op: a Script Command with unsaved edits asks <strong>Save &amp; switch</strong> / <strong>Discard</strong> / <strong>Cancel</strong>, while an NC Code editor or a List title sends its pending save without asking, and either one answers no when the user cancels or the save does not land — a refused gate drops the op and toasts that the open editor keeps its unsaved edits, which is why a delete that was already confirmed can still leave its row in place; then the API call, a rebuild scoped to the list it rewrote (the nearest list above both, for a move across lists), then the selection. The selection moves only when it already rode on the acted-on row — that row, or a section or nested entry under it: it follows a moved command, lands on the clone of a duplicated one, and after a delete lands on the nearest surviving entry of that list or, once the list is empty, on the owning list row; a selection riding elsewhere stays on its own re-indexed row, and Add Command never moves it at all — only the Add focus moves, onto the new row, so a run of adds chains in order. The root's own panel is informational — what the tree cannot say: a no-project note while no project is loaded, otherwise the command count and, while it is zero, a prompt to click Add Command; the run-order hint closes it either way. A command node's panel is that kind's own editor (a List shows only its optional Title; its entries are its tree children), and each of the kind's remaining setting groups becomes a section child of the command node. Every command type has its own page under <a href="mission/index.html">Mission</a>.</p>
<p><strong>Program</strong> (<code>execution/program</code>) is the read-only inspection twin of Mission: one node per NC source file the session read, its passes and execution marks filled in from run data rather than typed in. Its nodes, its per-pass line and mark views, and the status changes that rebuild it are on <a href="program.html">Program Branch</a>.</p> <p><strong>Program</strong> (<code>execution/program</code>) is the read-only inspection twin of Mission: one node per NC source file the session read, its passes and execution marks filled in from run data rather than typed in. Its nodes, its per-pass line and mark views, and the status changes that rebuild it are on <a href="program.html">Program Branch</a>.</p>
<p>Selection and URL are synced two ways through the <code>tree</code> query argument: the URL's <code>?tree=</code> is adopted once the tree is built, and every selection change replaces it. A <code>?tree=</code> id belonging to another page's tree redirects to that page (<code>routeForTreeId</code>), and <code>/mission</code> lands on <code>/execution?tree=execution/mission</code>.</p> <p>Selection and URL are synced two ways through the <code>tree</code> query argument: the URL's <code>?tree=</code> is adopted once the tree is built, and every selection change replaces it. A <code>?tree=</code> id belonging to another page's tree redirects to that page (<code>routeForTreeId</code>), and <code>/mission</code> lands on <code>/execution?tree=execution/mission</code>.</p>
<h2 id="renderingcanvas-behavior">RenderingCanvas Behavior</h2> <h2 id="renderingcanvas-behavior">RenderingCanvas Behavior</h2>
@@ -129,18 +129,19 @@
<ul> <ul>
<li><code>wwwroot-src/src/pages/ExecutionPage.vue</code> — the routed page at <code>/execution</code>: the four columns, their pixel / ratio splitters, the panel-expansion stacks, and the <code>execution</code>-scoped Control Tree host it provides.</li> <li><code>wwwroot-src/src/pages/ExecutionPage.vue</code> — the routed page at <code>/execution</code>: the four columns, their pixel / ratio splitters, the panel-expansion stacks, and the <code>execution</code>-scoped Control Tree host it provides.</li>
<li><code>wwwroot-src/src/router/routes.ts</code> — the <code>/</code><code>execution</code> redirect, the <code>execution</code> route, and the <code>/mission</code> redirect to <code>/execution?tree=execution/mission</code>.</li> <li><code>wwwroot-src/src/router/routes.ts</code> — the <code>/</code><code>execution</code> redirect, the <code>execution</code> route, and the <code>/mission</code> redirect to <code>/execution?tree=execution/mission</code>.</li>
<li><code>wwwroot-src/src/router/treeRoutes.ts</code><code>routeForTreeId</code>, which lands a <code>?tree=</code> id on the page that owns that branch.</li> <li><code>wwwroot-src/src/router/treeRoutes.ts</code><code>migrateLegacyTreeId</code>, which folds legacy ids onto the current ones (a bare <code>execution</code> becomes <code>execution/mission</code>), and <code>routeForTreeId</code>, which runs that migration first and then lands a <code>?tree=</code> id on the page that owns its first segment.</li>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — the Control Tree state machine: <code>buildExecutionRoot()</code> builds the <code>execution</code> root holding <code>execution/mission</code> above <code>execution/program</code>, syncs <code>?tree=</code>, and re-reads the Program branch whenever the broadcast execution status changes.</li> <li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — the Control Tree state machine: <code>buildExecutionRoots()</code> builds the two roots, <code>execution/mission</code> above <code>execution/program</code>; <code>landingSelection()</code> picks the remembered selection or the first root; the <code>?tree=</code> sync; the Program branch re-read on every broadcast execution-status change; and the five mission row ops — add, drag move, step, duplicate, delete — through one <code>missionRowOp</code> helper that owns the busy gate, the dirty-switch gate (a refusal drops the op and toasts it), the scoped rebuild and the post-op selection.</li>
<li><code>wwwroot-src/src/components/controlTree/ControlTreeDock.vue</code> — the left dock: the Control Tree row over the primary editor row.</li> <li><code>wwwroot-src/src/components/controlTree/useMissionTreeDrag.ts</code> — the HTML5 drag-and-drop bookkeeping between Mission rows: the edge / into drop modes and the row indicator classes; the move itself is the host's.</li>
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree pane; carries the live execution-status badge on the Execution tree item.</li> <li><code>wwwroot-src/src/components/controlTree/ControlTreeDock.vue</code> — the left dock: the Control Tree row over the primary editor row, each kept mounted while collapsed; the tree row's expansion header is the same on both tree pages, so nothing run-specific rides it.</li>
<li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — the primary editor pane for the selected node; mounts the Execution Tool Bar on top whenever the selection is <code>execution</code> or a descendant.</li> <li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree pane; on the Execution page it pins the run header — the Execution Tool Bar and the live status badge — above the tree scroller, and renders the Mission rows' drag handle, the hover-revealed row ops and the Add Command <strong>+</strong> on every list row.</li>
<li><code>wwwroot-src/src/components/controlTree/ExecutionRootPanel.vue</code> — the editor panel of the Execution root node.</li> <li><code>wwwroot-src/src/components/controlTree/AddCommandDialog.vue</code> — the search-first command catalog the <strong>+</strong> opens, fed by <code>GET /api/Mission/command-catalog</code>; one pick per opening.</li>
<li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — the primary editor pane shared by both tree pages: it mounts the selected node's registry panel, or one of the three inline root panels it carries for General Setup's equipment roots (Machine Tool, Fixture, Workpiece — object management plus a summary), which no Execution node ever selects; here it shows the registry panel alone, and hands that panel's dirty-switch gate to the host.</li>
</ul> </ul>
<p>Mission branch:</p> <p>Mission branch:</p>
<ul> <ul>
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — the branch's ItemType registry and the per-command enable ticks.</li> <li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — the branch's ItemType registry and the per-command enable ticks.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — the entry-list editor of a list command, serving the branch root and every nested list.</li> <li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — the Mission root's informational panel: a no-project note while no project is loaded, otherwise the command count and a &ldquo;No commands yet&rdquo; prompt while it is zero, and the run-order hint in every state.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — the per-command editor host.</li> <li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — the per-command editor host; a List command shows only its optional Title.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionSectionPanel.vue</code> — one setting section of a command.</li> <li><code>wwwroot-src/src/components/controlTree/MissionSectionPanel.vue</code> — one setting section of a command.</li>
</ul> </ul>
<p>Program branch (see the dedicated anatomy page for details):</p> <p>Program branch (see the dedicated anatomy page for details):</p>
@@ -150,7 +151,7 @@
<p>Panels and canvas:</p> <p>Panels and canvas:</p>
<ul> <ul>
<li><code>wwwroot-src/src/components/RenderingCanvas.vue</code> — the browser canvas and its <code>/renderingHub</code> connection.</li> <li><code>wwwroot-src/src/components/RenderingCanvas.vue</code> — the browser canvas and its <code>/renderingHub</code> connection.</li>
<li><code>wwwroot-src/src/components/execution/ExecutionToolBar.vue</code> — the transport controls.</li> <li><code>wwwroot-src/src/components/execution/ExecutionToolBar.vue</code> — the transport controls; the page's one instance, mounted in the tree pane's run header, registers F5F8.</li>
<li><code>wwwroot-src/src/components/execution/ExecutionExtendedToolBar.vue</code> — the view and rendering-flag controls adopted onto the canvas panel's header.</li> <li><code>wwwroot-src/src/components/execution/ExecutionExtendedToolBar.vue</code> — the view and rendering-flag controls adopted onto the canvas panel's header.</li>
<li><code>wwwroot-src/src/components/execution/SelectedStepInfoPanel.vue</code> — Step Properties.</li> <li><code>wwwroot-src/src/components/execution/SelectedStepInfoPanel.vue</code> — Step Properties.</li>
<li><code>wwwroot-src/src/components/execution/StepVolumePanel.vue</code> — the CWE panel.</li> <li><code>wwwroot-src/src/components/execution/StepVolumePanel.vue</code> — the CWE panel.</li>
@@ -173,7 +174,7 @@
<p>Backends:</p> <p>Backends:</p>
<ul> <ul>
<li><code>Execution/ExecutionController.cs</code><code>POST /api/Execution/start | pause | resume | run-line | run-step | stop | reset</code>; <code>GET status</code>, <code>status/{connectionId}</code>, <code>project-status</code>, <code>selected-step-info</code> and <code>cl-strip-dots</code>; the canvas actions <code>initialize/{connectionId}</code> (binds the displayee and calls <code>SetViewToHomeView</code>) and <code>fit-view/{connectionId}</code>; and the <code>step-volume/{connectionId}</code> family behind the CWE panel.</li> <li><code>Execution/ExecutionController.cs</code><code>POST /api/Execution/start | pause | resume | run-line | run-step | stop | reset</code>; <code>GET status</code>, <code>status/{connectionId}</code>, <code>project-status</code>, <code>selected-step-info</code> and <code>cl-strip-dots</code>; the canvas actions <code>initialize/{connectionId}</code> (binds the displayee and calls <code>SetViewToHomeView</code>) and <code>fit-view/{connectionId}</code>; and the <code>step-volume/{connectionId}</code> family behind the CWE panel.</li>
<li><code>Execution/ExecutionStatusHub.cs</code> + <code>Execution/ExecutionStatusService.cs</code><code>/executionStatusHub</code>, the run-state broadcast that drives the transport and the tree badge.</li> <li><code>Execution/ExecutionStatusHub.cs</code> + <code>Execution/ExecutionStatusService.cs</code><code>/executionStatusHub</code>, the run-state broadcast that drives the transport and the run header's badge.</li>
<li><code>Execution/SessionSinkHub.cs</code> + <code>Execution/SessionSinkBroadcastService.cs</code> — one hub per message sink (<code>/shellMessageHub</code>, <code>/ncDiagnosticHub</code>, <code>/stepDiagnosticHub</code>, <code>/ncManipulationDiagnosticHub</code>), so a client subscribes to exactly the sink it wants.</li> <li><code>Execution/SessionSinkHub.cs</code> + <code>Execution/SessionSinkBroadcastService.cs</code> — one hub per message sink (<code>/shellMessageHub</code>, <code>/ncDiagnosticHub</code>, <code>/stepDiagnosticHub</code>, <code>/ncManipulationDiagnosticHub</code>), so a client subscribes to exactly the sink it wants.</li>
<li><code>Execution/SelectedStepInfoService.cs</code> — the selected-step payload. It has no hub of its own: the &ldquo;selection changed&rdquo; push rides <code>/clStripHub</code>.</li> <li><code>Execution/SelectedStepInfoService.cs</code> — the selected-step payload. It has no hub of its own: the &ldquo;selection changed&rdquo; push rides <code>/clStripHub</code>.</li>
<li><code>Execution/ClStripController.cs</code> + <code>Execution/ClStripHub.cs</code> + <code>Execution/ClStripBroadcastService.cs</code> — CL-strip range state and the zoom / pan / select / enter broadcasts.</li> <li><code>Execution/ClStripController.cs</code> + <code>Execution/ClStripHub.cs</code> + <code>Execution/ClStripBroadcastService.cs</code> — CL-strip range state and the zoom / pan / select / enter broadcasts.</li>
@@ -197,10 +198,10 @@
</ol> </ol>
</div> </div>
<h2 id="pages">Pages</h2> <h2 id="pages">Pages</h2>
<p>Ordered as the cockpit reads: the two tool bars across the top, the step column and the charts down <p>Ordered as the cockpit reads: the two tool bars — the transport pinned in the Control Tree pane's run header, the extended controls on the canvas panel's header — then the step column and the charts down
the side, the menus and dialogs they open, then the Control-Tree branch the page hosts.</p> the side, the menus and dialogs they open, then the two Control-Tree branches the page hosts.</p>
<ul> <ul>
<li><a href="execution-tool-bar.html">Execution Tool Bar</a> — The transport controls on the primary panel header, and the status they read</li> <li><a href="execution-tool-bar.html">Execution Tool Bar</a> — The transport controls in the Control Tree pane's run header, and the status they read</li>
<li><a href="execution-extended-renderingcanvas-tool-bar.html">Execution Extended RenderingCanvas Tool Bar</a> — The run-specific canvas controls: the CL strip, fit view and the Scene menu</li> <li><a href="execution-extended-renderingcanvas-tool-bar.html">Execution Extended RenderingCanvas Tool Bar</a> — The run-specific canvas controls: the CL strip, fit view and the Scene menu</li>
<li><a href="selected-step-info-panel.html">Selected-Step Info Panel</a> — The Step Properties panel in the Step Info column</li> <li><a href="selected-step-info-panel.html">Selected-Step Info Panel</a> — The Step Properties panel in the Step Info column</li>
<li><a href="strip-charts.html">Strip Charts</a> — The whole-program charts in the Strip Charts column</li> <li><a href="strip-charts.html">Strip Charts</a> — The whole-program charts in the Strip Charts column</li>
@@ -94,11 +94,12 @@ with everything nested under it — the wrapper yields nothing while its flag is
own command is always a list, so the <a class="xref" href="mission-root-panel.html">Mission branch root</a> <em>is</em> a own command is always a list, so the <a class="xref" href="mission-root-panel.html">Mission branch root</a> <em>is</em> a
list, and every nested one is the same shape one level down.</p> list, and every nested one is the same shape one level down.</p>
<p><code>List</code> is an ordinary catalog kind — category Flow — so a list is added the way any command is, and <p><code>List</code> is an ordinary catalog kind — category Flow — so a list is added the way any command is, and
adding one grows a sub-tree: the node's children are its own entries, and its panel embeds the same adding one grows a sub-tree: the node's children are its own entries, edited on their own Control
entry-list editor the branch root uses, scoped to the nested list.</p> Tree rows, and the list's own panel holds only its optional title, beneath the Disabled Caption
while the command is unticked.</p>
<p>This page covers what a list is, how its title reads, and what moving commands in and out of one <p>This page covers what a list is, how its title reads, and what moving commands in and out of one
costs. The entry-list editor itself — Add Command, the row actions, the three drag landings — is costs. The Control Tree row affordances every list shares — Add Command, the row buttons, the three
documented once, on <a class="xref" href="mission-root-panel.html">Mission Root Panel</a>.</p> drag landings — are documented once, on <a class="xref" href="mission-root-panel.html">Mission Root Panel</a>.</p>
<h2 id="key-models">Key Models</h2> <h2 id="key-models">Key Models</h2>
<ul> <ul>
<li><strong>Primary</strong>: <a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html">ListCommand</a><a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html#Hi_SessionCommands_ListCommand_Title">Title</a> <li><strong>Primary</strong>: <a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html">ListCommand</a><a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html#Hi_SessionCommands_ListCommand_Title">Title</a>
@@ -121,72 +122,92 @@ and <a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html#Hi_Se
<ul> <ul>
<li>List Entry Panel <li>List Entry Panel
<ul> <ul>
<li>Control Bar <li>Disabled Caption
<ul> <ul>
<li>Up / Down / Duplicate / Delete — labelled buttons for the operations that rewrite the <li>Present only while the command is disabled: skipped during play, still editable.</li>
<strong>parent</strong> list. Delete asks for confirmation in a dialog naming the command.</li>
<li>At the bar's left, a caption while the command is disabled: skipped during play, still
editable.</li>
</ul> </ul>
</li> </li>
<li>Title (optional) Input</li> <li>Title (optional) Input</li>
<li>Embedded Entry-List Editor
<ul>
<li>This list's own entries, scoped to the node's path.</li>
</ul> </ul>
</li> </li>
</ul> </ul>
</li> <p>Nothing else is on the panel. The list's entries are the node's children in the tree, and the
</ul> operations that rewrite the <strong>parent</strong> list — Move up, Move down, Duplicate, Delete — are the
<p>The Title input holds the <strong>raw</strong> title — empty when unset — while the label the row and the tree buttons on the list's own tree row, revealed on hover and on the selected row, and always shown on
show is composed by the engine: <code>List</code> when the title is blank, <code>List [title]</code> when it is not. A a touch or pen device, where there is no hover; Delete asks for confirmation in a dialog naming the
command. The <code>+</code> on that row adds a command into this list.</p>
<p>The Title input holds the <strong>raw</strong> title — empty when unset — while the label the tree row shows is
composed by the engine: <code>List</code> when the title is blank, <code>List [title]</code> when it is not. A
titled list still says what it is. A whitespace-only title counts as unset and is never written into titled list still says what it is. A whitespace-only title counts as unset and is never written into
the project file, so it cannot come back as a changed title on the next load.</p> the project file: it reloads as the empty title, and the label reads <code>List</code> both before and after,
<p>Keystrokes debounce into one title save. The pending save is flushed before anything that shifts the so a save cannot come back as a different label on the next load.</p>
entry paths — a structural operation, a duplicate, a selection change — and cancelled on delete and <p>Keystrokes debounce into one title save. The same dirty gate flushes the pending save — and awaits a
on unmount, so a late write cannot land on whichever command slid into the old path. Once it is save already on the wire — on two occasions: before every Control Tree row op, whose rebuild
saved the tree label refreshes in place rather than by rebuilding the branch, which would remount remounts the panel and can shift the entry paths, and before a selection change, which switches
the open editor mid-edit.</p> the panel away; unmount cancels it, so a late write cannot land on whichever command slides into
the old path. A flush whose save fails refuses the op or the switch, and a refused op says so in a
notice; a save that was already on the wire when the gate ran is only waited for — its failure
raises a notice of its own, and the op then proceeds regardless, leaving the title unsaved. Once
it is saved the tree label refreshes in place rather than by rebuilding the branch, which would
remount the open editor mid-edit.</p>
<p>The root list is the one list without a title input: the branch root reads <code>Mission</code>.</p> <p>The root list is the one list without a title input: the branch root reads <code>Mission</code>.</p>
<h2 id="enabling-and-what-a-disabled-list-skips">Enabling, and What a Disabled List Skips</h2> <h2 id="enabling-and-what-a-disabled-list-skips">Enabling, and What a Disabled List Skips</h2>
<p>The enable switch is the checkbox on the command's own Control Tree item, not a control in the entry <p>The enable switch is the checkbox on the command's own Control Tree row, not a control on its panel
row. It decides only whether the command <strong>runs</strong>: while it is clear the row and the tree node dim, and not one of the row's buttons. It decides only whether the command <strong>runs</strong>: while it is clear
and the editor stays open and fully editable. Unticking a list dims its whole sub-tree — the dim the tree row dims, and the editor stays open and fully editable. The checkboxes are read-only while
rides ancestor propagation in the tree while each nested entry keeps its own flag, which is exactly a mission row op, or a tick's own writes, are in flight. Unticking a list dims its whole sub-tree —
what the run does: a disabled entry is skipped with everything under it.</p> the dim rides ancestor propagation in the tree while each nested entry keeps its own flag, which is
exactly what the run does: a disabled entry is skipped with everything under it.</p>
<h2 id="paths">Paths</h2> <h2 id="paths">Paths</h2>
<p>A command node's key is its Mission API path — <code>&quot;0&quot;</code>, <code>&quot;1&quot;</code>, nested <code>&quot;0.2&quot;</code> for entry 2 inside the <p>A command node's key is its Mission API path — <code>&quot;0&quot;</code>, <code>&quot;1&quot;</code>, nested <code>&quot;0.2&quot;</code> for entry 2 inside the
list at index 0. Every structural change re-mints them: deleting entry 2 slides the next command list at index 0. Every structural change re-mints them: deleting entry 2 slides the next command
into path <code>&quot;2&quot;</code>. Each branch build therefore stamps its nodes, so the editor panel remounts onto the into path <code>&quot;2&quot;</code>. Each branch build therefore stamps its nodes, so the editor panel remounts onto the
new path instead of going on showing the command that used to live there.</p> new path instead of going on showing a command the path no longer names. The host carries its own
index-based ids — the expansion set, the Add focus and the selection — through each row op, so they
follow the rows rather than the slots: a selection riding on the acted-on row follows it — the
stepped or dropped row at its new index, or the clone a Duplicate makes — except on Delete, where
no row remains to follow: it lands on the nearest remaining entry of that list, the index clamped
to the new count, or on the owning list node once the list is empty, where Add Command waits. Any
other selection keeps its own re-indexed row.</p>
<h2 id="moving-commands-in-and-out">Moving Commands In and Out</h2> <h2 id="moving-commands-in-and-out">Moving Commands In and Out</h2>
<ul> <ul>
<li><strong>Into a list</strong> — drag a row onto the middle band of a list row; that row's outer quarters still <li><strong>Into a list</strong> — drag a command's tree row — the whole row drags; the handle icon at its left
reorder around it.</li> only marks it as draggable — onto the middle band of a list row; that row's outer quarters still
<li><strong>Out of a list</strong> — drag onto the drop-out zone of a nested list's editor, which is visible only reorder around it. The Mission root row is all middle band: a drop anywhere on it lands in the
while a row inside that editor is being dragged. The entry lands right after the list command root list. Either way the entry lands at that list's tail.</li>
itself in the owning list.</li> <li><strong>Out of a list</strong> — drop the row on the edge of a command row in another list, before or after it;
the lower quarter of the list command's own row lands the entry right after the list in the
owning list.</li>
</ul> </ul>
<p>Both are the same reparent call. The server resolves the source list and the target list to object <p>Which call a landing makes depends on whether the entry changes list, not on where the pointer
references before it mutates either, so the index shift the removal causes cannot misroute the sat. A landing that changes the list — the middle band of a list the entry is not in, or an edge in
insert, and it refuses to move a list into itself or into one of its own descendants. That guard another list — is the reparent call; a landing that keeps the list — an edge in the entry's own
compares identity rather than path-string prefixes, because <code>&quot;02&quot;</code>, <code>&quot;+2&quot;</code> and <code>&quot; 2&quot;</code> all parse to list, or the middle band of the list row (the Mission root row included) that already holds it,
index 2.</p> which sends it to the tail — is the reorder call, sent as the list's whole new order. The server
resolves the source list and the target list to object references before it mutates either, so the
index shift the removal causes cannot misroute the insert, and it refuses to move a list into itself
or into one of its own descendants. That guard compares identity rather than path-string prefixes,
because <code>&quot;02&quot;</code>, <code>&quot;+2&quot;</code> and <code>&quot; 2&quot;</code> all parse to index 2.</p>
<p>Two more properties of a list follow from the same API:</p> <p>Two more properties of a list follow from the same API:</p>
<ul> <ul>
<li><strong>A new command lands at the end</strong> of the list it was added to, root or nested. Nothing is pinned; <li><strong>A new command lands right after the focused command</strong> when that command is a direct entry of
the order is entirely the user's, changed with the row's up / down buttons or by dragging.</li> the list the <code>+</code> belongs to, root or nested, and at that list's tail otherwise. The focus is one
for the whole Mission tree — the last selected or last added command, whichever list it sits in
— so each list row's <code>+</code>, scoped to its own list, ignores a focus that lies in another list.
Nothing is pinned; the order is entirely the user's, changed with the row's Move up / Move down
buttons or by dragging.</li>
<li><strong>Duplicate is a deep copy.</strong> The entry is cloned through the same XML round-trip the project file <li><strong>Duplicate is a deep copy.</strong> The entry is cloned through the same XML round-trip the project file
uses, so a nested list copies with its whole sub-tree, and the clone lands right after the source.</li> uses, so a nested list copies with its whole sub-tree, and the clone lands right after the source.</li>
</ul> </ul>
<p>Dragging serves rearrangement only: a drag carrying text or files is ignored, because the row's drag <p>Dragging serves rearrangement only: a row accepts a drop only while a mission row is being dragged,
handling returns as soon as the drag did not start on a row. To bring several program files in at so a drag carrying text or files keeps the browser's no-drop cursor. To bring several program files
once, open a <a class="xref" href="NcFileCommand-panel.html">Program File</a> command's picker and pick them in at once, open a <a class="xref" href="NcFileCommand-panel.html">Program File</a> command's picker and pick them
together — the first pick lands on that command and each further pick becomes another Program File together — the first pick lands on that command and each further pick becomes another Program File
command right after it, in pick order, inside the same list at any depth.</p> command right after it, in pick order, inside the same list at any depth.</p>
<h2 id="which-commands-a-list-can-hold">Which Commands a List Can Hold</h2> <h2 id="which-commands-a-list-can-hold">Which Commands a List Can Hold</h2>
<p>The addable set is the server's command catalog: every engine command carrying <code>[CommandCatalog]</code>, <p>The addable set is the server's command catalog: every engine command carrying <code>[CommandCatalog]</code>,
reflected into the picker Add Command opens, which searches by display label, kind key and alias. reflected into the picker Add Command opens, which searches by display label, kind key and alias
and takes one pick per opening.
<code>List</code> is one of those commands, which is what makes nesting an ordinary act rather than a special <code>List</code> is one of those commands, which is what makes nesting an ordinary act rather than a special
case. The frontend contributes an icon per kind, and its own label where it has one; the server case. The frontend contributes an icon per kind, and its own label where it has one; the server
supplies the localized label otherwise, so a newly attributed engine command becomes addable with no supplies the localized label otherwise, so a newly attributed engine command becomes addable with no
@@ -196,50 +217,74 @@ creation. General Config is the one such command with an editor of its own: it i
settings bundle, so a project file storing one loads as the individual setting commands it stands settings bundle, so a project file storing one loads as the individual setting commands it stands
for and saving never writes the bundle back — editable when a project still constructs one through for and saving never writes the bundle back — editable when a project still constructs one through
the API, and absent from the catalog.</p> the API, and absent from the catalog.</p>
<p>Selecting an entry row selects that command's tree node, and the command's editor opens on that <p>Selecting a command's tree row opens that command's editor on its node — the kind's own panel when
node — the kind's own panel when one exists, otherwise a generic editor built from the scalar fields one exists, otherwise a generic editor built from the scalar fields the command declares. Selection
the command declares. Selection is one row at a time: there is no multi-selection here, and every is one row at a time: there is no multi-selection here, and every row button acts on the row that
action acts on the row that carries it. Because the server composes every entry label, a command carries it, whether or not that row is the selected one. Because the server composes every entry
carrying no title of its own still reads as its localized display name.</p> label, a command carrying no title of its own still reads as its localized display name.</p>
<p>There is no second column inside this editor: the entry list is a single column in the tree's editor <p>A list's entries never appear in the editor pane: they are the node's children in the Control Tree,
pane. The draggable vertical divider on screen belongs to the Execution page, between the left dock and the pane below the tree shows only the selected command's panel. The left-most of the Execution
— the Control Tree over the editor panel — and the central area; a second divider inside that dock page's three draggable vertical dividers sits between the left dock — the Control Tree over the
drags the height between the tree and the editor.</p> editor panel — and the central area; the divider inside that dock drags the height between the tree
and the editor.</p>
<h2 id="source-code-path">Source Code Path</h2> <h2 id="source-code-path">Source Code Path</h2>
<p>See <a class="xref" href="../../index.html">HiNC App Anatomy</a> for git repository links.</p> <p>See <a class="xref" href="../../index.html">HiNC App Anatomy</a> for git repository links.</p>
<h3 id="web-application">Web Application</h3> <h3 id="web-application">Web Application</h3>
<ul> <ul>
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — a list entry's panel: the <li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — a list entry's panel: the
control bar, the optional Title input with its debounce / flush / cancel discipline, the embedded disabled caption, the optional Title input with its debounce / flush / cancel discipline and the
entry-list editor of a list entry, and the bespoke-or-generic editor choice for every other kind.</li> dirty gate it answers to the host, and the bespoke-or-generic editor choice for every other kind.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — the entry-list editor embedded <li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree rows: the draggable row
here and serving the branch root: the rows and their actions, the three drag landings, and the with its handle icon, the Move up / Move down / Duplicate / Delete buttons on every command row
drop-out zone shown only during a drag inside a nested editor.</li> (revealed on hover and on the selected row, always shown on a touch or pen device), the <code>+</code>
on every list row (the Mission root included) and the Add Command dialog it opens, and the
drop-indicator styles.</li>
<li><code>wwwroot-src/src/components/controlTree/useMissionTreeDrag.ts</code> — the drag bookkeeping between
mission rows: which rows drag, which receive, and the before / after / into landing read from the
pointer's position on the row.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — the branch root's panel, the one
without a title input: the command count and the run-order hint.</li>
<li><code>wwwroot-src/src/components/controlTree/AddCommandDialog.vue</code> — the search-first catalog picker;
one pick per opening.</li>
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — the child builders that recurse <li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — the child builders that recurse
into a list's own entries, the per-kind editor override map, the kind and category icons, and the into a list's own entries, the per-kind editor override map, and the per-build stamp that forces
per-build stamp that forces the panel remount.</li> the panel remount.</li>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — which nodes show a checkbox, the <li><code>wwwroot-src/src/components/controlTree/missionKindIcons.ts</code> — the kind and category icons the
dim that flows down a disabled command's sub-tree, the enable write, and the in-place label picker shows.</li>
refresh after a title edit or a language switch.</li> <li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — the five row ops — add, drag
move, step, duplicate, delete — through one <code>missionRowOp</code> helper (the busy gate, the open panel's
dirty flush, the API call, the scoped rebuild, the post-op selection), the insert-after-focus rule
scoped to the <code>+</code>'s own list, and the index translation that carries the expansion set, the Add
focus and the selection through each op; which nodes show a checkbox, the dim that flows down a
disabled command's sub-tree, the enable write, and the in-place label refresh after a title edit
or a language switch.</li>
<li><code>wwwroot-src/src/api/mission.ts</code> — the typed wrapper over the Mission API and the path convention <li><code>wwwroot-src/src/api/mission.ts</code> — the typed wrapper over the Mission API and the path convention
(<code>root</code> or empty = the root list, <code>0.2</code> = a nested entry).</li> (<code>root</code> or empty = the root list, <code>0.2</code> = a nested entry); <code>addEntry</code> takes the optional insert
index and resolves to the new entry's path.</li>
<li><code>wwwroot-src/src/components/mission/GenericCommandPanel.vue</code> — the editor a catalog kind gets when <li><code>wwwroot-src/src/components/mission/GenericCommandPanel.vue</code> — the editor a catalog kind gets when
it ships no bespoke panel, built from the command's declared scalar fields.</li> it ships no bespoke panel, built from the command's declared scalar fields.</li>
<li><code>wwwroot-src/src/components/mission/NcFileCommandPanel.vue</code> — the multi-pick file dialog: the <li><code>wwwroot-src/src/components/mission/NcFileCommandPanel.vue</code> — the multi-pick file dialog: the
first pick lands on the command, each further pick becomes another Program File command right first pick lands on the command, each further pick becomes another Program File command right
after it.</li> after it.</li>
<li><code>wwwroot-src/src/pages/ExecutionPage.vue</code> — the page-level splitter between the left dock and the <li><code>wwwroot-src/src/pages/ExecutionPage.vue</code> — the page-level splitters; the left-most parts the left
central area.</li> dock from the central area.</li>
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the <code>tree.mission.*</code> strings: the kind names, the drop-out <li><code>wwwroot-src/src/components/controlTree/ControlTreeDock.vue</code> — the left dock's two rows and the
zone, the run-order hint, the disabled hint and the operation labels.</li> height divider between the tree and the editor.</li>
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the <code>tree.mission.*</code> strings: the kind names, the run-order
hint that names the row affordances, the disabled hint, the cancelled-op notice and the operation
labels.</li>
<li><code>wwwroot-src/src/i18n/en/common.ts</code> — the row buttons' titles and the Title (optional) label.</li>
<li><code>wwwroot-src/src/i18n/en/dialog.ts</code> — the Delete Command confirmation.</li>
<li><code>Missions/MissionController.cs</code> — the entry lifecycle: <code>GET list-command/entries</code> (recursive), <li><code>Missions/MissionController.cs</code> — the entry lifecycle: <code>GET list-command/entries</code> (recursive),
<code>POST list-command/entries</code> and <code>POST list-command/entries/{path}</code> (append at the tail of the root <code>POST list-command/entries</code> and <code>POST list-command/entries/{path}</code> (into the root or a nested
or of a nested list), <code>DELETE list-command/entries/{path}</code>, list, at an optional <code>insertIndex</code> clamped to the list and otherwise at its tail, answering the
<code>POST list-command/entries/{path}/move</code>, <code>PUT list-command/reorder</code>, new entry's index and path), <code>DELETE list-command/entries/{path}</code>,
<code>POST list-command/entries/{path}/duplicate</code> (the XML-round-trip deep clone), <code>POST list-command/entries/{path}/move</code> (the row's Move up / Move down), <code>PUT list-command/reorder</code>
<code>POST list-command/entries/{path}/reparent</code> (drag-into-list and drop-out, with the self/descendant (a drop that keeps the owning list), <code>POST list-command/entries/{path}/duplicate</code> (the
guard), <code>PUT commands/{path}/listcommand</code> for the title, and <code>PUT commands/{path}/enabled</code> for an XML-round-trip deep clone), <code>POST list-command/entries/{path}/reparent</code> (a drop that changes the
entry's enable flag. <code>GetCommandTitle</code> composes every entry label the tree shows.</li> owning list, with the self/descendant guard), <code>PUT commands/{path}/listcommand</code> for the title, and
<code>PUT commands/{path}/enabled</code> for an entry's enable flag. <code>GetCommandTitle</code> composes every entry
label the tree shows.</li>
<li><code>Missions/MissionCommandCatalog.cs</code> — reflects the <code>[CommandCatalog]</code> commands into the addable <li><code>Missions/MissionCommandCatalog.cs</code> — reflects the <code>[CommandCatalog]</code> commands into the addable
set and constructs the picked kind.</li> set and constructs the picked kind.</li>
</ul> </ul>
@@ -260,7 +305,7 @@ a loaded project expands a stored one into the split setting commands.</li>
</ul> </ul>
<h2 id="see-also">See Also</h2> <h2 id="see-also">See Also</h2>
<ul> <ul>
<li><a class="xref" href="mission-root-panel.html">Mission Root Panel</a> — the entry-list editor this command embeds, documented once</li> <li><a class="xref" href="mission-root-panel.html">Mission Root Panel</a> — the branch root, and the Control Tree row affordances every list shares, documented once</li>
<li><a href="../../../manual/run/building-a-mission.html">Building a Mission</a> — the task this command serves: grouping a mission and moving entries between groups</li> <li><a href="../../../manual/run/building-a-mission.html">Building a Mission</a> — the task this command serves: grouping a mission and moving entries between groups</li>
<li><a href="index.html">Mission</a> — the rest of the command panels</li> <li><a href="index.html">Mission</a> — the rest of the command panels</li>
</ul> </ul>
@@ -100,9 +100,13 @@ program name the run log shows, which is why the model defaults it to the comman
<code>NC Code</code>, rather than to an empty string. It is also the detail the mission row brackets: the row <code>NC Code</code>, rather than to an empty string. It is also the detail the mission row brackets: the row
reads <code>NC Code</code> while the title is empty or still that default, and <code>NC Code [title]</code> once it says reads <code>NC Code</code> while the title is empty or still that default, and <code>NC Code [title]</code> once it says
something else.</p> something else.</p>
<p>The panel renders on the command's own node in the Mission branch of the Execution page's Control <p>The panel renders on the command's own node under the Mission root of the Execution page's Control
Tree, below the move / duplicate / delete control bar. A single-purpose kind like this one embeds Tree. The editor pane holds nothing but the editor: the command's move up / move down / duplicate /
its whole editor on that node rather than growing section child nodes.</p> delete buttons and its drag handle sit on its tree row, and the Add Command <code>+</code> sits on the row of
the list that holds it. A single-purpose kind like this one embeds its whole editor on that node
rather than growing section child nodes. Its tree checkbox only decides whether the run plays the
command; a disabled command is skipped during play — a caption above the title says so — and its
editor stays usable.</p>
<h2 id="layout">Layout</h2> <h2 id="layout">Layout</h2>
<ul> <ul>
<li>NcCodeCommand Panel <li>NcCodeCommand Panel
@@ -124,7 +128,7 @@ folder is the <a class="xref" href="script-command-panel.html">Script command</a
CodeMirror with a C# grammar, this one ships a text area.</li> CodeMirror with a C# grammar, this one ships a text area.</li>
</ul> </ul>
</li> </li>
<li>Stats and Actions Row (web) <li>Stats and Actions Row
<ul> <ul>
<li>Line count and character count, both recomputed as the text changes.</li> <li>Line count and character count, both recomputed as the text changes.</li>
<li>Trim Blank Lines Button — trims every line and drops the ones left empty, then saves at once.</li> <li>Trim Blank Lines Button — trims every line and drops the ones left empty, then saves at once.</li>
@@ -137,11 +141,32 @@ CodeMirror with a C# grammar, this one ships a text area.</li>
</ul> </ul>
<h2 id="saving">Saving</h2> <h2 id="saving">Saving</h2>
<p>Typing in either field schedules one save 400 ms after the last keystroke, so a burst of typing <p>Typing in either field schedules one save 400 ms after the last keystroke, so a burst of typing
costs one request instead of one per character. Trim Blank Lines and Clear save immediately rather costs one request instead of one per character. The title and the NC text share that timer, and the
than through that timer.</p> save carries every field edited since the last one. Trim Blank Lines and Clear save immediately
rather than through that timer.</p>
<p>The write is a single patch endpoint carrying the NC text and the title. Each field is applied only <p>The write is a single patch endpoint carrying the NC text and the title. Each field is applied only
when the body actually carries it, which is why the client sends the field it changed and a null for when the body actually carries it, which is why the client sends the fields it edited and a null
the one it did not.</p> for the rest. The endpoint carries no content hash, so nothing on the server refuses a save that
arrives late. After each save the tree relabels the command's node in place rather than rebuilding
the branch, which would remount the editor mid-edit.</p>
<p>The panel snapshots its command path at mount, and every load and save targets that snapshot
rather than the live selection. The path is an index-based entry path which every structural op
re-points, so the panel hands the Control Tree host a switch gate that runs before the selection
moves off the command and before every mission row op — move, duplicate, delete, drag, Add Command
— wherever in the tree that op acts: the gate first lets a save already on the wire land, then
sends the edit still waiting in the timer while the path is still the command's own. The gate is
there because an op rebuilds the list it rewrites — a drag between two lists rebuilds the nearest
list above both — and that rebuild re-mints the build stamp of every node under the rebuilt list.
Only one command editor is ever mounted, the selected node's, and its mount key carries that stamp,
so the editor remounts when its command sits inside the rebuilt list; the host does not ask whether
it does before running the gate — an op in a list that does not hold this command leaves the
editor mounted, and its staged edit is flushed all the same. A save that fails refuses the op, and
the host drops it with a notice.
Unmount cancels the timer instead of flushing it, so no save from a retired instance can land on
whichever command has slid into its path. Selection and the tick checkboxes are read-only while a
row op is in flight, and equally while a tick's own PUTs are on the wire: the host holds one busy
gate for both, so an enable toggle refuses a selection change and ignores further ticks until its
writes have landed, exactly as a row op does.</p>
<p>NC text is not validated while it is edited: there is no parse at edit time and no error surface on <p>NC text is not validated while it is edited: there is no parse at edit time and no error surface on
the panel — the server stores whatever string arrives. Errors surface when the mission plays the the panel — the server stores whatever string arrives. Errors surface when the mission plays the
text.</p> text.</p>
@@ -152,15 +177,35 @@ text.</p>
<ul> <ul>
<li><code>wwwroot-src/src/components/mission/NcCodeCommandPanel.vue</code> — this panel: the Title input, the <li><code>wwwroot-src/src/components/mission/NcCodeCommandPanel.vue</code> — this panel: the Title input, the
18-row monospace text area, the 400 ms debounced saves, the live line and character stats, Trim 18-row monospace text area, the 400 ms debounced saves, the live line and character stats, Trim
Blank Lines, and Clear behind a confirm dialog.</li> Blank Lines, and Clear behind a confirm dialog; the path snapshot taken at mount, the switch gate
that waits for a save on the wire and then drains the timer, and the unmount that cancels rather
than flushes.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — the command node's
slave panel: mounts this editor on the entry path, forwards its switch gate to the host, and
shows the disabled caption above the title.</li>
<li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — mounts the one editor pane, the
selected node's, under a key that carries the node's build stamp; a rebuild that re-mints the
stamp remounts it.</li>
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree rows: the drag handle
and the move / duplicate / delete buttons on the command's row, and the Add Command <code>+</code> on the
row of its list.</li>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — funnels every selection change
and every mission row op through the active panel's switch gate; holds the one busy gate that
keeps selection and the tick checkboxes read-only while a row op, or a tick's own PUTs, are in
flight; a refused gate drops the op with a notice, and a save relabels the command's node in
place.</li>
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — maps the <code>nccode</code> kind to this <li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — maps the <code>nccode</code> kind to this
panel, and states the rule it belongs to: a single-purpose kind embeds its whole editor on the panel, and states the rule it belongs to: a single-purpose kind embeds its whole editor on the
command node.</li> command node; mints the per-build stamp every command node under a rebuilt list carries.</li>
<li><code>wwwroot-src/src/api/mission.ts</code><code>loadNcCode</code> and <code>setNcCode</code>, and the command shape the panel <li><code>wwwroot-src/src/api/mission.ts</code><code>loadNcCode</code> and <code>setNcCode</code>, and the command shape the panel
edits (NC code plus title).</li> edits (NC code plus title).</li>
<li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the panel's wording: the NC Code label, the character <li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the panel's wording: the NC Code label, the character
count, Trim Blank Lines, and the line count it shares with the other panels.</li> count, Trim Blank Lines, and the line count it shares with the other panels.</li>
<li><code>wwwroot-src/src/i18n/en/common.ts</code> — the shared strings the panel borrows: the &ldquo;Title
(optional)&rdquo; label on the Title Field and the Clear button's label.</li>
<li><code>wwwroot-src/src/i18n/en/dialog.ts</code> — the Clear confirmation's title and message.</li> <li><code>wwwroot-src/src/i18n/en/dialog.ts</code> — the Clear confirmation's title and message.</li>
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the disabled caption and the notice a refused gate raises on
a row op.</li>
<li><code>Missions/MissionController.cs</code> — the single patch PUT for this command, whose NC-code and title <li><code>Missions/MissionController.cs</code> — the single patch PUT for this command, whose NC-code and title
fields are each applied when the body carries them, and the command-snapshot arm that returns both fields are each applied when the body carries them, and the command-snapshot arm that returns both
back to the panel.</li> back to the panel.</li>
@@ -178,9 +223,9 @@ how this command's NC text persists with the project.</li>
</ul> </ul>
<h2 id="see-also">See Also</h2> <h2 id="see-also">See Also</h2>
<ul> <ul>
<li><a class="xref" href="NcFileCommand-panel.html">NcFileCommand Panel</a> — the other Program command: a path to a file instead of text stored in the project</li> <li><a class="xref" href="NcFileCommand-panel.html">NcFileCommand Panel</a> — the other NC program command among the three kinds the Program catalog category holds (Program File, NC Code, Script): a path to a file instead of text stored in the project</li>
<li><a class="xref" href="script-command-panel.html">Script Command Panel</a> — the rich editor this folder does have, and why this command ships a plain text area instead</li> <li><a class="xref" href="script-command-panel.html">Script Command Panel</a> — the rich editor this folder does have, and why this command ships a plain text area instead</li>
<li><a href="../../../manual/run/playing-a-program.html">Playing a Program</a> — the task these two commands serve</li> <li><a href="../../../manual/run/playing-a-program.html">Playing a Program</a> — the task the two NC program commands, Program File and NC Code, serve; the Script command has its own manual page</li>
<li><a href="index.html">Mission</a> — the rest of the command panels</li> <li><a href="index.html">Mission</a> — the rest of the command panels</li>
</ul> </ul>
@@ -99,9 +99,13 @@ command: at play time <a class="xref" href="../../../api/Hi.MachiningProcs.Sessi
together with the project's own base directory to the local project service, and that is where a together with the project's own base directory to the local project service, and that is where a
relative path acquires its root; the convention behind it is the relative path acquires its root; the convention behind it is the
<a class="xref" href="../../conventions/gui-file-path-assignment.html">Load Pattern</a>.</p> <a class="xref" href="../../conventions/gui-file-path-assignment.html">Load Pattern</a>.</p>
<p>The panel renders on the command's own node in the Mission branch of the Execution page's Control <p>The panel renders on the command's own node under the Mission root of the Execution page's Control
Tree, below the move / duplicate / delete control bar. This command has no title of its own, so the Tree. The editor pane holds the editor and, while the command's tree checkbox is off, a one-line
row and tree label read <code>Program File [path]</code>, the path being the detail the label brackets.</p> disabled hint above it — nothing structural: the command's move up / move down / duplicate / delete
buttons and its drag handle sit on its tree row, and the Add Command <code>+</code> sits on the row of the
list that holds it. This command has no editable Title field — unlike NC Code, Script and List —
so its tree row label is composed from the path alone: <code>Program File [path]</code>, the path being the
detail the label brackets.</p>
<div class="NOTE"> <div class="NOTE">
<h5>Note</h5> <h5>Note</h5>
<p>The GUI labels this command &ldquo;Program File&rdquo;: it plays NC, CL (CLSF) and CSV files — the runner is <p>The GUI labels this command &ldquo;Program File&rdquo;: it plays NC, CL (CLSF) and CSV files — the runner is
@@ -178,11 +182,17 @@ browser to preserve. It is the backstop for a brand extension the NC group does
Auto routes to the CL and CSV runners, and everything else falls through to brand NC.</p> Auto routes to the CL and CSV runners, and everything else falls through to brand NC.</p>
<h2 id="multi-pick-fan-out">Multi-Pick Fan-Out</h2> <h2 id="multi-pick-fan-out">Multi-Pick Fan-Out</h2>
<p>The dialog is multi-select, and this is the one command editor that grows the mission. The first <p>The dialog is multi-select, and this is the one command editor that grows the mission. The first
picked file lands on this command. Each further pick becomes a <strong>new</strong> Program File command, added picked file lands on this command. Each further pick becomes a <strong>new</strong> Program File command,
to the list this command sits in and moved into place directly after it, in pick order — the same inserted into the list this command sits in at the index directly after it, in pick order — one
list, so a command inside a nested list fans out inside that nested list. The panel then reports a insert per pick, each at the next index, and the same list, so a command inside a nested list fans
structure change, which rebuilds the owning list's branch around the new rows and leaves the out inside that nested list. The panel then reports the insert range — the first new index and
selection on this command.</p> the count — and the command's slave panel scopes it to the owning list and names this command as
the selection. The Control Tree host takes that insert on its structure-changed path, which shares
two things with its own row ops — it holds the busy gate for the rebuild (a change arriving while
another op is in flight is not rebuilt) and carries the index-based ids (the expansion set and the
Add focus) over the new siblings — and not the third: the open panel's dirty gate, which every
row op runs first, is not part of this path. It then rebuilds the owning list's branch around the
new rows and leaves the selection on this command, whose own index is unchanged.</p>
<h2 id="where-the-program-text-is-edited">Where the Program Text Is Edited</h2> <h2 id="where-the-program-text-is-edited">Where the Program Text Is Edited</h2>
<p>The command stores a path, and the panel does not edit the file. It assigns the path, picks the <p>The command stores a path, and the panel does not edit the file. It assigns the path, picks the
runner, reports what the server knows about the file, and previews its first 100 lines read-only. runner, reports what the server knows about the file, and previews its first 100 lines read-only.
@@ -203,14 +213,27 @@ command stores.</li>
from; an empty extension list means all files.</li> from; an empty extension list means all files.</li>
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — maps the <code>ncfile</code> kind to this <li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — maps the <code>ncfile</code> kind to this
panel. A kind absent from that map is served by the generic field editor instead.</li> panel. A kind absent from that map is served by the generic field editor instead.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — the command node's
slave panel: mounts this editor on the entry path, and re-scopes the fan-out's structure change
to the owning list, with the insert range and this command as the selection.</li>
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree rows: the drag handle
and the move / duplicate / delete buttons on the command's row, and the Add Command <code>+</code> on the
row of its list.</li>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — takes the fan-out's insert on
its structure-changed path: the busy gate held for the rebuild, the index-based ids carried over
the new siblings (the two guarantees shared with the row ops; the dirty gate is not one of them),
the rebuild scoped to the owning list, and the selection the payload names.</li>
<li><code>wwwroot-src/src/api/mission.ts</code><code>loadNcFile</code>, <code>setNcFilePath</code>, <code>setNcFileNcKind</code>, <li><code>wwwroot-src/src/api/mission.ts</code><code>loadNcFile</code>, <code>setNcFilePath</code>, <code>setNcFileNcKind</code>,
<code>getNcFileInfo</code> and <code>previewNcFile</code>, plus the kind union and the file-info shape.</li> <code>getNcFileInfo</code> and <code>previewNcFile</code>, plus the kind union and the file-info shape; <code>addEntry</code>,
which the fan-out calls with the insert index and which answers the new entry's path.</li>
<li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the panel's wording: the path hint, the Play As hint, the <li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the panel's wording: the path hint, the Play As hint, the
four filter labels, the banner's found and not-found lines, and the preview titles.</li> four filter labels, the banner's found and not-found lines, and the preview titles.</li>
<li><code>Missions/MissionController.cs</code> — four endpoints serve this command: a PUT for the path, a PUT for <li><code>Missions/MissionController.cs</code> — four endpoints serve this command: a PUT for the path, a PUT for
the NC kind, and the two server-side reads behind the banner and the preview (both POSTs, both the NC kind, and the two server-side reads behind the banner and the preview (both POSTs, both
resolving a relative path against the project folder). The command-snapshot builder emits the file resolving a relative path against the project folder). The fan-out's extra picks go through the
path and the NC kind for this kind of command.</li> list-entry POST, which lands the new entry at the requested insert index — clamped to the list,
the tail when none is given — and answers its index and dotted path. The command-snapshot builder
emits the file path and the NC kind for this kind of command.</li>
</ul> </ul>
<h3 id="hiapi-engine">HiAPI Engine</h3> <h3 id="hiapi-engine">HiAPI Engine</h3>
<ul> <ul>
@@ -90,17 +90,24 @@
<p>The Mission branch root of the <a class="xref" href="../index.html">Execution page</a>'s Control Tree: route <p>The Mission branch root of the <a class="xref" href="../index.html">Execution page</a>'s Control Tree: route
<code>/execution</code>, Control-Tree path <code>execution/mission</code>, panel <code>MissionRootPanel.vue</code>. <code>/mission</code> <code>/execution</code>, Control-Tree path <code>execution/mission</code>, panel <code>MissionRootPanel.vue</code>. <code>/mission</code>
resolves to the same place — it redirects onto <code>/execution?tree=execution/mission</code>.</p> resolves to the same place — it redirects onto <code>/execution?tree=execution/mission</code>.</p>
<p>The panel edits one list of commands: the mission's own command, which is always a <p>The node roots one list of commands: the mission's own command, which is always a
<a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html">ListCommand</a>. The branch root is therefore a list editor — Add Command, the <a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html">ListCommand</a>. Its entries are the node's tree children, in run order, and
entries in run order, and the operations that rewrite the list. Editing a command is not this the row operations that rewrite the list — Add Command, drag, move up, move down, duplicate, delete —
panel's job: clicking a row selects that command's tree node, and the command's own editor renders live on the Control Tree rows and run in the tree host; no panel carries a second copy of them. The
on that node's panel.</p> one panel-side insert is the Program File editor's multi-pick: picking several files at once keeps
the first on that command and adds one Program File command per further file right after it, in its
own list, then hands the host the inserted range so the same busy gate and id translation cover the
rebuild. The root's own panel is informational: the command count and the run-order hint. Editing a
command is not this node's job either: selecting a command row opens that command's own editor on
its node's panel.</p>
<p>Command nodes are addressed by index-derived tree ids and by dotted API paths (<code>&quot;0&quot;</code>, <code>&quot;1&quot;</code>, nested <p>Command nodes are addressed by index-derived tree ids and by dotted API paths (<code>&quot;0&quot;</code>, <code>&quot;1&quot;</code>, nested
<code>&quot;0.2&quot;</code>). A command node id extends its parent's, so a root entry is <code>execution/mission/{index}</code> and <code>&quot;0.2&quot;</code>). A command node id extends its parent's, so a root entry is <code>execution/mission/{index}</code> and
an entry inside a nested list is <code>execution/mission/{index}/{index}</code>; a command's section children an entry inside a nested list is <code>execution/mission/{index}/{index}</code>; a command's section children
extend it once more, as <code>execution/mission/{index}/{id}</code> keyed on the section. Both forms shift on extend it once more, as <code>execution/mission/{index}/{id}</code> keyed on the section. Both forms shift on
every structural change — deleting entry 2 slides the next command into path <code>&quot;2&quot;</code> — so each branch every structural change — deleting entry 2 slides the next command into path <code>&quot;2&quot;</code> — so each branch
build stamps its nodes afresh and the editor panels remount onto the new paths.</p> build stamps its nodes afresh and the editor panels remount onto the new paths, and the host carries
its own index-based ids — the expansion set, the Add focus and the selection — through every row op
so they follow the rows rather than the slots.</p>
<h2 id="key-models">Key Models</h2> <h2 id="key-models">Key Models</h2>
<ul> <ul>
<li><strong>Primary</strong>: <a class="xref" href="../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> — the mission's command, <li><strong>Primary</strong>: <a class="xref" href="../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> — the mission's command,
@@ -122,17 +129,19 @@ top-down.</li>
<ul> <ul>
<li>Mission Root Panel <li>Mission Root Panel
<ul> <ul>
<li>Head Line <li>No-Project Caption
<ul> <ul>
<li>Add Command Button <li>&ldquo;No project loaded. Open or create a project first.&rdquo; while nothing is open; the head line,
<ul> separator and empty state are withheld with it.</li>
<li>Opens the Add Command dialog. Disabled while no project is open.</li>
</ul> </ul>
</li> </li>
<li>Head Line
<ul>
<li>Commands Caption</li> <li>Commands Caption</li>
<li>Command Count Badge <li>Command Count Badge
<ul> <ul>
<li>Outlined, and grey rather than primary while the list is empty.</li> <li>The root list's own entries — the node's command children. Outlined, and grey rather than
primary while the list is empty.</li>
</ul> </ul>
</li> </li>
</ul> </ul>
@@ -140,56 +149,101 @@ top-down.</li>
<li>Separator</li> <li>Separator</li>
<li>Empty State <li>Empty State
<ul> <ul>
<li>&ldquo;No project loaded&rdquo; while nothing is open; otherwise &ldquo;No commands yet&rdquo;, naming Add Command.</li> <li>&ldquo;No commands yet. Click Add Command to create one.&rdquo; while the list is empty.</li>
</ul>
</li>
<li>(Each) Command Row
<ul>
<li>Drag Handle Icon
<ul>
<li>The whole row is draggable; the handle is the affordance for it.</li>
</ul>
</li>
<li>Command Label
<ul>
<li>The command's title as the engine composes it: the kind's localized display name, with a
title the user typed appended as <code>Name [title]</code>.</li>
</ul>
</li>
<li>Move Up Button / Move Down Button
<ul>
<li>Disabled at the ends of the list.</li>
</ul>
</li>
<li>Duplicate Button</li>
<li>Delete Button</li>
<li>A disabled command's row is dimmed, and its buttons stay live.</li>
<li>Clicking the row anywhere but on a button selects that command's tree node.</li>
</ul>
</li>
<li>Drop-Out Zone
<ul>
<li>Present in a nested list editor only, and shown only while a row is being dragged. It sits
below the rows, so the rows do not shift under the pointer at drag start.</li>
</ul> </ul>
</li> </li>
<li>Run-Order Hint <li>Run-Order Hint
<ul> <ul>
<li>Commands run top-down, and the checkbox on each command's tree item enables or disables it.</li> <li>Always present. It names the row affordances: commands run top-down in the Control Tree; add
one with + on the Mission or a List row; drag a row to reorder it; a row's own buttons move,
duplicate or delete it; its checkbox enables or disables it.</li>
</ul>
</li>
</ul>
</li>
<li>Mission Root Row (Control Tree)
<ul>
<li>Add Command Button
<ul>
<li>The <code>+</code>, always visible and pinned to the row's right edge. Opens the Add Command dialog
scoped to the root list. Disabled while no project is open, and while the busy gate is held —
a mission op, or a checkbox toggle's save, in flight.</li>
<li>The row carries no drag handle and no command ops. It is a drop target: anywhere on its height
lands the dragged command in the root list.</li>
</ul>
</li>
</ul>
</li>
<li>(Each) Command Row
<ul>
<li>Enable Checkbox
<ul>
<li>The tree's tick, and the command's enable switch; a disabled command's label is dimmed.</li>
</ul>
</li>
<li>Drag Handle Icon
<ul>
<li>The whole row is draggable; the handle is the affordance for it. Plain and List command rows
carry one; the root row does not.</li>
</ul>
</li>
<li>Command Label
<ul>
<li>A real link to the node's <code>?tree=</code> URL, so the browser's context menu can open it in a new
tab, while a plain click keeps the in-app selection. The text is the command's title as the
engine composes it: the kind's localized display name, with the command's key value appended
in brackets where the kind has one — a List's or Script's typed title, a Program File's file,
a resolution's millimetres, a switch's On / Off.</li>
</ul>
</li>
<li>Move Up Button / Move Down Button / Duplicate Button / Delete Button
<ul>
<li>Hidden at rest, revealed on hover and on the selected row, and always shown where there is no
hover to reveal them with (touch). Move Up is disabled on the first entry and Move Down on the
last; all four while the busy gate is held — a mission op, or a checkbox toggle's save, in
flight.</li>
</ul>
</li>
<li>Add Command Button
<ul>
<li>On a List row only: the same <code>+</code>, scoped to that list, to the right of the row buttons.</li>
</ul>
</li>
<li>Drop Indicator
<ul>
<li>A primary edge line for a before / after landing, a tinted row for a landing into a list; the
dragged row itself dims.</li>
</ul> </ul>
</li> </li>
</ul> </ul>
</li> </li>
</ul> </ul>
<p>Enable/disable is not a control on this panel. It is the tree item's checkbox on the command node; a <p>Enable/disable is not a control on any panel. It is the tree item's checkbox on the command node; a
disabled command is skipped when the mission plays and stays fully editable.</p> disabled command is skipped when the mission plays and stays fully editable. A toggle PUTs straight
to the Mission API and flips the node's own state, with no rebuild; on failure the checkbox snaps
back. The toggle holds the same busy gate as the structural ops while its save is on the wire — a
row op sent meanwhile could be applied first server-side and land the flag on whichever command
slid into the ticked path — so until the save lands every row button and <code>+</code> is disabled, no drag
starts, the tree selection is refused, an op that still reaches the host returns silently, and a
further checkbox click snaps back. The gate holds in the other direction too: the checkboxes and
the tree selection are read-only while a mission op is in flight, since a tick would address the
node's pre-op path.</p>
<h2 id="add-command">Add Command</h2> <h2 id="add-command">Add Command</h2>
<p>The button opens a search-first picker. The search box matches a command's display label, its kind <p>The <code>+</code> on the Mission root row, or on any List row, opens a search-first picker. The search box
key, or one of its declared aliases — each alias searchable both by its English key and by its word matches a command's display label, its kind key, or one of its declared aliases — each alias
in the request language. Arrow keys walk the results and Enter takes the highlighted one. Results searchable both by its English key and by its word in the request language. Arrow keys walk the
are grouped by category, in the catalog's own display order.</p> results and Enter takes the highlighted one. Results are grouped by category, in the catalog's own
<p>The picked command is appended to the list this editor is scoped to, and the branch rebuilds in display order. One pick per opening: a second click or Enter before the dialog has closed adds
place: the selection stays on the list rather than jumping into the new command's panel.</p> nothing.</p>
<p>The picked command is inserted right after the focused command when that command is a direct
entry of the list the <code>+</code> is scoped to, and at that list's tail otherwise. The focus is one for the
whole mission, not one per list: the most recently selected command anywhere in the tree (a section
row counts for its owning command), or the last command an Add landed on. So the Mission row's <code>+</code>
never chases a focus inside a nested list — and once a nested command has been selected, the root
row's <code>+</code> appends at the root's tail rather than after whichever root command was selected before
it. The branch rebuilds in place, the new row is revealed and becomes the focus, so a run of adds
lands in order below it, and the selection stays where it was rather than jumping into the new
command's panel.</p>
<p>The addable set is served by the backend rather than mirrored in a frontend menu. Every engine <p>The addable set is served by the backend rather than mirrored in a frontend menu. Every engine
command carrying <code>[CommandCatalog]</code> is reflected into the catalog, so attributing a new engine command carrying <code>[CommandCatalog]</code> is reflected into the catalog, so attributing a new engine
command is all it takes for it to appear in the dialog. Thirteen kinds ship:</p> command is all it takes for it to appear in the dialog. Thirteen kinds ship:</p>
@@ -207,42 +261,64 @@ Failure, Physics</li>
can override that choice.</p> can override that choice.</p>
</div> </div>
<h2 id="ordering-duplicating-and-deleting">Ordering, Duplicating and Deleting</h2> <h2 id="ordering-duplicating-and-deleting">Ordering, Duplicating and Deleting</h2>
<p>Every structural op runs through one path in the tree host: a busy gate that holds every row
affordance, the tree selection and the checkboxes read-only while the op is in flight — the one
gate a checkbox toggle also holds while its save is on the wire, so an op and a tick never
interleave on the server; the open editor's dirty flush — an editor with staged edits (Script, NC
Code, a List's title) saves or resolves them first, waiting for a save already on the wire, and a
refused flush drops the op with a notice rather than silently; the API call; a rebuild scoped to
the list the op rewrote; then the post-op selection. The selection follows the acted-on row only
when it already rode on it — that row, or a node under it — and otherwise stays on its own
re-indexed row, so the editor the user is in is left alone.</p>
<p>Move Up and Move Down move an entry within its own list; they never change which list owns it. <p>Move Up and Move Down move an entry within its own list; they never change which list owns it.
Duplicate deep-clones the entry through the same XML round-trip the project file uses — so a nested Duplicate deep-clones the entry through the same XML round-trip the project file uses — so a nested
list copies with its whole subtree — and the clone lands right after the source. Delete asks for list copies with its whole subtree — and the clone lands right after the source; a selection riding
confirmation in a dialog naming the command.</p> on the source moves onto the clone. Delete asks for confirmation in a dialog naming the command,
before the dirty gate runs, so a cancelled delete forces no save prompt on the open editor; a
selection riding on the deleted row lands on the nearest remaining entry of that list, or on the
list node itself once the list is empty, where Add Command waits.</p>
<p>Dragging a row has three landings:</p> <p>Dragging a row has three landings:</p>
<ul> <ul>
<li>On another row — reorder within this list. A plain row splits at its midline into before and <li>On a command row's edge — before or after it. A plain command row splits at its midline; a List
after, and the whole new order is sent as one ordered path list.</li> row's outer quarters are its edges. When both rows share a list this is a reorder, and the whole
<li>On the middle band of a <code>list</code> row — move the entry inside that list. That row's outer quarters new order is sent as one ordered path list; when they do not, the entry relocates into the
still reorder around it.</li> target's list at that slot — which is also the way out of a nested list.</li>
<li>On the drop-out zone of a nested list editor — move the entry out, landing right after the list <li>On the middle band of a List row — move the entry inside that list, at its tail.</li>
command itself in the owning list.</li> <li>On the Mission root row — anywhere on its height moves the entry into the root list, at its tail.</li>
</ul> </ul>
<p>The last two are the same reparent call. The server resolves both lists to object references before <p>Which call a landing makes depends on whether the entry changes list, not on where the pointer
it mutates either, so the index shift the removal causes cannot misroute the insert, and it refuses sat. A landing that keeps the list — an edge in the entry's own list, or an into-landing on the
to move a list into itself or into one of its own descendants.</p> list that already holds it (a List row's middle band, or the Mission root row for a root entry),
which sends it to the tail — is the reorder call, the whole new order as one ordered path list; a
landing that changes the list — into a list the entry is not in, or an edge in another list — is
the reparent call. The client refuses to drop a row onto itself or into its own subtree, starts no
drag while the busy gate is held — an op, or a checkbox toggle's save, in flight — and abandons a
drop whose row was re-stamped by a rebuild mid-drag. The server resolves both lists to object
references before it mutates either, so the index shift the removal causes cannot misroute the
insert, and it refuses to move a list into itself or into one of its own descendants. A move across
lists rebuilds from the nearest list above both, and the selection follows the dragged command when
it rode on it.</p>
<h2 id="nesting">Nesting</h2> <h2 id="nesting">Nesting</h2>
<p>A <code>list</code> entry grows the same structure one level down: its children are its own entries, so nested <p>A <code>list</code> entry grows the same structure one level down: its children are its own entries, so nested
lists read as sub-trees at any depth, and the very same panel edits them. The differences are the lists read as sub-trees at any depth, and the very same row affordances act on them. The difference
scope — the root list, versus the node's own dotted path — and the drop-out zone, which appears only is the scope — the root list, versus the node's own dotted path: each List row's <code>+</code> inserts into
in a nested editor. A nested list's node adds an optional title above the embedded editor, and that its own list, and a drop into either lands there. A nested list's panel is the optional title alone,
title is appended to the List name in the row and tree label.</p> and that title is appended to the List name in the tree label.</p>
<p>Because the mission's own command is always a list, the root and a nested list are one editor at two <p>Because the mission's own command is always a list, the root and a nested list are one row shape at
scopes. A project file whose stored command is something else loads with that command wrapped into two scopes. A project file whose stored command is something else loads with that command wrapped
the root list, so the panel always has a list to edit.</p> into the root list, so the branch always has a list to root.</p>
<h2 id="where-a-command-is-edited">Where a Command Is Edited</h2> <h2 id="where-a-command-is-edited">Where a Command Is Edited</h2>
<p>A command's editor renders on its own tree node, below the control bar carrying the operations that <p>A command's editor renders on its own tree node; the row operations that rewrite the parent list stay
rewrite the parent list (Up, Down, Duplicate, Delete):</p> on the tree row:</p>
<ul> <ul>
<li>Nine kinds have a bespoke editor: General Config, Machining Motion Resolution, <li>Nine kinds have a bespoke editor: General Config, Machining Motion Resolution,
<a class="xref" href="NcFileCommand-panel.html">Program File</a>, <a class="xref" href="NcCodeCommand-panel.html">NC Code</a>, <a class="xref" href="NcFileCommand-panel.html">Program File</a>, <a class="xref" href="NcCodeCommand-panel.html">NC Code</a>,
<a class="xref" href="script-command-panel.html">Script</a>, <a class="xref" href="NcOptOption-panel.html">NC Optimization Config</a>, <a class="xref" href="script-command-panel.html">Script</a>, <a class="xref" href="NcOptOption-panel.html">NC Optimization Config</a>,
<a class="xref" href="PostExecutionCommand-panel.html">Post-Execution</a>, Record Meshed Geometry and Export Meshed <a class="xref" href="PostExecutionCommand-panel.html">Post-Execution</a>, Record Meshed Geometry and Export Meshed
Geometry.</li> Geometry.</li>
<li><code>list</code> is edited inline by the control-bar panel: the optional title over the embedded <li><code>list</code> shows only its optional title on its node; its entries are its tree children, and
<a class="xref" href="ListCommand-panel.html">list editor</a>.</li> <a class="xref" href="ListCommand-panel.html">List Command Panel</a> covers what a list is and what moving in and
out of one costs.</li>
<li>The four remaining Setup kinds — Machining Resolution, Collision Detection, Pause on Failure and <li>The four remaining Setup kinds — Machining Resolution, Collision Detection, Pause on Failure and
Physics — are served by the generic field editor, which renders the command's reflected Physics — are served by the generic field editor, which renders the command's reflected
<code>[CommandField]</code> scalars with server-localized labels. That is what the app does instead of <code>[CommandField]</code> scalars with server-localized labels. That is what the app does instead of
@@ -254,38 +330,59 @@ reads a command, but the catalog does not offer it: a project file that stores t
the individual commands it stands for, and the panel serves projects that construct one through the the individual commands it stands for, and the panel serves projects that construct one through the
API.</p> API.</p>
<p>The multi-card kinds — General Config, NC Optimization Config and Post-Execution — put their extra <p>The multi-card kinds — General Config, NC Optimization Config and Post-Execution — put their extra
cards on section child nodes of the command, one node per card, with the card's own enable flag cards on section child nodes of the command, one node per card. Where a card has its own enable
surfaced as that section node's tree checkbox. Post-Execution's Shot Files Output and Optimization flag — General Config's Meshed Geometry section and each of Post-Execution's five — that flag is the
Output sections appear only while the physics preference is on.</p> section node's tree checkbox; NC Optimization Config's five sections (Distances, Feedrate, Motion
Dynamics, Force &amp; Safety, Compensation) carry no checkbox — its enable switches sit on the command
node's own panel instead. Post-Execution's Shot Files Output and Optimization Output sections appear
only while the physics preference is on.</p>
<h2 id="source-code-path">Source Code Path</h2> <h2 id="source-code-path">Source Code Path</h2>
<p>See <a class="xref" href="../../index.html">HiNC App Anatomy</a> for git repository links.</p> <p>See <a class="xref" href="../../index.html">HiNC App Anatomy</a> for git repository links.</p>
<h3 id="web-application">Web Application</h3> <h3 id="web-application">Web Application</h3>
<ul> <ul>
<li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — this panel: Add Command, the entry <li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — this panel, informational only:
rows and their four actions, the three drag landings, and the delete confirmation. It serves the whether a project is open, the command count, the empty state and the run-order hint. It changes
Mission root and, embedded under a command's control bar, every nested <code>list</code> node.</li> nothing and emits nothing.</li>
<li><code>wwwroot-src/src/components/controlTree/AddCommandDialog.vue</code> — the search-first catalog picker.</li> <li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree pane that renders the
Mission rows' affordances: the drag handle, the hover-revealed move / duplicate / delete buttons on
every command row, the <code>+</code> on every list row (the Mission root included) and the Add Command
dialog it opens, plus the drop-indicator styles.</li>
<li><code>wwwroot-src/src/components/controlTree/useMissionTreeDrag.ts</code> — the HTML5 drag-and-drop
bookkeeping between Mission rows: which rows drag, which receive, the before / after / into mode
from the pointer position, and the stamp check that abandons a drop after a mid-drag rebuild.</li>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — builds the page's two roots,
Mission above Program; owns the five mission row ops — add, drag move, step, duplicate, delete —
through one <code>missionRowOp</code> helper (the busy gate, the open panel's dirty flush, the API call, the
scoped rebuild, the post-op selection) and the index translation that carries the expansion set,
the Add focus and the selection through each op; drives the command and section checkboxes,
holding the same busy gate while a tick's PUTs are on the wire.</li>
<li><code>wwwroot-src/src/components/controlTree/AddCommandDialog.vue</code> — the search-first catalog picker;
one pick per opening.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — one entry's panel: the <li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — one entry's panel: the
move / duplicate / delete control bar over the kind's editor, or over the title input and embedded kind's editor, or the optional title input alone for a <code>list</code> entry. It forwards the editor's
list editor of a <code>list</code> entry.</li> dirty-switch gate — and flushes a pending title save — to the host, and relays the Program File
editor's multi-pick as a structure change on the parent list carrying the inserted range.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionSectionPanel.vue</code> — the panel of a command's <li><code>wwwroot-src/src/components/controlTree/MissionSectionPanel.vue</code> — the panel of a command's
section child, rendering that one card.</li> section child, rendering that one card.</li>
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — the Mission wave of the Control <li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — the Mission wave of the Control
Tree: the item types, the child builders that carry the recursion, the per-kind editor map, the Tree: the item types, the child builders that carry the recursion, the per-kind editor map, and
section definitions and their enable flags, and the kind and category icons.</li> the section definitions and their enable flags.</li>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — builds the Execution root with <li><code>wwwroot-src/src/components/controlTree/missionKindIcons.ts</code> — the kind and category icons the
the Mission branch node above the Program branch, and drives the command and section checkboxes.</li> Add Command dialog shows.</li>
<li><code>wwwroot-src/src/api/mission.ts</code> — typed wrapper over <code>/api/Mission/*</code>: <code>listCommandEntries</code>, <li><code>wwwroot-src/src/api/mission.ts</code> — typed wrapper over <code>/api/Mission/*</code>: <code>listCommandEntries</code>,
<code>addEntry</code>, <code>removeEntry</code>, <code>moveEntry</code>, <code>duplicateEntry</code>, <code>reparentEntry</code>, <code>reorderEntries</code>, <code>addEntry</code> (with an optional insert index, resolving to the new entry's path), <code>removeEntry</code>,
<code>setListTitle</code>, <code>getCommandCatalog</code>, <code>loadCommandFields</code> / <code>setCommandField</code>, and the per-kind <code>moveEntry</code>, <code>duplicateEntry</code>, <code>reparentEntry</code>, <code>reorderEntries</code>, <code>setListTitle</code>,
readers and writers.</li> <code>getCommandCatalog</code>, <code>loadCommandFields</code> / <code>setCommandField</code>, and the per-kind readers and
writers.</li>
<li><code>wwwroot-src/src/components/mission/GenericCommandPanel.vue</code> — the fallback editor for a catalog <li><code>wwwroot-src/src/components/mission/GenericCommandPanel.vue</code> — the fallback editor for a catalog
kind with no bespoke panel: the command's reflected <code>[CommandField]</code> scalars.</li> kind with no bespoke panel: the command's reflected <code>[CommandField]</code> scalars.</li>
<li>The bespoke editors: <li>The bespoke editors:
<ul> <ul>
<li><code>wwwroot-src/src/components/mission/PreSettingCommandPanel.vue</code></li> <li><code>wwwroot-src/src/components/mission/PreSettingCommandPanel.vue</code></li>
<li><code>wwwroot-src/src/components/mission/MachiningMotionResolutionCommandPanel.vue</code></li> <li><code>wwwroot-src/src/components/mission/MachiningMotionResolutionCommandPanel.vue</code></li>
<li><code>wwwroot-src/src/components/mission/NcFileCommandPanel.vue</code></li> <li><code>wwwroot-src/src/components/mission/NcFileCommandPanel.vue</code> — also the one panel-side
insert: its multi-pick adds the extra files as new Program File commands right after its own,
through <code>addEntry</code> at an insert index.</li>
<li><code>wwwroot-src/src/components/mission/NcCodeCommandPanel.vue</code></li> <li><code>wwwroot-src/src/components/mission/NcCodeCommandPanel.vue</code></li>
<li><code>wwwroot-src/src/components/mission/ScriptCommandPanel.vue</code></li> <li><code>wwwroot-src/src/components/mission/ScriptCommandPanel.vue</code></li>
<li><code>wwwroot-src/src/components/mission/NcOptOptionCommandPanel.vue</code></li> <li><code>wwwroot-src/src/components/mission/NcOptOptionCommandPanel.vue</code></li>
@@ -294,18 +391,24 @@ kind with no bespoke panel: the command's reflected <code>[CommandField]</code>
<li><code>wwwroot-src/src/components/mission/ExportMeshedGeomCommandPanel.vue</code></li> <li><code>wwwroot-src/src/components/mission/ExportMeshedGeomCommandPanel.vue</code></li>
</ul> </ul>
</li> </li>
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the <code>tree.mission.*</code> strings this panel renders: Add Command, <li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the <code>tree.mission.*</code> strings: Add Command, the Commands
the Commands caption, the no-commands-yet state, the drop-out zone, the run-order hint, the kind caption, the no-commands-yet state, the run-order hint that names the row affordances, the
display names, the section names and the operation labels.</li> disabled-command hint, the cancelled-op notice, the kind display names, the section names and the
op-context phrases.</li>
<li><code>wwwroot-src/src/i18n/en/common.ts</code> — the row buttons' titles (Move up, Move down, Duplicate,
Delete), the List title's label and the no-project caption.</li>
<li><code>wwwroot-src/src/i18n/en/dialog.ts</code> — the Delete Command confirmation.</li>
<li><code>wwwroot-src/src/router/routes.ts</code> — resolves <code>/mission</code> onto <code>/execution?tree=execution/mission</code>.</li> <li><code>wwwroot-src/src/router/routes.ts</code> — resolves <code>/mission</code> onto <code>/execution?tree=execution/mission</code>.</li>
<li><code>Missions/MissionController.cs</code> — the entry lifecycle (<code>GET list-command/entries</code>, <li><code>Missions/MissionController.cs</code> — the entry lifecycle (<code>GET list-command/entries</code>,
<code>POST list-command/entries</code> and <code>POST list-command/entries/{path}</code> to add at the root or inside a <code>POST list-command/entries</code> and <code>POST list-command/entries/{path}</code> to add at the root or inside a
nested list, <code>DELETE list-command/entries/{path}</code>, <code>POST list-command/entries/{path}/move</code>, nested list — at an optional <code>insertIndex</code>, answering the new entry's index and path —
<code>DELETE list-command/entries/{path}</code>, <code>POST list-command/entries/{path}/move</code>,
<code>PUT list-command/reorder</code>, <code>POST list-command/entries/{path}/duplicate</code> and <code>PUT list-command/reorder</code>, <code>POST list-command/entries/{path}/duplicate</code> and
<code>POST list-command/entries/{path}/reparent</code>), the <code>GET command-catalog</code> the Add Command dialog <code>POST list-command/entries/{path}/reparent</code>), the <code>GET command-catalog</code> the Add Command dialog
reads, and the per-command endpoints including the generic <code>commands/{path}/fields[/{key}]</code> pair. reads, and the per-command endpoints including the generic <code>commands/{path}/fields[/{key}]</code> pair.
<code>reparent</code> is what backs both drag-into-a-list and drop-out-to-the-parent, and it is the endpoint <code>reparent</code> is what backs a drop that changes the entry's list — into another list, or an edge in
that rejects moving a list into itself or its own descendants.</li> another list — and it is the endpoint that rejects moving a list into itself or its own
descendants; a drop that keeps the list, the tail landing included, goes through <code>reorder</code>.</li>
<li><code>Missions/MissionCommandCatalog.cs</code> — reflects every <code>[CommandCatalog]</code> command into the addable <li><code>Missions/MissionCommandCatalog.cs</code> — reflects every <code>[CommandCatalog]</code> command into the addable
set served to Add Command, and creates the picked kind.</li> set served to Add Command, and creates the picked kind.</li>
<li><code>Missions/MissionCommandFields.cs</code> — the reflection layer behind the generic field endpoints: it <li><code>Missions/MissionCommandFields.cs</code> — the reflection layer behind the generic field endpoints: it
@@ -326,8 +429,8 @@ one when a project is read.</li>
<ul> <ul>
<li><a class="xref" href="../program.html">Program Branch</a> — the read-only inspection twin of this list: what a <li><a class="xref" href="../program.html">Program Branch</a> — the read-only inspection twin of this list: what a
run actually read, one node per NC source file</li> run actually read, one node per NC source file</li>
<li><a class="xref" href="ListCommand-panel.html">List Command Panel</a> — the same editor one level down, and what moving an entry in or out of a nested list costs</li> <li><a class="xref" href="ListCommand-panel.html">List Command Panel</a> — the same rows one level down, and what moving an entry in or out of a nested list costs</li>
<li><a href="../../../manual/run/building-a-mission.html">Building a Mission</a> — the task this panel serves, as a procedure</li> <li><a href="../../../manual/run/building-a-mission.html">Building a Mission</a> — the task this branch serves, as a procedure</li>
</ul> </ul>
</article> </article>
@@ -93,14 +93,16 @@
the project file, so the script travels with the project. <code>Run</code> evaluates the text against the the project file, so the script travels with the project. <code>Run</code> evaluates the text against the
session shell as the globals object, and when the script returns a sequence of actions that sequence session shell as the globals object, and when the script returns a sequence of actions that sequence
is yielded into the run.</p> is yielded into the run.</p>
<p>The title is what the mission row and the tree node show: the label is composed as <code>Script [title]</code>, <p>The title is what the command's tree row shows: the label is composed as <code>Script [title]</code>, falling
falling back to a bare <code>Script</code> while the title is empty. A newly added command starts empty on both back to a bare <code>Script</code> while the title is empty. A newly added command starts empty — no title, no
clients — no title, no text.</p> text.</p>
<p>The panel renders on the command's own node in the Mission branch of the Execution page's Control <p>The panel renders on the command's own node under the Mission root of the Execution page's Control
Tree, below the move / duplicate / delete control bar. A single-purpose kind like this one embeds its Tree. The editor pane holds nothing but the editor: the command's move up / move down / duplicate /
whole editor on that node rather than growing section child nodes. Its tree checkbox only decides delete buttons and its drag handle sit on its tree row, and the Add Command <code>+</code> sits on the row of
whether the run plays the command; a disabled script is skipped during play and its editor stays the list that holds it. A single-purpose kind like this one embeds its whole editor on that node
fully usable.</p> rather than growing section child nodes. Its tree checkbox only decides whether the run plays the
command; a disabled script is skipped during play — a caption above the title says so — and its
editor stays fully usable.</p>
<h2 id="layout">Layout</h2> <h2 id="layout">Layout</h2>
<ul> <ul>
<li>Head Line <li>Head Line
@@ -163,9 +165,20 @@ save handed back. Each field is applied only when the body carries it. The respo
hash to chain into the next save.</p> hash to chain into the next save.</p>
<p>Two prompts guard the edges, each with three buttons because neither is a yes/no question:</p> <p>Two prompts guard the edges, each with three buttons because neither is a yes/no question:</p>
<ul> <ul>
<li><strong>Unsaved Changes</strong>, raised when the Control Tree tries to move the selection off a command whose <li><strong>Unsaved Changes</strong>, raised by the switch gate the panel hands the Control Tree host, which runs
save is still pending: Save &amp; switch flushes and then allows the switch, Discard drops the pending it before the selection moves off the command and before every mission row op — move, duplicate,
write, Cancel keeps the selection where it is.</li> delete, drag, Add Command. The op rebuilds the list it acted on, and that rebuild remounts the
panel whenever this command sits inside that list (a nested List included); when the panel
survives instead, the discard below has only put the autosave to sleep, and the next keystroke
resumes it on the same, still-valid path. The gate first lets a save already on the wire land,
and prompts only when edits are still staged after it: Save &amp; switch flushes and proceeds only
when that save landed — a conflict answered with Cancel leaves the edit staged and refuses the
switch; Discard reverts the editor to the last confirmed value and puts the autosave to sleep
until the next edit; Cancel keeps the selection where it is. A refused gate drops a row op and
says so in a notice (&quot;Cancelled — the open editor keeps its unsaved edits.&quot;). A row op cannot
reach the prompt while another is in flight — the host's busy gate refuses it first — but a
selection change holds no such gate, so a <code>?tree=</code> change arriving while a tree click's prompt is
up shares the pending answer instead of replacing it.</li>
<li><strong>Script changed elsewhere</strong>, raised when the server rejects the save because the hash no longer <li><strong>Script changed elsewhere</strong>, raised when the server rejects the save because the hash no longer
matches — another tab, or a project reload, changed the command underneath. The rejection carries matches — another tab, or a project reload, changed the command underneath. The rejection carries
the server's current text, title and hash, so the panel can offer Discard &amp; reload, Force the server's current text, title and hash, so the panel can offer Discard &amp; reload, Force
@@ -173,8 +186,10 @@ overwrite, or Cancel without a second round trip.</li>
</ul> </ul>
<p>The panel snapshots its command path at mount, and the autosave closes over that snapshot rather <p>The panel snapshots its command path at mount, and the autosave closes over that snapshot rather
than over the live selection, so a flush can never land on whichever command happens to be selected than over the live selection, so a flush can never land on whichever command happens to be selected
when it fires. After each successful save the tree relabels the node in place instead of rebuilding when it fires. That path is an index-based entry path which every structural op re-points, which is
the branch, which would remount the editor mid-edit.</p> why the row ops run the gate above before their rebuild; an op on another row leaves the selection
on this editor's own row, re-indexed. After each successful save the tree relabels the node in
place instead of rebuilding the branch, which would remount the editor mid-edit.</p>
<h2 id="the-compile-gate">The Compile Gate</h2> <h2 id="the-compile-gate">The Compile Gate</h2>
<p>A script that does not compile does nothing at run time: the command reports the compile failure <p>A script that does not compile does nothing at run time: the command reports the compile failure
into the run's message stream and yields no work, so the run continues without it. Starting a run into the run's message stream and yields no work, so the run continues without it. Starting a run
@@ -190,8 +205,15 @@ the whole mission.</p>
<ul> <ul>
<li><code>wwwroot-src/src/components/mission/ScriptCommandPanel.vue</code> — this panel: the title row sharing <li><code>wwwroot-src/src/components/mission/ScriptCommandPanel.vue</code> — this panel: the title row sharing
its line with the autosave indicator, the editor below it, the 500 ms autosave, the two its line with the autosave indicator, the editor below it, the 500 ms autosave, the two
three-button prompts, the path snapshot taken at mount, and the change notice that relabels the three-button prompts, the path snapshot taken at mount, the switch gate that waits for a save on
the wire and hands a second caller the pending prompt, and the change notice that relabels the
tree node.</li> tree node.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — the command node's
slave panel: mounts this editor on the entry path, forwards its switch gate to the host, and
shows the disabled caption above the title.</li>
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree rows: the drag handle
and the move / duplicate / delete buttons on the command's row, and the Add Command <code>+</code> on its
list's row.</li>
<li><code>wwwroot-src/src/components/widgets/TextEditor.vue</code> — the CodeMirror 6 wrapper: language and <li><code>wwwroot-src/src/components/widgets/TextEditor.vue</code> — the CodeMirror 6 wrapper: language and
read-only swapped through compartments, CRLF normalised on the way in so an unedited file cannot read-only swapped through compartments, CRLF normalised on the way in so an unedited file cannot
dirty the autosave, an opt-in completion source that overrides the language's own, and a widened dirty the autosave, an opt-in completion source that overrides the language's own, and a widened
@@ -208,14 +230,23 @@ kind union that maps straight onto CodeMirror's completion types.</li>
loader, the save that carries the expected hash, and the conflict error that carries the server's loader, the save that carries the expected hash, and the conflict error that carries the server's
current copy.</li> current copy.</li>
<li><code>wwwroot-src/src/composables/useAutoSave.ts</code> — the debounce, the state machine and the conflict <li><code>wwwroot-src/src/composables/useAutoSave.ts</code> — the debounce, the state machine and the conflict
recovery behind the panel's saving, saved and error states.</li> recovery behind the panel's saving, saved and error states; the discard that reverts the editor
and sleeps the autosave until the next edit, and the wait for a save already on the wire.</li>
<li><code>wwwroot-src/src/components/widgets/AutoSaveIndicator.vue</code> — the status pill beside the title.</li> <li><code>wwwroot-src/src/components/widgets/AutoSaveIndicator.vue</code> — the status pill beside the title.</li>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — funnels every selection change <li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — funnels every selection change
through the active panel's switch gate, which is how the Unsaved Changes prompt gets its say.</li> and every mission row op through the active panel's switch gate, which is how the Unsaved
Changes prompt gets its say; selection is read-only while a row op is in flight, and a refused
gate drops the op with a notice.</li>
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — maps the <code>script</code> kind to this <li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — maps the <code>script</code> kind to this
panel and gives it no section children, so the whole editor lives on the command node.</li> panel and gives it no section children, so the whole editor lives on the command node.</li>
<li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the panel's wording: both prompts, their buttons, and the <li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the panel's wording: both prompts' titles and messages,
load and save error contexts.</li> the Save &amp; switch, Force overwrite and Discard &amp; reload buttons, and the load and save error
contexts.</li>
<li><code>wwwroot-src/src/i18n/en/common.ts</code> — the shared strings the panel borrows: the &ldquo;Title
(optional)&rdquo; label, the Cancel button both prompts carry, and the Unsaved Changes prompt's
Discard.</li>
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the disabled caption and the notice a refused gate raises on
a row op.</li>
<li><code>Missions/ScriptCompletionController.cs</code><code>POST /api/script/completions</code>: a thin wrapper that <li><code>Missions/ScriptCompletionController.cs</code><code>POST /api/script/completions</code>: a thin wrapper that
returns the items, 499 on cancellation and 500 with the message on failure.</li> returns the items, 499 on cancellation and 500 with the message on failure.</li>
<li><code>Missions/ScriptCompletionService.cs</code> — the singleton holding one workspace, built from the same <li><code>Missions/ScriptCompletionService.cs</code> — the singleton holding one workspace, built from the same
@@ -87,8 +87,9 @@
<article data-uid="Anatomy-ProgramBranch"> <article data-uid="Anatomy-ProgramBranch">
<h1 id="program-branch">Program Branch</h1> <h1 id="program-branch">Program Branch</h1>
<p>Program is the lower of the two Control-Tree branches the Execution page hosts: route <code>/execution</code>, <p>Program is the lower of the two roots of the Execution page's Control Tree, Mission being the upper:
Control-Tree path <code>execution/program</code>, one node per NC source file the session read. It is a route <code>/execution</code>, Control-Tree path <code>execution/program</code>, one node per NC source file the session
read. It is a
read-only view of a run — the file's text, the passes that went over it, the per-line marks the run read-only view of a run — the file's text, the passes that went over it, the per-line marks the run
left behind, and the writeback files the run wrote — assembled from session data rather than from left behind, and the writeback files the run wrote — assembled from session data rather than from
anything typed into it. Its node ids are positional, so an id addresses a node without surviving the anything typed into it. Its node ids are positional, so an id addresses a node without surviving the
@@ -97,9 +98,12 @@ branch growing around it.</p>
<p>Mission is what a run executes; Program is what the run read. That one difference sets the rest of <p>Mission is what a run executes; Program is what the run read. That one difference sets the rest of
the branch:</p> the branch:</p>
<ul> <ul>
<li>Mission's nodes edit the project. Program's item types declare a panel and a child builder and <li>Mission's nodes edit the project. Program's item types declare a panel and, on the root and the
nothing else no enable checkbox (the tree hides the tick on every node that is not a Mission file node, a child builder — and nothing else: no enable checkbox (the tree hides the tick on
command or an enable-bearing Mission section), no control bar, no add, delete, move or duplicate.</li> every node that is not a Mission command or an enable-bearing Mission section), none of the row
affordances a Mission row carries (no drag handle, no add, delete, move or duplicate button), and
no counterpart to Mission's one panel-side structural edit, the multi-pick insert of the
<a class="xref" href="mission/NcFileCommand-panel.html">Program File editor</a>.</li>
<li>Mission's shape is authored. Program's shape is a consequence: a subprogram file appears on it <li>Mission's shape is authored. Program's shape is a consequence: a subprogram file appears on it
only because a run followed a call into it.</li> only because a run followed a call into it.</li>
<li>Mission belongs to the project. Program's contents belong to the session — the index behind it is <li>Mission belongs to the project. Program's contents belong to the session — the index behind it is
@@ -115,10 +119,10 @@ merge uses, and they share one namespace, so a Program File path and an NC Code
alike collapse into one node. A Program File command whose path is still unset is skipped and seeds alike collapse into one node. A Program File command whose path is still unset is skipped and seeds
nothing. A placeholder carries no invocations, so its panel shows the file's text with no marks and nothing. A placeholder carries no invocations, so its panel shows the file's text with no marks and
an empty, disabled pass selector.</p> an empty, disabled pass selector.</p>
<p>The transport bar is the one control the branch does carry, and it is not the branch's own: the <p>The branch carries no transport of its own either. The <a href="execution-tool-bar.html">Execution Tool Bar</a>
primary editor pane pins the <a href="execution-tool-bar.html">Execution Tool Bar</a> above the panel of the sits in the Control Tree pane's run header — above the tree scroller, beside the execution-status
Execution root and of every node beneath it, so a run can be started, stepped and reset while a badge, on the Execution page only — so a run can be started, stepped and reset while a program file
program file is on screen.</p> is on screen, and the editor pane below the tree shows nothing but the selected node's panel.</p>
<h2 id="the-nodes-the-branch-mints">The Nodes the Branch Mints</h2> <h2 id="the-nodes-the-branch-mints">The Nodes the Branch Mints</h2>
<p>Three item types, each keyed by position rather than by identity.</p> <p>Three item types, each keyed by position rather than by identity.</p>
<p><strong>The branch root</strong> (<code>execution/program</code>) carries the summary panel and the child builder that <p><strong>The branch root</strong> (<code>execution/program</code>) carries the summary panel and the child builder that
@@ -229,8 +233,8 @@ when it mounts — or through a watcher, when it was already the selected panel.
before the first page of text resolves is parked again and re-applied once the line array is sized.</p> before the first page of text resolves is parked again and re-applied once the line array is sized.</p>
<h2 id="when-the-branch-is-rebuilt">When the Branch Is Rebuilt</h2> <h2 id="when-the-branch-is-rebuilt">When the Branch Is Rebuilt</h2>
<ul> <ul>
<li><strong>Page initialization.</strong> Building the Execution root builds the branch, and only when a project is <li><strong>Page initialization.</strong> Building the Execution page's two roots builds the branch, and only when
loaded; without one it stays empty.</li> a project is loaded; without one the root stands with no children.</li>
<li><strong>Any change in the broadcast execution status.</strong> The status the hub reports is one of <li><strong>Any change in the broadcast execution status.</strong> The status the hub reports is one of
<code>NoProject</code>, <code>Ready</code>, <code>Running</code>, <code>Paused</code> and <code>Finished</code>, and the host re-reads the branch <code>NoProject</code>, <code>Ready</code>, <code>Running</code>, <code>Paused</code> and <code>Finished</code>, and the host re-reads the branch
whenever that value changes. It deliberately does not take the structural-change path used whenever that value changes. It deliberately does not take the structural-change path used
@@ -239,9 +243,10 @@ keep re-opening a branch the reader had closed. The panels pick up <strong>part<
the replaced nodes: the path caption, the pass selector, the inline wording and the executed-line the replaced nodes: the path caption, the pass selector, the inline wording and the executed-line
count are all derived from the node, but the file text is not — it is fetched once per page on count are all derived from the node, but the file text is not — it is fetched once per page on
mount and on scroll, with no watcher on the path, and the panel is not remounted because its key mount and on scroll, with no watcher on the path, and the panel is not remounted because its key
is built from the node id, which is positional and therefore unchanged. A rebuild that puts a — the node id, the node key and the mission stamp — reduces on a Program node to the id alone,
different file at the same index leaves the previous file's text on screen under the new node's the other two parts being empty, and the id is positional and therefore unchanged. A rebuild that
caption and marks.</li> puts a different file at the same index leaves the previous file's text on screen under the new
node's caption and marks.</li>
<li><strong>The refresh button on the root panel.</strong> This one does take the structural-change path: it <li><strong>The refresh button on the root panel.</strong> This one does take the structural-change path: it
re-reads the file tree from the current session and expands the branch.</li> re-reads the file tree from the current session and expands the branch.</li>
</ul> </ul>
@@ -315,16 +320,18 @@ selector, the Follow toggle, the paged line viewer, the execution marks, the ste
converted-line badges, and the cursor and hover wiring.</li> converted-line badges, and the cursor and hover wiring.</li>
<li><code>wwwroot-src/src/components/controlTree/ProgramConversionFilePanel.vue</code> — one written file: the <li><code>wwwroot-src/src/components/controlTree/ProgramConversionFilePanel.vue</code> — one written file: the
paged line viewer and the source-line links back into the file panel.</li> paged line viewer and the source-line links back into the file panel.</li>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — declares the branch root under <li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — declares the branch root as the
the Execution root, re-reads it on every execution-status change without expanding it, and hides Execution page's second root, below Mission, re-reads it on every execution-status change without
the tick on every node that is not a Mission command or an enable-bearing Mission section.</li> expanding it, and hides the tick on every node that is not a Mission command or an enable-bearing
Mission section.</li>
<li><code>wwwroot-src/src/components/controlTree/itemTypes.ts</code> — the node shape carrying the program <li><code>wwwroot-src/src/components/controlTree/itemTypes.ts</code> — the node shape carrying the program
bookkeeping, the merged item-type registry, and the eager subtree builder.</li> bookkeeping, the merged item-type registry, and the eager subtree builder.</li>
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree pane that renders the <li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree pane that renders the
branch's nodes and binds the tree's strict tick strategy.</li> branch's nodes, binds the tree's strict tick strategy, and pins the run header — the transport bar
<li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — mounts the selected node's panel, and the execution-status badge — above the tree on the Execution page.</li>
forwards its selection request to the host, and pins the transport bar above every Execution-scope <li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — mounts the selected node's panel
node.</li> under a key built from the node id, the node key and the mission stamp — the last two empty on
every Program node — and forwards its selection request to the host.</li>
<li><code>wwwroot-src/src/api/ncProgram.ts</code> — the typed client for the file tree, the paged lines, the line <li><code>wwwroot-src/src/api/ncProgram.ts</code> — the typed client for the file tree, the paged lines, the line
marks, the syntax piece, the sentence-to-step mapping and both directions of conversion links.</li> marks, the syntax piece, the sentence-to-step mapping and both directions of conversion links.</li>
<li><code>wwwroot-src/src/api/clStrip.ts</code> — the step-select and step-enter posts a line click and a line <li><code>wwwroot-src/src/api/clStrip.ts</code> — the step-select and step-enter posts a line click and a line
@@ -363,8 +370,11 @@ inline node and whose text is that node's only source.</li>
</ul> </ul>
<h2 id="see-also">See Also</h2> <h2 id="see-also">See Also</h2>
<ul> <ul>
<li><a class="xref" href="mission/mission-root-panel.html">Mission Root Panel</a> — the editable twin: the command list this branch reports on, and <li><a class="xref" href="mission/mission-root-panel.html">Mission Root Panel</a> — the editable twin: the command list this branch reports on. Its
the only place the NC file list is changed</li> Add Command, drag, move, duplicate and delete ops live on the Control Tree rows and act on
commands of any kind; the root's own panel is informational — a no-project note when no project
is loaded, otherwise the command count with an Add Command prompt while that count is zero, and
the run-order hint in either case</li>
<li><a class="xref" href="index.html">Execution Page</a> — the page that hosts both branches, and the transport, canvas and charts <li><a class="xref" href="index.html">Execution Page</a> — the page that hosts both branches, and the transport, canvas and charts
the branch's selections drive</li> the branch's selections drive</li>
</ul> </ul>
@@ -92,8 +92,9 @@ page at <code>/execution</code> and the General Setup page at <code>/general-set
host — <code>useControlTreeHost('execution')</code> or <code>useControlTreeHost('equipment')</code> — provides it to its host — <code>useControlTreeHost('execution')</code> or <code>useControlTreeHost('equipment')</code> — provides it to its
panes under one injection key, and the host owns everything after that: the node graph, the branch panes under one injection key, and the host owns everything after that: the node graph, the branch
builders, the selection and the <code>?tree=</code> query that carries it, the editor panel a selection resolves builders, the selection and the <code>?tree=</code> query that carries it, the editor panel a selection resolves
to, and the mission enable ticks. The Tool House page at <code>/tool-house</code> reuses the same node shape and to, the mission enable ticks, and every structural operation on the Mission branch. The Tool House
the same item-type registry but renders a branch as nested tabs and creates no host.</p> page at <code>/tool-house</code> reuses the same node shape and the same item-type registry but renders a branch
as nested tabs and creates no host.</p>
<div class="IMPORTANT"> <div class="IMPORTANT">
<h5>Important</h5> <h5>Important</h5>
<p>Node ids are role paths, not identities that survive a version change. Anatomy makes no claim that <p>Node ids are role paths, not identities that survive a version change. Anatomy makes no claim that
@@ -105,7 +106,10 @@ for the migration hop that keeps an older link resolving.</p>
<ul> <ul>
<li><code>id</code> — the node's role path, slash-separated, whose first segment is the owning page's scope <li><code>id</code> — the node's role path, slash-separated, whose first segment is the owning page's scope
(<code>execution/…</code>, <code>equipment/…</code>, <code>toolhouse/…</code>). This is the addressing surface: the <code>?tree=</code> query, (<code>execution/…</code>, <code>equipment/…</code>, <code>toolhouse/…</code>). This is the addressing surface: the <code>?tree=</code> query,
the persisted expansion list and the persisted last selection all hold ids.</li> the persisted expansion list and the persisted last selection all hold ids. The General Setup
page's root carries its scope as its own id, <code>equipment</code>; the Execution page has no node with the
bare <code>execution</code> id — its two roots are <code>execution/mission</code> and <code>execution/program</code>, and the
segment is a scope key only.</li>
<li><code>label</code>, <code>labelKey</code>, <code>labelParams</code> — the display text; see <a href="#display-labels">Display Labels</a>.</li> <li><code>label</code>, <code>labelKey</code>, <code>labelParams</code> — the display text; see <a href="#display-labels">Display Labels</a>.</li>
<li><code>itemType</code> — the registry key that decides the node's editor and its child builder.</li> <li><code>itemType</code> — the registry key that decides the node's editor and its child builder.</li>
<li><code>key</code> — the bound object. In the geometry and equipment branches it is an IndexService key, <li><code>key</code> — the bound object. In the geometry and equipment branches it is an IndexService key,
@@ -126,7 +130,9 @@ therefore survives a rebuild, which is why expansion state, the URL and the land
keyed on ids. Two id families are positional rather than role-based: Mission entries are keyed on ids. Two id families are positional rather than role-based: Mission entries are
<code>${parentId}/${index}</code> and Program files are <code>${parentId}/${index}</code>, so moving or deleting a mission <code>${parentId}/${index}</code> and Program files are <code>${parentId}/${index}</code>, so moving or deleting a mission
command renumbers its siblings and a link to one names a position in the list rather than that command renumbers its siblings and a link to one names a position in the list rather than that
command.</p> command. The host keeps three id sets of its own that must follow the rows rather than the numbers —
the persisted expansion list, the Add Command focus and the selection — and translates all three
through every mission row operation it runs; see <a href="#the-structure-changed-event">the row operations</a>.</p>
<h2 id="the-item-type-registry">The Item-Type Registry</h2> <h2 id="the-item-type-registry">The Item-Type Registry</h2>
<p><code>ITEM_TYPES</code> maps an <code>itemType</code> string onto a <code>TreeItemDef</code> carrying up to three members:</p> <p><code>ITEM_TYPES</code> maps an <code>itemType</code> string onto a <code>TreeItemDef</code> carrying up to three members:</p>
<ul> <ul>
@@ -144,10 +150,11 @@ binds it to the node's key. The two composite geometry kinds do not embed nested
<code>TransformationGeom</code> grows an inner-geometry and an <code>TransformationGeom</code> grows an inner-geometry and an
inner-transformer slot, and <code>GeomCombination</code> grows one slot per item, so the tree owns the structure inner-transformer slot, and <code>GeomCombination</code> grows one slot per item, so the tree owns the structure
and every panel stays shallow.</p> and every panel stays shallow.</p>
<p>The map is one flat namespace assembled in <code>itemTypes.ts</code>: the <code>Group</code> stem type, the geometry, <p>The map is one flat namespace assembled in <code>itemTypes.ts</code>: the <code>Group</code> stem type and the geometry,
transformer, workpiece-leaf, thermal-condition and spindle entries, and the Execution root's own type transformer, workpiece-leaf, thermal-condition and spindle entries are written inline, and five
are written inline, and five per-wave registries are spread in beside them. The three roots the panel per-wave registries are spread in beside them. The Execution page's two roots are registry types —
host renders itself — Machine Tool, Fixture and Workpiece — have no entry here at all.</p> <code>MissionRoot</code> and <code>ProgramRoot</code>, from their waves — and no wrapper type stands over them. The three
roots the panel host renders itself — Machine Tool, Fixture and Workpiece — have no entry here at all.</p>
<table> <table>
<thead> <thead>
<tr> <tr>
@@ -160,7 +167,7 @@ host renders itself — Machine Tool, Fixture and Workpiece — have no entry he
<tr> <tr>
<td>Mission</td> <td>Mission</td>
<td><code>missionItemTypes.ts</code></td> <td><code>missionItemTypes.ts</code></td>
<td><code>MissionRoot</code>, <code>MissionCommand</code>, <code>MissionSection</code>; section children at <code>${command.id}/${sectionId}</code>; the per-kind bespoke editors, with a generic field editor as the fallback</td> <td><code>MissionRoot</code>, whose panel is informational — the command count and the run-order hint that names the row affordances; <code>MissionCommand</code>, whose panel is the kind's editor, or only a Title field for a List; <code>MissionSection</code>; section children at <code>${command.id}/${sectionId}</code>; the per-kind bespoke editors, with a generic field editor as the fallback</td>
</tr> </tr>
<tr> <tr>
<td>Program</td> <td>Program</td>
@@ -219,15 +226,50 @@ correct only while the change stays inside the emitting panel's own branch.</li>
<li><code>selectId</code> — the selection to adopt afterwards. It is assigned directly, <strong>bypassing the <li><code>selectId</code> — the selection to adopt afterwards. It is assigned directly, <strong>bypassing the
dirty-switch gate</strong>, because the emitting panel is being replaced on purpose. A <code>null</code> clears the dirty-switch gate</strong>, because the emitting panel is being replaced on purpose. A <code>null</code> clears the
selection.</li> selection.</li>
<li><code>inserted</code> — entries a panel inserted into a mission list itself: the list node's id, the child
index the run starts at and its count. The host then treats the rebuild as a mission operation —
it holds the busy gate and slides its index-based ids past the new siblings — rather than as a
plain branch refresh.</li>
</ul> </ul>
<p>A mission command's move, duplicate and delete re-scope to the parent list, because those operations <p>One command editor emits the event: the Program File editor, whose multi-pick turns every extra file
rewrite the parent's children, and they name the post-operation selection: the clone's slot after a into a new Program File command inserted right after it, in pick order; the command panel hosting it
duplicate, the neighbouring index after a delete, the parent list when the delete emptied it. Moving re-scopes the event to the parent list, keeps that command selected and passes the insert range
an entry out of a nested list re-scopes to the grandparent. The controller brand switch and the along. Two panels emit it with no payload and so take the default scope, their own node: the Program
runner's Object-Management install re-scope to the controller root. The Tool House type selectors and root panel's refresh button, which re-reads the file tree from the current session and rebuilds the
a flute add re-scope to their own node; everything that rewrites the tool collection — a new tool, a Program branch through <code>rebuildBranch</code>, so the branch opens under it; and the <code>GeomCombination</code>
duplicate, a delete, an id rename, an Object-Management install — re-scopes to the tool-house root, item panel after an item add, an item remove or a clear, since its item slots must be regrown. The
and a flute delete re-scopes to its fluting parent.</p> controller brand switch and the runner's Object-Management install re-scope to the controller
root. The Tool House type selectors and a flute add re-scope to their own node; everything that
rewrites the tool collection — a new tool, a duplicate, a delete, an id rename, an
Object-Management install — re-scopes to the tool-house root, and a flute delete re-scopes to its
fluting parent.</p>
<p>Every other structural change to the Mission branch is an operation of the host itself, not an
event, because the tree rows are the only surface that offers it: Add Command, a drag between rows,
Move up / Move down, Duplicate and Delete. A drag is HTML5 drag-and-drop between mission rows; every
command row drags, the Mission root row only receives, and where the pointer sits in the target row
decides the operation. A plain command row has no edge band: it splits at its midline, the upper
half putting the dragged command before that row and the lower half after it — a reorder when both
share a list, a relocation across lists otherwise. A List row keeps that before / after reading only
in its top and bottom quarters; its middle half, and the whole of the Mission root row, take the
command into that list, at the tail. A drop onto the dragged row's own subtree is
refused, and a drop aborts when a rebuild mid-drag re-stamped the dragged node, since its id may then
name another command. All five run through one helper that holds a busy gate
(one operation at a time), runs the open panel's dirty-switch gate, calls the Mission API, translates
the expansion list and the Add Command focus through the operation, rebuilds the branch of the list
or lists it rewrote — the one list, or the nearest list above both ends of a cross-list drag — and
only then translates the selection and names any post-operation selection, since the ids it names
exist only after the rebuild. A refused gate drops the operation and says so in a notification
(&quot;Cancelled — the open editor keeps its unsaved edits.&quot;); the delete's own confirm dialog runs
before the gate, so a cancelled delete forces no save prompt on the open editor.</p>
<p>The selection moves only when it rides on the acted-on row — that row itself, or a section or
nested entry under it. Then it follows a stepped or dragged command, lands on the clone after a
duplicate, and after a delete lands on the nearest remaining entry of that list, or on the list
node itself once the list is empty. Otherwise the editor the user is in stays on its own,
re-indexed row. Add Command never moves the selection: it reveals the new row and makes it the
focus, so a run of adds lands in order. The focus is the command most recently selected — a section
row counts for its owning command — or the last one added, and an Add Command from a list row's <code>+</code>
inserts right after that focus when the focus is a direct entry of that list, and at the list's
tail otherwise; the Mission root row's <code>+</code> therefore never chases a focus inside a nested list.</p>
<h3 id="whole-tree-rebuilds-and-the-refreshes-that-are-not-rebuilds">Whole-tree rebuilds, and the refreshes that are not rebuilds</h3> <h3 id="whole-tree-rebuilds-and-the-refreshes-that-are-not-rebuilds">Whole-tree rebuilds, and the refreshes that are not rebuilds</h3>
<p><code>rebuildTree()</code> replaces the root array outright, and runs after an Object-Management swap of the <p><code>rebuildTree()</code> replaces the root array outright, and runs after an Object-Management swap of the
machine tool or the fixture, after a blank machining chain is created, and after either runner-suit machine tool or the fixture, after a blank machining chain is created, and after either runner-suit
@@ -258,30 +300,38 @@ to the model, and the pages' canvases draw that model; the group stems and the M
Workpiece roots have no field editor to commit for at all.</p> Workpiece roots have no field editor to commit for at all.</p>
<h2 id="selection-and-the-dirty-switch-gate">Selection and the Dirty-Switch Gate</h2> <h2 id="selection-and-the-dirty-switch-gate">Selection and the Dirty-Switch Gate</h2>
<p>Every selection change funnels through <code>requestSelect(id)</code>. It returns immediately when the id is <p>Every selection change funnels through <code>requestSelect(id)</code>. It returns immediately when the id is
already selected; otherwise it awaits the mounted panel's optional <code>tryConsumeBeforeSwitch()</code> and already selected; it refuses outright while a mission row operation, or a tick's own writes, are in
abandons the switch when that returns false.</p> flight — the operation ends by naming the post-operation selection, which would silently undo a
change landed during its rebuild; otherwise it awaits the mounted panel's optional
<code>tryConsumeBeforeSwitch()</code> and abandons the switch when that returns false.</p>
<p>Three entrances use it: a click in the tree, a change to the URL's <code>?tree=</code> value, and a <code>select-node</code> <p>Three entrances use it: a click in the tree, a change to the URL's <code>?tree=</code> value, and a <code>select-node</code>
event from the mounted panel — the wire the panel host puts on every registry panel, so a group stem's event from the mounted panel — the wire the panel host puts on every registry panel, so a group stem's
child list, a mission list's entry row and the Program branch's conversion jumps all arrive through child list and the Program branch's conversion jumps both arrive through that one. Two paths assign
that one. A fourth path — the <code>selectId</code> of a structure change — assigns the selection directly and the selection directly and skip the gate: the <code>selectId</code> of a structure change, and the
skips the gate.</p> post-operation selection of a mission row operation, which has already run the gate itself.</p>
<p>There is no &ldquo;nothing selected&rdquo; state. Re-clicking the selected row makes the tree yield <code>null</code>, and <p>There is no &ldquo;nothing selected&rdquo; state. Re-clicking the selected row makes the tree yield <code>null</code>, and
that is ignored; an empty <code>?tree=</code> lands on the persisted last selection for that page when the built that is ignored; an empty <code>?tree=</code> lands on the persisted last selection for that page when the built
tree still contains it, and on the page's root otherwise. The editor row is therefore always alive, tree still contains it, and otherwise on the page's root — General Setup on the equipment host, and
Mission, the first of its two roots, on the execution host. The editor row is therefore always alive,
and reclaiming its height is the row's own collapse toggle rather than a deselection.</p> and reclaiming its height is the row's own collapse toggle rather than a deselection.</p>
<p>The gate itself is registered by the panel host: the mounted registry panel is handed to the host <p>The gate itself is registered by the panel host: the mounted registry panel is handed to the host
through a template ref, and the host asks that instance for <code>tryConsumeBeforeSwitch</code>. Panels that through a template ref, and the host asks that instance for <code>tryConsumeBeforeSwitch</code>. Panels that
write one field per request need no gate and register none. One panel exposes it — write one field per request need no gate and register none. One panel exposes it —
<code>MissionCommandSlavePanel</code>:</p> <code>MissionCommandSlavePanel</code>:</p>
<ul> <ul>
<li>on a <code>list</code> entry it flushes the debounced title save while the command path is still live, then <li>on a <code>list</code> entry it waits for a title save already on the wire, then flushes the debounced title
allows the switch;</li> save while the command path is still live, and allows the switch only when that save landed;</li>
<li>on any other entry it forwards its inner editor's gate. Today only the script editor has one: with <li>on any other entry it forwards its inner editor's gate. Two editors have one. The Script editor
unsaved text it asks save, discard or cancel, returning false on cancel and on a flush that ends in first lets a save already on the wire land, then with unsaved text asks save, discard or cancel:
an error.</li> cancel returns false, discard reverts to the last confirmed text and puts the autosave to sleep
until the next keystroke, and save proceeds only when the flush landed — a conflict answered with
Cancel leaves the edit staged and the switch refused. The NC Code editor waits for a save on the
wire, drains its debounced field save, and returns false when that save failed.</li>
</ul> </ul>
<p>The same gate is run before duplicating a command, so the clone is made from what has just been typed <p>The same gate runs before every mission row operation, not only before a selection change, because
rather than from the last saved state.</p> the operation's rebuild remounts the open editor and mission paths are index-based: a debounced save
that outlived the remount would land on whichever command slid into the path it captured at mount.
For the same reason both the NC Code editor and the list title cancel, never flush, on unmount.</p>
<h2 id="display-labels">Display Labels</h2> <h2 id="display-labels">Display Labels</h2>
<p><code>nodeDisplayLabel(n)</code> returns the translation of <code>labelKey</code> — with <code>labelParams</code> interpolated — when <p><code>nodeDisplayLabel(n)</code> returns the translation of <code>labelKey</code> — with <code>labelParams</code> interpolated — when
one is set, and the verbatim <code>label</code> otherwise. <code>labelKey</code> is therefore the form every role label the one is set, and the verbatim <code>label</code> otherwise. <code>labelKey</code> is therefore the form every role label the
@@ -316,10 +366,14 @@ the selection's type registers no panel.</li>
key, and the mission stamp where the node has one. So the editor remounts when the selection moves, key, and the mission stamp where the node has one. So the editor remounts when the selection moves,
when the bound object's key is re-minted, and when the Mission branch was rebuilt beneath it. That when the bound object's key is re-minted, and when the Mission branch was rebuilt beneath it. That
third term is exactly why the mission label refresh above mutates the node instead of rebuilding.</p> third term is exactly why the mission label refresh above mutates the node instead of rebuilding.</p>
<p>On the Execution page the editor row grows a header: the transport bar is pinned above the scroll area <p>The editor row carries nothing but the editor. The run controls sit in the tree pane instead: on the
whenever the Execution root or any of its descendants is selected, so the run controls never scroll Execution page the Control Tree pane pins a run header above its tree scroller — the transport bar
away; that one instance also owns the transport's function-key shortcuts, which are attached for as and the live execution-status badge — whatever the selection is. It rides the pane's content rather
long as it is mounted.</p> than the dock's expansion header because that header is the same component on General Setup, which
renders neither piece. This is the page's sole <code>ExecutionToolBar</code>, so it owns the F5F8 shortcuts,
and because the dock keeps the tree pane mounted while its row is collapsed, a collapsed tree row
does not drop them. When the tree column narrows, the six-button strip scrolls horizontally and the
badge never shrinks, so the run state is the last thing a resize can hide.</p>
<p>A pure <code>Group</code> stem is not a node without an editor. <code>Group</code> registers <code>GroupInfoPanel</code>, whose body is <p>A pure <code>Group</code> stem is not a node without an editor. <code>Group</code> registers <code>GroupInfoPanel</code>, whose body is
the stem's intro line followed by a clickable list of its children; a row click emits <code>select-node</code> the stem's intro line followed by a clickable list of its children; a row click emits <code>select-node</code>
and the host moves the selection there. The General Setup root, the two Anchor stems, the workpiece and the host moves the selection there. The General Setup root, the two Anchor stems, the workpiece
@@ -341,7 +395,10 @@ a mission section that carries its own enable flag. Writing the ticked set walks
any depth: a command whose state changed is PUT to the Mission API and, on success, has the new state any depth: a command whose state changed is PUT to the Mission API and, on success, has the new state
copied onto its section children; a section whose state changed is dispatched to its kind's writer. A copied onto its section children; a section whose state changed is dispatched to its kind's writer. A
failed write raises a toast and leaves the model untouched, so the getter re-derives the old value and failed write raises a toast and leaves the model untouched, so the getter re-derives the old value and
the box snaps back.</p> the box snaps back. The ticks share the mission operations' busy gate in both directions: a tick
during a row operation is ignored — it would write to the node's pre-operation path — and the box
snaps back the same way, while a tick's own writes hold the gate so no row operation can overtake
them on the server and land the enable flag on whichever command slid into the ticked path.</p>
<p>A row dims when it is itself disabled — a disabled command, or a section whose own flag is off — or <p>A row dims when it is itself disabled — a disabled command, or a section whose own flag is off — or
when an ancestor command is disabled, which is how a disabled command greys its whole subtree while when an ancestor command is disabled, which is how a disabled command greys its whole subtree while
each descendant keeps its own state. The switch decides only whether the command runs: a disabled each descendant keeps its own state. The switch decides only whether the command runs: a disabled
@@ -350,17 +407,43 @@ command stays fully editable.</p>
<ul> <ul>
<li>Left Dock — both tree pages, one nav-bar button toggling the whole column <li>Left Dock — both tree pages, one nav-bar button toggling the whole column
<ul> <ul>
<li><strong>Control Tree</strong> Expansion Row — collapses in place, keeping its header; stays mounted while <li><strong>Control Tree</strong> Expansion Row — collapses in place, keeping its header, which is the same
collapsed, so the tree keeps its scroll position page-neutral header on both pages; stays mounted while collapsed, so the tree keeps its scroll
position and the run header keeps its shortcuts
<ul> <ul>
<li>Tree — one root row per page: <strong>Execution</strong> or <strong>General Setup</strong> <li>Run Header — Execution page only, pinned above the tree scroller and separated from it by a
rule
<ul> <ul>
<li>Execution Transport Bar — the six transport buttons; the strip scrolls horizontally when the
column is narrower than it</li>
<li>Execution Status Badge — the status label in its status colour; never shrinks</li>
</ul>
</li>
<li>Tree — the Execution page has two root rows, <strong>Mission</strong> above <strong>Program</strong>; the General Setup
page has one, <strong>General Setup</strong>
<ul>
<li>Drag Handle — on every mission command row, List rows included, immediately before the
label. It is the first thing the row's own header renders, but the tree puts the expand
arrow, on a row with children, and then the enable checkbox ahead of that header, so the
handle sits to the checkbox's right rather than at the row's left edge. The Mission root row
has none. While a drag is under way the dragged row dims, a line along the target row's top
or bottom edge marks a before / after drop, and a tinted target row marks a drop into that
list</li>
<li>Node Row — the label is a real link to this node's <code>?tree=</code> URL on the page, so the browser's <li>Node Row — the label is a real link to this node's <code>?tree=</code> URL on the page, so the browser's
context menu offers open-in-new-tab and copy-link; a plain left click keeps the in-app context menu offers open-in-new-tab and copy-link; a plain left click keeps the in-app
selection instead of navigating, while a modified or middle click opens a tab and leaves the selection instead of navigating, while a modified or middle click opens a tab and leaves the
current selection where it is. No icons are rendered.</li> current selection where it is. No node icons are rendered.</li>
<li>Node CheckBox — mission command rows, and mission section rows carrying an enable flag</li> <li>Node CheckBox — mission command rows, and mission section rows carrying an enable flag</li>
<li>Execution Status Badge — on the <strong>Execution</strong> root row only</li> <li>Row Operations — on every mission command row, right-aligned: <strong>Move up</strong>, <strong>Move down</strong>,
<strong>Duplicate</strong> and <strong>Delete</strong>. Absent from the layout at rest, so a resting label keeps the
column's full width, and shown on the hovered row and on the selected row; on a device with
no hover they are always shown. Move up is disabled on a list's first entry, Move down on its
last, and all four while an operation is in flight</li>
<li>Add Command — the <code>+</code> at the right edge of the Mission root row and of every List row,
always visible, scoped to that row's list; disabled without an open project and while an
operation is in flight. It opens the Add Command dialog — a search box over the command
catalog, grouped by category, which fetches the catalog on every opening and accepts one
pick per opening</li>
</ul> </ul>
</li> </li>
<li>Spinner and &ldquo;Loading project…&rdquo; — shown instead of the tree until the first build lands</li> <li>Spinner and &ldquo;Loading project…&rdquo; — shown instead of the tree until the first build lands</li>
@@ -372,7 +455,6 @@ down to a 120 px editor floor and a 100 px tree floor</li>
<li><strong>Editor</strong> Expansion Row — its header carries the selection breadcrumb, the node path joined with <li><strong>Editor</strong> Expansion Row — its header carries the selection breadcrumb, the node path joined with
slashes, and falls back to <strong>Editor</strong>; stays mounted while collapsed slashes, and falls back to <strong>Editor</strong>; stays mounted while collapsed
<ul> <ul>
<li>Execution Transport Bar — Execution page, while an Execution-scope node is selected</li>
<li>The selected node's editor panel, or &ldquo;Select an item in the Control Tree to edit it here.&rdquo;</li> <li>The selected node's editor panel, or &ldquo;Select an item in the Control Tree to edit it here.&rdquo;</li>
</ul> </ul>
</li> </li>
@@ -405,17 +487,28 @@ when the project changes, and a host is therefore created once per project per p
<p>HiNC-2025-webservice (Quasar CLI SPA):</p> <p>HiNC-2025-webservice (Quasar CLI SPA):</p>
<ul> <ul>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — the host: the two scopes' root <li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — the host: the two scopes' root
builders, the selection gate, the <code>?tree=</code> sync, the mission ticks, the rebuild entry points, the builders, the selection gate, the <code>?tree=</code> sync, the mission ticks, the five mission row
re-index and Object-Management handlers, and the reactive surface the panes consume.</li> operations with their shared busy gate and id translation, the rebuild entry points, the re-index
and Object-Management handlers, and the reactive surface the panes consume.</li>
<li><code>wwwroot-src/src/components/controlTree/useMissionTreeDrag.ts</code> — the drag-and-drop bookkeeping
between mission rows: which rows drag, the drop mode from the pointer's position in the target
row, and the row classes behind the drop indicators.</li>
<li><code>wwwroot-src/src/components/controlTree/itemTypes.ts</code> — the <code>ControlNode</code> and <code>TreeItemDef</code> shapes, <li><code>wwwroot-src/src/components/controlTree/itemTypes.ts</code> — the <code>ControlNode</code> and <code>TreeItemDef</code> shapes,
the <code>SlotCtx</code> hooks, the structure-change payload, <code>nodeDisplayLabel</code> / <code>nodeDisplayInfo</code>, the the <code>SlotCtx</code> hooks, the structure-change payload, <code>nodeDisplayLabel</code> / <code>nodeDisplayInfo</code>, the
geometry and transformer builders, the <code>ITEM_TYPES</code> map and <code>buildSubtree</code>.</li> geometry and transformer builders, the <code>ITEM_TYPES</code> map and <code>buildSubtree</code>.</li>
<li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree column: the node anchors, <li><code>wwwroot-src/src/components/controlTree/ControlTreePanel.vue</code> — the tree column: the Execution
the click handling that keeps a plain click in-app, and the execution-status badge.</li> page's run header with the transport bar and the execution-status badge, the node anchors, the
click handling that keeps a plain click in-app, the drag handles, the row operations, the Add
Command <code>+</code> and the dialog it opens.</li>
<li><code>wwwroot-src/src/components/execution/ExecutionToolBar.vue</code> — the six transport buttons, and the
F5F8 shortcuts the sole instance registers.</li>
<li><code>wwwroot-src/src/utils/executionStatusPresent.ts</code> — the badge's status label and colour.</li>
<li><code>wwwroot-src/src/components/controlTree/AddCommandDialog.vue</code> — the search-first command picker
over the server-served catalog.</li>
<li><code>wwwroot-src/src/components/controlTree/ControlTreeDock.vue</code> — the two-row dock and the height <li><code>wwwroot-src/src/components/controlTree/ControlTreeDock.vue</code> — the two-row dock and the height
divider that sets the editor row's stored pixel height.</li> divider that sets the editor row's stored pixel height.</li>
<li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — the panel host: the three inline <li><code>wwwroot-src/src/components/controlTree/PrimarySlavePanel.vue</code> — the panel host: the three inline
root types, the registry lookup, the remount key, the gate registration and the transport header.</li> root types, the registry lookup, the remount key and the gate registration.</li>
<li><code>wwwroot-src/src/components/controlTree/ContentSlavePanel.vue</code> — the General Setup content column <li><code>wwwroot-src/src/components/controlTree/ContentSlavePanel.vue</code> — the General Setup content column
and its unkeyed content panel.</li> and its unkeyed content panel.</li>
<li><code>wwwroot-src/src/components/controlTree/GroupInfoPanel.vue</code> — a group stem's intro and its <li><code>wwwroot-src/src/components/controlTree/GroupInfoPanel.vue</code> — a group stem's intro and its
@@ -433,10 +526,22 @@ the core leaves every runner grows, and the snapshot flags that decide which bra
<li><code>wwwroot-src/src/components/controlTree/toolHouseItemTypes.ts</code> — the Tool House wave and its <li><code>wwwroot-src/src/components/controlTree/toolHouseItemTypes.ts</code> — the Tool House wave and its
<code>tool-&lt;id&gt;</code> role paths.</li> <code>tool-&lt;id&gt;</code> role paths.</li>
<li><code>wwwroot-src/src/components/controlTree/runnerSuitItemTypes.ts</code> — the two runner-suit leaves.</li> <li><code>wwwroot-src/src/components/controlTree/runnerSuitItemTypes.ts</code> — the two runner-suit leaves.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — the command control bar, and <li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — the Mission root's informational
the only panel that exposes a dirty-switch gate.</li> panel: the command count and the run-order hint.</li>
<li><code>wwwroot-src/src/components/controlTree/ProgramRootPanel.vue</code> — the Program root's summary panel
and the refresh button that emits a payload-less <code>structure-changed</code>.</li>
<li><code>wwwroot-src/src/components/controlTree/GeomCombinationTreePanel.vue</code> — the combination's item list,
whose add, remove and clear emit the same payload-less event.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — a command's editor host: a
List's Title field with its debounced save, and the only panel that exposes a dirty-switch gate.</li>
<li><code>wwwroot-src/src/components/mission/ScriptCommandPanel.vue</code> — the autosaving editor whose gate is <li><code>wwwroot-src/src/components/mission/ScriptCommandPanel.vue</code> — the autosaving editor whose gate is
forwarded, with its save / discard / cancel prompt.</li> forwarded, with its save / discard / cancel prompt.</li>
<li><code>wwwroot-src/src/composables/useAutoSave.ts</code> — the Script editor's autosave: the flush, the wait
for a save on the wire, and the discard that sleeps the instance until the next edit.</li>
<li><code>wwwroot-src/src/components/mission/NcCodeCommandPanel.vue</code> — the second forwarded gate: the
debounced field save it drains, and the unmount that cancels instead of flushing.</li>
<li><code>wwwroot-src/src/components/mission/NcFileCommandPanel.vue</code> — the one command editor that emits
<code>structure-changed</code>, with the <code>inserted</code> range of its multi-pick.</li>
<li><code>wwwroot-src/src/components/panels/PanelExpansion.vue</code> — the expansion row both dock rows are built <li><code>wwwroot-src/src/components/panels/PanelExpansion.vue</code> — the expansion row both dock rows are built
from.</li> from.</li>
<li><code>wwwroot-src/src/composables/useViewPrefs.ts</code> — the device-local expansion list, last selections, <li><code>wwwroot-src/src/composables/useViewPrefs.ts</code> — the device-local expansion list, last selections,
@@ -148,7 +148,7 @@ A bump discards every cached page and rebuilds it, so each page initializes on i
watching for project changes itself.</li> watching for project changes itself.</li>
<li>Bottom footer — the routine-progress bar: the latest foreground message with a recent-messages history menu on the left, the live session status in the middle, and in-flight background job progress on the right. See <a class="xref" href="bottom-message-bar.html">Message Section on Main Panel</a>.</li> <li>Bottom footer — the routine-progress bar: the latest foreground message with a recent-messages history menu on the left, the live session status in the middle, and in-flight background job progress on the right. See <a class="xref" href="bottom-message-bar.html">Message Section on Main Panel</a>.</li>
</ul> </ul>
<p>The menu bar carries no run tool bars at all: the transport controls ride the <a class="xref" href="../execution/index.html">Execution Page</a>&lsquo;s primary panel header and the view controls ride its canvas panel header. What the menu bar keeps instead is the page's set of column quick-toggles, the connection badge, the active page's title, the <code>Show Log</code> button and — when authentication is on — the logout button. The toggles follow whichever tree page is current: four on the Execution page (control dock, canvas, strip charts, step info) and three on General Setup (control dock, content, canvas); the Tool House page lays itself out with plain splitters and gets none. The connection badge is Execution-only — the other pages&rsquo; canvases carry their own in-panel badges.</p> <p>The menu bar carries no run tool bars at all: the transport controls and the execution status badge ride the run header the <a class="xref" href="../execution/index.html">Execution Page</a>&lsquo;s Control Tree pane pins above its tree, and the view controls ride its canvas panel header. What the menu bar keeps instead is the page's set of column quick-toggles, the connection badge, the active page's title, the <code>Show Log</code> button and — when authentication is on — the logout button. The toggles follow whichever tree page is current: four on the Execution page (control dock, canvas, strip charts, step info) and three on General Setup (control dock, content, canvas); the Tool House page lays itself out with plain splitters and gets none. The connection badge is Execution-only — the other pages&rsquo; canvases carry their own in-panel badges.</p>
<h2 id="project-menu-behavior">Project Menu Behavior</h2> <h2 id="project-menu-behavior">Project Menu Behavior</h2>
<p>The <code>Project Path Text Field</code> displays the current project path when a project is loaded. It is implemented as a pure text field (not a button) that allows users to select and copy the path.</p> <p>The <code>Project Path Text Field</code> displays the current project path when a project is loaded. It is implemented as a pure text field (not a button) that allows users to select and copy the path.</p>
<p>The <code>Project</code> Menu manages <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a> with the following operations:</p> <p>The <code>Project</code> Menu manages <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a> with the following operations:</p>
@@ -732,6 +732,51 @@ All native-backed members become no-ops afterwards
<a id="Hi_Disp_DispEngine_IsGlAvailable_" data-uid="Hi.Disp.DispEngine.IsGlAvailable*"></a>
<h3 id="Hi_Disp_DispEngine_IsGlAvailable" data-uid="Hi.Disp.DispEngine.IsGlAvailable">
IsGlAvailable
</h3>
<div class="markdown level1 summary"><p>Whether this process has a usable OpenGL context, i.e. whether 3D
rendering is available at all.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static bool IsGlAvailable { get; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd></dd>
</dl>
<h4 class="section" id="Hi_Disp_DispEngine_IsGlAvailable_remarks">Remarks</h4>
<div class="markdown level1 remarks"><p>False on a host with no usable GL — a driver whose kernel module and
userspace disagree, a container started without <code>/dev/dri</code>, a VM
with no 3D pass-through. The process still runs: NC play, physics,
training and every non-rendering API are unaffected, because none of
them touch the display engine. What is not available is the engine
itself, so callers must not construct or ask for a <a class="xref" href="Hi.Disp.DispEngine.html">DispEngine</a>
while this is false rather than guarding individual draw calls.
Meaningful only after <a class="xref" href="Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_Init_System_String_">Init(string)</a> has run; it is false
before that for the same reason it is false on a broken host, so read
it only from code that runs after application start-up.</p>
</div>
<a id="Hi_Disp_DispEngine_IsOnDispThread_" data-uid="Hi.Disp.DispEngine.IsOnDispThread*"></a> <a id="Hi_Disp_DispEngine_IsOnDispThread_" data-uid="Hi.Disp.DispEngine.IsOnDispThread*"></a>
<h3 id="Hi_Disp_DispEngine_IsOnDispThread" data-uid="Hi.Disp.DispEngine.IsOnDispThread"> <h3 id="Hi_Disp_DispEngine_IsOnDispThread" data-uid="Hi.Disp.DispEngine.IsOnDispThread">
@@ -565,6 +565,41 @@ This is for internal use only.</p>
<a id="Hi_MachiningProcs_MachiningActRunner_RapidCutMonitor_" data-uid="Hi.MachiningProcs.MachiningActRunner.RapidCutMonitor*"></a>
<h3 id="Hi_MachiningProcs_MachiningActRunner_RapidCutMonitor" data-uid="Hi.MachiningProcs.MachiningActRunner.RapidCutMonitor">
RapidCutMonitor
</h3>
<div class="markdown level1 summary"><p>Folds rapid-traverse steps that removed stock into one
<code>Play-RapidCut&ndash;Detected</code> warning per NC line. Fed on the
sequential post-physics stage, flushed by the session at the end of a
play, reset with the state.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public RapidCutMonitor RapidCutMonitor { get; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html">RapidCutMonitor</a></dt>
<dd></dd>
</dl>
<a id="Hi_MachiningProcs_MachiningActRunner_ShellThreadStepIndex_" data-uid="Hi.MachiningProcs.MachiningActRunner.ShellThreadStepIndex*"></a> <a id="Hi_MachiningProcs_MachiningActRunner_ShellThreadStepIndex_" data-uid="Hi.MachiningProcs.MachiningActRunner.ShellThreadStepIndex*"></a>
<h3 id="Hi_MachiningProcs_MachiningActRunner_ShellThreadStepIndex" data-uid="Hi.MachiningProcs.MachiningActRunner.ShellThreadStepIndex"> <h3 id="Hi_MachiningProcs_MachiningActRunner_ShellThreadStepIndex" data-uid="Hi.MachiningProcs.MachiningActRunner.ShellThreadStepIndex">
@@ -631,6 +631,47 @@ Default <a class="xref" href="Hi.NcParsers.Dependencys.Generic.RadiusOffsetBasis
<a id="Hi_MachiningProcs_MachiningActRunnerConfig_RapidCutVolumeThreshold_mm3_" data-uid="Hi.MachiningProcs.MachiningActRunnerConfig.RapidCutVolumeThreshold_mm3*"></a>
<h3 id="Hi_MachiningProcs_MachiningActRunnerConfig_RapidCutVolumeThreshold_mm3" data-uid="Hi.MachiningProcs.MachiningActRunnerConfig.RapidCutVolumeThreshold_mm3">
RapidCutVolumeThreshold_mm3
</h3>
<div class="markdown level1 summary"><p>Removed-stock volume, in mm³, below which a rapid traverse that touched
the workpiece is not reported. The steps of one NC line that were
commanded as rapid traverse (G00) and touched the stock fold into one
<code>Play-RapidCut&ndash;Detected</code> warning carrying the line's total removed
volume and its largest cutting depth (<a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html">RapidCutMonitor</a>);
the warning is emitted only when that total reaches this threshold.
Default 0: any contact reports. Steps with the spindle stopped are left
to collision detection while <a class="xref" href="Hi.MachiningProcs.MachiningActRunnerConfig.html#Hi_MachiningProcs_MachiningActRunnerConfig_EnableCollisionDetection">EnableCollisionDetection</a> is
on. Project-level on purpose: the same project must report the same
lines on every machine.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public double RapidCutVolumeThreshold_mm3 { get; set; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.double">double</a></dt>
<dd></dd>
</dl>
<a id="Hi_MachiningProcs_MachiningActRunnerConfig_XName_" data-uid="Hi.MachiningProcs.MachiningActRunnerConfig.XName*"></a> <a id="Hi_MachiningProcs_MachiningActRunnerConfig_XName_" data-uid="Hi.MachiningProcs.MachiningActRunnerConfig.XName*"></a>
<h3 id="Hi_MachiningProcs_MachiningActRunnerConfig_XName" data-uid="Hi.MachiningProcs.MachiningActRunnerConfig.XName"> <h3 id="Hi_MachiningProcs_MachiningActRunnerConfig_XName" data-uid="Hi.MachiningProcs.MachiningActRunnerConfig.XName">
@@ -0,0 +1,557 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Struct RapidCutMonitor.Sample | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Struct RapidCutMonitor.Sample | HiAPI-C# 2025 ">
<meta name="description" content="One built step as the monitor sees it — the few facts the fold needs, detached from so the fold is testable on synthetic steps.">
<link rel="icon" href="../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../public/docfx.min.css">
<link rel="stylesheet" href="../public/main.css">
<meta name="docfx:navrel" content="../toc.html">
<meta name="docfx:tocrel" content="toc.html">
<meta name="docfx:rel" content="../">
<meta name="loc:inThisArticle" content="In this article">
<meta name="loc:searchResultsCount" content="{count} results for &quot;{query}&quot;">
<meta name="loc:searchNoResults" content="No results for &quot;{query}&quot;">
<meta name="loc:tocFilter" content="Filter by title">
<meta name="loc:nextArticle" content="Next">
<meta name="loc:prevArticle" content="Previous">
<meta name="loc:themeLight" content="Light">
<meta name="loc:themeDark" content="Dark">
<meta name="loc:themeAuto" content="Auto">
<meta name="loc:changeTheme" content="Change theme">
<meta name="loc:copy" content="Copy">
<meta name="loc:downloadPdf" content="Download PDF">
<script type="module" src="./../public/docfx.min.js"></script>
<script>
const theme = localStorage.getItem('theme') || 'auto'
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
</script>
</head>
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="ManagedReference">
<header class="bg-body border-bottom">
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
<div class="container-xxl flex-nowrap">
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../img/HiAPI.logo.png" alt="">
</a>
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
<i class="bi bi-three-dots"></i>
</button>
<div class="collapse navbar-collapse" id="navpanel">
<div id="navbar">
<form class="search" role="search" id="search">
<i class="bi bi-search"></i>
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
</form>
</div>
</div>
</div>
</nav>
</header>
<main class="container-xxl">
<div class="toc-offcanvas">
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<nav class="toc" id="toc"></nav>
</div>
</div>
</div>
<div class="content">
<div class="actionbar">
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
<i class="bi bi-list"></i>
</button>
<nav id="breadcrumb"></nav>
</div>
<article data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample">
<h1 id="Hi_MachiningProcs_RapidCutMonitor_Sample" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample" class="text-break">
Struct RapidCutMonitor.Sample
</h1>
<div class="facts text-secondary">
<dl><dt>Namespace</dt><dd><a class="xref" href="Hi.html">Hi</a>.<a class="xref" href="Hi.MachiningProcs.html">MachiningProcs</a></dd></dl>
<dl><dt>Assembly</dt><dd>HiMech.dll</dd></dl>
</div>
<div class="markdown summary"><p>One built step as the monitor sees it — the few facts the fold needs,
detached from <a class="xref" href="Hi.MachiningSteps.MachiningStep.html">MachiningStep</a> so the fold is testable on
synthetic steps.</p>
</div>
<div class="markdown conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public readonly record struct RapidCutMonitor.Sample : IEquatable&lt;RapidCutMonitor.Sample&gt;</code></pre>
</div>
<dl class="typelist implements">
<dt>Implements</dt>
<dd>
<div><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.iequatable-1">IEquatable</a>&lt;<a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html">RapidCutMonitor</a>.<a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.Sample.html">Sample</a>&gt;</div>
</dd>
</dl>
<dl class="typelist inheritedMembers">
<dt>Inherited Members</dt>
<dd>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.valuetype.equals">ValueType.Equals(object)</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.valuetype.gethashcode">ValueType.GetHashCode()</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.valuetype.tostring">ValueType.ToString()</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)">object.Equals(object, object)</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.gettype">object.GetType()</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.referenceequals">object.ReferenceEquals(object, object)</a>
</div>
</dd></dl>
<dl class="typelist extensionMethods">
<dt>Extension Methods</dt>
<dd>
<div>
<a class="xref" href="Hi.Common.InvokeUtil.html#Hi_Common_InvokeUtil_SelfInvoke__1___0_System_Action___0__">InvokeUtil.SelfInvoke&lt;TSrc&gt;(TSrc, Action&lt;TSrc&gt;)</a>
</div>
<div>
<a class="xref" href="Hi.Common.InvokeUtil.html#Hi_Common_InvokeUtil_SelfInvoke__2___0_System_Func___0___1__">InvokeUtil.SelfInvoke&lt;TSrc, TDst&gt;(TSrc, Func&lt;TSrc, TDst&gt;)</a>
</div>
<div>
<a class="xref" href="Hi.Common.MaskUtil.html#Hi_Common_MaskUtil_GetMaskedValue__1___0___0_System_Boolean_">MaskUtil.GetMaskedValue&lt;T&gt;(T, T, bool)</a>
</div>
<div>
<a class="xref" href="Hi.Common.MaskUtil.html#Hi_Common_MaskUtil_SetMask__1___0____0_System_Boolean_">MaskUtil.SetMask&lt;T&gt;(ref T, T, bool)</a>
</div>
<div>
<a class="xref" href="Hi.Coloring.ColorUtil.html#Hi_Coloring_ColorUtil_GetGloomyColor_System_Object_System_Double_System_Double_">ColorUtil.GetGloomyColor(object, double, double)</a>
</div>
<div>
<a class="xref" href="Hi.Common.NameUtil.html#Hi_Common_NameUtil_GetSelectionName_System_Object_">NameUtil.GetSelectionName(object)</a>
</div>
<div>
<a class="xref" href="Hi.Common.StringUtil.html#Hi_Common_StringUtil_GetPropertyStringIfToStringNotOverloaded_System_Object_System_Boolean_System_Boolean_">StringUtil.GetPropertyStringIfToStringNotOverloaded(object, bool, bool)</a>
</div>
<div>
<a class="xref" href="Hi.Parallels.LockUtil.html#Hi_Parallels_LockUtil_Lock_System_Object_">LockUtil.Lock(object)</a>
</div>
</dd></dl>
<h2 class="section" id="constructors">Constructors
</h2>
<a id="Hi_MachiningProcs_RapidCutMonitor_Sample__ctor_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.#ctor*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_Sample__ctor_System_Int32_System_Nullable_System_Int32__System_Object_Hi_NcParsers_ISentenceCarrier_System_Boolean_System_Boolean_System_Boolean_System_Double_System_Double_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.#ctor(System.Int32,System.Nullable{System.Int32},System.Object,Hi.NcParsers.ISentenceCarrier,System.Boolean,System.Boolean,System.Boolean,System.Double,System.Double)">
Sample(int, int?, object, ISentenceCarrier, bool, bool, bool, double, double)
</h3>
<div class="markdown level1 summary"><p>One built step as the monitor sees it — the few facts the fold needs,
detached from <a class="xref" href="Hi.MachiningSteps.MachiningStep.html">MachiningStep</a> so the fold is testable on
synthetic steps.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public Sample(int StepIndex, int? LineNo, object LineKey, ISentenceCarrier Carrier, bool IsRapid, bool IsTouched, bool IsSpindleStopped, double RemovedVolume_mm3, double CuttingDepth_mm)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>StepIndex</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.int32">int</a></dt>
<dd><p>Execution-order index of the step.</p>
</dd>
<dt><code>LineNo</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.int32">int</a>?</dt>
<dd><p>NC line number, or null where the runner carries none (CSV / CL replay).</p>
</dd>
<dt><code>LineKey</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object">object</a></dt>
<dd><p>Fold key: the line number when known, else the sentence, else the step index.</p>
</dd>
<dt><code>Carrier</code> <a class="xref" href="Hi.NcParsers.ISentenceCarrier.html">ISentenceCarrier</a></dt>
<dd><p>NC-source carrier of the step; anchors the report. May be null.</p>
</dd>
<dt><code>IsRapid</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>Whether the step was commanded as rapid traverse.</p>
</dd>
<dt><code>IsTouched</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>Whether the step touched the workpiece.</p>
</dd>
<dt><code>IsSpindleStopped</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>Whether the spindle was stopped on this step.</p>
</dd>
<dt><code>RemovedVolume_mm3</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.double">double</a></dt>
<dd><p>Stock removed by this step in mm³ (0 when untouched or unknown).</p>
</dd>
<dt><code>CuttingDepth_mm</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.double">double</a></dt>
<dd><p>Axial cutting depth of this step in mm (0 when untouched).</p>
</dd>
</dl>
<h2 class="section" id="properties">Properties
</h2>
<a id="Hi_MachiningProcs_RapidCutMonitor_Sample_Carrier_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.Carrier*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_Sample_Carrier" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.Carrier">
Carrier
</h3>
<div class="markdown level1 summary"><p>NC-source carrier of the step; anchors the report. May be null.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public ISentenceCarrier Carrier { get; init; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="Hi.NcParsers.ISentenceCarrier.html">ISentenceCarrier</a></dt>
<dd></dd>
</dl>
<a id="Hi_MachiningProcs_RapidCutMonitor_Sample_CuttingDepth_mm_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.CuttingDepth_mm*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_Sample_CuttingDepth_mm" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.CuttingDepth_mm">
CuttingDepth_mm
</h3>
<div class="markdown level1 summary"><p>Axial cutting depth of this step in mm (0 when untouched).</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public double CuttingDepth_mm { get; init; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.double">double</a></dt>
<dd></dd>
</dl>
<a id="Hi_MachiningProcs_RapidCutMonitor_Sample_IsRapid_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.IsRapid*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_Sample_IsRapid" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.IsRapid">
IsRapid
</h3>
<div class="markdown level1 summary"><p>Whether the step was commanded as rapid traverse.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public bool IsRapid { get; init; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd></dd>
</dl>
<a id="Hi_MachiningProcs_RapidCutMonitor_Sample_IsSpindleStopped_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.IsSpindleStopped*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_Sample_IsSpindleStopped" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.IsSpindleStopped">
IsSpindleStopped
</h3>
<div class="markdown level1 summary"><p>Whether the spindle was stopped on this step.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public bool IsSpindleStopped { get; init; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd></dd>
</dl>
<a id="Hi_MachiningProcs_RapidCutMonitor_Sample_IsTouched_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.IsTouched*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_Sample_IsTouched" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.IsTouched">
IsTouched
</h3>
<div class="markdown level1 summary"><p>Whether the step touched the workpiece.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public bool IsTouched { get; init; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd></dd>
</dl>
<a id="Hi_MachiningProcs_RapidCutMonitor_Sample_LineKey_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.LineKey*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_Sample_LineKey" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.LineKey">
LineKey
</h3>
<div class="markdown level1 summary"><p>Fold key: the line number when known, else the sentence, else the step index.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public object LineKey { get; init; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object">object</a></dt>
<dd></dd>
</dl>
<a id="Hi_MachiningProcs_RapidCutMonitor_Sample_LineNo_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.LineNo*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_Sample_LineNo" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.LineNo">
LineNo
</h3>
<div class="markdown level1 summary"><p>NC line number, or null where the runner carries none (CSV / CL replay).</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public int? LineNo { get; init; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.int32">int</a>?</dt>
<dd></dd>
</dl>
<a id="Hi_MachiningProcs_RapidCutMonitor_Sample_RemovedVolume_mm3_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.RemovedVolume_mm3*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_Sample_RemovedVolume_mm3" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.RemovedVolume_mm3">
RemovedVolume_mm3
</h3>
<div class="markdown level1 summary"><p>Stock removed by this step in mm³ (0 when untouched or unknown).</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public double RemovedVolume_mm3 { get; init; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.double">double</a></dt>
<dd></dd>
</dl>
<a id="Hi_MachiningProcs_RapidCutMonitor_Sample_StepIndex_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.StepIndex*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_Sample_StepIndex" data-uid="Hi.MachiningProcs.RapidCutMonitor.Sample.StepIndex">
StepIndex
</h3>
<div class="markdown level1 summary"><p>Execution-order index of the step.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public int StepIndex { get; init; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.int32">int</a></dt>
<dd></dd>
</dl>
</article>
<div class="contribution d-print-none">
</div>
</div>
<div class="affix">
<nav id="affix"></nav>
</div>
</main>
<div class="container-xxl search-results" id="search-results"></div>
<footer class="border-top text-secondary">
<div class="container-xxl">
<div class="flex-fill">
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
</div>
</div>
</footer>
</body>
</html>
@@ -0,0 +1,420 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Class RapidCutMonitor | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Class RapidCutMonitor | HiAPI-C# 2025 ">
<meta name="description" content="Reports a rapid traverse that removed stock: the steps of one NC line that were commanded as rapid traverse (G00, ) and touched the workpiece fold into one Play-RapidCut&amp;ndash;Detected validation warning, anchored on the line&#39;s first touching step and carrying the line&#39;s total removed volume and its largest cutting depth. A rapid move through material breaks the tool or crashes the machine on a real run, yet with the spindle turning the engine treats it as ordinary cutting: the collision rule (Hi.Machining.MachiningEquipment.Detect) pairs flute and workpiece only while the spindle is stopped, so such a line used to pass with no message at all. One instance per . runs on the sequential post-physics stage of every built step (one thread, step order), closes the last line at the end of a play and drops a pending line on a session reset; both run on the shell thread after , so no lock is needed. Folding: consecutive rapid steps with the same (the NC line number, or the sentence itself where a runner has no line numbers) form one report; a feed step, a different line or the end of the play closes it. A line re-entered later (a subprogram loop) reports again, deliberately. The report is emitted only when the line&#39;s total removed volume reaches (default 0: any contact). Steps with the spindle stopped are skipped while collision detection is on — that rule owns them and raises Collision--Detected — and counted otherwise.">
<link rel="icon" href="../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../public/docfx.min.css">
<link rel="stylesheet" href="../public/main.css">
<meta name="docfx:navrel" content="../toc.html">
<meta name="docfx:tocrel" content="toc.html">
<meta name="docfx:rel" content="../">
<meta name="loc:inThisArticle" content="In this article">
<meta name="loc:searchResultsCount" content="{count} results for &quot;{query}&quot;">
<meta name="loc:searchNoResults" content="No results for &quot;{query}&quot;">
<meta name="loc:tocFilter" content="Filter by title">
<meta name="loc:nextArticle" content="Next">
<meta name="loc:prevArticle" content="Previous">
<meta name="loc:themeLight" content="Light">
<meta name="loc:themeDark" content="Dark">
<meta name="loc:themeAuto" content="Auto">
<meta name="loc:changeTheme" content="Change theme">
<meta name="loc:copy" content="Copy">
<meta name="loc:downloadPdf" content="Download PDF">
<script type="module" src="./../public/docfx.min.js"></script>
<script>
const theme = localStorage.getItem('theme') || 'auto'
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
</script>
</head>
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="ManagedReference">
<header class="bg-body border-bottom">
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
<div class="container-xxl flex-nowrap">
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../img/HiAPI.logo.png" alt="">
</a>
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
<i class="bi bi-three-dots"></i>
</button>
<div class="collapse navbar-collapse" id="navpanel">
<div id="navbar">
<form class="search" role="search" id="search">
<i class="bi bi-search"></i>
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
</form>
</div>
</div>
</div>
</nav>
</header>
<main class="container-xxl">
<div class="toc-offcanvas">
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<nav class="toc" id="toc"></nav>
</div>
</div>
</div>
<div class="content">
<div class="actionbar">
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
<i class="bi bi-list"></i>
</button>
<nav id="breadcrumb"></nav>
</div>
<article data-uid="Hi.MachiningProcs.RapidCutMonitor">
<h1 id="Hi_MachiningProcs_RapidCutMonitor" data-uid="Hi.MachiningProcs.RapidCutMonitor" class="text-break">
Class RapidCutMonitor
</h1>
<div class="facts text-secondary">
<dl><dt>Namespace</dt><dd><a class="xref" href="Hi.html">Hi</a>.<a class="xref" href="Hi.MachiningProcs.html">MachiningProcs</a></dd></dl>
<dl><dt>Assembly</dt><dd>HiMech.dll</dd></dl>
</div>
<div class="markdown summary"><p>Reports a rapid traverse that removed stock: the steps of one NC line
that were commanded as rapid traverse (G00,
<a class="xref" href="Hi.MachiningSteps.MachineMotionStep.html#Hi_MachiningSteps_MachineMotionStep_IsRapid">IsRapid</a>) and touched the workpiece fold
into one <code>Play-RapidCut&ndash;Detected</code> validation warning, anchored on
the line's first touching step and carrying the line's total removed
volume and its largest cutting depth. A rapid move through material
breaks the tool or crashes the machine on a real run, yet with the
spindle turning the engine treats it as ordinary cutting: the collision
rule (Hi.Machining.MachiningEquipment.Detect) pairs flute
and workpiece only while the spindle is stopped, so such a line used to
pass with no message at all.</p>
<p>
One instance per <a class="xref" href="Hi.MachiningProcs.MachiningActRunner.html">MachiningActRunner</a>. <a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Observe_Hi_MachiningProcs_RapidCutMonitor_Sample__System_Double_System_Boolean_System_IProgress_Hi_MachiningProcs_StepDiagnostic__">Observe(in Sample, double, bool, IProgress&lt;StepDiagnostic&gt;)</a>
runs on the sequential post-physics stage of every built step (one
thread, step order), <a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Flush_System_Double_System_IProgress_Hi_MachiningProcs_StepDiagnostic__">Flush(double, IProgress&lt;StepDiagnostic&gt;)</a> closes the last line at the end
of a play and <a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Reset">Reset()</a> drops a pending line on a session reset;
both run on the shell thread after
<a class="xref" href="Hi.MachiningProcs.MachiningActRunner.html#Hi_MachiningProcs_MachiningActRunner_WaitAll">WaitAll()</a>, so no lock is needed.
</p>
<p>
Folding: consecutive rapid steps with the same <a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_LineKey">LineKey</a>
(the NC line number, or the sentence itself where a runner has no line
numbers) form one report; a feed step, a different line or the end of
the play closes it. A line re-entered later (a subprogram loop) reports
again, deliberately. The report is emitted only when the line's total
removed volume reaches
<a class="xref" href="Hi.MachiningProcs.MachiningActRunnerConfig.html#Hi_MachiningProcs_MachiningActRunnerConfig_RapidCutVolumeThreshold_mm3">RapidCutVolumeThreshold_mm3</a>
(default 0: any contact). Steps with the spindle stopped are skipped
while collision detection is on — that rule owns them and raises
<code>Collision--Detected</code> — and counted otherwise.
</p>
</div>
<div class="markdown conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public sealed class RapidCutMonitor</code></pre>
</div>
<dl class="typelist inheritance">
<dt>Inheritance</dt>
<dd>
<div><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object">object</a></div>
<div><span class="xref">RapidCutMonitor</span></div>
</dd>
</dl>
<dl class="typelist inheritedMembers">
<dt>Inherited Members</dt>
<dd>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object)">object.Equals(object)</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)">object.Equals(object, object)</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.gethashcode">object.GetHashCode()</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.gettype">object.GetType()</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.referenceequals">object.ReferenceEquals(object, object)</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.tostring">object.ToString()</a>
</div>
</dd></dl>
<dl class="typelist extensionMethods">
<dt>Extension Methods</dt>
<dd>
<div>
<a class="xref" href="Hi.Common.DuplicateUtil.html#Hi_Common_DuplicateUtil_TryDuplicate__1___0_System_Object___">DuplicateUtil.TryDuplicate&lt;TSelf&gt;(TSelf, params object[])</a>
</div>
<div>
<a class="xref" href="Hi.Common.InvokeUtil.html#Hi_Common_InvokeUtil_SelfInvoke__1___0_System_Action___0__">InvokeUtil.SelfInvoke&lt;TSrc&gt;(TSrc, Action&lt;TSrc&gt;)</a>
</div>
<div>
<a class="xref" href="Hi.Common.InvokeUtil.html#Hi_Common_InvokeUtil_SelfInvoke__2___0_System_Func___0___1__">InvokeUtil.SelfInvoke&lt;TSrc, TDst&gt;(TSrc, Func&lt;TSrc, TDst&gt;)</a>
</div>
<div>
<a class="xref" href="Hi.Coloring.ColorUtil.html#Hi_Coloring_ColorUtil_GetGloomyColor_System_Object_System_Double_System_Double_">ColorUtil.GetGloomyColor(object, double, double)</a>
</div>
<div>
<a class="xref" href="Hi.Common.NameUtil.html#Hi_Common_NameUtil_GetSelectionName_System_Object_">NameUtil.GetSelectionName(object)</a>
</div>
<div>
<a class="xref" href="Hi.Common.StringUtil.html#Hi_Common_StringUtil_GetPropertyStringIfToStringNotOverloaded_System_Object_System_Boolean_System_Boolean_">StringUtil.GetPropertyStringIfToStringNotOverloaded(object, bool, bool)</a>
</div>
<div>
<a class="xref" href="Hi.Parallels.LockUtil.html#Hi_Parallels_LockUtil_Lock_System_Object_">LockUtil.Lock(object)</a>
</div>
</dd></dl>
<h2 class="section" id="fields">Fields
</h2>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_MessageId" data-uid="Hi.MachiningProcs.RapidCutMonitor.MessageId">
MessageId
</h3>
<div class="markdown level1 summary"><p>Id of the warning this monitor emits.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public const string MessageId = &quot;Play-RapidCut--Detected&quot;</code></pre>
</div>
<h4 class="section">Field Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.string">string</a></dt>
<dd></dd>
</dl>
<h2 class="section" id="methods">Methods
</h2>
<a id="Hi_MachiningProcs_RapidCutMonitor_Flush_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Flush*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_Flush_System_Double_System_IProgress_Hi_MachiningProcs_StepDiagnostic__" data-uid="Hi.MachiningProcs.RapidCutMonitor.Flush(System.Double,System.IProgress{Hi.MachiningProcs.StepDiagnostic})">
Flush(double, IProgress&lt;StepDiagnostic&gt;)
</h3>
<div class="markdown level1 summary"><p>Closes the pending rapid line: reports it when its total removed volume
reaches <code class="paramref">volumeThreshold_mm3</code>, then forgets it. Called
by <a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Observe_Hi_MachiningProcs_RapidCutMonitor_Sample__System_Double_System_Boolean_System_IProgress_Hi_MachiningProcs_StepDiagnostic__">Observe(in Sample, double, bool, IProgress&lt;StepDiagnostic&gt;)</a> at a line boundary and by the session at the
end of a play, for the last line.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public void Flush(double volumeThreshold_mm3, IProgress&lt;StepDiagnostic&gt; sink)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>volumeThreshold_mm3</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.double">double</a></dt>
<dd><p>Line-total removed volume below which the line is not reported.</p>
</dd>
<dt><code>sink</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.iprogress-1">IProgress</a>&lt;<a class="xref" href="Hi.MachiningProcs.StepDiagnostic.html">StepDiagnostic</a>&gt;</dt>
<dd><p>Step-anchored sink for the report; no-op if null.</p>
</dd>
</dl>
<a id="Hi_MachiningProcs_RapidCutMonitor_Observe_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Observe*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_Observe_Hi_MachiningProcs_RapidCutMonitor_Sample__System_Double_System_Boolean_System_IProgress_Hi_MachiningProcs_StepDiagnostic__" data-uid="Hi.MachiningProcs.RapidCutMonitor.Observe(Hi.MachiningProcs.RapidCutMonitor.Sample@,System.Double,System.Boolean,System.IProgress{Hi.MachiningProcs.StepDiagnostic})">
Observe(in Sample, double, bool, IProgress&lt;StepDiagnostic&gt;)
</h3>
<div class="markdown level1 summary"><p>Feeds one built step, in step order. A feed step or a step of another
line closes the pending rapid line (see <a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Flush_System_Double_System_IProgress_Hi_MachiningProcs_StepDiagnostic__">Flush(double, IProgress&lt;StepDiagnostic&gt;)</a>); a rapid
step that touched the stock opens or extends it.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public void Observe(in RapidCutMonitor.Sample sample, double volumeThreshold_mm3, bool collisionDetectionEnabled, IProgress&lt;StepDiagnostic&gt; sink)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>sample</code> <a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html">RapidCutMonitor</a>.<a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.Sample.html">Sample</a></dt>
<dd><p>The step, see <a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_SampleOf_Hi_MachiningSteps_MachiningStep_">SampleOf(MachiningStep)</a>.</p>
</dd>
<dt><code>volumeThreshold_mm3</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.double">double</a></dt>
<dd><p>Line-total removed volume below which the line is not reported.</p>
</dd>
<dt><code>collisionDetectionEnabled</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>When true, steps with the spindle stopped are left to collision detection.</p>
</dd>
<dt><code>sink</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.iprogress-1">IProgress</a>&lt;<a class="xref" href="Hi.MachiningProcs.StepDiagnostic.html">StepDiagnostic</a>&gt;</dt>
<dd><p>Step-anchored sink for the report; no-op if null.</p>
</dd>
</dl>
<a id="Hi_MachiningProcs_RapidCutMonitor_Reset_" data-uid="Hi.MachiningProcs.RapidCutMonitor.Reset*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_Reset" data-uid="Hi.MachiningProcs.RapidCutMonitor.Reset">
Reset()
</h3>
<div class="markdown level1 summary"><p>Forgets a pending line without reporting it (session reset).</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public void Reset()</code></pre>
</div>
<a id="Hi_MachiningProcs_RapidCutMonitor_SampleOf_" data-uid="Hi.MachiningProcs.RapidCutMonitor.SampleOf*"></a>
<h3 id="Hi_MachiningProcs_RapidCutMonitor_SampleOf_Hi_MachiningSteps_MachiningStep_" data-uid="Hi.MachiningProcs.RapidCutMonitor.SampleOf(Hi.MachiningSteps.MachiningStep)">
SampleOf(MachiningStep)
</h3>
<div class="markdown level1 summary"><p>Builds the monitor's view of a built step. The removed volume is the
step's material removal rate (<a class="xref" href="Hi.MachiningSteps.MachiningStep.html#Hi_MachiningSteps_MachiningStep_Mrr_mm3ds">Mrr_mm3ds</a>,
the swept engagement cross-section times the tip feedrate) over the
step duration — a geometry-only quantity, so the report needs no
physics; a NaN rate (undefined tip feedrate) counts as 0 but the
contact still counts.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static RapidCutMonitor.Sample SampleOf(MachiningStep step)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>step</code> <a class="xref" href="Hi.MachiningSteps.MachiningStep.html">MachiningStep</a></dt>
<dd><p>A built step.</p>
</dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html">RapidCutMonitor</a>.<a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.Sample.html">Sample</a></dt>
<dd></dd>
</dl>
</article>
<div class="contribution d-print-none">
</div>
</div>
<div class="affix">
<nav id="affix"></nav>
</div>
</main>
<div class="container-xxl search-results" id="search-results"></div>
<footer class="border-top text-secondary">
<div class="container-xxl">
<div class="flex-fill">
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
</div>
</div>
</footer>
</body>
</html>
@@ -210,6 +210,41 @@ rather than queued; controllers surface this as HTTP 409 Conflict.</p>
<dt><a class="xref" href="Hi.MachiningProcs.ProxyProjectService.html">ProxyProjectService</a></dt> <dt><a class="xref" href="Hi.MachiningProcs.ProxyProjectService.html">ProxyProjectService</a></dt>
<dd><p>Delegate (User-based) Project Service. <dd><p>Delegate (User-based) Project Service.
Apply relative file path from <a class="xref" href="Hi.MachiningProcs.ProxyProjectService.html#Hi_MachiningProcs_ProxyProjectService_AdminDirectory">AdminDirectory</a>.</p> Apply relative file path from <a class="xref" href="Hi.MachiningProcs.ProxyProjectService.html#Hi_MachiningProcs_ProxyProjectService_AdminDirectory">AdminDirectory</a>.</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html">RapidCutMonitor</a></dt>
<dd><p>Reports a rapid traverse that removed stock: the steps of one NC line
that were commanded as rapid traverse (G00,
<a class="xref" href="Hi.MachiningSteps.MachineMotionStep.html#Hi_MachiningSteps_MachineMotionStep_IsRapid">IsRapid</a>) and touched the workpiece fold
into one <code>Play-RapidCut&ndash;Detected</code> validation warning, anchored on
the line's first touching step and carrying the line's total removed
volume and its largest cutting depth. A rapid move through material
breaks the tool or crashes the machine on a real run, yet with the
spindle turning the engine treats it as ordinary cutting: the collision
rule (Hi.Machining.MachiningEquipment.Detect) pairs flute
and workpiece only while the spindle is stopped, so such a line used to
pass with no message at all.</p>
<p>
One instance per <a class="xref" href="Hi.MachiningProcs.MachiningActRunner.html">MachiningActRunner</a>. <a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Observe_Hi_MachiningProcs_RapidCutMonitor_Sample__System_Double_System_Boolean_System_IProgress_Hi_MachiningProcs_StepDiagnostic__">Observe(in Sample, double, bool, IProgress&lt;StepDiagnostic&gt;)</a>
runs on the sequential post-physics stage of every built step (one
thread, step order), <a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Flush_System_Double_System_IProgress_Hi_MachiningProcs_StepDiagnostic__">Flush(double, IProgress&lt;StepDiagnostic&gt;)</a> closes the last line at the end
of a play and <a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Reset">Reset()</a> drops a pending line on a session reset;
both run on the shell thread after
<a class="xref" href="Hi.MachiningProcs.MachiningActRunner.html#Hi_MachiningProcs_MachiningActRunner_WaitAll">WaitAll()</a>, so no lock is needed.
</p>
<p>
Folding: consecutive rapid steps with the same <a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_LineKey">LineKey</a>
(the NC line number, or the sentence itself where a runner has no line
numbers) form one report; a feed step, a different line or the end of
the play closes it. A line re-entered later (a subprogram loop) reports
again, deliberately. The report is emitted only when the line's total
removed volume reaches
<a class="xref" href="Hi.MachiningProcs.MachiningActRunnerConfig.html#Hi_MachiningProcs_MachiningActRunnerConfig_RapidCutVolumeThreshold_mm3">RapidCutVolumeThreshold_mm3</a>
(default 0: any contact). Steps with the spindle stopped are skipped
while collision detection is on — that rule owns them and raises
<code>Collision--Detected</code> — and counted otherwise.
</p>
</dd> </dd>
</dl> </dl>
<dl class="jumplist"> <dl class="jumplist">
@@ -339,6 +374,16 @@ steps writes to <i>different</i> scopes. Each parallel step task therefore holds
instance — never a shared mutable "current step" on <a class="xref" href="Hi.MachiningProcs.StepDiagnosticProgress.html">StepDiagnosticProgress</a>, which would instance — never a shared mutable "current step" on <a class="xref" href="Hi.MachiningProcs.StepDiagnosticProgress.html">StepDiagnosticProgress</a>, which would
race. race.
</p> </p>
</dd>
</dl>
<h3 id="structs">
Structs
</h3>
<dl class="jumplist">
<dt><a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.Sample.html">RapidCutMonitor.Sample</a></dt>
<dd><p>One built step as the monitor sees it — the few facts the fold needs,
detached from <a class="xref" href="Hi.MachiningSteps.MachiningStep.html">MachiningStep</a> so the fold is testable on
synthetic steps.</p>
</dd> </dd>
</dl> </dl>
<h3 id="interfaces"> <h3 id="interfaces">
@@ -919,6 +919,44 @@ per revolution.</p>
<a id="Hi_MachiningSteps_MachineMotionStep_IsRapid_" data-uid="Hi.MachiningSteps.MachineMotionStep.IsRapid*"></a>
<h3 id="Hi_MachiningSteps_MachineMotionStep_IsRapid" data-uid="Hi.MachiningSteps.MachineMotionStep.IsRapid">
IsRapid
</h3>
<div class="markdown level1 summary"><p>Whether the controller commanded this step as a rapid traverse (G00,
<a class="xref" href="Hi.Numerical.Acts.ActRapid.html">ActRapid</a>): <a class="xref" href="Hi.MachiningSteps.MachineMotionStep.html#Hi_MachiningSteps_MachineMotionStep_CommandedClFeedrate_mmds">CommandedClFeedrate_mmds</a>
is then the rapid rate, not a programmed feed. Assigned by the step
builder from <a class="xref" href="Hi.Numerical.Acts.StateActRunner.html#Hi_Numerical_Acts_StateActRunner_IsRapid">IsRapid</a>;
false for feed motion and for steps built outside an act runner. A
rapid step that removes stock is what
<a class="xref" href="Hi.MachiningProcs.RapidCutMonitor.html">RapidCutMonitor</a> reports.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public bool IsRapid { get; set; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd></dd>
</dl>
<a id="Hi_MachiningSteps_MachineMotionStep_McValues_" data-uid="Hi.MachiningSteps.MachineMotionStep.McValues*"></a> <a id="Hi_MachiningSteps_MachineMotionStep_McValues_" data-uid="Hi.MachiningSteps.MachineMotionStep.McValues*"></a>
<h3 id="Hi_MachiningSteps_MachineMotionStep_McValues" data-uid="Hi.MachiningSteps.MachineMotionStep.McValues"> <h3 id="Hi_MachiningSteps_MachineMotionStep_McValues" data-uid="Hi.MachiningSteps.MachineMotionStep.McValues">
@@ -191,6 +191,44 @@ begin reports that gap once through these helpers.</p>
<h3 id="Hi_NcParsers_Dependencys_StrokeLimitUtil_Tolerance" data-uid="Hi.NcParsers.Dependencys.StrokeLimitUtil.Tolerance">
Tolerance
</h3>
<div class="markdown level1 summary"><p>Slack, in mm or degrees, past which a position counts as over a
stroke limit. A machine coordinate that arrives through a work
offset, a tilt and a kinematic solve carries rounding noise of the
order of 1e-12; a program that parks an axis exactly on its limit
(CHEM20180926: <code>G28 Z0</code> on a machine whose Z travel ends at 0)
used to be reported as &ldquo;0.0000 &gt; 0.0000&rdquo; on every such block and
step. A tenth of a micrometre / microdegree is far below any
control's resolution and above any arithmetic noise.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public const double Tolerance = 0.0001</code></pre>
</div>
<h4 class="section">Field Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.double">double</a></dt>
<dd></dd>
</dl>
<h2 class="section" id="methods">Methods <h2 class="section" id="methods">Methods
</h2> </h2>
@@ -292,6 +330,101 @@ continuously legitimately has none and cannot be given one.</p>
<a id="Hi_NcParsers_Dependencys_StrokeLimitUtil_IsWithinRotaryTravel_" data-uid="Hi.NcParsers.Dependencys.StrokeLimitUtil.IsWithinRotaryTravel*"></a>
<h3 id="Hi_NcParsers_Dependencys_StrokeLimitUtil_IsWithinRotaryTravel_System_Double_System_Nullable_System_Double__System_Nullable_System_Double__" data-uid="Hi.NcParsers.Dependencys.StrokeLimitUtil.IsWithinRotaryTravel(System.Double,System.Nullable{System.Double},System.Nullable{System.Double})">
IsWithinRotaryTravel(double, double?, double?)
</h3>
<div class="markdown level1 summary"><p>Whether a rotary angle (degrees) lies within a travel given by its
two ends, either of which may be absent. A span of a full turn or
more admits every angle; otherwise the angle is wrapped into the
turn starting at the negative end before the test.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static bool IsWithinRotaryTravel(double angle_deg, double? negative_deg, double? positive_deg)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>angle_deg</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.double">double</a></dt>
<dd><p>The angle to test.</p>
</dd>
<dt><code>negative_deg</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.double">double</a>?</dt>
<dd><p>The negative end, or null when unbounded.</p>
</dd>
<dt><code>positive_deg</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.double">double</a>?</dt>
<dd><p>The positive end, or null when unbounded.</p>
</dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd></dd>
</dl>
<a id="Hi_NcParsers_Dependencys_StrokeLimitUtil_RotaryAdmissibility_" data-uid="Hi.NcParsers.Dependencys.StrokeLimitUtil.RotaryAdmissibility*"></a>
<h3 id="Hi_NcParsers_Dependencys_StrokeLimitUtil_RotaryAdmissibility_System_Collections_Generic_IEnumerable_Hi_NcParsers_Dependencys_INcDependency__" data-uid="Hi.NcParsers.Dependencys.StrokeLimitUtil.RotaryAdmissibility(System.Collections.Generic.IEnumerable{Hi.NcParsers.Dependencys.INcDependency})">
RotaryAdmissibility(IEnumerable&lt;INcDependency&gt;)
</h3>
<div class="markdown level1 summary"><p>The rotary-travel admissibility test for an inverse-kinematics solve
(<a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Vec3d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__">OrientationToMcAbc(Vec3d, Func&lt;Vec3d, bool&gt;, out Vec3d)</a>):
accepts a machine ABC (radians) whose configured A/B/C limits on the
list's <a class="xref" href="Hi.NcParsers.Dependencys.IStrokeLimitConfig.html">IStrokeLimitConfig</a> (degrees) are all met, so a
tilt solve prefers the branch the machine can reach. Null — admit
everything — when the list carries no stroke config or no rotary
limit at all. An axis whose two limits span a full turn or more is
always admissible; a narrower span is tested on the angle wrapped
into the turn that starts at the negative limit (the solver reports
atan2 angles, the limits are wherever the builder put them); a NaN
component (an axis the chain does not have) is not tested.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static Func&lt;Vec3d, bool&gt; RotaryAdmissibility(IEnumerable&lt;INcDependency&gt; dependencyList)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>dependencyList</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1">IEnumerable</a>&lt;<a class="xref" href="Hi.NcParsers.Dependencys.INcDependency.html">INcDependency</a>&gt;</dt>
<dd><p>The runner's effective dependency list.</p>
</dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.func-2">Func</a>&lt;<a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a>, <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a>&gt;</dt>
<dd></dd>
</dl>
</article> </article>
@@ -658,6 +658,59 @@ the solution only fit the orientation part of the <code class="paramref">tiltMat
<a id="Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_" data-uid="Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc*"></a>
<h3 id="Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_Hi_Geom_Mat4d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__" data-uid="Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Mat4d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)">
OrientationToMcAbc(Mat4d, Func&lt;Vec3d, bool&gt;, out Vec3d)
</h3>
<div class="markdown level1 summary"><p><a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Mat4d_Hi_Geom_Vec3d__">OrientationToMcAbc(Mat4d, out Vec3d)</a> restricted to the
rotary positions <code class="paramref">isMcAbcAdmissible</code> accepts (the
machine's rotary travel, typically). A full orientation fixes the
rotary positions up to axis periodicity, so a solution the predicate
refuses is a posture this machine cannot take: the conversion then
fails (false) and leaves the solver state as it was, so that the
caller can fall back to <a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Vec3d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__">OrientationToMcAbc(Vec3d, Func&lt;Vec3d, bool&gt;, out Vec3d)</a>,
where the free rotation about the tool axis opens the other branch.
A null predicate admits everything.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public bool OrientationToMcAbc(Mat4d tiltMat, Func&lt;Vec3d, bool&gt; isMcAbcAdmissible, out Vec3d mcAbc_rad)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>tiltMat</code> <a class="xref" href="Hi.Geom.Mat4d.html">Mat4d</a></dt>
<dd><p>The tilt matrix to convert.</p>
</dd>
<dt><code>isMcAbcAdmissible</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.func-2">Func</a>&lt;<a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a>, <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a>&gt;</dt>
<dd><p>Accepts a machine ABC (radians) or refuses it; null admits everything.</p>
</dd>
<dt><code>mcAbc_rad</code> <a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a></dt>
<dd><p>Output machine ABC coordinates in radians.</p>
</dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>Whether an admissible conversion was found.</p>
</dd>
</dl>
<a id="Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_" data-uid="Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc*"></a> <a id="Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_" data-uid="Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc*"></a>
<h3 id="Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__" data-uid="Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Vec3d,Hi.Geom.Vec3d@)"> <h3 id="Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__" data-uid="Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Vec3d,Hi.Geom.Vec3d@)">
@@ -708,6 +761,65 @@ likely to converge for tilt configurations such as <code>G68.2 I180 J90 K0</code
<a id="Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_" data-uid="Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc*"></a>
<h3 id="Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_Hi_Geom_Vec3d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__" data-uid="Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Vec3d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)">
OrientationToMcAbc(Vec3d, Func&lt;Vec3d, bool&gt;, out Vec3d)
</h3>
<div class="markdown level1 summary"><p><a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__">OrientationToMcAbc(Vec3d, out Vec3d)</a> preferring the
solution branch <code class="paramref">isMcAbcAdmissible</code> accepts. The
axial-only problem has two branches on a two-rotary-axis machine
(on a table-table A/C: (A, C) and (A, C+180°)); the plain overload
returns the branch nearest the solver's seed, which from the rotary
pole (A0 C0) is the one the tilt's azimuth happens to favour — half
the time the branch a cradle table with an asymmetric tilt travel
cannot reach (CHEM20180926 N100: <code>G68.2 I210 J-90</code> + <code>G53.1</code>
solved to A=+90° on a 120°…+30° A axis). When the nearest branch is
refused, an implementation with a real solver searches the other
branches and returns the admissible one nearest the seed; when none
is admissible it returns the refused solution and true, and the
stroke-limit check downstream reports it. A null predicate makes this
the plain overload. The default implementation is the plain solve —
the predicate is advisory for an implementation without a solver.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public bool OrientationToMcAbc(Vec3d toolAxialNormal, Func&lt;Vec3d, bool&gt; isMcAbcAdmissible, out Vec3d mcAbc_rad)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>toolAxialNormal</code> <a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a></dt>
<dd><p>Target tool axial direction in table coordinates.</p>
</dd>
<dt><code>isMcAbcAdmissible</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.func-2">Func</a>&lt;<a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a>, <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a>&gt;</dt>
<dd><p>Accepts a machine ABC (radians) or refuses it; null admits everything.</p>
</dd>
<dt><code>mcAbc_rad</code> <a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a></dt>
<dd><p>Output machine ABC coordinates in radians.</p>
</dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>Whether the conversion was successful (admissible or not).</p>
</dd>
</dl>
<a id="Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_PnToMc_" data-uid="Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.PnToMc*"></a> <a id="Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_PnToMc_" data-uid="Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.PnToMc*"></a>
<h3 id="Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_PnToMc_Hi_Geom_DVec3d_Hi_Geom_DVec3d__" data-uid="Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.PnToMc(Hi.Geom.DVec3d,Hi.Geom.DVec3d@)"> <h3 id="Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_PnToMc_Hi_Geom_DVec3d_Hi_Geom_DVec3d__" data-uid="Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.PnToMc(Hi.Geom.DVec3d,Hi.Geom.DVec3d@)">
@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Interface IPositioningDef | HiAPI-C# 2025 "> <meta name="title" content="Interface IPositioningDef | HiAPI-C# 2025 ">
<meta name="description" content="Modal positioning state — ISO Group 03 (G90 absolute / G91 incremental). Written by , consumed by , canned cycle syntaxes, and . Property names are used as JSON keys via nameof. is the brand-specific G-code (Fanuc/ISO G90/G91); is the conventional, brand-neutral name ( / )."> <meta name="description" content="Modal positioning state — ISO Group 03 (G90 absolute / G91 incremental). Written by , consumed by (linear words), (rotary words: G91 accumulates anchor + delta) and (the wrap pass keeps the axes the record lists literal), canned cycle syntaxes, and . A per-word entry beats this modal state for its word. The section stays G91 after the consumers have rewritten the block&#39;s words to absolutes (the next block&#39;s lookback needs it); the words that were converted are listed in the one-shot record. Property names are used as JSON keys via nameof. is the brand-specific G-code (Fanuc/ISO G90/G91); is the conventional, brand-neutral name ( / ).">
<link rel="icon" href="../img/HiAPI.favicon.ico"> <link rel="icon" href="../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../public/docfx.min.css"> <link rel="stylesheet" href="../public/docfx.min.css">
<link rel="stylesheet" href="../public/main.css"> <link rel="stylesheet" href="../public/main.css">
@@ -99,9 +99,19 @@ Interface IPositioningDef
<div class="markdown summary"><p>Modal positioning state — ISO Group 03 (G90 absolute / G91 incremental). <div class="markdown summary"><p>Modal positioning state — ISO Group 03 (G90 absolute / G91 incremental).
Written by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.PositioningSyntax.html">PositioningSyntax</a>, consumed by Written by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.PositioningSyntax.html">PositioningSyntax</a>, consumed by
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a>, canned cycle <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> (linear words),
syntaxes, and <a class="xref" href="Hi.NcParsers.LogicSyntaxs.MachineCoordSelectSyntax.html">MachineCoordSelectSyntax</a>. <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> (rotary words: G91
Property names are used as JSON keys via <code>nameof</code>.</p> accumulates anchor + delta) and
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a> (the wrap pass
keeps the axes the <a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> record lists
literal), canned cycle syntaxes, and
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.MachineCoordSelectSyntax.html">MachineCoordSelectSyntax</a>. A per-word
<a class="xref" href="Hi.NcParsers.Keywords.PositioningOverride.html">PositioningOverride</a> entry beats this modal state for
its word. The section stays <code>G91</code> after the consumers have
rewritten the block's words to absolutes (the next block's lookback
needs it); the words that were converted are listed in the one-shot
<a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> record. Property names are used as
JSON keys via <code>nameof</code>.</p>
<p> <p>
<a class="xref" href="Hi.NcParsers.Keywords.IPositioningDef.html#Hi_NcParsers_Keywords_IPositioningDef_Term">Term</a> is the brand-specific G-code (Fanuc/ISO G90/G91); <a class="xref" href="Hi.NcParsers.Keywords.IPositioningDef.html#Hi_NcParsers_Keywords_IPositioningDef_Term">Term</a> is the brand-specific G-code (Fanuc/ISO G90/G91);
<a class="xref" href="Hi.NcParsers.Keywords.IPositioningDef.html#Hi_NcParsers_Keywords_IPositioningDef_Mode">Mode</a> is the conventional, brand-neutral name <a class="xref" href="Hi.NcParsers.Keywords.IPositioningDef.html#Hi_NcParsers_Keywords_IPositioningDef_Mode">Mode</a> is the conventional, brand-neutral name
@@ -0,0 +1,226 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Class IncrementalWords | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Class IncrementalWords | HiAPI-C# 2025 ">
<meta name="description" content="One-shot block-root record of the axis words this block programmed as increments — under modal G91, or through a per-word entry (Siemens IC(), klartext IX+/IC+) — valued with the programmed delta and shaped like the Parsing tree the word came from: a root word is a root key ({ &amp;ldquo;X&amp;rdquo;: 10 }, { &amp;ldquo;C&amp;rdquo;: 20 }), a word inside a nested record sits under that record&#39;s key ({ &amp;ldquo;G28&amp;rdquo;: { &amp;ldquo;X&amp;rdquo;: 0, &amp;ldquo;C&amp;rdquo;: 10 } }, { &amp;ldquo;CC&amp;rdquo;: { &amp;ldquo;X&amp;rdquo;: 0, &amp;ldquo;Y&amp;rdquo;: 11 } }). Why it exists: the resolve is in place. rewrites the word inside Parsing to its absolute value and writes the accumulated angle into MachineCoordinateState, while the modal section must keep saying G91 for the next block&#39;s lookback. From that point on { &quot;Positioning&quot;: G91, &quot;Parsing&quot;: { &quot;G28&quot;: { &quot;X&quot;: 100 } } } is byte-identical to a program that wrote G90 G28 X100., and once the consumer has taken the word out of Parsing the programmed text is gone from the JSON altogether. This section is the trace that the word was an increment, and of what it was. Written by (the words at its working paths — root, G28, the klartext CC record) and (root rotary words). Read by as an idempotency guard — a word already listed at its path is never converted twice, whatever the syntax list looks like (a project file whose serialized list carries two instances, a re-run over a frozen piece) — and by , where a listed rotary axis is a signed traverse that passes the shortest-path wrap literally, whichever spelling made it incremental. Not listed in any key set — it never carries to later blocks. Not recorded: coded-position words (Siemens CIC() counts indexing positions, not an angle — its trace is the rewritten entry), and the words the two consumers ahead of the shared resolve take for themselves (&#39;s cycle words, &#39;s machine-frame words): both consume the word into their own section, so no absolute-looking copy is left in Parsing to be mistaken for a programmed absolute.">
<link rel="icon" href="../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../public/docfx.min.css">
<link rel="stylesheet" href="../public/main.css">
<meta name="docfx:navrel" content="../toc.html">
<meta name="docfx:tocrel" content="toc.html">
<meta name="docfx:rel" content="../">
<meta name="loc:inThisArticle" content="In this article">
<meta name="loc:searchResultsCount" content="{count} results for &quot;{query}&quot;">
<meta name="loc:searchNoResults" content="No results for &quot;{query}&quot;">
<meta name="loc:tocFilter" content="Filter by title">
<meta name="loc:nextArticle" content="Next">
<meta name="loc:prevArticle" content="Previous">
<meta name="loc:themeLight" content="Light">
<meta name="loc:themeDark" content="Dark">
<meta name="loc:themeAuto" content="Auto">
<meta name="loc:changeTheme" content="Change theme">
<meta name="loc:copy" content="Copy">
<meta name="loc:downloadPdf" content="Download PDF">
<script type="module" src="./../public/docfx.min.js"></script>
<script>
const theme = localStorage.getItem('theme') || 'auto'
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
</script>
</head>
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="ManagedReference">
<header class="bg-body border-bottom">
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
<div class="container-xxl flex-nowrap">
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../img/HiAPI.logo.png" alt="">
</a>
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
<i class="bi bi-three-dots"></i>
</button>
<div class="collapse navbar-collapse" id="navpanel">
<div id="navbar">
<form class="search" role="search" id="search">
<i class="bi bi-search"></i>
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
</form>
</div>
</div>
</div>
</nav>
</header>
<main class="container-xxl">
<div class="toc-offcanvas">
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<nav class="toc" id="toc"></nav>
</div>
</div>
</div>
<div class="content">
<div class="actionbar">
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
<i class="bi bi-list"></i>
</button>
<nav id="breadcrumb"></nav>
</div>
<article data-uid="Hi.NcParsers.Keywords.IncrementalWords">
<h1 id="Hi_NcParsers_Keywords_IncrementalWords" data-uid="Hi.NcParsers.Keywords.IncrementalWords" class="text-break">
Class IncrementalWords
</h1>
<div class="facts text-secondary">
<dl><dt>Namespace</dt><dd><a class="xref" href="Hi.html">Hi</a>.<a class="xref" href="Hi.NcParsers.html">NcParsers</a>.<a class="xref" href="Hi.NcParsers.Keywords.html">Keywords</a></dd></dl>
<dl><dt>Assembly</dt><dd>HiMech.dll</dd></dl>
</div>
<div class="markdown summary"><p>One-shot block-root record of the axis words this block programmed as
<b>increments</b> — under modal <code>G91</code>, or through a per-word
<a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_Incremental">Incremental</a> entry (Siemens <code>IC()</code>,
klartext <code>IX+</code>/<code>IC+</code>) — valued with the programmed delta
and shaped like the <code>Parsing</code> tree the word came from: a root
word is a root key (<code>{ &ldquo;X&rdquo;: 10 }</code>, <code>{ &ldquo;C&rdquo;: 20 }</code>), a word
inside a nested record sits under that record's key
(<code>{ &ldquo;G28&rdquo;: { &ldquo;X&rdquo;: 0, &ldquo;C&rdquo;: 10 } }</code>,
<code>{ &ldquo;CC&rdquo;: { &ldquo;X&rdquo;: 0, &ldquo;Y&rdquo;: 11 } }</code>).</p>
<p>
Why it exists: the resolve is in place.
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> rewrites the word
inside <code>Parsing</code> to its absolute value and
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> writes the accumulated angle
into <code>MachineCoordinateState</code>, while the modal
<a class="xref" href="Hi.NcParsers.Keywords.Positioning.html">Positioning</a> section must keep saying <code>G91</code> for the
next block's lookback. From that point on
<code>{ "Positioning": G91, "Parsing": { "G28": { "X": 100 } } }</code> is
byte-identical to a program that wrote <code>G90 G28 X100.</code>, and once
the consumer has taken the word out of <code>Parsing</code> the programmed
text is gone from the JSON altogether. This section is the trace that
the word was an increment, and of what it was.
</p>
<p>
Written by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> (the
words at its working paths — root, <code>G28</code>, the klartext
<code>CC</code> record) and <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> (root
rotary words). Read by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a>
as an idempotency guard — a word already listed at its path is never
converted twice, whatever the syntax list looks like (a project file
whose serialized list carries two instances, a re-run over a frozen
piece) — and by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a>,
where a listed rotary axis is a signed traverse that passes the
shortest-path wrap literally, whichever spelling made it incremental.
Not listed in any <a class="xref" href="Hi.NcParsers.PostLogicSyntaxs.ModalCarrySyntax.html">ModalCarrySyntax</a> key
set — it never carries to later blocks.
</p>
<p>
Not recorded: coded-position words (Siemens <code>CIC()</code> counts
indexing positions, not an angle — its trace is the rewritten
<a class="xref" href="Hi.NcParsers.Keywords.PositioningOverride.html">PositioningOverride</a> entry), and the words the two
consumers ahead of the shared resolve take for themselves
(<a class="xref" href="Hi.NcParsers.LogicSyntaxs.Heidenhain.HeidenhainCannedCycleSyntax.html">HeidenhainCannedCycleSyntax</a>'s
cycle words, <a class="xref" href="Hi.NcParsers.LogicSyntaxs.MachineCoordSelectSyntax.html">MachineCoordSelectSyntax</a>'s
machine-frame words): both consume the word into their own section, so
no absolute-looking copy is left in <code>Parsing</code> to be mistaken for
a programmed absolute.
</p>
</div>
<div class="markdown conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static class IncrementalWords</code></pre>
</div>
<dl class="typelist inheritance">
<dt>Inheritance</dt>
<dd>
<div><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object">object</a></div>
<div><span class="xref">IncrementalWords</span></div>
</dd>
</dl>
<dl class="typelist inheritedMembers">
<dt>Inherited Members</dt>
<dd>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object)">object.Equals(object)</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)">object.Equals(object, object)</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.gethashcode">object.GetHashCode()</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.gettype">object.GetType()</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.memberwiseclone">object.MemberwiseClone()</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.referenceequals">object.ReferenceEquals(object, object)</a>
</div>
<div>
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object.tostring">object.ToString()</a>
</div>
</dd></dl>
<h2 id="Hi_NcParsers_Keywords_IncrementalWords_examples">Examples</h2>
<pre><code class="lang-csharp">"IncrementalWords": { "X": 10, "G28": { "C": 10 } }</code></pre>
</article>
<div class="contribution d-print-none">
</div>
</div>
<div class="affix">
<nav id="affix"></nav>
</div>
</main>
<div class="container-xxl search-results" id="search-results"></div>
<footer class="border-top text-secondary">
<div class="container-xxl">
<div class="flex-fill">
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
</div>
</div>
</footer>
</body>
</html>
@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Class PositioningOverride | HiAPI-C# 2025 "> <meta name="title" content="Class PositioningOverride | HiAPI-C# 2025 ">
<meta name="description" content="Per-word positioning override — a non-modal block-root section keyed by word name (axis words and the I/J/K interpolation parameters) whose values are / / / / , plus the coded-position (indexing axis) family / / / / . Overrides the modal G90/G91 state (and, for I/J/K, the default incremental center reading) for the listed words on this block only. Written by when a word carries one of the Siemens per-word coordinate function wrappers AC() / IC() / DC() / ACP() / ACN() or their coded-position counterparts CAC() / CIC() / CDC() / CACP() / CACN(), and by the Heidenhain L / C / CC / CYCL CALL POS parsers (through ) for the klartext I-prefixed incremental words IX+20 / IC+90 — always there, keyed by the plain axis letter. Not written for the CYCL DEF 7 datum-shift words: those are increments of the active shift, not of the tool position, and stay inside the cycle&#39;s own record. Consumed by (linear axes) and (rotary axes) — both treat every non-Incremental value as an absolute write, and both resolve a coded entry&#39;s indexing position number through and rewrite the entry to its plain counterpart in place — by (the directional window for / and the non-modular-axis boundary warning; it never sees a coded value), and by (absolute I/J/K center components) — and, ahead of the shared resolve, by two consumers that take the raw word before it can see it: (CYCL CALL POS words and the M99/M89 root words, resolved against the last programmed position on the spot) and (a distance in the machine frame); words without an entry keep the default behavior unchanged. The section is not listed in any ModalCarry key set — it never carries to later blocks."> <meta name="description" content="Per-word positioning override — a non-modal block-root section keyed by word name (axis words and the I/J/K interpolation parameters) whose values are / / / / , plus the coded-position (indexing axis) family / / / / . Overrides the modal G90/G91 state (and, for I/J/K, the default incremental center reading) for the listed words on this block only. Written by when a word carries one of the Siemens per-word coordinate function wrappers AC() / IC() / DC() / ACP() / ACN() or their coded-position counterparts CAC() / CIC() / CDC() / CACP() / CACN(), and by the Heidenhain L / C / CC / CYCL CALL POS parsers (through ) for the klartext I-prefixed incremental words IX+20 / IC+90 — always there, keyed by the plain axis letter. Not written for the CYCL DEF 7 datum-shift words: those are increments of the active shift, not of the tool position, and stay inside the cycle&#39;s own record. Consumed by (linear axes) and (rotary axes) — both treat every non-Incremental value as an absolute write, both follow the modal state for a word that has no entry, and both resolve a coded entry&#39;s indexing position number through and rewrite the entry to its plain counterpart in place — by (the directional window for / and the non-modular-axis boundary warning; it never sees a coded value, and it does not read an entry — the literal pass-through follows the record the rotary writer leaves), and by (absolute I/J/K center components) — and, ahead of the shared resolve, by two consumers that take the raw word before it can see it: (CYCL CALL POS words and the M99/M89 root words, resolved against the last programmed position on the spot) and (a distance in the machine frame); words without an entry keep the default behavior unchanged. The section is not listed in any ModalCarry key set — it never carries to later blocks. It describes the programmed spelling; what the write stage actually converted, with the programmed delta, is the record.">
<link rel="icon" href="../img/HiAPI.favicon.ico"> <link rel="icon" href="../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../public/docfx.min.css"> <link rel="stylesheet" href="../public/docfx.min.css">
<link rel="stylesheet" href="../public/main.css"> <link rel="stylesheet" href="../public/main.css">
@@ -129,14 +129,19 @@ the tool position, and stay inside the cycle's own record.
Consumed by Consumed by
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> (linear axes) and <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> (linear axes) and
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> (rotary axes) — both treat <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> (rotary axes) — both treat
every non-Incremental value as an absolute write, and both resolve a every non-Incremental value as an absolute write, both follow the
modal <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html">Positioning</a> state for a word that has no entry,
and both resolve a
coded entry's indexing position number through coded entry's indexing position number through
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.CodedPositionUtil.html">CodedPositionUtil</a> and rewrite the entry to <a class="xref" href="Hi.NcParsers.LogicSyntaxs.CodedPositionUtil.html">CodedPositionUtil</a> and rewrite the entry to
its plain counterpart in place — by its plain counterpart in place — by
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a> (the directional <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a> (the directional
window for <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_PositiveOnly">PositiveOnly</a> / window for <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_PositiveOnly">PositiveOnly</a> /
<a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_NegativeOnly">NegativeOnly</a> and the non-modular-axis <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_NegativeOnly">NegativeOnly</a> and the non-modular-axis
boundary warning; it never sees a coded value), and by boundary warning; it never sees a coded value, and it does not read
an <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_Incremental">Incremental</a> entry — the literal
pass-through follows the <a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> record the
rotary writer leaves), and by
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensCircularMotionSyntax.html">SiemensCircularMotionSyntax</a> <a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensCircularMotionSyntax.html">SiemensCircularMotionSyntax</a>
(absolute I/J/K center components) — and, ahead of the shared (absolute I/J/K center components) — and, ahead of the shared
resolve, by two consumers that take the raw word before it can see resolve, by two consumers that take the raw word before it can see
@@ -146,7 +151,9 @@ the last programmed position on the spot) and
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.MachineCoordSelectSyntax.html">MachineCoordSelectSyntax</a> (a distance in <a class="xref" href="Hi.NcParsers.LogicSyntaxs.MachineCoordSelectSyntax.html">MachineCoordSelectSyntax</a> (a distance in
the machine frame); words without an entry keep the default behavior the machine frame); words without an entry keep the default behavior
unchanged. The section is not listed in any ModalCarry key set — it unchanged. The section is not listed in any ModalCarry key set — it
never carries to later blocks. never carries to later blocks. It describes the <i>programmed</i>
spelling; what the write stage actually converted, with the
programmed delta, is the <a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> record.
</p> </p>
</div> </div>
<div class="markdown conceptual"></div> <div class="markdown conceptual"></div>
@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Class RotaryWords | HiAPI-C# 2025 "> <meta name="title" content="Class RotaryWords | HiAPI-C# 2025 ">
<meta name="description" content="One-shot block-root record of the rotary axis words the block itself commanded — keyed by axis name (A/B/C), valued with the word as programmed: degrees for a plain word, the signed delta for a per-word incremental word (Siemens IC(), klartext IC+), the indexing position number for a coded-position word (CAC()/CIC()/…). The resolved absolute angle lives in ; this section only says which rotary axes this block spoke. Written by when it consumes A/B/C from Parsing into MachineCoordinateState — and only for axes the declares rotary. After the PostLogic carry MachineCoordinateState is a modal record (key presence never means &quot;commanded&quot;), so consumers that must know whether this block carried a rotary word read this section instead: (a rotary-only block under an active canned cycle is a modal repeat — Fanuc&#39;s any-axis-word rule, HardNc parity: the table indexes, then the cycle drills again) and (the cycle&#39;s pre-positioning item carries the block&#39;s MC A/B/C so the physical rotary state matches the root record instead of lagging one block behind). Not listed in any key set — it never carries to later blocks."> <meta name="description" content="One-shot block-root record of the rotary axis words the block itself commanded — keyed by axis name (A/B/C), valued with the word as programmed: degrees for a plain word, the signed delta for a per-word incremental word (Siemens IC(), klartext IC+), the indexing position number for a coded-position word (CAC()/CIC()/…). The resolved absolute angle lives in ; this section only says which rotary axes this block spoke. Written by when it consumes A/B/C from Parsing into MachineCoordinateState — and only for axes the declares rotary. After the PostLogic carry MachineCoordinateState is a modal record (key presence never means &quot;commanded&quot;), so consumers that must know whether this block carried a rotary word read this section instead: (a rotary-only block under an active canned cycle is a modal repeat — Fanuc&#39;s any-axis-word rule, HardNc parity: the table indexes, then the cycle drills again) and (the cycle&#39;s pre-positioning item carries the block&#39;s MC A/B/C so the physical rotary state matches the root record instead of lagging one block behind) and (the tilted-feature-frame re-anchor on a rotary-word block). Not listed in any key set — it never carries to later blocks. This section says which rotary words the block spoke, not how: an absolute C40. and an incremental C40. both record 40. Which of them were increments — and so which MC angles are accumulations rather than programmed absolutes — is the sibling record, the one reads for its literal pass-through.">
<link rel="icon" href="../img/HiAPI.favicon.ico"> <link rel="icon" href="../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../public/docfx.min.css"> <link rel="stylesheet" href="../public/docfx.min.css">
<link rel="stylesheet" href="../public/main.css"> <link rel="stylesheet" href="../public/main.css">
@@ -120,10 +120,20 @@ drills again) and
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.text.json.nodes.jsonobject">WriteCompoundMotion(JsonObject, string, JsonArray, Vec3d)</a> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.text.json.nodes.jsonobject">WriteCompoundMotion(JsonObject, string, JsonArray, Vec3d)</a>
(the cycle's pre-positioning item carries the block's MC A/B/C so the (the cycle's pre-positioning item carries the block's MC A/B/C so the
physical rotary state matches the root record instead of lagging one physical rotary state matches the root record instead of lagging one
block behind). Not listed in any block behind) and <a class="xref" href="Hi.NcParsers.LogicSyntaxs.PivotTransformUtil.html">PivotTransformUtil</a> (the
<a class="xref" href="Hi.NcParsers.PostLogicSyntaxs.ModalCarrySyntax.html">ModalCarrySyntax</a> key set — it never tilted-feature-frame re-anchor on a rotary-word block). Not listed in
any <a class="xref" href="Hi.NcParsers.PostLogicSyntaxs.ModalCarrySyntax.html">ModalCarrySyntax</a> key set — it never
carries to later blocks. carries to later blocks.
</p> </p>
<p>
This section says <i>which</i> rotary words the block spoke, not how:
an absolute <code>C40.</code> and an incremental <code>C40.</code> both record 40.
Which of them were increments — and so which MC angles are
accumulations rather than programmed absolutes — is the sibling
<a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> record, the one
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a> reads for its
literal pass-through.
</p>
</div> </div>
<div class="markdown conceptual"></div> <div class="markdown conceptual"></div>
@@ -358,6 +358,58 @@ downstream blocks unchanged).
<dl class="jumplist"> <dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.Keywords.Feedrate.html">Feedrate</a></dt> <dt><a class="xref" href="Hi.NcParsers.Keywords.Feedrate.html">Feedrate</a></dt>
<dd><p>Section key holder + concrete implementation for <a class="xref" href="Hi.NcParsers.Keywords.IFeedrateDef.html">IFeedrateDef</a>.</p> <dd><p>Section key holder + concrete implementation for <a class="xref" href="Hi.NcParsers.Keywords.IFeedrateDef.html">IFeedrateDef</a>.</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a></dt>
<dd><p>One-shot block-root record of the axis words this block programmed as
<b>increments</b> — under modal <code>G91</code>, or through a per-word
<a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_Incremental">Incremental</a> entry (Siemens <code>IC()</code>,
klartext <code>IX+</code>/<code>IC+</code>) — valued with the programmed delta
and shaped like the <code>Parsing</code> tree the word came from: a root
word is a root key (<code>{ &ldquo;X&rdquo;: 10 }</code>, <code>{ &ldquo;C&rdquo;: 20 }</code>), a word
inside a nested record sits under that record's key
(<code>{ &ldquo;G28&rdquo;: { &ldquo;X&rdquo;: 0, &ldquo;C&rdquo;: 10 } }</code>,
<code>{ &ldquo;CC&rdquo;: { &ldquo;X&rdquo;: 0, &ldquo;Y&rdquo;: 11 } }</code>).</p>
<p>
Why it exists: the resolve is in place.
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> rewrites the word
inside <code>Parsing</code> to its absolute value and
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> writes the accumulated angle
into <code>MachineCoordinateState</code>, while the modal
<a class="xref" href="Hi.NcParsers.Keywords.Positioning.html">Positioning</a> section must keep saying <code>G91</code> for the
next block's lookback. From that point on
<code>{ "Positioning": G91, "Parsing": { "G28": { "X": 100 } } }</code> is
byte-identical to a program that wrote <code>G90 G28 X100.</code>, and once
the consumer has taken the word out of <code>Parsing</code> the programmed
text is gone from the JSON altogether. This section is the trace that
the word was an increment, and of what it was.
</p>
<p>
Written by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> (the
words at its working paths — root, <code>G28</code>, the klartext
<code>CC</code> record) and <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> (root
rotary words). Read by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a>
as an idempotency guard — a word already listed at its path is never
converted twice, whatever the syntax list looks like (a project file
whose serialized list carries two instances, a re-run over a frozen
piece) — and by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a>,
where a listed rotary axis is a signed traverse that passes the
shortest-path wrap literally, whichever spelling made it incremental.
Not listed in any <a class="xref" href="Hi.NcParsers.PostLogicSyntaxs.ModalCarrySyntax.html">ModalCarrySyntax</a> key
set — it never carries to later blocks.
</p>
<p>
Not recorded: coded-position words (Siemens <code>CIC()</code> counts
indexing positions, not an angle — its trace is the rewritten
<a class="xref" href="Hi.NcParsers.Keywords.PositioningOverride.html">PositioningOverride</a> entry), and the words the two
consumers ahead of the shared resolve take for themselves
(<a class="xref" href="Hi.NcParsers.LogicSyntaxs.Heidenhain.HeidenhainCannedCycleSyntax.html">HeidenhainCannedCycleSyntax</a>'s
cycle words, <a class="xref" href="Hi.NcParsers.LogicSyntaxs.MachineCoordSelectSyntax.html">MachineCoordSelectSyntax</a>'s
machine-frame words): both consume the word into their own section, so
no absolute-looking copy is left in <code>Parsing</code> to be mistaken for
a programmed absolute.
</p>
</dd> </dd>
</dl> </dl>
<dl class="jumplist"> <dl class="jumplist">
@@ -484,14 +536,19 @@ the tool position, and stay inside the cycle's own record.
Consumed by Consumed by
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> (linear axes) and <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> (linear axes) and
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> (rotary axes) — both treat <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> (rotary axes) — both treat
every non-Incremental value as an absolute write, and both resolve a every non-Incremental value as an absolute write, both follow the
modal <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html">Positioning</a> state for a word that has no entry,
and both resolve a
coded entry's indexing position number through coded entry's indexing position number through
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.CodedPositionUtil.html">CodedPositionUtil</a> and rewrite the entry to <a class="xref" href="Hi.NcParsers.LogicSyntaxs.CodedPositionUtil.html">CodedPositionUtil</a> and rewrite the entry to
its plain counterpart in place — by its plain counterpart in place — by
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a> (the directional <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a> (the directional
window for <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_PositiveOnly">PositiveOnly</a> / window for <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_PositiveOnly">PositiveOnly</a> /
<a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_NegativeOnly">NegativeOnly</a> and the non-modular-axis <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_NegativeOnly">NegativeOnly</a> and the non-modular-axis
boundary warning; it never sees a coded value), and by boundary warning; it never sees a coded value, and it does not read
an <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_Incremental">Incremental</a> entry — the literal
pass-through follows the <a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> record the
rotary writer leaves), and by
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensCircularMotionSyntax.html">SiemensCircularMotionSyntax</a> <a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensCircularMotionSyntax.html">SiemensCircularMotionSyntax</a>
(absolute I/J/K center components) — and, ahead of the shared (absolute I/J/K center components) — and, ahead of the shared
resolve, by two consumers that take the raw word before it can see resolve, by two consumers that take the raw word before it can see
@@ -501,7 +558,9 @@ the last programmed position on the spot) and
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.MachineCoordSelectSyntax.html">MachineCoordSelectSyntax</a> (a distance in <a class="xref" href="Hi.NcParsers.LogicSyntaxs.MachineCoordSelectSyntax.html">MachineCoordSelectSyntax</a> (a distance in
the machine frame); words without an entry keep the default behavior the machine frame); words without an entry keep the default behavior
unchanged. The section is not listed in any ModalCarry key set — it unchanged. The section is not listed in any ModalCarry key set — it
never carries to later blocks. never carries to later blocks. It describes the <i>programmed</i>
spelling; what the write stage actually converted, with the
programmed delta, is the <a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> record.
</p> </p>
</dd> </dd>
</dl> </dl>
@@ -545,10 +604,20 @@ drills again) and
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.text.json.nodes.jsonobject">WriteCompoundMotion(JsonObject, string, JsonArray, Vec3d)</a> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.text.json.nodes.jsonobject">WriteCompoundMotion(JsonObject, string, JsonArray, Vec3d)</a>
(the cycle's pre-positioning item carries the block's MC A/B/C so the (the cycle's pre-positioning item carries the block's MC A/B/C so the
physical rotary state matches the root record instead of lagging one physical rotary state matches the root record instead of lagging one
block behind). Not listed in any block behind) and <a class="xref" href="Hi.NcParsers.LogicSyntaxs.PivotTransformUtil.html">PivotTransformUtil</a> (the
<a class="xref" href="Hi.NcParsers.PostLogicSyntaxs.ModalCarrySyntax.html">ModalCarrySyntax</a> key set — it never tilted-feature-frame re-anchor on a rotary-word block). Not listed in
any <a class="xref" href="Hi.NcParsers.PostLogicSyntaxs.ModalCarrySyntax.html">ModalCarrySyntax</a> key set — it never
carries to later blocks. carries to later blocks.
</p> </p>
<p>
This section says <i>which</i> rotary words the block spoke, not how:
an absolute <code>C40.</code> and an incremental <code>C40.</code> both record 40.
Which of them were increments — and so which MC angles are
accumulations rather than programmed absolutes — is the sibling
<a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> record, the one
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a> reads for its
literal pass-through.
</p>
</dd> </dd>
</dl> </dl>
<dl class="jumplist"> <dl class="jumplist">
@@ -911,9 +980,19 @@ the math is <code>InitRxcz + ProgramPolarRxcz</code>, mirroring HardNc
<dt><a class="xref" href="Hi.NcParsers.Keywords.IPositioningDef.html">IPositioningDef</a></dt> <dt><a class="xref" href="Hi.NcParsers.Keywords.IPositioningDef.html">IPositioningDef</a></dt>
<dd><p>Modal positioning state — ISO Group 03 (G90 absolute / G91 incremental). <dd><p>Modal positioning state — ISO Group 03 (G90 absolute / G91 incremental).
Written by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.PositioningSyntax.html">PositioningSyntax</a>, consumed by Written by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.PositioningSyntax.html">PositioningSyntax</a>, consumed by
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a>, canned cycle <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> (linear words),
syntaxes, and <a class="xref" href="Hi.NcParsers.LogicSyntaxs.MachineCoordSelectSyntax.html">MachineCoordSelectSyntax</a>. <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> (rotary words: G91
Property names are used as JSON keys via <code>nameof</code>.</p> accumulates anchor + delta) and
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a> (the wrap pass
keeps the axes the <a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> record lists
literal), canned cycle syntaxes, and
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.MachineCoordSelectSyntax.html">MachineCoordSelectSyntax</a>. A per-word
<a class="xref" href="Hi.NcParsers.Keywords.PositioningOverride.html">PositioningOverride</a> entry beats this modal state for
its word. The section stays <code>G91</code> after the consumers have
rewritten the block's words to absolutes (the next block's lookback
needs it); the words that were converted are listed in the one-shot
<a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> record. Property names are used as
JSON keys via <code>nameof</code>.</p>
<p> <p>
<a class="xref" href="Hi.NcParsers.Keywords.IPositioningDef.html#Hi_NcParsers_Keywords_IPositioningDef_Term">Term</a> is the brand-specific G-code (Fanuc/ISO G90/G91); <a class="xref" href="Hi.NcParsers.Keywords.IPositioningDef.html#Hi_NcParsers_Keywords_IPositioningDef_Term">Term</a> is the brand-specific G-code (Fanuc/ISO G90/G91);
<a class="xref" href="Hi.NcParsers.Keywords.IPositioningDef.html#Hi_NcParsers_Keywords_IPositioningDef_Mode">Mode</a> is the conventional, brand-neutral name <a class="xref" href="Hi.NcParsers.Keywords.IPositioningDef.html#Hi_NcParsers_Keywords_IPositioningDef_Mode">Mode</a> is the conventional, brand-neutral name
@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Class IncrementalResolveSyntax | HiAPI-C# 2025 "> <meta name="title" content="Class IncrementalResolveSyntax | HiAPI-C# 2025 ">
<meta name="description" content="Resolves G91 incremental axis values to absolute in-place within and its sub-sections. Reads written by . Per-word override: a block-root section (written by for the Siemens per-word coordinate functions, and by the Heidenhain L / C / CC / CYCL CALL POS parsers for the klartext I-prefixed words — see ; the CYCL CALL POS words never reach this syntax, resolves them on the spot ahead of it) beats the modal term for the listed axes on this block only: an entry converts that word even under G90, an entry skips it even under G91 — as does, deliberately, every other non-Incremental value (the rotary-family / / entries are absolute targets; their swing resolution lives in , not here). A coded-position entry ( / — Siemens CAC()/CIC() on a linear indexing axis) carries an indexing position number instead of a coordinate: the number is resolved through via , the word is rewritten to the resolved absolute coordinate, and the entry to ; a failed resolve reports an error and holds the last program position. Axes without an entry follow the modal term unchanged, so brands that never write the section (Fanuc/...) keep the exact legacy behavior. specifies which JSON paths contain axis values that need incremental-to-absolute conversion. Default: [[&quot;Parsing&quot;], [&quot;Parsing&quot;, &quot;G28&quot;]]; the Heidenhain bundle instead walks [&quot;Parsing&quot;, &quot;CC&quot;] for the klartext circle-center record (). All matching paths are converted against the same last program position — a nested record&#39;s words are distances from where the tool stands, exactly like the root&#39;s. Canned cycle paths (Parsing.G81, G82, G83, …) are intentionally excluded — their Z/R incremental semantics differ from normal axes (R is relative to init level, Z is relative to R-point). Resolution is handled by inside each cycle syntax class, which runs before this syntax. Uses to determine which tags are motion axes. Traces backward nodes for last known to resolve incremental values. After this syntax, all axis values in the working paths are absolute — can consume them without incremental logic."> <meta name="description" content="Resolves G91 incremental axis values to absolute in-place within and its sub-sections. Reads written by . Per-word override: a block-root section (written by for the Siemens per-word coordinate functions, and by the Heidenhain L / C / CC / CYCL CALL POS parsers for the klartext I-prefixed words — see ; the CYCL CALL POS words never reach this syntax, resolves them on the spot ahead of it) beats the modal term for the listed axes on this block only: an entry converts that word even under G90, an entry skips it even under G91 — as does, deliberately, every other non-Incremental value (the rotary-family / / entries are absolute targets; their swing resolution lives in , not here). A coded-position entry ( / — Siemens CAC()/CIC() on a linear indexing axis) carries an indexing position number instead of a coordinate: the number is resolved through via , the word is rewritten to the resolved absolute coordinate, and the entry to ; a failed resolve reports an error and holds the last program position. Axes without an entry follow the modal term unchanged, so brands that never write the section (Fanuc/...) keep the exact legacy behavior. specifies which JSON paths contain axis values that need incremental-to-absolute conversion. Default: [[&quot;Parsing&quot;], [&quot;Parsing&quot;, &quot;G28&quot;]]; the Heidenhain bundle instead walks [&quot;Parsing&quot;, &quot;CC&quot;] for the klartext circle-center record (). All matching paths are converted against the same last program position — a nested record&#39;s words are distances from where the tool stands, exactly like the root&#39;s. Canned cycle paths (Parsing.G81, G82, G83, …) are intentionally excluded — their Z/R incremental semantics differ from normal axes (R is relative to init level, Z is relative to R-point). Resolution is handled by inside each cycle syntax class, which runs before this syntax. Uses to determine which tags are motion axes. Traces backward nodes for last known to resolve incremental values. After this syntax, all axis values in the working paths are absolute — can consume them without incremental logic. Rotary words (A/B/C) at the Parsing root never reach this syntax — consumes them upstream and follows the modal G91 itself. Inside a nested record they do (G91 G28 C10. — the Parsing.G28 intermediate), and a rotary axis has no program→MC transform, so its anchor is the previous modal angle () rather than a component of the program XYZ: the intermediate lands at current + 10&#176;, the way HardNc&#39;s ParseG28 reads it against the previous MC. A never-set rotary axis anchors at 0. The rewrite is in place, and the modal section keeps saying G91 (the next block&#39;s lookback needs it), so a converted word is indistinguishable from a programmed absolute. Every word this syntax converts is therefore also recorded, as programmed, in the one-shot block-root section, shaped like the Parsing tree it came from ({ &quot;X&quot;: 10, &quot;G28&quot;: { &quot;C&quot;: 10 } }). The record doubles as the idempotency guard: a word already listed at its path is left alone, so a second pass over the same block — a project file whose serialized list carries two instances, a re-run over a frozen piece — cannot add the anchor twice. Coded-position words are not recorded (they are not increments of a coordinate; their trace is the rewritten override entry).">
<link rel="icon" href="../img/HiAPI.favicon.ico"> <link rel="icon" href="../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../public/docfx.min.css"> <link rel="stylesheet" href="../public/docfx.min.css">
<link rel="stylesheet" href="../public/main.css"> <link rel="stylesheet" href="../public/main.css">
@@ -160,6 +160,33 @@ After this syntax, all axis values in the working paths are absolute —
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.ProgramXyzSyntax.html">ProgramXyzSyntax</a> can consume them without <a class="xref" href="Hi.NcParsers.LogicSyntaxs.ProgramXyzSyntax.html">ProgramXyzSyntax</a> can consume them without
incremental logic. incremental logic.
</p> </p>
<p>
Rotary words (A/B/C) at the <code>Parsing</code> root never reach this
syntax — <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> consumes them upstream and follows
the modal G91 itself. Inside a nested record they do
(<code>G91 G28 C10.</code> — the <code>Parsing.G28</code> intermediate), and a
rotary axis has no program→MC transform, so its anchor is the
previous modal angle
(<a class="xref" href="Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.html#Hi_NcParsers_LogicSyntaxs_RotaryAxisUtil_FindPreviousMcAxisDeg_Hi_Common_Collections_LazyLinkedListNode_Hi_NcParsers_Syntaxs_SyntaxPiece__System_String_">FindPreviousMcAxisDeg(LazyLinkedListNode&lt;SyntaxPiece&gt;, string)</a>) rather than a
component of the program XYZ: the intermediate lands at
current + 10°, the way HardNc's <code>ParseG28</code> reads it against
the previous MC. A never-set rotary axis anchors at 0.
</p>
<p>
The rewrite is in place, and the modal <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html">Positioning</a>
section keeps saying <code>G91</code> (the next block's lookback needs it),
so a converted word is indistinguishable from a programmed absolute.
Every word this syntax converts is therefore also recorded, as
programmed, in the one-shot block-root <a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a>
section, shaped like the <code>Parsing</code> tree it came from
(<code>{ "X": 10, "G28": { "C": 10 } }</code>). The record doubles as the
idempotency guard: a word already listed at its path is left alone,
so a second pass over the same block — a project file whose
serialized list carries two instances, a re-run over a frozen piece
— cannot add the anchor twice. Coded-position words are not recorded
(they are not increments of a coordinate; their trace is the
rewritten override entry).
</p>
</div> </div>
<div class="markdown conceptual"></div> <div class="markdown conceptual"></div>
@@ -259,7 +286,8 @@ incremental deltas:
<code>MachineCoordinateState=(100,200,300)</code>. Under the identity <code>MachineCoordinateState=(100,200,300)</code>. Under the identity
<code>ProgramToMcTransform</code> chain, <code>GetLastProgramXyz</code> recovers <code>ProgramToMcTransform</code> chain, <code>GetLastProgramXyz</code> recovers
program XYZ equal to MC, so each axis in <code>Parsing</code> is rewritten program XYZ equal to MC, so each axis in <code>Parsing</code> is rewritten
to <code>lastAbs + incremental</code>: to <code>lastAbs + incremental</code>; the programmed deltas go to
<code>IncrementalWords</code>:
#Previous:</p> #Previous:</p>
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "X": 100, "Y": 200, "Z": 300 } }</code></pre> <pre><code class="lang-csharp">{ "MachineCoordinateState": { "X": 100, "Y": 200, "Z": 300 } }</code></pre>
<p>#BeforeBuild:</p> <p>#BeforeBuild:</p>
@@ -270,13 +298,15 @@ to <code>lastAbs + incremental</code>:
<p>#AfterBuild:</p> <p>#AfterBuild:</p>
<pre><code class="lang-csharp">{ <pre><code class="lang-csharp">{
"Positioning": { "Term": "G91", "Mode": "Incremental" }, "Positioning": { "Term": "G91", "Mode": "Incremental" },
"Parsing": { "X": 110, "Y": 220, "Z": 330 } "Parsing": { "X": 110, "Y": 220, "Z": 330 },
"IncrementalWords": { "X": 10, "Y": 20, "Z": 30 }
}</code></pre> }</code></pre>
<p>G91 + <code>Parsing.G28</code> sub-section — exercises the second entry <p>G91 + <code>Parsing.G28</code> sub-section — exercises the second entry
of the default <code>WorkingPathList</code>; the root <code>Parsing</code> has of the default <code>WorkingPathList</code>; the root <code>Parsing</code> has
no X/Y/Z so the first path no-ops, but the no X/Y/Z so the first path no-ops, but the
<code>[&ldquo;Parsing&rdquo;,&ldquo;G28&rdquo;]</code> path picks up the G28 intermediate axes <code>[&ldquo;Parsing&rdquo;,&ldquo;G28&rdquo;]</code> path picks up the G28 intermediate axes
and resolves them against the same <code>lastProgramXyz</code>: and resolves them against the same <code>lastProgramXyz</code>. The record
mirrors the nesting — the words sit under <code>G28</code>:
#Previous:</p> #Previous:</p>
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "X": 100, "Y": 200, "Z": 300 } }</code></pre> <pre><code class="lang-csharp">{ "MachineCoordinateState": { "X": 100, "Y": 200, "Z": 300 } }</code></pre>
<p>#BeforeBuild:</p> <p>#BeforeBuild:</p>
@@ -287,7 +317,8 @@ and resolves them against the same <code>lastProgramXyz</code>:
<p>#AfterBuild:</p> <p>#AfterBuild:</p>
<pre><code class="lang-csharp">{ <pre><code class="lang-csharp">{
"Positioning": { "Term": "G91", "Mode": "Incremental" }, "Positioning": { "Term": "G91", "Mode": "Incremental" },
"Parsing": { "G28": { "X": 105, "Y": 210, "Z": 315 } } "Parsing": { "G28": { "X": 105, "Y": 210, "Z": 315 } },
"IncrementalWords": { "G28": { "X": 5, "Y": 10, "Z": 15 } }
}</code></pre> }</code></pre>
<p>G90 (absolute) with a per-word <code>PositioningOverride</code> — the <p>G90 (absolute) with a per-word <code>PositioningOverride</code> — the
Siemens <code>X=IC(10)</code> shape after Siemens <code>X=IC(10)</code> shape after
@@ -305,11 +336,12 @@ against the last program position; Y follows the modal G90 and stays:
<pre><code class="lang-csharp">{ <pre><code class="lang-csharp">{
"Positioning": { "Term": "G90", "Mode": "Absolute" }, "Positioning": { "Term": "G90", "Mode": "Absolute" },
"PositioningOverride": { "X": "Incremental" }, "PositioningOverride": { "X": "Incremental" },
"Parsing": { "X": 110, "Y": 20 } "Parsing": { "X": 110, "Y": 20 },
"IncrementalWords": { "X": 10 }
}</code></pre> }</code></pre>
<p>G91 (incremental) with an <code>Absolute</code> override on X — X is <p>G91 (incremental) with an <code>Absolute</code> override on X — X is
skipped (already absolute, e.g. from <code>X=AC(25)</code>), Y still skipped (already absolute, e.g. from <code>X=AC(25)</code>) and stays out
converts under the modal G91: of the record, Y still converts under the modal G91:
#Previous:</p> #Previous:</p>
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "X": 100, "Y": 200, "Z": 300 } }</code></pre> <pre><code class="lang-csharp">{ "MachineCoordinateState": { "X": 100, "Y": 200, "Z": 300 } }</code></pre>
<p>#BeforeBuild:</p> <p>#BeforeBuild:</p>
@@ -322,7 +354,8 @@ converts under the modal G91:
<pre><code class="lang-csharp">{ <pre><code class="lang-csharp">{
"Positioning": { "Term": "G91", "Mode": "Incremental" }, "Positioning": { "Term": "G91", "Mode": "Incremental" },
"PositioningOverride": { "X": "Absolute" }, "PositioningOverride": { "X": "Absolute" },
"Parsing": { "X": 25, "Y": 220 } "Parsing": { "X": 25, "Y": 220 },
"IncrementalWords": { "Y": 20 }
}</code></pre> }</code></pre>
<p>Coded-position absolute on a linear indexing axis (the Siemens <p>Coded-position absolute on a linear indexing axis (the Siemens
<code>X=CAC(2)</code> workholder shape after the unwrap + evaluation <code>X=CAC(2)</code> workholder shape after the unwrap + evaluation
@@ -360,7 +393,46 @@ root carries no axis word on a CC block and is untouched:
<pre><code class="lang-csharp">{ <pre><code class="lang-csharp">{
"Positioning": { "Term": "G90", "Mode": "Absolute" }, "Positioning": { "Term": "G90", "Mode": "Absolute" },
"PositioningOverride": { "X": "Incremental", "Y": "Incremental" }, "PositioningOverride": { "X": "Incremental", "Y": "Incremental" },
"Parsing": { "CC": { "X": 10, "Y": 31 } } "Parsing": { "CC": { "X": 10, "Y": 31 } },
"IncrementalWords": { "CC": { "X": 0, "Y": 11 } }
}</code></pre>
<p>G91 + <code>Parsing.G28</code> carrying a rotary word (<code>G91 G28 X0 C10.</code>
on the A/B/C fallback axis list): the rotary anchor is the previous
modal angle in <code>#Previous:</code> <code>MachineCoordinateState.C</code>, so
the intermediate C is 30 + 10 = 40 — while X still resolves against
the last program position (100 + 0). A root rotary word would never
be here: <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> consumes it first:
#Previous:</p>
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "X": 100, "Y": 200, "Z": 300, "C": 30 } }</code></pre>
<p>#BeforeBuild:</p>
<pre><code class="lang-csharp">{
"Positioning": { "Term": "G91", "Mode": "Incremental" },
"Parsing": { "G28": { "X": 0, "C": 10 } }
}</code></pre>
<p>#AfterBuild:</p>
<pre><code class="lang-csharp">{
"Positioning": { "Term": "G91", "Mode": "Incremental" },
"Parsing": { "G28": { "X": 100, "C": 40 } },
"IncrementalWords": { "G28": { "X": 0, "C": 10 } }
}</code></pre>
<p>A second pass over an already-resolved block — the <code>#BeforeBuild:</code>
is the previous case's <code>#AfterBuild:</code> for a root word: the
record lists X, so the syntax leaves the (now absolute) 110 alone
instead of adding the anchor again. The guard is what makes the
in-place rewrite safe against a list that runs the resolve twice:
#Previous:</p>
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "X": 100, "Y": 200, "Z": 300 } }</code></pre>
<p>#BeforeBuild:</p>
<pre><code class="lang-csharp">{
"Positioning": { "Term": "G91", "Mode": "Incremental" },
"Parsing": { "X": 110 },
"IncrementalWords": { "X": 10 }
}</code></pre>
<p>#AfterBuild:</p>
<pre><code class="lang-csharp">{
"Positioning": { "Term": "G91", "Mode": "Incremental" },
"Parsing": { "X": 110 },
"IncrementalWords": { "X": 10 }
}</code></pre> }</code></pre>
@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Class McAbcCyclicPathSyntax | HiAPI-C# 2025 "> <meta name="title" content="Class McAbcCyclicPathSyntax | HiAPI-C# 2025 ">
<meta name="description" content="Resolve modular rotary axes to the shortest cyclic path relative to the previous node. Uses to determine which axes within need cyclic resolution. Falls back to hardcoded A/B/C if no is available. Must be placed after in . Two stages, mirroring : Root MachineCoordinateState — anchored at the previous block&#39;s modal rotary state..[*] — sequential walk through items, anchoring item 0 at the previous block&#39;s modal state and item i &amp;gt; 0 at item i-1&#39;s post-cycle value (per-axis chain). Items without a rotary MachineCoordinateState are skipped. The items pass enables rotary motion (e.g. G28 ABC intermediate / home stages) to surface as motion segments rather than a single root-MC stamp. Per-word directional override: a block-root entry (stamped by ) valued (Siemens ACP()) or (ACN()) swaps that axis&#39;s window for this block only: [anchor, anchor+360&#176;) / (anchor-360&#176;, anchor] instead of the default &#177;180&#176; — the approach direction is forced even when it is the longer way around. A target congruent with the anchor (within an ULP-scale epsilon) keeps the anchor value verbatim — no move, never a spurious full turn, and no deg→rad→deg drift. (DC()) is the default window and needs no special path here. The override is read from the current block only (it is one-shot, never carried — deliberately unlike the modal RotaryWrap gate&#39;s one-step previous fallback) and applies to the root MC stage, not to items in general (G28/G74/G75 expansions capture their words in sub-objects the stamping syntax never sees, so an override can only ever describe a root word) — with one exception: an item whose value for an axis equals the root&#39;s pre-pass value verbatim carries that same root word (the canned-cycle pre-positioning item that stamps from the root MC) and inherits the root&#39;s directive for that axis, so the default window cannot fold the forced swing the root resolved into the short way. Directional/shortest entries keyed by an axis outside the modular set are reported as Coord-McAbc--003 — the promise cannot be honored there and silence would mis-read the program&#39;s intent; an entry with no anchor to resolve against (first rotary value in the stream) is reported as Coord-McAbc--004 and adopted unwrapped, matching the default path. Per-word incremental override: an entry (Siemens IC(), klartext IC+270) is a signed traverse by definition already wrote anchor + delta — so this pass keeps that value verbatim for the axis instead of folding it into the &#177;180&#176; window (a +270&#176; chain dimension must not become a -90&#176; swing). Incremental entries on non-modular axes need no warning: the literal value is what the axis would do anyway."> <meta name="description" content="Resolve modular rotary axes to the shortest cyclic path relative to the previous node. Uses to determine which axes within need cyclic resolution. Falls back to hardcoded A/B/C if no is available. Must be placed after in . Two stages, mirroring : Root MachineCoordinateState — anchored at the previous block&#39;s modal rotary state..[*] — sequential walk through items, anchoring item 0 at the previous block&#39;s modal state and item i &amp;gt; 0 at item i-1&#39;s post-cycle value (per-axis chain). Items without a rotary MachineCoordinateState are skipped. The items pass enables rotary motion (e.g. G28 ABC intermediate / home stages) to surface as motion segments rather than a single root-MC stamp. Per-word directional override: a block-root entry (stamped by ) valued (Siemens ACP()) or (ACN()) swaps that axis&#39;s window for this block only: [anchor, anchor+360&#176;) / (anchor-360&#176;, anchor] instead of the default &#177;180&#176; — the approach direction is forced even when it is the longer way around. A target congruent with the anchor (within an ULP-scale epsilon) keeps the anchor value verbatim — no move, never a spurious full turn, and no deg→rad→deg drift. (DC()) is the default window and needs no special path here. The override is read from the current block only (it is one-shot, never carried — deliberately unlike the modal RotaryWrap gate&#39;s one-step previous fallback) and applies to the root MC stage, not to items in general (G28/G74/G75 expansions capture their words in sub-objects the stamping syntax never sees, so an override can only ever describe a root word) — with one exception: an item whose value for an axis equals the root&#39;s pre-pass value verbatim carries that same root word (the canned-cycle pre-positioning item that stamps from the root MC) and inherits the root&#39;s directive for that axis, so the default window cannot fold the forced swing the root resolved into the short way. Directional/shortest entries keyed by an axis outside the modular set are reported as Coord-McAbc--003 — the promise cannot be honored there and silence would mis-read the program&#39;s intent; an entry with no anchor to resolve against (first rotary value in the stream) is reported as Coord-McAbc--004 and adopted unwrapped, matching the default path. Incremental words: a rotary word programmed as an increment — per-word (Siemens IC(), klartext IC+270) or a bare word under modal G91 — is a signed traverse by definition. already wrote anchor + delta into the MC and listed the axis in the one-shot record; this pass reads that record — and only that record — and keeps the listed axes verbatim instead of folding them into the &#177;180&#176; window (a +270&#176; chain dimension must not become a -90&#176; swing). A listed non-modular axis needs nothing: the literal value is what the axis would do anyway. A rotary value the block carries without a word (lookback fill, or an absolute target another writer put there — G53.1, the Heidenhain PLANE syntax) is not listed and keeps the default window even under G91.">
<link rel="icon" href="../img/HiAPI.favicon.ico"> <link rel="icon" href="../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../public/docfx.min.css"> <link rel="stylesheet" href="../public/docfx.min.css">
<link rel="stylesheet" href="../public/main.css"> <link rel="stylesheet" href="../public/main.css">
@@ -148,14 +148,19 @@ to resolve against (first rotary value in the stream) is reported as
path. path.
</p> </p>
<p> <p>
Per-word incremental override: an <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_Incremental">Incremental</a> Incremental words: a rotary word programmed as an increment —
entry (Siemens <code>IC()</code>, klartext <code>IC+270</code>) is a signed per-word (Siemens <code>IC()</code>, klartext <code>IC+270</code>) or a bare
traverse by definition — <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> already wrote word under modal <code>G91</code> — is a signed traverse by definition.
anchor + delta — so this pass keeps that value verbatim for the <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> already wrote anchor + delta into the MC
axis instead of folding it into the ±180° window (a +270° chain and listed the axis in the one-shot <a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a>
dimension must not become a -90° swing). Incremental entries on record; this pass reads that record — and only that record — and
non-modular axes need no warning: the literal value is what the keeps the listed axes verbatim instead of folding them into the ±180°
axis would do anyway. window (a +270° chain dimension must not become a -90° swing). A
listed non-modular axis needs nothing: the literal value is what the
axis would do anyway. A rotary value the block carries without a
word (lookback fill, or an absolute target another writer put there
<code>G53.1</code>, the Heidenhain <code>PLANE</code> syntax) is not listed
and keeps the default window even under G91.
</p> </p>
</div> </div>
<div class="markdown conceptual"></div> <div class="markdown conceptual"></div>
@@ -354,20 +359,24 @@ would decide between "no move" and a spurious full -360° turn):
"PositioningOverride": { "B": "NegativeOnly" } "PositioningOverride": { "B": "NegativeOnly" }
}</code></pre> }</code></pre>
Incremental word (<code>B=IC(270)</code> / klartext <code>L IB+270</code>): the Incremental word (<code>B=IC(270)</code> / klartext <code>L IB+270</code>): the
rotary writer accumulated anchor 0° + 270° = 270°, and the pass keeps rotary writer accumulated anchor 0° + 270° = 270° and listed B in
the traverse literal — the same 270° that the default window above <code>IncrementalWords</code>, and the pass keeps the traverse literal —
rewrote to -90° stays +270°: the same 270° that the default window above rewrote to -90° stays
+270°. The per-word entry is still on the block (nothing consumes
it) but is not what this pass reads:
#Previous: #Previous:
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "B": 0 } }</code></pre> <pre><code class="lang-csharp">{ "MachineCoordinateState": { "B": 0 } }</code></pre>
#BeforeBuild: #BeforeBuild:
<pre><code class="lang-csharp">{ <pre><code class="lang-csharp">{
"MachineCoordinateState": { "B": 270 }, "MachineCoordinateState": { "B": 270 },
"PositioningOverride": { "B": "Incremental" } "PositioningOverride": { "B": "Incremental" },
"IncrementalWords": { "B": 270 }
}</code></pre> }</code></pre>
#AfterBuild: #AfterBuild:
<pre><code class="lang-csharp">{ <pre><code class="lang-csharp">{
"MachineCoordinateState": { "B": 270 }, "MachineCoordinateState": { "B": 270 },
"PositioningOverride": { "B": "Incremental" } "PositioningOverride": { "B": "Incremental" },
"IncrementalWords": { "B": 270 }
}</code></pre> }</code></pre>
A <code>CompoundMotion</code> item carrying the root word verbatim — the A <code>CompoundMotion</code> item carrying the root word verbatim — the
canned-cycle pre-positioning item that canned-cycle pre-positioning item that
@@ -402,6 +411,26 @@ and resolves under the default window against the chained anchor
] ]
} }
}</code></pre> }</code></pre>
A bare rotary word under modal G91 (Fanuc <code>G91 … B270.</code>) has no
per-word entry at all — the rotary writer accumulated 0° + 270° and
listed B in <code>IncrementalWords</code>, and that listing alone keeps the
+270° traverse literal. C is on the block without a word (the value
an absolute writer such as <code>G53.1</code> would leave), so it is not
listed and still resolves under the default window: 270° from anchor
0° folds to 90°. Neither <code>Positioning</code> nor <code>RotaryWords</code>
is consulted, so the case carries neither:
#Previous:
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "B": 0, "C": 0 } }</code></pre>
#BeforeBuild:
<pre><code class="lang-csharp">{
"IncrementalWords": { "B": 270 },
"MachineCoordinateState": { "B": 270, "C": 270 }
}</code></pre>
#AfterBuild:
<pre><code class="lang-csharp">{
"IncrementalWords": { "B": 270 },
"MachineCoordinateState": { "B": 270, "C": -90 }
}</code></pre>
@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Class McAbcSyntax | HiAPI-C# 2025 "> <meta name="title" content="Class McAbcSyntax | HiAPI-C# 2025 ">
<meta name="description" content="Writes rotary axis values (A/B/C) into from and modal lookback. Only active when declares rotary axes. Works for both 3+2-axis (no ) and simultaneous 5-axis configurations. This syntax is intentionally ABC-only. When the block is rotary-only (no ProgramXyz, e.g. G00 A30.) the section is created with ABC but without X/Y/Z. — placed after — copies X/Y/Z from the previous block&#39;s to finish the section. Splitting the XYZ fill out lets this syntax run before (and before ) without accidentally filling X/Y/Z from prev and thereby short-circuiting . Missing rotary axes are filled from previous lookback, unless the current section already has the value (e.g., from ). Values are stored in degrees (matching ). Per-word override: a block-root section (written by for the Siemens AC()/IC() coordinate functions, and by the Heidenhain L / C parsers for the klartext IA+/IB+/IC+ words) marks a rotary word : the parsed value is then added to the previous modal value of that axis (previous MachineCoordinateState lookback, falling back to a value already present in the current section, then 0) instead of being written as an absolute angle. The accumulated raw degrees stay monotonic across iterations: the tail-pass keeps an Incremental-stamped axis literal (a chain dimension is a signed traverse, never re-shortened), so even a +270&#176; step survives as net rotation. An entry (from AC()) matches the default write and needs no special path — and so, deliberately, do the rotary-family entries (DC()) / (ACP()) / (ACN()): this syntax writes the raw absolute target and the shortest/directional swing is resolved by the tail-pass, which owns the wrap math. Brands that never write the section keep the exact legacy behavior. Coded-position overrides (Siemens CAC()/CIC()/CDC()/CACP()/CACN()) carry an indexing position number instead of an angle: the number is resolved through via and the override entry is rewritten to the plain vocabulary ( / / / — a cyclic CIC keeps its programmed direction through the directional values) before the tail-pass runs, so the tail-pass never sees a coded value. A failed resolve (invalid number, missing table) reports an error and holds the axis at its previous value. Every rotary word the block actually carried is also recorded, as programmed, in the one-shot block-root section ({ &quot;C&quot;: 40 }) — the resolved angle goes into MachineCoordinateState, which after the modal carry can no longer tell &quot;commanded&quot; from &quot;carried&quot;. Downstream consumers that need that distinction ( repeating an active canned cycle on a rotary-only block, riding the block&#39;s ABC on the cycle&#39;s pre-positioning item) read the record; the section is never modal-carried. Must be placed before so syntaxes that need the current-block ABC to compute transforms (e.g. ) can see it; and before and ."> <meta name="description" content="Writes rotary axis values (A/B/C) into from and modal lookback. Only active when declares rotary axes. Works for both 3+2-axis (no ) and simultaneous 5-axis configurations. This syntax is intentionally ABC-only. When the block is rotary-only (no ProgramXyz, e.g. G00 A30.) the section is created with ABC but without X/Y/Z. — placed after — copies X/Y/Z from the previous block&#39;s to finish the section. Splitting the XYZ fill out lets this syntax run before (and before ) without accidentally filling X/Y/Z from prev and thereby short-circuiting . Missing rotary axes are filled from previous lookback, unless the current section already has the value (e.g., from ). Values are stored in degrees (matching ). Per-word override: a block-root section (written by for the Siemens AC()/IC() coordinate functions, and by the Heidenhain L / C parsers for the klartext IA+/IB+/IC+ words) marks a rotary word : the parsed value is then added to the previous modal value of that axis (previous MachineCoordinateState lookback, falling back to a value already present in the current section, then 0) instead of being written as an absolute angle. The accumulated raw degrees stay monotonic across iterations: the tail-pass keeps an Incremental-stamped axis literal (a chain dimension is a signed traverse, never re-shortened), so even a +270&#176; step survives as net rotation. An entry (from AC()) matches the default write and needs no special path — and so, deliberately, do the rotary-family entries (DC()) / (ACP()) / (ACN()): this syntax writes the raw absolute target and the shortest/directional swing is resolved by the tail-pass, which owns the wrap math. Brands that never write the section keep the exact legacy behavior. Modal G91: a rotary word with no per-word entry follows the block&#39;s state (written ahead of this syntax by on every brand list) the way the linear words follow it in — under G91 it takes the same anchor + delta path as the override, so G91 … C20. repeated turns the table 20&#176; further each block (Fanuc / Siemens / Heidenhain DIN-ISO all read an incremental rotary word as a signed traverse; the tail-pass keeps it literal for the axes the record lists). A per-word entry of any value beats the modal state for its word (G91 C=AC(90) is absolute). Rotary values another writer put on the block without a word — , the Heidenhain PLANE syntax — are absolute targets and are not touched. HardNc differs here by design of its own: HardNcLine.BuildOrdinaryMcAbc writes the word as an absolute angle under G91 and warns (&quot;G91 is not effect for commands ABC&quot;), so the two engines diverge on G91 rotary words — the parity fixtures assert the SoftNc leg only. Coded-position overrides (Siemens CAC()/CIC()/CDC()/CACP()/CACN()) carry an indexing position number instead of an angle: the number is resolved through via and the override entry is rewritten to the plain vocabulary ( / / / — a cyclic CIC keeps its programmed direction through the directional values) before the tail-pass runs, so the tail-pass never sees a coded value. A failed resolve (invalid number, missing table) reports an error and holds the axis at its previous value. Every rotary word the block actually carried is also recorded, as programmed, in the one-shot block-root section ({ &quot;C&quot;: 40 }) — the resolved angle goes into MachineCoordinateState, which after the modal carry can no longer tell &quot;commanded&quot; from &quot;carried&quot;. Downstream consumers that need that distinction ( repeating an active canned cycle on a rotary-only block, riding the block&#39;s ABC on the cycle&#39;s pre-positioning item) read the record; the section is never modal-carried. Its sibling records, with the programmed delta, the rotary words this syntax accumulated as increments (per-word IC()/IC+ or a bare word under modal G91): the MC value is an absolute angle from then on and the modal still says G91, so without the record an accumulated word would read like a programmed absolute. adds the block&#39;s linear increments to the same record later in the list, and reads it to pass the listed axes through the shortest-path wrap literally. Must be placed before so syntaxes that need the current-block ABC to compute transforms (e.g. ) can see it; and before and .">
<link rel="icon" href="../img/HiAPI.favicon.ico"> <link rel="icon" href="../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../public/docfx.min.css"> <link rel="stylesheet" href="../public/docfx.min.css">
<link rel="stylesheet" href="../public/main.css"> <link rel="stylesheet" href="../public/main.css">
@@ -152,6 +152,28 @@ math. Brands that never write the section keep the exact legacy
behavior. behavior.
</p> </p>
<p> <p>
Modal G91: a rotary word with <b>no</b> per-word entry follows the
block's <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html">Positioning</a> state (written ahead of this
syntax by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.PositioningSyntax.html">PositioningSyntax</a> on every brand list) the
way the linear words follow it in
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> — under <code>G91</code> it takes
the same anchor + delta path as the <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_Incremental">Incremental</a>
override, so <code>G91 … C20.</code> repeated turns the table 20° further
each block (Fanuc / Siemens / Heidenhain DIN-ISO all read an
incremental rotary word as a signed traverse; the
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a> tail-pass keeps it literal for
the axes the <a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> record lists). A per-word entry of any
value beats the modal state for its word (<code>G91 C=AC(90)</code> is
absolute). Rotary values another writer put on the block without a
word — <a class="xref" href="Hi.NcParsers.LogicSyntaxs.G53p1RotaryPositionSyntax.html">G53p1RotaryPositionSyntax</a>, the Heidenhain
<code>PLANE</code> syntax — are absolute targets and are not touched.
HardNc differs here by design of its own: <code>HardNcLine.BuildOrdinaryMcAbc</code>
writes the word as an absolute angle under G91 and warns
(<i>"G91 is not effect for commands ABC"</i>), so the two engines
diverge on G91 rotary words — the parity fixtures assert the
SoftNc leg only.
</p>
<p>
Coded-position overrides (Siemens Coded-position overrides (Siemens
<code>CAC()</code>/<code>CIC()</code>/<code>CDC()</code>/<code>CACP()</code>/<code>CACN()</code>) <code>CAC()</code>/<code>CIC()</code>/<code>CDC()</code>/<code>CACP()</code>/<code>CACN()</code>)
carry an indexing position <b>number</b> instead of an angle: the carry an indexing position <b>number</b> instead of an angle: the
@@ -177,7 +199,17 @@ that distinction (<a class="xref" href="Hi.NcParsers.LogicSyntaxs.CannedCycleRes
active canned cycle on a rotary-only block, active canned cycle on a rotary-only block,
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.text.json.nodes.jsonobject">WriteCompoundMotion(JsonObject, string, JsonArray, Vec3d)</a> riding the <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.text.json.nodes.jsonobject">WriteCompoundMotion(JsonObject, string, JsonArray, Vec3d)</a> riding the
block's ABC on the cycle's pre-positioning item) read the record; the block's ABC on the cycle's pre-positioning item) read the record; the
section is never modal-carried. section is never modal-carried. Its sibling
<a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> records, with the programmed delta,
the rotary words this syntax accumulated as increments (per-word
<code>IC()</code>/<code>IC+</code> or a bare word under modal G91): the MC
value is an absolute angle from then on and the modal
<a class="xref" href="Hi.NcParsers.Keywords.Positioning.html">Positioning</a> still says G91, so without the record an
accumulated word would read like a programmed absolute.
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> adds the block's linear
increments to the same record later in the list, and
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a> reads it to pass the listed axes
through the shortest-path wrap literally.
</p> </p>
<p> <p>
Must be placed <b>before</b> <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McXyzSyntax.html">McXyzSyntax</a> so syntaxes Must be placed <b>before</b> <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McXyzSyntax.html">McXyzSyntax</a> so syntaxes
@@ -294,7 +326,8 @@ spoke are recorded as programmed in the one-shot
}</code></pre> }</code></pre>
Only <code>Parsing.B</code> on the current block; <code>#Previous:</code> Only <code>Parsing.B</code> on the current block; <code>#Previous:</code>
carries a full MC including C=0. The missing C is filled from the carries a full MC including C=0. The missing C is filled from the
per-axis backward lookback (<a class="xref" href="Hi.NcParsers.Syntaxs.SyntaxPiece.html">FindPreviousMcAxis(LazyLinkedListNode&lt;SyntaxPiece&gt;, string)</a>) — and per-axis backward lookback
(<a class="xref" href="Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.html#Hi_NcParsers_LogicSyntaxs_RotaryAxisUtil_FindPreviousMcAxisDeg_Hi_Common_Collections_LazyLinkedListNode_Hi_NcParsers_Syntaxs_SyntaxPiece__System_String_">FindPreviousMcAxisDeg(LazyLinkedListNode&lt;SyntaxPiece&gt;, string)</a>) — and
stays out of <code>RotaryWords</code>, which lists commanded words only: stays out of <code>RotaryWords</code>, which lists commanded words only:
#Previous: #Previous:
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "B": 0, "C": 0 } }</code></pre> <pre><code class="lang-csharp">{ "MachineCoordinateState": { "B": 0, "C": 0 } }</code></pre>
@@ -309,7 +342,8 @@ Per-word incremental override (the Siemens <code>C=IC(...)</code> shape
after the unwrap + evaluation stages) — the parsed 21.5 is added onto after the unwrap + evaluation stages) — the parsed 21.5 is added onto
the previous modal C instead of overwriting it; B has no override the previous modal C instead of overwriting it; B has no override
entry and fills from lookback as usual. <code>RotaryWords</code> keeps the entry and fills from lookback as usual. <code>RotaryWords</code> keeps the
programmed delta, not the accumulated angle: programmed delta, not the accumulated angle, and the accumulated
word is listed in <code>IncrementalWords</code>:
#Previous: #Previous:
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "B": 10, "C": 40 } }</code></pre> <pre><code class="lang-csharp">{ "MachineCoordinateState": { "B": 10, "C": 40 } }</code></pre>
#BeforeBuild: #BeforeBuild:
@@ -321,7 +355,8 @@ programmed delta, not the accumulated angle:
<pre><code class="lang-csharp">{ <pre><code class="lang-csharp">{
"PositioningOverride": { "C": "Incremental" }, "PositioningOverride": { "C": "Incremental" },
"MachineCoordinateState": { "B": 10, "C": 61.5 }, "MachineCoordinateState": { "B": 10, "C": 61.5 },
"RotaryWords": { "C": 21.5 } "RotaryWords": { "C": 21.5 },
"IncrementalWords": { "C": 21.5 }
}</code></pre> }</code></pre>
Coded-position absolute (the Siemens <code>C=CAC(3)</code> shape after the Coded-position absolute (the Siemens <code>C=CAC(3)</code> shape after the
unwrap + evaluation stages). The case injects a unwrap + evaluation stages). The case injects a
@@ -358,6 +393,48 @@ so the swing keeps the programmed direction:
"MachineCoordinateState": { "C": 90 }, "MachineCoordinateState": { "C": 90 },
"RotaryWords": { "C": 2 } "RotaryWords": { "C": 2 }
}</code></pre> }</code></pre>
Modal G91 with no per-word entry (the Fanuc <code>G91 … C20.</code>
canned-cycle repeat block): the rotary word is a signed traverse
like the linear words, so it accumulates onto the previous modal C
exactly as the Incremental override above (20 + 20 = 40); B has no
word and fills from lookback. <code>RotaryWords</code> keeps the programmed
delta and <code>IncrementalWords</code> lists the word — the modal section
still says G91, and this record is what tells the accumulated 40
apart from a programmed <code>C40.</code>:
#Previous:
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "B": 10, "C": 20 } }</code></pre>
#BeforeBuild:
<pre><code class="lang-csharp">{
"Positioning": { "Term": "G91", "Mode": "Incremental" },
"Parsing": { "C": 20 }
}</code></pre>
#AfterBuild:
<pre><code class="lang-csharp">{
"Positioning": { "Term": "G91", "Mode": "Incremental" },
"MachineCoordinateState": { "B": 10, "C": 40 },
"RotaryWords": { "C": 20 },
"IncrementalWords": { "C": 20 }
}</code></pre>
Modal G91 with a per-word <code>Absolute</code> entry (the Siemens
<code>G91 … C=AC(90)</code> shape): the entry beats the modal state for
its word, so C is written as the absolute 90 — the same rule
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> applies to <code>X=AC(25)</code>
under G91:
#Previous:
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "B": 10, "C": 20 } }</code></pre>
#BeforeBuild:
<pre><code class="lang-csharp">{
"Positioning": { "Term": "G91", "Mode": "Incremental" },
"PositioningOverride": { "C": "Absolute" },
"Parsing": { "C": 90 }
}</code></pre>
#AfterBuild:
<pre><code class="lang-csharp">{
"Positioning": { "Term": "G91", "Mode": "Incremental" },
"PositioningOverride": { "C": "Absolute" },
"MachineCoordinateState": { "B": 10, "C": 90 },
"RotaryWords": { "C": 90 }
}</code></pre>
@@ -270,7 +270,10 @@ these per-SUT conformance assertions show only the raw literal /
canonical-home values written by this syntax, before any cyclic canonical-home values written by this syntax, before any cyclic
normalization runs. normalization runs.
</p> </p>
<code>G91 G28 B45.</code> — pure rotary G28. Emits a 2-item <code>G28 B45.</code> — pure rotary G28 (the record arrives absolute: under
G91 <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a>, which runs ahead of this
syntax, has already added the word onto the previous modal angle).
Emits a 2-item
<code>CompoundMotion</code> whose items carry only ABC keys in MC; no XYZ <code>CompoundMotion</code> whose items carry only ABC keys in MC; no XYZ
<code>ProgramXyz</code> and no XYZ MC because the block doesn't reference <code>ProgramXyz</code> and no XYZ MC because the block doesn't reference
X/Y/Z (and the conformance harness doesn't run X/Y/Z (and the conformance harness doesn't run
@@ -100,6 +100,7 @@ Class RotaryAxisUtil
<div class="markdown summary"><p>Shared utilities for rotary axis (A/B/C) resolution. <div class="markdown summary"><p>Shared utilities for rotary axis (A/B/C) resolution.
Used by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.G53p1RotaryPositionSyntax.html">G53p1RotaryPositionSyntax</a>, Used by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.G53p1RotaryPositionSyntax.html">G53p1RotaryPositionSyntax</a>,
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a>, <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IsoG68p2TiltSyntax.html">IsoG68p2TiltSyntax</a>, <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a>, <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IsoG68p2TiltSyntax.html">IsoG68p2TiltSyntax</a>,
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a>
and other syntaxes that read or write rotary axis values.</p> and other syntaxes that read or write rotary axis values.</p>
</div> </div>
<div class="markdown conceptual"></div> <div class="markdown conceptual"></div>
@@ -209,6 +210,60 @@ syntaxes do not re-process it.
<a id="Hi_NcParsers_LogicSyntaxs_RotaryAxisUtil_FindPreviousMcAxisDeg_" data-uid="Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.FindPreviousMcAxisDeg*"></a>
<h3 id="Hi_NcParsers_LogicSyntaxs_RotaryAxisUtil_FindPreviousMcAxisDeg_Hi_Common_Collections_LazyLinkedListNode_Hi_NcParsers_Syntaxs_SyntaxPiece__System_String_" data-uid="Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.FindPreviousMcAxisDeg(Hi.Common.Collections.LazyLinkedListNode{Hi.NcParsers.Syntaxs.SyntaxPiece},System.String)">
FindPreviousMcAxisDeg(LazyLinkedListNode&lt;SyntaxPiece&gt;, string)
</h3>
<div class="markdown level1 summary"><p>Walks backward through previous <a class="xref" href="Hi.NcParsers.Syntaxs.SyntaxPiece.html">SyntaxPiece</a> nodes to
find the most recent <a class="xref" href="Hi.NcParsers.Keywords.IMachineCoordinateStateDef.html#Hi_NcParsers_Keywords_IMachineCoordinateStateDef_MachineCoordinateState">MachineCoordinateState</a>
that carries a numeric value for the given <code class="paramref">axis</code>
— the axis's modal angle in degrees as the machine-state section
stores it (after the <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a> wrap of
that block), the anchor an incremental rotary word adds onto.
Returns null when no predecessor carries the axis.</p>
<p>
Per-axis (rather than whole-section) because intermediate blocks
— e.g. <a class="xref" href="Hi.NcParsers.LogicSyntaxs.CircularMotionSyntax.html">CircularMotionSyntax</a> blocks whose MC was
written by <a class="xref" href="Hi.NcParsers.SoftNcUtil.html#Hi_NcParsers_SoftNcUtil_SetVec3d_System_Text_Json_Nodes_JsonObject_System_String_Hi_Geom_Vec3d_">SetVec3d(JsonObject, string, Vec3d)</a> with XYZ only — can
lack rotary fields; whole-section lookback would stop at such a
block and mistakenly conclude the rotary value is unknown. Silent
on a non-numeric value (the throwing machine-state reader — a
non-numeric MC is a HiAPIs codegen bug, not a program error).
</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static double? FindPreviousMcAxisDeg(LazyLinkedListNode&lt;SyntaxPiece&gt; node, string axis)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>node</code> <a class="xref" href="Hi.Common.Collections.LazyLinkedListNode-1.html">LazyLinkedListNode</a>&lt;<a class="xref" href="Hi.NcParsers.Syntaxs.SyntaxPiece.html">SyntaxPiece</a>&gt;</dt>
<dd></dd>
<dt><code>axis</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.string">string</a></dt>
<dd></dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.double">double</a>?</dt>
<dd></dd>
</dl>
<a id="Hi_NcParsers_LogicSyntaxs_RotaryAxisUtil_GetRotaryAxes_" data-uid="Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.GetRotaryAxes*"></a> <a id="Hi_NcParsers_LogicSyntaxs_RotaryAxisUtil_GetRotaryAxes_" data-uid="Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.GetRotaryAxes*"></a>
<h3 id="Hi_NcParsers_LogicSyntaxs_RotaryAxisUtil_GetRotaryAxes_Hi_NcParsers_Dependencys_IMachineAxisConfig_" data-uid="Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.GetRotaryAxes(Hi.NcParsers.Dependencys.IMachineAxisConfig)"> <h3 id="Hi_NcParsers_LogicSyntaxs_RotaryAxisUtil_GetRotaryAxes_Hi_NcParsers_Dependencys_IMachineAxisConfig_" data-uid="Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.GetRotaryAxes(Hi.NcParsers.Dependencys.IMachineAxisConfig)">
@@ -507,6 +507,33 @@ After this syntax, all axis values in the working paths are absolute —
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.ProgramXyzSyntax.html">ProgramXyzSyntax</a> can consume them without <a class="xref" href="Hi.NcParsers.LogicSyntaxs.ProgramXyzSyntax.html">ProgramXyzSyntax</a> can consume them without
incremental logic. incremental logic.
</p> </p>
<p>
Rotary words (A/B/C) at the <code>Parsing</code> root never reach this
syntax — <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> consumes them upstream and follows
the modal G91 itself. Inside a nested record they do
(<code>G91 G28 C10.</code> — the <code>Parsing.G28</code> intermediate), and a
rotary axis has no program→MC transform, so its anchor is the
previous modal angle
(<a class="xref" href="Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.html#Hi_NcParsers_LogicSyntaxs_RotaryAxisUtil_FindPreviousMcAxisDeg_Hi_Common_Collections_LazyLinkedListNode_Hi_NcParsers_Syntaxs_SyntaxPiece__System_String_">FindPreviousMcAxisDeg(LazyLinkedListNode&lt;SyntaxPiece&gt;, string)</a>) rather than a
component of the program XYZ: the intermediate lands at
current + 10°, the way HardNc's <code>ParseG28</code> reads it against
the previous MC. A never-set rotary axis anchors at 0.
</p>
<p>
The rewrite is in place, and the modal <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html">Positioning</a>
section keeps saying <code>G91</code> (the next block's lookback needs it),
so a converted word is indistinguishable from a programmed absolute.
Every word this syntax converts is therefore also recorded, as
programmed, in the one-shot block-root <a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a>
section, shaped like the <code>Parsing</code> tree it came from
(<code>{ "X": 10, "G28": { "C": 10 } }</code>). The record doubles as the
idempotency guard: a word already listed at its path is left alone,
so a second pass over the same block — a project file whose
serialized list carries two instances, a re-run over a frozen piece
— cannot add the anchor twice. Coded-position words are not recorded
(they are not increments of a coordinate; their trace is the
rewritten override entry).
</p>
</dd> </dd>
</dl> </dl>
<dl class="jumplist"> <dl class="jumplist">
@@ -743,14 +770,19 @@ to resolve against (first rotary value in the stream) is reported as
path. path.
</p> </p>
<p> <p>
Per-word incremental override: an <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_Incremental">Incremental</a> Incremental words: a rotary word programmed as an increment —
entry (Siemens <code>IC()</code>, klartext <code>IC+270</code>) is a signed per-word (Siemens <code>IC()</code>, klartext <code>IC+270</code>) or a bare
traverse by definition — <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> already wrote word under modal <code>G91</code> — is a signed traverse by definition.
anchor + delta — so this pass keeps that value verbatim for the <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> already wrote anchor + delta into the MC
axis instead of folding it into the ±180° window (a +270° chain and listed the axis in the one-shot <a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a>
dimension must not become a -90° swing). Incremental entries on record; this pass reads that record — and only that record — and
non-modular axes need no warning: the literal value is what the keeps the listed axes verbatim instead of folding them into the ±180°
axis would do anyway. window (a +270° chain dimension must not become a -90° swing). A
listed non-modular axis needs nothing: the literal value is what the
axis would do anyway. A rotary value the block carries without a
word (lookback fill, or an absolute target another writer put there
<code>G53.1</code>, the Heidenhain <code>PLANE</code> syntax) is not listed
and keeps the default window even under G91.
</p> </p>
</dd> </dd>
</dl> </dl>
@@ -811,6 +843,28 @@ math. Brands that never write the section keep the exact legacy
behavior. behavior.
</p> </p>
<p> <p>
Modal G91: a rotary word with <b>no</b> per-word entry follows the
block's <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html">Positioning</a> state (written ahead of this
syntax by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.PositioningSyntax.html">PositioningSyntax</a> on every brand list) the
way the linear words follow it in
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> — under <code>G91</code> it takes
the same anchor + delta path as the <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_Incremental">Incremental</a>
override, so <code>G91 … C20.</code> repeated turns the table 20° further
each block (Fanuc / Siemens / Heidenhain DIN-ISO all read an
incremental rotary word as a signed traverse; the
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a> tail-pass keeps it literal for
the axes the <a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> record lists). A per-word entry of any
value beats the modal state for its word (<code>G91 C=AC(90)</code> is
absolute). Rotary values another writer put on the block without a
word — <a class="xref" href="Hi.NcParsers.LogicSyntaxs.G53p1RotaryPositionSyntax.html">G53p1RotaryPositionSyntax</a>, the Heidenhain
<code>PLANE</code> syntax — are absolute targets and are not touched.
HardNc differs here by design of its own: <code>HardNcLine.BuildOrdinaryMcAbc</code>
writes the word as an absolute angle under G91 and warns
(<i>"G91 is not effect for commands ABC"</i>), so the two engines
diverge on G91 rotary words — the parity fixtures assert the
SoftNc leg only.
</p>
<p>
Coded-position overrides (Siemens Coded-position overrides (Siemens
<code>CAC()</code>/<code>CIC()</code>/<code>CDC()</code>/<code>CACP()</code>/<code>CACN()</code>) <code>CAC()</code>/<code>CIC()</code>/<code>CDC()</code>/<code>CACP()</code>/<code>CACN()</code>)
carry an indexing position <b>number</b> instead of an angle: the carry an indexing position <b>number</b> instead of an angle: the
@@ -836,7 +890,17 @@ that distinction (<a class="xref" href="Hi.NcParsers.LogicSyntaxs.CannedCycleRes
active canned cycle on a rotary-only block, active canned cycle on a rotary-only block,
<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.text.json.nodes.jsonobject">WriteCompoundMotion(JsonObject, string, JsonArray, Vec3d)</a> riding the <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.text.json.nodes.jsonobject">WriteCompoundMotion(JsonObject, string, JsonArray, Vec3d)</a> riding the
block's ABC on the cycle's pre-positioning item) read the record; the block's ABC on the cycle's pre-positioning item) read the record; the
section is never modal-carried. section is never modal-carried. Its sibling
<a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a> records, with the programmed delta,
the rotary words this syntax accumulated as increments (per-word
<code>IC()</code>/<code>IC+</code> or a bare word under modal G91): the MC
value is an absolute angle from then on and the modal
<a class="xref" href="Hi.NcParsers.Keywords.Positioning.html">Positioning</a> still says G91, so without the record an
accumulated word would read like a programmed absolute.
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a> adds the block's linear
increments to the same record later in the list, and
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a> reads it to pass the listed axes
through the shortest-path wrap literally.
</p> </p>
<p> <p>
Must be placed <b>before</b> <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McXyzSyntax.html">McXyzSyntax</a> so syntaxes Must be placed <b>before</b> <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McXyzSyntax.html">McXyzSyntax</a> so syntaxes
@@ -1364,6 +1428,7 @@ for subsequent block lookback.
<dd><p>Shared utilities for rotary axis (A/B/C) resolution. <dd><p>Shared utilities for rotary axis (A/B/C) resolution.
Used by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.G53p1RotaryPositionSyntax.html">G53p1RotaryPositionSyntax</a>, Used by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.G53p1RotaryPositionSyntax.html">G53p1RotaryPositionSyntax</a>,
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a>, <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IsoG68p2TiltSyntax.html">IsoG68p2TiltSyntax</a>, <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a>, <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IsoG68p2TiltSyntax.html">IsoG68p2TiltSyntax</a>,
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IncrementalResolveSyntax.html">IncrementalResolveSyntax</a>
and other syntaxes that read or write rotary axis values.</p> and other syntaxes that read or write rotary axis values.</p>
</dd> </dd>
</dl> </dl>
@@ -1082,6 +1082,58 @@ runner. No-op when <code class="paramref">targetDeps</code> has no matching tabl
<a id="Hi_NcParsers_SoftNcRunner_PopulateLegacyStrokeLimitsWhereUnset_" data-uid="Hi.NcParsers.SoftNcRunner.PopulateLegacyStrokeLimitsWhereUnset*"></a>
<h3 id="Hi_NcParsers_SoftNcRunner_PopulateLegacyStrokeLimitsWhereUnset_System_Xml_Linq_XElement_System_Collections_Generic_List_Hi_NcParsers_Dependencys_INcDependency__" data-uid="Hi.NcParsers.SoftNcRunner.PopulateLegacyStrokeLimitsWhereUnset(System.Xml.Linq.XElement,System.Collections.Generic.List{Hi.NcParsers.Dependencys.INcDependency})">
PopulateLegacyStrokeLimitsWhereUnset(XElement, List&lt;INcDependency&gt;)
</h3>
<div class="markdown level1 summary"><p>Fills the stroke limits a proxy-era project never wrote onto its
parameter table from the legacy <code>HardNcEnv</code> boxes
(<code>StrokeLimitXyz_mm</code> / <code>StrokeLimitAbc_deg</code>), one axis at a
time and only where the table carries neither end. The boxes are what
the machine-limits editor and the <code>stroke-limit-*</code> endpoints
wrote until 2026-09-14, while every SoftNc reader — the per-block
<a class="xref" href="Hi.NcParsers.Semantics.StrokeLimitCheckSemantic.html">StrokeLimitCheckSemantic</a>, the per-step check
and the tilt solves' travel preference — reads the table: a project
rebuilt through that API (CHEM20180926) declared its travel and had
no check at all. Non-finite ends are skipped (unbounded). Explicit
table rows always win. No-op without a table or a legacy element.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static List&lt;string&gt; PopulateLegacyStrokeLimitsWhereUnset(XElement ncEnvXml, List&lt;INcDependency&gt; targetDeps)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>ncEnvXml</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.xml.linq.xelement">XElement</a></dt>
<dd><p>The inner XML element of the legacy <code>HardNcEnv</code>.</p>
</dd>
<dt><code>targetDeps</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.collections.generic.list-1">List</a>&lt;<a class="xref" href="Hi.NcParsers.Dependencys.INcDependency.html">INcDependency</a>&gt;</dt>
<dd><p>The proxy-resolved dependency list holding the parameter table.</p>
</dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.collections.generic.list-1">List</a>&lt;<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.string">string</a>&gt;</dt>
<dd><p>The axes that were filled, in X…C order; empty when nothing changed.</p>
</dd>
</dl>
<a id="Hi_NcParsers_SoftNcRunner_Reg_" data-uid="Hi.NcParsers.SoftNcRunner.Reg*"></a> <a id="Hi_NcParsers_SoftNcRunner_Reg_" data-uid="Hi.NcParsers.SoftNcRunner.Reg*"></a>
<h3 id="Hi_NcParsers_SoftNcRunner_Reg_Hi_Common_XmlUtils_XFactory_" data-uid="Hi.NcParsers.SoftNcRunner.Reg(Hi.Common.XmlUtils.XFactory)"> <h3 id="Hi_NcParsers_SoftNcRunner_Reg_Hi_Common_XmlUtils_XFactory_" data-uid="Hi.NcParsers.SoftNcRunner.Reg(Hi.Common.XmlUtils.XFactory)">
@@ -452,6 +452,42 @@ The value includes last action duration.</p>
<a id="Hi_Numerical_Acts_StateActRunner_IsRapid_" data-uid="Hi.Numerical.Acts.StateActRunner.IsRapid*"></a>
<h3 id="Hi_Numerical_Acts_StateActRunner_IsRapid" data-uid="Hi.Numerical.Acts.StateActRunner.IsRapid">
IsRapid
</h3>
<div class="markdown level1 summary"><p>Whether the last processed feedrate act was a rapid traverse
(<a class="xref" href="Hi.Numerical.Acts.ActRapid.html">ActRapid</a>): the motion acts that follow it, up to the
next <a class="xref" href="Hi.Numerical.Acts.ActFeedrate.html">ActFeedrate</a>, are G00 moves at
<a class="xref" href="Hi.Numerical.Acts.StateActRunner.html#Hi_Numerical_Acts_StateActRunner_CommandedClFeedrate_mmds">CommandedClFeedrate_mmds</a>. False before the first
feedrate act and after <a class="xref" href="Hi.Numerical.Acts.StateActRunner.html#Hi_Numerical_Acts_StateActRunner_ResetState">ResetState()</a>.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public bool IsRapid { get; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd></dd>
</dl>
<a id="Hi_Numerical_Acts_StateActRunner_SpindleAngle_deg_" data-uid="Hi.Numerical.Acts.StateActRunner.SpindleAngle_deg*"></a> <a id="Hi_Numerical_Acts_StateActRunner_SpindleAngle_deg_" data-uid="Hi.Numerical.Acts.StateActRunner.SpindleAngle_deg*"></a>
<h3 id="Hi_Numerical_Acts_StateActRunner_SpindleAngle_deg" data-uid="Hi.Numerical.Acts.StateActRunner.SpindleAngle_deg"> <h3 id="Hi_Numerical_Acts_StateActRunner_SpindleAngle_deg" data-uid="Hi.Numerical.Acts.StateActRunner.SpindleAngle_deg">
@@ -309,6 +309,59 @@ the solution only fit the orientation part of the <code class="paramref">tiltMat
<a id="Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_" data-uid="Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc*"></a>
<h3 id="Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Mat4d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__" data-uid="Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Mat4d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)">
OrientationToMcAbc(Mat4d, Func&lt;Vec3d, bool&gt;, out Vec3d)
</h3>
<div class="markdown level1 summary"><p><a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Mat4d_Hi_Geom_Vec3d__">OrientationToMcAbc(Mat4d, out Vec3d)</a> restricted to the
rotary positions <code class="paramref">isMcAbcAdmissible</code> accepts (the
machine's rotary travel, typically). A full orientation fixes the
rotary positions up to axis periodicity, so a solution the predicate
refuses is a posture this machine cannot take: the conversion then
fails (false) and leaves the solver state as it was, so that the
caller can fall back to <a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Vec3d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__">OrientationToMcAbc(Vec3d, Func&lt;Vec3d, bool&gt;, out Vec3d)</a>,
where the free rotation about the tool axis opens the other branch.
A null predicate admits everything.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">bool OrientationToMcAbc(Mat4d tiltMat, Func&lt;Vec3d, bool&gt; isMcAbcAdmissible, out Vec3d mcAbc_rad)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>tiltMat</code> <a class="xref" href="Hi.Geom.Mat4d.html">Mat4d</a></dt>
<dd><p>The tilt matrix to convert.</p>
</dd>
<dt><code>isMcAbcAdmissible</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.func-2">Func</a>&lt;<a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a>, <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a>&gt;</dt>
<dd><p>Accepts a machine ABC (radians) or refuses it; null admits everything.</p>
</dd>
<dt><code>mcAbc_rad</code> <a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a></dt>
<dd><p>Output machine ABC coordinates in radians.</p>
</dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>Whether an admissible conversion was found.</p>
</dd>
</dl>
<a id="Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_" data-uid="Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc*"></a> <a id="Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_" data-uid="Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc*"></a>
<h3 id="Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__" data-uid="Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Vec3d,Hi.Geom.Vec3d@)"> <h3 id="Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__" data-uid="Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Vec3d,Hi.Geom.Vec3d@)">
@@ -359,6 +412,65 @@ likely to converge for tilt configurations such as <code>G68.2 I180 J90 K0</code
<a id="Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_" data-uid="Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc*"></a>
<h3 id="Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Vec3d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__" data-uid="Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Vec3d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)">
OrientationToMcAbc(Vec3d, Func&lt;Vec3d, bool&gt;, out Vec3d)
</h3>
<div class="markdown level1 summary"><p><a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__">OrientationToMcAbc(Vec3d, out Vec3d)</a> preferring the
solution branch <code class="paramref">isMcAbcAdmissible</code> accepts. The
axial-only problem has two branches on a two-rotary-axis machine
(on a table-table A/C: (A, C) and (A, C+180°)); the plain overload
returns the branch nearest the solver's seed, which from the rotary
pole (A0 C0) is the one the tilt's azimuth happens to favour — half
the time the branch a cradle table with an asymmetric tilt travel
cannot reach (CHEM20180926 N100: <code>G68.2 I210 J-90</code> + <code>G53.1</code>
solved to A=+90° on a 120°…+30° A axis). When the nearest branch is
refused, an implementation with a real solver searches the other
branches and returns the admissible one nearest the seed; when none
is admissible it returns the refused solution and true, and the
stroke-limit check downstream reports it. A null predicate makes this
the plain overload. The default implementation is the plain solve —
the predicate is advisory for an implementation without a solver.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">bool OrientationToMcAbc(Vec3d toolAxialNormal, Func&lt;Vec3d, bool&gt; isMcAbcAdmissible, out Vec3d mcAbc_rad)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>toolAxialNormal</code> <a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a></dt>
<dd><p>Target tool axial direction in table coordinates.</p>
</dd>
<dt><code>isMcAbcAdmissible</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.func-2">Func</a>&lt;<a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a>, <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a>&gt;</dt>
<dd><p>Accepts a machine ABC (radians) or refuses it; null admits everything.</p>
</dd>
<dt><code>mcAbc_rad</code> <a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a></dt>
<dd><p>Output machine ABC coordinates in radians.</p>
</dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>Whether the conversion was successful (admissible or not).</p>
</dd>
</dl>
<a id="Hi_Numerical_Xyzabc_IMachineKinematics_PnToMc_" data-uid="Hi.Numerical.Xyzabc.IMachineKinematics.PnToMc*"></a> <a id="Hi_Numerical_Xyzabc_IMachineKinematics_PnToMc_" data-uid="Hi.Numerical.Xyzabc.IMachineKinematics.PnToMc*"></a>
<h3 id="Hi_Numerical_Xyzabc_IMachineKinematics_PnToMc_Hi_Geom_DVec3d_Hi_Geom_DVec3d__" data-uid="Hi.Numerical.Xyzabc.IMachineKinematics.PnToMc(Hi.Geom.DVec3d,Hi.Geom.DVec3d@)"> <h3 id="Hi_Numerical_Xyzabc_IMachineKinematics_PnToMc_Hi_Geom_DVec3d_Hi_Geom_DVec3d__" data-uid="Hi.Numerical.Xyzabc.IMachineKinematics.PnToMc(Hi.Geom.DVec3d,Hi.Geom.DVec3d@)">
@@ -478,6 +478,59 @@ the solution only fit the orientation part of the <code class="paramref">tiltMat
<a id="Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_" data-uid="Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc*"></a>
<h3 id="Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_Hi_Geom_Mat4d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__" data-uid="Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Mat4d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)">
OrientationToMcAbc(Mat4d, Func&lt;Vec3d, bool&gt;, out Vec3d)
</h3>
<div class="markdown level1 summary"><p><a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Mat4d_Hi_Geom_Vec3d__">OrientationToMcAbc(Mat4d, out Vec3d)</a> restricted to the
rotary positions <code class="paramref">isMcAbcAdmissible</code> accepts (the
machine's rotary travel, typically). A full orientation fixes the
rotary positions up to axis periodicity, so a solution the predicate
refuses is a posture this machine cannot take: the conversion then
fails (false) and leaves the solver state as it was, so that the
caller can fall back to <a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Vec3d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__">OrientationToMcAbc(Vec3d, Func&lt;Vec3d, bool&gt;, out Vec3d)</a>,
where the free rotation about the tool axis opens the other branch.
A null predicate admits everything.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public bool OrientationToMcAbc(Mat4d tiltMat, Func&lt;Vec3d, bool&gt; isMcAbcAdmissible, out Vec3d mcAbc_rad)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>tiltMat</code> <a class="xref" href="Hi.Geom.Mat4d.html">Mat4d</a></dt>
<dd><p>The tilt matrix to convert.</p>
</dd>
<dt><code>isMcAbcAdmissible</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.func-2">Func</a>&lt;<a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a>, <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a>&gt;</dt>
<dd><p>Accepts a machine ABC (radians) or refuses it; null admits everything.</p>
</dd>
<dt><code>mcAbc_rad</code> <a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a></dt>
<dd><p>Output machine ABC coordinates in radians.</p>
</dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>Whether an admissible conversion was found.</p>
</dd>
</dl>
<a id="Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_" data-uid="Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc*"></a> <a id="Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_" data-uid="Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc*"></a>
<h3 id="Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__" data-uid="Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Vec3d,Hi.Geom.Vec3d@)"> <h3 id="Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__" data-uid="Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Vec3d,Hi.Geom.Vec3d@)">
@@ -528,6 +581,65 @@ likely to converge for tilt configurations such as <code>G68.2 I180 J90 K0</code
<a id="Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_" data-uid="Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc*"></a>
<h3 id="Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_Hi_Geom_Vec3d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__" data-uid="Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Vec3d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)">
OrientationToMcAbc(Vec3d, Func&lt;Vec3d, bool&gt;, out Vec3d)
</h3>
<div class="markdown level1 summary"><p><a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__">OrientationToMcAbc(Vec3d, out Vec3d)</a> preferring the
solution branch <code class="paramref">isMcAbcAdmissible</code> accepts. The
axial-only problem has two branches on a two-rotary-axis machine
(on a table-table A/C: (A, C) and (A, C+180°)); the plain overload
returns the branch nearest the solver's seed, which from the rotary
pole (A0 C0) is the one the tilt's azimuth happens to favour — half
the time the branch a cradle table with an asymmetric tilt travel
cannot reach (CHEM20180926 N100: <code>G68.2 I210 J-90</code> + <code>G53.1</code>
solved to A=+90° on a 120°…+30° A axis). When the nearest branch is
refused, an implementation with a real solver searches the other
branches and returns the admissible one nearest the seed; when none
is admissible it returns the refused solution and true, and the
stroke-limit check downstream reports it. A null predicate makes this
the plain overload. The default implementation is the plain solve —
the predicate is advisory for an implementation without a solver.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public bool OrientationToMcAbc(Vec3d toolAxialNormal, Func&lt;Vec3d, bool&gt; isMcAbcAdmissible, out Vec3d mcAbc_rad)</code></pre>
</div>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>toolAxialNormal</code> <a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a></dt>
<dd><p>Target tool axial direction in table coordinates.</p>
</dd>
<dt><code>isMcAbcAdmissible</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.func-2">Func</a>&lt;<a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a>, <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a>&gt;</dt>
<dd><p>Accepts a machine ABC (radians) or refuses it; null admits everything.</p>
</dd>
<dt><code>mcAbc_rad</code> <a class="xref" href="Hi.Geom.Vec3d.html">Vec3d</a></dt>
<dd><p>Output machine ABC coordinates in radians.</p>
</dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>Whether the conversion was successful (admissible or not).</p>
</dd>
</dl>
<a id="Hi_Numerical_Xyzabc_XyzabcSolver_PnToMc_" data-uid="Hi.Numerical.Xyzabc.XyzabcSolver.PnToMc*"></a> <a id="Hi_Numerical_Xyzabc_XyzabcSolver_PnToMc_" data-uid="Hi.Numerical.Xyzabc.XyzabcSolver.PnToMc*"></a>
<h3 id="Hi_Numerical_Xyzabc_XyzabcSolver_PnToMc_Hi_Geom_DVec3d_Hi_Geom_DVec3d__" data-uid="Hi.Numerical.Xyzabc.XyzabcSolver.PnToMc(Hi.Geom.DVec3d,Hi.Geom.DVec3d@)"> <h3 id="Hi_Numerical_Xyzabc_XyzabcSolver_PnToMc_Hi_Geom_DVec3d_Hi_Geom_DVec3d__" data-uid="Hi.Numerical.Xyzabc.XyzabcSolver.PnToMc(Hi.Geom.DVec3d,Hi.Geom.DVec3d@)">
+9
View File
@@ -1425,6 +1425,12 @@
<li> <li>
<a href="Hi.MachiningProcs.ProxyProjectService.html" name="" title="ProxyProjectService">ProxyProjectService</a> <a href="Hi.MachiningProcs.ProxyProjectService.html" name="" title="ProxyProjectService">ProxyProjectService</a>
</li> </li>
<li>
<a href="Hi.MachiningProcs.RapidCutMonitor.html" name="" title="RapidCutMonitor">RapidCutMonitor</a>
</li>
<li>
<a href="Hi.MachiningProcs.RapidCutMonitor.Sample.html" name="" title="RapidCutMonitor.Sample">RapidCutMonitor.Sample</a>
</li>
<li> <li>
<a href="Hi.MachiningProcs.RenderingFlag.html" name="" title="RenderingFlag">RenderingFlag</a> <a href="Hi.MachiningProcs.RenderingFlag.html" name="" title="RenderingFlag">RenderingFlag</a>
</li> </li>
@@ -3142,6 +3148,9 @@
<li> <li>
<a href="Hi.NcParsers.Keywords.IUnparsedTextDef.html" name="" title="IUnparsedTextDef">IUnparsedTextDef</a> <a href="Hi.NcParsers.Keywords.IUnparsedTextDef.html" name="" title="IUnparsedTextDef">IUnparsedTextDef</a>
</li> </li>
<li>
<a href="Hi.NcParsers.Keywords.IncrementalWords.html" name="" title="IncrementalWords">IncrementalWords</a>
</li>
<li> <li>
<a href="Hi.NcParsers.Keywords.IndexNote.html" name="" title="IndexNote">IndexNote</a> <a href="Hi.NcParsers.Keywords.IndexNote.html" name="" title="IndexNote">IndexNote</a>
</li> </li>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 51 KiB

@@ -166,7 +166,8 @@ one, and it reveals nothing without a project open. In practice that means the t
on that address: pasting the link into a new tab, reloading on it, or opening General Setup for the on that address: pasting the link into a new tab, reloading on it, or opening General Setup for the
first time since the page or the project was loaded. Jumping to it from a screen that has already first time since the page or the project was loaded. Jumping to it from a screen that has already
shown General Setup for the current project does not rebuild that tree, so the address is dropped shown General Setup for the current project does not rebuild that tree, so the address is dropped
in silence with the selection left where it was.</p> in silence: the address bar keeps the value, the node does not appear, and the selection stays
where it was.</p>
</div> </div>
<p>The same page at <code>/general-setup?tree=equipment/controller-csv</code>, loaded fresh on that address with <p>The same page at <code>/general-setup?tree=equipment/controller-csv</code>, loaded fresh on that address with
the CSV Controller preference still off — the address alone is what puts the node in the tree. the CSV Controller preference still off — the address alone is what puts the node in the tree.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 190 KiB

@@ -152,8 +152,11 @@ last showed stays on the bar after the run has ended; a project change is what e
takes the strip away with it. A cursor line carries <code>Sn</code> and the sentence index it sits on; a takes the strip away with it. A cursor line carries <code>Sn</code> and the sentence index it sits on; a
message line carries whatever anchor the message supplies. Two limits are worth knowing: the strip message line carries whatever anchor the message supplies. Two limits are worth knowing: the strip
mirrors the newest message across three of the four lists — nothing from <strong>NC Manipulation</strong> reaches mirrors the newest message across three of the four lists — nothing from <strong>NC Manipulation</strong> reaches
it — and it is sampled rather than recorded, so messages arriving faster than it refreshes never it — and it is sampled rather than recorded. There is no refresh interval to tune: the service
appear on it at all. The lists on the service drop nothing.</p> sends the newest message and, while that send is still on its way to the browsers, keeps only the
newest of whatever arrives behind it, so a message that lands inside that window is replaced before
it was ever sent and never appears on the strip at all. The cursor line is thinned the same way
under a fast run. The lists on the service drop nothing.</p>
<h2 id="the-session-message-panel">The session message panel</h2> <h2 id="the-session-message-panel">The session message panel</h2>
<p>The panel sits on the Execution page, in the middle column, below the 3D Rendering Canvas. Its <p>The panel sits on the Execution page, in the middle column, below the 3D Rendering Canvas. Its
header row reads <strong>Session Messages</strong> and stays visible when the panel is collapsed, so a grey strip header row reads <strong>Session Messages</strong> and stays visible when the panel is collapsed, so a grey strip
@@ -205,9 +208,9 @@ behind its one line carries a chevron; clicking it opens what the message brough
a <strong>Reset</strong>. The badge at the right of that toolbar reads two numbers separated by a slash, and they a <strong>Reset</strong>. The badge at the right of that toolbar reads two numbers separated by a slash, and they
count different things — rows currently shown on the left, raw messages on the right, so folding count different things — rows currently shown on the left, raw messages on the right, so folding
alone makes them differ, and on a long session the left number stops at the most recent thousand alone makes them differ, and on a long session the left number stops at the most recent thousand
while the right goes on counting. That badge is also the tab's connection indicator: it is outlined rows while the right goes on counting. That badge is also the tab's connection indicator: it is
green only while the connection behind that list is up, and its tooltip names the state. <strong>Export</strong> outlined green only while the connection behind that list is up, and its tooltip names the state.
writes the tab's filtered rows to a CSV file.</p> <strong>Export</strong> writes the tab's filtered rows to a CSV file.</p>
<div class="IMPORTANT"> <div class="IMPORTANT">
<h5>Important</h5> <h5>Important</h5>
<p>Two different controls on this screen answer to <strong>Reset</strong>, and only one of them is labelled with <p>Two different controls on this screen answer to <strong>Reset</strong>, and only one of them is labelled with
@@ -249,7 +252,9 @@ file for today.</em>, and both hide the line count entirely — no count is draw
reading zero, so the caption simply being absent is itself the signal that nothing came back. The reading zero, so the caption simply being absent is itself the signal that nothing came back. The
day badge is what separates them: when the file exists, the day comes from the service's own clock; day badge is what separates them: when the file exists, the day comes from the service's own clock;
when there is no file at all, it comes from the browser's clock in UTC, which need not name the same when there is no file at all, it comes from the browser's clock in UTC, which need not name the same
day.</p> day — before eight in the morning in Taipei it names the day before. The service itself never
leaves the file empty: the day's file comes into being with its first line already in it, so an
empty file is one that something outside the service emptied.</p>
<p>A fetch that fails replaces the pane with the reason and a <strong>Retry</strong> button, and posts the reason to <p>A fetch that fails replaces the pane with the reason and a <strong>Retry</strong> button, and posts the reason to
the footer under the viewer's own name — one of the few lines that reaches the footer without ever the footer under the viewer's own name — one of the few lines that reaches the footer without ever
having been a toast.</p> having been a toast.</p>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

@@ -217,10 +217,11 @@ underneath — so a Save from any of them writes to the new path. A stale row co
time the service reports its state to that browser: a reload, the browser's status connection time the service reports its state to that browser: a reload, the browser's status connection
dropping and coming back, another project change, or a run being started, paused, finished or reset dropping and coming back, another project change, or a run being started, paused, finished or reset
from any browser.</p> from any browser.</p>
<p>New, Load, ReLoad, Save and Save As take a turn each. A second one asked for while the first is still <p>New, Load, ReLoad, Save, Save As and Close Project take a turn each. A second one asked for while the
running is refused rather than queued, and the refusal arrives as a warning reading <em>Another project first is still running is refused rather than queued, and the refusal arrives as a warning reading
operation is in progress. Please try again.</em> Close Project takes no part in that turn-taking: it <em>Another project operation is in progress. Please try again.</em> Close Project holds the turn like the
neither waits for a running operation nor holds one off, and it never raises the warning.</p> other five: a Close asked for while a Load is still reading is refused, and so is a Load asked for
while a Close is still tearing the project down.</p>
<h2 id="losing-work">Losing work</h2> <h2 id="losing-work">Losing work</h2>
<p>Nothing keeps track of whether the open project has unsaved changes. No marker in the menu bar or in <p>Nothing keeps track of whether the open project has unsaved changes. No marker in the menu bar or in
the path row says the project has been edited, there is no prompt in front of <strong>ReLoad</strong> or <strong>Close the path row says the project has been edited, there is no prompt in front of <strong>ReLoad</strong> or <strong>Close
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 101 KiB

@@ -152,10 +152,12 @@ the file is read again on the service, but the screens keep what they were showi
entry to use for that, and it is the one that always rebuilds.</p> entry to use for that, and it is the one that always rebuilds.</p>
<p>The same rebuild runs once at startup, with nobody having done anything: a browser reaching a service <p>The same rebuild runs once at startup, with nobody having done anything: a browser reaching a service
that already has a project open receives that path as its first project change and builds on it.</p> that already has a project open receives that path as its first project change and builds on it.</p>
<p><strong>New</strong>, <strong>Load</strong>, <strong>ReLoad</strong>, <strong>Save</strong> and <strong>Save As</strong> run one at a time. A second one started while <p><strong>New</strong>, <strong>Load</strong>, <strong>ReLoad</strong>, <strong>Save</strong>, <strong>Save As</strong> and <strong>Close Project</strong> run one at a time. A
the first is still running is refused rather than queued, and the refusal arrives as a warning reading second one started while the first is still running is refused rather than queued, and the refusal
<strong>Another project operation is in progress. Please try again.</strong> Nothing is rebuilt and nothing is arrives as a warning reading <strong>Another project operation is in progress. Please try again.</strong> Nothing
lost. <strong>Close Project</strong> takes no part in that turn-taking and never raises the warning.</p> is rebuilt and nothing is lost. The turn is held for the whole of the operation, so a Close asked for
while a Load is still reading is refused the same way, and so is a Load asked for while a Close is
still tearing the project down.</p>
<h2 id="the-footer">The footer</h2> <h2 id="the-footer">The footer</h2>
<p>A 29-pixel strip holding three regions, each independent of the other two.</p> <p>A 29-pixel strip holding three regions, each independent of the other two.</p>
<p><strong>Left — the latest reported line, with the recent ones behind it.</strong> The text is the most recent <p><strong>Left — the latest reported line, with the recent ones behind it.</strong> The text is the most recent
@@ -140,7 +140,7 @@ mechanics.</p>
<td>6</td> <td>6</td>
<td><strong>Program File</strong></td> <td><strong>Program File</strong></td>
<td>Program</td> <td>Program</td>
<td>the stage</td> <td>the stage's program — one control file, whole</td>
</tr> </tr>
<tr> <tr>
<td>7</td> <td>7</td>
@@ -158,16 +158,26 @@ mechanics.</p>
</table> </table>
<p>Every entry keeps its own checkbox, so any of them can be switched off without being deleted and <p>Every entry keeps its own checkbox, so any of them can be switched off without being deleted and
without its settings being lost.</p> without its settings being lost.</p>
<p><strong>A stage is rows 57 wrapped in a List command.</strong> List is the one command in the Flow category
of Add Command; give it the stage's name and its row reads <code>List [Roughing]</code>, with the record,
the Program File and the closing record as its rows one level down. The Setup rows stay loose
above the first stage and Post-Execution loose below the last. The List row carries a checkbox of
its own, and clearing it greys every row inside and skips the whole group — that checkbox is
what the re-running section below turns on and off.
<a href="building-a-mission.html#group-with-a-list">Group with a list</a> is how the group is made, titled
and moved.</p>
<h2 id="why-commands-rather-than-one-script">Why commands rather than one script</h2> <h2 id="why-commands-rather-than-one-script">Why commands rather than one script</h2>
<p>A script sets the same values, and that is the whole of its advantage. Against it:</p> <p>A script sets the same values, and that is the whole of its advantage. Against it:</p>
<ul> <ul>
<li><strong>A row states its value.</strong> <code>Machining Resolution [0.125 mm]</code>, <code>Physics [On]</code>, <li><strong>A row states its value.</strong> <code>Machining Resolution [0.125 mm]</code>, <code>Physics [On]</code>,
<code>Program File [NC/facing.ptp]</code> — the mission is legible without opening anything.</li> <code>Program File [NC/facing.ptp]</code> — the mission is legible without opening anything.</li>
<li><strong>A checkbox replaces commenting-out.</strong> A commented line is invisible in the tree and survives <li><strong>A checkbox replaces commenting-out.</strong> A commented line is invisible in the tree and survives
into the saved project as text nobody reads. A cleared checkbox greys the row and says so.</li> into the saved project as text nobody reads. A cleared checkbox greys the row, and the command's
editor below the tree says so.</li>
<li><strong>The fields are typed.</strong> A resolution is a number field with a unit, not a line that has to <li><strong>The fields are typed.</strong> A resolution is a number field with a unit, not a line that has to
compile.</li> compile.</li>
<li><strong>The order is the run.</strong> Moving a setting above or below a program is a drag, not an edit.</li> <li><strong>The order is the run.</strong> Moving a setting above or below a program is a drag of its row in the
Control Tree's <strong>Mission</strong> branch, not an edit.</li>
</ul> </ul>
<p>Leave in the Script only what no command covers, and title it for what it is.</p> <p>Leave in the Script only what no command covers, and title it for what it is.</p>
<h2 id="resolution-before-the-first-record">Resolution before the first record</h2> <h2 id="resolution-before-the-first-record">Resolution before the first record</h2>
@@ -216,18 +226,19 @@ writes the result.</li>
<li><strong>Every run after.</strong> Entry 5 finds its file and nothing has played, so it <strong>reads</strong> — the stock is <li><strong>Every run after.</strong> Entry 5 finds its file and nothing has played, so it <strong>reads</strong> — the stock is
not re-meshed. The program plays, so by entry 7 something has played, and it <strong>writes</strong> the fresh not re-meshed. The program plays, so by entry 7 something has played, and it <strong>writes</strong> the fresh
result.</li> result.</li>
<li><strong>Re-running one stage.</strong> Clear the checkbox on the stages you do not want. The first record entry <li><strong>Re-running one stage.</strong> Clear the checkbox on the <strong>List</strong> row of each stage you do not want.
that is still ticked becomes the first thing to run, so it reads its cache, and the run picks up The first record entry that is still ticked becomes the first thing to run, so it reads its
from there.</li> cache, and the run picks up from there.</li>
</ul> </ul>
<p><strong>Clearing a stage clears everything in it, including its record.</strong> A stage is a checkbox around a <p><strong>Clearing a stage clears everything in it, including its record.</strong> A stage is a List row with its
list, and a cleared one is skipped whole — so in a chain where the cache a stage resumes from is the entries beneath it; clear that row's checkbox and every entry inside greys with it and the group is
<em>previous</em> stage's end-of-stage record, clearing that previous stage removes the very entry that skipped whole — so in a chain where the cache a stage resumes from is the <em>previous</em> stage's
would have loaded it. The run then starts from the stock, quietly and without an error. Either leave end-of-stage record, clearing that previous stage removes the very entry that would have loaded
the earlier stages ticked and clear only the Program File rows inside them, or clear them but keep it. The run then starts from the stock, quietly and without an error. Either leave the earlier
the one stage whose end-of-stage record you are resuming from, with its own programs cleared. The stages ticked and clear only the Program File rows inside them, or clear them but keep the one
rule is simply that <strong>the record you are resuming from has to be reachable</strong>: every checkbox above stage whose end-of-stage record you are resuming from, with its own programs cleared. The rule is
it stays ticked.</p> simply that <strong>the record you are resuming from has to be reachable</strong>: every checkbox above it
stays ticked.</p>
<p>That last line is the point of the layout. The cost of getting back to the middle of a long job is <p>That last line is the point of the layout. The cost of getting back to the middle of a long job is
one file read.</p> one file read.</p>
<h2 id="the-stage-0-cache-goes-stale-silently">The stage-0 cache goes stale, silently</h2> <h2 id="the-stage-0-cache-goes-stale-silently">The stage-0 cache goes stale, silently</h2>
@@ -301,9 +312,10 @@ and costs the whole roughing run at the finishing price.</p>
caching the <em>stock</em>: there the frozen mesh is what the run starts from, so the resolution really is caching the <em>stock</em>: there the frozen mesh is what the run starts from, so the resolution really is
stuck until the file is cleared.</p> stuck until the file is cleared.</p>
<h2 id="one-record-per-stage">One record per stage</h2> <h2 id="one-record-per-stage">One record per stage</h2>
<p>A mission with several Program File entries gets a record after each, plus the stage-0 record where <p>A mission with several stages — one List per stage, each with its Program File — gets a record
that one earns its place. Name each file after the stage it ends, not after the program that wrote after each, plus the stage-0 record where that one earns its place. Name each file after the
it, so the file that a stage <em>reads</em> is the one named for the stage before it.</p> stage it ends, not after the program that wrote it, so the file that a stage <em>reads</em> is the one
named for the stage before it.</p>
<p>Do not split one control file into several Program File entries to get finer stages. A program's <p>Do not split one control file into several Program File entries to get finer stages. A program's
modal state — units, plane, work offset, absolute or incremental — is established in its header and modal state — units, plane, work offset, absolute or incremental — is established in its header and
carried forward; cutting it in half hands the second half to a runner that never saw the header. The carried forward; cutting it in half hands the second half to a runner that never saw the header. The
Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 100 KiB

@@ -92,10 +92,14 @@ what plays is exactly what the list says — including which entries are ticked
<h2 id="where-it-is">Where it is</h2> <h2 id="where-it-is">Where it is</h2>
<p>The Execution page at <code>/execution</code>, <strong>Mission</strong> branch of the Control Tree; <code>/mission</code> lands on the <p>The Execution page at <code>/execution</code>, <strong>Mission</strong> branch of the Control Tree; <code>/mission</code> lands on the
same place. This is the page the application opens on.</p> same place. This is the page the application opens on.</p>
<p>The branch root is the list editor: it is where the list is assembled and rearranged. A command's <p>The list is assembled and rearranged on the tree rows themselves: the <strong>Mission</strong> row and every
own settings are edited one level in, on that command's node.</p> <strong>List</strong> row carry a <strong>+</strong> that adds a command, and every command row carries a drag handle in
front of its label and its own move, duplicate and delete buttons. The <strong>Mission</strong> node's panel
below the tree is informational — the command count and a hint naming those affordances. A
command's own settings are edited one level in, on that command's node.</p>
<h2 id="add-a-command">Add a command</h2> <h2 id="add-a-command">Add a command</h2>
<p><strong>Add Command</strong> opens a search-first picker. Type to narrow it: the search matches a command's <p>The <strong>+</strong> pinned to the right edge of the <strong>Mission</strong> row, or of any <strong>List</strong> row, is <strong>Add
Command</strong>; it opens a search-first picker. Type to narrow it: the search matches a command's
display name, its internal kind key and the aliases it declares, and an alias matches both by its display name, its internal kind key and the aliases it declares, and an alias matches both by its
English key and by its word in the interface language. Arrow keys walk the results and English key and by its word in the interface language. Arrow keys walk the results and
<kbd>Enter</kbd> takes the highlighted one.</p> <kbd>Enter</kbd> takes the highlighted one.</p>
@@ -130,17 +134,25 @@ English key and by its word in the interface language. Arrow keys walk the resul
</tr> </tr>
</tbody> </tbody>
</table> </table>
<p>What you pick is appended to the <strong>end</strong> of the list you added it to, and the selection stays on the <p>What you pick lands in the list whose <strong>+</strong> you pressed, <strong>directly after the focused command</strong> when
list rather than jumping into the new command. Nothing is pinned to a position: the order is that command is an entry of the same list, and at the list's end otherwise. The focus is the
entirely yours, and every command is placeable anywhere.</p> selected command — or, while the selection sits on one of a command's child nodes, the command that
<p><strong>Add Command is disabled until a project is open.</strong> With nothing open the list reads <em>No project owns it — or the command the last add created; and when a move, duplicate, delete or drag carries
loaded</em>; with a project and an empty mission it reads <em>No commands yet</em> and names the button.</p> the selection to another row, the focus follows it there. So a run of adds lands in order below the
focus, and the <strong>Mission</strong> row's <strong>+</strong> always adds at root level even while a command inside a
group is selected. The new row is revealed in the tree, but the selection stays where it was rather
than jumping into the new command. Nothing is pinned to a position: the order is entirely yours, and
every command is placeable anywhere.</p>
<p><strong>Add Command is disabled until a project is open.</strong> With nothing open the <strong>Mission</strong> panel reads
<em>No project loaded. Open or create a project first.</em> With a project and an empty mission it reads
<em>No commands yet</em> and names the button.</p>
<p>The set on offer is served by the application rather than built into the interface, so a command <p>The set on offer is served by the application rather than built into the interface, so a command
kind can appear in this dialog before this manual has a page for it.</p> kind can appear in this dialog before this manual has a page for it.</p>
<p>The picker over the demo mission, at <code>/execution?tree=execution/mission</code> with <strong>Add Command</strong> <p>The picker over the demo mission, at <code>/execution?tree=execution/mission</code> with the <strong>Mission</strong>
pressed. The five category headings are the grouping in the table above, the search box at the top row's <strong>+</strong> pressed. The five category headings are the grouping in the table above, the search
is what narrows them, and the first result is highlighted ready for <kbd>Enter</kbd>.</p> box at the top is what narrows them, and the first result is highlighted ready for
<p><img src="building-a-mission-img/add-command.en.png" alt="The Add Command dialog open over the Execution page: a Search commands box above thirteen entries under five headings — Setup with Machining Resolution, Machining Motion Resolution, Collision Detection, Pause on Failure and Physics; Program with Program File, NC Code and Script; Optimization with NC Optimization Config; Output with Post-Execution, Record Meshed Geometry and Export Meshed Geometry STL; and Flow with List"></p> <kbd>Enter</kbd>.</p>
<p><img src="building-a-mission-img/add-command.en.png" alt="The Add Command dialog open over the Execution page, in front of the Control Tree whose Mission row carries a + at its right edge and whose transport buttons and green ready badge show above it: a Search commands box above thirteen entries, each with its kind icon, under five headings — Setup with Machining Resolution highlighted, Machining Motion Resolution, Collision Detection, Pause on Failure and Physics; Program with Program File, NC Code and Script; Optimization with NC Optimization Config; Output with Post-Execution, Record Meshed Geometry and Export Meshed Geometry STL; and Flow with List"></p>
<h2 id="the-shape-to-start-from">The shape to start from</h2> <h2 id="the-shape-to-start-from">The shape to start from</h2>
<p>An empty list is legal, but it is not where a project should end up. A finished mission has the <p>An empty list is legal, but it is not where a project should end up. A finished mission has the
same shape whatever it machines: <strong>setup at the top, the program in the middle, the program held same shape whatever it machines: <strong>setup at the top, the program in the middle, the program held
@@ -189,38 +201,61 @@ play; a box the kernel builds instantly, and caching it costs more than it saves
<p><a href="a-mission-that-resumes.html">A Mission That Resumes</a> is this layout in full, with the reasoning and <p><a href="a-mission-that-resumes.html">A Mission That Resumes</a> is this layout in full, with the reasoning and
the measurements behind each row.</p> the measurements behind each row.</p>
<h2 id="read-a-row">Read a row</h2> <h2 id="read-a-row">Read a row</h2>
<p>Each row shows the command's kind followed by the detail that identifies it, in brackets. Where you <p>Each row shows the command's kind and, where one detail identifies the command, that detail after
can name a command that detail is the title you typed, so a row still says what it is after it has it in brackets. Where you can name a command that detail is the title you typed, so a row still says
been named: <code>List [Roughing]</code>, <code>NC Code [Inline finishing pass]</code>. Where you cannot, the command brackets what what it is after it has been named: <code>List [Roughing]</code>, <code>NC Code [Inline finishing pass]</code> — and
it holds instead — <code>Program File [NC/circle.ptp]</code>, <code>Machining Resolution [1 mm]</code>, while the title is empty the row is the bare kind, <code>NC Code</code> or <code>Script</code>. Where you cannot, the
<code>Collision Detection [On]</code> — so a mission is readable without opening anything.</p> command brackets what it holds instead — <code>Program File [NC/circle.ptp]</code>,
<p>Beside the label sit four buttons — <strong>up</strong>, <strong>down</strong>, <strong>duplicate</strong> and <strong>delete</strong>. Up and down are <code>Machining Resolution [1 mm]</code>, <code>Collision Detection [On]</code> — so a mission is readable without
disabled at the ends of the list. Delete asks first, in a dialog naming the command. Duplicate is a opening anything. Two kinds have no single detail to show and read as their kind alone:
deep copy: a group copies with everything inside it, and the copy lands directly after the original.</p> <code>NC Optimization Config</code> and <code>Post-Execution</code>, whose settings are the child nodes beneath the row
<p>Clicking a row anywhere but on a button selects that command's node and opens its editor.</p> rather than one value.</p>
<p>Every command row carries four buttons — <strong>Move up</strong>, <strong>Move down</strong>, <strong>Duplicate</strong> and <strong>Delete</strong>
revealed while the pointer is over the row or while the row is selected, and always shown on a
touch screen. Up and down are disabled at the ends of the list. Delete asks for confirmation, in a
dialog naming the command. Duplicate is a deep copy: a group copies with everything inside it, and
the copy lands directly after the original. The selection follows the operation when it sits on
the acted-on row <strong>or anywhere beneath it</strong>: on an entry inside a group when you act on the group's
row, or on a child node when you act on its command's row. It then lands on the acted-on row itself
— the row at its new position, the copy, or the nearest survivor of a delete (the list itself, once
it is empty) — so an editor you were in beneath that row is replaced by the row's own panel. Acting
on a row the selection is neither on nor under leaves the selection, and the editor you are in,
where they are.</p>
<p>Before a row operation writes anything — for a delete, only after you have confirmed it — it
settles whatever the open editor has not yet saved. If you cancel that prompt, the operation is
dropped and a notice says so.</p>
<p>Clicking a row anywhere but on its checkbox or a button selects that command and opens its editor
below the tree.</p>
<h2 id="tick-what-runs">Tick what runs</h2> <h2 id="tick-what-runs">Tick what runs</h2>
<p><strong>The checkbox is on the tree item, not in the row, and it is the only thing that decides whether a <p><strong>The checkbox at the front of a command row is the only thing that decides whether a command
command runs.</strong> Clearing it greys the row and the tree node; the editor stays open and fully runs.</strong> Clearing it greys the row; the editor stays open and fully editable, with a note that the
editable. Clearing the box on a group greys the whole group, and the run skips the group together command is disabled. Clearing the box on a group greys the whole group, and the run skips the group
with everything nested inside it.</p> together with everything nested inside it.</p>
<p>Leaving a command in place with its box cleared is how you skip a step without losing its settings, <p>Leaving a command in place with its box cleared is how you skip a step without losing its settings,
which is what you want while you narrow down a problem.</p> which is what you want while you narrow down a problem.</p>
<h2 id="group-with-a-list">Group with a list</h2> <h2 id="group-with-a-list">Group with a list</h2>
<p><strong>List</strong> is an ordinary command in the Flow category, and adding one grows a sub-tree: its children <p><strong>List</strong> is an ordinary command in the Flow category, and adding one grows a sub-tree: its children
are its own entries, edited by the same list editor one level down. That nests to any depth, so a are its own entries, rows with the same handle and buttons one level down, and its row carries its
mission can be grouped by operation rather than left flat.</p> own <strong>+</strong>. That nests to any depth, so a mission can be grouped by operation rather than left flat.</p>
<p>A list carries an optional title, entered on its own node above the embedded editor. The row reads <p>A list carries an optional title, and its node's panel holds that <em>Title (optional)</em> field alone —
<code>List</code> while the title is empty and <code>List [title]</code> once it says something; a title of nothing but its entries are its rows in the tree — with, as on any command, the note that it is disabled above
spaces counts as unset. The Mission root is the one list with no title field — it reads <strong>Mission</strong>.</p> the field while its checkbox is cleared. The row reads <code>List</code> while the title is empty and
<code>List [title]</code> once it says something; a title of nothing but spaces counts as unset. The Mission
root is the one list with no title field — it reads <strong>Mission</strong>.</p>
<p>The demo mission at <code>/execution?tree=execution/mission</code>: two groups and seven loose entries. The <p>The demo mission at <code>/execution?tree=execution/mission</code>: two groups and seven loose entries. The
tree above shows <strong>List [Roughing]</strong> and <strong>List [Finishing]</strong> opened, with the two Program File transport buttons and the <strong>ready</strong> badge sit at the top of the Control Tree; <strong>Mission</strong> is its
entries inside each bracketing their files; the editor below shows the same nine root entries as first root, with <strong>List [Roughing]</strong> and <strong>List [Finishing]</strong> opened and the two Program File
rows. The greyed <strong>Program File</strong> and <strong>Post-Execution</strong> rows are entries left in place with their entries inside each bracketing their files, and the <strong>Mission</strong> row and both List rows carry a
checkboxes cleared — part of the mission, and not run.</p> <strong>+</strong> at the right edge. The <strong>Program</strong> root sits collapsed beneath. The <strong>Mission</strong> panel below
<p><img src="building-a-mission-img/grouped-mission.en.png" alt="The Mission branch of the Control Tree showing Machining Resolution 1 mm and Collision Detection On, then List Roughing expanded over Program File NC/circle.ptp and Program File NC/drill_slot.ptp, List Finishing expanded over Program File NC/side.ptp and Program File NC/slide.ptp, then Program File NC/circle.ptp, NC Code Inline finishing pass, a greyed Program File NC/slide-test-resolution-script.ptp with its checkbox cleared, NC Optimization Config and a greyed Post-Execution with its checkbox cleared; below it the list editor shows the same nine root entries under an Add Command button and a Commands badge reading 9, each row with up, down, duplicate and delete buttons, above the line reading that commands run top-down"></p> the tree reads <em>Commands 9</em> and the hint naming the row affordances. The greyed <strong>Program File</strong>
and <strong>Post-Execution</strong> rows are entries left in place with their checkboxes cleared — part of the
mission, and not run.</p>
<p><img src="building-a-mission-img/grouped-mission.en.png" alt="The Control Tree on the Execution page: six transport buttons and a green ready badge above the tree; the Mission root row with a + at its right edge, then Machining Resolution 1 mm and Collision Detection On, List Roughing expanded over Program File NC/circle.ptp and Program File NC/drill_slot.ptp, List Finishing expanded over Program File NC/side.ptp and Program File NC/slide.ptp, both List rows with their own +, then Program File NC/circle.ptp, NC Code Inline finishing pass, a greyed Program File NC/slide-test-resolution-script.ptp with its checkbox cleared, NC Optimization Config with a collapsed expand arrow and a greyed Post-Execution with a collapsed expand arrow and its checkbox cleared, every command row with a checkbox and a drag handle before its label; a collapsed Program root below; under the tree the Mission panel reads Commands 9 and the hint that commands run top-down in the Control Tree, naming the + on the Mission or a List row, drag to reorder, the row's own move, duplicate and delete buttons, and the checkbox that enables or disables the command"></p>
<h2 id="reorder-and-move-in-and-out">Reorder, and move in and out</h2> <h2 id="reorder-and-move-in-and-out">Reorder, and move in and out</h2>
<p>Up and down move an entry within its own list and never change which list owns it. Dragging does <p>Up and down move an entry within its own list and never change which list owns it. Dragging a row
more, and where you drop decides which:</p> does more — the handle in front of its label marks the row as draggable, but the whole row is the
grip: a drag started on the handle, on the label or on the blank space beside them picks the row
up — and where you drop decides which:</p>
<table> <table>
<thead> <thead>
<tr> <tr>
@@ -230,27 +265,35 @@ more, and where you drop decides which:</p>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td>Another row</td> <td>A command row</td>
<td>Reorder within this list. A row splits at its midline into <em>before</em> and <em>after</em>.</td> <td>Land <strong>before</strong> or <strong>after</strong> it — the row splits at its midline. In the same list that is a reorder; in another list, the entry moves there.</td>
</tr> </tr>
<tr> <tr>
<td>The middle band of a <strong>List</strong> row</td> <td>The middle band of a <strong>List</strong> row</td>
<td>Move the entry <strong>into</strong> that list. The row's outer quarters still reorder around it.</td> <td>Move the entry <strong>into</strong> that list, at its end. The row's outer quarters still land before or after it.</td>
</tr> </tr>
<tr> <tr>
<td>The drop-out zone below a nested list's entries</td> <td>The <strong>Mission</strong> row</td>
<td>Move the entry <strong>out</strong>, landing directly after the list it came from.</td> <td>Move the entry <strong>into</strong> the root list, at its end — the whole row is a landing.</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<p>The drop-out zone belongs to a nested list's editor and appears only while a row inside it is being <p>While the drag is over a row, a line along the row's top or bottom edge marks <em>before</em> or <em>after</em>
dragged. Moving a list into itself, or into one of its own groups, is refused.</p> and a tinted row marks <em>into</em>. To take an entry out of a group, drop it on a row outside the group,
<p>Dragging serves rearrangement only — dropping text or files on the list does nothing. To bring or on the <strong>Mission</strong> row. Moving a list into itself, or into one of its own groups, is refused. A
several programs in at once, use one Program File command's picker and select them together; see dragged command that was selected — or that held the selection somewhere beneath it, on one of its
entries or child nodes — is selected where it lands; the selection on any other row stays on that
row.</p>
<p>Dragging serves rearrangement only. The tree accepts nothing but its own rows: text or a file
dragged in from outside gets the browser's no-drop cursor over every row, and releasing it there
hands the drop to the browser's own default rather than to the application — nothing is imported,
and a browser typically opens a dropped file in the tab, leaving the page. To bring several
programs in at once, use one Program File command's picker and select them together: the extra
files become Program File commands directly after that one; see
<a href="playing-a-program.html">Playing a Program</a>.</p> <a href="playing-a-program.html">Playing a Program</a>.</p>
<h2 id="edit-one-command">Edit one command</h2> <h2 id="edit-one-command">Edit one command</h2>
<p>Select a command's node. Its editor opens below a control bar carrying the same up, down, duplicate <p>Select a command's row. Its editor opens in the panel below the tree — the editor alone, with a
and delete operations the row has, and a note while the command is switched off.</p> note while the command is switched off. Moving, duplicating and deleting stay on the row.</p>
<p>A command with one job — Program File, NC Code, Script — puts its whole editor on that one node. <p>A command with one job — Program File, NC Code, Script — puts its whole editor on that one node.
A command with several cards spreads them: the general settings stay on the command node and each A command with several cards spreads them: the general settings stay on the command node and each
remaining card becomes a <strong>child node</strong> beneath it, so a long command is read by walking down the remaining card becomes a <strong>child node</strong> beneath it, so a long command is read by walking down the
@@ -264,7 +307,7 @@ the child node's own checkbox. Which commands do that, and what each card holds,
<li><a href="the-other-commands.html">The Other Commands</a> — what the rest of the command kinds are for</li> <li><a href="the-other-commands.html">The Other Commands</a> — what the rest of the command kinds are for</li>
<li><a href="a-mission-that-resumes.html">A Mission That Resumes</a> — the shape a mission should start from, in full</li> <li><a href="a-mission-that-resumes.html">A Mission That Resumes</a> — the shape a mission should start from, in full</li>
<li><a href="running-a-simulation.html">Starting and Stepping</a> — the transport that plays the list built here</li> <li><a href="running-a-simulation.html">Starting and Stepping</a> — the transport that plays the list built here</li>
<li><a class="xref" href="../../anatomy/execution/mission/mission-root-panel.html">Mission Root Panel</a> — the component behind this branch: the list editor, the picker and the three drag landings</li> <li><a class="xref" href="../../anatomy/execution/mission/mission-root-panel.html">Mission Root Panel</a> — the node behind this branch: the row operations, the picker and the three drag landings</li>
<li><a class="xref" href="../../anatomy/execution/mission/ListCommand-panel.html">List Command Panel</a> — the component behind a group: what nesting costs, and what a disabled list skips</li> <li><a class="xref" href="../../anatomy/execution/mission/ListCommand-panel.html">List Command Panel</a> — the component behind a group: what nesting costs, and what a disabled list skips</li>
</ul> </ul>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 117 KiB

@@ -147,9 +147,12 @@ reading the run.</p>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<p>The two sensor charts are present only while their checkboxes on the <strong>Preference</strong> menu are ticked;
both are off by default, so a column nobody has configured ends at Sim Spindle Moment Cycle.</p>
<p>The group bar above them carries the step number as a badge, or <strong>No step selected</strong>. That badge is <p>The group bar above them carries the step number as a badge, or <strong>No step selected</strong>. That badge is
the only place the step index is shown — Step Properties leaves that row out rather than repeat it, the only place the step index is shown — Step Properties leaves that row out rather than repeat it,
which is why the list you configure and the list you see differ by one row.</p> so when S.I. is among the keys you chose, the list you configure and the list you see differ by one
row.</p>
<p><strong>Step Properties shows short names.</strong> Hovering a name gives the full one, and the unit follows the <p><strong>Step Properties shows short names.</strong> Hovering a name gives the full one, and the unit follows the
value. A field with nothing in it reads <code>-</code>.</p> value. A field with nothing in it reads <code>-</code>.</p>
<p><strong>CWE is a footprint, not a solid.</strong> It is a small 3D view of its own, drawing the contact contours <p><strong>CWE is a footprint, not a solid.</strong> It is a small 3D view of its own, drawing the contact contours
@@ -168,16 +171,22 @@ step</strong> while the simulated pair beside them is full.</p>
<p>Each cycle chart's header carries a <strong>value boundary</strong><em>Auto</em>, or a fixed ± bound that pins the <p>Each cycle chart's header carries a <strong>value boundary</strong><em>Auto</em>, or a fixed ± bound that pins the
scale so two steps can be compared without the axis moving under you — and a reload. The two spindle scale so two steps can be compared without the axis moving under you — and a reload. The two spindle
moment charts carry one more: a <strong>Line / Dartboard</strong> switch, where Dartboard replots the same cycle moment charts carry one more: a <strong>Line / Dartboard</strong> switch, where Dartboard replots the same cycle
as a locus in the plane instead of three channels against the cycle parameter.</p> as a locus in the plane instead of three channels against the cycle parameter. Sim Cutting Force
Cycle carries a frame switch instead — <strong>To workpiece / program</strong> or <strong>To tool / tool-running</strong>
choosing whether the plotted force is the one on the workpiece, in program coordinates, or the one
on the tool, in the tool's running coordinates.</p>
<p><strong>Clicking a point in a cycle chart marks that point for its whole group.</strong> The two simulated charts <p><strong>Clicking a point in a cycle chart marks that point for its whole group.</strong> The two simulated charts
share one mark in spindle angle; the two sensor charts share another in seconds. The mark survives a share one mark in spindle angle; the two sensor charts share another in seconds. The mark survives a
switch between Line and Dartboard and a change of selected step. It also reaches the CWE panel: the switch between Line and Dartboard and a change of selected step. The simulated pair's mark also
cutter in that view rotates to the angle you clicked, so &ldquo;the force peaked here&rdquo; and &ldquo;this is what reaches the CWE panel: the cutter in that view rotates to the angle you clicked, so &ldquo;the force peaked
the cutter was touching there&rdquo; become one picture rather than two.</p> here&rdquo; and &ldquo;this is what the cutter was touching there&rdquo; become one picture rather than two. The sensor
<p>The column with the demo mission paused and a step selected: Sentence Syntax at the top, the step pair's mark is a time, not an angle, so it stays on its own two charts and leaves the cutter where it
badge on the bar below it, then Step Properties, CWE and the two simulated cycle charts. The two sensor charts are folded away at the bottom — this project carries no measured data, is.</p>
so nothing is lost by leaving them shut.</p> <p>The column with a step selected and the other three columns toggled off, so it fills the window:
<p><img src="inspecting-a-step-img/step-info.en.png" alt="The Execution page's Step Info column filled: a Sentence Syntax panel showing the arc block N0120 G02 I0.0 J11. above its parsed form, a group bar badged step #500, a Step Properties list reading FileNo 1, LineNo 13, FilePath NC/circle.ptp and a Time of four seconds, a CWE panel whose small 3D view draws the cutter's flute contours against an orange contact patch on the workpiece, and two cycle charts carrying X, Y and Z traces of cutting force and spindle moment across a full 0 to 360 degree spindle revolution"></p> Sentence Syntax at the top, the step badge on the bar below it, then Step Properties, CWE and the two
simulated cycle charts. The two sensor charts are absent — their checkboxes on the Preference menu
are off, as they are by default.</p>
<p><img src="inspecting-a-step-img/step-info.en.png" alt="The Execution page with only its Step Info column shown, filling the window: a Sentence Syntax panel badged F1 L13 · Sn 13 with a copy button, showing the arc block N0120 G02 I0.0 J11. above the opening lines of its parsed form, a Step Info group bar badged step #500, a Step Properties list reading FileNo 1, LineNo 13, FilePath NC/circle.ptp, a Time just over four seconds and the top of a LineText row, a CWE panel whose small 3D view draws a fluted cutter overlay standing on the orange contact contours, with an X axis label beside it and a 12.5 mm scale bar in the lower right, a Sim Cutting Force Cycle chart headed To workpiece / program and Auto, and a Sim Spindle Moment Cycle chart headed Line and Auto, each carrying X, Y and Z traces across a full 0 to 360 degree spindle revolution; no sensor chart is present"></p>
<h2 id="choosing-what-step-properties-shows">Choosing what Step Properties shows</h2> <h2 id="choosing-what-step-properties-shows">Choosing what Step Properties shows</h2>
<p>Step Properties does not show everything a step carries — it shows what you asked for, out of a much <p>Step Properties does not show everything a step carries — it shows what you asked for, out of a much
longer list. The small button on that panel's header opens the chooser, beside the list it longer list. The small button on that panel's header opens the chooser, beside the list it
@@ -186,14 +195,15 @@ configures.</p>
group, and <strong>Add Selected</strong> moves what you ticked across. Anything already displayed is greyed with a group, and <strong>Add Selected</strong> moves what you ticked across. Anything already displayed is greyed with a
tick beside it, so the left side never offers you a duplicate. The displayed list is on the right, in tick beside it, so the left side never offers you a duplicate. The displayed list is on the right, in
the order it will appear: drag a row, or use its up and down buttons, and remove one row at a time or the order it will appear: drag a row, or use its up and down buttons, and remove one row at a time or
<strong>Clear</strong> the lot. <strong>Reset</strong> empties the list entirely.</p> <strong>Clear</strong> the lot. <strong>Reset</strong>, on the dialog's header, empties the list entirely; Clear and Reset each
ask you to confirm first.</p>
<p><strong>There is no Save button, and that is not an omission.</strong> Every add, removal and reorder is written <p><strong>There is no Save button, and that is not an omission.</strong> Every add, removal and reorder is written
as you make it, and the header reports the write — so the way to undo an experiment is to put the as you make it, and the header reports the write — so the way to undo an experiment is to put the
rows back, not to close the dialog.</p> rows back, not to close the dialog.</p>
<p>The chooser open over the column, at <code>/execution</code>. The counts in its header are this account's <p>The chooser open over the column, at <code>/execution</code>. The counts in its header are this account's
displayed list against everything the run can offer; the green ticks down the candidate side are the displayed list against every property a step can present; the green ticks down the candidate side
rows already on the right.</p> are the rows already on the right.</p>
<p><img src="inspecting-a-step-img/step-present.en.png" alt="The Step Present Preference dialog open over the Execution page: a header counting displayed against available keys with Reset and close, a Candidate Keys panel on the left with collapsible categories and an Add Selected button, and a Displayed Keys panel on the right listing the chosen properties with up, down and remove buttons and a Clear action"></p> <p><img src="inspecting-a-step-img/step-present.en.png" alt="The Step Present Preference dialog open over the Step Info column: a header reading 12 displayed / 77 available with Reset and close buttons, a Candidate Keys panel on the left with an Add Selected button and the first three of its categories open — File / Command / Flag / Time / System with 8 keys, Tool / Feedrate / Spindle Speed with 10 keys, and Coordinate / Move with 3 keys, the third cut off at the panel's bottom edge after its CL row with the remaining categories scrolled out of view below — where the rows already displayed are greyed with a green tick, and a Displayed Keys panel on the right with a Clear action and a reorder hint, listing the first eleven of the twelve chosen properties, S.I. down to MRR, with the last row scrolled out of view below the panel's edge; each row has a drag handle and up, down and remove buttons"></p>
<h2 id="see-also">See Also</h2> <h2 id="see-also">See Also</h2>
<ul> <ul>
<li><a href="index.html">Running a Simulation</a> — the rest of running a job</li> <li><a href="index.html">Running a Simulation</a> — the rest of running a job</li>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 110 KiB

@@ -91,8 +91,9 @@
lives rather than what it does: <strong>Program File</strong> references a file on disk, <strong>NC Code</strong> carries the lives rather than what it does: <strong>Program File</strong> references a file on disk, <strong>NC Code</strong> carries the
text inside the project.</p> text inside the project.</p>
<h2 id="where-they-are">Where they are</h2> <h2 id="where-they-are">Where they are</h2>
<p>The Execution page's <strong>Mission</strong> branch. Both sit in the <strong>Program</strong> category of <strong>Add Command</strong>, <p><strong>Mission</strong>, the first root of the Execution page's Control Tree. Both sit in the <strong>Program</strong>
and both are placed like any other command — see <a href="building-a-mission.html">Building a Mission</a>.</p> category of <strong>Add Command</strong>, the <strong>+</strong> on the Mission row or on a List row, and both are placed
like any other command — see <a href="building-a-mission.html">Building a Mission</a>.</p>
<h2 id="which-one-to-use">Which one to use</h2> <h2 id="which-one-to-use">Which one to use</h2>
<ul> <ul>
<li><strong>Program File</strong> — the program stays a file, and the project stores the path. Editing the file <li><strong>Program File</strong> — the program stays a file, and the project stores the path. Editing the file
@@ -139,7 +140,7 @@ reached by typing its absolute path into the field instead.</p>
</table> </table>
<p><strong>The picker takes more than one file.</strong> The first goes on the command you opened it from; every <p><strong>The picker takes more than one file.</strong> The first goes on the command you opened it from; every
further pick becomes a <strong>new Program File command</strong> placed directly after it, in the order you further pick becomes a <strong>new Program File command</strong> placed directly after it, in the order you
picked them, inside the same list — including inside a group. That is the quick way to bring a picked them, inside the same list — including inside a nested List. That is the quick way to bring a
folder of CAM output into a mission.</p> folder of CAM output into a mission.</p>
<h3 id="choose-the-reader">Choose the reader</h3> <h3 id="choose-the-reader">Choose the reader</h3>
<p><strong>Play As</strong> decides which reader plays the file:</p> <p><strong>Play As</strong> decides which reader plays the file:</p>
@@ -183,17 +184,19 @@ and what its words mean is <a href="../../technique/nc-dialects/index.html">NC D
<p>Typing saves the path as you type; the banner refreshes when you leave the field or press <p>Typing saves the path as you type; the banner refreshes when you leave the field or press
<kbd>Enter</kbd>. An orange banner is worth trusting: it means the path does not resolve on the <kbd>Enter</kbd>. An orange banner is worth trusting: it means the path does not resolve on the
machine that will play it, which is not always the machine you are typing on.</p> machine that will play it, which is not always the machine you are typing on.</p>
<p>The first Program File in the demo mission's <strong>Roughing</strong> group, at <p>The first Program File in the demo mission's <strong>List [Roughing]</strong>, at
<code>/execution?tree=execution/mission/2/0</code>. The path field carries a project-relative path, <strong>Play As</strong> <code>/execution?tree=execution/mission/2/0</code>, selected in the tree under the run header with its move,
reads <em>Auto</em>, and the green banner below reports the file's size, modified time and line count with duplicate and delete buttons revealed. The path field carries a project-relative path, <strong>Play As</strong>
<strong>Preview</strong> beside it. The row and the tree label both read <code>Program File</code> followed by the path, reads <em>Auto (by extension)</em>, and the green banner below reports the file's size, modified time and
which is how a mission of several programs stays readable.</p> line count with <strong>Preview</strong> beside it. The tree row and the panel's header both read <code>Program File</code>
<p><img src="playing-a-program-img/program-file.en.png" alt="The Program File command panel in the Control Tree dock: a program file path field with a Browse button, a Play As select reading Auto, and a green file information banner giving size, modified time and line count with a Preview button"></p> followed by the path in brackets, which is how a mission of several programs stays readable.</p>
<p><img src="playing-a-program-img/program-file.en.png" alt="The Execution page's Control Tree with the six transport buttons and a green ready badge above the tree; the Mission root row carries a + at its right edge, and under it Machining Resolution 1 mm, Collision Detection On, then List Roughing expanded with its own + over a selected Program File NC/circle.ptp row showing its move up, move down, duplicate and delete buttons and a Program File NC/drill_slot.ptp row, a collapsed List Finishing with a +, Program File NC/circle.ptp, NC Code Inline finishing pass, a greyed Program File NC/slide-test-resolution-script.ptp with its checkbox cleared, NC Optimization Config expanded over Distances, Feedrate, Motion Dynamics, Force &amp; Safety and Compensation, and a greyed Post-Execution with its checkbox cleared over a child row cut off at the tree's bottom edge, every command row with a checkbox and a drag handle; the panel below is headed Mission / List [Roughing] / Program File [NC/circle.ptp] and holds a Program File Path field reading NC/circle.ptp with a Browse button, a Play As select reading Auto (by extension), and a green banner reading 298 B, modified 2024-09-05 10:38:37, 21 lines with a Preview button"></p>
<h2 id="nc-code">NC Code</h2> <h2 id="nc-code">NC Code</h2>
<h3 id="name-it">Name it</h3> <h3 id="name-it">Name it</h3>
<p><strong>Title</strong> is optional in the sense that the field may be cleared, but it is not decoration: it is <p><strong>Title</strong> is optional in the sense that the field may be cleared, but it is not decoration: it is
the program name the run reports under, and it is the detail the mission row brackets. A new command the program name the run reports under, and it is the detail the command's row in the Control Tree
arrives with <code>NC Code</code> already in the field; rename it and both the log and the row follow.</p> brackets. A new command arrives with <code>NC Code</code> already in the field; rename it and both the log and
the row follow.</p>
<h3 id="write-it">Write it</h3> <h3 id="write-it">Write it</h3>
<p>The editor is a plain monospace area — no line numbers and no syntax highlighting, because this is <p>The editor is a plain monospace area — no line numbers and no syntax highlighting, because this is
NC text, not a program in a language the application parses while you type. Line and character NC text, not a program in a language the application parses while you type. Line and character
@@ -207,10 +210,11 @@ counts sit below it and follow what you type.</p>
<p><strong>Nothing is checked while you type.</strong> The text is stored exactly as written, and a mistake in it <p><strong>Nothing is checked while you type.</strong> The text is stored exactly as written, and a mistake in it
surfaces when the mission plays it — in <strong>NC Diagnostics</strong>, see surfaces when the mission plays it — in <strong>NC Diagnostics</strong>, see
<a href="when-something-goes-wrong.html">When Something Goes Wrong</a>.</p> <a href="when-something-goes-wrong.html">When Something Goes Wrong</a>.</p>
<p>The demo mission's short hand-written pass, at <code>/execution?tree=execution/mission/5</code>. The title <p>The demo mission's short hand-written pass, at <code>/execution?tree=execution/mission/5</code>, selected in
above the editor is what the row brackets, and the line and character counts below it are the whole the tree as <code>NC Code [Inline finishing pass]</code>. The title above the editor is what that row brackets,
of the feedback this editor gives.</p> and the editor holds the whole program, the closing % of which is cut off at the bottom edge; the
<p><img src="playing-a-program-img/nc-code.en.png" alt="The NC Code command panel: a Title field reading Inline finishing pass above a monospace text area holding a short NC program, with line and character counts and the Trim Blank Lines and Clear buttons below it"></p> counts and the two buttons sit beneath it, past the bottom of this view.</p>
<p><img src="playing-a-program-img/nc-code.en.png" alt="The Execution page's Control Tree with the six transport buttons and a green ready badge above the tree; the Mission root row carries a + at its right edge, List Roughing and the collapsed List Finishing carry their own +, and the NC Code Inline finishing pass row is selected with its move up, move down, duplicate and delete buttons revealed, the greyed Post-Execution at the bottom over a child row cut off at the tree's bottom edge, every command row with a checkbox and a drag handle; the panel below is headed Mission / NC Code [Inline finishing pass] and holds a Title (optional) field reading Inline finishing pass above a monospace NC Code text area whose program runs from a % line through N0010 to N0170 M30 and a closing % cut off at the bottom edge, the text area reaching the bottom edge of the panel"></p>
<h2 id="after-it-has-played">After it has played</h2> <h2 id="after-it-has-played">After it has played</h2>
<p>Every program a session read appears under the <strong>Program</strong> branch, with the passes that went over it <p>Every program a session read appears under the <strong>Program</strong> branch, with the passes that went over it
and the marks the run left on each line. That is where you see what happened to a line, as opposed and the marks the run left on each line. That is where you see what happened to a line, as opposed
Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 54 KiB

@@ -91,10 +91,11 @@
can press at a given moment is the part worth learning</strong>, because the availability of a button is can press at a given moment is the part worth learning</strong>, because the availability of a button is
what tells you where the run actually is.</p> what tells you where the run actually is.</p>
<h2 id="where-it-is">Where it is</h2> <h2 id="where-it-is">Where it is</h2>
<p>The Execution page at <code>/execution</code>. The transport sits along the top of the editor panel in the left <p>The Execution page at <code>/execution</code>. The transport sits in the run header at the top of the Control
dock, and it is mounted for the <strong>Execution</strong> root and every node beneath it — so it stays reachable Tree pane in the left dock, above the <strong>Mission</strong> and <strong>Program</strong> roots, with the run-state badge at
while you are editing a Mission command one level in. There is exactly one of it on the page, and it its right end. It is there whatever the tree has selected — so it stays reachable while you are
is the thing that binds <kbd>F5</kbd> to <kbd>F8</kbd>.</p> editing a Mission command — and its keys keep working while the Control Tree row is collapsed. There
is exactly one of it on the page, and it is the thing that binds <kbd>F5</kbd> to <kbd>F8</kbd>.</p>
<h2 id="the-six-controls">The six controls</h2> <h2 id="the-six-controls">The six controls</h2>
<table> <table>
<thead> <thead>
@@ -196,19 +197,21 @@ the run has not stopped yet.</p>
<p>The bar at rest, with the demo project open and nothing run yet, at <code>/execution</code>. Start, the two <p>The bar at rest, with the demo project open and nothing run yet, at <code>/execution</code>. Start, the two
single-advance buttons and Reset are live; Pause and Stop are greyed, because there is no run to hold single-advance buttons and Reset are live; Pause and Stop are greyed, because there is no run to hold
or to end — and the two single-advance buttons carry the <strong>L</strong> and the <strong>S</strong> that tell them apart. The or to end — and the two single-advance buttons carry the <strong>L</strong> and the <strong>S</strong> that tell them apart. The
badge on the <strong>Execution</strong> tree item reads <em>ready</em>, and the block on the canvas is uncut.</p> badge at the right end of the run header reads <em>ready</em>, and the block on the canvas is uncut.</p>
<p><img src="running-a-simulation-img/transport-ready.en.png" alt="The Execution page with the Control Tree on the left showing the Mission and Program branches, a green ready badge on the Execution item, the transport row above the editor panel with the pause and stop buttons greyed, and the 3D canvas showing an uncut rectangular aluminium block on its fixture"></p> <p><img src="running-a-simulation-img/transport-ready.en.png" alt="The Execution page with the run header at the top of the Control Tree pane — the six transport buttons with the pause and stop buttons greyed, and a green ready badge at the right end — above the Mission root with its nine command rows, each with a checkbox and a drag handle and two of them unticked and dimmed, a + on the Mission row and on the two List rows, and the Program root listing four .ptp files and an inline entry; the Mission editor panel below reads Commands 9; the 3D canvas shows an uncut light-grey rectangular block on its grey fixture, and the Session Messages Shell tab reads No messages match the current filter"></p>
<h2 id="reading-the-run-state">Reading the run state</h2> <h2 id="reading-the-run-state">Reading the run state</h2>
<p>The state rides the <strong>Execution</strong> item in the Control Tree as a coloured badge — <em>ready</em>, <em>running</em>, <p>The state sits at the right end of the run header, beside the transport, as a coloured badge —
<em>paused</em>, <em>finished</em>so it is readable from wherever you are in the tree rather than only from the <em>ready</em>, <em>running</em>, <em>paused</em>, <em>finished</em>pinned above the tree, so it stays in view however far you
transport. The footer along the bottom of the window carries the session's own messages beside it.</p> scroll the tree. When the left dock is narrowed the buttons scroll out of view before the badge does:
<p>The same page with the mission paused part way through. The badge now reads <em>paused</em> in orange, Pause the run state is the last thing a resize hides. The footer along the bottom of the window carries the
has gone grey, and Stop has joined the live ones — so the bar alone tells you a run is open and held. session's own messages.</p>
<p>The same page with the mission paused part way through. The badge reads <em>paused</em> in orange, Pause is
grey, and Stop has joined the live ones — so the bar alone tells you a run is open and held.
On the canvas the tool path the run has laid down so far is now drawn over the block, and the tabs On the canvas the tool path the run has laid down so far is now drawn over the block, and the tabs
under it are counting what the run has reported: <strong>Shell</strong> is badged with the eleven messages the under it are counting what the run has reported: <strong>Shell</strong> is badged with the eleven messages the
load and the run have written between them and <strong>NC Diagnostics</strong> with the one the parser raised, load and the run have written between them and <strong>NC Diagnostics</strong> with the one the parser raised,
while <strong>Step Diagnostics</strong> and <strong>NC Manipulation</strong> carry no badge at all.</p> while <strong>Step Diagnostics</strong> and <strong>NC Manipulation</strong> carry no badge at all.</p>
<p><img src="running-a-simulation-img/transport-paused.en.png" alt="The Execution page with the Control Tree on the left, its Execution item carrying an orange paused badge, the transport row above the editor panel with the pause button greyed and the rest live, the 3D canvas showing a gold disc cutter sunk into the top face of the white block on its grey fixture with a single thin green tool path entering from the upper left and dropping to it, and a footer reading Ready"></p> <p><img src="running-a-simulation-img/transport-paused.en.png" alt="The Execution page with the run header at the top of the Control Tree pane — the six transport buttons with only the pause button greyed, and an orange paused badge at the right end — above the Mission root with its nine command rows and the Program root with its five entries, the Mission editor panel below reading Commands 9, the 3D canvas showing a gold disc cutter sunk into the top face of the white block on its grey fixture with a single thin tool path entering from the upper left and dropping straight down in green to it, the Session Messages Shell tab badged 11 and NC Diagnostics badged 1 over a list of system messages, and a footer reading Ready"></p>
<h2 id="the-keys-and-where-they-stop">The keys, and where they stop</h2> <h2 id="the-keys-and-where-they-stop">The keys, and where they stop</h2>
<p><kbd>F5</kbd> to <kbd>F8</kbd> are bound only while the Execution page is the one on screen. On every <p><kbd>F5</kbd> to <kbd>F8</kbd> are bound only while the Execution page is the one on screen. On every
other page <kbd>F5</kbd> is the browser's own reload, and the same is true here in two cases: when other page <kbd>F5</kbd> is the browser's own reload, and the same is true here in two cases: when
Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 97 KiB

@@ -90,9 +90,10 @@
<p>Beyond putting a program into a run, a mission can change the session's settings part-way through, <p>Beyond putting a program into a run, a mission can change the session's settings part-way through,
steer the optimizer, write out what the run produced, and drive the session from a script.</p> steer the optimizer, write out what the run produced, and drive the session from a script.</p>
<h2 id="where-they-are">Where they are</h2> <h2 id="where-they-are">Where they are</h2>
<p>The Execution page's <strong>Mission</strong> branch, all from the same <strong>Add Command</strong>. The Program category's <p>The Execution page's <strong>Mission</strong> branch of the Control Tree, all from the same <strong>Add Command</strong>
other two commands are on <a href="playing-a-program.html">Playing a Program</a>, and the Flow category's one the <strong>+</strong> on the <strong>Mission</strong> row or on a <strong>List</strong> row. The Program category's other two commands
command is on <a href="building-a-mission.html">Building a Mission</a>.</p> are on <a href="playing-a-program.html">Playing a Program</a>, and the Flow category's one command is on
<a href="building-a-mission.html">Building a Mission</a>.</p>
<h2 id="settings-one-per-command">Settings, one per command</h2> <h2 id="settings-one-per-command">Settings, one per command</h2>
<p>The <strong>Setup</strong> category holds five commands, each carrying one setting:</p> <p>The <strong>Setup</strong> category holds five commands, each carrying one setting:</p>
<table> <table>
@@ -144,9 +145,10 @@ linear resolution in mm and a rotary one in degrees.</p>
<h5>Note</h5> <h5>Note</h5>
<p><strong>General Config is not on the menu, and it is not missing.</strong> It was one command carrying all five <p><strong>General Config is not on the menu, and it is not missing.</strong> It was one command carrying all five
of these settings at once, and the five above replace it. A project that still stores one loads as of these settings at once, and the five above replace it. A project that still stores one loads as
those five commands in its place — preceded by a Record Meshed Geometry command where the bundle those five commands in its place, and saving from then on writes the five. Where the bundle named a
also read a meshed geometry file — and saving from then on writes the five. There is nothing to meshed geometry file or had reading one switched on, a Record Meshed Geometry command set to
add and nothing to look for.</p> <strong>Read</strong> precedes them — ticked only where reading was switched on. There is nothing to add and
nothing to look for.</p>
</div> </div>
<h2 id="the-optimizer-as-a-step">The optimizer, as a step</h2> <h2 id="the-optimizer-as-a-step">The optimizer, as a step</h2>
<p><strong>NC Optimization Config</strong> is the Optimization category's one command, and it exists so the <p><strong>NC Optimization Config</strong> is the Optimization category's one command, and it exists so the
@@ -192,10 +194,12 @@ optimizer is on, which is the first switch on its panel.</p>
means, and why an optimized result can look wrong, is means, and why an optimized result can look wrong, is
<a href="../../technique/nc-optimization/index.html">NC Optimization</a>.</p> <a href="../../technique/nc-optimization/index.html">NC Optimization</a>.</p>
<p>The demo mission's optimizer command, at <code>/execution?tree=execution/mission/7</code>. In this mission it <p>The demo mission's optimizer command, at <code>/execution?tree=execution/mission/7</code>. In this mission it
sits below both program groups rather than above them, so the ordering rule at the top of this sits below both <strong>List</strong> groups and the three loose entries after them rather than above them, so
section is what decides how much of the run it reaches. The five switches are on the command's own the ordering rule at the top of this section is what decides how much of the run it reaches. The
panel; the five value nodes are indented under it in the tree.</p> five switches are on the command's own panel below the tree, headed <em>Mission / NC Optimization
<p><img src="the-other-commands-img/nc-optimization-config.en.png" alt="The NC Optimization Config command selected in the Mission branch, with Distances, Feedrate, Motion Dynamics, Force and Safety and Compensation child nodes listed beneath it, and the panel below showing the Enable Optimization, Enable Feedrate Optimization, Enable Depth Splition and Enable Interpolation checkboxes ticked above an unticked Omit Leading Zero in Output checkbox"></p> Config</em>; the five value nodes are indented under it in the tree. Because the row is selected, its
move, duplicate and delete buttons show at its right edge.</p>
<p><img src="the-other-commands-img/nc-optimization-config.en.png" alt="The Control Tree on the Execution page, with the six transport buttons and a green ready badge above the tree and the Mission root row carrying a + at its right edge; among the command rows, each with a checkbox and a drag handle, NC Optimization Config is selected with its move up, move down, duplicate and delete buttons revealed at the right, and Distances, Feedrate, Motion Dynamics, Force &amp; Safety and Compensation are listed beneath it without checkboxes, with a greyed, unticked Post-Execution row at the pane's bottom edge below them; the panel below is headed Mission / NC Optimization Config and shows Enable Optimization, Enable Feedrate Optimization, Enable Depth Splition and Enable Interpolation ticked above an unticked Omit Leading Zero in Output"></p>
<h2 id="writing-out-what-the-run-produced">Writing out what the run produced</h2> <h2 id="writing-out-what-the-run-produced">Writing out what the run produced</h2>
<p>The <strong>Output</strong> category holds three commands: <strong>Post-Execution</strong>, <strong>Record Meshed Geometry</strong> and <p>The <strong>Output</strong> category holds three commands: <strong>Post-Execution</strong>, <strong>Record Meshed Geometry</strong> and
<strong>Export Meshed Geometry (STL)</strong>.</p> <strong>Export Meshed Geometry (STL)</strong>.</p>
@@ -230,7 +234,7 @@ it writes an interim snapshot of the same accumulating run. <strong>Its placemen
</tr> </tr>
<tr> <tr>
<td><strong>CL → NC Writeback</strong></td> <td><strong>CL → NC Writeback</strong></td>
<td>brand NC re-synthesized from what was played</td> <td>Fanuc NC re-synthesized from what was played</td>
<td><code>Output/[NcName].nc</code></td> <td><code>Output/[NcName].nc</code></td>
</tr> </tr>
<tr> <tr>
@@ -260,8 +264,11 @@ tree lists them in, and which matters only if you are reading their timestamps.<
<p>The demo mission's Post-Execution command with <strong>Step Files Output</strong> selected, at <p>The demo mission's Post-Execution command with <strong>Step Files Output</strong> selected, at
<code>/execution?tree=execution/mission/8/step-files</code>. Each output is a child node with its own <code>/execution?tree=execution/mission/8/step-files</code>. Each output is a child node with its own
checkbox — that tick is what switches the output on — and the template field for the selected one checkbox — that tick is what switches the output on — and the template field for the selected one
sits in the panel below.</p> sits in the panel below, headed <em>Mission / Post-Execution / Step Files Output</em>. In the demo the
<p><img src="the-other-commands-img/post-execution.en.png" alt="The Post-Execution command in the Mission branch with its five child nodes, each carrying its own checkbox, and the Step File Template field in the panel below"></p> <strong>Post-Execution</strong> row itself is greyed with its checkbox cleared, and its outputs stay editable
all the same; the row is the last one the tree pane shows in full here, its child nodes cut off at
the pane's edge with only the top sliver of the first showing.</p>
<p><img src="the-other-commands-img/post-execution.en.png" alt="The Control Tree on the Execution page, with the six transport buttons and a green ready badge above the tree and the Mission root row carrying a + at its right edge; the command rows run down to a greyed Post-Execution row with its checkbox cleared at the bottom edge of the tree pane, only the top sliver of its first child row showing before the pane's edge cuts it off; the panel under the tree is headed Mission / Post-Execution / Step Files Output and holds one Step File Template field reading Output/[NcName].step.csv"></p>
<h2 id="keeping-the-workpiece-between-runs">Keeping the workpiece between runs</h2> <h2 id="keeping-the-workpiece-between-runs">Keeping the workpiece between runs</h2>
<p>The Output category's other two commands both take the workpiece as it stands at their own point in <p>The Output category's other two commands both take the workpiece as it stands at their own point in
the list. <strong>Record Meshed Geometry</strong> stores it in the application's mesh format so a later run can the list. <strong>Record Meshed Geometry</strong> stores it in the application's mesh format so a later run can
@@ -302,8 +309,10 @@ first such entry reads, and every one below a program writes. Building a mission
Resolution command belongs above it. A missing file is not an error: writing it is what a run does. Resolution command belongs above it. A missing file is not an error: writing it is what a run does.
<strong>Reset</strong> on the command's panel deletes the file it points at, so the next run records afresh.</p> <strong>Reset</strong> on the command's panel deletes the file it points at, so the next run records afresh.</p>
<p>Export Meshed Geometry (STL) takes a path — <code>Output/MeshedGeom.stl</code> by default, since an export is <p>Export Meshed Geometry (STL) takes a path — <code>Output/MeshedGeom.stl</code> by default, since an export is
something you asked for rather than a cache — and a resolution in millimetres; leave it at 0 for the something you asked for rather than a cache — and a resolution in millimetres for the triangles it
default. It also builds the mesh, so the same placement rule applies.</p> writes; 0 uses the display mesh resolution. What it triangulates is the same mesh Record Meshed
Geometry writes, built the same way, so the placement rule above applies to it too: the STL
resolution decides how finely that mesh is tessellated, not how finely it was cut.</p>
<h2 id="driving-the-session-from-a-script">Driving the session from a script</h2> <h2 id="driving-the-session-from-a-script">Driving the session from a script</h2>
<p><strong>Script</strong> is the Program category's third command: C# evaluated against the running session, for <p><strong>Script</strong> is the Program category's third command: C# evaluated against the running session, for
anything the other command kinds do not cover. Where the script returns a sequence of actions, that anything the other command kinds do not cover. Where the script returns a sequence of actions, that
@@ -317,10 +326,15 @@ tooltip. <strong>Staged means the service is holding the script, not that the pr
save the project to keep it.</p> save the project to keep it.</p>
<p>Two prompts guard the edges, and neither is a yes/no question, so each has three buttons:</p> <p>Two prompts guard the edges, and neither is a yes/no question, so each has three buttons:</p>
<ul> <ul>
<li><strong>Unsaved Changes</strong>, when you select another node while a save is still pending — <em>Save &amp; switch</em> <li><strong>Unsaved Changes</strong>, when the script still has unsaved edits and you select another node, or
flushes it first, <em>Discard</em> drops it, <em>Cancel</em> leaves the selection where it is.</li> move, duplicate, delete or add a command from the tree rows — a save already on its way is let
land first, and the prompt appears only for what is still unsaved after it. <em>Save &amp; switch</em>
saves and then proceeds, and only once the save has landed; <em>Discard</em> drops the edits; <em>Cancel</em>
leaves the selection where it is, and a cancelled row operation is dropped with a notice that
the editor keeps its unsaved edits.</li>
<li><strong>Script changed elsewhere</strong>, when the command changed underneath you — another tab, or a project <li><strong>Script changed elsewhere</strong>, when the command changed underneath you — another tab, or a project
reload.</li> reload. <em>Discard &amp; reload</em> takes the server's copy, <em>Force overwrite</em> writes yours over it,
<em>Cancel</em> keeps your edits in the editor, unsaved, and the server's copy as it is.</li>
</ul> </ul>
<p>Like NC Code, the title is optional and is what the row brackets.</p> <p>Like NC Code, the title is optional and is what the row brackets.</p>
<h2 id="the-list-is-not-closed">The list is not closed</h2> <h2 id="the-list-is-not-closed">The list is not closed</h2>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 50 KiB

@@ -88,26 +88,35 @@
<h1 id="the-program-branch">The Program Branch</h1> <h1 id="the-program-branch">The Program Branch</h1>
<p>What the run actually read, line by line, as opposed to what the mission asked for.</p> <p>What the run actually read, line by line, as opposed to what the mission asked for.</p>
<p>The Execution page's Control Tree carries two branches: <strong>Mission</strong> above, <strong>Program</strong> below, at <p>The Execution page's Control Tree carries two roots: <strong>Mission</strong> above, <strong>Program</strong> below, at
Control-Tree path <code>execution/program</code>. Program is read-only — every node on it is either a file the Control-Tree path <code>execution/program</code>. Program is read-only — its nodes are what the session played
mission points at or a pass a run made over one — and the transport bar stays pinned above its or produced: the files the mission points at, the files the run reached from them, the inline text
panels, so a run can be started, stepped and reset without leaving the branch.</p> of the NC Code commands, one node per distinct title, and the writeback files converted from a
played file — and the transport sits in the run header at the top of the Control Tree pane, with
the run-state badge at its right end, so a run can be started, stepped and reset without leaving
the branch.</p>
<h2 id="before-anything-runs">Before anything runs</h2> <h2 id="before-anything-runs">Before anything runs</h2>
<p>The branch is not empty before a run. The service seeds it from the mission: one node per distinct <p>The branch is not empty before a run. The service seeds it from the mission: first one node per
NC file a <strong>Program File</strong> command names, and one per <strong>NC Code</strong> command, taken in the order the distinct file an enabled <strong>Program File</strong> command namesNC, CL or CSV alike, since the seed reads
mission lists them and reaching into nested groups. Those nodes are placeholders — a file the run the command's path and not its kind — in the order the mission lists them and reaching into nested
has not opened yet — and the branch panel says so, badging itself <em>not run yet</em> beside the file <strong>List</strong> commands, then one node per distinct title among the enabled
count.</p> <strong>NC Code</strong> commands — so an NC Code command listed above a Program File still seeds below every
<p>Three things decide what is seeded, and each of them is visible in the screenshot below:</p> file node. Those nodes are placeholders — a file the run has not opened yet — and the branch panel
says so, badging itself <em>not run yet</em> beside the file count.</p>
<p>Three things decide what is seeded:</p>
<ul> <ul>
<li><strong>A disabled command seeds nothing.</strong> The mission's greyed <em>Program File</em> entry names an NC file <li><strong>A disabled command seeds nothing.</strong> The mission's greyed <em>Program File</em> entry names a file
that never reaches the branch, and nothing beneath a disabled group reaches it either.</li> that never reaches the branch, and nothing beneath a disabled List reaches it either.</li>
<li><strong>Two commands naming one file seed one node.</strong> Paths are compared with case and slash direction <li><strong>Two commands naming one file seed one node.</strong> Paths are compared with case and slash direction
ignored, so a file played twice appears once.</li> ignored, so a file played twice appears once. In the screenshot below the first <code>circle.ptp</code>
command sits inside the collapsed <strong>List [Roughing]</strong> and the second is the top-level
<strong>Program File</strong> row, so the branch shows one plain <code>circle.ptp</code>; the <code>×2</code> it takes once both
commands have played is in the next section.</li>
<li><strong>An NC Code command is seeded under its own title</strong>, not under a file name, because it has no <li><strong>An NC Code command is seeded under its own title</strong>, not under a file name, because it has no
file — its text lives in the mission. The branch marks it <code>(inline)</code>.</li> file — its text lives in the mission. The branch marks it <code>(inline)</code>, and two NC Code commands
with the same title share one node.</li>
</ul> </ul>
<p><img src="the-program-branch-img/program-before-run.en.png" alt="The Execution page before a run: the Control Tree shows the Mission branch with nine commands — two of them greyed out and unticked — over the Program branch, whose five nodes are circle.ptp, drill_slot.ptp, side.ptp, slide.ptp and (inline) Inline finishing pass. The branch panel below the transport bar is badged not run yet beside 5 files, and the four Session Messages tabs are empty"></p> <p><img src="the-program-branch-img/program-before-run.en.png" alt="The Execution page before a run: the run header at the top of the Control Tree pane shows the six transport buttons and a green ready badge at its right end; under it the Mission root row, with a + at its right edge, lists nine command rows, each with a checkbox and a drag handle, two of them greyed out and unticked, and the two List rows carry their own +; the Program root below is selected and holds five nodes circle.ptp, drill_slot.ptp, side.ptp, slide.ptp and (inline) Inline finishing pass; the Program panel in the editor row under the tree is badged not run yet beside 5 files with a round refresh button at the row's right end, above the hint to run the mission; the 3D canvas shows an uncut block, and the four Session Messages tabs carry no badge"></p>
<p><em>The Program branch at <code>/execution?tree=execution/program</code>, on a project that has not been played. <p><em>The Program branch at <code>/execution?tree=execution/program</code>, on a project that has not been played.
The disabled <code>Program File</code> entry in Mission has no node under Program; the enabled <code>NC Code</code> The disabled <code>Program File</code> entry in Mission has no node under Program; the enabled <code>NC Code</code>
command has one, under its title.</em></p> command has one, under its title.</em></p>
@@ -116,25 +125,37 @@ command has one, under its title.</em></p>
not name — a subprogram call nests its callee under the caller. The panel's badge changes from not name — a subprogram call nests its callee under the caller. The panel's badge changes from
<em>not run yet</em> to <em>run data</em>, and a file the run made more than one pass over takes a <code>×</code> and a <em>not run yet</em> to <em>run data</em>, and a file the run made more than one pass over takes a <code>×</code> and a
count in its tree label.</p> count in its tree label.</p>
<p><img src="the-program-branch-img/program-after-run.en.png" alt="The same page after the run has finished: the Execution root badge reads finished, the first Program node now reads circle.ptp ×2, the branch panel is badged run data beside 5 files, and the Session Messages tabs carry counts — Shell 11 and NC Diagnostics 7, with Step Diagnostics and NC Manipulation still unbadged"></p> <p><img src="the-program-branch-img/program-after-run.en.png" alt="The same page after the run has finished: the badge at the right end of the run header reads finished, the Mission rows are unchanged, the first Program node reads circle.ptp ×2, the Program panel under the tree is badged run data beside 5 files with the refresh button at the row's right end, the 3D canvas shows the cut block with a gold cutter and green tool paths above it, and the Session Messages tabs carry counts — Shell 11 and NC Diagnostics 7, with Step Diagnostics and NC Manipulation still unbadged — over a list of System messages"></p>
<p><em>The same deep link once the run has finished. <code>circle.ptp ×2</code> is one node holding two passes, <p><em>The same deep link once the run has finished. <code>circle.ptp ×2</code> is one node holding two passes,
because two Program File commands named the same file.</em></p> because two Program File commands named the same file.</em></p>
<div class="IMPORTANT"> <div class="IMPORTANT">
<h5>Important</h5> <h5>Important</h5>
<p>The branch is rebuilt when the run <strong>changes state</strong> — starting, finishing, being reset — and not <p>The branch is rebuilt when the run <strong>changes state</strong> — starting, pausing, finishing, being reset —
while it is playing. During a long run the nodes on screen are the ones the last transition left and not while it is playing. During a long run the nodes on screen are the ones the last
there, so a file the run has since opened may not be listed yet. Pausing brings it up to date.</p> transition left there, so a file the run has since opened may not be listed yet. The round
refresh button at the far right end of the Program panel's badge row — across the row from the
<em>run data</em> badge and the file count, its tooltip <em>Re-read the file tree from the current
session</em> — rebuilds the branch on the spot without touching the transport; pausing rebuilds it
too, since a pause is a state change.</p>
</div> </div>
<h2 id="reading-one-file">Reading one file</h2> <h2 id="reading-one-file">Reading one file</h2>
<p>Selecting a node opens the file as the run saw it: the path it was read from, a selector for the <p>Selecting a node opens the file as the run saw it: the path it was read from, a selector for the
passes made over it, and the text with what each line produced beside it.</p> passes made over it, and the text with what each line produced beside it.</p>
<p><img src="the-program-branch-img/program-file-passes.en.png" alt="The Program branch with circle.ptp ×2 selected: the breadcrumb reads Execution / Program / circle.ptp ×2, the path caption NC/circle.ptp, a pass selector reading Pass (2) and #2 · re-entry beside a Follow toggle, then twenty-one numbered lines of NC with a step range printed to the right of thirteen of them, and a footer reading 21 lines · 21 executed lines"></p> <p><img src="the-program-branch-img/program-file-passes.en.png" alt="The Program branch with circle.ptp ×2 selected and the canvas and right-hand columns switched off, so the Control Tree pane spans the window: the menu bar carries a red disconnected chip beside the four layout toggles, the run header's green finished badge sits at the far right, the Mission root row is collapsed with a + at its right edge, the Program root beneath it is open and holds five nodes — circle.ptp ×2 highlighted in blue, drill_slot.ptp, side.ptp, slide.ptp and (inline) Inline finishing pass — and the editor row's header reads Program / circle.ptp ×2; inside it the path caption NC/circle.ptp, a pass selector reading Pass (2) and #2 · re-entry beside a Follow toggle, then twenty-one numbered lines of NC with a step range printed to the right of ten of them, a footer reading 21 lines · 21 executed lines, and the window footer reading Ready"></p>
<p><em>One file node at <code>/execution?tree=execution/program/0</code>, with the canvas column switched off so the <p><em>One file node at <code>/execution?tree=execution/program/0</code>, with the canvas column switched off so the
line viewer has the width. The pass selector names the pass and why it was entered.</em></p> line viewer has the width — which is why the menu-bar chip reads <strong>disconnected</strong>: the badge folds the
page's rendering connection in with its service connections, and with the canvas column off the page
holds no rendering connection (see <a href="../basics/the-app-window.html">The Application Window</a>).
The pass selector names the pass and why it was entered.</em></p>
<ul> <ul>
<li><strong>The pass selector</strong> carries one entry per pass, labelled with how that pass was entered — the <li><strong>The pass selector</strong> carries one entry per pass, labelled with how that pass was entered. A
first arrival at the top of the file, a re-entry when the mission came back to it, or the call pass that an <code>M98</code>/<code>M198</code> subprogram call started carries the call word and its <code>P</code> number —
that reached it from another file.</li> <code>M98 P8</code> — on every pass, so a subprogram the caller repeats with an <code>L</code> count or calls a second
time reads <code>×N</code> with each pass labelled by the call, never as a re-entry. A pass with no call
behind it reads <em>top</em> on the first arrival at that path and <em>re-entry</em> on every later pass over
it — whether a second Program File command named the file again or a <code>WHILE</code> or <code>GOTO</code> inside a
single play of it started a new pass. So a file the mission names once can still read <code>×N</code>, with
every pass after the first labelled re-entry.</li>
<li><strong>The step range</strong> beside a line is what that line produced. A line with no range beside it ran <li><strong>The step range</strong> beside a line is what that line produced. A line with no range beside it ran
and produced no motion: <code>G</code> and <code>M</code> words that set state, and the tape marks, all execute without and produced no motion: <code>G</code> and <code>M</code> words that set state, and the tape marks, all execute without
cutting anything.</li> cutting anything.</li>
@@ -146,13 +167,17 @@ was put.</li>
</ul> </ul>
<h2 id="what-the-branch-does-not-hold">What the branch does not hold</h2> <h2 id="what-the-branch-does-not-hold">What the branch does not hold</h2>
<ul> <ul>
<li><strong>The writeback files are not inside the file nodes.</strong> Converting a played program back to NC <li><strong>The writeback files are not inside the file nodes.</strong> With <strong>Post-Execution CL → NC
makes its own node at the top of the branch, beside the file nodes rather than under them, and Writeback</strong> enabled, the mission re-serializes every file the session played — NC plays as well
clicking a line on either side jumps to its twin on the other. That conversion is the CL-to-NC as CL plays — and each converted file makes its own node, labelled <code></code> and the output file's
writeback, so a mission that plays brand NC produces none, and the branch shows only source files.</li> name, at the top level of the branch, after the file nodes rather than under them; the Program
<li><strong>Node addresses are positions, not files.</strong> A node is <code>execution/program</code> followed by its index, panel counts them beside the file count, and clicking a line on either side jumps to its twin on
so a deep link into the branch survives only as long as the branch has the same shape. Link to the the other. With that section disabled the branch shows only source files.</li>
branch, not into it.</li> <li><strong>Node addresses are positions, not files.</strong> A node is <code>execution/program</code> followed by an index
at each level of nesting — <code>execution/program/0</code> for a top-level file, <code>execution/program/0/0</code>
for a subprogram nested under it — and a writeback node takes <code>dst-</code> and its own index in place
of a file index, <code>execution/program/dst-0</code>. So a deep link into the branch survives only as long
as the branch has the same shape. Link to the branch, not into it.</li>
<li><strong>A skipped line is not only recorded here.</strong> A line suppressed by block skip is also announced in <li><strong>A skipped line is not only recorded here.</strong> A line suppressed by block skip is also announced in
the <strong>NC Diagnostics</strong> list while the run is playing — see the <strong>NC Diagnostics</strong> list while the run is playing — see
<a href="when-something-goes-wrong.html">When Something Goes Wrong</a>.</li> <a href="when-something-goes-wrong.html">When Something Goes Wrong</a>.</li>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 118 KiB

@@ -141,7 +141,7 @@ so re-expanding is instant rather than a fresh connection.</p>
<p>The <strong>Scene</strong> menu open over the canvas at <code>/execution</code>, with the Strip Charts column beside it. The <p>The <strong>Scene</strong> menu open over the canvas at <code>/execution</code>, with the Strip Charts column beside it. The
three groups are the ones listed above, and the ticked boxes are the set the page opens with — three groups are the ones listed above, and the ticked boxes are the set the page opens with —
Workpiece, Fixture and Dimension Bar — with Machine and Tool unticked.</p> Workpiece, Fixture and Dimension Bar — with Machine and Tool unticked.</p>
<p><img src="watching-the-run-img/scene-menu.en.png" alt="The Execution page with the Scene dropdown open over the 3D canvas, showing Solid with Machine, Tool, Workpiece and Fixture, Coordinate with Program Zero and ISO Coordinate, and Display Aids with Dimension Bar and Color Scale Bar; Workpiece, Fixture and Dimension Bar are ticked, and the Strip Charts column stands to the right"></p> <p><img src="watching-the-run-img/scene-menu.en.png" alt="The Execution page with the left dock hidden and the Scene dropdown open from the 3D Rendering Canvas header, showing Solid with Machine, Tool, Workpiece and Fixture, Coordinate with Program Zero and ISO Coordinate, and Display Aids with Dimension Bar and Color Scale Bar; Workpiece, Fixture and Dimension Bar are ticked, the canvas behind the menu shows a white block on a grey fixture with the dimension bar reading 22.9 mm, the Session Messages panel sits beneath it, and the Strip Charts column with its three filled charts stands to the right"></p>
<h2 id="the-three-strip-charts">The three strip charts</h2> <h2 id="the-three-strip-charts">The three strip charts</h2>
<p>One group bar drives three charts, and each of them plots <strong>the whole mission rather than the current <p>One group bar drives three charts, and each of them plots <strong>the whole mission rather than the current
moment</strong>:</p> moment</strong>:</p>
@@ -172,8 +172,10 @@ samples: the window is downsampled to the width it has on screen, so what you ar
shape of the run — where the spindle is loaded, where surface quality degrades, where thermal limits shape of the run — where the spindle is loaded, where surface quality degrades, where thermal limits
are approached — rather than individual values. The values themselves are in the legend panel down are approached — rather than individual values. The values themselves are in the legend panel down
the side of each chart, which follows the cursor and can be dragged wider.</p> the side of each chart, which follows the cursor and can be dragged wider.</p>
<p>All three carry a <strong>Y-axis range</strong> editor in their header<em>Fit</em> to the data, <em>Lock</em> to a minimum <p>All three carry a <strong>Y-axis range</strong> editor in their header, behind a button that reads <strong>Auto</strong>
and maximum you type, or <em>Symmetric</em> about zero with a bound; locking one is how you compare two until you change it. Its three choices are <em>Fit (auto)</em>, which follows the data; <em>Lock</em>, a <strong>Min</strong>
and <strong>Max</strong> you type, after which the button reads them as <code>[min, max]</code>; and <em>Symmetric</em>, about zero
with a <strong>± bound</strong> you type, which the button shows as <code>±bound</code>. Locking one is how you compare two
parts of a run without the axis moving under you. The parts of a run without the axis moving under you. The
Color Index chart adds two more: the property picker, which is a type-to-filter list of every Color Index chart adds two more: the property picker, which is a type-to-filter list of every
quantifiable step property, and <strong>Colors</strong>, which edits the colour guide. Colors is worth quantifiable step property, and <strong>Colors</strong>, which edits the colour guide. Colors is worth
@@ -202,7 +204,7 @@ colour scale bar, not the line in the chart.</p>
</tr> </tr>
<tr> <tr>
<td><strong>Fit view</strong></td> <td><strong>Fit view</strong></td>
<td>Fits the 3D canvas to the tool path — the one control here that acts on the canvas</td> <td>Fits the 3D canvas to the tool path, or to the home view when there is no tool path yet — the one control here that acts on the canvas</td>
</tr> </tr>
<tr> <tr>
<td><strong>Stick to live end</strong></td> <td><strong>Stick to live end</strong></td>
@@ -249,7 +251,7 @@ being dragged back to the live end — and <em>Reset display range</em> is how y
</tr> </tr>
<tr> <tr>
<td>Hover</td> <td>Hover</td>
<td>Puts that x-value in the group bar's cursor readout</td> <td>Puts that x-value in the group bar's cursor readout, and marks that step's position on the tool path in the canvas</td>
</tr> </tr>
<tr> <tr>
<td>One finger / two fingers</td> <td>One finger / two fingers</td>
@@ -259,15 +261,23 @@ being dragged back to the live end — and <em>Reset display range</em> is how y
</table> </table>
<p>A left drag shorter than a few pixels counts as a click, so selecting a step does not need a steady <p>A left drag shorter than a few pixels counts as a click, so selecting a step does not need a steady
hand.</p> hand.</p>
<p>Hovering is the light-touch twin of clicking. A click selects a step and fills the Step Info column;
a hover only tells the engine which step the pointer is over, and the canvas answers by lighting up
that step's cutter location on the tool path — a dot with an <code>@index</code> label, joined by a short
segment to the position before it — so sweeping the pointer along a chart walks a marker along the
cut. The marker goes away when the pointer leaves the chart, it is only drawn while <strong>Tool Path</strong> is
on, and a touch screen has no hover, so it never appears there.</p>
<p>Before anything has run, all three read <strong>No mission data</strong>. A chart that has data but no physics <p>Before anything has run, all three read <strong>No mission data</strong>. A chart that has data but no physics
behind it reads <strong>No physics data</strong> instead — that is what the Availability chart looks like when behind it reads <strong>No physics data</strong> instead — that is what the Availability chart looks like when
the run produced no physics results.</p> the run produced no physics results.</p>
<p>The three charts with the demo mission paused part way through and a step selected. The vertical rule <p>The three charts with the whole demo mission in the window and a step selected. The vertical rule
crossing all three at the same place is that selection; the range chip on the group bar names the crossing all three at the same place is that selection; the range chip on the group bar names the
window, the x-axis is in seconds, and each chart's legend stands down its right side with one entry window — here every one of the 6402 steps — the x-axis is in seconds, and each chart's legend
per series — five on each of the first two, one on the Color Index chart, which plots the single stands down its right side with one entry per series — five on each of the first two, one on the
property named in its header.</p> Color Index chart, which plots the single property named in its header. The transport and the
<p><img src="watching-the-run-img/strip-charts.en.png" alt="The Execution page's Strip Charts column filled from a paused run: an Availability Chart, a Surface Roughness Chart and a Color Index Time Chart stacked under one group bar, each showing banded series across the mission timeline with a legend listing its series down the right side, and the 3D canvas showing the part-machined block to the left"></p> run-state badge sit in the run header at the top of the Control Tree pane, in the left dock this
shot hides.</p>
<p><img src="watching-the-run-img/strip-charts.en.png" alt="The Execution page with the left dock hidden: the 3D Rendering Canvas on the left shows a white block on a grey fixture with the tool path drawn down onto a coloured cut in its top face and the dimension bar reading 22.9 mm, the Session Messages panel sits beneath it, and the Strip Charts column on the right stacks an Availability Chart, a Surface Roughness Chart and a Color Index Time Chart under one group bar whose range chip reads [0..6402] / 6402 and whose cursor readout reads Time (s): —; every chart's x-axis is Time (s), each chart header's range button reads Auto, a vertical selection rule crosses all three charts near the start of the timeline, and each chart carries a legend down its right side"></p>
<h2 id="see-also">See Also</h2> <h2 id="see-also">See Also</h2>
<ul> <ul>
<li><a href="index.html">Running a Simulation</a> — the rest of running a job</li> <li><a href="index.html">Running a Simulation</a> — the rest of running a job</li>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 47 KiB

@@ -97,15 +97,19 @@ something in it, so a tab with no number beside its name is a sink nothing has r
<ul> <ul>
<li><strong>Shell</strong> — the session's own account of itself: what started, what finished, what it built, and <li><strong>Shell</strong> — the session's own account of itself: what started, what finished, what it built, and
the verdicts it reaches at the end of a play. A conversion or an optimization reports itself here the verdicts it reaches at the end of a play. A conversion or an optimization reports itself here
too, stage by stage and file by file, from its opening row to its closing count. These rows carry too, from its opening row to its closing count — an optimization stage by stage and file by
no anchor, because there is nothing file; a conversion in those two rows alone, the closing one carrying the count and the names of
every file written in a single sentence, and a row of its own only for a file it could not write.
These rows carry no anchor, because there is nothing
in the program to anchor them to. <strong>This is the list a run that appears to have done nothing is in the program to anchor them to. <strong>This is the list a run that appears to have done nothing is
diagnosed from</strong>: a play that ends with no step having touched the workpiece is reported here, and diagnosed from</strong>: a play that ends with no step having touched the workpiece is reported here, and
the message names the usual causes — an incremental header with no <code>G90</code> after it, a work offset the message names the usual causes — an incremental header with no <code>G90</code> after it, a work offset
or program zero that puts the program somewhere else, stock that is not where the program expects or program zero that puts the program somewhere else, stock that is not where the program expects
it.</li> it, and the tool geometry.</li>
<li><strong>NC Diagnostics</strong> — everything the NC pipeline said while playing, which is not only complaints. <li><strong>NC Diagnostics</strong> — everything the NC pipeline said while playing, which is not only complaints.
It opens each file with the line count it found, and a row about one sentence carries an anchor It closes each file with the line count it read — the <em>contains lines</em> row is written once the
file's last line has been consumed, so it follows every diagnostic that file raised, and a file
the play is still reading has no such row yet — and a row about one sentence carries an anchor
naming it. This is the list to read when the program did not do what its text says.</li> naming it. This is the list to read when the program did not do what its text says.</li>
<li><strong>Step Diagnostics</strong> — anchored to a machining step rather than to a position in the text. Most of <li><strong>Step Diagnostics</strong> — anchored to a machining step rather than to a position in the text. Most of
it is about motion, but not all: an NC-embedded script that fails to compile is reported here too, it is about motion, but not all: an NC-embedded script that fails to compile is reported here too,
@@ -120,33 +124,44 @@ account of itself is on <strong>Shell</strong>.</li>
<p>A message about a <code>G</code> word and a message about a move are different problems, and they never share a <p>A message about a <code>G</code> word and a message about a move are different problems, and they never share a
list. Looking in the wrong one reads as silence.</p> list. Looking in the wrong one reads as silence.</p>
<h2 id="reading-a-row">Reading a row</h2> <h2 id="reading-a-row">Reading a row</h2>
<p><img src="when-something-goes-wrong-img/nc-diagnostics.en.png" alt="The Execution page with the left and right columns switched off: the canvas above, and below it the Session Messages panel with the NC Diagnostics tab selected. The tab row shows Shell badged 11 and NC Diagnostics badged 7, with Step Diagnostics and NC Manipulation carrying no badge at all. Under a filter toolbar of Severity, Category, a text box, Reset and Export, seven rows are listed: six System rows reading Sys-Init&ndash;FileLines with each file and its line count, and one warning row whose anchor column reads Sn 2105, category Unsupported, id Parsing&ndash;Unconsumed, text Unconsumed Parsing entries: G02"></p> <p><img src="when-something-goes-wrong-img/nc-diagnostics.en.png" alt="The Execution page with the left and right columns switched off, so no Control Tree pane and no run header is in view: the 3D Rendering Canvas above, showing a white block on a grey fixture with a gold disc cutter at its top face and green tool paths rising above it, and below it the Session Messages panel with the NC Diagnostics tab selected. The tab row shows Shell badged 11 and NC Diagnostics badged 7, with Step Diagnostics and NC Manipulation carrying no badge at all. Under a filter toolbar of Severity, Category, a Filter text box, Reset and Export, with a 7 / 7 counter at its right end, seven rows are listed: six System rows reading Sys-Init&ndash;FileLines with each file and its line count — circle.ptp listed twice, Inline finishing pass last — and, sixth in the list, one warning row whose anchor column reads Sn 2105, category Unsupported, id Parsing&ndash;Unconsumed, text Unconsumed Parsing entries: G02"></p>
<p><em>The four lists at <code>/execution</code>, with NC Diagnostics selected. Two of the four tabs carry no badge, <p><em>The four lists at <code>/execution</code>, with NC Diagnostics selected. Two of the four tabs carry no badge,
which is how an empty sink looks.</em></p> which is how an empty sink looks. The warning at <code>Sn 2105</code> sits above the line-count row for
<code>Inline finishing pass</code> because that row closes its file rather than opening it.</em></p>
<p>A row carries, left to right, the position it is about, the category, the message's own id, and its <p>A row carries, left to right, the position it is about, the category, the message's own id, and its
text. The position is the anchor: <code>Sn</code> and a number for a sentence, <code>S</code> and a number for a step. Not text. The position is the anchor. On the two NC lists it is <code>Sn</code> and a number, naming a sentence. On
every row has one — a complaint about the pipeline rather than about a particular sentence has <strong>Step Diagnostics</strong> it opens with <code>S</code> and the step's number, and when that step was reached from a
nothing to anchor to, and neither has anything on <strong>Shell</strong>.</p> sentence the one anchor carries both markers — <code>S12 · Sn 340</code> names the step and then the sentence
behind it; only a step with no sentence behind it reads <code>S</code> and its number alone. Not every row has
one — a complaint about the pipeline rather than about a particular sentence has nothing to anchor
to, and neither has anything on <strong>Shell</strong>.</p>
<p>The id is worth reading. It is stable across languages and releases, so it is the thing to quote <p>The id is worth reading. It is stable across languages and releases, so it is the thing to quote
when asking someone else about a message, and the thing to filter on when one message is repeating. when asking someone else about a message, and the thing to filter on when one message is repeating.
The <strong>Filter text…</strong> box, the <strong>Severity</strong> and <strong>Category</strong> lists and <strong>Export</strong> are described with The <strong>Filter text…</strong> box, the <strong>Severity</strong> and <strong>Category</strong> lists and <strong>Export</strong> are described with
the rest of the panel in <a href="../basics/messages-and-logs.html">Messages and Logs</a>.</p> the rest of the panel in <a href="../basics/messages-and-logs.html">Messages and Logs</a>.</p>
<div class="IMPORTANT"> <div class="IMPORTANT">
<h5>Important</h5> <h5>Important</h5>
<p><strong>On the two NC lists, a row is not an occurrence.</strong> <strong>NC Diagnostics</strong> folds across a play and <p><strong>On the two NC lists, a row is not an occurrence.</strong> <strong>NC Diagnostics</strong> folds across the play of
<strong>NC Manipulation</strong> across one conversion or optimization run; <strong>Shell</strong> and <strong>Step Diagnostics</strong> one mission command — one <strong>Program File</strong> or one <strong>NC Code</strong> entry, subprograms included, so a
fold nothing, and every report they take becomes a row of its own. Where it applies, the pipeline file played twice is two windows — and <strong>NC Manipulation</strong> across one conversion or optimization
keeps one entry per run; <strong>Shell</strong> and <strong>Step Diagnostics</strong> do no such folding — a report there gets a row of its own unless it is identical to the row just
distinct message — same id, same wording — and drops every repeat instead of listing it. When the before it, in which case it joins that row under the multiplier badge described below. Where it
program ends, each message that occurred more than once gets one summary row reading <em>repeated N applies, the pipeline keeps one entry per distinct message — same id, same wording — and drops
times in this run, first at</em> the sentence it was first seen on. So a diagnostic raised on forty every repeat instead of listing it. When the program ends, each message that occurred more than
different sentences leaves two rows for that program: the first occurrence, and the summary.</p> once gets one summary row: the first occurrence's text followed by <code>[repeated Nx in this run, first at Sn=…]</code>, with the count in place of <code>N</code> and the sentence it was first seen on after <code>Sn=</code>
(a message with no sentence to anchor to ends in <code>[repeated Nx in this run]</code> instead). So a
diagnostic raised on forty different sentences of one file leaves two rows for that file: the
first occurrence, and the summary — and the same diagnostic raised again in the next file, or on
the same file's second play, starts over with a first occurrence and a summary of its own. The
screenshot above shows the window's edge: <code>circle.ptp</code> is played twice, and its line-count row
is listed twice rather than folded.</p>
<p>Two consequences are worth holding on to. The count is only in that summary sentence — the <p>Two consequences are worth holding on to. The count is only in that summary sentence — the
multiplier badge that marks consecutive identical messages is a different mechanism and does not multiplier badge that marks consecutive identical messages is a different mechanism and does not
appear on these. And <strong>the summary row's anchor is the last occurrence while its text names the appear on these. And <strong>the summary row's anchor is the last occurrence while its text names the
first</strong>, so jumping from it lands at the end of the run of repeats, not at the beginning. first</strong>, so the <code>Sn</code> in its anchor column is the end of the run of repeats and the <code>Sn=</code> in its
Everything between the two rows has no anchor at all: to find those positions, fix the first one text the beginning. Neither is a link: clicking a row opens its detail when it has one and does
and play again.</p> nothing else, so an anchor is a position to read off, not a place to go. Everything between the
two rows has no anchor at all: to find those positions, fix the first one and play again.</p>
</div> </div>
<h2 id="then-the-runs-own-record">Then the run's own record</h2> <h2 id="then-the-runs-own-record">Then the run's own record</h2>
<p>The <strong>Program</strong> branch holds what the run did to each line — the passes it made and the marks each <p>The <strong>Program</strong> branch holds what the run did to each line — the passes it made and the marks each
@@ -157,12 +172,20 @@ what the pipeline thought of a sentence while it was playing, the <strong>Progra
sentence produced.</p> sentence produced.</p>
<h2 id="then-the-service-log">Then the service log</h2> <h2 id="then-the-service-log">Then the service log</h2>
<p><strong>Show Log</strong> on the menu bar opens the log the service is writing for the current day, with a <p><strong>Show Log</strong> on the menu bar opens the log the service is writing for the current day, with a
<strong>Download</strong> for sending it to someone else. It holds things the four lists never carry — the <strong>Download</strong> for sending it to someone else. It holds things the four lists do not carry — the
exception behind a failure, and the engine's own start-up account of itself and it is the only engine's own start-up account of itself, and the exception behind a failure the engine did not report
one of these surfaces that outlives the session. What it does not hold is the four lists: those are through a message, which the service writes to the log and nowhere else — and it outlives the
pushed to the browser and are never written to the file, so a message seen in a list is not session: a Reset on the transport — the eject button in the run header, not the <strong>Reset</strong> in a
findable there. The viewer itself is described in tab's filter toolbar, which clears that tab's filters and touches no list — empties <strong>Shell</strong>,
<a href="../basics/messages-and-logs.html">Messages and Logs</a>.</p> <strong>NC Diagnostics</strong> and <strong>Step Diagnostics</strong>, and the log keeps what it had. An exception the engine <em>did</em> report through a message is a different case: it rides
the row, which carries a chevron; opening it shows the exception in full, with a <strong>Copy</strong> of its
own, so a script that would not compile or a step record that could not be read is answered from
the list, not from the log. What the log does not hold is the four lists: those are pushed to the
browser and are never written to the file, so a message seen in a list is not findable there — the
exception on a row included. The one list the transport's Reset leaves
alone is <strong>NC Manipulation</strong> — the next conversion or optimization is what empties it — so the last
conversion's findings are still on that tab after the run has been reset away, not in the log. The
viewer itself is described in <a href="../basics/messages-and-logs.html">Messages and Logs</a>.</p>
<h2 id="while-an-optimization-is-running">While an optimization is running</h2> <h2 id="while-an-optimization-is-running">While an optimization is running</h2>
<p>An optimization reports itself on <strong>Shell</strong>, stage by stage. It opens with <em>Start NC optimization.</em> <p>An optimization reports itself on <strong>Shell</strong>, stage by stage. It opens with <em>Start NC optimization.</em>
and ends with <em>Total N files optimized.</em> and <em>optimization cache cleared.</em>, and between them every and ends with <em>Total N files optimized.</em> and <em>optimization cache cleared.</em>, and between them every
@@ -174,31 +197,50 @@ NC commands..</em>, with one <em>File optimized:</em> row naming each output fil
stopped one. While the per-step feeds are being solved, every thousandth step adds another stopped one. While the per-step feeds are being solved, every thousandth step adds another
<em>Computing Optimized Feed by indivisual step..</em> row carrying the source file and line it has <em>Computing Optimized Feed by indivisual step..</em> row carrying the source file and line it has
reached; while the optimized text is being written, every thousandth line adds a <em>Now optimizing reached; while the optimized text is being written, every thousandth line adds a <em>Now optimizing
to:</em> row carrying the same two numbers. <strong>Shell appends every one of them and folds nothing</strong>, so to:</em> row carrying the same two numbers. <strong>Each of them is a row on Shell</strong>, subject to the one
its newest row is where the run has got to: numbers that keep advancing are a run still working, and folding <strong>Shell</strong> does: the file and line on a step row are those of the sentence the step came
a list that has stopped growing on a stage whose successor has not been announced is a run that is from, so a sentence that expands to more than a thousand steps — a long arc at a fine resolution —
not.</p> puts the same two numbers on two consecutive rows, and those join under the multiplier badge. And
because the per-step feeds are solved in parallel, the numbers on successive step rows need not
climb in strict order. What holds either way is that the newest row is where the run has got to:
numbers that keep changing are a run still working, and a list that has stopped growing on a stage
whose successor has not been announced is a run that is not.</p>
<p>The counting rows are the instrument, not the stage rows. A stage with fewer than a thousand steps <p>The counting rows are the instrument, not the stage rows. A stage with fewer than a thousand steps
to solve, or fewer than a thousand lines to write, announces its start and then says nothing until to solve, or fewer than a thousand lines to write, announces its start and then says nothing until
it ends — so a short program crosses the whole ladder in near-silence, and that silence means it ends — so a short program crosses the whole ladder in near-silence, and that silence means
nothing on its own.</p> nothing on its own.</p>
<p><strong>A Stop ends an optimization on a success row.</strong> Stop reaches the optimizer between steps and <p><strong>A Stop ends an optimization on the same two closing rows as a finished one.</strong> Stop reaches the
between output files rather than only at the end, and what it leaves on <strong>Shell</strong> is <em>optimization optimizer between steps and between output files rather than only at the end, and what it leaves
canceled.</em> followed immediately by <em>Total N files optimized.</em> in success green — even <em>Total 0 files on <strong>Shell</strong> is <em>optimization canceled.</em> followed immediately by <em>Total N files optimized.</em> in
optimized.</em> arrives as a success. The count is of the files the run had opened, so a file the Stop success green and then <em>optimization cache cleared.</em>, the run's last row — even <em>Total 0 files
optimized.</em> arrives as a success. A Stop that lands while the per-step feeds are being solved puts
one more row ahead of those: <em>Optimization Feed Process canceled.</em> stands where <em>Optimization
Feedrate built.</em> would have. The count is of the files the run had opened, so a file the Stop
landed part-way through is counted with the rest and is left on disk short. The complete ones are landed part-way through is counted with the rest and is left on disk short. The complete ones are
those whose own <em>File optimized:</em> row appeared before the cancel.</p> those whose own <em>File optimized:</em> row appeared before the cancel.</p>
<h2 id="three-things-that-look-like-faults-and-are-not">Three things that look like faults and are not</h2> <h2 id="three-things-that-look-like-faults-and-are-not">Three things that look like faults and are not</h2>
<p><strong>An English message in a translated interface is the safe answer, not a bug.</strong> Engine messages <p><strong>An English message in a translated interface is the safe answer, not a bug.</strong> Engine messages
arrive with an id and their English text, and the interface substitutes its own translation only arrive with an id and their English text, and the interface translates by id. For a message that
when its copy of that message matches the one the engine sent. An engine built against a different carries values — a file name, a count, a line number — it substitutes its own translation only when
message set, or a message the interface has no copy of, leaves the original English in place rather its template for that id matches the one the engine sent; an engine built against a different
than rendering text that might say something else. The English is the accurate text.</p> message set, or a message the interface has no entry for, leaves the original English in place
rather than rendering text that might say something else. A message with no values in it is swapped
on its id alone, with no comparison of wording, so an engine that has reworded such a message while
keeping its id shows, in a translated interface, the translation of the wording it had before. In
both cases the English the engine sent is the accurate text, and switching the interface to English
shows every message exactly as it arrived.</p>
<p><strong>An action refused because a run is playing is a guard, not a fault.</strong> Switching the NC runner and <p><strong>An action refused because a run is playing is a guard, not a fault.</strong> Switching the NC runner and
switching the controller brand are both refused while a program is playing, rather than swapping the switching the controller brand are both refused while a program is playing, rather than swapping the
parser underneath it; the refusal names the reason and asks for the run to be paused or finished parser underneath it. The refusal is a toast that opens with the name of the action it refused and
first. It arrives on the action itself — no row is added to any of the four lists, so there is the status the service answered with: <em>Switch controller brand: HTTP 409: Cannot switch the
nothing to go looking for afterwards.</p> controller brand while an NC program is playing; pause and let the current program finish first.</em>
for a brand switch, and <em>Install NC runner: HTTP 409: Cannot switch the NC runner while an NC
program is playing; pause and let the current program finish first.</em> for a runner installed
through the <strong>Controller</strong> branch's <strong>Object Management</strong> menu, by a <strong>Load</strong> or a paste. The
<em>pause</em> in it is not the part that lifts the guard: a paused run is still a playing one to this
guard, so the switch is refused again until the program finishes or a Stop ends it. The refusal
arrives on the action itself — no row is added to any of the four lists, so there is nothing to go
looking for afterwards.</p>
<p><strong>An empty Step Diagnostics list is not proof that nothing was wrong.</strong> Collision detection is off <p><strong>An empty Step Diagnostics list is not proof that nothing was wrong.</strong> Collision detection is off
unless the mission turns it on, and the physics-dependent warnings — the cutter geometry checks unless the mission turns it on, and the physics-dependent warnings — the cutter geometry checks
raised at tool change among them — are not raised at all when physics is off. A quiet list on a run raised at tool change among them — are not raised at all when physics is off. A quiet list on a run
@@ -106,6 +106,10 @@ they are the fastest way to find out what a run actually did.</p>
<td>physics is on and steps touched, but no touched step carries a physics brief</td> <td>physics is on and steps touched, but no touched step carries a physics brief</td>
</tr> </tr>
<tr> <tr>
<td><code>Play-RapidCut--Detected</code></td>
<td>a rapid traverse (G00) removed stock — one warning per NC line, anchored on the line's first cutting step, with the line's removed volume and largest cutting depth; the line total is compared against the project's <code>RapidCutVolumeThreshold_mm3</code> (<code>MachiningActRunnerConfig</code>, default 0: any contact); with collision detection on, contact with the spindle stopped is reported there instead</td>
</tr>
<tr>
<td><code>Tool-FluteCount--Zero</code></td> <td><code>Tool-FluteCount--Zero</code></td>
<td>physics is on and a milling cutter resolves to zero flutes</td> <td>physics is on and a milling cutter resolves to zero flutes</td>
</tr> </tr>
@@ -228,6 +228,20 @@ seed pollution.</li>
<li><a class="xref" href="../../api/Hi.Numerical.Acts.ActMcXyzLinearContour.html">ActMcXyzLinearContour</a> steps by <strong>euclidean</strong> tip travel instead of the <li><a class="xref" href="../../api/Hi.Numerical.Acts.ActMcXyzLinearContour.html">ActMcXyzLinearContour</a> steps by <strong>euclidean</strong> tip travel instead of the
largest per-axis component, so <code>LinearResolution_mm</code> now caps actual tool-tip travel per step and a largest per-axis component, so <code>LinearResolution_mm</code> now caps actual tool-tip travel per step and a
diagonal move produces up to √3× more steps at the same setting.</li> diagonal move produces up to √3× more steps at the same setting.</li>
<li><strong>Cutterworkpiece engagement no longer depends on how the contact surface was tiled.</strong> The scan
that turns a step's contact contours into the engaged angle ranges of
<a class="xref" href="../../api/Hi.Milling.Engagements.LayerMillingEngagement.html">LayerMillingEngagement</a> switched to a bounding-box approximation on
dense steps, could pull a merged range back when a shorter slice nested inside it, started bottom
rings the floor never reached, and read the winding of each triangle — so the same cut produced a
different engagement, and therefore different cutting forces and temperatures, depending on how
many polygons the geometry kernel happened to cut the contact surface into. Every triangle is now
scanned exactly and orientation-free; a cylinder wall and a flat floor sector with known engagement
arcs reproduce them to 1e-9 rad at four tessellations, and the managed and native paths stay
bit-identical. Re-running an existing program moves the forces on most engaged steps (5895% of
them on the bench fixtures); the largest moves are floors that used to register as empty — the
whole bottom disc dropped out — and side ranges that were fragmented into pieces separated by
phantom 1° gaps. Coefficient sets trained before this change embed the old engagement of their
training program; retrain on a replay if that fit matters.</li>
<li>The SoftNc pipeline is the default engine.</li> <li>The SoftNc pipeline is the default engine.</li>
<li>Executed <code>SyntaxPiece</code>s freeze to UTF-8 (below), so their <code>JsonObject</code> is a fresh read-only snapshot <li>Executed <code>SyntaxPiece</code>s freeze to UTF-8 (below), so their <code>JsonObject</code> is a fresh read-only snapshot
per call rather than a retained live graph.</li> per call rather than a retained live graph.</li>
@@ -0,0 +1,68 @@
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 990 350' width='990' height='350'>
<defs>
<marker id='axis' markerWidth='10' markerHeight='10' refX='8' refY='5' orient='auto' markerUnits='userSpaceOnUse'><path d='M0,0 L10,5 L0,10 z' fill='#222'/></marker>
<marker id='mom' markerWidth='12' markerHeight='12' refX='9' refY='6' orient='auto' markerUnits='userSpaceOnUse'><path d='M0,0 L12,6 L0,12 z' fill='#d0342c'/></marker>
<marker id='ang' markerWidth='9' markerHeight='9' refX='7' refY='4.5' orient='auto' markerUnits='userSpaceOnUse'><path d='M0,0 L9,4.5 L0,9 z' fill='#2a9d4a'/></marker>
<marker id='rot' markerWidth='9' markerHeight='9' refX='7' refY='4.5' orient='auto' markerUnits='userSpaceOnUse'><path d='M0,0 L9,4.5 L0,9 z' fill='#d0342c' opacity='0.6'/></marker>
</defs>
<rect width='990' height='350' fill='white'/>
<line x1='330' y1='30' x2='330' y2='320' stroke='#ddd' stroke-width='1'/>
<line x1='660' y1='30' x2='660' y2='320' stroke='#ddd' stroke-width='1'/>
<text x='28.0' y='42.0' font-size='26' fill='#444' text-anchor='middle' font-weight='bold' font-family='Segoe UI, Helvetica, Arial, sans-serif'></text>
<circle cx='150' cy='195' r='80' fill='#eef2f7' stroke='#9aa7b5' stroke-width='1.5'/>
<line x1='150.0' y1='195.0' x2='290.0' y2='195.0' stroke='#222' stroke-width='2' stroke-linecap='round' marker-end='url(#axis)'/>
<line x1='150.0' y1='195.0' x2='150.0' y2='55.0' stroke='#222' stroke-width='2' stroke-linecap='round' marker-end='url(#axis)'/>
<text x='296.0' y='201.0' font-size='19' fill='#222' text-anchor='start' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>X</text>
<text x='146.0' y='49.0' font-size='19' fill='#222' text-anchor='end' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>Y</text>
<line x1='150.0' y1='195.0' x2='70.0' y2='195.0' stroke='#9fbde6' stroke-width='5' stroke-linecap='round'/>
<line x1='150.0' y1='195.0' x2='230.0' y2='195.0' stroke='#1f5fbf' stroke-width='6' stroke-linecap='round'/>
<line x1='227.8' y1='195.0' x2='227.8' y2='117.2' stroke='#d0342c' stroke-width='1.5' stroke-linecap='round' stroke-dasharray='4 4' opacity='0.6'/>
<line x1='150.0' y1='117.2' x2='227.8' y2='117.2' stroke='#d0342c' stroke-width='1.5' stroke-linecap='round' stroke-dasharray='4 4' opacity='0.6'/>
<line x1='150.0' y1='195.0' x2='227.8' y2='117.2' stroke='#d0342c' stroke-width='3.5' stroke-linecap='round' marker-end='url(#mom)'/>
<text x='222.3' y='91.8' font-size='20' fill='#d0342c' text-anchor='middle' font-weight='bold' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>M</text>
<line x1='227.8' y1='202.0' x2='227.8' y2='188.0' stroke='#d0342c' stroke-width='2.5' stroke-linecap='round'/>
<text x='227.8' y='209.0' font-size='17' fill='#d0342c' text-anchor='middle' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>M<tspan font-size='13' dy='4'>x</tspan></text>
<text x='166.0' y='229.0' font-size='17' fill='#2a9d4a' text-anchor='start' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>θ = 0</text>
<text x='165.0' y='328.0' font-size='19' fill='#333' text-anchor='middle' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>M<tspan font-size='13' dy='4'>x</tspan><tspan dy='-4'> = |M| / √2</tspan></text>
<text x='358.0' y='42.0' font-size='26' fill='#444' text-anchor='middle' font-weight='bold' font-family='Segoe UI, Helvetica, Arial, sans-serif'></text>
<circle cx='480' cy='195' r='80' fill='#eef2f7' stroke='#9aa7b5' stroke-width='1.5'/>
<line x1='480.0' y1='195.0' x2='620.0' y2='195.0' stroke='#222' stroke-width='2' stroke-linecap='round' marker-end='url(#axis)'/>
<line x1='480.0' y1='195.0' x2='480.0' y2='55.0' stroke='#222' stroke-width='2' stroke-linecap='round' marker-end='url(#axis)'/>
<text x='626.0' y='201.0' font-size='19' fill='#222' text-anchor='start' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>X</text>
<text x='476.0' y='49.0' font-size='19' fill='#222' text-anchor='end' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>Y</text>
<line x1='480.0' y1='195.0' x2='423.4' y2='138.4' stroke='#9fbde6' stroke-width='5' stroke-linecap='round'/>
<line x1='480.0' y1='195.0' x2='536.6' y2='251.6' stroke='#1f5fbf' stroke-width='6' stroke-linecap='round'/>
<line x1='480.0' y1='195.0' x2='557.8' y2='117.2' stroke='#d0342c' stroke-width='2.5' stroke-linecap='round' stroke-dasharray='6 4' opacity='0.6'/>
<path d='M 561.7 121.4 A 110 110 0 0 1 588.0 174.0' fill='none' stroke='#d0342c' stroke-width='1.5' marker-end='url(#rot)' stroke-dasharray='3 4'/>
<line x1='557.8' y1='195.0' x2='557.8' y2='117.2' stroke='#d0342c' stroke-width='1.2' stroke-linecap='round' stroke-dasharray='4 4' opacity='0.35'/>
<line x1='590.0' y1='195.0' x2='590.0' y2='195.0' stroke='#d0342c' stroke-width='1.5' stroke-linecap='round' stroke-dasharray='4 4' opacity='0.6'/>
<line x1='480.0' y1='195.0' x2='590.0' y2='195.0' stroke='#d0342c' stroke-width='1.5' stroke-linecap='round' stroke-dasharray='4 4' opacity='0.6'/>
<line x1='480.0' y1='195.0' x2='590.0' y2='195.0' stroke='#d0342c' stroke-width='3.5' stroke-linecap='round' marker-end='url(#mom)'/>
<text x='540.5' y='179.0' font-size='20' fill='#d0342c' text-anchor='middle' font-weight='bold' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>M</text>
<line x1='590.0' y1='202.0' x2='590.0' y2='188.0' stroke='#d0342c' stroke-width='2.5' stroke-linecap='round'/>
<text x='590.0' y='209.0' font-size='17' fill='#d0342c' text-anchor='middle' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>M<tspan font-size='13' dy='4'>x</tspan><tspan dy='-4'></tspan></text>
<line x1='557.8' y1='201.0' x2='557.8' y2='189.0' stroke='#d0342c' stroke-width='1.5' stroke-linecap='round' opacity='0.45'/>
<text x='557.8' y='209.0' font-size='16' fill='#d0342c' text-anchor='middle' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic' opacity='0.6'>M<tspan font-size='13' dy='4'>x</tspan></text>
<path d='M 532.0 195.0 A 52 52 0 0 1 516.8 231.8' fill='none' stroke='#2a9d4a' stroke-width='2' marker-end='url(#ang)'/>
<text x='540.9' y='241.4' font-size='17' fill='#2a9d4a' text-anchor='start' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>θ = 45°</text>
<text x='495.0' y='328.0' font-size='19' fill='#333' text-anchor='middle' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>M<tspan font-size='13' dy='4'>x</tspan><tspan dy='-4'> = |M|</tspan></text>
<text x='688.0' y='42.0' font-size='26' fill='#444' text-anchor='middle' font-weight='bold' font-family='Segoe UI, Helvetica, Arial, sans-serif'></text>
<circle cx='810' cy='195' r='80' fill='#eef2f7' stroke='#9aa7b5' stroke-width='1.5'/>
<line x1='810.0' y1='195.0' x2='950.0' y2='195.0' stroke='#222' stroke-width='2' stroke-linecap='round' marker-end='url(#axis)'/>
<line x1='810.0' y1='195.0' x2='810.0' y2='55.0' stroke='#222' stroke-width='2' stroke-linecap='round' marker-end='url(#axis)'/>
<text x='956.0' y='201.0' font-size='19' fill='#222' text-anchor='start' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>X</text>
<text x='806.0' y='49.0' font-size='19' fill='#222' text-anchor='end' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>Y</text>
<line x1='810.0' y1='195.0' x2='753.4' y2='251.6' stroke='#9fbde6' stroke-width='5' stroke-linecap='round'/>
<line x1='810.0' y1='195.0' x2='866.6' y2='138.4' stroke='#1f5fbf' stroke-width='6' stroke-linecap='round'/>
<line x1='810.0' y1='195.0' x2='887.8' y2='117.2' stroke='#d0342c' stroke-width='2.5' stroke-linecap='round' stroke-dasharray='6 4' opacity='0.6'/>
<path d='M 883.6 113.3 A 110 110 0 0 0 831.0 87.0' fill='none' stroke='#d0342c' stroke-width='1.5' marker-end='url(#rot)' stroke-dasharray='3 4'/>
<line x1='810.0' y1='195.0' x2='810.0' y2='85.0' stroke='#d0342c' stroke-width='1.5' stroke-linecap='round' stroke-dasharray='4 4' opacity='0.6'/>
<line x1='810.0' y1='85.0' x2='810.0' y2='85.0' stroke='#d0342c' stroke-width='1.5' stroke-linecap='round' stroke-dasharray='4 4' opacity='0.6'/>
<line x1='810.0' y1='195.0' x2='810.0' y2='85.0' stroke='#d0342c' stroke-width='3.5' stroke-linecap='round' marker-end='url(#mom)'/>
<text x='788.1' y='70.9' font-size='20' fill='#d0342c' text-anchor='middle' font-weight='bold' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>M</text>
<line x1='887.8' y1='201.0' x2='887.8' y2='189.0' stroke='#d0342c' stroke-width='1.5' stroke-linecap='round' opacity='0.45'/>
<text x='887.8' y='209.0' font-size='16' fill='#d0342c' text-anchor='middle' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic' opacity='0.6'>M<tspan font-size='13' dy='4'>x</tspan></text>
<path d='M 862.0 195.0 A 52 52 0 0 0 846.8 158.2' fill='none' stroke='#2a9d4a' stroke-width='2' marker-end='url(#ang)'/>
<text x='870.2' y='178.5' font-size='17' fill='#2a9d4a' text-anchor='start' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>θ = 45°</text>
<text x='825.0' y='328.0' font-size='19' fill='#333' text-anchor='middle' font-weight='normal' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-style='italic'>M<tspan font-size='13' dy='4'>x</tspan><tspan dy='-4'> = 0</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 9.5 KiB

@@ -104,10 +104,10 @@
<li>The impact of coordinate system misalignment is relatively smaller compared to the moment arm setting</li> <li>The impact of coordinate system misalignment is relatively smaller compared to the moment arm setting</li>
</ul> </ul>
</li> </li>
<li><p><strong>Installation Angle Adjustment</strong></p> <li><p><strong>Setup Angle Adjustment</strong></p>
<ul> <ul>
<li>If perfect alignment is not possible, measure the offset angle</li> <li>If perfect alignment is not possible, measure the offset angle</li>
<li>Enter the measured angle in the &ldquo;Installation Angle&rdquo; field</li> <li>Enter the measured angle in the cutter's <strong>Setup Angle</strong> field (Tool House → Cutter → Flute Contours)</li>
<li>The maximum possible deviation is 45 degrees</li> <li>The maximum possible deviation is 45 degrees</li>
</ul> </ul>
</li> </li>
@@ -115,15 +115,24 @@
<h2 id="factors-affecting-accuracy">Factors Affecting Accuracy</h2> <h2 id="factors-affecting-accuracy">Factors Affecting Accuracy</h2>
<h3 id="coordinate-transformation-effects">Coordinate Transformation Effects</h3> <h3 id="coordinate-transformation-effects">Coordinate Transformation Effects</h3>
<ul> <ul>
<li>An installation angle deviation can cause up to a √2 factor difference in values</li> <li>A setup angle offset rotates the measured (Mx, My) pair. The resultant |M| does not change, but a single channel can read anything from 0 to |M| — the same 45° offset takes Mx to √2 times its aligned value one way and to zero the other way</li>
<li>This difference is inherently a result of coordinate transformation, not a measurement accuracy issue</li> <li>This difference is inherently a result of coordinate transformation, not a measurement accuracy issue</li>
<li>Even with the same smart tool holder, different installation angles will produce different measurement data</li> <li>Even with the same smart tool holder, different setup angles will produce different measurement data</li>
</ul> </ul>
<p><img src="smart-tool-holder-img/setup-angle-rotation.svg" alt="Three top-view sketches of a two-flute cutter section: on the left the cutting edge lies on the sensor X axis and the moment vector M sits at 45°; in the middle the edge is turned 45° one way, M turns with it onto the X axis and Mx becomes the whole of |M|; on the right the edge is turned 45° the other way, M lands on the Y axis and Mx becomes zero">
<em>① — the cutting edge (blue) lies on the sensor X axis, θ = 0; in this example the transverse
moment M the cut produces sits at 45°, so Mx = My = |M|/√2. ② — the same cutter mounted with its
edge 45° clockwise of the X axis. Nothing about the cut has changed, so M is carried round with
the edge and lands on the X axis: Mx = |M|, √2 times the value in ①, and My = 0. ③ — the same
45° the other way puts M on the Y axis, and Mx = 0. In general Mx = |M| · cos(angle between M
and the sensor X axis): the resultant never changes, and one channel on its own can read anything
between 0 and |M| — a coordinate effect, not a measurement error. Entering θ as the cutter's
Setup Angle lets the simulation report in the sensor's own frame.</em></p>
<h3 id="best-practices">Best Practices</h3> <h3 id="best-practices">Best Practices</h3>
<ol> <ol>
<li>Prioritize accurate moment arm height configuration</li> <li>Prioritize accurate moment arm height configuration</li>
<li>Align the cutting edge with the sensor X-axis as closely as possible</li> <li>Align the cutting edge with the sensor X-axis as closely as possible</li>
<li>If perfect alignment is not achievable, always measure and set the correct installation angle</li> <li>If perfect alignment is not achievable, always measure and set the correct setup angle</li>
</ol> </ol>
<p>Only with these parameters correctly configured will the simulated micro-waveforms match the actual sensor measurements.</p> <p>Only with these parameters correctly configured will the simulated micro-waveforms match the actual sensor measurements.</p>
<h2 id="see-also">See Also</h2> <h2 id="see-also">See Also</h2>
@@ -101,7 +101,7 @@
</ul> </ul>
<p>For a known cutter, configure the matching material file under <code>Resource/CutterMaterial/</code> rather than guessing the grade.</p> <p>For a known cutter, configure the matching material file under <code>Resource/CutterMaterial/</code> rather than guessing the grade.</p>
<h2 id="before-reaching-for-the-cutter">Before Reaching for the Cutter</h2> <h2 id="before-reaching-for-the-cutter">Before Reaching for the Cutter</h2>
<p>The cutter-side levers below are for when the cutting parameters have already been tried, because <p>The cutter-side levers above are for when the cutting parameters have already been tried, because
the parameters are cheaper to change. In order:</p> the parameters are cheaper to change. In order:</p>
<ol> <ol>
<li><strong>Reduce feed per tooth.</strong> The most direct route to lower force, and the one the optimizer <li><strong>Reduce feed per tooth.</strong> The most direct route to lower force, and the one the optimizer
+407
View File
@@ -20225,6 +20225,19 @@ references:
isSpec: "True" isSpec: "True"
fullName: Hi.Disp.DispEngine.IsDisposed fullName: Hi.Disp.DispEngine.IsDisposed
nameWithType: DispEngine.IsDisposed nameWithType: DispEngine.IsDisposed
- uid: Hi.Disp.DispEngine.IsGlAvailable
name: IsGlAvailable
href: api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_IsGlAvailable
commentId: P:Hi.Disp.DispEngine.IsGlAvailable
fullName: Hi.Disp.DispEngine.IsGlAvailable
nameWithType: DispEngine.IsGlAvailable
- uid: Hi.Disp.DispEngine.IsGlAvailable*
name: IsGlAvailable
href: api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_IsGlAvailable_
commentId: Overload:Hi.Disp.DispEngine.IsGlAvailable
isSpec: "True"
fullName: Hi.Disp.DispEngine.IsGlAvailable
nameWithType: DispEngine.IsGlAvailable
- uid: Hi.Disp.DispEngine.IsKeyPressed(System.String) - uid: Hi.Disp.DispEngine.IsKeyPressed(System.String)
name: IsKeyPressed(string) name: IsKeyPressed(string)
href: api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_IsKeyPressed_System_String_ href: api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_IsKeyPressed_System_String_
@@ -73415,6 +73428,19 @@ references:
isSpec: "True" isSpec: "True"
fullName: Hi.MachiningProcs.MachiningActRunner.ProcAct fullName: Hi.MachiningProcs.MachiningActRunner.ProcAct
nameWithType: MachiningActRunner.ProcAct nameWithType: MachiningActRunner.ProcAct
- uid: Hi.MachiningProcs.MachiningActRunner.RapidCutMonitor
name: RapidCutMonitor
href: api/Hi.MachiningProcs.MachiningActRunner.html#Hi_MachiningProcs_MachiningActRunner_RapidCutMonitor
commentId: P:Hi.MachiningProcs.MachiningActRunner.RapidCutMonitor
fullName: Hi.MachiningProcs.MachiningActRunner.RapidCutMonitor
nameWithType: MachiningActRunner.RapidCutMonitor
- uid: Hi.MachiningProcs.MachiningActRunner.RapidCutMonitor*
name: RapidCutMonitor
href: api/Hi.MachiningProcs.MachiningActRunner.html#Hi_MachiningProcs_MachiningActRunner_RapidCutMonitor_
commentId: Overload:Hi.MachiningProcs.MachiningActRunner.RapidCutMonitor
isSpec: "True"
fullName: Hi.MachiningProcs.MachiningActRunner.RapidCutMonitor
nameWithType: MachiningActRunner.RapidCutMonitor
- uid: Hi.MachiningProcs.MachiningActRunner.ResetMillingStepLuggageDb(Hi.MachiningProcs.StepDiagnosticProgress,System.IProgress{Hi.Common.Messages.IMessage}) - uid: Hi.MachiningProcs.MachiningActRunner.ResetMillingStepLuggageDb(Hi.MachiningProcs.StepDiagnosticProgress,System.IProgress{Hi.Common.Messages.IMessage})
name: ResetMillingStepLuggageDb(StepDiagnosticProgress, IProgress<IMessage>) name: ResetMillingStepLuggageDb(StepDiagnosticProgress, IProgress<IMessage>)
href: api/Hi.MachiningProcs.MachiningActRunner.html#Hi_MachiningProcs_MachiningActRunner_ResetMillingStepLuggageDb_Hi_MachiningProcs_StepDiagnosticProgress_System_IProgress_Hi_Common_Messages_IMessage__ href: api/Hi.MachiningProcs.MachiningActRunner.html#Hi_MachiningProcs_MachiningActRunner_ResetMillingStepLuggageDb_Hi_MachiningProcs_StepDiagnosticProgress_System_IProgress_Hi_Common_Messages_IMessage__
@@ -73772,6 +73798,19 @@ references:
isSpec: "True" isSpec: "True"
fullName: Hi.MachiningProcs.MachiningActRunnerConfig.RadiusOffsetBasis fullName: Hi.MachiningProcs.MachiningActRunnerConfig.RadiusOffsetBasis
nameWithType: MachiningActRunnerConfig.RadiusOffsetBasis nameWithType: MachiningActRunnerConfig.RadiusOffsetBasis
- uid: Hi.MachiningProcs.MachiningActRunnerConfig.RapidCutVolumeThreshold_mm3
name: RapidCutVolumeThreshold_mm3
href: api/Hi.MachiningProcs.MachiningActRunnerConfig.html#Hi_MachiningProcs_MachiningActRunnerConfig_RapidCutVolumeThreshold_mm3
commentId: P:Hi.MachiningProcs.MachiningActRunnerConfig.RapidCutVolumeThreshold_mm3
fullName: Hi.MachiningProcs.MachiningActRunnerConfig.RapidCutVolumeThreshold_mm3
nameWithType: MachiningActRunnerConfig.RapidCutVolumeThreshold_mm3
- uid: Hi.MachiningProcs.MachiningActRunnerConfig.RapidCutVolumeThreshold_mm3*
name: RapidCutVolumeThreshold_mm3
href: api/Hi.MachiningProcs.MachiningActRunnerConfig.html#Hi_MachiningProcs_MachiningActRunnerConfig_RapidCutVolumeThreshold_mm3_
commentId: Overload:Hi.MachiningProcs.MachiningActRunnerConfig.RapidCutVolumeThreshold_mm3
isSpec: "True"
fullName: Hi.MachiningProcs.MachiningActRunnerConfig.RapidCutVolumeThreshold_mm3
nameWithType: MachiningActRunnerConfig.RapidCutVolumeThreshold_mm3
- uid: Hi.MachiningProcs.MachiningActRunnerConfig.Reg(Hi.Common.XmlUtils.XFactory) - uid: Hi.MachiningProcs.MachiningActRunnerConfig.Reg(Hi.Common.XmlUtils.XFactory)
name: Reg(XFactory) name: Reg(XFactory)
href: api/Hi.MachiningProcs.MachiningActRunnerConfig.html#Hi_MachiningProcs_MachiningActRunnerConfig_Reg_Hi_Common_XmlUtils_XFactory_ href: api/Hi.MachiningProcs.MachiningActRunnerConfig.html#Hi_MachiningProcs_MachiningActRunnerConfig_Reg_Hi_Common_XmlUtils_XFactory_
@@ -75604,6 +75643,218 @@ references:
isSpec: "True" isSpec: "True"
fullName: Hi.MachiningProcs.ProxyProjectService.SaveProject fullName: Hi.MachiningProcs.ProxyProjectService.SaveProject
nameWithType: ProxyProjectService.SaveProject nameWithType: ProxyProjectService.SaveProject
- uid: Hi.MachiningProcs.RapidCutMonitor
name: RapidCutMonitor
href: api/Hi.MachiningProcs.RapidCutMonitor.html
commentId: T:Hi.MachiningProcs.RapidCutMonitor
fullName: Hi.MachiningProcs.RapidCutMonitor
nameWithType: RapidCutMonitor
- uid: Hi.MachiningProcs.RapidCutMonitor.Flush(System.Double,System.IProgress{Hi.MachiningProcs.StepDiagnostic})
name: Flush(double, IProgress<StepDiagnostic>)
href: api/Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Flush_System_Double_System_IProgress_Hi_MachiningProcs_StepDiagnostic__
commentId: M:Hi.MachiningProcs.RapidCutMonitor.Flush(System.Double,System.IProgress{Hi.MachiningProcs.StepDiagnostic})
name.vb: Flush(Double, IProgress(Of StepDiagnostic))
fullName: Hi.MachiningProcs.RapidCutMonitor.Flush(double, System.IProgress<Hi.MachiningProcs.StepDiagnostic>)
fullName.vb: Hi.MachiningProcs.RapidCutMonitor.Flush(Double, System.IProgress(Of Hi.MachiningProcs.StepDiagnostic))
nameWithType: RapidCutMonitor.Flush(double, IProgress<StepDiagnostic>)
nameWithType.vb: RapidCutMonitor.Flush(Double, IProgress(Of StepDiagnostic))
- uid: Hi.MachiningProcs.RapidCutMonitor.Flush*
name: Flush
href: api/Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Flush_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.Flush
isSpec: "True"
fullName: Hi.MachiningProcs.RapidCutMonitor.Flush
nameWithType: RapidCutMonitor.Flush
- uid: Hi.MachiningProcs.RapidCutMonitor.MessageId
name: MessageId
href: api/Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_MessageId
commentId: F:Hi.MachiningProcs.RapidCutMonitor.MessageId
fullName: Hi.MachiningProcs.RapidCutMonitor.MessageId
nameWithType: RapidCutMonitor.MessageId
- uid: Hi.MachiningProcs.RapidCutMonitor.Observe(Hi.MachiningProcs.RapidCutMonitor.Sample@,System.Double,System.Boolean,System.IProgress{Hi.MachiningProcs.StepDiagnostic})
name: Observe(in Sample, double, bool, IProgress<StepDiagnostic>)
href: api/Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Observe_Hi_MachiningProcs_RapidCutMonitor_Sample__System_Double_System_Boolean_System_IProgress_Hi_MachiningProcs_StepDiagnostic__
commentId: M:Hi.MachiningProcs.RapidCutMonitor.Observe(Hi.MachiningProcs.RapidCutMonitor.Sample@,System.Double,System.Boolean,System.IProgress{Hi.MachiningProcs.StepDiagnostic})
name.vb: Observe(Sample, Double, Boolean, IProgress(Of StepDiagnostic))
fullName: Hi.MachiningProcs.RapidCutMonitor.Observe(in Hi.MachiningProcs.RapidCutMonitor.Sample, double, bool, System.IProgress<Hi.MachiningProcs.StepDiagnostic>)
fullName.vb: Hi.MachiningProcs.RapidCutMonitor.Observe(Hi.MachiningProcs.RapidCutMonitor.Sample, Double, Boolean, System.IProgress(Of Hi.MachiningProcs.StepDiagnostic))
nameWithType: RapidCutMonitor.Observe(in RapidCutMonitor.Sample, double, bool, IProgress<StepDiagnostic>)
nameWithType.vb: RapidCutMonitor.Observe(RapidCutMonitor.Sample, Double, Boolean, IProgress(Of StepDiagnostic))
- uid: Hi.MachiningProcs.RapidCutMonitor.Observe*
name: Observe
href: api/Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Observe_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.Observe
isSpec: "True"
fullName: Hi.MachiningProcs.RapidCutMonitor.Observe
nameWithType: RapidCutMonitor.Observe
- uid: Hi.MachiningProcs.RapidCutMonitor.Reset
name: Reset()
href: api/Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Reset
commentId: M:Hi.MachiningProcs.RapidCutMonitor.Reset
fullName: Hi.MachiningProcs.RapidCutMonitor.Reset()
nameWithType: RapidCutMonitor.Reset()
- uid: Hi.MachiningProcs.RapidCutMonitor.Reset*
name: Reset
href: api/Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_Reset_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.Reset
isSpec: "True"
fullName: Hi.MachiningProcs.RapidCutMonitor.Reset
nameWithType: RapidCutMonitor.Reset
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample
name: RapidCutMonitor.Sample
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html
commentId: T:Hi.MachiningProcs.RapidCutMonitor.Sample
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample
nameWithType: RapidCutMonitor.Sample
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.#ctor(System.Int32,System.Nullable{System.Int32},System.Object,Hi.NcParsers.ISentenceCarrier,System.Boolean,System.Boolean,System.Boolean,System.Double,System.Double)
name: Sample(int, int?, object, ISentenceCarrier, bool, bool, bool, double, double)
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample__ctor_System_Int32_System_Nullable_System_Int32__System_Object_Hi_NcParsers_ISentenceCarrier_System_Boolean_System_Boolean_System_Boolean_System_Double_System_Double_
commentId: M:Hi.MachiningProcs.RapidCutMonitor.Sample.#ctor(System.Int32,System.Nullable{System.Int32},System.Object,Hi.NcParsers.ISentenceCarrier,System.Boolean,System.Boolean,System.Boolean,System.Double,System.Double)
name.vb: New(Integer, Integer?, Object, ISentenceCarrier, Boolean, Boolean, Boolean, Double, Double)
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.Sample(int, int?, object, Hi.NcParsers.ISentenceCarrier, bool, bool, bool, double, double)
fullName.vb: Hi.MachiningProcs.RapidCutMonitor.Sample.New(Integer, Integer?, Object, Hi.NcParsers.ISentenceCarrier, Boolean, Boolean, Boolean, Double, Double)
nameWithType: RapidCutMonitor.Sample.Sample(int, int?, object, ISentenceCarrier, bool, bool, bool, double, double)
nameWithType.vb: RapidCutMonitor.Sample.New(Integer, Integer?, Object, ISentenceCarrier, Boolean, Boolean, Boolean, Double, Double)
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.#ctor*
name: Sample
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample__ctor_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.Sample.#ctor
isSpec: "True"
name.vb: New
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.Sample
fullName.vb: Hi.MachiningProcs.RapidCutMonitor.Sample.New
nameWithType: RapidCutMonitor.Sample.Sample
nameWithType.vb: RapidCutMonitor.Sample.New
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.Carrier
name: Carrier
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_Carrier
commentId: P:Hi.MachiningProcs.RapidCutMonitor.Sample.Carrier
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.Carrier
nameWithType: RapidCutMonitor.Sample.Carrier
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.Carrier*
name: Carrier
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_Carrier_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.Sample.Carrier
isSpec: "True"
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.Carrier
nameWithType: RapidCutMonitor.Sample.Carrier
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.CuttingDepth_mm
name: CuttingDepth_mm
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_CuttingDepth_mm
commentId: P:Hi.MachiningProcs.RapidCutMonitor.Sample.CuttingDepth_mm
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.CuttingDepth_mm
nameWithType: RapidCutMonitor.Sample.CuttingDepth_mm
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.CuttingDepth_mm*
name: CuttingDepth_mm
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_CuttingDepth_mm_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.Sample.CuttingDepth_mm
isSpec: "True"
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.CuttingDepth_mm
nameWithType: RapidCutMonitor.Sample.CuttingDepth_mm
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.IsRapid
name: IsRapid
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_IsRapid
commentId: P:Hi.MachiningProcs.RapidCutMonitor.Sample.IsRapid
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.IsRapid
nameWithType: RapidCutMonitor.Sample.IsRapid
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.IsRapid*
name: IsRapid
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_IsRapid_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.Sample.IsRapid
isSpec: "True"
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.IsRapid
nameWithType: RapidCutMonitor.Sample.IsRapid
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.IsSpindleStopped
name: IsSpindleStopped
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_IsSpindleStopped
commentId: P:Hi.MachiningProcs.RapidCutMonitor.Sample.IsSpindleStopped
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.IsSpindleStopped
nameWithType: RapidCutMonitor.Sample.IsSpindleStopped
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.IsSpindleStopped*
name: IsSpindleStopped
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_IsSpindleStopped_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.Sample.IsSpindleStopped
isSpec: "True"
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.IsSpindleStopped
nameWithType: RapidCutMonitor.Sample.IsSpindleStopped
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.IsTouched
name: IsTouched
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_IsTouched
commentId: P:Hi.MachiningProcs.RapidCutMonitor.Sample.IsTouched
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.IsTouched
nameWithType: RapidCutMonitor.Sample.IsTouched
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.IsTouched*
name: IsTouched
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_IsTouched_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.Sample.IsTouched
isSpec: "True"
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.IsTouched
nameWithType: RapidCutMonitor.Sample.IsTouched
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.LineKey
name: LineKey
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_LineKey
commentId: P:Hi.MachiningProcs.RapidCutMonitor.Sample.LineKey
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.LineKey
nameWithType: RapidCutMonitor.Sample.LineKey
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.LineKey*
name: LineKey
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_LineKey_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.Sample.LineKey
isSpec: "True"
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.LineKey
nameWithType: RapidCutMonitor.Sample.LineKey
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.LineNo
name: LineNo
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_LineNo
commentId: P:Hi.MachiningProcs.RapidCutMonitor.Sample.LineNo
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.LineNo
nameWithType: RapidCutMonitor.Sample.LineNo
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.LineNo*
name: LineNo
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_LineNo_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.Sample.LineNo
isSpec: "True"
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.LineNo
nameWithType: RapidCutMonitor.Sample.LineNo
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.RemovedVolume_mm3
name: RemovedVolume_mm3
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_RemovedVolume_mm3
commentId: P:Hi.MachiningProcs.RapidCutMonitor.Sample.RemovedVolume_mm3
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.RemovedVolume_mm3
nameWithType: RapidCutMonitor.Sample.RemovedVolume_mm3
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.RemovedVolume_mm3*
name: RemovedVolume_mm3
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_RemovedVolume_mm3_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.Sample.RemovedVolume_mm3
isSpec: "True"
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.RemovedVolume_mm3
nameWithType: RapidCutMonitor.Sample.RemovedVolume_mm3
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.StepIndex
name: StepIndex
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_StepIndex
commentId: P:Hi.MachiningProcs.RapidCutMonitor.Sample.StepIndex
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.StepIndex
nameWithType: RapidCutMonitor.Sample.StepIndex
- uid: Hi.MachiningProcs.RapidCutMonitor.Sample.StepIndex*
name: StepIndex
href: api/Hi.MachiningProcs.RapidCutMonitor.Sample.html#Hi_MachiningProcs_RapidCutMonitor_Sample_StepIndex_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.Sample.StepIndex
isSpec: "True"
fullName: Hi.MachiningProcs.RapidCutMonitor.Sample.StepIndex
nameWithType: RapidCutMonitor.Sample.StepIndex
- uid: Hi.MachiningProcs.RapidCutMonitor.SampleOf(Hi.MachiningSteps.MachiningStep)
name: SampleOf(MachiningStep)
href: api/Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_SampleOf_Hi_MachiningSteps_MachiningStep_
commentId: M:Hi.MachiningProcs.RapidCutMonitor.SampleOf(Hi.MachiningSteps.MachiningStep)
fullName: Hi.MachiningProcs.RapidCutMonitor.SampleOf(Hi.MachiningSteps.MachiningStep)
nameWithType: RapidCutMonitor.SampleOf(MachiningStep)
- uid: Hi.MachiningProcs.RapidCutMonitor.SampleOf*
name: SampleOf
href: api/Hi.MachiningProcs.RapidCutMonitor.html#Hi_MachiningProcs_RapidCutMonitor_SampleOf_
commentId: Overload:Hi.MachiningProcs.RapidCutMonitor.SampleOf
isSpec: "True"
fullName: Hi.MachiningProcs.RapidCutMonitor.SampleOf
nameWithType: RapidCutMonitor.SampleOf
- uid: Hi.MachiningProcs.RenderingFlag - uid: Hi.MachiningProcs.RenderingFlag
name: RenderingFlag name: RenderingFlag
href: api/Hi.MachiningProcs.RenderingFlag.html href: api/Hi.MachiningProcs.RenderingFlag.html
@@ -80814,6 +81065,19 @@ references:
isSpec: "True" isSpec: "True"
fullName: Hi.MachiningSteps.MachineMotionStep.GetToothSeqOnToolRunningCoordinate fullName: Hi.MachiningSteps.MachineMotionStep.GetToothSeqOnToolRunningCoordinate
nameWithType: MachineMotionStep.GetToothSeqOnToolRunningCoordinate nameWithType: MachineMotionStep.GetToothSeqOnToolRunningCoordinate
- uid: Hi.MachiningSteps.MachineMotionStep.IsRapid
name: IsRapid
href: api/Hi.MachiningSteps.MachineMotionStep.html#Hi_MachiningSteps_MachineMotionStep_IsRapid
commentId: P:Hi.MachiningSteps.MachineMotionStep.IsRapid
fullName: Hi.MachiningSteps.MachineMotionStep.IsRapid
nameWithType: MachineMotionStep.IsRapid
- uid: Hi.MachiningSteps.MachineMotionStep.IsRapid*
name: IsRapid
href: api/Hi.MachiningSteps.MachineMotionStep.html#Hi_MachiningSteps_MachineMotionStep_IsRapid_
commentId: Overload:Hi.MachiningSteps.MachineMotionStep.IsRapid
isSpec: "True"
fullName: Hi.MachiningSteps.MachineMotionStep.IsRapid
nameWithType: MachineMotionStep.IsRapid
- uid: Hi.MachiningSteps.MachineMotionStep.McValues - uid: Hi.MachiningSteps.MachineMotionStep.McValues
name: McValues name: McValues
href: api/Hi.MachiningSteps.MachineMotionStep.html#Hi_MachiningSteps_MachineMotionStep_McValues href: api/Hi.MachiningSteps.MachineMotionStep.html#Hi_MachiningSteps_MachineMotionStep_McValues
@@ -119826,12 +120090,50 @@ references:
isSpec: "True" isSpec: "True"
fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.GetChainAxisNames fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.GetChainAxisNames
nameWithType: StrokeLimitUtil.GetChainAxisNames nameWithType: StrokeLimitUtil.GetChainAxisNames
- uid: Hi.NcParsers.Dependencys.StrokeLimitUtil.IsWithinRotaryTravel(System.Double,System.Nullable{System.Double},System.Nullable{System.Double})
name: IsWithinRotaryTravel(double, double?, double?)
href: api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html#Hi_NcParsers_Dependencys_StrokeLimitUtil_IsWithinRotaryTravel_System_Double_System_Nullable_System_Double__System_Nullable_System_Double__
commentId: M:Hi.NcParsers.Dependencys.StrokeLimitUtil.IsWithinRotaryTravel(System.Double,System.Nullable{System.Double},System.Nullable{System.Double})
name.vb: IsWithinRotaryTravel(Double, Double?, Double?)
fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.IsWithinRotaryTravel(double, double?, double?)
fullName.vb: Hi.NcParsers.Dependencys.StrokeLimitUtil.IsWithinRotaryTravel(Double, Double?, Double?)
nameWithType: StrokeLimitUtil.IsWithinRotaryTravel(double, double?, double?)
nameWithType.vb: StrokeLimitUtil.IsWithinRotaryTravel(Double, Double?, Double?)
- uid: Hi.NcParsers.Dependencys.StrokeLimitUtil.IsWithinRotaryTravel*
name: IsWithinRotaryTravel
href: api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html#Hi_NcParsers_Dependencys_StrokeLimitUtil_IsWithinRotaryTravel_
commentId: Overload:Hi.NcParsers.Dependencys.StrokeLimitUtil.IsWithinRotaryTravel
isSpec: "True"
fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.IsWithinRotaryTravel
nameWithType: StrokeLimitUtil.IsWithinRotaryTravel
- uid: Hi.NcParsers.Dependencys.StrokeLimitUtil.McAxisNames - uid: Hi.NcParsers.Dependencys.StrokeLimitUtil.McAxisNames
name: McAxisNames name: McAxisNames
href: api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html#Hi_NcParsers_Dependencys_StrokeLimitUtil_McAxisNames href: api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html#Hi_NcParsers_Dependencys_StrokeLimitUtil_McAxisNames
commentId: F:Hi.NcParsers.Dependencys.StrokeLimitUtil.McAxisNames commentId: F:Hi.NcParsers.Dependencys.StrokeLimitUtil.McAxisNames
fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.McAxisNames fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.McAxisNames
nameWithType: StrokeLimitUtil.McAxisNames nameWithType: StrokeLimitUtil.McAxisNames
- uid: Hi.NcParsers.Dependencys.StrokeLimitUtil.RotaryAdmissibility(System.Collections.Generic.IEnumerable{Hi.NcParsers.Dependencys.INcDependency})
name: RotaryAdmissibility(IEnumerable<INcDependency>)
href: api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html#Hi_NcParsers_Dependencys_StrokeLimitUtil_RotaryAdmissibility_System_Collections_Generic_IEnumerable_Hi_NcParsers_Dependencys_INcDependency__
commentId: M:Hi.NcParsers.Dependencys.StrokeLimitUtil.RotaryAdmissibility(System.Collections.Generic.IEnumerable{Hi.NcParsers.Dependencys.INcDependency})
name.vb: RotaryAdmissibility(IEnumerable(Of INcDependency))
fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.RotaryAdmissibility(System.Collections.Generic.IEnumerable<Hi.NcParsers.Dependencys.INcDependency>)
fullName.vb: Hi.NcParsers.Dependencys.StrokeLimitUtil.RotaryAdmissibility(System.Collections.Generic.IEnumerable(Of Hi.NcParsers.Dependencys.INcDependency))
nameWithType: StrokeLimitUtil.RotaryAdmissibility(IEnumerable<INcDependency>)
nameWithType.vb: StrokeLimitUtil.RotaryAdmissibility(IEnumerable(Of INcDependency))
- uid: Hi.NcParsers.Dependencys.StrokeLimitUtil.RotaryAdmissibility*
name: RotaryAdmissibility
href: api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html#Hi_NcParsers_Dependencys_StrokeLimitUtil_RotaryAdmissibility_
commentId: Overload:Hi.NcParsers.Dependencys.StrokeLimitUtil.RotaryAdmissibility
isSpec: "True"
fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.RotaryAdmissibility
nameWithType: StrokeLimitUtil.RotaryAdmissibility
- uid: Hi.NcParsers.Dependencys.StrokeLimitUtil.Tolerance
name: Tolerance
href: api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html#Hi_NcParsers_Dependencys_StrokeLimitUtil_Tolerance
commentId: F:Hi.NcParsers.Dependencys.StrokeLimitUtil.Tolerance
fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.Tolerance
nameWithType: StrokeLimitUtil.Tolerance
- uid: Hi.NcParsers.Dependencys.Syntec - uid: Hi.NcParsers.Dependencys.Syntec
name: Hi.NcParsers.Dependencys.Syntec name: Hi.NcParsers.Dependencys.Syntec
href: api/Hi.NcParsers.Dependencys.Syntec.html href: api/Hi.NcParsers.Dependencys.Syntec.html
@@ -120818,6 +121120,15 @@ references:
fullName.vb: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Mat4d, Hi.Geom.Vec3d) fullName.vb: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Mat4d, Hi.Geom.Vec3d)
nameWithType: NcKinematicsDependency.OrientationToMcAbc(Mat4d, out Vec3d) nameWithType: NcKinematicsDependency.OrientationToMcAbc(Mat4d, out Vec3d)
nameWithType.vb: NcKinematicsDependency.OrientationToMcAbc(Mat4d, Vec3d) nameWithType.vb: NcKinematicsDependency.OrientationToMcAbc(Mat4d, Vec3d)
- uid: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Mat4d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)
name: OrientationToMcAbc(Mat4d, Func<Vec3d, bool>, out Vec3d)
href: api/Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.html#Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_Hi_Geom_Mat4d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__
commentId: M:Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Mat4d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)
name.vb: OrientationToMcAbc(Mat4d, Func(Of Vec3d, Boolean), Vec3d)
fullName: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Mat4d, System.Func<Hi.Geom.Vec3d, bool>, out Hi.Geom.Vec3d)
fullName.vb: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Mat4d, System.Func(Of Hi.Geom.Vec3d, Boolean), Hi.Geom.Vec3d)
nameWithType: NcKinematicsDependency.OrientationToMcAbc(Mat4d, Func<Vec3d, bool>, out Vec3d)
nameWithType.vb: NcKinematicsDependency.OrientationToMcAbc(Mat4d, Func(Of Vec3d, Boolean), Vec3d)
- uid: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Vec3d,Hi.Geom.Vec3d@) - uid: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Vec3d,Hi.Geom.Vec3d@)
name: OrientationToMcAbc(Vec3d, out Vec3d) name: OrientationToMcAbc(Vec3d, out Vec3d)
href: api/Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.html#Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__ href: api/Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.html#Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__
@@ -120827,6 +121138,15 @@ references:
fullName.vb: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Vec3d, Hi.Geom.Vec3d) fullName.vb: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Vec3d, Hi.Geom.Vec3d)
nameWithType: NcKinematicsDependency.OrientationToMcAbc(Vec3d, out Vec3d) nameWithType: NcKinematicsDependency.OrientationToMcAbc(Vec3d, out Vec3d)
nameWithType.vb: NcKinematicsDependency.OrientationToMcAbc(Vec3d, Vec3d) nameWithType.vb: NcKinematicsDependency.OrientationToMcAbc(Vec3d, Vec3d)
- uid: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Vec3d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)
name: OrientationToMcAbc(Vec3d, Func<Vec3d, bool>, out Vec3d)
href: api/Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.html#Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_Hi_Geom_Vec3d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__
commentId: M:Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Vec3d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)
name.vb: OrientationToMcAbc(Vec3d, Func(Of Vec3d, Boolean), Vec3d)
fullName: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Vec3d, System.Func<Hi.Geom.Vec3d, bool>, out Hi.Geom.Vec3d)
fullName.vb: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc(Hi.Geom.Vec3d, System.Func(Of Hi.Geom.Vec3d, Boolean), Hi.Geom.Vec3d)
nameWithType: NcKinematicsDependency.OrientationToMcAbc(Vec3d, Func<Vec3d, bool>, out Vec3d)
nameWithType.vb: NcKinematicsDependency.OrientationToMcAbc(Vec3d, Func(Of Vec3d, Boolean), Vec3d)
- uid: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc* - uid: Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.OrientationToMcAbc*
name: OrientationToMcAbc name: OrientationToMcAbc
href: api/Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.html#Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_ href: api/Hi.NcParsers.Dependencys.SystemWired.NcKinematicsDependency.html#Hi_NcParsers_Dependencys_SystemWired_NcKinematicsDependency_OrientationToMcAbc_
@@ -129936,6 +130256,12 @@ references:
isSpec: "True" isSpec: "True"
fullName: Hi.NcParsers.Keywords.IUnparsedTextDef.UnparsedText fullName: Hi.NcParsers.Keywords.IUnparsedTextDef.UnparsedText
nameWithType: IUnparsedTextDef.UnparsedText nameWithType: IUnparsedTextDef.UnparsedText
- uid: Hi.NcParsers.Keywords.IncrementalWords
name: IncrementalWords
href: api/Hi.NcParsers.Keywords.IncrementalWords.html
commentId: T:Hi.NcParsers.Keywords.IncrementalWords
fullName: Hi.NcParsers.Keywords.IncrementalWords
nameWithType: IncrementalWords
- uid: Hi.NcParsers.Keywords.IndexNote - uid: Hi.NcParsers.Keywords.IndexNote
name: IndexNote name: IndexNote
href: api/Hi.NcParsers.Keywords.IndexNote.html href: api/Hi.NcParsers.Keywords.IndexNote.html
@@ -139021,6 +139347,22 @@ references:
isSpec: "True" isSpec: "True"
fullName: Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.ConsumeAxis fullName: Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.ConsumeAxis
nameWithType: RotaryAxisUtil.ConsumeAxis nameWithType: RotaryAxisUtil.ConsumeAxis
- uid: Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.FindPreviousMcAxisDeg(Hi.Common.Collections.LazyLinkedListNode{Hi.NcParsers.Syntaxs.SyntaxPiece},System.String)
name: FindPreviousMcAxisDeg(LazyLinkedListNode<SyntaxPiece>, string)
href: api/Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.html#Hi_NcParsers_LogicSyntaxs_RotaryAxisUtil_FindPreviousMcAxisDeg_Hi_Common_Collections_LazyLinkedListNode_Hi_NcParsers_Syntaxs_SyntaxPiece__System_String_
commentId: M:Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.FindPreviousMcAxisDeg(Hi.Common.Collections.LazyLinkedListNode{Hi.NcParsers.Syntaxs.SyntaxPiece},System.String)
name.vb: FindPreviousMcAxisDeg(LazyLinkedListNode(Of SyntaxPiece), String)
fullName: Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.FindPreviousMcAxisDeg(Hi.Common.Collections.LazyLinkedListNode<Hi.NcParsers.Syntaxs.SyntaxPiece>, string)
fullName.vb: Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.FindPreviousMcAxisDeg(Hi.Common.Collections.LazyLinkedListNode(Of Hi.NcParsers.Syntaxs.SyntaxPiece), String)
nameWithType: RotaryAxisUtil.FindPreviousMcAxisDeg(LazyLinkedListNode<SyntaxPiece>, string)
nameWithType.vb: RotaryAxisUtil.FindPreviousMcAxisDeg(LazyLinkedListNode(Of SyntaxPiece), String)
- uid: Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.FindPreviousMcAxisDeg*
name: FindPreviousMcAxisDeg
href: api/Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.html#Hi_NcParsers_LogicSyntaxs_RotaryAxisUtil_FindPreviousMcAxisDeg_
commentId: Overload:Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.FindPreviousMcAxisDeg
isSpec: "True"
fullName: Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.FindPreviousMcAxisDeg
nameWithType: RotaryAxisUtil.FindPreviousMcAxisDeg
- uid: Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.GetRotaryAxes(Hi.NcParsers.Dependencys.IMachineAxisConfig) - uid: Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.GetRotaryAxes(Hi.NcParsers.Dependencys.IMachineAxisConfig)
name: GetRotaryAxes(IMachineAxisConfig) name: GetRotaryAxes(IMachineAxisConfig)
href: api/Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.html#Hi_NcParsers_LogicSyntaxs_RotaryAxisUtil_GetRotaryAxes_Hi_NcParsers_Dependencys_IMachineAxisConfig_ href: api/Hi.NcParsers.LogicSyntaxs.RotaryAxisUtil.html#Hi_NcParsers_LogicSyntaxs_RotaryAxisUtil_GetRotaryAxes_Hi_NcParsers_Dependencys_IMachineAxisConfig_
@@ -151517,6 +151859,22 @@ references:
isSpec: "True" isSpec: "True"
fullName: Hi.NcParsers.SoftNcRunner.PopulateLegacyPerCaseData fullName: Hi.NcParsers.SoftNcRunner.PopulateLegacyPerCaseData
nameWithType: SoftNcRunner.PopulateLegacyPerCaseData nameWithType: SoftNcRunner.PopulateLegacyPerCaseData
- uid: Hi.NcParsers.SoftNcRunner.PopulateLegacyStrokeLimitsWhereUnset(System.Xml.Linq.XElement,System.Collections.Generic.List{Hi.NcParsers.Dependencys.INcDependency})
name: PopulateLegacyStrokeLimitsWhereUnset(XElement, List<INcDependency>)
href: api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_PopulateLegacyStrokeLimitsWhereUnset_System_Xml_Linq_XElement_System_Collections_Generic_List_Hi_NcParsers_Dependencys_INcDependency__
commentId: M:Hi.NcParsers.SoftNcRunner.PopulateLegacyStrokeLimitsWhereUnset(System.Xml.Linq.XElement,System.Collections.Generic.List{Hi.NcParsers.Dependencys.INcDependency})
name.vb: PopulateLegacyStrokeLimitsWhereUnset(XElement, List(Of INcDependency))
fullName: Hi.NcParsers.SoftNcRunner.PopulateLegacyStrokeLimitsWhereUnset(System.Xml.Linq.XElement, System.Collections.Generic.List<Hi.NcParsers.Dependencys.INcDependency>)
fullName.vb: Hi.NcParsers.SoftNcRunner.PopulateLegacyStrokeLimitsWhereUnset(System.Xml.Linq.XElement, System.Collections.Generic.List(Of Hi.NcParsers.Dependencys.INcDependency))
nameWithType: SoftNcRunner.PopulateLegacyStrokeLimitsWhereUnset(XElement, List<INcDependency>)
nameWithType.vb: SoftNcRunner.PopulateLegacyStrokeLimitsWhereUnset(XElement, List(Of INcDependency))
- uid: Hi.NcParsers.SoftNcRunner.PopulateLegacyStrokeLimitsWhereUnset*
name: PopulateLegacyStrokeLimitsWhereUnset
href: api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_PopulateLegacyStrokeLimitsWhereUnset_
commentId: Overload:Hi.NcParsers.SoftNcRunner.PopulateLegacyStrokeLimitsWhereUnset
isSpec: "True"
fullName: Hi.NcParsers.SoftNcRunner.PopulateLegacyStrokeLimitsWhereUnset
nameWithType: SoftNcRunner.PopulateLegacyStrokeLimitsWhereUnset
- uid: Hi.NcParsers.SoftNcRunner.Reg(Hi.Common.XmlUtils.XFactory) - uid: Hi.NcParsers.SoftNcRunner.Reg(Hi.Common.XmlUtils.XFactory)
name: Reg(XFactory) name: Reg(XFactory)
href: api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_Reg_Hi_Common_XmlUtils_XFactory_ href: api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_Reg_Hi_Common_XmlUtils_XFactory_
@@ -155878,6 +156236,19 @@ references:
isSpec: "True" isSpec: "True"
fullName: Hi.Numerical.Acts.StateActRunner.IsCoolantOn fullName: Hi.Numerical.Acts.StateActRunner.IsCoolantOn
nameWithType: StateActRunner.IsCoolantOn nameWithType: StateActRunner.IsCoolantOn
- uid: Hi.Numerical.Acts.StateActRunner.IsRapid
name: IsRapid
href: api/Hi.Numerical.Acts.StateActRunner.html#Hi_Numerical_Acts_StateActRunner_IsRapid
commentId: P:Hi.Numerical.Acts.StateActRunner.IsRapid
fullName: Hi.Numerical.Acts.StateActRunner.IsRapid
nameWithType: StateActRunner.IsRapid
- uid: Hi.Numerical.Acts.StateActRunner.IsRapid*
name: IsRapid
href: api/Hi.Numerical.Acts.StateActRunner.html#Hi_Numerical_Acts_StateActRunner_IsRapid_
commentId: Overload:Hi.Numerical.Acts.StateActRunner.IsRapid
isSpec: "True"
fullName: Hi.Numerical.Acts.StateActRunner.IsRapid
nameWithType: StateActRunner.IsRapid
- uid: Hi.Numerical.Acts.StateActRunner.ProcAct(Hi.Numerical.Acts.IAct) - uid: Hi.Numerical.Acts.StateActRunner.ProcAct(Hi.Numerical.Acts.IAct)
name: ProcAct(IAct) name: ProcAct(IAct)
href: api/Hi.Numerical.Acts.StateActRunner.html#Hi_Numerical_Acts_StateActRunner_ProcAct_Hi_Numerical_Acts_IAct_ href: api/Hi.Numerical.Acts.StateActRunner.html#Hi_Numerical_Acts_StateActRunner_ProcAct_Hi_Numerical_Acts_IAct_
@@ -167624,6 +167995,15 @@ references:
fullName.vb: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Mat4d, Hi.Geom.Vec3d) fullName.vb: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Mat4d, Hi.Geom.Vec3d)
nameWithType: IMachineKinematics.OrientationToMcAbc(Mat4d, out Vec3d) nameWithType: IMachineKinematics.OrientationToMcAbc(Mat4d, out Vec3d)
nameWithType.vb: IMachineKinematics.OrientationToMcAbc(Mat4d, Vec3d) nameWithType.vb: IMachineKinematics.OrientationToMcAbc(Mat4d, Vec3d)
- uid: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Mat4d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)
name: OrientationToMcAbc(Mat4d, Func<Vec3d, bool>, out Vec3d)
href: api/Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Mat4d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__
commentId: M:Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Mat4d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)
name.vb: OrientationToMcAbc(Mat4d, Func(Of Vec3d, Boolean), Vec3d)
fullName: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Mat4d, System.Func<Hi.Geom.Vec3d, bool>, out Hi.Geom.Vec3d)
fullName.vb: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Mat4d, System.Func(Of Hi.Geom.Vec3d, Boolean), Hi.Geom.Vec3d)
nameWithType: IMachineKinematics.OrientationToMcAbc(Mat4d, Func<Vec3d, bool>, out Vec3d)
nameWithType.vb: IMachineKinematics.OrientationToMcAbc(Mat4d, Func(Of Vec3d, Boolean), Vec3d)
- uid: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Vec3d,Hi.Geom.Vec3d@) - uid: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Vec3d,Hi.Geom.Vec3d@)
name: OrientationToMcAbc(Vec3d, out Vec3d) name: OrientationToMcAbc(Vec3d, out Vec3d)
href: api/Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__ href: api/Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__
@@ -167633,6 +168013,15 @@ references:
fullName.vb: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Vec3d, Hi.Geom.Vec3d) fullName.vb: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Vec3d, Hi.Geom.Vec3d)
nameWithType: IMachineKinematics.OrientationToMcAbc(Vec3d, out Vec3d) nameWithType: IMachineKinematics.OrientationToMcAbc(Vec3d, out Vec3d)
nameWithType.vb: IMachineKinematics.OrientationToMcAbc(Vec3d, Vec3d) nameWithType.vb: IMachineKinematics.OrientationToMcAbc(Vec3d, Vec3d)
- uid: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Vec3d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)
name: OrientationToMcAbc(Vec3d, Func<Vec3d, bool>, out Vec3d)
href: api/Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_Hi_Geom_Vec3d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__
commentId: M:Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Vec3d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)
name.vb: OrientationToMcAbc(Vec3d, Func(Of Vec3d, Boolean), Vec3d)
fullName: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Vec3d, System.Func<Hi.Geom.Vec3d, bool>, out Hi.Geom.Vec3d)
fullName.vb: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc(Hi.Geom.Vec3d, System.Func(Of Hi.Geom.Vec3d, Boolean), Hi.Geom.Vec3d)
nameWithType: IMachineKinematics.OrientationToMcAbc(Vec3d, Func<Vec3d, bool>, out Vec3d)
nameWithType.vb: IMachineKinematics.OrientationToMcAbc(Vec3d, Func(Of Vec3d, Boolean), Vec3d)
- uid: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc* - uid: Hi.Numerical.Xyzabc.IMachineKinematics.OrientationToMcAbc*
name: OrientationToMcAbc name: OrientationToMcAbc
href: api/Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_ href: api/Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_OrientationToMcAbc_
@@ -168328,6 +168717,15 @@ references:
fullName.vb: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Mat4d, Hi.Geom.Vec3d) fullName.vb: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Mat4d, Hi.Geom.Vec3d)
nameWithType: XyzabcSolver.OrientationToMcAbc(Mat4d, out Vec3d) nameWithType: XyzabcSolver.OrientationToMcAbc(Mat4d, out Vec3d)
nameWithType.vb: XyzabcSolver.OrientationToMcAbc(Mat4d, Vec3d) nameWithType.vb: XyzabcSolver.OrientationToMcAbc(Mat4d, Vec3d)
- uid: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Mat4d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)
name: OrientationToMcAbc(Mat4d, Func<Vec3d, bool>, out Vec3d)
href: api/Hi.Numerical.Xyzabc.XyzabcSolver.html#Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_Hi_Geom_Mat4d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__
commentId: M:Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Mat4d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)
name.vb: OrientationToMcAbc(Mat4d, Func(Of Vec3d, Boolean), Vec3d)
fullName: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Mat4d, System.Func<Hi.Geom.Vec3d, bool>, out Hi.Geom.Vec3d)
fullName.vb: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Mat4d, System.Func(Of Hi.Geom.Vec3d, Boolean), Hi.Geom.Vec3d)
nameWithType: XyzabcSolver.OrientationToMcAbc(Mat4d, Func<Vec3d, bool>, out Vec3d)
nameWithType.vb: XyzabcSolver.OrientationToMcAbc(Mat4d, Func(Of Vec3d, Boolean), Vec3d)
- uid: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Vec3d,Hi.Geom.Vec3d@) - uid: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Vec3d,Hi.Geom.Vec3d@)
name: OrientationToMcAbc(Vec3d, out Vec3d) name: OrientationToMcAbc(Vec3d, out Vec3d)
href: api/Hi.Numerical.Xyzabc.XyzabcSolver.html#Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__ href: api/Hi.Numerical.Xyzabc.XyzabcSolver.html#Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_Hi_Geom_Vec3d_Hi_Geom_Vec3d__
@@ -168337,6 +168735,15 @@ references:
fullName.vb: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Vec3d, Hi.Geom.Vec3d) fullName.vb: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Vec3d, Hi.Geom.Vec3d)
nameWithType: XyzabcSolver.OrientationToMcAbc(Vec3d, out Vec3d) nameWithType: XyzabcSolver.OrientationToMcAbc(Vec3d, out Vec3d)
nameWithType.vb: XyzabcSolver.OrientationToMcAbc(Vec3d, Vec3d) nameWithType.vb: XyzabcSolver.OrientationToMcAbc(Vec3d, Vec3d)
- uid: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Vec3d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)
name: OrientationToMcAbc(Vec3d, Func<Vec3d, bool>, out Vec3d)
href: api/Hi.Numerical.Xyzabc.XyzabcSolver.html#Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_Hi_Geom_Vec3d_System_Func_Hi_Geom_Vec3d_System_Boolean__Hi_Geom_Vec3d__
commentId: M:Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Vec3d,System.Func{Hi.Geom.Vec3d,System.Boolean},Hi.Geom.Vec3d@)
name.vb: OrientationToMcAbc(Vec3d, Func(Of Vec3d, Boolean), Vec3d)
fullName: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Vec3d, System.Func<Hi.Geom.Vec3d, bool>, out Hi.Geom.Vec3d)
fullName.vb: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc(Hi.Geom.Vec3d, System.Func(Of Hi.Geom.Vec3d, Boolean), Hi.Geom.Vec3d)
nameWithType: XyzabcSolver.OrientationToMcAbc(Vec3d, Func<Vec3d, bool>, out Vec3d)
nameWithType.vb: XyzabcSolver.OrientationToMcAbc(Vec3d, Func(Of Vec3d, Boolean), Vec3d)
- uid: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc* - uid: Hi.Numerical.Xyzabc.XyzabcSolver.OrientationToMcAbc*
name: OrientationToMcAbc name: OrientationToMcAbc
href: api/Hi.Numerical.Xyzabc.XyzabcSolver.html#Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_ href: api/Hi.Numerical.Xyzabc.XyzabcSolver.html#Hi_Numerical_Xyzabc_XyzabcSolver_OrientationToMcAbc_
Binary file not shown.
Binary file not shown.
Binary file not shown.