feat(demos): author the CL demo's equipment on the setup face

Equipment split: the demo installs the CL device through the service
facade (setup face + follow) and authors the workpiece geometry on the
setup face before the session — a runtime-face write would be wiped by
the session-boundary re-materialise. The execution displayee fork reads
the runtime face with scoped collision red, matching the other apps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-27 17:31:30 +08:00
co-authored by Claude Fable 5
parent 139aac9198
commit 7acf47e02b
2 changed files with 44 additions and 27 deletions
+35 -24
View File
@@ -1,4 +1,4 @@
using Hi.Coloring;
using Hi.Coloring;
using Hi.MachiningProcs;
using Hi.Common;
using Hi.Disp;
@@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Collections;
using Hi.Geom;
using System.Linq;
using Hi.NcMech.Solids;
using Hi.Numerical;
using System;
@@ -85,26 +86,28 @@ public class MachiningProjectDisplayee : IDisplayee, IGetAnchor
LocalProjectService localProjectService = LocalProjectService;
HardNcEnv ncEnv = machiningProject.NcEnv;
var workpiece = localProjectService.Workpiece;
//the execution scene draws the RUNTIME face throughout (equipment
//split: the service facades expose the authored setup face instead)
var machiningEquipment = localProjectService.MachiningEquipment;
var workpiece = machiningEquipment?.Workpiece;
if (RenderingFlagBitArray[(int)RenderingFlag.ClStrip])
{
localProjectService.ClStrip.IsKeepingDispAlive = true;
dst.Add(new AnchoredDisplayee(
localProjectService.MachiningEquipment?.Workpiece?.ProgramZeroAnchor,
workpiece?.ProgramZeroAnchor,
localProjectService.ClStrip));
}
if (RenderingFlagBitArray[(int)RenderingFlag.Mech])
{
if (localProjectService.MachiningEquipment != null)
if (machiningEquipment != null)
{
List<IAnchoredDisplayee> machAncDisplayees = localProjectService
?.MachiningEquipment?.GetAnchoredDisplayeeList() ?? [];
List<IAnchoredDisplayee> machAncDisplayees =
machiningEquipment.GetAnchoredDisplayeeList() ?? [];
HashSet<Anchor> exclusiveAnchorSet = new([
.. localProjectService.Workpiece?.Asmb.GetDescendantAnchors()??[],
.. localProjectService.MachiningTool?.GetAsmb().GetDescendantAnchors()??[],
.. localProjectService.Fixture?.Asmb.GetDescendantAnchors()??[],
.. workpiece?.Asmb.GetDescendantAnchors()??[],
.. machiningEquipment.MachiningTool?.GetAsmb().GetDescendantAnchors()??[],
.. machiningEquipment.Fixture?.Asmb.GetDescendantAnchors()??[],
]);
dst.AddRange(machAncDisplayees.Where(ad =>
!exclusiveAnchorSet.Contains(ad.GetAnchor())));
@@ -118,19 +121,17 @@ public class MachiningProjectDisplayee : IDisplayee, IGetAnchor
}
if (RenderingFlagBitArray[(int)RenderingFlag.Tool])
{
if (localProjectService.MachiningEquipment != null
&& localProjectService.MachiningTool != null)
if (machiningEquipment?.MachiningTool != null)
dst.Add(new AnchoredDisplayee(
localProjectService.MachiningTool?.GetAnchor(),
localProjectService.MachiningTool));
machiningEquipment.MachiningTool?.GetAnchor(),
machiningEquipment.MachiningTool));
}
if (RenderingFlagBitArray[(int)RenderingFlag.Fixture])
{
if (localProjectService.MachiningEquipment != null
&& localProjectService.Fixture != null)
if (machiningEquipment?.Fixture != null)
dst.Add(new AnchoredDisplayee(
localProjectService.Fixture?.GeomAnchor,
localProjectService.Fixture));
machiningEquipment.Fixture?.GeomAnchor,
machiningEquipment.Fixture));
}
if (RenderingFlagBitArray[(int)RenderingFlag.ProgramZero])
{
@@ -155,14 +156,16 @@ public class MachiningProjectDisplayee : IDisplayee, IGetAnchor
internal static Anchor GetRootAnchor(
LocalProjectService localProjectService, BitArray renderingFlagBitArray)
{
//runtime face throughout: this roots the execution scene
var machiningEquipment = localProjectService?.MachiningEquipment;
if (renderingFlagBitArray[(int)RenderingFlag.Mech])
return localProjectService?.MachiningEquipment?.GetAnchor();
return machiningEquipment?.GetAnchor();
else if (renderingFlagBitArray[(int)RenderingFlag.WorkpieceGeom])
return localProjectService.Workpiece?.GetAnchor();
return machiningEquipment?.Workpiece?.GetAnchor();
else if (renderingFlagBitArray[(int)RenderingFlag.Fixture])
return localProjectService.Fixture?.GetAnchor();
return machiningEquipment?.Fixture?.GetAnchor();
else if (renderingFlagBitArray[(int)RenderingFlag.Tool])
return localProjectService.MachiningTool?.GetAnchor();
return machiningEquipment?.MachiningTool?.GetAnchor();
else
return null;
}
@@ -222,9 +225,17 @@ public class MachiningProjectDisplayee : IDisplayee, IGetAnchor
bind.ModelMatStack.Pop();
bind.PushColorByRgb(1, 1, 1);
LocalProjectService?.MachiningEquipment?.GetAsmb()?.Display(bind,
GetAnchor(),
GetAnchoredDisplayeeList().ToArray());
var machiningEquipment = LocalProjectService?.MachiningEquipment;
//Collision red is per-scenario state owned by the execution equipment
//(never stored on the shared Solid geometry): scope it to this scene
//so the setup topology never paints it.
using (CollisionRedScope.Enter(
machiningEquipment == null ? null : machiningEquipment.IsCollisionRed))
{
machiningEquipment?.GetAsmb()?.Display(bind,
GetAnchor(),
GetAnchoredDisplayeeList().ToArray());
}
bind.PopColor();
}
/// <inheritdoc/>
+9 -3
View File
@@ -51,13 +51,19 @@ namespace Sample.Machining
var projectDisplayee = new MachiningProjectDisplayee(localProjectService);
var device = new ClMillingDevice();
localProjectService.MachiningEquipment.MachiningChain = device;
//authored face (equipment split): the facade setter installs the
//chain on SetupEquipment and the runtime face follows by rebuild
localProjectService.MachiningChain = device;
localProjectService.ClStrip.IsShowDot = true;
double resolution_mm = 0.5;
var projectDir = Path.GetDirectoryName(projectPath);
localProjectService.WorkpieceService.InitGeom = new StlFile(stlFile_CylinderR20, projectDir);
localProjectService.WorkpieceService.IdealGeom = new StlFile(stlFile_CylinderR19, projectDir);
//author the workpiece on the setup face, then let the runtime
//face follow — a runtime-face write would be wiped by the
//session-boundary re-materialise
localProjectService.Workpiece.InitGeom = new StlFile(stlFile_CylinderR20, projectDir);
localProjectService.Workpiece.IdealGeom = new StlFile(stlFile_CylinderR19, projectDir);
localProjectService.Workpiece.InitResolution = resolution_mm;
localProjectService.NotifySetupEquipmentEdited();
SessionShell runtimeApi = localProjectService.SessionShell;
runtimeApi.SetNcResolutionFixed(9999, 15);