@chestnutlabs/gcode-model-renderer 0.11.0 → 0.12.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/three-mf.d.ts.map +1 -1
- package/dist/three-mf.js +30 -13
- package/package.json +4 -4
package/dist/three-mf.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"three-mf.d.ts","sourceRoot":"","sources":["../src/three-mf.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,KAAK,UAAU,EAEhB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAkC,KAAK,WAAW,EAAuB,MAAM,aAAa,CAAC;AAkbpG,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;CACnD;
|
|
1
|
+
{"version":3,"file":"three-mf.d.ts","sourceRoot":"","sources":["../src/three-mf.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,KAAK,UAAU,EAEhB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAkC,KAAK,WAAW,EAAuB,MAAM,aAAa,CAAC;AAkbpG,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;CACnD;AA4GD,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,UAAU,GAAG,WAAW,EAChC,MAAM,CAAC,EAAE,WAAW,EACpB,IAAI,CAAC,EAAE,eAAe,GACrB,OAAO,CAAC,UAAU,CAAC,CAyKrB"}
|
package/dist/three-mf.js
CHANGED
|
@@ -428,17 +428,27 @@ const EST_REJECT_MARGIN = 2;
|
|
|
428
428
|
/**
|
|
429
429
|
* Fast structural cost estimate (DD-022 Phase 0), run after the (tiny, for production-extension files)
|
|
430
430
|
* main part is parsed but BEFORE any large external geometry part is decompressed. Walks the build-item /
|
|
431
|
-
* component tree counting
|
|
432
|
-
* - a mesh
|
|
433
|
-
* - an external `p:path`
|
|
434
|
-
*
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
*
|
|
431
|
+
* component tree counting **placements** (all of them) and a lower-bound **unique**-triangle estimate:
|
|
432
|
+
* - a mesh master's triangles are counted **once per unique master** (already parsed), NOT per placement;
|
|
433
|
+
* - an external `p:path` part is estimated from its ZIP-directory uncompressed size / the conservative
|
|
434
|
+
* bytes-per-triangle bound, counted **once per unique path** (a safe under-count), treated as a leaf.
|
|
435
|
+
* Because instancing renders each master once (DD-022 Phase 1), the triangle estimate must be UNIQUE — a
|
|
436
|
+
* full-sheet plate of ~40 copies costs its ~1 master, not ~40× baked, so it is NOT rejected here. The
|
|
437
|
+
* placement count still guards an instance bomb (`maxInstances`). Throws {@link ModelParseError} for a
|
|
438
|
+
* clear instance-bomb / oversize file so it rejects in sub-second time instead of ~10 s of decompress-and-
|
|
439
|
+
* bake; files near the budget fall through to the exact per-triangle parse.
|
|
438
440
|
*/
|
|
439
441
|
function estimateSceneCost(mainPart, entryByName, lim) {
|
|
440
442
|
let instanceCount = 0;
|
|
441
443
|
let estTriangles = 0;
|
|
444
|
+
// Unique masters already counted toward the triangle estimate (keyed by objectid / external path), so a
|
|
445
|
+
// reused master is counted once — matching the instanced render, not the old per-placement bake.
|
|
446
|
+
const countedMasters = new Set();
|
|
447
|
+
const checkInstances = () => {
|
|
448
|
+
if (instanceCount > lim.maxInstances) {
|
|
449
|
+
throw new ModelParseError('E_MODEL_TOO_MANY_INSTANCES', `3MF declares more than ${lim.maxInstances} instance placements`);
|
|
450
|
+
}
|
|
451
|
+
};
|
|
442
452
|
const visit = (part, objectid, depth) => {
|
|
443
453
|
if (depth > MAX_DEPTH)
|
|
444
454
|
return;
|
|
@@ -447,23 +457,30 @@ function estimateSceneCost(mainPart, entryByName, lim) {
|
|
|
447
457
|
return;
|
|
448
458
|
if (obj.tris.length > 0) {
|
|
449
459
|
instanceCount++;
|
|
450
|
-
|
|
460
|
+
const key = `local:${objectid}`;
|
|
461
|
+
if (!countedMasters.has(key)) {
|
|
462
|
+
countedMasters.add(key);
|
|
463
|
+
estTriangles += obj.tris.length / 3;
|
|
464
|
+
}
|
|
465
|
+
checkInstances();
|
|
451
466
|
}
|
|
452
467
|
for (const comp of obj.components) {
|
|
453
468
|
if (comp.path !== undefined) {
|
|
454
469
|
// External production-extension part: estimate from its directory size WITHOUT decompressing it.
|
|
455
|
-
const
|
|
470
|
+
const norm = comp.path.replace(/^\//, '').toLowerCase();
|
|
471
|
+
const entry = entryByName(norm);
|
|
456
472
|
if (entry !== undefined) {
|
|
457
473
|
instanceCount++;
|
|
458
|
-
|
|
474
|
+
if (!countedMasters.has(norm)) {
|
|
475
|
+
countedMasters.add(norm);
|
|
476
|
+
estTriangles += entry.uncompressedSize / EST_MAX_BYTES_PER_TRIANGLE;
|
|
477
|
+
}
|
|
478
|
+
checkInstances();
|
|
459
479
|
}
|
|
460
480
|
}
|
|
461
481
|
else {
|
|
462
482
|
visit(part, comp.objectid, depth + 1); // local sub-object (already-parsed geometry)
|
|
463
483
|
}
|
|
464
|
-
if (instanceCount > lim.maxInstances) {
|
|
465
|
-
throw new ModelParseError('E_MODEL_TOO_MANY_INSTANCES', `3MF declares more than ${lim.maxInstances} instance placements`);
|
|
466
|
-
}
|
|
467
484
|
}
|
|
468
485
|
};
|
|
469
486
|
const roots = mainPart.items.length > 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chestnutlabs/gcode-model-renderer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Three.js presentation renderer for source models (STL/3MF) — clean thumbnails/cards, distinct from toolpath inspection (DD-018).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"3d-printing",
|
|
@@ -51,9 +51,9 @@
|
|
|
51
51
|
"test": "vitest run"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@chestnutlabs/gcode-containers": "0.
|
|
55
|
-
"@chestnutlabs/gcode-renderer-three": "0.
|
|
56
|
-
"@chestnutlabs/toolpath-core": "0.
|
|
54
|
+
"@chestnutlabs/gcode-containers": "0.12.0",
|
|
55
|
+
"@chestnutlabs/gcode-renderer-three": "0.12.0",
|
|
56
|
+
"@chestnutlabs/toolpath-core": "0.12.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@types/three": "0.178.0"
|