diff --git a/App/HiMech.dll b/App/HiMech.dll index 8e2bba66..3a0e4fd7 100644 Binary files a/App/HiMech.dll and b/App/HiMech.dll differ diff --git a/App/HiNC-2025-win-desktop.deps.json b/App/HiNC-2025-win-desktop.deps.json index 1d8016bf..0f565548 100644 --- a/App/HiNC-2025-win-desktop.deps.json +++ b/App/HiNC-2025-win-desktop.deps.json @@ -13,7 +13,7 @@ "FontAwesome.Sharp": "6.3.0", "Hi.WpfPlus": "3.2.21", "HiNc": "3.2.22", - "HiNc-Resource": "3.2.18", + "HiNc-Resource": "3.2.19", "Serilog.Extensions.Hosting": "10.0.0", "Serilog.Sinks.Console": "6.1.1", "Serilog.Sinks.File": "7.0.0", @@ -1718,11 +1718,11 @@ } } }, - "HiNc-Resource/3.2.18": { + "HiNc-Resource/3.2.19": { "runtime": { "lib/net10.0/HiNc-Resource.dll": { - "assemblyVersion": "3.2.18.0", - "fileVersion": "3.2.18.0" + "assemblyVersion": "3.2.19.0", + "fileVersion": "3.2.19.0" } } }, @@ -2155,7 +2155,7 @@ "HiMech/3.2.25": { "type": "package", "serviceable": true, - "sha512": "sha512-QxNuxhDsw8pq/XRSM4L/pUpZXYKlOfcXXQptCkXO03ekbxjJ5G4GSHqxt6VPAnUial7xTq0tDqWczJJiDiTBVQ==", + "sha512": "sha512-E7Z1tn7mZIoJxLxmfPqvYdYULz/Ubq506wtHNxjh5BqTg9uPkkdGu+NN5Pj/poNO0pON3VSx22EVL+lzUMMmZg==", "path": "himech/3.2.25", "hashPath": "himech.3.2.25.nupkg.sha512" }, @@ -2166,12 +2166,12 @@ "path": "hinc/3.2.22", "hashPath": "hinc.3.2.22.nupkg.sha512" }, - "HiNc-Resource/3.2.18": { + "HiNc-Resource/3.2.19": { "type": "package", "serviceable": true, - "sha512": "sha512-UwwVqPUtcwWXZgW1ahiX7w9jXbLyT7qhhrKBGBZNM/4mTI+3c9HdwPRlZmyTRb7x9VV6RK6m0XsvGQ6FoRg9ww==", - "path": "hinc-resource/3.2.18", - "hashPath": "hinc-resource.3.2.18.nupkg.sha512" + "sha512": "sha512-s1/DhSX8AQdFv9KD1Lmcc5TnjJh56e8Tfz00Q6keUnOMdRYirtdfSQKV4OnhqiBWTNOOL+QgQ8DqUE1d3+r+lg==", + "path": "hinc-resource/3.2.19", + "hashPath": "hinc-resource.3.2.19.nupkg.sha512" }, "HiUniNc/3.2.23": { "type": "package", diff --git a/App/HiNC-2025-win-desktop.dll b/App/HiNC-2025-win-desktop.dll index c16c4f1d..274ef578 100644 Binary files a/App/HiNC-2025-win-desktop.dll and b/App/HiNC-2025-win-desktop.dll differ diff --git a/App/HiNC-2025-win-desktop.exe b/App/HiNC-2025-win-desktop.exe index 3e07344b..7ad9a118 100644 Binary files a/App/HiNC-2025-win-desktop.exe and b/App/HiNC-2025-win-desktop.exe differ diff --git a/App/HiNC-2025-win-desktop.pdb b/App/HiNC-2025-win-desktop.pdb index 0ffb9195..4c615929 100644 Binary files a/App/HiNC-2025-win-desktop.pdb and b/App/HiNC-2025-win-desktop.pdb differ diff --git a/App/HiNc-Resource.dll b/App/HiNc-Resource.dll index 34b730be..6c7b34ae 100644 Binary files a/App/HiNc-Resource.dll and b/App/HiNc-Resource.dll differ diff --git a/App/wwwroot/HiAPI-docsite/anatomy/by-source/webservice-spa/index.html b/App/wwwroot/HiAPI-docsite/anatomy/by-source/webservice-spa/index.html index d0d77126..61c6a804 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/by-source/webservice-spa/index.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/by-source/webservice-spa/index.html @@ -89,7 +89,7 @@

HiNC-2025-webservice/wwwroot-src/src is the flagship front end: a Quasar CLI single-page application in Vue 3, TypeScript and Pinia, served by the same ASP.NET Core process that answers its -REST calls. Every page in Anatomy outside the desktop map documents something in this tree.

+REST calls. Every page in Anatomy documents something in this tree or in the backend beside it.

Folders below follow the stock Quasar skeleton order, with the two places the skeleton breaks called out where they occur.

The One Thing to Know First

diff --git a/App/wwwroot/HiAPI-docsite/anatomy/conventions/gui-file-path-assignment.html b/App/wwwroot/HiAPI-docsite/anatomy/conventions/gui-file-path-assignment.html index c8aa4ee2..05d30499 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/conventions/gui-file-path-assignment.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/conventions/gui-file-path-assignment.html @@ -104,30 +104,18 @@

Then you should keep the Protability.

File Path of Load Button and Save Button

-

The genneral convention of the File Path of Load and Save is different by the single-user desktop application and web page application.

-
-
Tip
-

Always preserve an empty filter ( * . * ) for the browser.

-
-

Single-User Desktop Application

-

The default directory of the Save/Load button are generally:

- -

The kinds of buttons are not exclusive, they can be existed on the same tool bar.

-

If the selected file path is under the project directory, apply the relative path from the project, i.e. baseDirectory is project directory and relFile is the relative path.

-

Web Page Application

-

The default directory of the Save/Load button are generally:

+

A Load or Save button opens the browser at one of three roots:

-

The Resource Directory and Project Directory are generally under the Admin Directory. And the admin directory is generally set in the appsettings.json file.

+

The Resource Directory and Project Directory are generally under the Admin Directory, and the admin directory is generally set in the appsettings.json file. The kinds of button are not exclusive — several may sit on the same tool bar — and a button that opens the Resource root has to say so in its label.

+

If the selected file path is under the project directory, apply the relative path from the project: baseDirectory is the project directory and relFile is the relative path.

+
+
Tip
+

Always preserve an empty filter ( * . * ) for the browser.

+

Typical Action if exhibitionOnly false

On IMakeXmlSource.MakeXmlSource(string, string, bool) with exhibitionOnly false, the argument (baseDirectory and relFile) should be the same from object's host (if exist) XML output function.

diff --git a/App/wwwroot/HiAPI-docsite/anatomy/conventions/translation-remarks.html b/App/wwwroot/HiAPI-docsite/anatomy/conventions/translation-remarks.html index e74b39dd..a7bb304f 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/conventions/translation-remarks.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/conventions/translation-remarks.html @@ -164,16 +164,11 @@ MIME-ish strings (STL, *.hincproj) · units (mm< localStorage keys and series identifiers — anything a machine compares. Language self-names (English, 简体中文, 繁體中文) stay in their own language in every locale. The full list lives with the bundles, in the i18n folder's README.

-

Terms Carried by the Desktop Client

-

Three milling-cutter surfaces exist only on the WPF client, and their terms belong to the same -contract, so none of the words is reused elsewhere:

- +

A Choice That Carries No Label

+

The cutter's integral mode reaches the web application as the integralMode datum rather than as a +named field: it decides whether the Tool House material section offers a separate shank material, +and shows no label of its own. A term with no visible string is still part of the contract — it has +to be settled before anything renders a value derived from it.

Source Code Path

See HiNC App Anatomy for git repository links.

  • File Info Banner @@ -180,9 +176,6 @@ browser to preserve. It is the backstop for a brand extension the NC group does

    CL and CSV are split out because they are closed extension sets: those are exactly the extensions Auto routes to the CL and CSV runners, and everything else falls through to brand NC.

    -

    The WPF Browse button opens an OpenFileDialog with the panel's file-filter resource, starting at -the project directory or at the current file's own directory. A pick under the project directory is -stored as a relative path, and a pick outside it as an absolute one.

    Multi-Pick Fan-Out

    The dialog is multi-select, and this is the one command editor that grows the mission. The first picked file lands on this command. Each further pick becomes a new Program File command, added @@ -191,18 +184,9 @@ list, so a command inside a nested list fans out inside that nested list. The pa structure change, which rebuilds the owning list's branch around the new rows and leaves the selection on this command.

    Where the Program Text Is Edited

    -

    The two clients part company here, and the command is the same either way: it stores a path.

    - +

    The command stores a path, and the panel does not edit the file. It assigns the path, picks the +runner, reports what the server knows about the file, and previews its first 100 lines read-only. +Nothing in the browser writes NC bytes back; the two file endpoints this panel calls are both reads.

    Source Code Path

    See HiNC App Anatomy for git repository links.

    Web Application

    diff --git a/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/NcOptOption-panel.html b/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/NcOptOption-panel.html index 85e51262..b6b3383f 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/NcOptOption-panel.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/NcOptOption-panel.html @@ -94,7 +94,7 @@ preference. Run assigns the command's option object onto the sessio sessionShell.NcOptOption = NcOptOption — so the settings take effect at the point the entry sits in the list. Everything played below it optimizes under them, and a second NC Optimization Config further down the list re-points them mid-mission.

    -

    The command carries no title on either client. Its row and its tree label always read +

    The command carries no title. Its row and its tree label always read NC Optimization Config: GetCommandTitle returns that fixed name and takes nothing from the user.

    Where It Renders

    The web client has one editor component for this command and mounts it once per tree node, each @@ -126,7 +126,6 @@ command — a disabled command is skipped during play and stays fully editable.<

  • Enable Depth Splition CheckBox
  • Enable Interpolation CheckBox @@ -327,11 +326,6 @@ feed per tooth or preferred force survives a project save and reload.

    -

    The Two Clients

    -

    The desktop client edits the same command in one scrolling panel of six group boxes, and it names 17 -of the model's options — the four enable switches, the two distances, the three feedrates, -acceleration and jerk, Preferred Force with the two spindle safety factors, and the three -compensation switches.

    The web client edits five more, and that is the whole difference between the two editors: Min Feed Per Tooth, Max Feed Per Tooth and Feedrate Assignment Ratio in the Feedrate section, and Yielding Safety Factor and Thermal Yield Safety Factor in Force & Safety.

    diff --git a/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/PostExecutionCommand-panel.html b/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/PostExecutionCommand-panel.html index 6fdf8f0b..7784ef9d 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/PostExecutionCommand-panel.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/PostExecutionCommand-panel.html @@ -87,8 +87,7 @@

    PostExecutionCommand Panel (Post-Execution)

    -

    The key model is PostExecutionCommand, the command both clients label -Post-Execution. It is the Output category's first catalog entry, and it carries five outputs +

    The key model is PostExecutionCommand, labelled Post-Execution. It is the Output category's first catalog entry, and it carries five outputs derived from what the session has played: step files, shot files, optimization files, a CL → NC writeback, and a geometry-difference detection.

    When It Runs, and What It Covers

    @@ -103,9 +102,7 @@ command before this command — and it re-serializes every control file the sess play is written back too. Read this together with General Config, the other half of the pair: those settings apply from their position forward, these outputs cover everything up to this position.

    -

    The web client places the command anywhere in the list, like any other. The WPF client pins it to -the end: a new command is inserted before a trailing Post-Execution while that is the list's only -one, and the drag guard refuses to move it off the last position.

    +

    The command sits anywhere in the list, like any other; nothing pins it to the end.

    Run executes the enabled outputs in an order of its own, which is not the order the tree and the list below show them in: shot files, then step files, then optimization, then the CL → NC writeback, then the geometry difference. Output timestamps follow that order rather than the layout.

    @@ -218,14 +215,6 @@ carries the catalog attribute, so they load from a project file but are not offe Command dialog. Post-Execution is the catalogued carrier of these outputs, which is why they are edited as its sections.

    -

    The WPF Client's Panel

    -

    There four of the outputs are group boxes on one panel, each an enable checkbox over a grid that is -disabled until the box is ticked: Step Files Output, Shot Files Output, Optimization Output and -Geometry Difference Detection. The physics condition collapses the Shot Files and Optimization group -boxes rather than omitting tree nodes.

    -

    CL → NC Writeback is the one output the web client has and this panel does not. Its two properties -live on the same engine command, and the web section and its two endpoints are where they are -edited.

    Source Code Path

    See HiNC App Anatomy for git repository links.

    Web Application

    @@ -251,7 +240,7 @@ overview caption and the writeback paragraph.
  • wwwroot-src/src/stores/appState.ts — the physics preference and licence flags the tree builder reads.
  • Environments/PreferenceController.cs — serves the physics preference already combined with the -advanced-physics licence, the same condition the WPF panel evaluates.
  • +advanced-physics licence.
  • Missions/MissionController.cs — the commands/{path}/postexecution/* endpoints: the five enable flags, the four templates, the shot-file time resolution and the geom-diff detect radius.
  • diff --git a/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/PreSettingCommand-panel.html b/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/PreSettingCommand-panel.html index abc38424..0efdd999 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/PreSettingCommand-panel.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/PreSettingCommand-panel.html @@ -87,18 +87,12 @@

    PreSettingCommand Panel (General Config)

    -

    The key model is PreSettingCommand, the command both clients label -General Config. It is one command carrying a bundle of session settings — the machining +

    The key model is PreSettingCommand, labelled General Config. It is one command carrying a bundle of session settings — the machining resolution, the machining motion resolution, collision detection, pause on failure, physics — plus an optional read of a meshed-geometry file.

    Where a General Config Comes From

    -

    The two clients differ on how a mission acquires these settings, and that difference is the first -thing to know about this panel.

    -

    The WPF client creates the bundle. Its Add menu carries a hard-coded item that constructs a -PreSettingCommand, and the insert rule pins it to the top of the list: a new General Config lands -at index 0 unless the list already starts with one, and while it is the list's only General Config -the drag guard refuses to move it off that position.

    -

    The web client's Add Command dialog is served by the server's command catalog, which reflects every +

    How a mission acquires these settings is the first thing to know about this panel.

    +

    The Add Command dialog is served by the server's command catalog, which reflects every engine command carrying [CommandCatalog]. PreSettingCommand carries no such attribute, so the dialog cannot produce one — the catalog keeps presetting only as a readable kind key, and creating a command looks the kind up in the addable set alone. What the web offers instead is the same @@ -212,21 +206,6 @@ project is loaded or assigned — not on a runtime reset and not when the workpi an explicit setting survives both. This command carries its own value, and overwrites the session's with it at the moment the command runs.

    -

    The WPF Client's Panel

    -

    There the whole bundle is one panel, in two group boxes.

    -

    Source Code Path

    See HiNC App Anatomy for git repository links.

    Web Application

    diff --git a/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/script-command-panel.html b/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/script-command-panel.html index 768f32eb..2ceaadaa 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/script-command-panel.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/execution/mission/script-command-panel.html @@ -108,7 +108,7 @@ fully usable.

  • Script Title Text Field
    • The model is ScriptTitle.
    • -
    • Labelled “Title (optional)” on the web, “Script Title” on WPF.
    • +
    • Labelled "Title (optional)".
  • Autosave Indicator (web) @@ -183,11 +183,6 @@ the evaluator uses — and refuses to start when any of them has an error, namin title, path, diagnostic id, message and line. The SPA's Start sends nothing to bypass that check, so the refusal is what a user sees. The same check is also an endpoint of its own, per command and for the whole mission.

    -

    The Two Clients

    -

    The desktop client edits the same command in AvalonEdit: a bold Script Title label with its text -box, a Script Text label, and the editor with C# syntax highlighting and a line-number gutter, -bound to the command through an attached behaviour. There is no completion popup and no autosave — -the binding writes straight into the command as the text changes.

    Source Code Path

    See HiNC App Anatomy for git repository links.

    Web Application

    diff --git a/App/wwwroot/HiAPI-docsite/anatomy/execution/step-present-dialog.html b/App/wwwroot/HiAPI-docsite/anatomy/execution/step-present-dialog.html index f061aba4..51c19e5e 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/execution/step-present-dialog.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/execution/step-present-dialog.html @@ -89,7 +89,6 @@

    Shipped Surface

    The dialog has no route and no Control-Tree node. It is a modal on the Execution page (/execution), opened by the tune icon button on the Step Properties panel's title bar in the Step Info column — so it is reachable only while that column and that panel are shown. The button sits next to the list it configures.

    -

    In the WPF application the same editor is a window opened from the Preference Menu Dropdown.

    The dialog's own view models are the two fetched values, categories and displayedKeys. The server models they mirror are UserService.CandidateStepPresentKeyList plus UserService.StepPresentAccessDictionary (the candidates) and UserConfig.DisplayedStepPresentKeyList (the ordered displayed list). The dialog's only prop is its open/closed flag.

    Layout

      @@ -144,10 +143,9 @@
    • custom — “Custom”, the catch-all for every key the mapping does not place, including the keys registered at run time through UserService.AdditionalStepPresentAccess.
    • All seven are always returned; nothing gates any of them, and the candidate list is read from UserService.CandidateStepPresentKeyList rather than from MachiningStep directly, so runtime-registered keys are included.

      -

      Each client carries its own copy of the key → category mapping: ResolveStepPresentCategory on the webservice, GetKeyCategory in the WPF window. The two are kept in step by hand, with the seven category codes as the shared contract — adding a property means editing both.

      +

      The key → category mapping is ResolveStepPresentCategory on the webservice, with the seven category codes as its contract.

      Labels and Localization

      The web app resolves name and shortName server-side for the requested language from the shipped step-present catalog, laid over the live PresentAttribute.Name and ShortName values — those are the English truth and the fallback for a missing catalog file or key. Unit is sent as-is and does not localize. The dialog pins the language with a ?lang= argument on the request and re-pulls when the UI locale changes.

      -

      The WPF window resolves the same labels locally, through a resource manager over MachiningStep; a key with no translation keeps its original value.

      Refer to the code to apply PresentAttribute:

      internal static void ShowStepPresent(
           UserService userEnv, MachiningStep machiningStep)
      @@ -162,7 +160,7 @@
       

      See Also

      Source Code Path

      diff --git a/App/wwwroot/HiAPI-docsite/anatomy/general-setup/background-coolant.html b/App/wwwroot/HiAPI-docsite/anatomy/general-setup/background-coolant.html index 60f69dc5..5cfc997d 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/general-setup/background-coolant.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/general-setup/background-coolant.html @@ -103,12 +103,6 @@ leaf)

    Key Model: SetupEquipment (+ its CoolantHeatCondition).

    -
    -
    Note
    -

    The WPF desktop app has no surface for either value — no page, no panel, and no handler for the -.CoolantHeatCondition extension. There, both are whatever the project XML carries on the -equipment face, or the class defaults when the XML says nothing.

    -

    Layout

    • Background leaf — equipment/background, item type ThermalCondition diff --git a/App/wwwroot/HiAPI-docsite/anatomy/general-setup/controller/machine/native-parameters.html b/App/wwwroot/HiAPI-docsite/anatomy/general-setup/controller/machine/native-parameters.html index e4b20f55..cbd7c40c 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/general-setup/controller/machine/native-parameters.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/general-setup/controller/machine/native-parameters.html @@ -252,8 +252,7 @@ decides which axis consumes which position table, is shown on written here as an Axis parameters (integer) row; the REST surface carries no assignment writer at all. The equidistant definition — the numerator MD30501 and the offset MD30503 as axis parameters, the denominator MD30502 as an integer axis parameter — has no endpoint that reads or -writes it and no panel that offers a cell for it: on the web surface it is three ordinary rows on -this leaf. The engine is its reader: an axis whose MD30500 is 3 resolves its station spacing from +writes it and no panel that offers a cell for it: it is three ordinary rows on this leaf. The engine is its reader: an axis whose MD30500 is 3 resolves its station spacing from the trio, and Indexing Position Tables prints that axis' assignment as Equidistant (MD30501–MD30503), naming the three numbers it offers no cell for. The two position lists themselves are the mirror image, stored as list properties outside all three dictionaries and so diff --git a/App/wwwroot/HiAPI-docsite/anatomy/general-setup/fixture.html b/App/wwwroot/HiAPI-docsite/anatomy/general-setup/fixture.html index fff604e8..713a85ca 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/general-setup/fixture.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/general-setup/fixture.html @@ -93,18 +93,16 @@ surfaces:

      • the equipment/fixture branch of the General Setup page's Control Tree (/general-setup?tree=equipment/fixture), an equipment child of the General Setup group between -Coolant and Workpiece. /fixture and anything below it redirects there;
      • -
      • in the WPF client, a sub-window opened from the Main Panel.
      • +Coolant and Workpiece. /fixture and anything below it redirects there.
      -

      Both edit the one fixture the project owns.

      +

      It edits the one fixture the project owns.

      • Key Model:
        • Fixture -On the web it is addressed by an IndexService key handed to the +It is addressed by an IndexService key handed to the Object Management Menu Button and installed back onto -the project through the controller's UpdateFixture. On the WPF client the same button is wired -with a TargetObjectGetter / TargetObjectSetter pair (see that page for the design pattern).
        • +the project through the controller's UpdateFixture.
      • Assistant Model: @@ -114,14 +112,11 @@ with a TargetObjectGetter / TargetObjectSetter pair (see that page for the desig
    -

    The displayee differs by client. The web branch has no fixture-only canvas: it shares the General -Setup canvas, whose displayee is the equipment-setup displayee (Disp/EquipmentSetupDisplayee.cs) — -the merged fixture + workpiece scene with the anchor, buckle and controller-coordinate overlays. Its -option set is the equipment-setup config (Disp/EquipmentSetupDisplayeeConfig.cs), carried on -UserService.UserConfig as its EquipmentSetupDisplayeeConfig property. The WPF sub-window has a -canvas of its own, whose displayee is FixtureEditorDisplayee configured by -FixtureEditorDisplayeeConfig, taken from UserService.UserConfig as its -FixtureSetupDisplayeeConfig property.

    +

    There is no fixture-only canvas: the branch shares the General Setup canvas, whose displayee is the +equipment-setup displayee (Disp/EquipmentSetupDisplayee.cs) — the merged fixture + workpiece scene +with the anchor, buckle and controller-coordinate overlays. Its option set is the equipment-setup +config (Disp/EquipmentSetupDisplayeeConfig.cs), carried on UserService.UserConfig as its +EquipmentSetupDisplayeeConfig property.

    Layout

    Control Tree Branch

    The root panel is rendered inline by the dock's primary editor pane, so it has no title label of its @@ -164,53 +159,10 @@ Display Options dropdown carries this branch's share of the scene — the -

    WPF Page

    - -

    Both clients put a draggable divider between the editor column and the canvas: a GridSplitter in the -WPF page, nested draggable splitters on the web page (dock / content column / canvas), plus the -dock's own height divider between the tree row and the editor row.

    Behavior

      -
    • ClearGeomCache() runs after any change at or below the branch. On -the web each node's afterChange chain ends in the controller's ClearGeometryCache, which calls it; -in WPF the page calls it directly from the geometry control's setter and update callbacks.
    • +
    • ClearGeomCache() runs after any change at or below the branch: +each node's afterChange chain ends in the controller's ClearGeometryCache, which calls it.
    • The two anchor slots re-commit their swap-in before clearing the cache: an inner-value edit re-posts UpdateGeomToWorkpieceTransformer / UpdateGeomToTableTransformer, so the object the switchboard produced is always the one installed on the owning field when the redraw happens.
    • @@ -222,10 +174,7 @@ once.
    • Kind pickers are parent-aware. Picking a geometry kind calls CreateGeometry, which installs the new object on Geom server-side and maps the literal None to null; picking a transformer kind creates the object and then rebinds the owning field.
    • -
    • View snapping differs by client. The WPF page snaps its canvas to the isometric view when the -displayee is bound, and again whenever a new geometry object is set, on the assumption that a -shape swap changes the scene more than an edit within one shape does. The shared web canvas snaps -once, when its displayee is bound — the display controller's initialize does it server-side. +
    • The shared canvas snaps to the isometric view once, when its displayee is bound — the display controller's initialize does it server-side. Afterwards a geometry set only clears the cache, and the operator re-frames from the RenderingCanvas Tool Bar's view picker.
    • Both canvases draw the live model, so an edit shows on the next frame with no further calls.
    • @@ -287,13 +236,11 @@ fixture + workpiece scene with the anchor, buckle and controller-coordinate over
      • HiMech/NcMech/Fixtures/Fixture.cs — the key model: the geometry, the table and workpiece buckles, the geom anchor, the two anchor transformers and ClearGeomCache.
      • -
      • HiMech/NcMech/Fixtures/FixtureEditorDisplayee.cs — the WPF fixture canvas's displayee.
      • -
      • HiMech/NcMech/Fixtures/FixtureEditorDisplayeeConfig.cs — its option set: ShowGeomAnchor, -ShowWorkpieceBuckle, ShowTableBuckle and the rendering mode.

      See Also

  • diff --git a/App/wwwroot/HiAPI-docsite/anatomy/general-setup/machine-tool.html b/App/wwwroot/HiAPI-docsite/anatomy/general-setup/machine-tool.html index 62518402..07b61100 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/general-setup/machine-tool.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/general-setup/machine-tool.html @@ -97,18 +97,16 @@ group and a leaf: chain structure belongs to the
  • the /machine-tool route, a standalone surface pairing a chain-only canvas with a load button and a GUI / XML view of what is loaded. Its fields are read-only, but the route is not: its Load installs the picked chain file onto the project. It carries no Page-menu entry and is reached by -URL;
  • -
  • in the WPF client, a sub-window opened from the Main Panel.
  • +URL. -

    All three edit the one chain the project owns.

    +

    Both edit the one chain the project owns.

    -

    WPF Page

    -

    Behavior

    -
    -
    Note
    -

    The WPF desktop app has no spindle-capability surface: no page, no panel, and no handler for the -.SpindleCapability extension. There, the value is whatever the project XML carries on the -equipment face, or the class defaults when the XML says nothing. The .SpindleCapability object -management menu ships on the web only, on this branch's root panel.

    -

    Layout

    The branch is one root plus five children, six selectable nodes in all. Each node's editor occupies the dock's PRIMARY row, and all six — the root included — register the same CONTENT-column view, diff --git a/App/wwwroot/HiAPI-docsite/anatomy/general-setup/workpiece.html b/App/wwwroot/HiAPI-docsite/anatomy/general-setup/workpiece.html index 788bfa0b..105f23fb 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/general-setup/workpiece.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/general-setup/workpiece.html @@ -87,16 +87,14 @@

    Workpiece

    -

    The Workpiece editor is the equipment/workpiece branch of the General Setup page's Control Tree (/general-setup?tree=equipment/workpiece); the old /workpiece route redirects there. In the WPF client it is a sub-window opened from the Main Panel.

    +

    The Workpiece editor is the equipment/workpiece branch of the General Setup page's Control Tree (/general-setup?tree=equipment/workpiece); the old /workpiece route redirects there.

    The key model is Workpiece, taken from the Main Panel's Workpiece. The cached solids it is drawn from belong to -WorkpieceService, which both clients share.

    -

    The display config differs by client. The web branch has none of its own: it shares the General Setup -canvas, gated by the equipment-setup config (Disp/EquipmentSetupDisplayeeConfig.cs), which carries +WorkpieceService.

    +

    The branch has no display config of its own: it shares the General Setup canvas, gated by the equipment-setup config (Disp/EquipmentSetupDisplayeeConfig.cs), which carries the fixture and workpiece flags together — the fixture and workpiece geometry anchors keep separate flags, while the fixture↔workpiece buckle pair, being one attached identity at one location, is a -single flag. The WPF page takes its own WorkpieceEditorDisplayeeConfig -from UserService.UserConfig.

    +single flag.

    Layout

    Control Tree Branch

    -

    WPF Page

    -
      -
    • Workpiece Page -
        -
      • Management Panel -
          -
        • Head Line - -
        • -
        • Management Tabs Panel -
            -
          • Raw Shape Tab - -
          • -
          • Target Shape Tab -
              -
            • Geometry Management Control
            • -
            -
          • -
          • Anchor Tab - -
          • -
          • Runtime Tab -
              -
            • Initial Resolution Dropdown — the same powers-of-two ladder as the Mesh item above.
            • -
            -
          • -
          • Material Tab -Visible if UserService.EnablePhysics is true. -
              -
            • Workpiece Material File Selector -
                -
              • Browse Button -The initial directory is the project directory.
              • -
              • Browse Resource Button -The directory is the Default Resource directory.
              • -
              • Readonly File Path TextBox
              • -
              • Readonly Name TextBox (Name) - -
              • -
              -
            • -
            • Cutting Parameter File Selector -
                -
              • Browse Button -The initial directory is the project directory.
              • -
              • Browse Resource Button -The directory is the Default Resource directory.
              • -
              • Readonly File Path TextBox
              • -
              • Readonly Name TextBox (Name) - -
              • -
              -
            • -
            -
          • -
          -
        • -
        -
      • -
      • Viewer Panel - -
      • -
      -
    • -

    Default Resource

    The default resources of Workpiece Material and Cutting Parameter exist in Resource folder under application folder (Not project folder). Both clients seed their file pickers at the matching Resource sub folder:

      @@ -336,9 +220,7 @@ None leaves the old object indexed, and re-committing would resurrect it.

    • Call WorkpieceService.ClearIdealGeomCache() on Target Shape set or changed.

    • -
    • Both clients reach that one service by different routes: the web branch posts the controller's -cache-clear endpoints, and the WPF page calls -WorkpieceEditorDisplayee, which forwards to the same service.

      +
    • The branch reaches that service by posting the controller's cache-clear endpoints.

    • Anchor edits re-commit their transformer and deliberately do not clear the geometry cache, so a placement change forces no CubeTreeFile re-mesh.

      @@ -348,10 +230,7 @@ cache chain runs after a change.

    • The equipment canvas snaps to the isometric view when its displayee is bound to a rendering connection; a shape edit on the branch re-commits and clears the cache so the next frame -re-solidifies, and leaves the view alone. The WPF page snaps its own canvas to isometric when a -Raw or Target shape is set to a different object, and whenever its meshed-geometry panel updates -its content — the assumption being that setting a shape changes the viewer more than changing its -content does, so only the setter event adjusts the view.

      +re-solidifies, and leaves the view alone.

    • Keep Portability of the Material properties.

    • diff --git a/App/wwwroot/HiAPI-docsite/anatomy/geom/box3d-control.html b/App/wwwroot/HiAPI-docsite/anatomy/geom/box3d-control.html index f7c91f4c..ff2e66b5 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/geom/box3d-control.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/geom/box3d-control.html @@ -94,9 +94,8 @@ slot, or the geometry switchboard embedded inline.

      Layout

      • Edit Mode — a selector over three modes. Its internal values are MinMax, MinDimension and -CenterDimension; the web labels them “Min / Max”, “Min + Dimension” and “Center + Dimension”, -the desktop client “Min and Max”, “Min and Dimension” and “Center and Dimension”.
      • -
      • Min, Max, Dimension, Center — four vector rows, one X / Y / Z input each. The web +CenterDimension, labelled “Min / Max”, “Min + Dimension” and “Center + Dimension”.
      • +
      • Min, Max, Dimension, Center — four vector rows, one X / Y / Z input each. The editor captions Dimension “Dimension (Max − Min)” and Center "Center ((Max + Min) / 2)"; the Min and Max captions come from the shared label set rather than the geometry one.
      @@ -107,18 +106,14 @@ in anything but Center + Dimension.

      Only Min and Max are settable on the type; Dim and Center are derived and get-only. That is why the other two modes are arithmetic over the same two stored corners rather than a different storage -shape — and on the web that arithmetic happens in the browser, which then posts the resulting Min -and Max.

      +shape — and that arithmetic happens in the browser, which then posts the resulting Min and Max.

      Behavior

      • A row commits on blur or Enter, not per keystroke. The vector widget emits only from its blur handlers, suppresses the emit when the parsed value is unchanged, and reverts an unparseable entry to its previous value.
      • -
      • The web editor has no read-only variant. The desktop control additionally carries an -IsInfoMode property that a host sets to turn the whole control into a display: every field goes -read-only and the Edit Mode selector is hidden outright. Two hosts use it, the STL file control and -the geometry combination control. The web equivalent is not this editor — the STL file editor draws -its own read-only bounding-box rows.
      • +
      • This editor has no read-only variant. A host that needs one draws its own rows instead — the +STL file editor's read-only bounding-box rows are not this editor.
      • Four endpoints ship without a caller. The controller exposes UpdateByMinDimension, UpdateByCenterDimension, IndexDimension and IndexCenter; the shipped SPA calls none of them, because the editor resolves every mode to a plain Update.
      • diff --git a/App/wwwroot/HiAPI-docsite/anatomy/geom/cylindroid-control.html b/App/wwwroot/HiAPI-docsite/anatomy/geom/cylindroid-control.html index 74df7039..161720cd 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/geom/cylindroid-control.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/geom/cylindroid-control.html @@ -101,16 +101,12 @@ of each row, disabled once only two pairs remain.
      • The caption — a one-line statement of the type: a solid of revolution defined by (Z, R) pairs, minimum two.
      -

      The desktop control is shaped differently for the same job: a title, an Add Point and a Clear -All button, and a data grid with Z, R and Actions columns. Clear All has no web counterpart — it -confirms, wipes the list and re-seeds a single pair.

      Behavior

      • A cell commits on blur or Enter. An empty or non-finite entry is dropped rather than written, and a negative radius is clamped to zero — on the client and again on the server.
      • -
      • The floor is two pairs, and both ends enforce it. The web disables the remove button at two -and the controller refuses the call below two. The desktop client blocks only at one, with a -warning dialog.
      • +
      • The floor is two pairs, and both ends enforce it. The remove button is disabled at two and +the controller refuses the call below two.
      • Creating one seeds three pairs. The create endpoint starts a new cylindroid at (0, 20), (30, 20) and (60, 10) rather than empty.
      • Four endpoints ship without a caller. The controller exposes GetPairCount, GetPairAt, @@ -119,12 +115,10 @@ warning dialog.
      • Tessellation Resolution Is Not a Property of the Shape

        There is no longitude count, and no per-instance resolution, on a cylindroid. The STL longitude number is derived internally at generation time from a resolution the caller supplies; the type -carries only a static default. The desktop client once had a Longitude Number field and its handler -was deleted when the backing property went away.

        +carries only a static default.

        Where resolution is exposed, it belongs to the holder rather than to the shape: the Tool House -cylindroid holder carries a Resolution surface beside its Geometry one — a tree node on the web, -a tab in the desktop client — offering a linear resolution in millimetres and an angle resolution in -degrees, described in the app as the tessellation resolution used for display and collision meshing.

        +cylindroid holder carries a Resolution tree node beside its Geometry one, offering a linear +resolution in millimetres and an angle resolution in degrees, described in the app as the tessellation resolution used for display and collision meshing.

        Source Code Path

        See HiNC App Anatomy for git repository links.

        HiNC-2025-webservice (Quasar CLI SPA):

        diff --git a/App/wwwroot/HiAPI-docsite/anatomy/geom/extended-cylinder-panel.html b/App/wwwroot/HiAPI-docsite/anatomy/geom/extended-cylinder-panel.html index be706c26..d136bae7 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/geom/extended-cylinder-panel.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/geom/extended-cylinder-panel.html @@ -89,13 +89,12 @@

        The Extended Cylinder editor edits one number on an ExtendedCylinder: its full length, measured from Z=0 and including the span below the start section. Its only home on -either client is the Tool House cutter's Upper Beam, where the start section is the flute top.

        +it is the Tool House cutter's Upper Beam, where the start section is the flute top.

        Layout

        • An explanatory block stating what the type is and, in bold, how the length is measured.
        • Full Length — a single numeric field in millimetres, with a hint under it.
        -

        The desktop panel is a title over the same one field.

        Behavior

        • The hint states a lower bound only when that bound is positive. The bound is the Z of the @@ -113,19 +112,15 @@ minimum — its minimum is inclusive — so a value exactly equal to the bound p caught one layer up by the editor, which raises an error to its host as a banner rather than an inline field message. The controller then rejects non-finite, non-positive, and at-or-below-bound values with a 400.
        • -
        • The field commits on blur or Enter. The desktop control does not: it writes on every -keystroke, and performs no minimum, positivity or finiteness check at all. The range guard is a -web and backend feature.
        • +
        • The field commits on blur or Enter, and the range guard runs on both the field and the backend.
        • Creating one through the cutter is not the same as creating one bare. The Upper Beam creates through the cutter's own endpoint so the backend seeds a valid full length and can return geometry-issue warnings — which the Upper Beam panel renders as persistent banners. The bare create endpoint seeds a length of 100 and a single start pair.

        Reach

        -

        Both clients restrict this kind to the cutter's upper beam, by different mechanisms. In the desktop -client the switchboard's Extended Cylinder entry ships collapsed and is revealed by a property that -exactly one host sets — the milling cutter panel. On the web no Geometry slot offers the kind at -all: it is absent from the container kinds, so it can be neither a transformation geometry's inner +

        This kind is restricted to the cutter's upper beam, and the mechanism is absence rather than a flag: +no Geometry slot offers it at all. it is absent from the container kinds, so it can be neither a transformation geometry's inner geometry nor a combination child, and it was taken out of the workpiece's raw geometry once a saved project was found to reload one degenerate. The single surface that offers it is the cutter's Upper Beam, which mounts the switchboard itself over its own six-kind list rather than being a Geometry diff --git a/App/wwwroot/HiAPI-docsite/anatomy/geom/geom-combination-control.html b/App/wwwroot/HiAPI-docsite/anatomy/geom/geom-combination-control.html index 9e5ed2c4..505e02f9 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/geom/geom-combination-control.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/geom/geom-combination-control.html @@ -87,10 +87,10 @@

        Geometry Combination Control

        -

        A GeomCombination is several geometries treated as one, and it has two faces on the -web: an inline editor that renders every child's own editor at once, and a Control-Tree panel that -manages the list only and puts each child on its own node. The desktop client has the inline shape -alone. There is no selection model on any of them — every child carries its own remove button.

        +

        A GeomCombination is several geometries treated as one, and it has two faces: an +inline editor that renders every child's own editor at once, and a Control-Tree panel that manages +the list only and puts each child on its own node. There is no selection model on either — every +child carries its own remove button.

        Layout

        The inline editor

          @@ -103,33 +103,23 @@ editable at once.

          Deliberately shallow: a list of read-only rows with Add, a per-row remove and Clear all, and a standing hint that an Item child node is where a child is actually edited. No editor is embedded here; each child is its own Item node — .../item-{index} — under this one.

          -

          The desktop control

          -

          A title, then an Add and a Clear All button over a scrolling list of bordered cards, each -holding that child's own geometry management panel and a remove button — no index badge and no type -caption. Below the list sits a collapsed Combination Information expander reporting the aggregate -triangle count and bounding box, the latter as a read-only box control.

          Adding a Child

          -

          The two clients differ here, and the web is the one that gained something:

          -
            -
          • Web — pick the kind first, then Add; the request carries the kind.
          • -
          • Desktop — Add takes no kind and always appends a 100 mm cube. The kind is switched afterwards, -on that child's own Geometry Type combo.
          • -
          +

          Pick the kind first, then Add; the request carries the kind.

          Five kinds may be children — Box3d, Cylindroid, StlFile, TransformationGeom and a nested GeomCombination, so combinations nest arbitrarily deep. CubeTreeFile and ExtendedCylinder are -accepted by neither client's switch.

          +accepted by neither switch.

          Behavior

          • A type switch rewires the slot, not just the alias. Changing a child's kind goes through SetItemAt, which replaces the entry in StlSources itself.
          • The aggregate STL is cached, and a child's own controller does not invalidate it. Editing a child through its own endpoints leaves the combination returning the mesh it had already built, so -both web faces call CleanCache before bubbling the change, and compose that call into the -ancestor chain. This is the behavioural fact the rest of the page depends on.
          • +both faces call CleanCache before bubbling the change, and compose that call into the ancestor +chain. This is the behavioural fact the rest of the page depends on.
          • Removing a child does not renumber the ones after it. Item keys are minted as {key}-item-{index} and the remove endpoint leaves later indices pointing at the old aliases, which is why every structural change rebuilds the branch and re-mints them.
          • -
          • Clear all confirms only on the desktop. The web posts it directly.
          • +
          • Clear all is posted directly, with no confirmation.

          Source Code Path

          See HiNC App Anatomy for git repository links.

          @@ -175,7 +165,7 @@ cache.

          See Also

          • Geometry Management Panel — the switchboard that offers this kind, and -the panel each desktop child card embeds
          • +the panel each child card embeds
        diff --git a/App/wwwroot/HiAPI-docsite/anatomy/geom/geom-manage-control.html b/App/wwwroot/HiAPI-docsite/anatomy/geom/geom-manage-control.html index 10c086e4..886e2600 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/geom/geom-manage-control.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/geom/geom-manage-control.html @@ -88,21 +88,17 @@

        Geometry Management Panel

        The geometry switchboard is one control: a kind picker over the kinds its host allows, and — unless -the host asked for the picker alone — the picked kind's editor beneath it. On the web it binds a +the host asked for the picker alone — the picked kind's editor beneath it. It binds a key into the shared object store, not an object, and every Control-Tree Geometry slot is this same control in selector-only mode.

        Layout

        Web: a geometry-type dropdown; a separator, drawn only while a kind is active; then that kind's editor. Picking a kind commits immediately — there is no Apply button. In selector-only mode everything below the dropdown is dropped, which is the form each Geometry slot node shows.

        -

        Desktop: a combo box on the left of a head line with a Convert menu on its right, over a bordered -content presenter that hosts the kind's own control.

        What It Binds

        The web panel has no target-geometry property. It takes a modelKey naming the object it edits and mutates what sits behind that key; a host that also owns the field holding the geometry passes an -onCreate hook, so switching the kind rebinds the host's field rather than just the key. The -desktop panel is the one that exchanges an IStlSource directly, through a getter and -setter pair its host supplies.

        +onCreate hook, so switching the kind rebinds the host's field rather than just the key.

        Each host's field type decides which kinds it may offer; whether the kind survives a save decides which of those it does. A fixture's geometry and a transformation geometry's inner geometry are IGetStl; a workpiece's initial geometry is an IMakeXmlSource, which is why the @@ -117,7 +113,7 @@ host that wires that source, the cutter's upper beam.

        Cylindroid, StlFile, TransformationGeom, GeomCombination and CubeTreeFile. ExtendedCylinder is in the kind map but out of that default: a host that can wire its start section names it explicitly. -Nothing is hidden by a flag on the web.

        +Nothing is hidden by a flag.

        The default is a guard rail, not a shipped list. Every host passes its own whitelist — the five Control-Tree Geometry slots from the node context, the four inline hosts as a constant — so no shipped surface renders the default at all, and the whitelist is what really decides reach.

        @@ -151,17 +147,13 @@ shipped surface renders the default at all, and the whitelist is what really dec only when the host asks for it: the three General Setup slots and a transformation geometry's inner geometry do, while the mechanism anchor, the cutter upper beam and combination children do not, so those pickers cannot clear the slot. Clearing goes through the host's create hook with the literal -kind None, which the container-aware endpoints map to null. The desktop combo always lists a -None item.

        -

        Converting Is Desktop-Only

        -

        Wrapping an existing geometry into a TransformationGeom — and extracting it back out -— exists only in the desktop client, as items in the Convert menu rather than as buttons. The -Convert to Transformation item re-titles itself Extract from Transformation when the current -geometry already is one; the combination item behaves the same way, and its extract is offered only -when the combination holds exactly one child. Three code-behind properties can hide the menu and each -of its two items, but no shipped host sets any of them.

        -

        The web has no equivalent, and the difference is not cosmetic. Picking TransformationGeom in -the picker creates a new, empty one and discards the geometry that was there — it does not wrap it.

        +kind None, which the container-aware endpoints map to null.

        +

        There Is No Way to Wrap an Existing Geometry

        +

        Wrapping a geometry that is already in a slot into a TransformationGeom — and +extracting it back out — is not offered anywhere in the application, and the difference from what +the picker looks like it does is not cosmetic. Picking TransformationGeom creates a new, empty +one and discards the geometry that was there. The same holds for a combination: there is no +operation that takes a geometry and puts a container around it in place.

        In the Control Tree

        Geometry is a slot item type. Its child builder probes the slot's key for the type behind it and, when that type is a known kind, grows exactly one child node of that kind bound to the same key @@ -219,8 +211,8 @@ editor

      • Extended Cylinder Panel — the same, and the kind exactly one host offers
      • STL File Control — the same, for an STL reference
      • Meshed Geometry Panel — the same, for a voxel cube tree
      • -
      • Transformation Geometry Control — the container kind this panel -can wrap into on the desktop client
      • +
      • Transformation Geometry Control — one of the container kinds +this panel offers, and why picking it replaces rather than wraps
      • Geometry Combination Control — the other container kind, whose every child embeds this panel again
      diff --git a/App/wwwroot/HiAPI-docsite/anatomy/geom/meshed-geom-panel.html b/App/wwwroot/HiAPI-docsite/anatomy/geom/meshed-geom-panel.html index b6bca137..a05f576c 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/geom/meshed-geom-panel.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/geom/meshed-geom-panel.html @@ -105,18 +105,14 @@ when nothing is chosen.
    • A standing description: the geometry is a pre-computed voxel cube tree, and loading it is deferred until it is needed.
    -

    The desktop panel is a read-only path field with Browse and Reload buttons. The web has no -Reload: the controller has no such action.

    Reach

    One slot offers this kind: the workpiece's Raw Geometry. The fixture's geometry and the workpiece's target geometry both exclude it, and it is not among the container kinds, so it can be neither a transformation geometry's inner geometry nor a combination child. The Control-Tree node carries the chosen file in its label, as MeshedGeomFile [<path>].

    -

    The desktop client reaches it differently. There, the workpiece page carries a Geometry Source -combo — Common Geometry or Meshed Geometry — that decides whether this panel or the geometry -switchboard is visible. The web has no such toggle: picking the MeshedGeomFile kind is choosing -the meshed source. The classification survives on the server, which still reports a raw geometry of -this type as a meshed one.

    +

    There is no separate geometry-source toggle: picking the MeshedGeomFile kind is choosing the +meshed source. The classification survives on the server, which still reports a raw geometry of this +type as a meshed one.

    Key Model

    CubeTreeFile is the file reference; CubeTree is the voxel tree itself. The reader resolves the stored relative path and opens it with no extension test of its own — .wct diff --git a/App/wwwroot/HiAPI-docsite/anatomy/geom/stlfile-control.html b/App/wwwroot/HiAPI-docsite/anatomy/geom/stlfile-control.html index fab9e04d..15535c1a 100644 --- a/App/wwwroot/HiAPI-docsite/anatomy/geom/stlfile-control.html +++ b/App/wwwroot/HiAPI-docsite/anatomy/geom/stlfile-control.html @@ -89,19 +89,17 @@

    The STL file editor points a geometry at an .stl file rather than describing a shape: the model holds a file reference, and the editor is a picker over it plus a read-only summary of what was -loaded. On the web the file lives on the server, not on the machine running the browser, and +loaded. The file lives on the server, not on the machine running the browser, and that difference shapes everything else on the page.

    Layout

    1. File reference — a read-only field showing the path currently referenced, with an empty-state hint when there is none.
    2. -
    3. The picker — on the web a Select dropdown whose menu holds Browse…, Browse Resource… -and, only while a path is set, Clear. Either Browse entry opens the in-app File Explorer dialog -filtered to .stl. In the desktop client this is a Browse button opening the operating -system's file dialog, beside a Reload button and a status line; the web has no Reload.
    4. -
    5. STL info — behind an info icon on the web, opening a dialog; a collapsed Information -expander in the desktop client. Both show the triangle count and the bounding box as read-only -vector rows, and the web dialog states an empty case when nothing is loaded.
    6. +
    7. The picker — a Select dropdown whose menu holds Browse…, Browse Resource… and, only +while a path is set, Clear. Either Browse entry opens the in-app File Explorer dialog filtered +to .stl. There is no reload action.
    8. +
    9. STL info — behind an info icon, opening a dialog that shows the triangle count and the +bounding box as read-only vector rows, and states an empty case when nothing is loaded.

    Behavior

    diff --git a/App/wwwroot/HiAPI-docsite/manual/run/a-mission-that-resumes.html b/App/wwwroot/HiAPI-docsite/manual/run/a-mission-that-resumes.html index 2423c010..88e4f7e7 100644 --- a/App/wwwroot/HiAPI-docsite/manual/run/a-mission-that-resumes.html +++ b/App/wwwroot/HiAPI-docsite/manual/run/a-mission-that-resumes.html @@ -217,6 +217,14 @@ result. that is still ticked becomes the first thing to run, so it reads its cache, and the run picks up from there. +

    Clearing a stage clears everything in it, including its record. A stage is a checkbox around a +list, and a cleared one is skipped whole — so in a chain where the cache a stage resumes from is the +previous stage's end-of-stage record, clearing that previous stage removes the very entry that +would have loaded it. The run then starts from the stock, quietly and without an error. Either leave +the earlier stages ticked and clear only the Program File rows inside them, or clear them but keep +the one stage whose end-of-stage record you are resuming from, with its own programs cleared. The +rule is simply that the record you are resuming from has to be reachable: every checkbox above +it stays ticked.

    That last line is the point of the layout. The cost of getting back to the middle of a long job is one file read.

    The stage-0 cache goes stale, silently

    @@ -232,6 +240,26 @@ second operation in a chained pair, a stage-0 record buys no time at all and fre upstream stage can be re-run all it likes and this one keeps reading the copy it took the first time. There, the previous stage's own end-of-stage file is already the cache, and the stage needs no record above its program.

    +

    Resuming, then cutting finer

    +

    A record freezes the workpiece as meshed at the width in force when it ran. Reading one back +does not pin the rest of the run to that width: put a finer Machining Resolution below the record +and above the next program, and that program's removal is built at the finer width. Measured on a +roughing stage recorded at 0.5 mm — read back, then cut at 0.0625 mm — the cut ran at 0.0625 mm and +took 779 s where the same program at 0.5 mm took 27 s, for five times the mesh's own memory. The +request binds; the record is not a ceiling, and at this end of the ladder it is not free either.

    +

    What reading back cannot do is add detail that was never stored. Surfaces inherited from the record +keep the width they were recorded at; only what the later program cuts is meshed finer. That is +normally exactly right — the roughed surface is about to be cut away, and the finish surface is the +one the fine mesh is for.

    +

    So record each stage at the width that stage needs — with one exception: the stage the finishing +pass reads from. Everything the finishing tool does not touch keeps that record's width, and that +includes the surface the finish is measured against. Choose that one record's width against the +finish, then, rather than against the roughing stage it happens to belong to.

    +

    The earlier stages have no such constraint. Roughing at the finishing width to be safe buys nothing +and costs the whole roughing run at the finishing price.

    +

    This is a different thing from the stage-0 trap above, which is about the record above a program +caching the stock: there the frozen mesh is what the run starts from, so the resolution really is +stuck until the file is cleared.

    One record per stage

    A mission with several Program File entries gets a record after each, plus the stage-0 record where that one earns its place. Name each file after the stage it ends, not after the program that wrote diff --git a/App/wwwroot/HiAPI-docsite/manual/run/playing-a-program.html b/App/wwwroot/HiAPI-docsite/manual/run/playing-a-program.html index 81dd7285..c30e0cea 100644 --- a/App/wwwroot/HiAPI-docsite/manual/run/playing-a-program.html +++ b/App/wwwroot/HiAPI-docsite/manual/run/playing-a-program.html @@ -222,6 +222,7 @@ to what the mission asked for — see The Prog

  • The Program Branch — what the run recorded against each line
  • The Other Commands — the rest of the command kinds, including the script that drives a session without NC
  • NcFileCommand Panel — the component behind Program File: its fields, its picker and the endpoints behind the banner
  • +
  • A Mission That Resumes — the layout these two commands sit in when the run has to be restartable
  • NcCodeCommand Panel — the component behind NC Code: its editor, its stats row and how it saves
  • diff --git a/App/wwwroot/HiAPI-docsite/manual/run/running-a-simulation.html b/App/wwwroot/HiAPI-docsite/manual/run/running-a-simulation.html index 57357360..457f4722 100644 --- a/App/wwwroot/HiAPI-docsite/manual/run/running-a-simulation.html +++ b/App/wwwroot/HiAPI-docsite/manual/run/running-a-simulation.html @@ -226,6 +226,7 @@ Pause with F6 first.

  • Inspecting a Step — the column that reads whichever step you stopped on
  • When Something Goes Wrong — what to read when the run does not do what you expected
  • The Application Window — the menu bar's connection badge, and the footer this page's state is reported in
  • +
  • A Mission That Resumes — how to lay the mission out so a stopped run restarts from where it got to
  • Execution Tool Bar — the component behind these buttons: the enable rules, the status feed and the key bindings
  • diff --git a/App/wwwroot/HiAPI-docsite/technique/api-foundations/xml-io.html b/App/wwwroot/HiAPI-docsite/technique/api-foundations/xml-io.html index bdab4925..29b3e566 100644 --- a/App/wwwroot/HiAPI-docsite/technique/api-foundations/xml-io.html +++ b/App/wwwroot/HiAPI-docsite/technique/api-foundations/xml-io.html @@ -323,6 +323,11 @@ public XElement MakeXmlSource(string baseDirectory, string relFile, bool exhibit return new XElement(XName, this.GetNameNoteXElementList(), new XElement(nameof(EnergyEfficiency), EnergyEfficiency), + //the constructor reads this element; without the matching write a + //save/load round trip through the web API silently reverted a + //non-default bound to the 65 C default. + new XElement(nameof(WorkingTemperatureUpperBoundary_C), + WorkingTemperatureUpperBoundary_C), new XElement(nameof(GearShiftSpindleSpeed_rpm), GearShiftSpindleSpeed_rpm), new XElement(nameof(DryRunFrictionPowerCoefficient_mWdrpm), DryRunFrictionPowerCoefficient_mWdrpm), diff --git a/App/wwwroot/HiAPI-docsite/technique/machine-capability/spindle-capability.html b/App/wwwroot/HiAPI-docsite/technique/machine-capability/spindle-capability.html index c183ce5b..2daca771 100644 --- a/App/wwwroot/HiAPI-docsite/technique/machine-capability/spindle-capability.html +++ b/App/wwwroot/HiAPI-docsite/technique/machine-capability/spindle-capability.html @@ -188,7 +188,7 @@
  • TMV-720A-STD-8000RPM.SpindleCapability
  • VP-8--Fanuc-10000RPM.SpindleCapability
  • -

    To edit values interactively, see Spindle Capability Page in the Quasar webservice. The desktop WPF app does not yet have a dedicated editor; load capabilities through the equipment's ObjectManagementMenuButton instead.

    +

    To edit values interactively, see Spindle Capability Page.

    See Also

    • Process Machinability — uses MaxSpindleTorqueRatio / MaxSpindlePowerRatio for tool-breakage prediction
    • diff --git a/App/wwwroot/HiAPI-docsite/technique/rendering/color-guide.html b/App/wwwroot/HiAPI-docsite/technique/rendering/color-guide.html index 093e7243..119e35e9 100644 --- a/App/wwwroot/HiAPI-docsite/technique/rendering/color-guide.html +++ b/App/wwwroot/HiAPI-docsite/technique/rendering/color-guide.html @@ -136,10 +136,9 @@

      To make the Color Guide effective in a project, implement the IColorGuide interface and register it in the project's color guide dictionary.

      XML Serialization

      See About XML IO for details on XML serialization implementation.

      -

      WPF Application Source And Sample Code Path

      +

      Source Code Path

        -
      • HiMech/Coloring/IColorGuide
      • -
      • HiNC-2025-win-desktop/Demo/DemoColorGuide
      • +
      • HiMech/Coloring/IColorGuide.cs

      See HiNC App Anatomy for git repository links.

      See Also

      diff --git a/App/wwwroot/HiAPI-docsite/technique/simulation-performance/mesh-resolution.html b/App/wwwroot/HiAPI-docsite/technique/simulation-performance/mesh-resolution.html index 3279aa16..3ae4932a 100644 --- a/App/wwwroot/HiAPI-docsite/technique/simulation-performance/mesh-resolution.html +++ b/App/wwwroot/HiAPI-docsite/technique/simulation-performance/mesh-resolution.html @@ -153,9 +153,87 @@ than the run needs, the next value that changes anything is 0.5 mm — and going 0.125 mm is another eight times the voxels, not a small step.

      The ladder bottoms out at 0.001953125 mm. A finer request is clamped to it, so the finest entry offered in the workpiece's Initial Resolution list builds the same mesh as the one above it.

      +

      The width only ever goes finer

      +

      A mesh that exists cannot be coarsened. Every cut takes the finer of the width already built and +the width being asked for, so raising Machining Resolution above the mesh the workpiece was built at +does not simplify anything — the request is dropped and the run keeps the mesh it has.

      +

      This is why the two settings are not interchangeable. The workpiece's Initial Resolution is what +builds the mesh and is therefore the memory setting; Machining Resolution gates how fine a +newly cut surface may go, and can only ever refine. To make a run cheaper in memory, coarsen the +Initial Resolution — coarsening Machining Resolution alone changes nothing about the stock that is +already there.

      +

      It still changes the time, and by a lot, because the same number sizes two other things: the +tessellation of the cutter's own solid, and the number of engagement layers per step. Both are +per-step work that is thrown away again, so a coarser Machining Resolution can cut the run time +several-fold while the memory figure does not move at all. A run that got faster without getting +smaller is this, not a mystery.

      Pick from the ladder and the number shown in the mission row is the number the run used. That matters beyond tidiness: a recorded mesh is built at whatever resolution is in force when the record runs, so an off-ladder value is silently baked into the cache as its rounded neighbour.

      +

      What It Costs in Memory

      +

      Far less than it costs in time, which is the opposite of what four rungs of the ladder — sixteen +times finer, and so four thousand times the voxels — leads most people to expect. Measured by +sweeping one case across five rungs with the program and the step count held fixed — a cylindrical +blank, one roughing program, 199,242 steps every run:

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Mesh widthPlay timeProcess memory outside the managed heap
      2 mm10.5 s665 MB
      1 mm15.3 s688 MB
      0.5 mm31.2 s722 MB
      0.25 mm76.6 s826 MB
      0.125 mm242.9 s1,456 MB
      +

      Sixteen times finer costs 23 times the time and 2.2 times the memory. Two things flatten that +second column, and it is worth separating them:

      +
        +
      • Most of the figure is a baseline the mesh does not set. The coarsest run in the sweep already +sits at 665 MB, and the whole sixteen-fold refinement adds 791 MB on top of it. Read the column as +increments rather than as totals: the ratio at the bottom of the table is diluted by everything in +the figure that would be there at any mesh width.
      • +
      • The increments grow slowly at coarse widths and then accelerate. Halving the width added +23 MB, then 34, then 104, then 630 — each increment about 1.5, then 3.1, then 6.1 times the one +before it, a local exponent climbing from roughly 0.6 to 2.6. A cube stops subdividing as soon as +the surface inside it is a single flat facet, so while the mesh is coarser than the part's facets +and curvature, refining mostly buys nothing. The volume-scaling intuition is not wrong; it only +arrives once the width is below the feature scale, and by then it arrives fast.
      • +
      +

      A big workpiece moves the same curve up: where the stock is a large imported solid rather than a +small procedural blank, there is far more surface to subdivide and the mesh-dependent part dominates +much earlier.

      +

      Do not judge the mesh by the process's peak memory. On a long run most of that figure is the +per-step data the run accumulates, which lives on the managed heap, scales with the number of steps +and not with the mesh at all — and it moves the other way when the mesh is refined, because a +slower run allocates more slowly and the collector commits less. The two cancel: measured on a +larger case across a four-fold refinement, peak memory fell slightly while the mesh's own footprint +grew by nearly 40%. Read the two apart before concluding anything.

      What the Mesh Does Not Change

      For a representative test case — downward circular slot milling with varying width and depth — the physical values move within about 20% across the full range of mesh widths. The diff --git a/App/wwwroot/HiAPI-docsite/workflows/force-training.html b/App/wwwroot/HiAPI-docsite/workflows/force-training.html index 134be413..819d50d3 100644 --- a/App/wwwroot/HiAPI-docsite/workflows/force-training.html +++ b/App/wwwroot/HiAPI-docsite/workflows/force-training.html @@ -367,7 +367,7 @@ refining further showed no benefit.

      WriteStepFiles("Output/[NcName].step.csv");
       WriteShotFiles("Output/[NcName].shot.csv", 0.1); // 2nd arg = sampling period in ms
       
      -

      The shot file contains time-resolved force columns: Tool.Fx/Fy/Fz, Workpiece.Fx/Fy/Fz, Spindle.Mx/My/Mz.

      +

      The shot file opens with FileNo, LineNo, Time and the mission's M-codes, then carries the time-resolved force columns: Tool.Fx/Fy/Fz, Workpiece.Fx/Fy/Fz, Holder.Mx/My/Mz — the same holder spelling the reader writes, not the obsolete Spindle.M*. A play driven from a controller CSV appends ActualDateTime; an NC-simulated play has no controller instant to stamp and omits that column.

      ⚠ The shot sampling period is the dominant accuracy lever

      The second argument of WriteShotFiles is the sampling period in milliseconds, and when a simulated shot file is fed back into training it — not the angular division count, not the machining resolution — sets the accuracy ceiling. Each row is interpolated from the per-division force waveform, so the information per revolution is min(MillingCycleDivisionNum, samples per revolution), where

      samples per revolution = 60000 / (rpm × samplingPeriod_ms)
      diff --git a/App/wwwroot/HiAPI-docsite/xrefmap.yml b/App/wwwroot/HiAPI-docsite/xrefmap.yml
      index 4c551a35..c2a63e59 100644
      --- a/App/wwwroot/HiAPI-docsite/xrefmap.yml
      +++ b/App/wwwroot/HiAPI-docsite/xrefmap.yml
      @@ -119270,6 +119270,50 @@ references:
         isSpec: "True"
         fullName: Hi.NcParsers.Dependencys.Siemens.SiemensToolOffsetTableProxy.XName
         nameWithType: SiemensToolOffsetTableProxy.XName
      +- uid: Hi.NcParsers.Dependencys.StrokeLimitUtil
      +  name: StrokeLimitUtil
      +  href: api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html
      +  commentId: T:Hi.NcParsers.Dependencys.StrokeLimitUtil
      +  fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil
      +  nameWithType: StrokeLimitUtil
      +- uid: Hi.NcParsers.Dependencys.StrokeLimitUtil.DescribeUnlimitedAxes(System.Collections.Generic.IEnumerable{System.String},System.Func{System.String,System.Nullable{System.Double}},System.Func{System.String,System.Nullable{System.Double}})
      +  name: DescribeUnlimitedAxes(IEnumerable, Func, Func)
      +  href: api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html#Hi_NcParsers_Dependencys_StrokeLimitUtil_DescribeUnlimitedAxes_System_Collections_Generic_IEnumerable_System_String__System_Func_System_String_System_Nullable_System_Double___System_Func_System_String_System_Nullable_System_Double___
      +  commentId: M:Hi.NcParsers.Dependencys.StrokeLimitUtil.DescribeUnlimitedAxes(System.Collections.Generic.IEnumerable{System.String},System.Func{System.String,System.Nullable{System.Double}},System.Func{System.String,System.Nullable{System.Double}})
      +  name.vb: DescribeUnlimitedAxes(IEnumerable(Of String), Func(Of String, Double?), Func(Of String, Double?))
      +  fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.DescribeUnlimitedAxes(System.Collections.Generic.IEnumerable, System.Func, System.Func)
      +  fullName.vb: Hi.NcParsers.Dependencys.StrokeLimitUtil.DescribeUnlimitedAxes(System.Collections.Generic.IEnumerable(Of String), System.Func(Of String, Double?), System.Func(Of String, Double?))
      +  nameWithType: StrokeLimitUtil.DescribeUnlimitedAxes(IEnumerable, Func, Func)
      +  nameWithType.vb: StrokeLimitUtil.DescribeUnlimitedAxes(IEnumerable(Of String), Func(Of String, Double?), Func(Of String, Double?))
      +- uid: Hi.NcParsers.Dependencys.StrokeLimitUtil.DescribeUnlimitedAxes*
      +  name: DescribeUnlimitedAxes
      +  href: api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html#Hi_NcParsers_Dependencys_StrokeLimitUtil_DescribeUnlimitedAxes_
      +  commentId: Overload:Hi.NcParsers.Dependencys.StrokeLimitUtil.DescribeUnlimitedAxes
      +  isSpec: "True"
      +  fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.DescribeUnlimitedAxes
      +  nameWithType: StrokeLimitUtil.DescribeUnlimitedAxes
      +- uid: Hi.NcParsers.Dependencys.StrokeLimitUtil.GetChainAxisNames(Hi.Numerical.Xyzabc.IXyzabcChain,System.Boolean)
      +  name: GetChainAxisNames(IXyzabcChain, bool)
      +  href: api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html#Hi_NcParsers_Dependencys_StrokeLimitUtil_GetChainAxisNames_Hi_Numerical_Xyzabc_IXyzabcChain_System_Boolean_
      +  commentId: M:Hi.NcParsers.Dependencys.StrokeLimitUtil.GetChainAxisNames(Hi.Numerical.Xyzabc.IXyzabcChain,System.Boolean)
      +  name.vb: GetChainAxisNames(IXyzabcChain, Boolean)
      +  fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.GetChainAxisNames(Hi.Numerical.Xyzabc.IXyzabcChain, bool)
      +  fullName.vb: Hi.NcParsers.Dependencys.StrokeLimitUtil.GetChainAxisNames(Hi.Numerical.Xyzabc.IXyzabcChain, Boolean)
      +  nameWithType: StrokeLimitUtil.GetChainAxisNames(IXyzabcChain, bool)
      +  nameWithType.vb: StrokeLimitUtil.GetChainAxisNames(IXyzabcChain, Boolean)
      +- uid: Hi.NcParsers.Dependencys.StrokeLimitUtil.GetChainAxisNames*
      +  name: GetChainAxisNames
      +  href: api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html#Hi_NcParsers_Dependencys_StrokeLimitUtil_GetChainAxisNames_
      +  commentId: Overload:Hi.NcParsers.Dependencys.StrokeLimitUtil.GetChainAxisNames
      +  isSpec: "True"
      +  fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.GetChainAxisNames
      +  nameWithType: StrokeLimitUtil.GetChainAxisNames
      +- uid: Hi.NcParsers.Dependencys.StrokeLimitUtil.McAxisNames
      +  name: McAxisNames
      +  href: api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html#Hi_NcParsers_Dependencys_StrokeLimitUtil_McAxisNames
      +  commentId: F:Hi.NcParsers.Dependencys.StrokeLimitUtil.McAxisNames
      +  fullName: Hi.NcParsers.Dependencys.StrokeLimitUtil.McAxisNames
      +  nameWithType: StrokeLimitUtil.McAxisNames
       - uid: Hi.NcParsers.Dependencys.Syntec
         name: Hi.NcParsers.Dependencys.Syntec
         href: api/Hi.NcParsers.Dependencys.Syntec.html
      @@ -137703,6 +137747,22 @@ references:
         isSpec: "True"
         fullName: Hi.NcParsers.LogicSyntaxs.ProgramEndSyntax.Build
         nameWithType: ProgramEndSyntax.Build
      +- uid: Hi.NcParsers.LogicSyntaxs.ProgramEndSyntax.IsResetEdge(Hi.Common.Collections.LazyLinkedListNode{Hi.NcParsers.Syntaxs.SyntaxPiece})
      +  name: IsResetEdge(LazyLinkedListNode)
      +  href: api/Hi.NcParsers.LogicSyntaxs.ProgramEndSyntax.html#Hi_NcParsers_LogicSyntaxs_ProgramEndSyntax_IsResetEdge_Hi_Common_Collections_LazyLinkedListNode_Hi_NcParsers_Syntaxs_SyntaxPiece__
      +  commentId: M:Hi.NcParsers.LogicSyntaxs.ProgramEndSyntax.IsResetEdge(Hi.Common.Collections.LazyLinkedListNode{Hi.NcParsers.Syntaxs.SyntaxPiece})
      +  name.vb: IsResetEdge(LazyLinkedListNode(Of SyntaxPiece))
      +  fullName: Hi.NcParsers.LogicSyntaxs.ProgramEndSyntax.IsResetEdge(Hi.Common.Collections.LazyLinkedListNode)
      +  fullName.vb: Hi.NcParsers.LogicSyntaxs.ProgramEndSyntax.IsResetEdge(Hi.Common.Collections.LazyLinkedListNode(Of Hi.NcParsers.Syntaxs.SyntaxPiece))
      +  nameWithType: ProgramEndSyntax.IsResetEdge(LazyLinkedListNode)
      +  nameWithType.vb: ProgramEndSyntax.IsResetEdge(LazyLinkedListNode(Of SyntaxPiece))
      +- uid: Hi.NcParsers.LogicSyntaxs.ProgramEndSyntax.IsResetEdge*
      +  name: IsResetEdge
      +  href: api/Hi.NcParsers.LogicSyntaxs.ProgramEndSyntax.html#Hi_NcParsers_LogicSyntaxs_ProgramEndSyntax_IsResetEdge_
      +  commentId: Overload:Hi.NcParsers.LogicSyntaxs.ProgramEndSyntax.IsResetEdge
      +  isSpec: "True"
      +  fullName: Hi.NcParsers.LogicSyntaxs.ProgramEndSyntax.IsResetEdge
      +  nameWithType: ProgramEndSyntax.IsResetEdge
       - uid: Hi.NcParsers.LogicSyntaxs.ProgramEndSyntax.MakeXmlSource(System.String,System.String,System.Boolean)
         name: MakeXmlSource(string, string, bool)
         href: api/Hi.NcParsers.LogicSyntaxs.ProgramEndSyntax.html#Hi_NcParsers_LogicSyntaxs_ProgramEndSyntax_MakeXmlSource_System_String_System_String_System_Boolean_