@toolpath/viewer 2.2.1 → 2.3.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 +110 -43
- package/dist/{chunk-7S6SIYHL.js → chunk-N54FHMTG.js} +753 -178
- package/dist/engine/index.d.ts +2 -2
- package/dist/engine/index.js +1 -1
- package/dist/index.d.ts +7 -205
- package/dist/index.js +49 -28
- package/dist/{normalize--FiXUhO4.d.ts → normalize-C4Wj4IGK.d.ts} +333 -3
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { Vector3, OrthographicCamera, PerspectiveCamera, Box3, Object3D, BufferGeometry, Group, Mesh, LineSegments, Plane, Raycaster, Intersection, Camera } from 'three';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* The normalized part — the only thing the renderer consumes.
|
|
@@ -151,6 +151,207 @@ interface FocusOptions {
|
|
|
151
151
|
readonly opacity?: number;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
type Projection = 'orthographic' | 'perspective';
|
|
155
|
+
type ViewerCamera = OrthographicCamera | PerspectiveCamera;
|
|
156
|
+
interface ViewportSize {
|
|
157
|
+
readonly width: number;
|
|
158
|
+
readonly height: number;
|
|
159
|
+
}
|
|
160
|
+
/** Vertical field of view, in degrees, for the perspective camera. */
|
|
161
|
+
declare const PERSPECTIVE_FOV = 30;
|
|
162
|
+
/** Padding around the framed bounds, as a multiple of its radius. */
|
|
163
|
+
declare const DEFAULT_FIT_MARGIN = 1.2;
|
|
164
|
+
/** Marks scene furniture — grid, axes — that the camera should not frame. */
|
|
165
|
+
declare const EXCLUDE_FROM_FRAME = "viewerExcludeFromFrame";
|
|
166
|
+
/**
|
|
167
|
+
* What the camera frames: a bounding *sphere*, not a box.
|
|
168
|
+
*
|
|
169
|
+
* A sphere makes framing rotation-invariant — the part stays fully visible from
|
|
170
|
+
* every angle, and a resize never needs to know the current pose. Framing
|
|
171
|
+
* per-axis box dimensions instead means recomputing the camera distance on
|
|
172
|
+
* every resize, and still clipping on some orientations.
|
|
173
|
+
*/
|
|
174
|
+
interface SceneBounds {
|
|
175
|
+
readonly center: Vector3;
|
|
176
|
+
readonly radius: number;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Bounds for a scene with nothing in it. A viewer is mounted before it has a
|
|
180
|
+
* part, and a camera with a zero-size frustum renders nothing at all.
|
|
181
|
+
*/
|
|
182
|
+
declare function defaultBounds(): SceneBounds;
|
|
183
|
+
/**
|
|
184
|
+
* A container can be laid out at zero size, and a degenerate aspect ratio
|
|
185
|
+
* produces a `NaN` projection matrix that never recovers. Fall back to square.
|
|
186
|
+
*/
|
|
187
|
+
declare function aspectRatio(size: ViewportSize): number;
|
|
188
|
+
/**
|
|
189
|
+
* A world length that covers `pixels` on screen at `point`.
|
|
190
|
+
*
|
|
191
|
+
* Anything sized in world units is a thumbnail on a plate and a wall on an
|
|
192
|
+
* insert; the whole reason a control is measured this way is that it is a
|
|
193
|
+
* control rather than part of the model. The section handle and the orbit
|
|
194
|
+
* target marker both size themselves with it, which is why it lives here with
|
|
195
|
+
* the camera rather than beside either of them.
|
|
196
|
+
*
|
|
197
|
+
* The two projections answer differently on purpose. An orthographic frustum
|
|
198
|
+
* covers the same world height wherever the point is, so distance does not
|
|
199
|
+
* enter; a perspective one covers more the further away it looks, so it does.
|
|
200
|
+
*/
|
|
201
|
+
declare function screenLength(camera: ViewerCamera, point: Vector3, viewport: ViewportSize, pixels: number): number;
|
|
202
|
+
declare function boundsFromBox(box: Box3): SceneBounds;
|
|
203
|
+
/**
|
|
204
|
+
* The bounds of everything worth framing under `root`.
|
|
205
|
+
*
|
|
206
|
+
* Skips objects flagged with {@link EXCLUDE_FROM_FRAME} and their descendants:
|
|
207
|
+
* a 100 mm grid around a 6 mm part would otherwise frame the grid, and the part
|
|
208
|
+
* would be a speck.
|
|
209
|
+
*/
|
|
210
|
+
declare function contentBounds(root: Object3D, into: Box3): SceneBounds;
|
|
211
|
+
/**
|
|
212
|
+
* Whether `object`, or anything between it and `root`, carries
|
|
213
|
+
* {@link EXCLUDE_FROM_FRAME}. The flag is set on an overlay's outermost group
|
|
214
|
+
* and means the whole subtree, so the walk goes up rather than reading the
|
|
215
|
+
* object alone.
|
|
216
|
+
*/
|
|
217
|
+
declare function excludedFromFrame(object: Object3D, root: Object3D): boolean;
|
|
218
|
+
/**
|
|
219
|
+
* The distance at which a sphere of `radius` fits inside a perspective frustum.
|
|
220
|
+
* Uses the narrower of the two field-of-view angles, so a portrait viewport
|
|
221
|
+
* frames on width and a landscape one on height.
|
|
222
|
+
*/
|
|
223
|
+
declare function perspectiveFitDistance(fovDegrees: number, aspect: number, radius: number): number;
|
|
224
|
+
/**
|
|
225
|
+
* Half-height of an orthographic frustum that fits a sphere of `radius`. A
|
|
226
|
+
* portrait viewport grows the height so the width still clears the sphere.
|
|
227
|
+
*/
|
|
228
|
+
declare function orthographicHalfHeight(aspect: number, radius: number): number;
|
|
229
|
+
declare function fitDistance(projection: Projection, size: ViewportSize, bounds: SceneBounds, margin?: number): number;
|
|
230
|
+
declare function startPosition(projection: Projection, size: ViewportSize, bounds: SceneBounds, margin?: number): Vector3;
|
|
231
|
+
/**
|
|
232
|
+
* How far out the wheel may pull, as a fraction of the fitted framing: the part
|
|
233
|
+
* may shrink to a quarter of the view and no further. Past that it is a speck
|
|
234
|
+
* with no cue that Fit is the way back.
|
|
235
|
+
*/
|
|
236
|
+
declare const MIN_FRAME_RATIO = 0.25;
|
|
237
|
+
/**
|
|
238
|
+
* How far in the wheel may push, as a multiple of the fitted framing.
|
|
239
|
+
*
|
|
240
|
+
* Both ratios are the legacy viewer's `minZoom` 0.25 / `maxZoom` 10
|
|
241
|
+
* (`three-object.tsx:289-311`), which transfer almost exactly: legacy's
|
|
242
|
+
* orthographic frustum was `largestDimension * 2` tall and this one is the
|
|
243
|
+
* fitted bounding sphere, which for a cube agree within a few percent. So the
|
|
244
|
+
* numbers are the ones that shipped, and here they carry a meaning they did not
|
|
245
|
+
* have there — `zoom` 1 *is* the fitted framing, so 0.25 and 10 say exactly
|
|
246
|
+
* what a reader thinks they say.
|
|
247
|
+
*/
|
|
248
|
+
declare const MAX_FRAME_RATIO = 10;
|
|
249
|
+
/** How far the camera may travel, in the two units the two cameras travel in. */
|
|
250
|
+
interface CameraLimits {
|
|
251
|
+
readonly minZoom: number;
|
|
252
|
+
readonly maxZoom: number;
|
|
253
|
+
readonly minDistance: number;
|
|
254
|
+
readonly maxDistance: number;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* The clamps for a scene, so the wheel cannot leave the viewport empty.
|
|
258
|
+
*
|
|
259
|
+
* Without them it can, from either end, and both cameras can do it: an
|
|
260
|
+
* orthographic `camera.zoom` reaches 1e30 in sixty notches, and a perspective
|
|
261
|
+
* camera dives inside the part in eight, because `minDistance` defaults to
|
|
262
|
+
* `Number.EPSILON`. Fit recovers from both — but Fit is a double middle click
|
|
263
|
+
* and nothing on screen says so, which makes it a way out rather than an
|
|
264
|
+
* answer.
|
|
265
|
+
*
|
|
266
|
+
* One rule for both cameras: the wheel may take the part from a quarter of its
|
|
267
|
+
* fitted size to ten times it. Under an orthographic camera that scale *is* the
|
|
268
|
+
* frustum, so the ratios land on `zoom`; under a perspective camera apparent
|
|
269
|
+
* size is the inverse of distance, so they land on `distance` — which is why
|
|
270
|
+
* they swap sides between the two.
|
|
271
|
+
*
|
|
272
|
+
* Pure, and derived from `bounds`, so it re-derives wherever the scene is
|
|
273
|
+
* re-measured rather than being sampled once at mount.
|
|
274
|
+
*
|
|
275
|
+
* `framed` is what the view has been framed *on*, when that is not the whole
|
|
276
|
+
* scene — `frameBox` on a single feature. The band is then taken about that
|
|
277
|
+
* framing as well as about the scene's, because a band centred on the part is
|
|
278
|
+
* the wrong band for a view of a 3 mm hole in it: ten times the *part's* fitted
|
|
279
|
+
* size can be less than once the hole's, so the framing the caller asked for sat
|
|
280
|
+
* outside the clamps meant to keep it in view. Under an orthographic camera
|
|
281
|
+
* `zoom` is measured against a frustum still sized to the scene, so the framing
|
|
282
|
+
* enters as the zoom ratio it takes to reach; under a perspective one it enters
|
|
283
|
+
* as its own fitted distance.
|
|
284
|
+
*
|
|
285
|
+
* Widened to the union of the two rather than moved onto `framed`, and that is
|
|
286
|
+
* the whole of why this takes both. A band that simply followed the last framing
|
|
287
|
+
* would take the part away: framing a hole would put "far enough out to see what
|
|
288
|
+
* the hole is in" past `maxDistance`, so the wheel could no longer get back to
|
|
289
|
+
* the part it had just been looking at, and Fit — a gesture with nothing on
|
|
290
|
+
* screen to say so — would be the only way. Reaching further in must not cost
|
|
291
|
+
* the reach back out, so each end takes whichever bound is looser. With no
|
|
292
|
+
* `framed`, or one the size of the scene, both ends collapse to the scene's own
|
|
293
|
+
* and this is the function it was before.
|
|
294
|
+
*/
|
|
295
|
+
declare function cameraLimits(projection: Projection, size: ViewportSize, bounds: SceneBounds, margin?: number, framed?: SceneBounds): CameraLimits;
|
|
296
|
+
/**
|
|
297
|
+
* The box the orbit target is confined to — the fitted framing, several frames
|
|
298
|
+
* over. Written into `into` so the per-frame path allocates nothing.
|
|
299
|
+
*/
|
|
300
|
+
declare function targetBoundary(bounds: SceneBounds, into: Box3, margin?: number): Box3;
|
|
301
|
+
/**
|
|
302
|
+
* Points an existing camera's frustum at `bounds` for the current viewport.
|
|
303
|
+
* Pose is untouched — that belongs to the controls.
|
|
304
|
+
*/
|
|
305
|
+
declare function applyProjection(camera: ViewerCamera, size: ViewportSize, bounds: SceneBounds, margin?: number): void;
|
|
306
|
+
/**
|
|
307
|
+
* The world-up convention. The part data is Z-up (millimetres, no conversion) —
|
|
308
|
+
* not the glTF-conventional Y-up — so the camera has to say so explicitly.
|
|
309
|
+
*/
|
|
310
|
+
declare const CAD_CAMERA_UP: Vector3;
|
|
311
|
+
/**
|
|
312
|
+
* `up` re-squared against a view direction: the part of it perpendicular to
|
|
313
|
+
* `view`, written into `into`.
|
|
314
|
+
*
|
|
315
|
+
* This is what keeps the horizon level while a free orbit carries the camera
|
|
316
|
+
* over a pole — the up vector follows the view instead of flipping. The
|
|
317
|
+
* controls run it on every update, which is what makes the next sentence the
|
|
318
|
+
* important one.
|
|
319
|
+
*
|
|
320
|
+
* **It is path-dependent.** It is a projection, so it discards the component it
|
|
321
|
+
* removes and cannot put it back: running it at one view and then another does
|
|
322
|
+
* not give what running it once at the second view would. So a camera carries
|
|
323
|
+
* the roll of every pose it has passed through, and any pose that is meant to
|
|
324
|
+
* be canonical — the opening frame, a reset, a named view — has to say what
|
|
325
|
+
* `up` is rather than inherit it. `viewer.tsx` does, at `resetContent`. The
|
|
326
|
+
* test beside this pins both halves.
|
|
327
|
+
*
|
|
328
|
+
* `into` may be `view` or `up` — three.js `crossVectors` reads all six
|
|
329
|
+
* components before it writes any, and the intermediate is this module's own
|
|
330
|
+
* scratch, so writing the result over an input is safe. Said here because this
|
|
331
|
+
* is exported and an out-parameter invites the question; the test beside this
|
|
332
|
+
* pins it, so a three.js change cannot quietly turn the answer around.
|
|
333
|
+
*
|
|
334
|
+
* `view` and `up` being parallel is the one degenerate case: their cross is
|
|
335
|
+
* zero, `normalize` leaves it zero, and the result is a zero vector rather than
|
|
336
|
+
* an error. A caller with a free-orbiting camera reaches that at the pole,
|
|
337
|
+
* which is what `freeOrbit` and a squared `up` at every canonical pose exist to
|
|
338
|
+
* keep it away from.
|
|
339
|
+
*/
|
|
340
|
+
declare function adaptedUp(view: Vector3, up: Vector3, into: Vector3): Vector3;
|
|
341
|
+
/** Named viewing directions, as unit vectors from the part toward the camera. */
|
|
342
|
+
declare const cadViewDirections: {
|
|
343
|
+
readonly front: Vector3;
|
|
344
|
+
readonly back: Vector3;
|
|
345
|
+
readonly left: Vector3;
|
|
346
|
+
readonly right: Vector3;
|
|
347
|
+
readonly top: Vector3;
|
|
348
|
+
readonly bottom: Vector3;
|
|
349
|
+
readonly isometric: Vector3;
|
|
350
|
+
};
|
|
351
|
+
type ViewerView = keyof typeof cadViewDirections;
|
|
352
|
+
/** The current orbit direction, so Fit can retain the direction being looked from. */
|
|
353
|
+
declare function currentViewDirection(camera: ViewerCamera, target: Vector3, into: Vector3): Vector3;
|
|
354
|
+
|
|
154
355
|
/**
|
|
155
356
|
* Viewer colors.
|
|
156
357
|
*
|
|
@@ -182,6 +383,8 @@ interface ViewerTheme {
|
|
|
182
383
|
/** `EdgesGeometry` line color and opacity. */
|
|
183
384
|
readonly edge: number;
|
|
184
385
|
readonly edgeOpacity: number;
|
|
386
|
+
/** The sharp corners `<PartMesh sharpCorners>` draws. */
|
|
387
|
+
readonly sharpCorner: number;
|
|
185
388
|
/**
|
|
186
389
|
* The capped face of a section cut: its fill, and the hatch lines drawn over
|
|
187
390
|
* it. The cap's edge takes {@link ViewerTheme.sectionHandleOutline}.
|
|
@@ -249,6 +452,100 @@ declare function themesEqual(a: ViewerTheme, b: ViewerTheme): boolean;
|
|
|
249
452
|
/** The color for a candidate direction, wrapping at {@link DIRECTION_COLORS}. */
|
|
250
453
|
declare function directionColor(index: number): number;
|
|
251
454
|
|
|
455
|
+
/**
|
|
456
|
+
* Every place two surfaces of the part meet, with how sharply and which way
|
|
457
|
+
* they fold there, and the two regions either side.
|
|
458
|
+
*
|
|
459
|
+
* This finds edges; it does not judge them. Which corners are a problem is the
|
|
460
|
+
* DFM rules' call, from the Engine's measurements (see
|
|
461
|
+
* {@link SharpCornerOptions.features}) — geometry alone calls every hole's rim
|
|
462
|
+
* and every stud's base sharp, and neither is anything an end mill minds. What
|
|
463
|
+
* the mesh contributes is *where*: the exact edges to draw for a feature the
|
|
464
|
+
* rules have already flagged.
|
|
465
|
+
*
|
|
466
|
+
* The walk is the one `regionEdgesGeometry` makes — an edge between two visual
|
|
467
|
+
* surfaces is a real edge of the part, an edge inside one is tessellation — and
|
|
468
|
+
* then each such edge is measured from the two triangles either side of it:
|
|
469
|
+
*
|
|
470
|
+
* - **The angle** between their normals. A fillet or a blend meets its
|
|
471
|
+
* neighbours tangentially, so it reads near 0°; a square shoulder reads 90°.
|
|
472
|
+
* On real Engine parts the two populations do not overlap — creases sit at
|
|
473
|
+
* 60–100°, tangent seams under 10°.
|
|
474
|
+
* - **Which way it folds.** Concave where each triangle's far corner stands in
|
|
475
|
+
* front of the other's plane: an inside corner.
|
|
476
|
+
*
|
|
477
|
+
* Endpoints are matched by **quantised position** — `keyFor`, the key
|
|
478
|
+
* `regionAdjacency` uses, so the two agree on a shared vertex — not by exact
|
|
479
|
+
* float: the two triangles either side of an edge belong to two
|
|
480
|
+
* surfaces tessellated separately, and the pairing is the whole measurement.
|
|
481
|
+
* The Engine's meshes are watertight — every edge on the parts measured is met
|
|
482
|
+
* by exactly two triangles — so an edge met once is a hole in a mesh from
|
|
483
|
+
* somewhere else and is skipped, and one met a third time keeps the first pair.
|
|
484
|
+
*
|
|
485
|
+
* The mesh must be non-indexed, which `parsePartGeometry` guarantees.
|
|
486
|
+
*/
|
|
487
|
+
interface SurfaceCreases {
|
|
488
|
+
/** How many segments. */
|
|
489
|
+
readonly count: number;
|
|
490
|
+
/** Each segment's two endpoints, `x y z x y z`, in the geometry's own space. */
|
|
491
|
+
readonly positions: Float32Array;
|
|
492
|
+
/** Degrees between the two faces' normals: 0 is smooth, 90 is square. */
|
|
493
|
+
readonly angles: Float32Array;
|
|
494
|
+
/** 1 where the surfaces fold inward — an inside corner — and 0 where they fold outward. */
|
|
495
|
+
readonly concave: Uint8Array;
|
|
496
|
+
/** The region `idx` either side of each segment, two to a segment; `-1` for a triangle in none. */
|
|
497
|
+
readonly regions: Int32Array;
|
|
498
|
+
/**
|
|
499
|
+
* The far corner of the triangle either side of each segment, `x y z x y z`:
|
|
500
|
+
* which way each face runs on from the corner, and how far.
|
|
501
|
+
*/
|
|
502
|
+
readonly fars: Float32Array;
|
|
503
|
+
}
|
|
504
|
+
interface SharpCornerOptions {
|
|
505
|
+
/**
|
|
506
|
+
* The features the DFM rules flag with a sharp corner — those whose
|
|
507
|
+
* `featureSheet(datasheet).sharpCorners` is set, from `@toolpath/dfm/model`.
|
|
508
|
+
* Each one's inside corners that run along its machining direction are
|
|
509
|
+
* drawn: the vertical corners between its walls that no end mill makes.
|
|
510
|
+
* Nothing else is. Tags are matched without regard to case.
|
|
511
|
+
*/
|
|
512
|
+
readonly features: readonly FeatureTag[];
|
|
513
|
+
}
|
|
514
|
+
/** Finds and measures every crease between two visual surfaces. See {@link SurfaceCreases}. */
|
|
515
|
+
declare function surfaceCreases(geometry: BufferGeometry, model: Pick<PartModel, 'regions'>): SurfaceCreases;
|
|
516
|
+
/**
|
|
517
|
+
* One sharp corner the DFM rules flag, as drawn: a run of crease segments end
|
|
518
|
+
* to end along its feature's machining direction — usually one, more where the
|
|
519
|
+
* mesh splits the corner.
|
|
520
|
+
*/
|
|
521
|
+
interface SharpCorner {
|
|
522
|
+
/** Its place among the part's corners, stable while the flagged features are. */
|
|
523
|
+
readonly index: number;
|
|
524
|
+
/** The flagged feature it belongs to, as the part model spells the tag. */
|
|
525
|
+
readonly feature: FeatureTag;
|
|
526
|
+
/** Its two ends, in the part's own space. */
|
|
527
|
+
readonly start: Vec3;
|
|
528
|
+
readonly end: Vec3;
|
|
529
|
+
/** How far it runs, mm: as deep as a tool would have to reach to make it. */
|
|
530
|
+
readonly length: number;
|
|
531
|
+
/** The angle between the two faces that meet in it, degrees: 90 for a square corner. */
|
|
532
|
+
readonly angle: number;
|
|
533
|
+
/** The regions either side of it. */
|
|
534
|
+
readonly regions: readonly number[];
|
|
535
|
+
/** Its segments, as indices into the {@link SurfaceCreases} it was found in. */
|
|
536
|
+
readonly segments: readonly number[];
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* The flagged features' corners: each inside crease with a flagged feature's
|
|
540
|
+
* face on either side of it, running along that feature's machining direction,
|
|
541
|
+
* joined end to end into whole corners. A floor meeting a wall square is a
|
|
542
|
+
* flat end mill's ordinary work, and runs across the direction rather than
|
|
543
|
+
* along it.
|
|
544
|
+
*/
|
|
545
|
+
declare function findSharpCorners(creases: SurfaceCreases, model: Pick<PartModel, 'features' | 'regionIndex'>, options: SharpCornerOptions): SharpCorner[];
|
|
546
|
+
/** The flagged features' corners, as `x y z x y z` endpoint pairs. See {@link findSharpCorners}. */
|
|
547
|
+
declare function sharpCornerPositions(creases: SurfaceCreases, model: Pick<PartModel, 'features' | 'regionIndex'>, options: SharpCornerOptions): Float32Array;
|
|
548
|
+
|
|
252
549
|
/** The vertex attribute carrying each vertex's column in the state texture. */
|
|
253
550
|
declare const REGION_ATTRIBUTE = "aRegion";
|
|
254
551
|
type PartDisplay = 'solid' | 'wireframe';
|
|
@@ -295,6 +592,24 @@ interface PartObject {
|
|
|
295
592
|
setTheme(theme: ViewerTheme): void;
|
|
296
593
|
/** Semantic edges only in wireframe; painted faces remain visible for interaction. */
|
|
297
594
|
setDisplay(display: PartDisplay, showEdges?: boolean): void;
|
|
595
|
+
/**
|
|
596
|
+
* Draws the sharp corners of the features the DFM rules flag, bold and
|
|
597
|
+
* through the part — see `render/sharp-corners.ts`. `null` hides them. Setting what is already drawn
|
|
598
|
+
* costs a string comparison, so a caller may pass a fresh object each render.
|
|
599
|
+
*/
|
|
600
|
+
setSharpCorners(options: SharpCornerOptions | null): void;
|
|
601
|
+
/** The corners drawn now, in the order their `index` counts; none while they are off. */
|
|
602
|
+
sharpCorners(): readonly SharpCorner[];
|
|
603
|
+
/**
|
|
604
|
+
* The drawn corner under a pointer on the part — `point` in world space,
|
|
605
|
+
* `region` the face it hit — or `null`. See `sharpCornerAt`.
|
|
606
|
+
*/
|
|
607
|
+
sharpCornerAt(hit: {
|
|
608
|
+
readonly point: Vector3;
|
|
609
|
+
readonly region: number;
|
|
610
|
+
}, camera: ViewerCamera, viewport: ViewportSize): SharpCorner | null;
|
|
611
|
+
/** Draws one corner up as the one under the pointer; `null` for none. */
|
|
612
|
+
setHoveredSharpCorner(index: number | null): void;
|
|
298
613
|
dispose(): void;
|
|
299
614
|
}
|
|
300
615
|
interface RegionPaint {
|
|
@@ -719,6 +1034,13 @@ interface PartPick {
|
|
|
719
1034
|
* part, and is nobody else's to answer.
|
|
720
1035
|
*/
|
|
721
1036
|
readonly doubled: boolean;
|
|
1037
|
+
/**
|
|
1038
|
+
* The sharp corner under the pointer, when `<PartMesh sharpCorners>` is
|
|
1039
|
+
* drawing them and the pointer is on one: within a few pixels of it, on one
|
|
1040
|
+
* of the two faces that meet there. The face is still `region`; this says the
|
|
1041
|
+
* pointer is on the corner drawn over it.
|
|
1042
|
+
*/
|
|
1043
|
+
readonly sharpCorner?: SharpCorner;
|
|
722
1044
|
}
|
|
723
1045
|
/** A unit vector from the part toward the camera, for the owner ranking. */
|
|
724
1046
|
declare function viewDirection(camera: Camera, target: Vector3): Vec3;
|
|
@@ -850,6 +1172,14 @@ interface PartMeshProps {
|
|
|
850
1172
|
onPick?: (pick: PartPick) => void;
|
|
851
1173
|
theme?: Partial<ViewerTheme>;
|
|
852
1174
|
showEdges?: boolean;
|
|
1175
|
+
/**
|
|
1176
|
+
* Draws the sharp corners of the features the DFM rules flag — `features`,
|
|
1177
|
+
* those whose `featureSheet(datasheet).sharpCorners` is set — bold, and
|
|
1178
|
+
* faintly through the part where it hides them. The rules decide which
|
|
1179
|
+
* corners; the mesh only says where they are. Off when omitted or `null`.
|
|
1180
|
+
* Coloured by the theme's `sharpCorner`.
|
|
1181
|
+
*/
|
|
1182
|
+
sharpCorners?: SharpCornerOptions | null;
|
|
853
1183
|
/** Wireframe shows region boundaries and any hovered/painted faces, with no triangle diagonals. */
|
|
854
1184
|
display?: PartDisplay;
|
|
855
1185
|
/**
|
|
@@ -868,7 +1198,7 @@ interface PartMeshProps {
|
|
|
868
1198
|
* React render at all: the hovered face lives in a ref, and routing it through
|
|
869
1199
|
* state is what this rewrite exists to stop doing.
|
|
870
1200
|
*/
|
|
871
|
-
declare const PartMesh: ({ model, geometry, selection, focus, candidates, highlights, regionHighlights, pickedRegions, hoveredFeatureIds, hover, activeDirection, section, onSectionChange, onAdjacency, focusFeature, onHover, onPick, theme, showEdges, display, children, }: PartMeshProps) => react.JSX.Element;
|
|
1201
|
+
declare const PartMesh: ({ model, geometry, selection, focus, candidates, highlights, regionHighlights, pickedRegions, hoveredFeatureIds, hover, activeDirection, section, onSectionChange, onAdjacency, focusFeature, onHover, onPick, theme, showEdges, sharpCorners, display, children, }: PartMeshProps) => react.JSX.Element;
|
|
872
1202
|
|
|
873
1203
|
interface EnginePartProps extends Omit<PartMeshProps, 'model' | 'geometry'> {
|
|
874
1204
|
/**
|
|
@@ -943,4 +1273,4 @@ declare function normalizePartReport(report: unknown): PartModel;
|
|
|
943
1273
|
*/
|
|
944
1274
|
declare function assertSupportedKernelVersion(kernelVersion: string): void;
|
|
945
1275
|
|
|
946
|
-
export {
|
|
1276
|
+
export { PREVIEW_SCALE as $, AXES_PLANE_OFFSET as A, type BuildPickInput as B, type CameraLimits as C, DEFAULT_FIT_MARGIN as D, EnginePart as E, type FeatureTag as F, type FeatureHighlight as G, type FocusOptions as H, HANDLE_PIXELS as I, HIGHLIGHT_COLORS as J, HIGHLIGHT_WEIGHT as K, HOVER_WEIGHT as L, MIN_KERNEL_VERSION as M, type HighlightLayers as N, type KnownFeatureType as O, type PartModel as P, type KnownShapeKind as Q, type RegionHighlight as R, type SectionOptions as S, type TriangleRange as T, MAX_FRAME_RATIO as U, type Vec3 as V, MIN_FRAME_RATIO as W, NO_MODIFIERS as X, OUTLINE_SCALE as Y, PERSPECTIVE_FOV as Z, PICKED_SURFACE_LABEL as _, type PartMeshRefs as a, viewDirection as a$, type PartDisplay as a0, PartMesh as a1, type PartMeshProps as a2, type PartObject as a3, type PickModifiers as a4, type PointerLocation as a5, REGION_ATTRIBUTE as a6, type RegionPaint as a7, SECTION_GIZMO_FRAME_SCALE as a8, SECTION_RENDER_ORDER as a9, excludedFromFrame as aA, findSharpCorners as aB, fitDistance as aC, focusForPick as aD, hitUnderRay as aE, orthographicHalfHeight as aF, perspectiveFitDistance as aG, pickedStartDepth as aH, resolveTheme as aI, screenLength as aJ, sectionAnchor as aK, sectionBounds as aL, sectionConstant as aM, sectionDepth as aN, sectionDepthConstant as aO, sectionDepthRange as aP, sectionFromPick as aQ, sectionMeasurement as aR, sectionOffset as aS, sectionOptionsFromState as aT, sectionPlane as aU, sharpCornerPositions as aV, startPosition as aW, surfaceCreases as aX, surfaceUnderRay as aY, targetBoundary as aZ, themesEqual as a_, type SceneBounds as aa, type SectionAnchor as ab, type SectionBounds as ac, type SectionPlacement as ad, type ShapeKind as ae, type SharpCorner as af, type SharpCornerOptions as ag, type SurfaceCreases as ah, type SurfaceHit as ai, adaptedUp as aj, applyHighlightLayers as ak, applyProjection as al, aspectRatio as am, axesPlanes as an, boundsFromBox as ao, buildPick as ap, buildRegionAttribute as aq, buildRegionTexels as ar, cadViewDirections as as, cameraLimits as at, contentBounds as au, createPart as av, currentViewDirection as aw, defaultBounds as ax, directionColor as ay, dragPlane as az, type EnginePartProps as b, assertSupportedKernelVersion as c, type PartPick as d, type ViewerTheme as e, type SectionState as f, type ViewerCamera as g, type ViewportSize as h, type PartModelRegion as i, type ViewerView as j, type Projection as k, type RegionIndex as l, type PartModelFeature as m, normalizePartReport as n, type FeatureType as o, AXES_PLANE_SCALE as p, type AxesPlane as q, CAD_CAMERA_UP as r, smoothRegionNormals as s, CANDIDATE_WEIGHT as t, CAP_HATCH as u, DEFAULT_SECTION_NORMAL as v, DEFAULT_THEME as w, DIRECTION_COLORS as x, DISABLED_SECTION as y, EXCLUDE_FROM_FRAME as z };
|