@niivue/niivue 0.24.2 → 0.24.3
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/niivue.es.js +942 -95
- package/dist/niivue.umd.js +110 -79
- package/package.json +1 -1
- package/src/colortables.js +1 -1
- package/src/indexDraw.html +4 -2
- package/src/niivue.js +460 -48
- package/src/nvimage.js +7 -4
- package/src/nvmesh.js +33 -14
- package/src/shader-srcs.js +39 -8
package/dist/niivue.es.js
CHANGED
|
@@ -787,6 +787,14 @@ float frac2ndc(vec3 frac) {
|
|
|
787
787
|
}
|
|
788
788
|
void main() {
|
|
789
789
|
fColor = vec4(0.0,0.0,0.0,0.0);
|
|
790
|
+
vec4 clipPlaneColorX = clipPlaneColor;
|
|
791
|
+
//if (clipPlaneColor.a < 0.0)
|
|
792
|
+
// clipPlaneColorX.a = - 1.0;
|
|
793
|
+
bool isColorPlaneInVolume = false;
|
|
794
|
+
if (clipPlaneColorX.a < 0.0) {
|
|
795
|
+
isColorPlaneInVolume = true;
|
|
796
|
+
clipPlaneColorX.a = 0.0;
|
|
797
|
+
}
|
|
790
798
|
//fColor = vec4(vColor.rgb, 1.0); return;
|
|
791
799
|
vec3 start = vColor;
|
|
792
800
|
gl_FragDepth = 0.0;
|
|
@@ -818,7 +826,7 @@ void main() {
|
|
|
818
826
|
}
|
|
819
827
|
if ((samplePos.a >= len) && ((overlays < 1.0) || (backgroundMasksOverlays > 0))) {
|
|
820
828
|
if (isClip)
|
|
821
|
-
fColor +=
|
|
829
|
+
fColor += clipPlaneColorX;
|
|
822
830
|
return;
|
|
823
831
|
}
|
|
824
832
|
fColor = vec4(1.0, 1.0, 1.0, 1.0);
|
|
@@ -850,8 +858,10 @@ void main() {
|
|
|
850
858
|
gl_FragDepth = frac2ndc(firstHit.xyz);
|
|
851
859
|
colAcc.a = (colAcc.a / earlyTermination) * backOpacity;
|
|
852
860
|
fColor = colAcc;
|
|
853
|
-
if (isClip) //CR
|
|
854
|
-
|
|
861
|
+
//if (isClip) //CR
|
|
862
|
+
if ((isColorPlaneInVolume) && (clipPos.a != samplePos.a) && (abs(firstHit.a - clipPos.a) < deltaDir.a))
|
|
863
|
+
fColor.rgb = mix(fColor.rgb, clipPlaneColorX.rgb, abs(clipPlaneColor.a));
|
|
864
|
+
//fColor.rgb = mix(fColor.rgb, clipPlaneColorX.rgb, clipPlaneColorX.a * 0.65);
|
|
855
865
|
if (overlays < 1.0) return;
|
|
856
866
|
//overlay pass
|
|
857
867
|
len = lenNoClip;
|
|
@@ -866,7 +876,7 @@ void main() {
|
|
|
866
876
|
}
|
|
867
877
|
if (samplePos.a >= len) {
|
|
868
878
|
if (isClip && (fColor.a == 0.0))
|
|
869
|
-
fColor +=
|
|
879
|
+
fColor += clipPlaneColorX;
|
|
870
880
|
return;
|
|
871
881
|
}
|
|
872
882
|
samplePos -= deltaDirFast;
|
|
@@ -894,7 +904,7 @@ void main() {
|
|
|
894
904
|
}
|
|
895
905
|
if (samplePos.a >= len) {
|
|
896
906
|
if (isClip && (fColor.a == 0.0))
|
|
897
|
-
fColor +=
|
|
907
|
+
fColor += clipPlaneColorX;
|
|
898
908
|
return;
|
|
899
909
|
}
|
|
900
910
|
//if (overFirstHit.a < len)
|
|
@@ -1290,15 +1300,13 @@ var fragGrowCutShader = `#version 300 es
|
|
|
1290
1300
|
layout(location = 0) out int label;
|
|
1291
1301
|
layout(location = 1) out int strength;
|
|
1292
1302
|
in vec2 TexCoord;
|
|
1293
|
-
|
|
1303
|
+
uniform int finalPass;
|
|
1294
1304
|
uniform float coordZ;
|
|
1295
1305
|
uniform lowp sampler3D in3D;
|
|
1296
1306
|
uniform highp isampler3D inputTexture0; // background
|
|
1297
1307
|
uniform highp isampler3D inputTexture1; // label
|
|
1298
1308
|
uniform highp isampler3D inputTexture2; // strength
|
|
1299
1309
|
void main(void) {
|
|
1300
|
-
//int MAX_STRENGTH = int(255);
|
|
1301
|
-
int MAX_STRENGTH = int(10000);
|
|
1302
1310
|
vec3 interpolatedTextureCoordinate = vec3(TexCoord.xy, coordZ);
|
|
1303
1311
|
ivec3 size = textureSize(inputTexture0, 0);
|
|
1304
1312
|
ivec3 texelIndex = ivec3(floor(interpolatedTextureCoordinate * vec3(size)));
|
|
@@ -1322,6 +1330,29 @@ void main(void) {
|
|
|
1322
1330
|
}
|
|
1323
1331
|
}
|
|
1324
1332
|
}
|
|
1333
|
+
if (finalPass < 1)
|
|
1334
|
+
return;
|
|
1335
|
+
int ok = 1;
|
|
1336
|
+
ivec4 labelCount = ivec4(0,0,0,0);
|
|
1337
|
+
for (int k = -1; k <= 1; k++)
|
|
1338
|
+
for (int j = -1; j <= 1; j++)
|
|
1339
|
+
for (int i = -1; i <= 1; i++) {
|
|
1340
|
+
ivec3 neighborIndex = texelIndex + ivec3(i,j,k);
|
|
1341
|
+
int ilabel = texelFetch(inputTexture1, neighborIndex, 0).r;
|
|
1342
|
+
if ((ilabel < 0) || (ilabel > 3))
|
|
1343
|
+
ok = 0;
|
|
1344
|
+
else
|
|
1345
|
+
labelCount[ilabel]++;
|
|
1346
|
+
}
|
|
1347
|
+
if (ok != 1) {
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
int maxIdx = 0;
|
|
1351
|
+
for (int i = 1; i < 4; i++) {
|
|
1352
|
+
if (labelCount[i] > labelCount[maxIdx])
|
|
1353
|
+
maxIdx = i;
|
|
1354
|
+
}
|
|
1355
|
+
label = maxIdx;
|
|
1325
1356
|
}`;
|
|
1326
1357
|
var vertSurfaceShader = `#version 300 es
|
|
1327
1358
|
layout(location=0) in vec3 pos;
|
|
@@ -1672,6 +1703,18 @@ function __extends(d, b) {
|
|
|
1672
1703
|
}
|
|
1673
1704
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
1674
1705
|
}
|
|
1706
|
+
var __assign = function() {
|
|
1707
|
+
__assign = Object.assign || function __assign2(t) {
|
|
1708
|
+
for (var s, i2 = 1, n = arguments.length; i2 < n; i2++) {
|
|
1709
|
+
s = arguments[i2];
|
|
1710
|
+
for (var p in s)
|
|
1711
|
+
if (Object.prototype.hasOwnProperty.call(s, p))
|
|
1712
|
+
t[p] = s[p];
|
|
1713
|
+
}
|
|
1714
|
+
return t;
|
|
1715
|
+
};
|
|
1716
|
+
return __assign.apply(this, arguments);
|
|
1717
|
+
};
|
|
1675
1718
|
function __values(o) {
|
|
1676
1719
|
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i2 = 0;
|
|
1677
1720
|
if (m)
|
|
@@ -1916,6 +1959,22 @@ function reportUnhandledError(err2) {
|
|
|
1916
1959
|
}
|
|
1917
1960
|
function noop() {
|
|
1918
1961
|
}
|
|
1962
|
+
var COMPLETE_NOTIFICATION = function() {
|
|
1963
|
+
return createNotification("C", void 0, void 0);
|
|
1964
|
+
}();
|
|
1965
|
+
function errorNotification(error) {
|
|
1966
|
+
return createNotification("E", void 0, error);
|
|
1967
|
+
}
|
|
1968
|
+
function nextNotification(value2) {
|
|
1969
|
+
return createNotification("N", value2, void 0);
|
|
1970
|
+
}
|
|
1971
|
+
function createNotification(kind, value2, error) {
|
|
1972
|
+
return {
|
|
1973
|
+
kind,
|
|
1974
|
+
value: value2,
|
|
1975
|
+
error
|
|
1976
|
+
};
|
|
1977
|
+
}
|
|
1919
1978
|
var context = null;
|
|
1920
1979
|
function errorContext(cb) {
|
|
1921
1980
|
if (config.useDeprecatedSynchronousErrorHandling) {
|
|
@@ -1954,24 +2013,24 @@ var Subscriber = function(_super) {
|
|
|
1954
2013
|
return new SafeSubscriber(next, error, complete);
|
|
1955
2014
|
};
|
|
1956
2015
|
Subscriber2.prototype.next = function(value2) {
|
|
1957
|
-
if (this.isStopped)
|
|
1958
|
-
;
|
|
1959
|
-
else {
|
|
2016
|
+
if (this.isStopped) {
|
|
2017
|
+
handleStoppedNotification(nextNotification(value2), this);
|
|
2018
|
+
} else {
|
|
1960
2019
|
this._next(value2);
|
|
1961
2020
|
}
|
|
1962
2021
|
};
|
|
1963
2022
|
Subscriber2.prototype.error = function(err2) {
|
|
1964
|
-
if (this.isStopped)
|
|
1965
|
-
;
|
|
1966
|
-
else {
|
|
2023
|
+
if (this.isStopped) {
|
|
2024
|
+
handleStoppedNotification(errorNotification(err2), this);
|
|
2025
|
+
} else {
|
|
1967
2026
|
this.isStopped = true;
|
|
1968
2027
|
this._error(err2);
|
|
1969
2028
|
}
|
|
1970
2029
|
};
|
|
1971
2030
|
Subscriber2.prototype.complete = function() {
|
|
1972
|
-
if (this.isStopped)
|
|
1973
|
-
;
|
|
1974
|
-
else {
|
|
2031
|
+
if (this.isStopped) {
|
|
2032
|
+
handleStoppedNotification(COMPLETE_NOTIFICATION, this);
|
|
2033
|
+
} else {
|
|
1975
2034
|
this.isStopped = true;
|
|
1976
2035
|
this._complete();
|
|
1977
2036
|
}
|
|
@@ -2084,6 +2143,12 @@ function handleUnhandledError(error) {
|
|
|
2084
2143
|
function defaultErrorHandler(err2) {
|
|
2085
2144
|
throw err2;
|
|
2086
2145
|
}
|
|
2146
|
+
function handleStoppedNotification(notification, subscriber) {
|
|
2147
|
+
var onStoppedNotification = config.onStoppedNotification;
|
|
2148
|
+
onStoppedNotification && timeoutProvider.setTimeout(function() {
|
|
2149
|
+
return onStoppedNotification(notification, subscriber);
|
|
2150
|
+
});
|
|
2151
|
+
}
|
|
2087
2152
|
var EMPTY_OBSERVER = {
|
|
2088
2153
|
closed: true,
|
|
2089
2154
|
next: noop,
|
|
@@ -2361,6 +2426,289 @@ var AnonymousSubject = function(_super) {
|
|
|
2361
2426
|
};
|
|
2362
2427
|
return AnonymousSubject2;
|
|
2363
2428
|
}(Subject);
|
|
2429
|
+
var dateTimestampProvider = {
|
|
2430
|
+
now: function() {
|
|
2431
|
+
return (dateTimestampProvider.delegate || Date).now();
|
|
2432
|
+
},
|
|
2433
|
+
delegate: void 0
|
|
2434
|
+
};
|
|
2435
|
+
var ReplaySubject = function(_super) {
|
|
2436
|
+
__extends(ReplaySubject2, _super);
|
|
2437
|
+
function ReplaySubject2(_bufferSize, _windowTime, _timestampProvider) {
|
|
2438
|
+
if (_bufferSize === void 0) {
|
|
2439
|
+
_bufferSize = Infinity;
|
|
2440
|
+
}
|
|
2441
|
+
if (_windowTime === void 0) {
|
|
2442
|
+
_windowTime = Infinity;
|
|
2443
|
+
}
|
|
2444
|
+
if (_timestampProvider === void 0) {
|
|
2445
|
+
_timestampProvider = dateTimestampProvider;
|
|
2446
|
+
}
|
|
2447
|
+
var _this = _super.call(this) || this;
|
|
2448
|
+
_this._bufferSize = _bufferSize;
|
|
2449
|
+
_this._windowTime = _windowTime;
|
|
2450
|
+
_this._timestampProvider = _timestampProvider;
|
|
2451
|
+
_this._buffer = [];
|
|
2452
|
+
_this._infiniteTimeWindow = true;
|
|
2453
|
+
_this._infiniteTimeWindow = _windowTime === Infinity;
|
|
2454
|
+
_this._bufferSize = Math.max(1, _bufferSize);
|
|
2455
|
+
_this._windowTime = Math.max(1, _windowTime);
|
|
2456
|
+
return _this;
|
|
2457
|
+
}
|
|
2458
|
+
ReplaySubject2.prototype.next = function(value2) {
|
|
2459
|
+
var _a2 = this, isStopped = _a2.isStopped, _buffer = _a2._buffer, _infiniteTimeWindow = _a2._infiniteTimeWindow, _timestampProvider = _a2._timestampProvider, _windowTime = _a2._windowTime;
|
|
2460
|
+
if (!isStopped) {
|
|
2461
|
+
_buffer.push(value2);
|
|
2462
|
+
!_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);
|
|
2463
|
+
}
|
|
2464
|
+
this._trimBuffer();
|
|
2465
|
+
_super.prototype.next.call(this, value2);
|
|
2466
|
+
};
|
|
2467
|
+
ReplaySubject2.prototype._subscribe = function(subscriber) {
|
|
2468
|
+
this._throwIfClosed();
|
|
2469
|
+
this._trimBuffer();
|
|
2470
|
+
var subscription = this._innerSubscribe(subscriber);
|
|
2471
|
+
var _a2 = this, _infiniteTimeWindow = _a2._infiniteTimeWindow, _buffer = _a2._buffer;
|
|
2472
|
+
var copy2 = _buffer.slice();
|
|
2473
|
+
for (var i2 = 0; i2 < copy2.length && !subscriber.closed; i2 += _infiniteTimeWindow ? 1 : 2) {
|
|
2474
|
+
subscriber.next(copy2[i2]);
|
|
2475
|
+
}
|
|
2476
|
+
this._checkFinalizedStatuses(subscriber);
|
|
2477
|
+
return subscription;
|
|
2478
|
+
};
|
|
2479
|
+
ReplaySubject2.prototype._trimBuffer = function() {
|
|
2480
|
+
var _a2 = this, _bufferSize = _a2._bufferSize, _timestampProvider = _a2._timestampProvider, _buffer = _a2._buffer, _infiniteTimeWindow = _a2._infiniteTimeWindow;
|
|
2481
|
+
var adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;
|
|
2482
|
+
_bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);
|
|
2483
|
+
if (!_infiniteTimeWindow) {
|
|
2484
|
+
var now = _timestampProvider.now();
|
|
2485
|
+
var last = 0;
|
|
2486
|
+
for (var i2 = 1; i2 < _buffer.length && _buffer[i2] <= now; i2 += 2) {
|
|
2487
|
+
last = i2;
|
|
2488
|
+
}
|
|
2489
|
+
last && _buffer.splice(0, last + 1);
|
|
2490
|
+
}
|
|
2491
|
+
};
|
|
2492
|
+
return ReplaySubject2;
|
|
2493
|
+
}(Subject);
|
|
2494
|
+
var Action = function(_super) {
|
|
2495
|
+
__extends(Action2, _super);
|
|
2496
|
+
function Action2(scheduler, work) {
|
|
2497
|
+
return _super.call(this) || this;
|
|
2498
|
+
}
|
|
2499
|
+
Action2.prototype.schedule = function(state, delay) {
|
|
2500
|
+
return this;
|
|
2501
|
+
};
|
|
2502
|
+
return Action2;
|
|
2503
|
+
}(Subscription);
|
|
2504
|
+
var intervalProvider = {
|
|
2505
|
+
setInterval: function(handler, timeout) {
|
|
2506
|
+
var args = [];
|
|
2507
|
+
for (var _i = 2; _i < arguments.length; _i++) {
|
|
2508
|
+
args[_i - 2] = arguments[_i];
|
|
2509
|
+
}
|
|
2510
|
+
var delegate = intervalProvider.delegate;
|
|
2511
|
+
if (delegate === null || delegate === void 0 ? void 0 : delegate.setInterval) {
|
|
2512
|
+
return delegate.setInterval.apply(delegate, __spreadArray([handler, timeout], __read(args)));
|
|
2513
|
+
}
|
|
2514
|
+
return setInterval.apply(void 0, __spreadArray([handler, timeout], __read(args)));
|
|
2515
|
+
},
|
|
2516
|
+
clearInterval: function(handle) {
|
|
2517
|
+
var delegate = intervalProvider.delegate;
|
|
2518
|
+
return ((delegate === null || delegate === void 0 ? void 0 : delegate.clearInterval) || clearInterval)(handle);
|
|
2519
|
+
},
|
|
2520
|
+
delegate: void 0
|
|
2521
|
+
};
|
|
2522
|
+
var AsyncAction = function(_super) {
|
|
2523
|
+
__extends(AsyncAction2, _super);
|
|
2524
|
+
function AsyncAction2(scheduler, work) {
|
|
2525
|
+
var _this = _super.call(this, scheduler, work) || this;
|
|
2526
|
+
_this.scheduler = scheduler;
|
|
2527
|
+
_this.work = work;
|
|
2528
|
+
_this.pending = false;
|
|
2529
|
+
return _this;
|
|
2530
|
+
}
|
|
2531
|
+
AsyncAction2.prototype.schedule = function(state, delay) {
|
|
2532
|
+
if (delay === void 0) {
|
|
2533
|
+
delay = 0;
|
|
2534
|
+
}
|
|
2535
|
+
if (this.closed) {
|
|
2536
|
+
return this;
|
|
2537
|
+
}
|
|
2538
|
+
this.state = state;
|
|
2539
|
+
var id = this.id;
|
|
2540
|
+
var scheduler = this.scheduler;
|
|
2541
|
+
if (id != null) {
|
|
2542
|
+
this.id = this.recycleAsyncId(scheduler, id, delay);
|
|
2543
|
+
}
|
|
2544
|
+
this.pending = true;
|
|
2545
|
+
this.delay = delay;
|
|
2546
|
+
this.id = this.id || this.requestAsyncId(scheduler, this.id, delay);
|
|
2547
|
+
return this;
|
|
2548
|
+
};
|
|
2549
|
+
AsyncAction2.prototype.requestAsyncId = function(scheduler, _id, delay) {
|
|
2550
|
+
if (delay === void 0) {
|
|
2551
|
+
delay = 0;
|
|
2552
|
+
}
|
|
2553
|
+
return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);
|
|
2554
|
+
};
|
|
2555
|
+
AsyncAction2.prototype.recycleAsyncId = function(_scheduler, id, delay) {
|
|
2556
|
+
if (delay === void 0) {
|
|
2557
|
+
delay = 0;
|
|
2558
|
+
}
|
|
2559
|
+
if (delay != null && this.delay === delay && this.pending === false) {
|
|
2560
|
+
return id;
|
|
2561
|
+
}
|
|
2562
|
+
intervalProvider.clearInterval(id);
|
|
2563
|
+
return void 0;
|
|
2564
|
+
};
|
|
2565
|
+
AsyncAction2.prototype.execute = function(state, delay) {
|
|
2566
|
+
if (this.closed) {
|
|
2567
|
+
return new Error("executing a cancelled action");
|
|
2568
|
+
}
|
|
2569
|
+
this.pending = false;
|
|
2570
|
+
var error = this._execute(state, delay);
|
|
2571
|
+
if (error) {
|
|
2572
|
+
return error;
|
|
2573
|
+
} else if (this.pending === false && this.id != null) {
|
|
2574
|
+
this.id = this.recycleAsyncId(this.scheduler, this.id, null);
|
|
2575
|
+
}
|
|
2576
|
+
};
|
|
2577
|
+
AsyncAction2.prototype._execute = function(state, _delay) {
|
|
2578
|
+
var errored = false;
|
|
2579
|
+
var errorValue;
|
|
2580
|
+
try {
|
|
2581
|
+
this.work(state);
|
|
2582
|
+
} catch (e) {
|
|
2583
|
+
errored = true;
|
|
2584
|
+
errorValue = e ? e : new Error("Scheduled action threw falsy error");
|
|
2585
|
+
}
|
|
2586
|
+
if (errored) {
|
|
2587
|
+
this.unsubscribe();
|
|
2588
|
+
return errorValue;
|
|
2589
|
+
}
|
|
2590
|
+
};
|
|
2591
|
+
AsyncAction2.prototype.unsubscribe = function() {
|
|
2592
|
+
if (!this.closed) {
|
|
2593
|
+
var _a2 = this, id = _a2.id, scheduler = _a2.scheduler;
|
|
2594
|
+
var actions = scheduler.actions;
|
|
2595
|
+
this.work = this.state = this.scheduler = null;
|
|
2596
|
+
this.pending = false;
|
|
2597
|
+
arrRemove(actions, this);
|
|
2598
|
+
if (id != null) {
|
|
2599
|
+
this.id = this.recycleAsyncId(scheduler, id, null);
|
|
2600
|
+
}
|
|
2601
|
+
this.delay = null;
|
|
2602
|
+
_super.prototype.unsubscribe.call(this);
|
|
2603
|
+
}
|
|
2604
|
+
};
|
|
2605
|
+
return AsyncAction2;
|
|
2606
|
+
}(Action);
|
|
2607
|
+
var Scheduler = function() {
|
|
2608
|
+
function Scheduler2(schedulerActionCtor, now) {
|
|
2609
|
+
if (now === void 0) {
|
|
2610
|
+
now = Scheduler2.now;
|
|
2611
|
+
}
|
|
2612
|
+
this.schedulerActionCtor = schedulerActionCtor;
|
|
2613
|
+
this.now = now;
|
|
2614
|
+
}
|
|
2615
|
+
Scheduler2.prototype.schedule = function(work, delay, state) {
|
|
2616
|
+
if (delay === void 0) {
|
|
2617
|
+
delay = 0;
|
|
2618
|
+
}
|
|
2619
|
+
return new this.schedulerActionCtor(this, work).schedule(state, delay);
|
|
2620
|
+
};
|
|
2621
|
+
Scheduler2.now = dateTimestampProvider.now;
|
|
2622
|
+
return Scheduler2;
|
|
2623
|
+
}();
|
|
2624
|
+
var AsyncScheduler = function(_super) {
|
|
2625
|
+
__extends(AsyncScheduler2, _super);
|
|
2626
|
+
function AsyncScheduler2(SchedulerAction, now) {
|
|
2627
|
+
if (now === void 0) {
|
|
2628
|
+
now = Scheduler.now;
|
|
2629
|
+
}
|
|
2630
|
+
var _this = _super.call(this, SchedulerAction, now) || this;
|
|
2631
|
+
_this.actions = [];
|
|
2632
|
+
_this._active = false;
|
|
2633
|
+
_this._scheduled = void 0;
|
|
2634
|
+
return _this;
|
|
2635
|
+
}
|
|
2636
|
+
AsyncScheduler2.prototype.flush = function(action) {
|
|
2637
|
+
var actions = this.actions;
|
|
2638
|
+
if (this._active) {
|
|
2639
|
+
actions.push(action);
|
|
2640
|
+
return;
|
|
2641
|
+
}
|
|
2642
|
+
var error;
|
|
2643
|
+
this._active = true;
|
|
2644
|
+
do {
|
|
2645
|
+
if (error = action.execute(action.state, action.delay)) {
|
|
2646
|
+
break;
|
|
2647
|
+
}
|
|
2648
|
+
} while (action = actions.shift());
|
|
2649
|
+
this._active = false;
|
|
2650
|
+
if (error) {
|
|
2651
|
+
while (action = actions.shift()) {
|
|
2652
|
+
action.unsubscribe();
|
|
2653
|
+
}
|
|
2654
|
+
throw error;
|
|
2655
|
+
}
|
|
2656
|
+
};
|
|
2657
|
+
return AsyncScheduler2;
|
|
2658
|
+
}(Scheduler);
|
|
2659
|
+
var asyncScheduler = new AsyncScheduler(AsyncAction);
|
|
2660
|
+
var async = asyncScheduler;
|
|
2661
|
+
function isScheduler(value2) {
|
|
2662
|
+
return value2 && isFunction(value2.schedule);
|
|
2663
|
+
}
|
|
2664
|
+
function isValidDate(value2) {
|
|
2665
|
+
return value2 instanceof Date && !isNaN(value2);
|
|
2666
|
+
}
|
|
2667
|
+
function timer(dueTime, intervalOrScheduler, scheduler) {
|
|
2668
|
+
if (dueTime === void 0) {
|
|
2669
|
+
dueTime = 0;
|
|
2670
|
+
}
|
|
2671
|
+
if (scheduler === void 0) {
|
|
2672
|
+
scheduler = async;
|
|
2673
|
+
}
|
|
2674
|
+
var intervalDuration = -1;
|
|
2675
|
+
if (intervalOrScheduler != null) {
|
|
2676
|
+
if (isScheduler(intervalOrScheduler)) {
|
|
2677
|
+
scheduler = intervalOrScheduler;
|
|
2678
|
+
} else {
|
|
2679
|
+
intervalDuration = intervalOrScheduler;
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
return new Observable(function(subscriber) {
|
|
2683
|
+
var due = isValidDate(dueTime) ? +dueTime - scheduler.now() : dueTime;
|
|
2684
|
+
if (due < 0) {
|
|
2685
|
+
due = 0;
|
|
2686
|
+
}
|
|
2687
|
+
var n = 0;
|
|
2688
|
+
return scheduler.schedule(function() {
|
|
2689
|
+
if (!subscriber.closed) {
|
|
2690
|
+
subscriber.next(n++);
|
|
2691
|
+
if (0 <= intervalDuration) {
|
|
2692
|
+
this.schedule(void 0, intervalDuration);
|
|
2693
|
+
} else {
|
|
2694
|
+
subscriber.complete();
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
}, due);
|
|
2698
|
+
});
|
|
2699
|
+
}
|
|
2700
|
+
function interval(period, scheduler) {
|
|
2701
|
+
if (period === void 0) {
|
|
2702
|
+
period = 0;
|
|
2703
|
+
}
|
|
2704
|
+
if (scheduler === void 0) {
|
|
2705
|
+
scheduler = asyncScheduler;
|
|
2706
|
+
}
|
|
2707
|
+
if (period < 0) {
|
|
2708
|
+
period = 0;
|
|
2709
|
+
}
|
|
2710
|
+
return timer(period, period, scheduler);
|
|
2711
|
+
}
|
|
2364
2712
|
var NiivueObject3D = function(id, vertexBuffer, mode, indexCount, indexBuffer = null, vao = null) {
|
|
2365
2713
|
this.BLEND = 1;
|
|
2366
2714
|
this.CULL_FACE = 2;
|
|
@@ -2785,12 +3133,12 @@ var utilities$1 = { exports: {} };
|
|
|
2785
3133
|
return data.getFloat64(start, littleEndian);
|
|
2786
3134
|
};
|
|
2787
3135
|
nifti3.Utils.getLongAt = function(data, start, littleEndian) {
|
|
2788
|
-
var ctr,
|
|
3136
|
+
var ctr, array2 = [], value2 = 0;
|
|
2789
3137
|
for (ctr = 0; ctr < 8; ctr += 1) {
|
|
2790
|
-
|
|
3138
|
+
array2[ctr] = nifti3.Utils.getByteAt(data, start + ctr, littleEndian);
|
|
2791
3139
|
}
|
|
2792
|
-
for (ctr =
|
|
2793
|
-
value2 = value2 * 256 +
|
|
3140
|
+
for (ctr = array2.length - 1; ctr >= 0; ctr--) {
|
|
3141
|
+
value2 = value2 * 256 + array2[ctr];
|
|
2794
3142
|
}
|
|
2795
3143
|
return value2;
|
|
2796
3144
|
};
|
|
@@ -7674,24 +8022,24 @@ var utilities = { exports: {} };
|
|
|
7674
8022
|
}
|
|
7675
8023
|
return tmp.buffer;
|
|
7676
8024
|
};
|
|
7677
|
-
daikon2.Utils.fillBuffer = function(
|
|
8025
|
+
daikon2.Utils.fillBuffer = function(array2, buffer2, offset, numBytes) {
|
|
7678
8026
|
var ctr;
|
|
7679
8027
|
if (numBytes === 1) {
|
|
7680
|
-
for (ctr = 0; ctr <
|
|
7681
|
-
buffer2.setUint8(offset + ctr,
|
|
8028
|
+
for (ctr = 0; ctr < array2.length; ctr += 1) {
|
|
8029
|
+
buffer2.setUint8(offset + ctr, array2[ctr]);
|
|
7682
8030
|
}
|
|
7683
8031
|
} else if (numBytes === 2) {
|
|
7684
|
-
for (ctr = 0; ctr <
|
|
7685
|
-
buffer2.setUint16(offset + ctr * 2,
|
|
8032
|
+
for (ctr = 0; ctr < array2.length; ctr += 1) {
|
|
8033
|
+
buffer2.setUint16(offset + ctr * 2, array2[ctr], true);
|
|
7686
8034
|
}
|
|
7687
8035
|
}
|
|
7688
8036
|
};
|
|
7689
|
-
daikon2.Utils.fillBufferRGB = function(
|
|
7690
|
-
var r, g, b, ctr, numElements = parseInt(
|
|
8037
|
+
daikon2.Utils.fillBufferRGB = function(array2, buffer2, offset) {
|
|
8038
|
+
var r, g, b, ctr, numElements = parseInt(array2.length / 3);
|
|
7691
8039
|
for (ctr = 0; ctr < numElements; ctr += 1) {
|
|
7692
|
-
r =
|
|
7693
|
-
g =
|
|
7694
|
-
b =
|
|
8040
|
+
r = array2[ctr * 3];
|
|
8041
|
+
g = array2[ctr * 3 + 1];
|
|
8042
|
+
b = array2[ctr * 3 + 2];
|
|
7695
8043
|
buffer2.setUint8(offset + ctr, parseInt((r + b + g) / 3), true);
|
|
7696
8044
|
}
|
|
7697
8045
|
};
|
|
@@ -13766,9 +14114,9 @@ var jpegBaseline = { exports: {} };
|
|
|
13766
14114
|
}
|
|
13767
14115
|
function readDataBlock() {
|
|
13768
14116
|
var length2 = readUint16();
|
|
13769
|
-
var
|
|
13770
|
-
offset +=
|
|
13771
|
-
return
|
|
14117
|
+
var array2 = data.subarray(offset, offset + length2 - 2);
|
|
14118
|
+
offset += array2.length;
|
|
14119
|
+
return array2;
|
|
13772
14120
|
}
|
|
13773
14121
|
function prepareComponents(frame2) {
|
|
13774
14122
|
var mcusPerLine = Math.ceil(frame2.samplesPerLine / 8 / frame2.maxH);
|
|
@@ -18476,10 +18824,10 @@ var require$$1 = /* @__PURE__ */ getAugmentedNamespace(__viteBrowserExternal$1);
|
|
|
18476
18824
|
return u8array;
|
|
18477
18825
|
}
|
|
18478
18826
|
Module["intArrayFromString"] = intArrayFromString;
|
|
18479
|
-
function intArrayToString(
|
|
18827
|
+
function intArrayToString(array2) {
|
|
18480
18828
|
var ret = [];
|
|
18481
|
-
for (var i2 = 0; i2 <
|
|
18482
|
-
var chr =
|
|
18829
|
+
for (var i2 = 0; i2 < array2.length; i2++) {
|
|
18830
|
+
var chr = array2[i2];
|
|
18483
18831
|
if (chr > 255) {
|
|
18484
18832
|
chr &= 255;
|
|
18485
18833
|
}
|
|
@@ -18489,18 +18837,18 @@ var require$$1 = /* @__PURE__ */ getAugmentedNamespace(__viteBrowserExternal$1);
|
|
|
18489
18837
|
}
|
|
18490
18838
|
Module["intArrayToString"] = intArrayToString;
|
|
18491
18839
|
function writeStringToMemory(string, buffer2, dontAddNull) {
|
|
18492
|
-
var
|
|
18840
|
+
var array2 = intArrayFromString(string, dontAddNull);
|
|
18493
18841
|
var i2 = 0;
|
|
18494
|
-
while (i2 <
|
|
18495
|
-
var chr =
|
|
18842
|
+
while (i2 < array2.length) {
|
|
18843
|
+
var chr = array2[i2];
|
|
18496
18844
|
HEAP8[buffer2 + i2 >> 0] = chr;
|
|
18497
18845
|
i2 = i2 + 1;
|
|
18498
18846
|
}
|
|
18499
18847
|
}
|
|
18500
18848
|
Module["writeStringToMemory"] = writeStringToMemory;
|
|
18501
|
-
function writeArrayToMemory(
|
|
18502
|
-
for (var i2 = 0; i2 <
|
|
18503
|
-
HEAP8[buffer2++ >> 0] =
|
|
18849
|
+
function writeArrayToMemory(array2, buffer2) {
|
|
18850
|
+
for (var i2 = 0; i2 < array2.length; i2++) {
|
|
18851
|
+
HEAP8[buffer2++ >> 0] = array2[i2];
|
|
18504
18852
|
}
|
|
18505
18853
|
}
|
|
18506
18854
|
Module["writeArrayToMemory"] = writeArrayToMemory;
|
|
@@ -18674,9 +19022,9 @@ var require$$1 = /* @__PURE__ */ getAugmentedNamespace(__viteBrowserExternal$1);
|
|
|
18674
19022
|
function __isLeapYear(year) {
|
|
18675
19023
|
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
18676
19024
|
}
|
|
18677
|
-
function __arraySum(
|
|
19025
|
+
function __arraySum(array2, index) {
|
|
18678
19026
|
var sum = 0;
|
|
18679
|
-
for (var i2 = 0; i2 <= index; sum +=
|
|
19027
|
+
for (var i2 = 0; i2 <= index; sum += array2[i2++])
|
|
18680
19028
|
;
|
|
18681
19029
|
return sum;
|
|
18682
19030
|
}
|
|
@@ -103140,7 +103488,7 @@ function NVImage(dataBuffer, name = "", colorMap = "gray", opacity = 1, pairedIm
|
|
|
103140
103488
|
let nVol4D = imgRaw.byteLength / this.nVox3D / (this.hdr.numBitsPerVoxel / 8);
|
|
103141
103489
|
if (nVol4D !== this.nFrame4D)
|
|
103142
103490
|
console.log("This header does not match voxel data", this.hdr, imgRaw.byteLength);
|
|
103143
|
-
if (this.hdr.intent_code === 1007 && this.nFrame4D === 3 && this.hdr.datatypeCode === this.DT_FLOAT) {
|
|
103491
|
+
if ((this.hdr.intent_code === 1007 || this.hdr.intent_code === 2003) && this.nFrame4D === 3 && this.hdr.datatypeCode === this.DT_FLOAT) {
|
|
103144
103492
|
let tmp = new Float32Array(imgRaw);
|
|
103145
103493
|
let f32 = tmp.slice();
|
|
103146
103494
|
this.hdr.datatypeCode = this.DT_RGB;
|
|
@@ -103768,11 +104116,12 @@ NVImage.prototype.readMGH = function(buffer2) {
|
|
|
103768
104116
|
let hdr = this.hdr;
|
|
103769
104117
|
hdr.dims = [3, 1, 1, 1, 0, 0, 0, 0];
|
|
103770
104118
|
hdr.pixDims = [1, 1, 1, 1, 1, 0, 0, 0];
|
|
103771
|
-
var reader = new DataView(buffer2);
|
|
103772
104119
|
var raw = buffer2;
|
|
104120
|
+
var reader = new DataView(raw);
|
|
103773
104121
|
if (reader.getUint8(0) === 31 && reader.getUint8(1) === 139) {
|
|
103774
|
-
|
|
103775
|
-
|
|
104122
|
+
let raw8 = decompressSync(new Uint8Array(buffer2));
|
|
104123
|
+
raw = raw8.buffer;
|
|
104124
|
+
reader = new DataView(raw);
|
|
103776
104125
|
}
|
|
103777
104126
|
let version = reader.getInt32(0, false);
|
|
103778
104127
|
let width = reader.getInt32(4, false);
|
|
@@ -106753,19 +107102,30 @@ NVMesh.readPLY = function(buffer2) {
|
|
|
106753
107102
|
}
|
|
106754
107103
|
let indices2 = new Int32Array(nface * 3);
|
|
106755
107104
|
let f = 0;
|
|
106756
|
-
let isTriangular2 = true;
|
|
106757
107105
|
for (var i2 = 0; i2 < nface; i2++) {
|
|
106758
107106
|
line = readStr();
|
|
106759
107107
|
let items = line.split(/\s/);
|
|
106760
|
-
|
|
106761
|
-
|
|
106762
|
-
|
|
106763
|
-
|
|
106764
|
-
|
|
106765
|
-
|
|
106766
|
-
|
|
106767
|
-
|
|
106768
|
-
|
|
107108
|
+
let nTri = parseInt(items[0]) - 2;
|
|
107109
|
+
if (nTri < 1)
|
|
107110
|
+
break;
|
|
107111
|
+
if (f + nTri * 3 > indices2.length) {
|
|
107112
|
+
var c2 = new Int32Array(indices2.length + indices2.length);
|
|
107113
|
+
c2.set(indices2);
|
|
107114
|
+
indices2 = c2.slice();
|
|
107115
|
+
}
|
|
107116
|
+
let idx0 = parseInt(items[1]);
|
|
107117
|
+
let idx1 = parseInt(items[2]);
|
|
107118
|
+
for (let j2 = 0; j2 < nTri; j2++) {
|
|
107119
|
+
let idx2 = parseInt(items[3 + j2]);
|
|
107120
|
+
indices2[f + 0] = idx0;
|
|
107121
|
+
indices2[f + 1] = idx1;
|
|
107122
|
+
indices2[f + 2] = idx2;
|
|
107123
|
+
idx1 = idx2;
|
|
107124
|
+
f += 3;
|
|
107125
|
+
}
|
|
107126
|
+
}
|
|
107127
|
+
if (indices2.length !== f)
|
|
107128
|
+
indices2 = indices2.slice(0, f);
|
|
106769
107129
|
return {
|
|
106770
107130
|
positions: positions2,
|
|
106771
107131
|
indices: indices2
|
|
@@ -106956,12 +107316,21 @@ NVMesh.readOBJ = function(buffer2) {
|
|
|
106956
107316
|
}
|
|
106957
107317
|
if (str[0] === "f") {
|
|
106958
107318
|
let items = str.split(" ");
|
|
107319
|
+
let new_t = items.length - 3;
|
|
107320
|
+
if (new_t < 1)
|
|
107321
|
+
break;
|
|
106959
107322
|
let tn = items[1].split("/");
|
|
106960
|
-
|
|
107323
|
+
let t0 = parseInt(tn[0]) - 1;
|
|
106961
107324
|
tn = items[2].split("/");
|
|
106962
|
-
|
|
106963
|
-
|
|
106964
|
-
|
|
107325
|
+
let tprev = parseInt(tn[0]) - 1;
|
|
107326
|
+
for (let j = 0; j < new_t; j++) {
|
|
107327
|
+
tn = items[3 + j].split("/");
|
|
107328
|
+
let tcurr = parseInt(tn[0]) - 1;
|
|
107329
|
+
t.push(t0);
|
|
107330
|
+
t.push(tprev);
|
|
107331
|
+
t.push(tcurr);
|
|
107332
|
+
tprev = tcurr;
|
|
107333
|
+
}
|
|
106965
107334
|
}
|
|
106966
107335
|
}
|
|
106967
107336
|
var positions = new Float32Array(pts);
|
|
@@ -109643,6 +110012,219 @@ var defaultFontMetrics = {
|
|
|
109643
110012
|
glyphs,
|
|
109644
110013
|
kerning
|
|
109645
110014
|
};
|
|
110015
|
+
var DEFAULT_WEBSOCKET_CONFIG = {
|
|
110016
|
+
url: "",
|
|
110017
|
+
deserializer: function(e) {
|
|
110018
|
+
return JSON.parse(e.data);
|
|
110019
|
+
},
|
|
110020
|
+
serializer: function(value2) {
|
|
110021
|
+
return JSON.stringify(value2);
|
|
110022
|
+
}
|
|
110023
|
+
};
|
|
110024
|
+
var WEBSOCKETSUBJECT_INVALID_ERROR_OBJECT = "WebSocketSubject.error must be called with an object with an error code, and an optional reason: { code: number, reason: string }";
|
|
110025
|
+
var WebSocketSubject = function(_super) {
|
|
110026
|
+
__extends(WebSocketSubject2, _super);
|
|
110027
|
+
function WebSocketSubject2(urlConfigOrSource, destination) {
|
|
110028
|
+
var _this = _super.call(this) || this;
|
|
110029
|
+
_this._socket = null;
|
|
110030
|
+
if (urlConfigOrSource instanceof Observable) {
|
|
110031
|
+
_this.destination = destination;
|
|
110032
|
+
_this.source = urlConfigOrSource;
|
|
110033
|
+
} else {
|
|
110034
|
+
var config2 = _this._config = __assign({}, DEFAULT_WEBSOCKET_CONFIG);
|
|
110035
|
+
_this._output = new Subject();
|
|
110036
|
+
if (typeof urlConfigOrSource === "string") {
|
|
110037
|
+
config2.url = urlConfigOrSource;
|
|
110038
|
+
} else {
|
|
110039
|
+
for (var key2 in urlConfigOrSource) {
|
|
110040
|
+
if (urlConfigOrSource.hasOwnProperty(key2)) {
|
|
110041
|
+
config2[key2] = urlConfigOrSource[key2];
|
|
110042
|
+
}
|
|
110043
|
+
}
|
|
110044
|
+
}
|
|
110045
|
+
if (!config2.WebSocketCtor && WebSocket) {
|
|
110046
|
+
config2.WebSocketCtor = WebSocket;
|
|
110047
|
+
} else if (!config2.WebSocketCtor) {
|
|
110048
|
+
throw new Error("no WebSocket constructor can be found");
|
|
110049
|
+
}
|
|
110050
|
+
_this.destination = new ReplaySubject();
|
|
110051
|
+
}
|
|
110052
|
+
return _this;
|
|
110053
|
+
}
|
|
110054
|
+
WebSocketSubject2.prototype.lift = function(operator) {
|
|
110055
|
+
var sock = new WebSocketSubject2(this._config, this.destination);
|
|
110056
|
+
sock.operator = operator;
|
|
110057
|
+
sock.source = this;
|
|
110058
|
+
return sock;
|
|
110059
|
+
};
|
|
110060
|
+
WebSocketSubject2.prototype._resetState = function() {
|
|
110061
|
+
this._socket = null;
|
|
110062
|
+
if (!this.source) {
|
|
110063
|
+
this.destination = new ReplaySubject();
|
|
110064
|
+
}
|
|
110065
|
+
this._output = new Subject();
|
|
110066
|
+
};
|
|
110067
|
+
WebSocketSubject2.prototype.multiplex = function(subMsg, unsubMsg, messageFilter) {
|
|
110068
|
+
var self2 = this;
|
|
110069
|
+
return new Observable(function(observer) {
|
|
110070
|
+
try {
|
|
110071
|
+
self2.next(subMsg());
|
|
110072
|
+
} catch (err2) {
|
|
110073
|
+
observer.error(err2);
|
|
110074
|
+
}
|
|
110075
|
+
var subscription = self2.subscribe({
|
|
110076
|
+
next: function(x2) {
|
|
110077
|
+
try {
|
|
110078
|
+
if (messageFilter(x2)) {
|
|
110079
|
+
observer.next(x2);
|
|
110080
|
+
}
|
|
110081
|
+
} catch (err2) {
|
|
110082
|
+
observer.error(err2);
|
|
110083
|
+
}
|
|
110084
|
+
},
|
|
110085
|
+
error: function(err2) {
|
|
110086
|
+
return observer.error(err2);
|
|
110087
|
+
},
|
|
110088
|
+
complete: function() {
|
|
110089
|
+
return observer.complete();
|
|
110090
|
+
}
|
|
110091
|
+
});
|
|
110092
|
+
return function() {
|
|
110093
|
+
try {
|
|
110094
|
+
self2.next(unsubMsg());
|
|
110095
|
+
} catch (err2) {
|
|
110096
|
+
observer.error(err2);
|
|
110097
|
+
}
|
|
110098
|
+
subscription.unsubscribe();
|
|
110099
|
+
};
|
|
110100
|
+
});
|
|
110101
|
+
};
|
|
110102
|
+
WebSocketSubject2.prototype._connectSocket = function() {
|
|
110103
|
+
var _this = this;
|
|
110104
|
+
var _a2 = this._config, WebSocketCtor = _a2.WebSocketCtor, protocol = _a2.protocol, url = _a2.url, binaryType = _a2.binaryType;
|
|
110105
|
+
var observer = this._output;
|
|
110106
|
+
var socket = null;
|
|
110107
|
+
try {
|
|
110108
|
+
socket = protocol ? new WebSocketCtor(url, protocol) : new WebSocketCtor(url);
|
|
110109
|
+
this._socket = socket;
|
|
110110
|
+
if (binaryType) {
|
|
110111
|
+
this._socket.binaryType = binaryType;
|
|
110112
|
+
}
|
|
110113
|
+
} catch (e) {
|
|
110114
|
+
observer.error(e);
|
|
110115
|
+
return;
|
|
110116
|
+
}
|
|
110117
|
+
var subscription = new Subscription(function() {
|
|
110118
|
+
_this._socket = null;
|
|
110119
|
+
if (socket && socket.readyState === 1) {
|
|
110120
|
+
socket.close();
|
|
110121
|
+
}
|
|
110122
|
+
});
|
|
110123
|
+
socket.onopen = function(evt) {
|
|
110124
|
+
var _socket = _this._socket;
|
|
110125
|
+
if (!_socket) {
|
|
110126
|
+
socket.close();
|
|
110127
|
+
_this._resetState();
|
|
110128
|
+
return;
|
|
110129
|
+
}
|
|
110130
|
+
var openObserver = _this._config.openObserver;
|
|
110131
|
+
if (openObserver) {
|
|
110132
|
+
openObserver.next(evt);
|
|
110133
|
+
}
|
|
110134
|
+
var queue = _this.destination;
|
|
110135
|
+
_this.destination = Subscriber.create(function(x2) {
|
|
110136
|
+
if (socket.readyState === 1) {
|
|
110137
|
+
try {
|
|
110138
|
+
var serializer = _this._config.serializer;
|
|
110139
|
+
socket.send(serializer(x2));
|
|
110140
|
+
} catch (e) {
|
|
110141
|
+
_this.destination.error(e);
|
|
110142
|
+
}
|
|
110143
|
+
}
|
|
110144
|
+
}, function(err2) {
|
|
110145
|
+
var closingObserver = _this._config.closingObserver;
|
|
110146
|
+
if (closingObserver) {
|
|
110147
|
+
closingObserver.next(void 0);
|
|
110148
|
+
}
|
|
110149
|
+
if (err2 && err2.code) {
|
|
110150
|
+
socket.close(err2.code, err2.reason);
|
|
110151
|
+
} else {
|
|
110152
|
+
observer.error(new TypeError(WEBSOCKETSUBJECT_INVALID_ERROR_OBJECT));
|
|
110153
|
+
}
|
|
110154
|
+
_this._resetState();
|
|
110155
|
+
}, function() {
|
|
110156
|
+
var closingObserver = _this._config.closingObserver;
|
|
110157
|
+
if (closingObserver) {
|
|
110158
|
+
closingObserver.next(void 0);
|
|
110159
|
+
}
|
|
110160
|
+
socket.close();
|
|
110161
|
+
_this._resetState();
|
|
110162
|
+
});
|
|
110163
|
+
if (queue && queue instanceof ReplaySubject) {
|
|
110164
|
+
subscription.add(queue.subscribe(_this.destination));
|
|
110165
|
+
}
|
|
110166
|
+
};
|
|
110167
|
+
socket.onerror = function(e) {
|
|
110168
|
+
_this._resetState();
|
|
110169
|
+
observer.error(e);
|
|
110170
|
+
};
|
|
110171
|
+
socket.onclose = function(e) {
|
|
110172
|
+
if (socket === _this._socket) {
|
|
110173
|
+
_this._resetState();
|
|
110174
|
+
}
|
|
110175
|
+
var closeObserver = _this._config.closeObserver;
|
|
110176
|
+
if (closeObserver) {
|
|
110177
|
+
closeObserver.next(e);
|
|
110178
|
+
}
|
|
110179
|
+
if (e.wasClean) {
|
|
110180
|
+
observer.complete();
|
|
110181
|
+
} else {
|
|
110182
|
+
observer.error(e);
|
|
110183
|
+
}
|
|
110184
|
+
};
|
|
110185
|
+
socket.onmessage = function(e) {
|
|
110186
|
+
try {
|
|
110187
|
+
var deserializer = _this._config.deserializer;
|
|
110188
|
+
observer.next(deserializer(e));
|
|
110189
|
+
} catch (err2) {
|
|
110190
|
+
observer.error(err2);
|
|
110191
|
+
}
|
|
110192
|
+
};
|
|
110193
|
+
};
|
|
110194
|
+
WebSocketSubject2.prototype._subscribe = function(subscriber) {
|
|
110195
|
+
var _this = this;
|
|
110196
|
+
var source = this.source;
|
|
110197
|
+
if (source) {
|
|
110198
|
+
return source.subscribe(subscriber);
|
|
110199
|
+
}
|
|
110200
|
+
if (!this._socket) {
|
|
110201
|
+
this._connectSocket();
|
|
110202
|
+
}
|
|
110203
|
+
this._output.subscribe(subscriber);
|
|
110204
|
+
subscriber.add(function() {
|
|
110205
|
+
var _socket = _this._socket;
|
|
110206
|
+
if (_this._output.observers.length === 0) {
|
|
110207
|
+
if (_socket && (_socket.readyState === 1 || _socket.readyState === 0)) {
|
|
110208
|
+
_socket.close();
|
|
110209
|
+
}
|
|
110210
|
+
_this._resetState();
|
|
110211
|
+
}
|
|
110212
|
+
});
|
|
110213
|
+
return subscriber;
|
|
110214
|
+
};
|
|
110215
|
+
WebSocketSubject2.prototype.unsubscribe = function() {
|
|
110216
|
+
var _socket = this._socket;
|
|
110217
|
+
if (_socket && (_socket.readyState === 1 || _socket.readyState === 0)) {
|
|
110218
|
+
_socket.close();
|
|
110219
|
+
}
|
|
110220
|
+
this._resetState();
|
|
110221
|
+
_super.prototype.unsubscribe.call(this);
|
|
110222
|
+
};
|
|
110223
|
+
return WebSocketSubject2;
|
|
110224
|
+
}(AnonymousSubject);
|
|
110225
|
+
function webSocket(urlConfigOrSource) {
|
|
110226
|
+
return new WebSocketSubject(urlConfigOrSource);
|
|
110227
|
+
}
|
|
109646
110228
|
const log = new Log();
|
|
109647
110229
|
const cmapper = new colortables();
|
|
109648
110230
|
function Niivue(options = {}) {
|
|
@@ -109678,7 +110260,9 @@ function Niivue(options = {}) {
|
|
|
109678
110260
|
this.volumeTexture = null;
|
|
109679
110261
|
this.drawTexture = null;
|
|
109680
110262
|
this.drawBitmap = null;
|
|
109681
|
-
this.
|
|
110263
|
+
this.maxDrawUndoBitmaps = 8;
|
|
110264
|
+
this.currentDrawUndoBitmap = this.maxDrawUndoBitmaps;
|
|
110265
|
+
this.drawUndoBitmaps = [];
|
|
109682
110266
|
this.drawOpacity = 0.8;
|
|
109683
110267
|
this.drawPenLocation = [NaN, NaN, NaN];
|
|
109684
110268
|
this.drawPenAxCorSag = -1;
|
|
@@ -109812,6 +110396,12 @@ function Niivue(options = {}) {
|
|
|
109812
110396
|
Frag: fragMeshToonShader
|
|
109813
110397
|
}
|
|
109814
110398
|
];
|
|
110399
|
+
this.isController = false;
|
|
110400
|
+
this.isInSession = false;
|
|
110401
|
+
this.sessionKey = "";
|
|
110402
|
+
this.sessionUrl = "";
|
|
110403
|
+
this.serverConnection$ = null;
|
|
110404
|
+
this.interval$ = null;
|
|
109815
110405
|
this.initialized = false;
|
|
109816
110406
|
for (let prop in this.defaults) {
|
|
109817
110407
|
this.opts[prop] = options[prop] === void 0 ? this.defaults[prop] : options[prop];
|
|
@@ -109902,6 +110492,85 @@ Niivue.prototype.sync = function() {
|
|
|
109902
110492
|
}
|
|
109903
110493
|
this.otherNV.drawScene();
|
|
109904
110494
|
};
|
|
110495
|
+
Niivue.prototype.connectToServer = function(wsServerUrl, sessionName) {
|
|
110496
|
+
const url = new URL(wsServerUrl);
|
|
110497
|
+
url.pathname = "websockets";
|
|
110498
|
+
url.search = "?session=" + sessionName;
|
|
110499
|
+
this.serverConnection$ = webSocket(url.href);
|
|
110500
|
+
console.log(url.href);
|
|
110501
|
+
};
|
|
110502
|
+
Niivue.prototype.setUpdateInterval = function() {
|
|
110503
|
+
this.interval$ = interval(300);
|
|
110504
|
+
this.interval$.subscribe(() => {
|
|
110505
|
+
this.serverConnection$.next({
|
|
110506
|
+
op: "update",
|
|
110507
|
+
azimuth: this.scene.renderAzimuth,
|
|
110508
|
+
elevation: this.scene.renderElevation,
|
|
110509
|
+
clipPlane: this.scene.clipPlane,
|
|
110510
|
+
zoom: this.volScaleMultiplier,
|
|
110511
|
+
key: this.sessionKey
|
|
110512
|
+
});
|
|
110513
|
+
});
|
|
110514
|
+
};
|
|
110515
|
+
Niivue.prototype.subscribeToServer = function(sessionCreatedCallback, sessionJoinedCallback) {
|
|
110516
|
+
this.serverConnection$.subscribe({
|
|
110517
|
+
next: (msg2) => {
|
|
110518
|
+
switch (msg2["op"]) {
|
|
110519
|
+
case "update":
|
|
110520
|
+
this.scene.renderAzimuth = msg2["azimuth"];
|
|
110521
|
+
this.scene.renderElevation = msg2["elevation"];
|
|
110522
|
+
this.volScaleMultiplier = msg2["zoom"];
|
|
110523
|
+
this.scene.clipPlane = msg2["clipPlane"];
|
|
110524
|
+
this.drawScene();
|
|
110525
|
+
break;
|
|
110526
|
+
case "create":
|
|
110527
|
+
console.log(msg2);
|
|
110528
|
+
if (!msg2["isError"]) {
|
|
110529
|
+
this.isInSession = true;
|
|
110530
|
+
this.sessionKey = msg2["key"];
|
|
110531
|
+
this.setUpdateInterval();
|
|
110532
|
+
}
|
|
110533
|
+
if (sessionCreatedCallback) {
|
|
110534
|
+
sessionCreatedCallback(msg2["message"], msg2["url"], msg2["key"], msg2["isError"]);
|
|
110535
|
+
}
|
|
110536
|
+
break;
|
|
110537
|
+
case "join":
|
|
110538
|
+
this.isInSession = true;
|
|
110539
|
+
this.isController = msg2["isController"];
|
|
110540
|
+
if (this.isController) {
|
|
110541
|
+
this.setUpdateInterval();
|
|
110542
|
+
}
|
|
110543
|
+
if (sessionJoinedCallback) {
|
|
110544
|
+
sessionJoinedCallback(msg2["message"], msg2["url"], msg2["isController"]);
|
|
110545
|
+
}
|
|
110546
|
+
break;
|
|
110547
|
+
}
|
|
110548
|
+
},
|
|
110549
|
+
error: (err2) => console.log(err2),
|
|
110550
|
+
complete: () => console.log("complete")
|
|
110551
|
+
});
|
|
110552
|
+
};
|
|
110553
|
+
Niivue.prototype.createSession = function(wsServerUrl, sessionName, sessionCreatedCallback) {
|
|
110554
|
+
this.connectToServer(wsServerUrl, sessionName);
|
|
110555
|
+
this.subscribeToServer(sessionCreatedCallback);
|
|
110556
|
+
this.serverConnection$.next({
|
|
110557
|
+
op: "create"
|
|
110558
|
+
});
|
|
110559
|
+
};
|
|
110560
|
+
Niivue.prototype.joinSession = function(wsServerUrl, sessionName, key2, sessionJoinedCallback) {
|
|
110561
|
+
this.connectToServer(wsServerUrl, sessionName);
|
|
110562
|
+
this.subscribeToServer(null, sessionJoinedCallback);
|
|
110563
|
+
this.serverConnection$.next({
|
|
110564
|
+
op: "join",
|
|
110565
|
+
key: key2
|
|
110566
|
+
});
|
|
110567
|
+
};
|
|
110568
|
+
Niivue.prototype.closeSession = function() {
|
|
110569
|
+
this.interval$.complete();
|
|
110570
|
+
this.serverConnection$.complete();
|
|
110571
|
+
this.isInSession = false;
|
|
110572
|
+
this.isController = false;
|
|
110573
|
+
};
|
|
109905
110574
|
Niivue.prototype.arrayEquals = function(a, b) {
|
|
109906
110575
|
return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((val, index) => val === b[index]);
|
|
109907
110576
|
};
|
|
@@ -109956,13 +110625,13 @@ Niivue.prototype.mouseRightButtonHandler = function(e) {
|
|
|
109956
110625
|
this.dragClipPlaneStartDepthAziElev = this.scene.clipPlaneDepthAziElev;
|
|
109957
110626
|
return;
|
|
109958
110627
|
};
|
|
109959
|
-
Niivue.prototype.calculateMinMaxVoxIdx = function(
|
|
109960
|
-
if (
|
|
110628
|
+
Niivue.prototype.calculateMinMaxVoxIdx = function(array2) {
|
|
110629
|
+
if (array2.length > 2) {
|
|
109961
110630
|
throw new Error("array must not contain more than two values");
|
|
109962
110631
|
}
|
|
109963
110632
|
return [
|
|
109964
|
-
Math.floor(Math.min(
|
|
109965
|
-
Math.floor(Math.max(
|
|
110633
|
+
Math.floor(Math.min(array2[0], array2[1])),
|
|
110634
|
+
Math.floor(Math.max(array2[0], array2[1]))
|
|
109966
110635
|
];
|
|
109967
110636
|
};
|
|
109968
110637
|
function intensityRaw2Scaled(hdr, raw) {
|
|
@@ -110027,6 +110696,8 @@ Niivue.prototype.mouseUpListener = function() {
|
|
|
110027
110696
|
this.scene.mouseButtonLeftDown = false;
|
|
110028
110697
|
if (this.drawPenFillPts.length > 0)
|
|
110029
110698
|
this.drawPenFilled();
|
|
110699
|
+
else if (this.drawPenAxCorSag >= 0)
|
|
110700
|
+
this.drawAddUndoBitmap();
|
|
110030
110701
|
this.drawPenLocation = [NaN, NaN, NaN];
|
|
110031
110702
|
this.drawPenAxCorSag = -1;
|
|
110032
110703
|
if (this.isDragging) {
|
|
@@ -110340,9 +111011,112 @@ Niivue.prototype.getVolumeIndexByID = function(id) {
|
|
|
110340
111011
|
}
|
|
110341
111012
|
return -1;
|
|
110342
111013
|
};
|
|
111014
|
+
function encodeRLE(data) {
|
|
111015
|
+
let dl = data.length;
|
|
111016
|
+
let dp = 0;
|
|
111017
|
+
let r = new Uint8Array(dl + Math.ceil(0.01 * dl));
|
|
111018
|
+
let rI = new Int8Array(r.buffer);
|
|
111019
|
+
let rp = 0;
|
|
111020
|
+
while (dp < dl) {
|
|
111021
|
+
let v = data[dp];
|
|
111022
|
+
dp++;
|
|
111023
|
+
let rl = 1;
|
|
111024
|
+
while (rl < 129 && dp < dl && data[dp] === v) {
|
|
111025
|
+
dp++;
|
|
111026
|
+
rl++;
|
|
111027
|
+
}
|
|
111028
|
+
if (rl > 1) {
|
|
111029
|
+
rI[rp] = -rl + 1;
|
|
111030
|
+
rp++;
|
|
111031
|
+
r[rp] = v;
|
|
111032
|
+
rp++;
|
|
111033
|
+
continue;
|
|
111034
|
+
}
|
|
111035
|
+
while (dp < dl) {
|
|
111036
|
+
if (rl > 127)
|
|
111037
|
+
break;
|
|
111038
|
+
if (dp + 2 < dl) {
|
|
111039
|
+
if (v !== data[dp] && data[dp + 2] === data[dp] && data[dp + 1] === data[dp])
|
|
111040
|
+
break;
|
|
111041
|
+
}
|
|
111042
|
+
v = data[dp];
|
|
111043
|
+
dp++;
|
|
111044
|
+
rl++;
|
|
111045
|
+
}
|
|
111046
|
+
r[rp] = rl - 1;
|
|
111047
|
+
rp++;
|
|
111048
|
+
for (let i2 = 0; i2 < rl; i2++) {
|
|
111049
|
+
r[rp] = data[dp - rl + i2];
|
|
111050
|
+
rp++;
|
|
111051
|
+
}
|
|
111052
|
+
}
|
|
111053
|
+
log.info("PackBits " + dl + " -> " + rp + " bytes (x" + dl / rp + ")");
|
|
111054
|
+
return r.slice(0, rp);
|
|
111055
|
+
}
|
|
111056
|
+
function decodeRLE(rle2, decodedlen) {
|
|
111057
|
+
let r = new Uint8Array(rle2.buffer);
|
|
111058
|
+
let rI = new Int8Array(r.buffer);
|
|
111059
|
+
let rp = 0;
|
|
111060
|
+
let d = new Uint8Array(decodedlen);
|
|
111061
|
+
let dp = 0;
|
|
111062
|
+
while (rp < r.length) {
|
|
111063
|
+
let hdr = rI[rp];
|
|
111064
|
+
rp++;
|
|
111065
|
+
if (hdr < 0) {
|
|
111066
|
+
let v = rI[rp];
|
|
111067
|
+
rp++;
|
|
111068
|
+
for (let i2 = 0; i2 < 1 - hdr; i2++) {
|
|
111069
|
+
d[dp] = v;
|
|
111070
|
+
dp++;
|
|
111071
|
+
}
|
|
111072
|
+
} else {
|
|
111073
|
+
for (let i2 = 0; i2 < hdr + 1; i2++) {
|
|
111074
|
+
d[dp] = rI[rp];
|
|
111075
|
+
rp++;
|
|
111076
|
+
dp++;
|
|
111077
|
+
}
|
|
111078
|
+
}
|
|
111079
|
+
}
|
|
111080
|
+
return d;
|
|
111081
|
+
}
|
|
111082
|
+
Niivue.prototype.drawAddUndoBitmap = async function(fnm) {
|
|
111083
|
+
if (!this.drawBitmap || this.drawBitmap.length < 1) {
|
|
111084
|
+
console.log("drawAddUndoBitmap error: No drawing open");
|
|
111085
|
+
return false;
|
|
111086
|
+
}
|
|
111087
|
+
this.currentDrawUndoBitmap++;
|
|
111088
|
+
if (this.currentDrawUndoBitmap >= this.maxDrawUndoBitmaps)
|
|
111089
|
+
this.currentDrawUndoBitmap = 0;
|
|
111090
|
+
this.drawUndoBitmaps[this.currentDrawUndoBitmap] = encodeRLE(this.drawBitmap);
|
|
111091
|
+
};
|
|
111092
|
+
Niivue.prototype.drawClearAllUndoBitmaps = async function() {
|
|
111093
|
+
this.currentDrawUndoBitmap = this.maxDrawUndoBitmaps;
|
|
111094
|
+
if (this.drawUndoBitmaps.length < 1)
|
|
111095
|
+
return;
|
|
111096
|
+
for (let i2 = this.drawUndoBitmaps.length - 1; i2 >= 0; i2--)
|
|
111097
|
+
array[i2] = [];
|
|
111098
|
+
};
|
|
111099
|
+
Niivue.prototype.drawUndo = function() {
|
|
111100
|
+
if (this.drawUndoBitmaps.length < 1) {
|
|
111101
|
+
console.log("undo bitmaps not loaded");
|
|
111102
|
+
return;
|
|
111103
|
+
}
|
|
111104
|
+
this.currentDrawUndoBitmap--;
|
|
111105
|
+
if (this.currentDrawUndoBitmap < 0)
|
|
111106
|
+
this.currentDrawUndoBitmap = this.drawUndoBitmaps.length - 1;
|
|
111107
|
+
if (this.currentDrawUndoBitmap >= this.drawUndoBitmaps.length)
|
|
111108
|
+
this.currentDrawUndoBitmap = 0;
|
|
111109
|
+
if (this.drawUndoBitmaps[this.currentDrawUndoBitmap].length < 2) {
|
|
111110
|
+
console.log("drawUndo is misbehaving");
|
|
111111
|
+
return;
|
|
111112
|
+
}
|
|
111113
|
+
this.drawBitmap = decodeRLE(this.drawUndoBitmaps[this.currentDrawUndoBitmap], this.drawBitmap.length);
|
|
111114
|
+
this.refreshDrawing(true);
|
|
111115
|
+
};
|
|
110343
111116
|
Niivue.prototype.loadDrawing = async function(fnm) {
|
|
110344
111117
|
if (this.drawBitmap)
|
|
110345
111118
|
console.log("Overwriting open drawing!");
|
|
111119
|
+
this.drawClearAllUndoBitmaps();
|
|
110346
111120
|
let volume = await NVImage.loadFromUrl({ url: fnm });
|
|
110347
111121
|
let dims = volume.hdr.dims;
|
|
110348
111122
|
if (dims[1] !== this.back.hdr.dims[1] || dims[2] !== this.back.hdr.dims[2] || dims[3] !== this.back.hdr.dims[3]) {
|
|
@@ -110353,7 +111127,6 @@ Niivue.prototype.loadDrawing = async function(fnm) {
|
|
|
110353
111127
|
console.log("Drawings should be UINT8");
|
|
110354
111128
|
let perm = volume.permRAS;
|
|
110355
111129
|
let vx = dims[1] * dims[2] * dims[3];
|
|
110356
|
-
this.drawUndoBitmap = null;
|
|
110357
111130
|
this.drawBitmap = new Uint8Array(vx);
|
|
110358
111131
|
this.drawTexture = this.r8Tex(this.drawTexture, this.gl.TEXTURE7, this.back.dims, true);
|
|
110359
111132
|
let layout = [0, 0, 0];
|
|
@@ -110405,6 +111178,7 @@ Niivue.prototype.loadDrawing = async function(fnm) {
|
|
|
110405
111178
|
}
|
|
110406
111179
|
}
|
|
110407
111180
|
}
|
|
111181
|
+
this.drawAddUndoBitmap();
|
|
110408
111182
|
this.refreshDrawing(false);
|
|
110409
111183
|
this.drawScene();
|
|
110410
111184
|
};
|
|
@@ -110698,6 +111472,8 @@ Niivue.prototype.setScale = function(scale2) {
|
|
|
110698
111472
|
};
|
|
110699
111473
|
Niivue.prototype.setClipPlaneColor = function(color) {
|
|
110700
111474
|
this.opts.clipPlaneColor = color;
|
|
111475
|
+
this.renderShader.use(this.gl);
|
|
111476
|
+
this.gl.uniform4fv(this.renderShader.uniforms["clipPlaneColor"], this.opts.clipPlaneColor);
|
|
110701
111477
|
this.drawScene();
|
|
110702
111478
|
};
|
|
110703
111479
|
Niivue.prototype.overlayRGBA = function(volume) {
|
|
@@ -110841,7 +111617,8 @@ Niivue.prototype.createEmptyDrawing = function() {
|
|
|
110841
111617
|
return;
|
|
110842
111618
|
let vx = this.back.dims[1] * this.back.dims[2] * this.back.dims[3];
|
|
110843
111619
|
this.drawBitmap = new Uint8Array(vx);
|
|
110844
|
-
this.
|
|
111620
|
+
this.drawClearAllUndoBitmaps();
|
|
111621
|
+
this.drawAddUndoBitmap();
|
|
110845
111622
|
this.drawTexture = this.r8Tex(this.drawTexture, this.gl.TEXTURE7, this.back.dims, true);
|
|
110846
111623
|
this.refreshDrawing(false);
|
|
110847
111624
|
};
|
|
@@ -110918,16 +111695,6 @@ function img2ras16(volume) {
|
|
|
110918
111695
|
}
|
|
110919
111696
|
return img16;
|
|
110920
111697
|
}
|
|
110921
|
-
Niivue.prototype.drawUndo = function() {
|
|
110922
|
-
let hdr = this.back.hdr;
|
|
110923
|
-
let nv = hdr.dims[1] * hdr.dims[2] * hdr.dims[3];
|
|
110924
|
-
if (this.drawUndoBitmap.length !== nv || this.drawBitmap.length !== nv) {
|
|
110925
|
-
console.log("bitmap dims are wrong");
|
|
110926
|
-
return;
|
|
110927
|
-
}
|
|
110928
|
-
this.drawBitmap = this.drawUndoBitmap.slice();
|
|
110929
|
-
this.refreshDrawing(true);
|
|
110930
|
-
};
|
|
110931
111698
|
Niivue.prototype.drawGrowCut = function() {
|
|
110932
111699
|
let hdr = this.back.hdr;
|
|
110933
111700
|
let nv = hdr.dims[1] * hdr.dims[2] * hdr.dims[3];
|
|
@@ -110935,7 +111702,6 @@ Niivue.prototype.drawGrowCut = function() {
|
|
|
110935
111702
|
console.log("bitmap dims are wrong");
|
|
110936
111703
|
return;
|
|
110937
111704
|
}
|
|
110938
|
-
this.drawUndoBitmap = this.drawBitmap.slice();
|
|
110939
111705
|
let gl = this.gl;
|
|
110940
111706
|
let fb = gl.createFramebuffer();
|
|
110941
111707
|
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
|
@@ -110948,16 +111714,19 @@ Niivue.prototype.drawGrowCut = function() {
|
|
|
110948
111714
|
img16[i2] = this.drawBitmap[i2];
|
|
110949
111715
|
let label0 = this.r16Tex(null, gl.TEXTURE6, this.back.dims, img16);
|
|
110950
111716
|
let label1 = this.r16Tex(null, gl.TEXTURE7, this.back.dims, img16);
|
|
111717
|
+
let kMAX_STRENGTH = 1e4;
|
|
110951
111718
|
for (let i2 = 1; i2 < nv; i2++)
|
|
110952
111719
|
if (img16[i2] > 0)
|
|
110953
|
-
img16[i2] =
|
|
111720
|
+
img16[i2] = kMAX_STRENGTH;
|
|
110954
111721
|
let strength0 = this.r16Tex(null, gl.TEXTURE4, this.back.dims, img16);
|
|
110955
111722
|
let strength1 = this.r16Tex(null, gl.TEXTURE5, this.back.dims, img16);
|
|
110956
111723
|
this.gl.bindVertexArray(this.genericVAO);
|
|
110957
111724
|
let shader = this.growCutShader;
|
|
110958
111725
|
shader.use(gl);
|
|
111726
|
+
let iterations = 128;
|
|
111727
|
+
gl.uniform1i(shader.uniforms["finalPass"], 0);
|
|
110959
111728
|
gl.uniform1i(shader.uniforms["inputTexture0"], 3);
|
|
110960
|
-
for (let j = 0; j <
|
|
111729
|
+
for (let j = 0; j < iterations; j++) {
|
|
110961
111730
|
gl.uniform1i(shader.uniforms["inputTexture1"], 6);
|
|
110962
111731
|
gl.uniform1i(shader.uniforms["inputTexture2"], 4);
|
|
110963
111732
|
for (let i2 = 0; i2 < this.back.dims[3]; i2++) {
|
|
@@ -110971,6 +111740,8 @@ Niivue.prototype.drawGrowCut = function() {
|
|
|
110971
111740
|
console.error("Incomplete framebuffer");
|
|
110972
111741
|
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
|
|
110973
111742
|
}
|
|
111743
|
+
if (j === iterations - 1)
|
|
111744
|
+
gl.uniform1i(shader.uniforms["finalPass"], 1);
|
|
110974
111745
|
gl.uniform1i(shader.uniforms["inputTexture1"], 7);
|
|
110975
111746
|
gl.uniform1i(shader.uniforms["inputTexture2"], 5);
|
|
110976
111747
|
for (let i2 = 0; i2 < this.back.dims[3]; i2++) {
|
|
@@ -110986,8 +111757,8 @@ Niivue.prototype.drawGrowCut = function() {
|
|
|
110986
111757
|
}
|
|
110987
111758
|
}
|
|
110988
111759
|
gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
|
|
110989
|
-
let readAttach = gl.
|
|
110990
|
-
let readTex =
|
|
111760
|
+
let readAttach = gl.COLOR_ATTACHMENT1;
|
|
111761
|
+
let readTex = label0;
|
|
110991
111762
|
gl.readBuffer(readAttach);
|
|
110992
111763
|
const format = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
|
|
110993
111764
|
const type2 = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
|
|
@@ -111023,6 +111794,7 @@ Niivue.prototype.drawGrowCut = function() {
|
|
|
111023
111794
|
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
|
|
111024
111795
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
111025
111796
|
gl.deleteFramebuffer(fb);
|
|
111797
|
+
this.drawAddUndoBitmap();
|
|
111026
111798
|
this.refreshDrawing(true);
|
|
111027
111799
|
};
|
|
111028
111800
|
Niivue.prototype.drawPt = function(x2, y, z, penValue) {
|
|
@@ -111106,6 +111878,74 @@ Niivue.prototype.drawLine = function(ptA, ptB, penValue) {
|
|
|
111106
111878
|
}
|
|
111107
111879
|
}
|
|
111108
111880
|
};
|
|
111881
|
+
Niivue.prototype.drawFloodFill = function(seedXYZ, newColor = 0) {
|
|
111882
|
+
newColor = Math.abs(newColor);
|
|
111883
|
+
let dims = [this.back.dims[1], this.back.dims[2], this.back.dims[3]];
|
|
111884
|
+
if (seedXYZ[0] < 0 || seedXYZ[1] < 0 || seedXYZ[2] < 0)
|
|
111885
|
+
return;
|
|
111886
|
+
if (seedXYZ[0] >= dims[0] || seedXYZ[1] >= dims[1] || seedXYZ[2] >= dims[2])
|
|
111887
|
+
return;
|
|
111888
|
+
let nx = dims[0];
|
|
111889
|
+
let nxy = nx * dims[1];
|
|
111890
|
+
let nxyz = nxy * dims[2];
|
|
111891
|
+
let img = this.drawBitmap.slice();
|
|
111892
|
+
if (img.length !== nxy * dims[2])
|
|
111893
|
+
return;
|
|
111894
|
+
function xyz2vx(pt) {
|
|
111895
|
+
return pt[0] + pt[1] * nx + pt[2] * nxy;
|
|
111896
|
+
}
|
|
111897
|
+
function vx2xyz(vx) {
|
|
111898
|
+
let Z = Math.floor(vx / nxy);
|
|
111899
|
+
let Y = Math.floor((vx - Z * nxy) / nx);
|
|
111900
|
+
let X = Math.floor(vx % nx);
|
|
111901
|
+
return [X, Y, Z];
|
|
111902
|
+
}
|
|
111903
|
+
let seedVx = xyz2vx(seedXYZ);
|
|
111904
|
+
let seedColor = img[seedVx];
|
|
111905
|
+
if (seedColor === newColor) {
|
|
111906
|
+
console.log("drawFloodFill selected voxel is already desired color");
|
|
111907
|
+
return;
|
|
111908
|
+
}
|
|
111909
|
+
for (let i2 = 1; i2 < nxyz; i2++) {
|
|
111910
|
+
img[i2] = 0;
|
|
111911
|
+
if (this.drawBitmap[i2] === seedColor)
|
|
111912
|
+
img[i2] = 1;
|
|
111913
|
+
}
|
|
111914
|
+
let Q = [];
|
|
111915
|
+
Q.push(seedVx);
|
|
111916
|
+
img[seedVx] = 2;
|
|
111917
|
+
while (Q.length > 0) {
|
|
111918
|
+
let testNeighbor = function(offset) {
|
|
111919
|
+
let xyzN = xyz.slice();
|
|
111920
|
+
xyzN[0] += offset[0];
|
|
111921
|
+
xyzN[1] += offset[1];
|
|
111922
|
+
xyzN[2] += offset[2];
|
|
111923
|
+
if (xyzN[0] < 0 || xyzN[1] < 0 || xyzN[2] < 0)
|
|
111924
|
+
return;
|
|
111925
|
+
if (xyzN[0] >= dims[0] || xyzN[1] >= dims[1] || xyzN[2] >= dims[2])
|
|
111926
|
+
return;
|
|
111927
|
+
let vxT = xyz2vx(xyzN);
|
|
111928
|
+
if (img[vxT] !== 1)
|
|
111929
|
+
return;
|
|
111930
|
+
img[vxT] = 2;
|
|
111931
|
+
Q.push(vxT);
|
|
111932
|
+
};
|
|
111933
|
+
let vx = Q[0];
|
|
111934
|
+
Q.shift();
|
|
111935
|
+
let xyz = vx2xyz(vx);
|
|
111936
|
+
testNeighbor([0, 0, -1]);
|
|
111937
|
+
testNeighbor([0, 0, 1]);
|
|
111938
|
+
testNeighbor([0, -1, 0]);
|
|
111939
|
+
testNeighbor([0, 1, 0]);
|
|
111940
|
+
testNeighbor([-1, 0, 0]);
|
|
111941
|
+
testNeighbor([1, 0, 0]);
|
|
111942
|
+
}
|
|
111943
|
+
for (let i2 = 1; i2 < nxyz; i2++)
|
|
111944
|
+
if (img[i2] === 2)
|
|
111945
|
+
this.drawBitmap[i2] = newColor;
|
|
111946
|
+
this.drawAddUndoBitmap();
|
|
111947
|
+
this.refreshDrawing(false);
|
|
111948
|
+
};
|
|
111109
111949
|
Niivue.prototype.drawPenFilled = function() {
|
|
111110
111950
|
let nPts = this.drawPenFillPts.length;
|
|
111111
111951
|
if (nPts < 2) {
|
|
@@ -111221,15 +112061,17 @@ Niivue.prototype.drawPenFilled = function() {
|
|
|
111221
112061
|
}
|
|
111222
112062
|
}
|
|
111223
112063
|
}
|
|
111224
|
-
if (!this.drawFillOverwrites && this.
|
|
111225
|
-
let nv = this.
|
|
112064
|
+
if (!this.drawFillOverwrites && this.drawUndoBitmaps[this.currentDrawUndoBitmap].length > 0) {
|
|
112065
|
+
let nv = this.drawBitmap.length;
|
|
112066
|
+
let bmp = decodeRLE(this.drawUndoBitmaps[this.currentDrawUndoBitmap], nv);
|
|
111226
112067
|
for (let i2 = 0; i2 < nv; i2++) {
|
|
111227
|
-
if (
|
|
112068
|
+
if (bmp[i2] === 0)
|
|
111228
112069
|
continue;
|
|
111229
|
-
this.drawBitmap[i2] =
|
|
112070
|
+
this.drawBitmap[i2] = bmp[i2];
|
|
111230
112071
|
}
|
|
111231
112072
|
}
|
|
111232
112073
|
this.drawPenFillPts = [];
|
|
112074
|
+
this.drawAddUndoBitmap();
|
|
111233
112075
|
this.refreshDrawing(false);
|
|
111234
112076
|
};
|
|
111235
112077
|
Niivue.prototype.closeDrawing = function() {
|
|
@@ -111947,11 +112789,14 @@ Niivue.prototype.mouseClick = function(x2, y, posChange = 0, isDelta = true) {
|
|
|
111947
112789
|
}
|
|
111948
112790
|
if (this.opts.drawingEnabled) {
|
|
111949
112791
|
let pt = this.frac2vox(this.scene.crosshairPos);
|
|
112792
|
+
if (this.opts.penValue < 0 || Object.is(this.opts.penValue, -0)) {
|
|
112793
|
+
this.drawFloodFill(pt, Math.abs(this.opts.penValue));
|
|
112794
|
+
return;
|
|
112795
|
+
}
|
|
111950
112796
|
if (isNaN(this.drawPenLocation[0])) {
|
|
111951
112797
|
this.drawPenAxCorSag = axCorSag;
|
|
111952
112798
|
this.drawPenFillPts = [];
|
|
111953
112799
|
this.drawPt(...pt, this.opts.penValue);
|
|
111954
|
-
this.drawUndoBitmap = this.drawBitmap.slice();
|
|
111955
112800
|
} else {
|
|
111956
112801
|
if (pt[0] === this.drawPenLocation[0] && pt[1] === this.drawPenLocation[1] && pt[2] === this.drawPenLocation[2])
|
|
111957
112802
|
return;
|
|
@@ -112107,9 +112952,12 @@ Niivue.prototype.setInterpolation = function(isNearest) {
|
|
|
112107
112952
|
this.updateInterpolation(1);
|
|
112108
112953
|
this.drawScene();
|
|
112109
112954
|
};
|
|
112110
|
-
Niivue.prototype.calculateMvpMatrixX = function() {
|
|
112111
|
-
let
|
|
112112
|
-
|
|
112955
|
+
Niivue.prototype.calculateMvpMatrixX = function(leftTopWidthHeight) {
|
|
112956
|
+
let gl = this.gl;
|
|
112957
|
+
gl.viewport(leftTopWidthHeight[0], leftTopWidthHeight[1], leftTopWidthHeight[2], leftTopWidthHeight[3]);
|
|
112958
|
+
let whratio = leftTopWidthHeight[2] / leftTopWidthHeight[3];
|
|
112959
|
+
console.log(">>", this.back.dimsRAS, this.back.matRAS);
|
|
112960
|
+
let scale2 = this.furthestFromPivot * 0.5;
|
|
112113
112961
|
let origin = [0, 0, 0];
|
|
112114
112962
|
let projectionMatrix = create$2();
|
|
112115
112963
|
if (whratio < 1)
|
|
@@ -112140,7 +112988,7 @@ Niivue.prototype.drawMesh3DX = function(isDepthTest = true, alpha = 1, leftTopWi
|
|
|
112140
112988
|
return;
|
|
112141
112989
|
let gl = this.gl;
|
|
112142
112990
|
let m, modelMtx, normMtx;
|
|
112143
|
-
[m, modelMtx, normMtx] = this.calculateMvpMatrixX(
|
|
112991
|
+
[m, modelMtx, normMtx] = this.calculateMvpMatrixX(leftTopWidthHeight);
|
|
112144
112992
|
gl.enable(gl.DEPTH_TEST);
|
|
112145
112993
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
112146
112994
|
gl.disable(gl.BLEND);
|
|
@@ -112273,7 +113121,6 @@ Niivue.prototype.draw2D = function(leftTopWidthHeight, axCorSag) {
|
|
|
112273
113121
|
], "S");
|
|
112274
113122
|
if (axCorSag !== this.sliceTypeAxial)
|
|
112275
113123
|
return;
|
|
112276
|
-
this.setPivot3D();
|
|
112277
113124
|
gl.viewport(leftTopWidthHeight[0], leftTopWidthHeight[1], leftTopWidthHeight[2], leftTopWidthHeight[3]);
|
|
112278
113125
|
gl.enable(gl.DEPTH_TEST);
|
|
112279
113126
|
gl.depthFunc(gl.ALWAYS);
|