brepjs-verify 0.4.0 → 0.13.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/CHANGELOG.md +223 -0
- package/README.md +55 -25
- package/dist/brepjs-verify.cjs +1 -1
- package/dist/brepjs-verify.js +1 -1
- package/dist/cli/main.cjs +42 -3
- package/dist/cli/main.js +42 -3
- package/dist/cli/openBrowser.d.ts +23 -0
- package/dist/{diff-BNmCp_8I.cjs → diff-3ivpxBET.cjs} +83 -10
- package/dist/{diff-D5U3Ie2F.js → diff-DyilrTFJ.js} +83 -10
- package/dist/index.d.ts +1 -1
- package/dist/mcp/server.cjs +489 -0
- package/dist/mcp/server.d.ts +10 -0
- package/dist/mcp/server.js +489 -0
- package/dist/mcp/tools.d.ts +77 -0
- package/dist/sandbox/runProgram.d.ts +76 -0
- package/dist/sandbox/runRecord.d.ts +20 -0
- package/dist/snapshot/shoot.cjs +2 -1
- package/dist/snapshot/shoot.d.ts +2 -0
- package/dist/snapshot/shoot.js +2 -1
- package/dist/verify/report.d.ts +13 -0
- package/package.json +12 -11
- package/viewer/dist/assets/brepjs-cDw_z4Rj.js +60 -0
- package/viewer/dist/assets/index-BBdw65cO.js +4167 -0
- package/viewer/dist/assets/kernelWorker-DeA3Hcd0.js +1 -0
- package/viewer/dist/index.html +1 -1
- package/viewer/dist/wasm/occt-wasm.wasm +0 -0
- package/viewer/dist/assets/brepjs-CI5VXw8W.js +0 -57
- package/viewer/dist/assets/index-CiN0lKoi.js +0 -4167
- package/viewer/dist/assets/kernelWorker-BtcMpY8t.js +0 -1
|
@@ -261,7 +261,7 @@ function shapeTypeOf(brep, s) {
|
|
|
261
261
|
return "Unknown";
|
|
262
262
|
}
|
|
263
263
|
function runChecks(brep, shape) {
|
|
264
|
-
const { isSolid, isShape3D, isFace,
|
|
264
|
+
const { isSolid, isShape3D, isFace, measureVolumeProps, measureArea, getBounds, getFaces, getEdges, getWires, getVertices, getSolids, getShells, isManifoldShell, validSolid, isOk } = brep;
|
|
265
265
|
const r = emptyReport();
|
|
266
266
|
r.shapeType = shapeTypeOf(brep, shape);
|
|
267
267
|
if (isSolid(shape)) {
|
|
@@ -278,19 +278,41 @@ function runChecks(brep, shape) {
|
|
|
278
278
|
});
|
|
279
279
|
}
|
|
280
280
|
r.checks.push(validCheck);
|
|
281
|
+
} else {
|
|
282
|
+
const solids = getSolids(shape);
|
|
283
|
+
if (solids.length > 0) {
|
|
284
|
+
const failures = [];
|
|
285
|
+
solids.forEach((s, i) => {
|
|
286
|
+
const v = validSolid(s);
|
|
287
|
+
if (!isOk(v)) failures.push(`body ${i}: ${v.error}`);
|
|
288
|
+
});
|
|
289
|
+
const bodiesCheck = {
|
|
290
|
+
name: "allBodiesValid",
|
|
291
|
+
passed: failures.length === 0
|
|
292
|
+
};
|
|
293
|
+
if (failures.length > 0) {
|
|
294
|
+
bodiesCheck.detail = `${failures.length}/${solids.length} bodies invalid — ${failures.join("; ")}`;
|
|
295
|
+
r.errorInfos.push({
|
|
296
|
+
message: `allBodiesValid: ${bodiesCheck.detail}`,
|
|
297
|
+
code: VALIDITY_FAILURE_CODE
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
r.checks.push(bodiesCheck);
|
|
301
|
+
}
|
|
281
302
|
}
|
|
282
303
|
if (isShape3D(shape)) {
|
|
283
|
-
const
|
|
284
|
-
if (isOk(
|
|
285
|
-
r.measurements.volume =
|
|
304
|
+
const volProps = measureVolumeProps(shape);
|
|
305
|
+
if (isOk(volProps)) {
|
|
306
|
+
r.measurements.volume = volProps.value.volume;
|
|
307
|
+
r.measurements.centerOfMass = volProps.value.centerOfMass;
|
|
286
308
|
r.checks.push({
|
|
287
309
|
name: "positiveVolume",
|
|
288
|
-
passed:
|
|
310
|
+
passed: volProps.value.volume > 0
|
|
289
311
|
});
|
|
290
312
|
} else pushError(r, {
|
|
291
|
-
message: `measureVolume: ${
|
|
292
|
-
code:
|
|
293
|
-
suggestion:
|
|
313
|
+
message: `measureVolume: ${volProps.error.message}`,
|
|
314
|
+
code: volProps.error.code,
|
|
315
|
+
suggestion: volProps.error.suggestion
|
|
294
316
|
});
|
|
295
317
|
}
|
|
296
318
|
if (isFace(shape) || isShape3D(shape)) {
|
|
@@ -302,6 +324,18 @@ function runChecks(brep, shape) {
|
|
|
302
324
|
} catch (e) {
|
|
303
325
|
pushError(r, { message: `getBounds: ${e.message}` });
|
|
304
326
|
}
|
|
327
|
+
try {
|
|
328
|
+
r.topology = {
|
|
329
|
+
faceCount: getFaces(shape).length,
|
|
330
|
+
edgeCount: getEdges(shape).length,
|
|
331
|
+
wireCount: getWires(shape).length,
|
|
332
|
+
vertexCount: getVertices(shape).length
|
|
333
|
+
};
|
|
334
|
+
} catch {}
|
|
335
|
+
if (r.topology) try {
|
|
336
|
+
const shells = getShells(shape);
|
|
337
|
+
if (shells.length > 0) r.topology.manifold = shells.every((s) => isManifoldShell(s));
|
|
338
|
+
} catch {}
|
|
305
339
|
r.hints = buildHints(r);
|
|
306
340
|
return r;
|
|
307
341
|
}
|
|
@@ -530,6 +564,39 @@ function typecheckPart(partPath, toolDir) {
|
|
|
530
564
|
}
|
|
531
565
|
//#endregion
|
|
532
566
|
//#region src/verify/runPart.ts
|
|
567
|
+
/** Centroid of a face group's vertices, in part (Z-up, mm) coordinates. */
|
|
568
|
+
function faceCentroid(m, start, count) {
|
|
569
|
+
let x = 0;
|
|
570
|
+
let y = 0;
|
|
571
|
+
let z = 0;
|
|
572
|
+
for (let i = start; i < start + count; i++) {
|
|
573
|
+
const vi = (m.triangles[i] ?? 0) * 3;
|
|
574
|
+
x += m.vertices[vi] ?? 0;
|
|
575
|
+
y += m.vertices[vi + 1] ?? 0;
|
|
576
|
+
z += m.vertices[vi + 2] ?? 0;
|
|
577
|
+
}
|
|
578
|
+
const n = count || 1;
|
|
579
|
+
return [
|
|
580
|
+
x / n,
|
|
581
|
+
y / n,
|
|
582
|
+
z / n
|
|
583
|
+
];
|
|
584
|
+
}
|
|
585
|
+
function buildMaterialMap(m, spec) {
|
|
586
|
+
if (spec === void 0 || spec === null) return {};
|
|
587
|
+
if (typeof spec !== "function" && (typeof spec !== "object" || Array.isArray(spec))) return { warning: "export const materials must be a function or a material object — ignored" };
|
|
588
|
+
const sel = spec;
|
|
589
|
+
const select = typeof sel === "function" ? sel : () => sel;
|
|
590
|
+
const map = /* @__PURE__ */ new Map();
|
|
591
|
+
for (const fg of m.faceGroups) {
|
|
592
|
+
const mat = select({
|
|
593
|
+
faceId: fg.faceId,
|
|
594
|
+
center: faceCentroid(m, fg.start, fg.count)
|
|
595
|
+
});
|
|
596
|
+
if (mat) map.set(fg.faceId, mat);
|
|
597
|
+
}
|
|
598
|
+
return map.size > 0 ? { map } : {};
|
|
599
|
+
}
|
|
533
600
|
async function loadPart(modulePath) {
|
|
534
601
|
try {
|
|
535
602
|
return await import((0, node_url.pathToFileURL)(modulePath).href);
|
|
@@ -648,7 +715,13 @@ async function runPart(modulePath, opts = {}) {
|
|
|
648
715
|
let glb;
|
|
649
716
|
let step;
|
|
650
717
|
if (opts.glb) try {
|
|
651
|
-
|
|
718
|
+
const shapeMesh = mesh(shape);
|
|
719
|
+
const { map, warning } = buildMaterialMap(shapeMesh, mod.materials);
|
|
720
|
+
if (warning) pushError(result, {
|
|
721
|
+
message: `materials: ${warning}`,
|
|
722
|
+
code: "MATERIALS_IGNORED"
|
|
723
|
+
});
|
|
724
|
+
glb = map ? exportGlb(shapeMesh, { materials: map }) : exportGlb(shapeMesh);
|
|
652
725
|
} catch (e) {
|
|
653
726
|
pushError(result, toErrorInfo("exportGlb", e));
|
|
654
727
|
}
|
|
@@ -665,7 +738,7 @@ async function runPart(modulePath, opts = {}) {
|
|
|
665
738
|
});
|
|
666
739
|
}
|
|
667
740
|
//#endregion
|
|
668
|
-
//#region \0@oxc-project+runtime@0.
|
|
741
|
+
//#region \0@oxc-project+runtime@0.133.0/helpers/esm/usingCtx.js
|
|
669
742
|
function _usingCtx() {
|
|
670
743
|
var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
|
|
671
744
|
var n = Error();
|
|
@@ -259,7 +259,7 @@ function shapeTypeOf(brep, s) {
|
|
|
259
259
|
return "Unknown";
|
|
260
260
|
}
|
|
261
261
|
function runChecks(brep, shape) {
|
|
262
|
-
const { isSolid, isShape3D, isFace,
|
|
262
|
+
const { isSolid, isShape3D, isFace, measureVolumeProps, measureArea, getBounds, getFaces, getEdges, getWires, getVertices, getSolids, getShells, isManifoldShell, validSolid, isOk } = brep;
|
|
263
263
|
const r = emptyReport();
|
|
264
264
|
r.shapeType = shapeTypeOf(brep, shape);
|
|
265
265
|
if (isSolid(shape)) {
|
|
@@ -276,19 +276,41 @@ function runChecks(brep, shape) {
|
|
|
276
276
|
});
|
|
277
277
|
}
|
|
278
278
|
r.checks.push(validCheck);
|
|
279
|
+
} else {
|
|
280
|
+
const solids = getSolids(shape);
|
|
281
|
+
if (solids.length > 0) {
|
|
282
|
+
const failures = [];
|
|
283
|
+
solids.forEach((s, i) => {
|
|
284
|
+
const v = validSolid(s);
|
|
285
|
+
if (!isOk(v)) failures.push(`body ${i}: ${v.error}`);
|
|
286
|
+
});
|
|
287
|
+
const bodiesCheck = {
|
|
288
|
+
name: "allBodiesValid",
|
|
289
|
+
passed: failures.length === 0
|
|
290
|
+
};
|
|
291
|
+
if (failures.length > 0) {
|
|
292
|
+
bodiesCheck.detail = `${failures.length}/${solids.length} bodies invalid — ${failures.join("; ")}`;
|
|
293
|
+
r.errorInfos.push({
|
|
294
|
+
message: `allBodiesValid: ${bodiesCheck.detail}`,
|
|
295
|
+
code: VALIDITY_FAILURE_CODE
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
r.checks.push(bodiesCheck);
|
|
299
|
+
}
|
|
279
300
|
}
|
|
280
301
|
if (isShape3D(shape)) {
|
|
281
|
-
const
|
|
282
|
-
if (isOk(
|
|
283
|
-
r.measurements.volume =
|
|
302
|
+
const volProps = measureVolumeProps(shape);
|
|
303
|
+
if (isOk(volProps)) {
|
|
304
|
+
r.measurements.volume = volProps.value.volume;
|
|
305
|
+
r.measurements.centerOfMass = volProps.value.centerOfMass;
|
|
284
306
|
r.checks.push({
|
|
285
307
|
name: "positiveVolume",
|
|
286
|
-
passed:
|
|
308
|
+
passed: volProps.value.volume > 0
|
|
287
309
|
});
|
|
288
310
|
} else pushError(r, {
|
|
289
|
-
message: `measureVolume: ${
|
|
290
|
-
code:
|
|
291
|
-
suggestion:
|
|
311
|
+
message: `measureVolume: ${volProps.error.message}`,
|
|
312
|
+
code: volProps.error.code,
|
|
313
|
+
suggestion: volProps.error.suggestion
|
|
292
314
|
});
|
|
293
315
|
}
|
|
294
316
|
if (isFace(shape) || isShape3D(shape)) {
|
|
@@ -300,6 +322,18 @@ function runChecks(brep, shape) {
|
|
|
300
322
|
} catch (e) {
|
|
301
323
|
pushError(r, { message: `getBounds: ${e.message}` });
|
|
302
324
|
}
|
|
325
|
+
try {
|
|
326
|
+
r.topology = {
|
|
327
|
+
faceCount: getFaces(shape).length,
|
|
328
|
+
edgeCount: getEdges(shape).length,
|
|
329
|
+
wireCount: getWires(shape).length,
|
|
330
|
+
vertexCount: getVertices(shape).length
|
|
331
|
+
};
|
|
332
|
+
} catch {}
|
|
333
|
+
if (r.topology) try {
|
|
334
|
+
const shells = getShells(shape);
|
|
335
|
+
if (shells.length > 0) r.topology.manifold = shells.every((s) => isManifoldShell(s));
|
|
336
|
+
} catch {}
|
|
303
337
|
r.hints = buildHints(r);
|
|
304
338
|
return r;
|
|
305
339
|
}
|
|
@@ -528,6 +562,39 @@ function typecheckPart(partPath, toolDir) {
|
|
|
528
562
|
}
|
|
529
563
|
//#endregion
|
|
530
564
|
//#region src/verify/runPart.ts
|
|
565
|
+
/** Centroid of a face group's vertices, in part (Z-up, mm) coordinates. */
|
|
566
|
+
function faceCentroid(m, start, count) {
|
|
567
|
+
let x = 0;
|
|
568
|
+
let y = 0;
|
|
569
|
+
let z = 0;
|
|
570
|
+
for (let i = start; i < start + count; i++) {
|
|
571
|
+
const vi = (m.triangles[i] ?? 0) * 3;
|
|
572
|
+
x += m.vertices[vi] ?? 0;
|
|
573
|
+
y += m.vertices[vi + 1] ?? 0;
|
|
574
|
+
z += m.vertices[vi + 2] ?? 0;
|
|
575
|
+
}
|
|
576
|
+
const n = count || 1;
|
|
577
|
+
return [
|
|
578
|
+
x / n,
|
|
579
|
+
y / n,
|
|
580
|
+
z / n
|
|
581
|
+
];
|
|
582
|
+
}
|
|
583
|
+
function buildMaterialMap(m, spec) {
|
|
584
|
+
if (spec === void 0 || spec === null) return {};
|
|
585
|
+
if (typeof spec !== "function" && (typeof spec !== "object" || Array.isArray(spec))) return { warning: "export const materials must be a function or a material object — ignored" };
|
|
586
|
+
const sel = spec;
|
|
587
|
+
const select = typeof sel === "function" ? sel : () => sel;
|
|
588
|
+
const map = /* @__PURE__ */ new Map();
|
|
589
|
+
for (const fg of m.faceGroups) {
|
|
590
|
+
const mat = select({
|
|
591
|
+
faceId: fg.faceId,
|
|
592
|
+
center: faceCentroid(m, fg.start, fg.count)
|
|
593
|
+
});
|
|
594
|
+
if (mat) map.set(fg.faceId, mat);
|
|
595
|
+
}
|
|
596
|
+
return map.size > 0 ? { map } : {};
|
|
597
|
+
}
|
|
531
598
|
async function loadPart(modulePath) {
|
|
532
599
|
try {
|
|
533
600
|
return await import(pathToFileURL(modulePath).href);
|
|
@@ -646,7 +713,13 @@ async function runPart(modulePath, opts = {}) {
|
|
|
646
713
|
let glb;
|
|
647
714
|
let step;
|
|
648
715
|
if (opts.glb) try {
|
|
649
|
-
|
|
716
|
+
const shapeMesh = mesh(shape);
|
|
717
|
+
const { map, warning } = buildMaterialMap(shapeMesh, mod.materials);
|
|
718
|
+
if (warning) pushError(result, {
|
|
719
|
+
message: `materials: ${warning}`,
|
|
720
|
+
code: "MATERIALS_IGNORED"
|
|
721
|
+
});
|
|
722
|
+
glb = map ? exportGlb(shapeMesh, { materials: map }) : exportGlb(shapeMesh);
|
|
650
723
|
} catch (e) {
|
|
651
724
|
pushError(result, toErrorInfo("exportGlb", e));
|
|
652
725
|
}
|
|
@@ -663,7 +736,7 @@ async function runPart(modulePath, opts = {}) {
|
|
|
663
736
|
});
|
|
664
737
|
}
|
|
665
738
|
//#endregion
|
|
666
|
-
//#region \0@oxc-project+runtime@0.
|
|
739
|
+
//#region \0@oxc-project+runtime@0.133.0/helpers/esm/usingCtx.js
|
|
667
740
|
function _usingCtx() {
|
|
668
741
|
var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
|
|
669
742
|
var n = Error();
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ export { runPart, type RunPartOptions, type RunPartResult } from './verify/runPa
|
|
|
2
2
|
export { runChecks } from './verify/checks.js';
|
|
3
3
|
export { runMeasure, type MeasureReport } from './verify/measure.js';
|
|
4
4
|
export { runDiff } from './verify/diff.js';
|
|
5
|
-
export { serializeReport, emptyReport, type VerifyReport, type VerifyCheck, type VerifyMeasurements, type VerifyAssertion, type DiffReport, type BoundsDelta, } from './verify/report.js';
|
|
5
|
+
export { serializeReport, emptyReport, type VerifyReport, type VerifyCheck, type VerifyMeasurements, type VerifyTopology, type VerifyAssertion, type DiffReport, type BoundsDelta, } from './verify/report.js';
|
|
6
6
|
export { typecheckPart, TYPECHECK_CODE, type TypecheckResult } from './verify/typecheck.js';
|
|
7
7
|
export { evaluateExpected, isExpectedDims, pctDelta, DEFAULT_TOLERANCE_PCT, type ExpectedDims, type ExpectedBounds, } from './verify/expected.js';
|