copper3d 3.6.5 → 3.6.7
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/Utils/segmentation/NrrdTools.d.ts +18 -4
- package/dist/Utils/segmentation/NrrdTools.js +39 -7
- package/dist/Utils/segmentation/NrrdTools.js.map +1 -1
- package/dist/Utils/surfaceAnnotation/MeshGraph.d.ts +4 -0
- package/dist/Utils/surfaceAnnotation/MeshGraph.js +9 -0
- package/dist/Utils/surfaceAnnotation/MeshGraph.js.map +1 -1
- package/dist/Utils/surfaceAnnotation/SurfaceAnnotator.d.ts +31 -0
- package/dist/Utils/surfaceAnnotation/SurfaceAnnotator.js +138 -12
- package/dist/Utils/surfaceAnnotation/SurfaceAnnotator.js.map +1 -1
- package/dist/Utils/surfaceAnnotation/annotationStore.d.ts +2 -0
- package/dist/Utils/surfaceAnnotation/annotationStore.js +8 -0
- package/dist/Utils/surfaceAnnotation/annotationStore.js.map +1 -1
- package/dist/Utils/surfaceAnnotation/types.d.ts +1 -0
- package/dist/Utils/surfaceAnnotation/types.js.map +1 -1
- package/dist/bundle.esm.js +206 -22
- package/dist/bundle.umd.js +206 -22
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/types/Utils/segmentation/NrrdTools.d.ts +18 -4
- package/dist/types/Utils/surfaceAnnotation/MeshGraph.d.ts +4 -0
- package/dist/types/Utils/surfaceAnnotation/SurfaceAnnotator.d.ts +31 -0
- package/dist/types/Utils/surfaceAnnotation/annotationStore.d.ts +2 -0
- package/dist/types/Utils/surfaceAnnotation/types.d.ts +1 -0
- package/package.json +1 -1
package/dist/bundle.esm.js
CHANGED
|
@@ -61165,6 +61165,15 @@ class MeshGraph {
|
|
|
61165
61165
|
const nm = new Matrix3().getNormalMatrix(mesh.matrixWorld);
|
|
61166
61166
|
return n.applyMatrix3(nm).normalize();
|
|
61167
61167
|
}
|
|
61168
|
+
/** Vertex local normal at index i (reads from the welded graphGeo normal attribute). */
|
|
61169
|
+
vertexNormalLocal(i) {
|
|
61170
|
+
return new Vector3(this.normals ? this.normals[i * 3] : 0, this.normals ? this.normals[i * 3 + 1] : 0, this.normals ? this.normals[i * 3 + 2] : 1);
|
|
61171
|
+
}
|
|
61172
|
+
/** Normal at the vertex nearest to localPoint (for recovering normals from imported point coordinates). */
|
|
61173
|
+
nearestNormalLocal(p) {
|
|
61174
|
+
const i = this.nearestVertex(p);
|
|
61175
|
+
return this.vertexNormalLocal(i);
|
|
61176
|
+
}
|
|
61168
61177
|
/** Vertex local coordinates + local normal (the graph geometry is already local space). */
|
|
61169
61178
|
vertexLocal(i) {
|
|
61170
61179
|
return {
|
|
@@ -61390,6 +61399,13 @@ class AnnotationStore {
|
|
|
61390
61399
|
this.notify();
|
|
61391
61400
|
}
|
|
61392
61401
|
}
|
|
61402
|
+
setVisible(id, visible) {
|
|
61403
|
+
const a = this.get(id);
|
|
61404
|
+
if (a) {
|
|
61405
|
+
a.visible = visible;
|
|
61406
|
+
this.notify();
|
|
61407
|
+
}
|
|
61408
|
+
}
|
|
61393
61409
|
toJSON(modelName, mesh, opts = {}) {
|
|
61394
61410
|
var _a;
|
|
61395
61411
|
const space = (_a = opts.space) !== null && _a !== void 0 ? _a : "local";
|
|
@@ -61414,6 +61430,7 @@ class AnnotationStore {
|
|
|
61414
61430
|
label: a.label,
|
|
61415
61431
|
color: a.color,
|
|
61416
61432
|
closed: a.closed,
|
|
61433
|
+
visible: a.visible,
|
|
61417
61434
|
points: a.vertices.map(toPt),
|
|
61418
61435
|
})),
|
|
61419
61436
|
};
|
|
@@ -61433,6 +61450,10 @@ class SurfaceAnnotator {
|
|
|
61433
61450
|
var _a, _b, _c;
|
|
61434
61451
|
this.mode = "navigate";
|
|
61435
61452
|
this.spaceHeld = false;
|
|
61453
|
+
this.drawLock = false;
|
|
61454
|
+
this.armed = "freehand";
|
|
61455
|
+
this.spaceDownAt = 0;
|
|
61456
|
+
this.spaceDragged = false;
|
|
61436
61457
|
this.pointerDown = false;
|
|
61437
61458
|
this.store = new AnnotationStore();
|
|
61438
61459
|
this.managed = new Set();
|
|
@@ -61459,14 +61480,18 @@ class SurfaceAnnotator {
|
|
|
61459
61480
|
(this.activeGeoLine.material.resolution.set(w, h));
|
|
61460
61481
|
};
|
|
61461
61482
|
this.onPointerDown = (e) => {
|
|
61462
|
-
if (this.spaceHeld)
|
|
61463
|
-
return;
|
|
61464
61483
|
if (e.button !== 0)
|
|
61465
61484
|
return; // left button only
|
|
61466
61485
|
if (!this.insideContainer(e))
|
|
61467
61486
|
return;
|
|
61468
61487
|
this.pointerDown = true;
|
|
61469
|
-
|
|
61488
|
+
// Only act with the armed tool when in drawing mode (drawLock or spaceHeld).
|
|
61489
|
+
// When not drawing, navigation is the default — pointer events go to camera controls.
|
|
61490
|
+
if (!this.drawing)
|
|
61491
|
+
return;
|
|
61492
|
+
// Use armed tool (not this.mode which may be "navigate")
|
|
61493
|
+
const activeTool = this.armed;
|
|
61494
|
+
if (activeTool === "point") {
|
|
61470
61495
|
const h = this.hit(e);
|
|
61471
61496
|
if (!h)
|
|
61472
61497
|
return;
|
|
@@ -61480,13 +61505,14 @@ class SurfaceAnnotator {
|
|
|
61480
61505
|
label: `Point ${this.seq}`,
|
|
61481
61506
|
color: this.pointColorVal,
|
|
61482
61507
|
closed: false,
|
|
61508
|
+
visible: true,
|
|
61483
61509
|
vertices: [v],
|
|
61484
61510
|
object3D: marker,
|
|
61485
61511
|
};
|
|
61486
61512
|
this.store.add(ann);
|
|
61487
61513
|
return;
|
|
61488
61514
|
}
|
|
61489
|
-
if (
|
|
61515
|
+
if (activeTool === "freehand") {
|
|
61490
61516
|
this.activeStroke = new StrokeContour(this.minGap, this.maxJump, this.o.mesh);
|
|
61491
61517
|
this.activeStroke.begin();
|
|
61492
61518
|
const h = this.hit(e);
|
|
@@ -61496,7 +61522,7 @@ class SurfaceAnnotator {
|
|
|
61496
61522
|
this.o.scene.add(this.activeLine);
|
|
61497
61523
|
return;
|
|
61498
61524
|
}
|
|
61499
|
-
if (
|
|
61525
|
+
if (activeTool === "geodesic") {
|
|
61500
61526
|
// First check whether an existing anchor was clicked → cancel that point (any point can be canceled).
|
|
61501
61527
|
const pick = this.pickGeoMarker(e);
|
|
61502
61528
|
if (pick >= 0 && this.activeGeo) {
|
|
@@ -61523,15 +61549,26 @@ class SurfaceAnnotator {
|
|
|
61523
61549
|
}
|
|
61524
61550
|
};
|
|
61525
61551
|
this.onPointerMove = (e) => {
|
|
61526
|
-
if (
|
|
61527
|
-
|
|
61552
|
+
// Track if user dragged while space was held (so a hold-drag is not treated as a tap).
|
|
61553
|
+
if (this.spaceHeld && this.pointerDown) {
|
|
61554
|
+
this.spaceDragged = true;
|
|
61555
|
+
}
|
|
61556
|
+
// When not drawing, navigation is default — don't interfere with camera controls.
|
|
61557
|
+
if (!this.drawing) {
|
|
61558
|
+
// In geodesic mode we can still show the hover hint when not drawing.
|
|
61559
|
+
if (this.armed === "geodesic" && !this.pointerDown) {
|
|
61560
|
+
this.setGeoHover(this.insideContainer(e) ? this.pickGeoMarker(e) : -1);
|
|
61561
|
+
}
|
|
61562
|
+
else {
|
|
61563
|
+
this.setGeoHover(-1);
|
|
61564
|
+
}
|
|
61528
61565
|
return;
|
|
61529
61566
|
}
|
|
61530
|
-
//
|
|
61531
|
-
if (this.
|
|
61567
|
+
// Drawing mode: geodesic hover hint
|
|
61568
|
+
if (this.armed === "geodesic" && !this.pointerDown) {
|
|
61532
61569
|
this.setGeoHover(this.insideContainer(e) ? this.pickGeoMarker(e) : -1);
|
|
61533
61570
|
}
|
|
61534
|
-
if (this.
|
|
61571
|
+
if (this.armed === "freehand" &&
|
|
61535
61572
|
this.pointerDown &&
|
|
61536
61573
|
this.activeStroke &&
|
|
61537
61574
|
this.activeLine) {
|
|
@@ -61556,6 +61593,7 @@ class SurfaceAnnotator {
|
|
|
61556
61593
|
label: `Contour ${this.seq}`,
|
|
61557
61594
|
color: this.freehandColor,
|
|
61558
61595
|
closed: false,
|
|
61596
|
+
visible: true,
|
|
61559
61597
|
vertices: verts,
|
|
61560
61598
|
object3D: this.activeLine,
|
|
61561
61599
|
};
|
|
@@ -61573,11 +61611,17 @@ class SurfaceAnnotator {
|
|
|
61573
61611
|
if (this.isTypingTarget(e))
|
|
61574
61612
|
return;
|
|
61575
61613
|
if (e.code === "Space") {
|
|
61614
|
+
if (!this.spaceHeld) {
|
|
61615
|
+
this.spaceDownAt = performance.now();
|
|
61616
|
+
this.spaceDragged = false;
|
|
61617
|
+
}
|
|
61576
61618
|
this.spaceHeld = true;
|
|
61577
61619
|
this.applyCameraGating();
|
|
61620
|
+
e.preventDefault();
|
|
61578
61621
|
return;
|
|
61579
61622
|
}
|
|
61580
61623
|
if (e.key === "Escape") {
|
|
61624
|
+
this.drawLock = false;
|
|
61581
61625
|
this.setMode("navigate");
|
|
61582
61626
|
return;
|
|
61583
61627
|
}
|
|
@@ -61610,7 +61654,11 @@ class SurfaceAnnotator {
|
|
|
61610
61654
|
};
|
|
61611
61655
|
this.onKeyUp = (e) => {
|
|
61612
61656
|
if (e.code === "Space") {
|
|
61657
|
+
const held = performance.now() - this.spaceDownAt;
|
|
61613
61658
|
this.spaceHeld = false;
|
|
61659
|
+
if (held <= SurfaceAnnotator.TAP_MS && !this.spaceDragged) {
|
|
61660
|
+
this.drawLock = !this.drawLock; // tap toggles lock
|
|
61661
|
+
}
|
|
61614
61662
|
this.applyCameraGating();
|
|
61615
61663
|
}
|
|
61616
61664
|
};
|
|
@@ -61666,6 +61714,10 @@ class SurfaceAnnotator {
|
|
|
61666
61714
|
if (m !== "geodesic" && this.activeGeo)
|
|
61667
61715
|
this.clearActiveGeo();
|
|
61668
61716
|
this.mode = m;
|
|
61717
|
+
// Record armed tool when choosing a drawing mode (not navigate).
|
|
61718
|
+
// Camera gating is NOT changed here — the user must use Space to enter drawing.
|
|
61719
|
+
if (m !== "navigate")
|
|
61720
|
+
this.armed = m;
|
|
61669
61721
|
this.applyCameraGating();
|
|
61670
61722
|
(_b = (_a = this.o).onModeChange) === null || _b === void 0 ? void 0 : _b.call(_a, m);
|
|
61671
61723
|
}
|
|
@@ -61728,10 +61780,92 @@ class SurfaceAnnotator {
|
|
|
61728
61780
|
exportJSON(modelName, opts) {
|
|
61729
61781
|
return this.store.toJSON(modelName, this.o.mesh, opts);
|
|
61730
61782
|
}
|
|
61783
|
+
setVisible(id, visible) {
|
|
61784
|
+
this.store.setVisible(id, visible);
|
|
61785
|
+
}
|
|
61786
|
+
/**
|
|
61787
|
+
* Rebuild annotations from an exported payload (local-space points). Normals are taken from the
|
|
61788
|
+
* point when present ([x,y,z,nx,ny,nz]); otherwise recovered from the welded graph's nearest
|
|
61789
|
+
* vertex. Each imported item becomes first-class (select/recolor/hide/delete/export).
|
|
61790
|
+
*/
|
|
61791
|
+
importAnnotations(payload) {
|
|
61792
|
+
var _a, _b, _c, _d;
|
|
61793
|
+
let count = 0;
|
|
61794
|
+
let maxImported = this.seq;
|
|
61795
|
+
for (const a of (_a = payload.annotations) !== null && _a !== void 0 ? _a : []) {
|
|
61796
|
+
const verts = a.points.map((p) => {
|
|
61797
|
+
const [x, y, z] = p;
|
|
61798
|
+
let nx = p[3], ny = p[4], nz = p[5];
|
|
61799
|
+
if (nx === undefined || ny === undefined || nz === undefined) {
|
|
61800
|
+
const nrm = this.graph.nearestNormalLocal(new Vector3(x, y, z));
|
|
61801
|
+
nx = nrm.x;
|
|
61802
|
+
ny = nrm.y;
|
|
61803
|
+
nz = nrm.z;
|
|
61804
|
+
}
|
|
61805
|
+
return { x, y, z, nx, ny, nz, faceIndex: 0 };
|
|
61806
|
+
});
|
|
61807
|
+
if (a.type === "points") {
|
|
61808
|
+
for (const v of verts) {
|
|
61809
|
+
// Only reuse the provided id for a single-point entry (the round-trip case);
|
|
61810
|
+
// a multi-point points entry must get a fresh id per marker to avoid duplicate keys.
|
|
61811
|
+
const id = a.id && verts.length === 1 ? a.id : this.nextId();
|
|
61812
|
+
const marker = makePointMarker(v, this.o.mesh, a.color, this.markerRadius);
|
|
61813
|
+
this.o.scene.add(marker);
|
|
61814
|
+
this.store.add({
|
|
61815
|
+
id,
|
|
61816
|
+
type: "points",
|
|
61817
|
+
mode: null,
|
|
61818
|
+
label: a.label,
|
|
61819
|
+
color: a.color,
|
|
61820
|
+
closed: false,
|
|
61821
|
+
visible: (_b = a.visible) !== null && _b !== void 0 ? _b : true,
|
|
61822
|
+
vertices: [v],
|
|
61823
|
+
object3D: marker,
|
|
61824
|
+
});
|
|
61825
|
+
// track max numeric id
|
|
61826
|
+
const m = id.match(/^a(\d+)$/);
|
|
61827
|
+
if (m)
|
|
61828
|
+
maxImported = Math.max(maxImported, parseInt(m[1], 10));
|
|
61829
|
+
count++;
|
|
61830
|
+
}
|
|
61831
|
+
}
|
|
61832
|
+
else {
|
|
61833
|
+
if (verts.length < 2)
|
|
61834
|
+
continue;
|
|
61835
|
+
const id = (_c = a.id) !== null && _c !== void 0 ? _c : this.nextId();
|
|
61836
|
+
const line = makeContourLine(verts, a.color, a.closed, this.o.container, this.epsilon, this.o.mesh);
|
|
61837
|
+
this.o.scene.add(line);
|
|
61838
|
+
this.store.add({
|
|
61839
|
+
id,
|
|
61840
|
+
type: "contour",
|
|
61841
|
+
mode: a.mode,
|
|
61842
|
+
label: a.label,
|
|
61843
|
+
color: a.color,
|
|
61844
|
+
closed: a.closed,
|
|
61845
|
+
visible: (_d = a.visible) !== null && _d !== void 0 ? _d : true,
|
|
61846
|
+
vertices: verts,
|
|
61847
|
+
object3D: line,
|
|
61848
|
+
});
|
|
61849
|
+
const m = id.match(/^a(\d+)$/);
|
|
61850
|
+
if (m)
|
|
61851
|
+
maxImported = Math.max(maxImported, parseInt(m[1], 10));
|
|
61852
|
+
count++;
|
|
61853
|
+
}
|
|
61854
|
+
}
|
|
61855
|
+
// keep seq ahead of any imported numeric ids to avoid collisions
|
|
61856
|
+
if (maxImported > this.seq)
|
|
61857
|
+
this.seq = maxImported;
|
|
61858
|
+
return count;
|
|
61859
|
+
}
|
|
61731
61860
|
// ---- Internal ----
|
|
61861
|
+
get drawing() {
|
|
61862
|
+
return this.drawLock || this.spaceHeld;
|
|
61863
|
+
}
|
|
61732
61864
|
applyCameraGating() {
|
|
61733
|
-
|
|
61734
|
-
|
|
61865
|
+
var _a, _b;
|
|
61866
|
+
// Default is navigate (camera enabled). Drawing only when drawLock or spaceHeld.
|
|
61867
|
+
this.o.controls.enabled = !this.drawing;
|
|
61868
|
+
(_b = (_a = this.o).onInteractionChange) === null || _b === void 0 ? void 0 : _b.call(_a, { drawing: this.drawing, armed: this.armed, locked: this.drawLock });
|
|
61735
61869
|
}
|
|
61736
61870
|
/** Reconcile the scene against store.list(): add missing objects, remove deleted ones (no dispose, kept for undo restore). */
|
|
61737
61871
|
reconcile() {
|
|
@@ -61749,6 +61883,11 @@ class SurfaceAnnotator {
|
|
|
61749
61883
|
this.o.scene.add(o);
|
|
61750
61884
|
}
|
|
61751
61885
|
this.managed = present;
|
|
61886
|
+
// Apply per-annotation visibility
|
|
61887
|
+
for (const a of this.store.list()) {
|
|
61888
|
+
if (a.object3D)
|
|
61889
|
+
a.object3D.visible = a.visible;
|
|
61890
|
+
}
|
|
61752
61891
|
this.applySelection();
|
|
61753
61892
|
(_b = (_a = this.o).onChange) === null || _b === void 0 ? void 0 : _b.call(_a, this.store.list());
|
|
61754
61893
|
}
|
|
@@ -61756,6 +61895,8 @@ class SurfaceAnnotator {
|
|
|
61756
61895
|
for (const a of this.store.list()) {
|
|
61757
61896
|
if (!a.object3D)
|
|
61758
61897
|
continue;
|
|
61898
|
+
if (!a.visible)
|
|
61899
|
+
continue;
|
|
61759
61900
|
const sel = a.id === this.selectedId;
|
|
61760
61901
|
if (a.type === "contour") {
|
|
61761
61902
|
const mat = a.object3D.material;
|
|
@@ -61988,6 +62129,7 @@ class SurfaceAnnotator {
|
|
|
61988
62129
|
label: `Contour ${this.seq}`,
|
|
61989
62130
|
color: this.geodesicColor,
|
|
61990
62131
|
closed,
|
|
62132
|
+
visible: true,
|
|
61991
62133
|
vertices: verts,
|
|
61992
62134
|
object3D: this.activeGeoLine,
|
|
61993
62135
|
};
|
|
@@ -62021,7 +62163,8 @@ class SurfaceAnnotator {
|
|
|
62021
62163
|
window.removeEventListener("keyup", this.onKeyUp);
|
|
62022
62164
|
window.removeEventListener("resize", this.onResize);
|
|
62023
62165
|
}
|
|
62024
|
-
}
|
|
62166
|
+
}
|
|
62167
|
+
SurfaceAnnotator.TAP_MS = 250;
|
|
62025
62168
|
|
|
62026
62169
|
class copperScene extends baseScene {
|
|
62027
62170
|
// rayster pick
|
|
@@ -83011,12 +83154,20 @@ class NrrdTools {
|
|
|
83011
83154
|
return this.drawCore.aiAssistTool.getScratchSegments();
|
|
83012
83155
|
}
|
|
83013
83156
|
/**
|
|
83014
|
-
* Merge the AI scratch into a target layer
|
|
83015
|
-
* merge —
|
|
83016
|
-
*
|
|
83017
|
-
*
|
|
83157
|
+
* Merge the AI scratch into a target layer with an explicit per-segmentation
|
|
83158
|
+
* mapping, as a single undoable group (sandbox merge — non-destructive + one
|
|
83159
|
+
* Ctrl+Z). `mapping` is `{ AI scratch label -> target channel(1-8) }`; any label
|
|
83160
|
+
* absent from the mapping (or mapped to 0) is DISCARDED (not merged). Several AI
|
|
83161
|
+
* labels MAY map to the SAME channel — after merge the channel is the identity
|
|
83162
|
+
* (CLAUDE.md decision M2), so the merged voxels take that channel's fixed colour.
|
|
83163
|
+
*
|
|
83164
|
+
* UNION semantics (M4): an AI voxel only fills a target voxel that is currently
|
|
83165
|
+
* EMPTY (0) — existing manual annotation is NEVER erased. Where two AI labels map
|
|
83166
|
+
* to different channels and overlap the same voxel, the first one written wins
|
|
83167
|
+
* (iteration order), an accepted edge case for a single-value-per-voxel mask.
|
|
83168
|
+
* Scans all z-slices, so voxels painted from any view are caught.
|
|
83018
83169
|
*/
|
|
83019
|
-
|
|
83170
|
+
aiCommitToLayerMapped(targetLayer, mapping) {
|
|
83020
83171
|
const scratch = this.drawCore.aiAssistTool.getScratchVolume();
|
|
83021
83172
|
if (!scratch)
|
|
83022
83173
|
return;
|
|
@@ -83038,10 +83189,21 @@ class NrrdTools {
|
|
|
83038
83189
|
continue;
|
|
83039
83190
|
const oldSlice = target.getSliceUint8(z, "z").data; // copy
|
|
83040
83191
|
const newSlice = oldSlice.slice();
|
|
83192
|
+
let changed = false;
|
|
83041
83193
|
for (let i = 0; i < newSlice.length; i++) {
|
|
83042
|
-
|
|
83043
|
-
|
|
83194
|
+
const label = sc[i];
|
|
83195
|
+
if (label === 0)
|
|
83196
|
+
continue;
|
|
83197
|
+
const ch = mapping[label];
|
|
83198
|
+
if (!ch)
|
|
83199
|
+
continue; // unmapped / discarded segmentation
|
|
83200
|
+
if (newSlice[i] === 0) { // union: fill only EMPTY voxels (M4)
|
|
83201
|
+
newSlice[i] = ch;
|
|
83202
|
+
changed = true;
|
|
83203
|
+
}
|
|
83044
83204
|
}
|
|
83205
|
+
if (!changed)
|
|
83206
|
+
continue; // nothing landed on this slice → no delta
|
|
83045
83207
|
target.setSliceUint8(z, newSlice, "z");
|
|
83046
83208
|
deltas.push({ layerId: targetLayer, axis: "z", sliceIndex: z, oldSlice, newSlice: newSlice.slice() });
|
|
83047
83209
|
}
|
|
@@ -83049,6 +83211,19 @@ class NrrdTools {
|
|
|
83049
83211
|
this.drawCore.undoManager.pushGroup(deltas);
|
|
83050
83212
|
this.reloadMasksFromVolume();
|
|
83051
83213
|
}
|
|
83214
|
+
/**
|
|
83215
|
+
* Back-compat shim: merge with an IDENTITY mapping (each AI label → the same
|
|
83216
|
+
* channel number) via the mapped path above. Newer callers should use
|
|
83217
|
+
* `aiCommitToLayerMapped` with an explicit per-segmentation mapping.
|
|
83218
|
+
*/
|
|
83219
|
+
aiCommitToLayer(targetLayer = "layer1") {
|
|
83220
|
+
var _a;
|
|
83221
|
+
const segs = this.drawCore.aiAssistTool.getScratchSegments();
|
|
83222
|
+
const mapping = {};
|
|
83223
|
+
for (const s of (_a = segs === null || segs === void 0 ? void 0 : segs.segments) !== null && _a !== void 0 ? _a : [])
|
|
83224
|
+
mapping[s.label] = s.label;
|
|
83225
|
+
this.aiCommitToLayerMapped(targetLayer, mapping);
|
|
83226
|
+
}
|
|
83052
83227
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
83053
83228
|
// 11. Clear / Reset
|
|
83054
83229
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -83412,8 +83587,17 @@ function evaluateElement(element, weights) {
|
|
|
83412
83587
|
}
|
|
83413
83588
|
|
|
83414
83589
|
// import * as kiwrious from "copper3d_plugin_heart_k";
|
|
83415
|
-
// "v3.6.
|
|
83416
|
-
|
|
83590
|
+
// "v3.6.7" is injected at build time by rollup @rollup/plugin-replace, sourced from package.json version.
|
|
83591
|
+
// When copper3d is consumed from local source (no rollup replace step), the identifier is undefined and
|
|
83592
|
+
// referencing it throws a ReferenceError — guard it so local loading still works.
|
|
83593
|
+
let _revision = "unknown";
|
|
83594
|
+
try {
|
|
83595
|
+
_revision = "v3.6.7";
|
|
83596
|
+
}
|
|
83597
|
+
catch (_a) {
|
|
83598
|
+
/* "v3.6.7" not injected (local source build) */
|
|
83599
|
+
}
|
|
83600
|
+
const REVISION = _revision;
|
|
83417
83601
|
// Expose on global so the version can be read in a production browser console via window.__COPPER3D_VERSION__
|
|
83418
83602
|
if (typeof window !== "undefined") {
|
|
83419
83603
|
window.__COPPER3D_VERSION__ = REVISION;
|