This commit is contained in:
2025-12-22 23:35:40 +08:00
parent 32ff8b45e3
commit 4556281c0a
77 changed files with 9248 additions and 3996 deletions
@@ -90,7 +90,7 @@
<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.Wpf</code> packages, rather than creating your own. These implementations are fully tested, optimized, and maintained.</p>
<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>
@@ -92,7 +92,7 @@
<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.Wpf</code> for WPF 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>
@@ -159,7 +159,7 @@ 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.Wpf.Disp;
using Hi.WpfPlus.Disp;
// Create displayee object
var displayee = new MyCompositeDisplayee();
@@ -117,7 +117,7 @@
</ol>
<div class="NOTE">
<h5>Note</h5>
<p>Add <code>Hi.Wpf</code> packages to the project if the building WPF project.</p>
<p>Add <code>Hi.WpfPlus</code> packages to the project if the building WPF project.</p>
</div>
</li>
<li>Create Main Window, set the layout according to <a href="main-panel.html#main-panel-layout">Main Panel Layout</a>.</li>
@@ -114,7 +114,7 @@
<li>Machine Tool MenuItem
Open <a href="mech/machining-chain-page.html">Machine Tool Page</a>
Sole window in WPF app.
The page manages <a class="xref" href="../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_MachiningEquipment">MachiningEquipment</a>.&lt;Hi.Machining.MachiningEquipmentUtils.MachiningEquipment.MachiningChain&gt;.</li>
The page manages &lt;xref:Hi.MachiningProcs.MachiningProject.MachiningEquipment&gt;.&lt;Hi.Machining.MachiningEquipmentUtils.MachiningEquipment.MachiningChain&gt;.</li>
<li>Controller MenuItem
Open <a href="controller/index.html">Controller Page</a></li>
<li>Tool House MenuItem</li>
@@ -174,7 +174,7 @@ The model is <a class="xref" href="../../../../../api/Hi.Milling.Cutters.Milling
<li>Minimum Available Cutting Thickness (μm)
<ul>
<li>Readonly field with format &ldquo;G4&rdquo;</li>
<li>Shows calculated value from <a class="xref" href="../../../../../api/Hi.Milling.Cutters.MillingCutter.html#Hi_Milling_Cutters_MillingCutter_GetMinimumUncutChipThickness_um_Hi_MillingForces_Fittings_ICuttingPara_">GetMinimumUncutChipThickness_um(ICuttingPara)</a>. The argument (cutting parameter) is obtained by the <a class="xref" href="../../../../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a>.<a class="xref" href="../../../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_Workpiece_">Workpiece</a>.<a class="xref" href="../../../../../api/Hi.NcMech.Workpieces.Workpiece.html#Hi_NcMech_Workpieces_Workpiece_CuttingPara">CuttingPara</a>. Series pass the models by the GUI if needed.</li>
<li>Shows calculated value from <a class="xref" href="../../../../../api/Hi.Milling.Cutters.MillingCutter.html#Hi_Milling_Cutters_MillingCutter_GetMinimumUncutChipThickness_um_Hi_MillingForces_Fittings_ICuttingPara_">GetMinimumUncutChipThickness_um(ICuttingPara)</a>. The argument (cutting parameter) is obtained by the <a class="xref" href="../../../../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a>.&lt;xref:Hi.MachiningProcs.MachiningProject.Workpiece*&gt;.<a class="xref" href="../../../../../api/Hi.NcMech.Workpieces.Workpiece.html#Hi_NcMech_Workpieces_Workpiece_CuttingPara">CuttingPara</a>. Series pass the models by the GUI if needed.</li>
<li>Note Label
<ul>
<li>Show Workpiece Cutting Parameter Name.
@@ -383,7 +383,7 @@ Apply <a class="xref" href="../../../../../api/Hi.Physics.CoatingMaterial.html">
<li>Limit by Theoretical Minimum Feed Per Tooth Checkbox
<ul>
<li>Shows calculated minimum uncut chip thickness value.
To get the value, <a class="xref" href="../../../../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a>.<a class="xref" href="../../../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_Workpiece_">Workpiece</a>.<a class="xref" href="../../../../../api/Hi.NcMech.Workpieces.Workpiece.html#Hi_NcMech_Workpieces_Workpiece_CuttingPara_">CuttingPara</a> and <a class="xref" href="../../../../../api/Hi.Milling.Cutters.MillingCutter.html">MillingCutter</a> are required. Series pass the model by the GUI if needed.</li>
To get the value, <a class="xref" href="../../../../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a>.&lt;xref:Hi.MachiningProcs.MachiningProject.Workpiece*&gt;.<a class="xref" href="../../../../../api/Hi.NcMech.Workpieces.Workpiece.html#Hi_NcMech_Workpieces_Workpiece_CuttingPara_">CuttingPara</a> and <a class="xref" href="../../../../../api/Hi.Milling.Cutters.MillingCutter.html">MillingCutter</a> are required. Series pass the model by the GUI if needed.</li>
<li>When checked, enforces minimum feed constraint</li>
</ul>
</li>
@@ -89,7 +89,7 @@
<p>The page triggers by <a href="../main-panel.html">Main Panel</a>.</p>
<p>The key model is <a class="xref" href="../../../../api/Hi.NcMech.Fixtures.Fixture.html">Fixture</a> and <a class="xref" href="../../../../api/Hi.NcMech.Fixtures.FixtureEditorDisplayeeConfig.html">FixtureEditorDisplayeeConfig</a>.
Fixture is assigned from the Main Panel's <a class="xref" href="../../../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a>.<a class="xref" href="../../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_MachiningEquipment">MachiningEquipment</a>.<a class="xref" href="../../../../api/Hi.Machining.MachiningEquipmentUtils.MachiningEquipment.html#Hi_Machining_MachiningEquipmentUtils_MachiningEquipment_Fixture">Fixture</a>.</p>
Fixture is assigned from the Main Panel's <a class="xref" href="../../../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a>.&lt;xref:Hi.MachiningProcs.MachiningProject.MachiningEquipment&gt;.<a class="xref" href="../../../../api/Hi.Machining.MachiningEquipmentUtils.MachiningEquipment.html#Hi_Machining_MachiningEquipmentUtils_MachiningEquipment_Fixture">Fixture</a>.</p>
<p><a class="xref" href="../../../../api/Hi.NcMech.Fixtures.FixtureEditorDisplayeeConfig.html">FixtureEditorDisplayeeConfig</a> is from &lt;xref:Hi.HiNcKits.AppService&gt;.&lt;xref:Hi.HiNcKits.AppConfig&gt; which assigned from the parent component.</p>
<h2 id="layout">Layout</h2>
<ul>
@@ -89,7 +89,7 @@
<p>The page triggers by <a href="../main-panel.html">Main Panel</a>.</p>
<p>The key model is <a class="xref" href="../../../../api/Hi.NcMech.Workpieces.Workpiece.html">Workpiece</a> and <a class="xref" href="../../../../api/Hi.NcMech.Workpieces.WorkpieceEditorDisplayeeConfig.html">WorkpieceEditorDisplayeeConfig</a>.
Which is assigned from the Main Panel's <a class="xref" href="../../../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a>.<a class="xref" href="../../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_Workpiece">Workpiece</a>.</p>
Which is assigned from the Main Panel's <a class="xref" href="../../../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a>.&lt;xref:Hi.MachiningProcs.MachiningProject.Workpiece&gt;.</p>
<p><a class="xref" href="../../../../api/Hi.NcMech.Fixtures.FixtureEditorDisplayeeConfig.html">FixtureEditorDisplayeeConfig</a> is from &lt;xref:Hi.HiNcKits.AppService&gt;.&lt;xref:Hi.HiNcKits.AppConfig&gt; which assigned from the parent component.</p>
<h2 id="layout">Layout</h2>
<ul>
@@ -113,7 +113,7 @@
<li>Pause</li>
</ul>
</li>
<li>Both webservice and win-desktop applications use <a class="xref" href="../../../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> events for monitoring <a class="xref" href="../../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PacePlayer">PacePlayer</a> status changes.</li>
<li>Both webservice and win-desktop applications use <a class="xref" href="../../../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> events for monitoring &lt;xref:Hi.MachiningProcs.MachiningProject.PacePlayer&gt; status changes.</li>
<li>In webservice applications, the <code>PlayerStatusService</code> subscribes to these <a class="xref" href="../../../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> events and broadcasts status changes via <code>PlayerStatusHub</code> using SignalR for real-time communication.</li>
<li>Win-desktop applications can directly subscribe to <a class="xref" href="../../../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> events for status updates.</li>
<li>Alter the background color of the <code>Status Text Field</code> if the status changed.
@@ -162,7 +162,7 @@
<li>Players/PlayerStatusService.cs</li>
</ul>
<h4 id="signalr-implementation-webapi-only">SignalR Implementation (Webapi Only)</h4>
<p><code>PlayerStatusHub</code> provides real-time player status updates, with methods <code>GetPlayerStatus()</code> and event <code>PlayerStatusUpdated</code>. <code>PlayerStatusService</code> monitors <a class="xref" href="../../../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> events (<a class="xref" href="../../../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_PacePlayer_IsRunningChangedEvent">PacePlayer_IsRunningChangedEvent</a>, <a class="xref" href="../../../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_PacePlayer_IsLockedChangedEvent">PacePlayer_IsLockedChangedEvent</a>, <a class="xref" href="../../../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_PacePlayer_IsFinishedChangedEvent">PacePlayer_IsFinishedChangedEvent</a>, <a class="xref" href="../../../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_PacePlayer_ResetedEvent">PacePlayer_ResetedEvent</a>) and broadcasts changes via SignalR. The JavaScript component connects to <code>/playerStatusHub</code> and listens for status updates. API endpoints include <code>/api/player/start</code>, <code>/api/player/pause</code>, <code>/api/player/resume</code>, <code>/api/player/run-line</code>, <code>/api/player/run-step</code>, <code>/api/player/stop</code>, and <code>/api/player/reset</code>.</p>
<p><code>PlayerStatusHub</code> provides real-time player status updates, with methods <code>GetPlayerStatus()</code> and event <code>PlayerStatusUpdated</code>. <code>PlayerStatusService</code> monitors <a class="xref" href="../../../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> events (&lt;xref:Hi.MachiningProcs.LocalProjectService.PacePlayer_IsRunningChangedEvent&gt;, &lt;xref:Hi.MachiningProcs.LocalProjectService.PacePlayer_IsLockedChangedEvent&gt;, &lt;xref:Hi.MachiningProcs.LocalProjectService.PacePlayer_IsFinishedChangedEvent&gt;, &lt;xref:Hi.MachiningProcs.LocalProjectService.PacePlayer_ResetedEvent&gt;) and broadcasts changes via SignalR. The JavaScript component connects to <code>/playerStatusHub</code> and listens for status updates. API endpoints include <code>/api/player/start</code>, <code>/api/player/pause</code>, <code>/api/player/resume</code>, <code>/api/player/run-line</code>, <code>/api/player/run-step</code>, <code>/api/player/stop</code>, and <code>/api/player/reset</code>.</p>
<h3 id="razor-page-source-code">Razor Page Source Code</h3>
<pre><code class="lang-csharp" name="SampleCode-razor">@using Hi.Common.PathUtils;
@using Hi.HiNcKits;
@@ -173,6 +173,7 @@
@{
MachiningProject machiningProject = hiNcHost.MachiningProject;
var localProjectService = hiNcHost.LocalProjectService;
bool disabledByMachiningProject = machiningProject == null;
}
@@ -186,15 +187,15 @@
&lt;div class=&quot;d-inline-block&quot; style=&quot;width: 4rem&quot;&gt;
@{
if (machiningProject == null) { }
else if (machiningProject.PacePlayer.IsRunning)
else if (localProjectService.PacePlayer.IsRunning)
{
&lt;span class=&quot;badge text-bg-warning&quot;&gt;@Loc[&quot;Running&quot;]&lt;/span&gt;
}
else if (machiningProject.PacePlayer.IsLocked)
else if (localProjectService.PacePlayer.IsLocked)
{
&lt;span class=&quot;badge text-bg-secondary&quot;&gt;@Loc[&quot;Pause&quot;]&lt;/span&gt;
}
else if (machiningProject.PacePlayer.IsFinished)
else if (localProjectService.PacePlayer.IsFinished)
{
&lt;span class=&quot;badge text-bg-success&quot;&gt;@Loc[&quot;Finish&quot;]&lt;/span&gt;
}
@@ -210,11 +211,11 @@
&lt;div id=&quot;player-@Tid&quot; class=&quot;btn-group collapse collapse-horizontal show&quot; role=&quot;group&quot;&gt;
@if (machiningProject == null) { }
else if (!machiningProject.PacePlayer.IsLocked)
else if (!localProjectService.PacePlayer.IsLocked)
{
&lt;button class=&quot;btn btn-primary text-nowrap&quot; title=&quot;@Loc[&quot;Start&quot;] (S)&quot;
accesskey=&quot;s&quot;
disabled=&quot;@(disabledByMachiningProject||machiningProject.PacePlayer.IsFinished)&quot;
disabled=&quot;@(disabledByMachiningProject||localProjectService.PacePlayer.IsFinished)&quot;
@onclick=&quot;StartOrContinue&quot;&gt;
&lt;span class=&quot;oi oi-media-play me-1&quot;&gt;&lt;/span&gt;
&lt;/button&gt;
@@ -224,27 +225,27 @@
&lt;button class=&quot;btn btn-primary text-nowrap&quot; title=&quot;@Loc[&quot;Continue&quot;] (S)&quot;
accesskey=&quot;s&quot;
@onclick=&quot;StartOrContinue&quot;
disabled=&quot;@(disabledByMachiningProject||machiningProject.PacePlayer.IsFinished||machiningProject.PacePlayer.IsRunning)&quot;&gt;
disabled=&quot;@(disabledByMachiningProject||localProjectService.PacePlayer.IsFinished||localProjectService.PacePlayer.IsRunning)&quot;&gt;
&lt;span class=&quot;oi oi-media-play me-1&quot;&gt;&lt;/span&gt;
&lt;/button&gt;
}
&lt;button class=&quot;btn btn-primary text-nowrap&quot; title=&quot;@Loc[&quot;Pause&quot;] (P)&quot;
accesskey=&quot;p&quot;
@onclick=&quot;Pause&quot;
disabled=&quot;@(disabledByMachiningProject||!machiningProject.PacePlayer.IsRunning)&quot;&gt;
disabled=&quot;@(disabledByMachiningProject||!localProjectService.PacePlayer.IsRunning)&quot;&gt;
&lt;span class=&quot;oi oi-media-pause me-1&quot;&gt;&lt;/span&gt;
&lt;/button&gt;
&lt;button class=&quot;btn btn-primary text-nowrap&quot; title=&quot;@Loc[&quot;Run One Line&quot;] (L)&quot;
accesskey=&quot;l&quot;
@onclick=&quot;RunToLineEnd&quot;
disabled=&quot;@(disabledByMachiningProject||machiningProject.PacePlayer.IsFinished)&quot;&gt;
disabled=&quot;@(disabledByMachiningProject||localProjectService.PacePlayer.IsFinished)&quot;&gt;
&lt;span class=&quot;oi oi-media-step-forward me-1&quot;&gt;&lt;/span&gt;
&lt;/button&gt;
&lt;button class=&quot;btn btn-primary text-nowrap&quot; title=&quot;@Loc[&quot;Run One Step&quot;] (K)&quot;
accesskey=&quot;k&quot;
@onclick=&quot;RunToNextPace&quot;
disabled=&quot;@(disabledByMachiningProject||machiningProject.PacePlayer.IsFinished)&quot;&gt;
disabled=&quot;@(disabledByMachiningProject||localProjectService.PacePlayer.IsFinished)&quot;&gt;
&lt;CommonRcl.Shared.CombinedIcon&gt;
&lt;IconA&gt;
&lt;span class=&quot;oi oi-media-step-forward me-1&quot;&gt;&lt;/span&gt;
@@ -259,7 +260,7 @@
&lt;button class=&quot;btn btn-primary text-nowrap&quot; title=&quot;@Loc[&quot;Break&quot;]&quot;
@onclick=&quot;@Break&quot;
disabled=&quot;@(disabledByMachiningProject||!(machiningProject.PacePlayer.IsLocked||machiningProject.PacePlayer.IsFinished))&quot;&gt;
disabled=&quot;@(disabledByMachiningProject||!(localProjectService.PacePlayer.IsLocked||localProjectService.PacePlayer.IsFinished))&quot;&gt;
&lt;span class=&quot;oi oi-media-stop me-1&quot;&gt;&lt;/span&gt;
&lt;/button&gt;
@@ -285,6 +286,7 @@ namespace HiNcRcl.Areas.Player
StringLocalizer Loc { get; } = new StringLocalizer(typeof(PlayerDiv));
SemaphoreSlim DisposeSemaphore { get; } = new SemaphoreSlim(1);
MachiningProject MachiningProject =&gt; hiNcHost.MachiningProject;
LocalProjectService LocalProjectService =&gt; hiNcHost.LocalProjectService;
bool disposedValue = false;
/// &lt;inheritdoc/&gt;
protected override async Task OnAfterRenderAsync(bool firstRender)
@@ -297,11 +299,11 @@ namespace HiNcRcl.Areas.Player
var machiningProject = MachiningProject;
if (machiningProject != null)
{
machiningProject.PacePlayer.IsLockedChangedEvent
LocalProjectService.PacePlayer.IsLockedChangedEvent
+= EnumerablePlayer_IsLockedEventHandler;
machiningProject.PacePlayer.IsRunningChangedEvent
LocalProjectService.PacePlayer.IsRunningChangedEvent
+= EnumerablePlayer_IsLockedEventHandler;
machiningProject.PacePlayer.IsFinishedChangedEvent
LocalProjectService.PacePlayer.IsFinishedChangedEvent
+= EnumerablePlayer_IsLockedEventHandler;
}
}
@@ -314,11 +316,11 @@ namespace HiNcRcl.Areas.Player
var machiningProject = MachiningProject;
if (machiningProject != null)
{
machiningProject.PacePlayer.IsLockedChangedEvent
LocalProjectService.PacePlayer.IsLockedChangedEvent
-= EnumerablePlayer_IsLockedEventHandler;
machiningProject.PacePlayer.IsRunningChangedEvent
LocalProjectService.PacePlayer.IsRunningChangedEvent
-= EnumerablePlayer_IsLockedEventHandler;
machiningProject.PacePlayer.IsFinishedChangedEvent
LocalProjectService.PacePlayer.IsFinishedChangedEvent
-= EnumerablePlayer_IsLockedEventHandler;
}
disposedValue = true;
@@ -333,14 +335,15 @@ namespace HiNcRcl.Areas.Player
{
await Task.Run(() =&gt;
{
if (!MachiningProject.PacePlayer.IsLocked)
var pacePlayer = LocalProjectService.PacePlayer;
if (!pacePlayer.IsLocked)
{
MachiningProject.PacePlayer.Start();
pacePlayer.Start();
}
else if (!MachiningProject.PacePlayer.IsRunning
&amp;&amp; !MachiningProject.PacePlayer.IsFinished)
else if (!pacePlayer.IsRunning
&amp;&amp; !pacePlayer.IsFinished)
{
MachiningProject.PacePlayer.Resume();
pacePlayer.Resume();
}
}).ShowIfCatched(this);
}
@@ -348,35 +351,35 @@ namespace HiNcRcl.Areas.Player
{
await Task.Run(() =&gt;
{
MachiningProject?.PacePlayer.Pause();
LocalProjectService.PacePlayer.Pause();
}).ShowIfCatched(this);
}
public async Task RunToLineEnd()
{
await Task.Run(() =&gt;
{
MachiningProject?.NcRunner.RunToLineEnd();
LocalProjectService.NcRunner.RunToLineEnd();
}).ShowIfCatched(this);
}
public async Task RunToNextPace()
{
await Task.Run(() =&gt;
{
MachiningProject?.PacePlayer.RunToNextPace();
LocalProjectService.PacePlayer.RunToNextPace();
}).ShowIfCatched(this);
}
public async Task Break()
{
await Task.Run(() =&gt;
{
MachiningProject?.PacePlayer.Terminate();
LocalProjectService.PacePlayer.Terminate();
}).ShowIfCatched(this);
}
public async Task Reset()
{
await Task.Run(() =&gt;
{
MachiningProject?.PacePlayer.Reset();
LocalProjectService.PacePlayer.Reset();
}).ShowIfCatched(this);
}
}
@@ -89,7 +89,7 @@
<p>The panel locates on the <a href="index.html">Player Panel</a>.</p>
<p>The model is <a class="xref" href="../../../../api/Hi.MachiningSteps.MachiningStep.html">MachiningStep</a> and &lt;xref:Hi.HiNcKits.AppService&gt;.</p>
<p>The <a class="xref" href="../../../../api/Hi.MachiningSteps.MachiningStep.html">MachiningStep</a> is assigned by <a class="xref" href="../../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_ClStrip">ClStrip</a>.<a class="xref" href="../../../../api/Hi.CutterLocations.ClStrips.ClStrip.html#Hi_CutterLocations_ClStrips_ClStrip_PosSelected">PosSelected</a>.</p>
<p>The <a class="xref" href="../../../../api/Hi.MachiningSteps.MachiningStep.html">MachiningStep</a> is assigned by &lt;xref:Hi.MachiningProcs.MachiningProject.ClStrip&gt;.<a class="xref" href="../../../../api/Hi.CutterLocations.ClStrips.ClStrip.html#Hi_CutterLocations_ClStrips_ClStrip_PosSelected">PosSelected</a>.</p>
<p>Show step infomation from &lt;xref:Hi.HiNcKits.AppService&gt;.&lt;xref:Hi.HiNcKits.AppService.DisplayedStepPresentAccessList&gt;.</p>
<p>The resx of <a class="xref" href="../../../../api/Hi.MachiningSteps.MachiningStep.html">MachiningStep</a> contains the translation of <a class="xref" href="../../../../api/Hi.MachiningSteps.PresentAttribute.html">PresentAttribute</a>.<a class="xref" href="../../../../api/Hi.MachiningSteps.PresentAttribute.html#Hi_MachiningSteps_PresentAttribute_Name">Name</a>, apply the translation to the GUI. If the translation not existed, use the original value.</p>
<p>See Also <a href="../preference/step-present-preference-page.html">Step Present Preference Page</a>.</p>
@@ -106,7 +106,7 @@
}
}
</code></pre><h2 id="signalr-implementation-webapi-only">SignalR Implementation (Webapi Only)</h2>
<p><code>SelectedStepInfoHub</code> provides real-time step updates with method <code>GetSelectedStepInfo()</code> and event <code>SelectedStepInfoUpdated</code>. <code>SelectedStepInfoService</code> monitors <a class="xref" href="../../../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_ClStrip_PosSelected">ClStrip_PosSelected</a> and <a class="xref" href="../../../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_ClStrip_MachiningStepSelected">ClStrip_MachiningStepSelected</a> events and broadcasts updates. The JavaScript component connects to <code>/selectedStepInfoHub</code> to receive step change notifications and update the UI accordingly.</p>
<p><code>SelectedStepInfoHub</code> provides real-time step updates with method <code>GetSelectedStepInfo()</code> and event <code>SelectedStepInfoUpdated</code>. <code>SelectedStepInfoService</code> monitors &lt;xref:Hi.MachiningProcs.LocalProjectService.ClStrip_PosSelected&gt; and &lt;xref:Hi.MachiningProcs.LocalProjectService.ClStrip_MachiningStepSelected&gt; events and broadcasts updates. The JavaScript component connects to <code>/selectedStepInfoHub</code> to receive step change notifications and update the UI accordingly.</p>
<h2 id="source-code-path">Source Code Path</h2>
<p>See <a href="../index.html">this page</a> for git repository.</p>
<h3 id="wpf-application-source-code-path">WPF Application Source Code Path</h3>
@@ -217,11 +217,11 @@ Apply <a class="xref" href="../../../../api/Hi.MachiningSteps.PresentAttribute.h
&lt;div class=&quot;@cardTextClass&quot;&gt;
&lt;p class=&quot;@pCalss&quot;&gt;
@{
var mcCodes = HostMachiningProject?.MachiningEquipment?.GetMachiningChain()?.McCodes;
if (mcCodes != null)
{
var mcTransformers = HostMachiningProject
?.MachiningEquipment?.GetMachiningChain()?.McTransformers;
var mcCodes = LocalProjectService.MachiningEquipment?.GetMachiningChain()?.McCodes;
if (mcCodes != null)
{
var mcTransformers = LocalProjectService
?.MachiningEquipment?.GetMachiningChain()?.McTransformers;
for (int i = 0; i &lt; mcCodes.Length; i++)
{
if (mcTransformers[i] == null)
@@ -414,7 +414,7 @@ Apply <a class="xref" href="../../../../api/Hi.MachiningSteps.PresentAttribute.h
{
foreach(var entry in flexDictionary)
{
if(HostMachiningProject?.StepPropertyAccessDictionary.TryGetValue(
if(LocalProjectService.StepPropertyAccessDictionary.TryGetValue(
entry.Key, out var stepPropertyAccess)==true)
{
&lt;div class=&quot;w-auto&quot; title=&quot;@(stepPropertyAccess.PresentAttribute?.Name)&quot;&gt;
@@ -87,7 +87,7 @@
<article data-uid="">
<h1 id="session-message-panel">Session Message Panel</h1>
<p>The model is <a class="xref" href="../../../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a>.<a class="xref" href="../../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_SessionMessageHost">SessionMessageHost</a>.</p>
<p>The model is <a class="xref" href="../../../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a>.&lt;xref:Hi.MachiningProcs.MachiningProject.SessionMessageHost&gt;.</p>
<p><a class="xref" href="../../../../api/Hi.MachiningProcs.MachiningProject.html">MachiningProject</a> is assigned from the <a href="../player/index.html">Player Panel</a>.</p>
<h2 id="layout">Layout</h2>
<ul>
@@ -114,9 +114,9 @@
<h2 id="central-message-table">Central Message Table</h2>
<p>The model of Central Message Table is <a class="xref" href="../../../../api/Hi.MachiningProcs.SessionMessageHost.html">SessionMessageHost</a>.<a class="xref" href="../../../../api/Hi.MachiningProcs.SessionMessageHost.html#Hi_MachiningProcs_SessionMessageHost_MessageCollection">MessageCollection</a>.</p>
<p>Only take last 1000 filtered elements in the <a class="xref" href="../../../../api/Hi.MachiningProcs.SessionMessageHost.html#Hi_MachiningProcs_SessionMessageHost_MessageCollection">MessageCollection</a> by <a class="xref" href="../../../../api/Hi.MachiningProcs.SessionMessageHost.html#Hi_MachiningProcs_SessionMessageHost_GetFliteredList_Hi_MachiningProcs_SessionMessageHost_FilterFlag_System_String_">GetFliteredList(FilterFlag, string)</a> to show for user experience. Find the usage example in the code:</p>
<pre><code class="lang-csharp" name="Demo_UseSessionMessageHost">internal static void DemoUseSessionMessageHost(MachiningProject project)
<pre><code class="lang-csharp" name="Demo_UseSessionMessageHost">internal static void DemoUseSessionMessageHost(LocalProjectService localProjectService)
{
SessionMessageHost sessionMessageHost = project.SessionMessageHost;
SessionMessageHost sessionMessageHost = localProjectService.SessionMessageHost;
SessionMessageHost.FilterFlag filterFlags =
SessionMessageHost.FilterFlag.NC |
@@ -162,7 +162,7 @@
<h2 id="behavior-of-export-button">Behavior of Export Button</h2>
<p>Export ALL filtered elements in the <a class="xref" href="../../../../api/Hi.MachiningProcs.SessionMessageHost.html#Hi_MachiningProcs_SessionMessageHost_MessageCollection">MessageCollection</a> by <a class="xref" href="../../../../api/Hi.MachiningProcs.SessionMessageHost.html#Hi_MachiningProcs_SessionMessageHost_GetFliteredList_Hi_MachiningProcs_SessionMessageHost_FilterFlag_System_String_">GetFliteredList(FilterFlag, string)</a>.</p>
<h2 id="signalr-implementation-webapi-only">SignalR Implementation (Webapi Only)</h2>
<p><code>SessionMessageHub</code> provides real-time message updates with method <code>GetSessionMessages(string filterFlags, string filterText, int limit)</code> and event <code>SessionMessagesUpdated</code>. <code>SessionMessageService</code> monitors <a class="xref" href="../../../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_SessionMessageHost_CollectionItemChanged">SessionMessageHost_CollectionItemChanged</a> and broadcasts updates. The service uses <a class="xref" href="../../../../api/Hi.Common.LooseRunner.html">LooseRunner</a> for non-blocking async operations. The JavaScript component connects to <code>/sessionMessageHub</code> to receive real-time message updates.</p>
<p><code>SessionMessageHub</code> provides real-time message updates with method <code>GetSessionMessages(string filterFlags, string filterText, int limit)</code> and event <code>SessionMessagesUpdated</code>. <code>SessionMessageService</code> monitors &lt;xref:Hi.MachiningProcs.LocalProjectService.SessionMessageHost_CollectionItemChanged&gt; and broadcasts updates. The service uses <a class="xref" href="../../../../api/Hi.Common.LooseRunner.html">LooseRunner</a> for non-blocking async operations. The JavaScript component connects to <code>/sessionMessageHub</code> to receive real-time message updates.</p>
<h2 id="source-code-path">Source Code Path</h2>
<p>See <a href="../index.html">this page</a> for git repository.</p>
<h3 id="wpf-application-source-code-path">WPF Application Source Code Path</h3>
@@ -131,7 +131,7 @@
</ul>
<p>The PlayerCommand is typically a <a class="xref" href="../../../api/Hi.ShellCommands.ListCommand.html">ListCommand</a> that contains a sequence of command entries to be executed during the simulation.</p>
<h2 id="4-run-the-tasks-simulation-and-optimization">4. Run the Tasks (Simulation and Optimization)</h2>
<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.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PacePlayer">PacePlayer</a>.</p>
<p>Run <a class="xref" href="../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_PlayerCommand">PlayerCommand</a> through &lt;xref:Hi.MachiningProcs.MachiningProject.PacePlayer&gt;.</p>
<p>At this stage, the simulation process is similar to video playback, which can be:</p>
<ul>
<li>Started</li>
@@ -141,7 +141,7 @@
<li>Run one step</li>
<li>Reset</li>
</ul>
<p>The <a class="xref" href="../../../api/Hi.MachiningProcs.MachiningProject.html#Hi_MachiningProcs_MachiningProject_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>
<p>The &lt;xref:Hi.MachiningProcs.MachiningProject.PacePlayer&gt; controls the execution pace of the simulation, allowing you to observe the machining process in detail or run it at full speed.</p>
<h3 id="view-the-analysis-during-process-or-result">View the Analysis During Process or Result</h3>
<p><a class="xref" href="../../../api/Hi.MachiningProcs.SessionMessageHost.html">SessionMessageHost</a> contains a sequence of simulation messages and step data, which can be used to monitor and analyze the simulation process and results.</p>
<h2 id="ui-pattern">UI Pattern</h2>
@@ -114,7 +114,7 @@
<pre><code class="lang-xml">&lt;ItemGroup&gt;
&lt;PackageReference Include=&quot;HiNc&quot; Version=&quot;3.1.*&quot; /&gt;
&lt;!--optional--&gt;
&lt;PackageReference Include=&quot;Hi.Wpf&quot; Version=&quot;*&quot; /&gt;
&lt;PackageReference Include=&quot;Hi.WpfPlus&quot; Version=&quot;*&quot; /&gt;
&lt;/ItemGroup&gt;
</code></pre>
</li>
@@ -109,7 +109,7 @@
HiUniNc --&gt; HiNc
HiDisp --&gt; Hi.WinForm
HiDisp --&gt; Hi.Wpf
HiDisp --&gt; Hi.WpfPlus
style HiNc fill:#d3d,stroke:#333,stroke-width:2px
</code></pre>
@@ -117,7 +117,7 @@
<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.Wpf</code> package.</li>
<li>For WPF applications, use the <code>Hi.WpfPlus</code> package.</li>
</ul>
<div class="NOTE">
<h5>Note</h5>
@@ -130,9 +130,9 @@
<li><a href="https://superhightech-gitea.webredirect.org/HiNC-Deploy/Hi.WinForm.git">https://superhightech-gitea.webredirect.org/HiNC-Deploy/Hi.WinForm.git</a></li>
</ul>
</li>
<li>Hi.Wpf
<li>Hi.WpfPlus
<ul>
<li><a href="https://superhightech-gitea.webredirect.org/HiNC-Deploy/Hi.Wpf.git">https://superhightech-gitea.webredirect.org/HiNC-Deploy/Hi.WinForm.git</a></li>
<li><a href="https://superhightech-gitea.webredirect.org/HiNC-Deploy/Hi.WpfPlus.git">https://superhightech-gitea.webredirect.org/HiNC-Deploy/Hi.WpfPlus.git</a></li>
</ul>
</li>
</ul>
@@ -172,9 +172,9 @@ namespace Sample.Common
public static class DemoSessionMessage
{
#region Demo_UseSessionMessageHost
internal static void DemoUseSessionMessageHost(MachiningProject project)
internal static void DemoUseSessionMessageHost(LocalProjectService localProjectService)
{
SessionMessageHost sessionMessageHost = project.SessionMessageHost;
SessionMessageHost sessionMessageHost = localProjectService.SessionMessageHost;
SessionMessageHost.FilterFlag filterFlags =
SessionMessageHost.FilterFlag.NC |
@@ -208,10 +208,10 @@ namespace Sample.Common
}
#endregion
internal static void DemoUseSessionMessageHost2(MachiningProject project)
internal static void DemoUseSessionMessageHost2(LocalProjectService localProjectService)
{
SessionMessageHost sessionMessageHost = project.SessionMessageHost;
IMachiningChain machiningChain = project.MachiningEquipment?.MachiningChain;
SessionMessageHost sessionMessageHost = localProjectService.SessionMessageHost;
IMachiningChain machiningChain = localProjectService.MachiningChain;
PresentAttribute mrrPresent = typeof(MachiningStep).GetProperty(nameof(MachiningStep.Mrr_mm3ds)).GetCustomAttribute&lt;PresentAttribute&gt;();
string mrrUnit = mrrPresent?.TailUnitString;
@@ -155,7 +155,7 @@ Handles common initialization and cleanup tasks for visualization examples.</p>
using Hi.HiNcKits;
using Hi.Licenses;
using Hi.MongoUtils;
using Hi.Wpf.Disp;
using Hi.WpfPlus.Disp;
using System.Windows;
namespace Sample.Disp
@@ -193,11 +193,13 @@ namespace Sample.Machining
static void Main()
{
LocalApp.AppBegin();
LocalProjectService localProjectService = new LocalProjectService();
var projectPath = &quot;C:/HiNC-Projects/NewProject/Main.hincproj&quot;;
var projectDirectory = Path.GetDirectoryName(projectPath);
Console.WriteLine($&quot;Directory of the New Project: {projectDirectory}&quot;);
MachiningProject machiningProject = new MachiningProject(projectDirectory);
localProjectService.LoadProject(projectPath);
MachiningProject machiningProject = localProjectService.MachiningProject;
CylindroidHolder cylindroidHolder = new CylindroidHolder()
{
@@ -205,7 +207,7 @@ namespace Sample.Machining
Cylindroid = new Cylindroid([ new PairZr(0,12),new PairZr(20,12),
new PairZr(20,16),new PairZr(30,16)])
};
machiningProject.MachiningToolHouse = new MachiningToolHouse()
localProjectService.MachiningToolHouse = new MachiningToolHouse()
{
[1] = new MillingTool()
{
@@ -216,13 +218,13 @@ namespace Sample.Machining
},
};
machiningProject.MachiningEquipment.Fixture = new Fixture()
localProjectService.Fixture = new Fixture()
{
Geom = new Box3d(new Vec3d(-40, -40, 0), new Vec3d(40, 40, 10)),
GeomToWorkpieceTransformer = new StaticTranslation(new Vec3d(0, 0, 10)),
};
machiningProject.MachiningEquipment.Workpiece = new Workpiece()
localProjectService.Workpiece = new Workpiece()
{
InitResolution = 0.25,
InitGeom = new Box3d(0, 0, -50, 70, 50, 0),
@@ -230,12 +232,12 @@ namespace Sample.Machining
WorkpieceGeomToFixtureBuckleTransformer = new StaticTranslation(new Vec3d(0, 0, 0)),
};
machiningProject.MachiningEquipment.MachiningChain
localProjectService.MachiningChain
= XFactory.GenByFile&lt;CodeXyzabcMachineTool&gt;(
&quot;Resource&quot;, &quot;MachineTool/PMC-B1/PMC-B1.mt&quot;, GenMode.Default);
machiningProject.MachiningEquipment.MachiningChainFile = &quot;PMC-B1/PMC-B1.mt&quot;;
localProjectService.MachiningChainFile = &quot;PMC-B1/PMC-B1.mt&quot;;
machiningProject.MakeXmlSourceFile(projectPath);
localProjectService.SaveProject();
machiningProject.Dispose();
LocalApp.AppEnd();
@@ -297,14 +297,16 @@ namespace Sample.Machining
static void Main()
{
LocalApp.AppBegin();
LocalProjectService localProjectService = new LocalProjectService();
var projectPath = &quot;C:/HiNC-Projects/NewProject/Main.hincproj&quot;;
var projectDirectory = Path.GetDirectoryName(projectPath);
Console.WriteLine($&quot;Directory of the New Project: {projectDirectory}&quot;);
MachiningProject machiningProject = new MachiningProject(projectDirectory);
localProjectService.LoadProject(projectPath);
MachiningProject machiningProject = localProjectService.MachiningProject;
#region ConfigureMachiningToolHouse
machiningProject.MachiningToolHouse = new MachiningToolHouse()
localProjectService.MachiningToolHouse = new MachiningToolHouse()
{
[1] = new MillingTool()
{
@@ -331,7 +333,7 @@ namespace Sample.Machining
#endregion
#region ConfigureFixture
machiningProject.MachiningEquipment.Fixture = new Fixture()
localProjectService.Fixture = new Fixture()
{
Geom = new Box3d(new Vec3d(-40, -40, 0), new Vec3d(40, 40, 10)),
GeomToWorkpieceTransformer = new StaticTranslation(new Vec3d(0, 0, 10)),
@@ -339,7 +341,7 @@ namespace Sample.Machining
#endregion
#region ConfigureWorkpiece
machiningProject.MachiningEquipment.Workpiece = new Workpiece()
localProjectService.Workpiece = new Workpiece()
{
InitResolution = 0.25,
InitGeom = new Box3d(0, 0, -50, 70, 50, 0),
@@ -353,7 +355,7 @@ namespace Sample.Machining
#endregion
#region ConfigureMachineChain
machiningProject.MachiningEquipment.MachiningChain
localProjectService.MachiningChain
= XFactory.GenByFile&lt;CodeXyzabcMachineTool&gt;(
&quot;Resource&quot;, &quot;MachineTool/PMC-B1/PMC-B1.mt&quot;, GenMode.Default);
#endregion
@@ -155,7 +155,7 @@ using Hi.Geom.Resolution;
using Hi.HiNcKits;
using Hi.MachiningProcs;
using Hi.Numerical.Acts;
using Hi.Wpf.Disp;
using Hi.WpfPlus.Disp;
using HiMachining.Milling;
using System;
using System.IO;
@@ -192,21 +192,21 @@ namespace Sample.Machining
//var projectPath = &quot;C:/HiNC-Projects/DemoStandardPath/Main.hincproj&quot;;
var projectPath = &quot;C:/HiNC-Projects/demo-test-1/Main.hincproj&quot;;
Console.WriteLine($&quot;Load Project: {projectPath}&quot;);
localProjectService.LoadProject(projectPath).ShowIfCatched(null);
localProjectService.LoadProject(projectPath);
var project = localProjectService.MachiningProject;
#endregion
var projectDisplayee = new MachiningProjectDisplayee(()=&gt; localProjectService.MachiningProject);
var projectDisplayee = new MachiningProjectDisplayee(localProjectService);
var device = new ClMillingDevice();
project.MachiningEquipment.MachiningChain = device;
project.ClStrip.IsShowDot = true;
localProjectService.MachiningEquipment.MachiningChain = device;
localProjectService.ClStrip.IsShowDot = true;
double resolution_mm = 0.5;
var projectDir = Path.GetDirectoryName(projectPath);
project.Workpiece.InitGeom = new StlFile(stlFile_CylinderR20, projectDir);
project.Workpiece.IdealGeom = new StlFile(stlFile_CylinderR19, projectDir);
project.Workpiece.InitResolution = resolution_mm;
localProjectService.Workpiece.InitGeom = new StlFile(stlFile_CylinderR20, projectDir);
localProjectService.Workpiece.IdealGeom = new StlFile(stlFile_CylinderR19, projectDir);
localProjectService.Workpiece.InitResolution = resolution_mm;
RuntimeApi runtimeApi = project.RuntimeApi;
RuntimeApi runtimeApi = localProjectService.RuntimeApi;
runtimeApi.SetNcResolutionFixed(9999, 15);
runtimeApi.EnableCollisionDetection = false;
runtimeApi.EnablePhysics = false;
@@ -215,13 +215,13 @@ namespace Sample.Machining
//RunConsole(project, projectDisplayee, resolution_mm);
RunWindow(localProjectService, projectDisplayee, resolution_mm);
}
static void RunConsole(IProjectService projectService,
static void RunConsole(LocalProjectService projectService,
MachiningProjectDisplayee projectDisplayee, double resolution_mm)
{
RunSession(projectService, resolution_mm);
DispEngine dispEngine = new DispEngine(projectDisplayee);
dispEngine.SetViewToIsometricView();
dispEngine.SketchView = projectService.MachiningProject.ClStrip.GetFittingView(dispEngine.SketchView);
dispEngine.SketchView = projectService.ClStrip.GetFittingView(dispEngine.SketchView);
dispEngine.SketchView = dispEngine.SketchView.Scale(0.5);
dispEngine.Snapshot($&quot;Cache/result.bmp&quot;, 1000, 1000);
@@ -229,7 +229,7 @@ namespace Sample.Machining
LocalApp.AppEnd();
Console.WriteLine($&quot;App exit.&quot;);
}
static void RunWindow(IProjectService projectService,
static void RunWindow(LocalProjectService projectService,
MachiningProjectDisplayee projectDisplayee, double resolution_mm)
{
var task = Task.Run(() =&gt;
@@ -256,16 +256,16 @@ namespace Sample.Machining
});
#endregion
}
static void RunSession(IProjectService projectService, double resolution_mm)
static void RunSession(LocalProjectService localProjectService, double resolution_mm)
{
var project=projectService.MachiningProject;
RuntimeApi runtimeApi = project.RuntimeApi;
var project=localProjectService.MachiningProject;
RuntimeApi runtimeApi = localProjectService.RuntimeApi;
project.BeginSession();
localProjectService.BeginSession();
double radius = 20;
double z = -1;
project.Act(new ActToolingTeleport(1));//equip tool
project.Act(new ActClTeleport(new DVec3d(radius, 0, z, 0, 0, 1)));//goto initial position
localProjectService.Act(new ActToolingTeleport(1));//equip tool
localProjectService.Act(new ActClTeleport(new DVec3d(radius, 0, z, 0, 0, 1)));//goto initial position
//run an arbitrary contour.
int divNum = 36;
for (int i = 0; i &lt;= divNum; i++)
@@ -275,16 +275,16 @@ namespace Sample.Machining
radius * Math.Sin(i * Math.PI * 2 / divNum), z,
0, 0, 1);
Console.WriteLine($&quot;{cl.Point.CsvText},{cl.Normal.CsvText},&quot;);
project.Act(new ActClStep(cl));
localProjectService.Act(new ActClStep(cl));
}
double diffLimit_mm = resolution_mm * 2;
runtimeApi.Diff(resolution_mm * 2);
Console.WriteLine($&quot;IsDifferenceAceptable: {IsDifferenceAceptable(project, diffLimit_mm)}&quot;);
project.EndSession();
Console.WriteLine($&quot;IsDifferenceAceptable: {IsDifferenceAceptable(localProjectService, diffLimit_mm)}&quot;);
localProjectService.EndSession();
}
static bool IsDifferenceAceptable(MachiningProject project, double diffLimit)
static bool IsDifferenceAceptable(LocalProjectService localProjectService, double diffLimit)
{
foreach (var attachment in project.Workpiece.DiffAttachmentBag)
foreach (var attachment in localProjectService.Workpiece.DiffAttachmentBag)
{
if (double.IsNaN(attachment.Diff) || Math.Abs(attachment.Diff) &gt; diffLimit)
{
@@ -151,7 +151,7 @@ Provides a complete example of a 3D visualization application with HiAPI and WPF
<h2 id="Sample_Machining_DemoRenderingMachiningProcessAndStripPosSelection_remarks">Remarks</h2>
<div class="markdown level0 remarks"><h3 id="source-code">Source Code</h3>
<pre><code class="lang-csharp" name="SampleCode">using Hi.Wpf.Disp;
<pre><code class="lang-csharp" name="SampleCode">using Hi.WpfPlus.Disp;
using System;
using Hi.MachiningProcs;
using Hi.Common.FileLines;
@@ -176,22 +176,24 @@ namespace Sample.Machining
static void Main(string[] args)
{
LocalApp.AppBegin();
LocalProjectService localProjectService = new LocalProjectService();
#region Load Machining Project
var projectPath = &quot;C:/HiNC-Projects/DemoStandardPath/Main.hincproj&quot;;
Console.WriteLine($&quot;Load Project: {projectPath}&quot;);
MachiningProject machiningProject = MachiningProject.LoadFile(projectPath);
localProjectService.LoadProject(projectPath);
MachiningProject machiningProject = localProjectService.MachiningProject;
machiningProject.RuntimeApi.MachiningStepSelected += (MachiningStep step) =&gt;
localProjectService.RuntimeApi.MachiningStepSelected += (MachiningStep step) =&gt;
{
var sourceCommand = step.SourceCommand;
Console.WriteLine($&quot;Step Selected: MRR = {step.Mrr_mm3ds} At \&quot;{sourceCommand?.FilePath}\&quot; (Line {sourceCommand?.GetLineNo()}) \&quot;{sourceCommand?.Line}\&quot;&quot;);
};
machiningProject.PacePlayer.Start();
localProjectService.PacePlayer.Start();
#endregion
#region Configure Rendering Options
var projectDisplayee = new MachiningProjectDisplayee(()=&gt;machiningProject);
var projectDisplayee = new MachiningProjectDisplayee(localProjectService);
projectDisplayee.RenderingFlagBitArray[(int)RenderingFlag.Mech] = true;
projectDisplayee.RenderingFlagBitArray[(int)RenderingFlag.Fixture] = true;
projectDisplayee.RenderingFlagBitArray[(int)RenderingFlag.WorkpieceGeom] = true;
@@ -176,11 +176,13 @@ namespace Sample.Machining
static void Main()
{
LocalApp.AppBegin();
LocalProjectService localProjectService = new LocalProjectService();
#region ProjectLoading
var projectPath = &quot;C:/HiNC-Projects/DemoStandardPath/Main.hincproj&quot;;
Console.WriteLine($&quot;Load Project: {projectPath}&quot;);
MachiningProject machiningProject = MachiningProject.LoadFile(projectPath);
localProjectService.LoadProject(projectPath);
MachiningProject machiningProject = localProjectService.MachiningProject;
#endregion
#region EventHandling
@@ -188,7 +190,7 @@ namespace Sample.Machining
using StreamWriter writer = new StreamWriter(&quot;msg.txt&quot;);
//show message if something abnormal.
machiningProject.SessionMessageHost.CollectionItemAdded += pack =&gt;
localProjectService.SessionMessageHost.CollectionItemAdded += pack =&gt;
{
if (pack.Tags.Contains(MessageFlag.Warning.ToString()) ||
pack.Tags.Contains(MessageFlag.Error.ToString()) ||
@@ -200,7 +202,7 @@ namespace Sample.Machining
};
Console.WriteLine($&quot;Set machining step event.&quot;);
//show MRR.
machiningProject.RuntimeApi.MachiningStepBuilt += (preStep, curStep) =&gt;
localProjectService.RuntimeApi.MachiningStepBuilt += (preStep, curStep) =&gt;
{
var sourceCommand = curStep.SourceCommand;
if (curStep.Mrr_mm3ds &gt; 500) //show only the step that contains large MRR.
@@ -210,18 +212,18 @@ namespace Sample.Machining
#region MachiningExecution
Console.WriteLine($&quot;Reset runtime status.&quot;);
machiningProject.ResetRuntime();
localProjectService.ResetRuntime();
Console.WriteLine($&quot;Session begin.&quot;);
machiningProject.BeginSession();
machiningProject.RuntimeApi.MachiningResolution_mm = 1;
machiningProject.RuntimeApi.EnableCollisionDetection = true;
machiningProject.RuntimeApi.EnablePauseOnFailure = false;
machiningProject.RuntimeApi.EnablePhysics = false;
localProjectService.BeginSession();
localProjectService.RuntimeApi.MachiningResolution_mm = 1;
localProjectService.RuntimeApi.EnableCollisionDetection = true;
localProjectService.RuntimeApi.EnablePauseOnFailure = false;
localProjectService.RuntimeApi.EnablePhysics = false;
//the path from Shell-API is relative by project directory.
machiningProject.RuntimeApi.PlayNcFile(&quot;NC/side.ptp&quot;);
machiningProject.RuntimeApi.PlayNcFile(&quot;NC/circle.ptp&quot;);
machiningProject.EndSession();
localProjectService.RuntimeApi.PlayNcFile(&quot;NC/side.ptp&quot;);
localProjectService.RuntimeApi.PlayNcFile(&quot;NC/circle.ptp&quot;);
localProjectService.EndSession();
Console.WriteLine($&quot;Session end.&quot;);
#endregion
Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

@@ -0,0 +1,136 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>關於仿真過程CPU的使用率 | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="關於仿真過程CPU的使用率 | 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="關於仿真過程cpu的使用率">關於仿真過程CPU的使用率</h1>
<h2 id="仿真的運算線程">仿真的運算線程</h2>
<p>時序資料的計算是單線程(同一時間只使用一個CPU核心),其他資料則可以平行計算。</p>
<h3 id="幾何移除">幾何移除</h3>
<p>幾何移除是單線程,因為按照次序切削才能得到正確的CWE(刀具工件接觸面)。幾何移除後的工件幾何表面是淡粉色,通常代表該處的物理量尚未計算完成。</p>
<h3 id="物理計算">物理計算</h3>
<p>切削力的計算在取得CWE之後,因其不受計算次序影響,一般模式下為多線程計算。力矩等物理量也會在這個步驟多線程計算。</p>
<p>溫度的計算必須是時序,所以又會收斂至單線程。</p>
<p>整個加工仿真的計算過程就這樣分分合合,一個步被計算完成後會在該步著上指定指標的顏色。</p>
<h2 id="cpu的使用率">CPU的使用率</h2>
<h3 id="幾何解析度大時">幾何解析度大時</h3>
<p>幾何解析度大的時候,幾何移除較物理計算快,所以仿真過程會看到一大片的淡粉色跟在刀具後面跑。未計算完成的步數有數量限制,幾何移除在該數量內才會運行。</p>
<p>這種情況主要是CPU的多核運算(物理計算),比較容易看到CPU多核使用率偏高。</p>
<p><img src="geom-quick.png" alt="幾何解析度大時"></p>
<h3 id="幾何解析度小時">幾何解析度小時</h3>
<p>幾何解析度小的時候,幾何移除較物理計算慢,所以幾乎看不到淡粉色。</p>
<p>這種情況主要是CPU的單核運算(幾何計算)。</p>
<p><img src="geom-slow.png" alt="幾何解析度小時"></p>
<h3 id="平衡狀態">平衡狀態</h3>
<p>如果幾何解析度剛好使得幾何計算與物理計算不互相拖累,那淡粉色區域會出現但快速消失。此時物理計算不會拖累幾何計算,通常幾何計算才是運算速度的瓶頸。</p>
<h3 id="cpu未跑滿的情況">CPU未跑滿的情況</h3>
<p>至於CPU沒有跑滿,可能是作業系統為了確保GUI能即時反應,所以預留空間不讓跑。這部分目前沒有解法。</p>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></div>
</div>
<div class="affix">
<nav id="affix"></nav>
</div>
</main>
<div class="container-xxl search-results" id="search-results"></div>
<footer class="border-top text-secondary">
<div class="container-xxl">
<div class="flex-fill">
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
</div>
</div>
</footer>
</body>
</html>
@@ -214,6 +214,9 @@
<li>
<a href="technique/relief-face-avoidance/index.html" name="" title="第一離隙角避讓">第一離隙角避讓</a>
</li>
<li>
<a href="theory-and-technique/cpu-usage/index.html" name="" title="仿真CPU使用率">仿真CPU使用率</a>
</li>
</ul>
</li>
</ul>
File diff suppressed because one or more lines are too long