deploy webservice static-file routing for docsite folder URLs, per-instance step-cache db, and constant-height panel title bars.
This commit is contained in:
@@ -89,14 +89,15 @@
|
||||
|
||||
<p>HiNc applications use three independent message categories. Each category serves a distinct purpose and should not be mixed.</p>
|
||||
<h2 id="categories">Categories</h2>
|
||||
<h3 id="1-diagnostic--iprogressobject">1. Diagnostic — <code>IProgress<object></code></h3>
|
||||
<p>Operation-scoped progress and diagnostic messages. The caller provides an <code>IProgress<object></code> to the callee, which reports progress, warnings, and errors through it.</p>
|
||||
<h3 id="1-diagnostic--iprogressimessage">1. Diagnostic — <code>IProgress<IMessage></code></h3>
|
||||
<p>Operation-scoped progress and diagnostic messages. The caller provides an <code>IProgress<IMessage></code> sink to the callee, which reports progress, warnings, and errors through it. Every <a class="xref" href="../../api/Hi.Common.Messages.IMessage.html">IMessage</a> carries a <a class="xref" href="../../api/Hi.Common.Messages.Severity.html">Severity</a>, a <a class="xref" href="../../api/Hi.Common.Messages.Category.html">Category</a>, and a filterable id.</p>
|
||||
<ul>
|
||||
<li><strong>Session-scoped</strong>: <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_SessionProgress">SessionProgress</a> feeds the <a href="../../app-anatomy/session-message-panel/index.html">Session Message Panel</a>.</li>
|
||||
<li><strong>XML IO chain</strong>: <a class="xref" href="../../api/Hi.Common.XmlUtils.XFactory.html">XFactory</a> threads <code>IProgress<object></code> through all deserialization calls so that parsing errors are reported to the caller rather than a global handler.</li>
|
||||
<li><strong>Script-level</strong>: <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_SessionProgress">SessionProgress</a> exposes the session progress to user scripts.</li>
|
||||
<li><strong>Session-scoped</strong>: <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_ShellProgress">ShellProgress</a> feeds the <a href="../../app-anatomy/session-message-panel/index.html">Session Message Panel</a>; <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_StepDiagnosticProgress">StepDiagnosticProgress</a> retains step-anchored diagnostics and <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_NcDiagnosticProgress">NcDiagnosticProgress</a> retains NC-parsing diagnostics.</li>
|
||||
<li><strong>XML IO chain</strong>: <a class="xref" href="../../api/Hi.Common.XmlUtils.XFactory.html">XFactory</a> threads <code>IProgress<IMessage></code> through all deserialization calls so that parsing errors are reported to the caller rather than a global handler.</li>
|
||||
<li><strong>Script-level</strong>: <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_ShellProgress">ShellProgress</a> exposes the session sink to user scripts.</li>
|
||||
<li><strong>Per-call</strong>: inject a <a class="xref" href="../../api/Hi.Common.Messages.MessageCollector.html">MessageCollector</a> to buffer one call's messages and read them back afterwards (e.g., to return them inline in an HTTP response).</li>
|
||||
</ul>
|
||||
<p>Use <a class="xref" href="../../api/Hi.Common.Messages.MultiTagMessageUtil.html">MultiTagMessageUtil</a> extension methods (<code>ReportProgress</code>, <code>ReportMessage</code>, <code>ReportWarning</code>, <code>ReportError</code>, <code>ReportInfo</code>) to report typed messages.</p>
|
||||
<p>Use the <a class="xref" href="../../api/Hi.Common.Messages.MessageUtil.html">MessageUtil</a> id-first helpers (<code>SystemError</code>, <code>SystemWarning</code>, <code>ValidationWarning</code>, <code>ConfigurationWarning</code>, …) to report typed messages.</p>
|
||||
<h3 id="2-ui-error-notification--messageboardutil">2. UI Error Notification — <code>MessageBoardUtil</code></h3>
|
||||
<p>Toast-style popups for immediate user attention (e.g., “File saved”, “Load failed”). <a class="xref" href="../../api/Hi.Common.Messages.MessageBoardUtil.html">MessageBoardUtil</a> triggers the <code>ShowMessageBoard</code> event consumed by the GUI layer.</p>
|
||||
<div class="NOTE">
|
||||
@@ -107,9 +108,9 @@
|
||||
<p>Standard .NET <code>ILogger</code> for application-level logging. Use <a class="xref" href="../../api/Hi.Common.Messages.ActionProgress-1.html">ActionProgress<T></a>.<a class="xref" href="../../api/Hi.Common.Messages.ActionProgress-1.html#Hi_Common_Messages_ActionProgress_1_FromLogger_">FromLogger</a> to bridge <code>IProgress<object></code> APIs to an <code>ILogger</code> instance:</p>
|
||||
<pre><code class="lang-csharp">IProgress<object> progress = ActionProgress<object>.FromLogger(logger);
|
||||
</code></pre>
|
||||
<p>This routes <a class="xref" href="../../api/Hi.Common.Messages.MultiTagMessage.html">MultiTagMessage</a> to the appropriate log level (<code>LogError</code>, <code>LogWarning</code>, <code>LogInformation</code>) based on message tags.</p>
|
||||
<p>This routes each reported <a class="xref" href="../../api/Hi.Common.Messages.IMessage.html">IMessage</a> (or raw <code>Exception</code>) to the appropriate log level (<code>LogError</code>, <code>LogWarning</code>, <code>LogInformation</code>) based on its severity.</p>
|
||||
<h2 id="basic-component--utility-level">Basic-Component / Utility Level</h2>
|
||||
<p>Low-level utilities (e.g., in <code>Hi.Common</code>, <code>Hi.Geom</code>) cannot assume which category the caller intends. These APIs accept <code>Action<Exception></code> or <code>IProgress<object></code> as parameters so the caller decides how to handle messages:</p>
|
||||
<p>Low-level utilities (e.g., in <code>Hi.Common</code>, <code>Hi.Geom</code>) cannot assume which category the caller intends. These APIs accept <code>Action<Exception></code> or <code>IProgress<IMessage></code> as parameters so the caller decides how to handle messages:</p>
|
||||
<pre><code class="lang-csharp">await task.CatchExceptions(ex => progress?.Report(ex));
|
||||
</code></pre>
|
||||
<h2 id="design-rationale">Design Rationale</h2>
|
||||
|
||||
@@ -152,15 +152,15 @@ public static void Reg(XFactory factory = null)
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="iprogress-threading">IProgress Threading</h3>
|
||||
<p>The <code>IProgress<object></code> parameter is threaded through the entire deserialization chain. When a class constructor calls <a class="xref" href="../../api/Hi.Common.XmlUtils.XFactory.html">XFactory</a> to deserialize child objects, it passes the same <code>progress</code> instance:</p>
|
||||
<p>The <code>IProgress<IMessage></code> parameter is threaded through the entire deserialization chain. When a class constructor calls <a class="xref" href="../../api/Hi.Common.XmlUtils.XFactory.html">XFactory</a> to deserialize child objects, it passes the same <code>progress</code> instance:</p>
|
||||
<pre><code class="lang-csharp">public MyClass(XElement src, string baseDirectory, string relFile,
|
||||
IProgress<object> progress)
|
||||
IProgress<IMessage> progress)
|
||||
{
|
||||
Child = XFactory.GenByChild<IChild>(
|
||||
src.Element(nameof(Child)), subBaseDirectory, progress);
|
||||
}
|
||||
</code></pre>
|
||||
<p>Parsing errors are reported to the caller-provided <code>IProgress<object></code> handler.</p>
|
||||
<p>Parsing errors are reported to the caller-provided <code>IProgress<IMessage></code> handler.</p>
|
||||
<h2 id="boot-path">Boot path</h2>
|
||||
<p>An application's entry point (web service <code>Program.cs</code>, WPF <code>App.xaml.cs</code>, test fixture, etc.) must call the appropriate top-level <code>Reg()</code> once at startup, before any project XML is deserialized. For the simulation pipeline this is:</p>
|
||||
<pre><code class="lang-csharp">LocalProjectService.Reg();
|
||||
@@ -336,7 +336,7 @@ public XElement MakeXmlSource(string baseDirectory, string relFile, bool exhibit
|
||||
<li><strong>Registration</strong>: Expose <code>public static void Reg(XFactory factory = null)</code>; first line is <code>factory ??= XFactory.Default;</code> then <code>factory.Generators.TryAdd(XName, …)</code>.</li>
|
||||
<li><strong>Chain dependents</strong>: For every concrete type T that the ctor reads via <code>XFactory.Gen<T></code> / <code>XFactory.GenByChild<T></code>, add <code>T.Reg(factory);</code> to the chain. For polymorphic <code>GenByChild<IInterface></code>, chain every implementation that the XML may carry.</li>
|
||||
<li><strong>Idempotent</strong>: Use <code>TryAdd</code>, never <code>Add</code>. The same <code>Reg</code> is called from many boot paths.</li>
|
||||
<li><strong>Progress Threading</strong>: Pass the <code>IProgress<object></code> parameter through all nested <code>XFactory</code> calls. See <a href="message-management.html">Message Management</a> for the rationale.</li>
|
||||
<li><strong>Progress Threading</strong>: Pass the <code>IProgress<IMessage></code> parameter through all nested <code>XFactory</code> calls. See <a href="message-management.html">Message Management</a> for the rationale.</li>
|
||||
<li><strong>Legacy Support</strong>: Register the canonical <code>XName</code> first, then group aliases under a <code>//legacy aliases</code> comment.</li>
|
||||
<li><strong>Derived class registration</strong>: When a derived class needs its own <code>Reg</code>, mark it <code>public new static void Reg(XFactory factory = null)</code> so the C# compiler does not warn about hiding the base method.</li>
|
||||
</ol>
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
</ul>
|
||||
<p>The <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_PacePlayer">PacePlayer</a> controls the execution pace of the simulation, allowing you to observe the machining process in detail or run it at full speed.</p>
|
||||
<h3 id="view-the-analysis-during-process-or-result">View the Analysis During Process or Result</h3>
|
||||
<p><a class="xref" href="../../api/Hi.MachiningProcs.SessionProgress.html">SessionProgress</a> contains a sequence of simulation messages and step data, which can be used to monitor and analyze the simulation process and results.</p>
|
||||
<p><a class="xref" href="../../api/Hi.MachiningProcs.ShellProgress.html">ShellProgress</a> contains a sequence of simulation messages and step data, which can be used to monitor and analyze the simulation process and results.</p>
|
||||
<h2 id="ui-pattern">UI Pattern</h2>
|
||||
<p>The user interface navigation bar matches the workflow. Top-level navigation items include:</p>
|
||||
<ul>
|
||||
|
||||
@@ -111,93 +111,92 @@ using Hi.NcMech.Holders;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hi.Milling.MillingTools
|
||||
namespace Hi.Milling.MillingTools;
|
||||
|
||||
/// <summary>
|
||||
/// Display host for a milling tool composed of a cutter and a holder.
|
||||
/// </summary>
|
||||
public class MillingToolEditorDisplayee : ITopoDisplayee, IClearCache
|
||||
{
|
||||
/// <summary>
|
||||
/// Display host for a milling tool composed of a cutter and a holder.
|
||||
/// Gets or sets the delegate that provides the <see cref="MillingTool"/> instance.
|
||||
/// </summary>
|
||||
public class MillingToolEditorDisplayee : ITopoDisplayee, IClearCache
|
||||
public Func<MillingTool> MillingToolGetter { get; set; }
|
||||
/// <summary>
|
||||
/// Gets the current <see cref="MillingTool"/> instance.
|
||||
/// </summary>
|
||||
public MillingTool MillingTool => MillingToolGetter?.Invoke();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether to show the cutter.
|
||||
/// </summary>
|
||||
public bool ShowCutter { get; set; } = true;
|
||||
/// <summary>
|
||||
/// Gets or sets whether to show the holder.
|
||||
/// </summary>
|
||||
public bool ShowHolder { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the displayee for the milling cutter.
|
||||
/// </summary>
|
||||
public MillingCutterEditorDisplayee MillingCutterEditorDisplayee { get; }
|
||||
= new MillingCutterEditorDisplayee();
|
||||
/// <summary>
|
||||
/// Gets the displayee for the holder.
|
||||
/// </summary>
|
||||
public HolderEditorDisplayee HolderEditorDisplayee { get; }
|
||||
= new HolderEditorDisplayee();
|
||||
/// <inheritdoc/>
|
||||
public List<IAnchoredDisplayee> GetAnchoredDisplayeeList()
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the delegate that provides the <see cref="MillingTool"/> instance.
|
||||
/// </summary>
|
||||
public Func<MillingTool> MillingToolGetter { get; set; }
|
||||
/// <summary>
|
||||
/// Gets the current <see cref="MillingTool"/> instance.
|
||||
/// </summary>
|
||||
public MillingTool MillingTool => MillingToolGetter?.Invoke();
|
||||
var dst = new List<IAnchoredDisplayee>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether to show the cutter.
|
||||
/// </summary>
|
||||
public bool ShowCutter { get; set; } = true;
|
||||
/// <summary>
|
||||
/// Gets or sets whether to show the holder.
|
||||
/// </summary>
|
||||
public bool ShowHolder { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the displayee for the milling cutter.
|
||||
/// </summary>
|
||||
public MillingCutterEditorDisplayee MillingCutterEditorDisplayee { get; }
|
||||
= new MillingCutterEditorDisplayee();
|
||||
/// <summary>
|
||||
/// Gets the displayee for the holder.
|
||||
/// </summary>
|
||||
public HolderEditorDisplayee HolderEditorDisplayee { get; }
|
||||
= new HolderEditorDisplayee();
|
||||
/// <inheritdoc/>
|
||||
public List<IAnchoredDisplayee> GetAnchoredDisplayeeList()
|
||||
{
|
||||
var dst = new List<IAnchoredDisplayee>();
|
||||
|
||||
var millingTool = MillingTool;
|
||||
if (millingTool == null)
|
||||
return dst;
|
||||
|
||||
if (ShowCutter)
|
||||
{
|
||||
var cutter = millingTool.Cutter;
|
||||
if (cutter is MillingCutter millingCutter)
|
||||
{
|
||||
//MessageKit.AddMessage($"MillingTool.Cutter: {MillingTool?.Cutter?.GetHashCode()}");
|
||||
MillingCutterEditorDisplayee.MillingCutterSourceFunc
|
||||
= () => MillingTool?.Cutter as MillingCutter;
|
||||
dst.Add(MillingCutterEditorDisplayee);
|
||||
}
|
||||
else if(cutter!=null)
|
||||
dst.Add(cutter);
|
||||
}
|
||||
if (ShowHolder)
|
||||
{
|
||||
HolderEditorDisplayee.Holder = millingTool.Holder;
|
||||
dst.Add(HolderEditorDisplayee);
|
||||
}
|
||||
var millingTool = MillingTool;
|
||||
if (millingTool == null)
|
||||
return dst;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void Display(Bind bind)
|
||||
{
|
||||
bind.PushCoveringPixelMode();
|
||||
DimensionBar.Display(bind, "mm");
|
||||
bind.ModelMatStack.Pop();
|
||||
|
||||
TopoDisplayeeUtil.Display(this, bind);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void ExpandToBox3d(Box3d dst)
|
||||
if (ShowCutter)
|
||||
{
|
||||
TopoDisplayeeUtil.ExpandToBox3d(this, dst);
|
||||
var cutter = millingTool.Cutter;
|
||||
if (cutter is MillingCutter millingCutter)
|
||||
{
|
||||
//MessageKit.AddMessage($"MillingTool.Cutter: {MillingTool?.Cutter?.GetHashCode()}");
|
||||
MillingCutterEditorDisplayee.MillingCutterSourceFunc
|
||||
= () => MillingTool?.Cutter as MillingCutter;
|
||||
dst.Add(MillingCutterEditorDisplayee);
|
||||
}
|
||||
else if(cutter!=null)
|
||||
dst.Add(cutter);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public Asmb GetAsmb() => MillingTool?.Asmb;
|
||||
/// <inheritdoc/>
|
||||
public Anchor GetAnchor() => MillingTool?.GetAnchor();
|
||||
/// <inheritdoc/>
|
||||
public void ClearCache()
|
||||
if (ShowHolder)
|
||||
{
|
||||
MillingCutterEditorDisplayee?.ClearCache();
|
||||
HolderEditorDisplayee.Holder = millingTool.Holder;
|
||||
dst.Add(HolderEditorDisplayee);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void Display(Bind bind)
|
||||
{
|
||||
bind.PushCoveringPixelMode();
|
||||
DimensionBar.Display(bind, "mm");
|
||||
bind.ModelMatStack.Pop();
|
||||
|
||||
TopoDisplayeeUtil.Display(this, bind);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void ExpandToBox3d(Box3d dst)
|
||||
{
|
||||
TopoDisplayeeUtil.ExpandToBox3d(this, dst);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public Asmb GetAsmb() => MillingTool?.Asmb;
|
||||
/// <inheritdoc/>
|
||||
public Anchor GetAnchor() => MillingTool?.GetAnchor();
|
||||
/// <inheritdoc/>
|
||||
public void ClearCache()
|
||||
{
|
||||
MillingCutterEditorDisplayee?.ClearCache();
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
@@ -0,0 +1,473 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>NC Parsing Engine | HiAPI-C# 2025 </title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="title" content="NC Parsing Engine | 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 "{query}"">
|
||||
<meta name="loc:searchNoResults" content="No results for "{query}"">
|
||||
<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="Fundamentals-NcParsingEngine">
|
||||
<h1 id="nc-parsing-engine">NC Parsing Engine</h1>
|
||||
|
||||
<p><a class="xref" href="../../api/Hi.NcParsers.SoftNcRunner.html">SoftNcRunner</a> is the NC interpreter. It reads a controller program — Fanuc,
|
||||
Siemens, Syntec, Mazak or Heidenhain G-code, an NX cutter-location file, or a CSV controller
|
||||
recording — and turns it into the machine actions the simulation executes.</p>
|
||||
<p>It is a <strong>composed</strong> interpreter rather than a fixed one. The segmenter, the initializers, the
|
||||
syntax stages, the semantics and the dependency data are five ordered lists on the runner object,
|
||||
all of them serializable. Adding support for a G-code means adding one syntax unit and one line to a
|
||||
list; removing support means removing that line. Nothing about a brand is compiled into a central
|
||||
class.</p>
|
||||
<div class="NOTE">
|
||||
<h5>Note</h5>
|
||||
<p><code>SoftNcRunner</code> is the default NC pipeline as of 3.2
|
||||
(<a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_EnableSoftNcRunner">EnableSoftNcRunner</a> defaults to <code>true</code>).
|
||||
<a class="xref" href="../../api/Hi.Numerical.FilePlayers.HardNcRunner.html">HardNcRunner</a> remains reachable as the opt-out fallback for the
|
||||
shrinking set of features still bound to it.</p>
|
||||
</div>
|
||||
<h2 id="the-pipeline">The pipeline</h2>
|
||||
<p>A program becomes actions in five ordered stages. Each shipped preset expresses them as five
|
||||
<a class="xref" href="../../api/Hi.NcParsers.Syntaxs.BundleSyntax.html">BundleSyntax</a> containers named <code>Parsing</code>, <code>Evaluation</code>, <code>Logic</code>,
|
||||
<code>PostLogic</code> and <code>Inspection</code>.</p>
|
||||
<pre><code class="lang-mermaid">graph TD
|
||||
A[NC raw lines] --> SEG[ISegmenter]
|
||||
SEG --> SENT[Sentence stream]
|
||||
SENT --> INIT[INcInitializer]
|
||||
INIT --> P[Parsing<br/>text to structure]
|
||||
P --> E[Evaluation<br/>variables, expressions,<br/>calls, control flow]
|
||||
E --> L[Logic<br/>modal state, coordinates,<br/>compensation, motion]
|
||||
L --> PL[PostLogic<br/>modal carry]
|
||||
PL --> I[Inspection<br/>backfill, unconsumed check,<br/>snapshot]
|
||||
I --> SEM[INcSemantic]
|
||||
SEM --> OUT[Machine actions]
|
||||
|
||||
DEP[INcDependency list<br/>brand tables, coordinate systems,<br/>tool offsets, kinematics, ...]
|
||||
DEP -. injected .-> P
|
||||
DEP -. injected .-> E
|
||||
DEP -. injected .-> L
|
||||
DEP -. injected .-> SEM
|
||||
</code></pre>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Stage</th>
|
||||
<th>Responsibility</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.NcParsers.Segmenters.ISegmenter.html">ISegmenter</a></td>
|
||||
<td>cuts the raw text into blocks. Three implementations ship — one line per block, and the two multi-line forms Heidenhain and Siemens programs need</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.NcParsers.Initializers.INcInitializer.html">INcInitializer</a></td>
|
||||
<td>seeds the stream head with the machine's starting state, for example the configured home position</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Parsing</strong></td>
|
||||
<td>recognizes the text: words, statements, cycle bodies, comments. Writes structure, never meaning</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Evaluation</strong></td>
|
||||
<td>resolves anything the block computes for itself — variable reads and writes, arithmetic, conditional jumps, loops, and subprogram or macro calls, whose bodies are spliced into the stream so later stages walk them as if they had always been in the host file</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Logic</strong></td>
|
||||
<td>the modal machine model: units, positioning mode, plane, feed, spindle, coolant, tool change and compensation, work offsets, tilt and RTCP, and the program-to-machine coordinate chain</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>PostLogic</strong></td>
|
||||
<td>carries the block's full modal context forward, so every block's data is self-contained</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Inspection</strong></td>
|
||||
<td>back-fills derived values, reports words nothing consumed, and optionally snapshots the block</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.NcParsers.Semantics.INcSemantic.html">INcSemantic</a></td>
|
||||
<td>turns the finished block into machine actions — linear and arc motion, teleports, tool change, spindle, dwell, stroke-limit checks</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Over 150 syntax units ship across those five stages, plus the per-brand lists that select and order
|
||||
them.</p>
|
||||
<p>Most syntax units implement <a class="xref" href="../../api/Hi.NcParsers.Syntaxs.ISituNcSyntax.html">ISituNcSyntax</a> — they mutate the block in
|
||||
place. <a class="xref" href="../../api/Hi.NcParsers.Syntaxs.IExpandingNcSyntax.html">IExpandingNcSyntax</a> exists for a unit that must turn one block into
|
||||
several. Note that the shipped call and repeat syntaxes are <em>not</em> expanders: they splice the callee's
|
||||
already-segmented blocks into the stream ahead of the current position, which keeps one block's
|
||||
identity intact through the rest of the pipeline.</p>
|
||||
<h2 id="composition-and-presets">Composition and presets</h2>
|
||||
<p>The runner is a container; its five lists are what make it a Fanuc runner or a Heidenhain one.</p>
|
||||
<pre><code class="lang-xml"><SoftNcRunner>
|
||||
<PipelineNcDependencyList>...</PipelineNcDependencyList>
|
||||
<Segmenter>...</Segmenter>
|
||||
<NcInitializationList>...</NcInitializationList>
|
||||
<NcSyntaxList>...</NcSyntaxList>
|
||||
<NcSemanticList>...</NcSemanticList>
|
||||
</SoftNcRunner>
|
||||
</code></pre>
|
||||
<p>Every unit implements <a class="xref" href="../../api/Hi.Common.XmlUtils.IMakeXmlSource.html">IMakeXmlSource</a> and registers itself with
|
||||
<a class="xref" href="../../api/Hi.Common.XmlUtils.XFactory.html">XFactory</a>, so the whole pipeline round-trips through XML. Seven presets are
|
||||
built in:</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Preset</th>
|
||||
<th>Reads</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_FanucNcRunner">FanucNcRunner</a></td>
|
||||
<td>Fanuc G-code, including Custom Macro B</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_SiemensNcRunner">SiemensNcRunner</a></td>
|
||||
<td>Sinumerik <code>.mpf</code> / <code>.spf</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_SyntecNcRunner">SyntecNcRunner</a></td>
|
||||
<td>Syntec G-code</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_MazakNcRunner">MazakNcRunner</a></td>
|
||||
<td>Mazak EIA/ISO</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_HeidenhainNcRunner">HeidenhainNcRunner</a></td>
|
||||
<td>klartext <strong>and</strong> DIN/ISO, on one preset</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.Numerical.CsvParsers.GeneralCsvRunner.html">GeneralCsvRunner</a></td>
|
||||
<td>a CSV controller recording</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.Numerical.ClsfParsers.NxClRunner.html">NxClRunner</a></td>
|
||||
<td>NX CLSF / APT-source cutter-location files</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The five brand presets also ship as standalone files under <code>Resource/Controller/</code> with the
|
||||
<code>.Controller</code> extension, written by <a class="xref" href="../../api/Hi.NcParsers.ControllerPresetWriter.html">ControllerPresetWriter</a>, so the load browser
|
||||
starts populated. Those files are regenerable snapshots — the static properties above are the source
|
||||
of truth, and the files are rewritten whenever a brand pipeline changes.</p>
|
||||
<div class="IMPORTANT">
|
||||
<h5>Important</h5>
|
||||
<p>Reading a preset file back requires the pipeline types to be registered first
|
||||
(<a class="xref" href="../../api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_Reg_">Reg</a> through
|
||||
<a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_Reg_">Reg</a> at startup). The loader <strong>drops unregistered
|
||||
entries silently</strong> rather than failing the load, so an unregistered process reads a hollow
|
||||
pipeline that parses nothing.</p>
|
||||
<p>A runner rehydrated from an older saved file keeps the syntax list it was saved with — nothing
|
||||
re-derives a brand's syntax list at read time. To pick up new brand syntaxes, take the current
|
||||
preset or a fresh <a class="xref" href="../../api/Hi.NcParsers.NcRunnerSuit.html">NcRunnerSuit</a> built from it. Missing <em>system-wired</em>
|
||||
dependencies are back-filled automatically on load; syntaxes are not.</p>
|
||||
</div>
|
||||
<h2 id="the-dataflow">The dataflow</h2>
|
||||
<p>Each block travels the pipeline as a <a class="xref" href="../../api/Hi.NcParsers.Syntaxs.SyntaxPiece.html">SyntaxPiece</a> carrying a JSON object.
|
||||
Every stage reads some keys, writes some keys, and removes the keys it has consumed. The convention
|
||||
is <strong>section plus term</strong>: the section key is a semantic name that is the same across brands
|
||||
(<code>Unit</code>, <code>Feedrate</code>, <code>Motion</code>, <code>CoordinateOffset</code>), while the controller's actual keyword lives in
|
||||
the section's <code>Term</code> field so the correspondence with the source text is never lost.</p>
|
||||
<p>A Fanuc block <code>N162 X-14.696 Y-6.42 Z45.638</code>, after the pipeline (matrices elided):</p>
|
||||
<pre><code class="lang-json">{
|
||||
"IndexNote": {"Symbol":"N","Number":162},
|
||||
"Positioning": {"Term":"G90","Mode":"Absolute"},
|
||||
"Unit": {"Term":"G21","System":"Metric"},
|
||||
"PlaneSelect": {"Term":"G17","Plane":"XY"},
|
||||
"Feedrate": {"FeedrateValue":400,"Term":"G94","Unit":"mm/min"},
|
||||
"SpindleSpeed": {"SpindleSpeed_rpm":20000,"Direction":"CW"},
|
||||
"Coolant": {"IsOn":true,"Mode":"Flood"},
|
||||
"ToolChange": {"ToolId":4,"IsChange":false},
|
||||
"TiltTransform": {"Term":"G68.2"},
|
||||
"EndPointProgramToMcTransform": [
|
||||
{"Source":"TiltTransform", "Mat4d":[ ... ]},
|
||||
{"Source":"ToolHeightCompensation", "Mat4d":[ ... ]},
|
||||
{"Source":"CoordinateOffset", "Mat4d":[ ... ]},
|
||||
{"Source":"PivotTransform", "Mat4d":[ ... ]}
|
||||
],
|
||||
"ToolHeightCompensation": {"Offset_mm":16,"Term":"G43","OffsetId":4},
|
||||
"CoordinateOffset": {"CoordinateId":"G54","Offset_X":72.4,"Offset_Y":-72.4,"Offset_Z":-116.44},
|
||||
"ProgramXyz": {"X":-14.696,"Y":-6.42,"Z":45.638},
|
||||
"MachineCoordinate": {"X":140.5947,"Y":-78.8200,"Z":-124.4559},
|
||||
"MotionState": {"Term":"G01"},
|
||||
"MotionEvent": {"Form":"McLinear","IsRapid":false},
|
||||
"RadiusCompensation": {"Term":"G40","OffsetId":0,"Radius_mm":0}
|
||||
}
|
||||
</code></pre>
|
||||
<p>Three things are worth reading off that block.</p>
|
||||
<p><strong>Program and machine coordinates are both present.</strong> The source states program coordinates; the
|
||||
pipeline keeps them and adds the solved machine coordinates, so a report or a UI can use either.</p>
|
||||
<p><strong><code>EndPointProgramToMcTransform</code> flattens the cause chain.</strong> The program-to-machine mapping is not
|
||||
one opaque matrix but the ordered list of contributions that built it — tilt, tool height, work
|
||||
offset, pivot — each with its own matrix. When a machine coordinate is not what you expected, this
|
||||
array names which compensation is responsible without re-running anything.</p>
|
||||
<p><strong>Modal state is complete on every block</strong>, even where the source line states none of it, because
|
||||
PostLogic carries the previous block's sections forward. A section the pipeline synthesized rather
|
||||
than read from the source carries an <code>AddedBy</code> marker (<code>ModalCarry</code> or <code>Backfill</code>), so a reader can
|
||||
tell authored data from carried data — see <a class="xref" href="../../api/Hi.NcParsers.Syntaxs.SyntaxStageKeys.html">SyntaxStageKeys</a>.</p>
|
||||
<h3 id="retention-and-the-freeze">Retention and the freeze</h3>
|
||||
<p>A session retains every executed block for its lifetime, and the live JSON graph costs about 12 KB
|
||||
per line against about 1.6 KB for its compact UTF-8 form — which is what made multi-million-line
|
||||
programs exhaust a client machine. Once a block leaves the executing window its piece is <strong>frozen</strong>:
|
||||
the graph is replaced by those bytes (<a class="xref" href="../../api/Hi.NcParsers.Syntaxs.SyntaxPiece.html#Hi_NcParsers_Syntaxs_SyntaxPiece_Freeze_">Freeze</a>,
|
||||
<a class="xref" href="../../api/Hi.NcParsers.Syntaxs.SyntaxPiece.html#Hi_NcParsers_Syntaxs_SyntaxPiece_IsFrozen">IsFrozen</a>). On a 25,000-line play that takes session retention
|
||||
from 406 MB to 142 MB. The switch is
|
||||
<a class="xref" href="../../api/Hi.MachiningProcs.NcRunnerSessionState.html#Hi_MachiningProcs_NcRunnerSessionState_FreezeExecutedPieces">FreezeExecutedPieces</a>, on by default.</p>
|
||||
<p>Downstream readers are unaffected — the <code>JsonObject</code> getter re-parses on demand and the encoding is
|
||||
byte-identical to the live form — but the object it returns is a <strong>fresh read-only snapshot per
|
||||
call</strong>, with no caching and no write-back. Two reads are not reference-equal, a mutation lands on a
|
||||
throwaway copy, and code that reads the same piece repeatedly should hold the snapshot in a local. To
|
||||
inspect the dataflow, snapshot it <em>in</em> the pipeline with the <code>SnapshotSyntax</code> entry each bundle
|
||||
carries (disabled by default) rather than holding pieces and poking them afterwards.</p>
|
||||
<p>Type discrimination is slightly looser after a round trip, because JSON has fewer types than the live
|
||||
graph: <code>NaN</code> and <code>±Infinity</code> serialize as quoted strings and thaw as string nodes, and <code>5.0</code> freezes
|
||||
as <code>5</code>, so an integer read of it succeeds where it previously would not.
|
||||
<a class="xref" href="../../api/Hi.Common.JsonUtil.html#Hi_Common_JsonUtil_GetDouble_">GetDouble</a> maps the quoted non-finite spellings back to their <code>double</code>
|
||||
constants, so read numbers through it rather than through a raw node cast.</p>
|
||||
<h2 id="dependencies">Dependencies</h2>
|
||||
<p>Machine and case data reach the syntaxes as a list of <a class="xref" href="../../api/Hi.NcParsers.Dependencys.INcDependency.html">INcDependency</a>
|
||||
objects rather than as fields on a shared configuration object. A syntax declares what it needs by
|
||||
interface and pulls it:</p>
|
||||
<pre><code class="lang-csharp">// A syntax that needs the machine's home position asks for the interface, not for a class.
|
||||
var homeConfig = ncDependencyList.OfType<IHomeMcConfig>().FirstOrDefault();
|
||||
</code></pre>
|
||||
<p>Adding a brand means adding a table that implements the interfaces its syntaxes ask for — the brand
|
||||
parameter tables derive from <a class="xref" href="../../api/Hi.NcParsers.Dependencys.ControllerParameterTableBase.html">ControllerParameterTableBase</a>.</p>
|
||||
<p><strong>Per-case data travels as a proxy.</strong> Tool offsets, work-coordinate offsets, Siemens frames,
|
||||
Heidenhain datums and retained macro variables belong to a <em>job</em>, not to a controller
|
||||
configuration. Those entries sit in the pipeline list as placeholders that resolve, per session,
|
||||
against the owning project's per-case list — which is what lets one controller configuration be
|
||||
shared across projects. <a class="xref" href="../../api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_PipelineNcDependencyList">PipelineNcDependencyList</a> is the raw list;
|
||||
consumers read the resolved view through
|
||||
<a class="xref" href="../../api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_GetEffectiveNcDependencyList_">GetEffectiveNcDependencyList</a>.</p>
|
||||
<p><a class="xref" href="../../api/Hi.NcParsers.NcRunnerSuit.html">NcRunnerSuit</a> bundles a runner with its per-case data as one file-loadable unit,
|
||||
so a whole parser configuration — pipeline and job data together — moves as a single file.</p>
|
||||
<h2 id="machine-wiring">Machine wiring</h2>
|
||||
<p><a class="xref" href="../../api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_ConfigureByMachiningChain_">ConfigureByMachiningChain</a> takes the machining chain and settles
|
||||
what the pipeline needs to know about the physical machine: axis order, which axes are rotary and
|
||||
which linear, and the kinematics the coordinate syntaxes solve against. A five-axis machine, a
|
||||
four-axis machine and a twin-table machine all run the same program path — the difference is the
|
||||
chain, not the parser.</p>
|
||||
<h2 id="extending-it">Extending it</h2>
|
||||
<p>Three kinds of customization need no rebuild of the libraries:</p>
|
||||
<p><strong>Switch brand.</strong></p>
|
||||
<pre><code class="lang-csharp">var runner = SoftNcRunner.HeidenhainNcRunner;
|
||||
runner.ConfigureByMachiningChain(machine.Chain);
|
||||
</code></pre>
|
||||
<p><strong>Add a syntax for one machine's own vocabulary.</strong> A machine whose PLC uses a non-standard <code>M168</code>
|
||||
for clamping needs a class implementing <a class="xref" href="../../api/Hi.NcParsers.Syntaxs.ISituNcSyntax.html">ISituNcSyntax</a> and one entry in
|
||||
that project's pipeline list. No HiAPIs source changes.</p>
|
||||
<p><strong>Declare OEM M-codes without writing code at all.</strong>
|
||||
<a class="xref" href="../../api/Hi.NcParsers.Dependencys.IMCodeDeclarationConfig.html">IMCodeDeclarationConfig</a> and
|
||||
<a class="xref" href="../../api/Hi.NcParsers.Dependencys.MCodeEffects.html">MCodeEffects</a> let a machine state what its own M-codes do — a
|
||||
composite spindle-and-coolant code, a tool-change trigger, turret <code>T</code>-word semantics — and
|
||||
<a class="xref" href="../../api/Hi.NcParsers.LogicSyntaxs.MCodeExpansionSyntax.html">MCodeExpansionSyntax</a> expands them into the canonical ISO flags the
|
||||
shared consumers already understand. A code declared with no modeled effects is voiced once as
|
||||
<code>DeclaredMCode--UnmodeledEffects</code> instead of raising an unknown-code warning on every occurrence.</p>
|
||||
<div class="IMPORTANT">
|
||||
<h5>Important</h5>
|
||||
<p><strong>Composing the pipeline is a licensed capability.</strong> Registering a unit that is not built in —
|
||||
into the syntax list, the dependency list, the semantics, the initializers or the segmenter — and
|
||||
executing an NC-embedded C# script both require the <code>NcComposition</code> licence feature. The check
|
||||
runs once per session at the run entry, so it covers project-XML load, whole-object replacement
|
||||
and direct list mutation alike.</p>
|
||||
<p>Degradation is <strong>silent and functional</strong>, not an error: external units are skipped for that
|
||||
session and named in one <code>Composition--NotLicensed</code> diagnostic, an external segmenter falls back
|
||||
to the single-line segmenter, and scripts are skipped with <code>Script--NotLicensed</code>. The runner's
|
||||
persisted lists are never mutated, so the project still saves correctly — but the simulation that
|
||||
ran is a different one. If you build against this surface, check for that diagnostic rather than
|
||||
assuming your unit ran.</p>
|
||||
<p>Built-in units are unrestricted in order, count, duplication and constructor configuration, and
|
||||
calling the public API from your own application or session script needs no extra licence.</p>
|
||||
</div>
|
||||
<h2 id="brand-support">Brand support</h2>
|
||||
<p>Coverage is stated in three states. <strong>Recognized but not simulated</strong> is a deliberate state, not a
|
||||
gap: the construct is consumed safely and reported with its own diagnostic id, so it can never be
|
||||
misread as something else — a <code>PLANE AXIAL B+45</code> will not be mistaken for a rotary axis command.</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Brand</th>
|
||||
<th>Supported</th>
|
||||
<th>Recognized, not simulated</th>
|
||||
<th>Not supported</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong>Fanuc</strong></td>
|
||||
<td>ISO core, canned cycles G73–G89, G41/G42, G43.4 RTCP, G53/G53.1, G68/G68.2/G69, G12.1/G13.1 polar with compensation, Custom Macro B (<code>#</code> variables, <code>IF</code>/<code>GOTO</code>, <code>WHILE</code>/<code>DO</code>), <code>M98</code>/<code>M99</code> subprograms, <code>G65</code>/<code>G66</code>/<code>G67</code> macro calls</td>
|
||||
<td>—</td>
|
||||
<td><code>G10</code> programmable data setting, <code>G50</code> spindle limit, <code>G31</code> skip</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Siemens</strong></td>
|
||||
<td>modal vocabulary, <code>SUPA</code>/<code>G153</code>, <code>T="name"</code> with <code>D</code> offsets, <code>$TC_DP</code> tool tables, R-parameters and <code>DEF</code> variables with a full expression evaluator, <code>$P_UIFR</code>, <code>TRANS</code>/<code>ATRANS</code>/<code>ROT</code>/<code>AROT</code> frames, <code>TRAORI</code>/<code>TRAFOOF</code>, <code>CYCLE800</code>, <code>MSG</code>/<code>STOPRE</code>, <code>CR=</code>/<code>TURN=</code> arcs, <code>L</code>/named subprograms, <code>MCALL</code>, <code>REPEAT</code>, <code>PROC</code>/labels, <code>GOTOF</code>/<code>GOTOB</code>, <code>IF</code>/<code>ELSE</code>/<code>ENDIF</code>, <code>WHILE</code>/<code>FOR</code>/<code>REPEAT-UNTIL</code>/<code>LOOP</code>, <code>AC()</code>/<code>IC()</code>/<code>DC()</code>/<code>ACP()</code>/<code>ACN()</code>, the coded-position family, <code>G74</code>/<code>G75</code></td>
|
||||
<td><code>ROTS</code>/<code>AROTS</code>, <code>SCALE</code>/<code>ASCALE</code>, <code>MIRROR</code>/<code>AMIRROR</code> (<code>SiemensFrame--Unsupported</code>)</td>
|
||||
<td><code>SETAL</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Heidenhain</strong></td>
|
||||
<td>klartext motion and <code>FMAX</code>, <code>M91</code>, <code>TOOL CALL</code> with <code>DL</code>/<code>DR</code>, <code>CYCL DEF 247</code> presets and <code>CYCL DEF 7</code> additive shifts, <code>CC</code>/<code>C</code> arcs, <code>RL</code>/<code>RR</code>/<code>R0</code>, <code>M126</code>/<code>M127</code>, <code>M140</code>, <code>CYCL DEF 32</code>, Q/QR parameters with the FN grammar and FN 9–12 jumps, <code>PLANE SPATIAL</code>, <code>FUNCTION TCPM</code>, <code>M128</code>/<code>M129</code>, machining cycles 200/232/251/252/253, <code>CYCL CALL</code>/<code>CYCL CALL POS</code>, <code>CALL LBL</code> with <code>REP</code>, <code>CALL PGM</code>, tilde continuation, <code>BLK FORM</code>, <code>STOP</code>, mirror image (<code>G28</code> and <code>CYCL DEF 8</code>), and the DIN/ISO dialect with absolute <code>I</code>/<code>J</code>/<code>K</code> centres, the ISO label family, <code>G247</code>, <code>G54</code> datum words and <code>G70</code>/<code>G71</code></td>
|
||||
<td><code>PLANE VECTOR</code> (captured), <code>PLANE EULER</code> / <code>POINTS</code> / <code>RELATIV</code> / <code>AXIAL</code> / <code>PROJECTED</code> (<code>HeidenhainPlane--Unsupported</code>), unimplemented <code>FN</code> opcodes such as <code>FN 18 SYSREAD</code>, unrecognized <code>CYCL DEF</code> bodies (<code>HeidenhainCycl--Unsupported</code>)</td>
|
||||
<td><code>TOOL DEF</code>, <code>FK</code> free contour, <code>SL</code> cycles, <code>PATTERN DEF</code>, <code>TCH PROBE</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Syntec</strong></td>
|
||||
<td>ISO core plus the Fanuc-family macro and subprogram vocabulary, polar interpolation</td>
|
||||
<td>—</td>
|
||||
<td>custom G macros, <code>Pr</code> parameter mapping, twin-head / twin-turret syntax</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Mazak</strong></td>
|
||||
<td>EIA/ISO with the Fanuc-family macro and subprogram vocabulary, polar interpolation</td>
|
||||
<td>—</td>
|
||||
<td>Mazatrol conversational sections, MAZATROL ↔ EIA/ISO switching</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="NOTE">
|
||||
<h5>Note</h5>
|
||||
<p>On the Heidenhain preset, DIN/ISO <code>G28</code> is <strong>MIRROR IMAGE</strong>, not a Fanuc reference-point return,
|
||||
and <code>ReferenceReturnSyntax</code> is not in that preset's Logic list. <code>HardNcRunner</code> keeps the Fanuc
|
||||
reading, so the two engines are deliberately divergent on Heidenhain <code>G28</code> files.</p>
|
||||
</div>
|
||||
<h2 id="loading-a-hardnc-era-project">Loading a HardNc-era project</h2>
|
||||
<p>Projects written for the legacy interpreter still load.</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Mechanism</th>
|
||||
<th>Purpose</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_FromLegacyNcEnvXml_">FromLegacyNcEnvXml</a></td>
|
||||
<td>builds a <code>SoftNcRunner</code> from a legacy configuration element</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>the <code>NcEnv</code> XML alias</td>
|
||||
<td>a project saved under the old element name still deserializes</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>the legacy version patches</td>
|
||||
<td>a project saved by an older build gains the syntaxes and semantics added since, according to the project API version it carries</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>the system-wired back-fill</td>
|
||||
<td>a saved pipeline gains the runtime-wired dependencies it predates</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_EnableSoftNcRunner">EnableSoftNcRunner</a></td>
|
||||
<td>set <code>false</code> to run the legacy interpreter for comparison</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The version patches cover projects back to the 3.1.163 era; the back-fill is unconditional, because
|
||||
the dependencies it adds are stateless runtime-wired singletons for which presence is the only
|
||||
question worth asking.</p>
|
||||
|
||||
</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>
|
||||
@@ -65,6 +65,9 @@
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="nc-parsing/index.html" name="" title="NC Parsing Engine">NC Parsing Engine</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="common/message-management.html" name="" title="Message Management">Message Management</a>
|
||||
</li>
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
|
||||
{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"System Requirements","href":"system-requirements.html","topicHref":"system-requirements.html"},{"name":"Getting Started","href":"getting-started/index.html","topicHref":"getting-started/index.html"},{"name":"General HiNC Workflow","href":"general-hinc-workflow/index.html","topicHref":"general-hinc-workflow/index.html"},{"name":"Basic Geometry","href":"geom/basic-geometry.html","topicHref":"geom/basic-geometry.html"},{"name":"Rendering","href":"rendering/index.html","topicHref":"rendering/index.html","items":[{"name":"Using RenderingCanvas with DispEngine","href":"rendering/rendering-canvas/index.html","topicHref":"rendering/rendering-canvas/index.html"},{"name":"Building Your Own Rendering Canvas","href":"rendering/rendering-canvas/custom-implementation.html","topicHref":"rendering/rendering-canvas/custom-implementation.html"},{"name":"Drawing","href":"rendering/drawing/index.html","topicHref":"rendering/drawing/index.html"},{"name":"Color Guide System","href":"rendering/color-guide/index.html","topicHref":"rendering/color-guide/index.html"}]},{"name":"Mechanism Topology","items":[{"name":"Overview","href":"mechanism/index.html","topicHref":"mechanism/index.html"},{"name":"Topology Structure","href":"mechanism/Topo/index.html","topicHref":"mechanism/Topo/index.html"},{"name":"Transformers","href":"mechanism/transformers/index.html","topicHref":"mechanism/transformers/index.html"},{"name":"Render Topology","href":"mechanism/render-topology/index.html","topicHref":"mechanism/render-topology/index.html"}]},{"name":"Message Management","href":"common/message-management.html","topicHref":"common/message-management.html"},{"name":"XML IO","href":"common/xml-io.html","topicHref":"common/xml-io.html"}]}
|
||||
{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"System Requirements","href":"system-requirements.html","topicHref":"system-requirements.html"},{"name":"Getting Started","href":"getting-started/index.html","topicHref":"getting-started/index.html"},{"name":"General HiNC Workflow","href":"general-hinc-workflow/index.html","topicHref":"general-hinc-workflow/index.html"},{"name":"Basic Geometry","href":"geom/basic-geometry.html","topicHref":"geom/basic-geometry.html"},{"name":"Rendering","href":"rendering/index.html","topicHref":"rendering/index.html","items":[{"name":"Using RenderingCanvas with DispEngine","href":"rendering/rendering-canvas/index.html","topicHref":"rendering/rendering-canvas/index.html"},{"name":"Building Your Own Rendering Canvas","href":"rendering/rendering-canvas/custom-implementation.html","topicHref":"rendering/rendering-canvas/custom-implementation.html"},{"name":"Drawing","href":"rendering/drawing/index.html","topicHref":"rendering/drawing/index.html"},{"name":"Color Guide System","href":"rendering/color-guide/index.html","topicHref":"rendering/color-guide/index.html"}]},{"name":"Mechanism Topology","items":[{"name":"Overview","href":"mechanism/index.html","topicHref":"mechanism/index.html"},{"name":"Topology Structure","href":"mechanism/Topo/index.html","topicHref":"mechanism/Topo/index.html"},{"name":"Transformers","href":"mechanism/transformers/index.html","topicHref":"mechanism/transformers/index.html"},{"name":"Render Topology","href":"mechanism/render-topology/index.html","topicHref":"mechanism/render-topology/index.html"}]},{"name":"NC Parsing Engine","href":"nc-parsing/index.html","topicHref":"nc-parsing/index.html"},{"name":"Message Management","href":"common/message-management.html","topicHref":"common/message-management.html"},{"name":"XML IO","href":"common/xml-io.html","topicHref":"common/xml-io.html"}]}
|
||||
|
||||
Reference in New Issue
Block a user