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,194 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Geometry Objects | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Geometry Objects | 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="Technique-BasicGeometry">
<h1 id="geometry-objects">Geometry Objects</h1>
<p><strong><a class="xref" href="../../api/Hi.Geom.IGetStl.html">IGetStl</a></strong> is the single-member interface that hands back an <a class="xref" href="../../api/Hi.Geom.Stl.html">Stl</a>, and
it is what the geometries listed below have in common — most of them reach it through
<a class="xref" href="../../api/Hi.Geom.IStlSource.html">IStlSource</a>, which adds XML persistence on top of it. It does not span every geometry
object: a voxel mesh reference such as <a class="xref" href="../../api/Hi.Cbtr.CubeTreeFile.html">CubeTreeFile</a> persists itself and presents
itself without ever answering <code>GetStl</code>. Code meant to accept every kind of geometry binds to the
interface that group actually shares, not to <code>IGetStl</code>.</p>
<p>Several common geometry types are available:</p>
<ul>
<li>Basic Geometrys
<ul>
<li><a class="xref" href="../../api/Hi.Geom.Box3d.html">Box3d</a></li>
<li><a class="xref" href="../../api/Hi.Geom.Cylindroid.html">Cylindroid</a></li>
<li><a class="xref" href="../../api/Hi.Geom.Stl.html">Stl</a></li>
<li><a class="xref" href="../../api/Hi.Geom.StlFile.html">StlFile</a></li>
</ul>
</li>
<li>Management Geometrys
<ul>
<li><a class="xref" href="../../api/Hi.Geom.TransformationGeom.html">TransformationGeom</a></li>
<li><a class="xref" href="../../api/Hi.Geom.GeomCombination.html">GeomCombination</a></li>
</ul>
</li>
</ul>
<p>See <a class="xref" href="../mechanism/transformers.html">Transformations</a> for <a class="xref" href="../../api/Hi.Geom.TransformationGeom.html">TransformationGeom</a>.</p>
<ul>
<li><a class="xref" href="../../api/Hi.Mech.Topo.GeneralTransform.html">GeneralTransform</a></li>
<li><a class="xref" href="../../api/Hi.Mech.Topo.StaticRotation.html">StaticRotation</a></li>
<li><a class="xref" href="../../api/Hi.Mech.Topo.StaticTranslation.html">StaticTranslation</a></li>
</ul>
<div class="NOTE">
<h5>Note</h5>
<p>All coordinate values use standard units (millimeters, radians)</p>
</div>
<h2 id="example-usage">Example Usage</h2>
<pre><code class="lang-csharp" name="SampleCode">using System;
using System.Collections.Generic;
using Hi.Geom;
using Hi.Mech.Topo;
namespace Sample.Geom;
/// &lt;summary&gt;
/// Demonstrates the creation and manipulation of geometric objects in HiAPI.
/// Shows how to create and transform various geometry types including boxes, cylindroids, and STL files.
/// &lt;/summary&gt;
/// &lt;remarks&gt;
/// ### Source Code
/// [!code-csharp[SampleCode](~/../Hi.Sample/Geom/DemoBuildGeom.cs)]
/// &lt;/remarks&gt;
public static class DemoBuildGeom
{
/// &lt;summary&gt;
/// Generates a collection of geometric objects for demonstration purposes.
/// Creates various geometry types including boxes, cylindroids, STL files, and transformed geometries.
/// &lt;/summary&gt;
/// &lt;returns&gt;A list of geometries implementing the IGetStl interface&lt;/returns&gt;
public static List&lt;IGetStl&gt; GenGeoms()
{
Box3d box = new Box3d(0, 0, -50, 70, 50, 0);
Cylindroid cylindroid = new Cylindroid([ new PairZr(0,12),new PairZr(20,12),
new PairZr(20,16),new PairZr(30,16)]);
Stl stl = new Stl(&quot;geom.stl&quot;);
StlFile stlFile = new StlFile(&quot;geom.stl&quot;);
TransformationGeom transformationGeom = new TransformationGeom()
{
Transformer = new GeneralTransform(1,
new StaticRotation(new Vec3d(0, 0, 1), MathUtil.ToRad(15), new Vec3d(0, 0, 0)),
new StaticTranslation(new Vec3d(0, 0, 0))),
Geom = stl
};
GeomCombination geomCombination = new GeomCombination(stlFile, transformationGeom);
return new List&lt;IGetStl&gt;([box, cylindroid, stl, stlFile, transformationGeom]);
}
}
</code></pre><h2 id="see-also">See Also</h2>
<ul>
<li><a href="getting-started.html">Getting Started with HiAPI</a> — the environment these geometries are assembled into</li>
<li><a href="xml-io.html">About XML IO</a> — how a geometry is persisted with its project</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,282 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Getting Started with HiAPI | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Getting Started with HiAPI | 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="Technique-GettingStarted">
<h1 id="getting-started-with-hiapi">Getting Started with HiAPI</h1>
<p>What a first HiAPI application needs: where the packages come from, what the program has to
initialise, and the shape every HiNC program follows once it runs.</p>
<h2 id="installation">Installation</h2>
<ol>
<li><p>Create a dotnet project. A console or service project targets <strong>net10.0</strong>. A project that also
takes one of the Windows UI packages targets <strong>net10.0-windows</strong> — that is what <code>Hi.WinForm</code> and
<code>Hi.WpfPlus</code> are built for, and a plain <code>net10.0</code> project cannot reference them. An earlier
target framework cannot reference any of the packages.</p>
</li>
<li><p>Register the HiAPI package source on the machine.</p>
<p>The feed requires authentication, and the same account that gives you the sample repositories
gives you the packages. One command registers the source <em>and</em> its credentials, which is the
whole of what a restore needs:</p>
<pre><code>dotnet nuget add source https://superhightech-gitea.webredirect.org/api/packages/HiAPI/nuget/index.json --name HiAPI --username &lt;your-account&gt; --password &lt;your-token&gt; --store-password-in-clear-text
</code></pre>
<p>Run it once per machine. Customers served by the mainland mirror register the feed address
issued with their account in place of the URL above; nothing else changes.</p>
<p><strong>Prefer this to a project-local <code>nuget.config</code>, and never declare the feed in both places.</strong>
NuGet resolves credentials by source <em>name</em>, and the match is case-sensitive, so a file that
declares the same URL under a name the machine holds no credentials for adds a <em>second</em>,
credential-less source. NuGet asks every source about every package, and one <code>401</code> fails the
whole restore instead of falling through — so the packages it then reports as missing are the
public <code>nuget.org</code> ones, and the cause is nowhere near the symptom. A credential-free file
cannot stand in for the command either: the feed rejects anonymous requests, so it carries a
fresh clone no further than having no source at all.</p>
<p>Where a per-machine source is genuinely unavailable — an ephemeral build agent, say — a
<code>nuget.config</code> beside the project file does the job, provided it is the only declaration of
that URL and carries its own credentials under exactly the key it gave the source:</p>
<pre><code class="lang-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;configuration&gt;
&lt;packageSources&gt;
&lt;add key=&quot;HiAPI&quot; value=&quot;https://superhightech-gitea.webredirect.org/api/packages/HiAPI/nuget/index.json&quot; /&gt;
&lt;add key=&quot;nuget.org&quot; value=&quot;https://api.nuget.org/v3/index.json&quot; protocolVersion=&quot;3&quot; /&gt;
&lt;/packageSources&gt;
&lt;packageSourceCredentials&gt;
&lt;HiAPI&gt;
&lt;add key=&quot;Username&quot; value=&quot;xxxxxx&quot; /&gt;
&lt;add key=&quot;ClearTextPassword&quot; value=&quot;xxxxxx&quot; /&gt;
&lt;/HiAPI&gt;
&lt;/packageSourceCredentials&gt;
&lt;/configuration&gt;
</code></pre>
<p>That file holds a password in clear text: keep it out of version control.</p>
</li>
<li><p>In the dotnet project file, add the package reference.</p>
<pre><code class="lang-xml">&lt;ItemGroup&gt;
&lt;PackageReference Include=&quot;HiNc&quot; Version=&quot;3.2.*&quot; /&gt;
&lt;!--optional; needs a net10.0-windows project--&gt;
&lt;PackageReference Include=&quot;Hi.WpfPlus&quot; Version=&quot;3.2.*&quot; /&gt;
&lt;/ItemGroup&gt;
</code></pre>
</li>
<li><p>In the program file, setting the HiNC application initialization and finalization.</p>
<pre><code class="lang-csharp" name="SampleCode">using Hi.HiNcKits;
using Microsoft.Extensions.Logging;
using System;
namespace Sample
{
/// &lt;summary&gt;
/// A sample class demonstrating initialization and usage of the HiAPI framework.
/// Shows the basic setup of display engine, MongoDB server, licensing, and other core functionality.
/// &lt;/summary&gt;
/// &lt;remarks&gt;
/// This example serves as an entry point for those getting started with HiAPI.
/// It demonstrates proper initialization and teardown of key components.
/// ### Source Code
/// [!code-csharp[SampleCode](~/../Hi.Sample/HelloHiAPI.cs)]
/// &lt;/remarks&gt;
public static class HelloHiAPI
{
static int Main(string[] args)
{
Console.WriteLine(&quot;HiAPI starting.&quot;);
using var loggerFactory = Microsoft.Extensions.Logging.LoggerFactory.Create(b =&gt; b.AddConsole());
LocalApp.AppBegin(loggerFactory.CreateLogger(&quot;Hi.Sample&quot;));
Console.WriteLine(&quot;Hello World! HiAPI.&quot;);
LocalApp.AppEnd();
Console.WriteLine(&quot;HiAPI exited.&quot;);
return 0;
}
}
}
</code></pre></li>
</ol>
<h2 id="the-shape-of-a-hinc-program">The Shape of a HiNC Program</h2>
<p>Every HiNC program, whether it is the shipped application or twenty lines in a console project,
runs the same five steps. <code>DemoBuildMachiningProject</code> in the Hi.Sample repository is the complete
worked example.</p>
<pre><code class="lang-mermaid">graph TD
A[&quot;Create MachiningProject&quot;] --&gt; B[&quot;Setting Environment&quot;]
B --&gt; C[&quot;Setting Project Tasks&quot;]
C --&gt; D[&quot;Run Tasks&quot;]
D --&gt; E[&quot;View Analysis Results&quot;]
</code></pre>
<h3 id="1-create-">1. Create <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a></h3>
<p>Creating a machining project is the first step in the HiNC workflow, accomplished by initializing a <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a> object.</p>
<h3 id="2-setting-environment-in-">2. Setting Environment In <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a></h3>
<p>The equipment has two faces. <a class="xref" href="../../api/Hi.Machining.MachiningEquipmentUtils.SetupEquipment.html">SetupEquipment</a> is the
authored one — the only face a project file persists, and the one every setting below is written to.
<a class="xref" href="../../api/Hi.Machining.MachiningEquipmentUtils.MachiningEquipment.html">MachiningEquipment</a> is the runtime face the runner,
physics, collision and execution display read; it is rebuilt from the authored face at project
assignment and at session boundaries, so a value written onto it is discarded rather than saved.</p>
<ul>
<li>Set <a class="xref" href="../../api/Hi.Machining.MachiningEquipmentUtils.SetupEquipment.html">SetupEquipment</a>:
<ul>
<li>Usually one-time settings:
<ul>
<li><a class="xref" href="../../api/Hi.Machining.MachiningEquipmentUtils.SetupEquipment.html#Hi_Machining_MachiningEquipmentUtils_SetupEquipment_MachiningChain">MachiningChain</a> - Configure the complete machine tool including geometry, kinematic chain, and coordinate transformations</li>
<li><a class="xref" href="../../api/Hi.Machining.MachiningEquipmentUtils.SetupEquipment.html#Hi_Machining_MachiningEquipmentUtils_SetupEquipment_SpindleCapability">SpindleCapability</a> - Configure <a class="xref" href="../../api/Hi.Milling.SpindleCapability.html">SpindleCapability</a></li>
<li><a class="xref" href="../../api/Hi.Machining.MachiningEquipmentUtils.SetupEquipment.html#Hi_Machining_MachiningEquipmentUtils_SetupEquipment_CoolantHeatCondition">CoolantHeatCondition</a> - Configure coolant heat conditions</li>
<li><a class="xref" href="../../api/Hi.Machining.MachiningEquipmentUtils.SetupEquipment.html#Hi_Machining_MachiningEquipmentUtils_SetupEquipment_BackgroundTemperature_C">BackgroundTemperature_C</a> - Configure the environment background temperature in Celsius; <a class="xref" href="../../api/Hi.Machining.MachiningEquipmentUtils.SetupEquipment.html#Hi_Machining_MachiningEquipmentUtils_SetupEquipment_BackgroundTemperature_K">BackgroundTemperature_K</a> holds the same value in Kelvin</li>
</ul>
</li>
<li>Variable settings:
<ul>
<li><a class="xref" href="../../api/Hi.NcMech.Fixtures.Fixture.html">Fixture</a> - Configure fixture</li>
<li><a class="xref" href="../../api/Hi.NcMech.Workpieces.Workpiece.html">Workpiece</a> - Configure workpiece</li>
</ul>
</li>
</ul>
</li>
<li>Set <a class="xref" href="../../api/Hi.Machining.MachiningToolHouse.html">MachiningToolHouse</a> - Configure tool house</li>
<li>Set <a class="xref" href="../../api/Hi.Numerical.HardNcEnv.html">HardNcEnv</a> (Controller) - Configure NC system environment parameters</li>
</ul>
<h3 id="3-setting-project-tasks">3. Setting Project Tasks</h3>
<p>Set sequential tasks using <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a>:</p>
<ul>
<li>Set NC Files - Set the file path and customize simulation and optimization settings for each NC file</li>
<li>Configure NC optimization - Configure NC code optimization parameters</li>
<li>Set <a class="xref" href="../../api/Hi.SessionCommands.GeomDiffCommand.html">GeomDiffCommand</a> - Configure geometry comparison functionality to compare target workpiece shape with simulated shape</li>
<li>Set <a class="xref" href="../../api/Hi.MillingForces.Training.MillingTraining.html">MillingTraining</a> - Configure milling parameter training to calibrate simulation parameters based on actual machining data</li>
<li>Other task configurations&hellip;</li>
</ul>
<p>The PlayerCommand is typically a <a class="xref" href="../../api/Hi.SessionCommands.ListCommand.html">ListCommand</a> that contains a sequence of command entries to be executed during the simulation.</p>
<h3 id="4-run-the-tasks-simulation-and-optimization">4. Run the Tasks (Simulation and Optimization)</h3>
<p>Run <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> through <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_PacePlayer">PacePlayer</a>.</p>
<p>At this stage, the simulation process is similar to video playback, which can be:</p>
<ul>
<li>Started</li>
<li>Stopped</li>
<li>Paused</li>
<li>Run one line</li>
<li>Run one step</li>
<li>Reset</li>
</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>
<h4 id="view-the-analysis-during-process-or-result">View the Analysis During Process or Result</h4>
<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="sample-code-to-start-a-">Sample Code to Start a <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a></h2>
<p>See the following sample code to start a HiAPI application.</p>
<ul>
<li><code>DemoBuildMachiningProject</code>
Build a <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a>.</li>
<li><code>DemoUseMachiningProject</code>
Load a <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a> and run NC simulation.</li>
<li><code>DemoRenderingMachiningProcessAndStripPosSelection</code>
Apply <a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a> to 3D canvas with user-interaction in windows platform.</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="packages-and-samples.html">HiAPI Packages and Sample Code</a> — the NuGet feed and the sample repositories the demos named here live in</li>
<li><a href="basic-geometry.html">Geometry Objects</a> — the geometry types the environment in step 2 is assembled from</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,137 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>API Foundations | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="API Foundations | 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="">
<h1 id="api-foundations">API Foundations</h1>
<p>What a C# application built on HiAPI needs before anything else runs: where the packages come
from, what a program has to initialise, the geometry objects it passes around, and the two
cross-cutting services — messages and XML serialization — that the rest of the API assumes are
already there.</p>
<p>Ordered the way a new application meets them: getting the packages, writing the first program,
then the pieces every later page takes for granted.</p>
<h2 id="starting-an-application">Starting an Application</h2>
<ul>
<li><a href="packages-and-samples.html">HiAPI Packages and Sample Code</a> — The NuGet feed, the package dependency chain, which package a UI framework needs, and the three sample repositories</li>
<li><a href="getting-started.html">Getting Started with HiAPI</a> — Wiring the feed into a project, initialising and finalising the runtime, and the five steps every HiNC program follows</li>
</ul>
<h2 id="what-every-page-assumes">What Every Page Assumes</h2>
<ul>
<li><a href="basic-geometry.html">Geometry Objects</a> — The STL-backed interface behind every geometry type, and the basic and management geometries built on it</li>
<li><a href="message-management.html">Message Management</a> — Three independent message channels — diagnostic, UI notification, application log — and why they are never mixed</li>
<li><a href="xml-io.html">About XML IO</a> — The serialization pattern every persisted HiAPI type implements, and the registration that must happen before a project is loaded</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="../rendering/index.html">Rendering</a> — putting what these types describe on a screen</li>
<li><a href="../mechanism/index.html">Mechanism</a> — assembling them into a machine that moves</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,161 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Message Management | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Message Management | 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="Technique-MessageManagement">
<h1 id="message-management">Message Management</h1>
<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--iprogressimessage">1. Diagnostic — <code>IProgress&lt;IMessage&gt;</code></h3>
<p>Operation-scoped progress and diagnostic messages. The caller provides an <code>IProgress&lt;IMessage&gt;</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_ShellProgress">ShellProgress</a> feeds the <a class="xref" href="../../anatomy/shell/session-message-panel.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&lt;IMessage&gt;</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>
<li><strong>Project IO</strong>: <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_LoadProject_">LoadProject</a> and <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_ReloadProject_">ReloadProject</a> take a sink of their own, because project IO runs outside any session and none of the session sinks above exists while it runs. A load-time diagnostic — a referenced STL missing on disk, a child XML that will not deserialize — does not fail the load; the project comes up without that geometry and the call returns normally. Passing no sink leaves the application log as the only witness, and the caller sees an unqualified success.</li>
</ul>
<h4 id="reporting-to-a-sink-and-the-log-at-once">Reporting to a sink and the log at once</h4>
<p>An operation a caller may or may not be watching reports to both: always to the service <code>ILogger</code>, and additionally to an injected <code>IProgress&lt;IMessage&gt;</code> when there is one. <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_EnableCollisionDetection_">EnableCollisionDetection</a>, <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_ResetRuntime_">ResetRuntime</a> and the two project-load entry points share that shape, and the parameter being optional is what lets a host with no caller to answer to — a script, a desktop shell — behave exactly as it did before the sink existed.</p>
<p>The counterpart obligation is that one operation reports one diagnostic once. Where a later stage re-reads what an earlier one has already reported on — the XML round trip that materialises execution equipment re-walks the sources the deserialization pass just read — that stage stays logger-only deliberately, so a caller collecting a project load does not receive every missing file twice.</p>
<h4 id="reporting-helpers-and-the-args-channel">Reporting helpers, and the args channel</h4>
<p>Use the <a class="xref" href="../../api/Hi.Common.Messages.MessageUtil.html">MessageUtil</a> id-first helpers to report typed messages. Each is named <code>{Category}{Severity}</code><code>SystemError</code>, <code>SystemWarning</code>, <code>ValidationWarning</code>, <code>ConfigurationWarning</code>, … — takes the structured id first, and is null-safe on the sink.</p>
<p>Every helper has a <code>{Category}{Severity}Fmt</code> sibling that takes a <code>FormattableString</code> in place of the <code>string</code>. The sibling keeps the template and the values interpolated into it on the message itself, as <a class="xref" href="../../api/Hi.Common.Messages.IMessage.html#Hi_Common_Messages_IMessage_GetFormat">GetFormat()</a> and <a class="xref" href="../../api/Hi.Common.Messages.IMessage.html#Hi_Common_Messages_IMessage_GetArgs">GetArgs()</a>, so a consumer holding a translation of that template can re-render the message in another language instead of dropping the numbers. The notification stays the invariant English rendering, so a value carried in it never picks up a decimal separator from a locale. What a client does with the pair, and why the English template is load-bearing rather than descriptive, is under <a class="xref" href="../../anatomy/platform/i18n.html">Internationalization</a>.</p>
<pre><code class="lang-csharp">progress.SystemErrorFmt(&quot;StlFile-Read--Failed&quot;, $&quot;File Reading Failed: {path}&quot;);
</code></pre>
<div class="IMPORTANT">
<h5>Important</h5>
<p><strong>The sibling is opted into by name, and nothing reports its absence.</strong> An interpolated literal handed to the plain helper binds to <code>string</code>, is formatted on the spot, and the template is gone: the call compiles, reads identically at the site, and produces a message no client can translate. Report through <code>Fmt</code> wherever the text interpolates a value. Where it does not, stay on the plain helper — a client swaps a hole-less message by id alone, so giving it a template only adds a way for the equality gate to miss.</p>
</div>
<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., &ldquo;File saved&rdquo;, &ldquo;Load failed&rdquo;). <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">
<h5>Note</h5>
<p><code>MessageBoardUtil</code> is not yet mature for all scenarios. In practice, <code>ILogger</code> with level-filtered treatment is often applied instead.</p>
</div>
<h3 id="3-app-log--ilogger">3. App Log — <code>ILogger</code></h3>
<p>Standard .NET <code>ILogger</code> for application-level logging. Use <a class="xref" href="../../api/Hi.Common.Messages.ActionProgress-1.html">ActionProgress&lt;T&gt;</a>.<a class="xref" href="../../api/Hi.Common.Messages.ActionProgress-1.html#Hi_Common_Messages_ActionProgress_1_FromLogger_">FromLogger</a> to bridge <code>IProgress&lt;object&gt;</code> APIs to an <code>ILogger</code> instance:</p>
<pre><code class="lang-csharp">IProgress&lt;object&gt; progress = ActionProgress&lt;object&gt;.FromLogger(logger);
</code></pre>
<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 — with one precedence worth knowing: a message carrying an <code>Exception</code> as its detail goes to <code>LogError</code> with that exception attached whatever severity the message itself declares, so a warning that names an exception is logged as an error.</p>
<p>A null <code>logger</code> is accepted and becomes a no-op sink. A host built without dependency injection has none to hand over, and this bridge is reached from the error-reporting path itself, so a version that threw on a null logger would turn the first reported error into a crash inside the code meant to describe it.</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&lt;Exception&gt;</code> or <code>IProgress&lt;IMessage&gt;</code> as parameters so the caller decides how to handle messages:</p>
<pre><code class="lang-csharp">await task.CatchExceptions(ex =&gt; progress?.Report(ex));
</code></pre>
<h2 id="design-rationale">Design Rationale</h2>
<p>Static/global message sinks mix the three categories, making it unclear whether a message is diagnostic, UI notification, or app log. The current pattern threads the handler explicitly through the call chain so each caller decides the appropriate category.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="xml-io.html">About XML IO</a> — the other cross-cutting service, and the one that threads a progress channel through deserialization</li>
<li><a href="../scripting/shell-progress.html">ShellProgress</a> — the session-scoped face of the diagnostic channel, as a script sees it</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,181 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HiAPI Packages and Sample Code | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="HiAPI Packages and Sample Code | 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="Technique-PackagesAndSamples">
<h1 id="hiapi-packages-and-sample-code">HiAPI Packages and Sample Code</h1>
<p>HiAPI is a C# software development kit for machining simulation. It provides libraries for NC motion simulation, collision detection, geometry removal simulation, milling force simulation, optimization, and more.</p>
<h2 id="nuget-packages">Nuget Packages</h2>
<p>The HiAPI is applied by the form of Nuget Packages. You have to apply <code>HiNc</code> nuget package and its dependencies. They include all the functionality of the HiNC software, but do not include the GUI components.</p>
<p>The packages can be downloaded and installed from the HiAPI NuGet Server. The server URL is:</p>
<p><a href="https://superhightech-gitea.webredirect.org/api/packages/HiAPI/nuget/index.json">https://superhightech-gitea.webredirect.org/api/packages/HiAPI/nuget/index.json</a></p>
<div class="NOTE">
<h5>Note</h5>
<ul>
<li>Authentication is required to access the server. Register the feed and the account together
with the single <code>dotnet nuget add source</code> command in
<a href="getting-started.html#installation">Getting Started</a> — the feed rejects anonymous requests, so a
source declared without credentials gets a restore no further.</li>
<li>Direct browser access to the URL will not show meaningful content. Since the server is designed for Visual Studio NuGet package management. For more information about NuGet, visit <a href="https://www.nuget.org/">NuGet.org</a></li>
</ul>
</div>
<h3 id="package-dependencies">Package Dependencies</h3>
<p>The <code>HiNc</code> package has the following dependency chain:</p>
<pre><code class="lang-mermaid">graph LR
HiGeom --&gt; HiDisp
HiDisp --&gt; HiCbtr
HiCbtr --&gt; HiMech
HiMech --&gt; HiUniNc
HiUniNc --&gt; HiNc
HiDisp --&gt; Hi.WinForm
HiDisp --&gt; Hi.WpfPlus
style HiNc fill:#d3d,stroke:#333,stroke-width:2px
</code></pre>
<h3 id="ui-framework-support">UI Framework Support</h3>
<p>If you need to develop Windows desktop applications:</p>
<ul>
<li>For Windows Forms applications, use the <code>Hi.WinForm</code> package.</li>
<li>For WPF applications, use the <code>Hi.WpfPlus</code> package.</li>
</ul>
<div class="NOTE">
<h5>Note</h5>
<p>See <a class="xref" href="../rendering/custom-rendering-canvas.html">Building Your Own Rendering Canvas</a> to build the rendering canvas cross-platform.</p>
</div>
<h2 id="hiapi-sample-code">HiAPI Sample Code</h2>
<p>Download the sample repositories below to get the samples. They demonstrate various aspects of using HiAPI for machining simulation:</p>
<ul>
<li>HiNC-2025-webservice
<ul>
<li><a href="https://superhightech-gitea.webredirect.org/HiAPI/HiNC-2025-webservice.git">https://superhightech-gitea.webredirect.org/HiAPI/HiNC-2025-webservice.git</a></li>
<li>The source of the shipped HiNC application itself — a Quasar SPA served by ASP.NET Core. It is the production-scale example: every screen you see in the product is built from the public API documented here, and each component is dissected in <a class="xref" href="../../anatomy/index.html">HiNC App Anatomy</a>.</li>
</ul>
</li>
<li>Hi.Sample
<ul>
<li><a href="https://superhightech-gitea.webredirect.org/HiNC-Deploy/Hi.Sample.git">https://superhightech-gitea.webredirect.org/HiNC-Deploy/Hi.Sample.git</a></li>
<li>The repository generally contains the sample codes without using rendering canvas.</li>
</ul>
</li>
<li>Hi.Sample.Wpf
<ul>
<li><a href="https://superhightech-gitea.webredirect.org/HiNC-Deploy/Hi.Sample.Wpf.git">https://superhightech-gitea.webredirect.org/HiNC-Deploy/Hi.Sample.Wpf.git</a></li>
<li>The repository generally contains the sample code that requires rendering canvas.</li>
</ul>
</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="getting-started.html">Getting Started with HiAPI</a> — wiring this feed into a project and writing the first program against it</li>
<li><a href="../rendering/index.html">Rendering</a> — what the Hi.WinForm and Hi.WpfPlus packages above are for</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,37 @@
<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="packages-and-samples.html" name="" title="HiAPI Packages and Sample Code">HiAPI Packages and Sample Code</a>
</li>
<li>
<a href="getting-started.html" name="" title="Getting Started">Getting Started</a>
</li>
<li>
<a href="basic-geometry.html" name="" title="Geometry Objects">Geometry Objects</a>
</li>
<li>
<a href="message-management.html" name="" title="Message Management">Message Management</a>
</li>
<li>
<a href="xml-io.html" name="" title="XML IO">XML IO</a>
</li>
</ul>
</div>
</div>
</div>
</div>
@@ -0,0 +1,2 @@
{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"HiAPI Packages and Sample Code","href":"packages-and-samples.html","topicHref":"packages-and-samples.html"},{"name":"Getting Started","href":"getting-started.html","topicHref":"getting-started.html"},{"name":"Geometry Objects","href":"basic-geometry.html","topicHref":"basic-geometry.html"},{"name":"Message Management","href":"message-management.html","topicHref":"message-management.html"},{"name":"XML IO","href":"xml-io.html","topicHref":"xml-io.html"}]}
@@ -0,0 +1,393 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>About XML IO | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="About XML IO | 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="Technique-XmlIo">
<h1 id="about-xml-io">About XML IO</h1>
<p>The XML IO design pattern in HiNc Framework is based on <a class="xref" href="../../api/Hi.Common.XmlUtils.IMakeXmlSource.html">IMakeXmlSource</a> interface and <a class="xref" href="../../api/Hi.Common.XmlUtils.XFactory.html">XFactory</a> class. This pattern provides a standardized way to serialize and deserialize objects to and from XML format.</p>
<p>Don't serialize the runtime member object like <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.func-1">Func&lt;TResult&gt;</a> or <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.action">Action</a> either cache object. The runtime objects can be optionally sent by the <code>res</code> part on the XFactory Registration or set by the other host or dependent object. If it is set by the other object, then there is nothing can do to it in the XML IO procedure.</p>
<h2 id="core-components">Core Components</h2>
<h3 id="imakexmlsource-interface">IMakeXmlSource Interface</h3>
<p>The <a class="xref" href="../../api/Hi.Common.XmlUtils.IMakeXmlSource.html">IMakeXmlSource</a> interface defines the contract for objects that can be serialized to XML format. It contains a single method <code>MakeXmlSource</code>.</p>
<h3 id="xfactory">XFactory</h3>
<p><a class="xref" href="../../api/Hi.Common.XmlUtils.XFactory.html">XFactory</a> is an instance class with a process-wide <code>Default</code> singleton (<code>XFactory.Default</code>). The instance form exists for test isolation and parallel pipelines that need disjoint generator registries; the static <code>Gen&lt;T&gt;</code> / <code>GenByChild&lt;T&gt;</code> / <code>GenByFile&lt;T&gt;</code> entry points always read from <code>Default</code>.</p>
<p>Each instance owns its own <code>Generators</code> dictionary (XML element name → generator delegate). Types add themselves via a <code>Reg(factory)</code> call (see below).</p>
<h3 id="explicit-registration-via-regxfactory-factory--null">Explicit Registration via <code>Reg(XFactory factory = null)</code></h3>
<p>Every class implementing IMakeXmlSource exposes a public static <code>Reg</code> method:</p>
<pre><code class="lang-csharp">public static void Reg(XFactory factory = null)
{
factory ??= XFactory.Default;
factory.Generators.TryAdd(XName, (xml, baseDirectory, relFile, progress, res)
=&gt; new MyClass(xml, baseDirectory, relFile, progress));
}
</code></pre>
<p>Key properties:</p>
<ul>
<li><strong>Explicit.</strong> Callers see registration happen — no hidden side effect from accessing a static member or constructing a type.</li>
<li><strong>Idempotent.</strong> Uses <code>TryAdd</code>, so the same <code>Reg</code> may be invoked any number of times from any number of boot paths.</li>
<li><strong>Composable.</strong> Custom factory instances are supported via the optional <code>factory</code> parameter; default usage (<code>MyClass.Reg();</code>) populates <code>XFactory.Default</code>.</li>
</ul>
<p>For example, see <a class="xref" href="../../api/Hi.Milling.Apts.BallApt.html">BallApt</a>:</p>
<pre><code class="lang-csharp" name="XmlRegistration">/// &lt;summary&gt;
/// Registers this type's deserializer with the given &lt;see cref=&quot;XFactory&quot;/&gt;
/// (or &lt;see cref=&quot;XFactory.Default&quot;/&gt; when &lt;paramref name=&quot;factory&quot;/&gt; is
/// &lt;c&gt;null&lt;/c&gt;). Idempotent.
/// &lt;/summary&gt;
public static void Reg(XFactory factory = null)
{
factory ??= XFactory.Default;
factory.Generators.TryAdd(XName, (xml,baseDirectory, relFile, progress, res) =&gt; new BallApt(xml));
}
</code></pre><h3 id="composite-types-chain-regfactory-on-dependents">Composite types chain <code>Reg(factory)</code> on dependents</h3>
<p>When a class deserializes child elements via <code>XFactory.Gen&lt;T&gt;</code> / <code>XFactory.GenByChild&lt;T&gt;</code>, its <code>Reg(factory)</code> must chain <code>Reg(factory)</code> on each concrete child type so the whole dependency graph is reachable from a single root call:</p>
<pre><code class="lang-csharp">public static void Reg(XFactory factory = null)
{
factory ??= XFactory.Default;
DependentA.Reg(factory);
DependentB.Reg(factory);
factory.Generators.TryAdd(XName, (xml, baseDirectory, relFile, progress, res)
=&gt; new MyComposite(xml, baseDirectory, relFile, progress));
}
</code></pre>
<p>For polymorphic deserialization (<code>GenByChild&lt;IInterface&gt;</code>), the composite must chain every concrete implementation that may appear in the XML. The largest composite, <a class="xref" href="../../api/Hi.NcParsers.SoftNcRunner.html">SoftNcRunner</a>, chains roughly 130 dependents (every dependency, initializer, segmenter, syntax, and semantic the NC pipeline may deserialize).</p>
<h3 id="multi-name-registration-legacy-aliases">Multi-name registration (legacy aliases)</h3>
<p>When the XML payload may carry an old element name for backward compatibility, register the current <code>XName</code> first and group legacy aliases under a <code>//legacy aliases</code> comment:</p>
<pre><code class="lang-csharp">public static void Reg(XFactory factory = null)
{
factory ??= XFactory.Default;
XFactory.XGeneratorDelegate gen = (xml, baseDirectory, relFile, progress, res)
=&gt; new MachiningProject(xml, baseDirectory, progress);
factory.Generators.TryAdd(XName, gen);
//legacy aliases
factory.Generators.TryAdd(&quot;MachiningCourse&quot;, gen);
factory.Generators.TryAdd(&quot;MillingCourse&quot;, gen);
}
</code></pre>
<h3 id="iprogress-threading">IProgress Threading</h3>
<p>The <code>IProgress&lt;IMessage&gt;</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&lt;IMessage&gt; progress)
{
Child = XFactory.GenByChild&lt;IChild&gt;(
src.Element(nameof(Child)), subBaseDirectory, progress);
}
</code></pre>
<p>Parsing errors are reported to the caller-provided <code>IProgress&lt;IMessage&gt;</code> handler.</p>
<h3 id="what-a-failing-child-does">What a failing child does</h3>
<p><code>XFactory</code> does not swallow failures: a generator that throws propagates, and the load fails with it. Tolerance is opted into per type, and is visible at the place that chose it.</p>
<ul>
<li>A type that owns an external file catches its own read failure and reports it, then comes up without that content. <a class="xref" href="../../api/Hi.Geom.StlFile.html">StlFile</a> reports the <strong>resolved</strong> path rather than the relative <code>SourceFile</code>, because the base directory is gone by the time the message is read anywhere else — a load response, a message panel — and the folder is what says which machine or part file is missing.</li>
<li><a class="xref" href="../../api/Hi.Common.XmlUtils.XFactory.html#Hi_Common_XmlUtils_XFactory_GenListSkippingUnloadable_">GenListSkippingUnloadable</a> drops the list entries whose element name is unregistered or whose generator throws, reporting each as a warning. It is for lists whose schema drifts while a feature is in development — the NC pipeline's dependency, initializer and syntax lists — where a partially loadable list beats aborting the whole load.</li>
</ul>
<h2 id="writing">Writing</h2>
<p><a class="xref" href="../../api/Hi.Common.XmlUtils.IMakeXmlSource.html#Hi_Common_XmlUtils_IMakeXmlSource_MakeXmlSource_">MakeXmlSource</a> produces the element; the file layer around it is <a class="xref" href="../../api/Hi.Common.XmlUtils.XmlUtil.html#Hi_Common_XmlUtils_XmlUtil_MakeXmlSourceToFileRef_">MakeXmlSourceToFileRef</a>, which either hands that element back inline — when no relative file is named for it — or writes it to a file of its own and returns a file-reference element in its place. That is what makes a project file a document of references instead of one large document.</p>
<h3 id="children-first-parent-last">Children first, parent last</h3>
<p><code>MakeXmlSourceToFileRef</code> prepares only the directory up front. The children's own side files — nested XML, STL copies — are written from inside <code>MakeXmlSource</code>, and the parent file itself is written by <a class="xref" href="../../api/Hi.Common.XmlUtils.XmlUtil.html#Hi_Common_XmlUtils_XmlUtil_SaveToFileRef_">SaveToFileRef</a> only once every child has succeeded. A child that fails — a locked or read-only side file, a full disk, a serialization bug — therefore leaves the previous version of the parent intact, rather than an empty file that points nowhere.</p>
<p>An <strong>existing</strong> parent is probed for write access before the children are touched, by opening it without truncating. A read-only or locked parent fails there, instead of leaving a folder of freshly written children beside an unchanged old parent.</p>
<h3 id="copy-on-save-and-the-file-that-must-stay-missing">Copy-on-save, and the file that must stay missing</h3>
<p><a class="xref" href="../../api/Hi.Geom.StlFile.html">StlFile</a> serializes as its path and copies its mesh beside the new document, but only when nothing is at that target path already — the mechanism that lets one project be written under several base directories without rewriting meshes that are there. <a class="xref" href="../../api/Hi.Geom.StlFile.html#Hi_Geom_StlFile_SaveStlToFile_">SaveStlToFile</a> owns the directory creation, from the resolved path, and stays away from the file system entirely when <a class="xref" href="../../api/Hi.Geom.StlFile.html#Hi_Geom_StlFile_CacheStl">CacheStl</a> is null.</p>
<p>That last condition is the contract, not a guard. An STL whose source was missing when the project was read has no cached mesh and must stay missing: a zero-length file in its place reads back as an opaque loading failure instead of an exception naming the path, and it is a new untracked file in someone's project folder.</p>
<div class="IMPORTANT">
<h5>Important</h5>
<p><strong><code>exhibitionOnly</code> suppresses the XML writes; it does not reach the copy.</strong> <code>MakeXmlSourceToFileRef</code> and <code>SaveToFileRef</code> both honour it and produce the reference elements without creating anything, but <code>StlFile</code>'s copy-on-save does not consult it at all. So a purely in-memory round trip still copies cached meshes into a base directory that lacks them — which is what a project load does when it materialises the runtime equipment from the authored one. Writing is not confined to saving.</p>
</div>
<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();
</code></pre>
<p><code>LocalProjectService.Reg()</code> chains <code>MachiningProject.Reg()</code>, which in turn chains every type the simulation pipeline may deserialize. After this single call returns, <code>XFactory.Default.Generators</code> carries the full deserialization graph.</p>
<h2 id="implementation-patterns">Implementation Patterns</h2>
<h3 id="simple-value-objects">Simple Value Objects</h3>
<p>See <a class="xref" href="../../api/Hi.Milling.Apts.BallApt.html">BallApt</a> implementation:</p>
<pre><code class="lang-csharp" name="XmlImplementation">/// &lt;summary&gt;
/// Name for XML IO.
/// &lt;/summary&gt;
public static string XName =&gt; nameof(BallApt);
/// &lt;summary&gt;
/// Ctor.
/// &lt;/summary&gt;
/// &lt;param name=&quot;src&quot;&gt;XML&lt;/param&gt;
public BallApt(XElement src)
{
Diameter_mm = double.Parse(src.Element(&quot;D&quot;).Value);
FluteHeight_mm = double.Parse(src.Element(&quot;FluteH&quot;).Value);
}
/// &lt;inheritdoc/&gt;
public XElement MakeXmlSource(string baseDirectory, string relFile, bool exhibitionOnly) =&gt; ToXElement();
/// &lt;inheritdoc/&gt;
public XElement ToXElement()
{
return new XElement(XName,
new XElement(&quot;D&quot;, Diameter_mm),
new XElement(&quot;FluteH&quot;, FluteHeight_mm)
);
}
</code></pre><h3 id="complex-data-structures">Complex Data Structures</h3>
<p>See <a class="xref" href="../../api/Hi.Milling.SpindleCapability.html">SpindleCapability</a> implementation:</p>
<pre><code class="lang-csharp" name="XmlImplementation">/// &lt;summary&gt;
/// Name for XML IO.
/// &lt;/summary&gt;
public static string XName =&gt; nameof(SpindleCapability);
/// &lt;summary&gt;
/// Initializes a new instance of the &lt;see cref=&quot;SpindleCapability&quot;/&gt; class.
/// &lt;/summary&gt;
/// &lt;param name=&quot;src&quot;&gt;The XML element containing spindle data.&lt;/param&gt;
/// &lt;param name=&quot;baseDirectory&quot;&gt;The base directory for resolving relative paths.&lt;/param&gt;
/// &lt;param name=&quot;res&quot;&gt;Additional resolution parameters.&lt;/param&gt;
public SpindleCapability(XElement src, string baseDirectory, params object[] res)
{
this.SetNameNote(src);
if (src.Element(nameof(EnergyEfficiency)) != null)
EnergyEfficiency = XmlConvert.ToDouble(
src.Element(nameof(EnergyEfficiency)).Value);
src.Element(nameof(WorkingTemperatureUpperBoundary_C))?.SelfInvoke(
e =&gt; WorkingTemperatureUpperBoundary_C = XmlConvert.ToDouble(e.Value));
src.Element(nameof(GearShiftSpindleSpeed_rpm))?.Value?.SelfInvoke(
s =&gt; GearShiftSpindleSpeed_rpm = string.IsNullOrEmpty(s)
? null : XmlConvert.ToDouble(s));
if (src.Element(nameof(DryRunFrictionPowerCoefficient_mWdrpm)) != null)
DryRunFrictionPowerCoefficient_mWdrpm = XmlConvert.ToDouble(
src.Element(nameof(DryRunFrictionPowerCoefficient_mWdrpm)).Value);
if (src.Element(nameof(DryRunWindagePowerCoefficient_pWdrpm3)) != null)
DryRunWindagePowerCoefficient_pWdrpm3 = XmlConvert.ToDouble(
src.Element(nameof(DryRunWindagePowerCoefficient_pWdrpm3)).Value);
if (src.Element(&quot;SpindleSpeedToPowerContours&quot;) != null) //for legacy
WorkableDurationToSpindleSpeedPowerContoursDictionary_min_cycleDs_kW =
src.Element(&quot;SpindleSpeedToPowerContours&quot;).Elements(&quot;Contour&quot;)
.ToDictionary(
contourElem =&gt;
{
double r = XmlConvert.ToDouble(contourElem.Attribute(&quot;InsistentRatio&quot;)?.Value);
//600s=10mins
return r == 1 ? double.PositiveInfinity : (r * 600);
},
contourElem =&gt; contourElem.Elements(&quot;SpindleSpeedToPower&quot;).Select(
elem =&gt; new Vec2d(
XmlConvert.ToDouble(elem.Element(&quot;SpindleSpeed-RPM&quot;).Value) / 60,
XmlConvert.ToDouble(elem.Element(&quot;Power-kW&quot;).Value)))
.ToList());
src.Element(&quot;WorkableDurationToSpindleSpeedPowerContoursDictionary&quot;)
?.SelfInvoke(dicElem =&gt;
{
WorkableDurationToSpindleSpeedPowerContoursDictionary_min_cycleDs_kW
= dicElem.Elements(&quot;Contour&quot;)
.ToDictionary(
contourElem =&gt; XmlConvert.ToDouble(
contourElem.Attribute(&quot;WorkableDuration-min&quot;)?.Value),
contourElem =&gt; contourElem.Elements(&quot;SpindleSpeedToPower&quot;).Select(
elem =&gt; new Vec2d(
XmlConvert.ToDouble(elem.Element(&quot;SpindleSpeed-RPM&quot;).Value) / 60,
XmlConvert.ToDouble(elem.Element(&quot;Power-kW&quot;).Value)))
.ToList());
});
if (src.Element(&quot;SpindleSpeedToTorqueContours&quot;) != null) //for legacy
WorkableDurationToSpindleSpeedTorqueContoursDictionary_min_cycleDs_Nm =
src.Element(&quot;SpindleSpeedToTorqueContours&quot;).Elements(&quot;Contour&quot;)
.ToDictionary(
contourElem =&gt;
{
double r = XmlConvert.ToDouble(contourElem.Attribute(&quot;InsistentRatio&quot;)?.Value);
//600s=10mins
return r == 1 ? double.PositiveInfinity : (r * 600);
},
contourElem =&gt; contourElem.Elements(&quot;SpindleSpeedToTorque&quot;).Select(
elem =&gt; new Vec2d(
XmlConvert.ToDouble(elem.Element(&quot;SpindleSpeed-RPM&quot;).Value) / 60,
XmlConvert.ToDouble(elem.Element(&quot;Torque-Nm&quot;).Value)))
.ToList());
src.Element(&quot;WorkableDurationToSpindleSpeedTorqueContoursDictionary&quot;)
?.SelfInvoke(dicElem =&gt;
{
//MessageUtil.WriteLine($&quot;dicElem: {dicElem}&quot;);
WorkableDurationToSpindleSpeedTorqueContoursDictionary_min_cycleDs_Nm =
dicElem.Elements(&quot;Contour&quot;).ToDictionary(
contourElem =&gt; XmlConvert.ToDouble(
contourElem.Attribute(&quot;WorkableDuration-min&quot;)?.Value),
contourElem =&gt; contourElem.Elements(&quot;SpindleSpeedToTorque&quot;).Select(
elem =&gt; new Vec2d(
XmlConvert.ToDouble(elem.Element(&quot;SpindleSpeed-RPM&quot;).Value) / 60,
XmlConvert.ToDouble(elem.Element(&quot;Torque-Nm&quot;).Value)))
.ToList());
//MessageUtil.WriteLine($&quot;keys: {string.Join(',',WorkableDurationToSpindleSpeedTorqueContoursDictionary_min_cycleDs_Nm.Select(e=&gt;e.Key))}&quot;);
});
//for legacy compatible.
if (src.Element(&quot;SpindleSpeedToPower--RPM-to-kW&quot;) != null)
InfInsistentSpindleSpeedToPower_cycleDs_kW =
src.Element(&quot;SpindleSpeedToPower--RPM-to-kW&quot;).Elements()
.Select(elem =&gt; new Vec2d(XmlConvert.ToDouble(elem.Attribute(
&quot;SpindleSpeed-RPM&quot;).Value) / 60,
XmlConvert.ToDouble(elem.Value))).ToList();
//for legacy compatible.
if (src.Element(&quot;SpindleSpeedToTorque--RPM-to-Nm&quot;) != null)
InfInsistentSpindleSpeedToTorque_cycleDs_Nm =
src.Element(&quot;SpindleSpeedToTorque--RPM-to-Nm&quot;).Elements()
.Select(elem =&gt; new Vec2d(XmlConvert.ToDouble(elem.Attribute(
&quot;SpindleSpeed-RPM&quot;).Value) / 60,
XmlConvert.ToDouble(elem.Value))).ToList();
}
/// &lt;inheritdoc/&gt;
public XElement MakeXmlSource(string baseDirectory, string relFile, bool exhibitionOnly)
{
return new XElement(XName,
this.GetNameNoteXElementList(),
new XElement(nameof(EnergyEfficiency), EnergyEfficiency),
new XElement(nameof(GearShiftSpindleSpeed_rpm), GearShiftSpindleSpeed_rpm),
new XElement(nameof(DryRunFrictionPowerCoefficient_mWdrpm),
DryRunFrictionPowerCoefficient_mWdrpm),
new XElement(nameof(DryRunWindagePowerCoefficient_pWdrpm3),
DryRunWindagePowerCoefficient_pWdrpm3),
new XElement(&quot;WorkableDurationToSpindleSpeedPowerContoursDictionary&quot;,
WorkableDurationToSpindleSpeedPowerContoursDictionary_min_cycleDs_kW.OrderBy(entry =&gt; entry.Key)
.Select(entry =&gt; new XElement(&quot;Contour&quot;,
new XAttribute(&quot;WorkableDuration-min&quot;, entry.Key),
entry.Value.Select(entry
=&gt; new XElement(&quot;SpindleSpeedToPower&quot;,
new XElement(&quot;SpindleSpeed-RPM&quot;, entry.X * 60),
new XElement(&quot;Power-kW&quot;, entry.Y)))))
),
new XElement(&quot;WorkableDurationToSpindleSpeedTorqueContoursDictionary&quot;,
WorkableDurationToSpindleSpeedTorqueContoursDictionary_min_cycleDs_Nm.OrderBy(entry =&gt; entry.Key)
.Select(entry =&gt; new XElement(&quot;Contour&quot;,
new XAttribute(&quot;WorkableDuration-min&quot;, entry.Key),
entry.Value.Select(entry
=&gt; new XElement(&quot;SpindleSpeedToTorque&quot;,
new XElement(&quot;SpindleSpeed-RPM&quot;, entry.X * 60),
new XElement(&quot;Torque-Nm&quot;, entry.Y)))))
)
);
}
</code></pre><h2 id="best-practices">Best Practices</h2>
<ol>
<li><strong>XName</strong>: Always define static <code>XName</code> property matching the class name.</li>
<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&lt;T&gt;</code> / <code>XFactory.GenByChild&lt;T&gt;</code>, add <code>T.Reg(factory);</code> to the chain. For polymorphic <code>GenByChild&lt;IInterface&gt;</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&lt;IMessage&gt;</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>
<li><strong>Side files from inside <code>MakeXmlSource</code>, never ahead of it</strong>: an implementation that owns an external file writes it from within <code>MakeXmlSource</code>, which is what keeps the framework's children-first ordering true. It must not create a file for content it does not hold — a source that was missing at load time stays missing, because an empty file is harder to diagnose than an absent one.</li>
</ol>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="message-management.html">Message Management</a> — the diagnostic channel threaded through deserialization</li>
<li><a href="basic-geometry.html">Geometry Objects</a> — the types most often persisted through this pattern</li>
<li><a href="../rendering/color-guide.html">Color Guide System</a> — a project-registered implementation serialized this way</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,142 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Technique | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Technique | 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="Technique-Index">
<h1 id="technique">Technique</h1>
<p>The durable knowledge behind HiNC: the milling physics the simulation implements, what the
machine and the workstation can actually deliver, how a measured quantity gets into the model,
and how the NC optimizer decides a feed rate. GUI-neutral by design — this is the layer that
stays true when a screen moves.</p>
<p>Ordered by how far the subject sits from the cutting edge: what happens at the edge first, then
what the equipment around it can supply, then what is measured, then what is rewritten — and last
the API surfaces an application is built on: scripting, rendering, and the mechanism topology.</p>
<ul>
<li><a href="milling-physics/index.html">Milling Physics</a> — The frames the numbers live in, the criteria that decide whether a cut survives, tool wear, and the cutter-side levers that move both</li>
<li><a href="machine-capability/index.html">Machine Capability</a> — Spindle boundary curves and thermal envelope, controller behaviour, CAM-side drift, and the simulating workstation's own throughput ceiling</li>
<li><a href="measurement/index.html">Measurement</a> — How a real cutter angle and a real cutting force get from the bench into the model</li>
<li><a href="nc-optimization/index.html">NC Optimization</a> — What the optimizer targets, what limits each step, and why corner feed rates come out low</li>
<li><a href="simulation-performance/index.html">Simulation Performance</a> — What the simulation itself costs to run, and what a coarser mesh gives up</li>
<li><a href="validation/index.html">Validation</a> — What has been checked against measurement, how closely it agreed, and where the agreement stops</li>
<li><a href="scripting/index.html">Scripting</a> — The C# command surface a session is driven from, the step objects a run produces, and the message stream it reports through</li>
<li><a href="rendering/index.html">Rendering</a> — Hosting the display engine in a UI framework, producing what it draws, and deciding the colour a machining step comes out with</li>
<li><a href="mechanism/index.html">Mechanism</a> — The kinematic topology a machine is assembled from, the transform matrices that move it, and drawing an assembly through its anchors</li>
<li><a href="nc-dialects/index.html">NC Dialects</a> — The interpreter that turns a controller program into motion, and the brand-by-brand support matrix</li>
<li><a href="api-foundations/index.html">API Foundations</a> — The packages, the shape of a first program, and the geometry, messaging and serialization services everything else assumes</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="../manual/index.html">Manual</a> — how to do it in the app, chapter by chapter</li>
<li><a href="../manual/setup/index.html">Setup</a> — the equipment settings these models stand behind</li>
<li><a href="../workflows/index.html">Workflows</a> — end-to-end task guides</li>
<li><a href="../api/Hi.Machining.html">API Reference</a> — the generated C# reference</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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

@@ -0,0 +1,186 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CAM Floating-Point Drift Triggers Floor-Contact Force Peaks | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="CAM Floating-Point Drift Triggers Floor-Contact Force Peaks | 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="Technique-CamFloatingPointDrift">
<h1 id="cam-floating-point-drift-triggers-floor-contact-force-peaks">CAM Floating-Point Drift Triggers Floor-Contact Force Peaks</h1>
<p>Layered (Z-stepped) cuts can produce force peaks that look like simulation bugs but reflect a real physical sensitivity: sub-micron contact between the cutter bottom face and the previous-layer floor produces a large force difference, and CAM-generated NC programs often drift between layers by similar amounts on whichever axis carries the repeated path. This coupling between CAM floating-point drift and sub-micron floor sensitivity is rarely recognized in typical workflows; HiNC surfaces and diagnoses it through smart-tool-holder validation and force-simulation comparison.</p>
<p>See also <a class="xref" href="../nc-optimization/nc-optimization-principles.html">NC Optimization</a> and <a class="xref" href="../nc-optimization/corner-behavior.html">Corner Feedrate Behavior</a>.</p>
<h2 id="phenomenon">Phenomenon</h2>
<p>In a Z-stepped uniform cut, one or two specific layers occasionally show a sharp force spike. In the example below, the X-direction force peak reaches ~865 N where adjacent layers stay near a ~477 N steady level on a D16 mm cutter in aluminum. Users often interpret this as a simulation anomaly because the NC optimizer slows the feedrate dramatically at the spike.</p>
<p><img src="cam-floating-point-drift-img/layered-cut.png" alt="Layered cut schematic">
<em>Schematic of a Z-stepped layered cut. Each horizontal trace is one layer; sub-thousandth-mm in-plane drift between layers (Y in this example) shifts where each layer enters and exits the previous-layer floor.</em></p>
<p><img src="cam-floating-point-drift-img/spike-per-rev-force.png" alt="Per-revolution force on a spike layer">
<em>Spike layer that contacts the previous-layer ridge — X peaks reach ~865 N.</em></p>
<p><img src="cam-floating-point-drift-img/normal-per-rev-force.png" alt="Per-revolution force on a normal layer">
<em>Adjacent normal layer at the &ldquo;same&rdquo; XY — X stays near ~477 N.</em></p>
<h2 id="mechanism">Mechanism</h2>
<p>Smart-tool-holder measurements show that the cutter bottom face is sensitive to sub-micron contact with the previous-layer floor:</p>
<ul>
<li>A gap of less than 1 μm already produces a measurable force difference.</li>
<li>Below the minimum effective chip thickness — 7.5 μm in this example, and in general varying with workpiece material and cutter edge geometry — no chip is formed, but friction on the cutter's lower contact band still loads the spindle.</li>
<li>In simulation, modeling the cutter floor as lifted by 0.15 μm versus not lifted yields visibly different spindle-torque waveforms — and only the lifted version matches the real smart-holder torque shape.</li>
</ul>
<p>Simulation force peaks driven by floor contact therefore reflect a real sensitivity, not a numerical artifact.</p>
<h2 id="nc-side-trigger-layer-to-layer-drift">NC-Side Trigger: Layer-to-Layer Drift</h2>
<p>CAM-generated NC programs frequently drift by ~0.001 mm between consecutive Z layers when they traverse the &ldquo;same&rdquo; position. In the example below, the drift falls on Y; in other programs it may fall on X or any in-plane axis along the repeated path.</p>
<pre><code>N1000 G01 Y10.001 (layers 1..4)
N1100 G01 Y10.002 (layer 5)
N… G01 Y10.005 (last layer)
</code></pre>
<p>Each layer lands at a slightly different position relative to the previous floor. Some layers contact the leftover ridge from the layer above; others miss it. The contacting layers exhibit the peak.</p>
<h2 id="why-the-simulation-peak-is-real">Why the Simulation Peak Is Real</h2>
<p>The simulation force model simplifies how the cutter upper portion engages when the gap is below the minimum effective chip thickness, so the simulated peak may be slightly larger than the real peak. For ductile materials (aluminum being a representative case), friction dominates the cutting force, so the overestimate is small.</p>
<p>The actual machine has independent safety margins: the controller decelerates at corners (see <a class="xref" href="../nc-optimization/corner-behavior.html">Corner Feedrate Behavior</a>), and cutter rotation provides a flute-level <a href="#probabilistic-peak-dodging">Probabilistic Peak Dodging</a> effect.</p>
<p>In the example above, the cutter remains inside its safe limits at the spike peak (~865 N versus the ~477 N baseline). Harder materials would be more prone to flute breakage at the same NC, but the fix is the same.</p>
<h2 id="probabilistic-peak-dodging">Probabilistic Peak Dodging</h2>
<p>For a multi-flute cutter, whether a contacting layer actually produces a peak depends on the flute phase at the contact moment. Force samples within one flute period typically split into:</p>
<ul>
<li>~6 samples in the high-force window (e.g., above ~500 N in the spike-layer chart above)</li>
<li>~3 samples low enough to &ldquo;miss&rdquo; the spike</li>
</ul>
<p>i.e., ~2/3 fall in the high-force window and ~1/3 miss it. This is why neighboring layers can give different results despite nominally identical geometry. It also explains why the issue is a yield problem rather than a deterministic failure — and why peaks still appear after fixing some, but not all, of the drifting NC lines.</p>
<h2 id="mitigation-fix-the-nc">Mitigation: Fix the NC</h2>
<p>Clean up the NC program rather than tune the simulation:</p>
<ul>
<li>Identify the drifting positions (typically a few dozen lines in a layered pocket) and snap the drifting coordinate to a consistent value across layers.</li>
<li>This restores a clean floor-to-floor relationship and removes the spurious peaks.</li>
</ul>
<p>Tuning the simulation around the peak would mask a signal that the controller and the cutter both feel in practice.</p>
<h2 id="when-the-nc-cannot-be-modified">When the NC Cannot Be Modified</h2>
<p>For mature client products the NC is often a frozen standard, and the floor-contact peaks have to be accepted on the simulation side. Two optimizer-side levers absorb the peaks without modifying the NC:</p>
<ul>
<li><p><strong><a class="xref" href="../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MinFeedPerTooth_mm">MinFeedPerTooth_mm</a> (API)</strong> — a floor on the optimizer's chosen feed-per-tooth. Set it to a scaled fraction of the original feed so the optimizer cannot slow further at a single-revolution spike:</p>
<pre><code class="lang-csharp">MachiningStepBuilt += (preStep, curStep) =&gt;
{
curStep.UpdateNcOptOption(opt =&gt;
{
opt.MinFeedPerTooth_mm = FeedPerTooth_mm * scale;
});
};
</code></pre>
</li>
<li><p><strong><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_OptYieldingUtilizationFactor">OptYieldingUtilizationFactor</a> (API)</strong> — raise the acceptance threshold for the yield-stress ratio based on the observed stable extreme (e.g., if 150 % is routinely tolerated, set <code>1.5</code>). See <a href="../nc-optimization/nc-optimization-principles.html#tuning-peak-tolerance">Tuning Peak Tolerance</a> for the full set of per-metric factors and which can be relaxed.</p>
</li>
</ul>
<p>Prefer these over modifying cutting coefficients to suppress peaks. The coefficients describe material behaviour; tuning them away from physical values masks the real signal for every downstream calculation (force, moment, wear, thermal).</p>
<div class="NOTE">
<h5>Note</h5>
<p>The current API does not filter single-revolution spikes out of the optimization basis. If a client policy requires excluding such spikes, apply the levers above at the <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_MachiningStepBuilt">MachiningStepBuilt</a> (API) callback so per-step settings can be overridden without disturbing the global option.</p>
</div>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../milling-physics/probabilistic-peak-crack.html">Probabilistic Peak &amp; Cutter Crack</a> — The general statement of the probabilistic peak effect this section describes</li>
<li><a class="xref" href="../nc-optimization/corner-behavior.html">Corner Feedrate Behavior</a> — Force-peak interaction with controller deceleration at corners</li>
<li><a class="xref" href="../measurement/smart-holder-training.html">Smart Holder Training</a> — Smart tool holder measurement that confirms sub-micron sensitivity</li>
<li><a class="xref" href="../milling-physics/relief-face-avoidance.html">Relief Face Avoidance</a> — Related geometry sensitivity on the relief side</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,140 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Machine Capability | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Machine Capability | 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="">
<h1 id="machine-capability">Machine Capability</h1>
<p>What the machine tool in the loop can actually deliver, and what happens when a cut asks for more
than that. Every ceiling here belongs to the equipment executing the cut, and none of them is
visible in the NC program.</p>
<p>Ordered by what the ceiling belongs to — the spindle first, then the controller and the NC
toolchain feeding it.</p>
<h2 id="spindle">Spindle</h2>
<ul>
<li><a href="spindle-capability.html">Spindle Capability</a> — Duration-keyed boundary curves, the thermal envelope, and the denominators behind the four torque and power ratios</li>
<li><a href="spindle-power-evaluation.html">Spindle Power Evaluation</a> — Empirical validation of the simulated spindle power against measured Fanuc ServoGuide TCMD data</li>
</ul>
<h2 id="controller-and-nc-toolchain">Controller and NC Toolchain</h2>
<ul>
<li><a href="cam-floating-point-drift.html">CAM Floating-Point Drift</a> — Sub-micron layer-to-layer drift in CAM output meeting a genuinely sub-micron floor-contact sensitivity, and what to do when the NC cannot be changed</li>
</ul>
<h2 id="condition-of-the-machine-itself">Condition of the Machine Itself</h2>
<ul>
<li><a href="machine-condition.html">Machine Condition and Safety Factors</a> — Why the results hold only while every ratio stays under 100%, and how a worn machine is described to the optimizer</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="../milling-physics/index.html">Milling Physics</a> — the physics of the cut that runs into these ceilings</li>
<li><a href="../nc-optimization/index.html">NC Optimization</a> — what the optimizer does with these ceilings once it knows them</li>
<li><a href="../simulation-performance/index.html">Simulation Performance</a> — the other machine in the loop: what the workstation running the simulation can deliver</li>
<li><a href="../validation/index.html">Validation</a> — the measurements these ceilings were calibrated and checked against</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,141 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Machine Condition and Safety Factors | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Machine Condition and Safety Factors | 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="Technique-MachineCondition">
<h1 id="machine-condition-and-safety-factors">Machine Condition and Safety Factors</h1>
<p>Two machines of the same model, one maintained and one not, do not accept the same NC program.
The simulation models the cut, not the wear state of the machine running it, so the machine's
condition enters through the safety factors — and setting them honestly is the difference between
an optimized program that runs and one that only runs in simulation.</p>
<h2 id="the-simulation-is-valid-only-under-stable-machining">The Simulation Is Valid Only Under Stable Machining</h2>
<p>Every availability ratio HiNC reports — yield stress, spindle torque, spindle power, thermal
yield — is a fraction of what the cut is allowed to demand. <strong>The results describe reality only
while all of them stay under 100%.</strong> Above that the machine is no longer doing what the model
says it is doing: the spindle droops, the feed per tooth rises, and the divergence grows rather
than staying proportional.</p>
<p>Reading those ratios, and what each one means at 100%, is
<a href="../milling-physics/machinability.html">Evaluating Process Machinability</a>.</p>
<h2 id="safety-factors-are-where-the-machines-condition-goes">Safety Factors Are Where the Machine's Condition Goes</h2>
<p>HiNC exposes a safety factor per limiting quantity — spindle power, spindle torque, thermal
yield — and they feed straight into the optimizer's output. They are not decoration: raising a
factor lowers the feed the optimizer is willing to assign, across the whole program.</p>
<p>Use them to describe the machine you actually have. A machine in poor condition should be given
larger factors, or a lower preferred cutting force, so that the optimized program leaves it more
headroom. The same program optimized for a well-maintained machine will be faster, and will be
the wrong program for the worn one.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="spindle-capability.html">Spindle Capability</a> — the curves the power and torque factors are applied to</li>
<li><a href="../milling-physics/chatter.html">Chatter, and What the Simulation Does About It</a> — the failure mode the force ceiling exists to avoid, and the two cases it does not cover</li>
<li><a class="xref" href="../validation/cutting-force.html">Cutting Force and Torque Validation</a> — a worked maximum feed rate, and where the safety factor enters it</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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

@@ -0,0 +1,228 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Spindle Capability | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Spindle Capability | 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="Technique-SpindleCapability">
<h1 id="spindle-capability">Spindle Capability</h1>
<p><a class="xref" href="../../api/Hi.Milling.SpindleCapability.html">SpindleCapability</a> <small>(API)</small> describes the energy, torque, power, and thermal envelope of a machine spindle. It is loaded as XML (<code>.SpindleCapability</code> files under <code>Resource/SpindleCapability/</code>) and lives on <a class="xref" href="../../api/Hi.Machining.MachiningEquipmentUtils.MachiningEquipment.html#Hi_Machining_MachiningEquipmentUtils_MachiningEquipment_SpindleCapability">SpindleCapability</a> <small>(API)</small> as part of the project equipment. This page explains what the model represents physically and how the per-step ratios on a machining step are derived.</p>
<p>For editing values interactively, see <a class="xref" href="../../anatomy/general-setup/spindle-capability.html">Spindle Capability Page</a>. For empirical validation of the resulting power numbers against Fanuc ServoGuide, see <a class="xref" href="spindle-power-evaluation.html">Spindle Power Evaluation</a>.</p>
<h2 id="boundary-curves-continuous-vs-instantaneous">Boundary curves: continuous vs instantaneous</h2>
<p><img src="spindle-capability-img/fanuc-at12-12000i.jpg" alt="Power and torque vs spindle speed for a FANUC aT12/12000i spindle"></p>
<p><em>A typical spindle datasheet chart (FANUC aT12/12000i, shipped as <code>FANUC-aT12-12000i.SpindleCapability</code>): torque (N-m) and power (kW) plotted against spindle speed. The <strong>S1 Cont.</strong> curves are the continuous boundary; the <strong>S3 60%</strong> curves are a short-duration rating. HiNC stores exactly these curves, keyed by workable duration.</em></p>
<p>The capability stores <strong>two dictionaries keyed by workable duration (in minutes)</strong>, mapping spindle speed to the maximum power or torque the spindle can deliver for that duration:</p>
<ul>
<li><a class="xref" href="../../api/Hi.Milling.SpindleCapability.html#Hi_Milling_SpindleCapability_WorkableDurationToSpindleSpeedPowerContoursDictionary_min_cycleDs_kW">WorkableDurationToSpindleSpeedPowerContoursDictionary_min_cycleDs_kW</a> <small>(API)</small></li>
<li><a class="xref" href="../../api/Hi.Milling.SpindleCapability.html#Hi_Milling_SpindleCapability_WorkableDurationToSpindleSpeedTorqueContoursDictionary_min_cycleDs_Nm">WorkableDurationToSpindleSpeedTorqueContoursDictionary_min_cycleDs_Nm</a> <small>(API)</small></li>
</ul>
<p>Two duration keys are special:</p>
<ul>
<li><strong><code>PositiveInfinity</code></strong> — the <strong>continuous boundary</strong>. The spindle can run at any (speed, value) point on this curve forever without overheating. Industry usage often calls this the S1 rating.</li>
<li><strong>The smallest finite key</strong> (e.g. <code>15</code>) — the <strong>instantaneous boundary</strong>. The spindle can run at any (speed, value) point on this curve only for that workable duration before the temperature ceiling is reached.</li>
</ul>
<p>A capability typically also has intermediate keys (e.g. <code>60</code> minutes) which document the spindle's published rating curve.</p>
<div class="NOTE">
<h5>Note</h5>
<p><strong>Why duration-keyed and not just two curves?</strong></p>
<p>The duration key serves two roles. The contour values give peak load capability (used by the ratio computation, see below). The duration values implicitly encode the thermal time constants (used by the thermal envelope, see further below). One family of curves drives both.</p>
</div>
<p>If <a class="xref" href="../../api/Hi.Milling.SpindleCapability.html#Hi_Milling_SpindleCapability_GearShiftSpindleSpeed_rpm">GearShiftSpindleSpeed_rpm</a> <small>(API)</small> is set, each contour is treated as two segments split at that speed; only the segment for the current spindle speed is used for interpolation. Outside the segment, interpolation uses nearest-neighbour clamping rather than extrapolation.</p>
<h2 id="how-the-four-ratios-are-computed">How the four ratios are computed</h2>
<p>For every machining step where the spindle speed changes, <a class="xref" href="../../api/Hi.MachiningProcs.SpindleSpeedCache.html">SpindleSpeedCache</a> <small>(API)</small> interpolates each of the four contour-based curves at the current spindle speed and stores four scalar boundaries:</p>
<table>
<thead>
<tr>
<th>Boundary (denominator)</th>
<th>Source contour</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>MinInsistentRatioSpindleTorqueBoundary_Nm</code></td>
<td>smallest-key entry of the torque dictionary, interpolated at current rpm</td>
</tr>
<tr>
<td><code>InfInsistentRatioSpindleTorqueBoundary_Nm</code></td>
<td><code></code>-key entry of the torque dictionary, interpolated at current rpm</td>
</tr>
<tr>
<td><code>MinInsistentRatioSpindlePowerBoundary_W</code></td>
<td>smallest-key entry of the power dictionary, interpolated at current rpm</td>
</tr>
<tr>
<td><code>InfInsistentRatioSpindlePowerBoundary_W</code></td>
<td><code></code>-key entry of the power dictionary, interpolated at current rpm</td>
</tr>
</tbody>
</table>
<p>The four <code>MachiningStep</code> ratios are then divisions:</p>
<div class="math">
\[
\begin{aligned}
\text{MaxSpindleTorqueRatio} &amp;= \frac{\text{MaxAxialTorque\_Nm}}{\text{MinInsistentRatioSpindleTorqueBoundary\_Nm}} \\[6pt]
\text{ContinueSpindleTorqueRatio} &amp;= \frac{\text{MaxAxialTorque\_Nm}}{\text{InfInsistentRatioSpindleTorqueBoundary\_Nm}} \\[6pt]
\text{MaxSpindlePowerRatio} &amp;= \frac{\text{inputPower\_W}}{\text{MinInsistentRatioSpindlePowerBoundary\_W}} \\[6pt]
\text{ContinueSpindlePowerRatio} &amp;= \frac{\text{inputPower\_W}}{\text{InfInsistentRatioSpindlePowerBoundary\_W}}
\end{aligned}
\]</div>
<p>Because the continuous boundary is always lower than (or equal to) the short-duration boundary, the corresponding <code>Continue-</code> ratio is always greater than (or equal to) its <code>Max-</code> counterpart for the same load:</p>
<ul>
<li>A <strong><code>Max-</code> ratio above 100%</strong> means the spindle is overdriven instantaneously and will trip thermal protection within the rated short duration. This is the criterion <a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html#Hi_MachiningSteps_MachiningStep_MaxSpindleTorqueRatio">MaxSpindleTorqueRatio</a> <small>(API)</small> and <a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html#Hi_MachiningSteps_MachiningStep_MaxSpindlePowerRatio">MaxSpindlePowerRatio</a> <small>(API)</small> use to flag tool breakage on <a class="xref" href="../milling-physics/machinability.html">Process Machinability</a>.</li>
<li>A <strong><code>Continue-</code> ratio above 100%</strong> means the spindle cannot sustain this load forever — short bursts may still be safe. Useful for pacing long operations rather than predicting immediate failure.</li>
</ul>
<h2 id="input-power-vs-output-power">Input power vs output power</h2>
<p>The power numerator above is <strong>input power</strong> (energy entering the spindle), not output power (energy reaching the cutting end). They are related by the spindle's energy efficiency:</p>
<p><span class="math">\(\text{inputPower\_W} = \frac{\text{AbsAxialPower\_W}}{\text{EnergyEfficiency}}\)</span></p>
<p>— where <code>EnergyEfficiency</code> is <a class="xref" href="../../api/Hi.Milling.SpindleCapability.html#Hi_Milling_SpindleCapability_EnergyEfficiency">EnergyEfficiency</a> <small>(API)</small> and <code>AbsAxialPower_W</code> is what the cutting actually demands. The lost fraction <span class="math">\((1 - \text{EnergyEfficiency})\)</span> becomes heat that the thermal envelope has to dissipate.</p>
<p><a class="xref" href="spindle-power-evaluation.html">Spindle Power Evaluation</a> documents the empirical justification for this conversion against measured Fanuc ServoGuide TCMD data.</p>
<h2 id="dry-run-idle-power">Dry-run idle power</h2>
<p>Even when the cutter is in air, a rotating spindle dissipates power as bearing friction and aerodynamic windage. HiNC models this as a sum of a linear-in-rpm term (bearing friction) and a higher-order term (windage), parameterised by:</p>
<ul>
<li><a class="xref" href="../../api/Hi.Milling.SpindleCapability.html#Hi_Milling_SpindleCapability_DryRunFrictionPowerCoefficient_mWdrpm">DryRunFrictionPowerCoefficient_mWdrpm</a> <small>(API)</small> — friction term coefficient</li>
<li><a class="xref" href="../../api/Hi.Milling.SpindleCapability.html#Hi_Milling_SpindleCapability_DryRunWindagePowerCoefficient_pWdrpm3">DryRunWindagePowerCoefficient_pWdrpm3</a> <small>(API)</small> — windage term coefficient</li>
</ul>
<p>The friction term dominates at low rpm; the windage term takes over at high rpm. The thermal envelope (next section) uses the larger of the dry-run idle power and the cutting-induced heat, so the spindle keeps warming up even during air moves.</p>
<h2 id="thermal-envelope">Thermal envelope</h2>
<p>The same <code>SpindleCapability</code> also drives a thermal model of the spindle body. <strong>You do not set heat capacity or convection directly</strong> — the thermal model is auto-calibrated from your existing inputs.</p>
<ul>
<li>The <strong>continuous (<code></code>-key) curve</strong> plus <a class="xref" href="../../api/Hi.Milling.SpindleCapability.html#Hi_Milling_SpindleCapability_WorkingTemperatureUpperBoundary_C">WorkingTemperatureUpperBoundary_C</a> <small>(API)</small> together determine how fast the spindle dumps heat at steady state. Physically: the continuous rating is, by definition, the load the spindle can hold forever without exceeding the working-temperature ceiling — so HiNC infers the steady-state heat-loss capacity from this constraint.</li>
<li>The <strong>shortest-duration curve</strong> plus its duration key together determine how much heat the spindle can absorb before reaching the ceiling. Physically: the short-duration rating is, by definition, the load that brings the spindle to the ceiling exactly within that workable time — so HiNC infers the body's effective thermal mass from this constraint.</li>
</ul>
<p><strong>What this means for you</strong>: refining the contour data (more accurate (speed, power/torque) points, better matched duration keys) automatically improves both load-capacity prediction and thermal-response speed. There is no separate thermal parameter to tune.</p>
<h3 id="per-step-temperature-outputs">Per-step temperature outputs</h3>
<p>At each step the body temperature evolves under whatever heat input is currently applied (cutting losses or dry-run, whichever is larger), approaching the steady-state temperature implied by that heat input. The two outputs published per step are:</p>
<ul>
<li><a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html#Hi_MachiningSteps_MachiningStep_SpindleTemperature_C">SpindleTemperature_C</a> <small>(API)</small> — current body temperature</li>
<li><a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html#Hi_MachiningSteps_MachiningStep_SpindleWorkingTemperatureRatio">SpindleWorkingTemperatureRatio</a> <small>(API)</small> — body temperature normalised so that ambient is <code>0</code> and the working-temperature ceiling is <code>1</code>. A value approaching <code>1.0</code> means the spindle is near its thermal limit.</li>
</ul>
<div class="NOTE">
<h5>Note</h5>
<p><code>SpindleWorkingTemperatureRatio</code> describes the <strong>spindle housing</strong> as a whole. It is <strong>not</strong> the same as the cutter-edge thermal failure tracked by <code>ThermalYieldRatio</code> in <a class="xref" href="../milling-physics/machinability.html">Process Machinability</a>, which is a localized cutting-edge phenomenon.</p>
</div>
<h2 id="editing-and-file-io">Editing and file IO</h2>
<p>Capabilities are persisted as XML (<code>.SpindleCapability</code> files). Three pre-built spindles ship in <code>Resource/SpindleCapability/</code>:</p>
<ul>
<li><code>FANUC-aT12-12000i.SpindleCapability</code></li>
<li><code>TMV-720A-STD-8000RPM.SpindleCapability</code></li>
<li><code>VP-8--Fanuc-10000RPM.SpindleCapability</code></li>
</ul>
<p>To edit values interactively, see <a class="xref" href="../../anatomy/general-setup/spindle-capability.html">Spindle Capability Page</a> in the Quasar webservice. The desktop WPF app does not yet have a dedicated editor; load capabilities through the equipment's <code>ObjectManagementMenuButton</code> instead.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../milling-physics/machinability.html">Process Machinability</a> — uses <code>MaxSpindleTorqueRatio</code> / <code>MaxSpindlePowerRatio</code> for tool-breakage prediction</li>
<li><a class="xref" href="spindle-power-evaluation.html">Spindle Power Evaluation</a> — empirical validation of HiNC spindle power against Fanuc ServoGuide measurements</li>
<li><a class="xref" href="../scripting/step-fields.html">Step Field Reference</a> — where the spindle power and torque ratios surface, step by step</li>
<li><a class="xref" href="../../anatomy/general-setup/spindle-capability.html">Spindle Capability Page</a> — UI editor walkthrough</li>
<li><a class="xref" href="../../workflows/project-data-checklist.html">Project Data Checklist</a> — what to collect from the machine owner, the speed-power-torque curve included</li>
<li><a class="xref" href="../simulation-performance/cpu-usage.html">CPU Usage During Simulation</a> — the workstation-side throughput ceiling, alongside this spindle-side one</li>
<li><a href="machine-condition.html">Machine Condition and Safety Factors</a> — the factors applied to these curves, and why a worn machine needs larger ones</li>
<li><a href="../../manual/setup/spindle-capability.html">Spindle Capability Setup</a> — entering these curves in the application, and the stand-in a project without them inherits</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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 911 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

@@ -0,0 +1,217 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Spindle Power Evaluation | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Spindle Power Evaluation | 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="Technique-SpindlePowerEvaluation">
<h1 id="spindle-power-evaluation">Spindle Power Evaluation</h1>
<p>For the spindle capability model itself (boundary curves, thermal envelope, and the four torque/power ratios), see <a class="xref" href="spindle-capability.html">Spindle Capability</a>. This page focuses on <strong>empirical validation</strong> of HiNC's spindle-power evaluation against measured data.</p>
<h2 id="the-role-of-spindle-power-for-energy-cost-of-milling">The role of spindle power for energy cost of Milling</h2>
<p>The energy distribution can be referenced from Heidenhain's published measurements<a id="fnref:1" href="#fn:1" class="footnote-ref"><sup>1</sup></a>. The total machine power splits into two main flows:</p>
<ul>
<li><strong>External processing</strong> — Cooling lubricant and Compressed air, typically supplied by facility infrastructure.</li>
<li><strong>Electrical power of the machine</strong> — The machine's own electrical consumption, further split into Auxiliary components and CNC control (which contains Spindle and Feed drives).</li>
</ul>
<div class="NOTE">
<h5>Note</h5>
<p><strong>Case A: Mean power requirement for manufacturing a housing part — Roughing (13 kW)</strong></p>
<pre><code class="lang-mermaid">sankey-beta
Total power (13 kW),External processing,6.4
External processing,Cooling lubricant,5.1
External processing,Compressed air,1.3
Total power (13 kW),Electrical power of the machine,6.6
Electrical power of the machine,Auxiliary components,3.1
Electrical power of the machine,CNC control,3.5
CNC control,Spindle,3.25
CNC control,Feed drives,0.25
</code></pre>
</div>
<div class="NOTE">
<h5>Note</h5>
<p><strong>Case A: Mean power requirement for manufacturing a housing part — Finishing (7.4 kW)</strong></p>
<pre><code class="lang-mermaid">sankey-beta
Total power (7.4 kW),External processing,2.8
External processing,Cooling lubricant,1.5
External processing,Compressed air,1.3
Total power (7.4 kW),Electrical power of the machine,4.6
Electrical power of the machine,Auxiliary components,2.8
Electrical power of the machine,CNC control,1.8
CNC control,Spindle,1.55
CNC control,Feed drives,0.25
</code></pre>
</div>
<div class="NOTE">
<h5>Note</h5>
<p><strong>Case B: Mean power consumption of the drives during rough facing</strong></p>
<p>Face-milling cutter D = 60 mm, speed 4 100 rpm, infeed depth 4 mm.</p>
<pre><code class="lang-mermaid">xychart-beta
title &quot;Mean power consumption of the drives (kW)&quot;
x-axis [&quot;Spindle&quot;, &quot;Feed axes&quot;]
y-axis &quot;Mean power (kW)&quot; 0 --&gt; 20
bar [18.5, 0.3]
</code></pre>
</div>
<p>In Case A roughing, the workpiece material seems like Al6061. CNC control (Spindle + Feed drives) takes about 27% of the total power (3.5 / 13 ≈ 26.9%).</p>
<p>From HiNC spindle power evaluation:</p>
<ul>
<li>Milling S45C cost 200% energy compare to Al6061T6.</li>
<li>Milling Inconel718 cost 800% energy compare to Al6061T6</li>
</ul>
<p>i.e.,</p>
<ul>
<li>Spindle power of milling S45C occupies 42% of total power.</li>
<li>Spindle power of milling Inconel718 occupies 75% of total power.</li>
</ul>
<p>Conclusion: Spindle Power matters for not easy-working materials for computing the energy cost of milling.</p>
<h2 id="verification-of-hinc-spindle-power-evaluation">Verification of HiNC Spindle Power Evaluation</h2>
<p>HiNC Spindle Power Evaluation is verified by comparison of the gathering Data based on the following setting.</p>
<h3 id="setting">Setting</h3>
<ul>
<li><p>Machine Tool: YCM NDV102A</p>
</li>
<li><p>Max Spindle Power: 22.4 kW</p>
</li>
<li><p>Controller: Fanuc 31i-Model A</p>
</li>
<li><p>Sampling: 1ms</p>
</li>
<li><p>Total Spindle Expended Energy: 0.412 kWh</p>
<p>The total spindle expended energy is rearranged from Fanuc ServoGuide TCMD data.</p>
</li>
<li><p>Work Time: 8min 30s</p>
</li>
</ul>
<h3 id="comparison">Comparison</h3>
<p>The following figures are spindle power based on Controller and the spindle power evaluated by HiNC.</p>
<div class="NOTE">
<h5>Note</h5>
<p><strong>The spindle power by Fanuc ServoGuide TCMD(%) * MaxSpindlePower</strong></p>
<p><img src="spindle-power-evaluation-img/Fanuc_Spindle_Power.png" alt="Fanuc_Spindle_Power"></p>
</div>
<div class="NOTE">
<h5>Note</h5>
<p><strong>The evaluated spindle power by HiNC Milling Power * Energy Conversion Efficiency (here is 0.4)</strong></p>
<p><img src="spindle-power-evaluation-img/HiNC_Spindle_Power.png" alt="HiNC_Spindle_Power"></p>
</div>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="spindle-capability.html">Spindle Capability</a> — the model these measurements validate</li>
</ul>
<div class="footnotes">
<hr>
<ol>
<li id="fn:1">
<p>Data summarized from Heidenhain, <em>Technical Information: Aspects of Energy Efficiency in Machine Tools</em>, November 2010.<a href="#fnref:1" class="footnote-back-ref">&#8617;</a></p>
</li>
</ol>
</div>
</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,34 @@
<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="spindle-capability.html" name="" title="Spindle Capability">Spindle Capability</a>
</li>
<li>
<a href="spindle-power-evaluation.html" name="" title="Spindle Power Evaluation">Spindle Power Evaluation</a>
</li>
<li>
<a href="cam-floating-point-drift.html" name="" title="CAM Floating-Point Drift">CAM Floating-Point Drift</a>
</li>
<li>
<a href="machine-condition.html" name="" title="Machine Condition and Safety Factors">Machine Condition and Safety Factors</a>
</li>
</ul>
</div>
</div>
</div>
</div>
@@ -0,0 +1,2 @@
{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"Spindle Capability","href":"spindle-capability.html","topicHref":"spindle-capability.html"},{"name":"Spindle Power Evaluation","href":"spindle-power-evaluation.html","topicHref":"spindle-power-evaluation.html"},{"name":"CAM Floating-Point Drift","href":"cam-floating-point-drift.html","topicHref":"cam-floating-point-drift.html"},{"name":"Machine Condition and Safety Factors","href":"machine-condition.html","topicHref":"machine-condition.html"}]}
@@ -0,0 +1,129 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Measurement | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Measurement | 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="">
<h1 id="measurement">Measurement</h1>
<p>How a physical quantity gets from a real cutter or a real cut into the model. These are protocols
rather than theory: follow them and the simulation is fed a measured number instead of a default.</p>
<p>Ordered from the cutter on the bench, through the instrument that watches it, to the cutter in the
cut and the experiment that has to be designed before it.</p>
<ul>
<li><a href="radial-angle-measurement.html">Radial Angle Measurement</a> — Reading the radial rake and radial relief angles off a cutting-plane scan</li>
<li><a href="smart-tool-holder.html">Smart Tool Holder</a> — The moment arm and installation angle that decide whether the holder's torque is scaled right at all</li>
<li><a href="smart-holder-training.html">Smart Holder Training</a> — The three cut shapes and the conditions that let a smart tool holder train milling coefficients</li>
<li><a href="training-cut-set-design.html">Designing a Training Cut Set</a> — The two degeneracies that leave a coefficient unrecoverable whatever the data quality, and the helix and feed spread that remove them</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="../milling-physics/index.html">Milling Physics</a> — the model these measurements feed</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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

@@ -0,0 +1,136 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Radial Rake Angle and Radial Relief Angle Measurement on the Cutting Plane | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Radial Rake Angle and Radial Relief Angle Measurement on the Cutting Plane | 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="Technique-RadialAngleMeasurement">
<h1 id="radial-rake-angle-and-radial-relief-angle-measurement-on-the-cutting-plane">Radial Rake Angle and Radial Relief Angle Measurement on the Cutting Plane</h1>
<p>The method for measuring angles on the tool cutting plane scan is illustrated below:</p>
<p><img src="radial-angle-measurement-img/clip-cutter-angle-scheme.jpg" alt="Tool angle measurement"></p>
<h2 id="radial-rake-angle-α">Radial Rake Angle (α)</h2>
<ol>
<li>Sweep along the tool rotation direction to find the trailing point A of the cutting edge</li>
<li>Connect point A to the center O</li>
<li>The angle ∠OAA' between line OA and the first polyline endpoint A' on the cutting side of the edge is the rake angle α</li>
</ol>
<h2 id="radial-relief-angle-β">Radial Relief Angle (β)</h2>
<ol>
<li>Find the contact point B between the tool and the envelope circle</li>
<li>Construct the tangent line Lt to the envelope circle at point B</li>
<li>BB' is the first line segment on the relief side of the tool</li>
<li>Pick an arbitrary point B'' on Lt in the relief direction</li>
<li>The angle ∠B'BB'' between BB' and Lt is the relief angle β</li>
</ol>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../milling-physics/relief-face-avoidance.html">Relief Face Avoidance</a> — the minimum relief angle the measured β has to clear</li>
<li><a class="xref" href="../milling-physics/cutter-geometry.html">Cutter Geometry</a> — the cutter description these angles are part of</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 @@
%
G40 G17 G49 G54 G80
G91 G28 Z0.0
T01 M06
S1500 M03
G43 Z10. H01
G01 G90 X2. Y-20. M08
G01 Z-1. F600.
G01 Y16.
Z10.
G01 X14. Y-20.
G01 Z-1. F600.
G01 Y16.
Z10.
G01 X26. Y-20.
G01 Z-1. F600.
G01 Y16.
Z10.
G00 G90 X-20. Y10.
G17 G01 Z-1. F600.
S50 M03
;@MachiningResolution_mm=0.0625;
;@SetNcResolutionFeedPerTooth();
X13. F20. ;@LineSelection("lineA",AnchorMode.FirstTouch,AnchorMode.LastTouch);
X25. F10. ;@LineSelection("lineB",AnchorMode.FirstTouch,AnchorMode.LastTouch);
S1500 M03
Z10. F600.
G91 G28 Z0.
T02 M06
S50 M03
G43 Z10. H02
G01 G90 X10. Y30. M08
G01 Z-4. F20. ;@LineSelection("drillA",AnchorMode.FirstTouch,AnchorMode.LastTouch);
Z10.
X20.
G01 Z-4. F10. ;@LineSelection("drillB",AnchorMode.FirstTouch,AnchorMode.LastTouch);
Z10.
M09
M05
G91 G28 Z0.0
M30
%
Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

@@ -0,0 +1,156 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Smart Tool Holder Coefficient Training | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Smart Tool Holder Coefficient Training | 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="Technique-SmartHolderTraining">
<h1 id="smart-tool-holder-coefficient-training">Smart Tool Holder Coefficient Training</h1>
<p>By cutting the following shapes and collecting three-direction torques with a smart tool holder, you can train milling coefficients through HiNC projects.</p>
<h2 id="overview">Overview</h2>
<p><img src="smart-holder-training-img/training-path-diagram.png" alt="Smart Tool Holder Coefficient Training Path Diagram"></p>
<ul>
<li>T1 End mill D10 4 flutes</li>
<li>T2 Drill bit, diameter unrestricted</li>
</ul>
<p>Click to download <a href="smart-holder-training-img/train.nc">NC code</a>.</p>
<div class="NOTE">
<h5>Note</h5>
<p><strong>Adjusting Machining Method</strong></p>
<ul>
<li>Speed and feed can be changed according to material conditions, but feed per tooth must be in multiples.</li>
<li>Slower spindle speed allows the smart tool holder to collect more data per unit time.</li>
<li>The wall thickness between the two slots in <a href="#shape-i">Shape I</a> needs to be thin enough so that <a href="#shape-ii">Shape II</a> cutting is discontinuous per revolution.</li>
</ul>
</div>
<h2 id="shape-i">Shape I</h2>
<p>Shape I consists of three red slots, which are preparatory shapes, no need to collect smart tool holder data.</p>
<ul>
<li>ae10; ap1; S1500; F600</li>
</ul>
<h2 id="shape-ii">Shape II</h2>
<p>Shape II penetrates through the thin walls between the three red slots, need to collect smart tool holder data.</p>
<ul>
<li>lineA: T1; ap1; S50; F20 (frt0.1)</li>
<li>lineB: T1; ap1; S50; F10 (frt0.05)</li>
</ul>
<h2 id="shape-iii">Shape III</h2>
<p>Shape III is drilling, need to collect smart tool holder data.</p>
<ul>
<li>drillA: T2; dp4; S50; F20</li>
<li>drillB: T2; dp4; S50; F10</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="training-cut-set-design.html">Designing a Training Cut Set</a> — what a set of passes has to span before the coefficients are recoverable at all</li>
<li><a href="smart-tool-holder.html">Smart Tool Holder</a> — the moment arm and installation angle a training run assumes are already right</li>
<li><a class="xref" href="../machine-capability/cam-floating-point-drift.html">CAM Floating-Point Drift</a> — a measurement error source to rule out before trusting a training run</li>
<li><a class="xref" href="../milling-physics/milling-physics-coordinates.html">Milling Physics Coordinates</a> — the spindle-rotation frame the holder's torques are reported in</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,160 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Smart Tool Holder | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Smart Tool Holder | 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="Technique-SmartToolHolder">
<h1 id="smart-tool-holder">Smart Tool Holder</h1>
<p>A smart tool holder is a machine tool accessory equipped with sensors that can monitor force and torque data in real time during machining. To ensure simulation accuracy, the following parameters must be configured correctly:</p>
<h2 id="sensor-configuration">Sensor Configuration</h2>
<h3 id="moment-arm-height">Moment Arm Height</h3>
<ul>
<li>The sensor height setting has a significant impact on simulation accuracy</li>
<li>This height defines the moment arm distance for the torque measured by the sensor</li>
<li>If not set correctly, a constant scaling error will appear in the torque calculation</li>
</ul>
<h3 id="coordinate-system-alignment">Coordinate System Alignment</h3>
<ol>
<li><p><strong>Basic Principle</strong></p>
<ul>
<li>The cutting edge should be aligned with the sensor's X-axis</li>
<li>Ensure the sensor XY coordinate system is consistent with the simulation XY coordinate system</li>
<li>The impact of coordinate system misalignment is relatively smaller compared to the moment arm setting</li>
</ul>
</li>
<li><p><strong>Installation Angle Adjustment</strong></p>
<ul>
<li>If perfect alignment is not possible, measure the offset angle</li>
<li>Enter the measured angle in the &ldquo;Installation Angle&rdquo; field</li>
<li>The maximum possible deviation is 45 degrees</li>
</ul>
</li>
</ol>
<h2 id="factors-affecting-accuracy">Factors Affecting Accuracy</h2>
<h3 id="coordinate-transformation-effects">Coordinate Transformation Effects</h3>
<ul>
<li>An installation angle deviation can cause up to a √2 factor difference in values</li>
<li>This difference is inherently a result of coordinate transformation, not a measurement accuracy issue</li>
<li>Even with the same smart tool holder, different installation angles will produce different measurement data</li>
</ul>
<h3 id="best-practices">Best Practices</h3>
<ol>
<li>Prioritize accurate moment arm height configuration</li>
<li>Align the cutting edge with the sensor X-axis as closely as possible</li>
<li>If perfect alignment is not achievable, always measure and set the correct installation angle</li>
</ol>
<p>Only with these parameters correctly configured will the simulated micro-waveforms match the actual sensor measurements.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="smart-holder-training.html">Smart Holder Training</a> — the cut shapes and conditions that turn a correctly configured holder into trained milling coefficients</li>
<li><a class="xref" href="../milling-physics/milling-physics-coordinates.html">Milling Physics Coordinates</a> — the frame the holder's forces and torques are reported in</li>
<li><a href="../../manual/setup/cutter.html">Cutter</a> — where the holder's settings are entered in the application</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,34 @@
<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="radial-angle-measurement.html" name="" title="Radial Angle Measurement">Radial Angle Measurement</a>
</li>
<li>
<a href="smart-tool-holder.html" name="" title="Smart Tool Holder">Smart Tool Holder</a>
</li>
<li>
<a href="smart-holder-training.html" name="" title="Smart Holder Training">Smart Holder Training</a>
</li>
<li>
<a href="training-cut-set-design.html" name="" title="Designing a Training Cut Set">Designing a Training Cut Set</a>
</li>
</ul>
</div>
</div>
</div>
</div>
@@ -0,0 +1,2 @@
{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"Radial Angle Measurement","href":"radial-angle-measurement.html","topicHref":"radial-angle-measurement.html"},{"name":"Smart Tool Holder","href":"smart-tool-holder.html","topicHref":"smart-tool-holder.html"},{"name":"Smart Holder Training","href":"smart-holder-training.html","topicHref":"smart-holder-training.html"},{"name":"Designing a Training Cut Set","href":"training-cut-set-design.html","topicHref":"training-cut-set-design.html"}]}
@@ -0,0 +1,183 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Designing a Training Cut Set | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Designing a Training Cut Set | 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="Technique-TrainingCutSetDesign">
<h1 id="designing-a-training-cut-set">Designing a Training Cut Set</h1>
<p>Training recovers the six milling coefficients by fitting simulated force against measured force
over a set of passes. Whether a given set of cutters and passes can determine those coefficients at
all is a property of the design rather than of the data quality: two specific degeneracies leave a
coefficient unrecoverable however clean the samples are. Each has its own fix, and neither fix
substitutes for the other.</p>
<h2 id="the-two-degeneracies">The Two Degeneracies</h2>
<table>
<thead>
<tr>
<th>What goes wrong</th>
<th>How it shows up in the result</th>
<th>What removes it</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>The bending-moment plane null.</strong> In rotation-averaged Mx/My one particular combination of the edge and normal shear coefficients is exactly unobservable</td>
<td>Shear coefficients come back orders of magnitude too large, and their signs flip between runs on the same data</td>
<td><strong>Helix diversity</strong> — at least two clearly different helix angles among the cutters trained together</td>
</tr>
<tr>
<td><strong>Slopeintercept collinearity</strong> between the shear and ploughing coefficients, which enter the fit as the slope and the intercept of the same line</td>
<td>The correlation still looks good. Shear comes back low by roughly a tenth, ploughing high by around a half</td>
<td><strong>A spread of feed per tooth</strong> across the passes — a range of chip loads, not a range of depths</td>
</tr>
</tbody>
</table>
<p>A set that fixes one and not the other still fails, and it fails in the manner of the one left
unfixed. Both are properties of the cut set as a whole, so both are decided before any metal is cut.</p>
<h2 id="why-the-helix-angle-is-the-lever">Why the Helix Angle Is the Lever</h2>
<p>The unobservable direction is a combination of the edge and normal shear coefficients weighted by
the cosine and sine of the helix angle. Changing the helix angle does not remove that direction —
it <strong>rotates</strong> it. Two helix angles far enough apart therefore give two different null directions
whose only common point is zero, so the pooled fit has no null at all, and the edge coefficient
becomes identifiable from the measurement alone: no torque channel, no prior value, no externally
supplied phase.</p>
<p>A single helix angle of zero is the worst case, and misleadingly so, because it aligns the null
exactly with the edge-coefficient axis. A cut set built that way returns an edge coefficient that
is null-space fill rather than a value the data demands, while the normal coefficient beside it
comes out as the most accurate number on the page.</p>
<div class="IMPORTANT">
<h5>Important</h5>
<p>At a single helix angle the individual edge and normal shear values are not meaningful on their
own, even when the correlation coefficient is high. A training run is judged by the force it
reproduces over time — see <a class="xref" href="../validation/cutting-force.html">Cutting Force and Torque</a>
not by the magnitude of any one coefficient.</p>
</div>
<h2 id="flute-count-is-not-a-lever">Flute Count Is Not a Lever</h2>
<p>Adding more passes with the same symmetric multi-flute cutter buys nothing, at any feed. That
sample subspace is degenerate, and more of it stays degenerate: a set made only of symmetric
four-flute passes cannot derive its own cutter phase, and the fit collapses rather than degrading.
What buys identifiability is spread — in helix angle, and in feed per tooth.</p>
<p>Symmetric off-the-shelf cutters are nonetheless sufficient. Custom single-flute grinding is not
required for either fix; a pair of stock two-flute cutters ground at different helix angles carries
the same identifiability, and is what a shop can actually obtain.</p>
<h2 id="engagement-side-cuts-rather-than-slots">Engagement: Side Cuts Rather Than Slots</h2>
<p>The useful excitation comes from passes whose radial engagement is small enough that at most one
helix flute is in contact at a time — the engagement arc narrower than the angular pitch between
flutes. A full slot holds several flutes in the cut at once and averages away the very variation
the fit needs. Stepping a shallow side cut along the edge of the stock produces a set where no pass
is ever a slot.</p>
<p>Adding depth of cut is not a substitute. Depth moves the load without changing the chip load, so it
does nothing for the slopeintercept collinearity that the feed-per-tooth spread exists to break.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="smart-holder-training.html">Smart Holder Training</a> — the shipped cut shapes these constraints apply to</li>
<li><a class="xref" href="../milling-physics/cutter-geometry.html">Cutter Geometry</a> — where the helix angle this design turns on is described and entered</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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

@@ -0,0 +1,149 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Assembly Anchors | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Assembly Anchors | 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="Technique-AssemblyAnchors">
<h1 id="assembly-anchors">Assembly Anchors</h1>
<p>How the parts of a machining scene are held together. Assembly in HiNC is not a placement step but a
statement of coincidence: two named anchors are declared equal, and everything they belong to moves
so that they are. The buckle anchors below are the joints the machine, fixture, workpiece and tool
are assembled at.</p>
<p>Ordered from what an anchor is, to the two chains built out of them.</p>
<h2 id="what-an-anchor-is">What an Anchor Is</h2>
<p><strong>Anchors</strong> are used for assembly purposes. When anchors between geometries coincide, assembly is completed.</p>
<p>Strictly speaking, an <strong>Anchor</strong> is not a point, but a coordinate system. For two coordinate systems to be equal, their origins must coincide and their rotation directions must be the same.</p>
<div class="NOTE">
<h5>Note</h5>
<p><strong>Anchor Assembly Example</strong></p>
<p>As shown in the figure below, there are two components, each with two anchors, {<code>AnchorA</code>,<code>AnchorB</code>} and {<code>AnchorC</code>,<code>AnchorD</code>} respectively.
The two components are assembled by making <code>AnchorB</code> and <code>AnchorC</code> coincide.</p>
<p><img src="assembly-anchors-img/Anchor%20for%20contact.png" alt="anc-contact"></p>
</div>
<h2 id="worktable-anchor-and-workpiece-anchor">Worktable Anchor and Workpiece Anchor</h2>
<p>The machine's worktable end is the chain's <code>w</code> anchor. The fixture carries a <code>TableBuckle</code> that meets it, and a <code>WorkpieceBuckle</code> that the workpiece meets — and the workpiece's own anchor there is named <code>FixtureBuckle</code>, so this joint is made of two anchors each named after the <em>other</em> part.</p>
<p>Only the machine-to-fixture branch carries an editable transform, which is where the fixture is placed on the table. The fixture-to-workpiece branch carries none: it is plain coincidence.</p>
<div class="NOTE">
<h5>Note</h5>
<p><strong>Workpiece Fixture Assembly Example</strong></p>
<p>Workpiece and fixture are assembled by making the fixture's <code>WorkpieceBuckle</code> and the workpiece's <code>FixtureBuckle</code> coincide.</p>
<p><img src="assembly-anchors-img/Anchor%20for%20contact%20workpiece%20and%20fixture.png" alt=""></p>
</div>
<p>If no fixture is set, both fixture anchors drop out of the chain and the machine's <code>w</code> anchor meets the workpiece's <code>FixtureBuckle</code> directly, carrying the same placement transform.</p>
<h2 id="spindle-anchor-and-cutter-anchor">Spindle Anchor and Cutter Anchor</h2>
<p>The machine's tool end is the chain's <code>t</code> anchor, and it meets the <code>SpindleBuckle</code> of the tool as a whole. Inside that tool the holder sits between spindle and cutter: the tool's <code>SpindleBuckle</code> meets the holder's own <code>SpindleBuckle</code>, and the holder's <code>CutterBuckle</code> meets the cutter's buckle anchor (<code>Buckle</code>).</p>
<p>If no holder is set, both holder anchors drop out and the tool's <code>SpindleBuckle</code> meets the cutter's <code>Buckle</code> directly. The machine-side joint is the same either way.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="topology.html">Kinematic Topology</a> — the anchor, branch and assembly classes this convention is expressed in</li>
<li><a href="../../manual/setup/anchor.html">Anchor</a> — where these relationships are edited in the application</li>
<li><a href="../../manual/setup/program-zero-alignment.html">Program Zero Alignment</a> — aligning the program origin onto these anchors</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,181 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Machine Chain Code | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Machine Chain Code | 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="Technique-ChainCode">
<h1 id="machine-chain-code">Machine Chain Code</h1>
<p>A machine tool file can carry its kinematic topology as a <strong>chain code</strong> — a short bracket notation
for the same connectivity the mechanism builder produces, meant for hand-editing the XML. It is read
and written by <a class="xref" href="../../api/Hi.Numerical.Xyzabc.CodeXyzabcChain.html">CodeXyzabcChain</a><small>(API)</small>, which builds the very
same mechanism, so a hand-written code and a builder-drawn structure are interchangeable — with two
exceptions on the way back: a mechanism with two components sharing one name, or with an unnamed
component that more than one segment would have to mention, cannot be written down as code.</p>
<p>The code carries <strong>connectivity only</strong>. Pivots, exact axis vectors, end-anchor offsets and shapes
are properties of the mechanism, and editing the code preserves them for every component whose name
is unchanged.</p>
<h2 id="the-notation">The Notation</h2>
<p>Each segment declares branches from left to right:</p>
<pre><code>[O][base][Z][C][w];[O][base][Y][X][B][S][t]
</code></pre>
<ul>
<li><p><code>[A][B][C]</code> is shorthand for the branches <code>[A][B];[B][C]</code>, so a segment is just a path.</p>
</li>
<li><p>Words are components. The <strong>same word in different segments is the same component</strong>, which is how
segments join into one structure.</p>
</li>
<li><p>The first word of the whole code names the ground anchor. Within a segment each branch runs from
the word on its left to the word on its right.</p>
</li>
<li><p>Reserved words are the topology keywords: <code>X</code>, <code>Y</code>, <code>Z</code>, <code>A</code>, <code>B</code>, <code>C</code> become motion axes, and <code>w</code>
and <code>t</code> become the end anchors. <strong>Any other word is a plain component</strong> carried along without
motion, such as <code>base</code> or <code>S</code> above. A code must name exactly one <code>[w]</code> and one <code>[t]</code>; the six
axes are optional, and each may be used at most once. That uniqueness check reads the words
without regard to letter case, so it refuses a code naming no table buckle at all — <em>the chain
code must contain the table buckle [w]</em> — and a code letting two components claim one role —
<em>more than one component claims the table buckle: [w], [W]</em>. A lone <code>[W]</code> satisfies it, one
component claiming the role, and builds a component named <code>W</code>; that code is refused further
along, by the exact-match end-anchor check below.</p>
</li>
<li><p><strong>Spell the keywords exactly</strong> — upper case for the axes, lower case for <code>t</code> and <code>w</code>. Everything
downstream of the code compares them as written: axis discovery, the default collision pairs, and
the end-anchor check a machine file is loaded through. So a mis-cased axis contributes no motion,
and a mis-cased end anchor stops the file loading, with a message naming the near miss.</p>
</li>
<li><p><code>[]</code> is an anonymous component. Each occurrence is a separate one, it cannot be referred to from
another segment, and it cannot hold a geometric shape — shapes are stored by component name.</p>
</li>
<li><p>Declaring the same branch twice is harmless; it states the same connection.</p>
</li>
<li><p>A segment with a single word just declares a component, which is how a ground anchor that only
receives branches gets named.</p>
</li>
<li><p>Any number of segments is allowed, so auxiliary structures can branch off any component:</p>
<pre><code>[O][base][Z][C][w];[O][base][Y][X][B][S][t];[base][loader][gripper]
</code></pre>
</li>
</ul>
<h2 id="direction-and-convergence">Direction and Convergence</h2>
<p><strong>Branch direction is free.</strong> A branch authored towards the ground anchor is simply written that way,
as in <code>[Z][O]</code>. A branch belongs to the component farther from the ground anchor, so <code>[O][Y]</code> and
<code>[Y][O]</code> both make <code>Y</code> the axis; only the direction differs. Pointing every branch away from the
ground anchor remains a readability convention — it makes the structure read outwards, ground → base
→ motion axes → the <code>t</code> and <code>w</code> end anchors — but the motion, the axis keywords and the default
collision pairs all read a branch the same way round regardless.</p>
<p><strong>Limbs may meet again.</strong> <code>[A][B][D];[A][C][D]</code> gives <code>D</code> two incoming branches. Only one route
through such a loop drives the motion, so use it for structure rather than for a second motion path.</p>
<p>Axis directions follow the machine-building convention: axes between the ground anchor and <code>w</code> are
seeded negative, the others positive.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="topology.html">Kinematic Topology</a> — the anchors, branches and assemblies this notation encodes</li>
<li><a href="../../manual/setup/machine-tool.html">Machine Tool</a> — building the same structure in the mechanism builder, and the keywords both forms share</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,136 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HiAPI Mechanics Overview | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="HiAPI Mechanics Overview | 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="HiMech.Overview">
<h1 id="mechanism">Mechanism</h1>
<p>How a machine tool is assembled out of moving parts, and how HiAPI solves where each part ends
up. A kinematic topology describes the motion relationships between components; from it come
forward and inverse kinematics, component placement, and the geometry collision detection runs
against.</p>
<p>Ordered from the structure outwards: the topology first and the shorthand that writes it down, then
the matrices that move it, then drawing it.</p>
<ul>
<li><a href="topology.html">Kinematic Topology</a> — Anchors, branches and assemblies, and how a machine chain is built out of them</li>
<li><a href="chain-code.html">Machine Chain Code</a> — The bracket notation a machine file can carry its connectivity in, and the keyword spelling everything downstream reads it by</li>
<li><a href="assembly-anchors.html">Assembly Anchors</a> — What an anchor is, and the buckles the machine, fixture, workpiece and tool are assembled at</li>
<li><a href="transformers.html">Handle Transform Matrix by ITransformer</a> — The transform-matrix interface behind every joint, and the implementations covering the common cases</li>
<li><a href="render-topology.html">Render Topology</a> — Drawing an assembly through its anchors, by anchoring matrix map or by anchored displayee</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="../rendering/index.html">Rendering</a> — the engine that draws what the topology places</li>
<li><a href="../api-foundations/index.html">API Foundations</a> — the geometry types a topology carries, and how an assembly is persisted</li>
<li><a class="xref" href="../../api/Hi.Mech.Topo.html">Hi.Mech.Topo</a> — the generated reference for the namespace</li>
<li><a class="xref" href="../../api/Hi.Mech.Topo.Asmb.html">Asmb</a> — assemblies</li>
<li><a class="xref" href="../../api/Hi.Mech.Topo.Branch.html">Branch</a> — chains</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,231 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Render Topology | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Render Topology | 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="Technique-RenderTopology">
<h1 id="render-topology">Render Topology</h1>
<p>Read <a class="xref" href="topology.html">Kinematic Topology</a> <a href="../rendering/index.html">Rendering</a> for the prerequisite.</p>
<p>A <a class="xref" href="../../api/Hi.Mech.Topo.Asmb.html">Asmb</a> is a group to render its descendent <a class="xref" href="../../api/Hi.Mech.Topo.Anchor.html">Anchor</a>s.</p>
<p>Several ways to render with the topology:</p>
<ul>
<li>Render by Anchoring Matrix Map</li>
<li>Render by Anchored Displayee</li>
</ul>
<h2 id="render-by-anchoring-matrix-map">Render by Anchoring Matrix Map</h2>
<h2 id="render-by-anchored-displayee">Render by Anchored Displayee</h2>
<p>Inherit <a class="xref" href="../../api/Hi.Mech.Topo.IAnchoredDisplayee.html">IAnchoredDisplayee</a> or apply <a class="xref" href="../../api/Hi.Mech.Topo.AnchoredDisplayee.html">AnchoredDisplayee</a> to <a class="xref" href="../../api/Hi.Mech.Topo.Asmb.html">Asmb</a>.Display().</p>
<p>Inherit <a class="xref" href="../../api/Hi.Mech.Topo.ITopoDisplayee.html">ITopoDisplayee</a> to manage the object with <a class="xref" href="../../api/Hi.Mech.Topo.Asmb.html">Asmb</a> and plural anchors .</p>
<p>The base logic is also by the anchoring matrix. Here is some class and function wrapping the logic.</p>
<p>The sample code shows the topology rendering for a <a class="xref" href="../../api/Hi.Milling.MillingTools.MillingTool.html">MillingTool</a> editing helper:</p>
<pre><code class="lang-csharp" name="MillingToolEditorDisplayee">using Hi.Common;
using Hi.Common.Messages;
using Hi.Disp;
using Hi.Disp.Flag;
using Hi.Geom;
using Hi.Mech.Topo;
using Hi.Milling.Cutters;
using Hi.NcMech.Holders;
using System;
using System.Collections.Generic;
namespace Hi.Milling.MillingTools;
/// &lt;summary&gt;
/// Display host for a milling tool composed of a cutter and a holder.
/// &lt;/summary&gt;
public class MillingToolEditorDisplayee : ITopoDisplayee, IClearCache
{
/// &lt;summary&gt;
/// Gets or sets the delegate that provides the &lt;see cref=&quot;MillingTool&quot;/&gt; instance.
/// &lt;/summary&gt;
public Func&lt;MillingTool&gt; MillingToolGetter { get; set; }
/// &lt;summary&gt;
/// Gets the current &lt;see cref=&quot;MillingTool&quot;/&gt; instance.
/// &lt;/summary&gt;
public MillingTool MillingTool =&gt; MillingToolGetter?.Invoke();
/// &lt;summary&gt;
/// Gets or sets whether to show the cutter.
/// &lt;/summary&gt;
public bool ShowCutter { get; set; } = true;
/// &lt;summary&gt;
/// Gets or sets whether to show the holder.
/// &lt;/summary&gt;
public bool ShowHolder { get; set; } = true;
/// &lt;summary&gt;
/// Gets the displayee for the milling cutter.
/// &lt;/summary&gt;
public MillingCutterEditorDisplayee MillingCutterEditorDisplayee { get; }
= new MillingCutterEditorDisplayee();
/// &lt;summary&gt;
/// Gets the displayee for the holder.
/// &lt;/summary&gt;
public HolderEditorDisplayee HolderEditorDisplayee { get; }
= new HolderEditorDisplayee();
/// &lt;inheritdoc/&gt;
public List&lt;IAnchoredDisplayee&gt; GetAnchoredDisplayeeList()
{
var dst = new List&lt;IAnchoredDisplayee&gt;();
var millingTool = MillingTool;
if (millingTool == null)
return dst;
if (ShowCutter)
{
var cutter = millingTool.Cutter;
if (cutter is MillingCutter millingCutter)
{
//MessageKit.AddMessage($&quot;MillingTool.Cutter: {MillingTool?.Cutter?.GetHashCode()}&quot;);
MillingCutterEditorDisplayee.MillingCutterSourceFunc
= () =&gt; MillingTool?.Cutter as MillingCutter;
dst.Add(MillingCutterEditorDisplayee);
}
else if(cutter!=null)
dst.Add(cutter);
}
if (ShowHolder)
{
HolderEditorDisplayee.Holder = millingTool.Holder;
dst.Add(HolderEditorDisplayee);
}
return dst;
}
/// &lt;inheritdoc/&gt;
public void Display(Bind bind)
{
bind.PushCoveringPixelMode();
DimensionBar.Display(bind, &quot;mm&quot;);
bind.ModelMatStack.Pop();
TopoDisplayeeUtil.Display(this, bind);
}
/// &lt;inheritdoc/&gt;
public void ExpandToBox3d(Box3d dst)
{
TopoDisplayeeUtil.ExpandToBox3d(this, dst);
}
/// &lt;inheritdoc/&gt;
public Asmb GetAsmb() =&gt; MillingTool?.Asmb;
/// &lt;inheritdoc/&gt;
public Anchor GetAnchor() =&gt; MillingTool?.GetAnchor();
/// &lt;inheritdoc/&gt;
public void ClearCache()
{
MillingCutterEditorDisplayee?.ClearCache();
}
}
</code></pre><h2 id="see-also">See Also</h2>
<ul>
<li><a href="topology.html">Kinematic Topology</a> — the assembly and anchors this renders through</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,37 @@
<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="topology.html" name="" title="Kinematic Topology">Kinematic Topology</a>
</li>
<li>
<a href="chain-code.html" name="" title="Machine Chain Code">Machine Chain Code</a>
</li>
<li>
<a href="assembly-anchors.html" name="" title="Assembly Anchors">Assembly Anchors</a>
</li>
<li>
<a href="transformers.html" name="" title="Transformers">Transformers</a>
</li>
<li>
<a href="render-topology.html" name="" title="Render Topology">Render Topology</a>
</li>
</ul>
</div>
</div>
</div>
</div>
@@ -0,0 +1,2 @@
{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"Kinematic Topology","href":"topology.html","topicHref":"topology.html"},{"name":"Machine Chain Code","href":"chain-code.html","topicHref":"chain-code.html"},{"name":"Assembly Anchors","href":"assembly-anchors.html","topicHref":"assembly-anchors.html"},{"name":"Transformers","href":"transformers.html","topicHref":"transformers.html"},{"name":"Render Topology","href":"render-topology.html","topicHref":"render-topology.html"}]}
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

@@ -0,0 +1,156 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Kinematic Topology | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Kinematic Topology | 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="Usage.HiMech.Topo">
<h1 id="kinematic-topology">Kinematic Topology</h1>
<p>The Kinematic Topology is composed of three elemental classes: <strong><a class="xref" href="../../api/Hi.Mech.Topo.Anchor.html">Anchor</a></strong>, <strong><a class="xref" href="../../api/Hi.Mech.Topo.Branch.html">Branch</a></strong> and <strong><a class="xref" href="../../api/Hi.Mech.Topo.Asmb.html">Asmb</a></strong>.</p>
<h2 id="basic-elements">Basic Elements</h2>
<h3 id="anchors-and-branches">Anchors and Branches</h3>
<p><strong><a class="xref" href="../../api/Hi.Mech.Topo.Anchor.html">Anchor</a></strong> object contains a cartesian coordinate. It can be a mechanical component or a flag.</p>
<p><strong><a class="xref" href="../../api/Hi.Mech.Topo.Branch.html">Branch</a></strong> object is a directional link between two <a class="xref" href="../../api/Hi.Mech.Topo.Anchor.html">Anchor</a> objects. It contains the <strong><a class="xref" href="../../api/Hi.Mech.Topo.ITransformer.html">ITransformer</a></strong> object. The <a class="xref" href="../../api/Hi.Mech.Topo.ITransformer.html">ITransformer</a> object contains a coordinate <strong>transformation matrix</strong>. As shown in the following sketch:</p>
<p><img src="topology-img/chainLink.png" alt="Chain Structure"></p>
<h3 id="assembly-management">Assembly Management</h3>
<p><strong><a class="xref" href="../../api/Hi.Mech.Topo.Asmb.html">Asmb</a></strong> (Assembly) provides organization and management of Anchors. An Assembly can contain both Anchors and other Assemblies. Key features include:</p>
<ul>
<li>Grouping related Anchors together</li>
<li>Managing coordinate transformations</li>
<li>Providing display and indexing functions</li>
<li>Supporting hierarchical structure</li>
</ul>
<h2 id="kinematic-chain-example">Kinematic Chain Example</h2>
<p>The following figure shows a kinematic chain of a non-orthogonal 5-axis machine tool:</p>
<p><img src="topology-img/vmt.png" alt="VMT Structure"></p>
<p>Each <a class="xref" href="../../api/Hi.Mech.Topo.Anchor.html">Anchor</a> represents a component:</p>
<ul>
<li>Axis components: X, Y, Z, B, C</li>
<li>Base components: O (base1), O* (base2)</li>
<li>Tool components: S (spindle), T (tool body), T* (tool flute)</li>
<li>Workpiece: W</li>
</ul>
<p>The relative transform between two Anchors is calculated by multiplying the transform matrices along the Branch. For example, the transform matrix from W to T is:</p>
<div class="math">
\[
M_{WT} = M_{CW}^{-1} \cdot M_{YC}^{-1} \cdot M_{OY}^{-1} \cdot M_{OO^*} \cdot M_{O^*X} \cdot M_{XZ} \cdot M_{ZB} \cdot M_{BS} \cdot M_{ST}
\]</div>
<p>This matrix can be obtained using <a class="xref" href="../../api/Hi.Mech.Topo.Asmb.html#Hi_Mech_Topo_Asmb_GetMat4d_Hi_Mech_Topo_IGetAnchor_Hi_Mech_Topo_IGetAnchor_">GetMat4d(IGetAnchor, IGetAnchor)</a>.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><p><a href="chain-code.html">Machine Chain Code</a> — the bracket notation that writes this same connectivity down for hand-editing</p>
</li>
<li><p><a href="assembly-anchors.html">Assembly Anchors</a> — the four named buckle anchors a machining scene is assembled at</p>
</li>
<li><p><a href="transformers.html">Handle Transform Matrix by ITransformer</a> — what sits on each branch and moves it</p>
</li>
<li><p><a href="render-topology.html">Render Topology</a> — drawing an assembly through the anchors defined here</p>
</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,204 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Handle Transform Matrix by ITransformer | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Handle Transform Matrix by ITransformer | 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="HiMech.Tutor.transformers">
<h1 id="handle-transform-matrix-by-itransformer">Handle Transform Matrix by ITransformer</h1>
<p><strong><a class="xref" href="../../api/Hi.Mech.Topo.ITransformer.html">ITransformer</a></strong> contains a transform matrix and a inverse transform matrix. The matrix is 4x4 column-major matrix, which describe the orientation or movement between 3D coordinates.</p>
<p>Several common used interface and class are implemented from <a class="xref" href="../../api/Hi.Mech.Topo.ITransformer.html">ITransformer</a>. The inheritance is shown:</p>
<ul>
<li><a class="xref" href="../../api/Hi.Mech.Topo.IStaticTransformer.html">IStaticTransformer</a>
<ul>
<li><a class="xref" href="../../api/Hi.Mech.Topo.NoTransform.html">NoTransform</a></li>
<li><a class="xref" href="../../api/Hi.Mech.Topo.StaticTranslation.html">StaticTranslation</a></li>
<li><a class="xref" href="../../api/Hi.Mech.Topo.StaticRotation.html">StaticRotation</a></li>
<li><a class="xref" href="../../api/Hi.Mech.Topo.StaticFreeform.html">StaticFreeform</a></li>
<li><a class="xref" href="../../api/Hi.Mech.Topo.GeneralTransform.html">GeneralTransform</a></li>
</ul>
</li>
<li><a class="xref" href="../../api/Hi.Mech.Topo.IDynamicTransformer.html">IDynamicTransformer</a>
<ul>
<li><a class="xref" href="../../api/Hi.Mech.Topo.IDynamicRegular.html">IDynamicRegular</a>
<ul>
<li><a class="xref" href="../../api/Hi.Mech.Topo.DynamicTranslation.html">DynamicTranslation</a></li>
<li><a class="xref" href="../../api/Hi.Mech.Topo.DynamicRotation.html">DynamicRotation</a></li>
</ul>
</li>
<li><a class="xref" href="../../api/Hi.Mech.Topo.DynamicFreeform.html">DynamicFreeform</a></li>
</ul>
</li>
</ul>
<p><strong><a class="xref" href="../../api/Hi.Mech.Topo.IStaticTransformer.html">IStaticTransformer</a></strong> is transformer with constant matrix. <strong><a class="xref" href="../../api/Hi.Mech.Topo.NoTransform.html">NoTransform</a></strong>, <strong><a class="xref" href="../../api/Hi.Mech.Topo.StaticTranslation.html">StaticTranslation</a></strong> and <strong><a class="xref" href="../../api/Hi.Mech.Topo.StaticRotation.html">StaticRotation</a></strong> contains transform matrix of identity, translate and rotate respectively. <strong><a class="xref" href="../../api/Hi.Mech.Topo.StaticFreeform.html">StaticFreeform</a></strong> contains a arbitrary constant transform matrix.</p>
<p>The transform matrix of <a class="xref" href="../../api/Hi.Mech.Topo.StaticTranslation.html">StaticTranslation</a> is:</p>
<div class="math">
\[
M_{StaticTranslate}=
\begin{bmatrix}
1 &amp; 0 &amp; 0 &amp; 0 \\\\
0 &amp; 1 &amp; 0 &amp; 0 \\\\
0 &amp; 0 &amp; 1 &amp; 0 \\\\
Trans.x &amp; Trans.y &amp; Trans.z &amp; 1
\end{bmatrix}
\]</div>
<p>The transform matrix of <a class="xref" href="../../api/Hi.Mech.Topo.StaticRotation.html">StaticRotation</a> and <a class="xref" href="../../api/Hi.Mech.Topo.DynamicRotation.html">DynamicRotation</a> is:</p>
<div class="math">
\[
M_{Rotate}=
\begin{bmatrix}
1 &amp; 0 &amp; 0 &amp; 0 \\\\
0 &amp; 1 &amp; 0 &amp; 0 \\\\
0 &amp; 0 &amp; 1 &amp; 0 \\\\
-Pivot.x &amp; -Pivot.y &amp; -Pivot.z &amp; 1
\end{bmatrix}
\cdot
\\\\
\begin{bmatrix}
Rot_{00}(axis,rad) &amp; Rot_{01}(axis,rad) &amp; Rot_{02}(axis,rad) &amp; 0 \\\\
Rot_{10}(axis,rad) &amp; Rot_{11}(axis,rad) &amp; Rot_{12}(axis,rad) &amp; 0 \\\\
Rot_{20}(axis,rad) &amp; Rot_{21}(axis,rad) &amp; Rot_{22}(axis,rad) &amp; 0 \\\\
0 &amp; 0 &amp; 0 &amp; 1
\end{bmatrix}
\cdot
\\\\
\begin{bmatrix}
1 &amp; 0 &amp; 0 &amp; 0 \\\\
0 &amp; 1 &amp; 0 &amp; 0 \\\\
0 &amp; 0 &amp; 1 &amp; 0 \\\\
Pivot.x &amp; Pivot.y &amp; Pivot.z &amp; 1
\end{bmatrix}
\]</div>
<p>Where <a class="xref" href="../../api/Hi.Mech.Topo.DynamicRotation.html#Hi_Mech_Topo_DynamicRotation_Pivot">Pivot</a> is the position of the rotation axis.</p>
<div class="TIP">
<h5>Tip</h5>
<p>Pivot is a point. However, rotation axis is a line. It means that it causes the same matrix no matter how the pivot is moving along the axis.</p>
</div>
<p><strong><a class="xref" href="../../api/Hi.Mech.Topo.IDynamicTransformer.html">IDynamicTransformer</a></strong> is transformer with inconstant transform matrix. <strong><a class="xref" href="../../api/Hi.Mech.Topo.IDynamicRegular.html">IDynamicRegular</a></strong> has a property <a class="xref" href="../../api/Hi.Mech.Topo.IDynamicRegular.html#Hi_Mech_Topo_IDynamicRegular_Step">Step</a>, implied that the transform matrix is one parameter driven. <a class="xref" href="../../api/Hi.Mech.Topo.TransformerUtil.html#Hi_Mech_Topo_TransformerUtil_GetSteps_Hi_Mech_Topo_IDynamicRegular___">GetSteps(IDynamicRegular[])</a> and <a class="xref" href="../../api/Hi.Mech.Topo.TransformerUtil.html#Hi_Mech_Topo_TransformerUtil_SetSteps_Hi_Mech_Topo_IDynamicRegular___System_Double___">SetSteps(IDynamicRegular[], double[])</a> provide easy handle of an array of <a class="xref" href="../../api/Hi.Mech.Topo.IDynamicRegular.html">IDynamicRegular</a> objects.</p>
<p>The transform matrix of <a class="xref" href="../../api/Hi.Mech.Topo.DynamicTranslation.html">DynamicTranslation</a> is:</p>
<div class="math">
\[
M_{DynamicTranslate}=
\begin{bmatrix}
1 &amp; 0 &amp; 0 &amp; 0 \\\\
0 &amp; 1 &amp; 0 &amp; 0 \\\\
0 &amp; 0 &amp; 1 &amp; 0 \\\\
Trans.x \cdot Step &amp; Trans.y \cdot Step &amp; Trans.z \cdot Step &amp; 1
\end{bmatrix}
\]</div>
<div class="NOTE">
<h5>Note</h5>
<p>In convention, <a class="xref" href="../../api/Hi.Mech.Topo.StaticTranslation.html#Hi_Mech_Topo_StaticTranslation_Trans">Trans</a> should be normalized.</p>
</div>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="topology.html">Kinematic Topology</a> — the anchors and branches these matrices move</li>
<li><a href="../../anatomy/geom/transformation-geom-control.html">TransformationGeomControl</a> — the app panel that wraps a geometry in one of these transforms</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,148 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Chatter, and What the Simulation Does About It | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Chatter, and What the Simulation Does About It | 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="Technique-Chatter">
<h1 id="chatter-and-what-the-simulation-does-about-it">Chatter, and What the Simulation Does About It</h1>
<p>Chatter is self-excited vibration between cutter and workpiece, and it is the one failure mode
that a purely geometric look at the toolpath cannot see. HiNC does not predict chatter directly.
What it does instead is give the cut a force ceiling that keeps it out of the regime where chatter
starts, which covers the cutter side and leaves two other cases to be handled by the operator.</p>
<h2 id="cutter-chatter--handled-by-a-force-ceiling">Cutter Chatter — Handled by a Force Ceiling</h2>
<p>Cutter chatter does not begin while the cutting force stays below a threshold. That threshold is a
property of the machine, not of the program: a well-maintained machine tolerates a higher force
before it chatters, and the same NC on a worn one will chatter earlier.</p>
<p>So the lever is the optimizer's <strong>preferred cutting force</strong>
(<a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_OptPreferedForce_N">OptPreferedForce_N</a>). Optimizing to a preferred force holds
the cut under a ceiling for its whole length instead of only at the peaks, and if a particular
machine still chatters, the answer is a lower preferred force rather than a different toolpath.
The value that works is found once per machine and reused.</p>
<h2 id="workpiece-chatter--not-estimated">Workpiece Chatter — Not Estimated</h2>
<p>Workpiece chatter is not estimated. A thin, tall or poorly supported workpiece can vibrate at
forces the cutter itself tolerates comfortably, and nothing in the simulation reports it. Where
the part is the flexible member, the force ceiling that protects the cutter is not the ceiling
that protects the surface.</p>
<h2 id="fixed-frequency-vibration--not-the-programs-fault">Fixed-Frequency Vibration — Not the Program's Fault</h2>
<p>Fixed-frequency vibration comes from the machine's own condition — bearings, drives, structure —
and is <strong>independent of the toolpath</strong>. No NC change removes it, and re-optimizing will not help.
The practical avoidance is a spindle speed that does not coincide with the machine's harmonic
frequencies.</p>
<h2 id="strain-hardening--why-it-is-not-modelled">Strain Hardening — Why It Is Not Modelled</h2>
<p>A related question that comes up in the same conversation: milling's depth of cut is far greater
than the strain-hardened layer left by the previous pass, so the hardened material is a small
fraction of what each tooth removes. The effect on the process is minimal, and the simulation does
not model it.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="../machine-capability/machine-condition.html">Machine Condition and Safety Factors</a> — the machine-side settings that decide how much force the model is allowed to ask for</li>
<li><a href="cutter-adjustment-levers.html">Cutter Adjustment Levers for Force Reduction</a> — what to change when the force has to come down and the feed rate is already as low as it can go</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,256 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Coolant Model | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Coolant Model | 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="Technique-CoolantModel">
<h1 id="coolant-model">Coolant Model</h1>
<p>What the cutting-zone cooling actually does to the simulation. The chosen condition lives on
<a class="xref" href="../../api/Hi.Physics.CoolantHeatCondition.html">CoolantHeatCondition</a><small>(API)</small> and is consumed by
<a class="xref" href="../../api/Hi.Physics.MillingTemperatureUtil.html">MillingTemperatureUtil</a><small>(API)</small> every simulation step, which is why the
NC program's own coolant M-codes, not a single setting, decide the coefficient in force at any
moment.</p>
<p>Ordered from what selects a coefficient, through what the shipped presets set and what each field
means, to how the condition is stored.</p>
<h2 id="nc-program-drives-the-mode">NC program drives the mode</h2>
<p>The parser reads M07/M08/M09 into <a class="xref" href="../../api/Hi.Numerical.CoolantMode.html">CoolantMode</a><small>(API)</small> and carries it on every <a class="xref" href="../../api/Hi.MachiningSteps.MachineMotionStep.html">MachineMotionStep</a><small>(API)</small>. The FEM picks the effective convection coefficient at run time from that mode.</p>
<table>
<thead>
<tr>
<th>M-code</th>
<th><code>CoolantMode</code></th>
<th>Coefficient source</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>M08</code></td>
<td><code>Flood</code></td>
<td><code>CoolantConvectionCoefficient_Wdm2K</code> (baseline of the chosen type)</td>
</tr>
<tr>
<td><code>M07</code></td>
<td><code>Mist</code></td>
<td>baseline × <code>MistFloodConvectionRatio</code></td>
</tr>
<tr>
<td><code>M09</code></td>
<td><code>Off</code></td>
<td><code>OffConvectionCoefficient_Wdm2K</code></td>
</tr>
</tbody>
</table>
<p>Before the first M07/M08/M09 the mode is <code>UnDefined</code>; the FEM treats it as <code>Off</code>.</p>
<p>For <strong>StandardForcedAir</strong> (dry cutting) the machine has no liquid circuit, so even <code>M08</code> only means &ldquo;air blast on&rdquo; — its flood baseline is an air-blast coefficient, not a liquid one.</p>
<h2 id="what-each-shipped-file-sets">What each shipped file sets</h2>
<p>Each shipped cooling type is also a static preset on <a class="xref" href="../../api/Hi.Physics.CoolantHeatCondition.html">CoolantHeatCondition</a><small>(API)</small> (<code>StandardForcedAir</code>, <code>StandardWaterSolubleCoolant</code>, <code>StandardOilBasedCoolant</code>) — the same pattern as <code>WorkpieceMaterial.Al6061T6</code>; the resource files are generated from them:</p>
<table>
<thead>
<tr>
<th>Preset / file</th>
<th>Flood baseline W/(m²·K)</th>
<th>Mist ratio</th>
<th>Off W/(m²·K)</th>
<th>Temperature °C</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>StandardForcedAir</code></td>
<td>100</td>
<td>0.5</td>
<td>50</td>
<td>25</td>
</tr>
<tr>
<td><code>StandardWaterSolubleCoolant</code></td>
<td>1 000</td>
<td>0.5</td>
<td>50</td>
<td>25</td>
</tr>
<tr>
<td><code>StandardOilBasedCoolant</code></td>
<td>300</td>
<td>0.5</td>
<td>50</td>
<td>25</td>
</tr>
</tbody>
</table>
<p>The baselines are engineering defaults from the literature ranges below; when you have dynamometer / thermocouple data for your own system, tune the fields and save your own file instead. API side: <code>ApplyPreset</code> copies a preset in place; <code>MatchStandardPreset</code> maps values back to a preset name.</p>
<h2 id="properties">Properties</h2>
<p>These are the fields shown under Name / Note in the Coolant panel:</p>
<table>
<thead>
<tr>
<th>Property</th>
<th>Default</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>CoolantTemperature_C</code></td>
<td>25</td>
<td>Room temperature inside the enclosure.</td>
</tr>
<tr>
<td><code>CoolantConvectionCoefficient_Wdm2K</code></td>
<td>1 000</td>
<td>Flood baseline. Water-based emulsion ≈ 1 0003 000, oil ≈ 100500, forced air ≈ 10500.</td>
</tr>
<tr>
<td><code>MistFloodConvectionRatio</code></td>
<td>0.5</td>
<td>MQL is roughly half the heat removal of flood. See below.</td>
</tr>
<tr>
<td><code>OffConvectionCoefficient_Wdm2K</code></td>
<td>50</td>
<td>Forced air inside a running enclosure. Natural air ≈ 525.</td>
</tr>
<tr>
<td><code>Name</code> / <code>Note</code></td>
<td></td>
<td>From the loaded file / preset; <strong>Save As&hellip;</strong> renames the condition after the file. Legacy projects without a name still work.</td>
</tr>
</tbody>
</table>
<h2 id="why-the-mist-ratio-defaults-to-05">Why the mist ratio defaults to 0.5</h2>
<p>MQL removes much less heat than flood because a thin oil aerosol has a tiny thermal mass; its main value is lubrication plus evaporative cooling, not convection. Industry handbooks place it at <strong>roughly half of flood</strong>, which gives the conservative default <code>0.5</code>. Override it when you have dynamometer / thermocouple data for your own MQL system.</p>
<div class="NOTE">
<h5>Note</h5>
<p>Further reading: UNIST <em>MQL Handbook</em> (source of the &ldquo;about half&rdquo; rule), ANEBON mist-vs-flood AISI 1045 tests, Mukesh et al. <em>IEJ</em> May 2023 review on sustainable machining. Use these only to dig deeper — the <code>0.5</code> default is already calibrated from them.</p>
</div>
<h2 id="coolant-files-workpiecematerial-pattern">Coolant files (WorkpieceMaterial pattern)</h2>
<p><code>MachiningEquipment.CoolantHeatConditionFile</code> tracks an optional <code>.CoolantHeatCondition</code> side-file, exactly like <code>Workpiece.WorkpieceMaterialFile</code> tracks a material file:</p>
<ul>
<li><strong>No file (default):</strong> the condition serializes inline in the <code>.hincproj</code>, byte-compatible with pre-pattern readers.</li>
<li><strong>File tracked:</strong> the project save externalizes the condition as <code>&lt;CoolantHeatCondition&gt;&lt;XmlSource&gt;relPath&lt;/XmlSource&gt;&lt;/CoolantHeatCondition&gt;</code> and (re)writes the side-file. Loading a file installs it in place of the current condition and records the reference (<code>XFactory.GenByFile&lt;CoolantHeatCondition&gt;</code>); a file loaded from the resource folder is copied into the project on the next save (self-contained project root).</li>
</ul>
<h2 id="xml">XML</h2>
<pre><code class="lang-xml">&lt;CoolantHeatCondition&gt;
&lt;Name&gt;StandardOilBasedCoolant&lt;/Name&gt;
&lt;Note&gt;Oil-based cutting fluid (neat oil).&lt;/Note&gt;
&lt;CoolantTemperature_C&gt;25&lt;/CoolantTemperature_C&gt;
&lt;CoolantConvectionCoefficient_Wdm2K&gt;300&lt;/CoolantConvectionCoefficient_Wdm2K&gt;
&lt;MistFloodConvectionRatio&gt;0.5&lt;/MistFloodConvectionRatio&gt;
&lt;OffConvectionCoefficient_Wdm2K&gt;50&lt;/OffConvectionCoefficient_Wdm2K&gt;
&lt;/CoolantHeatCondition&gt;
</code></pre>
<p><code>Name</code>/<code>Note</code> are optional (pre-preset files omit them); omit the last two elements to accept the defaults. The same element saved standalone is the <code>.CoolantHeatCondition</code> file format; inside a <code>.hincproj</code> it may instead appear as the <code>&lt;XmlSource&gt;</code> reference shown above.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="../../manual/setup/coolant.html">Coolant</a> — picking a cooling type in the application, which is the whole of the end-user setup</li>
<li><a class="xref" href="../../anatomy/general-setup/background-coolant.html">Background / Coolant Page</a> — the Control-Tree editor for these values, field by field</li>
<li><a href="machinability.html">Process Machinability</a> — the thermal-yield ratio this model's temperatures feed</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,148 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cutter Adjustment Levers for Force Reduction | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Cutter Adjustment Levers for Force Reduction | 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="Technique-CutterAdjustmentLevers">
<h1 id="cutter-adjustment-levers-for-force-reduction">Cutter Adjustment Levers for Force Reduction</h1>
<p>When force peaks push close to or beyond tool limits, three cutter-side levers reduce peaks without changing the NC or the toolpath.</p>
<h2 id="shorten-tool-overhang">Shorten Tool Overhang</h2>
<p>The unsupported tool length above the cut multiplies bending stress. A common installation leaves 15 mm or more above the flute start; reducing this exposure toward ~5 mm typically produces a large drop in the yield-stress ratio for the same NC.</p>
<p>Process documents may fix the overhang for procedural reasons. If the engineering envelope allows, shortening the overhang is the cheapest mitigation before tuning anything else.</p>
<h2 id="adjust-core-radius">Adjust Core Radius</h2>
<p>Heavy-cut cutters narrow the chip-evacuation flute to thicken the cutter core, raising bending strength. The exact core radius cannot be measured externally; it is an empirical input.</p>
<p>The HiNC default is <code>0.6</code> (cutter-core radius as a fraction of cutter radius) for 4-flute end mills. If the cutter routinely tolerates yield-stress ratios around 200 % without breakage, the actual core is thicker than the default — raise the value in steps (e.g., <code>0.7</code>) until the simulated ratio aligns with the observed safety margin.</p>
<h2 id="upgrade-cutter-material">Upgrade Cutter Material</h2>
<p>The default <code>WC-Co6-800nm</code> is a low-cost grade. Finer-grain or coated grades have higher yielding stress and better thermal tolerance:</p>
<ul>
<li><strong><code>WC-Co6-TiC-400nm</code></strong> — finer grain with TiC. A reasonable upgrade when the cutter quality is unknown but suspected better than the baseline.</li>
</ul>
<p>For a known cutter, configure the matching material file under <code>Resource/CutterMaterial/</code> rather than guessing the grade.</p>
<h2 id="before-reaching-for-the-cutter">Before Reaching for the Cutter</h2>
<p>The cutter-side levers below are for when the cutting parameters have already been tried, because
the parameters are cheaper to change. In order:</p>
<ol>
<li><strong>Reduce feed per tooth.</strong> The most direct route to lower force, and the one the optimizer
itself takes.</li>
<li><strong>Reduce depth of cut, or width of cut.</strong> Where feed per tooth alone is not enough. Both cut
the engagement rather than the chip load per tooth, so both cost more cycle time per unit of
force removed.</li>
</ol>
<p>Only when those are exhausted, or when they would cost more cycle time than the job can afford,
do the cutter-side levers become the better trade.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="machinability.html">Evaluating Process Machinability</a> — Reading the yield-stress ratio and the spindle ratios</li>
<li><a href="chatter.html">Chatter, and What the Simulation Does About It</a> — the force ceiling that keeps a cut out of the chattering regime</li>
<li><a href="../nc-optimization/nc-optimization-principles.html#tuning-peak-tolerance">Tuning Peak Tolerance</a> — Per-metric utilization factors and when each is safe to relax</li>
<li><a class="xref" href="wear.html">Tool Life &amp; Wear</a> — Wear modes affected by material grade</li>
<li><a href="cutter-geometry.html">Cutter Geometry</a> — the full cutter description these three levers are quantities of</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>
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB

@@ -0,0 +1,285 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cutter Geometry | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Cutter Geometry | 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="Technique-CutterGeometry">
<h1 id="cutter-geometry">Cutter Geometry</h1>
<p>How a cutting tool is described to the simulation: what kind of tool it is, how its cutting envelope
is expressed, and the individual quantities the force, wear and thermal models read off it. Every
value here is a property of the tool rather than of a cut, so it is entered once per tool and reused
by every step that tool takes.</p>
<p>Ordered from the classification, through the two ways an envelope is expressed, to the quantities
that hang off it.</p>
<h2 id="cutter-body-types">Cutter Body Types</h2>
<p>Cutter body types include:</p>
<ul>
<li><strong>Milling</strong>
Any tool that machines by rotation is classified as milling in HiNC, including drilling and boring.</li>
<li><strong>Freeform Subtraction</strong>
Cutting tools, EDM (electrical discharge machining) dies.</li>
</ul>
<h2 id="milling-tool-description-parameters">Milling Tool Description Parameters</h2>
<ul>
<li>Material: Shank material, cutter body material, (multi-layer) coating material and thickness.</li>
<li>Cutting edge rotation envelope: Can use simplified parameters (APT) or a custom ZR table.</li>
<li>Simplified (yield-equivalent) edge center rotation envelope:
<ul>
<li>Solid space ratio of the cutting edge rotation envelope.</li>
<li>Custom ZR table.</li>
</ul>
</li>
<li>Clamping end (non-cutting zone) shape: Custom ZR table.</li>
<li>Per-tooth geometry (including side edges and bottom edges):
<ul>
<li>Simplified parameters: Helix angle position, rake angle, relief angle.</li>
<li>Custom per-Z value: Helix angle position, rake angle, relief angle, radius length.</li>
</ul>
</li>
<li>Hone radius, tool weight, insert weight, and (thermal-equivalent) thickness.</li>
</ul>
<blockquote>
<p>For information on measuring rake angle and relief angle, refer to <a class="xref" href="../measurement/radial-angle-measurement.html">Radial Angle Measurement</a>.</p>
</blockquote>
<h2 id="apt--the-simplified-edge-envelope">APT — the Simplified Edge Envelope</h2>
<p>APT (Automatically Programmed Tool) is a universal tool definition, and the simplified alternative
to a custom ZR table for the cutting-edge rotation envelope. Refer to the APT parameter diagram:</p>
<div class="NOTE">
<h5>Note</h5>
<p><img src="cutter-geometry-img/APT.svg" alt="APT"></p>
</div>
<p>APT parameter description:</p>
<ul>
<li><code>D</code>: Diameter</li>
<li><code>Rc</code>: Corner radius</li>
<li><code>Rr</code>: Distance from corner center to tool centerline</li>
<li><code>Rz</code>: Distance from corner center to tool tip horizontal plane</li>
<li><code>Alpha</code>: Angle between horizontal plane and tool tip cone surface</li>
<li><code>Beta</code>: Angle between tool centerline and tool wall cone surface</li>
</ul>
<h2 id="upper-beam-clamping-end--shank-geometry">Upper Beam (Clamping End / Shank) Geometry</h2>
<p>The <em>upper beam</em> is the cutter's shank / body above the flute — the non-cutting,
clamping zone. It can be modeled with several geometry types; the two common
choices are:</p>
<ul>
<li><p><strong>Cylindroid</strong> — an explicit ZR table. You author every <code>(Z, r)</code> pair, so the
shank radius (and any stepped / necked profile) is whatever you type in. This
faithfully reproduces a <em>known</em> shank, but every value is data you must supply.</p>
</li>
<li><p><strong>Extended Cylinder</strong> — a cylinder whose <strong>start (bottom) profile is driven by
the flute</strong> and whose only parameter is the total length. Its radius follows
the cutter (flute-top) radius automatically, so it needs <strong>no shank
measurements</strong> — only a length long enough to reach the holder.</p>
<p><strong><code>FullLength</code> is the beam's FULL length measured from <code>Z=0</code> (the cutter
tip), so it includes the flute span</strong> — it is <em>not</em> the remaining segment from
the flute top to the exposed end. It must therefore be <strong>larger than the flute
height</strong>: e.g. flute height 20 mm and 10 mm of shank above it → <code>FullLength = 30</code>, not 10. A value at or below the flute height inverts the beam solid;
thermal physics then cannot build its shank shell layers and reports a
<code>Cutter-UpperBeam--BelowFluteHeight</code> configuration error at tool change (the
web editor rejects such a value outright).</p>
</li>
</ul>
<p><strong>Convention — prefer the Extended Cylinder when the shank is not given.</strong> Most
tool sheets (especially at quoting stage) list only the cutting diameter, corner
radius, and stick-out; they do not give a shank diameter or a stepped/necked
profile. In that case use the <strong>Extended Cylinder</strong>: it extends the flute by a
length without inventing a radius the data does not support. A hand-authored
Cylindroid here would bake a <em>guessed</em> shank radius into the model — and an
over-fat guess produces false clearance / collision results, while an over-thin
one understates the body. Reserve the <strong>Cylindroid</strong> (explicit ZR) for tools
whose shank or neck profile is actually known or measured — e.g. stepped,
necked, or back-tapered shanks where a flute-radius extension would be wrong.</p>
<blockquote>
<p>Tip: because the Extended Cylinder's radius tracks the flute, set its length
comfortably past the exposed cutter height so the beam reaches into the holder
with no gap; the overlap is harmless for clearance checks.</p>
</blockquote>
<h2 id="relief-angle-setting">Relief Angle Setting</h2>
<p>The relief angle setting in HiNC refers to the primary relief angle. It is used to calculate flank wear width (Flank Wear, VB).</p>
<h2 id="cutter-body-weight">Cutter Body Weight</h2>
<p>Cutter body weight is used for thermal transfer calculations.</p>
<ul>
<li>Solid tools: Enter the weight of the solid tool as the cutter body weight.</li>
<li>Indexable tools: Enter the total insert weight as the cutter body weight, excluding the weight of the tool body.</li>
</ul>
<h2 id="hone-radius">Hone Radius</h2>
<p>The hone radius represents the sharpness of the tool and is the radius at the cutting edge tip. Typical values range from 20 to 50 um.</p>
<p>Tools used for machining easy-to-cut materials typically have a smaller hone radius (e.g., Al6061-T6, which can be assumed as 20 um); tools used for difficult-to-cut materials typically have a larger hone radius (e.g., stainless steel, which can be assumed as 50 um).</p>
<h2 id="edge-profile-and-edge-grind--bottom-edge-grind">Edge Profile and Edge Grind — Bottom Edge Grind</h2>
<p>The bottom edge grind needs to be configured when the bottom edge is horizontal or concave, and it affects segments with downward cutting.</p>
<p>Drill bits do not require bottom edge grind configuration — only the side edge grind needs to be set. This is because drill bit bottoms are not horizontal or concave. If a custom drill bit has a horizontal or concave bottom, then the bottom edge grind must be configured.</p>
<p>Typically, only bull-nose cutters require bottom edge grind configuration. Note that flat end mills usually do not perform downward cutting and should not, but if the process does so, the bottom edge grind must be configured.</p>
<h2 id="insert-cutters--a-worked-zr-table">Insert Cutters — a Worked ZR Table</h2>
<p>Insert cutters can be modeled in the virtual environment. See the examples below.</p>
<p><img src="cutter-geometry-img/insert-cut-mark.png" alt="An insert photographed against the Z and R axes, with the Z and R values of two edge points, the helix shift and the rake and relief angles marked on it"></p>
<p><img src="cutter-geometry-img/demo-virtual-insert-cutter.png" alt="The same insert cutter rebuilt in the virtual environment from the ZR table below"></p>
<table>
<thead>
<tr>
<th>Z</th>
<th>R</th>
<th>S.Ang.</th>
<th>R.Ang.</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>8</td>
<td>1</td>
<td>3</td>
</tr>
<tr>
<td>0.2</td>
<td>8</td>
<td>0.5</td>
<td>3</td>
</tr>
<tr>
<td>0.4</td>
<td>8</td>
<td>0</td>
<td>3</td>
</tr>
<tr>
<td>0.5</td>
<td>8</td>
<td>0</td>
<td>3</td>
</tr>
<tr>
<td>3</td>
<td>8</td>
<td>3</td>
<td>3</td>
</tr>
<tr>
<td>6</td>
<td>8</td>
<td>4</td>
<td>3</td>
</tr>
<tr>
<td>8</td>
<td>8</td>
<td>4</td>
<td>3</td>
</tr>
</tbody>
</table>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../measurement/radial-angle-measurement.html">Radial Angle Measurement</a> — how to measure the rake and relief angles entered here</li>
<li><a class="xref" href="../measurement/training-cut-set-design.html">Designing a Training Cut Set</a> — why the helix angle entered here decides whether a training run can recover the shear coefficients</li>
<li><a class="xref" href="../scripting/cutter-location-playback.html">Cutter-Location (CL) Playback</a> — a CL file's <code>TLDATA</code> feeds this same tool-geometry model</li>
<li><a href="cutter-adjustment-levers.html">Cutter Adjustment Levers</a> — the three of these quantities a process engineer can actually move to cut a force peak</li>
<li><a href="../../manual/setup/cutter.html">Cutter</a> — where a tool carrying this geometry is created and edited in the application</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,150 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Milling Physics | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Milling Physics | 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="">
<h1 id="milling-physics">Milling Physics</h1>
<p>What happens where the flute meets the workpiece, and what it does to the cutter. These pages
carry the model the simulation implements — the frames the numbers are expressed in, the criteria
that decide whether a cut is survivable, and the two ways a cutter is lost: instantly, and slowly.</p>
<p>Ordered from what the model is handed, through the frame the numbers live in and instantaneous
failure, to long-term wear and the levers that move both.</p>
<h2 id="what-the-model-is-given">What the Model Is Given</h2>
<ul>
<li><a href="cutter-geometry.html">Cutter Geometry</a> — How a tool is described to the model: the body types, the APT envelope and the ZR-table alternative, the upper beam, and the hone radius, weight and angles the force, wear and thermal models read</li>
<li><a href="coolant-model.html">Coolant Model</a> — What the cutting-zone cooling does to the temperature model: the coefficient the running program's own M-codes select, the shipped presets, and how a condition is stored</li>
</ul>
<h2 id="frames">Frames</h2>
<ul>
<li><a href="milling-physics-coordinates.html">Milling Physics Coordinates</a> — The workpiece, tool-running and spindle-rotation frames, and which sensor reports in which</li>
</ul>
<h2 id="instantaneous-failure">Instantaneous Failure</h2>
<ul>
<li><a href="machinability.html">Process Machinability</a> — The yield-stress, spindle-torque, spindle-power and thermal-yield ratios, what a value above 100% means for each, and the mesh-quantization ripple that is an artifact rather than a signal</li>
<li><a href="probabilistic-peak-crack.html">Probabilistic Peak &amp; Cutter Crack</a> — Why one narrow angular window of high contact makes an identical cut pass most of the time and crack a flute occasionally</li>
<li><a href="relief-face-avoidance.html">Relief Face Avoidance</a> — The minimum relief angle the trochoidal edge path demands, and what happens when the clearance face presses on uncut material</li>
</ul>
<h2 id="long-term-loss-and-what-to-change">Long-Term Loss and What To Change</h2>
<ul>
<li><a href="wear.html">Tool Life &amp; Wear</a> — The wear model, the three quantities it reports, and where flank-wear width stops being a valid measure</li>
<li><a href="cutter-adjustment-levers.html">Cutter Adjustment Levers</a> — Overhang, core radius and material grade: three cutter-side ways to cut a force peak without touching the NC</li>
<li><a href="chatter.html">Chatter</a> — The force ceiling that keeps a cut out of the chattering regime, the two chatter cases it does not cover, and why strain hardening is not modelled</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="../machine-capability/index.html">Machine Capability</a> — the equipment ceilings this physics runs into</li>
<li><a href="../measurement/index.html">Measurement</a> — where the coefficients and angles in this model come from</li>
<li><a href="../../manual/setup/cutter.html">Cutter</a> — the application task that creates a tool carrying this geometry</li>
<li><a href="../nc-optimization/index.html">NC Optimization</a> — what the optimizer does when a cut fails these criteria</li>
<li><a href="../scripting/index.html">Scripting</a> — the per-step values that carry these quantities out of a run</li>
<li><a href="../validation/index.html">Validation</a> — how closely this model has been held against measurement</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,165 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Evaluating Process Machinability | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Evaluating Process Machinability | 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="Technique-Machinability">
<h1 id="evaluating-process-machinability">Evaluating Process Machinability</h1>
<p>The <strong>machinability time-series chart</strong> can be used to evaluate tool breakage risk during machining.</p>
<p>Tool breakage occurs when any of the following exceeds 100% and persists for longer than one simulation step: <strong>Yielding Stress Ratio</strong> <small>[<a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html#Hi_MachiningSteps_MachiningStep_YieldingStressRatio">YieldingStressRatio</a> (API)]</small>, <strong>Max Spindle Torque Ratio</strong> <small>[<a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html#Hi_MachiningSteps_MachiningStep_MaxSpindleTorqueRatio">MaxSpindleTorqueRatio</a> (API)]</small>, or <strong>Max Spindle Power Ratio</strong> <small>[<a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html#Hi_MachiningSteps_MachiningStep_MaxSpindlePowerRatio">MaxSpindlePowerRatio</a> (API)]</small>.
If the value significantly exceeds 100% — roughly speaking, above 200% — tool breakage can occur even without sustained duration.</p>
<blockquote>
<p><strong>Note</strong>: The default simulation uses per-revolution milling mode, where one simulation step equals one spindle revolution.</p>
</blockquote>
<p><strong>Yielding Stress Ratio</strong> is a percentage indicator with the tool material's breakage force as the denominator. The numerator is the simulation step's absolute force <a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html#Hi_MachiningSteps_MachiningStep_MaxAbsForce_N">MaxAbsForce_N</a><small>(API)</small>. Compared to using the absolute force value directly as a limit, the ratio incorporates tool material mechanics and more accurately reflects the tool's actual safety margin. The optimization target force <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_OptPreferedForce_N">OptPreferedForce_N</a><small>(API)</small> represents the desired MaxAbsForce_N after optimization.</p>
<p>For small tools, breakage is typically caused by insufficient tool force capacity, and breakage is based on the <strong>Yielding Stress Ratio</strong>.</p>
<p>For small-to-medium tools, breakage is typically caused by insufficient spindle performance, and breakage is based on the <strong>Max Spindle Torque Ratio</strong> or <strong>Max Spindle Power Ratio</strong>.
When cutting resistance exceeds spindle performance, the machine feed rate remains constant but the spindle speed continuously decreases, causing the feed per tooth to continuously increase, which drives cutting forces to spike until tool breakage or machine stoppage.
For the underlying boundary curves and how each ratio's denominator is computed at the current rpm, see <a class="xref" href="../machine-capability/spindle-capability.html">Spindle Capability</a>.</p>
<div class="NOTE">
<h5>Note</h5>
<p><strong>Tool Breakage Solutions</strong></p>
<p>Modify the toolpath to reduce cutting width/depth, or use HiNC's optimization feature to adjust feed rates, bringing the <strong>Yielding Stress Ratio</strong>, <strong>Max Spindle Torque Ratio</strong>, and <strong>Max Spindle Power Ratio</strong> below 100%.</p>
</div>
<h2 id="ripple-on-curved-and-tilted-cuts-mesh-quantization">Ripple on Curved and Tilted Cuts (Mesh Quantization)</h2>
<p>On a nominally constant-engagement cut that is <strong>curved or tilted</strong> — arc or helical hole milling, ramping, or 5-axis moves — the <strong>Yielding Stress Ratio</strong> (and the underlying <a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html#Hi_MachiningSteps_MachiningStep_MaxAbsForce_N">MaxAbsForce_N</a><small>(API)</small>) can show a small step-to-step ripple even though the theoretical engagement is steady. This is a discretization artifact, not a bug.</p>
<p><strong>Cause.</strong> The workpiece is represented by an axis-aligned cubic voxel mesh (see <a href="../../workflows/basic-simulation.html#31-workpiece-entity-resolution">Workpiece Entity Resolution</a>). Orthogonal cubes cannot represent a circle or an inclined face smoothly, so the removed volume and the contact engagement area quantize against the grid from step to step. That quantization shows up as ripple in the per-step peak force, and therefore in the ratio.</p>
<p><strong>What helps.</strong> A <strong>finer</strong> <code>MachiningResolution_mm</code> makes the quantization step smaller, so the ripple amplitude shrinks — at the cost of slower geometry removal (see <a class="xref" href="../simulation-performance/cpu-usage.html">CPU Usage During Simulation</a>).</p>
<p><strong>What does <em>not</em> help.</strong> Switching to <strong>fixed-pace / sweeping</strong> motion resolution (<code>FixedPace</code>) does not remove this ripple. The ripple comes from the spatial cubic grid, not from the spacing between steps, so changing the step spacing leaves it essentially unchanged.</p>
<p><strong>Getting a smooth curve.</strong> There is no built-in filter that smooths step-series curves. If a smooth curve is needed for a report, post-process the exported CSV (<a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_WriteStepFiles_">WriteStepFiles</a><small>(API)</small>) yourself — e.g. a moving average. Note that the Yielding Stress Ratio is defined on the per-revolution <strong>peak</strong> force only (there is no averaged variant); the averaged force fields (<code>Avg…</code>) are inherently smoother when a trend, rather than the breakage peak, is what you need to read.</p>
<h2 id="thermal-plastic-deformation-of-cutting-edge">Thermal Plastic Deformation of Cutting Edge</h2>
<p>If the <strong>Thermal Yield Ratio</strong> <small>[<a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html#Hi_MachiningSteps_MachiningStep_ThermalYieldRatio">ThermalYieldRatio</a> (API)]</small> exceeds 100%, thermal plastic deformation of the cutting edge occurs, accelerating wear.
Unlike the Yielding Stress Ratio, Max Spindle Torque Ratio, and Max Spindle Power Ratio, this is a long-term indicator — exceeding 100% does not cause immediate effects.</p>
<div class="NOTE">
<h5>Note</h5>
<p><strong>Thermal Plastic Deformation Solutions</strong></p>
<p>After addressing tool breakage issues, reduce the spindle speed to allow sufficient time for the cutting edge to dissipate heat.</p>
<p>Note that whether the coolant is properly directed at the cutting edge has a significant impact. If the coolant is not aimed at the cutting edge, it effectively reduces the heat dissipation coefficient.</p>
</div>
<p>Tool manufacturers typically provide recommended machining conditions, and the Thermal Yield Ratio obtained by simulating under those conditions usually exceeds 100%. This is because the manufacturing formulations of tool materials differ from HiNC's conservatively set default values.
If you consider machining conditions with a Thermal Yield Ratio above 100% to be reasonable, you can adjust the thermal properties of the tool material so that the calculated Thermal Yield Ratio approaches 100%.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><p><a href="coolant-model.html">Coolant Model</a> — what decides the convection coefficient behind the thermal-yield ratio</p>
</li>
<li><p><a class="xref" href="cutter-adjustment-levers.html">Cutter Adjustment Levers</a> — what to change on the cutter when a step is not machinable as programmed</p>
</li>
<li><p><a class="xref" href="../machine-capability/spindle-capability.html">Spindle Capability</a> — where the spindle torque and power ratios come from</p>
</li>
<li><p><a class="xref" href="../simulation-performance/cpu-usage.html">CPU Usage During Simulation</a> — what a finer <code>MachiningResolution_mm</code> costs in simulation time</p>
</li>
<li><p><a class="xref" href="../simulation-performance/mesh-resolution.html">Mesh Resolution</a> — how to choose that value, and the thin-wall geometry a coarse mesh can lose entirely</p>
</li>
<li><p><a class="xref" href="../validation/cutting-force.html">Cutting Force and Torque Validation</a> — how closely the forces behind these ratios agree with measurement</p>
</li>
<li><p><a class="xref" href="../validation/anomaly-cases.html">Cutting Force Anomaly Cases</a> — two production failures these ratios would have flagged</p>
</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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

@@ -0,0 +1,142 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Milling Physics Coordinate Systems | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Milling Physics Coordinate Systems | 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="Milling-Physics-Coordinates">
<h1 id="milling-physics-coordinate-systems">Milling Physics Coordinate Systems</h1>
<p>Physical properties such as milling forces, milling torques, and deformations can be represented in different coordinate systems. Sensor raw data also corresponds to different coordinate systems.</p>
<p>When viewing physical simulation data in HiNC, you will often see coordinate system notations. This chapter explains the three coordinate systems shown in the figure below.</p>
<div class="NOTE">
<h5>Note</h5>
<p><img src="milling-physics-coordinates-img/Machining-3-Coordinate.png" alt="Machining-3-Coordinate"></p>
</div>
<h2 id="workpiece-coordinate-system">Workpiece Coordinate System</h2>
<p>Workpiece Coordinate System, abbreviated as <code>[W]</code>.</p>
<p>Usually the program origin coordinate system.</p>
<p>The workpiece coordinate system is consistent with the dynamometer coordinate system.</p>
<h2 id="tool-running-coordinate-system">Tool Running Coordinate System</h2>
<p>Tool Running Coordinate System, abbreviated as <code>[TR]</code>.</p>
<p>Takes the tool running direction excluding tool normal movement as +X, tool normal vector as +Z, and defines +Y by the right-hand rule. For climb milling, +Y direction is away from the wall.</p>
<p>The tool running coordinate system is suitable for understanding machining conditions.</p>
<h2 id="spindle-rotation-coordinate-system">Spindle Rotation Coordinate System</h2>
<p>Spindle Rotation Coordinate System, abbreviated as <code>[SR]</code>.</p>
<p>The tool running coordinate system rotated around the Z axis by spindle motion angle <span class="math">\(\theta\)</span> becomes the spindle rotation coordinate system.</p>
<p>The spindle rotation coordinate system is consistent with the smart tool holder coordinate system, as the smart tool holder sensor rotates with the spindle.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><p><a href="../measurement/smart-tool-holder.html">Smart Tool Holder</a> — the sensor whose torque is reported in the spindle-rotation frame, and the mounting values that decide its scale</p>
</li>
<li><p><a class="xref" href="../scripting/step-fields.html">Step Field Reference</a> — the per-step outputs whose <code>[W]</code> / <code>[TR]</code> / <code>[SR]</code> marks these frames decode</p>
</li>
<li><p><a class="xref" href="../measurement/smart-holder-training.html">Smart Holder Training</a> — the measurement that reports in the spindle-rotation frame</p>
</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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

@@ -0,0 +1,144 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Probabilistic Peak: Why a Cut Passes Most of the Time and Occasionally Cracks the Cutter | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Probabilistic Peak: Why a Cut Passes Most of the Time and Occasionally Cracks the Cutter | 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="Technique-ProbabilisticPeakCrack">
<h1 id="probabilistic-peak-why-a-cut-passes-most-of-the-time-and-occasionally-cracks-the-cutter">Probabilistic Peak: Why a Cut Passes Most of the Time and Occasionally Cracks the Cutter</h1>
<p><img src="probabilistic-peak-crack-img/dartboard-engagement.png" alt="Spindle-moment dartboard and the matching 3D engagement for one spindle revolution">
<em>Left — spindle-moment dartboard. The <code>(Mx, My)</code> moment-vector tip is drawn as a closed
locus over one spindle revolution, coloured by the axial moment <code>Mz</code>; the concentric rings
are moment magnitude (Nm). For most of the revolution the locus stays near the centre —
small fluteworkpiece contact length, small moment. One narrow lobe stretches out to the
outer rings: the angle where the contact length spikes and produces the large force that
can crack the flute. Right — the 3D engagement at that high-load phase, showing the flute
deeply engaged with the workpiece.</em></p>
<h2 id="the-mechanism">The Mechanism</h2>
<p>The fluteworkpiece contact length is small for most spindle angles and spikes only inside
one <strong>narrow angular window</strong>. The large force — and the crack risk — exists only inside
that window.</p>
<p>The cutter's flutes are <strong>discrete</strong>. Whether a cutting flute actually lands inside the
narrow high-contact window is a matter of flute phase, not a certainty:</p>
<ul>
<li><strong>High probability</strong> — the flutes fall in the wide low-contact region and step over the
window. The pass completes safely.</li>
<li><strong>Low probability</strong> — a flute lands inside the narrow window, takes the full contact
length, and sees the large force. The flute can crack.</li>
</ul>
<p>This is why a cut with a clear high-contact window still passes most of the time and only
occasionally breaks the cutter, and why nominally identical geometry can pass on one pass
and crack on another. It is the same effect documented under
<a href="../machine-capability/cam-floating-point-drift.html#probabilistic-peak-dodging">Probabilistic Peak Dodging</a>.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../machine-capability/cam-floating-point-drift.html">CAM Floating-Point Drift</a> — a concrete case of the same
probabilistic peak effect, triggered by sub-micron floor contact.</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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

@@ -0,0 +1,147 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Primary Relief Angle Clearance | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Primary Relief Angle Clearance | 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="Technique-ReliefFaceAvoidance">
<h1 id="primary-relief-angle-clearance">Primary Relief Angle Clearance</h1>
<p>All relief angles discussed in this article refer to the primary relief angle — the relief angle closest to the cutting zone. Also known as the clearance angle.</p>
<p>During cutting, the milling cutter edge follows a trochoidal motion, shown as the red trochoid in the figure below. The blue circle is the tool envelope circle.</p>
<p>The region inside the red trochoid (toward the center of the envelope circle) is the already-cut area; the region outside the red trochoid is the uncut area. If the relief face falls in that region, it will collide with the uncut material.
Therefore, <strong>the angle marked RA (abbreviation for Relief Angle) represents the minimum required relief angle.</strong></p>
<p><img src="relief-face-avoidance-img/relief-angle.png" alt="relief-angle.png"></p>
<p>If the actual tool relief angle is smaller than the minimum required relief angle, the clearance face will press against the uncut workpiece, increasing forces on both the tool and the workpiece. This leads to greater tool vibration, workpiece surface springback, a sharp rise in surface roughness, and reduced tool life.</p>
<h2 id="minimum-required-relief-angle-calculation">Minimum Required Relief Angle Calculation</h2>
<p>For fixed-axis machining, the minimum required relief angle can be calculated from the feed rate, spindle speed, and tool radius. For simultaneous multi-axis machining, it must be computed in batch for each contact point along the program path.</p>
<p>The following outlines the calculation for fixed-axis machining.</p>
<p><span class="math">\(\vec r_p = \left(t\cdot v-R\cdot\sin\left(t\cdot w\right),R-R\cdot\cos\left(t\cdot w\right)\right)\)</span></p>
<p><span class="math">\(\vec r_b = \left(a\cdot v-R\cdot\cos\left(s\right),R-R\cdot\sin\left(s\right)\right)\)</span></p>
<p>Where:
<span class="math">\(\vec r_p\)</span> is the position vector of the red trochoid;
<span class="math">\(\vec r_b\)</span> is the position vector of the blue circle;
<span class="math">\(R\)</span> is the tool radius (mm);
<span class="math">\(w\)</span> is the spindle speed (rad/s);
<span class="math">\(v\)</span> is the feed rate (mm/s);
<span class="math">\(t\)</span> is time;
<span class="math">\(s = t\cdot w\)</span>;
<span class="math">\(a\)</span> is a specified time, used as a constant.</p>
<p>Let the velocity vectors be</p>
<div class="math">
\[
\vec v_p = \frac{d\vec r_p}{dt} ,
\vec v_b = \frac{d\vec r_b}{ds}
\]</div>
<p>The angle between <span class="math">\(\vec v_p\)</span> and <span class="math">\(\vec v_b\)</span> is the minimum required relief angle.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../machine-capability/cam-floating-point-drift.html">CAM Floating-Point Drift</a> — drift in the toolpath that can look like relief-face contact</li>
<li><a class="xref" href="../measurement/radial-angle-measurement.html">Radial Angle Measurement</a> — how the cutter's actual relief angle is measured</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,49 @@
<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="cutter-geometry.html" name="" title="Cutter Geometry">Cutter Geometry</a>
</li>
<li>
<a href="coolant-model.html" name="" title="Coolant Model">Coolant Model</a>
</li>
<li>
<a href="milling-physics-coordinates.html" name="" title="Milling Physics Coordinates">Milling Physics Coordinates</a>
</li>
<li>
<a href="machinability.html" name="" title="Process Machinability">Process Machinability</a>
</li>
<li>
<a href="probabilistic-peak-crack.html" name="" title="Probabilistic Peak &amp; Cutter Crack">Probabilistic Peak &amp; Cutter Crack</a>
</li>
<li>
<a href="relief-face-avoidance.html" name="" title="Relief Face Avoidance">Relief Face Avoidance</a>
</li>
<li>
<a href="wear.html" name="" title="Tool Life &amp; Wear">Tool Life &amp; Wear</a>
</li>
<li>
<a href="cutter-adjustment-levers.html" name="" title="Cutter Adjustment Levers">Cutter Adjustment Levers</a>
</li>
<li>
<a href="chatter.html" name="" title="Chatter">Chatter</a>
</li>
</ul>
</div>
</div>
</div>
</div>
@@ -0,0 +1,2 @@
{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"Cutter Geometry","href":"cutter-geometry.html","topicHref":"cutter-geometry.html"},{"name":"Coolant Model","href":"coolant-model.html","topicHref":"coolant-model.html"},{"name":"Milling Physics Coordinates","href":"milling-physics-coordinates.html","topicHref":"milling-physics-coordinates.html"},{"name":"Process Machinability","href":"machinability.html","topicHref":"machinability.html"},{"name":"Probabilistic Peak & Cutter Crack","href":"probabilistic-peak-crack.html","topicHref":"probabilistic-peak-crack.html"},{"name":"Relief Face Avoidance","href":"relief-face-avoidance.html","topicHref":"relief-face-avoidance.html"},{"name":"Tool Life & Wear","href":"wear.html","topicHref":"wear.html"},{"name":"Cutter Adjustment Levers","href":"cutter-adjustment-levers.html","topicHref":"cutter-adjustment-levers.html"},{"name":"Chatter","href":"chatter.html","topicHref":"chatter.html"}]}
@@ -0,0 +1,144 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tool Life and Wear | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Tool Life and Wear | 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="Wear">
<h1 id="tool-life-and-wear">Tool Life and Wear</h1>
<p>There are many modes of cutting edge damage, which can be attributed to instantaneous failure modes, including tool breakage and thermal cracking, see <a class="xref" href="machinability.html">this article</a>; while for modes attributed to long-term consumption failure, <u>it is recommended to use <strong>flank wear</strong> as the target for evaluating tool life</u>.</p>
<p>HiNC adopts the wear model<a id="fnref:1" href="#fn:1" class="footnote-ref"><sup>1</sup></a>:</p>
<p><span class="math">\(W(T) = \frac{k(T) L P}{H(T)}\)</span></p>
<p>where W is wear amount, k is wear coefficient, L is contact length, P is pressure, H is hardness, T is temperature.</p>
<p>HiNC calculates wear including:</p>
<ul>
<li>Crater Wear</li>
<li>Flank Wear Width</li>
<li>Flank Wear Depth</li>
</ul>
<p>Here crater wear refers to crater wear depth.</p>
<p>Flank wear width is most commonly used as an evaluation target in papers because it has measurement standards. In planar motion, tools will wear at the cutting peak first then the flank, so flank wear width can be used to evaluate total wear in laboratory settings.</p>
<p>However, if the tool has up and down motion during milling, the flank will experience random collisions before the cutting peak is worn out, in which case flank wear width loses its value for evaluating total wear.</p>
<p>The flank wear width calculated by HiNC assumes no random flank collisions and is only applicable to planar cutting. HiNC retains this value for research purposes.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><p><a class="xref" href="../validation/temperature-and-wear.html">Temperature and Wear Validation</a> — this model checked against thermal imaging and a measured wear depth</p>
</li>
<li><p><a class="xref" href="cutter-adjustment-levers.html">Cutter Adjustment Levers</a> — which cutter parameters to move once wear is the limit</p>
</li>
</ul>
<div class="footnotes">
<hr>
<ol>
<li id="fn:1">
<p>Lee, R. S, and J. L Jou. &ldquo;Application of Numerical Simulation for Wear Analysis of Warm Forging Die.&rdquo; Journal of Materials Processing Technology, Proceedings of the 6th Asia Pacific Conference on materials Processing, 140, no. 1 (September 22, 2003): 4348.<a href="#fnref:1" class="footnote-back-ref">&#8617;</a></p>
</li>
</ol>
</div>
</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,431 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Heidenhain Controller Support | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Heidenhain Controller Support | 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="Controllers/HeidenhainSupport">
<h1 id="heidenhain-controller-support">Heidenhain Controller Support</h1>
<p>Heidenhain programs run on a single controller preset that reads <strong>both</strong> dialects — TNC klartext
(TNC 640 / TNC 530 conversational) and Heidenhain <strong>DIN/ISO</strong>. There is no separate selection to
make: pick Heidenhain as the project's controller and the program is read in whichever dialect it is
written in.</p>
<p>Coverage is stated in the same three states as
<a href="controller-iso.html#how-to-read-this-page">General NC Code Support</a> — supported, recognized but not
simulated, and not supported. <em>Recognized but not simulated</em> is a deliberate state: the construct is
consumed and reported under its own message id, so it can never be silently misread as something
else. A <code>PLANE AXIAL B+45</code> will never be mistaken for a rotary-axis command.</p>
<h2 id="program-format">Program format</h2>
<h3 id="separators-are-optional">Separators are optional</h3>
<p>Klartext is normally written with spaces between the letter instructions, and that is what the
control shows. Some post-processors emit the same program with no separators at all. <strong>Both forms
parse</strong>, and so does the detached feed spelling.</p>
<blockquote>
<p>Equivalent, all parsed:</p>
<ul>
<li><code>L X-26.3 Y+43.1 Z+100.3 A-90.0 C+13.123 FQ3</code> and <code>LX-26.3Y+43.1Z+100.3A-90.0C+13.123FQ3</code></li>
<li><code>L X+0 Y+0 R0 FMAX</code> and <code>LX+0Y+0R0FMAX</code></li>
<li><code>FMAX M03 M08</code> and <code>FMAXM03M08</code></li>
<li><code>F20000</code> and <code>F 20000</code></li>
</ul>
</blockquote>
<h3 id="multi-line-blocks">Multi-line blocks</h3>
<p>A statement broken across lines with the tilde continuation — the usual shape of a <code>CYCL DEF</code> body or
a long <code>PLANE</code> statement — is joined back into one block before parsing, so it is read as the single
statement it is.</p>
<h2 id="motion">Motion</h2>
<table>
<thead>
<tr>
<th>Construct</th>
<th>Support</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>L</code></td>
<td>Straight-line motion with its axis words.</td>
</tr>
<tr>
<td><code>LN</code></td>
<td>Surface-normal block — a straight line carrying the endpoint plus up to two normalized vectors, in the fixed element order <code>X,Y,Z</code><code>NX,NY,NZ</code><code>TX,TY,TZ</code>. See <a href="#vector-blocks-ln">Vector blocks</a>.</td>
</tr>
<tr>
<td><code>FMAX</code></td>
<td>Rapid traverse.</td>
</tr>
<tr>
<td><code>CC</code> / <code>C</code></td>
<td>Circular motion — <code>CC</code> sets the pole, <code>C</code> states the end point. <code>DR-</code> is clockwise and <code>DR+</code> counter-clockwise, the centre always comes from the modal <code>CC</code> rather than from the <code>C</code> block, and an arc that closes on its start point is a full circle. See <a href="#arc-centres-cc">Arc centres</a>.</td>
</tr>
<tr>
<td><code>RL</code> / <code>RR</code> / <code>R0</code></td>
<td>Radius compensation left / right / off.</td>
</tr>
<tr>
<td><code>M91</code></td>
<td>One-shot machine-coordinate move for that block.</td>
</tr>
<tr>
<td><code>M126</code> / <code>M127</code></td>
<td>Shortest-path rotary traverse on / off. With neither stated, shortest path is the default.</td>
</tr>
<tr>
<td><code>M140 MB+n</code> / <code>M140 MB MAX</code></td>
<td>Tool-axis retract — by <code>n</code> mm, or to the positive Z stroke limit. Without a configured stroke limit, <code>MB MAX</code> reports <code>M140--NoStrokeLimit</code> and is skipped. The statement's own <code>F</code> drives the retract without entering the modal feedrate.</td>
</tr>
<tr>
<td><code>STOP</code></td>
<td>Program stop, alongside <code>M00</code> / <code>M01</code>.</td>
</tr>
<tr>
<td><code>CYCL DEF 32 TOLERANCE</code></td>
<td>Path-smoothing tolerance.</td>
</tr>
<tr>
<td><code>BLK FORM</code></td>
<td>Recorded as a stock declaration. It does <strong>not</strong> replace the workpiece configured in the project.</td>
</tr>
</tbody>
</table>
<h3 id="arc-centres-cc">Arc centres (<code>CC</code>)</h3>
<p>A <code>C</code> block never states its own centre. Each in-plane component is resolved from the modal <code>CC</code>
section: the <code>CC</code> block's own axis word first, then the same axis of the previous <code>CC</code>, and last the
arc's own start point. A <code>CC</code> stating no coordinates is the one spelling that supplies all three at
once — it takes the last programmed position, read at the <code>CC</code> block rather than at the arc, and
replaces the modal centre instead of inheriting it. That is what makes the manual's own shape work:
<code>CC</code> on the centre, a move out to the arc start, then the <code>C</code> block.</p>
<p>A centre that lands on the arc's own start point leaves the block with no radius and so no arc
geometry: it reports <code>Arc-CircleCenter--OnStartPoint</code> and is degraded to a straight move to the
endpoint. One in-plane coordinate is enough to escape that — an arc whose modal chain still leaves
the other coordinate to the start point keeps real geometry and plays normally, and is refused only
by the optimizer's splition, described under <a href="#optimized-output">Optimized output</a>.</p>
<h3 id="vector-blocks-ln">Vector blocks (<code>LN</code>)</h3>
<p>CAM-generated five-axis programs state the posture as vectors rather than as rotary words. An <code>LN</code>
block carries the endpoint plus the surface-normal vector <code>NX</code>/<code>NY</code>/<code>NZ</code> — the 3D tool-compensation
direction — and, optionally, the tool vector <code>TX</code>/<code>TY</code>/<code>TZ</code>. HiNC resolves whichever vector governs
into the machine's rotary axes and feeds the result through the same RTCP machinery the rotary-word
programs use, so there is no second motion path to reason about.</p>
<p>Which vector governs follows the control's own rules:</p>
<table>
<thead>
<tr>
<th>Situation</th>
<th>Tool axis</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>T</code> present, <code>M128</code> or <code>FUNCTION TCPM</code> active</td>
<td>The <code>T</code> vector — the tool keeps the set orientation.</td>
</tr>
<tr>
<td><code>T</code> absent, RTCP active</td>
<td>The surface normal <code>N</code> — the tool is held perpendicular to the contour.</td>
</tr>
<tr>
<td>RTCP inactive</td>
<td>The <code>T</code> vector is <strong>ignored</strong>, exactly as the control ignores it. Reported as <code>Orientation-Vector--IgnoredNoTcpm</code>, with the posture left untouched.</td>
</tr>
</tbody>
</table>
<p>RTCP counts as active when the same block turns it on, so a block that both activates RTCP and
carries a vector is not skipped.</p>
<p>Two limits are worth knowing before trusting the result:</p>
<ul>
<li>The vector is read in the <strong>untilted</strong> program frame. An <code>LN</code> block under an active <code>PLANE</code> tilt is
reported as <code>Orientation-Vector--TiltedFrameAssumed</code> rather than remapped.</li>
<li>Compensation <strong>along</strong> the surface normal (<code>DR2</code> / 3D-ToolComp) is recognized, not simulated —
<code>SurfaceNormal--CompNotSimulated</code>, raised once per run.</li>
</ul>
<p>A vector that is not unit length is normalized and reported (<code>Orientation-Vector--NotNormalized</code>); a
zero vector is reported as <code>Orientation-Vector--ZeroVector</code>.</p>
<h2 id="tools">Tools</h2>
<p><code>TOOL CALL</code> performs the tool change on its own — klartext has no separate <code>M06</code> trigger. A tool
number or a quoted tool name is accepted.</p>
<blockquote>
<p>Parsed:</p>
<ul>
<li><code>TOOL CALL 1 Z S5000</code></li>
<li><code>TOOL CALL &quot;1&quot; Z S5000</code></li>
<li><code>TOOL CALL &quot;B40R&quot; Z S3000 DL+0.5</code></li>
</ul>
</blockquote>
<ul>
<li>The spindle speed <code>S</code> is recorded modally.</li>
<li><code>DL</code> is a length delta — the effective tool height is the tool-table height <strong>plus</strong> <code>DL</code>.</li>
<li><code>DR</code> is read and recorded but <strong>not applied</strong>: radius compensation uses the tool-table radius as-is,
and the block reports <code>ToolChange--DeltaUnsupported</code>.</li>
<li>A tool axis other than <code>Z</code> reports <code>ToolChange--AxisUnsupported</code>.</li>
<li>A <code>TOOL CALL</code> whose tool number could not be captured — an unevaluated variable, for example —
reports <code>ToolChange--MissingToolId</code>.</li>
</ul>
<h2 id="datums">Datums</h2>
<p><code>CYCL DEF 247</code> sets the datum preset and <code>CYCL DEF 7</code> is an <strong>additive</strong> shift on top of it, which is
the TNC semantic. The two compose as separate entries in the coordinate chain instead of replacing
each other.</p>
<blockquote>
<p>Parsed:</p>
<pre><code>CYCL DEF 247 Q339=+1
</code></pre>
<pre><code>CYCL DEF 7.0 DATUM SHIFT
CYCL DEF 7.1 X10.123
CYCL DEF 7.2 Y22.223
CYCL DEF 7.3 Z32.97
</code></pre>
</blockquote>
<h2 id="q-parameters-and-fn">Q parameters and FN</h2>
<p><code>Q</code>, <code>QR</code>, <code>QL</code> and <code>QS</code> parameters are read wherever a value is expected, so <code>FQ1</code> reaches the
feedrate, <code>L X+Q2</code> reaches the program position and <code>TOOL CALL SQ3</code> reaches the spindle speed. <code>Q0</code><code>Q99</code>
free parameters and <code>QR0</code><code>QR499</code> permanent parameters are held as per-project data and saved with
the project.</p>
<table>
<thead>
<tr>
<th>Construct</th>
<th>Support</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>FN 0</code><code>FN 5</code></td>
<td>Assignment and arithmetic, including the <code>DIV</code> keyword of FN 4 and the prefix <code>SQRT</code> of FN 5.</td>
</tr>
<tr>
<td><code>FN 9</code><code>FN 12</code></td>
<td>Conditional jumps — <strong>executed</strong>, with a per-label iteration cap so a corrupt or hostile program cannot spin forever.</td>
</tr>
<tr>
<td>Other <code>FN</code> opcodes (<code>FN 14</code>, <code>FN 16</code>, <code>FN 18 SYSREAD</code>, …)</td>
<td>Recognized, not simulated. The statement is claimed and reported, so its target parameter stays empty instead of taking a fabricated value.</td>
</tr>
</tbody>
</table>
<blockquote>
<p>Parsed:</p>
<ul>
<li><code>Q1 = 5000</code></li>
<li><code>FN0: Q1 = 5000</code></li>
<li><code>FN1: Q1 = -Q2 + -5</code></li>
<li><code>FN2: Q1 = +10 - +5</code></li>
<li><code>FN3: Q2 = +3 * +3</code></li>
</ul>
</blockquote>
<h2 id="tilted-planes-and-rtcp">Tilted planes and RTCP</h2>
<table>
<thead>
<tr>
<th>Construct</th>
<th>Support</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>PLANE SPATIAL</code></td>
<td>Fully composed, including <code>SEQ+</code> / <code>SEQ-</code>, <code>COORD ROT</code> / <code>TABLE ROT</code>, and the <code>STAY</code> / <code>MOVE</code> / <code>TURN</code> positioning behaviours.</td>
</tr>
<tr>
<td><code>PLANE RESET</code></td>
<td>Cancels the tilt.</td>
</tr>
<tr>
<td><code>PLANE VECTOR</code></td>
<td>Structurally captured, not simulated.</td>
</tr>
<tr>
<td><code>PLANE EULER</code> / <code>POINTS</code> / <code>RELATIV</code> / <code>AXIAL</code> / <code>PROJECTED</code></td>
<td>Recognized, not simulated — consumed and reported as <code>HeidenhainPlane--Unsupported</code>, with the previous tilt retained.</td>
</tr>
<tr>
<td><code>FUNCTION TCPM</code></td>
<td>Supported, read as the default <code>REFPNT TIP-TIP</code>. A center-referenced reference point (<code>REFPNT CNT-CNT</code> / <code>TIP-CENTER</code>) is <strong>recognized, not simulated</strong>: the coordinates are still taken as tip-to-tip, so CNT-referenced CAM output simulates offset by the ball radius along the tool axis. Reported as <code>Orientation-RefPoint--CntNotSimulated</code>.</td>
</tr>
<tr>
<td><code>M128</code> / <code>M129</code></td>
<td>Tool centre point control on / off — real RTCP, the Heidenhain sibling of ISO <code>G43.4</code> and Siemens <code>TRAORI</code>.</td>
</tr>
</tbody>
</table>
<blockquote>
<p>Parsed:</p>
<ul>
<li><code>PLANE SPATIAL SPA-60.3 SPB+0 SPC-19.88 STAY SEQ- TABLE ROT</code></li>
<li><code>PLANE RESET STAY</code></li>
</ul>
</blockquote>
<h2 id="cycles-and-calls">Cycles and calls</h2>
<ul>
<li><strong><code>CYCL DEF 2xx</code></strong> bodies are read with their <code>Q</code> parameters mirrored into the block. Cycles <strong>200</strong>,
<strong>232</strong>, <strong>251</strong>, <strong>252</strong> and <strong>253</strong> are mapped onto the shared drilling machinery and simulated;
the mapping follows the cycle's own <code>Q</code> values, so a <code>Q202</code> peck increment routes to peck drilling
and a <code>Q211</code> bottom dwell to dwell drilling.</li>
<li>A <code>CYCL DEF</code> body that is not one of those is recognized, not simulated — reported as
<code>HeidenhainCycl--Unsupported</code>.</li>
<li><strong><code>CYCL CALL</code></strong> and <strong><code>CYCL CALL POS</code></strong> fire the cycle once; <code>M99</code> fires once and <code>M89</code> arms modal
firing.</li>
<li><strong><code>CALL LBL n</code></strong> inlines the label body up to <code>LBL 0</code>; <strong><code>CALL LBL n REP m</code></strong> repeats that section
<code>m</code> times.</li>
<li><strong><code>CALL PGM</code></strong> resolves the called program by file name.</li>
<li><strong>Mirror image</strong> in both spellings — the klartext <code>CYCL DEF 8</code> form and the DIN/ISO <code>G28</code> form.</li>
</ul>
<h2 id="diniso-dialect">DIN/ISO dialect</h2>
<p>The same preset, with nothing to switch.</p>
<ul>
<li><code>%</code> tape header and <code>N</code> block numbers.</li>
<li><code>T</code> plus <code>M06</code> tool change.</li>
<li><strong>Arc centres <code>I</code> / <code>J</code> / <code>K</code> are absolute pole coordinates</strong>, not incremental offsets from the
start point. This is the Heidenhain reading, and the pole carries forward modally.</li>
<li>The ISO label family — <code>G98 L&lt;n&gt;</code> definitions, and the head-anchored <code>L&lt;n&gt;,&lt;m&gt;</code> call whose comma
count maps onto the repeat count.</li>
<li><code>G247 Q339</code> stamps the same datum preset as <code>CYCL DEF 247</code>.</li>
<li><code>G54</code> with axis words is read as a datum-shift declaration.</li>
<li><code>G70</code> / <code>G71</code> units.</li>
</ul>
<div class="WARNING">
<h5>Warning</h5>
<p><strong><code>G28</code> on Heidenhain is MIRROR IMAGE, not a reference-point return.</strong> The Fanuc reading of <code>G28</code>
is deliberately absent from the Heidenhain preset. Select the Heidenhain controller for a
Heidenhain DIN/ISO file — read as Fanuc, every mirror statement becomes a home move.</p>
</div>
<h2 id="optimized-output">Optimized output</h2>
<p>An optimized program is patched into the source text block by block rather than re-emitted, so it
comes back in the dialect it was written in, and two rules keep the result a program a TNC will
accept.</p>
<p>A feed the optimizer writes into a block that carried none lands after the coordinate words and
after <code>DR+</code> / <code>DR-</code> and <code>RL</code> / <code>RR</code> / <code>R0</code>, so the element order the control expects — coordinates,
rotation direction, radius compensation, <code>F</code>, <code>M</code> — holds on the patched block: <code>L X+10 Y+20 RL</code>
comes back as <code>L X+10 Y+20 RL F500</code>. A block that already states an <code>F</code> keeps that word where it
stands, and only its number changes — unless the feed is <code>FMAX</code>, <code>FAUTO</code> or a <code>Q</code> parameter, which
patch mode refuses to rewrite: the block is left exactly as written, reporting
<code>Writeback-Patch--KeywordValue</code> or <code>Writeback-Patch--VariableValue</code>.</p>
<p>The optimizer's embedded source note is written in the klartext comment grammar — a <code>;</code> comment,
never a parenthesized one, because a TNC reads parentheses as code:</p>
<pre><code>120 L X+35 Y-11.7 R0 F500 ;src(LineNo: 140, StepIndex: 256)
</code></pre>
<p>Re-interpolation itself is not refused for being klartext. A <code>C … DR±</code> arc splits like any other
when the modal <code>CC</code> chain supplies both in-plane centre coordinates: no centre words are rebuilt,
and each fragment carries the block's own words with its own endpoint and feed, around the one <code>CC</code>
line they all share unchanged. The arc that is optimized whole instead is the one whose modal chain
left an in-plane coordinate unstated — no <code>CC</code> ever gave it, so the arc's own start point supplies
it, and every fragment would re-derive that centre from its own start. Such pieces are optimized as
whole lines under <code>NcOpt--SplitionStartPointCenterUnsupported</code>, raised once per run.</p>
<h2 id="not-supported">Not supported</h2>
<p><code>TOOL DEF</code>, <code>FK</code> free-contour programming, <code>SL</code> cycles, <code>PATTERN DEF</code>, and <code>TCH PROBE</code>. These are left
unconsumed, and the block that carried them reports <code>Parsing--Unconsumed</code> naming the words.</p>
<p>Machine-specific M-codes that are not part of the Heidenhain vocabulary above are declared on the
machine rather than built in — see the M-code note on
<a href="controller-iso.html#m-codes">General NC Code Support</a>.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="controller-iso.html">General NC Code Support</a> — Fanuc, Syntec, Mazak and Siemens SINUMERIK.</li>
<li><a class="xref" href="nc-parsing.html">NC Parsing Engine</a> — the pipeline behind these constructs, the
brand-by-brand support matrix in one table, and how a machine's own vocabulary is added without
changing HiNC.</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,547 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>General NC Code Support | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="General NC Code Support | 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="Technique-GeneralNcCodeSupport">
<h1 id="general-nc-code-support">General NC Code Support</h1>
<p>The vocabulary HiNC interprets is decided by the controller brand selected for the project. This page
covers the ISO-family presets — <strong>Fanuc</strong>, <strong>Syntec</strong> and <strong>Mazak</strong> — and <strong>Siemens SINUMERIK</strong>.
Heidenhain is a different language and has its own page: <a href="controller-heidenhain.html">Heidenhain Support</a>.</p>
<h2 id="how-to-read-this-page">How to read this page</h2>
<p>Coverage is stated in three states.</p>
<table>
<thead>
<tr>
<th>State</th>
<th>What happens when the construct appears in your program</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Supported</strong></td>
<td>interpreted, and its effect is simulated.</td>
</tr>
<tr>
<td><strong>Recognized, not simulated</strong></td>
<td>consumed on purpose and reported under its own message id. The block keeps running and the construct's effect does not apply — but it can never be silently misread as something else.</td>
</tr>
<tr>
<td><strong>Not supported</strong></td>
<td>the words are left over, and the block reports <code>Parsing--Unconsumed</code> naming them.</td>
</tr>
</tbody>
</table>
<div class="TIP">
<h5>Tip</h5>
<p>The message list a run produces is the coverage report for <strong>your</strong> program. Every word the
interpreter could not use is named on the block that carried it, so you never have to infer
coverage from the simulated result. An unknown code does not stop the run — it is reported and
skipped.</p>
</div>
<h2 id="iso-core">ISO core</h2>
<p>Fanuc, Syntec and Mazak share the vocabulary below. Siemens spells most of it the same way and adds
its own for the rest — see <a href="#siemens-sinumerik">Siemens SINUMERIK</a>.</p>
<h3 id="motion">Motion</h3>
<table>
<thead>
<tr>
<th>Code</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>G00</code></td>
<td>Rapid positioning.</td>
</tr>
<tr>
<td><code>G01</code></td>
<td>Linear interpolation at the programmed feedrate.</td>
</tr>
<tr>
<td><code>G02</code> / <code>G03</code></td>
<td>Circular interpolation, clockwise / counter-clockwise. The centre may be given as <code>I</code> / <code>J</code> / <code>K</code> offsets or as a radius <code>R</code>.</td>
</tr>
<tr>
<td><code>G04</code></td>
<td>Dwell. <code>X</code> / <code>U</code> are seconds, <code>P</code> is milliseconds, <code>S</code> is spindle revolutions. Both the <code>G4</code> and <code>G04</code> spellings are read.</td>
</tr>
<tr>
<td><code>G28</code></td>
<td>Reference-point (home) return through an intermediate point.</td>
</tr>
<tr>
<td><code>G53</code></td>
<td>One-shot machine-coordinate move — work offsets are bypassed for that block only.</td>
</tr>
</tbody>
</table>
<h3 id="plane-units-and-positioning-mode">Plane, units and positioning mode</h3>
<table>
<thead>
<tr>
<th>Code</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>G17</code> / <code>G18</code> / <code>G19</code></td>
<td>Plane selection — XY / ZX / YZ. Arcs and canned cycles follow the active plane.</td>
</tr>
<tr>
<td><code>G21</code></td>
<td>Metric. This is the HiNC default.</td>
</tr>
<tr>
<td><code>G71</code></td>
<td>Metric — the RS-274-D / Fanuc G-code system C / Syntec spelling of <code>G21</code>, accepted the same way on the Fanuc and Syntec presets. Mazak EIA stays <code>G20</code> / <code>G21</code> only.</td>
</tr>
<tr>
<td><code>G20</code></td>
<td>Inch — <strong>not supported</strong>. The block reports <code>Unit--InchNotSupported</code>; post the program in metric.</td>
</tr>
<tr>
<td><code>G70</code></td>
<td>Inch — the RS-274-D / Fanuc G-code system C / Syntec spelling of <code>G20</code>, read on the Fanuc and Syntec presets. <strong>Not supported</strong>; the block reports <code>Unit--InchNotSupported</code>; post the program in metric.</td>
</tr>
<tr>
<td><code>G90</code> / <code>G91</code></td>
<td>Absolute / incremental positioning.</td>
</tr>
<tr>
<td><code>G94</code> / <code>G95</code></td>
<td>Feed per minute / feed per revolution.</td>
</tr>
</tbody>
</table>
<h3 id="work-coordinates">Work coordinates</h3>
<table>
<thead>
<tr>
<th>Code</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>G54</code><code>G59</code></td>
<td>Standard work coordinate systems.</td>
</tr>
<tr>
<td><code>G59.1</code><code>G59.9</code></td>
<td>Extended work coordinate systems, backed by the brand-neutral table the Fanuc, Mazak and Syntec presets carry behind their brand table. Like <code>G54</code><code>G59</code>, a row left at zero is read as an authoring convention and stays silent.</td>
</tr>
<tr>
<td><code>G54.1 P1</code><code>P48</code></td>
<td>Fanuc additional work coordinate systems, backed by the extended work offset table. Also read in the manual's second spelling <code>G54 P1</code><code>P48</code>, with or without the space; a <code>G54</code> with no P word is the plain G54 above. A selected row nobody has entered reports <code>Coord-WorkOffset--AdditionalZero</code>.</td>
</tr>
<tr>
<td><code>G52</code></td>
<td>Local coordinate offset, applied on top of the active work coordinate system.</td>
</tr>
</tbody>
</table>
<h3 id="tool-compensation">Tool compensation</h3>
<table>
<thead>
<tr>
<th>Code</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>G43</code> / <code>G44</code> / <code>G49</code></td>
<td>Tool length compensation, positive / negative / cancel. <code>H</code> selects the offset row.</td>
</tr>
<tr>
<td><code>G41</code> / <code>G42</code> / <code>G40</code></td>
<td>Cutter radius compensation, left / right / cancel. <code>D</code> selects the offset row.</td>
</tr>
</tbody>
</table>
<p>Radius compensation is resolved against the blocks that actually travel in the compensation plane. A
block whose own words command no movement in that plane — a bare <code>G41</code> / <code>G42</code>, a comment, an empty
line, a Z-only plunge — takes no offset of its own and no part in a corner:</p>
<ul>
<li><strong>Start-up waits for motion.</strong> A <code>G41</code> or <code>G42</code> block that does not move in the plane does not
start the offset; the first block that travels in the plane is the start-up block and takes the
perpendicular (type A) offset. The blocks between them carry the previous block's offset vector,
so nothing moves on their account.</li>
<li><strong>Corners are resolved between travelling blocks.</strong> Wordless blocks sitting between two moves are
passed over, and the corner is the intersection of the two real segments. Running axes are the
in-plane part of each displacement, so a ramping move keeps its full offset and a Z-only plunge
stays on the offset line.</li>
<li><strong>A bare <code>G40</code> closes the region.</strong> The last compensated block ends on its own perpendicular
offset rather than turning toward the first uncompensated move after the cancel. A <code>G40</code> that
carries motion is the last corner's partner instead, and the compensated path meets the cancel
line at their intersection (Fanuc type B); the legacy interpreter
(<a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_EnableSoftNcRunner">EnableSoftNcRunner</a> set <code>false</code>) ends that case
perpendicular.</li>
</ul>
<h3 id="rotation-tilted-planes-and-five-axis">Rotation, tilted planes and five-axis</h3>
<table>
<thead>
<tr>
<th>Code</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>G68</code></td>
<td>Coordinate rotation in the active plane, around a centre point by angle <code>R</code>.</td>
</tr>
<tr>
<td><code>G68.2</code></td>
<td>Tilted work plane — Euler angles <code>I</code> / <code>J</code> / <code>K</code> with origin <code>X</code> / <code>Y</code> / <code>Z</code>.</td>
</tr>
<tr>
<td><code>G69</code></td>
<td>Cancels <code>G68</code> and <code>G68.2</code>.</td>
</tr>
<tr>
<td><code>G53.1</code></td>
<td>Tool-axis direction — swings the rotary axes into line with the active <code>G68.2</code> plane.</td>
</tr>
<tr>
<td><code>G43.4</code></td>
<td>RTCP / tool centre point management. The Siemens equivalent is <code>TRAORI</code>, the Heidenhain equivalent <code>M128</code>.</td>
</tr>
</tbody>
</table>
<h3 id="canned-cycles">Canned cycles</h3>
<table>
<thead>
<tr>
<th>Code</th>
<th>Cycle</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>G73</code></td>
<td>High-speed peck drilling — <code>Q</code> increments with a partial retract.</td>
</tr>
<tr>
<td><code>G74</code></td>
<td>Left-hand tapping.</td>
</tr>
<tr>
<td><code>G76</code></td>
<td>Fine boring — oriented spindle stop, <code>Q</code> shift, rapid out.</td>
</tr>
<tr>
<td><code>G81</code></td>
<td>Drilling.</td>
</tr>
<tr>
<td><code>G82</code></td>
<td>Drilling with a dwell at the bottom.</td>
</tr>
<tr>
<td><code>G83</code></td>
<td>Peck drilling — <code>Q</code> increments with a full retract to the <code>R</code> point.</td>
</tr>
<tr>
<td><code>G84</code></td>
<td>Right-hand tapping.</td>
</tr>
<tr>
<td><code>G85</code></td>
<td>Boring, feed out.</td>
</tr>
<tr>
<td><code>G86</code></td>
<td>Boring, spindle stop then rapid out.</td>
</tr>
<tr>
<td><code>G87</code></td>
<td>Back boring.</td>
</tr>
<tr>
<td><code>G89</code></td>
<td>Boring with a dwell at the bottom.</td>
</tr>
<tr>
<td><code>G80</code></td>
<td>Cancel.</td>
</tr>
<tr>
<td><code>G98</code> / <code>G99</code></td>
<td>Retract to the initial level / to the <code>R</code> level.</td>
</tr>
</tbody>
</table>
<p>A cycle is expanded into the individual strokes it performs — approach, peck, dwell, retract — each
with its own feedrate, so material removal and cycle time come out of the real motion rather than an
approximation. Modal repetition and <code>G91</code> incremental cycle data are resolved before the strokes are
built.</p>
<h3 id="polar-interpolation">Polar interpolation</h3>
<p><code>G12.1</code> turns polar coordinate interpolation on and <code>G13.1</code> turns it off. Inside a polar section the
<code>X</code> word is a <strong>diameter</strong> and the <code>C</code> word is a hypothetical Cartesian axis in millimetres, not
rotary degrees. HiNC halves <code>X</code>, resolves <code>G90</code> / <code>G91</code>, writes both the polar and the derived
Cartesian positions along with the machine C angle, and simulates polar linear and polar arc motion —
the arc as real spiral geometry that stays continuous across ±180°. <code>G41</code> / <code>G42</code> compensation is
resolved on the hypothetical plane, and <code>YA</code> / <code>ZB</code> axis pairs work the same way. G codes that
conflict with polar mode are checked before the mode is entered.</p>
<h3 id="path-smoothing">Path smoothing</h3>
<p><code>G05.1 Q1</code> enables high-precision contour control (AICC / Nano Smoothing) and <code>Q0</code> disables it. The
optional <code>R</code> precision level is preserved.</p>
<p><strong>Bare <code>G05</code> (or <code>G5</code>) is a different feature under a confusingly similar name</strong>, and the two are
tracked separately so they cannot cancel one another. It selects a function through its <code>P</code> word, on
the Fanuc, Syntec and Mazak presets:</p>
<table>
<thead>
<tr>
<th><code>P</code></th>
<th>Reading</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>P10000</code></td>
<td>HPCC — RISC-based high-precision contour control. Recognized, deliberately not simulated: it changes the machine's look-ahead, acceleration and servo behaviour, never the programmed coordinates. Reports <code>Hpcc--NoOp</code>.</td>
</tr>
<tr>
<td><code>P0</code></td>
<td>Cancels HPCC. Consumed silently — cancelling a no-op needs no message.</td>
</tr>
<tr>
<td><code>P10001</code><code>P10999</code></td>
<td>High-speed cycle machining. The real machine executes cycle data pre-registered in its variable area, which is <strong>actual axis motion HiNC cannot see</strong>, so the simulated result misses that machining. Reports <code>Hpcc--HighSpeedCycleIgnored</code> as a warning.</td>
</tr>
<tr>
<td>anything else, or no <code>P</code> at all</td>
<td>Not supported offline and ignored, reported as <code>Hpcc--UnsupportedFunction</code>. Small <code>P</code> values select the high-speed remote buffer modes.</td>
</tr>
</tbody>
</table>
<p>An unevaluated macro variable or expression in <code>P</code> is tolerated — it reports
<code>Hpcc--UnsupportedFunction</code> rather than failing the block.</p>
<h3 id="m-codes">M codes</h3>
<table>
<thead>
<tr>
<th>Code</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>M00</code> / <code>M01</code></td>
<td>Program stop / optional stop.</td>
</tr>
<tr>
<td><code>M02</code> / <code>M30</code></td>
<td>Program end.</td>
</tr>
<tr>
<td><code>M03</code> / <code>M04</code> / <code>M05</code></td>
<td>Spindle clockwise / counter-clockwise / stop.</td>
</tr>
<tr>
<td><code>M06</code></td>
<td>Tool change. The axis travel the change requires is synthesized rather than teleported.</td>
</tr>
<tr>
<td><code>M07</code> / <code>M08</code> / <code>M09</code></td>
<td>Mist coolant on / flood coolant on / coolant off.</td>
</tr>
<tr>
<td><code>M98</code> / <code>M99</code></td>
<td>Subprogram call (<code>M98 P{program} L{repeat}</code>) and return, including <code>M99 P{sequence}</code> early return.</td>
</tr>
<tr>
<td><code>M198</code></td>
<td>Subprogram call from external storage — same shape as <code>M98</code>, different lookup folder.</td>
</tr>
</tbody>
</table>
<div class="NOTE">
<h5>Note</h5>
<p><strong>Composite and OEM M-codes are not built in — they are declared on the machine.</strong> An <code>M13</code> that
means &ldquo;spindle CW plus flood coolant&rdquo;, an M-code that triggers a tool change, or turret <code>T</code>-word
semantics are stated once in the machine's own M-code table and expanded into the ISO effects the
rest of the pipeline already understands. A code declared with no modelled effect is voiced once as
<code>DeclaredMCode--UnmodeledEffects</code> instead of raising an unknown-code warning on every occurrence.</p>
</div>
<div class="NOTE">
<h5>Note</h5>
<p>If a program states a spindle speed greater than zero but never issues a direction, HiNC assumes
clockwise and reports <code>SpindleDirection--AssumedCw</code>. Without that assumption the cutting-force
model would silently produce zero mechanics for the whole file.</p>
</div>
<h2 id="fanuc">Fanuc</h2>
<p>Everything in the ISO core, plus:</p>
<p><strong>Custom Macro B.</strong> <code>#</code> variable assignment and arithmetic, with each range routed to the store it
belongs to — <code>#1</code><code>#33</code> local to the macro frame, <code>#100</code><code>#499</code> volatile and cleared on <code>M02</code> /
<code>M30</code>, <code>#500</code><code>#999</code> retained and saved with the project, <code>#3000</code><code>#3999</code> system control. Boolean and
logical operators, <code>IF [..] GOTO n</code>, <code>IF [..] THEN &lt;statement&gt;</code>, and <code>WHILE [..] DO m</code> / <code>END m</code> with
a bounded-loop watchdog. Position and tool-offset system variables read back into expressions.</p>
<p><strong>Macro and subprogram calls.</strong> <code>G65</code> one-shot macro call, binding arguments <code>A</code><code>Z</code> onto <code>#1</code><code>#26</code>;
<code>G66</code> / <code>G67</code> modal macro, firing at every positioning block until cancelled; <code>M98</code> / <code>M198</code> / <code>M99</code>.
A callee's blocks are spliced into the program at the call site, so the rest of the run treats them
exactly as if they had been written in the main file.</p>
<p><strong>Not supported.</strong> <code>G10</code> programmable data setting, <code>G50</code> spindle speed clamp, <code>G31</code> skip.</p>
<h2 id="syntec">Syntec</h2>
<p>Syntec runs the ISO core plus the Fanuc-family macro and subprogram vocabulary and polar
interpolation.</p>
<p><strong>Not supported.</strong> Custom <code>G</code> macros defined on the controller, <code>Pr</code> parameter mapping, and
twin-head / twin-turret program syntax.</p>
<h2 id="mazak">Mazak</h2>
<p>Mazak reads EIA/ISO with the Fanuc-family macro and subprogram vocabulary and polar interpolation.</p>
<p><strong>Not supported.</strong> MAZATROL conversational sections, and switching between MAZATROL and EIA/ISO
inside one program. Export the EIA/ISO program from the controller.</p>
<h2 id="siemens-sinumerik">Siemens SINUMERIK</h2>
<p>Real <code>.mpf</code> / <code>.spf</code> programs replay end to end — this is not an ISO subset with a Siemens label on
it.</p>
<p><strong>Modal vocabulary.</strong> <code>SUPA</code> / <code>G153</code> suppress all frames for one block; <code>G70</code> / <code>G71</code> units; the
path-smoothing family (<code>G60x</code> / <code>G64x</code>, <code>FNORM</code> / <code>SOFT</code> / <code>FFWON</code> / <code>COMP*</code> / <code>UPATH</code>, <code>CYCLE832</code>);
<code>MSG()</code> and <code>STOPRE</code>; <code>CR=</code> and <code>TURN=</code> arcs. Tail comments are quote-aware, so a <code>;</code> inside
<code>MSG(&quot;A;B&quot;)</code> does not truncate the block. <code>G74</code> / <code>G75</code> fixed-point return is claimed as a whole
block, so the dummy axis values it carries never mint a rapid to those coordinates and its <code>F</code> never
reaches the modal feedrate.</p>
<p><strong>Tools.</strong> <code>T=&quot;NAME&quot;</code> string tool calls with <code>D</code> cutting-edge offsets, resolved through the <code>$TC_DP</code>
tool table — lengths and radius plus additive wear.</p>
<p><strong>Variables and expressions.</strong> R parameters <code>R0</code><code>R999</code> are held as per-project data, <code>DEF REAL</code> /
<code>DEF INT</code> declarations lower into assignments, and a full expression evaluator means <code>Z=R63+150</code> and
<code>X=SIN(R10)*20</code> drive real motion. <code>$P_UIFR[n,axis,TR]</code> binds both ways to the frame table. Any other
<code>$</code> variable is recorded with an unsupported note rather than silently dropped.</p>
<p><strong>Frames and five-axis.</strong> <code>TRANS</code> / <code>ATRANS</code> / <code>ROT</code> / <code>AROT</code> (with <code>RPL=</code>) compose into the tilt
chain in Sinumerik RPY order; <code>TRAORI</code> is a real RTCP mode, the sibling of ISO <code>G43.4</code>, with
<code>TRAFOOF</code> handing the offset back; <code>CYCLE800</code> is decoded from its MODE bits across all four swivel
modes.</p>
<p><strong>Calls and control flow.</strong> <code>L</code>-prefixed and named subprogram calls, inlined with their <code>P</code> repetition
count; <code>M17</code> / <code>RET</code>; <code>REPEAT</code> over a labelled slice; <code>MCALL CYCLE81</code> / <code>82</code> / <code>83</code> / <code>85</code> mapped onto
the shared canned-cycle machinery; <code>PROC</code> headers and labels. <code>GOTOF</code> / <code>GOTOB</code>, <code>IF</code> / <code>ELSE</code> /
<code>ENDIF</code>, and <code>WHILE</code> / <code>FOR</code> / <code>REPEAT-UNTIL</code> / <code>LOOP</code>. Jumps and loop iterations are capped rather
than hanging the session — over the cap the construct warns and falls through.</p>
<p><strong>Per-word coordinate functions.</strong> <code>AC()</code> / <code>IC()</code> / <code>DC()</code> / <code>ACP()</code> / <code>ACN()</code>, including on <code>I</code> /
<code>J</code> / <code>K</code> circle centres, so <code>G90 C=IC(360/17)</code> is one incremental index inside an absolute program.
<code>ACP()</code> takes the forward window, <code>ACN()</code> the backward one, and <code>DC()</code> the shortest swing.</p>
<p><strong>Coded positions.</strong> <code>CAC</code> / <code>CIC</code> / <code>CDC</code> / <code>CACP</code> / <code>CACN</code> take a 1-based indexing position number
instead of a coordinate, resolved against the machine's own indexing-position tables.</p>
<p><strong>OEM auxiliary M-codes.</strong> The preset declares <code>M12</code> / <code>M13</code> / <code>M22</code> / <code>M23</code> and <code>M330</code> / <code>M331</code> as
note-only, so each occurrence voices <code>DeclaredMCode--UnmodeledEffects</code> rather than an unknown-code
warning. A machine's own table overrides the declaration once the real effects are known.</p>
<p><strong>Recognized, not simulated.</strong> <code>ROTS</code> / <code>AROTS</code>, <code>SCALE</code> / <code>ASCALE</code>, and <code>MIRROR</code> / <code>AMIRROR</code> — each
reported as <code>SiemensFrame--Unsupported</code>.</p>
<p><strong>Not supported.</strong> <code>SETAL</code>.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="controller-heidenhain.html">Heidenhain Support</a> — klartext and Heidenhain DIN/ISO.</li>
<li><a class="xref" href="nc-parsing.html">NC Parsing Engine</a> — the pipeline behind these codes, the
brand-by-brand support matrix in one table, and how a machine's own vocabulary is added without
changing HiNC.</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,132 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>NC Dialects | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="NC Dialects | 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="">
<h1 id="nc-dialects">NC Dialects</h1>
<p>How a controller program becomes motion. A machine's NC is not one language but a family of
dialects that disagree about almost everything except the axis letters, so HiNC parses a program
against the brand it was written for and reports what it could not honour rather than guessing.</p>
<p>Ordered from the engine that reads every dialect to the two reader-facing pages that say what each
brand's vocabulary actually does.</p>
<ul>
<li><a href="nc-parsing.html">NC Parsing Engine</a> — The interpreter pipeline, the brand-by-brand support matrix, and how a machine's own vocabulary is added without changing HiNC</li>
<li><a href="controller-iso.html">ISO / General NC</a> — What Fanuc, Syntec, Mazak and Siemens SINUMERIK code HiNC honours, recognises without acting on, or refuses</li>
<li><a href="controller-heidenhain.html">Heidenhain</a> — Klartext and Heidenhain DIN/ISO: the block format, Q parameters, tilted planes and the cycles that are read</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="../nc-optimization/index.html">NC Optimization</a> — what rewrites the program this engine reads</li>
<li><a href="../../manual/setup/index.html">Setup</a> — the setup tasks these dialects are configured from</li>
<li><a href="../../manual/setup/program-zero-alignment.html">Program Zero Alignment</a> — the setup task that decides which work offset the code in these pages resolves against</li>
<li><a href="../../manual/setup/controller.html">Controller</a> — picking the brand a project reads its programs with, and the tables that brand grows</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,490 @@
<!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 &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="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] --&gt; SEG[ISegmenter]
SEG --&gt; SENT[Sentence stream]
SENT --&gt; INIT[INcInitializer]
INIT --&gt; P[Parsing&lt;br/&gt;text to structure]
P --&gt; E[Evaluation&lt;br/&gt;variables, expressions,&lt;br/&gt;calls, control flow]
E --&gt; L[Logic&lt;br/&gt;modal state, coordinates,&lt;br/&gt;compensation, motion]
L --&gt; PL[PostLogic&lt;br/&gt;modal carry]
PL --&gt; I[Inspection&lt;br/&gt;backfill, unconsumed check,&lt;br/&gt;snapshot]
I --&gt; SEM[INcSemantic]
SEM --&gt; OUT[Machine actions]
DEP[INcDependency list&lt;br/&gt;brand tables, coordinate systems,&lt;br/&gt;tool offsets, kinematics, ...]
DEP -. injected .-&gt; P
DEP -. injected .-&gt; E
DEP -. injected .-&gt; L
DEP -. injected .-&gt; 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">&lt;SoftNcRunner&gt;
&lt;PipelineNcDependencyList&gt;...&lt;/PipelineNcDependencyList&gt;
&lt;Segmenter&gt;...&lt;/Segmenter&gt;
&lt;NcInitializationList&gt;...&lt;/NcInitializationList&gt;
&lt;NcSyntaxList&gt;...&lt;/NcSyntaxList&gt;
&lt;NcSemanticList&gt;...&lt;/NcSemanticList&gt;
&lt;/SoftNcRunner&gt;
</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">{
&quot;IndexNote&quot;: {&quot;Symbol&quot;:&quot;N&quot;,&quot;Number&quot;:162},
&quot;Positioning&quot;: {&quot;Term&quot;:&quot;G90&quot;,&quot;Mode&quot;:&quot;Absolute&quot;},
&quot;Unit&quot;: {&quot;Term&quot;:&quot;G21&quot;,&quot;System&quot;:&quot;Metric&quot;},
&quot;PlaneSelect&quot;: {&quot;Term&quot;:&quot;G17&quot;,&quot;Plane&quot;:&quot;XY&quot;},
&quot;Feedrate&quot;: {&quot;FeedrateValue&quot;:400,&quot;Term&quot;:&quot;G94&quot;,&quot;Unit&quot;:&quot;mm/min&quot;},
&quot;SpindleSpeed&quot;: {&quot;SpindleSpeed_rpm&quot;:20000,&quot;Direction&quot;:&quot;CW&quot;},
&quot;Coolant&quot;: {&quot;IsOn&quot;:true,&quot;Mode&quot;:&quot;Flood&quot;},
&quot;ToolChange&quot;: {&quot;ToolId&quot;:4,&quot;IsChange&quot;:false},
&quot;TiltTransform&quot;: {&quot;Term&quot;:&quot;G68.2&quot;},
&quot;ProgramToMcTransform&quot;: [
{&quot;Source&quot;:&quot;TiltTransform&quot;, &quot;Mat4d&quot;:[ ... ]},
{&quot;Source&quot;:&quot;ToolHeightCompensation&quot;, &quot;Mat4d&quot;:[ ... ]},
{&quot;Source&quot;:&quot;CoordinateOffset&quot;, &quot;Mat4d&quot;:[ ... ]},
{&quot;Source&quot;:&quot;PivotTransform&quot;, &quot;Mat4d&quot;:[ ... ]}
],
&quot;ToolHeightCompensation&quot;: {&quot;Offset_mm&quot;:16,&quot;Term&quot;:&quot;G43&quot;,&quot;OffsetId&quot;:4},
&quot;CoordinateOffset&quot;: {&quot;CoordinateId&quot;:&quot;G54&quot;,&quot;Offset_X&quot;:72.4,&quot;Offset_Y&quot;:-72.4,&quot;Offset_Z&quot;:-116.44},
&quot;ProgramXyz&quot;: {&quot;X&quot;:-14.696,&quot;Y&quot;:-6.42,&quot;Z&quot;:45.638},
&quot;MachineCoordinateState&quot;: {&quot;X&quot;:140.5947,&quot;Y&quot;:-78.8200,&quot;Z&quot;:-124.4559},
&quot;MotionState&quot;: {&quot;Term&quot;:&quot;G01&quot;},
&quot;MotionEvent&quot;: {&quot;Form&quot;:&quot;McLinear&quot;,&quot;IsRapid&quot;:false},
&quot;RadiusCompensation&quot;: {&quot;Term&quot;:&quot;G40&quot;,&quot;OffsetId&quot;:0,&quot;Radius_mm&quot;: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>ProgramToMcTransform</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&lt;IHomeMcConfig&gt;().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 G73G89, 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>bare <code>G05 P</code> HPCC selections (<code>Hpcc--NoOp</code>, <code>Hpcc--HighSpeedCycleIgnored</code>, <code>Hpcc--UnsupportedFunction</code>)</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=&quot;name&quot;</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>LN</code> surface-normal blocks resolved into the rotary axes, <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 912 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>), center-referenced <code>FUNCTION TCPM REFPNT</code> (<code>Orientation-RefPoint--CntNotSimulated</code>), and 3D-ToolComp along the <code>LN</code> surface normal (<code>SurfaceNormal--CompNotSimulated</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>bare <code>G05 P</code> HPCC selections, as Fanuc</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>bare <code>G05 P</code> HPCC selections, as Fanuc</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="scope-and-testing">Scope and testing</h2>
<p>Two limits sit outside the per-brand table and apply to everything in it.</p>
<ul>
<li><strong>Milling only.</strong> Turning and tapping operations are not simulated. A program containing them
parses as far as its milling content allows; the operations themselves are not modelled.</li>
<li><strong>Fanuc syntax is the primary test surface.</strong> All five presets are exercised, but Fanuc carries
the most coverage, and a construct that is unusual in Fanuc but ordinary in another dialect is
the likeliest place to meet an unimplemented case. The three-state table above exists so that
such a case is reported rather than silently mis-read.</li>
</ul>
<p>Full five-axis RTCP is supported across the presets that have it — Fanuc <code>G43.4</code>, Heidenhain
<code>FUNCTION TCPM</code> and <code>M128</code>, Siemens <code>TRAORI</code>.</p>
<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>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="controller-heidenhain.html">Heidenhain Support</a> — the reader-facing page for klartext and Heidenhain DIN/ISO</li>
<li><a class="xref" href="controller-iso.html">General NC Code Support</a> — the reader-facing page for Fanuc, Syntec, Mazak and Siemens SINUMERIK</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,31 @@
<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="nc-parsing.html" name="" title="NC Parsing Engine">NC Parsing Engine</a>
</li>
<li>
<a href="controller-iso.html" name="" title="ISO / General NC">ISO / General NC</a>
</li>
<li>
<a href="controller-heidenhain.html" name="" title="Heidenhain">Heidenhain</a>
</li>
</ul>
</div>
</div>
</div>
</div>
@@ -0,0 +1,2 @@
{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"NC Parsing Engine","href":"nc-parsing.html","topicHref":"nc-parsing.html"},{"name":"ISO / General NC","href":"controller-iso.html","topicHref":"controller-iso.html"},{"name":"Heidenhain","href":"controller-heidenhain.html","topicHref":"controller-heidenhain.html"}]}
Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 KiB

@@ -0,0 +1,199 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Optimized Feed Rate at Corners Is Lower Than Empirically Feasible | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Optimized Feed Rate at Corners Is Lower Than Empirically Feasible | 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="Technique-CornerBehavior">
<h1 id="optimized-feed-rate-at-corners-is-lower-than-empirically-feasible">Optimized Feed Rate at Corners Is Lower Than Empirically Feasible</h1>
<p>See also <a class="xref" href="nc-optimization-principles.html">NC Optimization</a> and the script command <a class="xref" href="../../workflows/nc-optimization.html">Workflow: NC Optimization</a>.</p>
<h2 id="phenomenon">Phenomenon</h2>
<p>During NC feed rate optimization, corners often exhibit significant feed rate reductions — sometimes even lower than what is empirically known to be feasible. This puzzles users: actual machining at corners doesn't require such drastic reductions, so why does the optimization produce these results?</p>
<h2 id="controller-deceleration-at-corners">Controller Deceleration at Corners</h2>
<p>At corners, the controller <strong>automatically decelerates</strong> at high speeds. This is a built-in controller behavior as well as a hardware limitation, designed to ensure the machine can safely and accurately complete direction changes. The controller also provides parameters to adjust this acceleration/deceleration behavior.</p>
<h3 id="relationship-between-buffer-distance-and-speed">Relationship Between Buffer Distance and Speed</h3>
<p>The higher the speed, the longer the required buffer distance. The figure below shows machining conditions for several straight-line paths:</p>
<p><img src="corner-behavior-img/StraightLine-path.png" alt="Straight-line path machining conditions"></p>
<p>The figure labels the spindle speed (S) and feed rate (F) settings for different segments:</p>
<ul>
<li>through1/through2: S500, F200/F100</li>
<li>low1/low2/low3: S1200, F200/F400/F600</li>
<li>high1/high2/high3: S7200, F1200/F2400/F3600</li>
</ul>
<h2 id="why-corners-produce-force-peaks">Why Corners Produce Force Peaks</h2>
<p>Independently of feed-rate optimization, corners themselves generate force peaks that can be 34× the straight-line steady force. The mechanism is geometric:</p>
<ul>
<li><strong>Contact area grows at the corner.</strong> Two cut segments share the corner's swept volume, so during the turn the engaged arc on the cutter exceeds the steady-state arc.</li>
<li><strong>Friction force scales with contact area.</strong> For ductile materials (aluminum, nickel) friction is a large share of the cutting force, so the area increase translates directly into a torque/force peak. Both bending moment and torque feel it.</li>
<li><strong>CAM can amplify the contact area.</strong> Layer-to-layer drift or imperfect corner alignment in CAM-generated NC leaves residual ridges that increase the corner sweep on subsequent layers; the peak then reflects both the geometric corner effect and the CAM-side drift. See <a class="xref" href="../machine-capability/cam-floating-point-drift.html">CAM Floating-Point Drift</a> for the floor-contact mechanism that compounds with this.</li>
<li><strong>Peaks are expected, not artifacts.</strong> As long as the corner geometry is correctly aligned, peaks will appear in simulation; absent them, suspect a misalignment.</li>
</ul>
<p>A peak contained inside a single revolution is itself a partial safety margin — controller corner smoothing and spindle inertia together absorb a single-rev overshoot. Sustained peaks across multiple revolutions are a different story: they drag the spindle below commanded rpm and compound through feed-per-tooth growth. See <a href="nc-optimization-principles.html#tuning-peak-tolerance">Tuning Peak Tolerance</a> for which metrics can be relaxed in response and which cannot.</p>
<h2 id="force-simulation-error-analysis">Force Simulation Error Analysis</h2>
<p>The figure below shows the force simulation error after applying and comparing dynamometer data, with blue-to-red indicating error ratio from low to high:</p>
<p><img src="corner-behavior-img/corner-force-overview.png" alt="Corner force error overview"></p>
<h3 id="error-characteristics">Error Characteristics</h3>
<p>The following characteristics can be observed from the figure:</p>
<ol>
<li><strong>Errors increase closer to tool retraction (corners toward the Z direction)</strong></li>
<li><strong>Higher feed rates result in longer high-error intervals</strong></li>
</ol>
<h3 id="error-sources">Error Sources</h3>
<p>The errors mainly originate from <strong>controller deceleration</strong>. From the per-revolution waveform at the <code>F3600</code> corner in the lower part of the figure:</p>
<table>
<thead>
<tr>
<th>Data Source</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Left (simulated ideal force)</td>
<td>Ideal cutting force calculated based on the set feed rate</td>
</tr>
<tr>
<td>Right (dynamometer data)</td>
<td>Measured cutting force, approximately one-third of the ideal force</td>
</tr>
</tbody>
</table>
<p>The test material was S45C. At that location, <strong>the actual feed should be even lower than one-third of the ideal feed</strong>.</p>
<h2 id="why-is-the-optimized-value-lower-than-the-empirical-value">Why Is the Optimized Value Lower Than the Empirical Value?</h2>
<p>During NC feed rate optimization, corners often show significant feed rate reductions. Beyond the fact that corners typically produce higher cutting forces, the reason the optimized value is lower than the empirically feasible feed rate is:</p>
<blockquote>
<p><strong>The controller has already reduced the feed rate on its own; the optimization simply reveals this.</strong></p>
</blockquote>
<p>In other words, the optimization result reflects the feed rate actually executed by the controller, not the feed rate specified in the NC program. This &ldquo;excessively low&rdquo; optimized value is in fact the real machine behavior.</p>
<h2 id="conclusion">Conclusion</h2>
<p>When you find that the optimized feed rate at corners is unusually low, this is typically not a system error but rather:</p>
<ol>
<li>The controller has already automatically reduced the actual feed rate for safe cornering</li>
<li>The optimization function faithfully reflects this deceleration behavior</li>
<li>Even if you set the empirical value, the controller would still decelerate to a similar value during actual machining</li>
</ol>
<p>Understanding this phenomenon allows you to evaluate optimization results more rationally and adjust cornering strategies or machine parameters as needed.</p>
<h2 id="tracking-the-limiting-physical-quantity-per-step">Tracking the Limiting Physical Quantity per Step</h2>
<p>To find out which physical quantity limits the feed rate at each individual step, refer to the <a href="nc-optimization-principles.html#tracking-physical-quantity-constraints-of-individual-steps">Tracking Physical Quantity Constraints of Individual Steps</a> section in <a class="xref" href="../../workflows/nc-optimization.html">Workflow: NC Optimization</a>.</p>
<h2 id="feed-rate-acceleration-is-not-simulated">Feed Rate Acceleration Is Not Simulated</h2>
<p>HiNC applies the programmed feed rate from the NC directly; it does not model the controller's
acceleration and deceleration. The error that introduces is <strong>in the safe direction</strong>: the real
machine slows into a corner, so the real cutting force there is lower than the simulated one, and
a program that passes in simulation has margin in hand on the machine.</p>
<p>The recovery is quick. A corner feed rate typically returns to the programmed value within about
<strong>five spindle revolutions — roughly 100 ms</strong> — though the exact figure depends on the
controller's own settings. That is short enough that the simulated force is a good description of
everything except the corner itself, and it is the reason the corner is the one place where the
optimizer's answer and the machinist's experience disagree.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../machine-capability/cam-floating-point-drift.html">CAM Floating-Point Drift</a> — how drift in the CAM output shows up at corners</li>
<li><a href="machining-time-estimation.html">Machining Time Estimation</a> — the same omitted dynamics, and what they mean for a quoted cycle time</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,132 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>NC Optimization | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="NC Optimization | 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="">
<h1 id="nc-optimization">NC Optimization</h1>
<p>How HiNC rewrites feed rates against the physical limits of a cut, and how to read a result that
looks wrong. The optimizer is conservative by construction: it lowers feed until every tracked
ratio sits under its ceiling, so an unexpectedly low value is usually a report of a real limit
rather than a fault.</p>
<p>Ordered from the general rule to the case that most often prompts the question.</p>
<ul>
<li><a href="nc-optimization-principles.html">NC Optimization Principles</a> — The optimization objective, what limits each step, velocity smoothing, and the per-metric utilization factors that decide which peaks may be tolerated</li>
<li><a href="corner-behavior.html">Corner Feedrate Behavior</a> — Why the optimized feed at a corner falls below the empirically feasible value, and why that is the controller's own deceleration being reported back</li>
<li><a href="machining-time-estimation.html">Machining Time Estimation</a> — What the quoted cycle times are computed from, why they agree with controller simulators, and why the ratio is sounder than the absolute</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="../milling-physics/index.html">Milling Physics</a> — the per-step criteria the optimizer holds under 100%</li>
<li><a href="../machine-capability/index.html">Machine Capability</a> — the spindle, controller and workstation ceilings the optimizer works against</li>
<li><a href="../scripting/index.html">Scripting</a> — the <code>Opt*</code> settings a script uses to drive the optimizer</li>
<li><a href="../nc-dialects/index.html">NC Dialects</a> — the engine that reads the program before it is rewritten</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,163 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Machining Time Estimation | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Machining Time Estimation | 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="Technique-MachiningTimeEstimation">
<h1 id="machining-time-estimation">Machining Time Estimation</h1>
<p>Every optimization result is quoted as a time — 303 minutes down to 95 — so it matters what that
number is and is not. HiNC's machining time is computed from the <strong>ideal feed rate in the NC or CL
program</strong> together with the <strong>maximum rotary-axis speed limits</strong>. It does not model dynamic
behaviour: no acceleration and deceleration ramps, no look-ahead, no servo lag.</p>
<h2 id="why-it-matches-controller-simulators">Why It Matches Controller Simulators</h2>
<p>That simplification is the same one the controller vendors' own simulators make, which is why the
two agree closely. On a five-axis impeller program:</p>
<table>
<thead>
<tr>
<th>Estimator</th>
<th>Cutting time</th>
</tr>
</thead>
<tbody>
<tr>
<td>Heidenhain simulator</td>
<td>15 h 02 min</td>
</tr>
<tr>
<td>HiNC</td>
<td>15 h 05 min</td>
</tr>
<tr>
<td>Difference</td>
<td>0.39%</td>
</tr>
</tbody>
</table>
<p>Agreeing with the vendor's simulator is a useful check that the program was read correctly. It is
not evidence that either number matches the shop floor.</p>
<h2 id="why-the-shop-floor-differs">Why the Shop Floor Differs</h2>
<p>Real machining time can differ substantially from any of these estimates — the vendor's included —
because the dynamics they all omit are real. Acceleration limits at direction changes, look-ahead
window size, and block processing rate all cost time that no ideal-feed estimate contains. The
same NC on two controllers with different look-ahead settings takes different times.</p>
<p>The consequence for reading an optimization result: <strong>trust the ratio, not the absolute</strong>. Before
and after are computed the same way and omit the same dynamics, so a reported reduction from 303
to 95 minutes is a sound statement about what the optimization achieved, even where neither number
will be observed on the machine.</p>
<p>Feed rate acceleration is also the reason an optimized corner feed is conservative rather than
wrong — see <a href="corner-behavior.html">Optimized Feed Rate at Corners</a>.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="corner-behavior.html">Optimized Feed Rate at Corners</a> — the same missing dynamics, seen from the corner where they matter most</li>
<li><a href="nc-optimization-principles.html">NC Optimization Principles</a> — what the optimizer changes to produce the reduction this page quantifies</li>
<li><a class="xref" href="../validation/optimization-results.html">Optimization Results</a> — the tables whose ratios this page says to trust</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,232 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>NC Optimization | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="NC Optimization | 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="NcOptimization">
<h1 id="nc-optimization">NC Optimization</h1>
<p>Also refer to the script commands section <a class="xref" href="../../workflows/nc-optimization.html">Workflow: NC Optimization</a>.</p>
<h2 id="optimization-objective">Optimization Objective</h2>
<p>Optimization aims to make the physical quantities during machining as close to the target values as possible.</p>
<p>Since the optimization uses a conservative feed rate strategy, the physical quantities in the optimized NC code will be as close to <strong>equal to or less than</strong> the target values as possible.</p>
<h3 id="factors-determining-the-optimized-feed-rate">Factors Determining the Optimized Feed Rate</h3>
<p>The optimized feed rate is determined by:</p>
<ol>
<li><strong>Physical quantity constraints of individual <a class="xref" href="../scripting/step.html">steps</a></strong>: Feed rate limits calculated for each step based on target force, yielding stress, spindle torque, etc. For detailed descriptions of indicators such as yielding stress ratio and spindle torque ratio, refer to &quot;<a class="xref" href="../milling-physics/machinability.html">Evaluating Process Machinability</a>&quot;.</li>
<li><strong>Inter-step smoothing</strong>: Interactions such as acceleration/deceleration limits and extended distances.</li>
</ol>
<h2 id="differences-in-simulation-results-after-optimization">Differences in Simulation Results After Optimization</h2>
<p>Simulation with modified feed rates produces different interpolation points than before, resulting in:</p>
<ol>
<li>Different simulation mesh errors</li>
<li>Surface morphology changes at the surface roughness level</li>
</ol>
<p>Therefore, the simulated physical quantities after optimization may not always be equal to or below the target values — they may also be slightly above.</p>
<p>The influence of interpolation point density on surface morphology is greater at rounded corners than on straight lines, so this effect may be more pronounced at corners.</p>
<div class="TIP">
<h5>Tip</h5>
<p>For abnormally low optimized feed rates at corners, refer to <a class="xref" href="corner-behavior.html">Corner Feed Rate Optimization</a>.</p>
</div>
<h2 id="velocity-smoothing">Velocity Smoothing</h2>
<p>The smoothing range terminates at macro commands or line commands with unresolvable paths.</p>
<p><em>Velocity smoothing</em> applies acceleration/deceleration limits based on the path length traversed by the current line command.
Therefore, <em>velocity smoothing</em> is effective for <em>re-interpolatable</em> regions;
however, for non-re-interpolatable regions, although acceleration/deceleration limits still apply, the excessively long path length of a single line may render them impractical in actual use.</p>
<h2 id="impact-of-geometric-errors">Impact of Geometric Errors</h2>
<p>Current NC optimization is based on an ideal geometric model. If the workpiece is a casting or has installation errors, a conservatively larger workpiece geometry should be configured in the system to prevent the system from misidentifying cutting regions as non-cutting regions, which could cause tool crashes.</p>
<h2 id="tool-breakage-solutions">Tool Breakage Solutions</h2>
<p>Modify the toolpath to reduce cutting width/depth, or use HiNC's optimization feature to adjust feed rates, bringing the <strong>yielding stress ratio</strong>, <strong>max spindle torque ratio</strong>, and <strong>max spindle power ratio</strong> below 100%.</p>
<p>For detailed descriptions of these indicators and tool breakage criteria, refer to &quot;<a class="xref" href="../milling-physics/machinability.html">Evaluating Process Machinability</a>&quot;.</p>
<h2 id="tuning-peak-tolerance">Tuning Peak Tolerance</h2>
<p>Optimization defaults treat the 100 % line on every ratio as a hard ceiling. In practice some metrics tolerate routine excursions and others don't. The per-metric <code>Opt*UtilizationFactor</code> levers let the optimizer accept higher peaks where physically safe.</p>
<table>
<thead>
<tr>
<th>Metric</th>
<th>Factor (API)</th>
<th>When to raise</th>
</tr>
</thead>
<tbody>
<tr>
<td>Yielding stress</td>
<td><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_OptYieldingUtilizationFactor">OptYieldingUtilizationFactor</a></td>
<td><strong>Per-instant.</strong> Safe to raise. If 150 % is routinely tolerated without breakage, set <code>1.5</code>. Controller corner smoothing and spindle inertia absorb a single-revolution overshoot.</td>
</tr>
<tr>
<td>Spindle torque</td>
<td><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_OptSpindleTorqueUtilizationFactor">OptSpindleTorqueUtilizationFactor</a></td>
<td><strong>Cumulative.</strong> Keep at 1. Sustained excursions stall the spindle: feed continues, rpm drops, feed-per-tooth grows, forces spike further.</td>
</tr>
<tr>
<td>Spindle power</td>
<td><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_OptSpindlePowerUtilizationFactor">OptSpindlePowerUtilizationFactor</a></td>
<td><strong>Cumulative.</strong> Keep at 1. Same reason as torque.</td>
</tr>
<tr>
<td>Thermal yield</td>
<td><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_OptThermalYieldUtilizationFactor">OptThermalYieldUtilizationFactor</a></td>
<td><strong>Long-term.</strong> Can be raised modestly if the calibrated tool material is more thermally tolerant than the conservative defaults — see <a href="../milling-physics/machinability.html#thermal-plastic-deformation-of-cutting-edge">Thermal Plastic Deformation of Cutting Edge</a>.</td>
</tr>
</tbody>
</table>
<p>Rule of thumb: relax per-instant per-step metrics based on observed stable extremes; never relax cumulative metrics.</p>
<p>For a complementary feed-rate floor lever — useful when the NC cannot be modified to remove single-revolution peaks — see <a class="xref" href="../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MinFeedPerTooth_mm">MinFeedPerTooth_mm</a> (API) and <a href="../machine-capability/cam-floating-point-drift.html#when-the-nc-cannot-be-modified">When the NC Cannot Be Modified</a>.</p>
<h2 id="thermal-edge-chipping-solutions">Thermal Edge Chipping Solutions</h2>
<p>After addressing tool breakage issues, reduce the spindle speed to allow sufficient time for the cutting edge to dissipate heat.</p>
<p>Note that whether the coolant is properly directed at the cutting edge has a significant impact.</p>
<h2 id="tracking-physical-quantity-constraints-of-individual-steps">Tracking Physical Quantity Constraints of Individual Steps</h2>
<p>Every optimization already writes the per-step log — one <code>.IndependentStepAdjustment.log</code> beside each
optimized NC file that had steps to solve — so nothing has to be switched on to obtain it. What that
log cannot answer on its own is which physical quantity limited an individual step, because
smoothing carries neighbouring steps into the feed it records. Disable the smoothing settings before
the run:</p>
<pre><code class="lang-csharp">OptMaxAcceleration_mmds2 = double.PositiveInfinity;
OptFeedrateAssignmentRatio = 0;
OptExtendedPreDistance_mm = 0;
OptExtendedPostDistance_mm = 0;
</code></pre>
<p>After running the optimization, inspect the <code>.IndependentStepAdjustment.log</code> file to view the independent optimization calculation results for each step and identify which physical quantity limited the feed rate.</p>
<p>For detailed field descriptions of the log file, refer to the <a href="../../workflows/nc-optimization.html#optimization-logs">Optimization Logs</a> section in the <a class="xref" href="../../workflows/nc-optimization.html">Workflow: NC Optimization</a> workflow.</p>
<h2 id="when-a-step-cannot-be-solved">When a Step Cannot Be Solved</h2>
<p>A step whose solve fails does not stop the optimization. That step keeps the feed rate the simulation ran it at instead of a solved one, and every other step is optimized as usual, so a completed optimization can contain steps no physical criterion ever set the feed of. Three records name them:</p>
<ul>
<li>an <strong>Error</strong> message per failed step, carrying the step index, the NC file and line, and the underlying exception — the first twenty failures of a run, after which only the summary is kept;</li>
<li>one <strong>Warning</strong> at the end of the pass, giving the number of failed steps and the first of them;</li>
<li>a <code>StepFailed</code> row in that file's <code>.IndependentStepAdjustment.log</code>, in place of the step's usual per-criterion row.</li>
</ul>
<p>What such a step does not keep is that feed all the way to the file. The stages after the solve treat
it like any other step, constraining it against the extended segment and the acceleration limit, and
where the step shares one feed word with the rest of its line, the value written is the lowest that
line allowed. So the output NC marks nothing and the feed in it names nothing either: a failed step
is indistinguishable in the file both from a step the optimizer had no reason to change and from one
it had every reason to slow down. The messages are the only place that difference is stated, so read
them before sending an optimized program to a machine.</p>
<p>Failures also do not shorten the pass. The per-step solve closes with exactly one row of its own in
every run — <strong>Optimization Feedrate built.</strong> when it reached the end of the steps, <strong>Optimization
Feed Process canceled.</strong> when Stop caught it first — and that row follows the failure summary rather
than replacing it. The run then carries on through the stages after the solve. A pass that reported
failures still produces optimized files, and neither of those two rows having appeared yet means the
solve is still working, not that it gave up.</p>
<p>A run ended with <strong>Stop</strong> leaves the per-step log short. Its buffered tail is dropped rather than
flushed, so the lines written since the last batch — batches go out at most once a second — never
reach the file, and neither does any step line still held back waiting for a lower step index the
stopped run never solved. A log that ends before the last step the run reached is the stop showing,
not a gap in what the optimizer reports.</p>
<h3 id="a-nan-feed-boundary-is-refused-by-name">A NaN Feed Boundary Is Refused by Name</h3>
<p>Each step's feed-per-tooth boundary is composed from the option's feed-rate limits and feed-per-tooth limits, the step's tooth-arc duration, and the cutter's own optimization limits. A boundary that comes out <code>NaN</code> is refused before the solver runs, and the message names the values it was given — <a class="xref" href="../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MinFeedrate_mmdmin">MinFeedrate_mmdmin</a>, <a class="xref" href="../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MaxFeedrate_mmdmin">MaxFeedrate_mmdmin</a>, <a class="xref" href="../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MinFeedPerTooth_mm">MinFeedPerTooth_mm</a>, <a class="xref" href="../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_MaxFeedPerTooth_mm">MaxFeedPerTooth_mm</a> and the step's tooth-arc duration — because a <code>NaN</code> trial feed otherwise reaches the physics and is reported far from its cause. The usual source is a script writing <code>NaN</code> into the per-step option from a step event; see <a class="xref" href="../scripting/script-command.html">Script Commands</a>.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../milling-physics/cutter-adjustment-levers.html">Cutter Adjustment Levers</a> — what to change on the cutter when feed optimization runs out of room</li>
<li><a class="xref" href="../scripting/script-command.html">Script Commands</a> — the script side of the per-step options, including the one that fails a step</li>
<li><a href="machining-time-estimation.html">Machining Time Estimation</a> — what the cycle-time reduction this produces is measured against</li>
<li><a class="xref" href="../validation/optimization-results.html">Optimization Results</a> — measured before-and-after on a hardened mould and a five-axis titanium job</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,31 @@
<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="nc-optimization-principles.html" name="" title="NC Optimization Principles">NC Optimization Principles</a>
</li>
<li>
<a href="corner-behavior.html" name="" title="Corner Feedrate Behavior">Corner Feedrate Behavior</a>
</li>
<li>
<a href="machining-time-estimation.html" name="" title="Machining Time Estimation">Machining Time Estimation</a>
</li>
</ul>
</div>
</div>
</div>
</div>
@@ -0,0 +1,2 @@
{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"NC Optimization Principles","href":"nc-optimization-principles.html","topicHref":"nc-optimization-principles.html"},{"name":"Corner Feedrate Behavior","href":"corner-behavior.html","topicHref":"corner-behavior.html"},{"name":"Machining Time Estimation","href":"machining-time-estimation.html","topicHref":"machining-time-estimation.html"}]}
@@ -0,0 +1,175 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Color Guide System | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Color Guide System | 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="Technique-ColorGuide">
<h1 id="color-guide-system">Color Guide System</h1>
<p>The Color Guide System allows you to assign colors and rendering priorities to visual elements based on machining steps or data states.</p>
<h2 id="overview">Overview</h2>
<p>The <a class="xref" href="../../api/Hi.Coloring.IColorGuide.html">IColorGuide</a> interface defines the core functionality for color mapping, allowing different colors and rendering priorities to be returned based on various steps or states. This system is particularly suitable for scenarios requiring visual encoding based on data states, such as CNC machining path visualization.</p>
<h2 id="core-interface">Core Interface</h2>
<h3 id="icolorguide-interface">IColorGuide Interface</h3>
<p><a class="xref" href="../../api/Hi.Coloring.IColorGuide.html">IColorGuide</a> is the core interface of the Color Guide System, inheriting from <a class="xref" href="../../api/Hi.Common.XmlUtils.IMakeXmlSource.html">IMakeXmlSource</a> and <a class="xref" href="../../api/Hi.Coloring.IGetColorGuide.html">IGetColorGuide</a>.</p>
<h4 id="methods">Methods</h4>
<table>
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="../../api/Hi.Coloring.IColorGuide.html#Hi_Coloring_IColorGuide_GetRgb_">GetRgb</a></td>
<td>Returns RGB color value based on the step object</td>
</tr>
<tr>
<td><a class="xref" href="../../api/Hi.Coloring.IColorGuide.html#Hi_Coloring_IColorGuide_GetRgbWithPriority_">GetRgbWithPriority</a></td>
<td>Returns RGB color and rendering priority</td>
</tr>
</tbody>
</table>
<h4 id="priority-explanation">Priority Explanation</h4>
<p>The <code>attachmentPriority</code> parameter controls the overlay priority during rendering:</p>
<ul>
<li><strong>Higher values take priority</strong>: Larger priority values are displayed first</li>
<li><strong>Graph scaling for pixel consolidation</strong>: When multiple machining steps are rendered within the same pixel, higher priority colors take precedence</li>
</ul>
<h4 id="effects-on-rendering-systems">Effects on Rendering Systems</h4>
<p><strong>In CubeTree (<a class="xref" href="../../api/Hi.Cbtr.CubeTree.html">CubeTree</a>):</strong></p>
<ul>
<li>Color priorities determine which machining state is displayed when multiple operations overlap in 3D space</li>
<li>Higher priority colors (like collision detection) will override lower priority colors (like normal cutting)</li>
</ul>
<h2 id="application-scenarios">Application Scenarios</h2>
<p>The Color Guide System is suitable for the following scenarios:</p>
<ol>
<li><strong>CNC Machining Visualization</strong>: Display different path colors based on machining states</li>
<li><strong>Data State Encoding</strong>: Convert numerical states to visual color representations</li>
<li><strong>Priority-based Graph Scaling</strong>: When zooming out or viewing dense data, higher priority colors (critical states) remain visible while lower priority colors may be consolidated</li>
<li><strong>Multi-resolution Rendering</strong>: Critical machining issues (collisions, safety violations) are always displayed regardless of zoom level or data density</li>
</ol>
<h2 id="registering-color-guide-in-project">Registering Color Guide in Project</h2>
<p>To make the Color Guide effective in a project, implement the <a class="xref" href="../../api/Hi.Coloring.IColorGuide.html">IColorGuide</a> interface and register it in the project's color guide dictionary.</p>
<h2 id="xml-serialization">XML Serialization</h2>
<p>See <a class="xref" href="../api-foundations/xml-io.html">About XML IO</a> for details on XML serialization implementation.</p>
<h2 id="wpf-application-source-and-sample-code-path">WPF Application Source And Sample Code Path</h2>
<ul>
<li>HiMech/Coloring/IColorGuide</li>
<li>HiNC-2025-win-desktop/Demo/DemoColorGuide</li>
</ul>
<p>See <a class="xref" href="../../anatomy/index.html">HiNC App Anatomy</a> for git repository links.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="drawing.html">Drawing</a> — the rendering unit whose colour and priority this system decides</li>
<li><a class="xref" href="../api-foundations/xml-io.html">About XML IO</a> — how a colour guide is serialized with its project</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,905 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Building Your Own Rendering Canvas | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Building Your Own Rendering Canvas | 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="Technique-CustomRenderingCanvas">
<h1 id="building-your-own-rendering-canvas">Building Your Own Rendering Canvas</h1>
<p>This guide provides detailed implementation information for creating your own <code>RenderingCanvas</code> using the <a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a>. By understanding these implementation details, you can customize the rendering component for specific application needs or create implementations for other UI frameworks.</p>
<div class="NOTE">
<h5>Note</h5>
<p><strong>For Windows Applications</strong>: If you are developing for Windows systems, it is recommended to directly use the existing <code>RenderingCanvas</code> implementations in the <code>Hi.WinForm</code> or <code>Hi.WpfPlus</code> packages, rather than creating your own. These implementations are fully tested, optimized, and maintained.</p>
<p>The implementation details provided in this document are primarily for educational purposes or for developers who need to port RenderingCanvas to other platforms/frameworks.</p>
</div>
<h2 id="basic-dispengine-usage">Basic DispEngine Usage</h2>
<p>The <a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a> is designed to display objects that implement the <a class="xref" href="../../api/Hi.Disp.IDisplayee.html">IDisplayee</a> interface. This is the fundamental purpose of DispEngine - to render displayable objects. Assign <a class="xref" href="../../api/Hi.Disp.IDisplayee.html">IDisplayee</a> to <a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a>.<a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_Displayee">Displayee</a>.</p>
<h2 id="core-implementation-pattern">Core Implementation Pattern</h2>
<p>When implementing a custom <code>RenderingCanvas</code> for a UI platform, follow these key steps:</p>
<ol>
<li><strong>Initialize UI Component</strong> - Set up the UI control properties and event handling</li>
<li><strong>Configure DispEngine</strong> - Create and properly initialize the <a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a> instance</li>
<li><strong>Set Up Rendering Pipeline</strong> - Implement buffer swapping mechanism for visualization</li>
<li><strong>Handle User Input</strong> - Map platform-specific input events to DispEngine methods</li>
<li><strong>Manage Component Lifecycle</strong> - Ensure proper resource management and cleanup</li>
</ol>
<p>Let's examine the actual implementations in WinForm and WPF frameworks to understand these patterns in practice.</p>
<h2 id="winform-implementation-details">WinForm Implementation Details</h2>
<p>The WinForm implementation in <code>Hi.WinForm</code> combines Windows Forms controls with the <a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a> rendering system.</p>
<h3 id="core-properties-and-fields">Core Properties and Fields</h3>
<p>Here are the essential properties and fields defined in the WinForm implementation:</p>
<pre><code class="lang-csharp" name="RenderingCanvas">/// &lt;summary&gt;
/// &lt;see cref=&quot;DispEngine&quot;/&gt;.
/// &lt;/summary&gt;
public DispEngine DispEngine { get; }
// Constants and structures for WM_TOUCH
private const int WM_TOUCH = 0x0240;
private const int TOUCHEVENTF_MOVE = 0x0001;
private const int TOUCHEVENTF_DOWN = 0x0002;
private const int TOUCHEVENTF_UP = 0x0004;
[StructLayout(LayoutKind.Sequential)]
private struct TOUCHINPUT
{
public int x;
public int y;
public IntPtr hSource;
public int dwID;
public int dwFlags;
public int dwMask;
public int dwTime;
public IntPtr dwExtraInfo;
public int cxContact;
public int cyContact;
}
[DllImport(&quot;user32.dll&quot;)]
private static extern bool RegisterTouchWindow(IntPtr hWnd, uint ulFlags);
[DllImport(&quot;user32.dll&quot;)]
private static extern bool GetTouchInputInfo(IntPtr hTouchInput, int cInputs, [In, Out] TOUCHINPUT[] pInputs, int cbSize);
[DllImport(&quot;user32.dll&quot;)]
private static extern void CloseTouchInputHandle(IntPtr lParam);
</code></pre><h3 id="initialization">Initialization</h3>
<p>The initialization code sets up event handlers and creates the DispEngine:</p>
<pre><code class="lang-csharp" name="RenderingCanvas">/// &lt;summary&gt;
/// Ctor.
/// &lt;/summary&gt;
/// &lt;param name=&quot;displayees&quot;&gt;displayees&lt;/param&gt;
public unsafe RenderingCanvas(params IDisplayee[] displayees)
{
// Configure the control's visual styles
SetStyle(ControlStyles.Selectable, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
SetStyle(ControlStyles.ContainerControl, false);
SetStyle(ControlStyles.ResizeRedraw, false);
DoubleBuffered = true;
InitializeComponent();
Dock = DockStyle.Fill;
// Connect event handlers for user input and window events
this.Resize += RenderingCanvas_Resize;
this.VisibleChanged += RenderingCanvas_VisibleChanged;
this.MouseMove += RenderingCanvas_MouseMove;
this.MouseDown += RenderingCanvas_MouseDown;
this.MouseUp += RenderingCanvas_MouseUp;
this.MouseWheel += RenderingCanvas_MouseWheel;
this.KeyDown += RenderingCanvas_KeyDown;
this.KeyUp += RenderingCanvas_KeyUp;
// Add focus event handler
this.GotFocus += RenderingCanvas_GotFocus;
this.HandleCreated += OnHandleCreated;
// Enable touch input and click events for the control
this.SetStyle(ControlStyles.StandardClick, true);
this.SetStyle(ControlStyles.StandardDoubleClick, true);
this.TabStop = true;
// Initialize the DispEngine with provided displayees
DispEngine = new DispEngine(displayees);
DispEngine.BackgroundColor = new Vec3d(0.1, 0.1, 0.5);
DispEngine.BackgroundOpacity = 0.1;
DispEngine.SetViewToHomeView();
DispEngine.ImageRequestAfterBufferSwapped += DispEngine_ImageRequestAfterBufferSwapped;
// Set initial size and start the rendering engine
this.Size = new System.Drawing.Size(500, 300);
DispEngine.Start(this.ClientSize.Width, this.ClientSize.Height);
}
</code></pre><h3 id="rendering-pipeline">Rendering Pipeline</h3>
<p>The rendering pipeline processes images from DispEngine and displays them:</p>
<pre><code class="lang-csharp" name="RenderingCanvas">private unsafe void DispEngine_ImageRequestAfterBufferSwapped(byte* bgra_unsignedbyte_pixels, int w, int h)
{
// Create a bitmap from the raw pixel data provided by DispEngine
Bitmap bitmap;
bitmap = new Bitmap(new Bitmap(w, h, w * 4,
PixelFormat.Format32bppArgb, new IntPtr(bgra_unsignedbyte_pixels)));
// Update the background image and dispose the previous one
Image pre = this.BackgroundImage;
this.BackgroundImage = bitmap;
pre?.Dispose();
}
</code></pre><h3 id="input-handling">Input Handling</h3>
<h4 id="windows-message-handling-for-touch">Windows Message Handling for Touch</h4>
<p>WinForm implementation intercepts Windows touch messages and forwards them to DispEngine:</p>
<pre><code class="lang-csharp" name="RenderingCanvas">/// &lt;summary&gt;
/// Processes Windows messages, handling touch input and forwarding other messages to the base class.
/// &lt;/summary&gt;
/// &lt;param name=&quot;m&quot;&gt;The Windows message to process.&lt;/param&gt;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_TOUCH)
{
HandleTouchInput(m.WParam, m.LParam);
return;
}
base.WndProc(ref m);
}
private void OnHandleCreated(object sender, EventArgs e)
{
// Register window to receive touch messages
RegisterTouchWindow(this.Handle, 0);
}
private void HandleTouchInput(IntPtr wParam, IntPtr lParam)
{
int inputCount = wParam.ToInt32();
TOUCHINPUT[] inputs = new TOUCHINPUT[inputCount];
if (!GetTouchInputInfo(lParam, inputCount, inputs, Marshal.SizeOf(typeof(TOUCHINPUT))))
return;
try
{
for (int i = 0; i &lt; inputCount; i++)
{
TOUCHINPUT ti = inputs[i];
int touchId = ti.dwID;
// Convert touch coordinates to client coordinates
Point touchPoint = PointToClient(new Point(ti.x / 100, ti.y / 100));
if ((ti.dwFlags &amp; TOUCHEVENTF_DOWN) != 0)
{
// Touch down event
DispEngine.TouchDown(touchId, touchPoint.X, touchPoint.Y);
this.Focus();
}
else if ((ti.dwFlags &amp; TOUCHEVENTF_MOVE) != 0)
{
// Touch move event
DispEngine.TouchMove(touchId, touchPoint.X, touchPoint.Y);
}
else if ((ti.dwFlags &amp; TOUCHEVENTF_UP) != 0)
{
// Touch up event
DispEngine.TouchUp(touchId);
}
}
}
finally
{
CloseTouchInputHandle(lParam);
}
}
</code></pre>
<p>The key aspect is mapping Windows touch events to DispEngine's touch API:</p>
<pre><code class="lang-csharp">// Inside HandleTouchInput method
if ((ti.dwFlags &amp; TOUCHEVENTF_DOWN) != 0)
{
// Touch down event - delegate to DispEngine
DispEngine.TouchDown(touchId, touchPoint.X, touchPoint.Y);
this.Focus();
}
else if ((ti.dwFlags &amp; TOUCHEVENTF_MOVE) != 0)
{
// Touch move event - delegate to DispEngine
DispEngine.TouchMove(touchId, touchPoint.X, touchPoint.Y);
}
else if ((ti.dwFlags &amp; TOUCHEVENTF_UP) != 0)
{
// Touch up event - delegate to DispEngine
DispEngine.TouchUp(touchId);
}
</code></pre>
<h4 id="mouse-events">Mouse Events</h4>
<pre><code class="lang-csharp" name="RenderingCanvas">private void RenderingCanvas_MouseMove(object sender, MouseEventArgs e)
{
// Update mouse position and handle drag transforms
DispEngine.MouseMove(e.Location.X, e.Location.Y);
DispEngine.MouseDragTransform(e.Location.X, e.Location.Y,
new mouse_button_table__transform_view_by_mouse_drag_t()
{
LEFT_BUTTON = (long)MouseButtons.Left,
RIGHT_BUTTON = (long)MouseButtons.Right
});
}
private void RenderingCanvas_MouseDown(object sender, MouseEventArgs e)
{
// Handle mouse button press
DispEngine.MouseButtonDown((long)e.Button);
this.Focus();
}
private void RenderingCanvas_MouseUp(object sender, MouseEventArgs e)
{
// Handle mouse button release
DispEngine.MouseButtonUp((long)e.Button);
}
private void RenderingCanvas_MouseWheel(object sender, MouseEventArgs e)
{
// Handle mouse wheel for zoom operations
DispEngine.MouseWheel(0, e.Delta / 120);
DispEngine.MouseWheelTransform(0, e.Delta / 120);
}
</code></pre><h4 id="keyboard-events">Keyboard Events</h4>
<pre><code class="lang-csharp" name="RenderingCanvas">/// &lt;inheritdoc/&gt;
protected override bool IsInputKey(Keys keyData)
{
//since in default, arrow does not trigger key event(keyDown and keyUp).
return true;
}
/// &lt;summary&gt;
/// Convert WinForms Keys to W3C KeyboardEvent.key string.
/// &lt;/summary&gt;
static string WinFormsKeyToW3C(Keys key) =&gt; (key &amp; Keys.KeyCode) switch
{
Keys.Home =&gt; &quot;Home&quot;,
Keys.End =&gt; &quot;End&quot;,
Keys.PageUp =&gt; &quot;PageUp&quot;,
Keys.PageDown =&gt; &quot;PageDown&quot;,
Keys.Left =&gt; &quot;ArrowLeft&quot;,
Keys.Right =&gt; &quot;ArrowRight&quot;,
Keys.Up =&gt; &quot;ArrowUp&quot;,
Keys.Down =&gt; &quot;ArrowDown&quot;,
Keys.LShiftKey or Keys.RShiftKey or Keys.ShiftKey =&gt; &quot;Shift&quot;,
Keys.LControlKey or Keys.RControlKey or Keys.ControlKey =&gt; &quot;Control&quot;,
Keys.LMenu or Keys.RMenu or Keys.Menu =&gt; &quot;Alt&quot;,
Keys.Return =&gt; &quot;Enter&quot;,
Keys.Escape =&gt; &quot;Escape&quot;,
Keys.Back =&gt; &quot;Backspace&quot;,
Keys.Tab =&gt; &quot;Tab&quot;,
Keys.Delete =&gt; &quot;Delete&quot;,
Keys.Insert =&gt; &quot;Insert&quot;,
Keys.Space =&gt; &quot; &quot;,
Keys.F1 =&gt; &quot;F1&quot;,
Keys.F2 =&gt; &quot;F2&quot;,
Keys.F3 =&gt; &quot;F3&quot;,
Keys.F4 =&gt; &quot;F4&quot;,
Keys.F5 =&gt; &quot;F5&quot;,
Keys.F6 =&gt; &quot;F6&quot;,
Keys.F7 =&gt; &quot;F7&quot;,
Keys.F8 =&gt; &quot;F8&quot;,
Keys.F9 =&gt; &quot;F9&quot;,
Keys.F10 =&gt; &quot;F10&quot;,
Keys.F11 =&gt; &quot;F11&quot;,
Keys.F12 =&gt; &quot;F12&quot;,
&gt;= Keys.A and &lt;= Keys.Z =&gt; ((char)('a' + ((key &amp; Keys.KeyCode) - Keys.A))).ToString(),
&gt;= Keys.D0 and &lt;= Keys.D9 =&gt; ((char)('0' + ((key &amp; Keys.KeyCode) - Keys.D0))).ToString(),
_ =&gt; &quot;Unidentified&quot;
};
private void RenderingCanvas_KeyDown(object sender, KeyEventArgs e)
{
Focus();
string key = WinFormsKeyToW3C(e.KeyData);
DispEngine.KeyDown(key);
DispEngine.KeyDownTransform(key, new key_table__transform_view_by_key_pressing_t()
{
HOME = &quot;Home&quot;,
PAGE_UP = &quot;PageUp&quot;,
PAGE_DOWN = &quot;PageDown&quot;,
F1 = &quot;F1&quot;,
F2 = &quot;F2&quot;,
F3 = &quot;F3&quot;,
F4 = &quot;F4&quot;,
SHIFT = &quot;Shift&quot;,
ARROW_LEFT = &quot;ArrowLeft&quot;,
ARROW_RIGHT = &quot;ArrowRight&quot;,
ARROW_DOWN = &quot;ArrowDown&quot;,
ARROW_UP = &quot;ArrowUp&quot;
});
}
private void RenderingCanvas_KeyUp(object sender, KeyEventArgs e)
{
DispEngine.KeyUp(WinFormsKeyToW3C(e.KeyData));
}
</code></pre><h3 id="lifecycle-management">Lifecycle Management</h3>
<p>Window event handling ensures proper state management:</p>
<pre><code class="lang-csharp" name="RenderingCanvas">private void RenderingCanvas_Resize(object sender, EventArgs e)
{
// Notify DispEngine of size changes
DispEngine.Resize(this.ClientSize.Width, this.ClientSize.Height);
}
private void RenderingCanvas_VisibleChanged(object sender, EventArgs e)
{
// Update visibility state in DispEngine
DispEngine.IsVisible = this.Visible;
}
</code></pre><h3 id="resource-cleanup">Resource Cleanup</h3>
<pre><code class="lang-csharp" name="RenderingCanvas">/// &lt;summary&gt;
/// Clean up any resources being used.
/// &lt;/summary&gt;
/// &lt;param name=&quot;disposing&quot;&gt;true if managed resources should be disposed; otherwise, false.&lt;/param&gt;
protected override void Dispose(bool disposing)
{
if (disposing &amp;&amp; (components != null))
{
// Dispose the DispEngine to free resources
DispEngine.Dispose();
components.Dispose();
}
base.Dispose(disposing);
}
</code></pre><h2 id="wpf-implementation-details">WPF Implementation Details</h2>
<p>The WPF implementation uses WPF-specific controls and mechanisms but follows the same core pattern.</p>
<h3 id="core-properties">Core Properties</h3>
<pre><code class="lang-csharp" name="RenderingCanvas">/// &lt;summary&gt;
/// The DispEngine instance that handles rendering and user interactions
/// &lt;/summary&gt;
public DispEngine DispEngine { get; } = new DispEngine();
/// &lt;summary&gt;
/// Internal container for rendering content
/// &lt;/summary&gt;
private UserControl DisplayerPane { get; }
/// &lt;summary&gt;
/// Dictionary to store touch point information
/// &lt;/summary&gt;
private Dictionary&lt;int, Point&gt; TouchingPointsMap { get; } = new Dictionary&lt;int, Point&gt;();
/// &lt;summary&gt;
/// Dictionary to store previous positions of touch points
/// &lt;/summary&gt;
private Dictionary&lt;int, Point&gt; PreviousTouchingPointsMap { get; } = new Dictionary&lt;int, Point&gt;();
</code></pre><h3 id="initialization-1">Initialization</h3>
<pre><code class="lang-csharp" name="RenderingCanvas">/// &lt;summary&gt;
/// Initializes a new instance of the RenderingCanvas
/// &lt;/summary&gt;
public RenderingCanvas()
{
DispEngine.BackgroundColor = new Vec3d(0.1, 0.1, 0.5);
DispEngine.BackgroundOpacity = 0.1;
// Configure the main control properties
HorizontalAlignment = HorizontalAlignment.Stretch;
VerticalAlignment = VerticalAlignment.Stretch;
Focusable = true;
KeyboardNavigation.SetDirectionalNavigation(this, KeyboardNavigationMode.Cycle);
DataContextChanged += CanvasDataContextChanged;
// Create and configure the display pane
DisplayerPane = new UserControl();
DisplayerPane.HorizontalAlignment = HorizontalAlignment.Stretch;
DisplayerPane.VerticalAlignment = VerticalAlignment.Stretch;
DisplayerPane.Focusable = true;
DisplayerPane.IsTabStop = true;
// Connect event handlers for user input and window events
DisplayerPane.SizeChanged += RenderingCanvas_SizeChanged;
DisplayerPane.MouseMove += RenderingCanvas_MouseMove;
DisplayerPane.MouseDown += RenderingCanvas_MouseDown;
DisplayerPane.MouseUp += RenderingCanvas_MouseUp;
DisplayerPane.MouseWheel += RenderingCanvas_MouseWheel;
DisplayerPane.KeyDown += RenderingCanvas_KeyDown;
DisplayerPane.KeyUp += RenderingCanvas_KeyUp;
DisplayerPane.Loaded += RenderingCanvas_Loaded;
DisplayerPane.Unloaded += RenderingCanvas_Unloaded;
DisplayerPane.IsVisibleChanged += DisplayerPane_IsVisibleChanged;
// Add touch event handlers
DisplayerPane.TouchDown += RenderingCanvas_TouchDown;
DisplayerPane.TouchMove += RenderingCanvas_TouchMove;
DisplayerPane.TouchUp += RenderingCanvas_TouchUp;
// Enable touch support
this.IsManipulationEnabled = true;
// Initialize power management
InitializePowerManagement();
// Add the display pane to this control's content
Content = DisplayerPane;
}
</code></pre><h3 id="rendering-pipeline-1">Rendering Pipeline</h3>
<pre><code class="lang-csharp" name="RenderingCanvas">/// &lt;summary&gt;
/// Handles the buffer swapped event from DispEngine
/// &lt;/summary&gt;
private unsafe void RenderingCanvas_BufferSwapped(byte* data, int w, int h)
{
if (data == null)
return;
Span&lt;byte&gt; bgra = new Span&lt;byte&gt;(data, w * h * 4);
// Copy pixel data from DispEngine
int n = w * h * 4;
byte[] arr = new byte[n];
for (int i = 0; i &lt; n; i++)
arr[i] = data[i];
// Update UI on the UI thread
DisplayerPane.Dispatcher.InvokeAsync(() =&gt;
{
BitmapSource bitmap = BitmapSource.Create(w, h, 1, 1, PixelFormats.Bgra32, null, arr, w * 4);
DisplayerPane.Background = new ImageBrush(bitmap);
});
}
/// &lt;summary&gt;
/// Handles the size changed event
/// &lt;/summary&gt;
private void RenderingCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
{
// Notify DispEngine of size changes
DispEngine.Resize((int)DisplayerPane.RenderSize.Width, (int)DisplayerPane.RenderSize.Height);
}
/// &lt;summary&gt;
/// Handles visibility changes
/// &lt;/summary&gt;
private unsafe void DisplayerPane_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
// Update visibility state in DispEngine
DispEngine.IsVisible = IsVisible;
}
</code></pre><h3 id="mouse-and-keyboard-handling">Mouse and Keyboard Handling</h3>
<pre><code class="lang-csharp" name="RenderingCanvas">/// &lt;summary&gt;
/// Helper method to get mouse button mask
/// &lt;/summary&gt;
internal static HiMouseButtonMask GetMouseButtonMask(MouseDevice device)
{
HiMouseButtonMask mouseButtonMask = 0;
mouseButtonMask.SetLeftPressed(device.LeftButton == MouseButtonState.Pressed);
mouseButtonMask.SetMiddlePressed(device.MiddleButton == MouseButtonState.Pressed);
mouseButtonMask.SetRightPressed(device.RightButton == MouseButtonState.Pressed);
mouseButtonMask.SetXButton1Pressed(device.XButton1 == MouseButtonState.Pressed);
mouseButtonMask.SetXButton2Pressed(device.XButton2 == MouseButtonState.Pressed);
return mouseButtonMask;
}
/// &lt;summary&gt;
/// Handles the mouse wheel event
/// &lt;/summary&gt;
private void RenderingCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
// Handle mouse wheel for zoom operations
DispEngine.MouseWheel(0, e.Delta / 120);
DispEngine.MouseWheelTransform(0, e.Delta / 120);
}
/// &lt;summary&gt;
/// Handles the mouse up event
/// &lt;/summary&gt;
private void RenderingCanvas_MouseUp(object sender, MouseButtonEventArgs e)
{
// Handle mouse button release
DispEngine.MouseButtonUp((long)e.ChangedButton);
(sender as UIElement)?.ReleaseMouseCapture();
}
/// &lt;summary&gt;
/// Handles the mouse down event
/// &lt;/summary&gt;
private void RenderingCanvas_MouseDown(object sender, MouseButtonEventArgs e)
{
// Handle mouse button press
DispEngine.MouseButtonDown((long)e.ChangedButton);
DisplayerPane.Focus();
(sender as UIElement)?.CaptureMouse();
}
/// &lt;summary&gt;
/// Handles the mouse move event
/// &lt;/summary&gt;
private void RenderingCanvas_MouseMove(object sender, MouseEventArgs e)
{
// Update mouse position and handle drag transforms
Point p = e.GetPosition(DisplayerPane);
DispEngine.MouseMove((int)p.X, (int)p.Y);
DispEngine.MouseDragTransform((int)p.X, (int)p.Y,
new mouse_button_table__transform_view_by_mouse_drag_t()
{
LEFT_BUTTON = (long)MouseButton.Left,
RIGHT_BUTTON = (long)MouseButton.Right
});
}
</code></pre><pre><code class="lang-csharp" name="RenderingCanvas">/// &lt;summary&gt;
/// Convert WPF Key to W3C KeyboardEvent.key string.
/// &lt;/summary&gt;
static string WpfKeyToW3C(Key key) =&gt; key switch
{
Key.Home =&gt; &quot;Home&quot;,
Key.End =&gt; &quot;End&quot;,
Key.PageUp =&gt; &quot;PageUp&quot;,
Key.PageDown =&gt; &quot;PageDown&quot;,
Key.Left =&gt; &quot;ArrowLeft&quot;,
Key.Right =&gt; &quot;ArrowRight&quot;,
Key.Up =&gt; &quot;ArrowUp&quot;,
Key.Down =&gt; &quot;ArrowDown&quot;,
Key.LeftShift or Key.RightShift =&gt; &quot;Shift&quot;,
Key.LeftCtrl or Key.RightCtrl =&gt; &quot;Control&quot;,
Key.LeftAlt or Key.RightAlt =&gt; &quot;Alt&quot;,
Key.Return =&gt; &quot;Enter&quot;,
Key.Escape =&gt; &quot;Escape&quot;,
Key.Back =&gt; &quot;Backspace&quot;,
Key.Tab =&gt; &quot;Tab&quot;,
Key.Delete =&gt; &quot;Delete&quot;,
Key.Insert =&gt; &quot;Insert&quot;,
Key.Space =&gt; &quot; &quot;,
Key.F1 =&gt; &quot;F1&quot;,
Key.F2 =&gt; &quot;F2&quot;,
Key.F3 =&gt; &quot;F3&quot;,
Key.F4 =&gt; &quot;F4&quot;,
Key.F5 =&gt; &quot;F5&quot;,
Key.F6 =&gt; &quot;F6&quot;,
Key.F7 =&gt; &quot;F7&quot;,
Key.F8 =&gt; &quot;F8&quot;,
Key.F9 =&gt; &quot;F9&quot;,
Key.F10 =&gt; &quot;F10&quot;,
Key.F11 =&gt; &quot;F11&quot;,
Key.F12 =&gt; &quot;F12&quot;,
&gt;= Key.A and &lt;= Key.Z =&gt; ((char)('a' + (key - Key.A))).ToString(),
&gt;= Key.D0 and &lt;= Key.D9 =&gt; ((char)('0' + (key - Key.D0))).ToString(),
_ =&gt; &quot;Unidentified&quot;
};
/// &lt;summary&gt;
/// Handles the key up event
/// &lt;/summary&gt;
private void RenderingCanvas_KeyUp(object sender, KeyEventArgs e)
{
DispEngine.KeyUp(WpfKeyToW3C(e.Key));
}
/// &lt;summary&gt;
/// Handles the key down event
/// &lt;/summary&gt;
private void RenderingCanvas_KeyDown(object sender, KeyEventArgs e)
{
string key = WpfKeyToW3C(e.Key);
DispEngine.KeyDown(key);
DispEngine.KeyDownTransform(key, new key_table__transform_view_by_key_pressing_t()
{
HOME = &quot;Home&quot;,
PAGE_UP = &quot;PageUp&quot;,
PAGE_DOWN = &quot;PageDown&quot;,
F1 = &quot;F1&quot;,
F2 = &quot;F2&quot;,
F3 = &quot;F3&quot;,
F4 = &quot;F4&quot;,
SHIFT = &quot;Shift&quot;,
ARROW_LEFT = &quot;ArrowLeft&quot;,
ARROW_RIGHT = &quot;ArrowRight&quot;,
ARROW_DOWN = &quot;ArrowDown&quot;,
ARROW_UP = &quot;ArrowUp&quot;
});
}
</code></pre><h3 id="lifecycle-management-1">Lifecycle Management</h3>
<pre><code class="lang-csharp" name="RenderingCanvas">/// &lt;summary&gt;
/// Handles window state changes (maximize, minimize, etc.)
/// &lt;/summary&gt;
private unsafe void RenderingCanvas_StateChanged(object sender, EventArgs e)
{
switch ((sender as Window).WindowState)
{
case WindowState.Maximized:
DispEngine.IsVisible = true;
break;
case WindowState.Minimized:
DispEngine.IsVisible = false;
break;
case WindowState.Normal:
DispEngine.IsVisible = true;
break;
}
}
/// &lt;summary&gt;
/// Handles data context changes
/// &lt;/summary&gt;
private unsafe void CanvasDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
DispEngine pre = e.OldValue as DispEngine;
DispEngine cur = e.NewValue as DispEngine;
//child's binding event is triggered after IsVisible event and Load event.
if (pre != null) //this section will never occur if the datacontext not set twice.
{
pre.Terminate();
pre.ImageRequestAfterBufferSwapped -= RenderingCanvas_BufferSwapped;
}
if (cur != null)
{
cur.ImageRequestAfterBufferSwapped += RenderingCanvas_BufferSwapped;
cur.Start((int)DisplayerPane.RenderSize.Width, (int)DisplayerPane.RenderSize.Height);
cur.IsVisible = IsVisible;
}
}
/// &lt;summary&gt;
/// Reference to the current window containing this control
/// &lt;/summary&gt;
private Window currentWindow;
/// &lt;summary&gt;
/// Gets or sets the current window, connecting or disconnecting state change events
/// &lt;/summary&gt;
Window CurrentWindow
{
get =&gt; currentWindow; set
{
if (currentWindow != null)
currentWindow.StateChanged -= RenderingCanvas_StateChanged;
currentWindow = value;
if (currentWindow != null)
currentWindow.StateChanged += RenderingCanvas_StateChanged;
}
}
/// &lt;summary&gt;
/// Handles the loaded event
/// &lt;/summary&gt;
private unsafe void RenderingCanvas_Loaded(object sender, RoutedEventArgs e)
{
// Get the window containing this control
CurrentWindow = Window.GetWindow(this);
// Set up DispEngine rendering
DispEngine.ImageRequestAfterBufferSwapped -= RenderingCanvas_BufferSwapped;
DispEngine.ImageRequestAfterBufferSwapped += RenderingCanvas_BufferSwapped;
DispEngine.Start((int)DisplayerPane.RenderSize.Width, (int)DisplayerPane.RenderSize.Height);
DispEngine.IsVisible = IsVisible;
}
/// &lt;summary&gt;
/// Handles the unloaded event
/// &lt;/summary&gt;
private unsafe void RenderingCanvas_Unloaded(object sender, RoutedEventArgs e)
{
DispEngine.IsVisible = IsVisible;
DispEngine.ImageRequestAfterBufferSwapped -= RenderingCanvas_BufferSwapped;
CurrentWindow = null;
}
</code></pre><h3 id="resource-cleanup-1">Resource Cleanup</h3>
<pre><code class="lang-csharp" name="RenderingCanvas">/// &lt;summary&gt;
/// Flag to track disposed state
/// &lt;/summary&gt;
private bool disposedValue;
/// &lt;summary&gt;
/// Disposes managed resources
/// &lt;/summary&gt;
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// Unsubscribe from power events
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
// Dispose the DispEngine to free resources
DispEngine.Dispose();
}
disposedValue = true;
}
}
/// &lt;summary&gt;
/// Public dispose method to free resources
/// &lt;/summary&gt;
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
</code></pre><h2 id="core-dispengine-integration-patterns">Core DispEngine Integration Patterns</h2>
<h3 id="1-initialization-sequence">1. Initialization Sequence</h3>
<pre><code class="lang-csharp">// Create DispEngine (optionally with displayees)
var engine = new DispEngine(displayees);
// Set up image buffer callback
engine.ImageRequestAfterBufferSwapped += OnBufferSwapped;
// Initialize with canvas size
engine.Start(width, height);
// Set initial view (optional)
engine.SetViewToHomeView();
</code></pre>
<h3 id="2-render-loop">2. Render Loop</h3>
<p>The rendering process follows this pattern:</p>
<ol>
<li><a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a> processes <a class="xref" href="../../api/Hi.Disp.IDisplayee.html">IDisplayee</a> objects</li>
<li>Buffer is swapped and callback is triggered</li>
<li>UI framework renders the buffer to screen</li>
<li>User input triggers view updates</li>
<li>Process repeats</li>
</ol>
<h3 id="3-complete-user-input-mapping">3. Complete User Input Mapping</h3>
<p>All user interactions must be mapped to <a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a> methods:</p>
<table>
<thead>
<tr>
<th>User Action</th>
<th>DispEngine Method</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mouse move</td>
<td><a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_MouseMove_System_Int32_System_Int32_">MouseMove(int, int)</a></td>
</tr>
<tr>
<td>Mouse drag</td>
<td><a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_MouseDragTransform_System_Int32_System_Int32_Hi_Native_mouse_button_table__transform_view_by_mouse_drag_t_">MouseDragTransform(int, int, mouse_button_table__transform_view_by_mouse_drag_t)</a></td>
</tr>
<tr>
<td>Mouse button</td>
<td><a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_MouseButtonDown_System_Int64_">MouseButtonDown(long)</a> / <a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_MouseButtonUp_System_Int64_">MouseButtonUp(long)</a></td>
</tr>
<tr>
<td>Mouse wheel</td>
<td><a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_MouseWheel_System_Int32_System_Int32_">MouseWheel(int, int)</a> and <a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_MouseWheelTransform_System_Int32_System_Int32_System_Double_">MouseWheelTransform(int, int, double)</a></td>
</tr>
<tr>
<td>Key press</td>
<td><a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_KeyDown_System_String_">KeyDown(string)</a> / <a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_KeyUp_System_String_">KeyUp(string)</a> and <a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_KeyDownTransform_System_String_Hi_Native_key_table__transform_view_by_key_pressing_t_">KeyDownTransform(string, key_table__transform_view_by_key_pressing_t)</a></td>
</tr>
<tr>
<td>Touch events</td>
<td><a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_TouchDown_System_Int32_System_Int32_System_Int32_">TouchDown(int, int, int)</a> / <a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_TouchMove_System_Int32_System_Int32_System_Int32_">TouchMove(int, int, int)</a> / <a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_TouchUp_System_Int32_">TouchUp(int)</a></td>
</tr>
</tbody>
</table>
<h3 id="4-proper-resource-cleanup">4. Proper Resource Cleanup</h3>
<p>Resource management is critical for proper operation:</p>
<pre><code class="lang-csharp">// In dispose method
DispEngine.ImageRequestAfterBufferSwapped -= OnBufferSwapped;
DispEngine.Terminate();
DispEngine.Dispose();
</code></pre>
<h2 id="advanced-implementation-considerations">Advanced Implementation Considerations</h2>
<p>When creating custom implementations, consider these aspects:</p>
<h3 id="view-manipulation">View Manipulation</h3>
<p>Use <a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_SketchView">SketchView</a> to directly access or modify the view matrix:</p>
<pre><code class="lang-csharp">// Get current view matrix
Mat4d currentView = engine.SketchView;
// Apply custom rotation
Mat4d rotation = Mat4d.RotateX(Math.PI/4);
engine.SketchView = currentView * rotation;
</code></pre>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a></li>
<li><a class="xref" href="../../api/Hi.Disp.IDisplayee.html">IDisplayee</a></li>
<li><a class="xref" href="../../api/Hi.Geom.Vec2d.html">Vec2d</a></li>
<li><a class="xref" href="../../api/Hi.Geom.Mat4d.html">Mat4d</a></li>
<li><a href="rendering-canvas.html">Using RenderingCanvas with DispEngine</a> — the shipped controls this guide reimplements</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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

@@ -0,0 +1,304 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Using Hi.Disp.Drawing | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Using Hi.Disp.Drawing | 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="Technique-Drawing">
<h1 id="using-hidispdrawing">Using Hi.Disp.Drawing</h1>
<p>The <a class="xref" href="../../api/Hi.Disp.Drawing.html">Drawing</a> class is the most fundamental and efficient rendering unit that allows you to draw points, lines, and surfaces within the <a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a>.</p>
<h2 id="understanding-drawing-structure">Understanding Drawing Structure</h2>
<p>Looking at the constructor <a class="xref" href="../../api/Hi.Disp.Drawing.html#Hi_Disp_Drawing__ctor_System_Double___Hi_Disp_Stamp_System_Int32_">Drawing(double[], Stamp, int)</a> helps explain its structure:</p>
<ul>
<li>The <code>double[]</code> array contains batch data for rendering, composed of one or more data groups of consistent length</li>
<li>Each data group's length is determined by the <a class="xref" href="../../api/Hi.Disp.Stamp.html">Stamp</a> parameter</li>
<li>Each data group describes a single vertex</li>
</ul>
<h2 id="data-components">Data Components</h2>
<p>A data group can contain up to four types of information:</p>
<table>
<thead>
<tr>
<th>Information</th>
<th>Abbreviation</th>
<th>Description</th>
<th>Size</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Vertex</strong></td>
<td>V</td>
<td>The position of the point (x, y, z)</td>
<td>3 doubles</td>
</tr>
<tr>
<td><strong>Normal</strong></td>
<td>N</td>
<td>The normal vector affecting light reflection (Nx, Ny, Nz)</td>
<td>3 doubles</td>
</tr>
<tr>
<td><strong>Color</strong></td>
<td>C</td>
<td>RGB color values ranging from 0 to 1</td>
<td>3 doubles</td>
</tr>
<tr>
<td><strong>Pick ID</strong></td>
<td>P</td>
<td>A single double value converted from an integer for selection operations</td>
<td>1 double</td>
</tr>
</tbody>
</table>
<p>The <a class="xref" href="../../api/Hi.Disp.Stamp.html">Stamp</a> enumeration combines these abbreviations to create these possible stamps: <code>{V, NV, CV, CNV, PV, PNV, PCV, PCNV}</code>.</p>
<h3 id="important-notes">Important Notes:</h3>
<ul>
<li>The <strong>Vertex</strong> (V) is mandatory, which is why V appears in every Stamp option</li>
<li><strong>Normal</strong> vectors (N) are typically used for 3D graphics to create a sense of depth through lighting</li>
<li><strong>Color</strong> (C) uses three double values (R, G, B) in the range of 0 to 1</li>
<li><strong>Pick ID</strong> (P) is used for graphical selection operations</li>
</ul>
<h2 id="data-structure-example">Data Structure Example</h2>
<ul>
<li>If <a class="xref" href="../../api/Hi.Disp.Stamp.html">Stamp</a> is <code>V</code>, each data group consists of 3 double values (x, y, z)</li>
<li>If <a class="xref" href="../../api/Hi.Disp.Stamp.html">Stamp</a> is <code>PCV</code>, each data group consists of 1(P) + 3(C) + 3(V) = 7 double values</li>
</ul>
<h2 id="rendering-mode">Rendering Mode</h2>
<p>The <code>glPrimitive</code> parameter is an OpenGL constant that specifies the drawing mode, and the same value
stays settable afterwards through the <code>GlPrimitive</code> property. Illustrations of the available modes
are published under the name &ldquo;OpenGL Primitives&rdquo;.</p>
<h2 id="example-usage">Example Usage</h2>
<pre><code class="lang-csharp">// Creating a simple line strip with three vertices
double[] vertices = new double[] {
0, 0, 0, // First point at origin
1, 0, 0, // Second point along X-axis
0, 0, 1 // Third point along Z-axis
};
// Create drawing object using the vertices
var drawing = new Drawing(vertices, Stamp.V, (int)OpenGL.GL_LINE_STRIP);
</code></pre>
<p>This example creates three vertices with only position information (V), so each vertex has just xyz coordinates. The drawing mode is set to LineStrip.</p>
<p><img src="drawing-img/easydraw_lines.png" alt="Line Strip Drawing Example"></p>
<h2 id="performance-considerations">Performance Considerations</h2>
<div class="NOTE">
<h5>Note</h5>
<p>After a <a class="xref" href="../../api/Hi.Disp.Drawing.html">Drawing</a> object is created, its source data is stored in GPU memory. Regardless of the amount of data, the CPU processing load when calling <a class="xref" href="../../api/Hi.Disp.IDisplayee.html#Hi_Disp_IDisplayee_Display_Hi_Disp_Bind_">Display(Bind)</a> remains consistent. This means displaying 100 points with one <a class="xref" href="../../api/Hi.Disp.Drawing.html">Drawing</a> object is approximately 100 times faster than using 100 separate Drawing objects to display 100 individual points.</p>
</div>
<h2 id="composing-multiple-idisplayee-objects">Composing Multiple IDisplayee Objects</h2>
<p>A common pattern is to combine multiple <a class="xref" href="../../api/Hi.Disp.IDisplayee.html">IDisplayee</a> objects, including <a class="xref" href="../../api/Hi.Disp.Drawing.html">Drawing</a> objects:</p>
<pre><code class="lang-csharp">public class MyCompositeDisplayee : IDisplayee
{
private readonly List&lt;IDisplayee&gt; _displayees = new List&lt;IDisplayee&gt;();
public MyCompositeDisplayee()
{
// Create a grid drawing
_displayees.Add(CreateGridDrawing());
// Create an axes drawing
_displayees.Add(CreateAxesDrawing());
// Add other custom drawings
_displayees.Add(CreateCustomDrawing());
}
private Drawing CreateGridDrawing()
{
// Code to create a grid
double[] gridVertices = new double[/* grid data */];
return new Drawing(gridVertices, Stamp.CV, (int)OpenGL.GL_LINES);
}
private Drawing CreateAxesDrawing()
{
// Create colored axes
double[] axesData = new double[] {
// Red X-axis (with color)
1, 0, 0, 0, 0, 0, // Red color, origin
1, 0, 0, 1, 0, 0, // Red color, x-axis end
// Green Y-axis (with color)
0, 1, 0, 0, 0, 0, // Green color, origin
0, 1, 0, 0, 1, 0, // Green color, y-axis end
// Blue Z-axis (with color)
0, 0, 1, 0, 0, 0, // Blue color, origin
0, 0, 1, 0, 0, 1 // Blue color, z-axis end
};
return new Drawing(axesData, Stamp.CV, (int)OpenGL.GL_LINES);
}
public void Display(Bind bind)
{
// Render all contained displayees
foreach (var displayee in _displayees)
{
displayee.Display(bind);
}
}
public void ExpandToBox3d(Box3d box)
{
// Update bounding box based on all displayees
foreach (var displayee in _displayees)
{
displayee.ExpandToBox3d(box);
}
}
}
</code></pre>
<h2 id="creating-common-shapes">Creating Common Shapes</h2>
<p>Here are some examples of creating common shapes using the <a class="xref" href="../../api/Hi.Disp.Drawing.html">Drawing</a> class:</p>
<h3 id="creating-points">Creating Points</h3>
<pre><code class="lang-csharp">// Create an array of points
double[] pointData = new double[] {
0, 0, 0, // Point 1
1, 1, 1, // Point 2
2, 0, 0, // Point 3
0, 2, 0 // Point 4
};
// Create a Drawing for points
var pointDrawing = new Drawing(pointData, Stamp.V, (int)OpenGL.GL_POINTS);
</code></pre>
<h3 id="creating-lines">Creating Lines</h3>
<pre><code class="lang-csharp">// Create line segments (pairs of vertices)
double[] lineData = new double[] {
0, 0, 0, 1, 1, 0, // Line 1: (0,0,0) to (1,1,0)
2, 0, 0, 2, 2, 0 // Line 2: (2,0,0) to (2,2,0)
};
// Create a Drawing for lines
var lineDrawing = new Drawing(lineData, Stamp.V, (int)OpenGL.GL_LINES);
</code></pre>
<h3 id="creating-triangles">Creating Triangles</h3>
<pre><code class="lang-csharp">// Create triangles (triplets of vertices)
double[] triangleData = new double[] {
// Triangle 1
0, 0, 0, // Vertex 1
1, 0, 0, // Vertex 2
0, 1, 0 // Vertex 3
};
// Create a Drawing for triangles
var triangleDrawing = new Drawing(triangleData, Stamp.V, (int)OpenGL.GL_TRIANGLES);
</code></pre>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a></li>
<li><a class="xref" href="../../api/Hi.Disp.IDisplayee.html">IDisplayee</a></li>
<li><a class="xref" href="../../api/Hi.Disp.DispList.html">DispList</a></li>
<li><a href="rendering-canvas.html">Using RenderingCanvas with DispEngine</a> — the control that hosts the engine these drawings are rendered by</li>
<li><a href="color-guide.html">Color Guide System</a> — deciding the colour and priority a drawn step comes out with</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,136 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Rendering | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Rendering | 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="">
<h1 id="rendering">Rendering</h1>
<p>How HiAPI puts geometry on a screen. The whole system rests on one relationship — a
<a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a> renders <a class="xref" href="../../api/Hi.Disp.IDisplayee.html">IDisplayee</a> objects — so every page here is
either a way to host the engine in a UI framework, a way to produce something for it to render,
or a way to decide what colour the result comes out.</p>
<p>Ordered from hosting the engine to feeding it: the canvas first, then what is drawn on it.</p>
<h2 id="hosting-the-engine">Hosting the Engine</h2>
<ul>
<li><a href="rendering-canvas.html">Using RenderingCanvas with DispEngine</a> — The shipped canvas controls for Windows Forms and WPF, the DispEngine surface they expose, and the input and camera operations that come with it</li>
<li><a href="custom-rendering-canvas.html">Building Your Own Rendering Canvas</a> — What a canvas has to implement to host a DispEngine on a framework HiAPI ships no control for, shown against both reference implementations</li>
</ul>
<h2 id="what-gets-drawn">What Gets Drawn</h2>
<ul>
<li><a href="drawing.html">Using Hi.Disp.Drawing</a> — The primitive rendering unit for points, lines and surfaces, and how to compose displayees without paying for each one</li>
<li><a href="color-guide.html">Color Guide System</a> — Assigning colour and rendering priority per machining step, and what priority decides when many steps land in one pixel</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="../mechanism/index.html">Mechanism</a> — the topology that decides where a displayee is drawn</li>
<li><a href="../api-foundations/index.html">API Foundations</a> — the packages, geometry types and services this sits on</li>
<li><a href="../api-foundations/packages-and-samples.html">HiAPI Packages and Sample Code</a> — which package a Windows Forms or WPF application needs</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,265 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Using RenderingCanvas with DispEngine | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Using RenderingCanvas with DispEngine | 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="Technique-RenderingCanvas">
<h1 id="using-renderingcanvas-with-dispengine">Using RenderingCanvas with DispEngine</h1>
<p>The <code>RenderingCanvas</code> is the primary UI component for displaying and interacting with 3D content across different platforms. This section explains how to use it with the <a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a> to create cross-platform applications.</p>
<h2 id="overview">Overview</h2>
<p>The <code>RenderingCanvas</code> class is available in frameworks:</p>
<ul>
<li><code>Hi.WinForm</code> for Windows Forms applications</li>
<li><code>Hi.WpfPlus</code> for WPF applications</li>
</ul>
<p>All implementations share a common architecture centered around the <a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a> class, enabling consistent rendering and interaction across platforms.</p>
<h2 id="core-concept-dispengine-and-idisplayee">Core Concept: DispEngine and IDisplayee</h2>
<p>At the heart of the rendering system is the relationship between <a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a> and <a class="xref" href="../../api/Hi.Disp.IDisplayee.html">IDisplayee</a>:</p>
<ul>
<li><a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a>: The rendering engine that manages the OpenGL context and handles user interaction</li>
<li><a class="xref" href="../../api/Hi.Disp.IDisplayee.html">IDisplayee</a>: The interface that defines objects that can be rendered by the DispEngine</li>
</ul>
<p>This relationship is fundamental - <strong>the purpose of <a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a> is to render <a class="xref" href="../../api/Hi.Disp.IDisplayee.html">IDisplayee</a> objects</strong>.</p>
<pre><code class="lang-mermaid">graph TD
A[IDisplayee Objects] --&gt;|Rendered by| B
B[DispEngine] &lt;--&gt; C[RenderingCanvas UI Component]
</code></pre>
<h3 id="working-with-idisplayee">Working with IDisplayee</h3>
<p>Objects implementing <a class="xref" href="../../api/Hi.Disp.IDisplayee.html">IDisplayee</a> define what gets rendered. Typically, you'll use <a class="xref" href="../../api/Hi.Disp.Drawing.html">Drawing</a> objects or compose multiple IDisplayee objects together:</p>
<pre><code class="lang-csharp">// Create a composite displayee
public class MyCompositeDisplayee : IDisplayee
{
private List&lt;IDisplayee&gt; _displayees = new List&lt;IDisplayee&gt;();
public MyCompositeDisplayee()
{
// Add various displayees
_displayees.Add(new AxesDisplayee());
_displayees.Add(new ModelDisplayee());
}
public void Display(Bind bind)
{
// Render all contained displayees
foreach (var displayee in _displayees)
{
displayee.Display(bind);
}
}
public void ExpandToBox3d(Box3d box)
{
// Update bounding box based on all displayees
foreach (var displayee in _displayees)
{
displayee.ExpandToBox3d(box);
}
}
}
</code></pre>
<p>For more detailed information on creating displayees with <a class="xref" href="../../api/Hi.Disp.Drawing.html">Drawing</a>, see the <a href="drawing.html">Drawing</a> section.</p>
<h2 id="basic-usage">Basic Usage</h2>
<h3 id="apply-hiwinform">Apply Hi.WinForm</h3>
<pre><code class="lang-csharp">// Create a new instance with displayee objects
using Hi.WinForm.Disp;
// Create displayee object
var displayee = new MyCompositeDisplayee();
// Initialize canvas with the displayee
var canvas = new RenderingCanvas(displayee);
// Access the DispEngine for direct manipulation
DispEngine engine = canvas.DispEngine;
// Add to a form
myForm.Controls.Add(canvas);
</code></pre>
<h3 id="apply-hiwpf">Apply Hi.WPF</h3>
<pre><code class="lang-csharp">// Create a new instance
using Hi.WpfPlus.Disp;
// Create displayee object
var displayee = new MyCompositeDisplayee();
// Initialize the canvas
var canvas = new RenderingCanvas();
// Set displayee objects through the DispEngine
canvas.DispEngine.Displayee = displayee;
// Add to a container
myGrid.Children.Add(canvas);
</code></pre>
<h2 id="switching-displayees-at-runtime">Switching Displayees at Runtime</h2>
<p>You can dynamically change what's being displayed:</p>
<pre><code class="lang-csharp">// Switch to a different displayee
renderingCanvas.DispEngine.Displayee = alternativeDisplayee;
// Or update a DispList
var displayList = new DispList();
if (showModel) displayList.Add(modelDisplayee);
if (showGrid) displayList.Add(gridDisplayee);
renderingCanvas.DispEngine.Displayee = displayList;
</code></pre>
<h2 id="key-features-of-dispengine">Key Features of DispEngine</h2>
<p>The <a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a> provides cross-platform support for:</p>
<ul>
<li>Handles buffer swapping and image generation</li>
<li>Mouse/pointer events</li>
<li>Keyboard navigation</li>
<li>Touch gestures</li>
<li>Zoom, pan, and rotate operations</li>
<li>Resize and Visibility changed.</li>
<li>Camera positioning and orientation</li>
<li>Standard views (front, top, isometric, etc.)</li>
<li>Renders <a class="xref" href="../../api/Hi.Disp.IDisplayee.html">IDisplayee</a> implementations</li>
</ul>
<h2 id="touch-and-gesture-support">Touch and Gesture Support</h2>
<p>The <a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a> centralizes touch handling across all platforms with a unified API that supports:</p>
<ul>
<li>Single-finger pan</li>
<li>Two-finger rotate and scale</li>
<li>Multi-finger specialized operations</li>
</ul>
<p>The touch API is designed to be simple for UI implementations to use. Platform-specific UI components only need to capture touch events and forward them to the DispEngine.</p>
<h2 id="common-operations">Common Operations</h2>
<pre><code class="lang-csharp">// Accessing DispEngine (works on all platforms)
var engine = renderingCanvas.DispEngine;
// Set to standard views
engine.SetViewToHomeView();
engine.SetViewToFrontView();
// Manual camera manipulation
engine.Translate(dx, dy);
engine.Rotate(deltaX, deltaY);
// Resize handling
engine.Resize(width, height);
</code></pre>
<h2 id="implementation-details">Implementation Details</h2>
<p>For detailed implementation information, including:</p>
<ul>
<li>Full source code examples</li>
<li>Implementation details for each platform</li>
<li>Advanced touch handling</li>
<li>Custom implementation guidance</li>
</ul>
<p>See the <a href="custom-rendering-canvas.html">Building Your Own Rendering Canvas</a> guide.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../../api/Hi.Disp.DispEngine.html">DispEngine</a></li>
<li><a class="xref" href="../../api/Hi.Disp.IDisplayee.html">IDisplayee</a></li>
<li><a class="xref" href="../../api/Hi.Disp.DispList.html">DispList</a></li>
<li><a href="custom-rendering-canvas.html">Building Your Own Rendering Canvas</a> — what a canvas has to implement to host the engine itself</li>
<li><a href="drawing.html">Drawing</a> — producing the displayees this canvas renders</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,34 @@
<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="rendering-canvas.html" name="" title="Using RenderingCanvas with DispEngine">Using RenderingCanvas with DispEngine</a>
</li>
<li>
<a href="custom-rendering-canvas.html" name="" title="Building Your Own Rendering Canvas">Building Your Own Rendering Canvas</a>
</li>
<li>
<a href="drawing.html" name="" title="Drawing">Drawing</a>
</li>
<li>
<a href="color-guide.html" name="" title="Color Guide System">Color Guide System</a>
</li>
</ul>
</div>
</div>
</div>
</div>
@@ -0,0 +1,2 @@
{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"Using RenderingCanvas with DispEngine","href":"rendering-canvas.html","topicHref":"rendering-canvas.html"},{"name":"Building Your Own Rendering Canvas","href":"custom-rendering-canvas.html","topicHref":"custom-rendering-canvas.html"},{"name":"Drawing","href":"drawing.html","topicHref":"drawing.html"},{"name":"Color Guide System","href":"color-guide.html","topicHref":"color-guide.html"}]}
@@ -0,0 +1,227 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cutter-Location (CL) Playback | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Cutter-Location (CL) Playback | 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="CutterLocation-Playback">
<h1 id="cutter-location-cl-playback">Cutter-Location (CL) Playback</h1>
<p><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_PlayClFile_">PlayClFile</a> replays a <strong>CAM cutter-location file</strong> — an NX CLSF (<code>.cls</code>) / APT-source toolpath — directly as tool motion, without a post-processor. Use it to verify the <em>programmed</em> toolpath itself (gouge, overcut, engagement) <strong>before</strong> it is post-processed for any particular machine.</p>
<p>The same file can also be played onto a real machine-tool chain, and a played CL program can be written back out as Fanuc NC — see <a href="#two-chains-two-questions">Two chains, two questions</a> and <a href="#converting-cl-to-nc">Converting CL to NC</a>.</p>
<h2 id="cl-vs-nc--two-different-inputs">CL vs. NC — two different inputs</h2>
<table>
<thead>
<tr>
<th></th>
<th><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_PlayNcFile_">PlayNcFile</a> (NC / G-code)</th>
<th><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_PlayClFile_">PlayClFile</a> (CL / CLSF)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Source</td>
<td>Post-processed G-code for <strong>one specific machine</strong></td>
<td>CAM cutter-location output, <strong>before</strong> post-processing, machine-independent</td>
</tr>
<tr>
<td>Content</td>
<td>Axis moves (<code>G01 X.. Y.. Z..</code>), work offsets, canned cycles</td>
<td>Cutter locations (<code>GOTO</code>), arcs (<code>CIRCLE</code>), tool axis vectors</td>
</tr>
<tr>
<td>Drives</td>
<td>A <strong>machine-tool chain</strong> (X/Y/Z/A/B/C axes) through kinematics</td>
<td>Either chain — see below</td>
</tr>
<tr>
<td>Answers</td>
<td>&ldquo;What does <em>this machine</em> do with this program?&rdquo;</td>
<td>&ldquo;Is the <em>programmed path</em> correct?&rdquo; — or, on a machine chain, both questions at once</td>
</tr>
</tbody>
</table>
<p>A cutter location is a <strong>point plus a tool-axis direction</strong> in workpiece coordinates. <code>PlayClFile</code> places the tool at each location in turn and sweeps the removed material between them.</p>
<h2 id="two-chains-two-questions">Two chains, two questions</h2>
<p>The chain configured in project setup decides what a CL play means.</p>
<p><strong>On a <a class="xref" href="../../api/HiMachining.Milling.ClMillingDevice.html">ClMillingDevice</a></strong> the cutter location is applied straight to the tool: no inverse kinematics, no work-coordinate offsets, no controller dialect. This is the machine-independent check — it answers whether the CAM output itself is correct, and it is the right chain when you do not yet know which machine will run the job.</p>
<p><strong>On a machine-tool chain</strong> every CLSF motion endpoint is inverse-solved at parse time and expressed in the same program-to-machine transform vocabulary the NC pipeline uses — a tool-height entry from the active tool, a pivot entry anchored to the workpiece frame, and the solved rotary axes — so the shared machine-coordinate and rotary-wrap handling is reused unchanged. This answers what a <em>particular</em> machine would do with the path, including reach and rotary behaviour, without a post-processor in between.</p>
<div class="NOTE">
<h5>Note</h5>
<p>A machine-chain play needs the project's kinematics to resolve to a live solver. Where an endpoint cannot be solved, the motion is reported rather than silently dropped — watch for <code>ClToMc--EndpointIkFailed</code> and <code>ClToMc--NoToolOffset</code> in the diagnostics.</p>
</div>
<h2 id="converting-cl-to-nc">Converting CL to NC</h2>
<p><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_ConvertClToNcFiles_">ConvertClToNcFiles</a> writes a played CL program back out as Fanuc NC, one file per source file, template-substituting <code>[NcName]</code> (default <code>Output/[NcName].nc</code>). It requires a prior play <strong>on a machine chain</strong> — a <code>ClMillingDevice</code> leaves no machine-solved data to serialize — and reports <code>ConvertClToNc--NoPlay</code> otherwise. A mission can declare the writeback through <a class="xref" href="../../api/Hi.SessionCommands.PostExecutionCommand.html#Hi_SessionCommands_PostExecutionCommand_EnableConvertClToNcFiles">EnableConvertClToNcFiles</a> and <a class="xref" href="../../api/Hi.SessionCommands.PostExecutionCommand.html#Hi_SessionCommands_PostExecutionCommand_ClToNcFileTemplate">ClToNcFileTemplate</a>.</p>
<h2 id="file-format">File format</h2>
<p>The reader parses <strong>NX CLSF</strong> records (the APT-source language):</p>
<table>
<thead>
<tr>
<th>Record</th>
<th>Effect</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>GOTO</code></td>
<td>Cutter location — first one positions the tool (rapid teleport); subsequent ones cut a straight CL path</td>
</tr>
<tr>
<td><code>CIRCLE</code> / <code>MOVARC</code></td>
<td>Arms an arc; the following <code>GOTO</code> closes it into a true circular CL path</td>
</tr>
<tr>
<td><code>RAPID</code></td>
<td>Marks the next move as a non-cutting rapid</td>
</tr>
<tr>
<td><code>FEDRAT</code></td>
<td>Feed rate (<code>MMPM</code> / <code>IPM</code>)</td>
</tr>
<tr>
<td><code>SPINDL</code></td>
<td>Spindle speed and direction</td>
</tr>
<tr>
<td><code>COOLNT</code></td>
<td>Coolant mode (<code>ON</code> / <code>FLOOD</code> / <code>MIST</code> / <code>OFF</code>)</td>
</tr>
<tr>
<td><code>TLDATA</code></td>
<td>Tool geometry (diameter, corner radius, length, angles)</td>
</tr>
<tr>
<td><code>LOAD/TOOL</code></td>
<td>Tool change to a tool id</td>
</tr>
</tbody>
</table>
<p>Comments (<code>$$</code> to end of line) and line continuation (trailing <code>$</code>) are honored. Records outside this set (<code>PAINT</code>, <code>TOOLNO</code>, <code>TOOL PATH</code>, …) are skipped.</p>
<div class="NOTE">
<h5>Note</h5>
<p>&ldquo;APT&rdquo; here means the APT <strong>toolpath language</strong> (<code>GOTO</code>, <code>CIRCLE</code>, …). This is a different use of the word from the <a class="xref" href="../milling-physics/cutter-geometry.html">Cutter Geometry</a> page, which defines cutter <strong>geometry</strong>. A CL file's <code>TLDATA</code> feeds that same tool-geometry model — see below.</p>
</div>
<p>The dialect parsed is Siemens NX (<code>.cls</code>). Other CAM systems emit the same APT record family under different names (CATIA APTSOURCE, Creo CL files); those dialects are not yet parsed.</p>
<h2 id="tools-from-the-file">Tools from the file</h2>
<p>A CL file usually carries its own tool definitions. On <code>LOAD/TOOL,&lt;id&gt;</code>, if the tool house has no matching id, the preceding <code>TLDATA</code> geometry is used to create the tool automatically. An id <strong>already present</strong> in the tool house keeps its configured tool — so you can pre-configure tools for accuracy, or let simple files be self-contained.</p>
<h2 id="example">Example</h2>
<pre><code class="lang-csharp">// The machining chain must be a ClMillingDevice (set in project setup).
MachiningResolution_mm = 0.125;
EnablePhysics = false; // geometry-only check first
PlayClFile(&quot;CL/part-op10.cls&quot;); // replay the CAM cutter-location file
Diff(&quot;target/part-op10.stl&quot;); // compare the cut against the design target
</code></pre>
<p>The project keeps a dedicated CL runner suit (<a class="xref" href="../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_ClsfRunnerSuit">ClsfRunnerSuit</a>) alongside its NC and CSV suits; the parser itself is the <a class="xref" href="../../api/Hi.Numerical.ClsfParsers.NxClRunner.html">NxClRunner</a> preset.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_PlayClFile_">PlayClFile</a> — the script command</li>
<li><a class="xref" href="../../api/HiMachining.Milling.ClMillingDevice.html">ClMillingDevice</a> — the cutter-location-driven chain</li>
<li><a class="xref" href="../milling-physics/cutter-geometry.html">Cutter Geometry</a> — cutter geometry (the other meaning of &ldquo;APT&rdquo;)</li>
<li><a class="xref" href="script-command.html">Script Commands</a> — what is a script command</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,141 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Scripting | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Scripting | 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="">
<h1 id="scripting">Scripting</h1>
<p>How a HiNC session is driven from C#: the command surface a script is written against, the step
objects a run produces, and the message stream it reports through. The same commands run from the
app's script panels, from inside an NC comment, and from a hosted session, so this section
describes the surface rather than the screen.</p>
<p>Ordered the way a script meets them — the language and its global scope first, then what a run
produces and how it reports, then the one input that is not G-code.</p>
<h2 id="writing-a-script">Writing a Script</h2>
<ul>
<li><a href="script-command.html">Script Command</a> — The C# syntax, the session lifecycle a command runs inside, <code>;@</code> commands embedded in NC, and the <code>[NcName]</code> output template</li>
<li><a href="session-shell.html">SessionShell</a> — The global scope every command resolves against, mapped family by family onto the work each family does</li>
</ul>
<h2 id="what-a-run-produces">What a Run Produces</h2>
<ul>
<li><a href="step.html">Step</a> — The computation unit, one spindle revolution by default: its custom variables, and how a script reads and exports it</li>
<li><a href="step-fields.html">Step Field Reference</a> — What each group of per-step output covers, and the two values that are most often misread</li>
<li><a href="shell-progress.html">ShellProgress</a> — The four message severities, tag filtering, and exporting a session log</li>
</ul>
<h2 id="playing-something-other-than-g-code">Playing Something Other Than G-code</h2>
<ul>
<li><a href="cutter-location-playback.html">Cutter-Location (CL) Playback</a> — Replaying a CAM cutter-location file before it is post-processed, and what the chain choice decides</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="../milling-physics/index.html">Milling Physics</a> — what the per-step values a script exports are measuring</li>
<li><a href="../nc-optimization/index.html">NC Optimization</a> — the optimizer that the <code>Opt*</code> settings on this surface drive</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,232 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Script Commands | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Script Commands | 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="Glossary-ScriptCommand">
<h1 id="script-commands">Script Commands</h1>
<h2 id="what-is-a-script-command">What Is a Script Command?</h2>
<p>A <strong>script command</strong> is a C# statement executed by the HiNC scripting engine. Scripts directly reference members and methods of <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html">SessionShell</a>, which serves as the global scope — no explicit object reference is needed.</p>
<pre><code class="lang-csharp">// These are all SessionShell members used directly as globals
EnablePhysics = true;
MachiningResolution_mm = 0.125;
PlayNcFile(&quot;NC/file1.nc&quot;);
Message(&quot;Done&quot;);
</code></pre>
<h2 id="script-syntax-basics">Script Syntax Basics</h2>
<p>Scripts use <strong>native C#</strong> syntax:</p>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Syntax</th>
</tr>
</thead>
<tbody>
<tr>
<td>Statement terminator</td>
<td><code>;</code></td>
</tr>
<tr>
<td>End-of-line comment</td>
<td><code>// comment</code></td>
</tr>
<tr>
<td>String interpolation</td>
<td><code>$&quot;Value is {variable}&quot;</code></td>
</tr>
<tr>
<td>Positive infinity</td>
<td><code>double.PositiveInfinity</code></td>
</tr>
<tr>
<td>Negative infinity</td>
<td><code>double.NegativeInfinity</code></td>
</tr>
<tr>
<td>Bitwise OR (for flags)</td>
<td><code>Fx|Fy|Fz</code></td>
</tr>
</tbody>
</table>
<p>All standard C# language features (variables, loops, conditionals, LINQ, etc.) are available.</p>
<hr>
<h2 id="execution-model">Execution Model</h2>
<h3 id="session-lifecycle">Session Lifecycle</h3>
<ol>
<li>Scripts execute in order on the <strong>Task</strong> page</li>
<li>A <a class="xref" href="../../api/Hi.Common.PacePlayer.html">PacePlayer</a><small>(API)</small> controls playback — script commands like <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_PlayNcFile_">PlayNcFile</a><small>(API)</small> block until the NC program completes</li>
<li>Player control commands (<a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_Pace">Pace()</a><small>(API)</small>, <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_Pause">Pause()</a><small>(API)</small>, <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_Reset">Reset()</a><small>(API)</small>) interact with the <a class="xref" href="../../api/Hi.Common.PacePlayer.html">PacePlayer</a><small>(API)</small></li>
<li><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_ResetRuntime_">ResetRuntime</a><small>(API)</small> clears event handlers, buffers, and runtime state</li>
</ol>
<h3 id="event-driven-execution">Event-Driven Execution</h3>
<p>Events like <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_SessionStepBuilt">SessionStepBuilt</a><small>(API)</small> fire during simulation and allow per-step logic:</p>
<pre><code class="lang-csharp">SessionStepBuilt += (preStep, curStep) =&gt; {
if (curStep != null)
Message($&quot;Step: ToolId={curStep.ToolId}&quot;);
};
PlayNcFile(&quot;NC/file1.nc&quot;);
</code></pre>
<p>Events are cleared by <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_ResetRuntime_">ResetRuntime</a>.</p>
<hr>
<h2 id="script-commands-in-nc-code">Script Commands in NC Code</h2>
<p>Script commands can be embedded inside NC code comments. Lines starting with <code>;@</code> execute before that NC line runs:</p>
<p>The marker is read inside the line's <strong>comment</strong>, so the comment character is the controller's own. Where <code>;</code> opens a comment:</p>
<pre><code>T01 M06 ;@MachiningResolution_mm=0.03125;
S1270 M03
G43 Z10. H01
</code></pre>
<p>For controllers that do not support <code>;</code> as a comment character (FANUC and the other <code>( )</code> dialects), the same marker goes inside the parentheses:</p>
<pre><code>T01 M06 (;@MachiningResolution_mm=0.03125;)
S1270 M03
G43 Z10. H01
</code></pre>
<hr>
<h2 id="file-path-templates">File Path Templates</h2>
<p>Commands that output files support the <code>[NcName]</code> token, which is replaced with each NC file name:</p>
<pre><code class="lang-csharp">PlayNcFile(&quot;NC/file1.nc&quot;);
PlayNcFile(&quot;NC/file2.nc&quot;);
WriteShotFiles(&quot;Output/[NcName].shot.csv&quot;, 1);
// Produces: Output/file1.nc.shot.csv, Output/file2.nc.shot.csv
</code></pre>
<p>All file paths are relative to the <strong>project directory</strong> unless an absolute path is given.</p>
<hr>
<h2 id="important-warnings">Important Warnings</h2>
<p>The following operations can corrupt simulation state or produce incorrect results:</p>
<ul>
<li><strong>Do not save the project during simulation.</strong> System-internal configuration (e.g., training-specific resolution overrides) may overwrite your settings.</li>
<li><strong>Do not reset the player during milling coefficient training.</strong> Close the project instead of pressing the reset button to avoid unexpected errors.</li>
<li><strong>Do not modify resolution, tool, or controller settings during training.</strong> Changing these mid-training invalidates the results.</li>
<li><strong>Do not combine <code>UpdateNcOptOption</code> in <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_SessionStepBuilt">SessionStepBuilt</a><small>(API)</small> with NC-embedded optimization commands.</strong> Parallel computation may cause undefined behavior.</li>
<li><strong>Do not write <code>NaN</code> into a per-step <code>NcOptOption</code>.</strong> A <code>NaN</code> feed-per-tooth boundary is refused when the step is solved: that step keeps its simulated feed rate and is reported as an error naming the option values, and the rest of the run is optimized normally. See <a href="../nc-optimization/nc-optimization-principles.html#when-a-step-cannot-be-solved">When a Step Cannot Be Solved</a>.</li>
</ul>
<hr>
<h2 id="global-variables">Global Variables</h2>
<p><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_Global">Global</a> provides a key-value dictionary for sharing data across scripts:</p>
<pre><code class="lang-csharp">Global[&quot;material&quot;] = &quot;Steel&quot;;
var material = Global[&quot;material&quot;];
</code></pre>
<hr>
<h2 id="full-api-reference">Full API Reference</h2>
<p>For the complete list of available commands, properties, and events, see:</p>
<ul>
<li><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html">SessionShell</a> — full API documentation</li>
<li><a class="xref" href="session-shell.html">SessionShell</a> — the command families, and which workflow uses each</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="session-shell.html">SessionShell</a> — the command families this syntax reaches</li>
<li><a class="xref" href="step.html">Step</a> — machining step data model</li>
<li><a class="xref" href="../../workflows/basic-simulation.html">Workflow: Basic Machining Simulation</a> — using scripts in a simulation workflow</li>
<li><a class="xref" href="cutter-location-playback.html">Cutter-Location (CL) Playback</a> — replaying a CL toolpath from a script</li>
<li><a class="xref" href="shell-progress.html">ShellProgress</a> — the message stream a running script writes to</li>
<li><a class="xref" href="../nc-optimization/nc-optimization-principles.html">NC Optimization</a> — what a per-step optimization option does, and how a step that fails to solve is reported</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>SessionShell | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="SessionShell | 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="Glossary-SessionShell">
<h1 id="sessionshell">SessionShell</h1>
<p><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html">SessionShell</a> is the global scope of the HiNC scripting engine: a script names its members directly, with no object reference and no <code>using</code>. Everything a script does to a session — start a playback, set a resolution, export a file, train a coefficient, read a step — is a member of this one type.</p>
<p>The complete and current list of commands, properties and events is the generated <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html">SessionShell</a> reference. This page is the map onto it — which family does what, and which workflow reaches for it. The members are deliberately not re-listed here: a hand-copied index of an API drifts the moment the API changes, and nothing in the build can catch it.</p>
<h2 id="command-families">Command Families</h2>
<table>
<thead>
<tr>
<th>Family</th>
<th>What it does</th>
<th>Where it is used</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Playback</strong></td>
<td>Runs a program — NC files and NC strings, CSV-driven playback, cutter-location files, and tool teleports. Parse-only variants return the action sequence without pacing it.</td>
<td><a class="xref" href="../../workflows/basic-simulation.html">Workflow: Basic Machining Simulation</a>, <a class="xref" href="cutter-location-playback.html">Cutter-Location (CL) Playback</a></td>
</tr>
<tr>
<td><strong>Player control</strong></td>
<td>Paces, pauses and resets the running player: the checkpoints a script inserts into a playback.</td>
<td><a class="xref" href="../../workflows/basic-simulation.html">Workflow: Basic Machining Simulation</a></td>
</tr>
<tr>
<td><strong>Resolution and cache</strong></td>
<td>Workpiece entity resolution, motion resolution mode, display cache size. The largest single influence a script has on run time.</td>
<td><a class="xref" href="../../workflows/basic-simulation.html">Workflow: Basic Machining Simulation</a>, <a class="xref" href="../simulation-performance/cpu-usage.html">CPU Usage During Simulation</a></td>
</tr>
<tr>
<td><strong>Physics switches</strong></td>
<td>Whether milling force, wear effect and collision detection are evaluated; angular divisions per revolution; initial spindle temperature; whether a failure or a collision pauses the run.</td>
<td><a class="xref" href="../../workflows/force-training.html">Workflow: Milling Force Parameter Training</a>, <a class="xref" href="../../workflows/geometry-validation.html">Workflow: Geometry Validation</a></td>
</tr>
<tr>
<td><strong>Data export</strong></td>
<td>Step-level CSV and waveform (shot) CSV, both accepting the <code>[NcName]</code> template.</td>
<td><a class="xref" href="../../workflows/basic-simulation.html">Workflow: Basic Machining Simulation</a>, <a class="xref" href="../../workflows/force-training.html">Workflow: Milling Force Parameter Training</a></td>
</tr>
<tr>
<td><strong>Sensor mapping</strong></td>
<td>Puts measured data alongside the simulated run: one-to-one and series mapping from CSV, time-range selection written into NC comments, and clearing what was mapped.</td>
<td><a class="xref" href="../../workflows/sensor-mapping.html">Workflow: Sensor Data Mapping</a></td>
</tr>
<tr>
<td><strong>Training</strong></td>
<td>Trains milling coefficients from mapped data, calibrates existing ones, and loads cutting parameters into the workpiece.</td>
<td><a class="xref" href="../../workflows/force-training.html">Workflow: Milling Force Parameter Training</a></td>
</tr>
<tr>
<td><strong>Optimization</strong></td>
<td>The optimizer's file output and its whole settings surface — feed-rate and re-interpolation switches, feed and acceleration limits, the four safety factors, the target force, the preserve ranges that exempt lines, and the per-step log.</td>
<td><a class="xref" href="../../workflows/nc-optimization.html">Workflow: NC Optimization</a></td>
</tr>
<tr>
<td><strong>Geometry</strong></td>
<td>Reads, writes and exports meshed geometry (STL / OBJ / PLY), compares the cut against a target, removes disconnected residual material, and scans for defects.</td>
<td><a class="xref" href="../../workflows/geometry-validation.html">Workflow: Geometry Validation</a></td>
</tr>
<tr>
<td><strong>Messages</strong></td>
<td>The four message severities and the file export, all routed through <a class="xref" href="shell-progress.html">ShellProgress</a>.</td>
<td>all workflows</td>
</tr>
<tr>
<td><strong>Step access</strong></td>
<td>Reads a step by index, reports the step count, and registers custom step variables.</td>
<td><a class="xref" href="step.html">Step</a></td>
</tr>
<tr>
<td><strong>Events</strong></td>
<td>Per-step hooks that fire as a step is built or selected.</td>
<td><a class="xref" href="../../workflows/nc-optimization.html">Workflow: NC Optimization</a></td>
</tr>
<tr>
<td><strong>Runtime management</strong></td>
<td>Clears event handlers, buffers and runtime state, and carries data between scripts through the <code>Global</code> dictionary.</td>
<td><a class="xref" href="script-command.html">Script Commands</a></td>
</tr>
<tr>
<td><strong>Tool setup</strong></td>
<td>Adjusts contour shift angle and smart-holder observation height at run time.</td>
<td><a class="xref" href="../measurement/smart-holder-training.html">Smart Tool Holder Coefficient Training</a></td>
</tr>
</tbody>
</table>
<h2 id="what-the-generated-reference-does-not-say">What the Generated Reference Does Not Say</h2>
<ul>
<li><strong>Tool setup is for a mismatch, not for configuration.</strong> Those members exist for the case where the actual installation differs from the configured tool. Where the two agree, set the value in the tool configuration file instead — a script that sets it is silently overriding what everyone else reads.</li>
<li><strong>The geometry family answers to hidden legacy names.</strong> <code>WriteRuntimeGeom</code> / <code>ReadRuntimeGeom</code> / <code>ExportRuntimeGeomTo*</code> / <code>ScanRuntimeGeomInfDefect</code> still run in existing player scripts as aliases of the <code>MeshedGeom</code> names; new scripts use the new names. The full mapping is in <a href="../../release-note/upgrading-to-3.2/breaking-changes.html#5-renames-with-no-shim">Renames with no shim</a>.</li>
<li><strong>Resetting the runtime does not clear the record.</strong> Event handlers, buffers and runtime state go; messages already recorded stay — see <a class="xref" href="shell-progress.html">ShellProgress</a>.</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html">SessionShell</a> — the generated reference this page maps</li>
<li><a class="xref" href="script-command.html">Script Commands</a> — the syntax and lifecycle a command runs inside</li>
<li><a class="xref" href="step.html">Step</a> — the data model the step-access family returns</li>
<li><a class="xref" href="shell-progress.html">ShellProgress</a> — the message host the message family writes 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,239 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ShellProgress | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="ShellProgress | 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="Glossary-ShellProgress">
<h1 id="shellprogress">ShellProgress</h1>
<h2 id="what-is-shellprogress">What Is ShellProgress?</h2>
<p><strong>ShellProgress</strong> (<a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_ShellProgress">ShellProgress</a>) is the message host object that manages all messages generated during a HiNC scripting session. It serves as the central hub for logging, filtering, and exporting diagnostic information.</p>
<div class="NOTE">
<h5>Note</h5>
<p>This host was previously named <code>SessionProgress</code> (and earlier <code>SessionMessageHost</code>); those names are superseded by <code>ShellProgress</code>.</p>
</div>
<hr>
<h2 id="message-types">Message Types</h2>
<p>HiNC provides four message types, each with a distinct severity and typical display behavior:</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Command</th>
<th>Description</th>
<th>Typical Display</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Message</strong></td>
<td><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_Message_">Message</a></td>
<td>General informational message</td>
<td>Message panel</td>
</tr>
<tr>
<td><strong>ProgressMessage</strong></td>
<td><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_ProgressMessage_">ProgressMessage</a></td>
<td>Progress-related status update</td>
<td>Progress bar / status area</td>
</tr>
<tr>
<td><strong>WarningMessage</strong></td>
<td><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_WarningMessage_">WarningMessage</a></td>
<td>Warning (does not interrupt execution)</td>
<td>Message panel (yellow)</td>
</tr>
<tr>
<td><strong>ErrorMessage</strong></td>
<td><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_ErrorMessage_">ErrorMessage</a></td>
<td>Error (may affect execution flow)</td>
<td>Message panel (red)</td>
</tr>
</tbody>
</table>
<h3 id="usage-examples">Usage Examples</h3>
<pre><code class="lang-csharp">Message(&quot;Starting simulation&quot;);
ProgressMessage(&quot;Loading workpiece...&quot;);
WarningMessage(&quot;No cutting engagement detected in this segment&quot;);
ErrorMessage(&quot;Workpiece does not exist&quot;);
</code></pre>
<hr>
<h2 id="message-tags">Message Tags</h2>
<p>Messages can be tagged for filtering. Standard tags include <code>&quot;Error&quot;</code> and <code>&quot;Warning&quot;</code>. When exporting messages, you can filter by one or more tags.</p>
<hr>
<h2 id="displaying-messages">Displaying Messages</h2>
<p>All messages are automatically recorded in the session message host and appear in the HiNC UI <strong>message panel</strong>. Progress messages additionally update the <strong>progress bar</strong>.</p>
<h3 id="accessing-the-message-host">Accessing the Message Host</h3>
<pre><code class="lang-csharp">var messageHost = ShellProgress;
</code></pre>
<hr>
<h2 id="exporting-messages">Exporting Messages</h2>
<p><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_AppendMessagesToFile_">AppendMessagesToFile</a> writes messages to a text file, with optional tag-based filtering:</p>
<pre><code class="lang-csharp">// Export all messages
AppendMessagesToFile(&quot;Output/messages.txt&quot;);
// Export only errors and warnings
AppendMessagesToFile(&quot;Output/errors.txt&quot;, &quot;Error&quot;, &quot;Warning&quot;);
</code></pre>
<div class="TIP">
<h5>Tip</h5>
<p>Export messages after simulation to create a persistent log for debugging or reporting.</p>
</div>
<hr>
<h2 id="common-patterns">Common Patterns</h2>
<h3 id="logging-simulation-progress">Logging Simulation Progress</h3>
<pre><code class="lang-csharp">Message(&quot;Simulation started&quot;);
PlayNcFile(&quot;NC/file1.nc&quot;);
Message($&quot;Simulation complete. Total steps: {StepCount}&quot;);
AppendMessagesToFile(&quot;Output/log.txt&quot;);
</code></pre>
<h3 id="conditional-warnings">Conditional Warnings</h3>
<pre><code class="lang-csharp">if (StepCount == 0)
{
WarningMessage(&quot;No steps were executed&quot;);
}
</code></pre>
<h3 id="error-guard">Error Guard</h3>
<pre><code class="lang-csharp">if (Workpiece == null)
{
ErrorMessage(&quot;Workpiece does not exist&quot;);
return;
}
</code></pre>
<h3 id="per-step-logging-via-events">Per-Step Logging via Events</h3>
<pre><code class="lang-csharp">SessionStepBuilt += (preStep, curStep) =&gt; {
if (curStep != null)
Message($&quot;Step {curStep.StepIndex}: ToolId={curStep.ToolId}&quot;);
};
PlayNcFile(&quot;NC/file1.nc&quot;);
</code></pre>
<h3 id="step-selection-logging">Step Selection Logging</h3>
<pre><code class="lang-csharp">MachiningStepSelected += (step) =&gt; {
if (step != null &amp;&amp; step.ToolId == 1)
ProgressMessage($&quot;Tool 1 step selected at line {step.LineNo}&quot;);
};
</code></pre>
<hr>
<h2 id="message-lifecycle">Message Lifecycle</h2>
<ol>
<li>Messages are generated during script execution via the four message commands</li>
<li>All messages are stored in the <code>ShellProgress</code> host object</li>
<li>Messages persist until the session ends or the runtime is reset</li>
<li><code>ResetRuntime()</code> clears event handlers but does <strong>not</strong> clear previously recorded messages</li>
<li>Messages can be exported at any point using <code>AppendMessagesToFile</code></li>
</ol>
<hr>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="script-command.html">Script Commands</a> — script command basics</li>
<li><a class="xref" href="session-shell.html">SessionShell</a> — SessionShell quick-reference</li>
<li><a class="xref" href="../../workflows/basic-simulation.html">Workflow: Basic Machining Simulation</a> — using messages in a simulation workflow</li>
<li><a href="../api-foundations/message-management.html">Message Management</a> — the three application-level channels this session-scoped host is one face of</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,179 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Step Field Reference | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Step Field Reference | 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="Doc-Step-Fields">
<h1 id="step-field-reference">Step Field Reference</h1>
<p>Every simulated <a class="xref" href="step.html">step</a> carries a row of output: the NC line it came from, the kinematics, the load, and what that load did to the cutter. The field-by-field definitions are generated — <a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html">MachiningStep</a> is the complete and current list, and it is not copied here. This page states what each group covers, how the numbers are to be read, and the two readings that are most often misread.</p>
<h2 id="how-a-steps-numbers-are-formed">How a Step's Numbers Are Formed</h2>
<p>A step's data covers the <strong>time interval between two consecutive steps</strong> — from the previous step to this one — not an instant. Most fields are therefore a simplification over that period, and the prefix says which: <code>Avg</code> (average), <code>Min</code> / <code>Max</code> (extremes), <code>Delta</code> (range) and <code>MaxAbs</code> (maximum absolute value).</p>
<p>A field that depends on a frame carries the frame in its name: <code>[W]</code> workpiece, <code>[TR]</code> tool running, <code>[SR]</code> spindle rotation. The frames themselves are defined in <a class="xref" href="../milling-physics/milling-physics-coordinates.html">Milling Physics Coordinates</a>.</p>
<h2 id="field-groups">Field Groups</h2>
<table>
<thead>
<tr>
<th>Group</th>
<th>What it covers</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Source</strong></td>
<td>The file, line, line text and flags of the NC command that produced the step, its index in the run, and the active tool id</td>
</tr>
<tr>
<td><strong>Time and motion</strong></td>
<td>End-of-step timecode, step duration (one spindle revolution in the default per-revolution mode), spindle angle at the start, the cutter location with its IJK normal, the machine coordinates, the displacement in program coordinates, and the feed / spindle-speed / cutting-speed / per-tooth family</td>
</tr>
<tr>
<td><strong>Engagement and removal</strong></td>
<td>Whether the cutter was engaged at all, radial and axial engagement (ae, ap), material removal rate, and the program-side cusp height and its distribution</td>
</tr>
<tr>
<td><strong>Chip</strong></td>
<td>Chip thickness, volume and mass</td>
</tr>
<tr>
<td><strong>Force and torque</strong></td>
<td>Average and maximum force on the tool, torques about the tool tip and about the sensor point in each frame, and the mapping-comparison fields that put a measured signal beside the simulated one — error ratios and symbolic error correlation</td>
</tr>
<tr>
<td><strong>Power and energy</strong></td>
<td>Spindle input power (what enters the spindle) and output power (what reaches the cut after spindle losses; the ratio between them is the spindle's configured <a class="xref" href="../../api/Hi.Milling.SpindleCapability.html#Hi_Milling_SpindleCapability_EnergyEfficiency">EnergyEfficiency</a><small>(API)</small>), the instantaneous and continuous power and torque ratios against the spindle capability curve, and accumulated energy consumption</td>
</tr>
<tr>
<td><strong>Thermal</strong></td>
<td>Cutter body, cutter surface, workpiece surface and chip temperatures, cutter subsurface temperature at a given depth, and thermal stress with its yield ratio</td>
</tr>
<tr>
<td><strong>Wear and deflection</strong></td>
<td>Instantaneous and accumulated crater wear, accumulated flank wear depth and width, tool tip and bottom-edge deflection, and re-cut depth</td>
</tr>
</tbody>
</table>
<p>For what the thermal yield ratio implies about breakage risk see <a class="xref" href="../milling-physics/machinability.html">Evaluating Process Machinability</a>; for the wear model behind the wear fields see <a class="xref" href="../milling-physics/wear.html">Tool Life and Wear</a>.</p>
<div class="NOTE">
<h5>Note</h5>
<p><code>EndTimecode</code> was named <code>AccumulatedTime</code> before the rename, and step CSVs written with the legacy header are still read.</p>
</div>
<h2 id="two-readings-that-are-usually-misread">Two Readings That Are Usually Misread</h2>
<h3 id="a-cusp-spike-is-usually-a-rapid-move-collision-not-a-finish-result">A cusp spike is usually a rapid-move collision, not a finish result</h3>
<p>The program-side cusp is computed from the <em>ideal program feedrate</em> while the cutter is engaged with the workpiece. A rapid traverse is not meant to touch material; when it does, the cusp formula is fed the (very high) rapid feedrate, so the value spikes far above any real cutting cusp. Treat an isolated cusp peak at a rapid / G00 line as a likely gouge or collision to investigate. The same engagement-during-rapid usually shows up beside it as spikes in the availability ratios — yielding stress, spindle torque, spindle power.</p>
<h3 id="a-power-or-torque-ratio-over-100-is-load-damage-and-it-is-read-by-duration">A power or torque ratio over 100% is load damage, and it is read by duration</h3>
<p>A ratio above 100% means the spindle cannot supply the demanded load at the commanded rpm, so it droops: with feed held, rpm drops, feed-per-tooth rises, and forces climb further — a runaway loop that, left unchecked, grows the chip until the cutter breaks and the spindle and drive are overstressed. That is load damage, not a tool-versus-workpiece collision (see <a class="xref" href="../nc-optimization/nc-optimization-principles.html">NC optimization</a>).</p>
<p>Read it by <em>duration</em>, not just by height. A one-revolution overshoot usually still completes the pass, leaving a slightly insufficient cut there; a ratio that stays above 100% across many consecutive spindle revolutions is a genuine overload to fix. A high-load step typically also shows large cutterworkpiece engagement, large tip deflection, and more vibration and noise. Because the ratio is normalized by the spindle-capability curve, a placeholder or guessed spindle skews it — confirm against the real spindle's speedpower and speedtorque curves before calling a cut overloaded.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="step.html">Step</a> — what a step is, and when one is produced</li>
<li><a class="xref" href="../machine-capability/spindle-capability.html">Spindle Capability</a> — the curves that normalize the power and torque ratios above</li>
<li><a class="xref" href="../milling-physics/milling-physics-coordinates.html">Milling Physics Coordinates</a> — what the <code>[W]</code> / <code>[TR]</code> / <code>[SR]</code> marks on these fields mean</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,207 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Step | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Step | 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="Glossary-Step">
<h1 id="step">Step</h1>
<h2 id="what-is-a-step">What Is a Step?</h2>
<p>A <strong>MachiningStep</strong> (<a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html">MachiningStep</a>) is a single computation unit in the HiNC simulation. By default, one step corresponds to one spindle revolution, but this interval is configurable via the <a href="../../workflows/basic-simulation.html">Basic Simulation</a> workflow.</p>
<p>Each step contains data for the <strong>time interval</strong> between two consecutive steps (from the previous step to the current step). Since this represents a period rather than an instant, many fields are simplified representations using prefixes like Average (Avg), Extremes (Min, Max), Range (Delta), and Maximum Absolute Value (MaxAbs).</p>
<hr>
<h2 id="registering-custom-step-variables">Registering Custom Step Variables</h2>
<p>Beyond default properties, you can register custom step variables using <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_RegisterStepVariable_">RegisterStepVariable</a>:</p>
<pre><code class="lang-csharp">RegisterStepVariable(
&quot;ChipVolume&quot;, // key
&quot;Chip Volume&quot;, // display name
&quot;mm3&quot;, // unit
&quot;F2&quot;, // format string
(step) =&gt; step.ChipVolume_mm3 // value function
);
PlayNcFile(&quot;NC/file1.nc&quot;);
</code></pre>
<p>Parameters:</p>
<ul>
<li><strong>key</strong>: Unique identifier</li>
<li><strong>name</strong>: Display name (shown in UI)</li>
<li><strong>unit</strong>: Physical unit (can be null)</li>
<li><strong>formatString</strong>: .NET numeric format string (can be null)</li>
<li><strong>variableFunction</strong>: Lambda that computes the value from a step (can be null)</li>
</ul>
<p>Registered variables appear in the UI and in output files from <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_WriteStepFiles_">WriteStepFiles</a>.</p>
<h3 id="indexer-access">Indexer Access</h3>
<p>Use the <a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html#Hi_MachiningSteps_MachiningStep_Item_System_String_">this[string]</a> indexer to read/write custom data on a step:</p>
<pre><code class="lang-csharp">SessionStepBuilt += (preStep, curStep) =&gt; {
if (curStep != null)
curStep[&quot;MyCustomField&quot;] = someCalculation();
};
</code></pre>
<hr>
<h2 id="accessing-step-data">Accessing Step Data</h2>
<h3 id="getmillingstep">GetMillingStep</h3>
<p><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_GetMillingStep_">GetMillingStep</a> retrieves a step by index:</p>
<pre><code class="lang-csharp">var step = GetMillingStep(100);
if (step != null)
{
Message($&quot;ToolId={step.ToolId}, Force={step.MaxAbsForce_N} N&quot;);
}
</code></pre>
<h3 id="stepcount">StepCount</h3>
<p><a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_StepCount">StepCount</a> returns the total number of steps:</p>
<pre><code class="lang-csharp">Message($&quot;Total steps: {StepCount}&quot;);
</code></pre>
<h3 id="iterating-all-steps">Iterating All Steps</h3>
<pre><code class="lang-csharp">for (int i = 0; i &lt; StepCount; i++)
{
var step = GetMillingStep(i);
// process step...
}
</code></pre>
<hr>
<h2 id="step-output-files">Step Output Files</h2>
<p>Steps can be exported to CSV using <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_WriteStepFiles_">WriteStepFiles</a>:</p>
<pre><code class="lang-csharp">WriteStepFiles(&quot;Output/[NcName].step.csv&quot;);
</code></pre>
<p>The CSV contains all default properties plus any registered custom variables. The file can be read back with <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_PlayCsvFile_">PlayCsvFile</a>.</p>
<p>For waveform-level data (sub-step time resolution), use <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_WriteShotFiles_">WriteShotFiles</a>:</p>
<pre><code class="lang-csharp">WriteShotFiles(&quot;Output/[NcName].shot.csv&quot;, 1); // 1 ms time resolution
</code></pre>
<hr>
<h2 id="dynamically-registered-variables-training">Dynamically Registered Variables (Training)</h2>
<p>After executing <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_TrainMillingPara_">TrainMillingPara</a> or <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_ReTrainMillingPara_">ReTrainMillingPara</a>, two additional step variables are automatically registered for steps within the training region:</p>
<table>
<thead>
<tr>
<th>Variable</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>TrainingErrRatio</code></td>
<td>Error metric between simulation and measurement for each step</td>
</tr>
<tr>
<td><code>AngleOffset</code></td>
<td>Cutter rotation phase difference between measured and simulated data</td>
</tr>
</tbody>
</table>
<hr>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="step-fields.html">Step Field Reference</a> — complete field reference</li>
<li><a class="xref" href="session-shell.html">SessionShell</a> — SessionShell quick-reference</li>
<li><a class="xref" href="../../workflows/basic-simulation.html">Workflow: Basic Machining Simulation</a> — simulation workflow producing steps</li>
<li><a class="xref" href="../../workflows/force-training.html">Workflow: Milling Force Parameter Training</a> — training workflow that adds step variables</li>
<li><a class="xref" href="script-command.html">Script Commands</a> — the script command that drives a session</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,40 @@
<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="script-command.html" name="" title="Script Command">Script Command</a>
</li>
<li>
<a href="session-shell.html" name="" title="SessionShell">SessionShell</a>
</li>
<li>
<a href="step.html" name="" title="Step">Step</a>
</li>
<li>
<a href="step-fields.html" name="" title="Step Field Reference">Step Field Reference</a>
</li>
<li>
<a href="shell-progress.html" name="" title="ShellProgress">ShellProgress</a>
</li>
<li>
<a href="cutter-location-playback.html" name="" title="Cutter-Location (CL) Playback">Cutter-Location (CL) Playback</a>
</li>
</ul>
</div>
</div>
</div>
</div>
@@ -0,0 +1,2 @@
{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"Script Command","href":"script-command.html","topicHref":"script-command.html"},{"name":"SessionShell","href":"session-shell.html","topicHref":"session-shell.html"},{"name":"Step","href":"step.html","topicHref":"step.html"},{"name":"Step Field Reference","href":"step-fields.html","topicHref":"step-fields.html"},{"name":"ShellProgress","href":"shell-progress.html","topicHref":"shell-progress.html"},{"name":"Cutter-Location (CL) Playback","href":"cutter-location-playback.html","topicHref":"cutter-location-playback.html"}]}
Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

@@ -0,0 +1,172 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CPU Usage During Simulation | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="CPU Usage During Simulation | 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="Technique-CpuUsage">
<h1 id="cpu-usage-during-simulation">CPU Usage During Simulation</h1>
<h2 id="simulation-computation-threads">Simulation Computation Threads</h2>
<p>Time-series data is computed on a single thread (using only one CPU core at a time); other data can be computed in parallel.</p>
<h3 id="geometry-removal">Geometry Removal</h3>
<p>Geometry removal is single-threaded because sequential cutting is required to obtain the correct CWE (Cutter-Workpiece Engagement). The workpiece geometry surface after removal appears in light pink, which typically indicates that the physics for that region have not yet been computed.</p>
<h3 id="physics-computation">Physics Computation</h3>
<p>Cutting force computation begins after CWE is obtained. Since it is independent of computation order, it runs in multi-threaded mode under normal conditions. Torque and other physical quantities are also computed in parallel during this stage.</p>
<p>Temperature computation must follow time-series order, so it converges back to a single thread.</p>
<p>The entire machining simulation alternates between these modes. Once a step is fully computed, it is colored according to the designated indicator.</p>
<h2 id="two-independent-cost-drivers">Two Independent Cost Drivers</h2>
<p>Total simulation time comes from two largely independent parts:</p>
<ul>
<li><strong>Per-step physics</strong> (force, torque, power, temperature, wear) — computed once per <strong>step</strong>. The total physics cost scales with the <strong>number of steps</strong>, which is set by the <a href="../../workflows/basic-simulation.html#33-machining-motion-resolution">machining motion resolution</a> together with the spindle revolutions along the toolpath. It does <strong>not</strong> depend on the mesh resolution, and it does <strong>not</strong> depend on the overall workpiece size.</li>
<li><strong>Geometry removal</strong> (voxel subtraction) — its cost is set by the mesh resolution (<a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_MachiningResolution_mm">MachiningResolution_mm</a>). A finer mesh (smaller value) is more expensive; a coarser mesh (larger value) is cheaper. Removal work is localized to the toolworkpiece contact region, so it is roughly area-scaled and, again, largely independent of the bulk workpiece size.</li>
</ul>
<p><code>MachiningResolution_mm</code> genuinely controls the removal resolution — it is <strong>not</strong> clamped away or ignored. But because removal and physics run concurrently, the <strong>larger</strong> of the two costs governs wall-clock time:</p>
<ul>
<li>When geometry removal dominates — <strong>the common case at the fine resolutions real NC machining needs</strong> — a finer mesh is much slower, and a coarser mesh reduces total time.</li>
<li>When the mesh is coarse enough that geometry removal is already cheap, several <strong>fixed per-step costs</strong> (physics, thermal/wear, per-step bookkeeping) dominate instead. Coarsening further — e.g. raising <code>MachiningResolution_mm</code> from 1.0 to 2.0 mm — then barely changes total time; to speed up, <strong>reduce the number of steps</strong> with a coarser motion resolution. (Note: 12 mm is already very coarse for NC machining.)</li>
</ul>
<h2 id="cpu-usage">CPU Usage</h2>
<h3 id="coarse-mesh--physics-bound">Coarse Mesh — Physics-Bound</h3>
<p>When the mesh is coarse (a large <code>MachiningResolution_mm</code>), geometry removal is faster than physics computation, so a large area of light pink follows behind the tool during simulation. There is a cap on the number of unfinished steps; geometry removal only proceeds when the count is within that limit. When physics computation cannot keep up with geometry removal, the number of pink steps stays constant.</p>
<p>In this scenario, the workload is primarily multi-core (physics computation), and you are more likely to see high multi-core CPU utilization. Making the mesh even coarser will not reduce total time — the step count (physics) is the limit.</p>
<p><img src="cpu-usage-img/geom-quick.png" alt="Coarse mesh: geometry removal outruns physics, leaving a large pink trail"></p>
<h3 id="fine-mesh--geometry-bound">Fine Mesh — Geometry-Bound</h3>
<p>When the mesh is fine (a small <code>MachiningResolution_mm</code>), geometry removal is slower than physics computation, so the light pink area is barely visible.</p>
<p>In this scenario, the workload is primarily single-core (geometry computation), and a coarser mesh will reduce total time.</p>
<p><img src="cpu-usage-img/geom-slow.png" alt="Fine mesh: physics keeps up with geometry removal, almost no pink trail"></p>
<h3 id="balanced-state">Balanced State</h3>
<p>If the geometry resolution is such that geometry and physics computation do not bottleneck each other, the light pink area appears and fluctuates within a certain range. In this case, physics computation does not hold back geometry computation, and geometry computation is typically the performance bottleneck.</p>
<h3 id="optimization--one-burst-then-one-core">Optimization — One Burst, Then One Core</h3>
<p>An NC optimization is not the play loop, and its CPU trace has a different shape. Exactly one of its
stages is parallel: the per-step feed solve, which spreads the played steps across a private pool of
workers running at below-normal thread priority, so it stays behind interactive work on the same
machine. Every stage announced after it — the two feed constraints, the compensation build, the NC
regeneration and the file write — runs on a single thread.</p>
<p>So an optimization shows one multi-core burst and then a single-core tail. A CPU sitting near one
core's worth of load for the rest of the run is the expected shape, not a stalled run.</p>
<p>The host setting <code>HiNC:OptCoreNum</code> sizes that one parallel stage. The shipped value <code>0</code> gives it one
worker per logical processor; any other value caps it at that many workers, which leaves more of the
machine for other work and lengthens the burst. It changes nothing else: not the single-threaded
stages that follow, and not the simulation loop above.</p>
<h3 id="cpu-not-fully-utilized">CPU Not Fully Utilized</h3>
<p>Possible reasons why the CPU is not fully utilized include:</p>
<ul>
<li>The operating system reserves headroom to ensure the GUI remains responsive. For example, Windows desktop applications (such as WPF) lower the priority of non-GUI threads by one level.</li>
<li>The software/hardware throughput has reached its limit for the process.
The reported CPU usage may not reach 100%, but other resources such as cache and bus bandwidth may be saturated. System-level factors like branch misprediction are also not reflected in the reported CPU usage.</li>
</ul>
<p>There is no setting that changes either of these. A CPU that looks idle during an NC optimization is
a different question, and it is answered by the stage shape above rather than by this list.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../milling-physics/machinability.html">Process Machinability</a> — the mesh-quantization ripple a finer mesh removes, and what that costs in removal time</li>
<li><a class="xref" href="../machine-capability/spindle-capability.html">Spindle Capability</a> — the other throughput ceiling in the loop: what the spindle can deliver, rather than what the workstation can compute</li>
<li><a href="mesh-resolution.html">Mesh Resolution</a> — choosing the value that decides which of the two cost drivers above is in the way</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,128 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Simulation Performance | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Simulation Performance | 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="">
<h1 id="simulation-performance">Simulation Performance</h1>
<p>What the simulation costs to run, and what it gives up when it is made cheaper. Two settings
account for nearly all of it — the mesh resolution and the number of steps — and they bottleneck
independently, so making a run faster starts with knowing which of the two is currently in the
way.</p>
<p>Ordered from the machine doing the work to the setting chosen before the run starts.</p>
<ul>
<li><a href="cpu-usage.html">CPU Usage During Simulation</a> — Why a run is slow while the CPU is not saturated: single-threaded geometry removal against multi-threaded physics, and the two independent cost drivers</li>
<li><a href="mesh-resolution.html">Mesh Resolution</a> — Choosing a mesh width: what it costs in run time, how little it moves the physics, and the one kind of geometry it can make disappear</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="../machine-capability/index.html">Machine Capability</a> — the ceilings of the machine being simulated, as opposed to the workstation simulating it</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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Some files were not shown because too many files have changed in this diff Show More