forgecad 0.9.15 → 0.9.16
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/assets/{AdminPage-CDyGUinA.js → AdminPage-CXvls4-J.js} +1 -1
- package/dist/assets/{BenchmarkPage-DfPMY_-d.js → BenchmarkPage-B27zk8xL.js} +1 -1
- package/dist/assets/{BlogPage-kF0fkdJT.js → BlogPage-CMAVvgQL.js} +1 -1
- package/dist/assets/{DocsPage-B954L3YN.js → DocsPage-knf4I4h7.js} +1 -1
- package/dist/assets/EditorApp-BHMQlJ-D.js +14686 -0
- package/dist/assets/{EditorApp-CuDLxKqL.css → EditorApp-BpjZgzk0.css} +148 -0
- package/dist/assets/{EmbedViewer-C77B-TrF.js → EmbedViewer-D7ZGlFjx.js} +2 -2
- package/dist/assets/{LandingPageProofDriven-Cr6fXMDj.js → LandingPageProofDriven-CnevhTE8.js} +2 -2
- package/dist/assets/{LegalPage-Dzklqmmg.js → LegalPage-BPTUmqeg.js} +1 -1
- package/dist/assets/{PricingPage-zWXkvlwl.js → PricingPage-B0D4goG_.js} +1 -1
- package/dist/assets/{SettingsPage-Bz0of4KQ.js → SettingsPage-CFF-UgjI.js} +1 -1
- package/dist/assets/{app-D3kDkggg.js → app-T0pDcSX4.js} +1184 -218
- package/dist/assets/cli/{render-DSY3mMQa.js → render-C5pcIISc.js} +144 -26
- package/dist/assets/{constructionHistoryWorker-gpDo-uH2.js → constructionHistoryWorker-Ba2Hm58b.js} +1 -0
- package/dist/assets/{evalWorker-CU0Ke6DP.js → evalWorker-vkx310U2.js} +1380 -2173
- package/dist/assets/{inspectWorker-COyp8XXA.js → inspectWorker-BuTJDVX6.js} +252 -30
- package/dist/assets/{targets-B9sGB5nB.js → jointPose-B_Cgedn9.js} +71 -3
- package/dist/assets/{manifold-DNkrUWpA.js → manifold-BWgsjmAM.js} +1 -1
- package/dist/assets/{manifold-C-3h2M7p.js → manifold-D6IFSkhH.js} +2 -2
- package/dist/assets/{manifold-BRI5prcH.js → manifold-rZexZI0G.js} +1 -1
- package/dist/assets/{reportWorker-CdBz5bNg.js → reportWorker-0AGij1Ru.js} +1373 -2166
- package/dist/assets/{scalar-sampling-budget-wJF98aY9.js → scalar-sampling-budget-J5cuzxT1.js} +1494 -2251
- package/dist/assets/{scanProxyWorker-B-9VbLIs.js → scanProxyWorker-Vl4Wxa1y.js} +18 -5
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +1 -1
- package/dist/docs-raw/AI/usage.md +2 -0
- package/dist/docs-raw/CLI.md +4 -0
- package/dist/docs-raw/generated/assembly.md +104 -6
- package/dist/docs-raw/generated/concepts.md +14 -4
- package/dist/docs-raw/generated/lib.md +2 -18
- package/dist/docs-raw/generated/output.md +14 -4
- package/dist/docs-raw/generated/runtime-names.md +27 -19
- package/dist/docs-raw/skills/forgecad-make-a-model.md +39 -38
- package/dist/docs-raw/skills/forgecad-project.md +2 -0
- package/dist/docs-raw/welcome.md +2 -0
- package/dist/index.html +1 -1
- package/dist/sitemap.xml +13 -13
- package/dist-cli/{check-compiler-SDX5QIXI.js → check-compiler-SYQ2PWOB.js} +1 -1
- package/dist-cli/{check-query-propagation-EAYEFT77.js → check-query-propagation-HIAGV62W.js} +1 -1
- package/dist-cli/{chunk-N4O47JLF.js → chunk-SPZE3DUY.js} +1591 -2356
- package/dist-cli/forgecad.js +1698 -487
- package/dist-skill/CONTEXT.md +117 -46
- package/dist-skill/docs/CLI.md +4 -0
- package/dist-skill/docs/generated/assembly.md +83 -5
- package/dist-skill/docs/generated/lib.md +2 -18
- package/dist-skill/docs/generated/output.md +14 -4
- package/dist-skill/docs/generated/runtime-names.md +18 -19
- package/dist-skill/library/forgecad-make-a-model/SKILL.md +39 -38
- package/dist-skill/library/forgecad-project/SKILL.md +2 -0
- package/examples/api/helix-basics.forge.js +2 -2
- package/examples/api/route3d-elbow.forge.js +3 -0
- package/examples/api/variable-sweep-test.forge.js +3 -1
- package/package.json +4 -1
- package/dist/assets/EditorApp-Beb-IZ0y.js +0 -14014
- package/examples/api/bolted-service-cover.forge.js +0 -17
- package/examples/api/cable-gland-anchor.forge.js +0 -14
- package/examples/api/captured-cartridge-guide.forge.js +0 -14
- package/examples/api/captured-linear-slide.forge.js +0 -13
- package/examples/api/clevis-pin-joint.forge.js +0 -13
- package/examples/api/datum-enclosure.forge.js +0 -16
- package/examples/api/hose-barb-port.forge.js +0 -14
- package/examples/api/knuckled-hinge-assembly.forge.js +0 -15
- package/examples/api/living-hinge-cover.forge.js +0 -14
- package/examples/api/pcb-terminal-block.forge.js +0 -22
- package/examples/api/pinned-lever-pivot-stack.forge.js +0 -14
- package/examples/api/retained-shaft-knob-stack.forge.js +0 -15
- package/examples/api/routed-tube-clip.forge.js +0 -15
- package/examples/api/seated-bearing-stack.forge.js +0 -30
- package/examples/api/snap-latch-cover.forge.js +0 -14
- package/examples/api/thumb-screw-clamp.forge.js +0 -15
|
@@ -12589,6 +12589,7 @@ class Transform {
|
|
|
12589
12589
|
return this.rotateAxis([0, 0, 1], angleDeg, pivot);
|
|
12590
12590
|
}
|
|
12591
12591
|
/** Scale after the current transform. */
|
|
12592
|
+
// biome-ignore lint/suspicious/useAdjacentOverloadSignatures: Static Transform.scale() and chainable instance scale() intentionally share the CAD API name.
|
|
12592
12593
|
scale(v) {
|
|
12593
12594
|
return this.mul(Transform.scale(v));
|
|
12594
12595
|
}
|
|
@@ -30024,18 +30025,18 @@ function faceAxes(face) {
|
|
|
30024
30025
|
}
|
|
30025
30026
|
return {};
|
|
30026
30027
|
}
|
|
30027
|
-
function edgeKey$
|
|
30028
|
+
function edgeKey$2(start, end) {
|
|
30028
30029
|
const encode = (p2) => p2.map((value) => value.toFixed(9)).join(",");
|
|
30029
30030
|
const a2 = encode(start);
|
|
30030
30031
|
const b = encode(end);
|
|
30031
30032
|
return a2 < b ? `${a2}|${b}` : `${b}|${a2}`;
|
|
30032
30033
|
}
|
|
30033
30034
|
function faceEdgeIndex(face, start, end) {
|
|
30034
|
-
const target = edgeKey$
|
|
30035
|
+
const target = edgeKey$2(start, end);
|
|
30035
30036
|
for (let i = 0; i < face.vertices.length; i++) {
|
|
30036
30037
|
const faceStart = face.vertices[i];
|
|
30037
30038
|
const faceEnd = face.vertices[(i + 1) % face.vertices.length];
|
|
30038
|
-
if (faceStart && faceEnd && edgeKey$
|
|
30039
|
+
if (faceStart && faceEnd && edgeKey$2(faceStart, faceEnd) === target) return i;
|
|
30039
30040
|
}
|
|
30040
30041
|
return null;
|
|
30041
30042
|
}
|
|
@@ -30236,7 +30237,7 @@ function topologyPayloadToTopology(payload) {
|
|
|
30236
30237
|
const start = explicitVertices[explicitEdge.vertices[0]];
|
|
30237
30238
|
const end = explicitVertices[explicitEdge.vertices[1]];
|
|
30238
30239
|
if (!isVec3(start) || !isVec3(end)) continue;
|
|
30239
|
-
const key = edgeKey$
|
|
30240
|
+
const key = edgeKey$2(start, end);
|
|
30240
30241
|
if (seenEdges.has(key)) continue;
|
|
30241
30242
|
seenEdges.set(key, edges.size);
|
|
30242
30243
|
const display = explicitEdgeDisplayName(payload, explicitEdge, explicitEdgeIndex, start, end);
|
|
@@ -30256,7 +30257,7 @@ function topologyPayloadToTopology(payload) {
|
|
|
30256
30257
|
const start = face.vertices[i];
|
|
30257
30258
|
const end = face.vertices[(i + 1) % face.vertices.length];
|
|
30258
30259
|
if (!start || !end) continue;
|
|
30259
|
-
const key = edgeKey$
|
|
30260
|
+
const key = edgeKey$2(start, end);
|
|
30260
30261
|
if (seenEdges.has(key)) continue;
|
|
30261
30262
|
seenEdges.set(key, edges.size);
|
|
30262
30263
|
edges.set(`${face.id}:edge-${i}`, {
|
|
@@ -48788,6 +48789,92 @@ function percentile(sorted, q) {
|
|
|
48788
48789
|
const index2 = MathUtils.clamp(Math.floor(sorted.length * q), 0, sorted.length - 1);
|
|
48789
48790
|
return Number(sorted[index2].toFixed(2));
|
|
48790
48791
|
}
|
|
48792
|
+
class DisjointSet {
|
|
48793
|
+
constructor(size) {
|
|
48794
|
+
__publicField(this, "parent");
|
|
48795
|
+
__publicField(this, "rank");
|
|
48796
|
+
this.parent = Array.from({ length: size }, (_2, index2) => index2);
|
|
48797
|
+
this.rank = Array.from({ length: size }, () => 0);
|
|
48798
|
+
}
|
|
48799
|
+
find(index2) {
|
|
48800
|
+
const parent = this.parent[index2];
|
|
48801
|
+
if (parent === index2) return index2;
|
|
48802
|
+
const root = this.find(parent);
|
|
48803
|
+
this.parent[index2] = root;
|
|
48804
|
+
return root;
|
|
48805
|
+
}
|
|
48806
|
+
union(a2, b) {
|
|
48807
|
+
const rootA = this.find(a2);
|
|
48808
|
+
const rootB = this.find(b);
|
|
48809
|
+
if (rootA === rootB) return;
|
|
48810
|
+
if (this.rank[rootA] < this.rank[rootB]) {
|
|
48811
|
+
this.parent[rootA] = rootB;
|
|
48812
|
+
} else if (this.rank[rootA] > this.rank[rootB]) {
|
|
48813
|
+
this.parent[rootB] = rootA;
|
|
48814
|
+
} else {
|
|
48815
|
+
this.parent[rootB] = rootA;
|
|
48816
|
+
this.rank[rootA] += 1;
|
|
48817
|
+
}
|
|
48818
|
+
}
|
|
48819
|
+
}
|
|
48820
|
+
function connectedCoplanarSurfacePatches(triangles) {
|
|
48821
|
+
const snap = surfacePatchSnap(triangles);
|
|
48822
|
+
const planeKeys = triangles.map((triangle) => planeKey(triangle, snap));
|
|
48823
|
+
const edgeOwners = /* @__PURE__ */ new Map();
|
|
48824
|
+
const sets = new DisjointSet(triangles.length);
|
|
48825
|
+
triangles.forEach((triangle, index2) => {
|
|
48826
|
+
for (const key of triangleEdgeKeys(triangle, snap)) {
|
|
48827
|
+
const owners = edgeOwners.get(key);
|
|
48828
|
+
if (owners) {
|
|
48829
|
+
for (const owner of owners) {
|
|
48830
|
+
if (planeKeys[owner] === planeKeys[index2]) sets.union(owner, index2);
|
|
48831
|
+
}
|
|
48832
|
+
owners.push(index2);
|
|
48833
|
+
} else {
|
|
48834
|
+
edgeOwners.set(key, [index2]);
|
|
48835
|
+
}
|
|
48836
|
+
}
|
|
48837
|
+
});
|
|
48838
|
+
const patchByRoot = /* @__PURE__ */ new Map();
|
|
48839
|
+
triangles.forEach((triangle, index2) => {
|
|
48840
|
+
const root = sets.find(index2);
|
|
48841
|
+
const patch = patchByRoot.get(root) ?? { triangleIndexes: [], area: 0 };
|
|
48842
|
+
patch.triangleIndexes.push(index2);
|
|
48843
|
+
patch.area += triangle.area;
|
|
48844
|
+
patchByRoot.set(root, patch);
|
|
48845
|
+
});
|
|
48846
|
+
return [...patchByRoot.values()];
|
|
48847
|
+
}
|
|
48848
|
+
function surfacePatchSnap(triangles) {
|
|
48849
|
+
const bounds = new Box3();
|
|
48850
|
+
for (const triangle of triangles) {
|
|
48851
|
+
bounds.expandByPoint(triangle.a);
|
|
48852
|
+
bounds.expandByPoint(triangle.b);
|
|
48853
|
+
bounds.expandByPoint(triangle.c);
|
|
48854
|
+
}
|
|
48855
|
+
const size = bounds.getSize(new Vector3());
|
|
48856
|
+
return Math.max(1e-6, size.length() * 1e-8);
|
|
48857
|
+
}
|
|
48858
|
+
function planeKey(triangle, snap) {
|
|
48859
|
+
const normalSnap = 1e-6;
|
|
48860
|
+
const distance = triangle.normal.dot(triangle.a);
|
|
48861
|
+
return [
|
|
48862
|
+
Math.round(triangle.normal.x / normalSnap),
|
|
48863
|
+
Math.round(triangle.normal.y / normalSnap),
|
|
48864
|
+
Math.round(triangle.normal.z / normalSnap),
|
|
48865
|
+
Math.round(distance / snap)
|
|
48866
|
+
].join(",");
|
|
48867
|
+
}
|
|
48868
|
+
function triangleEdgeKeys(triangle, snap) {
|
|
48869
|
+
const vertices = [vertexKey$2(triangle.a, snap), vertexKey$2(triangle.b, snap), vertexKey$2(triangle.c, snap)];
|
|
48870
|
+
return [edgeKey$1(vertices[0], vertices[1]), edgeKey$1(vertices[1], vertices[2]), edgeKey$1(vertices[2], vertices[0])];
|
|
48871
|
+
}
|
|
48872
|
+
function vertexKey$2(point, snap) {
|
|
48873
|
+
return `${Math.round(point.x / snap)},${Math.round(point.y / snap)},${Math.round(point.z / snap)}`;
|
|
48874
|
+
}
|
|
48875
|
+
function edgeKey$1(a2, b) {
|
|
48876
|
+
return a2 < b ? `${a2}|${b}` : `${b}|${a2}`;
|
|
48877
|
+
}
|
|
48791
48878
|
const MIN_TRIANGLE_AREA = 1e-12;
|
|
48792
48879
|
const R2_ALPHA = 0.7548776662466927;
|
|
48793
48880
|
const R2_BETA = 0.5698402909980532;
|
|
@@ -48840,7 +48927,7 @@ function allocateAreaSampleCounts(triangles, maxSamples) {
|
|
|
48840
48927
|
return counts;
|
|
48841
48928
|
}
|
|
48842
48929
|
function sampleSurfaceTriangles(triangles, maxSamples) {
|
|
48843
|
-
const counts =
|
|
48930
|
+
const counts = allocateSurfacePatchSampleCounts(triangles, maxSamples);
|
|
48844
48931
|
const samples = [];
|
|
48845
48932
|
const position = new Vector3();
|
|
48846
48933
|
let sampleIndex = 0;
|
|
@@ -48865,6 +48952,35 @@ function sampleSurfaceTriangles(triangles, maxSamples) {
|
|
|
48865
48952
|
});
|
|
48866
48953
|
return samples;
|
|
48867
48954
|
}
|
|
48955
|
+
function allocateSurfacePatchSampleCounts(triangles, maxSamples) {
|
|
48956
|
+
const counts = new Array(triangles.length).fill(0);
|
|
48957
|
+
if (triangles.length === 0) return counts;
|
|
48958
|
+
const patches = connectedCoplanarSurfacePatches(triangles);
|
|
48959
|
+
const patchCounts = allocateAreaSampleCounts(
|
|
48960
|
+
patches.map((patch, index2) => {
|
|
48961
|
+
var _a3, _b3, _c2, _d2;
|
|
48962
|
+
return {
|
|
48963
|
+
index: index2,
|
|
48964
|
+
a: ((_a3 = triangles[patch.triangleIndexes[0]]) == null ? void 0 : _a3.a) ?? new Vector3(),
|
|
48965
|
+
b: ((_b3 = triangles[patch.triangleIndexes[0]]) == null ? void 0 : _b3.b) ?? new Vector3(),
|
|
48966
|
+
c: ((_c2 = triangles[patch.triangleIndexes[0]]) == null ? void 0 : _c2.c) ?? new Vector3(),
|
|
48967
|
+
normal: ((_d2 = triangles[patch.triangleIndexes[0]]) == null ? void 0 : _d2.normal) ?? new Vector3(0, 0, 1),
|
|
48968
|
+
area: patch.area
|
|
48969
|
+
};
|
|
48970
|
+
}),
|
|
48971
|
+
maxSamples
|
|
48972
|
+
);
|
|
48973
|
+
patches.forEach((patch, patchIndex) => {
|
|
48974
|
+
const patchBudget = patchCounts[patchIndex] ?? 0;
|
|
48975
|
+
if (patchBudget <= 0) return;
|
|
48976
|
+
const patchTriangles = patch.triangleIndexes.map((index2) => triangles[index2]);
|
|
48977
|
+
const localCounts = allocateAreaSampleCounts(patchTriangles, patchBudget);
|
|
48978
|
+
patch.triangleIndexes.forEach((triangleIndex, localIndex) => {
|
|
48979
|
+
counts[triangleIndex] += localCounts[localIndex] ?? 0;
|
|
48980
|
+
});
|
|
48981
|
+
});
|
|
48982
|
+
return counts;
|
|
48983
|
+
}
|
|
48868
48984
|
function totalSurfaceArea(triangles) {
|
|
48869
48985
|
return triangles.reduce((sum2, triangle) => sum2 + triangle.area, 0);
|
|
48870
48986
|
}
|
|
@@ -49045,16 +49161,23 @@ const DEFAULT_THICKNESS_INSPECTION_OPTIONS = {
|
|
|
49045
49161
|
minThickness: 1.2,
|
|
49046
49162
|
warnThickness: 2,
|
|
49047
49163
|
maxThickness: 6,
|
|
49164
|
+
colorMinThickness: 0,
|
|
49165
|
+
colorMaxThickness: 6,
|
|
49048
49166
|
maxSamplesPerObject: 5e3,
|
|
49049
49167
|
contactTolerance: DEFAULT_PHYSICAL_CONNECTIVITY_OPTIONS.contactTolerance
|
|
49050
49168
|
};
|
|
49051
49169
|
const THICKNESS_COLORS = {
|
|
49052
49170
|
critical: [255, 28, 28],
|
|
49053
|
-
warning: [255, 150, 0],
|
|
49054
49171
|
ok: [60, 220, 90],
|
|
49055
49172
|
thick: [70, 145, 255],
|
|
49056
49173
|
unknown: [90, 90, 90]
|
|
49057
49174
|
};
|
|
49175
|
+
const THICKNESS_GRADIENT_COLORS = [
|
|
49176
|
+
THICKNESS_COLORS.critical,
|
|
49177
|
+
[255, 222, 0],
|
|
49178
|
+
THICKNESS_COLORS.ok,
|
|
49179
|
+
THICKNESS_COLORS.thick
|
|
49180
|
+
];
|
|
49058
49181
|
function finitePositive(value, fallback, label) {
|
|
49059
49182
|
if (value === void 0) return fallback;
|
|
49060
49183
|
if (!Number.isFinite(value) || value <= 0) {
|
|
@@ -49073,6 +49196,16 @@ function resolveThicknessInspectionOptions(raw = {}) {
|
|
|
49073
49196
|
const minThickness = finitePositive(raw.minThickness, DEFAULT_THICKNESS_INSPECTION_OPTIONS.minThickness, "minThickness");
|
|
49074
49197
|
const warnThickness = finitePositive(raw.warnThickness, DEFAULT_THICKNESS_INSPECTION_OPTIONS.warnThickness, "warnThickness");
|
|
49075
49198
|
const maxThickness = finitePositive(raw.maxThickness, DEFAULT_THICKNESS_INSPECTION_OPTIONS.maxThickness, "maxThickness");
|
|
49199
|
+
const colorMinThickness = finiteNonNegative(
|
|
49200
|
+
raw.colorMinThickness,
|
|
49201
|
+
DEFAULT_THICKNESS_INSPECTION_OPTIONS.colorMinThickness,
|
|
49202
|
+
"colorMinThickness"
|
|
49203
|
+
);
|
|
49204
|
+
const colorMaxThickness = finitePositive(
|
|
49205
|
+
raw.colorMaxThickness,
|
|
49206
|
+
DEFAULT_THICKNESS_INSPECTION_OPTIONS.colorMaxThickness,
|
|
49207
|
+
"colorMaxThickness"
|
|
49208
|
+
);
|
|
49076
49209
|
const maxSamplesPerObject = finitePositive(
|
|
49077
49210
|
raw.maxSamplesPerObject,
|
|
49078
49211
|
DEFAULT_THICKNESS_INSPECTION_OPTIONS.maxSamplesPerObject,
|
|
@@ -49089,10 +49222,15 @@ function resolveThicknessInspectionOptions(raw = {}) {
|
|
|
49089
49222
|
if (warnThickness > maxThickness) {
|
|
49090
49223
|
throw new Error("warnThickness must be less than or equal to maxThickness.");
|
|
49091
49224
|
}
|
|
49225
|
+
if (colorMinThickness >= colorMaxThickness) {
|
|
49226
|
+
throw new Error("colorMinThickness must be less than colorMaxThickness.");
|
|
49227
|
+
}
|
|
49092
49228
|
return {
|
|
49093
49229
|
minThickness,
|
|
49094
49230
|
warnThickness,
|
|
49095
49231
|
maxThickness,
|
|
49232
|
+
colorMinThickness,
|
|
49233
|
+
colorMaxThickness,
|
|
49096
49234
|
maxSamplesPerObject: Math.max(1, Math.floor(maxSamplesPerObject)),
|
|
49097
49235
|
contactTolerance
|
|
49098
49236
|
};
|
|
@@ -49103,6 +49241,16 @@ function lerp$1(a2, b, t) {
|
|
|
49103
49241
|
function lerpColor(a2, b, t) {
|
|
49104
49242
|
return [Math.round(lerp$1(a2[0], b[0], t)), Math.round(lerp$1(a2[1], b[1], t)), Math.round(lerp$1(a2[2], b[2], t))];
|
|
49105
49243
|
}
|
|
49244
|
+
function gradientColor(stops, t) {
|
|
49245
|
+
if (stops.length === 0) return THICKNESS_COLORS.unknown;
|
|
49246
|
+
if (stops.length === 1) return stops[0] ?? THICKNESS_COLORS.unknown;
|
|
49247
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
49248
|
+
const scaled = clamped * (stops.length - 1);
|
|
49249
|
+
const leftIndex = Math.min(stops.length - 2, Math.floor(scaled));
|
|
49250
|
+
const left = stops[leftIndex] ?? THICKNESS_COLORS.unknown;
|
|
49251
|
+
const right = stops[leftIndex + 1] ?? left;
|
|
49252
|
+
return lerpColor(left, right, scaled - leftIndex);
|
|
49253
|
+
}
|
|
49106
49254
|
function thicknessClass(thickness, options) {
|
|
49107
49255
|
if (thickness == null || !Number.isFinite(thickness) || thickness <= 0) return "unknown";
|
|
49108
49256
|
if (thickness <= options.minThickness) return "critical";
|
|
@@ -49111,18 +49259,9 @@ function thicknessClass(thickness, options) {
|
|
|
49111
49259
|
return "thick";
|
|
49112
49260
|
}
|
|
49113
49261
|
function thicknessColor(thickness, options) {
|
|
49114
|
-
|
|
49115
|
-
|
|
49116
|
-
|
|
49117
|
-
if (cls === "warning") {
|
|
49118
|
-
const span = Math.max(1e-9, options.warnThickness - options.minThickness);
|
|
49119
|
-
return lerpColor(THICKNESS_COLORS.critical, THICKNESS_COLORS.warning, ((thickness ?? 0) - options.minThickness) / span);
|
|
49120
|
-
}
|
|
49121
|
-
if (cls === "ok") {
|
|
49122
|
-
const span = Math.max(1e-9, options.maxThickness - options.warnThickness);
|
|
49123
|
-
return lerpColor(THICKNESS_COLORS.ok, THICKNESS_COLORS.thick, ((thickness ?? 0) - options.warnThickness) / span);
|
|
49124
|
-
}
|
|
49125
|
-
return THICKNESS_COLORS.thick;
|
|
49262
|
+
if (thickness == null || !Number.isFinite(thickness) || thickness <= 0) return THICKNESS_COLORS.unknown;
|
|
49263
|
+
const span = Math.max(1e-9, options.colorMaxThickness - options.colorMinThickness);
|
|
49264
|
+
return gradientColor(THICKNESS_GRADIENT_COLORS, (thickness - options.colorMinThickness) / span);
|
|
49126
49265
|
}
|
|
49127
49266
|
function cloneGeometryForFaceColors(geometry) {
|
|
49128
49267
|
return geometry.index ? geometry.toNonIndexed() : geometry.clone();
|
|
@@ -49986,7 +50125,7 @@ for (let radius = 0; radius <= MAX_SEARCH_RADIUS; radius += 1) {
|
|
|
49986
50125
|
function gridKey(x2, y2, z2) {
|
|
49987
50126
|
return `${x2},${y2},${z2}`;
|
|
49988
50127
|
}
|
|
49989
|
-
function
|
|
50128
|
+
function buildInspectHeatmapFieldBounds(geometry) {
|
|
49990
50129
|
const position = geometry.getAttribute("position");
|
|
49991
50130
|
if (!position || position.count === 0) return null;
|
|
49992
50131
|
const bounds = new Box3().setFromBufferAttribute(position);
|
|
@@ -49994,7 +50133,11 @@ function buildGeometryBounds(geometry) {
|
|
|
49994
50133
|
const size = bounds.getSize(new Vector3());
|
|
49995
50134
|
const pad = Math.max(size.x, size.y, size.z, 1) * 1e-5;
|
|
49996
50135
|
bounds.expandByScalar(pad);
|
|
49997
|
-
|
|
50136
|
+
const boundsSize = bounds.getSize(new Vector3());
|
|
50137
|
+
return {
|
|
50138
|
+
boundsMin: [bounds.min.x, bounds.min.y, bounds.min.z],
|
|
50139
|
+
boundsSize: [boundsSize.x, boundsSize.y, boundsSize.z]
|
|
50140
|
+
};
|
|
49998
50141
|
}
|
|
49999
50142
|
function buildSampleGrid(pointCloud) {
|
|
50000
50143
|
const sampleCount = Math.floor(pointCloud.positions.length / 3);
|
|
@@ -50078,11 +50221,15 @@ function blendedColorAt(point, pointCloud, sampleGrid) {
|
|
|
50078
50221
|
return [r / weightSum, g2 / weightSum, b / weightSum];
|
|
50079
50222
|
}
|
|
50080
50223
|
function buildInspectHeatmapFieldData(geometry, pointCloud) {
|
|
50081
|
-
const bounds =
|
|
50224
|
+
const bounds = buildInspectHeatmapFieldBounds(geometry);
|
|
50225
|
+
return bounds ? buildInspectHeatmapFieldDataFromBounds(bounds, pointCloud) : null;
|
|
50226
|
+
}
|
|
50227
|
+
function buildInspectHeatmapFieldDataFromBounds(bounds, pointCloud) {
|
|
50082
50228
|
const sampleGrid = buildSampleGrid(pointCloud);
|
|
50083
50229
|
if (!bounds || !sampleGrid) return null;
|
|
50084
50230
|
const gridSize = fieldGridSizeForSampleCount(Math.floor(pointCloud.positions.length / 3));
|
|
50085
|
-
const
|
|
50231
|
+
const boundsMin = new Vector3(...bounds.boundsMin);
|
|
50232
|
+
const boundsSize = new Vector3(...bounds.boundsSize);
|
|
50086
50233
|
const data = new Uint8Array(gridSize * gridSize * gridSize * 4);
|
|
50087
50234
|
const point = new Vector3();
|
|
50088
50235
|
let dataOffset = 0;
|
|
@@ -50090,9 +50237,9 @@ function buildInspectHeatmapFieldData(geometry, pointCloud) {
|
|
|
50090
50237
|
for (let z2 = 0; z2 < gridSize; z2 += 1) {
|
|
50091
50238
|
for (let x2 = 0; x2 < gridSize; x2 += 1) {
|
|
50092
50239
|
point.set(
|
|
50093
|
-
|
|
50094
|
-
|
|
50095
|
-
|
|
50240
|
+
boundsMin.x + boundsSize.x * x2 / (gridSize - 1),
|
|
50241
|
+
boundsMin.y + boundsSize.y * y2 / (gridSize - 1),
|
|
50242
|
+
boundsMin.z + boundsSize.z * z2 / (gridSize - 1)
|
|
50096
50243
|
);
|
|
50097
50244
|
const [r, g2, b] = blendedColorAt(point, pointCloud, sampleGrid);
|
|
50098
50245
|
data[dataOffset] = Math.max(0, Math.min(255, Math.round(r)));
|
|
@@ -50105,13 +50252,14 @@ function buildInspectHeatmapFieldData(geometry, pointCloud) {
|
|
|
50105
50252
|
}
|
|
50106
50253
|
return {
|
|
50107
50254
|
data,
|
|
50108
|
-
boundsMin:
|
|
50255
|
+
boundsMin: bounds.boundsMin,
|
|
50109
50256
|
boundsSize: [boundsSize.x, boundsSize.y, boundsSize.z],
|
|
50110
50257
|
gridSize
|
|
50111
50258
|
};
|
|
50112
50259
|
}
|
|
50113
50260
|
const workerScope = self;
|
|
50114
50261
|
let manifoldReadyPromise = null;
|
|
50262
|
+
let cachedThicknessColorizeAnalysis = null;
|
|
50115
50263
|
function ensureManifoldReady() {
|
|
50116
50264
|
if (!manifoldReadyPromise) manifoldReadyPromise = initKernelManifoldOnly();
|
|
50117
50265
|
return manifoldReadyPromise;
|
|
@@ -50157,6 +50305,7 @@ function geometryFromPositions(positions) {
|
|
|
50157
50305
|
function pointBuffers(samples) {
|
|
50158
50306
|
const positions = new Float32Array(samples.length * 3);
|
|
50159
50307
|
const colors = new Float32Array(samples.length * 3);
|
|
50308
|
+
const values = new Float32Array(samples.length);
|
|
50160
50309
|
samples.forEach((sample, index2) => {
|
|
50161
50310
|
const base = index2 * 3;
|
|
50162
50311
|
positions[base] = sample.position[0] + sample.normal[0] * 0.025;
|
|
@@ -50165,8 +50314,9 @@ function pointBuffers(samples) {
|
|
|
50165
50314
|
colors[base] = sample.color[0] / 255;
|
|
50166
50315
|
colors[base + 1] = sample.color[1] / 255;
|
|
50167
50316
|
colors[base + 2] = sample.color[2] / 255;
|
|
50317
|
+
values[index2] = sample.value ?? Number.NaN;
|
|
50168
50318
|
});
|
|
50169
|
-
return { positions, colors };
|
|
50319
|
+
return { positions, colors, values };
|
|
50170
50320
|
}
|
|
50171
50321
|
function rgbFloatsForHex(hex) {
|
|
50172
50322
|
const color = new Color(hex);
|
|
@@ -50191,6 +50341,7 @@ function analyzeScalarChannel(request) {
|
|
|
50191
50341
|
const pointObjects = [];
|
|
50192
50342
|
const heatmapFieldObjects = [];
|
|
50193
50343
|
const warnings = [];
|
|
50344
|
+
const thicknessCacheObjects = [];
|
|
50194
50345
|
for (const object of request.objects) {
|
|
50195
50346
|
if (!object.positions || object.positions.length < 9) continue;
|
|
50196
50347
|
const geometry = geometryFromPositions(object.positions);
|
|
@@ -50198,13 +50349,22 @@ function analyzeScalarChannel(request) {
|
|
|
50198
50349
|
const analysis = request.channel === "thickness" ? analyzeThicknessGeometry(geometry, request.thickness) : analyzeRoughnessGeometry(geometry, request.roughness);
|
|
50199
50350
|
analysis.warnings.forEach((warning) => warnings.push(`${object.name}: ${warning}`));
|
|
50200
50351
|
const buffers = pointBuffers(analysis.pointSamples);
|
|
50201
|
-
const
|
|
50352
|
+
const heatmapBounds = buildInspectHeatmapFieldBounds(analysis.geometry);
|
|
50353
|
+
const field = heatmapBounds ? buildInspectHeatmapFieldDataFromBounds(heatmapBounds, buffers) : buildInspectHeatmapFieldData(analysis.geometry, buffers);
|
|
50202
50354
|
if (field) {
|
|
50203
50355
|
heatmapFieldObjects.push({
|
|
50204
50356
|
objectId: object.id,
|
|
50205
50357
|
...field
|
|
50206
50358
|
});
|
|
50207
50359
|
}
|
|
50360
|
+
if (request.channel === "thickness" && buffers.values) {
|
|
50361
|
+
thicknessCacheObjects.push({
|
|
50362
|
+
objectId: object.id,
|
|
50363
|
+
positions: new Float32Array(buffers.positions),
|
|
50364
|
+
values: new Float32Array(buffers.values),
|
|
50365
|
+
heatmapBounds
|
|
50366
|
+
});
|
|
50367
|
+
}
|
|
50208
50368
|
pointObjects.push({
|
|
50209
50369
|
objectId: object.id,
|
|
50210
50370
|
sampleCount: analysis.pointSamples.length,
|
|
@@ -50215,7 +50375,9 @@ function analyzeScalarChannel(request) {
|
|
|
50215
50375
|
geometry.dispose();
|
|
50216
50376
|
}
|
|
50217
50377
|
}
|
|
50378
|
+
cachedThicknessColorizeAnalysis = request.channel === "thickness" ? { analysisId: request.reqId, objects: thicknessCacheObjects } : null;
|
|
50218
50379
|
return {
|
|
50380
|
+
analysisId: request.reqId,
|
|
50219
50381
|
channel: request.channel,
|
|
50220
50382
|
objectColors: {},
|
|
50221
50383
|
pointObjects,
|
|
@@ -50225,6 +50387,47 @@ function analyzeScalarChannel(request) {
|
|
|
50225
50387
|
warnings
|
|
50226
50388
|
};
|
|
50227
50389
|
}
|
|
50390
|
+
function thicknessColorsForValues(values, colorMinThickness, colorMaxThickness) {
|
|
50391
|
+
const options = resolveThicknessInspectionOptions({ colorMinThickness, colorMaxThickness });
|
|
50392
|
+
const colors = new Float32Array(values.length * 3);
|
|
50393
|
+
for (let index2 = 0; index2 < values.length; index2 += 1) {
|
|
50394
|
+
const color = thicknessColor(values[index2], options);
|
|
50395
|
+
const offset = index2 * 3;
|
|
50396
|
+
colors[offset] = color[0] / 255;
|
|
50397
|
+
colors[offset + 1] = color[1] / 255;
|
|
50398
|
+
colors[offset + 2] = color[2] / 255;
|
|
50399
|
+
}
|
|
50400
|
+
return colors;
|
|
50401
|
+
}
|
|
50402
|
+
function colorizeThicknessAnalysis(request) {
|
|
50403
|
+
const cached = cachedThicknessColorizeAnalysis;
|
|
50404
|
+
if (!cached || cached.analysisId !== request.analysisId) {
|
|
50405
|
+
throw new Error("Thickness colorize cache is no longer available.");
|
|
50406
|
+
}
|
|
50407
|
+
const pointObjects = [];
|
|
50408
|
+
const heatmapFieldObjects = [];
|
|
50409
|
+
for (const object of cached.objects) {
|
|
50410
|
+
const colors = thicknessColorsForValues(object.values, request.colorMinThickness, request.colorMaxThickness);
|
|
50411
|
+
pointObjects.push({ objectId: object.objectId, colors });
|
|
50412
|
+
if (object.heatmapBounds) {
|
|
50413
|
+
const field = buildInspectHeatmapFieldDataFromBounds(object.heatmapBounds, {
|
|
50414
|
+
positions: object.positions,
|
|
50415
|
+
colors
|
|
50416
|
+
});
|
|
50417
|
+
if (field) {
|
|
50418
|
+
heatmapFieldObjects.push({
|
|
50419
|
+
objectId: object.objectId,
|
|
50420
|
+
...field
|
|
50421
|
+
});
|
|
50422
|
+
}
|
|
50423
|
+
}
|
|
50424
|
+
}
|
|
50425
|
+
return {
|
|
50426
|
+
analysisId: cached.analysisId,
|
|
50427
|
+
pointObjects,
|
|
50428
|
+
heatmapFieldObjects
|
|
50429
|
+
};
|
|
50430
|
+
}
|
|
50228
50431
|
function analyzeConnectivityChannel(request) {
|
|
50229
50432
|
const bodyInput = buildMeshBodyConnectivityInput(
|
|
50230
50433
|
request.objects.map((object) => ({
|
|
@@ -50391,7 +50594,11 @@ function analyzeCollisionChannel(request) {
|
|
|
50391
50594
|
}
|
|
50392
50595
|
function transferFor(result) {
|
|
50393
50596
|
return [
|
|
50394
|
-
...result.pointObjects.flatMap((object) => [
|
|
50597
|
+
...result.pointObjects.flatMap((object) => [
|
|
50598
|
+
object.positions.buffer,
|
|
50599
|
+
object.colors.buffer,
|
|
50600
|
+
...object.values ? [object.values.buffer] : []
|
|
50601
|
+
]),
|
|
50395
50602
|
...result.meshColorObjects.map((object) => object.colors.buffer),
|
|
50396
50603
|
...result.heatmapFieldObjects.map((object) => object.data.buffer),
|
|
50397
50604
|
...result.collisionGeometryObjects.flatMap((object) => [object.positions.buffer, object.normals.buffer, object.edgePositions.buffer])
|
|
@@ -50399,6 +50606,21 @@ function transferFor(result) {
|
|
|
50399
50606
|
}
|
|
50400
50607
|
async function handleRequest(request) {
|
|
50401
50608
|
try {
|
|
50609
|
+
if (request.type === "colorize-thickness") {
|
|
50610
|
+
const result2 = colorizeThicknessAnalysis(request.payload);
|
|
50611
|
+
const response2 = {
|
|
50612
|
+
type: "inspect-colorize-success",
|
|
50613
|
+
payload: {
|
|
50614
|
+
reqId: request.payload.reqId,
|
|
50615
|
+
result: result2
|
|
50616
|
+
}
|
|
50617
|
+
};
|
|
50618
|
+
workerScope.postMessage(response2, [
|
|
50619
|
+
...result2.pointObjects.map((object) => object.colors.buffer),
|
|
50620
|
+
...result2.heatmapFieldObjects.map((object) => object.data.buffer)
|
|
50621
|
+
]);
|
|
50622
|
+
return;
|
|
50623
|
+
}
|
|
50402
50624
|
if (request.payload.channel === "collisions") await ensureManifoldReady();
|
|
50403
50625
|
const result = request.payload.channel === "thickness" || request.payload.channel === "roughness" ? analyzeScalarChannel(request.payload) : request.payload.channel === "collisions" ? analyzeCollisionChannel(request.payload) : analyzeConnectivityChannel(request.payload);
|
|
50404
50626
|
const response = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c1 as parseViewportCameraState } from "./scalar-sampling-budget-J5cuzxT1.js";
|
|
2
2
|
const roundNumber = (value, digits) => {
|
|
3
3
|
const scale = 10 ** digits;
|
|
4
4
|
return Math.round(value * scale) / scale;
|
|
@@ -148,10 +148,78 @@ function getSceneObjectKind(object) {
|
|
|
148
148
|
if (object.shape) return "shape";
|
|
149
149
|
return "object";
|
|
150
150
|
}
|
|
151
|
+
function hasJointOverrides(overrides) {
|
|
152
|
+
return Boolean(overrides && Object.keys(overrides).length > 0);
|
|
153
|
+
}
|
|
154
|
+
function resolveJointSliderRange(joint) {
|
|
155
|
+
return {
|
|
156
|
+
min: joint.min ?? (joint.type === "prismatic" ? -100 : 0),
|
|
157
|
+
max: joint.max ?? (joint.type === "prismatic" ? 100 : 360)
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function editableJointNames(view) {
|
|
161
|
+
const coupledTargets = new Set(view.couplings.map((coupling) => coupling.joint));
|
|
162
|
+
return view.joints.filter((joint) => !joint.hidden && !coupledTargets.has(joint.name)).map((joint) => joint.name);
|
|
163
|
+
}
|
|
164
|
+
function availableText(names) {
|
|
165
|
+
return names.length > 0 ? names.join(", ") : "(none)";
|
|
166
|
+
}
|
|
167
|
+
function validateJointOverrides(view, overrides, flag = "--joint") {
|
|
168
|
+
var _a;
|
|
169
|
+
if (!hasJointOverrides(overrides)) return;
|
|
170
|
+
if (!view || view.enabled === false || view.joints.length === 0) {
|
|
171
|
+
throw new Error(`${flag} requires a Forge script that exposes Motion tab joints. Available joints: (none).`);
|
|
172
|
+
}
|
|
173
|
+
const jointsByName = new Map(view.joints.map((joint) => [joint.name, joint]));
|
|
174
|
+
const coupledTargets = new Set(view.couplings.map((coupling) => coupling.joint));
|
|
175
|
+
const available = editableJointNames(view);
|
|
176
|
+
for (const [name, value] of Object.entries(overrides)) {
|
|
177
|
+
const joint = jointsByName.get(name);
|
|
178
|
+
if (!joint) {
|
|
179
|
+
throw new Error(`Unknown joint "${name}" for ${flag}. Available editable joints: ${availableText(available)}.`);
|
|
180
|
+
}
|
|
181
|
+
if (joint.hidden) {
|
|
182
|
+
throw new Error(`Joint "${name}" is hidden and cannot be set with ${flag}. Available editable joints: ${availableText(available)}.`);
|
|
183
|
+
}
|
|
184
|
+
if (coupledTargets.has(name)) {
|
|
185
|
+
const drivers = (_a = view.couplings.find((coupling) => coupling.joint === name)) == null ? void 0 : _a.terms.map((term) => term.joint).join(", ");
|
|
186
|
+
throw new Error(
|
|
187
|
+
`Joint "${name}" is driven by a coupling and cannot be set with ${flag}.` + (drivers ? ` Set driver joint(s): ${drivers}.` : ` Available editable joints: ${availableText(available)}.`)
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
const { min, max } = resolveJointSliderRange(joint);
|
|
191
|
+
if (value < min || value > max) {
|
|
192
|
+
throw new Error(`Joint "${name}" value ${value} is outside Motion tab range [${min}, ${max}].`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function buildBaseJointValues(joints, overrides = {}) {
|
|
197
|
+
const values = {};
|
|
198
|
+
joints.forEach((joint) => {
|
|
199
|
+
values[joint.name] = overrides[joint.name] ?? joint.defaultValue;
|
|
200
|
+
});
|
|
201
|
+
return values;
|
|
202
|
+
}
|
|
203
|
+
function formatJointNumber(value) {
|
|
204
|
+
const rounded = Number(value.toFixed(6));
|
|
205
|
+
return Object.is(rounded, -0) ? "0" : String(rounded);
|
|
206
|
+
}
|
|
207
|
+
function quoteForCli(value) {
|
|
208
|
+
return `"${value.replace(/(["\\$`])/g, "\\$1")}"`;
|
|
209
|
+
}
|
|
210
|
+
function formatCliJointPoseFlags(joints, displayedValues, coupledJointNames) {
|
|
211
|
+
return joints.filter((joint) => !joint.hidden && !coupledJointNames.has(joint.name)).map((joint) => {
|
|
212
|
+
const value = displayedValues[joint.name] ?? joint.defaultValue;
|
|
213
|
+
return `--joint ${quoteForCli(`${joint.name}=${formatJointNumber(value)}`)}`;
|
|
214
|
+
}).join(" ");
|
|
215
|
+
}
|
|
151
216
|
export {
|
|
152
217
|
getSceneObjectKind as a,
|
|
153
|
-
|
|
218
|
+
buildBaseJointValues as b,
|
|
219
|
+
formatRenderSceneCliSpec as c,
|
|
220
|
+
formatCliJointPoseFlags as f,
|
|
154
221
|
getSceneObjectTreePath as g,
|
|
155
222
|
mergeViewportRenderSceneStates as m,
|
|
156
|
-
parseRenderSceneCliSpec as p
|
|
223
|
+
parseRenderSceneCliSpec as p,
|
|
224
|
+
validateJointOverrides as v
|
|
157
225
|
};
|
|
@@ -12,7 +12,7 @@ var Module = (() => {
|
|
|
12
12
|
var ENVIRONMENT_IS_WORKER = typeof WorkerGlobalScope != "undefined";
|
|
13
13
|
var ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string" && process.type != "renderer";
|
|
14
14
|
if (ENVIRONMENT_IS_NODE) {
|
|
15
|
-
const { createRequire } = await import("./evalWorker-
|
|
15
|
+
const { createRequire } = await import("./evalWorker-vkx310U2.js").then(function(n) {
|
|
16
16
|
return n._;
|
|
17
17
|
});
|
|
18
18
|
var require2 = createRequire(import.meta.url);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as __vitePreload } from "./scalar-sampling-budget-
|
|
1
|
+
import { _ as __vitePreload } from "./scalar-sampling-budget-J5cuzxT1.js";
|
|
2
2
|
var Module = (() => {
|
|
3
3
|
var _scriptName = import.meta.url;
|
|
4
4
|
return (async function(moduleArg = {}) {
|
|
@@ -14,7 +14,7 @@ var Module = (() => {
|
|
|
14
14
|
var ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string" && process.type != "renderer";
|
|
15
15
|
if (ENVIRONMENT_IS_NODE) {
|
|
16
16
|
const { createRequire } = await __vitePreload(async () => {
|
|
17
|
-
const { createRequire: createRequire2 } = await import("./scalar-sampling-budget-
|
|
17
|
+
const { createRequire: createRequire2 } = await import("./scalar-sampling-budget-J5cuzxT1.js").then((n) => n.dg);
|
|
18
18
|
return { createRequire: createRequire2 };
|
|
19
19
|
}, true ? [] : void 0);
|
|
20
20
|
var require2 = createRequire(import.meta.url);
|
|
@@ -12,7 +12,7 @@ var Module = (() => {
|
|
|
12
12
|
var ENVIRONMENT_IS_WORKER = typeof WorkerGlobalScope != "undefined";
|
|
13
13
|
var ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string" && process.type != "renderer";
|
|
14
14
|
if (ENVIRONMENT_IS_NODE) {
|
|
15
|
-
const { createRequire } = await import("./reportWorker-
|
|
15
|
+
const { createRequire } = await import("./reportWorker-0AGij1Ru.js").then(function(n) {
|
|
16
16
|
return n._;
|
|
17
17
|
});
|
|
18
18
|
var require2 = createRequire(import.meta.url);
|