@niivue/niivue 0.16.0 → 0.17.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/README.md CHANGED
@@ -38,7 +38,7 @@ We host many NiiVue examples via github pages. These are updated and deployed au
38
38
 
39
39
  ## existing html page
40
40
  ```html
41
- <script src="https://unpkg.com/@niivue/niivue@0.16.0/dist/niivue.umd.js"></script>
41
+ <script src="https://unpkg.com/@niivue/niivue@0.17.0/dist/niivue.umd.js"></script>
42
42
 
43
43
  <canvas id="gl" height=480 width=640></canvas>
44
44
 
package/dist/niivue.es.js CHANGED
@@ -10559,6 +10559,16 @@ NVImage.prototype.vox2mm = function(XYZ, mtx) {
10559
10559
  let pos3 = fromValues$1(pos[0], pos[1], pos[2]);
10560
10560
  return pos3;
10561
10561
  };
10562
+ NVImage.prototype.mm2vox = function(mm) {
10563
+ let sform = fromValues$2(...this.hdr.affine.flat());
10564
+ let out = clone(sform);
10565
+ transpose(out, sform);
10566
+ invert(out, out);
10567
+ let pos = fromValues(mm[0], mm[1], mm[2], 1);
10568
+ transformMat4(pos, pos, out);
10569
+ let pos3 = fromValues$1(pos[0], pos[1], pos[2]);
10570
+ return [Math.round(pos3[0]), Math.round(pos3[1]), Math.round(pos3[2])];
10571
+ };
10562
10572
  NVImage.prototype.arrayEquals = function(a, b) {
10563
10573
  return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((val, index) => val === b[index]);
10564
10574
  };
@@ -10785,35 +10795,37 @@ String.prototype.getBytes = function() {
10785
10795
  }
10786
10796
  return bytes;
10787
10797
  };
10798
+ NVImage.prototype.getValue = function(x, y, z) {
10799
+ const { nx, ny } = this.getImageMetadata();
10800
+ return this.img[x + y * nx + z * nx * ny];
10801
+ };
10788
10802
  const Log = function(logLevel) {
10789
- this.DEBUG = "debug";
10790
- this.INFO = "info";
10791
- this.WARN = "warn";
10792
- this.ERROR = "error";
10793
- this.LOG_PREFIX = "NiiVue: ";
10803
+ this.LOGGING_ON = true;
10804
+ this.LOGGING_OFF = false;
10805
+ this.LOG_PREFIX = "NiiVue:";
10794
10806
  this.logLevel = logLevel;
10795
10807
  };
10796
10808
  Log.prototype.getTimeStamp = function() {
10797
- return `${this.LOG_PREFIX}${Date.now()} `;
10809
+ return `${this.LOG_PREFIX} `;
10798
10810
  };
10799
10811
  Log.prototype.debug = function() {
10800
- if (this.logLevel === this.DEBUG) {
10801
- console.log(this.getTimeStamp(), ...arguments);
10812
+ if (this.logLevel === this.LOGGING_ON) {
10813
+ console.log(this.getTimeStamp(), "DEBUG", ...arguments);
10802
10814
  }
10803
10815
  };
10804
10816
  Log.prototype.info = function() {
10805
- if (this.logLevel === this.INFO) {
10806
- console.log(this.getTimeStamp(), ...arguments);
10817
+ if (this.logLevel === this.LOGGING_ON) {
10818
+ console.log(this.getTimeStamp(), "INFO", ...arguments);
10807
10819
  }
10808
10820
  };
10809
10821
  Log.prototype.warn = function() {
10810
- if (this.logLevel === this.WARN) {
10811
- console.warn(this.getTimeStamp(), ...arguments);
10822
+ if (this.logLevel === this.LOGGING_ON) {
10823
+ console.warn(this.getTimeStamp(), "WARN", ...arguments);
10812
10824
  }
10813
10825
  };
10814
10826
  Log.prototype.error = function() {
10815
- if (this.logLevel === this.ERROR) {
10816
- console.error(this.getTimeStamp(), ...arguments);
10827
+ if (this.logLevel === this.LOGGING_ON) {
10828
+ console.error(this.getTimeStamp(), "ERROR", ...arguments);
10817
10829
  }
10818
10830
  };
10819
10831
  Log.prototype.setLogLevel = function(logLevel) {
@@ -12370,7 +12382,7 @@ const Niivue = function(options = {}) {
12370
12382
  viewModeHotKey: "KeyV",
12371
12383
  keyDebounceTime: 50,
12372
12384
  isRadiologicalConvention: false,
12373
- logLevel: "info"
12385
+ logging: false
12374
12386
  };
12375
12387
  this.canvas = null;
12376
12388
  this.gl = null;
@@ -12440,7 +12452,7 @@ const Niivue = function(options = {}) {
12440
12452
  this.intensityRange$ = new Subject();
12441
12453
  this.scene.location$ = new Subject();
12442
12454
  this.scene.loading$ = new Subject();
12443
- this.loadingText = "drag and drop to start";
12455
+ this.loadingText = "waiting for images...";
12444
12456
  this.currentClipPlaneIndex = 0;
12445
12457
  this.lastCalled = new Date().getTime();
12446
12458
  this.multiTouchGesture = false;
@@ -12453,7 +12465,7 @@ const Niivue = function(options = {}) {
12453
12465
  for (let prop in this.defaults) {
12454
12466
  this.opts[prop] = options[prop] === void 0 ? this.defaults[prop] : options[prop];
12455
12467
  }
12456
- log.setLogLevel(this.opts.logLevel);
12468
+ log.setLogLevel(this.opts.logging);
12457
12469
  this.eventsToSubjects = {
12458
12470
  location: this.scene.location$,
12459
12471
  loading: this.scene.loading$
@@ -12462,7 +12474,7 @@ const Niivue = function(options = {}) {
12462
12474
  };
12463
12475
  Niivue.prototype.attachTo = async function(id) {
12464
12476
  await this.attachToCanvas(document.getElementById(id));
12465
- log.debug("attached to canvas", [1, 0, 1], false);
12477
+ log.debug("attached to element with id: ", id);
12466
12478
  return this;
12467
12479
  };
12468
12480
  Niivue.prototype.on = function(event, callback) {
@@ -12587,14 +12599,14 @@ function intensityRaw2Scaled(hdr, raw) {
12587
12599
  hdr.scl_slope = 1;
12588
12600
  return raw * hdr.scl_slope + hdr.scl_inter;
12589
12601
  }
12590
- Niivue.prototype.calculateNewRange = function() {
12602
+ Niivue.prototype.calculateNewRange = function(volIdx = 0) {
12591
12603
  if (this.sliceType === this.sliceTypeRender) {
12592
12604
  return;
12593
12605
  }
12594
12606
  let frac = this.canvasPos2frac([this.dragStart[0], this.dragStart[1]]);
12595
- let startVox = this.frac2vox(frac);
12607
+ let startVox = this.frac2vox(frac, volIdx);
12596
12608
  frac = this.canvasPos2frac([this.dragEnd[0], this.dragEnd[1]]);
12597
- let endVox = this.frac2vox(frac);
12609
+ let endVox = this.frac2vox(frac, volIdx);
12598
12610
  let hi = -Number.MAX_VALUE, lo = Number.MAX_VALUE;
12599
12611
  let xrange;
12600
12612
  let yrange;
@@ -12609,8 +12621,8 @@ Niivue.prototype.calculateNewRange = function() {
12609
12621
  } else if (startVox[2] - endVox[2] === 0) {
12610
12622
  zrange[1] = startVox[2] + 1;
12611
12623
  }
12612
- const hdr = this.volumes[0].hdr;
12613
- const img = this.volumes[0].img;
12624
+ const hdr = this.volumes[volIdx].hdr;
12625
+ const img = this.volumes[volIdx].img;
12614
12626
  const xdim = hdr.dims[1];
12615
12627
  const ydim = hdr.dims[2];
12616
12628
  for (let z = zrange[0]; z < zrange[1]; z++) {
@@ -12630,8 +12642,8 @@ Niivue.prototype.calculateNewRange = function() {
12630
12642
  }
12631
12643
  var mnScale = intensityRaw2Scaled(hdr, lo);
12632
12644
  var mxScale = intensityRaw2Scaled(hdr, hi);
12633
- this.volumes[0].cal_min = mnScale;
12634
- this.volumes[0].cal_max = mxScale;
12645
+ this.volumes[volIdx].cal_min = mnScale;
12646
+ this.volumes[volIdx].cal_max = mxScale;
12635
12647
  this.intensityRange$.next([mnScale, mxScale]);
12636
12648
  };
12637
12649
  Niivue.prototype.mouseUpListener = function() {
@@ -12986,12 +12998,11 @@ Niivue.prototype.loadVolumes = async function(volumeList) {
12986
12998
  this.loadingText = "loading...";
12987
12999
  this.drawScene();
12988
13000
  } else {
12989
- this.loadingText = "drag and drop to start";
13001
+ this.loadingText = "waiting for images...";
12990
13002
  }
12991
13003
  });
12992
- if (!this.initialized) {
12993
- await this.init();
12994
- }
13004
+ if (!this.initialized)
13005
+ ;
12995
13006
  this.volumes = [];
12996
13007
  this.gl.clearColor(0, 0, 0, 1);
12997
13008
  this.gl.clear(this.gl.COLOR_BUFFER_BIT);
@@ -13107,6 +13118,11 @@ Niivue.prototype.initText = async function() {
13107
13118
  this.drawLoadingText(this.loadingText);
13108
13119
  };
13109
13120
  Niivue.prototype.init = async function() {
13121
+ let rendererInfo = this.gl.getExtension("WEBGL_debug_renderer_info");
13122
+ let vendor = this.gl.getParameter(rendererInfo.UNMASKED_VENDOR_WEBGL);
13123
+ let renderer = this.gl.getParameter(rendererInfo.UNMASKED_RENDERER_WEBGL);
13124
+ log.info("renderer vendor: ", vendor);
13125
+ log.info("renderer: ", renderer);
13110
13126
  this.gl.enable(this.gl.CULL_FACE);
13111
13127
  this.gl.cullFace(this.gl.FRONT);
13112
13128
  this.gl.enable(this.gl.BLEND);
@@ -13534,7 +13550,13 @@ Niivue.prototype.mouseClick = function(x, y, posChange = 0, isDelta = true) {
13534
13550
  this.scene.location$.next({
13535
13551
  mm: this.frac2mm(this.scene.crosshairPos),
13536
13552
  vox: this.frac2vox(this.scene.crosshairPos),
13537
- frac: this.scene.crosshairPos
13553
+ frac: this.scene.crosshairPos,
13554
+ values: this.volumes.map((v, index) => {
13555
+ let mm = this.frac2mm(this.scene.crosshairPos);
13556
+ let vox = v.mm2vox(mm);
13557
+ let val = v.getValue(...vox);
13558
+ return val;
13559
+ })
13538
13560
  });
13539
13561
  return;
13540
13562
  }
@@ -13554,7 +13576,13 @@ Niivue.prototype.mouseClick = function(x, y, posChange = 0, isDelta = true) {
13554
13576
  this.scene.location$.next({
13555
13577
  mm: this.frac2mm(this.scene.crosshairPos),
13556
13578
  vox: this.frac2vox(this.scene.crosshairPos),
13557
- frac: this.scene.crosshairPos
13579
+ frac: this.scene.crosshairPos,
13580
+ values: this.volumes.map((v, index) => {
13581
+ let mm = this.frac2mm(this.scene.crosshairPos);
13582
+ let vox = v.mm2vox(mm);
13583
+ let val = v.getValue(...vox);
13584
+ return val;
13585
+ })
13558
13586
  });
13559
13587
  return;
13560
13588
  } else {
@@ -13848,16 +13876,16 @@ Niivue.prototype.draw3D = function() {
13848
13876
  this.sync();
13849
13877
  return posString;
13850
13878
  };
13851
- Niivue.prototype.mm2frac = function(mm) {
13879
+ Niivue.prototype.mm2frac = function(mm, volIdx = 0) {
13852
13880
  let mm4 = fromValues(mm[0], mm[1], mm[2], 1);
13853
- let d = this.back.dims;
13881
+ let d = this.volumes[volIdx].hdr.dims;
13854
13882
  let frac = [0, 0, 0];
13855
13883
  if (typeof d === "undefined") {
13856
13884
  return frac;
13857
13885
  }
13858
13886
  if (d[1] < 1 || d[2] < 1 || d[3] < 1)
13859
13887
  return frac;
13860
- let sform = clone(this.back.matRAS);
13888
+ let sform = clone(this.volumes[volIdx].matRAS);
13861
13889
  transpose(sform, sform);
13862
13890
  invert(sform, sform);
13863
13891
  transformMat4(mm4, mm4, sform);
@@ -13866,32 +13894,31 @@ Niivue.prototype.mm2frac = function(mm) {
13866
13894
  frac[2] = (mm4[2] + 0.5) / d[3];
13867
13895
  return frac;
13868
13896
  };
13869
- Niivue.prototype.vox2frac = function(vox) {
13897
+ Niivue.prototype.vox2frac = function(vox, volIdx = 0) {
13870
13898
  let frac = [
13871
- (vox[0] + 0.5) / this.back.dims[1],
13872
- (vox[1] + 0.5) / this.back.dims[2],
13873
- (vox[2] + 0.5) / this.back.dims[3]
13899
+ (vox[0] + 0.5) / this.volumes[volIdx].hdr.dims[1],
13900
+ (vox[1] + 0.5) / this.volumes[volIdx].hdr.dims[2],
13901
+ (vox[2] + 0.5) / this.volumes[volIdx].hdr.dims[3]
13874
13902
  ];
13875
13903
  return frac;
13876
13904
  };
13877
- Niivue.prototype.frac2vox = function(frac) {
13905
+ Niivue.prototype.frac2vox = function(frac, volIdx = 0) {
13878
13906
  let vox = [
13879
- Math.round(frac[0] * this.back.dims[1] - 0.5),
13880
- Math.round(frac[1] * this.back.dims[2] - 0.5),
13881
- Math.round(frac[2] * this.back.dims[3] - 0.5)
13907
+ Math.round(frac[0] * this.volumes[volIdx].hdr.dims[1] - 0.5),
13908
+ Math.round(frac[1] * this.volumes[volIdx].hdr.dims[2] - 0.5),
13909
+ Math.round(frac[2] * this.volumes[volIdx].hdr.dims[3] - 0.5)
13882
13910
  ];
13883
13911
  return vox;
13884
13912
  };
13885
- Niivue.prototype.frac2mm = function(frac) {
13913
+ Niivue.prototype.frac2mm = function(frac, volIdx = 0) {
13886
13914
  let pos = fromValues(frac[0], frac[1], frac[2], 1);
13887
- let dim = fromValues(this.back.dims[1], this.back.dims[2], this.back.dims[3], 1);
13888
- let sform = clone(this.back.matRAS);
13915
+ let dim = fromValues(this.volumes[volIdx].hdr.dims[1], this.volumes[volIdx].hdr.dims[2], this.volumes[volIdx].hdr.dims[3], 1);
13916
+ let sform = clone(this.volumes[volIdx].matRAS);
13889
13917
  transpose(sform, sform);
13890
13918
  mul(pos, pos, dim);
13891
13919
  let shim = fromValues(-0.5, -0.5, -0.5, 0);
13892
13920
  add(pos, pos, shim);
13893
13921
  transformMat4(pos, pos, sform);
13894
- this.mm2frac(pos);
13895
13922
  return pos;
13896
13923
  };
13897
13924
  Niivue.prototype.canvasPos2frac = function(canvasPos) {