@toolpath/viewer 0.2.0 → 0.3.1
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 +1 -1
- package/dist/{chunk-7NQBV7EQ.js → chunk-RICG6UVH.js} +13 -132
- package/dist/engine/index.d.ts +2 -2
- package/dist/engine/index.js +1 -1
- package/dist/index.d.ts +17 -49
- package/dist/index.js +1 -3
- package/dist/{normalize-B0HBvzGu.d.ts → normalize-Bzzwwxt4.d.ts} +19 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ import { EnginePart } from '@toolpath/viewer/engine'
|
|
|
22
22
|
</Suspense>
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
`EnginePart` takes a `
|
|
25
|
+
`EnginePart` takes a `PartResponse` exactly as `@toolpath/api` returns it and validates it:
|
|
26
26
|
a malformed report throws `PartReportFormatError` carrying every problem it found, and one from a
|
|
27
27
|
kernel older than `0.3.0` — before `regions[]` and `featureTag` existed — throws
|
|
28
28
|
`UnsupportedKernelVersionError`. It fetches `meshGlbUrl`, falls back to `meshStlUrl`, and refuses a
|
|
@@ -47,107 +47,6 @@ function trim(value) {
|
|
|
47
47
|
return Number.parseFloat(value.toFixed(3)).toString();
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
// src/model/surfaces.ts
|
|
51
|
-
var CONTINUES_WITHIN = Math.cos(1 * Math.PI / 180);
|
|
52
|
-
var MERGEABLE = "Plane";
|
|
53
|
-
var worked = /* @__PURE__ */ new WeakMap();
|
|
54
|
-
function visualSurfaces(geometry, regions) {
|
|
55
|
-
const already = worked.get(geometry);
|
|
56
|
-
if (already && already.regions === regions) return already.of;
|
|
57
|
-
const found = computeSurfaces(geometry, regions);
|
|
58
|
-
worked.set(geometry, { regions, of: found });
|
|
59
|
-
return found;
|
|
60
|
-
}
|
|
61
|
-
function computeSurfaces(geometry, regions) {
|
|
62
|
-
const position = geometry.getAttribute("position");
|
|
63
|
-
const surfaces = /* @__PURE__ */ new Map();
|
|
64
|
-
for (const region of regions) surfaces.set(region.idx, region.idx);
|
|
65
|
-
if (!position || geometry.index) return surfaces;
|
|
66
|
-
const triangleCount = Math.floor(position.count / 3);
|
|
67
|
-
const regionOf = new Int32Array(triangleCount).fill(-1);
|
|
68
|
-
const kindOf = /* @__PURE__ */ new Map();
|
|
69
|
-
for (const region of regions) {
|
|
70
|
-
kindOf.set(region.idx, region.shapeKind);
|
|
71
|
-
const end = Math.min(region.triangles.end, triangleCount);
|
|
72
|
-
for (let triangle = region.triangles.start; triangle < end; triangle += 1) {
|
|
73
|
-
regionOf[triangle] = region.idx;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
const normals = facetNormals(geometry, triangleCount);
|
|
77
|
-
const parent = new Map(surfaces);
|
|
78
|
-
const find = (idx) => {
|
|
79
|
-
let root = idx;
|
|
80
|
-
while (parent.get(root) !== root) root = parent.get(root) ?? root;
|
|
81
|
-
let walk = idx;
|
|
82
|
-
while (parent.get(walk) !== root) {
|
|
83
|
-
const next = parent.get(walk) ?? root;
|
|
84
|
-
parent.set(walk, root);
|
|
85
|
-
walk = next;
|
|
86
|
-
}
|
|
87
|
-
return root;
|
|
88
|
-
};
|
|
89
|
-
const union = (a, b) => {
|
|
90
|
-
const [rootA, rootB] = [find(a), find(b)];
|
|
91
|
-
if (rootA !== rootB) parent.set(rootB, rootA);
|
|
92
|
-
};
|
|
93
|
-
const seen = /* @__PURE__ */ new Map();
|
|
94
|
-
for (let triangle = 0; triangle < triangleCount; triangle += 1) {
|
|
95
|
-
for (let corner = 0; corner < 3; corner += 1) {
|
|
96
|
-
const a = triangle * 3 + corner;
|
|
97
|
-
const b = triangle * 3 + (corner + 1) % 3;
|
|
98
|
-
const id = edgeKey(position, a, b);
|
|
99
|
-
const met = seen.get(id);
|
|
100
|
-
if (met === void 0) {
|
|
101
|
-
seen.set(id, triangle);
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
const here = regionOf[triangle] ?? -1;
|
|
105
|
-
const there = regionOf[met] ?? -1;
|
|
106
|
-
if (here === -1 || there === -1 || here === there) continue;
|
|
107
|
-
if (kindOf.get(here) !== kindOf.get(there)) continue;
|
|
108
|
-
const facing = normals[triangle * 3] * normals[met * 3] + normals[triangle * 3 + 1] * normals[met * 3 + 1] + normals[triangle * 3 + 2] * normals[met * 3 + 2];
|
|
109
|
-
if (kindOf.get(here) !== MERGEABLE) continue;
|
|
110
|
-
if (facing >= CONTINUES_WITHIN) union(here, there);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
for (const region of regions) surfaces.set(region.idx, find(region.idx));
|
|
114
|
-
return surfaces;
|
|
115
|
-
}
|
|
116
|
-
function facetNormals(geometry, triangleCount) {
|
|
117
|
-
const position = geometry.getAttribute("position");
|
|
118
|
-
const normals = new Float32Array(triangleCount * 3);
|
|
119
|
-
for (let triangle = 0; triangle < triangleCount; triangle += 1) {
|
|
120
|
-
const at = triangle * 3;
|
|
121
|
-
const ax = position.getX(at);
|
|
122
|
-
const ay = position.getY(at);
|
|
123
|
-
const az = position.getZ(at);
|
|
124
|
-
const bx = position.getX(at + 1) - ax;
|
|
125
|
-
const by = position.getY(at + 1) - ay;
|
|
126
|
-
const bz = position.getZ(at + 1) - az;
|
|
127
|
-
const cx = position.getX(at + 2) - ax;
|
|
128
|
-
const cy = position.getY(at + 2) - ay;
|
|
129
|
-
const cz = position.getZ(at + 2) - az;
|
|
130
|
-
const nx = by * cz - bz * cy;
|
|
131
|
-
const ny = bz * cx - bx * cz;
|
|
132
|
-
const nz = bx * cy - by * cx;
|
|
133
|
-
const length = Math.hypot(nx, ny, nz) || 1;
|
|
134
|
-
normals[at] = nx / length;
|
|
135
|
-
normals[at + 1] = ny / length;
|
|
136
|
-
normals[at + 2] = nz / length;
|
|
137
|
-
}
|
|
138
|
-
return normals;
|
|
139
|
-
}
|
|
140
|
-
function edgeKey(position, a, b) {
|
|
141
|
-
const ax = position.getX(a);
|
|
142
|
-
const ay = position.getY(a);
|
|
143
|
-
const az = position.getZ(a);
|
|
144
|
-
const bx = position.getX(b);
|
|
145
|
-
const by = position.getY(b);
|
|
146
|
-
const bz = position.getZ(b);
|
|
147
|
-
const first = ax < bx || ax === bx && (ay < by || ay === by && az <= bz);
|
|
148
|
-
return first ? `${ax},${ay},${az}|${bx},${by},${bz}` : `${bx},${by},${bz}|${ax},${ay},${az}`;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
50
|
// src/render/theme.ts
|
|
152
51
|
var HIGHLIGHT_COLORS = {
|
|
153
52
|
default: 16753434,
|
|
@@ -262,31 +161,6 @@ function applyHighlightLayers(part, layers, theme) {
|
|
|
262
161
|
if (layers.hoverRegion != null && !selectedRegions(part, layers).has(layers.hoverRegion)) {
|
|
263
162
|
part.paintRegion(layers.hoverRegion, theme.hover, HOVER_WEIGHT);
|
|
264
163
|
}
|
|
265
|
-
spreadAcrossSurfaces(part);
|
|
266
|
-
}
|
|
267
|
-
function spreadAcrossSurfaces(part) {
|
|
268
|
-
const surfaces = visualSurfaces(part.mesh.geometry, part.model.regions);
|
|
269
|
-
const claims = /* @__PURE__ */ new Map();
|
|
270
|
-
for (const region of part.model.regions) {
|
|
271
|
-
const paint = part.regionPaint(region.idx);
|
|
272
|
-
if (!paint || paint.weight === 0) continue;
|
|
273
|
-
const surface = surfaces.get(region.idx) ?? region.idx;
|
|
274
|
-
const claim = claims.get(surface);
|
|
275
|
-
if (!claim) {
|
|
276
|
-
claims.set(surface, { color: paint.color, weight: paint.weight });
|
|
277
|
-
continue;
|
|
278
|
-
}
|
|
279
|
-
if (claim === "contested") continue;
|
|
280
|
-
if (claim.color !== paint.color || claim.weight !== paint.weight) {
|
|
281
|
-
claims.set(surface, "contested");
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
for (const region of part.model.regions) {
|
|
285
|
-
const paint = part.regionPaint(region.idx);
|
|
286
|
-
if (paint && paint.weight > 0) continue;
|
|
287
|
-
const claim = claims.get(surfaces.get(region.idx) ?? region.idx);
|
|
288
|
-
if (claim && claim !== "contested") part.paintRegion(region.idx, claim.color, claim.weight);
|
|
289
|
-
}
|
|
290
164
|
}
|
|
291
165
|
|
|
292
166
|
// src/render/section.ts
|
|
@@ -432,13 +306,20 @@ import {
|
|
|
432
306
|
|
|
433
307
|
// src/render/edges.ts
|
|
434
308
|
import { BufferGeometry as Buffer, Float32BufferAttribute } from "three";
|
|
309
|
+
|
|
310
|
+
// src/model/surfaces.ts
|
|
311
|
+
function visualSurfaces(regions) {
|
|
312
|
+
return new Map(regions.map((region) => [region.idx, region.splitOrigin]));
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// src/render/edges.ts
|
|
435
316
|
function regionEdgesGeometry(geometry, model) {
|
|
436
317
|
const position = geometry.getAttribute("position");
|
|
437
318
|
const edges = new Buffer();
|
|
438
319
|
edges.setAttribute("position", new Float32BufferAttribute([], 3));
|
|
439
320
|
if (!position || geometry.index) return edges;
|
|
440
321
|
const triangleCount = Math.floor(position.count / 3);
|
|
441
|
-
const surfaces = visualSurfaces(
|
|
322
|
+
const surfaces = visualSurfaces(model.regions);
|
|
442
323
|
const regionOf = new Int32Array(triangleCount).fill(-1);
|
|
443
324
|
for (const region of model.regions) {
|
|
444
325
|
const end = Math.min(region.triangles.end, triangleCount);
|
|
@@ -1942,7 +1823,7 @@ function smoothRegionNormals(geometry, regions) {
|
|
|
1942
1823
|
if (!position || geometry.index) return;
|
|
1943
1824
|
const vertexCount = position.count;
|
|
1944
1825
|
const triangleCount = Math.floor(vertexCount / 3);
|
|
1945
|
-
const surfaces = visualSurfaces(
|
|
1826
|
+
const surfaces = visualSurfaces(regions);
|
|
1946
1827
|
const regionOf = new Int32Array(triangleCount).fill(-1);
|
|
1947
1828
|
for (const region of regions) {
|
|
1948
1829
|
const end = Math.min(region.triangles.end, triangleCount);
|
|
@@ -2304,15 +2185,16 @@ function readRegions(value, issues) {
|
|
|
2304
2185
|
continue;
|
|
2305
2186
|
}
|
|
2306
2187
|
const idx = raw["idx"];
|
|
2188
|
+
const splitOrigin = raw["splitOrigin"];
|
|
2307
2189
|
const start = raw["triangleStart"];
|
|
2308
2190
|
const end = raw["triangleEnd"];
|
|
2309
2191
|
const area = raw["area"];
|
|
2310
2192
|
const shapeKind = raw["shapeKind"];
|
|
2311
|
-
if (!isNonNegativeInteger(idx) || !isNonNegativeInteger(start) || !isNonNegativeInteger(end) || !isFiniteNumber(area) || !isString(shapeKind)) {
|
|
2193
|
+
if (!isNonNegativeInteger(idx) || !isNonNegativeInteger(splitOrigin) || !isNonNegativeInteger(start) || !isNonNegativeInteger(end) || !isFiniteNumber(area) || !isString(shapeKind)) {
|
|
2312
2194
|
issues.push(`regions[${i}] does not match the Region schema`);
|
|
2313
2195
|
continue;
|
|
2314
2196
|
}
|
|
2315
|
-
regions.push({ idx, shapeKind, area, triangles: { start, end } });
|
|
2197
|
+
regions.push({ idx, splitOrigin, shapeKind, area, triangles: { start, end } });
|
|
2316
2198
|
}
|
|
2317
2199
|
return regions;
|
|
2318
2200
|
}
|
|
@@ -2446,8 +2328,6 @@ export {
|
|
|
2446
2328
|
directionIndexOf,
|
|
2447
2329
|
groupByDirection,
|
|
2448
2330
|
directionLabel,
|
|
2449
|
-
CONTINUES_WITHIN,
|
|
2450
|
-
visualSurfaces,
|
|
2451
2331
|
HIGHLIGHT_COLORS,
|
|
2452
2332
|
DIRECTION_COLORS,
|
|
2453
2333
|
DEFAULT_THEME,
|
|
@@ -2476,6 +2356,7 @@ export {
|
|
|
2476
2356
|
movedFar,
|
|
2477
2357
|
trackTaps,
|
|
2478
2358
|
useTapGuard,
|
|
2359
|
+
visualSurfaces,
|
|
2479
2360
|
regionEdgesGeometry,
|
|
2480
2361
|
REGION_ATTRIBUTE,
|
|
2481
2362
|
buildRegionTexels,
|
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-Bzzwwxt4.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-Bzzwwxt4.js';
|
|
3
3
|
import { BufferGeometry } from 'three';
|
|
4
4
|
import 'react';
|
|
5
5
|
|
package/dist/engine/index.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { V as Vec3, d as ViewerTheme, P as PartModel, e as PartModelRegion, f as ViewerCamera, g as ViewerView, h as Projection, T as TriangleRange, F as FeatureTag, R as RegionIndex, i as PartModelFeature, j as FeatureType } from './normalize-
|
|
2
|
-
export { B as BuildPickInput, C as CAD_CAMERA_UP, k as CANDIDATE_WEIGHT, D as DEFAULT_FIT_MARGIN, l as DEFAULT_THEME, m as DIRECTION_COLORS, o as EXCLUDE_FROM_FRAME, E as EnginePart, p as FeatureHighlight, H as HANDLE_PIXELS, q as HIGHLIGHT_COLORS, r as HIGHLIGHT_WEIGHT, t as HOVER_WEIGHT, u as HighlightLayers, K as KnownFeatureType, N as NO_MODIFIERS, v as PERSPECTIVE_FOV, w as PICKED_SURFACE_LABEL, x as PartMesh, y as PartMeshProps, a as PartMeshRefs, z as PartObject, A as PartPick, G as PickModifiers, I as REGION_ATTRIBUTE, J as RegionHighlight, L as RegionPaint, S as SECTION_RENDER_ORDER, O as SceneBounds, Q as SectionAnchor, U as SectionBounds, W as SectionOptions, X as SectionPlacement, Y as SectionState, Z as SectionView, _ as ViewportSize, $ as applyHighlightLayers, a0 as applyProjection, a1 as aspectRatio, a2 as boundsFromBox, a3 as buildPick, a4 as buildRegionAttribute, a5 as buildRegionTexels, a6 as cadViewDirections, a7 as contentBounds, a8 as createPart, a9 as currentViewDirection, aa as defaultBounds, ab as directionColor, ac as dragPlane, ad as fitDistance, ae as focusForPick, n as normalizePartReport, af as orthographicHalfHeight, ag as perspectiveFitDistance, ah as pickedStartDepth, ai as resolveSectionPlane, aj as resolveTheme, ak as screenLength, al as sectionBounds, am as sectionConstant, an as sectionDepth, ao as sectionDepthConstant, ap as sectionDepthRange, aq as sectionFromPick, ar as sectionOffset, as as sectionPlane, s as smoothRegionNormals, at as startPosition, au as themesEqual, av as viewDirection } from './normalize-
|
|
1
|
+
import { V as Vec3, d as ViewerTheme, P as PartModel, e as PartModelRegion, f as ViewerCamera, g as ViewerView, h as Projection, T as TriangleRange, F as FeatureTag, R as RegionIndex, i as PartModelFeature, j as FeatureType } from './normalize-Bzzwwxt4.js';
|
|
2
|
+
export { B as BuildPickInput, C as CAD_CAMERA_UP, k as CANDIDATE_WEIGHT, D as DEFAULT_FIT_MARGIN, l as DEFAULT_THEME, m as DIRECTION_COLORS, o as EXCLUDE_FROM_FRAME, E as EnginePart, p as FeatureHighlight, H as HANDLE_PIXELS, q as HIGHLIGHT_COLORS, r as HIGHLIGHT_WEIGHT, t as HOVER_WEIGHT, u as HighlightLayers, K as KnownFeatureType, N as NO_MODIFIERS, v as PERSPECTIVE_FOV, w as PICKED_SURFACE_LABEL, x as PartMesh, y as PartMeshProps, a as PartMeshRefs, z as PartObject, A as PartPick, G as PickModifiers, I as REGION_ATTRIBUTE, J as RegionHighlight, L as RegionPaint, S as SECTION_RENDER_ORDER, O as SceneBounds, Q as SectionAnchor, U as SectionBounds, W as SectionOptions, X as SectionPlacement, Y as SectionState, Z as SectionView, _ as ViewportSize, $ as applyHighlightLayers, a0 as applyProjection, a1 as aspectRatio, a2 as boundsFromBox, a3 as buildPick, a4 as buildRegionAttribute, a5 as buildRegionTexels, a6 as cadViewDirections, a7 as contentBounds, a8 as createPart, a9 as currentViewDirection, aa as defaultBounds, ab as directionColor, ac as dragPlane, ad as fitDistance, ae as focusForPick, n as normalizePartReport, af as orthographicHalfHeight, ag as perspectiveFitDistance, ah as pickedStartDepth, ai as resolveSectionPlane, aj as resolveTheme, ak as screenLength, al as sectionBounds, am as sectionConstant, an as sectionDepth, ao as sectionDepthConstant, ap as sectionDepthRange, aq as sectionFromPick, ar as sectionOffset, as as sectionPlane, s as smoothRegionNormals, at as startPosition, au as themesEqual, av as viewDirection } from './normalize-Bzzwwxt4.js';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { RefObject, ReactNode, CSSProperties } from 'react';
|
|
5
5
|
import { BufferGeometry, CanvasTexture, Vector3, Box3 } from 'three';
|
|
@@ -283,59 +283,27 @@ declare function gridGeometry(spec: GridSpec): BufferGeometry;
|
|
|
283
283
|
* With one qualification. The Engine splits a surface where that makes a better
|
|
284
284
|
* machining plan, and those splits are boundaries between regions without being
|
|
285
285
|
* edges of the part: a floor cut in two to be reached from two directions is
|
|
286
|
-
* still one
|
|
287
|
-
*
|
|
288
|
-
*
|
|
286
|
+
* still one face to look at. So the walk is over *visual surfaces* — regions
|
|
287
|
+
* grouped by the kernel's exact `splitOrigin` lineage — and a split leaves no
|
|
288
|
+
* line. Nothing about picking or features goes through that grouping.
|
|
289
289
|
*
|
|
290
290
|
* The mesh must be non-indexed, which `parsePartGeometry` guarantees.
|
|
291
291
|
*/
|
|
292
292
|
declare function regionEdgesGeometry(geometry: BufferGeometry, model: Pick<PartModel, 'regions' | 'regionIndex'>): BufferGeometry;
|
|
293
293
|
|
|
294
|
+
/** Region index → the visual surface it belongs to. */
|
|
295
|
+
type SurfaceOf = ReadonlyMap<number, number>;
|
|
294
296
|
/**
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
* The
|
|
298
|
-
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
* So this groups regions that continue each other, and the grouping is used for
|
|
305
|
-
* the two things that are about how the part *looks* — its edges and its
|
|
306
|
-
* shading. Nothing about picking, highlighting or features goes through here:
|
|
307
|
-
* a split is still two regions to click on and still two regions a feature can
|
|
308
|
-
* own, which is the whole reason the Engine made it.
|
|
309
|
-
*
|
|
310
|
-
* Two regions continue each other when they meet along an edge, are both
|
|
311
|
-
* **planes**, and are flat to within a degree of one another — which for a
|
|
312
|
-
* plane means they are the same plane.
|
|
313
|
-
*
|
|
314
|
-
* Planes only, and that is a limit of what the report says rather than caution.
|
|
315
|
-
* A region carries an `idx`, a `shapeKind`, an area and a triangle range: there
|
|
316
|
-
* is nothing in it that says which analytic surface a region was cut from. On a
|
|
317
|
-
* flat face that does not matter, because two coplanar planes meeting along an
|
|
318
|
-
* edge *are* one plane and no part has an edge there. On a curved one it
|
|
319
|
-
* matters entirely: a fillet running tangentially into a shaft and a fillet
|
|
320
|
-
* split down the middle look identical from the facets alone, and guessing
|
|
321
|
-
* between them either rubs out a line the part has or leaves one it does not.
|
|
322
|
-
* A line the part has is the worse of the two to lose, so curved boundaries are
|
|
323
|
-
* all drawn.
|
|
324
|
-
*
|
|
325
|
-
* The exact version of this wants the Engine to say which surface a region came
|
|
326
|
-
* from. Until it does, this is the half that can be proved.
|
|
297
|
+
* The visual surface of each post-split region.
|
|
298
|
+
*
|
|
299
|
+
* The kernel divides B-rep faces to make machining relationships unambiguous.
|
|
300
|
+
* Those divisions remain meaningful to feature extraction and picking, but
|
|
301
|
+
* they are not physical edges. `splitOrigin` is the kernel's exact lineage
|
|
302
|
+
* relation: equal values mean the regions were one face before that analysis
|
|
303
|
+
* split. It is therefore the single grouping used for rendering, rather than
|
|
304
|
+
* attempting to infer continuations from mesh normals or surface kinds.
|
|
327
305
|
*/
|
|
328
|
-
|
|
329
|
-
* How far two planes may disagree across a shared edge and still be one plane.
|
|
330
|
-
*
|
|
331
|
-
* A degree, which is a rounding error rather than a judgement: a split is
|
|
332
|
-
* exactly coplanar, and anything a part actually turns through is a chamfer at
|
|
333
|
-
* fifteen degrees or more.
|
|
334
|
-
*/
|
|
335
|
-
declare const CONTINUES_WITHIN: number;
|
|
336
|
-
/** Region index → the surface it belongs to, by region `idx`. */
|
|
337
|
-
type SurfaceOf = ReadonlyMap<number, number>;
|
|
338
|
-
declare function visualSurfaces(geometry: BufferGeometry, regions: readonly PartModelRegion[]): SurfaceOf;
|
|
306
|
+
declare function visualSurfaces(regions: readonly PartModelRegion[]): SurfaceOf;
|
|
339
307
|
|
|
340
308
|
/**
|
|
341
309
|
* Mouse and trackpad presets.
|
|
@@ -634,4 +602,4 @@ declare function bestOwner(model: PartModel, owners: readonly FeatureTag[], cont
|
|
|
634
602
|
*/
|
|
635
603
|
declare function cycleOwner(owners: readonly FeatureTag[], current: FeatureTag | null): FeatureTag | null;
|
|
636
604
|
|
|
637
|
-
export { type ArrowPlacement, Axes, type AxesProps, CHAMFER,
|
|
605
|
+
export { type ArrowPlacement, Axes, type AxesProps, CHAMFER, CadCameraControls, type CadCameraControlsProps, type ControlScheme, type CubeZone, DirectionArrows, type DirectionArrowsProps, type DirectionGroup, ExtendedCameraControls, type ExtendedCameraControlsOptions, FEATURE_TYPE_RANKS, FeatureTag, FeatureType, Grid, type GridProps, type GridSpec, type NamedDirection, PartModel, PartModelFeature, PartModelRegion, PartReportFormatError, Projection, type RankingContext, RegionIndex, type SurfaceOf, TAP_SLOP, type TapPoint, type TapTracker, TriangleRange, UnsupportedKernelVersionError, VIEW_NAMES, VIEW_SIGNS, Vec3, ViewCube, type ViewCubeProps, type ViewKind, type ViewName, Viewer, ViewerCamera, type ViewerControls, type ViewerHandle, type ViewerProps, ViewerTheme, ViewerView, arrowPlacement, bestOwner, buildRegionIndex, cubeOutlineGeometry, cubeZones, cycleOwner, directionIndexOf, directionLabel, featureTypeRank, gridGeometry, gridSpec, groupByDirection, labelGeometry, labelTexture, movedFar, panelGeometry, rankOwners, regionEdgesGeometry, regionNormals, sameDirection, trackTaps, useContentBox, useTapGuard, useViewerControls, viewKind, viewUp, viewVector, visualSurfaces };
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
CAD_CAMERA_UP,
|
|
3
3
|
CANDIDATE_WEIGHT,
|
|
4
4
|
CONE_AXIS,
|
|
5
|
-
CONTINUES_WITHIN,
|
|
6
5
|
CadCameraControls,
|
|
7
6
|
DEFAULT_FIT_MARGIN,
|
|
8
7
|
DEFAULT_THEME,
|
|
@@ -81,7 +80,7 @@ import {
|
|
|
81
80
|
useViewerControls,
|
|
82
81
|
viewDirection,
|
|
83
82
|
visualSurfaces
|
|
84
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-RICG6UVH.js";
|
|
85
84
|
|
|
86
85
|
// src/primitives.tsx
|
|
87
86
|
import { GizmoHelper } from "@react-three/drei";
|
|
@@ -581,7 +580,6 @@ export {
|
|
|
581
580
|
CAD_CAMERA_UP,
|
|
582
581
|
CANDIDATE_WEIGHT,
|
|
583
582
|
CHAMFER,
|
|
584
|
-
CONTINUES_WITHIN,
|
|
585
583
|
CadCameraControls,
|
|
586
584
|
DEFAULT_FIT_MARGIN,
|
|
587
585
|
DEFAULT_THEME,
|
|
@@ -5,7 +5,7 @@ import { Group, Mesh, LineSegments, Box3, Plane, BufferGeometry, Camera, Vector3
|
|
|
5
5
|
* The normalized part — the only thing the renderer consumes.
|
|
6
6
|
*
|
|
7
7
|
* `engine/` produces this; nothing under `model/` or `render/` sees a
|
|
8
|
-
* `
|
|
8
|
+
* `PartResponse`. The renderer therefore survives an API change, and the
|
|
9
9
|
* viewer can be driven from a local file with no API at all, which is also how
|
|
10
10
|
* it gets tested.
|
|
11
11
|
*
|
|
@@ -84,6 +84,16 @@ interface RegionIndex {
|
|
|
84
84
|
rangeForRegion(region: number): TriangleRange | null;
|
|
85
85
|
}
|
|
86
86
|
interface PartModelRegion {
|
|
87
|
+
/**
|
|
88
|
+
* Opaque, report-local identity of the B-rep face this region came from before
|
|
89
|
+
* analysis split it. Equal values are one visual surface; it is not an index
|
|
90
|
+
* or a kernel surface identifier.
|
|
91
|
+
*/
|
|
92
|
+
readonly splitOrigin: number;
|
|
93
|
+
/**
|
|
94
|
+
* Post-split region identity. Feature ownership, picking, and triangle
|
|
95
|
+
* ranges deliberately continue to use this rather than `splitOrigin`.
|
|
96
|
+
*/
|
|
87
97
|
readonly idx: number;
|
|
88
98
|
readonly shapeKind: ShapeKind;
|
|
89
99
|
/**
|
|
@@ -246,7 +256,7 @@ interface PartObject {
|
|
|
246
256
|
paintRegion(region: number, color: number, weight: number): void;
|
|
247
257
|
/** What a region is painted with now. `null` for a region it does not have. */
|
|
248
258
|
regionPaint(region: number): RegionPaint | null;
|
|
249
|
-
/** Paints every region
|
|
259
|
+
/** Paints every region the feature explicitly owns. */
|
|
250
260
|
paintFeature(tag: FeatureTag, color: number, weight: number): void;
|
|
251
261
|
clearPaint(): void;
|
|
252
262
|
/** A feature's bounds in part space, for framing. `null` if it has none. */
|
|
@@ -265,8 +275,10 @@ interface RegionPaint {
|
|
|
265
275
|
/** 0 for untouched, 1 for fully painted. */
|
|
266
276
|
readonly weight: number;
|
|
267
277
|
}
|
|
268
|
-
/** The part of a
|
|
269
|
-
type RegionTable =
|
|
278
|
+
/** The part of a region table the buffer builders need. */
|
|
279
|
+
type RegionTable = {
|
|
280
|
+
readonly regions: readonly Pick<PartModel['regions'][number], 'idx' | 'triangles'>[];
|
|
281
|
+
};
|
|
270
282
|
/**
|
|
271
283
|
* Maps a region's `idx` to its column in the state texture.
|
|
272
284
|
*
|
|
@@ -821,10 +833,9 @@ declare const EnginePart: ({ report, ...props }: EnginePartProps) => react.JSX.E
|
|
|
821
833
|
* triangle its own normal, which is honest but leaves a bore looking like a
|
|
822
834
|
* fifty-sided nut, because that is exactly what its triangles are.
|
|
823
835
|
*
|
|
824
|
-
*
|
|
825
|
-
*
|
|
826
|
-
*
|
|
827
|
-
* distinction a mesh cannot express is one the region table can.
|
|
836
|
+
* The report says which post-split regions came from one original B-rep face.
|
|
837
|
+
* Averaging within that exact visual surface and never across one gives a bore
|
|
838
|
+
* that shades like a bore and an edge that stays an edge.
|
|
828
839
|
*
|
|
829
840
|
* Two vertices are the same point if their coordinates match exactly. That is
|
|
830
841
|
* safe rather than optimistic — `toNonIndexed` copies each shared vertex from
|