@niivue/niivue 0.41.0 → 0.41.1
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 +34 -60
- package/build/index.js +411 -495
- package/build/index.js.map +1 -1
- package/build/index.min.js +1 -1
- package/package.json +35 -34
- package/src/niivue/index.ts +141 -178
- package/src/niivue-object3D.ts +42 -13
- package/src/nvconnectome.ts +10 -8
- package/src/nvdocument.ts +4 -1
- package/src/nvimage/index.ts +4 -1
- package/src/nvmesh-loaders.ts +82 -117
- package/src/nvmesh-types.ts +12 -12
- package/src/nvmesh.ts +73 -244
- package/src/shader-srcs.ts +114 -13
- package/src/types.ts +1 -0
package/build/index.js
CHANGED
|
@@ -10,11 +10,10 @@ var __publicField = (obj, key, value) => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
// src/niivue/index.ts
|
|
13
|
-
import { Subject } from "rxjs";
|
|
14
13
|
import { mat4 as mat46, vec2, vec3 as vec310, vec4 as vec47 } from "gl-matrix";
|
|
15
14
|
|
|
16
15
|
// package.json
|
|
17
|
-
var version = "0.41.
|
|
16
|
+
var version = "0.41.1";
|
|
18
17
|
|
|
19
18
|
// src/logger.ts
|
|
20
19
|
var _Log = class _Log {
|
|
@@ -745,8 +744,109 @@ out vec4 color;` + kDrawFunc + `void main() {
|
|
|
745
744
|
if ((isAlphaClipDark) && (background.a == 0.0)) color.a = 0.0; //FSLeyes clipping range
|
|
746
745
|
vec4 ocolor = vec4(0.0);
|
|
747
746
|
float overlayAlpha = overlayAlphaShader;
|
|
748
|
-
if (overlays > 0.0)
|
|
747
|
+
if (overlays > 0.0) {
|
|
749
748
|
ocolor = texture(overlay, texPos);
|
|
749
|
+
//dFdx for "boxing" issue 435 has aliasing on some implementations (coarse vs fine)
|
|
750
|
+
//however, this only identifies 50% of the edges due to aliasing effects
|
|
751
|
+
// http://www.aclockworkberry.com/shader-derivative-functions/
|
|
752
|
+
// https://bgolus.medium.com/distinctive-derivative-differences-cce38d36797b
|
|
753
|
+
//if ((ocolor.a >= 1.0) && ((dFdx(ocolor.a) != 0.0) || (dFdy(ocolor.a) != 0.0) ))
|
|
754
|
+
// ocolor.rbg = vec3(0.0, 0.0, 0.0);
|
|
755
|
+
bool isOutlineBelowNotAboveThreshold = true;
|
|
756
|
+
if (isOutlineBelowNotAboveThreshold) {
|
|
757
|
+
if ((overlayOutlineWidth > 0.0) && (ocolor.a < 1.0)) { //check voxel neighbors for edge
|
|
758
|
+
vec3 vx = (overlayOutlineWidth ) / vec3(textureSize(overlay, 0));
|
|
759
|
+
//6 voxel neighbors that share a face
|
|
760
|
+
vec3 vxR = vec3(texPos.x+vx.x, texPos.y, texPos.z);
|
|
761
|
+
vec3 vxL = vec3(texPos.x-vx.x, texPos.y, texPos.z);
|
|
762
|
+
vec3 vxA = vec3(texPos.x, texPos.y+vx.y, texPos.z);
|
|
763
|
+
vec3 vxP = vec3(texPos.x, texPos.y-vx.y, texPos.z);
|
|
764
|
+
vec3 vxS = vec3(texPos.x, texPos.y, texPos.z+vx.z);
|
|
765
|
+
vec3 vxI = vec3(texPos.x, texPos.y, texPos.z-vx.z);
|
|
766
|
+
float a = 0.0;
|
|
767
|
+
if (axCorSag != 2) {
|
|
768
|
+
a = max(a, texture(overlay, vxR).a);
|
|
769
|
+
a = max(a, texture(overlay, vxL).a);
|
|
770
|
+
}
|
|
771
|
+
if (axCorSag != 1) {
|
|
772
|
+
a = max(a, texture(overlay, vxA).a);
|
|
773
|
+
a = max(a, texture(overlay, vxP).a);
|
|
774
|
+
}
|
|
775
|
+
if (axCorSag != 0) {
|
|
776
|
+
a = max(a, texture(overlay, vxS).a);
|
|
777
|
+
a = max(a, texture(overlay, vxI).a);
|
|
778
|
+
}
|
|
779
|
+
bool isCheckCorners = true;
|
|
780
|
+
if (isCheckCorners) {
|
|
781
|
+
//12 voxel neighbors that share an edge
|
|
782
|
+
vec3 vxRA = vec3(texPos.x+vx.x, texPos.y+vx.y, texPos.z);
|
|
783
|
+
vec3 vxLA = vec3(texPos.x-vx.x, texPos.y+vx.y, texPos.z);
|
|
784
|
+
vec3 vxRP = vec3(texPos.x+vx.x, texPos.y-vx.y, texPos.z);
|
|
785
|
+
vec3 vxLP = vec3(texPos.x-vx.x, texPos.y-vx.y, texPos.z);
|
|
786
|
+
vec3 vxRS = vec3(texPos.x+vx.x, texPos.y, texPos.z+vx.z);
|
|
787
|
+
vec3 vxLS = vec3(texPos.x-vx.x, texPos.y, texPos.z+vx.z);
|
|
788
|
+
vec3 vxRI = vec3(texPos.x+vx.x, texPos.y, texPos.z-vx.z);
|
|
789
|
+
vec3 vxLI = vec3(texPos.x-vx.x, texPos.y, texPos.z-vx.z);
|
|
790
|
+
vec3 vxAS = vec3(texPos.x, texPos.y+vx.y, texPos.z+vx.z);
|
|
791
|
+
vec3 vxPS = vec3(texPos.x, texPos.y-vx.y, texPos.z+vx.z);
|
|
792
|
+
vec3 vxAI = vec3(texPos.x, texPos.y+vx.y, texPos.z-vx.z);
|
|
793
|
+
vec3 vxPI = vec3(texPos.x, texPos.y-vx.y, texPos.z-vx.z);
|
|
794
|
+
|
|
795
|
+
if (axCorSag == 0) { //axial corners
|
|
796
|
+
a = max(a, texture(overlay, vxRA).a);
|
|
797
|
+
a = max(a, texture(overlay, vxLA).a);
|
|
798
|
+
a = max(a, texture(overlay, vxRP).a);
|
|
799
|
+
a = max(a, texture(overlay, vxLP).a);
|
|
800
|
+
}
|
|
801
|
+
if (axCorSag == 1) { //coronal corners
|
|
802
|
+
a = max(a, texture(overlay, vxRS).a);
|
|
803
|
+
a = max(a, texture(overlay, vxLS).a);
|
|
804
|
+
a = max(a, texture(overlay, vxRI).a);
|
|
805
|
+
a = max(a, texture(overlay, vxLI).a);
|
|
806
|
+
}
|
|
807
|
+
if (axCorSag == 2) { //sagittal corners
|
|
808
|
+
a = max(a, texture(overlay, vxAS).a);
|
|
809
|
+
a = max(a, texture(overlay, vxPS).a);
|
|
810
|
+
a = max(a, texture(overlay, vxAI).a);
|
|
811
|
+
a = max(a, texture(overlay, vxPI).a);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
if (a >= 1.0) {
|
|
815
|
+
ocolor = vec4(0.0, 0.0, 0.0, 1.0);
|
|
816
|
+
overlayAlpha = 1.0;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
} else {
|
|
821
|
+
if ((overlayOutlineWidth > 0.0) && (ocolor.a >= 1.0)) { //check voxel neighbors for edge
|
|
822
|
+
vec3 vx = (overlayOutlineWidth ) / vec3(textureSize(overlay, 0));
|
|
823
|
+
vec3 vxR = vec3(texPos.x+vx.x, texPos.y, texPos.z);
|
|
824
|
+
vec3 vxL = vec3(texPos.x-vx.x, texPos.y, texPos.z);
|
|
825
|
+
vec3 vxA = vec3(texPos.x, texPos.y+vx.y, texPos.z);
|
|
826
|
+
vec3 vxP = vec3(texPos.x, texPos.y-vx.y, texPos.z);
|
|
827
|
+
vec3 vxS = vec3(texPos.x, texPos.y, texPos.z+vx.z);
|
|
828
|
+
vec3 vxI = vec3(texPos.x, texPos.y, texPos.z-vx.z);
|
|
829
|
+
float a = 1.0;
|
|
830
|
+
if (axCorSag != 2) {
|
|
831
|
+
a = min(a, texture(overlay, vxR).a);
|
|
832
|
+
a = min(a, texture(overlay, vxL).a);
|
|
833
|
+
}
|
|
834
|
+
if (axCorSag != 1) {
|
|
835
|
+
a = min(a, texture(overlay, vxA).a);
|
|
836
|
+
a = min(a, texture(overlay, vxP).a);
|
|
837
|
+
}
|
|
838
|
+
if (axCorSag != 0) {
|
|
839
|
+
a = min(a, texture(overlay, vxS).a);
|
|
840
|
+
a = min(a, texture(overlay, vxI).a);
|
|
841
|
+
}
|
|
842
|
+
if (a < 1.0) {
|
|
843
|
+
ocolor = vec4(0.0, 0.0, 0.0, 1.0);
|
|
844
|
+
overlayAlpha = 1.0;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
} //outline above threshold
|
|
848
|
+
}
|
|
849
|
+
|
|
750
850
|
`;
|
|
751
851
|
var kFragSliceTail = ` ocolor.a *= overlayAlpha;
|
|
752
852
|
vec4 dcolor = drawColor(texture(drawing, texPos).r, drawOpacity);
|
|
@@ -1176,28 +1276,28 @@ var fragGrowCutShader = `#version 300 es
|
|
|
1176
1276
|
uniform int finalPass;
|
|
1177
1277
|
uniform float coordZ;
|
|
1178
1278
|
uniform lowp sampler3D in3D;
|
|
1179
|
-
uniform highp isampler3D
|
|
1180
|
-
uniform highp isampler3D
|
|
1181
|
-
uniform highp isampler3D
|
|
1279
|
+
uniform highp isampler3D backTex; // background
|
|
1280
|
+
uniform highp isampler3D labelTex; // label
|
|
1281
|
+
uniform highp isampler3D strengthTex; // strength
|
|
1182
1282
|
void main(void) {
|
|
1183
1283
|
vec3 interpolatedTextureCoordinate = vec3(TexCoord.xy, coordZ);
|
|
1184
|
-
ivec3 size = textureSize(
|
|
1284
|
+
ivec3 size = textureSize(backTex, 0);
|
|
1185
1285
|
ivec3 texelIndex = ivec3(floor(interpolatedTextureCoordinate * vec3(size)));
|
|
1186
|
-
int background = texelFetch(
|
|
1187
|
-
label = texelFetch(
|
|
1188
|
-
strength = texelFetch(
|
|
1286
|
+
int background = texelFetch(backTex, texelIndex, 0).r;
|
|
1287
|
+
label = texelFetch(labelTex, texelIndex, 0).r;
|
|
1288
|
+
strength = texelFetch(strengthTex, texelIndex, 0).r;
|
|
1189
1289
|
for (int k = -1; k <= 1; k++) {
|
|
1190
1290
|
for (int j = -1; j <= 1; j++) {
|
|
1191
1291
|
for (int i = -1; i <= 1; i++) {
|
|
1192
1292
|
if (i != 0 && j != 0 && k != 0) {
|
|
1193
1293
|
ivec3 neighborIndex = texelIndex + ivec3(i,j,k);
|
|
1194
|
-
int neighborBackground = texelFetch(
|
|
1195
|
-
int neighborStrength = texelFetch(
|
|
1294
|
+
int neighborBackground = texelFetch(backTex, neighborIndex, 0).r;
|
|
1295
|
+
int neighborStrength = texelFetch(strengthTex, neighborIndex, 0).r;
|
|
1196
1296
|
int strengthCost = abs(neighborBackground - background);
|
|
1197
1297
|
int takeoverStrength = neighborStrength - strengthCost;
|
|
1198
1298
|
if (takeoverStrength > strength) {
|
|
1199
1299
|
strength = takeoverStrength;
|
|
1200
|
-
label = texelFetch(
|
|
1300
|
+
label = texelFetch(labelTex, neighborIndex, 0).r;
|
|
1201
1301
|
}
|
|
1202
1302
|
}
|
|
1203
1303
|
}
|
|
@@ -1211,7 +1311,7 @@ void main(void) {
|
|
|
1211
1311
|
for (int j = -1; j <= 1; j++)
|
|
1212
1312
|
for (int i = -1; i <= 1; i++) {
|
|
1213
1313
|
ivec3 neighborIndex = texelIndex + ivec3(i,j,k);
|
|
1214
|
-
int ilabel = texelFetch(
|
|
1314
|
+
int ilabel = texelFetch(labelTex, neighborIndex, 0).r;
|
|
1215
1315
|
if ((ilabel < 0) || (ilabel > 3))
|
|
1216
1316
|
ok = 0;
|
|
1217
1317
|
else
|
|
@@ -2816,8 +2916,8 @@ __publicField(_NiivueObject3D, "CULL_FACE", 2);
|
|
|
2816
2916
|
__publicField(_NiivueObject3D, "CULL_FRONT", 4);
|
|
2817
2917
|
__publicField(_NiivueObject3D, "CULL_BACK", 8);
|
|
2818
2918
|
__publicField(_NiivueObject3D, "ENABLE_DEPTH_TEST", 16);
|
|
2819
|
-
__publicField(_NiivueObject3D, "generateCrosshairs", function(gl, id, xyzMM, xyzMin, xyzMax, radius, sides = 20) {
|
|
2820
|
-
const geometry = _NiivueObject3D.generateCrosshairsGeometry(gl, xyzMM, xyzMin, xyzMax, radius, sides);
|
|
2919
|
+
__publicField(_NiivueObject3D, "generateCrosshairs", function(gl, id, xyzMM, xyzMin, xyzMax, radius, sides = 20, gap = 0) {
|
|
2920
|
+
const geometry = _NiivueObject3D.generateCrosshairsGeometry(gl, xyzMM, xyzMin, xyzMax, radius, sides, gap);
|
|
2821
2921
|
return new _NiivueObject3D(
|
|
2822
2922
|
id,
|
|
2823
2923
|
geometry.vertexBuffer,
|
|
@@ -2828,18 +2928,40 @@ __publicField(_NiivueObject3D, "generateCrosshairs", function(gl, id, xyzMM, xyz
|
|
|
2828
2928
|
);
|
|
2829
2929
|
});
|
|
2830
2930
|
// not included in public docs
|
|
2831
|
-
__publicField(_NiivueObject3D, "generateCrosshairsGeometry", function(gl, xyzMM, xyzMin, xyzMax, radius, sides = 20) {
|
|
2931
|
+
__publicField(_NiivueObject3D, "generateCrosshairsGeometry", function(gl, xyzMM, xyzMin, xyzMax, radius, sides = 20, gap = 0) {
|
|
2832
2932
|
const vertices = [];
|
|
2833
2933
|
const indices = [];
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2934
|
+
const gapX = radius * gap;
|
|
2935
|
+
if (gapX <= 0) {
|
|
2936
|
+
let start = vec3.fromValues(xyzMin[0], xyzMM[1], xyzMM[2]);
|
|
2937
|
+
let dest = vec3.fromValues(xyzMax[0], xyzMM[1], xyzMM[2]);
|
|
2938
|
+
_NiivueObject3D.makeCylinder(vertices, indices, start, dest, radius, sides);
|
|
2939
|
+
start = vec3.fromValues(xyzMM[0], xyzMin[1], xyzMM[2]);
|
|
2940
|
+
dest = vec3.fromValues(xyzMM[0], xyzMax[1], xyzMM[2]);
|
|
2941
|
+
_NiivueObject3D.makeCylinder(vertices, indices, start, dest, radius, sides);
|
|
2942
|
+
start = vec3.fromValues(xyzMM[0], xyzMM[1], xyzMin[2]);
|
|
2943
|
+
dest = vec3.fromValues(xyzMM[0], xyzMM[1], xyzMax[2]);
|
|
2944
|
+
_NiivueObject3D.makeCylinder(vertices, indices, start, dest, radius, sides);
|
|
2945
|
+
} else {
|
|
2946
|
+
let start = vec3.fromValues(xyzMin[0], xyzMM[1], xyzMM[2]);
|
|
2947
|
+
let dest = vec3.fromValues(xyzMM[0] - gapX, xyzMM[1], xyzMM[2]);
|
|
2948
|
+
_NiivueObject3D.makeCylinder(vertices, indices, start, dest, radius, sides, false);
|
|
2949
|
+
start = vec3.fromValues(xyzMM[0] + gapX, xyzMM[1], xyzMM[2]);
|
|
2950
|
+
dest = vec3.fromValues(xyzMax[0], xyzMM[1], xyzMM[2]);
|
|
2951
|
+
_NiivueObject3D.makeCylinder(vertices, indices, start, dest, radius, sides, false);
|
|
2952
|
+
start = vec3.fromValues(xyzMM[0], xyzMin[1], xyzMM[2]);
|
|
2953
|
+
dest = vec3.fromValues(xyzMM[0], xyzMM[1] - gapX, xyzMM[2]);
|
|
2954
|
+
_NiivueObject3D.makeCylinder(vertices, indices, start, dest, radius, sides, false);
|
|
2955
|
+
start = vec3.fromValues(xyzMM[0], xyzMM[1] + gapX, xyzMM[2]);
|
|
2956
|
+
dest = vec3.fromValues(xyzMM[0], xyzMax[1], xyzMM[2]);
|
|
2957
|
+
_NiivueObject3D.makeCylinder(vertices, indices, start, dest, radius, sides, false);
|
|
2958
|
+
start = vec3.fromValues(xyzMM[0], xyzMM[1], xyzMin[2]);
|
|
2959
|
+
dest = vec3.fromValues(xyzMM[0], xyzMM[1], xyzMM[2] - gapX);
|
|
2960
|
+
_NiivueObject3D.makeCylinder(vertices, indices, start, dest, radius, sides, false);
|
|
2961
|
+
start = vec3.fromValues(xyzMM[0], xyzMM[1], xyzMM[2] + gapX);
|
|
2962
|
+
dest = vec3.fromValues(xyzMM[0], xyzMM[1], xyzMax[2]);
|
|
2963
|
+
_NiivueObject3D.makeCylinder(vertices, indices, start, dest, radius, sides, false);
|
|
2964
|
+
}
|
|
2843
2965
|
const vertexBuffer = gl.createBuffer();
|
|
2844
2966
|
if (vertexBuffer === null) {
|
|
2845
2967
|
throw new Error("could not instantiate vertex buffer");
|
|
@@ -11374,11 +11496,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11374
11496
|
const offsetPt0 = [];
|
|
11375
11497
|
offsetPt0.push(npt);
|
|
11376
11498
|
const pts = [];
|
|
11377
|
-
const
|
|
11378
|
-
dps.push({
|
|
11379
|
-
id: "tract",
|
|
11380
|
-
vals: []
|
|
11381
|
-
});
|
|
11499
|
+
const bundleTags = [];
|
|
11382
11500
|
for (let t = 0; t < n_tracts; t++) {
|
|
11383
11501
|
line = readStr();
|
|
11384
11502
|
const new_tracts = readNumericTag("ni_dimen=");
|
|
@@ -11398,13 +11516,18 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11398
11516
|
}
|
|
11399
11517
|
npt += new_pts;
|
|
11400
11518
|
offsetPt0.push(npt);
|
|
11401
|
-
|
|
11519
|
+
bundleTags.push(bundleTag);
|
|
11402
11520
|
}
|
|
11403
11521
|
line = readStr();
|
|
11404
11522
|
}
|
|
11523
|
+
const dps = [];
|
|
11524
|
+
dps.push({
|
|
11525
|
+
id: "tract",
|
|
11526
|
+
vals: Float32Array.from(bundleTags)
|
|
11527
|
+
});
|
|
11405
11528
|
return {
|
|
11406
|
-
pts,
|
|
11407
|
-
offsetPt0,
|
|
11529
|
+
pts: new Float32Array(pts),
|
|
11530
|
+
offsetPt0: new Uint32Array(offsetPt0),
|
|
11408
11531
|
dps
|
|
11409
11532
|
};
|
|
11410
11533
|
}
|
|
@@ -11493,8 +11616,8 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11493
11616
|
}
|
|
11494
11617
|
return mat2;
|
|
11495
11618
|
}
|
|
11496
|
-
let offsetPt0 =
|
|
11497
|
-
let pts =
|
|
11619
|
+
let offsetPt0 = new Uint32Array(0);
|
|
11620
|
+
let pts = new Float32Array(0);
|
|
11498
11621
|
const mat = readMatV4(buffer);
|
|
11499
11622
|
if (!("trans_to_mni" in mat)) {
|
|
11500
11623
|
throw new Error("TT format file must have 'trans_to_mni'");
|
|
@@ -11526,8 +11649,6 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11526
11649
|
m[15]
|
|
11527
11650
|
);
|
|
11528
11651
|
mat42.transpose(trans_to_mni, trans_to_mni);
|
|
11529
|
-
const zoomMat = mat42.create();
|
|
11530
|
-
mat42.transpose(zoomMat, zoomMat);
|
|
11531
11652
|
function parse_tt(track) {
|
|
11532
11653
|
const dv = new DataView(track.buffer);
|
|
11533
11654
|
const pos = [];
|
|
@@ -11565,12 +11686,10 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11565
11686
|
for (let i2 = 0; i2 < npt; i2++) {
|
|
11566
11687
|
pts[i2] = pts[i2] / 32;
|
|
11567
11688
|
}
|
|
11568
|
-
const vox2mmMat = mat42.create();
|
|
11569
|
-
mat42.mul(vox2mmMat, trans_to_mni, zoomMat);
|
|
11570
11689
|
let v = 0;
|
|
11571
11690
|
for (let i2 = 0; i2 < npt / 3; i2++) {
|
|
11572
11691
|
const pos2 = vec42.fromValues(pts[v], pts[v + 1], pts[v + 2], 1);
|
|
11573
|
-
vec42.transformMat4(pos2, pos2,
|
|
11692
|
+
vec42.transformMat4(pos2, pos2, trans_to_mni);
|
|
11574
11693
|
pts[v++] = pos2[0];
|
|
11575
11694
|
pts[v++] = pos2[1];
|
|
11576
11695
|
pts[v++] = pos2[2];
|
|
@@ -11594,7 +11713,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11594
11713
|
}
|
|
11595
11714
|
let noff = 0;
|
|
11596
11715
|
let npt = 0;
|
|
11597
|
-
let pts = [];
|
|
11716
|
+
let pts = new Float32Array([]);
|
|
11598
11717
|
const offsetPt0 = [];
|
|
11599
11718
|
const dpg = [];
|
|
11600
11719
|
const dps = [];
|
|
@@ -11669,31 +11788,21 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11669
11788
|
if (pname.includes("groups")) {
|
|
11670
11789
|
dpg.push({
|
|
11671
11790
|
id: tag,
|
|
11672
|
-
vals:
|
|
11791
|
+
vals: Float32Array.from(vals.slice())
|
|
11673
11792
|
});
|
|
11674
11793
|
continue;
|
|
11675
11794
|
}
|
|
11676
11795
|
if (pname.includes("dpv")) {
|
|
11677
|
-
let mn = vals[0];
|
|
11678
|
-
let mx = vals[0];
|
|
11679
|
-
for (let i2 = 1; i2 < vals.length; i2++) {
|
|
11680
|
-
mn = Math.min(vals[i2], mn);
|
|
11681
|
-
mx = Math.max(vals[i2], mx);
|
|
11682
|
-
}
|
|
11683
11796
|
dpv.push({
|
|
11684
11797
|
id: tag,
|
|
11685
|
-
vals:
|
|
11686
|
-
global_min: mn,
|
|
11687
|
-
global_max: mx,
|
|
11688
|
-
cal_min: mn,
|
|
11689
|
-
cal_max: mx
|
|
11798
|
+
vals: Float32Array.from(vals.slice())
|
|
11690
11799
|
});
|
|
11691
11800
|
continue;
|
|
11692
11801
|
}
|
|
11693
11802
|
if (pname.includes("dps")) {
|
|
11694
11803
|
dps.push({
|
|
11695
11804
|
id: tag,
|
|
11696
|
-
vals:
|
|
11805
|
+
vals: Float32Array.from(vals.slice())
|
|
11697
11806
|
});
|
|
11698
11807
|
continue;
|
|
11699
11808
|
}
|
|
@@ -11705,7 +11814,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11705
11814
|
}
|
|
11706
11815
|
if (fname.startsWith("positions.3.")) {
|
|
11707
11816
|
npt = nval;
|
|
11708
|
-
pts =
|
|
11817
|
+
pts = new Float32Array(vals);
|
|
11709
11818
|
}
|
|
11710
11819
|
}
|
|
11711
11820
|
if (noff === 0 || npt === 0) {
|
|
@@ -11716,8 +11825,8 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11716
11825
|
}
|
|
11717
11826
|
offsetPt0[noff] = npt / 3;
|
|
11718
11827
|
return {
|
|
11719
|
-
pts
|
|
11720
|
-
offsetPt0:
|
|
11828
|
+
pts,
|
|
11829
|
+
offsetPt0: new Uint32Array(offsetPt0),
|
|
11721
11830
|
dpg,
|
|
11722
11831
|
dps,
|
|
11723
11832
|
dpv,
|
|
@@ -11877,23 +11986,16 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11877
11986
|
if (vers > 2 || hdr_sz !== 1e3 || magic !== 1128354388) {
|
|
11878
11987
|
throw new Error("Not a valid TRK file");
|
|
11879
11988
|
}
|
|
11880
|
-
const dps = [];
|
|
11881
|
-
const dpv = [];
|
|
11882
11989
|
const n_scalars = reader.getInt16(36, true);
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11886
|
-
|
|
11887
|
-
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
global_max: 0,
|
|
11893
|
-
cal_min: 0,
|
|
11894
|
-
cal_max: 0
|
|
11895
|
-
});
|
|
11896
|
-
}
|
|
11990
|
+
const dpv = [];
|
|
11991
|
+
for (let i2 = 0; i2 < n_scalars; i2++) {
|
|
11992
|
+
const arr = new Uint8Array(buffer.slice(38 + i2 * 20, 58 + i2 * 20));
|
|
11993
|
+
const str = new TextDecoder().decode(arr).split("\0").shift();
|
|
11994
|
+
dpv.push({
|
|
11995
|
+
id: str.trim(),
|
|
11996
|
+
// TODO can we guarantee this?
|
|
11997
|
+
vals: []
|
|
11998
|
+
});
|
|
11897
11999
|
}
|
|
11898
12000
|
const voxel_sizeX = reader.getFloat32(12, true);
|
|
11899
12001
|
const voxel_sizeY = reader.getFloat32(16, true);
|
|
@@ -11917,16 +12019,15 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11917
12019
|
1
|
|
11918
12020
|
);
|
|
11919
12021
|
const n_properties = reader.getInt16(238, true);
|
|
11920
|
-
|
|
11921
|
-
|
|
11922
|
-
|
|
11923
|
-
|
|
11924
|
-
|
|
11925
|
-
|
|
11926
|
-
|
|
11927
|
-
|
|
11928
|
-
|
|
11929
|
-
}
|
|
12022
|
+
const dps = [];
|
|
12023
|
+
for (let i2 = 0; i2 < n_properties; i2++) {
|
|
12024
|
+
const arr = new Uint8Array(buffer.slice(240 + i2 * 20, 260 + i2 * 20));
|
|
12025
|
+
const str = new TextDecoder().decode(arr).split("\0").shift();
|
|
12026
|
+
dps.push({
|
|
12027
|
+
id: str.trim(),
|
|
12028
|
+
// TODO can we guarantee this?
|
|
12029
|
+
vals: []
|
|
12030
|
+
});
|
|
11930
12031
|
}
|
|
11931
12032
|
const mat = mat42.create();
|
|
11932
12033
|
for (let i2 = 0; i2 < 16; i2++) {
|
|
@@ -11938,9 +12039,6 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11938
12039
|
}
|
|
11939
12040
|
const vox2mmMat = mat42.create();
|
|
11940
12041
|
mat42.mul(vox2mmMat, zoomMat, mat);
|
|
11941
|
-
vox2mmMat[3] = mat[3];
|
|
11942
|
-
vox2mmMat[7] = mat[7];
|
|
11943
|
-
vox2mmMat[11] = mat[11];
|
|
11944
12042
|
let i32 = null;
|
|
11945
12043
|
let f32 = null;
|
|
11946
12044
|
i32 = new Int32Array(buffer.slice(hdr_sz));
|
|
@@ -11982,15 +12080,19 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11982
12080
|
}
|
|
11983
12081
|
}
|
|
11984
12082
|
}
|
|
11985
|
-
|
|
11986
|
-
|
|
11987
|
-
|
|
11988
|
-
|
|
11989
|
-
|
|
11990
|
-
|
|
11991
|
-
|
|
11992
|
-
|
|
11993
|
-
|
|
12083
|
+
const dps32 = [];
|
|
12084
|
+
for (let i2 = 0; i2 < dps.length; i2++) {
|
|
12085
|
+
dps32.push({
|
|
12086
|
+
id: dps[i2].id,
|
|
12087
|
+
vals: Float32Array.from(dps[i2].vals)
|
|
12088
|
+
});
|
|
12089
|
+
}
|
|
12090
|
+
const dpv32 = [];
|
|
12091
|
+
for (let s = 0; s < dpv.length; s++) {
|
|
12092
|
+
dpv32.push({
|
|
12093
|
+
id: dpv[i].id,
|
|
12094
|
+
vals: Float32Array.from(dpv[i].vals)
|
|
12095
|
+
});
|
|
11994
12096
|
}
|
|
11995
12097
|
offsetPt0[noffset++] = npt;
|
|
11996
12098
|
pts = pts.slice(0, npt3);
|
|
@@ -11998,8 +12100,8 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
11998
12100
|
return {
|
|
11999
12101
|
pts,
|
|
12000
12102
|
offsetPt0,
|
|
12001
|
-
dps,
|
|
12002
|
-
dpv
|
|
12103
|
+
dps: dps32,
|
|
12104
|
+
dpv: dpv32
|
|
12003
12105
|
};
|
|
12004
12106
|
}
|
|
12005
12107
|
// readTRK()
|
|
@@ -12157,7 +12259,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
12157
12259
|
} else {
|
|
12158
12260
|
throw new Error("Unsupported ASCII VTK datatype " + items[0]);
|
|
12159
12261
|
}
|
|
12160
|
-
const indices = new
|
|
12262
|
+
const indices = new Uint32Array(tris);
|
|
12161
12263
|
return {
|
|
12162
12264
|
positions,
|
|
12163
12265
|
indices
|
|
@@ -12203,7 +12305,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
12203
12305
|
const mx2 = vals.reduce((acc, current) => Math.max(acc, current));
|
|
12204
12306
|
nvmesh.dpv.push({
|
|
12205
12307
|
id: tag,
|
|
12206
|
-
vals:
|
|
12308
|
+
vals: Float32Array.from(vals.slice()),
|
|
12207
12309
|
global_min: mn2,
|
|
12208
12310
|
global_max: mx2,
|
|
12209
12311
|
cal_min: mn2,
|
|
@@ -12615,7 +12717,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
12615
12717
|
}
|
|
12616
12718
|
if (ntri < 1) {
|
|
12617
12719
|
ntri = parseInt(items[0]);
|
|
12618
|
-
indices = new
|
|
12720
|
+
indices = new Uint32Array(ntri * 3);
|
|
12619
12721
|
continue;
|
|
12620
12722
|
}
|
|
12621
12723
|
if (t >= ntri * 3) {
|
|
@@ -12671,7 +12773,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
12671
12773
|
positions[j + 2] = parseFloat(items[2]);
|
|
12672
12774
|
j += 3;
|
|
12673
12775
|
}
|
|
12674
|
-
const indices = new
|
|
12776
|
+
const indices = new Uint32Array(ntri * 3);
|
|
12675
12777
|
j = 0;
|
|
12676
12778
|
for (let i = 0; i < ntri; i++) {
|
|
12677
12779
|
line = readStr();
|
|
@@ -12853,7 +12955,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
12853
12955
|
} else {
|
|
12854
12956
|
throw new Error("Unsupported binary VTK datatype " + items[0]);
|
|
12855
12957
|
}
|
|
12856
|
-
const indices = new
|
|
12958
|
+
const indices = new Uint32Array(tris);
|
|
12857
12959
|
return {
|
|
12858
12960
|
positions,
|
|
12859
12961
|
indices
|
|
@@ -12874,7 +12976,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
12874
12976
|
const nvert = reader.getUint32(28, true);
|
|
12875
12977
|
const vcoffset = reader.getUint32(48, true);
|
|
12876
12978
|
let pos = hdrBytes;
|
|
12877
|
-
const indices = new
|
|
12979
|
+
const indices = new Uint32Array(buffer, pos, nface * 3);
|
|
12878
12980
|
pos += nface * 3 * 4;
|
|
12879
12981
|
const positions = new Float32Array(buffer, pos, nvert * 3);
|
|
12880
12982
|
for (let i = 0; i < nvert * 3; i += 3) {
|
|
@@ -12957,7 +13059,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
12957
13059
|
let filepos = 16 + nskip;
|
|
12958
13060
|
let indices = null;
|
|
12959
13061
|
if (isFace) {
|
|
12960
|
-
indices = new
|
|
13062
|
+
indices = new Uint32Array(_buffer, filepos, nface * 3);
|
|
12961
13063
|
filepos += nface * 3 * 4;
|
|
12962
13064
|
}
|
|
12963
13065
|
let positions = null;
|
|
@@ -13111,7 +13213,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13111
13213
|
positions2[v + 2] = parseFloat(items[2]);
|
|
13112
13214
|
v += 3;
|
|
13113
13215
|
}
|
|
13114
|
-
let indices2 = new
|
|
13216
|
+
let indices2 = new Uint32Array(nface * 3);
|
|
13115
13217
|
let f = 0;
|
|
13116
13218
|
for (let i = 0; i < nface; i++) {
|
|
13117
13219
|
line = readStr();
|
|
@@ -13121,7 +13223,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13121
13223
|
break;
|
|
13122
13224
|
}
|
|
13123
13225
|
if (f + nTri * 3 > indices2.length) {
|
|
13124
|
-
const c = new
|
|
13226
|
+
const c = new Uint32Array(indices2.length + indices2.length);
|
|
13125
13227
|
c.set(indices2);
|
|
13126
13228
|
indices2 = c.slice();
|
|
13127
13229
|
}
|
|
@@ -13171,7 +13273,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13171
13273
|
pos += vertStride;
|
|
13172
13274
|
}
|
|
13173
13275
|
}
|
|
13174
|
-
const indices = new
|
|
13276
|
+
const indices = new Uint32Array(nface * 3);
|
|
13175
13277
|
let isTriangular = true;
|
|
13176
13278
|
let j = 0;
|
|
13177
13279
|
if (indexCountBytes === 1 && indexBytes === 4 && indexStrideBytes === 13) {
|
|
@@ -13262,7 +13364,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13262
13364
|
header = lines[line].trim().split(/\s+/);
|
|
13263
13365
|
line++;
|
|
13264
13366
|
const num_f = parseInt(header[0]);
|
|
13265
|
-
const indices = new
|
|
13367
|
+
const indices = new Uint32Array(num_f * 3);
|
|
13266
13368
|
for (let i = 0; i < num_f; i++) {
|
|
13267
13369
|
const items = lines[line].trim().split(/\s+/);
|
|
13268
13370
|
line++;
|
|
@@ -13347,7 +13449,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13347
13449
|
}
|
|
13348
13450
|
}
|
|
13349
13451
|
const positions = new Float32Array(pts);
|
|
13350
|
-
const indices = new
|
|
13452
|
+
const indices = new Uint32Array(t);
|
|
13351
13453
|
return {
|
|
13352
13454
|
positions,
|
|
13353
13455
|
indices
|
|
@@ -13393,7 +13495,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13393
13495
|
i++;
|
|
13394
13496
|
}
|
|
13395
13497
|
const positions = new Float32Array(pts);
|
|
13396
|
-
const indices = new
|
|
13498
|
+
const indices = new Uint32Array(t);
|
|
13397
13499
|
return {
|
|
13398
13500
|
positions,
|
|
13399
13501
|
indices
|
|
@@ -13429,7 +13531,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13429
13531
|
j += num_c * 4;
|
|
13430
13532
|
j += nTri;
|
|
13431
13533
|
const nTriX3 = nTri * 3;
|
|
13432
|
-
const indices = new
|
|
13534
|
+
const indices = new Uint32Array(nTriX3);
|
|
13433
13535
|
for (let i = 0; i < nTriX3; i++) {
|
|
13434
13536
|
indices[i] = parseInt(items[j++]);
|
|
13435
13537
|
}
|
|
@@ -13478,7 +13580,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13478
13580
|
}
|
|
13479
13581
|
}
|
|
13480
13582
|
const positions = new Float32Array(pts);
|
|
13481
|
-
const indices = new
|
|
13583
|
+
const indices = new Uint32Array(t);
|
|
13482
13584
|
return {
|
|
13483
13585
|
positions,
|
|
13484
13586
|
indices
|
|
@@ -13513,7 +13615,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13513
13615
|
offset += 4;
|
|
13514
13616
|
}
|
|
13515
13617
|
nf *= 3;
|
|
13516
|
-
const indices = new
|
|
13618
|
+
const indices = new Uint32Array(nf);
|
|
13517
13619
|
for (let i = 0; i < nf; i++) {
|
|
13518
13620
|
indices[i] = view.getUint32(offset, false);
|
|
13519
13621
|
offset += 4;
|
|
@@ -13630,7 +13732,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13630
13732
|
const nNearest = reader.getUint32(pos, true);
|
|
13631
13733
|
pos += 4 + 4 * nNearest;
|
|
13632
13734
|
}
|
|
13633
|
-
const indices = new
|
|
13735
|
+
const indices = new Uint32Array(nTri * 3);
|
|
13634
13736
|
for (let i = 0; i < nTri * 3; i++) {
|
|
13635
13737
|
indices[i] = reader.getInt32(pos, true);
|
|
13636
13738
|
pos += 4;
|
|
@@ -13669,7 +13771,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13669
13771
|
throw new Error("Unable to parse ASCII STL file.");
|
|
13670
13772
|
}
|
|
13671
13773
|
const positions = new Float32Array(pts);
|
|
13672
|
-
const indices = new
|
|
13774
|
+
const indices = new Uint32Array(npts);
|
|
13673
13775
|
for (let i = 0; i < npts; i++) {
|
|
13674
13776
|
indices[i] = i;
|
|
13675
13777
|
}
|
|
@@ -13695,7 +13797,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13695
13797
|
if (buffer.byteLength < 80 + 4 + ntri * 50) {
|
|
13696
13798
|
throw new Error("STL file too small to store triangles = " + ntri);
|
|
13697
13799
|
}
|
|
13698
|
-
const indices = new
|
|
13800
|
+
const indices = new Uint32Array(ntri3);
|
|
13699
13801
|
const positions = new Float32Array(ntri3 * 3);
|
|
13700
13802
|
let pos = 80 + 4 + 12;
|
|
13701
13803
|
let v = 0;
|
|
@@ -13790,7 +13892,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13790
13892
|
let indexCount = 0;
|
|
13791
13893
|
let surfaceNumberOfVertices = 0;
|
|
13792
13894
|
let brainStructure = "";
|
|
13793
|
-
let vertexIndices = new
|
|
13895
|
+
let vertexIndices = new Uint32Array();
|
|
13794
13896
|
const bytes = new Uint8Array(buffer);
|
|
13795
13897
|
let pos = 552;
|
|
13796
13898
|
let line;
|
|
@@ -13840,7 +13942,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
13840
13942
|
if (items.length < indexCount) {
|
|
13841
13943
|
log.error("Error parsing VertexIndices");
|
|
13842
13944
|
}
|
|
13843
|
-
vertexIndices = new
|
|
13945
|
+
vertexIndices = new Uint32Array(indexCount);
|
|
13844
13946
|
for (let i = 0; i < indexCount; i++) {
|
|
13845
13947
|
vertexIndices[i] = parseInt(items[i]);
|
|
13846
13948
|
}
|
|
@@ -14372,8 +14474,8 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
14372
14474
|
}
|
|
14373
14475
|
return {
|
|
14374
14476
|
positions: Float32Array.from(positions),
|
|
14375
|
-
indices:
|
|
14376
|
-
rgba255
|
|
14477
|
+
indices: Uint32Array.from(indices),
|
|
14478
|
+
rgba255: Uint8Array.from(rgba255)
|
|
14377
14479
|
};
|
|
14378
14480
|
}
|
|
14379
14481
|
// readX3D()
|
|
@@ -14441,7 +14543,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
14441
14543
|
}
|
|
14442
14544
|
len = tag.contentEndPos;
|
|
14443
14545
|
let positions = new Float32Array();
|
|
14444
|
-
let indices = new
|
|
14546
|
+
let indices = new Uint32Array();
|
|
14445
14547
|
let scalars = new Float32Array();
|
|
14446
14548
|
let anatomicalStructurePrimary = "";
|
|
14447
14549
|
let isIdx = false;
|
|
@@ -14568,7 +14670,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
14568
14670
|
if (dataType !== 8) {
|
|
14569
14671
|
log.warn("expect indices as INT32");
|
|
14570
14672
|
}
|
|
14571
|
-
indices = new
|
|
14673
|
+
indices = new Uint32Array(datBin.buffer);
|
|
14572
14674
|
if (isColMajor) {
|
|
14573
14675
|
const tmp = indices.slice();
|
|
14574
14676
|
const np = tmp.length / 3;
|
|
@@ -14701,7 +14803,7 @@ var NVMeshLoaders = class _NVMeshLoaders {
|
|
|
14701
14803
|
|
|
14702
14804
|
// src/nvmesh.ts
|
|
14703
14805
|
var NVMeshFromUrlOptions = class {
|
|
14704
|
-
constructor(url = "", gl = null, name = "", opacity = 1, rgba255 = [255, 255, 255, 255], visible = true, layers = [], colorbarVisible = true) {
|
|
14806
|
+
constructor(url = "", gl = null, name = "", opacity = 1, rgba255 = new Uint8Array([255, 255, 255, 255]), visible = true, layers = [], colorbarVisible = true) {
|
|
14705
14807
|
__publicField(this, "url");
|
|
14706
14808
|
__publicField(this, "gl");
|
|
14707
14809
|
__publicField(this, "name");
|
|
@@ -14736,7 +14838,7 @@ var NVMesh = class _NVMesh {
|
|
|
14736
14838
|
* @param colorbarVisible - does this mesh display a colorbar
|
|
14737
14839
|
* @param anatomicalStructurePrimary - region for mesh. Default is an empty string
|
|
14738
14840
|
*/
|
|
14739
|
-
constructor(pts, tris, name = "", rgba255 = [255, 255, 255, 255], opacity = 1, visible = true, gl, connectome = null, dpg = null, dps = null, dpv = null, colorbarVisible = true, anatomicalStructurePrimary = "") {
|
|
14841
|
+
constructor(pts, tris, name = "", rgba255 = new Uint8Array([255, 255, 255, 255]), opacity = 1, visible = true, gl, connectome = null, dpg = null, dps = null, dpv = null, colorbarVisible = true, anatomicalStructurePrimary = "") {
|
|
14740
14842
|
__publicField(this, "id");
|
|
14741
14843
|
__publicField(this, "name");
|
|
14742
14844
|
__publicField(this, "anatomicalStructurePrimary");
|
|
@@ -14784,6 +14886,7 @@ var NVMesh = class _NVMesh {
|
|
|
14784
14886
|
__publicField(this, "vertexCount", 1);
|
|
14785
14887
|
__publicField(this, "nodeScale", 4);
|
|
14786
14888
|
__publicField(this, "edgeScale", 1);
|
|
14889
|
+
__publicField(this, "legendLineThickness", 0);
|
|
14787
14890
|
__publicField(this, "nodeColormap", "warm");
|
|
14788
14891
|
__publicField(this, "edgeColormap", "warm");
|
|
14789
14892
|
__publicField(this, "nodeColormapNegative");
|
|
@@ -14846,6 +14949,15 @@ var NVMesh = class _NVMesh {
|
|
|
14846
14949
|
this.dpg = dpg;
|
|
14847
14950
|
this.dps = dps;
|
|
14848
14951
|
this.dpv = dpv;
|
|
14952
|
+
if (dpg) {
|
|
14953
|
+
this.initValuesArray(dpg);
|
|
14954
|
+
}
|
|
14955
|
+
if (dps) {
|
|
14956
|
+
this.initValuesArray(dps);
|
|
14957
|
+
}
|
|
14958
|
+
if (dpv) {
|
|
14959
|
+
this.initValuesArray(dpv);
|
|
14960
|
+
}
|
|
14849
14961
|
this.offsetPt0 = tris;
|
|
14850
14962
|
this.updateFibers(gl);
|
|
14851
14963
|
gl.bindVertexArray(this.vaoFiber);
|
|
@@ -14870,6 +14982,17 @@ var NVMesh = class _NVMesh {
|
|
|
14870
14982
|
this.tris = tris;
|
|
14871
14983
|
this.updateMesh(gl);
|
|
14872
14984
|
}
|
|
14985
|
+
initValuesArray(va) {
|
|
14986
|
+
for (let i = 0; i < va.length; i++) {
|
|
14987
|
+
const mn = va[i].vals.reduce((acc, current) => Math.min(acc, current));
|
|
14988
|
+
const mx = va[i].vals.reduce((acc, current) => Math.max(acc, current));
|
|
14989
|
+
va[i].global_min = mn;
|
|
14990
|
+
va[i].global_max = mx;
|
|
14991
|
+
va[i].cal_min = mn;
|
|
14992
|
+
va[i].cal_max = mx;
|
|
14993
|
+
}
|
|
14994
|
+
return va;
|
|
14995
|
+
}
|
|
14873
14996
|
// given streamlines (which webGL renders as a single pixel), extrude to cylinders
|
|
14874
14997
|
linesToCylinders(gl, posClrF32, indices) {
|
|
14875
14998
|
function v4ToV3(v4) {
|
|
@@ -14965,7 +15088,7 @@ var NVMesh = class _NVMesh {
|
|
|
14965
15088
|
}
|
|
14966
15089
|
}
|
|
14967
15090
|
const nidx = (n_line_vtx - n_streamlines) * cyl_sides * 2 * 3;
|
|
14968
|
-
const idxs = new
|
|
15091
|
+
const idxs = new Uint32Array(nidx);
|
|
14969
15092
|
let idx = 0;
|
|
14970
15093
|
vtx = 0;
|
|
14971
15094
|
for (let i = 1; i < n_count; i++) {
|
|
@@ -14997,9 +15120,9 @@ var NVMesh = class _NVMesh {
|
|
|
14997
15120
|
vtx += cyl_sides;
|
|
14998
15121
|
}
|
|
14999
15122
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
|
15000
|
-
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
|
|
15123
|
+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, Uint32Array.from(idxs), gl.STATIC_DRAW);
|
|
15001
15124
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
15002
|
-
gl.bufferData(gl.ARRAY_BUFFER,
|
|
15125
|
+
gl.bufferData(gl.ARRAY_BUFFER, Float32Array.from(f32), gl.STATIC_DRAW);
|
|
15003
15126
|
this.indexCount = nidx;
|
|
15004
15127
|
}
|
|
15005
15128
|
// linesToCylinders
|
|
@@ -15014,7 +15137,7 @@ var NVMesh = class _NVMesh {
|
|
|
15014
15137
|
const n_count = offsetPt0.length - 1;
|
|
15015
15138
|
const npt = pts.length / 3;
|
|
15016
15139
|
if (!this.fiberLengths) {
|
|
15017
|
-
this.fiberLengths =
|
|
15140
|
+
this.fiberLengths = new Uint32Array(n_count);
|
|
15018
15141
|
for (let i = 0; i < n_count; i++) {
|
|
15019
15142
|
const vStart3 = offsetPt0[i] * 3;
|
|
15020
15143
|
const vEnd3 = (offsetPt0[i + 1] - 1) * 3;
|
|
@@ -15023,7 +15146,7 @@ var NVMesh = class _NVMesh {
|
|
|
15023
15146
|
const v = vec34.fromValues(pts[j + 0] - pts[j + 3], pts[j + 1] - pts[j + 4], pts[j + 2] - pts[j + 5]);
|
|
15024
15147
|
len += vec34.len(v);
|
|
15025
15148
|
}
|
|
15026
|
-
this.fiberLengths
|
|
15149
|
+
this.fiberLengths[i] = len;
|
|
15027
15150
|
}
|
|
15028
15151
|
}
|
|
15029
15152
|
const posClrF32 = new Float32Array(npt * 4);
|
|
@@ -15236,119 +15359,12 @@ var NVMesh = class _NVMesh {
|
|
|
15236
15359
|
} else {
|
|
15237
15360
|
this.indexCount = indices.length;
|
|
15238
15361
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
15239
|
-
gl.bufferData(gl.ARRAY_BUFFER,
|
|
15362
|
+
gl.bufferData(gl.ARRAY_BUFFER, Uint32Array.from(posClrU32), gl.STATIC_DRAW);
|
|
15240
15363
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
|
15241
|
-
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
|
|
15364
|
+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, Uint32Array.from(indices), gl.STATIC_DRAW);
|
|
15242
15365
|
}
|
|
15243
15366
|
}
|
|
15244
15367
|
// updateFibers()
|
|
15245
|
-
// internal function filters connectome to identify which color, size and visibility of nodes and edges
|
|
15246
|
-
updateConnectome(gl) {
|
|
15247
|
-
const tris = [];
|
|
15248
|
-
const nNode = this.nodes.X.length;
|
|
15249
|
-
let hasEdges = false;
|
|
15250
|
-
if (nNode > 1 && this.edges) {
|
|
15251
|
-
let nEdges = this.edges.length;
|
|
15252
|
-
if (nEdges = nNode * nNode) {
|
|
15253
|
-
hasEdges = true;
|
|
15254
|
-
} else {
|
|
15255
|
-
log.warn("Expected %d edges not %d", nNode * nNode, nEdges);
|
|
15256
|
-
}
|
|
15257
|
-
}
|
|
15258
|
-
const pts = [];
|
|
15259
|
-
const rgba255 = [];
|
|
15260
|
-
let lut = cmapper.colormap(this.nodeColormap, this.colormapInvert);
|
|
15261
|
-
let lutNeg = cmapper.colormap(this.nodeColormapNegative, this.colormapInvert);
|
|
15262
|
-
let hasNeg = this.nodeColormapNegative !== void 0;
|
|
15263
|
-
let min = this.nodeMinColor;
|
|
15264
|
-
let max = this.nodeMaxColor;
|
|
15265
|
-
for (let i = 0; i < nNode; i++) {
|
|
15266
|
-
const radius = this.nodes.Size[i] * this.nodeScale;
|
|
15267
|
-
if (radius <= 0) {
|
|
15268
|
-
continue;
|
|
15269
|
-
}
|
|
15270
|
-
let color = this.nodes.Color[i];
|
|
15271
|
-
let isNeg = false;
|
|
15272
|
-
if (hasNeg && color < 0) {
|
|
15273
|
-
isNeg = true;
|
|
15274
|
-
color = -color;
|
|
15275
|
-
}
|
|
15276
|
-
if (min < max) {
|
|
15277
|
-
if (color < min) {
|
|
15278
|
-
continue;
|
|
15279
|
-
}
|
|
15280
|
-
color = (color - min) / (max - min);
|
|
15281
|
-
} else {
|
|
15282
|
-
color = 1;
|
|
15283
|
-
}
|
|
15284
|
-
color = Math.round(Math.max(Math.min(255, color * 255))) * 4;
|
|
15285
|
-
let rgba = [lut[color], lut[color + 1], lut[color + 2], 255];
|
|
15286
|
-
if (isNeg) {
|
|
15287
|
-
rgba = [lutNeg[color], lutNeg[color + 1], lutNeg[color + 2], 255];
|
|
15288
|
-
}
|
|
15289
|
-
const pt = [
|
|
15290
|
-
this.nodes.X[i],
|
|
15291
|
-
this.nodes.Y[i],
|
|
15292
|
-
this.nodes.Z[i]
|
|
15293
|
-
];
|
|
15294
|
-
NiivueObject3D.makeColoredSphere(pts, tris, rgba255, radius, pt, rgba);
|
|
15295
|
-
}
|
|
15296
|
-
if (hasEdges) {
|
|
15297
|
-
lut = cmapper.colormap(this.edgeColormap, this.colormapInvert);
|
|
15298
|
-
lutNeg = cmapper.colormap(this.edgeColormapNegative, this.colormapInvert);
|
|
15299
|
-
hasNeg = this.edgeColormapNegative !== void 0;
|
|
15300
|
-
min = this.edgeMin;
|
|
15301
|
-
max = this.edgeMax;
|
|
15302
|
-
for (let i = 0; i < nNode - 1; i++) {
|
|
15303
|
-
for (let j = i + 1; j < nNode; j++) {
|
|
15304
|
-
let color = this.edges[i * nNode + j];
|
|
15305
|
-
let isNeg = false;
|
|
15306
|
-
if (hasNeg && color < 0) {
|
|
15307
|
-
isNeg = true;
|
|
15308
|
-
color = -color;
|
|
15309
|
-
}
|
|
15310
|
-
const radius = color * this.edgeScale;
|
|
15311
|
-
if (radius <= 0) {
|
|
15312
|
-
continue;
|
|
15313
|
-
}
|
|
15314
|
-
if (min < max) {
|
|
15315
|
-
if (color < min) {
|
|
15316
|
-
continue;
|
|
15317
|
-
}
|
|
15318
|
-
color = (color - min) / (max - min);
|
|
15319
|
-
} else {
|
|
15320
|
-
color = 1;
|
|
15321
|
-
}
|
|
15322
|
-
color = Math.round(Math.max(Math.min(255, color * 255))) * 4;
|
|
15323
|
-
let rgba = [lut[color], lut[color + 1], lut[color + 2], 255];
|
|
15324
|
-
if (isNeg) {
|
|
15325
|
-
rgba = [lutNeg[color], lutNeg[color + 1], lutNeg[color + 2], 255];
|
|
15326
|
-
}
|
|
15327
|
-
const pti = [
|
|
15328
|
-
this.nodes.X[i],
|
|
15329
|
-
this.nodes.Y[i],
|
|
15330
|
-
this.nodes.Z[i]
|
|
15331
|
-
];
|
|
15332
|
-
const ptj = [
|
|
15333
|
-
this.nodes.X[j],
|
|
15334
|
-
this.nodes.Y[j],
|
|
15335
|
-
this.nodes.Z[j]
|
|
15336
|
-
];
|
|
15337
|
-
NiivueObject3D.makeColoredCylinder(pts, tris, rgba255, pti, ptj, radius, rgba);
|
|
15338
|
-
}
|
|
15339
|
-
}
|
|
15340
|
-
}
|
|
15341
|
-
const obj = NVMeshUtilities.getExtents(pts);
|
|
15342
|
-
this.furthestVertexFromOrigin = obj.mxDx;
|
|
15343
|
-
this.extentsMin = obj.extentsMin;
|
|
15344
|
-
this.extentsMax = obj.extentsMax;
|
|
15345
|
-
const posNormClr = this.generatePosNormClr(pts, tris, rgba255);
|
|
15346
|
-
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
|
15347
|
-
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Int32Array(tris), gl.STATIC_DRAW);
|
|
15348
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
15349
|
-
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(posNormClr), gl.STATIC_DRAW);
|
|
15350
|
-
this.indexCount = tris.length;
|
|
15351
|
-
}
|
|
15352
15368
|
// given X,Y,Z coordinates in world space, return index of nearest vertex as well as
|
|
15353
15369
|
// the distance of this closest vertex to the coordinates
|
|
15354
15370
|
indexNearestXYZmm(Xmm, Ymm, Zmm) {
|
|
@@ -15376,7 +15392,6 @@ var NVMesh = class _NVMesh {
|
|
|
15376
15392
|
return;
|
|
15377
15393
|
}
|
|
15378
15394
|
if (this.hasConnectome) {
|
|
15379
|
-
this.updateConnectome(gl);
|
|
15380
15395
|
return;
|
|
15381
15396
|
}
|
|
15382
15397
|
if (!this.pts || !this.tris || !this.rgba255) {
|
|
@@ -15649,9 +15664,9 @@ var NVMesh = class _NVMesh {
|
|
|
15649
15664
|
}
|
|
15650
15665
|
}
|
|
15651
15666
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
|
15652
|
-
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
|
|
15667
|
+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, Uint32Array.from(this.tris), gl.STATIC_DRAW);
|
|
15653
15668
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
15654
|
-
gl.bufferData(gl.ARRAY_BUFFER,
|
|
15669
|
+
gl.bufferData(gl.ARRAY_BUFFER, Float32Array.from(posNormClr), gl.STATIC_DRAW);
|
|
15655
15670
|
this.indexCount = this.tris.length;
|
|
15656
15671
|
this.vertexCount = this.pts.length;
|
|
15657
15672
|
}
|
|
@@ -15738,75 +15753,10 @@ var NVMesh = class _NVMesh {
|
|
|
15738
15753
|
}
|
|
15739
15754
|
return f32;
|
|
15740
15755
|
}
|
|
15741
|
-
static loadConnectomeFromFreeSurfer(json, gl, name = "", opacity = 1, visible = true) {
|
|
15742
|
-
let isValid = true;
|
|
15743
|
-
if (json.data_type === void 0) {
|
|
15744
|
-
isValid = false;
|
|
15745
|
-
} else if (json.data_type !== "fs_pointset") {
|
|
15746
|
-
isValid = false;
|
|
15747
|
-
}
|
|
15748
|
-
if (json.points === void 0) {
|
|
15749
|
-
isValid = false;
|
|
15750
|
-
}
|
|
15751
|
-
if (!isValid) {
|
|
15752
|
-
throw Error("not a valid FreeSurfer json pointset");
|
|
15753
|
-
}
|
|
15754
|
-
const jcon = {
|
|
15755
|
-
nodes: {
|
|
15756
|
-
names: [],
|
|
15757
|
-
prefilled: [],
|
|
15758
|
-
X: [],
|
|
15759
|
-
Y: [],
|
|
15760
|
-
Z: [],
|
|
15761
|
-
Color: [],
|
|
15762
|
-
Size: []
|
|
15763
|
-
},
|
|
15764
|
-
edges: [],
|
|
15765
|
-
// @ts-expect-error not sure where this should come from
|
|
15766
|
-
name: this.data_type
|
|
15767
|
-
};
|
|
15768
|
-
if (!json.points) {
|
|
15769
|
-
throw new Error("points are not set!");
|
|
15770
|
-
}
|
|
15771
|
-
for (let i = 0; i < json.points.length; i++) {
|
|
15772
|
-
let name2 = "";
|
|
15773
|
-
if (json.points[i].comments) {
|
|
15774
|
-
if (json.points[i].comments[0].text) {
|
|
15775
|
-
name2 = json.points[i].comments[0].text;
|
|
15776
|
-
}
|
|
15777
|
-
}
|
|
15778
|
-
jcon.nodes.names.push(name2);
|
|
15779
|
-
let prefilled = "";
|
|
15780
|
-
if (json.points[i].comments) {
|
|
15781
|
-
if (json.points[i].comments[0].prefilled) {
|
|
15782
|
-
prefilled = json.points[i].comments[0].prefilled;
|
|
15783
|
-
}
|
|
15784
|
-
}
|
|
15785
|
-
jcon.nodes.prefilled.push(prefilled);
|
|
15786
|
-
jcon.nodes.X.push(json.points[i].coordinates.x);
|
|
15787
|
-
jcon.nodes.Y.push(json.points[i].coordinates.y);
|
|
15788
|
-
jcon.nodes.Z.push(json.points[i].coordinates.z);
|
|
15789
|
-
jcon.nodes.Color.push(1);
|
|
15790
|
-
jcon.nodes.Size.push(1);
|
|
15791
|
-
}
|
|
15792
|
-
return new _NVMesh([], [], name, [], opacity, visible, gl, jcon);
|
|
15793
|
-
}
|
|
15794
|
-
// loadConnectomeFromFreeSurfer
|
|
15795
|
-
// read connectome saved as JSON
|
|
15796
|
-
static loadConnectomeFromJSON(json, gl, name = "", opacity = 1, visible = true) {
|
|
15797
|
-
if ("name" in json) {
|
|
15798
|
-
name = this.name;
|
|
15799
|
-
}
|
|
15800
|
-
if (!("nodes" in json)) {
|
|
15801
|
-
throw Error("not a valid jcon connectome file");
|
|
15802
|
-
}
|
|
15803
|
-
return new _NVMesh([], [], name, [], opacity, visible, gl, json);
|
|
15804
|
-
}
|
|
15805
|
-
// loadConnectomeFromJSON()
|
|
15806
15756
|
// wrapper to read meshes, tractograms and connectomes regardless of format
|
|
15807
|
-
static readMesh(buffer, name, gl, opacity = 1, rgba255 = [255, 255, 255, 255], visible = true) {
|
|
15808
|
-
let tris = [];
|
|
15809
|
-
let pts = [];
|
|
15757
|
+
static readMesh(buffer, name, gl, opacity = 1, rgba255 = new Uint8Array([255, 255, 255, 255]), visible = true) {
|
|
15758
|
+
let tris = new Uint32Array([]);
|
|
15759
|
+
let pts = new Float32Array([]);
|
|
15810
15760
|
let anatomicalStructurePrimary = "";
|
|
15811
15761
|
let obj;
|
|
15812
15762
|
const re = /(?:\.([^.]+))?$/;
|
|
@@ -15817,12 +15767,12 @@ var NVMesh = class _NVMesh {
|
|
|
15817
15767
|
ext = ext.toUpperCase();
|
|
15818
15768
|
}
|
|
15819
15769
|
if (ext === "JCON") {
|
|
15820
|
-
|
|
15770
|
+
log.error("you should never see this message: load using nvconnectome not nvmesh");
|
|
15821
15771
|
}
|
|
15822
15772
|
if (ext === "JSON") {
|
|
15823
|
-
|
|
15773
|
+
log.error("you should never see this message: load using nvconnectome not nvmesh");
|
|
15824
15774
|
}
|
|
15825
|
-
rgba255[3] = Math.max(
|
|
15775
|
+
rgba255[3] = Math.max(1, rgba255[3]);
|
|
15826
15776
|
if (ext === "TCK" || ext === "TRK" || ext === "TT" || ext === "TRX" || ext === "TRACT") {
|
|
15827
15777
|
if (ext === "TCK") {
|
|
15828
15778
|
obj = NVMeshLoaders.readTCK(buffer);
|
|
@@ -15836,12 +15786,12 @@ var NVMesh = class _NVMesh {
|
|
|
15836
15786
|
obj = NVMeshLoaders.readTRK(buffer);
|
|
15837
15787
|
}
|
|
15838
15788
|
if (typeof obj === "undefined") {
|
|
15839
|
-
const pts2 = [0, 0, 0, 0, 0, 0];
|
|
15840
|
-
const offsetPt0 = [0];
|
|
15789
|
+
const pts2 = new Float32Array([0, 0, 0, 0, 0, 0]);
|
|
15790
|
+
const offsetPt0 = new Uint32Array([0]);
|
|
15841
15791
|
obj = { pts: pts2, offsetPt0 };
|
|
15842
15792
|
log.error("Creating empty tracts");
|
|
15843
15793
|
}
|
|
15844
|
-
rgba255[3] =
|
|
15794
|
+
rgba255[3] = 0;
|
|
15845
15795
|
return new _NVMesh(
|
|
15846
15796
|
obj.pts,
|
|
15847
15797
|
obj.offsetPt0,
|
|
@@ -15889,10 +15839,10 @@ var NVMesh = class _NVMesh {
|
|
|
15889
15839
|
} else if (ext === "FIB" || ext === "VTK") {
|
|
15890
15840
|
obj = NVMeshLoaders.readVTK(buffer);
|
|
15891
15841
|
if ("offsetPt0" in obj) {
|
|
15892
|
-
rgba255[3] =
|
|
15842
|
+
rgba255[3] = 0;
|
|
15893
15843
|
return new _NVMesh(
|
|
15894
|
-
|
|
15895
|
-
|
|
15844
|
+
obj.pts,
|
|
15845
|
+
obj.offsetPt0,
|
|
15896
15846
|
name,
|
|
15897
15847
|
rgba255,
|
|
15898
15848
|
// colormap,
|
|
@@ -15923,20 +15873,21 @@ var NVMesh = class _NVMesh {
|
|
|
15923
15873
|
if (!obj.indices) {
|
|
15924
15874
|
throw new Error("indices not loaded");
|
|
15925
15875
|
}
|
|
15926
|
-
pts =
|
|
15927
|
-
tris =
|
|
15876
|
+
pts = obj.positions;
|
|
15877
|
+
tris = obj.indices;
|
|
15928
15878
|
if ("rgba255" in obj && obj.rgba255.length > 0) {
|
|
15929
15879
|
rgba255 = obj.rgba255;
|
|
15930
15880
|
}
|
|
15931
15881
|
if ("colors" in obj && obj.colors && obj.colors.length === pts.length) {
|
|
15932
|
-
rgba255 = [];
|
|
15933
15882
|
const n = pts.length / 3;
|
|
15883
|
+
rgba255 = new Uint8Array(n * 4);
|
|
15934
15884
|
let c = 0;
|
|
15885
|
+
let k = 0;
|
|
15935
15886
|
for (let i = 0; i < n; i++) {
|
|
15936
|
-
rgba255
|
|
15937
|
-
rgba255
|
|
15938
|
-
rgba255
|
|
15939
|
-
rgba255
|
|
15887
|
+
rgba255[k++] = obj.colors[c] * 255;
|
|
15888
|
+
rgba255[k++] = obj.colors[c + 1] * 255;
|
|
15889
|
+
rgba255[k++] = obj.colors[c + 2] * 255;
|
|
15890
|
+
rgba255[k++] = 255;
|
|
15940
15891
|
c += 3;
|
|
15941
15892
|
}
|
|
15942
15893
|
}
|
|
@@ -15945,6 +15896,7 @@ var NVMesh = class _NVMesh {
|
|
|
15945
15896
|
if (ntri < 1 || npt < 3) {
|
|
15946
15897
|
throw new Error("Mesh should have at least one triangle and three vertices");
|
|
15947
15898
|
}
|
|
15899
|
+
rgba255[3] = Math.max(1, rgba255[3]);
|
|
15948
15900
|
const nvm = new _NVMesh(
|
|
15949
15901
|
pts,
|
|
15950
15902
|
tris,
|
|
@@ -16088,7 +16040,7 @@ var NVMesh = class _NVMesh {
|
|
|
16088
16040
|
throw Error(response.statusText);
|
|
16089
16041
|
}
|
|
16090
16042
|
const buffer = await response.arrayBuffer();
|
|
16091
|
-
const nvmesh = await this.readMesh(buffer, name, gl, opacity, rgba255, visible);
|
|
16043
|
+
const nvmesh = await this.readMesh(buffer, name, gl, opacity, new Uint8Array(rgba255), visible);
|
|
16092
16044
|
if (!layers || layers.length < 1) {
|
|
16093
16045
|
return nvmesh;
|
|
16094
16046
|
}
|
|
@@ -16131,7 +16083,7 @@ var NVMesh = class _NVMesh {
|
|
|
16131
16083
|
throw new Error("rendering context must be set");
|
|
16132
16084
|
}
|
|
16133
16085
|
const buffer = await _NVMesh.readFileAsync(file);
|
|
16134
|
-
const nvmesh = _NVMesh.readMesh(buffer, name, gl, opacity, rgba255, visible);
|
|
16086
|
+
const nvmesh = _NVMesh.readMesh(buffer, name, gl, opacity, new Uint8Array(rgba255), visible);
|
|
16135
16087
|
if (!layers || layers.length < 1) {
|
|
16136
16088
|
return nvmesh;
|
|
16137
16089
|
}
|
|
@@ -16169,7 +16121,7 @@ var NVMesh = class _NVMesh {
|
|
|
16169
16121
|
return bytes.buffer;
|
|
16170
16122
|
}
|
|
16171
16123
|
const buffer = base64ToArrayBuffer(base64);
|
|
16172
|
-
const nvmesh = await _NVMesh.readMesh(buffer, name, gl, opacity, rgba255, visible);
|
|
16124
|
+
const nvmesh = await _NVMesh.readMesh(buffer, name, gl, opacity, new Uint8Array(rgba255), visible);
|
|
16173
16125
|
if (!layers || layers.length < 1) {
|
|
16174
16126
|
return nvmesh;
|
|
16175
16127
|
}
|
|
@@ -16259,7 +16211,7 @@ var NVMesh = class _NVMesh {
|
|
|
16259
16211
|
return NVMeshLoaders.readTSF(buffer);
|
|
16260
16212
|
}
|
|
16261
16213
|
static readTT(buffer) {
|
|
16262
|
-
return NVMeshLoaders.
|
|
16214
|
+
return NVMeshLoaders.readTT(buffer);
|
|
16263
16215
|
}
|
|
16264
16216
|
static readTRX(buffer) {
|
|
16265
16217
|
return NVMeshLoaders.readTRX(buffer);
|
|
@@ -20962,7 +20914,7 @@ var NVImage = class _NVImage {
|
|
|
20962
20914
|
*/
|
|
20963
20915
|
clone() {
|
|
20964
20916
|
const clonedImage = new _NVImage();
|
|
20965
|
-
clonedImage.id =
|
|
20917
|
+
clonedImage.id = uuidv42();
|
|
20966
20918
|
clonedImage.hdr = Object.assign({}, this.hdr);
|
|
20967
20919
|
clonedImage.img = this.img.slice();
|
|
20968
20920
|
clonedImage.calculateRAS();
|
|
@@ -21393,6 +21345,7 @@ var DEFAULT_OPTIONS = {
|
|
|
21393
21345
|
textHeight: 0.06,
|
|
21394
21346
|
colorbarHeight: 0.05,
|
|
21395
21347
|
crosshairWidth: 1,
|
|
21348
|
+
crosshairGap: 0,
|
|
21396
21349
|
rulerWidth: 4,
|
|
21397
21350
|
show3Dcrosshair: false,
|
|
21398
21351
|
backColor: [0, 0, 0, 1],
|
|
@@ -21772,7 +21725,7 @@ var NVDocument = class _NVDocument {
|
|
|
21772
21725
|
pts: mesh.pts,
|
|
21773
21726
|
tris: mesh.tris,
|
|
21774
21727
|
name: mesh.name,
|
|
21775
|
-
rgba255: mesh.rgba255,
|
|
21728
|
+
rgba255: Uint8Array.from(mesh.rgba255),
|
|
21776
21729
|
opacity: mesh.opacity,
|
|
21777
21730
|
connectome: mesh.connectome,
|
|
21778
21731
|
dpg: mesh.dpg,
|
|
@@ -21809,6 +21762,7 @@ var NVDocument = class _NVDocument {
|
|
|
21809
21762
|
nodeMaxColor: mesh.nodeMaxColor,
|
|
21810
21763
|
nodeMinColor: mesh.nodeMinColor,
|
|
21811
21764
|
nodeScale: mesh.nodeScale,
|
|
21765
|
+
legendLineThickness: mesh.legendLineThickness,
|
|
21812
21766
|
offsetPt0: mesh.offsetPt0,
|
|
21813
21767
|
nodes: mesh.nodes
|
|
21814
21768
|
};
|
|
@@ -21952,14 +21906,14 @@ var defaultOptions = {
|
|
|
21952
21906
|
edgeColormapNegative: "winter",
|
|
21953
21907
|
edgeMin: 2,
|
|
21954
21908
|
edgeMax: 6,
|
|
21955
|
-
edgeScale: 1
|
|
21909
|
+
edgeScale: 1,
|
|
21910
|
+
legendLineThickness: 0
|
|
21956
21911
|
};
|
|
21957
21912
|
var NVConnectome = class _NVConnectome extends NVMesh {
|
|
21958
21913
|
constructor(gl, connectome) {
|
|
21959
|
-
super([], [], connectome.name, [], 1, true, gl, connectome);
|
|
21914
|
+
super(new Float32Array([]), new Uint32Array([]), connectome.name, new Uint8Array([]), 1, true, gl, connectome);
|
|
21960
21915
|
__publicField(this, "gl");
|
|
21961
21916
|
__publicField(this, "nodesChanged");
|
|
21962
|
-
__publicField(this, "legendLineThickness");
|
|
21963
21917
|
this.gl = gl;
|
|
21964
21918
|
this.type = "connectome" /* CONNECTOME */;
|
|
21965
21919
|
if (this.nodes) {
|
|
@@ -22235,19 +22189,22 @@ var NVConnectome = class _NVConnectome extends NVMesh {
|
|
|
22235
22189
|
const ptj = vec38.fromValues(nodes[edge.second].x, nodes[edge.second].y, nodes[edge.second].z);
|
|
22236
22190
|
NiivueObject3D.makeColoredCylinder(pts, tris, rgba255, pti, ptj, radius, rgba);
|
|
22237
22191
|
}
|
|
22238
|
-
const
|
|
22192
|
+
const pts32 = new Float32Array(pts);
|
|
22193
|
+
const tris32 = new Uint32Array(tris);
|
|
22194
|
+
const obj = NVMeshUtilities.getExtents(pts32);
|
|
22239
22195
|
this.furthestVertexFromOrigin = obj.mxDx;
|
|
22240
22196
|
this.extentsMin = obj.extentsMin;
|
|
22241
22197
|
this.extentsMax = obj.extentsMax;
|
|
22242
|
-
const posNormClr = this.generatePosNormClr(
|
|
22198
|
+
const posNormClr = this.generatePosNormClr(pts32, tris32, new Uint8Array(rgba255));
|
|
22243
22199
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
|
22244
|
-
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
|
|
22200
|
+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, Uint32Array.from(tris32), gl.STATIC_DRAW);
|
|
22245
22201
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
22246
|
-
gl.bufferData(gl.ARRAY_BUFFER,
|
|
22202
|
+
gl.bufferData(gl.ARRAY_BUFFER, Float32Array.from(posNormClr), gl.STATIC_DRAW);
|
|
22247
22203
|
this.indexCount = tris.length;
|
|
22248
22204
|
}
|
|
22249
22205
|
updateMesh(gl) {
|
|
22250
22206
|
this.updateConnectome(gl);
|
|
22207
|
+
this.updateLabels();
|
|
22251
22208
|
}
|
|
22252
22209
|
json() {
|
|
22253
22210
|
const json = {};
|
|
@@ -23048,6 +23005,22 @@ var MESH_EXTENSIONS = [
|
|
|
23048
23005
|
var LEFT_MOUSE_BUTTON = 0;
|
|
23049
23006
|
var CENTER_MOUSE_BUTTON = 1;
|
|
23050
23007
|
var RIGHT_MOUSE_BUTTON = 2;
|
|
23008
|
+
var TEXTURE0_BACK_VOL = 33984;
|
|
23009
|
+
var TEXTURE1_COLORMAPS = 33985;
|
|
23010
|
+
var TEXTURE2_OVERLAY_VOL = 33986;
|
|
23011
|
+
var TEXTURE3_FONT = 33987;
|
|
23012
|
+
var TEXTURE4_THUMBNAIL = 33988;
|
|
23013
|
+
var TEXTURE5_MATCAP = 33989;
|
|
23014
|
+
var TEXTURE6_GRADIENT = 33990;
|
|
23015
|
+
var TEXTURE7_DRAW = 33991;
|
|
23016
|
+
var TEXTURE8_GRADIENT_TEMP = 33992;
|
|
23017
|
+
var TEXTURE9_ORIENT = 33993;
|
|
23018
|
+
var TEXTURE10_BLEND = 33994;
|
|
23019
|
+
var TEXTURE11_GC_BACK = 33995;
|
|
23020
|
+
var TEXTURE12_GC_STRENGTH0 = 33996;
|
|
23021
|
+
var TEXTURE13_GC_STRENGTH1 = 33997;
|
|
23022
|
+
var TEXTURE14_GC_LABEL0 = 33998;
|
|
23023
|
+
var TEXTURE15_GC_LABEL1 = 33999;
|
|
23051
23024
|
var defaultSaveImageOptions = {
|
|
23052
23025
|
filename: "",
|
|
23053
23026
|
isSaveDrawing: false,
|
|
@@ -23177,13 +23150,7 @@ var Niivue = class _Niivue {
|
|
|
23177
23150
|
dragEnd: [0, 0],
|
|
23178
23151
|
dragClipPlaneStartDepthAziElev: [0, 0, 0],
|
|
23179
23152
|
lastTwoTouchDistance: 0,
|
|
23180
|
-
multiTouchGesture: false
|
|
23181
|
-
loading$: new Subject()
|
|
23182
|
-
// whether or not the scene is loading
|
|
23183
|
-
});
|
|
23184
|
-
// mapping of keys (event strings) to rxjs subjects
|
|
23185
|
-
__publicField(this, "eventsToSubjects", {
|
|
23186
|
-
loading: this.uiData.loading$
|
|
23153
|
+
multiTouchGesture: false
|
|
23187
23154
|
});
|
|
23188
23155
|
__publicField(this, "back", null);
|
|
23189
23156
|
// base layer; defines image space to work in. Defined as this.volumes[0] in Niivue.loadVolumes
|
|
@@ -23472,8 +23439,6 @@ var Niivue = class _Niivue {
|
|
|
23472
23439
|
__publicField(this, "initialized", false);
|
|
23473
23440
|
__publicField(this, "currentDrawUndoBitmap");
|
|
23474
23441
|
__publicField(this, "loadingText");
|
|
23475
|
-
// rxjs subscriptions. Keeping a reference array like this allows us to unsubscribe later
|
|
23476
|
-
__publicField(this, "subscriptions", []);
|
|
23477
23442
|
for (const name in options) {
|
|
23478
23443
|
if (typeof options[name] === "function") {
|
|
23479
23444
|
this[name] = options[name];
|
|
@@ -23566,57 +23531,6 @@ var Niivue = class _Niivue {
|
|
|
23566
23531
|
log.debug("attached to element with id: ", id);
|
|
23567
23532
|
return this;
|
|
23568
23533
|
}
|
|
23569
|
-
// on handles matching event strings (event) with know rxjs subjects within NiiVue.
|
|
23570
|
-
// if the event string exists (e.g. 'location') then the corresponding rxjs subject reference
|
|
23571
|
-
// is extracted from this.eventsToSubjects and the callback passed as the second argument to NiiVue.on
|
|
23572
|
-
// is added to the subsciptions to the next method. These callbacks are called whenever subject.next is called within
|
|
23573
|
-
// various NiiVue methods.
|
|
23574
|
-
/**
|
|
23575
|
-
* register a callback function to run when known Niivue events happen
|
|
23576
|
-
* @param event - the name of the event to watch for. Event names are shown in the type column
|
|
23577
|
-
* @param callback - the function to call when the event happens
|
|
23578
|
-
* @example
|
|
23579
|
-
* niivue = new Niivue()
|
|
23580
|
-
*
|
|
23581
|
-
* // 'location' update event is fired when the crosshair changes position via user input
|
|
23582
|
-
* function doSomethingWithLocationData(data)\{
|
|
23583
|
-
* // data has the shape \{mm: [N, N, N], vox: [N, N, N], frac: [N, N, N], values: this.volumes.map(v =\> \{return val\})\}
|
|
23584
|
-
* //...
|
|
23585
|
-
* \}
|
|
23586
|
-
*/
|
|
23587
|
-
on(event, callback) {
|
|
23588
|
-
const knownEvents = Object.keys(this.eventsToSubjects);
|
|
23589
|
-
if (!knownEvents.includes(event)) {
|
|
23590
|
-
return;
|
|
23591
|
-
}
|
|
23592
|
-
const subject = this.eventsToSubjects[event];
|
|
23593
|
-
const subscription = subject.subscribe({
|
|
23594
|
-
next: (data) => callback(data)
|
|
23595
|
-
});
|
|
23596
|
-
this.subscriptions.push({ [event]: subscription });
|
|
23597
|
-
}
|
|
23598
|
-
/**
|
|
23599
|
-
* off unsubscribes events and subjects (the opposite of on)
|
|
23600
|
-
* @param event - the name of the event to watch for. Event names are shown in the type column
|
|
23601
|
-
* @example
|
|
23602
|
-
* niivue = new Niivue()
|
|
23603
|
-
* niivue.off('location')
|
|
23604
|
-
*/
|
|
23605
|
-
off(event) {
|
|
23606
|
-
const knownEvents = Object.keys(this.eventsToSubjects);
|
|
23607
|
-
if (!knownEvents.includes(event)) {
|
|
23608
|
-
return;
|
|
23609
|
-
}
|
|
23610
|
-
const nsubs = this.subscriptions.length;
|
|
23611
|
-
for (let i = 0; i < nsubs; i++) {
|
|
23612
|
-
const key = Object.keys(this.subscriptions[i])[0];
|
|
23613
|
-
if (key === event) {
|
|
23614
|
-
this.subscriptions[i][event].unsubscribe();
|
|
23615
|
-
this.subscriptions.splice(i, 1);
|
|
23616
|
-
return;
|
|
23617
|
-
}
|
|
23618
|
-
}
|
|
23619
|
-
}
|
|
23620
23534
|
/**
|
|
23621
23535
|
* attach the Niivue instance to a canvas element directly
|
|
23622
23536
|
* @param canvas - the canvas element reference
|
|
@@ -24302,6 +24216,12 @@ var Niivue = class _Niivue {
|
|
|
24302
24216
|
this.moveCrosshairInVox(0, -1, 0);
|
|
24303
24217
|
} else if (e.code === "KeyK" && this.opts.sliceType !== 4 /* RENDER */) {
|
|
24304
24218
|
this.moveCrosshairInVox(0, 1, 0);
|
|
24219
|
+
} else if (e.code === "KeyM" && this.opts.sliceType !== 4 /* RENDER */) {
|
|
24220
|
+
this.opts.dragMode++;
|
|
24221
|
+
if (this.opts.dragMode >= 4 /* slicer3D */) {
|
|
24222
|
+
this.opts.dragMode = 0 /* none */;
|
|
24223
|
+
}
|
|
24224
|
+
log.info("drag mode changed to ", DRAG_MODE[this.opts.dragMode]);
|
|
24305
24225
|
} else if (e.code === "ArrowLeft") {
|
|
24306
24226
|
this.setFrame4D(this.volumes[0].id, this.volumes[0].frame4D - 1);
|
|
24307
24227
|
} else if (e.code === "ArrowRight") {
|
|
@@ -24538,7 +24458,6 @@ var Niivue = class _Niivue {
|
|
|
24538
24458
|
gl: this.gl,
|
|
24539
24459
|
name: file.name
|
|
24540
24460
|
}).then((mesh) => {
|
|
24541
|
-
this.uiData.loading$.next(false);
|
|
24542
24461
|
this.addMesh(mesh);
|
|
24543
24462
|
}).catch((e2) => {
|
|
24544
24463
|
throw e2;
|
|
@@ -24615,6 +24534,9 @@ var Niivue = class _Niivue {
|
|
|
24615
24534
|
* @see {@link https://niivue.github.io/niivue/features/layout.html|live demo usage}
|
|
24616
24535
|
*/
|
|
24617
24536
|
setMultiplanarLayout(layout) {
|
|
24537
|
+
if (typeof layout === "string") {
|
|
24538
|
+
layout = parseInt(layout);
|
|
24539
|
+
}
|
|
24618
24540
|
this.opts.multiplanarLayout = layout;
|
|
24619
24541
|
this.drawScene();
|
|
24620
24542
|
}
|
|
@@ -24845,7 +24767,7 @@ var Niivue = class _Niivue {
|
|
|
24845
24767
|
const perm = drawingBitmap.permRAS;
|
|
24846
24768
|
const vx = dims[1] * dims[2] * dims[3];
|
|
24847
24769
|
this.drawBitmap = new Uint8Array(vx);
|
|
24848
|
-
this.drawTexture = this.r8Tex(this.drawTexture,
|
|
24770
|
+
this.drawTexture = this.r8Tex(this.drawTexture, TEXTURE7_DRAW, this.back.dims, true);
|
|
24849
24771
|
const layout = [0, 0, 0];
|
|
24850
24772
|
for (let i = 0; i < 3; i++) {
|
|
24851
24773
|
for (let j2 = 0; j2 < 3; j2++) {
|
|
@@ -26053,14 +25975,8 @@ var Niivue = class _Niivue {
|
|
|
26053
25975
|
* @see {@link https://niivue.github.io/niivue/features/mask.html|live demo usage}
|
|
26054
25976
|
*/
|
|
26055
25977
|
async loadVolumes(volumeList) {
|
|
26056
|
-
this.
|
|
26057
|
-
|
|
26058
|
-
this.loadingText = "loading...";
|
|
26059
|
-
this.drawScene();
|
|
26060
|
-
} else {
|
|
26061
|
-
this.loadingText = this.opts.loadingText;
|
|
26062
|
-
}
|
|
26063
|
-
});
|
|
25978
|
+
this.loadingText = "loading...";
|
|
25979
|
+
this.drawScene();
|
|
26064
25980
|
if (this.thumbnailVisible) {
|
|
26065
25981
|
this.deferredVolumes = volumeList;
|
|
26066
25982
|
return this;
|
|
@@ -26068,9 +25984,7 @@ var Niivue = class _Niivue {
|
|
|
26068
25984
|
this.volumes = [];
|
|
26069
25985
|
this.gl.clearColor(0, 0, 0, 1);
|
|
26070
25986
|
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
|
|
26071
|
-
this.uiData.loading$.next(false);
|
|
26072
25987
|
for (let i = 0; i < volumeList.length; i++) {
|
|
26073
|
-
this.uiData.loading$.next(true);
|
|
26074
25988
|
if (volumeList[i].colorMap !== void 0) {
|
|
26075
25989
|
volumeList[i].colormap = volumeList[i].colorMap;
|
|
26076
25990
|
}
|
|
@@ -26091,7 +26005,6 @@ var Niivue = class _Niivue {
|
|
|
26091
26005
|
colorbarVisible: volumeList[i].colorbarVisible
|
|
26092
26006
|
};
|
|
26093
26007
|
await this.addVolumeFromUrl(imageOptions);
|
|
26094
|
-
this.uiData.loading$.next(false);
|
|
26095
26008
|
}
|
|
26096
26009
|
return this;
|
|
26097
26010
|
}
|
|
@@ -26100,6 +26013,16 @@ var Niivue = class _Niivue {
|
|
|
26100
26013
|
* @see {@link https://niivue.github.io/niivue/features/multiuser.meshes.html|live demo usage}
|
|
26101
26014
|
*/
|
|
26102
26015
|
async addMeshFromUrl(meshOptions) {
|
|
26016
|
+
const ext = this.getFileExt(meshOptions.url);
|
|
26017
|
+
if (ext === "JCON" || ext === "JSON") {
|
|
26018
|
+
const response = await fetch(meshOptions.url, {});
|
|
26019
|
+
const json = await response.json();
|
|
26020
|
+
const mesh2 = this.loadConnectomeAsMesh(json);
|
|
26021
|
+
this.mediaUrlMap.set(mesh2, meshOptions.url);
|
|
26022
|
+
this.onMeshAddedFromUrl(meshOptions, mesh2);
|
|
26023
|
+
this.addMesh(mesh2);
|
|
26024
|
+
return mesh2;
|
|
26025
|
+
}
|
|
26103
26026
|
const mesh = await NVMesh.loadFromUrl({ ...meshOptions, gl: this.gl });
|
|
26104
26027
|
this.mediaUrlMap.set(mesh, meshOptions.url);
|
|
26105
26028
|
this.onMeshAddedFromUrl(meshOptions, mesh);
|
|
@@ -26116,14 +26039,8 @@ var Niivue = class _Niivue {
|
|
|
26116
26039
|
* @see {@link https://niivue.github.io/niivue/features/meshes.html|live demo usage}
|
|
26117
26040
|
*/
|
|
26118
26041
|
async loadMeshes(meshList) {
|
|
26119
|
-
this.
|
|
26120
|
-
|
|
26121
|
-
this.loadingText = "loading...";
|
|
26122
|
-
this.drawScene();
|
|
26123
|
-
} else {
|
|
26124
|
-
this.loadingText = this.opts.loadingText;
|
|
26125
|
-
}
|
|
26126
|
-
});
|
|
26042
|
+
this.loadingText = "loading...";
|
|
26043
|
+
this.drawScene();
|
|
26127
26044
|
if (this.thumbnailVisible) {
|
|
26128
26045
|
this.deferredMeshes = meshList;
|
|
26129
26046
|
return this;
|
|
@@ -26133,11 +26050,8 @@ var Niivue = class _Niivue {
|
|
|
26133
26050
|
this.meshes = [];
|
|
26134
26051
|
this.gl.clearColor(0, 0, 0, 1);
|
|
26135
26052
|
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
|
|
26136
|
-
this.uiData.loading$.next(false);
|
|
26137
26053
|
for (let i = 0; i < meshList.length; i++) {
|
|
26138
|
-
this.uiData.loading$.next(true);
|
|
26139
26054
|
await this.addMeshFromUrl(meshList[i]);
|
|
26140
|
-
this.uiData.loading$.next(false);
|
|
26141
26055
|
}
|
|
26142
26056
|
this.drawScene();
|
|
26143
26057
|
return this;
|
|
@@ -26190,6 +26104,22 @@ var Niivue = class _Niivue {
|
|
|
26190
26104
|
);
|
|
26191
26105
|
this.drawScene();
|
|
26192
26106
|
}
|
|
26107
|
+
loadConnectomeAsMesh(json) {
|
|
26108
|
+
let connectome = json;
|
|
26109
|
+
if ("data_type" in json && json.data_type === "fs_pointset") {
|
|
26110
|
+
connectome = NVConnectome.convertFreeSurferConnectome(json);
|
|
26111
|
+
log.warn("converted FreeSurfer connectome", connectome);
|
|
26112
|
+
} else if ("nodes" in json) {
|
|
26113
|
+
const nodes = json.nodes;
|
|
26114
|
+
if ("names" in nodes && "X" in nodes && "Y" in nodes && "Z" in nodes && "Color" in nodes && "Size" in nodes) {
|
|
26115
|
+
connectome = NVConnectome.convertLegacyConnectome(json);
|
|
26116
|
+
log.warn("converted legacy connectome", connectome);
|
|
26117
|
+
}
|
|
26118
|
+
} else {
|
|
26119
|
+
throw new Error("not a known connectome format");
|
|
26120
|
+
}
|
|
26121
|
+
return new NVConnectome(this.gl, connectome);
|
|
26122
|
+
}
|
|
26193
26123
|
/**
|
|
26194
26124
|
* load a connectome specified by json
|
|
26195
26125
|
* @param connectome - model
|
|
@@ -26197,27 +26127,13 @@ var Niivue = class _Niivue {
|
|
|
26197
26127
|
* @see {@link https://niivue.github.io/niivue/features/connectome.html|live demo usage}
|
|
26198
26128
|
*/
|
|
26199
26129
|
loadConnectome(json) {
|
|
26200
|
-
this.
|
|
26201
|
-
|
|
26202
|
-
this.loadingText = "loading...";
|
|
26203
|
-
this.drawScene();
|
|
26204
|
-
} else {
|
|
26205
|
-
this.loadingText = this.opts.loadingText;
|
|
26206
|
-
}
|
|
26207
|
-
});
|
|
26130
|
+
this.loadingText = "loading...";
|
|
26131
|
+
this.drawScene();
|
|
26208
26132
|
this.meshes = [];
|
|
26209
26133
|
this.gl.clearColor(0, 0, 0, 1);
|
|
26210
26134
|
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
|
|
26211
|
-
this.
|
|
26212
|
-
let connectome = json;
|
|
26213
|
-
const nodes = json.nodes;
|
|
26214
|
-
if ("names" in nodes && "X" in nodes && "Y" in nodes && "Z" in nodes && "Color" in nodes && "Size" in nodes) {
|
|
26215
|
-
connectome = NVConnectome.convertLegacyConnectome(json);
|
|
26216
|
-
log.warn("converted legacy connectome", connectome);
|
|
26217
|
-
}
|
|
26218
|
-
const mesh = new NVConnectome(this.gl, connectome);
|
|
26135
|
+
const mesh = this.loadConnectomeAsMesh(json);
|
|
26219
26136
|
this.addMesh(mesh);
|
|
26220
|
-
this.uiData.loading$.next(false);
|
|
26221
26137
|
this.drawScene();
|
|
26222
26138
|
return this;
|
|
26223
26139
|
}
|
|
@@ -26238,7 +26154,7 @@ var Niivue = class _Niivue {
|
|
|
26238
26154
|
this.drawBitmap = new Uint8Array(vx);
|
|
26239
26155
|
this.drawClearAllUndoBitmaps();
|
|
26240
26156
|
this.drawAddUndoBitmap();
|
|
26241
|
-
this.drawTexture = this.r8Tex(this.drawTexture,
|
|
26157
|
+
this.drawTexture = this.r8Tex(this.drawTexture, TEXTURE7_DRAW, this.back.dims, true);
|
|
26242
26158
|
this.refreshDrawing(false);
|
|
26243
26159
|
}
|
|
26244
26160
|
// not included in public docs
|
|
@@ -26299,29 +26215,29 @@ var Niivue = class _Niivue {
|
|
|
26299
26215
|
gl.viewport(0, 0, this.back.dims[1], this.back.dims[2]);
|
|
26300
26216
|
gl.disable(gl.BLEND);
|
|
26301
26217
|
let img16 = img2ras16(this.back);
|
|
26302
|
-
const background = this.r16Tex(null,
|
|
26218
|
+
const background = this.r16Tex(null, TEXTURE11_GC_BACK, this.back.dims, img16);
|
|
26303
26219
|
for (let i = 1; i < nv; i++) {
|
|
26304
26220
|
img16[i] = this.drawBitmap[i];
|
|
26305
26221
|
}
|
|
26306
|
-
const label0 = this.r16Tex(null,
|
|
26307
|
-
const label1 = this.r16Tex(null,
|
|
26222
|
+
const label0 = this.r16Tex(null, TEXTURE14_GC_LABEL0, this.back.dims, img16);
|
|
26223
|
+
const label1 = this.r16Tex(null, TEXTURE15_GC_LABEL1, this.back.dims, img16);
|
|
26308
26224
|
const kMAX_STRENGTH = 1e4;
|
|
26309
26225
|
for (let i = 1; i < nv; i++) {
|
|
26310
26226
|
if (img16[i] > 0) {
|
|
26311
26227
|
img16[i] = kMAX_STRENGTH;
|
|
26312
26228
|
}
|
|
26313
26229
|
}
|
|
26314
|
-
const strength0 = this.r16Tex(null,
|
|
26315
|
-
const strength1 = this.r16Tex(null,
|
|
26230
|
+
const strength0 = this.r16Tex(null, TEXTURE12_GC_STRENGTH0, this.back.dims, img16);
|
|
26231
|
+
const strength1 = this.r16Tex(null, TEXTURE13_GC_STRENGTH1, this.back.dims, img16);
|
|
26316
26232
|
gl.bindVertexArray(this.genericVAO);
|
|
26317
26233
|
const shader = this.growCutShader;
|
|
26318
26234
|
shader.use(gl);
|
|
26319
26235
|
const iterations = 128;
|
|
26320
26236
|
gl.uniform1i(shader.uniforms.finalPass, 0);
|
|
26321
|
-
gl.uniform1i(shader.uniforms.
|
|
26237
|
+
gl.uniform1i(shader.uniforms.backTex, 11);
|
|
26322
26238
|
for (let j = 0; j < iterations; j++) {
|
|
26323
|
-
gl.uniform1i(shader.uniforms.
|
|
26324
|
-
gl.uniform1i(shader.uniforms.
|
|
26239
|
+
gl.uniform1i(shader.uniforms.labelTex, 14);
|
|
26240
|
+
gl.uniform1i(shader.uniforms.strengthTex, 12);
|
|
26325
26241
|
for (let i = 0; i < this.back.dims[3]; i++) {
|
|
26326
26242
|
const coordZ = 1 / this.back.dims[3] * (i + 0.5);
|
|
26327
26243
|
gl.uniform1f(shader.uniforms.coordZ, coordZ);
|
|
@@ -26337,8 +26253,8 @@ var Niivue = class _Niivue {
|
|
|
26337
26253
|
if (j === iterations - 1) {
|
|
26338
26254
|
gl.uniform1i(shader.uniforms.finalPass, 1);
|
|
26339
26255
|
}
|
|
26340
|
-
gl.uniform1i(shader.uniforms.
|
|
26341
|
-
gl.uniform1i(shader.uniforms.
|
|
26256
|
+
gl.uniform1i(shader.uniforms.labelTex, 15);
|
|
26257
|
+
gl.uniform1i(shader.uniforms.strengthTex, 13);
|
|
26342
26258
|
for (let i = 0; i < this.back.dims[3]; i++) {
|
|
26343
26259
|
const coordZ = 1 / this.back.dims[3] * (i + 0.5);
|
|
26344
26260
|
gl.uniform1f(shader.uniforms.coordZ, coordZ);
|
|
@@ -26384,14 +26300,6 @@ var Niivue = class _Niivue {
|
|
|
26384
26300
|
for (let i = 1; i < nv; i++) {
|
|
26385
26301
|
this.drawBitmap[i] = img16[i];
|
|
26386
26302
|
}
|
|
26387
|
-
gl.activeTexture(gl.TEXTURE2);
|
|
26388
|
-
gl.bindTexture(gl.TEXTURE_3D, this.overlayTexture);
|
|
26389
|
-
gl.activeTexture(gl.TEXTURE3);
|
|
26390
|
-
gl.bindTexture(gl.TEXTURE_2D, this.fontTexture);
|
|
26391
|
-
gl.activeTexture(gl.TEXTURE4);
|
|
26392
|
-
gl.bindTexture(gl.TEXTURE_2D, this.bmpTexture);
|
|
26393
|
-
gl.activeTexture(gl.TEXTURE7);
|
|
26394
|
-
gl.bindTexture(gl.TEXTURE_3D, this.drawTexture);
|
|
26395
26303
|
gl.deleteTexture(background);
|
|
26396
26304
|
gl.deleteTexture(strength0);
|
|
26397
26305
|
gl.deleteTexture(strength1);
|
|
@@ -26817,7 +26725,7 @@ var Niivue = class _Niivue {
|
|
|
26817
26725
|
*/
|
|
26818
26726
|
closeDrawing() {
|
|
26819
26727
|
this.drawClearAllUndoBitmaps();
|
|
26820
|
-
this.rgbaTex(this.drawTexture,
|
|
26728
|
+
this.rgbaTex(this.drawTexture, TEXTURE7_DRAW, [2, 2, 2, 2], true);
|
|
26821
26729
|
this.drawBitmap = null;
|
|
26822
26730
|
this.drawScene();
|
|
26823
26731
|
}
|
|
@@ -26843,7 +26751,7 @@ var Niivue = class _Niivue {
|
|
|
26843
26751
|
} else if (vx !== this.drawBitmap.length) {
|
|
26844
26752
|
log.warn("Drawing bitmap must match the background image");
|
|
26845
26753
|
}
|
|
26846
|
-
this.gl.activeTexture(
|
|
26754
|
+
this.gl.activeTexture(TEXTURE7_DRAW);
|
|
26847
26755
|
this.gl.bindTexture(this.gl.TEXTURE_3D, this.drawTexture);
|
|
26848
26756
|
this.gl.texSubImage3D(
|
|
26849
26757
|
this.gl.TEXTURE_3D,
|
|
@@ -26954,11 +26862,11 @@ var Niivue = class _Niivue {
|
|
|
26954
26862
|
this.bmpTexture = this.gl.createTexture();
|
|
26955
26863
|
pngTexture = this.bmpTexture;
|
|
26956
26864
|
this.bmpTextureWH = img.width / img.height;
|
|
26957
|
-
this.gl.activeTexture(
|
|
26865
|
+
this.gl.activeTexture(TEXTURE4_THUMBNAIL);
|
|
26958
26866
|
this.bmpShader.use(this.gl);
|
|
26959
26867
|
this.gl.uniform1i(this.bmpShader.uniforms.bmpTexture, 4);
|
|
26960
26868
|
} else if (textureNum === 5) {
|
|
26961
|
-
this.gl.activeTexture(
|
|
26869
|
+
this.gl.activeTexture(TEXTURE5_MATCAP);
|
|
26962
26870
|
if (this.matCapTexture !== null) {
|
|
26963
26871
|
this.gl.deleteTexture(this.matCapTexture);
|
|
26964
26872
|
}
|
|
@@ -26966,7 +26874,7 @@ var Niivue = class _Niivue {
|
|
|
26966
26874
|
pngTexture = this.matCapTexture;
|
|
26967
26875
|
} else {
|
|
26968
26876
|
this.fontShader.use(this.gl);
|
|
26969
|
-
this.gl.activeTexture(
|
|
26877
|
+
this.gl.activeTexture(TEXTURE3_FONT);
|
|
26970
26878
|
this.gl.uniform1i(this.fontShader.uniforms.fontTexture, 3);
|
|
26971
26879
|
if (this.fontTexture !== null) {
|
|
26972
26880
|
this.gl.deleteTexture(this.fontTexture);
|
|
@@ -27201,9 +27109,9 @@ var Niivue = class _Niivue {
|
|
|
27201
27109
|
this.gl.cullFace(this.gl.FRONT);
|
|
27202
27110
|
this.gl.enable(this.gl.BLEND);
|
|
27203
27111
|
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
|
|
27204
|
-
this.volumeTexture = this.rgbaTex(this.volumeTexture,
|
|
27205
|
-
this.overlayTexture = this.rgbaTex(this.overlayTexture,
|
|
27206
|
-
this.drawTexture = this.r8Tex(this.drawTexture,
|
|
27112
|
+
this.volumeTexture = this.rgbaTex(this.volumeTexture, TEXTURE0_BACK_VOL, [2, 2, 2, 2], true);
|
|
27113
|
+
this.overlayTexture = this.rgbaTex(this.overlayTexture, TEXTURE2_OVERLAY_VOL, [2, 2, 2, 2], true);
|
|
27114
|
+
this.drawTexture = this.r8Tex(this.drawTexture, TEXTURE7_DRAW, [2, 2, 2, 2], true);
|
|
27207
27115
|
const rectStrip = [
|
|
27208
27116
|
1,
|
|
27209
27117
|
1,
|
|
@@ -27340,10 +27248,10 @@ var Niivue = class _Niivue {
|
|
|
27340
27248
|
gl.disable(gl.CULL_FACE);
|
|
27341
27249
|
gl.viewport(0, 0, hdr.dims[1], hdr.dims[2]);
|
|
27342
27250
|
gl.disable(gl.BLEND);
|
|
27343
|
-
const tempTex3D = this.rgbaTex(null,
|
|
27251
|
+
const tempTex3D = this.rgbaTex(null, TEXTURE8_GRADIENT_TEMP, hdr.dims);
|
|
27344
27252
|
const blurShader = this.blurShader;
|
|
27345
27253
|
blurShader.use(gl);
|
|
27346
|
-
gl.activeTexture(
|
|
27254
|
+
gl.activeTexture(TEXTURE0_BACK_VOL);
|
|
27347
27255
|
gl.bindTexture(gl.TEXTURE_3D, this.volumeTexture);
|
|
27348
27256
|
const blurRadius = 0.7;
|
|
27349
27257
|
gl.uniform1i(blurShader.uniforms.intensityVol, 0);
|
|
@@ -27360,20 +27268,20 @@ var Niivue = class _Niivue {
|
|
|
27360
27268
|
}
|
|
27361
27269
|
const sobelShader = this.sobelShader;
|
|
27362
27270
|
sobelShader.use(gl);
|
|
27363
|
-
gl.activeTexture(
|
|
27271
|
+
gl.activeTexture(TEXTURE8_GRADIENT_TEMP);
|
|
27364
27272
|
gl.bindTexture(gl.TEXTURE_3D, tempTex3D);
|
|
27365
|
-
gl.uniform1i(sobelShader.uniforms.intensityVol,
|
|
27273
|
+
gl.uniform1i(sobelShader.uniforms.intensityVol, 8);
|
|
27366
27274
|
const sobelRadius = 0.7;
|
|
27367
27275
|
gl.uniform1f(sobelShader.uniforms.dX, sobelRadius / hdr.dims[1]);
|
|
27368
27276
|
gl.uniform1f(sobelShader.uniforms.dY, sobelRadius / hdr.dims[2]);
|
|
27369
27277
|
gl.uniform1f(sobelShader.uniforms.dZ, sobelRadius / hdr.dims[3]);
|
|
27370
27278
|
gl.uniform1f(sobelShader.uniforms.coordZ, 0.5);
|
|
27371
27279
|
gl.bindVertexArray(vao2);
|
|
27372
|
-
gl.activeTexture(
|
|
27280
|
+
gl.activeTexture(TEXTURE0_BACK_VOL);
|
|
27373
27281
|
if (this.gradientTexture !== null) {
|
|
27374
27282
|
gl.deleteTexture(this.gradientTexture);
|
|
27375
27283
|
}
|
|
27376
|
-
this.gradientTexture = this.rgbaTex(this.gradientTexture,
|
|
27284
|
+
this.gradientTexture = this.rgbaTex(this.gradientTexture, TEXTURE6_GRADIENT, hdr.dims);
|
|
27377
27285
|
for (let i = 0; i < hdr.dims[3] - 1; i++) {
|
|
27378
27286
|
const coordZ = 1 / hdr.dims[3] * (i + 0.5);
|
|
27379
27287
|
gl.uniform1f(sobelShader.uniforms.coordZ, coordZ);
|
|
@@ -27555,7 +27463,7 @@ var Niivue = class _Niivue {
|
|
|
27555
27463
|
this.back.matRAS = overlayItem.matRAS;
|
|
27556
27464
|
this.back.dims = overlayItem.dimsRAS;
|
|
27557
27465
|
this.back.pixDims = overlayItem.pixDimsRAS;
|
|
27558
|
-
outTexture = this.rgbaTex(this.volumeTexture,
|
|
27466
|
+
outTexture = this.rgbaTex(this.volumeTexture, TEXTURE0_BACK_VOL, overlayItem.dimsRAS);
|
|
27559
27467
|
const { volScale: volScale2, vox: vox2 } = this.sliceScale(true);
|
|
27560
27468
|
this.volScale = volScale2;
|
|
27561
27469
|
this.vox = vox2;
|
|
@@ -27604,7 +27512,7 @@ var Niivue = class _Niivue {
|
|
|
27604
27512
|
);
|
|
27605
27513
|
mat46.invert(mtx, mtx);
|
|
27606
27514
|
if (layer === 1) {
|
|
27607
|
-
outTexture = this.rgbaTex(this.overlayTexture,
|
|
27515
|
+
outTexture = this.rgbaTex(this.overlayTexture, TEXTURE2_OVERLAY_VOL, this.back.dims);
|
|
27608
27516
|
this.overlayTexture = outTexture;
|
|
27609
27517
|
this.overlayTextureID = outTexture;
|
|
27610
27518
|
} else {
|
|
@@ -27617,7 +27525,7 @@ var Niivue = class _Niivue {
|
|
|
27617
27525
|
this.gl.viewport(0, 0, this.back.dims[1], this.back.dims[2]);
|
|
27618
27526
|
this.gl.disable(this.gl.BLEND);
|
|
27619
27527
|
const tempTex3D = this.gl.createTexture();
|
|
27620
|
-
this.gl.activeTexture(
|
|
27528
|
+
this.gl.activeTexture(TEXTURE9_ORIENT);
|
|
27621
27529
|
this.gl.bindTexture(this.gl.TEXTURE_3D, tempTex3D);
|
|
27622
27530
|
this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
|
|
27623
27531
|
this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
|
|
@@ -27766,22 +27674,22 @@ var Niivue = class _Niivue {
|
|
|
27766
27674
|
const isUseCopyTexSubImage3D = false;
|
|
27767
27675
|
if (isUseCopyTexSubImage3D) {
|
|
27768
27676
|
if (layer > 1) {
|
|
27769
|
-
blendTexture = this.rgbaTex(blendTexture,
|
|
27677
|
+
blendTexture = this.rgbaTex(blendTexture, TEXTURE10_BLEND, this.back.dims, true);
|
|
27770
27678
|
this.gl.bindTexture(this.gl.TEXTURE_3D, blendTexture);
|
|
27771
27679
|
for (let i = 0; i < this.back.dims[3]; i++) {
|
|
27772
27680
|
this.gl.framebufferTextureLayer(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.overlayTexture, 0, i);
|
|
27773
|
-
this.gl.activeTexture(
|
|
27681
|
+
this.gl.activeTexture(TEXTURE10_BLEND);
|
|
27774
27682
|
this.gl.copyTexSubImage3D(this.gl.TEXTURE_3D, 0, 0, 0, i, 0, 0, this.back.dims[1], this.back.dims[2]);
|
|
27775
27683
|
}
|
|
27776
27684
|
} else {
|
|
27777
|
-
blendTexture = this.rgbaTex(blendTexture,
|
|
27685
|
+
blendTexture = this.rgbaTex(blendTexture, TEXTURE10_BLEND, [2, 2, 2, 2], true);
|
|
27778
27686
|
}
|
|
27779
27687
|
} else {
|
|
27780
27688
|
if (layer > 1) {
|
|
27781
27689
|
if (!this.back.dims) {
|
|
27782
27690
|
throw new Error("back.dims undefined");
|
|
27783
27691
|
}
|
|
27784
|
-
blendTexture = this.rgbaTex(blendTexture,
|
|
27692
|
+
blendTexture = this.rgbaTex(blendTexture, TEXTURE10_BLEND, this.back.dims);
|
|
27785
27693
|
this.gl.bindTexture(this.gl.TEXTURE_3D, blendTexture);
|
|
27786
27694
|
const passShader = this.passThroughShader;
|
|
27787
27695
|
passShader.use(this.gl);
|
|
@@ -27793,11 +27701,11 @@ var Niivue = class _Niivue {
|
|
|
27793
27701
|
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
|
|
27794
27702
|
}
|
|
27795
27703
|
} else {
|
|
27796
|
-
blendTexture = this.rgbaTex(blendTexture,
|
|
27704
|
+
blendTexture = this.rgbaTex(blendTexture, TEXTURE10_BLEND, [2, 2, 2, 2]);
|
|
27797
27705
|
}
|
|
27798
27706
|
}
|
|
27799
27707
|
orientShader.use(this.gl);
|
|
27800
|
-
this.gl.activeTexture(
|
|
27708
|
+
this.gl.activeTexture(TEXTURE1_COLORMAPS);
|
|
27801
27709
|
let colormapLabelTexture = null;
|
|
27802
27710
|
if (overlayItem.colormapLabel !== null && overlayItem.colormapLabel.lut.length > 7) {
|
|
27803
27711
|
const nLabel = overlayItem.colormapLabel.max - overlayItem.colormapLabel.min + 1;
|
|
@@ -27840,8 +27748,8 @@ var Niivue = class _Niivue {
|
|
|
27840
27748
|
this.gl.uniform1f(orientShader.uniforms.cal_minNeg ?? null, mnNeg);
|
|
27841
27749
|
this.gl.uniform1f(orientShader.uniforms.cal_maxNeg ?? null, mxNeg);
|
|
27842
27750
|
this.gl.bindTexture(this.gl.TEXTURE_3D, tempTex3D);
|
|
27843
|
-
this.gl.uniform1i(orientShader.uniforms.intensityVol ?? null,
|
|
27844
|
-
this.gl.uniform1i(orientShader.uniforms.blend3D ?? null,
|
|
27751
|
+
this.gl.uniform1i(orientShader.uniforms.intensityVol ?? null, 9);
|
|
27752
|
+
this.gl.uniform1i(orientShader.uniforms.blend3D ?? null, 10);
|
|
27845
27753
|
this.gl.uniform1i(orientShader.uniforms.colormap ?? null, 1);
|
|
27846
27754
|
this.gl.uniform1f(orientShader.uniforms.scl_inter ?? null, hdr.scl_inter);
|
|
27847
27755
|
this.gl.uniform1f(orientShader.uniforms.scl_slope ?? null, hdr.scl_slope);
|
|
@@ -28004,11 +27912,11 @@ var Niivue = class _Niivue {
|
|
|
28004
27912
|
this.gl.uniform1f(shader.uniforms.drawOpacity, this.drawOpacity);
|
|
28005
27913
|
if (colormapLabelTexture !== null) {
|
|
28006
27914
|
this.gl.deleteTexture(colormapLabelTexture);
|
|
28007
|
-
this.gl.activeTexture(
|
|
27915
|
+
this.gl.activeTexture(TEXTURE1_COLORMAPS);
|
|
28008
27916
|
this.gl.bindTexture(this.gl.TEXTURE_2D, this.colormapTexture);
|
|
28009
27917
|
}
|
|
28010
27918
|
this.gl.uniform1i(shader.uniforms.drawing, 7);
|
|
28011
|
-
this.gl.activeTexture(
|
|
27919
|
+
this.gl.activeTexture(TEXTURE7_DRAW);
|
|
28012
27920
|
this.gl.bindTexture(this.gl.TEXTURE_3D, this.drawTexture);
|
|
28013
27921
|
this.updateInterpolation(layer);
|
|
28014
27922
|
}
|
|
@@ -28081,7 +27989,7 @@ var Niivue = class _Niivue {
|
|
|
28081
27989
|
/**
|
|
28082
27990
|
* modulate intensity of one image based on intensity of another
|
|
28083
27991
|
* @param idTarget - the ID of the NVImage to be biased
|
|
28084
|
-
* @param idModulation - the ID of the NVImage that controls bias (
|
|
27992
|
+
* @param idModulation - the ID of the NVImage that controls bias (empty string to disable modulation)
|
|
28085
27993
|
* @param modulateAlpha - does the modulation influence alpha transparency (values greater than 1).
|
|
28086
27994
|
* @example niivue.setModulationImage(niivue.volumes[0].id, niivue.volumes[1].id);
|
|
28087
27995
|
* @see {@link https://niivue.github.io/niivue/features/modulate.html|live demo scalar usage}
|
|
@@ -28090,7 +27998,9 @@ var Niivue = class _Niivue {
|
|
|
28090
27998
|
setModulationImage(idTarget, idModulation, modulateAlpha = 0) {
|
|
28091
27999
|
const idxTarget = this.getVolumeIndexByID(idTarget);
|
|
28092
28000
|
let idxModulation = null;
|
|
28093
|
-
|
|
28001
|
+
if (idModulation.length > 0) {
|
|
28002
|
+
idxModulation = this.getVolumeIndexByID(idModulation);
|
|
28003
|
+
}
|
|
28094
28004
|
this.volumes[idxTarget].modulationImage = idxModulation;
|
|
28095
28005
|
this.volumes[idxTarget].modulateAlpha = modulateAlpha;
|
|
28096
28006
|
this.updateGLVolume();
|
|
@@ -28181,7 +28091,7 @@ var Niivue = class _Niivue {
|
|
|
28181
28091
|
return null;
|
|
28182
28092
|
}
|
|
28183
28093
|
texture = this.gl.createTexture();
|
|
28184
|
-
this.gl.activeTexture(
|
|
28094
|
+
this.gl.activeTexture(TEXTURE1_COLORMAPS);
|
|
28185
28095
|
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
|
|
28186
28096
|
this.gl.texStorage2D(this.gl.TEXTURE_2D, 1, this.gl.RGBA8, nCol, nRow);
|
|
28187
28097
|
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
|
|
@@ -28821,7 +28731,7 @@ var Niivue = class _Niivue {
|
|
|
28821
28731
|
throw new Error("colorbarShader undefined");
|
|
28822
28732
|
}
|
|
28823
28733
|
this.colorbarShader.use(this.gl);
|
|
28824
|
-
this.gl.activeTexture(
|
|
28734
|
+
this.gl.activeTexture(TEXTURE1_COLORMAPS);
|
|
28825
28735
|
this.gl.bindTexture(this.gl.TEXTURE_2D, this.colormapTexture);
|
|
28826
28736
|
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
|
|
28827
28737
|
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
|
|
@@ -29064,9 +28974,9 @@ var Niivue = class _Niivue {
|
|
|
29064
28974
|
interp = this.gl.NEAREST;
|
|
29065
28975
|
}
|
|
29066
28976
|
if (layer === 0) {
|
|
29067
|
-
this.gl.activeTexture(
|
|
28977
|
+
this.gl.activeTexture(TEXTURE0_BACK_VOL);
|
|
29068
28978
|
} else {
|
|
29069
|
-
this.gl.activeTexture(
|
|
28979
|
+
this.gl.activeTexture(TEXTURE2_OVERLAY_VOL);
|
|
29070
28980
|
}
|
|
29071
28981
|
this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_MIN_FILTER, interp);
|
|
29072
28982
|
this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_MAG_FILTER, interp);
|
|
@@ -29636,6 +29546,12 @@ var Niivue = class _Niivue {
|
|
|
29636
29546
|
if (graph.opacity <= 0 || graph.LTWH[2] <= 5 || graph.LTWH[3] <= 5) {
|
|
29637
29547
|
return;
|
|
29638
29548
|
}
|
|
29549
|
+
if (graph.LTWH[0] + graph.LTWH[2] > this.gl.canvas.width) {
|
|
29550
|
+
return;
|
|
29551
|
+
}
|
|
29552
|
+
if (graph.LTWH[1] + graph.LTWH[3] > this.gl.canvas.height) {
|
|
29553
|
+
return;
|
|
29554
|
+
}
|
|
29639
29555
|
graph.backColor = [0.15, 0.15, 0.15, graph.opacity];
|
|
29640
29556
|
graph.lineColor = [1, 1, 1, 1];
|
|
29641
29557
|
if (this.opts.backColor[0] + this.opts.backColor[1] + this.opts.backColor[2] > 1.5) {
|
|
@@ -29899,7 +29815,7 @@ var Niivue = class _Niivue {
|
|
|
29899
29815
|
shader.use(this.gl);
|
|
29900
29816
|
gl.uniform1i(shader.uniforms.backgroundMasksOverlays, this.backgroundMasksOverlays);
|
|
29901
29817
|
if (this.gradientTextureAmount > 0) {
|
|
29902
|
-
gl.activeTexture(
|
|
29818
|
+
gl.activeTexture(TEXTURE6_GRADIENT);
|
|
29903
29819
|
gl.bindTexture(gl.TEXTURE_3D, this.gradientTexture);
|
|
29904
29820
|
const modelMatrix = this.calculateModelMatrix(azimuth, elevation);
|
|
29905
29821
|
const iModelMatrix = mat46.create();
|
|
@@ -30307,7 +30223,7 @@ var Niivue = class _Niivue {
|
|
|
30307
30223
|
continue;
|
|
30308
30224
|
}
|
|
30309
30225
|
if (shader.isMatcap) {
|
|
30310
|
-
gl.activeTexture(
|
|
30226
|
+
gl.activeTexture(TEXTURE5_MATCAP);
|
|
30311
30227
|
gl.bindTexture(gl.TEXTURE_2D, this.matCapTexture);
|
|
30312
30228
|
}
|
|
30313
30229
|
gl.bindVertexArray(this.meshes[i].vao);
|
|
@@ -30367,7 +30283,7 @@ var Niivue = class _Niivue {
|
|
|
30367
30283
|
radius = range[0] * 0.02;
|
|
30368
30284
|
}
|
|
30369
30285
|
radius *= this.opts.crosshairWidth;
|
|
30370
|
-
this.crosshairs3D = NiivueObject3D.generateCrosshairs(this.gl, 1, mm, mn, mx, radius);
|
|
30286
|
+
this.crosshairs3D = NiivueObject3D.generateCrosshairs(this.gl, 1, mm, mn, mx, radius, 20, this.opts.crosshairGap);
|
|
30371
30287
|
this.crosshairs3D.mm = mm;
|
|
30372
30288
|
}
|
|
30373
30289
|
if (!this.surfaceShader) {
|