This commit is contained in:
2026-09-09 17:35:23 +08:00
parent 2a98ae7556
commit 161af68fe3
1271 changed files with 58251 additions and 98639 deletions
@@ -0,0 +1,322 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>List Command Panel | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="List Command Panel | HiAPI-C# 2025 ">
<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="">
<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="Anatomy-ListCommandPanel">
<h1 id="list-command-panel">List Command Panel</h1>
<p>A <a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html">ListCommand</a> is the container command: an optional title plus a list of
enable-wrapped commands. Running one walks
<a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html#Hi_SessionCommands_ListCommand_CommandEntryList">CommandEntryList</a> top-down and skips a disabled entry together
with everything nested under it — the wrapper yields nothing while its flag is clear. The mission's
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>
<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
entry-list editor the branch root uses, scoped to the nested list.</p>
<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
documented once, on <a class="xref" href="mission-root-panel.html">Mission Root Panel</a>.</p>
<h2 id="key-models">Key Models</h2>
<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>
and <a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html#Hi_SessionCommands_ListCommand_CommandEntryList">CommandEntryList</a>.</li>
<li><strong>Supporting</strong>:
<ul>
<li><a class="xref" href="../../../api/Hi.SessionCommands.EnablingWrapper.html">EnablingWrapper</a> — one entry:
<a class="xref" href="../../../api/Hi.SessionCommands.EnablingWrapper.html#Hi_SessionCommands_EnablingWrapper_Command">Command</a> plus
<a class="xref" href="../../../api/Hi.SessionCommands.EnablingWrapper.html#Hi_SessionCommands_EnablingWrapper_IsEnabled">IsEnabled</a>.</li>
<li><a class="xref" href="../../../api/Hi.SessionCommands.ITitleCommand.html">ITitleCommand</a> — <code>ListCommand</code> implements it, and
<a class="xref" href="../../../api/Hi.SessionCommands.ITitleCommand.html#Hi_SessionCommands_ITitleCommand_GetCommandTitle_">GetCommandTitle</a> composes the label a row shows.</li>
<li><a class="xref" href="../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> — the mission's command, a list.</li>
<li><a class="xref" href="../../../api/Hi.SessionCommands.CommandCatalogAttribute.html">CommandCatalogAttribute</a> and <a class="xref" href="../../../api/Hi.SessionCommands.CommandCategory.html">CommandCategory</a>
— what makes <code>List</code> addable, and the group it is offered under.</li>
</ul>
</li>
</ul>
<h2 id="the-panel-of-a-list-entry">The Panel of a List Entry</h2>
<p>Selecting a list command in the Control Tree opens, top to bottom:</p>
<ul>
<li>List Entry Panel
<ul>
<li>Control Bar
<ul>
<li>Up / Down / Duplicate / Delete — labelled buttons for the operations that rewrite the
<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>
</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>
</li>
</ul>
</li>
</ul>
<p>The Title input holds the <strong>raw</strong> title — empty when unset — while the label the row and the tree
show 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
the project file, so it cannot come back as a changed title on the next load.</p>
<p>Keystrokes debounce into one title save. The pending save is flushed before anything that shifts the
entry paths — a structural operation, a duplicate, a selection change — and cancelled on delete and
on unmount, so a late write cannot land on whichever command slid into the old path. 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>
<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
row. It decides only whether the command <strong>runs</strong>: while it is clear the row and the tree node dim,
and the editor stays open and fully editable. Unticking a list dims its whole sub-tree — 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>
<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
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>
<h2 id="moving-commands-in-and-out">Moving Commands In and Out</h2>
<ul>
<li><strong>Into a list</strong> — drag a row onto the middle band of a list row; that row's outer quarters still
reorder around it.</li>
<li><strong>Out of a list</strong> — drag onto the drop-out zone of a nested list's editor, which is visible only
while a row inside that editor is being dragged. The entry lands right after the list command
itself in the owning list.</li>
</ul>
<p>Both are the same reparent call. 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>
<ul>
<li><strong>A new command lands at the end</strong> of the list it was added to, root or nested. Nothing is pinned;
the order is entirely the user's, changed with the row's up / 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
uses, so a nested list copies with its whole sub-tree, and the clone lands right after the source.</li>
</ul>
<p>Dragging serves rearrangement only: a drag carrying text or files is ignored, because the row's drag
handling returns as soon as the drag did not start on a row. To bring several program files 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
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>
<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.
<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
supplies the localized label otherwise, so a newly attributed engine command becomes addable with no
frontend change.</p>
<p>A command without that attribute stays loadable from a project file but is never offered for
creation. General Config is the one such command with an editor of its own: it is the legacy
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
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
node — the kind's own panel when one exists, otherwise a generic editor built from the scalar fields
the command declares. Selection is one row at a time: there is no multi-selection here, and every
action acts on the row that carries it. Because the server composes every entry 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
pane. The draggable vertical divider on screen belongs to the Execution page, between the left dock
— the Control Tree over the editor panel — and the central area; a second divider inside that dock
drags the height between the tree and the editor.</p>
<h2 id="the-wpf-clients-list-panel">The WPF Client's List Panel</h2>
<p>The WPF panel edits the <strong>root</strong> list only. It binds the project's player command as a list, its Add
menu offers no List item, and its content switch has no List arm, so a nested list entry selected
there renders the literal text &ldquo;No editor available for ListCommand&rdquo;. Nesting is a web surface.</p>
<ul>
<li>Two columns: a 400px entry column, a <code>GridSplitter</code>, and the selected command's content column,
both columns floored at 300px.</li>
<li>One toolbar over the list — Add, Remove, Move Up, Move Down — acting on the list selection. There
is no duplicate.</li>
<li>Add is a plain button that pops a fixed six-item context menu built in its click handler:
&ldquo;Pre-Setting Command&rdquo;, &ldquo;NC Opt Option Command&rdquo;, &ldquo;NC File Command&rdquo;, &ldquo;NC Code Command&rdquo;,
&ldquo;Script Command&rdquo; and &ldquo;Post Execution Command&rdquo;.</li>
<li>The list box is extended-select. Remove takes every selected entry, prompting with a count when
more than one is selected, and a drag can carry a whole selection; Move Up and Move Down stay
disabled unless exactly one entry is selected.</li>
<li>Each entry box carries a labelled Enable checkbox at its left, the command's title in bold, and a
pin icon with a &ldquo;Pin at beginning&rdquo; / &ldquo;Pin at end&rdquo; label — shown on the first entry when it is a
General Config command, and on the last when it is a Post-Execution command.</li>
<li>Insertion works around the ends: a new entry lands before a trailing Post-Execution when that is
the list's only one, and a General Config lands at the top unless the list already starts with
one. A drag that would move a pinned entry — or drop another entry onto it — is refused, the guard
testing that the entry is the only command of its kind and sits at that end. The Move Up / Move
Down buttons are not covered by that guard.</li>
<li>The content panel is greyed and made read-only while the selected entry's Enable box is clear.</li>
<li>Files dropped from the file explorer onto the entry list create one enabled NC File command per
file, taking a project-relative path when the file sits under the project directory.</li>
<li>The entry label falls back to the raw class name for a command that composes no title of its
own — <code>GeomDiffCommand</code>, <code>OptimizeToFilesCommand</code>, <code>WriteStepFilesCommand</code> and
<code>WriteShotFilesCommand</code>.</li>
</ul>
<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>
<h3 id="web-application">Web Application</h3>
<ul>
<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
entry-list editor of a list entry, 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
here and serving the branch root: the rows and their actions, the three drag landings, and the
drop-out zone shown only during a drag inside a nested editor.</li>
<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
per-build stamp that forces the panel remount.</li>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — 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
(<code>root</code> or empty = the root list, <code>0.2</code> = a nested entry).</li>
<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>
<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
after it.</li>
<li><code>wwwroot-src/src/pages/ExecutionPage.vue</code> — the page-level splitter between the left dock and 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
zone, the run-order hint, the disabled hint and the operation labels.</li>
<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
or of a nested list), <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> (the XML-round-trip deep clone),
<code>POST list-command/entries/{path}/reparent</code> (drag-into-list and drop-out, 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
set and constructs the picked kind.</li>
</ul>
<h3 id="hiapi-engine">HiAPI Engine</h3>
<ul>
<li><code>HiNc/SessionCommands/ListCommand.cs</code> — the container: the optional title, the entry list a run
walks top-down, the whitespace-only-title-is-unset XML rule, the Flow catalog attribute, and the
<code>List</code> / <code>List [title]</code> composition.</li>
<li><code>HiNc/SessionCommands/EnablingWrapper.cs</code> — the enable flag plus the wrapped command that together
make one entry.</li>
<li><code>HiNc/SessionCommands/ITitleCommand.cs</code> — the interface a command implements to compose its own
title from the caller's vocabulary.</li>
<li><code>HiNc/SessionCommands/CommandCatalogAttribute.cs</code> — <code>CommandCategory</code> and the attribute (category,
order, kind key, aliases) that makes the addable set backend-owned.</li>
<li><code>HiNc/SessionCommands/PreSettingCommand.cs</code> — the General Config bundle: no catalog attribute, and
a loaded project expands a stored one into the split setting commands.</li>
<li><code>HiNc/MachiningProcs/MachiningProject.cs</code> — declares the mission's command and keeps it a list.</li>
</ul>
<h2 id="see-also">See Also</h2>
<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 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>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></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,212 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>NcCodeCommand Panel | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="NcCodeCommand Panel | HiAPI-C# 2025 ">
<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="">
<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="Anatomy-NcCodeCommandPanel">
<h1 id="nccodecommand-panel">NcCodeCommand Panel</h1>
<p>The key model is <a class="xref" href="../../../api/Hi.SessionCommands.NcCodeCommand.html">NcCodeCommand</a>.</p>
<p>The command carries two values: <a class="xref" href="../../../api/Hi.SessionCommands.NcCodeCommand.html#Hi_SessionCommands_NcCodeCommand_NcText">NcText</a>, the NC program
itself, and <a class="xref" href="../../../api/Hi.SessionCommands.NcCodeCommand.html#Hi_SessionCommands_NcCodeCommand_Title">Title</a>, the name that program runs under. Both
are written into the project file — the command emits a title element and an NC-text element, and
the project nests the whole command list into its own XML — so the program travels with the project
instead of existing as a file beside it. That is the whole difference from
<a class="xref" href="NcFileCommand-panel.html">Program File</a>, which stores a path and leaves the program on disk.
A mission can therefore carry a short program without producing an artifact of its own.</p>
<p>Title is not decoration. <code>Run</code> passes it to <a class="xref" href="../../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_RunNc_">RunNc</a> as the
program name the run log shows, which is why the model defaults it to the command's own name,
<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
something else.</p>
<p>The panel renders on the command's own node in the Mission branch of the Execution page's Control
Tree, below the move / duplicate / delete control bar. A single-purpose kind like this one embeds
its whole editor on that node rather than growing section child nodes.</p>
<h2 id="layout">Layout</h2>
<ul>
<li>NcCodeCommand Panel
<ul>
<li>Title Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.NcCodeCommand.html#Hi_SessionCommands_NcCodeCommand_Title">Title</a>.</li>
<li>Labelled &quot;Title (optional)&quot;. A newly added command arrives with the model's default name,
<code>NC Code</code>, already in the field; renaming it renames the program in the run log and in the
mission row.</li>
</ul>
</li>
<li>NC Code Editor Area
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.NcCodeCommand.html#Hi_SessionCommands_NcCodeCommand_NcText">NcText</a>.</li>
<li>A plain monospace text area: on the web an 18-row field with a 360 px floor, on WPF a Consolas
text box in an NC Code group box that takes the panel's remaining height.</li>
<li>No line-number gutter and no syntax highlighting on either client. The rich editor in this
folder is the <a class="xref" href="script-command-panel.html">Script command</a>'s — that command ships
CodeMirror with a C# grammar, this one ships a text area.</li>
</ul>
</li>
<li>Stats and Actions Row (web)
<ul>
<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>Clear Button — confirms in a dialog before emptying the NC text.</li>
<li>Both buttons stay disabled while the code is empty.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="saving">Saving</h2>
<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
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
when the body actually carries it, which is why the client sends the field it changed and a null for
the one it did not.</p>
<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
text.</p>
<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>
<h3 id="web-application">Web Application</h3>
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
<ul>
<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
Blank Lines, and Clear behind a confirm dialog.</li>
<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
command node.</li>
<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>
<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>
<li><code>wwwroot-src/src/i18n/en/dialog.ts</code> — the Clear confirmation's title and message.</li>
<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
back to the panel.</li>
</ul>
<h3 id="hiapi-engine">HiAPI Engine</h3>
<ul>
<li><code>HiNc/SessionCommands/NcCodeCommand.cs</code> — the model: <code>NcText</code>, <code>Title</code> defaulting to the command's
own display name, the Program-category catalog registration, the XML round-trip that puts the NC
text into the project file, <code>Run</code> handing text and title to the session shell, and the row-label
rule that shows the bare name while the title is unset or still the default.</li>
<li><code>HiNc/MachiningProcs/SessionShell.cs</code> — <code>RunNc</code> takes the NC text plus an alternative file name,
and that name is the title this command supplies for the log.</li>
<li><code>HiNc/MachiningProcs/MachiningProject.cs</code> — nests the command list into the project XML, which is
how this command's NC text persists with the project.</li>
</ul>
<h2 id="see-also">See Also</h2>
<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="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="index.html">Mission</a> — the rest of the command panels</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></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,273 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>NcFileCommand Panel (Program File) | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="NcFileCommand Panel (Program File) | HiAPI-C# 2025 ">
<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="">
<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="Anatomy-NcFileCommandPanel">
<h1 id="ncfilecommand-panel-program-file">NcFileCommand Panel (Program File)</h1>
<p>The key model is <a class="xref" href="../../../api/Hi.SessionCommands.NcFileCommand.html">NcFileCommand</a>.</p>
<p>The command carries exactly two values: <a class="xref" href="../../../api/Hi.SessionCommands.NcFileCommand.html#Hi_SessionCommands_NcFileCommand_NcFile">NcFile</a>, the path of
the program to play, and <a class="xref" href="../../../api/Hi.SessionCommands.NcFileCommand.html#Hi_SessionCommands_NcFileCommand_NcKind">NcKind</a>, the runner that plays it.
The program text stays a file on disk — the project stores the path and nothing else, which is what
separates this command from <a class="xref" href="NcCodeCommand-panel.html">NC Code</a>, whose text is serialized
into the project itself.</p>
<p><code>NcFile</code> is normally a path relative to the project folder — that is what the browse dialog yields —
and an absolute path on the server is accepted just as well. No base directory is stored with the
command: at play time <a class="xref" href="../../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_RunNcFile_">RunNcFile</a> hands the stored path
together with the project's own base directory to the local project service, and that is where a
relative path acquires its root. The WPF panel's <code>BaseDirectory</code> is the code-behind assistant
property the <a class="xref" href="../../conventions/gui-file-path-assignment.html">Load Pattern</a> asks a file-assigning GUI to carry,
assigned to the panel by its parent — a panel member, not a model member.</p>
<p>The panel renders on the command's own node in the Mission branch of the Execution page's Control
Tree, below the move / duplicate / delete control bar. This command has no title of its own, so the
row and tree label read <code>Program File [path]</code>, the path being the detail the label brackets.</p>
<div class="NOTE">
<h5>Note</h5>
<p>The GUI labels this command &ldquo;Program File&rdquo;: it plays NC, CL (CLSF) and CSV files — the runner is
picked by <a class="xref" href="../../../api/Hi.SessionCommands.NcFileCommand.html#Hi_SessionCommands_NcFileCommand_NcKind">NcKind</a>, and
<a class="xref" href="../../../api/Hi.MachiningProcs.NcKind.html#Hi_MachiningProcs_NcKind_Auto">Auto</a> reads it off the extension
(<a class="xref" href="../../../api/Hi.MachiningProcs.NcKindUtil.html#Hi_MachiningProcs_NcKindUtil_DetectByPath_">DetectByPath</a>: <code>.cl</code>, <code>.cls</code> and <code>.clsf</code> play as CL, <code>.csv</code>
as CSV, and every other extension as brand NC).</p>
</div>
<h2 id="layout">Layout</h2>
<ul>
<li>NcFileCommand Panel
<ul>
<li>Head Line
<ul>
<li>Program File Path Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.NcFileCommand.html#Hi_SessionCommands_NcFileCommand_NcFile">NcFile</a>.</li>
<li>Its hint names both accepted forms: an absolute path on the server, or a path relative to
the project folder.</li>
<li>Every keystroke saves the path. Leaving the field or pressing Enter additionally refreshes
the file-info banner.</li>
<li>The web field flexes to fill the row beside the Browse button at any panel width; the WPF
field is a fixed 200 px column carrying its own label.</li>
</ul>
</li>
<li>Browse Button
<ul>
<li>Opens the shared file-explorer dialog — see <a href="#browsing-for-a-program">Browsing for a Program</a>.</li>
</ul>
</li>
</ul>
</li>
<li>Play As Select
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.NcFileCommand.html#Hi_SessionCommands_NcFileCommand_NcKind">NcKind</a>.</li>
<li>Four choices: Auto (by extension), Brand NC, CL (CLSF) and CSV. The hint restates what Auto
detects, so the runner can be pinned when the extension would route the file elsewhere.</li>
<li>This control is the web client's. The WPF panel ships no kind control, so a project edited
there keeps the kind it already holds — Auto until something else sets it.</li>
</ul>
</li>
<li>File Info Banner
<ul>
<li>Appears once the path field is non-empty. Every fact in it is read on the server.</li>
<li>Found: a green banner stating the file size, its modified stamp and its line count, with a
Preview button in the banner's action slot.</li>
<li>Missing: an orange banner saying the file is not found on the server, and no Preview button.</li>
</ul>
</li>
<li>Preview Dialog
<ul>
<li>Read-only. The server returns the file's first 100 lines and the dialog shows them in a
monospace block that scrolls within 60% of the viewport height, inside a card capped at 80%.
An empty file previews as &quot;(empty)&quot;.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="browsing-for-a-program">Browsing for a Program</h2>
<p>Browse opens the shared server-side file explorer dialog. File reads happen on the server; the
browser never uploads file bytes.</p>
<p>The <a class="xref" href="../../conventions/gui-file-path-assignment.html">Load Pattern</a>'s general web convention offers the Admin,
Project and Resource roots. This picker narrows to one: it opens on the project directory and allows
no other root, so a pick always yields a project-relative path. A file outside the project is
reached by typing its absolute path into the path field, which the server accepts.</p>
<p>The dialog carries four filter groups rather than one catch-all:</p>
<ul>
<li><strong>NC Files</strong> — <code>.nc</code>, <code>.anc</code>, <code>.tap</code>, <code>.eia</code>, <code>.mpf</code>, <code>.spf</code>, <code>.cnc</code>, <code>.ptp</code>, <code>.h</code>. The open set:
brand controller extensions, of which these are the common ones rather than all of them.</li>
<li><strong>CL Files</strong> — <code>.cl</code>, <code>.cls</code>, <code>.clsf</code>.</li>
<li><strong>CSV Files</strong> — <code>.csv</code>.</li>
<li><strong>All Files</strong> — an empty extension list, which is the empty filter the Load Pattern asks every
browser to preserve. It is the backstop for a brand extension the NC group does not name.</li>
</ul>
<p>CL and CSV are split out because they are closed extension sets: those are exactly the extensions
Auto routes to the CL and CSV runners, and everything else falls through to brand NC.</p>
<p>The WPF Browse button opens an <code>OpenFileDialog</code> with the panel's file-filter resource, starting at
the project directory or at the current file's own directory. A pick under the project directory is
stored as a relative path, and a pick outside it as an absolute one.</p>
<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
picked file lands on this command. Each further pick becomes a <strong>new</strong> Program File command, added
to the list this command sits in and moved into place directly after it, in pick order — the same
list, so a command inside a nested list fans out inside that nested list. The panel then reports a
structure change, which rebuilds the owning list's branch around the new rows and leaves the
selection on this command.</p>
<h2 id="where-the-program-text-is-edited">Where the Program Text Is Edited</h2>
<p>The two clients part company here, and the command is the same either way: it stores a path.</p>
<ul>
<li><strong>Web</strong> — 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. Nothing in the
browser writes NC bytes back; the two file endpoints this panel calls are both reads.</li>
<li><strong>WPF</strong> — the panel opens the file. A non-text file, or one the panel cannot find, disables the
editor and states why in the Head Message Place above it. A text file within 20000 lines opens for
editing, with its line count in the group-box header; a longer one shows its first 20000 lines
read-only and warns in the Head Message Place. Two seconds after the last keystroke the editor
writes the file back, and reports the save in that same message place. The editor is AvalonEdit
with line numbers where that assembly resolves, and a plain Consolas text box otherwise.</li>
</ul>
<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>
<h3 id="web-application">Web Application</h3>
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
<ul>
<li><code>wwwroot-src/src/components/mission/NcFileCommandPanel.vue</code> — this panel: the path field and
Browse, the &ldquo;Play As&rdquo; kind select, the file-info banner and its Preview button, the read-only
preview dialog, the four filter groups, and the multi-pick fan-out.</li>
<li><code>wwwroot-src/src/components/widgets/FileExplorerDialog.vue</code> — the shared server-side browser
Browse opens: the pickable / multi / filters / initial-root / allowed-roots props, and the pick
event whose emitted strings pair a root name with a relative path — that relative half is what the
command stores.</li>
<li><code>wwwroot-src/src/components/widgets/fileFilter.ts</code> — the filter shape the four groups are built
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
panel. A kind absent from that map is served by the generic field editor instead.</li>
<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>
<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>
<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
resolving a relative path against the project folder). The command-snapshot builder emits the file
path and the NC kind for this kind of command.</li>
</ul>
<h3 id="hiapi-engine">HiAPI Engine</h3>
<ul>
<li><code>HiNc/SessionCommands/NcFileCommand.cs</code> — the model: <code>NcFile</code>, <code>NcKind</code> defaulting to Auto, the
&ldquo;Program File&rdquo; display name and its Program-category catalog registration, the XML round-trip that
writes the path verbatim, the <code>Program File [path]</code> row label, and <code>Run</code> handing path and kind to
the session shell.</li>
<li><code>HiMech/MachiningProcs/NcKind.cs</code> — the kind enum (Auto / BrandNc / Cl / Csv) and the
detect-by-path helper, the authority for what Auto does.</li>
<li><code>HiNc/MachiningProcs/SessionShell.cs</code> — <code>RunNcFile</code> passes the stored path together with the
project's base directory to the local project service.</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="NcCodeCommand-panel.html">NcCodeCommand Panel</a> — the other Program command: NC text stored in the project instead of a path to a file</li>
<li><a href="../../../manual/run/playing-a-program.html">Playing a Program</a> — the task these two commands serve</li>
<li><a href="index.html">Mission</a> — the rest of the command panels</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></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,411 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>NC Optimization Option Panel (NC Optimization Config) | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="NC Optimization Option Panel (NC Optimization Config) | HiAPI-C# 2025 ">
<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="">
<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="Anatomy-NcOptOptionPanel">
<h1 id="nc-optimization-option-panel-nc-optimization-config">NC Optimization Option Panel (NC Optimization Config)</h1>
<p>The key model is <a class="xref" href="../../../api/Hi.SessionCommands.NcOptOptionCommand.html">NcOptOptionCommand</a>; the options it carries are a
<a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html">NcOptOption</a>.</p>
<p>The command exists so the optimizer's settings are a step in the mission rather than a global
preference. <code>Run</code> assigns the command's option object onto the session shell — the whole body is
<code>sessionShell.NcOptOption = NcOptOption</code> — so the settings take effect at the point the entry sits
in the list. Everything played below it optimizes under them, and a second NC Optimization Config
further down the list re-points them mid-mission.</p>
<p>The command carries no title on either client. Its row and its tree label always read
<code>NC Optimization Config</code>: <code>GetCommandTitle</code> returns that fixed name and takes nothing from the user.</p>
<h2 id="where-it-renders">Where It Renders</h2>
<p>The web client has one editor component for this command and mounts it once per tree node, each
mount scoped to one group of options:</p>
<ul>
<li>The <strong>NC Optimization Config</strong> node itself carries the four enable checkboxes, below the
move / duplicate / delete control bar every command node shows.</li>
<li>The node grows five <strong>section children</strong> — Distances, Feedrate, Motion Dynamics, Force &amp; Safety,
Compensation — and each mounts the same component scoped to its own section.</li>
</ul>
<p>Unlike the General Config and Post-Execution sections, none of these five section nodes carries an
enable checkbox: this kind declares no section enable flags, so the tree hides the tick on them. The
command node's own checkbox is the only switch, and it only decides whether the mission runs the
command — a disabled command is skipped during play and stays fully editable.</p>
<h2 id="layout">Layout</h2>
<ul>
<li><p>NC Optimization Config Node</p>
<ul>
<li>Enable Optimization CheckBox
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_EnableOpt">EnableOpt</a>.</li>
</ul>
</li>
<li>Enable Feedrate Optimization CheckBox
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_EnableOptFeedrate">EnableOptFeedrate</a>.</li>
</ul>
</li>
<li>Enable Depth Splition CheckBox
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_EnableDepthSplition">EnableDepthSplition</a>.</li>
<li>The desktop client labels the same switch &ldquo;Enable Depth Splitting&rdquo;.</li>
</ul>
</li>
<li>Enable Interpolation CheckBox
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_EnableInterpolation">EnableInterpolation</a>.</li>
</ul>
</li>
</ul>
</li>
<li><p>Distances Section</p>
<ul>
<li>Extended Pre Distance Numeric Field (mm)
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_ExtendedPreDistance_mm">ExtendedPreDistance_mm</a>.</li>
</ul>
</li>
<li>Extended Post Distance Numeric Field (mm)
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_ExtendedPostDistance_mm">ExtendedPostDistance_mm</a>.</li>
</ul>
</li>
</ul>
</li>
<li><p>Feedrate Section</p>
<ul>
<li>Min Feedrate Numeric Field (mm/min)
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MinFeedrate_mmdmin">MinFeedrate_mmdmin</a>.</li>
</ul>
</li>
<li>Max Feedrate Numeric Field (mm/min)
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MaxFeedrate_mmdmin">MaxFeedrate_mmdmin</a>.</li>
</ul>
</li>
<li>Rapid Feed Numeric Field (mm/min)
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_RapidFeed_mmdmin">RapidFeed_mmdmin</a>.</li>
</ul>
</li>
<li>Min Feed Per Tooth Numeric Field (mm)
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MinFeedPerTooth_mm">MinFeedPerTooth_mm</a>.</li>
</ul>
</li>
<li>Max Feed Per Tooth Numeric Field (mm)
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MaxFeedPerTooth_mm">MaxFeedPerTooth_mm</a>.</li>
</ul>
</li>
<li>Feedrate Assignment Ratio Numeric Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_FeedrateAssignmentRatio">FeedrateAssignmentRatio</a>.</li>
</ul>
</li>
</ul>
</li>
<li><p>Motion Dynamics Section</p>
<ul>
<li>Max Acceleration Numeric Field (mm/s²)
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MaxAcceleration_mmds2">MaxAcceleration_mmds2</a>.</li>
</ul>
</li>
<li>Max Jerk Numeric Field (mm/s³)
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MaxJerk_mmds3">MaxJerk_mmds3</a>.</li>
</ul>
</li>
</ul>
</li>
<li><p>Force &amp; Safety Section</p>
<ul>
<li>Preferred Force Numeric Field (N)
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_PreferedForce_N">PreferedForce_N</a>.</li>
<li>The one field hinted &quot;Accepts Infinity.&quot;, and the one field with no lower bound.</li>
</ul>
</li>
<li>Yielding Safety Factor Numeric Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_YieldingSafetyFactor">YieldingSafetyFactor</a>.</li>
</ul>
</li>
<li>Thermal Yield Safety Factor Numeric Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_ThermalYieldSafetyFactor">ThermalYieldSafetyFactor</a>.</li>
</ul>
</li>
<li>Spindle Torque Safety Factor Numeric Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MaxSpindleTorqueSafetyFactor">MaxSpindleTorqueSafetyFactor</a>.</li>
</ul>
</li>
<li>Spindle Power Safety Factor Numeric Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MaxSpindlePowerSafetyFactor">MaxSpindlePowerSafetyFactor</a>.</li>
</ul>
</li>
</ul>
</li>
<li><p>Compensation Section</p>
<ul>
<li>Enable Forward Compensation CheckBox
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_EnableForwardCompensation">EnableForwardCompensation</a>.</li>
</ul>
</li>
<li>Enable Side Compensation CheckBox
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_EnableSideCompensation">EnableSideCompensation</a>.</li>
</ul>
</li>
<li>Enable Depth Compensation CheckBox
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_EnableDepthCompensation">EnableDepthCompensation</a>.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>The three compensation switches are bit accessors over the model's compensation mask — forward is
bit 0, side bit 1, depth bit 2 — so all three travel as one integer in the project file.</p>
<h2 id="saving">Saving</h2>
<p>Every edit writes at once. There is no Save button and no dirty state: a checkbox saves on click, a
numeric field saves when it loses focus or on Enter, and each write is one PUT for that one
property. The value is applied locally first; if the request fails, the panel re-reads the whole
command and raises a toast, so the field snaps back to what the server holds.</p>
<p>The read side is a single command snapshot rather than one GET per property: the panel loads the
command and takes its <code>ncOptOption</code> object. Two keys in that object drop the engine's <code>Max</code> prefix —
the spindle torque and spindle power safety factors travel as <code>spindleTorqueSafetyFactor</code> and
<code>spindlePowerSafetyFactor</code>.</p>
<h2 id="infinity-and-bounds">Infinity and Bounds</h2>
<p><code>Infinity</code> is a legal value for Preferred Force and Max Feed Per Tooth, and those two are exactly
the properties whose endpoints take a string body: the client sends the literal <code>Infinity</code> (or
<code>-Infinity</code>), and the reader parses the same spelling back. Every other property's endpoint takes a
typed <code>bool</code> or <code>double</code>.</p>
<p>Every numeric field except Preferred Force is bounded at 0 — a smaller number is refused in the
field with &ldquo;Must be ≥ 0&rdquo; and never reaches the server.</p>
<div class="TIP">
<h5>Tip</h5>
<p>The engine's XML form parses these values through <code>XmlConvert.ToDouble</code>, which is why an infinite
feed per tooth or preferred force survives a project save and reload.</p>
</div>
<h2 id="defaults">Defaults</h2>
<p>A freshly added command carries the option model's own initial values, so the panel opens on them:</p>
<table>
<thead>
<tr>
<th>Option</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>The four enable switches</td>
<td>all on</td>
</tr>
<tr>
<td>Extended Pre / Post Distance</td>
<td>2 mm</td>
</tr>
<tr>
<td>Min / Max Feedrate</td>
<td>1 / 20000 mm/min</td>
</tr>
<tr>
<td>Rapid Feed</td>
<td>20000 mm/min</td>
</tr>
<tr>
<td>Min / Max Feed Per Tooth</td>
<td>0 mm / <code>Infinity</code></td>
</tr>
<tr>
<td>Feedrate Assignment Ratio</td>
<td>0.01</td>
</tr>
<tr>
<td>Max Acceleration / Max Jerk</td>
<td>10 mm/s² / 100 mm/s³</td>
</tr>
<tr>
<td>Preferred Force</td>
<td><code>Infinity</code></td>
</tr>
<tr>
<td>Yielding / Thermal Yield Safety Factor</td>
<td>0</td>
</tr>
<tr>
<td>Spindle Torque / Power Safety Factor</td>
<td>1.5</td>
</tr>
<tr>
<td>The three compensation switches</td>
<td>all off</td>
</tr>
</tbody>
</table>
<h2 id="the-two-clients">The Two Clients</h2>
<p>The desktop client edits the same command in one scrolling panel of six group boxes, and it names 17
of the model's options — the four enable switches, the two distances, the three feedrates,
acceleration and jerk, Preferred Force with the two spindle safety factors, and the three
compensation switches.</p>
<p>The web client edits five more, and that is the whole difference between the two editors: Min Feed
Per Tooth, Max Feed Per Tooth and Feedrate Assignment Ratio in the Feedrate section, and Yielding
Safety Factor and Thermal Yield Safety Factor in Force &amp; Safety.</p>
<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>
<h3 id="web-application">Web Application</h3>
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
<ul>
<li><code>wwwroot-src/src/components/mission/NcOptOptionCommandPanel.vue</code> — this panel. A <code>section</code> prop
picks the one group it renders, a setter map routes each field to its API call, and a failed write
re-reads the command and notifies.</li>
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — registers the <code>ncoptoption</code> kind's
bespoke editor, declares its five section children, gives it the <code>tune</code> icon and the
<code>NC Optimization Config</code> display name, and leaves it out of the section-enable readers and writers
so its section nodes carry no checkbox.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue</code> — the control bar above the
command node's checkboxes.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionSectionPanel.vue</code> — mounts this panel once per
section node, scoped to that node's section.</li>
<li><code>wwwroot-src/src/api/mission.ts</code> — the option shape the panel edits, the reader that takes the
<code>ncOptOption</code> snapshot and parses <code>Infinity</code>, and one setter per property over
<code>commands/{path}/ncoptoption/{endpoint}</code>.</li>
<li><code>wwwroot-src/src/components/widgets/NumericInput.vue</code> — the field every non-boolean option uses:
it commits on blur or Enter, spells infinity as <code>Infinity</code>, and enforces the minimum the panel
passes.</li>
<li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the option labels and the &ldquo;Accepts Infinity.&rdquo; hint.</li>
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the kind name and the five section names the tree shows.</li>
<li><code>Missions/NcOptOptionEndpoints.cs</code> — a partial of the same <code>MissionController</code>: one PUT per
editable property, two of them string-bodied so <code>Infinity</code> round-trips. Each creates the option
object when the command has none, and answers a command-type mismatch when the path holds another
kind.</li>
<li><code>Missions/MissionController.cs</code> — builds the command snapshot the panel reads, re-keying the two
spindle safety factors onto their wire names, and owns the entry lifecycle — add, delete, move,
duplicate, reparent — that puts this command in the list.</li>
</ul>
<h3 id="hiapi-engine">HiAPI Engine</h3>
<ul>
<li><code>HiNc/SessionCommands/NcOptOptionCommand.cs</code> — the mission entry: the <code>NC Optimization Config</code>
display name, its Optimization catalog registration, the single option property, the fixed command
title, the XML round-trip that nests the options in the project file, and the <code>Run</code> that assigns
them onto the session shell.</li>
<li><code>HiMech/NcOpt/NcOptOption.cs</code> — the option model: the engine-side names
<code>MaxSpindleTorqueSafetyFactor</code> and <code>MaxSpindlePowerSafetyFactor</code>, the compensation booleans as bit
accessors over one mask, and the mm/min feedrates as conversions over mm/s storage.</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="PostExecutionCommand-panel.html">PostExecutionCommand Panel</a> — where the optimized programs are written out, under the settings this command puts in force</li>
<li><a href="../../../manual/run/the-other-commands.html">The Other Commands</a> — the task this command serves</li>
<li><a href="index.html">Mission</a> — the rest of the command panels</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></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,310 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PostExecutionCommand Panel (Post-Execution) | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="PostExecutionCommand Panel (Post-Execution) | HiAPI-C# 2025 ">
<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="">
<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="Anatomy-PostExecutionCommandPanel">
<h1 id="postexecutioncommand-panel-post-execution">PostExecutionCommand Panel (Post-Execution)</h1>
<p>The key model is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html">PostExecutionCommand</a>, the command both clients label
<strong>Post-Execution</strong>. It is the Output category's first catalog entry, and it carries five outputs
derived from what the session has played: step files, shot files, optimization files, a CL → NC
writeback, and a geometry-difference detection.</p>
<h2 id="when-it-runs-and-what-it-covers">When It Runs, and What It Covers</h2>
<p>Post-Execution is an ordinary entry in the command list, not an end-of-run hook. Its name describes
what it consumes, not a fixed position: the list runs its entries in order and skips any whose
Enable box is clear, and everything this command writes is derived from what the session has played
<strong>so far</strong>.</p>
<p>That makes its placement the whole question. Put it after two program entries and it writes both.
Put a second one halfway down the list and it writes an interim snapshot of the same accumulating
state. The CL → NC writeback says this outright in the panel — place the CL-playing Program File
command before this command — and it re-serializes every control file the session played, so an NC
play is written back too. Read this together with
<a class="xref" href="PreSettingCommand-panel.html">General Config</a>, the other half of the pair: those settings
apply from their position forward, these outputs cover everything up to this position.</p>
<p>The web client places the command anywhere in the list, like any other. The WPF client pins it to
the end: a new command is inserted before a trailing Post-Execution while that is the list's only
one, and the drag guard refuses to move it off the last position.</p>
<p><code>Run</code> executes the enabled outputs in an order of its own, which is <strong>not</strong> the order the tree and
the list below show them in: shot files, then step files, then optimization, then the CL → NC
writeback, then the geometry difference. Output timestamps follow that order rather than the layout.</p>
<h2 id="layout">Layout</h2>
<p>Every output is a section child node of the command, and each section's enable flag is that node's
own tree checkbox. The command node itself carries only a caption saying so; the section panels hold
the template and numeric fields, which stay editable whether or not the output is switched on —
the flag decides what runs, not what can be edited.</p>
<ul>
<li>Step Files Output Section
<ul>
<li>The node's checkbox is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html#Hi_SessionCommands_PostExecutionCommand_EnableWriteStepFiles">EnableWriteStepFiles</a>.</li>
<li>Step File Template Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html#Hi_SessionCommands_PostExecutionCommand_StepFileTemplate">StepFileTemplate</a>.</li>
<li>Default value: <code>Output/[NcName].step.csv</code></li>
</ul>
</li>
<li>Writes the step-series data of what the session has played.</li>
</ul>
</li>
<li>Shot Files Output Section
<ul>
<li>The node's checkbox is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html#Hi_SessionCommands_PostExecutionCommand_EnableWriteShotFiles">EnableWriteShotFiles</a>.</li>
<li>Shot File Template Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html#Hi_SessionCommands_PostExecutionCommand_ShotFileTemplate">ShotFileTemplate</a>.</li>
<li>Default value: <code>Output/[NcName].shot.csv</code></li>
</ul>
</li>
<li>Shot File Time Resolution Number Field (ms)
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html#Hi_SessionCommands_PostExecutionCommand_ShotFileTimeResolution_ms">ShotFileTimeResolution_ms</a>.</li>
<li>Default value: 1</li>
<li>This sampling period — not the machining resolution — sets the accuracy ceiling of the
time-series data, and a fine period produces a large file: a six-cut program writes about
13 MB at 1 ms and about 128 MB at 0.1 ms.</li>
</ul>
</li>
</ul>
</li>
<li>Optimization Output Section
<ul>
<li>The node's checkbox is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html#Hi_SessionCommands_PostExecutionCommand_EnableOptimizeToFiles">EnableOptimizeToFiles</a>.</li>
<li>Optimization File Template Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html#Hi_SessionCommands_PostExecutionCommand_OptimizationFileTemplate">OptimizationFileTemplate</a>.</li>
<li>Default value: <code>Output/Opt-[NcName]</code></li>
</ul>
</li>
<li>The SoftNc pipeline runs when the SoftNc runner is on and the session holds played syntax
layers; otherwise the HardNc path runs. Both clear every cutter's optimization-limit cache
first.</li>
</ul>
</li>
<li>CL → NC Writeback Section
<ul>
<li>The node's checkbox is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html#Hi_SessionCommands_PostExecutionCommand_EnableConvertClToNcFiles">EnableConvertClToNcFiles</a>.</li>
<li>NC Output Template Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html#Hi_SessionCommands_PostExecutionCommand_ClToNcFileTemplate">ClToNcFileTemplate</a>.</li>
<li>Default value: <code>Output/[NcName].nc</code></li>
<li>Its hint states the substitution: <code>[NcName]</code> is replaced by the source file name, extension
kept.</li>
</ul>
</li>
<li>A caption below the field explains the synthesis: the MSYS frame becomes a <code>G68.2</code> tilted
working plane, tool posture becomes <code>G43.4</code> RTCP with rotary words, and motions become
<code>G00</code>/<code>G01</code>/<code>G02</code>/<code>G03</code>. The CL must have been played on an XYZABC machine chain first. The
converted files appear as <code>→ file.nc</code> nodes on the Execution Program branch, with source ⇄
output line jumps.</li>
</ul>
</li>
<li>Geometry Difference Detection Section
<ul>
<li>The node's checkbox is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html#Hi_SessionCommands_PostExecutionCommand_EnableGeomDiff">EnableGeomDiff</a>.</li>
<li>Detect Radius Number Field (mm)
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html#Hi_SessionCommands_PostExecutionCommand_GeomDiffDetectRadius_mm">GeomDiffDetectRadius_mm</a>.</li>
<li>Default value: 1</li>
</ul>
</li>
<li>Compares the workpiece geometry at that radius. With no workpiece in the session it reports
&ldquo;No Workpiece exist&rdquo; and does nothing.</li>
</ul>
</li>
</ul>
<p>Shot Files Output and Optimization Output are the two physics-gated sections. The condition is the
physics preference <strong>and</strong> the advanced-physics licence, served to the client already combined; when
it is off, the tree builder omits those two nodes entirely, and a preference flip shows up on the
next branch rebuild. CL → NC Writeback is deliberately not gated — writeback is a SoftNc syntax
feature, not a physics one.</p>
<p>Every edit saves as it is made. A rejected save is reported and the panel reloads the command.</p>
<div class="NOTE">
<h5>Note</h5>
<p>Post-Execution writes run-derived files only. The meshed-geometry snapshot is a placeable command
of its own, because a snapshot can be taken at any spot in a mission: Record Meshed Geometry
(<a class="xref" href="../../../api/Hi.SessionCommands.RecordMeshedGeomCommand.html">RecordMeshedGeomCommand</a>, with its No Action / Read / Write / Read On
First Or Write modes) and Export Meshed Geometry (STL)
(<a class="xref" href="../../../api/Hi.SessionCommands.ExportMeshedGeomToStlCommand.html">ExportMeshedGeomToStlCommand</a>) are both Output-category catalog entries
with editors of their own. Opening a project that still carries an enabled meshed-geometry output
on this command raises a system warning naming the replacement, and re-saving the project drops
the element.</p>
</div>
<div class="NOTE">
<h5>Note</h5>
<p><a class="xref" href="../../../api/Hi.SessionCommands.GeomDiffCommand.html">GeomDiffCommand</a> exists as a standalone command, as do
<code>WriteStepFilesCommand</code>, <code>WriteShotFilesCommand</code> and <code>OptimizeToFilesCommand</code>. None of them
carries the catalog attribute, so they load from a project file but are not offered in the Add
Command dialog. Post-Execution is the catalogued carrier of these outputs, which is why they are
edited as its sections.</p>
</div>
<h2 id="the-wpf-clients-panel">The WPF Client's Panel</h2>
<p>There four of the outputs are group boxes on one panel, each an enable checkbox over a grid that is
disabled until the box is ticked: Step Files Output, Shot Files Output, Optimization Output and
Geometry Difference Detection. The physics condition collapses the Shot Files and Optimization group
boxes rather than omitting tree nodes.</p>
<p>CL → NC Writeback is the one output the web client has and this panel does not. Its two properties
live on the same engine command, and the web section and its two endpoints are where they are
edited.</p>
<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>
<h3 id="web-application">Web Application</h3>
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
<ul>
<li><code>wwwroot-src/src/components/mission/PostExecutionCommandPanel.vue</code> — the command node's caption
and one headerless block per section: step-files, shot-files, optimization, cl-nc-writeback and
geom-diff. No checkboxes live here.</li>
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — declares the five sections with
their labels, marks Shot Files and Optimization physics-gated with an explicit note that CL → NC
is not, filters the gated sections out of the tree, and maps each section id to its enable-flag
reader and writer.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionSectionPanel.vue</code> — renders one section headerless,
the breadcrumb already naming it, and passes no enable state down because the flags decide only
what runs.</li>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — the ticks: a command node ticks
its own enable flag, a section node with an enable flag ticks that, and every other node hides the
box.</li>
<li><code>wwwroot-src/src/api/mission.ts</code> — <code>loadPostExecution</code> and the eleven <code>postexecution/*</code> PUTs.</li>
<li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the field labels, the <code>[NcName]</code> hint, the command node's
overview caption and the writeback paragraph.</li>
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the five section node labels.</li>
<li><code>wwwroot-src/src/stores/appState.ts</code> — the physics preference and licence flags the tree builder
reads.</li>
<li><code>Environments/PreferenceController.cs</code> — serves the physics preference already combined with the
advanced-physics licence, the same condition the WPF panel evaluates.</li>
<li><code>Missions/MissionController.cs</code> — the <code>commands/{path}/postexecution/*</code> endpoints: the five enable
flags, the four templates, the shot-file time resolution and the geom-diff detect radius.</li>
</ul>
<h3 id="hiapi-engine">HiAPI Engine</h3>
<ul>
<li><code>HiNc/SessionCommands/PostExecutionCommand.cs</code> — the model, its display name and Output-category
catalog registration, every default above, the run order, and the warning raised for a project
still carrying a meshed-geometry output.</li>
<li><code>HiNc/SessionCommands/ListCommand.cs</code> — the in-order run that skips disabled entries, which is
what makes this command's placement decide what it covers.</li>
<li><code>HiNc/MachiningProcs/SessionShell.cs</code> — what each output actually calls: the shot-file writer and
its sampling-period guidance, the step-file writer, the optimization routing between the SoftNc
and HardNc paths, the CL → NC writeback synthesis, and the workpiece difference.</li>
<li><code>HiNc/SessionCommands/GeomDiffCommand.cs</code>, <code>HiNc/SessionCommands/WriteStepFilesCommand.cs</code>,
<code>HiNc/SessionCommands/WriteShotFilesCommand.cs</code> and
<code>HiNc/SessionCommands/OptimizeToFilesCommand.cs</code> — the standalone commands behind the same four
outputs: loadable from a project file, absent from the catalog.</li>
<li><code>HiNc/SessionCommands/RecordMeshedGeomCommand.cs</code> and
<code>HiNc/SessionCommands/ExportMeshedGeomToStlCommand.cs</code> — the two catalogued Output commands that
carry the meshed-geometry snapshot.</li>
<li><code>HiNc/SessionCommands/CommandCatalogAttribute.cs</code> — the attribute that separates a loadable
command from an addable one.</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="PreSettingCommand-panel.html">PreSettingCommand Panel</a> — the other half of the positional pair: those settings apply forward, these outputs cover everything up to here</li>
<li><a class="xref" href="NcOptOption-panel.html">NC Optimization Option Panel</a> — the settings the Optimization Output section writes its result under</li>
<li><a href="../../../manual/run/the-other-commands.html">The Other Commands</a> — the task this command serves</li>
<li><a href="index.html">Mission</a> — the rest of the command panels</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></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,316 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PreSettingCommand Panel (General Config) | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="PreSettingCommand Panel (General Config) | HiAPI-C# 2025 ">
<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="">
<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="Anatomy-PreSettingCommandPanel">
<h1 id="presettingcommand-panel-general-config">PreSettingCommand Panel (General Config)</h1>
<p>The key model is <a class="xref" href="../../../api/Hi.SessionCommands.PreSettingCommand.html">PreSettingCommand</a>, the command both clients label
<strong>General Config</strong>. It is one command carrying a bundle of session settings — the machining
resolution, the machining motion resolution, collision detection, pause on failure, physics — plus
an optional read of a meshed-geometry file.</p>
<h2 id="where-a-general-config-comes-from">Where a General Config Comes From</h2>
<p>The two clients differ on how a mission acquires these settings, and that difference is the first
thing to know about this panel.</p>
<p>The WPF client creates the bundle. Its Add menu carries a hard-coded item that constructs a
<code>PreSettingCommand</code>, and the insert rule pins it to the top of the list: a new General Config lands
at index 0 unless the list already starts with one, and while it is the list's only General Config
the drag guard refuses to move it off that position.</p>
<p>The web client's Add Command dialog is served by the server's command catalog, which reflects every
engine command carrying <code>[CommandCatalog]</code>. <code>PreSettingCommand</code> carries no such attribute, so the
dialog cannot produce one — the catalog keeps <code>presetting</code> only as a readable kind key, and creating
a command looks the kind up in the addable set alone. What the web offers instead is the same
settings as five separate Setup commands, each placeable anywhere in the list:</p>
<ul>
<li>Machining Resolution — <a class="xref" href="../../../api/Hi.SessionCommands.MachiningResolutionCommand.html">MachiningResolutionCommand</a>, 0.125 mm by default,
reading <code>Machining Resolution [0.125 mm]</code> in the list.</li>
<li>Machining Motion Resolution — <a class="xref" href="../../../api/Hi.SessionCommands.MachiningMotionResolutionCommand.html">MachiningMotionResolutionCommand</a>, Feed Per
Cycle by default.</li>
<li>Collision Detection — <a class="xref" href="../../../api/Hi.SessionCommands.CollisionDetectionCommand.html">CollisionDetectionCommand</a>, on by default.</li>
<li>Pause on Failure — <a class="xref" href="../../../api/Hi.SessionCommands.PauseOnFailureCommand.html">PauseOnFailureCommand</a>, off by default.</li>
<li>Physics — <a class="xref" href="../../../api/Hi.SessionCommands.PhysicsCommand.html">PhysicsCommand</a>, on by default, its field declared
physics-licence gated.</li>
</ul>
<p>Machining Motion Resolution ships an editor of its own. The other four declare their one scalar with
<code>[CommandField]</code> and are served by the generic field editor, which builds their input and its
server-localized label from that declaration — so the web ships strictly more here than one bundle
panel, and none of the four needed frontend code.</p>
<p>A project file never brings a reader to this panel either. Reading a stored bundle materializes
those five commands in its place, in the order the bundle applies them, preceded by a Read-mode
Record Meshed Geometry entry whenever the meshed-geometry read is enabled or a file is set. The
bundle's own enable state is consumed into every entry the expansion produces, and the Record entry
additionally keeps the bundle's read flag. A bundle stored as the project's bare root command
expands the same way, and what the project saves from then on is the split commands.</p>
<p>That leaves one case this panel serves: a <code>PreSettingCommand</code> an API caller constructed into the
list in place, which has not yet round-tripped through a project file. It edits that command through
the <code>commands/{path}/presetting/*</code> endpoints, and every field is a PUT of its own.</p>
<h2 id="when-the-settings-take-effect">When the Settings Take Effect</h2>
<p>A list runs its entries in order and skips any entry whose Enable box is clear. General Config's
<code>Run</code> then assigns straight onto the session shell, in this order: the meshed-geometry read when it
is enabled, the machining resolution, the motion resolution, collision detection, pause on failure,
physics.</p>
<p>So these are positional settings, not global pre-run settings. A program entry <strong>above</strong> this
command plays under whatever was in force before it; entries <strong>below</strong> it play under these values,
until something further down changes the session again. The five Setup commands state the same
contract one setting at a time — each is documented as taking effect &ldquo;from this command on&rdquo; — and
each can sit at a different point in the list, which is what having them separate buys.</p>
<h2 id="layout">Layout</h2>
<p>In the web client the command owns two tree nodes: the command node carrying the machining settings,
and one section child carrying the meshed-geometry file reference.</p>
<ul>
<li>Command Node
<ul>
<li>Machining Resolution Number Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.PreSettingCommand.html#Hi_SessionCommands_PreSettingCommand_MachiningResolution_mm">MachiningResolution_mm</a>.</li>
<li>Unit mm, floored at 0, default 0.125. A free numeric field — the web offers no option list.</li>
</ul>
</li>
<li>Motion Resolution
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.PreSettingCommand.html#Hi_SessionCommands_PreSettingCommand_MachiningMotionResolution">MachiningMotionResolution</a>.</li>
<li>A caption over a select with three choices: Feed Per Cycle, Feed Per Tooth and Fixed.</li>
<li>Fixed adds a row of two number fields inline, both floored at 0: Linear Resolution (mm) and
Rotary Resolution (deg), the two values of
<a class="xref" href="../../../api/Hi.Numerical.MachiningMotionResolutionUtils.FixedMachiningMotionResolution.html">FixedMachiningMotionResolution</a>.</li>
<li>Switching the type to Fixed carries the outgoing resolution's current linear and rotary values
into the new fixed pair rather than resetting them.</li>
</ul>
</li>
<li>Enable Collision Detection CheckBox
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.PreSettingCommand.html#Hi_SessionCommands_PreSettingCommand_EnableCollisionDetection">EnableCollisionDetection</a>.</li>
<li>Default value: true</li>
</ul>
</li>
<li>Enable Pause On Failure CheckBox
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.PreSettingCommand.html#Hi_SessionCommands_PreSettingCommand_EnablePauseOnFailure">EnablePauseOnFailure</a>.</li>
<li>Default value: false</li>
</ul>
</li>
<li>Enable Physics CheckBox
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.PreSettingCommand.html#Hi_SessionCommands_PreSettingCommand_EnablePhysics">EnablePhysics</a>.</li>
<li>Default value: true</li>
<li>Disabled unless the advanced-physics licence is held. The engine declares the same gate on the
split Physics command's field, so both editors refuse the same edit for the same reason.</li>
</ul>
</li>
</ul>
</li>
<li>Meshed Geometry Section Node
<ul>
<li>The node's own tree checkbox is
<a class="xref" href="../../../api/Hi.SessionCommands.PreSettingCommand.html#Hi_SessionCommands_PreSettingCommand_EnableReadMeshedGeom">EnableReadMeshedGeom</a>; the panel below it holds the
file reference only. The flag decides what runs, not what can be edited, so the field stays
editable whether or not the box is ticked — a read can be prepared before it is switched on.</li>
<li>Meshed Geometry File Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.PreSettingCommand.html#Hi_SessionCommands_PreSettingCommand_MeshedGeomFile">MeshedGeomFile</a>.</li>
<li>Hinted as a <code>.wct</code> or <code>.stl</code> path relative to the project folder.</li>
</ul>
</li>
<li>Browse Button
<ul>
<li>Opens the shared server-side file explorer, filtered to <code>.wct</code> / <code>.stl</code> with an All Files
fallback. It opens on the project directory and allows no other root, so a pick always yields
a project-relative path.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Every edit saves as it is made. A rejected save is reported and the panel reloads the command, so
what is on screen is what the server holds.</p>
<div class="NOTE">
<h5>Note</h5>
<p>The session's machining resolution is seeded from the workpiece's initial resolution when a
project is loaded or assigned — not on a runtime reset and not when the workpiece is swapped, so
an explicit setting survives both. This command carries its own value, and overwrites the
session's with it at the moment the command runs.</p>
</div>
<h2 id="the-wpf-clients-panel">The WPF Client's Panel</h2>
<p>There the whole bundle is one panel, in two group boxes.</p>
<ul>
<li><strong>Meshed Geometry Settings</strong> — an Enable Read Meshed Geometry checkbox over a Geometry File text
box and a Browse button; the grid beneath the checkbox is disabled until it is ticked. Browse is
an <code>OpenFileDialog</code> filtered to <code>*.wct;*.stl</code>, storing a pick under the project directory as a
relative path and one outside it as an absolute path.</li>
<li><strong>Machining Settings</strong> — the Machining Resolution control is an editable ComboBox pre-filled with
fifteen powers of two, from 0.0009765625 up to 16 in doublings, and a typed value outside that
list is accepted. Beside the Motion Resolution ComboBox a content presenter holds the fixed
fields, built at runtime and labelled Linear Resolution (mm) and Angle Resolution (deg) — Angle
Resolution being this client's wording for the same <code>RotaryResolution_deg</code> the web labels Rotary
Resolution. The three checkboxes sit loose in the same grid, and the Enable Physics one carries no
licence gate.</li>
</ul>
<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>
<h3 id="web-application">Web Application</h3>
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
<ul>
<li><code>wwwroot-src/src/components/mission/PreSettingCommandPanel.vue</code> — this editor in both of its
modes: the command node's machining settings, and the <code>meshed-geometry</code> section's file field with
its Browse button.</li>
<li><code>wwwroot-src/src/components/controlTree/missionItemTypes.ts</code> — maps the <code>presetting</code> kind to this
panel, declares its one Meshed Geometry section child, and turns <code>EnableReadMeshedGeom</code> into that
node's tree checkbox on read and on write.</li>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — which nodes show a checkbox: a
command node ticks its own enable flag, a section node with an enable flag ticks that, and every
other node hides the box. A disabled command dims its whole subtree.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionSectionPanel.vue</code> — renders one section of a
command's editor headerless, the breadcrumb already naming it.</li>
<li><code>wwwroot-src/src/components/widgets/FileExplorerDialog.vue</code> — the server-side browser Browse
opens, with the project-directory root and the filter list this panel passes it.</li>
<li><code>wwwroot-src/src/components/mission/GenericCommandPanel.vue</code> — the editor the four
bespoke-panel-less Setup commands get, built from their declared scalar fields.</li>
<li><code>wwwroot-src/src/api/mission.ts</code> — <code>loadPreSetting</code> and the nine <code>presetting/*</code> PUTs behind it.</li>
<li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the panel's wording, including the Rotary Resolution label
and the meshed-geometry hint and filter names.</li>
<li><code>wwwroot-src/src/stores/appState.ts</code> — the physics-licence flag the Enable Physics checkbox reads.</li>
<li><code>Missions/MissionCommandCatalog.cs</code> — the addable set the Add Command dialog is built from: the
reflected <code>[CommandCatalog]</code> entries, plus <code>presetting</code> as a read-only kind key that creation
never looks at.</li>
<li><code>Missions/MissionController.cs</code> — the <code>commands/{path}/presetting/*</code> endpoints:
enable-read-meshed-geom, meshed-geom-file, machining-resolution-mm,
machining-motion-resolution-type, fixed-linear-resolution-mm, fixed-rotary-resolution-deg,
enable-collision-detection, enable-pause-on-failure and enable-physics. The type switch is where
the current linear and rotary values are carried into a new fixed resolution.</li>
</ul>
<h3 id="hiapi-engine">HiAPI Engine</h3>
<ul>
<li><code>HiNc/SessionCommands/PreSettingCommand.cs</code> — the model, its defaults, the order <code>Run</code> applies
them onto the session shell, and the expansion into the split Setup commands.</li>
<li><code>HiNc/SessionCommands/CommandCatalogAttribute.cs</code> — the attribute the catalog reflects, and the
five categories. A command without it stays loadable from project files but is not offered for
creation.</li>
<li><code>HiNc/SessionCommands/CommandFieldAttribute.cs</code> — the scalar-field declaration the generic editor
renders, with its label, unit and physics-licence gate.</li>
<li><code>HiNc/SessionCommands/ListCommand.cs</code> — the in-order run that skips disabled entries, and the XML
read path that expands a stored bundle in place.</li>
<li><code>HiNc/MachiningProcs/MachiningProject.cs</code> — the same expansion for a bundle stored as the
project's bare root command.</li>
<li><code>HiNc/SessionCommands/MachiningResolutionCommand.cs</code>,
<code>HiNc/SessionCommands/MachiningMotionResolutionCommand.cs</code>,
<code>HiNc/SessionCommands/CollisionDetectionCommand.cs</code>,
<code>HiNc/SessionCommands/PauseOnFailureCommand.cs</code> and <code>HiNc/SessionCommands/PhysicsCommand.cs</code> — the
five Setup commands the web catalog offers, their defaults and their list titles. The detection,
pause and physics settings each carry the &ldquo;from this command on&rdquo; wording.</li>
<li><code>HiNc/MachiningProcs/LocalProjectService.cs</code> — the session's machining resolution and the seeding
from the workpiece's initial resolution on project load or assignment.</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="PostExecutionCommand-panel.html">PostExecutionCommand Panel</a> — the other half of the positional pair: these settings apply forward, those outputs cover everything up to there</li>
<li><a href="../../../manual/run/the-other-commands.html">The Other Commands</a> — the five Setup commands this bundle expands into, as a task</li>
<li><a href="index.html">Mission</a> — the rest of the command panels</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></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,143 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mission | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Mission | HiAPI-C# 2025 ">
<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="">
<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="Anatomy-Mission">
<h1 id="mission">Mission</h1>
<p>Mission is a branch of the Execution page's Control Tree, reached as
<code>/execution?tree=execution/mission</code>. It holds the command list a run executes: the project's own
command is always a list, and nested lists read as sub-trees, so the branch is the mission and the
mission is a tree of commands.</p>
<p>Each command type has its own editor panel. The pages below document one type each; the root panel
documents the list itself — adding, ordering and removing what the run will play.</p>
<p>Ordered by where a command falls in a run: the branch root and its container first, then what is
set up before the run, what the run plays, and what happens after it.</p>
<h2 id="pages">Pages</h2>
<ul>
<li><a href="mission-root-panel.html">Mission Root Panel</a> — The branch root: the command list, and how a mission is assembled</li>
<li><a href="ListCommand-panel.html">List Command Panel</a> — The container command; a nested one becomes a sub-tree of the mission</li>
<li><a href="PreSettingCommand-panel.html">PreSetting Command Panel</a> — What is applied to the machine state before the run reaches a program</li>
<li><a href="NcOptOption-panel.html">NC Optimization Option Panel</a> — The optimizer's options as a command in the list, so a run can change them mid-mission</li>
<li><a href="NcFileCommand-panel.html">NcFile Command Panel</a> — Playing a program file from disk</li>
<li><a href="NcCodeCommand-panel.html">NcCode Command Panel</a> — Playing NC text held in the project rather than in a file</li>
<li><a href="script-command-panel.html">Script Command Panel</a> — Driving the session from C# script rather than from NC</li>
<li><a href="PostExecutionCommand-panel.html">PostExecution Command Panel</a> — What runs once the program above it has finished</li>
</ul>
<p>The pages above do not cover every command kind a mission can hold. Three more ship an editor of
their own — Machining Motion Resolution, Record Meshed Geom and Export Meshed Geom — and the rest
fall back to a generic field editor built from the scalars the command declares, so a kind becomes
addable and editable before anyone writes a panel for it. The set on offer is whatever the server's
command catalog returns, which is why this folder cannot be a closed list.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../index.html">Execution Page</a> — the run cockpit this branch belongs to</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></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,357 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mission Root Panel | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Mission Root Panel | HiAPI-C# 2025 ">
<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="">
<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="Anatomy-MissionRootPanel">
<h1 id="mission-root-panel">Mission Root Panel</h1>
<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>
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
<a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html">ListCommand</a>. The branch root is therefore a list editor — Add Command, the
entries in run order, and the operations that rewrite the list. Editing a command is not this
panel's job: clicking a row selects that command's tree node, and the command's own editor renders
on that 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
<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
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
build stamps its nodes afresh and the editor panels remount onto the new paths.</p>
<h2 id="key-models">Key Models</h2>
<ul>
<li><strong>Primary</strong>: <a class="xref" href="../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> — the mission's command,
always a <code>ListCommand</code>.</li>
<li><strong>Supporting</strong>:
<ul>
<li><a class="xref" href="../../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a></li>
<li><a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html">ListCommand</a> — the root command and every nested one.
<a class="xref" href="../../../api/Hi.SessionCommands.ListCommand.html#Hi_SessionCommands_ListCommand_CommandEntryList">CommandEntryList</a> is the row list, and a run walks it
top-down.</li>
<li><a class="xref" href="../../../api/Hi.SessionCommands.EnablingWrapper.html">EnablingWrapper</a> — one entry: the command plus
<a class="xref" href="../../../api/Hi.SessionCommands.EnablingWrapper.html#Hi_SessionCommands_EnablingWrapper_IsEnabled">IsEnabled</a>.</li>
<li><a class="xref" href="../../../api/Hi.SessionCommands.CommandCatalogAttribute.html">CommandCatalogAttribute</a> and <a class="xref" href="../../../api/Hi.SessionCommands.CommandCategory.html">CommandCategory</a>
— what Add Command offers, and the group it is offered under.</li>
</ul>
</li>
</ul>
<h2 id="layout">Layout</h2>
<ul>
<li>Mission Root Panel
<ul>
<li>Head Line
<ul>
<li>Add Command Button
<ul>
<li>Opens the Add Command dialog. Disabled while no project is open.</li>
</ul>
</li>
<li>Commands Caption</li>
<li>Command Count Badge
<ul>
<li>Outlined, and grey rather than primary while the list is empty.</li>
</ul>
</li>
</ul>
</li>
<li>Separator</li>
<li>Empty State
<ul>
<li>&ldquo;No project loaded&rdquo; while nothing is open; otherwise &ldquo;No commands yet&rdquo;, naming Add Command.</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>
</li>
<li>Run-Order Hint
<ul>
<li>Commands run top-down, and the checkbox on each command's tree item enables or disables it.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Enable/disable is not a control on this 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>
<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
key, or one of its declared aliases — each alias searchable both by its English key and by its word
in the request language. Arrow keys walk the results and Enter takes the highlighted one. Results
are grouped by category, in the catalog's own display order.</p>
<p>The picked command is appended to the list this editor is scoped to, and the branch rebuilds in
place: the selection stays on the list 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
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>
<ul>
<li><strong>Setup</strong> — Machining Resolution, Machining Motion Resolution, Collision Detection, Pause on
Failure, Physics</li>
<li><strong>Program</strong> — Program File, NC Code, Script</li>
<li><strong>Optimization</strong> — NC Optimization Config</li>
<li><strong>Output</strong> — Post-Execution, Record Meshed Geometry, Export Meshed Geometry (STL)</li>
<li><strong>Flow</strong> — List</li>
</ul>
<div class="NOTE">
<h5>Note</h5>
<p>Program File plays NC, CL or CSV. The runner is picked from the file extension, and the command
can override that choice.</p>
</div>
<h2 id="ordering-duplicating-and-deleting">Ordering, Duplicating and Deleting</h2>
<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
list copies with its whole subtree — and the clone lands right after the source. Delete asks for
confirmation in a dialog naming the command.</p>
<p>Dragging a row has three landings:</p>
<ul>
<li>On another row — reorder within this list. A plain row splits at its midline into before and
after, and the whole new order is sent as one ordered path list.</li>
<li>On the middle band of a <code>list</code> row — move the entry inside that list. That row's outer quarters
still reorder around it.</li>
<li>On the drop-out zone of a nested list editor — move the entry out, landing right after the list
command itself in the owning list.</li>
</ul>
<p>The last two are the same reparent call. 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.</p>
<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
lists read as sub-trees at any depth, and the very same panel edits them. The differences are the
scope — the root list, versus the node's own dotted path — and the drop-out zone, which appears only
in a nested editor. A nested list's node adds an optional title above the embedded editor, and that
title is appended to the List name in the row and 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
scopes. A project file whose stored command is something else loads with that command wrapped into
the root list, so the panel always has a list to edit.</p>
<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
rewrite the parent list (Up, Down, Duplicate, Delete):</p>
<ul>
<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="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
Geometry.</li>
<li><code>list</code> is edited inline by the control-bar panel: the optional title over the embedded
<a class="xref" href="ListCommand-panel.html">list editor</a>.</li>
<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
<code>[CommandField]</code> scalars with server-localized labels. That is what the app does instead of
shipping one panel per kind: a catalog kind needs frontend code only when it wants a richer
editor.</li>
</ul>
<p><a class="xref" href="PreSettingCommand-panel.html">General Config</a> is the one asymmetry. Its editor ships and
reads a command, but the catalog does not offer it: a project file that stores the bundle loads as
the individual commands it stands for, and the panel serves projects that construct one through the
API.</p>
<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
surfaced as that section node's tree checkbox. 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>
<p>See <a class="xref" href="../../index.html">HiNC App Anatomy</a> for git repository links.</p>
<h3 id="web-application">Web Application</h3>
<ul>
<li><code>wwwroot-src/src/components/controlTree/MissionRootPanel.vue</code> — this panel: Add Command, the entry
rows and their four actions, the three drag landings, and the delete confirmation. It serves the
Mission root and, embedded under a command's control bar, every nested <code>list</code> node.</li>
<li><code>wwwroot-src/src/components/controlTree/AddCommandDialog.vue</code> — the search-first catalog picker.</li>
<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
list editor of a <code>list</code> entry.</li>
<li><code>wwwroot-src/src/components/controlTree/MissionSectionPanel.vue</code> — the panel of a command's
section child, rendering that one card.</li>
<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
section definitions and their enable flags, and the kind and category icons.</li>
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — builds the Execution root with
the Mission branch node above the Program branch, and drives the command and section checkboxes.</li>
<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>setListTitle</code>, <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
kind with no bespoke panel: the command's reflected <code>[CommandField]</code> scalars.</li>
<li>The bespoke editors:
<ul>
<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/NcFileCommandPanel.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/NcOptOptionCommandPanel.vue</code></li>
<li><code>wwwroot-src/src/components/mission/PostExecutionCommandPanel.vue</code></li>
<li><code>wwwroot-src/src/components/mission/RecordMeshedGeomCommandPanel.vue</code></li>
<li><code>wwwroot-src/src/components/mission/ExportMeshedGeomCommandPanel.vue</code></li>
</ul>
</li>
<li><code>wwwroot-src/src/i18n/en/tree.ts</code> — the <code>tree.mission.*</code> strings this panel renders: Add Command,
the Commands caption, the no-commands-yet state, the drop-out zone, the run-order hint, the kind
display names, the section names and the operation labels.</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>,
<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>,
<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
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
that rejects moving a list into itself or its own descendants.</li>
<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>
<li><code>Missions/MissionCommandFields.cs</code> — the reflection layer behind the generic field endpoints: it
describes and updates a command's <code>[CommandField]</code> scalars.</li>
<li><code>Missions/NcOptOptionEndpoints.cs</code> — the NC Optimization Config per-property PUT endpoints.</li>
</ul>
<h3 id="hiapi-engine">HiAPI Engine</h3>
<ul>
<li><code>HiNc/SessionCommands/CommandCatalogAttribute.cs</code> — <code>CommandCategory</code> and the <code>[CommandCatalog]</code>
attribute (category, order, kind key, aliases), plus the class-name-minus-<code>Command</code> derivation of
the kind key. This is what makes the addable set backend-owned.</li>
<li><code>HiNc/SessionCommands/ListCommand.cs</code> — the container command: the entry list a run walks
top-down, skipping disabled entries.</li>
<li><code>HiNc/MachiningProcs/MachiningProject.cs</code> — declares the mission's command as a list and keeps it
one when a project is read.</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<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>
<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 href="../../../manual/run/building-a-mission.html">Building a Mission</a> — the task this panel serves, as a procedure</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></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,274 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Script Command Panel | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Script Command Panel | HiAPI-C# 2025 ">
<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="">
<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="Anatomy-ScriptCommandPanel">
<h1 id="script-command-panel">Script Command Panel</h1>
<p>The key model is <a class="xref" href="../../../api/Hi.SessionCommands.ScriptCommand.html">ScriptCommand</a>.</p>
<p>The command holds two values: <a class="xref" href="../../../api/Hi.SessionCommands.ScriptCommand.html#Hi_SessionCommands_ScriptCommand_ScriptText">ScriptText</a>, a C# script, and
<a class="xref" href="../../../api/Hi.SessionCommands.ScriptCommand.html#Hi_SessionCommands_ScriptCommand_ScriptTitle">ScriptTitle</a>, the name it runs under. Both are written into
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
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>,
falling back to a bare <code>Script</code> while the title is empty. A newly added command starts empty on both
clients — no title, no text.</p>
<p>The panel renders on the command's own node in the Mission branch of the Execution page's Control
Tree, below the move / duplicate / delete control bar. 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 script is skipped during play and its editor stays
fully usable.</p>
<h2 id="layout">Layout</h2>
<ul>
<li>Head Line
<ul>
<li>Script Title Text Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.ScriptCommand.html#Hi_SessionCommands_ScriptCommand_ScriptTitle">ScriptTitle</a>.</li>
<li>Labelled &ldquo;Title (optional)&rdquo; on the web, &ldquo;Script Title&rdquo; on WPF.</li>
</ul>
</li>
<li>Autosave Indicator (web)
<ul>
<li>Shares the title row. See <a href="#saving">Saving</a>.</li>
</ul>
</li>
</ul>
</li>
<li>Script Editor Area
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.ScriptCommand.html#Hi_SessionCommands_ScriptCommand_ScriptText">ScriptText</a>.</li>
<li>Fills the rest of the panel.</li>
</ul>
</li>
</ul>
<h2 id="the-editor">The Editor</h2>
<p>The web editor is CodeMirror 6 running the <code>mission-script</code> mode: a stream tokenizer written for
the dialect a mission script actually is — top-level statements, not a compilation unit. It colours
keywords and boolean literals, strings (plain, verbatim <code>@&quot;&quot;</code>, interpolated <code>$&quot;&quot;</code> and <code>$@&quot;&quot;</code>),
character literals, hex and floating-point numbers, line and block comments, and it tags a call site
apart from a plain identifier. Because it is linear rather than a parser, every identifier of the
same kind gets the same colour no matter where it sits in the file.</p>
<p>The C# Lezer grammar the client also ships is not what this editor runs: its <code>compilationUnit</code> rule
rejects top-level statements, so it would recover from an error on line 1 and tag identical names
inconsistently. That grammar serves the separate <code>csharp</code> mode a <code>.cs</code> file opens in elsewhere in
the app.</p>
<p>Nothing in the highlighting is semantic. Everything the editor knows about types and members comes
from the backend, through completion.</p>
<h2 id="completion">Completion</h2>
<p>Typing an identifier — or asking explicitly — sends the whole script text plus the zero-based cursor
offset to <code>POST /api/script/completions</code>, and the response is an <code>items</code> array. Each item carries a
label, a kind already normalised to CodeMirror's own completion type names, a <code>detail</code> (the
signature, shown dim beside the label), a <code>documentation</code> (the XML <code>&lt;summary&gt;</code>, rendered to plain
text by Roslyn and shown in the popup's info pane) and an <code>insertText</code>.</p>
<p>Completion is Roslyn in-process, over the very <code>ScriptOptions</code> — the same references and imports —
that the run compiles the script with, so the session shell's members and the runtime API surface
complete for real rather than by name matching. The service prepends the synthesised
<code>using</code> / <code>using static</code> prefix those imports need and offsets the cursor by its length, so what the
list offers is what the evaluator will see. A cancelled request is answered 499, and a result that
arrives after the editor has moved on is dropped rather than shown.</p>
<p>Picking a method inserts the server-formatted call with each argument as a Tab stop, so the cursor
lands on the first parameter and Tab walks the rest; a method with no parameters inserts as <code>()</code>.
Properties, fields, types and keywords insert as their plain text — a snippet there would be noise.</p>
<h2 id="saving">Saving</h2>
<p>There is no Save button. Every keystroke in either field updates the model and schedules one save
500 ms after the last edit, and the pill beside the title reports the state: Idle, Dirty, Staging…,
Staged, or Error with the message in its tooltip. Staged means the server runtime holds the value —
its tooltip says so, because a staged script is not yet a committed project.</p>
<p>The write is a single PUT carrying the script text, the title and the content hash the last load or
save handed back. Each field is applied only when the body carries it. The response returns the new
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>
<ul>
<li><strong>Unsaved Changes</strong>, raised when the Control Tree tries to move the selection off a command whose
save is still pending: Save &amp; switch flushes and then allows the switch, Discard drops the pending
write, Cancel keeps the selection where it is.</li>
<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
the server's current text, title and hash, so the panel can offer Discard &amp; reload, Force
overwrite, or Cancel without a second round trip.</li>
</ul>
<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
when it fires. 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>
<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
therefore compile-checks every enabled script first — with the same script options and globals type
the evaluator uses — and refuses to start when any of them has an error, naming the first offender's
title, path, diagnostic id, message and line. The SPA's Start sends nothing to bypass that check, so
the refusal is what a user sees. The same check is also an endpoint of its own, per command and for
the whole mission.</p>
<h2 id="the-two-clients">The Two Clients</h2>
<p>The desktop client edits the same command in AvalonEdit: a bold Script Title label with its text
box, a Script Text label, and the editor with C# syntax highlighting and a line-number gutter,
bound to the command through an attached behaviour. There is no completion popup and no autosave —
the binding writes straight into the command as the text changes.</p>
<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>
<h3 id="web-application">Web Application</h3>
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
<ul>
<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
three-button prompts, the path snapshot taken at mount, and the change notice that relabels the
tree node.</li>
<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
dirty the autosave, an opt-in completion source that overrides the language's own, and a widened
monospace popup so full signatures fit before the dim detail column truncates.</li>
<li><code>wwwroot-src/src/components/widgets/missionScriptLanguage.ts</code> — the <code>mission-script</code> mode: the
keyword set, the string and character rules, numbers, comments, call-site tagging, and its own
highlight style.</li>
<li><code>wwwroot-src/src/components/mission/csharpCompletionSource.ts</code> — the completion source: fires on
an identifier prefix or an explicit request, sends the whole document with the cursor offset,
drops stale results, and applies every candidate as a snippet.</li>
<li><code>wwwroot-src/src/api/scriptCompletion.ts</code> — the typed wrapper over the completion endpoint and the
kind union that maps straight onto CodeMirror's completion types.</li>
<li><code>wwwroot-src/src/api/mission.ts</code> — the script command shape (text, title, content hash), its
loader, the save that carries the expected hash, and the conflict error that carries the server's
current copy.</li>
<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>
<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
through the active panel's switch gate, which is how the Unsaved Changes prompt gets its say.</li>
<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>
<li><code>wwwroot-src/src/i18n/en/mission.ts</code> — the panel's wording: both prompts, their buttons, and the
load and save error contexts.</li>
<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>
<li><code>Missions/ScriptCompletionService.cs</code> — the singleton holding one workspace, built from the same
script options the session evaluates with, and the snippet insert text it builds for methods.</li>
<li><code>Missions/ScriptCompileCheckService.cs</code> — compiles a script without running it, and walks the
mission for every enabled one; it backs the two compile-check endpoints and the pre-start gate.</li>
<li><code>Missions/MissionController.cs</code> — the single script PUT with its hash-based concurrency, the
content hash stamped into the command snapshot, and the two compile-check endpoints.</li>
<li><code>Execution/ExecutionController.cs</code> — the start gate that compile-checks the enabled scripts and
refuses to run while one of them has an error.</li>
</ul>
<h3 id="hiapi-engine">HiAPI Engine</h3>
<ul>
<li><code>HiNc/SessionCommands/ScriptCommand.cs</code> — the model: the title and text, the Program-category
catalog registration, the XML round-trip that puts the script into the project file, the
evaluation against the session shell with a compile failure reported into the run's message
stream, the returned actions yielded into the run, and the label rule that brackets the title
after the command name.</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="NcCodeCommand-panel.html">NcCodeCommand Panel</a> — the other command that stores its text in the project, and the one that ships no editor chrome</li>
<li><a href="../../../manual/run/the-other-commands.html">The Other Commands</a> — the task this command serves, beside the settings and output kinds</li>
<li><a href="index.html">Mission</a> — the rest of the command panels</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></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,46 @@
<div id="sidetoggle">
<div>
<div class="sidefilter">
<form class="toc-filter">
<span class="glyphicon glyphicon-filter filter-icon"></span>
<span class="glyphicon glyphicon-remove clear-icon" id="toc_filter_clear"></span>
<input type="text" id="toc_filter_input" placeholder="Filter by title" onkeypress="if(event.keyCode==13) {return false;}">
</form>
</div>
<div class="sidetoc">
<div class="toc" id="toc">
<ul class="nav level1">
<li>
<a href="index.html" name="" title="Overview">Overview</a>
</li>
<li>
<a href="mission-root-panel.html" name="" title="Mission Root Panel">Mission Root Panel</a>
</li>
<li>
<a href="ListCommand-panel.html" name="" title="List Command Panel">List Command Panel</a>
</li>
<li>
<a href="PreSettingCommand-panel.html" name="" title="PreSetting Command Panel">PreSetting Command Panel</a>
</li>
<li>
<a href="NcOptOption-panel.html" name="" title="NcOptOption Panel">NcOptOption Panel</a>
</li>
<li>
<a href="NcFileCommand-panel.html" name="" title="NcFile Command Panel">NcFile Command Panel</a>
</li>
<li>
<a href="NcCodeCommand-panel.html" name="" title="NcCode Command Panel">NcCode Command Panel</a>
</li>
<li>
<a href="script-command-panel.html" name="" title="Script Command Panel">Script Command Panel</a>
</li>
<li>
<a href="PostExecutionCommand-panel.html" name="" title="PostExecution Command Panel">PostExecution Command Panel</a>
</li>
</ul>
</div>
</div>
</div>
</div>
@@ -0,0 +1,2 @@
{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"Mission Root Panel","href":"mission-root-panel.html","topicHref":"mission-root-panel.html"},{"name":"List Command Panel","href":"ListCommand-panel.html","topicHref":"ListCommand-panel.html"},{"name":"PreSetting Command Panel","href":"PreSettingCommand-panel.html","topicHref":"PreSettingCommand-panel.html"},{"name":"NcOptOption Panel","href":"NcOptOption-panel.html","topicHref":"NcOptOption-panel.html"},{"name":"NcFile Command Panel","href":"NcFileCommand-panel.html","topicHref":"NcFileCommand-panel.html"},{"name":"NcCode Command Panel","href":"NcCodeCommand-panel.html","topicHref":"NcCodeCommand-panel.html"},{"name":"Script Command Panel","href":"script-command-panel.html","topicHref":"script-command-panel.html"},{"name":"PostExecution Command Panel","href":"PostExecutionCommand-panel.html","topicHref":"PostExecutionCommand-panel.html"}]}