@kitware/vtk.js 32.5.1 → 32.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,28 @@
1
+ const TYPE_INDEXED = 1;
2
+ const TYPE_RGB = 2;
3
+ const TYPE_GREY = 3;
4
+ const TYPE_RLE_INDEXED = 9;
5
+ const TYPE_RLE_RGB = 10;
6
+ const TYPE_RLE_GREY = 11;
7
+ const ORIGIN_MASK = 0x30;
8
+ const ORIGIN_SHIFT = 0x04;
9
+ const ORIGIN_BL = 0x00;
10
+ const ORIGIN_BR = 0x01;
11
+ const ORIGIN_UL = 0x02;
12
+ const ORIGIN_UR = 0x03;
13
+ var Constants = {
14
+ TYPE_INDEXED,
15
+ TYPE_RGB,
16
+ TYPE_GREY,
17
+ TYPE_RLE_INDEXED,
18
+ TYPE_RLE_RGB,
19
+ TYPE_RLE_GREY,
20
+ ORIGIN_MASK,
21
+ ORIGIN_SHIFT,
22
+ ORIGIN_BL,
23
+ ORIGIN_BR,
24
+ ORIGIN_UL,
25
+ ORIGIN_UR
26
+ };
27
+
28
+ export { Constants as default };
@@ -0,0 +1,121 @@
1
+ import { vtkAlgorithm, vtkObject } from './../../interfaces';
2
+ import HtmlDataAccessHelper from './../Core/DataAccessHelper/HtmlDataAccessHelper';
3
+ import HttpDataAccessHelper from './../Core/DataAccessHelper/HttpDataAccessHelper';
4
+ import JSZipDataAccessHelper from './../Core/DataAccessHelper/JSZipDataAccessHelper';
5
+ import LiteHttpDataAccessHelper from './../Core/DataAccessHelper/LiteHttpDataAccessHelper';
6
+
7
+ interface ITGAReaderOptions {
8
+ compression?: string;
9
+ progressCallback?: any;
10
+ }
11
+
12
+ /**
13
+ *
14
+ */
15
+ export interface ITGAReaderInitialValues {}
16
+
17
+ type vtkTGAReaderBase = vtkObject &
18
+ Omit<
19
+ vtkAlgorithm,
20
+ | 'getInputData'
21
+ | 'setInputData'
22
+ | 'setInputConnection'
23
+ | 'getInputConnection'
24
+ | 'addInputConnection'
25
+ | 'addInputData'
26
+ >;
27
+
28
+ export interface vtkTGAReader extends vtkTGAReaderBase {
29
+ /**
30
+ * Get the base url.
31
+ */
32
+ getBaseURL(): string;
33
+
34
+ /**
35
+ * Get the dataAccess helper.
36
+ */
37
+ getDataAccessHelper():
38
+ | HtmlDataAccessHelper
39
+ | HttpDataAccessHelper
40
+ | JSZipDataAccessHelper
41
+ | LiteHttpDataAccessHelper;
42
+
43
+ /**
44
+ * Get the url of the object to load.
45
+ */
46
+ getUrl(): string;
47
+
48
+ /**
49
+ * Load the object data.
50
+ * @param {ITGAReaderOptions} [options]
51
+ */
52
+ loadData(options?: ITGAReaderOptions): Promise<any>;
53
+
54
+ /**
55
+ * Parse data.
56
+ * @param {ArrayBuffer} content The content to parse.
57
+ */
58
+ parse(content: ArrayBuffer): void;
59
+
60
+ /**
61
+ * Parse data as ArrayBuffer.
62
+ * @param {ArrayBuffer} content The content to parse.
63
+ */
64
+ parseAsArrayBuffer(content: ArrayBuffer): void;
65
+
66
+ /**
67
+ *
68
+ * @param inData
69
+ * @param outData
70
+ */
71
+ requestData(inData: any, outData: any): void;
72
+
73
+ /**
74
+ *
75
+ * @param dataAccessHelper
76
+ */
77
+ setDataAccessHelper(
78
+ dataAccessHelper:
79
+ | HtmlDataAccessHelper
80
+ | HttpDataAccessHelper
81
+ | JSZipDataAccessHelper
82
+ | LiteHttpDataAccessHelper
83
+ ): boolean;
84
+
85
+ /**
86
+ * Set the url of the object to load.
87
+ * @param {String} url the url of the object to load.
88
+ * @param {ITGAReaderOptions} [option] The PLY reader options.
89
+ */
90
+ setUrl(url: string, option?: ITGAReaderOptions): Promise<string | any>;
91
+ }
92
+
93
+ /**
94
+ * Method used to decorate a given object (publicAPI+model) with vtkTGAReader characteristics.
95
+ *
96
+ * @param publicAPI object on which methods will be bounds (public)
97
+ * @param model object on which data structure will be bounds (protected)
98
+ * @param {ITGAReaderInitialValues} [initialValues] (default: {})
99
+ */
100
+ export function extend(
101
+ publicAPI: object,
102
+ model: object,
103
+ initialValues?: ITGAReaderInitialValues
104
+ ): void;
105
+
106
+ /**
107
+ * Method used to create a new instance of vtkTGAReader
108
+ * @param {ITGAReaderInitialValues} [initialValues] for pre-setting some of its content
109
+ */
110
+ export function newInstance(
111
+ initialValues?: ITGAReaderInitialValues
112
+ ): vtkTGAReader;
113
+
114
+ /**
115
+ * vtkTGAReader is a source object that reads Truevision Targa(TGA) files.
116
+ */
117
+ export declare const vtkTGAReader: {
118
+ newInstance: typeof newInstance;
119
+ extend: typeof extend;
120
+ };
121
+ export default vtkTGAReader;
@@ -0,0 +1,418 @@
1
+ import '../Core/DataAccessHelper/LiteHttpDataAccessHelper.js';
2
+ import { m as macro } from '../../macros2.js';
3
+ import DataAccessHelper from '../Core/DataAccessHelper.js';
4
+ import vtkImageData from '../../Common/DataModel/ImageData.js';
5
+ import vtkDataArray from '../../Common/Core/DataArray.js';
6
+ import Constants from './TGAReader/Constants.js';
7
+
8
+ /* eslint-disable no-bitwise */
9
+ const {
10
+ vtkErrorMacro
11
+ } = macro;
12
+
13
+ // ----------------------------------------------------------------------------
14
+ // vtkTGAReader methods
15
+ // ----------------------------------------------------------------------------
16
+
17
+ function vtkTGAReader(publicAPI, model) {
18
+ // Set our className
19
+ model.classHierarchy.push('vtkTGAReader');
20
+
21
+ // Create default dataAccessHelper if not available
22
+ if (!model.dataAccessHelper) {
23
+ model.dataAccessHelper = DataAccessHelper.get('http');
24
+ }
25
+
26
+ /**
27
+ * Gets the header of a TGA file
28
+ * @param data defines the TGA data
29
+ * @returns the header
30
+ */
31
+ function parseHeader(data) {
32
+ let offset = 0;
33
+ const header = {
34
+ idLength: data[offset++],
35
+ colormap_type: data[offset++],
36
+ imageType: data[offset++],
37
+ colormapIndex: data[offset++] | data[offset++] << 8,
38
+ colormapLength: data[offset++] | data[offset++] << 8,
39
+ colormapSize: data[offset++],
40
+ origin: [data[offset++] | data[offset++] << 8, data[offset++] | data[offset++] << 8],
41
+ width: data[offset++] | data[offset++] << 8,
42
+ height: data[offset++] | data[offset++] << 8,
43
+ pixelSize: data[offset++],
44
+ flags: data[offset++]
45
+ };
46
+ return header;
47
+ }
48
+ const handlers = {
49
+ getImageData8bits(header, palettes, pixeData, yStart, yStep, yEnd, xStart, xStep, xEnd) {
50
+ const image = pixeData;
51
+ const colormap = palettes;
52
+ const width = header.width;
53
+ const height = header.height;
54
+ let color;
55
+ let i = 0;
56
+ let x;
57
+ let y;
58
+ const imageData = new Uint8Array(width * height * 4);
59
+ for (y = yStart; y !== yEnd; y += yStep) {
60
+ for (x = xStart; x !== xEnd; x += xStep, i++) {
61
+ color = image[i];
62
+ imageData[(x + width * y) * 4 + 3] = 255;
63
+ imageData[(x + width * y) * 4 + 2] = colormap[color * 3 + 0];
64
+ imageData[(x + width * y) * 4 + 1] = colormap[color * 3 + 1];
65
+ imageData[(x + width * y) * 4 + 0] = colormap[color * 3 + 2];
66
+ }
67
+ }
68
+ return imageData;
69
+ },
70
+ getImageData16bits(header, palettes, pixeData, yStart, yStep, yEnd, xStart, xStep, xEnd) {
71
+ const image = pixeData;
72
+ const width = header.width;
73
+ const height = header.height;
74
+ let color;
75
+ let i = 0;
76
+ let x;
77
+ let y;
78
+ const imageData = new Uint8Array(width * height * 4);
79
+ for (y = yStart; y !== yEnd; y += yStep) {
80
+ for (x = xStart; x !== xEnd; x += xStep, i += 2) {
81
+ color = image[i + 0] + (image[i + 1] << 8); // Inversed ?
82
+ const r = ((color & 0x7c00) >> 10) * 255 / 0x1f | 0;
83
+ const g = ((color & 0x03e0) >> 5) * 255 / 0x1f | 0;
84
+ const b = (color & 0x001f) * 255 / 0x1f | 0;
85
+ imageData[(x + width * y) * 4 + 0] = r;
86
+ imageData[(x + width * y) * 4 + 1] = g;
87
+ imageData[(x + width * y) * 4 + 2] = b;
88
+ imageData[(x + width * y) * 4 + 3] = color & 0x8000 ? 0 : 255;
89
+ }
90
+ }
91
+ return imageData;
92
+ },
93
+ getImageData24bits(header, palettes, pixeData, yStart, yStep, yEnd, xStart, xStep, xEnd) {
94
+ const image = pixeData;
95
+ const width = header.width;
96
+ const height = header.height;
97
+ let i = 0;
98
+ let x;
99
+ let y;
100
+ const imageData = new Uint8Array(width * height * 4);
101
+ for (y = yStart; y !== yEnd; y += yStep) {
102
+ for (x = xStart; x !== xEnd; x += xStep, i += 3) {
103
+ imageData[(x + width * y) * 4 + 3] = 255;
104
+ imageData[(x + width * y) * 4 + 2] = image[i + 0];
105
+ imageData[(x + width * y) * 4 + 1] = image[i + 1];
106
+ imageData[(x + width * y) * 4 + 0] = image[i + 2];
107
+ }
108
+ }
109
+ return imageData;
110
+ },
111
+ getImageData32bits(header, palettes, pixeData, yStart, yStep, yEnd, xStart, xStep, xEnd) {
112
+ const image = pixeData;
113
+ const width = header.width;
114
+ const height = header.height;
115
+ let i = 0;
116
+ let x;
117
+ let y;
118
+ const imageData = new Uint8Array(width * height * 4);
119
+ for (y = yStart; y !== yEnd; y += yStep) {
120
+ for (x = xStart; x !== xEnd; x += xStep, i += 4) {
121
+ imageData[(x + width * y) * 4 + 2] = image[i + 0];
122
+ imageData[(x + width * y) * 4 + 1] = image[i + 1];
123
+ imageData[(x + width * y) * 4 + 0] = image[i + 2];
124
+ imageData[(x + width * y) * 4 + 3] = image[i + 3];
125
+ }
126
+ }
127
+ return imageData;
128
+ },
129
+ getImageDataGrey8bits(header, palettes, pixeData, yStart, yStep, yEnd, xStart, xStep, xEnd) {
130
+ const image = pixeData;
131
+ const width = header.width;
132
+ const height = header.height;
133
+ let color;
134
+ let i = 0;
135
+ let x;
136
+ let y;
137
+ const imageData = new Uint8Array(width * height * 4);
138
+ for (y = yStart; y !== yEnd; y += yStep) {
139
+ for (x = xStart; x !== xEnd; x += xStep, i++) {
140
+ color = image[i];
141
+ imageData[(x + width * y) * 4 + 0] = color;
142
+ imageData[(x + width * y) * 4 + 1] = color;
143
+ imageData[(x + width * y) * 4 + 2] = color;
144
+ imageData[(x + width * y) * 4 + 3] = 255;
145
+ }
146
+ }
147
+ return imageData;
148
+ },
149
+ getImageDataGrey16bits(header, palettes, pixeData, yStart, yStep, yEnd, xStart, xStep, xEnd) {
150
+ const image = pixeData;
151
+ const width = header.width;
152
+ const height = header.height;
153
+ let i = 0;
154
+ let x;
155
+ let y;
156
+ const imageData = new Uint8Array(width * height * 4);
157
+ for (y = yStart; y !== yEnd; y += yStep) {
158
+ for (x = xStart; x !== xEnd; x += xStep, i += 2) {
159
+ imageData[(x + width * y) * 4 + 0] = image[i + 0];
160
+ imageData[(x + width * y) * 4 + 1] = image[i + 0];
161
+ imageData[(x + width * y) * 4 + 2] = image[i + 0];
162
+ imageData[(x + width * y) * 4 + 3] = image[i + 1];
163
+ }
164
+ }
165
+ return imageData;
166
+ }
167
+ };
168
+
169
+ // Internal method to fetch Array
170
+ function fetchData(url) {
171
+ const {
172
+ compression,
173
+ progressCallback
174
+ } = model;
175
+ return model.dataAccessHelper.fetchBinary(url, {
176
+ compression,
177
+ progressCallback
178
+ });
179
+ }
180
+
181
+ // Set DataSet url
182
+ publicAPI.setUrl = function (url) {
183
+ let option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
184
+ binary: true
185
+ };
186
+ model.url = url;
187
+
188
+ // Remove the file in the URL
189
+ const path = url.split('/');
190
+ path.pop();
191
+ model.baseURL = path.join('/');
192
+ model.compression = option.compression;
193
+
194
+ // Fetch metadata
195
+ return publicAPI.loadData({
196
+ progressCallback: option.progressCallback
197
+ });
198
+ };
199
+
200
+ // Fetch the actual data arrays
201
+ publicAPI.loadData = function () {
202
+ const promise = fetchData(model.url);
203
+ promise.then(publicAPI.parse);
204
+ return promise;
205
+ };
206
+ publicAPI.parse = content => {
207
+ publicAPI.parseAsArrayBuffer(content);
208
+ };
209
+ publicAPI.parseAsArrayBuffer = content => {
210
+ if (!content) {
211
+ return;
212
+ }
213
+ const data = new Uint8Array(content);
214
+ // Not enough data to contain header ?
215
+ if (data.length < 19) {
216
+ vtkErrorMacro('Unable to load TGA file - Not enough data to contain header');
217
+ return;
218
+ }
219
+
220
+ // Read Header
221
+ let offset = 18;
222
+ const header = parseHeader(data);
223
+
224
+ // Assume it's a valid Targa file.
225
+ if (header.idLength + offset > data.length) {
226
+ vtkErrorMacro('Unable to load TGA file - Not enough data');
227
+ return;
228
+ }
229
+
230
+ // Skip not needed data
231
+ offset += header.idLength;
232
+ let useRle = false;
233
+ let usePal = false;
234
+ let useGrey = false;
235
+
236
+ // Get some informations.
237
+ switch (header.imageType) {
238
+ case Constants.TYPE_RLE_INDEXED:
239
+ useRle = true;
240
+ // eslint-disable-next-line no-fallthrough
241
+ case Constants.TYPE_INDEXED:
242
+ usePal = true;
243
+ break;
244
+ case Constants.TYPE_RLE_RGB:
245
+ useRle = true;
246
+ // eslint-disable-next-line no-fallthrough
247
+ case Constants.TYPE_RGB:
248
+ // use_rgb = true;
249
+ break;
250
+ case Constants.TYPE_RLE_GREY:
251
+ useRle = true;
252
+ // eslint-disable-next-line no-fallthrough
253
+ case Constants.TYPE_GREY:
254
+ useGrey = true;
255
+ break;
256
+ default:
257
+ vtkErrorMacro('TGA file has unknown image type');
258
+ return;
259
+ }
260
+ let pixelData;
261
+ const pixelSize = header.pixelSize >> 3;
262
+ const pixelTotal = header.width * header.height * pixelSize;
263
+
264
+ // Read palettes
265
+ let palettes;
266
+ if (usePal) {
267
+ palettes = data.subarray(offset, offset += header.colormapLength * (header.colormapSize >> 3));
268
+ }
269
+
270
+ // Read LRE
271
+ if (useRle) {
272
+ pixelData = new Uint8Array(pixelTotal);
273
+ let c;
274
+ let count;
275
+ let i;
276
+ let localOffset = 0;
277
+ const pixels = new Uint8Array(pixelSize);
278
+ while (offset < pixelTotal && localOffset < pixelTotal) {
279
+ c = data[offset++];
280
+ count = (c & 0x7f) + 1;
281
+
282
+ // RLE pixels
283
+ if (c & 0x80) {
284
+ // Bind pixel tmp array
285
+ for (i = 0; i < pixelSize; ++i) {
286
+ pixels[i] = data[offset++];
287
+ }
288
+
289
+ // Copy pixel array
290
+ for (i = 0; i < count; ++i) {
291
+ pixelData.set(pixels, localOffset + i * pixelSize);
292
+ }
293
+ localOffset += pixelSize * count;
294
+ }
295
+ // Raw pixels
296
+ else {
297
+ count *= pixelSize;
298
+ for (i = 0; i < count; ++i) {
299
+ pixelData[localOffset + i] = data[offset++];
300
+ }
301
+ localOffset += count;
302
+ }
303
+ }
304
+ }
305
+ // RAW Pixels
306
+ else {
307
+ pixelData = data.subarray(offset, offset += usePal ? header.width * header.height : pixelTotal);
308
+ }
309
+
310
+ // Load to texture
311
+ let xStart;
312
+ let yStart;
313
+ let xStep;
314
+ let yStep;
315
+ let yEnd;
316
+ let xEnd;
317
+ switch ((header.flags & Constants.ORIGIN_MASK) >> Constants.ORIGIN_SHIFT) {
318
+ case Constants.ORIGIN_UL:
319
+ xStart = 0;
320
+ xStep = 1;
321
+ xEnd = header.width;
322
+ yStart = 0;
323
+ yStep = 1;
324
+ yEnd = header.height;
325
+ break;
326
+ case Constants.ORIGIN_BL:
327
+ xStart = 0;
328
+ xStep = 1;
329
+ xEnd = header.width;
330
+ yStart = 0;
331
+ yStep = 1;
332
+ yEnd = header.height;
333
+ break;
334
+ case Constants.ORIGIN_UR:
335
+ xStart = header.width - 1;
336
+ xStep = -1;
337
+ xEnd = -1;
338
+ yStart = 0;
339
+ yStep = 1;
340
+ yEnd = header.height;
341
+ break;
342
+ case Constants.ORIGIN_BR:
343
+ xStart = header.width - 1;
344
+ xStep = -1;
345
+ xEnd = -1;
346
+ yStart = header.height - 1;
347
+ yStep = -1;
348
+ yEnd = -1;
349
+ break;
350
+ default:
351
+ vtkErrorMacro('TGA file has unknown origin');
352
+ return;
353
+ }
354
+ const func = `getImageData${useGrey ? 'Grey' : ''}${header.pixelSize}bits`;
355
+ const output = handlers[func](header, palettes, pixelData, yStart, yStep, yEnd, xStart, xStep, xEnd);
356
+ const dataExtent = [0, header.width - 1, 0, header.height - 1];
357
+ const dataSpacing = [1, 1, 1];
358
+ const imageData = vtkImageData.newInstance();
359
+ imageData.setDimensions(header.width, header.height, 1);
360
+ imageData.setExtent(dataExtent);
361
+ imageData.setSpacing(dataSpacing);
362
+ const dataArray = vtkDataArray.newInstance({
363
+ name: 'TGAImage',
364
+ numberOfComponents: 4,
365
+ values: output
366
+ });
367
+ imageData.getPointData().setScalars(dataArray);
368
+ model.output[0] = imageData;
369
+ };
370
+ publicAPI.requestData = (inData, outData) => {
371
+ publicAPI.parse(model.parseData);
372
+ };
373
+ }
374
+
375
+ // ----------------------------------------------------------------------------
376
+ // Object factory
377
+ // ----------------------------------------------------------------------------
378
+
379
+ const DEFAULT_VALUES = {};
380
+
381
+ // ----------------------------------------------------------------------------
382
+
383
+ function extend(publicAPI, model) {
384
+ let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
385
+ Object.assign(model, DEFAULT_VALUES, initialValues);
386
+
387
+ // Make this a VTK object
388
+ macro.obj(publicAPI, model);
389
+
390
+ // Also make it an algorithm with one input and one output
391
+ macro.algo(publicAPI, model, 0, 1);
392
+ macro.get(publicAPI, model, ['url', 'baseURL']);
393
+ macro.setGet(publicAPI, model, ['dataAccessHelper']);
394
+
395
+ // Object specific methods
396
+ vtkTGAReader(publicAPI, model);
397
+
398
+ // To support destructuring
399
+ if (!model.compression) {
400
+ model.compression = null;
401
+ }
402
+ if (!model.progressCallback) {
403
+ model.progressCallback = null;
404
+ }
405
+ }
406
+
407
+ // ----------------------------------------------------------------------------
408
+
409
+ const newInstance = macro.newInstance(extend, 'vtkTGAReader');
410
+
411
+ // ----------------------------------------------------------------------------
412
+
413
+ var vtkTGAReader$1 = {
414
+ newInstance,
415
+ extend
416
+ };
417
+
418
+ export { vtkTGAReader$1 as default, extend, newInstance };
package/IO/Image.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import vtkHDRReader from './Image/HDRReader.js';
2
+ import vtkTGAReader from './Image/TGAReader.js';
2
3
 
