@toolpath/viewer 1.5.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -25
- package/dist/{chunk-4TBLMR4Z.js → chunk-WTTOUG4P.js} +27 -14
- package/dist/engine/index.d.ts +2 -2
- package/dist/engine/index.js +1 -1
- package/dist/index.d.ts +224 -27
- package/dist/index.js +563 -111
- package/dist/{normalize-CvnV9Ggh.d.ts → normalize--FiXUhO4.d.ts} +7 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -76,7 +76,7 @@ What each wrapper is for:
|
|
|
76
76
|
├─ <EnginePart> validates the report, loads the mesh, then renders <PartMesh>
|
|
77
77
|
│ └─ <PartMesh> draws the part and handles hover, click, colours, section cuts
|
|
78
78
|
├─ <DirectionArrows> arrows for the directions the part can be machined from
|
|
79
|
-
├─ <Stock>
|
|
79
|
+
├─ <Stock> translucent geometry, GLB, box or cylinder stock, included in Fit
|
|
80
80
|
├─ <SectionTool> optional: click a face or a plane to cut the part open
|
|
81
81
|
├─ <MeasureTool> optional: click two points for a distance, three for an angle
|
|
82
82
|
├─ <Grid> <Axes> reference geometry, sized to the part
|
|
@@ -146,9 +146,8 @@ context rather than a fact of the part surface.
|
|
|
146
146
|
|
|
147
147
|
### Stock and display controls
|
|
148
148
|
|
|
149
|
-
Use `<
|
|
150
|
-
|
|
151
|
-
must use the same millimetre, Z-up frame. Both components include stock in Fit and Reset while
|
|
149
|
+
Use `<Stock>` for a box, cylinder, prepared geometry or GLB bytes. Stock and part coordinates
|
|
150
|
+
must use the same millimetre, Z-up frame. Stock is included in Fit and Reset while
|
|
152
151
|
keeping section tools, measurements, the grid, and direction arrows sized to the finished part.
|
|
153
152
|
Stock does not intercept clicks or get clipped by the part's section plane.
|
|
154
153
|
|
|
@@ -156,7 +155,7 @@ Stock does not intercept clicks or get clipped by the part's section plane.
|
|
|
156
155
|
import { useMemo, useRef, useState } from 'react'
|
|
157
156
|
import {
|
|
158
157
|
Axes,
|
|
159
|
-
|
|
158
|
+
Stock,
|
|
160
159
|
DirectionArrows,
|
|
161
160
|
PartMesh,
|
|
162
161
|
Viewer,
|
|
@@ -187,7 +186,7 @@ export function StockPreview({ model, geometry }: { model: PartModel; geometry:
|
|
|
187
186
|
regionHighlights={colors}
|
|
188
187
|
activeDirection={directions ? direction : null}
|
|
189
188
|
/>
|
|
190
|
-
{stock && <
|
|
189
|
+
{stock && <Stock box={{ partGeometry: geometry, allowance: { wall: 3, floor: 3 } }} />}
|
|
191
190
|
{axes && <Axes />}
|
|
192
191
|
<DirectionArrows
|
|
193
192
|
directions={model.candidateDirections}
|
|
@@ -214,25 +213,103 @@ export function StockPreview({ model, geometry }: { model: PartModel; geometry:
|
|
|
214
213
|
}
|
|
215
214
|
```
|
|
216
215
|
|
|
217
|
-
|
|
216
|
+
For a box preview, pass `box={{ partGeometry, allowance, offset }}`. Allowance is padding
|
|
217
|
+
**per side**, in millimetres. The preferred form is
|
|
218
218
|
`{ wall, floor }`: wall stock expands X/Y and floor stock expands Z, matching the wall/floor
|
|
219
219
|
roughing-stock distinction used by machining settings. A number or `{ x, y, z }` remains accepted
|
|
220
220
|
for uniform or axis-specific padding. It defaults to zero. `offset` translates the stock from the
|
|
221
221
|
part's bounding-box centre. `boxStockBounds(geometry, allowance, offset)` returns the same `Box3`
|
|
222
222
|
for displaying dimensions.
|
|
223
223
|
|
|
224
|
-
For fixed-box
|
|
224
|
+
For fixed-box previews, pass `box={{ partGeometry, dimensions, position, positionOffset, offset }}`
|
|
225
|
+
instead, where `dimensions` is `{ x, y, z }`. Dimensions and allowance are alternative sizing
|
|
226
|
+
modes, not simultaneous options. `position` accepts
|
|
225
227
|
`model_centered`, `offset_from_top`, or `offset_from_bottom`, and `positionOffset` is the distance
|
|
226
228
|
from the selected top or bottom bound. All fixed-box values use millimetres and the part's Z-up
|
|
227
229
|
coordinate frame.
|
|
228
230
|
Negative/non-finite allowances, non-finite coordinates, and empty or non-positive stock dimensions
|
|
229
231
|
throw `RangeError`. The 3 mm allowance above is an example, not an automatic stock recommendation.
|
|
230
232
|
|
|
231
|
-
|
|
232
|
-
`
|
|
233
|
+
`<Stock cylinder={{ origin, axis, diameter, length }} />` draws round stock along any axis:
|
|
234
|
+
`origin` is the centre of its base and `axis` points from the base toward its far end, in part
|
|
235
|
+
coordinates. For a preview, pass
|
|
236
|
+
`cylinder={{ partGeometry, diameter, length, position, positionOffset }}` instead. It stands along
|
|
237
|
+
the part's Z, is centred on the part's bounding box, and is placed along Z by the same `position`
|
|
238
|
+
rule as fixed-box stock. The kernel centres fixed round stock on the part's
|
|
239
|
+
smallest enclosing circle about the first setup's cutting direction, so render the resolved stock
|
|
240
|
+
once a job is planned.
|
|
241
|
+
|
|
242
|
+
`<Stock box={{ frame, lower, upper }} />` draws a block whose corners are given in a frame
|
|
243
|
+
of `location`, `axis` and `refDirection`: a point `(x, y, z)` sits at
|
|
244
|
+
`location + x·refDirection + y·(axis × refDirection) + z·axis`, with `axis` normalised and
|
|
245
|
+
`refDirection` projected square to it and normalised. That is the shape of an Engine plan's
|
|
246
|
+
`stock.resolved` box, which is squared to the setup rather than to the part. Omit `frame` when
|
|
247
|
+
`lower` and `upper` are already in part coordinates. Resolved placement and `partGeometry`
|
|
248
|
+
preview options are mutually exclusive for both shapes.
|
|
249
|
+
|
|
250
|
+
Box and cylinder sources rebuild their mesh only when their figures/options change (or the
|
|
251
|
+
preview's `partGeometry` reference changes). Inline option objects do not trigger repeated part
|
|
252
|
+
scans on ordinary renders. Figures that cannot make a
|
|
253
|
+
solid — a zero axis, a non-positive size, a frame whose axis and reference direction are parallel —
|
|
254
|
+
throw `RangeError`.
|
|
255
|
+
|
|
256
|
+
`Stock` accepts exactly one of `geometry`, `glb`, `box` or `cylinder`:
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
<Stock geometry={geometry} showEdges={false} />
|
|
260
|
+
// Or:
|
|
261
|
+
<Stock glb={glbBytes} showEdges={false} />
|
|
262
|
+
<Stock box={resolvedBox} />
|
|
263
|
+
<Stock cylinder={resolvedCylinder} />
|
|
264
|
+
<Stock box={{ partGeometry, dimensions, position, positionOffset }} />
|
|
265
|
+
<Stock cylinder={{ partGeometry, diameter, length, position, positionOffset }} />
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
All four inputs are mutually exclusive in `StockProps`. With `geometry`, the caller owns its
|
|
269
|
+
lifetime and disposal. With `box` or `cylinder`, `Stock` owns the generated geometry. With `glb`,
|
|
270
|
+
`Stock` decodes the bytes internally and disposes decoded
|
|
271
|
+
geometry when the bytes change or the component unmounts. Keep the same `ArrayBuffer` reference
|
|
272
|
+
while displaying the same artifact to avoid decoding it again on ordinary renders.
|
|
273
|
+
It renders nothing while decoding and throws decoding failures to the nearest error boundary.
|
|
274
|
+
Changing the source immediately hides the previous stock; late results from an earlier decode
|
|
275
|
+
are discarded and cleaned up.
|
|
276
|
+
|
|
277
|
+
The component does not fetch, cache or store artifacts. The caller supplies the bytes.
|
|
278
|
+
GLB node transforms are applied without centering, rescaling or changing axes:
|
|
279
|
+
Engine stock artifacts are already in part coordinates, millimetres and Z-up. Indexed geometry
|
|
280
|
+
stays indexed; missing normals are computed without requiring a part report. The parser cleans up
|
|
281
|
+
its temporary scene after preparing the returned geometry.
|
|
282
|
+
|
|
283
|
+
Engine stock files are plain GLB served with HTTP gzip, which the browser handles automatically;
|
|
284
|
+
no meshopt decoder is needed. Authentication, durable artifact copies, action selection and
|
|
285
|
+
missing-artifact fallback and artifact caching belong to the application. The example's
|
|
286
|
+
**Stock source → GLB fixture** option exercises synthetic blanks encoded by the services stock
|
|
287
|
+
writer. **Shape preview** exposes the separate box/cylinder shape controls.
|
|
288
|
+
|
|
289
|
+
`Stock` accepts `color`, `emissive` (default black), `flatShading` (default `false`),
|
|
290
|
+
`opacity` (default `0.2`), `edgeColor`, `edgeOpacity`, and `showEdges`. Emissive shading
|
|
291
|
+
and flat shading change only the material, not the source's vertices, indices or normals.
|
|
292
|
+
`renderStyle="legacy-workpiece"` reproduces legacy Workpiece rendering: white with dark emissive
|
|
293
|
+
shading, per-face shading, 20% opacity, two shared-geometry surface passes and black 50%-opacity
|
|
294
|
+
edges drawn before surfaces (rather than over them). The default `overlay` style is unchanged.
|
|
295
|
+
|
|
296
|
+
For action-to-action playback, `retainPrevious` keeps the current decoded GLB visible until
|
|
297
|
+
the next GLB is ready, then swaps meshes without a blank frame. Key the stock's parent by
|
|
298
|
+
part/calculation identity (not action) to prevent retaining geometry across unrelated runs.
|
|
299
|
+
The default still hides the previous source during decoding. Geometry is disposed after a
|
|
300
|
+
replacement commits; cancelled/late results are discarded.
|
|
301
|
+
The outline is built the first time it is shown, so a large stock mesh with `showEdges={false}`
|
|
302
|
+
costs no edge pass. All source types accept the same appearance props. Caller-provided geometry is never disposed; the
|
|
233
303
|
components dispose their own materials and outlines. Conditionally mount stock to toggle it.
|
|
234
304
|
Toggling stock preserves the camera; Fit/Reset then frames the visible stock together with the part.
|
|
235
305
|
|
|
306
|
+
**Migration from 1.x:** `BoxStock` and `BoxStockProps` have been removed. Use
|
|
307
|
+
`<Stock box={{ partGeometry, allowance, offset }} />` for allowance-based previews, or
|
|
308
|
+
`<Stock box={{ partGeometry, dimensions, position, positionOffset, offset }} />` for fixed
|
|
309
|
+
dimensions. No preview-builder helper is required. `Stock geometry={geometry}` remains supported.
|
|
310
|
+
`StockProps` is now a union type alias, so `interface X extends StockProps` becomes
|
|
311
|
+
`type X = StockProps & { … }`; `StockAppearanceProps` names the shared appearance props alone.
|
|
312
|
+
|
|
236
313
|
`directionHighlights(model, activeDirection?)` returns region colors in the same palette as
|
|
237
314
|
`DirectionArrows`. For a face with several owners, the most specific feature wins, followed by
|
|
238
315
|
candidate-direction order and feature tag. Unmatched directions are left unpainted. Hover and
|
|
@@ -280,8 +357,8 @@ individual buttons to use only the controls and order your application needs.
|
|
|
280
357
|
</ViewerToolbarProvider>
|
|
281
358
|
```
|
|
282
359
|
|
|
283
|
-
`ViewerToolbar.Controls`, `Divider`, and the
|
|
284
|
-
`ViewerToolbar`: `StockButton`, `AxesButton`, `GridButton`, `BananaButton`, `DirectionsButton`,
|
|
360
|
+
`ViewerToolbar.Controls`, `Divider`, and the fourteen `*Button` components are available on
|
|
361
|
+
`ViewerToolbar`: `StockButton`, `AxesButton`, `GridButton`, `BananaButton`, `ToolsButton`, `DirectionsButton`,
|
|
285
362
|
`HoverButton`, `FocusButton`, `WireframeButton`, `SectionButton`, `MeasureButton`, `FitButton`,
|
|
286
363
|
`ResetButton`, and `TopButton`. A rendered button requires its matching provider control. For an
|
|
287
364
|
application-specific toolbar component, `useViewerToolbar()` reads the same controls from inside
|
|
@@ -311,19 +388,19 @@ override any of these selectors in your application stylesheet.
|
|
|
311
388
|
The following `data-*` attributes identify generated elements without depending on labels, which
|
|
312
389
|
can change with state or localization:
|
|
313
390
|
|
|
314
|
-
| Attribute | Element and values
|
|
315
|
-
| ------------------------------------- |
|
|
316
|
-
| `data-viewer-root="true"` | `<Viewer>` wrapper
|
|
317
|
-
| `data-viewer-canvas-container="true"` | R3F canvas event container
|
|
318
|
-
| `data-viewer-canvas-frame="true"` | R3F canvas-sizing frame
|
|
319
|
-
| `data-viewer-canvas="true"` | The `<canvas>` itself
|
|
320
|
-
| `data-viewer-hover-card="true"` | `<HoverCard>` shell
|
|
321
|
-
| `data-viewer-toolbar="true"` | Toolbar stack
|
|
322
|
-
| `data-viewer-toolbar-controls="true"` | Controls group
|
|
323
|
-
| `data-viewer-toolbar-action` | Standard button: `stock`, `axes`, `grid`, `banana`, `directions`, `hover`, `focus`, `wireframe`, `section`, `measure`, `fit`, `reset`, or `top` |
|
|
324
|
-
| `data-viewer-toolbar-icon="true"` | Standard button SVG
|
|
325
|
-
| `data-viewer-toolbar-tooltip="true"` | Standard button tooltip
|
|
326
|
-
| `data-viewer-toolbar-divider="true"` | Toolbar separator
|
|
391
|
+
| Attribute | Element and values |
|
|
392
|
+
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
393
|
+
| `data-viewer-root="true"` | `<Viewer>` wrapper |
|
|
394
|
+
| `data-viewer-canvas-container="true"` | R3F canvas event container |
|
|
395
|
+
| `data-viewer-canvas-frame="true"` | R3F canvas-sizing frame |
|
|
396
|
+
| `data-viewer-canvas="true"` | The `<canvas>` itself |
|
|
397
|
+
| `data-viewer-hover-card="true"` | `<HoverCard>` shell |
|
|
398
|
+
| `data-viewer-toolbar="true"` | Toolbar stack |
|
|
399
|
+
| `data-viewer-toolbar-controls="true"` | Controls group |
|
|
400
|
+
| `data-viewer-toolbar-action` | Standard button: `stock`, `axes`, `grid`, `banana`, `tools`, `directions`, `hover`, `focus`, `wireframe`, `section`, `measure`, `fit`, `reset`, or `top` |
|
|
401
|
+
| `data-viewer-toolbar-icon="true"` | Standard button SVG |
|
|
402
|
+
| `data-viewer-toolbar-tooltip="true"` | Standard button tooltip |
|
|
403
|
+
| `data-viewer-toolbar-divider="true"` | Toolbar separator |
|
|
327
404
|
|
|
328
405
|
Toggle buttons also carry standard `aria-pressed="true"` or `"false"`; use that to style their
|
|
329
406
|
current state. `Fit`, `Reset`, and `Top view` are actions rather than toggles, so they omit the
|
|
@@ -424,6 +501,7 @@ Draws the part and handles clicks. You only use it directly when you
|
|
|
424
501
|
| `section` | `SectionOptions` | Cut the part open. Omit it to follow the viewer's own cut. See [Section view](#section-view). |
|
|
425
502
|
| `onSectionChange` | `(state: SectionState) => void` | Called when the cut moves or goes away. With `section`, passing it also shows the drag handle. |
|
|
426
503
|
| `onAdjacency` | `(map) => void` | Called once per mesh with which faces touch which. |
|
|
504
|
+
| `children` | `ReactNode` | Objects drawn on the part. They read its model and mesh with `usePartContext()`. |
|
|
427
505
|
|
|
428
506
|
Hovering over the part is handled for you. You only need `onHover` if you want to show the hovered
|
|
429
507
|
feature elsewhere in your UI.
|
|
@@ -529,6 +607,56 @@ what a label looks like is your stylesheet's, through the `toolpath-measure-labe
|
|
|
529
607
|
data attributes on each one — see [Measuring](#measuring) for a starting point. While the tool is
|
|
530
608
|
mounted the part reports no hovers or picks, as with `<SectionTool>`.
|
|
531
609
|
|
|
610
|
+
### `<ToolMarks>`
|
|
611
|
+
|
|
612
|
+
Cutting tools drawn on the part, each to scale where it stands: a see-through end mill — flat,
|
|
613
|
+
bull nose or ball — or any tool given by its profile, rimmed at its bottom and top, with a dimension
|
|
614
|
+
across its top and a label on it. What a tool stands for is yours: the widest tool a pocket admits, the tool an operation uses.
|
|
615
|
+
Nothing here reads a datasheet.
|
|
616
|
+
|
|
617
|
+
```tsx
|
|
618
|
+
<EnginePart report={report}>
|
|
619
|
+
<ToolMarks
|
|
620
|
+
marks={[
|
|
621
|
+
{
|
|
622
|
+
base: { x: 12, y: 4, z: -8 },
|
|
623
|
+
axis: { x: 0, y: 0, z: 1 },
|
|
624
|
+
diameter: 6,
|
|
625
|
+
height: 8,
|
|
626
|
+
cornerRadius: 0.5,
|
|
627
|
+
label: '⌀ 6.000 mm',
|
|
628
|
+
note: 'bull nose R 0.5',
|
|
629
|
+
},
|
|
630
|
+
]}
|
|
631
|
+
/>
|
|
632
|
+
</EnginePart>
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
| Prop | What it does |
|
|
636
|
+
| ---------------- | ---------------------------------------------------------------------------------- |
|
|
637
|
+
| `marks` | The tools, in the coordinates the part is drawn in. See `ToolMark` below. |
|
|
638
|
+
| `visible` | `false` hides them without unmounting. On by default. |
|
|
639
|
+
| `labelClassName` | Added to every label, beside `toolpath-measure-label`. |
|
|
640
|
+
| `theme` | `measure` colours the rims and the dimension, as it does the measure tool's lines. |
|
|
641
|
+
|
|
642
|
+
A `ToolMark` is `base` (the centre of the tool's bottom), `axis` (up the tool), `diameter`,
|
|
643
|
+
`height`, and optionally `cornerRadius` (0 flat, half the diameter a ball), `across` (which way the
|
|
644
|
+
dimension runs; any direction square to the axis otherwise), `label` and `note`. Any other tool —
|
|
645
|
+
a drill, a chamfer mill, a tool in its holder — takes `profile`: its side as `{ r, z }` points from
|
|
646
|
+
the tip up, such as `@toolpath/tool-drawing`'s outline, turned about the axis in place of the end
|
|
647
|
+
mill.
|
|
648
|
+
|
|
649
|
+
Show and hide them with `visible`, from the toolbar's `ToolsButton` and its `tools` control.
|
|
650
|
+
|
|
651
|
+
It draws as `<MeasureTool>` draws: the lines show through the part, and each label is an unstyled
|
|
652
|
+
`<div class="toolpath-measure-label" data-measure-label="tool">` with its text in a
|
|
653
|
+
`data-measure-value` span and its note in a `data-measure-note` one. The marks take no pointer
|
|
654
|
+
events and are left out of framing.
|
|
655
|
+
|
|
656
|
+
Inside `<PartMesh>` or `<EnginePart>`, `usePartContext()` gives the part's `model` and `geometry`,
|
|
657
|
+
and `featureTriangles(model, geometry, tag)` a feature's triangles, for working out where a tool
|
|
658
|
+
stands.
|
|
659
|
+
|
|
532
660
|
### `<Grid>` and `<Axes>`
|
|
533
661
|
|
|
534
662
|
Reference geometry. The camera ignores both when it frames the part.
|
|
@@ -1108,6 +1236,7 @@ is a complete app built this way, with no API key needed.
|
|
|
1108
1236
|
| `useViewerToolbar()` | Inside `<ViewerToolbarProvider>` | Get the actions and state supplied to the provider. |
|
|
1109
1237
|
| `useSectionStore()` | Inside `<Viewer>` | Read, set, or subscribe to the viewer's own cut. |
|
|
1110
1238
|
| `useContentBox()` | Inside `<Viewer>` | Get the part's bounding box (a `THREE.Box3`, empty until loaded). |
|
|
1239
|
+
| `usePartContext()` | Inside `<PartMesh>` | Get the part's `model` and the `geometry` it is drawn from, for an overlay. |
|
|
1111
1240
|
| `useTapGuard()` | Inside `<Viewer>` | Check whether a pointer event was a click and not a drag. |
|
|
1112
1241
|
|
|
1113
1242
|
### Helpers
|
|
@@ -1121,6 +1250,7 @@ is a complete app built this way, with no API key needed.
|
|
|
1121
1250
|
| `focusForPick(pick, lastRegion, lastFocus)` | Steps through a face's matches on repeated clicks. |
|
|
1122
1251
|
| `rankOwners` / `bestOwner` | The ranking `onPick` uses, if you want to run it yourself. |
|
|
1123
1252
|
| `groupByDirection(model)` | Features grouped by machining direction. |
|
|
1253
|
+
| `featureTriangles(model, geometry, tag)` | A feature's triangles and outward normals, as plain arrays. |
|
|
1124
1254
|
| `directionLabel(v)` / `directionColor(i)` | A direction's label and colour. |
|
|
1125
1255
|
| `sectionFromPick({ point, normal })` | Turns a clicked surface into a section plane. |
|
|
1126
1256
|
| `measurementLabel(measurement, format?)` | Writes a measurement the way `<MeasureTool>` labels it. |
|
|
@@ -13,6 +13,15 @@ import {
|
|
|
13
13
|
} from "react";
|
|
14
14
|
import { Vector3 as Vector311 } from "three";
|
|
15
15
|
|
|
16
|
+
// src/part-context.tsx
|
|
17
|
+
import { createContext, useContext } from "react";
|
|
18
|
+
var PartContext = createContext(null);
|
|
19
|
+
var usePartContext = () => {
|
|
20
|
+
const part = useContext(PartContext);
|
|
21
|
+
if (!part) throw new Error("usePartContext must be used inside <PartMesh> or <EnginePart>");
|
|
22
|
+
return part;
|
|
23
|
+
};
|
|
24
|
+
|
|
16
25
|
// src/model/directions.ts
|
|
17
26
|
var EPSILON = 1e-6;
|
|
18
27
|
function sameDirection(a, b) {
|
|
@@ -781,8 +790,8 @@ function perpendicular(axis) {
|
|
|
781
790
|
// src/tap.tsx
|
|
782
791
|
import { useThree } from "@react-three/fiber";
|
|
783
792
|
import {
|
|
784
|
-
createContext,
|
|
785
|
-
useContext,
|
|
793
|
+
createContext as createContext2,
|
|
794
|
+
useContext as useContext2,
|
|
786
795
|
useEffect,
|
|
787
796
|
useMemo,
|
|
788
797
|
useRef
|
|
@@ -823,10 +832,10 @@ function trackDoubleTaps(within = DOUBLE_TAP_MS, slop = TAP_SLOP) {
|
|
|
823
832
|
|
|
824
833
|
// src/tap.tsx
|
|
825
834
|
import { jsx } from "react/jsx-runtime";
|
|
826
|
-
var ViewerTapContext =
|
|
835
|
+
var ViewerTapContext = createContext2(null);
|
|
827
836
|
var ViewerTapProvider = ({ value, children }) => /* @__PURE__ */ jsx(ViewerTapContext.Provider, { value, children });
|
|
828
837
|
function useTapGuard() {
|
|
829
|
-
const shared =
|
|
838
|
+
const shared = useContext2(ViewerTapContext);
|
|
830
839
|
const domElement = useThree((state) => state.gl.domElement);
|
|
831
840
|
const tracker = useRef(null);
|
|
832
841
|
useEffect(() => {
|
|
@@ -1319,10 +1328,10 @@ function focusForPick(pick, previousRegion, previousFocus) {
|
|
|
1319
1328
|
// src/viewer.tsx
|
|
1320
1329
|
import { Canvas, useFrame as useFrame3, useThree as useThree4 } from "@react-three/fiber";
|
|
1321
1330
|
import {
|
|
1322
|
-
createContext as
|
|
1331
|
+
createContext as createContext3,
|
|
1323
1332
|
forwardRef,
|
|
1324
1333
|
useCallback,
|
|
1325
|
-
useContext as
|
|
1334
|
+
useContext as useContext3,
|
|
1326
1335
|
useEffect as useEffect4,
|
|
1327
1336
|
useImperativeHandle,
|
|
1328
1337
|
useMemo as useMemo4,
|
|
@@ -2193,20 +2202,20 @@ function labelTexture(label, color) {
|
|
|
2193
2202
|
|
|
2194
2203
|
// src/viewer.tsx
|
|
2195
2204
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2196
|
-
var ViewerControlsContext =
|
|
2205
|
+
var ViewerControlsContext = createContext3(null);
|
|
2197
2206
|
var useViewerControls = () => {
|
|
2198
|
-
const controls =
|
|
2207
|
+
const controls = useContext3(ViewerControlsContext);
|
|
2199
2208
|
if (!controls) throw new Error("useViewerControls must be used inside <Viewer>");
|
|
2200
2209
|
return controls;
|
|
2201
2210
|
};
|
|
2202
|
-
var SectionStoreContext =
|
|
2211
|
+
var SectionStoreContext = createContext3(null);
|
|
2203
2212
|
var useSectionStore = () => {
|
|
2204
|
-
const store =
|
|
2213
|
+
const store = useContext3(SectionStoreContext);
|
|
2205
2214
|
if (!store) throw new Error("useSectionStore must be used inside <Viewer>");
|
|
2206
2215
|
return store;
|
|
2207
2216
|
};
|
|
2208
|
-
var ViewerRetargetContext =
|
|
2209
|
-
var useRetarget = () =>
|
|
2217
|
+
var ViewerRetargetContext = createContext3(null);
|
|
2218
|
+
var useRetarget = () => useContext3(ViewerRetargetContext);
|
|
2210
2219
|
var ViewerScene = ({
|
|
2211
2220
|
children,
|
|
2212
2221
|
setControls,
|
|
@@ -3029,9 +3038,11 @@ var PartMesh = ({
|
|
|
3029
3038
|
onPick,
|
|
3030
3039
|
theme,
|
|
3031
3040
|
showEdges = true,
|
|
3032
|
-
display = "solid"
|
|
3041
|
+
display = "solid",
|
|
3042
|
+
children
|
|
3033
3043
|
}) => {
|
|
3034
3044
|
const { camera, controls, invalidate } = useThree7();
|
|
3045
|
+
const context = useMemo6(() => ({ model, geometry }), [model, geometry]);
|
|
3035
3046
|
const viewerControls = useViewerControls();
|
|
3036
3047
|
const resolved = useStableTheme(theme);
|
|
3037
3048
|
const currentTheme = useRef6(resolved);
|
|
@@ -3243,7 +3254,8 @@ var PartMesh = ({
|
|
|
3243
3254
|
showHandle: !controlled || onSectionChange !== void 0,
|
|
3244
3255
|
onDrag: !controlled || onSectionChange ? dragSection : void 0
|
|
3245
3256
|
}
|
|
3246
|
-
) : null
|
|
3257
|
+
) : null,
|
|
3258
|
+
children ? /* @__PURE__ */ jsx5(PartContext.Provider, { value: context, children }) : null
|
|
3247
3259
|
] });
|
|
3248
3260
|
};
|
|
3249
3261
|
var ORIGIN = new Vector311();
|
|
@@ -3890,6 +3902,7 @@ function useGeometryResource(part) {
|
|
|
3890
3902
|
}
|
|
3891
3903
|
|
|
3892
3904
|
export {
|
|
3905
|
+
usePartContext,
|
|
3893
3906
|
sameDirection,
|
|
3894
3907
|
directionIndexOf,
|
|
3895
3908
|
groupByDirection,
|
package/dist/engine/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as PartModel, a as PartMeshRefs } from '../normalize
|
|
2
|
-
export { E as EnginePart, b as EnginePartProps, M as MIN_KERNEL_VERSION, c as assertSupportedKernelVersion, n as normalizePartReport, s as smoothRegionNormals } from '../normalize
|
|
1
|
+
import { P as PartModel, a as PartMeshRefs } from '../normalize--FiXUhO4.js';
|
|
2
|
+
export { E as EnginePart, b as EnginePartProps, M as MIN_KERNEL_VERSION, c as assertSupportedKernelVersion, n as normalizePartReport, s as smoothRegionNormals } from '../normalize--FiXUhO4.js';
|
|
3
3
|
import { BufferGeometry } from 'three';
|
|
4
4
|
import 'react';
|
|
5
5
|
|