Archived
434 lines
28 KiB
HTML
434 lines
28 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>STL Preview Pane | HiAPI-C# 2025 </title>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="title" content="STL Preview Pane | HiAPI-C# 2025 ">
|
||
|
||
|
||
<link rel="icon" href="../../img/HiAPI.favicon.ico">
|
||
<link rel="stylesheet" href="../../public/docfx.min.css">
|
||
<link rel="stylesheet" href="../../public/main.css">
|
||
<meta name="docfx:navrel" content="../../toc.html">
|
||
<meta name="docfx:tocrel" content="toc.html">
|
||
|
||
<meta name="docfx:rel" content="../../">
|
||
|
||
|
||
|
||
<meta name="loc:inThisArticle" content="In this article">
|
||
<meta name="loc:searchResultsCount" content="{count} results for "{query}"">
|
||
<meta name="loc:searchNoResults" content="No results for "{query}"">
|
||
<meta name="loc:tocFilter" content="Filter by title">
|
||
<meta name="loc:nextArticle" content="Next">
|
||
<meta name="loc:prevArticle" content="Previous">
|
||
<meta name="loc:themeLight" content="Light">
|
||
<meta name="loc:themeDark" content="Dark">
|
||
<meta name="loc:themeAuto" content="Auto">
|
||
<meta name="loc:changeTheme" content="Change theme">
|
||
<meta name="loc:copy" content="Copy">
|
||
<meta name="loc:downloadPdf" content="Download PDF">
|
||
|
||
<script type="module" src="./../../public/docfx.min.js"></script>
|
||
|
||
<script>
|
||
const theme = localStorage.getItem('theme') || 'auto'
|
||
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
|
||
</script>
|
||
|
||
</head>
|
||
|
||
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
|
||
<header class="bg-body border-bottom">
|
||
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
|
||
<div class="container-xxl flex-nowrap">
|
||
<a class="navbar-brand" href="../../index.html">
|
||
<img id="logo" class="svg" src="../../img/HiAPI.logo.png" alt="">
|
||
|
||
</a>
|
||
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
|
||
<i class="bi bi-three-dots"></i>
|
||
</button>
|
||
<div class="collapse navbar-collapse" id="navpanel">
|
||
<div id="navbar">
|
||
<form class="search" role="search" id="search">
|
||
<i class="bi bi-search"></i>
|
||
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
</header>
|
||
|
||
<main class="container-xxl">
|
||
<div class="toc-offcanvas">
|
||
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
|
||
<div class="offcanvas-header">
|
||
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
|
||
</div>
|
||
<div class="offcanvas-body">
|
||
<nav class="toc" id="toc"></nav>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="content">
|
||
<div class="actionbar">
|
||
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
|
||
<i class="bi bi-list"></i>
|
||
</button>
|
||
|
||
<nav id="breadcrumb"></nav>
|
||
</div>
|
||
|
||
<article data-uid="Anatomy-StlPreviewPane">
|
||
<h1 id="stl-preview-pane">STL Preview Pane</h1>
|
||
|
||
<p>The STL Preview Pane is the server-rendered 3D view that takes over the File Explorer's editor
|
||
column while an <code>.stl</code> file is open. It is neither a route nor a dialog of its own: it renders
|
||
inside the right-hand slave panel of <code>/util/file-explorer</code>, and of the modal file picker built on
|
||
the same browser component, replacing the text editor's bar and body for as long as an STL is
|
||
selected. It carries its own rendering connection, its own copy of the file's triangles, and a
|
||
Transform section that can bake a pose back into the file on disk.</p>
|
||
<h2 id="where-it-renders">Where It Renders</h2>
|
||
<p>The File Explorer mounts the pane on the root-relative path of the STL being previewed; the named
|
||
root and that path are both pinned when the preview opens, so switching the explorer's root closes
|
||
the preview rather than silently re-targeting it. Three gestures open one, and all key on the <code>stl</code>
|
||
extension alone:</p>
|
||
<ul>
|
||
<li>Selecting the row, but only while the editor slave panel is showing.</li>
|
||
<li>Submitting the file's path in the toolbar's path field, under that same panel-showing guard.</li>
|
||
<li>Double-clicking the row header, which shows the panel first.</li>
|
||
</ul>
|
||
<p>Panel visibility starts from the device-local File Explorer preferences on the page and defaults to
|
||
shown. Inside the modal picker it always starts hidden and is never written back, so there the
|
||
double-click is the only gesture that reaches a preview until the toolbar's editor-panel toggle is
|
||
pressed — and in a save-mode picker, where the path field names the save target rather than a place
|
||
to navigate to, submitting it never opens a preview at all.</p>
|
||
<p>Four gestures close one: the bar's own close button, opening a text file in the same panel, a root
|
||
switch, and the toolbar's editor-panel toggle. The first three leave the panel showing the text
|
||
editor; the last settles the text buffer, hides the whole panel and drops the preview together.</p>
|
||
<h2 id="layout">Layout</h2>
|
||
<ul>
|
||
<li>STL Preview Pane
|
||
<ul>
|
||
<li>Preview Bar
|
||
<ul>
|
||
<li>Location Label — the root's display name and the root-relative path, ellipsized, with the
|
||
full string as its hover title.</li>
|
||
<li>Triangle Count Badge — an outlined badge rendered only once a load has reported a count, and
|
||
cleared again at the start of every new load. The number is formatted for the app locale.</li>
|
||
<li><code>Scene ▾</code> Menu — the shared display-options dropdown, carrying one checkbox here,
|
||
<strong>Origin axes</strong>.</li>
|
||
<li><code>View ▾</code> Menu — the shared
|
||
<a class="xref" href="../widget/renderingcanvas-tool-bar.html">RenderingCanvas Tool Bar</a>, bound to this pane's canvas.</li>
|
||
<li><strong>Transform</strong> Button — shows and hides the Transform section; it reads primary-coloured while
|
||
the section is open, and starts off on every mount.</li>
|
||
<li>Close Button — a round <code>close</code> icon titled <strong>Close preview</strong>.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Transform Section — rendered only while the Transform button is on.
|
||
<ul>
|
||
<li>Header Row — a <strong>Transform</strong> caption and a <strong>Save</strong> button. Save stays disabled until a load
|
||
has published a transform key, and shows a loading state while the write is in flight.</li>
|
||
<li>General Transform Editor — the standard transformer editor, scrolling inside a capped height
|
||
so the canvas keeps most of the pane:
|
||
<ul>
|
||
<li><strong>Scale</strong> numeric field.</li>
|
||
<li><strong>Rotation sub-transformer</strong> card — <strong>Rotation axis</strong> as three components with a normalize
|
||
button, <strong>Angle</strong> in degrees, and <strong>Pivot</strong> in mm.</li>
|
||
<li><strong>Translation sub-transformer</strong> card — a <strong>Translation</strong> caption over three mm components.</li>
|
||
<li>A caption naming the composed transform as <code>T × R × scale × I</code>.</li>
|
||
<li>Every field here commits on blur or on Enter, one write per field.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Failure Text — with no transform key held, the section reads “Failed to load STL preview.” in
|
||
place of the editor.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Canvas Body
|
||
<ul>
|
||
<li>Rendering Canvas — fills the rest of the pane.</li>
|
||
<li>Loading Overlay — a centred spinner over a dim, click-through wash. The previously loaded
|
||
model stays visible beneath it rather than being cleared.</li>
|
||
<li>Error Banner — pinned to the foot of the canvas, carrying the failed load's message.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h2 id="loading-a-preview">Loading a Preview</h2>
|
||
<p>One request path serves every trigger: the canvas reporting a connection id, and any change to the
|
||
root or the relative path. Each request clears the banner and the triangle badge, raises the
|
||
spinner, and posts the named root and the relative path to <code>show</code>.</p>
|
||
<p>Server side, the controller resolves the root name, re-combines it with the relative path, refuses
|
||
a result that is not a descendant of that root, and refuses a path that does not exist. The read
|
||
itself runs on a thread-pool task rather than the request thread, and the format is sniffed from
|
||
the file's first two lines rather than from its extension — ASCII and binary STL both load. The
|
||
file is opened for shared read and write, so a load does not lock it against other readers.</p>
|
||
<p>A successful read builds the native topology, commits it into the connection's slot, and only then
|
||
touches the engine: the displayee is re-pointed at the new composition, the camera is reset to the
|
||
engine's home view and the render cache cleared, and the geometry the commit replaced is disposed
|
||
afterwards, so the render thread never spends a frame on a dead reference.</p>
|
||
<p>The response carries the triangle count, the bounding box, the connection's origin-axes flag and
|
||
the transform key. The pane reads all of those except the bounding box, which it ignores — the
|
||
bounding-box readout a reader sees belongs to the StlFile Editor's info dialog, not to this pane.</p>
|
||
<p>A rejected load — unknown or unavailable root, a path escaping the root, a missing file, an
|
||
unreadable file — answers a non-2xx status carrying the server's message, and the shared response
|
||
helper folds the status into the text; that composite is what the banner shows. The message itself
|
||
is passed through as the server wrote it: unlike the File Explorer's own endpoints, this controller
|
||
runs no root-prefix scrub over an exception message, so a read or write that fails down in the
|
||
filesystem layer can surface a server path in the banner.</p>
|
||
<h2 id="cancelling-a-load">Cancelling a Load</h2>
|
||
<p>Cancellation is the pane's defining behaviour: clicking down a folder of large STLs does not stack
|
||
multi-second reads behind each other, and the tree stays fully interactive throughout.</p>
|
||
<p>Three mechanisms compose:</p>
|
||
<ul>
|
||
<li><strong>A monotonic show token in the pane.</strong> Every request takes the next number; a response arriving
|
||
under a stale number is discarded, and the spinner is lowered only by the newest request. Without
|
||
it the slower of two racing round-trips would win the badge.</li>
|
||
<li><strong>An abort controller in the pane.</strong> Each request aborts the previous one's controller before
|
||
issuing its own, and swallows the resulting abort error. The same controller is aborted when the
|
||
pane unmounts.</li>
|
||
<li><strong>Supersede in the preview service.</strong> Before reading anything the controller asks the service to
|
||
supersede the connection, which cancels whatever load is still running and installs a fresh
|
||
cancellation source. That source doubles as the commit ticket. The request then reads under a
|
||
token linked from the ticket and from the request-aborted token, so a browser abort and a newer
|
||
selection cancel the same read.</li>
|
||
</ul>
|
||
<p>The read is cooperatively cancellable rather than interruptible: the STL reader checks the token
|
||
once every 4096 triangles, and once every 4096 lines of the pre-scan an ASCII file needs, which
|
||
bounds the latency to a few thousand parses rather than a whole file.</p>
|
||
<p>The commit is gated on the ticket. A load that finishes after a newer one superseded it is refused,
|
||
disposes the geometry it has just built, and answers HTTP 200 with a <code>canceled</code> flag; the pane drops
|
||
that response without touching the badge or the banner, and lowers the spinner only when no newer
|
||
request has taken the pane over in the meantime.</p>
|
||
<h2 id="the-rendering-connection">The Rendering Connection</h2>
|
||
<p>The pane embeds one rendering canvas, so it opens its own SignalR connection to <code>/renderingHub</code> and
|
||
the server gives that connection its own display engine — a second live engine beside the host
|
||
page's canvas whenever the preview is running inside the modal picker. See
|
||
<a class="xref" href="../conventions/rendering-canvas-web-service.html">Rendering Canvas on Web Service Application</a> for the
|
||
transport itself.</p>
|
||
<p>The connection id is the key for everything on the server side: the display engine, and the preview
|
||
service's per-connection slot. The canvas re-emits it after every automatic reconnect, and the pane
|
||
answers by re-issuing the show — which is what restores the preview after a connection drop. The
|
||
reconnected slot starts empty, so the pane re-pushes its own <strong>Origin axes</strong> preference whenever the
|
||
server's answer disagrees with it. The pose is not restored: every commit mints a fresh identity
|
||
transform.</p>
|
||
<p>Release runs off the connection's death rather than off an explicit teardown call. Closing the
|
||
preview unmounts the pane, which aborts the in-flight fetch and disconnects the canvas; the hub's
|
||
disconnect handler disposes the engine and raises its engine-removed event; the preview service's
|
||
subscriber then cancels any load still running, disposes the STL topology and the origin-axes
|
||
drawing, and withdraws the transform key. That subscriber exists because a display engine disposes
|
||
only itself — never the displayee it was pointed at.</p>
|
||
<p>The <code>clear</code> endpoint performs most of that detach on demand — it cancels the load in flight, empties
|
||
the canvas, disposes the topology and withdraws the transform key — but it keeps the connection's
|
||
slot registered, with its origin-axes drawing and flag intact for the next preview; only the
|
||
connection's death frees those. It is also the one entry in this surface that ships without a caller
|
||
in the SPA.</p>
|
||
<h2 id="server-side-composition">Server-Side Composition</h2>
|
||
<p>The slot a connection owns holds a small display graph rather than a bare mesh:</p>
|
||
<ul>
|
||
<li><a class="xref" href="../../api/Hi.Geom.Topo.NativeTopoStl3d.html">NativeTopoStl3d</a> — the native topology built from the file's triangles, and one
|
||
of the two objects here that have to be disposed by hand.</li>
|
||
<li><a class="xref" href="../../api/Hi.Disp.Treat.TransformationWrapper.html">TransformationWrapper</a> — wraps that topology and carries the pose matrix.</li>
|
||
<li><a class="xref" href="../../api/Hi.Disp.Flag.CoordinateDrawing.html">CoordinateDrawing</a> — the origin axes, created on first enable and kept across
|
||
file switches, because the flag is a per-connection viewing preference rather than a property of
|
||
the file. It is the other hand-disposed object, and only the connection's death frees it.</li>
|
||
<li><a class="xref" href="../../api/Hi.Disp.DispList.html">DispList</a> — the composition assigned to <a class="xref" href="../../api/Hi.Disp.DispEngine.html#Hi_Disp_DispEngine_Displayee">Displayee</a>: the
|
||
axes drawing, when shown, followed by the wrapper.</li>
|
||
<li><a class="xref" href="../../api/Hi.Mech.Topo.GeneralTransform.html">GeneralTransform</a> — the pose the Transform section drives.</li>
|
||
</ul>
|
||
<p><a class="xref" href="../../api/Hi.Geom.Stl.html">Stl</a> is not among them. The reader's output is a local of the show request, alive only
|
||
long enough for the native topology to copy its triangles into its own buffer and for the response
|
||
to report the triangle count and the bounding box; the save path then mints a second one out of the
|
||
topology's own snapshot, and it is that second object the save transforms and writes.</p>
|
||
<p>The committed topology always holds the file's as-loaded triangles. The editor's pose lives only in
|
||
the wrapper, which is why it can be re-applied, reset or saved repeatedly without drift.</p>
|
||
<h2 id="transform-and-save">Transform and Save</h2>
|
||
<p>Each committed load registers a fresh <a class="xref" href="../../api/Hi.Mech.Topo.GeneralTransform.html">GeneralTransform</a> — identity, and a new
|
||
object rather than a reset one — in the server's keyed object store, and returns its key. The pane
|
||
hands that key to the standard general-transform editor, the same component and the same REST
|
||
surface the Transformer panels use; there is no preview-specific transform schema. After every
|
||
committed edit the pane posts <code>apply-transform</code>, which re-reads the transform's matrix into the
|
||
display wrapper and clears the render cache. That is display only — the file is untouched.</p>
|
||
<p>Save asks for confirmation naming the root-relative path, then bakes. The service snapshots the
|
||
native triangles under the topology's own dispose lock, multiplies them by the current matrix and
|
||
writes the result over the previewed file as a <strong>binary</strong> STL, so an ASCII source is rewritten in
|
||
binary form. Because the shown topology keeps the as-loaded triangles and the editor keeps its
|
||
values, screen and disk agree afterwards — both are the original geometry times the current matrix —
|
||
and saving twice with the same values rewrites the same file rather than compounding the pose.
|
||
Resetting the editor's fields returns to the as-loaded pose.</p>
|
||
<p>A save that finds the topology already disposed by a newer selection reports that it was superseded
|
||
instead of writing. On success the pane raises a toast and the File Explorer re-lists the containing
|
||
folder, so the row's size and modified columns catch up. Nothing else is refreshed: a
|
||
<a class="xref" href="../../api/Hi.Geom.StlFile.html">StlFile</a> geometry elsewhere in the project that references the same path keeps the
|
||
triangles it already loaded.</p>
|
||
<p>Switching files re-mints the transform — a new key, an identity pose, and an editor that re-reads
|
||
cleanly because the key changed. The old key is withdrawn from the keyed store on replacement, on
|
||
clear and on connection death; the two derived keys the editor mints beneath it for the rotation and
|
||
translation sub-transformers are not withdrawn with it.</p>
|
||
<h2 id="endpoints">Endpoints</h2>
|
||
<p>Every entry is a POST under <code>/api/stl-preview</code>, addressed by the rendering connection id. The four
|
||
that touch the canvas resolve the display engine through the non-creating lookup, so a disconnected
|
||
id cannot orphan a fresh engine; <code>save</code> needs no engine at all and writes straight from the slot.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Path</th>
|
||
<th>Body</th>
|
||
<th>Purpose</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>show/{renderingConnectionId}</code></td>
|
||
<td><code>{ rootName, relFile }</code></td>
|
||
<td>Supersede, read, commit, re-point the engine. Answers the triangle count, the bounding box, the origin-axes flag and the transform key — or a <code>canceled</code> flag.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>set-coordinate/{renderingConnectionId}</code></td>
|
||
<td>a bare boolean</td>
|
||
<td>Show or hide the origin axes. With nothing on the canvas yet it stores the flag for the next commit.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>apply-transform/{renderingConnectionId}</code></td>
|
||
<td>none</td>
|
||
<td>Re-read the transform's matrix into the display wrapper.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>save/{renderingConnectionId}</code></td>
|
||
<td>none</td>
|
||
<td>Bake the matrix into the geometry and overwrite the file.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>clear/{renderingConnectionId}</code></td>
|
||
<td>none</td>
|
||
<td>Cancel the load in flight, empty the canvas, free the STL geometry; the slot and its origin-axes drawing survive.</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p><code>rootName</code> is one of the three named roots — the admin directory, the loaded project directory and
|
||
the shared resource directory — resolved server-side; the project root is unavailable until a
|
||
project is loaded. Addressing is root-relative in both directions and the absolute path is formed
|
||
and kept on the server; the unscrubbed error text noted above is the one place it can escape.</p>
|
||
<h2 id="the-text-buffer-underneath">The Text Buffer Underneath</h2>
|
||
<p>Opening a preview does not disturb the text editor beneath it. There is no flush, no discard prompt
|
||
and no reload: the loaded path, the buffer, its saved snapshot and its dirty mark are all left as
|
||
they were, and the bar's close button brings them straight back, dirty star included. Clicking a
|
||
text file while a preview is open closes the preview first and then loads that file through the
|
||
editor's normal open path, which settles the outgoing buffer the way any file switch does.</p>
|
||
<p>Two consequences follow from the buffer staying live. The toolbar's editor-panel toggle remains
|
||
reachable while the preview is up, and it settles the buffer before hiding the panel — so a dirty
|
||
buffer in manual mode raises its discard confirm at that point, even though the visible pane is a 3D
|
||
canvas. And an auto-save debounce armed just before the preview opened still fires underneath it.</p>
|
||
<h2 id="source-code-path">Source Code Path</h2>
|
||
<p>See <a class="xref" href="../index.html">HiNC App Anatomy</a> for git repository links.</p>
|
||
<h3 id="web-application">Web Application</h3>
|
||
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
|
||
<ul>
|
||
<li><code>wwwroot-src/src/components/StlPreviewPane.vue</code> — this pane: the bar, the Transform section, the
|
||
canvas body with its overlay and banner, the show token and abort controller, and the optimistic
|
||
origin-axes toggle.</li>
|
||
<li><code>wwwroot-src/src/components/FileExplorer.vue</code> — the sole host: the preview slot in the editor
|
||
slave panel, the extension test and the three opening gestures, the pinned root, the close paths,
|
||
and the folder refresh after a save.</li>
|
||
<li><code>wwwroot-src/src/components/widgets/FileExplorerDialog.vue</code> — the modal wrapper, whose picker
|
||
props are what leave the editor panel hidden inside the picker.</li>
|
||
<li><code>wwwroot-src/src/pages/FileExplorerPage.vue</code> — the routed host at <code>/util/file-explorer</code>.</li>
|
||
<li><code>wwwroot-src/src/api/stlPreview.ts</code> — the typed wrapper over the five endpoints, the result shape,
|
||
and the abort signal threaded into <code>show</code>.</li>
|
||
<li><code>wwwroot-src/src/api/http.ts</code> — the shared response helper that wrapper uses: a non-2xx throws an
|
||
error whose text is the status followed by the server's message, while a 200 body carrying
|
||
<code>success: false</code> reaches the caller as data, which is what lets the <code>canceled</code> answer be ignored
|
||
silently.</li>
|
||
<li><code>wwwroot-src/src/components/RenderingCanvas.vue</code> — the connection the pane owns, its reconnect
|
||
loop and the re-emitted connection id.</li>
|
||
<li><code>wwwroot-src/src/components/RenderingCanvasToolBar.vue</code> — the <code>View ▾</code> menu in the bar.</li>
|
||
<li><code>wwwroot-src/src/components/widgets/DisplayOptionsMenu.vue</code> — the <code>Scene ▾</code> dropdown; the pane
|
||
passes one checkbox group and no label, so the button falls back to the localized “Scene”.</li>
|
||
<li><code>wwwroot-src/src/components/topo/GeneralTransformEditor.vue</code>,
|
||
<code>wwwroot-src/src/components/topo/StaticRotationEditor.vue</code> and
|
||
<code>wwwroot-src/src/components/topo/StaticTranslationEditor.vue</code> — the Transform section's editor and
|
||
its two sub-transformer cards.</li>
|
||
<li><code>wwwroot-src/src/components/widgets/NumericInput.vue</code> and
|
||
<code>wwwroot-src/src/components/widgets/Vec3Input.vue</code> — the fields inside them, committing on blur or
|
||
Enter.</li>
|
||
<li><code>wwwroot-src/src/api/transformer.ts</code>, <code>wwwroot-src/src/api/geometry.ts</code> and
|
||
<code>wwwroot-src/src/api/index-service.ts</code> — the standard transform surface those editors write
|
||
through.</li>
|
||
<li><code>wwwroot-src/src/i18n/en/explorer.ts</code> — the <code>explorer.preview.*</code> strings: the close title, the
|
||
failure text, <strong>Origin axes</strong>, <strong>Transform</strong>, and the save-confirm dialog.</li>
|
||
<li><code>wwwroot-src/src/i18n/en/geom.ts</code> — the pluralized triangle-count phrase in the badge.</li>
|
||
<li><code>wwwroot-src/src/i18n/en/topo.ts</code> and <code>wwwroot-src/src/i18n/en/widgets.ts</code> — the transform-editor
|
||
captions, and the <code>Scene</code> and <code>View</code> menu labels.</li>
|
||
<li><code>Disp/StlPreviewController.cs</code> — the five endpoints, the root resolution and descendant check, the
|
||
off-thread read, the commit-then-swap ordering, the <code>canceled</code> answer, and the failure replies
|
||
that pass an exception message through unaltered.</li>
|
||
<li><code>Common/FileExplorerController.cs</code> — the root-prefix scrub over exception text that the File
|
||
Explorer's own endpoints apply and this surface does not share.</li>
|
||
<li><code>Disp/StlPreviewService.cs</code> — the per-connection slot: supersede and the commit ticket, the display
|
||
composition, the origin-axes flag that survives file switches, the bake-and-write save, and the
|
||
engine-removed handler that frees everything.</li>
|
||
<li><code>Disp/RenderingService.cs</code> — the per-connection engine store, the non-creating lookup HTTP
|
||
endpoints must use, and the engine-removed event.</li>
|
||
<li><code>Disp/RenderingHub.cs</code> — the hub whose disconnect disposes the engine and raises that event.</li>
|
||
<li><code>Common/NamedRootResolver.cs</code> — the three named roots and their availability rules.</li>
|
||
<li><code>Common/IndexService.cs</code> — the keyed object store the transform is published in.</li>
|
||
<li><code>Mech/Topo/GeneralTransformController.cs</code> — the standard transform endpoints, including the two
|
||
that index the rotation and translation sub-transformers under derived keys.</li>
|
||
</ul>
|
||
<h3 id="hiapi-engine">HiAPI Engine</h3>
|
||
<ul>
|
||
<li><code>HiGeom/Geom/Stl.cs</code> — the reader: content-sniffed ASCII / binary detection, the cancellation check
|
||
every 4096 triangles or pre-scan lines, and the binary writer the save uses.</li>
|
||
<li><code>HiDisp/Geom/Topo/NativeTopoStl3d.cs</code> — the native topology, and the locked triangle snapshot the
|
||
save takes, which answers nothing once the topology has been disposed.</li>
|
||
<li><code>HiDisp/Disp/Treat/TransformationWrapper.cs</code> — the display-time pose applied to that topology.</li>
|
||
<li><code>HiDisp/Disp/Flag/CoordinateDrawing.cs</code> — the origin-axes drawing.</li>
|
||
<li><code>HiDisp/Disp/DispList.cs</code> — the one- or two-element composition the engine is pointed at.</li>
|
||
<li><code>HiDisp/Disp/DispEngine.cs</code> — the engine: its displayee, its cache clear, its home view, and a
|
||
dispose that frees the native engine alone.</li>
|
||
<li><code>HiMech/Mech/Topo/GeneralTransform.cs</code> — the pose model, its uniform scale and its two
|
||
sub-transformers.</li>
|
||
</ul>
|
||
<h2 id="see-also">See Also</h2>
|
||
<ul>
|
||
<li><a href="file-explorer.html">File Explorer</a> — the one screen that mounts this pane, and the editor column it
|
||
takes over</li>
|
||
<li><a class="xref" href="../geom/stlfile-editor.html">StlFile Editor</a> — the geometry editor whose file picker is where this preview is
|
||
most often met, and the surface that owns the bounding-box readout this pane does not show</li>
|
||
<li><a class="xref" href="../widget/renderingcanvas-tool-bar.html">RenderingCanvas Tool Bar</a> — the <code>View ▾</code> and <code>Scene ▾</code> menus the preview bar embeds</li>
|
||
<li><a class="xref" href="../conventions/rendering-canvas-web-service.html">Rendering Canvas on Web Service Application</a> — the hub connection the pane opens, and the
|
||
engine-removed event that frees the preview's native geometry</li>
|
||
</ul>
|
||
|
||
</article>
|
||
|
||
<div class="contribution d-print-none">
|
||
</div>
|
||
|
||
<div class="next-article d-print-none border-top" id="nextArticle"></div>
|
||
|
||
</div>
|
||
|
||
<div class="affix">
|
||
<nav id="affix"></nav>
|
||
</div>
|
||
</main>
|
||
|
||
<div class="container-xxl search-results" id="search-results"></div>
|
||
|
||
<footer class="border-top text-secondary">
|
||
<div class="container-xxl">
|
||
<div class="flex-fill">
|
||
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
</body>
|
||
</html>
|