@constructorfleet/sketchforge-engine 1.27.0 → 1.28.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/dist/cadAnalysis.d.ts.map +1 -1
- package/dist/cadAnalysis.js +14 -0
- package/dist/cadAnalysis.js.map +1 -1
- package/dist/cadBakeMetadata.d.ts +11 -2
- package/dist/cadBakeMetadata.d.ts.map +1 -1
- package/dist/cadBakeMetadata.js +9 -0
- package/dist/cadBakeMetadata.js.map +1 -1
- package/dist/cadProjection.d.ts.map +1 -1
- package/dist/cadProjection.js.map +1 -1
- package/dist/cadSection.d.ts.map +1 -1
- package/dist/cadShell.d.ts +1 -1
- package/dist/cadShell.d.ts.map +1 -1
- package/dist/cadShell.js +7 -0
- package/dist/cadShell.js.map +1 -1
- package/dist/cadSolids.d.ts.map +1 -1
- package/dist/cadSolids.js +18 -1
- package/dist/cadSolids.js.map +1 -1
- package/dist/cutBrepFrameMigration.d.ts +46 -0
- package/dist/cutBrepFrameMigration.d.ts.map +1 -0
- package/dist/cutBrepFrameMigration.js +105 -0
- package/dist/cutBrepFrameMigration.js.map +1 -0
- package/dist/cutterPadding.d.ts.map +1 -1
- package/dist/domain/cameraProjection.js.map +1 -1
- package/dist/domain/sketchforge.d.ts +30 -0
- package/dist/domain/sketchforge.d.ts.map +1 -1
- package/dist/editorHistory.d.ts.map +1 -1
- package/dist/editorHistory.js.map +1 -1
- package/dist/engine.d.ts +3 -3
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +102 -66
- package/dist/engine.js.map +1 -1
- package/dist/exactBooleanParts.d.ts +4 -2
- package/dist/exactBooleanParts.d.ts.map +1 -1
- package/dist/exactBooleanParts.js +7 -3
- package/dist/exactBooleanParts.js.map +1 -1
- package/dist/exactBooleanSolids.d.ts.map +1 -1
- package/dist/gearProfile.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/loftProfile.d.ts +1 -1
- package/dist/loftProfile.d.ts.map +1 -1
- package/dist/loftProfile.js.map +1 -1
- package/dist/meshEdgeProjection.d.ts +104 -0
- package/dist/meshEdgeProjection.d.ts.map +1 -0
- package/dist/meshEdgeProjection.js +439 -0
- package/dist/meshEdgeProjection.js.map +1 -0
- package/dist/meshImport.d.ts.map +1 -1
- package/dist/meshImport.js +2 -20
- package/dist/meshImport.js.map +1 -1
- package/dist/meshMassProperties.d.ts +92 -0
- package/dist/meshMassProperties.d.ts.map +1 -0
- package/dist/meshMassProperties.js +570 -0
- package/dist/meshMassProperties.js.map +1 -0
- package/dist/meshSection.d.ts +44 -0
- package/dist/meshSection.d.ts.map +1 -0
- package/dist/meshSection.js +154 -0
- package/dist/meshSection.js.map +1 -0
- package/dist/meshShellOverlap.d.ts +75 -0
- package/dist/meshShellOverlap.d.ts.map +1 -0
- package/dist/meshShellOverlap.js +797 -0
- package/dist/meshShellOverlap.js.map +1 -0
- package/dist/meshShellSolids.d.ts +44 -0
- package/dist/meshShellSolids.d.ts.map +1 -0
- package/dist/meshShellSolids.js +116 -0
- package/dist/meshShellSolids.js.map +1 -0
- package/dist/nodeSvgDomParser.d.ts +3 -0
- package/dist/nodeSvgDomParser.d.ts.map +1 -0
- package/dist/nodeSvgDomParser.js +53 -0
- package/dist/nodeSvgDomParser.js.map +1 -0
- package/dist/parametricRecompute.d.ts.map +1 -1
- package/dist/parametricRecompute.js +56 -6
- package/dist/parametricRecompute.js.map +1 -1
- package/dist/placementWorkplane.d.ts.map +1 -1
- package/dist/placementWorkplane.js.map +1 -1
- package/dist/projectAssets.d.ts +1 -1
- package/dist/projectStore.d.ts +1 -1
- package/dist/projectStore.d.ts.map +1 -1
- package/dist/projectStore.js +23 -2
- package/dist/projectStore.js.map +1 -1
- package/dist/revolveRequests.d.ts +57 -1
- package/dist/revolveRequests.d.ts.map +1 -1
- package/dist/revolveRequests.js +103 -4
- package/dist/revolveRequests.js.map +1 -1
- package/dist/sceneExport.d.ts +6 -0
- package/dist/sceneExport.d.ts.map +1 -1
- package/dist/sceneExport.js +6 -2
- package/dist/sceneExport.js.map +1 -1
- package/dist/serverCadInterference.d.ts.map +1 -1
- package/dist/serverCadInterference.js +9 -2
- package/dist/serverCadInterference.js.map +1 -1
- package/dist/serverCadOperations.d.ts +73 -4
- package/dist/serverCadOperations.d.ts.map +1 -1
- package/dist/serverCadOperations.js +285 -51
- package/dist/serverCadOperations.js.map +1 -1
- package/dist/serverCadProjection.d.ts +14 -1
- package/dist/serverCadProjection.d.ts.map +1 -1
- package/dist/serverCadProjection.js +135 -13
- package/dist/serverCadProjection.js.map +1 -1
- package/dist/serverCadProperties.d.ts +14 -7
- package/dist/serverCadProperties.d.ts.map +1 -1
- package/dist/serverCadProperties.js +60 -24
- package/dist/serverCadProperties.js.map +1 -1
- package/dist/serverCadSection.d.ts +21 -1
- package/dist/serverCadSection.d.ts.map +1 -1
- package/dist/serverCadSection.js +157 -43
- package/dist/serverCadSection.js.map +1 -1
- package/dist/serverCadShell.d.ts.map +1 -1
- package/dist/serverCadShell.js +0 -3
- package/dist/serverCadShell.js.map +1 -1
- package/dist/serverShapeBooleans.d.ts +75 -0
- package/dist/serverShapeBooleans.d.ts.map +1 -1
- package/dist/serverShapeBooleans.js +251 -9
- package/dist/serverShapeBooleans.js.map +1 -1
- package/dist/serverShapeGroups.js.map +1 -1
- package/dist/shapeBounds.d.ts.map +1 -1
- package/dist/shapeCatalog.d.ts.map +1 -1
- package/dist/shapeCatalog.js +1 -0
- package/dist/shapeCatalog.js.map +1 -1
- package/dist/shapeRequests.d.ts +13 -0
- package/dist/shapeRequests.d.ts.map +1 -1
- package/dist/shapeRequests.js +14 -0
- package/dist/shapeRequests.js.map +1 -1
- package/dist/sketchCadProfile.d.ts +13 -0
- package/dist/sketchCadProfile.d.ts.map +1 -1
- package/dist/sketchCadProfile.js +108 -0
- package/dist/sketchCadProfile.js.map +1 -1
- package/dist/sketchCadSweep.js.map +1 -1
- package/dist/sketchEdgeSegmentLineage.d.ts +32 -0
- package/dist/sketchEdgeSegmentLineage.d.ts.map +1 -0
- package/dist/sketchEdgeSegmentLineage.js +49 -0
- package/dist/sketchEdgeSegmentLineage.js.map +1 -0
- package/dist/sketchEdgeSegmentLineageKernel.d.ts +83 -0
- package/dist/sketchEdgeSegmentLineageKernel.d.ts.map +1 -0
- package/dist/sketchEdgeSegmentLineageKernel.js +125 -0
- package/dist/sketchEdgeSegmentLineageKernel.js.map +1 -0
- package/dist/sketchFaceDraftKernel.d.ts +11 -4
- package/dist/sketchFaceDraftKernel.d.ts.map +1 -1
- package/dist/sketchFaceDraftKernel.js +8 -2
- package/dist/sketchFaceDraftKernel.js.map +1 -1
- package/dist/sketchRevolve.d.ts +13 -0
- package/dist/sketchRevolve.d.ts.map +1 -1
- package/dist/sketchRevolve.js +4 -1
- package/dist/sketchRevolve.js.map +1 -1
- package/dist/skfProject.d.ts +1 -1
- package/dist/skfProject.d.ts.map +1 -1
- package/dist/skfProject.js +63 -4
- package/dist/skfProject.js.map +1 -1
- package/dist/sphereTessellation.d.ts.map +1 -1
- package/dist/stepAssemblyExplode.d.ts.map +1 -1
- package/dist/stepAssemblyExplode.js +1 -1
- package/dist/stepAssemblyExplode.js.map +1 -1
- package/dist/stepAssemblyHierarchy.js.map +1 -1
- package/dist/stepComponentMetadata.d.ts +1 -1
- package/dist/stepComponentMetadata.d.ts.map +1 -1
- package/dist/stepComponentMetadata.js +93 -39
- package/dist/stepComponentMetadata.js.map +1 -1
- package/dist/stepExport.d.ts +14 -1
- package/dist/stepExport.d.ts.map +1 -1
- package/dist/stepExport.js +81 -32
- package/dist/stepExport.js.map +1 -1
- package/dist/stepImportCommon.d.ts +4 -1
- package/dist/stepImportCommon.d.ts.map +1 -1
- package/dist/stepImportCommon.js +7 -6
- package/dist/stepImportCommon.js.map +1 -1
- package/dist/stlImport.js.map +1 -1
- package/dist/support/cadModifierTypes.d.ts +41 -1
- package/dist/support/cadModifierTypes.d.ts.map +1 -1
- package/dist/support/i18n/LocalizedError.d.ts.map +1 -1
- package/dist/support/i18n/locales/en/messages.json +30 -2
- package/dist/support/i18n/locales.d.ts.map +1 -1
- package/dist/support/lib/appTheme.d.ts.map +1 -1
- package/dist/support/lib/materialPresets.js.map +1 -1
- package/dist/support/lib/measurementUnits.d.ts.map +1 -1
- package/dist/support/lib/operator-configuration.json +13 -1
- package/dist/support/lib/operatorConfiguration.d.ts +5 -5
- package/dist/support/lib/workplaneGrid.js.map +1 -1
- package/dist/svgImport.d.ts +2 -0
- package/dist/svgImport.d.ts.map +1 -1
- package/dist/svgImport.js +7 -0
- package/dist/svgImport.js.map +1 -1
- package/dist/threadCatalog.js.map +1 -1
- package/dist/workplaneSettings.js.map +1 -1
- package/dist/workplaneShapes.d.ts +2 -2
- package/dist/workplaneShapes.d.ts.map +1 -1
- package/dist/workplaneShapes.js.map +1 -1
- package/package.json +7 -6
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A 2D drawing of a triangle mesh by its feature edges (issue #506).
|
|
3
|
+
*
|
|
4
|
+
* A mesh has no curves and no faces bigger than a triangle, so handing it to
|
|
5
|
+
* OCCT's hidden-line removal draws every triangle edge: a 57.6k-triangle part
|
|
6
|
+
* came out as a 9.4 MB SVG after 161 s, its flat faces a dense wireframe and
|
|
7
|
+
* its curved ones solid black. A mesh viewer draws the same mesh with a
|
|
8
|
+
* "crease angle" instead, and so does this:
|
|
9
|
+
*
|
|
10
|
+
* - a **feature edge** is one whose two triangles meet at more than
|
|
11
|
+
* `featureAngle` degrees, so the triangulation of a flat or gently curved
|
|
12
|
+
* face disappears and a real corner stays;
|
|
13
|
+
* - a **boundary** edge (one triangle) or a non-manifold one (three or more)
|
|
14
|
+
* is always drawn;
|
|
15
|
+
* - a **silhouette** edge is a smooth edge where one triangle faces the camera
|
|
16
|
+
* and the other faces away; it is found per view, which is what gives a
|
|
17
|
+
* faceted cylinder its outline without its seams.
|
|
18
|
+
*
|
|
19
|
+
* Which of those edges a camera can see is answered by a depth buffer of the
|
|
20
|
+
* whole scene's triangles, sampled along each edge, rather than by the kernel.
|
|
21
|
+
* Everything here is arithmetic on arrays: no kernel, no DOM, testable alone.
|
|
22
|
+
* `serverCadProjection.ts` combines it with the exact solids' drawing.
|
|
23
|
+
*/
|
|
24
|
+
import { viewUp } from "./cadProjection.js";
|
|
25
|
+
/** Below this, the triangulation of a gently curved surface is not drawn. */
|
|
26
|
+
export const DEFAULT_FEATURE_ANGLE = 30;
|
|
27
|
+
/**
|
|
28
|
+
* Whether a crease angle is one this drawing accepts: a finite number of
|
|
29
|
+
* degrees from 0 (every edge) to 180 (only boundaries and silhouettes).
|
|
30
|
+
*/
|
|
31
|
+
export function isFeatureAngle(value) {
|
|
32
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 180;
|
|
33
|
+
}
|
|
34
|
+
function soupDiagonal(soup) {
|
|
35
|
+
let minX = Infinity, minY = Infinity, minZ = Infinity, maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
|
|
36
|
+
for (let index = 0; index + 2 < soup.length; index += 3) {
|
|
37
|
+
const x = soup[index], y = soup[index + 1], z = soup[index + 2];
|
|
38
|
+
if (x < minX)
|
|
39
|
+
minX = x;
|
|
40
|
+
if (x > maxX)
|
|
41
|
+
maxX = x;
|
|
42
|
+
if (y < minY)
|
|
43
|
+
minY = y;
|
|
44
|
+
if (y > maxY)
|
|
45
|
+
maxY = y;
|
|
46
|
+
if (z < minZ)
|
|
47
|
+
minZ = z;
|
|
48
|
+
if (z > maxZ)
|
|
49
|
+
maxZ = z;
|
|
50
|
+
}
|
|
51
|
+
return Number.isFinite(minX) ? Math.hypot(maxX - minX, maxY - minY, maxZ - minZ) : 0;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The edges of a triangle soup worth drawing at `featureAngle` degrees.
|
|
55
|
+
*
|
|
56
|
+
* Corners are welded on a grid a ten-millionth of the mesh's diagonal wide,
|
|
57
|
+
* which joins the copies of a vertex an STL repeats per triangle without
|
|
58
|
+
* joining two vertices a real model keeps apart. Degenerate triangles carry no
|
|
59
|
+
* normal and contribute no edges.
|
|
60
|
+
*/
|
|
61
|
+
export function meshEdgeSet(soup, featureAngle = DEFAULT_FEATURE_ANGLE) {
|
|
62
|
+
const triangleCount = Math.floor(soup.length / 9);
|
|
63
|
+
const quantum = Math.max(soupDiagonal(soup) * 1e-7, 1e-12);
|
|
64
|
+
const vertexIds = new Map();
|
|
65
|
+
const vertices = [];
|
|
66
|
+
const corner = new Int32Array(triangleCount * 3);
|
|
67
|
+
for (let index = 0; index < triangleCount * 3; index += 1) {
|
|
68
|
+
const x = soup[index * 3], y = soup[index * 3 + 1], z = soup[index * 3 + 2];
|
|
69
|
+
const key = `${Math.round(x / quantum)},${Math.round(y / quantum)},${Math.round(z / quantum)}`;
|
|
70
|
+
let id = vertexIds.get(key);
|
|
71
|
+
if (id === undefined) {
|
|
72
|
+
id = vertices.length / 3;
|
|
73
|
+
vertexIds.set(key, id);
|
|
74
|
+
vertices.push(x, y, z);
|
|
75
|
+
}
|
|
76
|
+
corner[index] = id;
|
|
77
|
+
}
|
|
78
|
+
const normals = new Float64Array(triangleCount * 3);
|
|
79
|
+
const valid = new Uint8Array(triangleCount);
|
|
80
|
+
for (let triangle = 0; triangle < triangleCount; triangle += 1) {
|
|
81
|
+
const [a, b, c] = [corner[triangle * 3], corner[triangle * 3 + 1], corner[triangle * 3 + 2]];
|
|
82
|
+
if (a === b || b === c || a === c)
|
|
83
|
+
continue;
|
|
84
|
+
const ux = vertices[b * 3] - vertices[a * 3], uy = vertices[b * 3 + 1] - vertices[a * 3 + 1], uz = vertices[b * 3 + 2] - vertices[a * 3 + 2];
|
|
85
|
+
const vx = vertices[c * 3] - vertices[a * 3], vy = vertices[c * 3 + 1] - vertices[a * 3 + 1], vz = vertices[c * 3 + 2] - vertices[a * 3 + 2];
|
|
86
|
+
const nx = uy * vz - uz * vy, ny = uz * vx - ux * vz, nz = ux * vy - uy * vx;
|
|
87
|
+
const length = Math.hypot(nx, ny, nz);
|
|
88
|
+
if (!(length > 0))
|
|
89
|
+
continue;
|
|
90
|
+
normals[triangle * 3] = nx / length;
|
|
91
|
+
normals[triangle * 3 + 1] = ny / length;
|
|
92
|
+
normals[triangle * 3 + 2] = nz / length;
|
|
93
|
+
valid[triangle] = 1;
|
|
94
|
+
}
|
|
95
|
+
// Each undirected edge, with the triangles on it and the direction each one
|
|
96
|
+
// walks it in: consistently wound neighbours walk a shared edge oppositely.
|
|
97
|
+
const vertexCount = vertices.length / 3;
|
|
98
|
+
const edges = new Map();
|
|
99
|
+
for (let triangle = 0; triangle < triangleCount; triangle += 1) {
|
|
100
|
+
if (!valid[triangle])
|
|
101
|
+
continue;
|
|
102
|
+
for (let side = 0; side < 3; side += 1) {
|
|
103
|
+
const from = corner[triangle * 3 + side];
|
|
104
|
+
const to = corner[triangle * 3 + ((side + 1) % 3)];
|
|
105
|
+
const low = Math.min(from, to), high = Math.max(from, to);
|
|
106
|
+
const key = low * vertexCount + high;
|
|
107
|
+
let edge = edges.get(key);
|
|
108
|
+
if (!edge) {
|
|
109
|
+
edge = { from: low, to: high, triangles: [], forward: [] };
|
|
110
|
+
edges.set(key, edge);
|
|
111
|
+
}
|
|
112
|
+
edge.triangles.push(triangle);
|
|
113
|
+
edge.forward.push(from === low);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const cosine = Math.cos((featureAngle * Math.PI) / 180);
|
|
117
|
+
const always = [];
|
|
118
|
+
const alwaysNormals = [];
|
|
119
|
+
const smooth = [];
|
|
120
|
+
const smoothNormals = [];
|
|
121
|
+
const ends = (edge) => [
|
|
122
|
+
vertices[edge.from * 3], vertices[edge.from * 3 + 1], vertices[edge.from * 3 + 2],
|
|
123
|
+
vertices[edge.to * 3], vertices[edge.to * 3 + 1], vertices[edge.to * 3 + 2],
|
|
124
|
+
];
|
|
125
|
+
for (const edge of edges.values()) {
|
|
126
|
+
const first = edge.triangles[0];
|
|
127
|
+
const n1 = [normals[first * 3], normals[first * 3 + 1], normals[first * 3 + 2]];
|
|
128
|
+
if (edge.triangles.length !== 2) {
|
|
129
|
+
always.push(...ends(edge));
|
|
130
|
+
alwaysNormals.push(...n1);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const second = edge.triangles[1];
|
|
134
|
+
// A neighbour wound the same way round the edge is wound inconsistently;
|
|
135
|
+
// turning its normal over is what makes a flat face read as flat.
|
|
136
|
+
const flip = edge.forward[0] === edge.forward[1] ? -1 : 1;
|
|
137
|
+
const n2 = [normals[second * 3] * flip, normals[second * 3 + 1] * flip, normals[second * 3 + 2] * flip];
|
|
138
|
+
const alignment = n1[0] * n2[0] + n1[1] * n2[1] + n1[2] * n2[2];
|
|
139
|
+
// Strictly greater than the angle, so at 0 degrees every edge that is not
|
|
140
|
+
// exactly flat is drawn.
|
|
141
|
+
if (alignment < cosine - 1e-12) {
|
|
142
|
+
always.push(...ends(edge));
|
|
143
|
+
alwaysNormals.push(...n1);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
smooth.push(...ends(edge));
|
|
147
|
+
smoothNormals.push(...n1, ...n2);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
always: Float64Array.from(always),
|
|
152
|
+
alwaysNormals: Float64Array.from(alwaysNormals),
|
|
153
|
+
smooth: Float64Array.from(smooth),
|
|
154
|
+
smoothNormals: Float64Array.from(smoothNormals),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
const RASTER_RESOLUTION = 1024;
|
|
158
|
+
const MAX_SLOPE = 20;
|
|
159
|
+
function projector(basis) {
|
|
160
|
+
const up = viewUp(basis);
|
|
161
|
+
const { right, toward } = basis;
|
|
162
|
+
return (x, y, z) => [
|
|
163
|
+
x * right.x + y * right.y + z * right.z,
|
|
164
|
+
x * up.x + y * up.y + z * up.z,
|
|
165
|
+
x * toward.x + y * toward.y + z * toward.z,
|
|
166
|
+
];
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* The pixel grid covering every soup and every extra 2D point in the view,
|
|
170
|
+
* a thousand and twenty-four pixels across its longer side.
|
|
171
|
+
*/
|
|
172
|
+
export function viewRaster(basis, soups, points = []) {
|
|
173
|
+
const project = projector(basis);
|
|
174
|
+
let minU = Infinity, maxU = -Infinity, minV = Infinity, maxV = -Infinity, diagonal = 0;
|
|
175
|
+
for (const soup of soups) {
|
|
176
|
+
diagonal = Math.max(diagonal, soupDiagonal(soup));
|
|
177
|
+
for (let index = 0; index + 2 < soup.length; index += 3) {
|
|
178
|
+
const [u, v] = project(soup[index], soup[index + 1], soup[index + 2]);
|
|
179
|
+
if (u < minU)
|
|
180
|
+
minU = u;
|
|
181
|
+
if (u > maxU)
|
|
182
|
+
maxU = u;
|
|
183
|
+
if (v < minV)
|
|
184
|
+
minV = v;
|
|
185
|
+
if (v > maxV)
|
|
186
|
+
maxV = v;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
for (const line of points) {
|
|
190
|
+
for (let index = 0; index + 1 < line.length; index += 2) {
|
|
191
|
+
if (line[index] < minU)
|
|
192
|
+
minU = line[index];
|
|
193
|
+
if (line[index] > maxU)
|
|
194
|
+
maxU = line[index];
|
|
195
|
+
if (line[index + 1] < minV)
|
|
196
|
+
minV = line[index + 1];
|
|
197
|
+
if (line[index + 1] > maxV)
|
|
198
|
+
maxV = line[index + 1];
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (!Number.isFinite(minU)) {
|
|
202
|
+
minU = maxU = minV = maxV = 0;
|
|
203
|
+
}
|
|
204
|
+
const range = Math.max(maxU - minU, maxV - minV, 1e-9);
|
|
205
|
+
const pixel = range / RASTER_RESOLUTION;
|
|
206
|
+
const margin = 2 * pixel;
|
|
207
|
+
diagonal = Math.max(diagonal, range);
|
|
208
|
+
return {
|
|
209
|
+
basis,
|
|
210
|
+
minU: minU - margin,
|
|
211
|
+
minV: minV - margin,
|
|
212
|
+
pixel,
|
|
213
|
+
width: Math.ceil((maxU - minU) / pixel) + 5,
|
|
214
|
+
height: Math.ceil((maxV - minV) / pixel) + 5,
|
|
215
|
+
tolerance: diagonal * 0.002 + pixel,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/** The soups rasterised into one depth buffer on `raster`. */
|
|
219
|
+
export function depthBuffer(raster, soups) {
|
|
220
|
+
const { width, height, minU, minV, pixel } = raster;
|
|
221
|
+
const closeness = new Float32Array(width * height).fill(-Infinity);
|
|
222
|
+
const project = projector(raster.basis);
|
|
223
|
+
for (const soup of soups) {
|
|
224
|
+
for (let index = 0; index + 8 < soup.length; index += 9) {
|
|
225
|
+
const a = project(soup[index], soup[index + 1], soup[index + 2]);
|
|
226
|
+
const b = project(soup[index + 3], soup[index + 4], soup[index + 5]);
|
|
227
|
+
const c = project(soup[index + 6], soup[index + 7], soup[index + 8]);
|
|
228
|
+
// Into pixel coordinates, pixel centres at half-integers.
|
|
229
|
+
const ax = (a[0] - minU) / pixel, ay = (a[1] - minV) / pixel;
|
|
230
|
+
const bx = (b[0] - minU) / pixel, by = (b[1] - minV) / pixel;
|
|
231
|
+
const cx = (c[0] - minU) / pixel, cy = (c[1] - minV) / pixel;
|
|
232
|
+
const area = (bx - ax) * (cy - ay) - (by - ay) * (cx - ax);
|
|
233
|
+
if (Math.abs(area) < 1e-12)
|
|
234
|
+
continue;
|
|
235
|
+
const x0 = Math.max(0, Math.floor(Math.min(ax, bx, cx))), x1 = Math.min(width - 1, Math.ceil(Math.max(ax, bx, cx)));
|
|
236
|
+
const y0 = Math.max(0, Math.floor(Math.min(ay, by, cy))), y1 = Math.min(height - 1, Math.ceil(Math.max(ay, by, cy)));
|
|
237
|
+
for (let y = y0; y <= y1; y += 1) {
|
|
238
|
+
const py = y + 0.5;
|
|
239
|
+
for (let x = x0; x <= x1; x += 1) {
|
|
240
|
+
const px = x + 0.5;
|
|
241
|
+
const wa = ((bx - px) * (cy - py) - (by - py) * (cx - px)) / area;
|
|
242
|
+
const wb = ((cx - px) * (ay - py) - (cy - py) * (ax - px)) / area;
|
|
243
|
+
const wc = 1 - wa - wb;
|
|
244
|
+
if (wa < -1e-9 || wb < -1e-9 || wc < -1e-9)
|
|
245
|
+
continue;
|
|
246
|
+
const depth = wa * a[2] + wb * b[2] + wc * c[2];
|
|
247
|
+
const at = y * width + x;
|
|
248
|
+
if (depth > closeness[at])
|
|
249
|
+
closeness[at] = depth;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return { raster, closeness };
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* The surface a point would have to be behind to be hidden: the farthest of
|
|
258
|
+
* the covered pixels around it, or nothing when the pixel itself is empty.
|
|
259
|
+
*
|
|
260
|
+
* Taking the farthest neighbour is what keeps an edge from being hidden by
|
|
261
|
+
* the very faces it bounds -- a pixel centre beside a steep face, or across a
|
|
262
|
+
* silhouette, reads nearer than the edge itself.
|
|
263
|
+
*/
|
|
264
|
+
function occluderAt(buffer, u, v) {
|
|
265
|
+
const { raster, closeness } = buffer;
|
|
266
|
+
const x = Math.floor((u - raster.minU) / raster.pixel);
|
|
267
|
+
const y = Math.floor((v - raster.minV) / raster.pixel);
|
|
268
|
+
if (x < 0 || y < 0 || x >= raster.width || y >= raster.height)
|
|
269
|
+
return -Infinity;
|
|
270
|
+
if (closeness[y * raster.width + x] === -Infinity)
|
|
271
|
+
return -Infinity;
|
|
272
|
+
let farthest = Infinity;
|
|
273
|
+
for (let dy = -1; dy <= 1; dy += 1) {
|
|
274
|
+
const row = y + dy;
|
|
275
|
+
if (row < 0 || row >= raster.height)
|
|
276
|
+
continue;
|
|
277
|
+
for (let dx = -1; dx <= 1; dx += 1) {
|
|
278
|
+
const column = x + dx;
|
|
279
|
+
if (column < 0 || column >= raster.width)
|
|
280
|
+
continue;
|
|
281
|
+
const value = closeness[row * raster.width + column];
|
|
282
|
+
if (value !== -Infinity && value < farthest)
|
|
283
|
+
farthest = value;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return farthest;
|
|
287
|
+
}
|
|
288
|
+
/** The nearest covered surface around a point, or -Infinity when none is. */
|
|
289
|
+
function nearestAt(buffer, u, v) {
|
|
290
|
+
const { raster, closeness } = buffer;
|
|
291
|
+
const x = Math.floor((u - raster.minU) / raster.pixel);
|
|
292
|
+
const y = Math.floor((v - raster.minV) / raster.pixel);
|
|
293
|
+
let nearest = -Infinity;
|
|
294
|
+
for (let dy = -1; dy <= 1; dy += 1) {
|
|
295
|
+
const row = y + dy;
|
|
296
|
+
if (row < 0 || row >= raster.height)
|
|
297
|
+
continue;
|
|
298
|
+
for (let dx = -1; dx <= 1; dx += 1) {
|
|
299
|
+
const column = x + dx;
|
|
300
|
+
if (column < 0 || column >= raster.width)
|
|
301
|
+
continue;
|
|
302
|
+
const value = closeness[row * raster.width + column];
|
|
303
|
+
if (value > nearest)
|
|
304
|
+
nearest = value;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return nearest;
|
|
308
|
+
}
|
|
309
|
+
/** Runs shorter than this many samples (pixels of a 1024-pixel view) take their neighbours' visibility. */
|
|
310
|
+
const MIN_RUN = 6;
|
|
311
|
+
/**
|
|
312
|
+
* A segment split into visible and hidden straight runs by `hiddenAt`, which
|
|
313
|
+
* answers for a parameter along it. Specks shorter than a few pixels -- where
|
|
314
|
+
* an edge passes within the tolerance of a surface, as a hidden edge does at
|
|
315
|
+
* the silhouette vertex it runs into -- join the run beside them.
|
|
316
|
+
*/
|
|
317
|
+
function splitSegment(u0, v0, u1, v1, pixel, hiddenAt, visible, hidden) {
|
|
318
|
+
const samples = Math.min(4096, Math.max(2, Math.ceil(Math.hypot(u1 - u0, v1 - v0) / pixel) + 1));
|
|
319
|
+
const states = [];
|
|
320
|
+
for (let index = 0; index < samples; index += 1)
|
|
321
|
+
states.push(hiddenAt(index / (samples - 1)));
|
|
322
|
+
// Run-length encode, then fold specks into the run before them (or after,
|
|
323
|
+
// for a speck at the start).
|
|
324
|
+
const runs = [];
|
|
325
|
+
for (let index = 0; index < samples; index += 1) {
|
|
326
|
+
const last = runs[runs.length - 1];
|
|
327
|
+
if (last && last.hidden === states[index])
|
|
328
|
+
last.end = index;
|
|
329
|
+
else
|
|
330
|
+
runs.push({ hidden: states[index], start: index, end: index });
|
|
331
|
+
}
|
|
332
|
+
for (let changed = true; changed && runs.length > 1;) {
|
|
333
|
+
changed = false;
|
|
334
|
+
for (let index = 0; index < runs.length; index += 1) {
|
|
335
|
+
const run = runs[index];
|
|
336
|
+
if (run.end - run.start + 1 >= MIN_RUN)
|
|
337
|
+
continue;
|
|
338
|
+
const neighbour = index > 0 ? runs[index - 1] : runs[index + 1];
|
|
339
|
+
neighbour.start = Math.min(neighbour.start, run.start);
|
|
340
|
+
neighbour.end = Math.max(neighbour.end, run.end);
|
|
341
|
+
runs.splice(index, 1);
|
|
342
|
+
// Two runs of one kind that now touch become one.
|
|
343
|
+
for (let merge = 1; merge < runs.length; merge += 1) {
|
|
344
|
+
if (runs[merge].hidden === runs[merge - 1].hidden) {
|
|
345
|
+
runs[merge - 1].end = runs[merge].end;
|
|
346
|
+
runs.splice(merge, 1);
|
|
347
|
+
merge -= 1;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
changed = true;
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
for (const run of runs) {
|
|
355
|
+
const t0 = run.start / (samples - 1);
|
|
356
|
+
const t1 = run.end / (samples - 1);
|
|
357
|
+
if (t1 <= t0)
|
|
358
|
+
continue;
|
|
359
|
+
const line = [u0 + (u1 - u0) * t0, v0 + (v1 - v0) * t0, u0 + (u1 - u0) * t1, v0 + (v1 - v0) * t1];
|
|
360
|
+
(run.hidden ? hidden : visible).push(line);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* How steeply a surface with this normal recedes per model unit across the
|
|
365
|
+
* screen, capped: an edge-on face would otherwise ask for infinite tolerance.
|
|
366
|
+
*/
|
|
367
|
+
function slopeOf(project, nx, ny, nz) {
|
|
368
|
+
const [nu, nv, nc] = project(nx, ny, nz);
|
|
369
|
+
if (Math.abs(nc) < 1 / MAX_SLOPE)
|
|
370
|
+
return MAX_SLOPE;
|
|
371
|
+
return Math.min(MAX_SLOPE, Math.hypot(nu, nv) / Math.abs(nc));
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* The mesh's edges as this view draws them, split into what the camera sees
|
|
375
|
+
* and what the scene in `occluders` hides.
|
|
376
|
+
*/
|
|
377
|
+
export function drawMeshEdges(edgeSet, occluders, raster) {
|
|
378
|
+
const project = projector(raster.basis);
|
|
379
|
+
const { toward } = raster.basis;
|
|
380
|
+
const visible = [];
|
|
381
|
+
const hidden = [];
|
|
382
|
+
const draw = (ends, offset, slope) => {
|
|
383
|
+
const [u0, v0, c0] = project(ends[offset], ends[offset + 1], ends[offset + 2]);
|
|
384
|
+
const [u1, v1, c1] = project(ends[offset + 3], ends[offset + 4], ends[offset + 5]);
|
|
385
|
+
// Seen end on, an edge is a point and draws nothing.
|
|
386
|
+
if (Math.hypot(u1 - u0, v1 - v0) < raster.pixel * 1e-3)
|
|
387
|
+
return;
|
|
388
|
+
const tolerance = raster.tolerance + 2 * raster.pixel * slope;
|
|
389
|
+
splitSegment(u0, v0, u1, v1, raster.pixel, (t) => {
|
|
390
|
+
const u = u0 + (u1 - u0) * t, v = v0 + (v1 - v0) * t, c = c0 + (c1 - c0) * t;
|
|
391
|
+
return occluders.some((buffer) => occluderAt(buffer, u, v) > c + tolerance);
|
|
392
|
+
}, visible, hidden);
|
|
393
|
+
};
|
|
394
|
+
for (let edge = 0; edge * 6 < edgeSet.always.length; edge += 1) {
|
|
395
|
+
const n = edgeSet.alwaysNormals;
|
|
396
|
+
draw(edgeSet.always, edge * 6, slopeOf(project, n[edge * 3], n[edge * 3 + 1], n[edge * 3 + 2]));
|
|
397
|
+
}
|
|
398
|
+
for (let edge = 0; edge * 6 < edgeSet.smooth.length; edge += 1) {
|
|
399
|
+
const n = edgeSet.smoothNormals;
|
|
400
|
+
const first = n[edge * 6] * toward.x + n[edge * 6 + 1] * toward.y + n[edge * 6 + 2] * toward.z;
|
|
401
|
+
const second = n[edge * 6 + 3] * toward.x + n[edge * 6 + 4] * toward.y + n[edge * 6 + 5] * toward.z;
|
|
402
|
+
if ((first > 0) === (second > 0))
|
|
403
|
+
continue;
|
|
404
|
+
draw(edgeSet.smooth, edge * 6, MAX_SLOPE);
|
|
405
|
+
}
|
|
406
|
+
return { visible, hidden };
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Exact-solid edges the kernel drew as visible, with the stretches a mesh
|
|
410
|
+
* stands in front of moved to `hidden`.
|
|
411
|
+
*
|
|
412
|
+
* The kernel's hidden-line removal never saw the meshes, and its 2D output
|
|
413
|
+
* has no depth, so a point's depth is read back off the exact solids' own
|
|
414
|
+
* buffer: a visible edge lies on the nearest exact surface at that point.
|
|
415
|
+
*/
|
|
416
|
+
export function occludeByMeshes(lines, own, meshes, visible, hidden) {
|
|
417
|
+
const { raster } = own;
|
|
418
|
+
const tolerance = raster.tolerance + 2 * raster.pixel;
|
|
419
|
+
for (const line of lines) {
|
|
420
|
+
const seen = [];
|
|
421
|
+
const behind = [];
|
|
422
|
+
for (let index = 0; index + 3 < line.length; index += 2) {
|
|
423
|
+
const u0 = line[index], v0 = line[index + 1], u1 = line[index + 2], v1 = line[index + 3];
|
|
424
|
+
splitSegment(u0, v0, u1, v1, raster.pixel, (t) => {
|
|
425
|
+
const u = u0 + (u1 - u0) * t, v = v0 + (v1 - v0) * t;
|
|
426
|
+
const depth = nearestAt(own, u, v);
|
|
427
|
+
return depth !== -Infinity && occluderAt(meshes, u, v) > depth + tolerance;
|
|
428
|
+
}, seen, behind);
|
|
429
|
+
}
|
|
430
|
+
// A line nothing hides keeps its own vertices rather than one stroke per segment.
|
|
431
|
+
if (!behind.length)
|
|
432
|
+
visible.push(line);
|
|
433
|
+
else {
|
|
434
|
+
visible.push(...seen);
|
|
435
|
+
hidden.push(...behind);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
//# sourceMappingURL=meshEdgeProjection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meshEdgeProjection.js","sourceRoot":"","sources":["../src/meshEdgeProjection.ts"],"names":[],"mappings":"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"}
|
package/dist/meshImport.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meshImport.d.ts","sourceRoot":"","sources":["../src/meshImport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAUH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE5E,6EAA6E;AAC7E,eAAO,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"meshImport.d.ts","sourceRoot":"","sources":["../src/meshImport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAUH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE5E,6EAA6E;AAC7E,eAAO,MAAM,uBAAuB,YAAI,KAAK,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAEtE,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5E,MAAM,MAAM,YAAY,GAAG;IAAE,KAAK,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC;AAE1E,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAKlF;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,UAAU,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,CAAC,CAgBvB"}
|
package/dist/meshImport.js
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
import { importedShapeFromObj } from "./objImport.js";
|
|
30
30
|
import { attachProjectAsset, projectAssetFromBytes, sourceFormatForFileName, } from "./projectAssets.js";
|
|
31
31
|
import { importedShapeFromStl } from "./stlImport.js";
|
|
32
|
-
import {
|
|
32
|
+
import { importedShapeFromSvgOnHost } from "./svgImport.js";
|
|
33
33
|
/** The file formats an import can read with no browser and no CAD kernel. */
|
|
34
34
|
export const IMPORTABLE_MESH_FORMATS = ["stl", "obj", "svg"];
|
|
35
35
|
/** The format a file name names, or null when nothing here can read it. */
|
|
@@ -39,21 +39,6 @@ export function importableMeshFormat(fileName) {
|
|
|
39
39
|
? format
|
|
40
40
|
: null;
|
|
41
41
|
}
|
|
42
|
-
/**
|
|
43
|
-
* Why an import could not be read, in words, or null when it can be.
|
|
44
|
-
*
|
|
45
|
-
* SVG is read by `three`'s `SVGLoader`, which parses with a `DOMParser`. A
|
|
46
|
-
* browser has one and a bare Node process does not, and the difference shows
|
|
47
|
-
* up as a `ReferenceError` from inside a loader -- so it is said plainly here
|
|
48
|
-
* instead, before any bytes are touched.
|
|
49
|
-
*/
|
|
50
|
-
function unreadableReason(format) {
|
|
51
|
-
if (format !== "svg")
|
|
52
|
-
return null;
|
|
53
|
-
return typeof DOMParser === "undefined"
|
|
54
|
-
? "SVG import needs a DOMParser, which this runtime does not provide; export the drawing as STL or OBJ instead."
|
|
55
|
-
: null;
|
|
56
|
-
}
|
|
57
42
|
/**
|
|
58
43
|
* The shape a model file describes, with the asset that keeps the file itself.
|
|
59
44
|
*
|
|
@@ -69,13 +54,10 @@ export async function importedMeshFromFile(fileName, bytes, mediaType) {
|
|
|
69
54
|
if (!format) {
|
|
70
55
|
throw new Error(`Cannot import "${fileName}": the readable formats are ${IMPORTABLE_MESH_FORMATS.join(", ")}.`);
|
|
71
56
|
}
|
|
72
|
-
const unreadable = unreadableReason(format);
|
|
73
|
-
if (unreadable)
|
|
74
|
-
throw new Error(unreadable);
|
|
75
57
|
const shape = format === "obj"
|
|
76
58
|
? importedShapeFromObj(fileName, new TextDecoder().decode(bytes))
|
|
77
59
|
: format === "svg"
|
|
78
|
-
?
|
|
60
|
+
? await importedShapeFromSvgOnHost(fileName, new TextDecoder().decode(bytes))
|
|
79
61
|
// A fresh buffer rather than the view's own: an importer reads the whole
|
|
80
62
|
// `ArrayBuffer`, and a `Uint8Array` decoded from base64 or read off a
|
|
81
63
|
// form may be a window onto a larger one.
|
package/dist/meshImport.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meshImport.js","sourceRoot":"","sources":["../src/meshImport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"meshImport.js","sourceRoot":"","sources":["../src/meshImport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAG5D,6EAA6E;AAC7E,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAMtE,2EAA2E;AAC3E,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,MAAM,MAAM,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACjD,OAAO,MAAM,IAAK,uBAA6C,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC9E,CAAC,CAAE,MAA+B;QAClC,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAgB,EAChB,KAAiB,EACjB,SAAkB;IAElB,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,kBAAkB,QAAQ,+BAA+B,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClH,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,KAAK,KAAK;QAC5B,CAAC,CAAC,oBAAoB,CAAC,QAAQ,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACjE,CAAC,CAAC,MAAM,KAAK,KAAK;YAChB,CAAC,CAAC,MAAM,0BAA0B,CAAC,QAAQ,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC7E,yEAAyE;YACzE,sEAAsE;YACtE,0CAA0C;YAC1C,CAAC,CAAC,oBAAoB,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,MAAqB,CAAC,CAAC;IAE1E,MAAM,KAAK,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAC9E,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mass properties of a triangle mesh, straight from its triangles (#508).
|
|
3
|
+
*
|
|
4
|
+
* Sewing an imported mesh into an OCCT solid only to ask the kernel for its
|
|
5
|
+
* volume took over a minute on a 57k-triangle STL, blocked every other call
|
|
6
|
+
* while it ran, and reported the answer as tessellated anyway. The divergence
|
|
7
|
+
* theorem gives the same numbers from the triangles in one pass.
|
|
8
|
+
*
|
|
9
|
+
* The mesh may hold several shells, and some of them may be voids. Each shell's
|
|
10
|
+
* triangles are first wound consistently with one another; whether the shell
|
|
11
|
+
* then counts as material or as a cavity is decided by how many other shells
|
|
12
|
+
* enclose it (even: material, odd: void), not by the file's winding, which
|
|
13
|
+
* imported meshes get wrong often enough that OCCT's path had to repair it.
|
|
14
|
+
* That reading needs the shells to nest; two bodies overlapping without one
|
|
15
|
+
* enclosing the other would have the overlap counted twice, so a mesh holding
|
|
16
|
+
* them gets no answer here (#529, see meshShellOverlap.ts).
|
|
17
|
+
*
|
|
18
|
+
* Only a mesh whose every shell is closed gets an answer. The signed volume of
|
|
19
|
+
* an open fragment depends on where the origin is, so there is no honest number
|
|
20
|
+
* to give for one; `null` sends the caller back to the kernel's sewing, which
|
|
21
|
+
* can close gaps this does not and refuses what it cannot close.
|
|
22
|
+
*
|
|
23
|
+
* Pure arithmetic, no kernel: safe to call from anywhere.
|
|
24
|
+
*/
|
|
25
|
+
import type { MeshData } from "./meshTransform.js";
|
|
26
|
+
export type MeshMassProperties = {
|
|
27
|
+
volume: number;
|
|
28
|
+
area: number;
|
|
29
|
+
centerOfMass: {
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
z: number;
|
|
33
|
+
};
|
|
34
|
+
bbox: {
|
|
35
|
+
xmin: number;
|
|
36
|
+
ymin: number;
|
|
37
|
+
zmin: number;
|
|
38
|
+
xmax: number;
|
|
39
|
+
ymax: number;
|
|
40
|
+
zmax: number;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* The mesh's mass properties, or `null` when its triangles do not bound a
|
|
45
|
+
* solid at any weld tolerance.
|
|
46
|
+
*
|
|
47
|
+
* Throws `MeshShellsOverlapError` when two of its closed bodies overlap without
|
|
48
|
+
* one enclosing the other (#529): adding them would count the overlap twice,
|
|
49
|
+
* and sewing them only for the kernel to refuse them held it for minutes on a
|
|
50
|
+
* large mesh, so the refusal comes from here.
|
|
51
|
+
*/
|
|
52
|
+
export declare function meshMassProperties(mesh: MeshData): MeshMassProperties | null;
|
|
53
|
+
/**
|
|
54
|
+
* Whether two of the mesh's closed shells overlap without one enclosing the
|
|
55
|
+
* other; `null` when the mesh does not close, so it has no shells to compare.
|
|
56
|
+
* Shells that only touch -- on a face, an edge or a corner -- do not overlap:
|
|
57
|
+
* what they share has no volume.
|
|
58
|
+
*/
|
|
59
|
+
export declare function meshShellsOverlap(mesh: MeshData): boolean | null;
|
|
60
|
+
/** One closed shell of a mesh, with its triangles wound as the mesh wound them. */
|
|
61
|
+
export type MeshSolidShell = {
|
|
62
|
+
/** Flat triangle corners in the mesh's own coordinates. */
|
|
63
|
+
positions: number[];
|
|
64
|
+
/** How many other shells enclose it: even is material, odd is a void. */
|
|
65
|
+
depth: number;
|
|
66
|
+
/**
|
|
67
|
+
* The volume it contributes to the mesh: positive for a body, negative for a
|
|
68
|
+
* void. Their sum is the mesh's own volume, which is what a solid assembled
|
|
69
|
+
* from the shells must come to if the nesting was read correctly.
|
|
70
|
+
*/
|
|
71
|
+
volume: number;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* The closed shells a mesh is made of, each with its nesting depth (#501).
|
|
75
|
+
*
|
|
76
|
+
* OCCT sews one shell into one solid; a mesh with a sealed internal void, or
|
|
77
|
+
* with several separate bodies, has more than one, and sewing them together
|
|
78
|
+
* fails. A caller builds each shell into a solid and puts them back together:
|
|
79
|
+
* material at even depth, voids at odd depth taken out of what encloses them.
|
|
80
|
+
* The winding is left alone, since the depth -- not the winding -- says which
|
|
81
|
+
* side is material, and the sewing orients each solid outward by itself.
|
|
82
|
+
*
|
|
83
|
+
* The shells are those of the first weld tolerance that closes the mesh, so
|
|
84
|
+
* their corners are the welded ones. Null unless every shell is closed and
|
|
85
|
+
* consistently orientable, because only then is the nesting well defined. A
|
|
86
|
+
* shell enclosing no volume is left out. Throws `MeshShellsOverlapError` when
|
|
87
|
+
* two shells overlap without nesting, since no nesting assembles them.
|
|
88
|
+
*/
|
|
89
|
+
export declare function meshSolidShells(mesh: MeshData): MeshSolidShell[] | null;
|
|
90
|
+
/** Flat triangle corners, as a stored mesh holds them, as `MeshData`. */
|
|
91
|
+
export declare function meshDataFromPositions(positions: readonly number[]): MeshData;
|
|
92
|
+
//# sourceMappingURL=meshMassProperties.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meshMassProperties.d.ts","sourceRoot":"","sources":["../src/meshMassProperties.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9F,CAAC;AAsBF;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,GAAG,kBAAkB,GAAG,IAAI,CAI5E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,IAAI,CAGhE;AAED,mFAAmF;AACnF,MAAM,MAAM,cAAc,GAAG;IAC3B,2DAA2D;IAC3D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc,EAAE,GAAG,IAAI,CAgBvE;AAED,yEAAyE;AACzE,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,CAY5E"}
|