3
4
  var index = {
4
- vtkHDRReader
5
+ vtkHDRReader,
6
+ vtkTGAReader
5
7
  };
6
8
 
7
9
  export { index as default };
@@ -63,7 +63,7 @@ export interface IRenderWindowInteractorInitialValues {
63
63
  mouseScrollDebounceByPass?: boolean;
64
64
  }
65
65
 
66
- interface IPosition {
66
+ export interface IPosition {
67
67
  type: string;
68
68
  }
69
69
 
@@ -168,9 +168,9 @@ function vtkOpenGLImageMapper(publicAPI, model) {
168
168
  // check for the outline thickness and opacity
169
169
  const vtkImageLabelOutline = actor.getProperty().getUseLabelOutline();
170
170
  if (vtkImageLabelOutline === true) {
171
- FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::LabelOutline::Dec', ['uniform int outlineThickness;', 'uniform float vpWidth;', 'uniform float vpHeight;', 'uniform float vpOffsetX;', 'uniform float vpOffsetY;', 'uniform mat4 PCWCMatrix;', 'uniform mat4 vWCtoIDX;', 'uniform ivec3 imageDimensions;']).result;
171
+ FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::LabelOutline::Dec', ['uniform int outlineThickness;', 'uniform float vpWidth;', 'uniform float vpHeight;', 'uniform float vpOffsetX;', 'uniform float vpOffsetY;', 'uniform mat4 PCWCMatrix;', 'uniform mat4 vWCtoIDX;', 'uniform ivec3 imageDimensions;', 'uniform int sliceAxis;']).result;
172
172
  FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::ImageLabelOutlineOn', '#define vtkImageLabelOutlineOn').result;
173
- FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::LabelOutlineHelperFunction', ['#ifdef vtkImageLabelOutlineOn', 'vec3 fragCoordToIndexSpace(vec4 fragCoord) {', ' vec4 pcPos = vec4(', ' (fragCoord.x / vpWidth - vpOffsetX - 0.5) * 2.0,', ' (fragCoord.y / vpHeight - vpOffsetY - 0.5) * 2.0,', ' (fragCoord.z - 0.5) * 2.0,', ' 1.0);', '', ' vec4 worldCoord = PCWCMatrix * pcPos;', ' vec4 vertex = (worldCoord/worldCoord.w);', '', ' vec3 index = (vWCtoIDX * vertex).xyz;', '', ' // half voxel fix for labelmapOutline', ' return (index + vec3(0.5)) / vec3(imageDimensions);', '}', '#endif']).result;
173
+ FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::LabelOutlineHelperFunction', ['#ifdef vtkImageLabelOutlineOn', 'vec3 fragCoordToIndexSpace(vec4 fragCoord) {', ' vec4 pcPos = vec4(', ' (fragCoord.x / vpWidth - vpOffsetX - 0.5) * 2.0,', ' (fragCoord.y / vpHeight - vpOffsetY - 0.5) * 2.0,', ' (fragCoord.z - 0.5) * 2.0,', ' 1.0);', '', ' vec4 worldCoord = PCWCMatrix * pcPos;', ' vec4 vertex = (worldCoord/worldCoord.w);', '', ' vec3 index = (vWCtoIDX * vertex).xyz;', '', ' // half voxel fix for labelmapOutline', ' return (index + vec3(0.5)) / vec3(imageDimensions);', '}', 'vec2 getSliceCoords(vec3 coord, int axis) {', ' if (axis == 0) return coord.yz;', ' if (axis == 1) return coord.xz;', ' if (axis == 2) return coord.xy;', '}', '#endif']).result;
174
174
  }
175
175
  if (iComps) {
176
176
  const rgba = ['r', 'g', 'b', 'a'];
@@ -202,7 +202,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
202
202
  FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::TCoord::Impl', [...splitStringOnEnter(`
203
203
  #ifdef vtkImageLabelOutlineOn
204
204
  vec3 centerPosIS = fragCoordToIndexSpace(gl_FragCoord);
205
- float centerValue = texture2D(texture1, centerPosIS.xy).r;
205
+ float centerValue = texture2D(texture1, getSliceCoords(centerPosIS, sliceAxis)).r;
206
206
  bool pixelOnBorder = false;
207
207
  vec3 tColor = texture2D(colorTexture1, vec2(centerValue * cscale0 + cshift0, 0.5)).rgb;
208
208
  float scalarOpacity = texture2D(pwfTexture1, vec2(centerValue * pwfscale0 + pwfshift0, 0.5)).r;
@@ -213,7 +213,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
213
213
  int actualThickness = int(textureValue * 255.0);
214
214
 
215
215
  if (segmentIndex == 0){
216
- gl_FragData[0] = vec4(0.0, 1.0, 1.0, 0.0);
216
+ gl_FragData[0] = vec4(0.0, 0.0, 0.0, 0.0);
217
217
  return;
218
218
  }
219
219
 
@@ -226,7 +226,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
226
226
  gl_FragCoord.y + float(j),
227
227
  gl_FragCoord.z, gl_FragCoord.w);
228
228
  vec3 neighborPosIS = fragCoordToIndexSpace(neighborPixelCoord);
229
- float value = texture2D(texture1, neighborPosIS.xy).r;
229
+ float value = texture2D(texture1, getSliceCoords(neighborPosIS, sliceAxis)).r;
230
230
  if (value != centerValue) {
231
231
  pixelOnBorder = true;
232
232
  break;
@@ -475,7 +475,14 @@ function vtkOpenGLImageMapper(publicAPI, model) {
475
475
  if (vtkImageLabelOutline === true) {
476
476
  const worldToIndex = image.getWorldToIndex();
477
477
  const imageDimensions = image.getDimensions();
478
- program.setUniform3i('imageDimensions', imageDimensions[0], imageDimensions[1], 1);
478
+ let sliceAxis = model.renderable.getClosestIJKAxis().ijkMode;
479
+
480
+ // SlicingMode.NONE equates to SlicingMode.K
481
+ if (sliceAxis === SlicingMode.NONE) {
482
+ sliceAxis = SlicingMode.K;
483
+ }
484
+ program.setUniform3i('imageDimensions', imageDimensions[0], imageDimensions[1], imageDimensions[2]);
485
+ program.setUniformi('sliceAxis', sliceAxis);
479
486
  program.setUniformMatrix('vWCtoIDX', worldToIndex);
480
487
  const labelOutlineKeyMats = model.openGLCamera.getKeyMatrices(ren);
481
488
 
@@ -896,7 +903,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
896
903
  }
897
904
  };
898
905
  publicAPI.updatelabelOutlineThicknessTexture = image => {
899
- const labelOutlineThicknessArray = image.getProperty().getLabelOutlineThickness();
906
+ const labelOutlineThicknessArray = image.getProperty().getLabelOutlineThicknessByReference();
900
907
  const lTex = model._openGLRenderWindow.getGraphicsResourceForObject(labelOutlineThicknessArray);
901
908
 
902
909
  // compute the join of the labelOutlineThicknessArray so that
package/index.d.ts CHANGED
@@ -97,6 +97,7 @@
97
97
  /// <reference path="./IO/Geometry/STLReader.d.ts" />
98
98
  /// <reference path="./IO/Geometry/STLWriter.d.ts" />
99
99
  /// <reference path="./IO/Image/HDRReader.d.ts" />
100
+ /// <reference path="./IO/Image/TGAReader.d.ts" />
100
101
  /// <reference path="./IO/Misc/ElevationReader.d.ts" />
101
102
  /// <reference path="./IO/Misc/GCodeReader.d.ts" />
102
103
  /// <reference path="./IO/Misc/ITKImageReader.d.ts" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitware/vtk.js",
3
- "version": "32.5.1",
3
+ "version": "32.6.0",
4
4
  "description": "Visualization Toolkit for the Web",
5
5
  "keywords": [
6
6
  "3d",