@niivue/niivue 0.43.6 → 0.43.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/build/index.d.ts CHANGED
@@ -645,6 +645,11 @@ type NVConfigOptions = {
645
645
  multiplanarLayout: MULTIPLANAR_TYPE;
646
646
  renderOverlayBlend: number;
647
647
  sliceMosaicString: string;
648
+ centerMosaic: boolean;
649
+ clickToSegment: boolean;
650
+ clickToSegmentRadius: number;
651
+ clickToSegmentSteps: number;
652
+ clickToSegmentBright: boolean;
648
653
  };
649
654
  declare const DEFAULT_OPTIONS: NVConfigOptions;
650
655
  type SceneData = {
@@ -1687,7 +1692,6 @@ declare class Niivue {
1687
1692
  private resizeObserver;
1688
1693
  syncOpts: Record<string, unknown>;
1689
1694
  readyForSync: boolean;
1690
- centerMosaic: boolean;
1691
1695
  uiData: UIData;
1692
1696
  back: NVImage | null;
1693
1697
  overlays: NVImage[];
@@ -1773,6 +1777,19 @@ declare class Niivue {
1773
1777
  * }
1774
1778
  */
1775
1779
  onIntensityChange: (volume: NVImage) => void;
1780
+ /**
1781
+ * callback function when clickToSegment is enabled and the user clicks on the image. data contains the volume of the segmented region in mm3 and mL
1782
+ * @example
1783
+ * niivue.onClickToSegment = (data) => {
1784
+ * console.log('clicked to segment')
1785
+ * console.log('volume mm3: ', data.mm3)
1786
+ * console.log('volume mL: ', data.mL)
1787
+ * }
1788
+ */
1789
+ onClickToSegment: (data: {
1790
+ mm3: number;
1791
+ mL: number;
1792
+ }) => void;
1776
1793
  /**
1777
1794
  * callback function to run when a new volume is loaded
1778
1795
  * @example
package/build/index.js CHANGED
@@ -13,7 +13,7 @@ var __publicField = (obj, key, value) => {
13
13
  import { mat4 as mat46, vec2, vec3 as vec311, vec4 as vec48 } from "gl-matrix";
14
14
 
15
15
  // package.json
16
- var version = "0.43.6";
16
+ var version = "0.43.7";
17
17
 
18
18
  // src/logger.ts
19
19
  var _Log = class _Log {
@@ -22006,7 +22006,12 @@ var DEFAULT_OPTIONS = {
22006
22006
  legendTextColor: [1, 1, 1, 1],
22007
22007
  multiplanarLayout: 0 /* AUTO */,
22008
22008
  renderOverlayBlend: 1,
22009
- sliceMosaicString: ""
22009
+ sliceMosaicString: "",
22010
+ centerMosaic: false,
22011
+ clickToSegment: false,
22012
+ clickToSegmentRadius: 2,
22013
+ clickToSegmentSteps: 10,
22014
+ clickToSegmentBright: true
22010
22015
  };
22011
22016
  var INITIAL_SCENE_DATA = {
22012
22017
  azimuth: 110,
@@ -23783,7 +23788,6 @@ var Niivue = class _Niivue {
23783
23788
  __publicField(this, "resizeObserver", null);
23784
23789
  __publicField(this, "syncOpts", {});
23785
23790
  __publicField(this, "readyForSync", false);
23786
- __publicField(this, "centerMosaic", false);
23787
23791
  // UI Data
23788
23792
  __publicField(this, "uiData", {
23789
23793
  mousedown: false,
@@ -23947,6 +23951,17 @@ var Niivue = class _Niivue {
23947
23951
  */
23948
23952
  __publicField(this, "onIntensityChange", () => {
23949
23953
  });
23954
+ /**
23955
+ * callback function when clickToSegment is enabled and the user clicks on the image. data contains the volume of the segmented region in mm3 and mL
23956
+ * @example
23957
+ * niivue.onClickToSegment = (data) => {
23958
+ * console.log('clicked to segment')
23959
+ * console.log('volume mm3: ', data.mm3)
23960
+ * console.log('volume mL: ', data.mL)
23961
+ * }
23962
+ */
23963
+ __publicField(this, "onClickToSegment", () => {
23964
+ });
23950
23965
  /**
23951
23966
  * callback function to run when a new volume is loaded
23952
23967
  * @example
@@ -25029,7 +25044,10 @@ var Niivue = class _Niivue {
25029
25044
  // nothing
25030
25045
  imageType: NVIMAGE_TYPE.DCM_FOLDER
25031
25046
  // signify that this is a dicom directory
25032
- }).then((volume) => this.addVolume(volume)).catch((e) => {
25047
+ }).then((volume) => {
25048
+ this.addVolume(volume);
25049
+ this.setDrawingEnabled(true);
25050
+ }).catch((e) => {
25033
25051
  throw e;
25034
25052
  });
25035
25053
  }).catch((e) => {
@@ -25215,6 +25233,7 @@ var Niivue = class _Niivue {
25215
25233
  this.loadDrawing(volume);
25216
25234
  } else {
25217
25235
  this.addVolume(volume);
25236
+ this.setDrawingEnabled(true);
25218
25237
  }
25219
25238
  }).catch((e2) => {
25220
25239
  throw e2;
@@ -25763,7 +25782,10 @@ var Niivue = class _Niivue {
25763
25782
  * @see {@link https://niivue.github.io/niivue/features/draw.ui.html | live demo usage}
25764
25783
  */
25765
25784
  saveImage(options = defaultSaveImageOptions) {
25766
- const saveOptions = { ...defaultSaveImageOptions, ...options };
25785
+ const saveOptions = {
25786
+ ...defaultSaveImageOptions,
25787
+ ...options
25788
+ };
25767
25789
  const { filename, isSaveDrawing, volumeByIndex } = saveOptions;
25768
25790
  log.debug("saveImage", filename, isSaveDrawing, volumeByIndex);
25769
25791
  if (this.back?.dims === void 0) {
@@ -26580,7 +26602,7 @@ var Niivue = class _Niivue {
26580
26602
  * @param esm - bundled version of NiiVue
26581
26603
  * @example
26582
26604
  * const javascript = this.generateLoadDocumentJavaScript("gl1");
26583
- * const html = `<html><body><canvas id="gl1"></canvas><script type="module" async>
26605
+ * const html = `<html><body><canvas id="gl1"></canvas><script type="module" async>
26584
26606
  ${javascript}</script></body></html>`;
26585
26607
  */
26586
26608
  async generateLoadDocumentJavaScript(canvasId, esm) {
@@ -26588,26 +26610,26 @@ var Niivue = class _Niivue {
26588
26610
  const base64 = await NVUtilities.compressToBase64String(JSON.stringify(json));
26589
26611
  const javascript = `
26590
26612
  ${esm}
26591
-
26592
- async function saveNiivueAsHtml(pageName) {
26613
+
26614
+ async function saveNiivueAsHtml(pageName) {
26593
26615
  //get new docstring
26594
26616
  const docString = nv1.json();
26595
- const html =
26617
+ const html =
26596
26618
  document.getElementsByTagName("html")[0]
26597
26619
  .innerHTML.replace(base64, await NVUtilities.compressToBase64String(JSON.stringify(docString)));
26598
26620
  NVUtilities.download(html, pageName, "application/html");
26599
26621
  }
26600
-
26622
+
26601
26623
  var nv1 = new Niivue();
26602
- nv1.attachTo("${canvasId}");
26624
+ nv1.attachTo("${canvasId}");
26603
26625
  var base64 = "${base64}";
26604
26626
  NVUtilities.decompressBase64String(base64).then((jsonText) => {
26605
26627
  var json = JSON.parse(jsonText); // string -> JSON
26606
- var doc = NVDocument.loadFromJSON(json);
26628
+ var doc = NVDocument.loadFromJSON(json);
26607
26629
  nv1.loadDocument(doc);
26608
26630
  nv1.updateGLVolume();
26609
26631
  });
26610
-
26632
+
26611
26633
  `;
26612
26634
  return javascript;
26613
26635
  }
@@ -26681,14 +26703,14 @@ var Niivue = class _Niivue {
26681
26703
  <main>
26682
26704
  <canvas id="gl1"></canvas>
26683
26705
  </main>
26684
- <script type="module" async>
26706
+ <script type="module" async>
26685
26707
  ${javascript}
26686
26708
  function saveAsHtml() {
26687
26709
  saveNiivueAsHtml("page.html");
26688
- }
26710
+ }
26689
26711
  // assign our event handler
26690
26712
  var button = document.getElementById("save");
26691
- button.onclick = saveAsHtml;
26713
+ button.onclick = saveAsHtml;
26692
26714
  </script>
26693
26715
  </body>
26694
26716
  </html>`;
@@ -29747,11 +29769,43 @@ var Niivue = class _Niivue {
29747
29769
  }
29748
29770
  if (this.opts.drawingEnabled) {
29749
29771
  const pt = this.frac2vox(this.scene.crosshairPos);
29772
+ if (this.opts.clickToSegment) {
29773
+ const radius = this.opts.clickToSegmentRadius;
29774
+ const steps = this.opts.clickToSegmentSteps;
29775
+ const brightOrDark = this.opts.clickToSegmentBright ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
29776
+ this.drawPenFillPts = [];
29777
+ this.drawPenAxCorSag = axCorSag;
29778
+ for (let i2 = 1; i2 <= steps; i2++) {
29779
+ const angle = i2 / steps * 2 * Math.PI;
29780
+ let xVox = pt[0] + radius * Math.cos(angle);
29781
+ let yVox = pt[1] + radius * Math.sin(angle);
29782
+ const zVox = pt[2];
29783
+ xVox = Math.round(xVox);
29784
+ yVox = Math.round(yVox);
29785
+ this.drawPt(xVox, yVox, zVox, this.opts.penValue);
29786
+ this.drawPenFillPts.push([xVox, yVox, pt[2]]);
29787
+ if (i2 === steps) {
29788
+ this.drawFloodFill([xVox, yVox, pt[2]], 0, brightOrDark, NaN, NaN, this.opts.floodFillNeighbors);
29789
+ }
29790
+ }
29791
+ this.drawScene();
29792
+ this.createOnLocationChange(axCorSag);
29793
+ const info = this.getDescriptives(0, [], true);
29794
+ this.onClickToSegment({ mL: info.volumeML, mm3: info.volumeMM3 });
29795
+ return;
29796
+ }
29750
29797
  if (!isFinite(this.opts.penValue) || this.opts.penValue < 0 || Object.is(this.opts.penValue, -0)) {
29751
29798
  if (!isFinite(this.opts.penValue)) {
29752
- this.drawFloodFill(pt, 0, this.opts.penValue, this.opts.floodFillNeighbors);
29799
+ this.drawFloodFill(pt, 0, this.opts.penValue, NaN, NaN, this.opts.floodFillNeighbors);
29753
29800
  } else {
29754
- this.drawFloodFill(pt, Math.abs(this.opts.penValue), this.opts.floodFillNeighbors);
29801
+ this.drawFloodFill(
29802
+ pt,
29803
+ Math.abs(this.opts.penValue),
29804
+ this.opts.penValue,
29805
+ NaN,
29806
+ NaN,
29807
+ this.opts.floodFillNeighbors
29808
+ );
29755
29809
  }
29756
29810
  return;
29757
29811
  }
@@ -31319,7 +31373,13 @@ var Niivue = class _Niivue {
31319
31373
  const mm2 = this.frac2mm(this.scene.crosshairPos, 0, true);
31320
31374
  const vox = v.mm2vox(mm2);
31321
31375
  const val = v.getValue(vox[0], vox[1], vox[2], v.frame4D);
31322
- return { name: v.name, value: val, id: v.id, mm: mm2, vox };
31376
+ return {
31377
+ name: v.name,
31378
+ value: val,
31379
+ id: v.id,
31380
+ mm: mm2,
31381
+ vox
31382
+ };
31323
31383
  }),
31324
31384
  string: str
31325
31385
  };
@@ -32254,7 +32314,7 @@ var Niivue = class _Niivue {
32254
32314
  const scaleW = this.gl.canvas.width / mxRowWid;
32255
32315
  const scaleH = this.effectiveCanvasHeight() / top;
32256
32316
  scale = Math.min(scaleW, scaleH);
32257
- if (this.centerMosaic) {
32317
+ if (this.opts.centerMosaic) {
32258
32318
  marginLeft = Math.floor(0.5 * (this.gl.canvas.width - mxRowWid * scale));
32259
32319
  marginTop = Math.floor(0.5 * (this.effectiveCanvasHeight() - top * scale));
32260
32320
  }