@@ -97,6 +97,121 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
97
97
updateScrollManipulator ( ) ;
98
98
}
99
99
100
+ function isCameraViewInitialized ( camera ) {
101
+ const dist = camera . getDistance ( ) ;
102
+
103
+ return (
104
+ typeof dist === 'number' && dist === Number ( dist ) && Number . isFinite ( dist )
105
+ ) ;
106
+ }
107
+
108
+ function onRotateChanged ( args ) {
109
+ setSliceNormalInternal ( args . detail . sliceNormal ) ;
110
+ setViewUpInternal ( args . detail . sliceViewUp ) ;
111
+ }
112
+
113
+ function setViewUpInternal ( viewUp ) {
114
+ const renderer = model . interactor . getCurrentRenderer ( ) ;
115
+ const camera = renderer . getActiveCamera ( ) ;
116
+ const _viewUp = [ ...viewUp ] ;
117
+
118
+ if ( model . volumeMapper ) {
119
+ let mapper = model . volumeMapper ;
120
+ // get the mapper if the model is actually the actor, not the mapper
121
+ if ( ! model . volumeMapper . getInputData && model . volumeMapper . getMapper ) {
122
+ mapper = model . volumeMapper . getMapper ( ) ;
123
+ }
124
+ let volumeCoordinateSpace = vec9toMat3 (
125
+ mapper . getInputData ( ) . getDirection ( )
126
+ ) ;
127
+ // Transpose the volume's coordinate space to create a transformation matrix
128
+ vtkMath . transpose3x3 ( volumeCoordinateSpace , volumeCoordinateSpace ) ;
129
+
130
+ vtkMath . multiply3x3_vect3 ( volumeCoordinateSpace , _viewUp , _viewUp ) ;
131
+ camera . setViewUp ( ..._viewUp ) ;
132
+ }
133
+ }
134
+
135
+ // in world space
136
+ function setSliceNormalInternal ( normal ) {
137
+ const renderer = model . interactor . getCurrentRenderer ( ) ;
138
+ const camera = renderer . getActiveCamera ( ) ;
139
+
140
+ //copy arguments for internal editing so we don't cause sideeffects
141
+ const _normal = [ ...normal ] ;
142
+
143
+ if ( model . volumeMapper ) {
144
+ vtkMath . normalize ( _normal ) ;
145
+ let mapper = model . volumeMapper ;
146
+ // get the mapper if the model is actually the actor, not the mapper
147
+ if ( ! model . volumeMapper . getInputData && model . volumeMapper . getMapper ) {
148
+ mapper = model . volumeMapper . getMapper ( ) ;
149
+ }
150
+ let volumeCoordinateSpace = vec9toMat3 (
151
+ mapper . getInputData ( ) . getDirection ( )
152
+ ) ;
153
+ // Transpose the volume's coordinate space to create a transformation matrix
154
+ vtkMath . transpose3x3 ( volumeCoordinateSpace , volumeCoordinateSpace ) ;
155
+ // Convert the provided normal into the volume's space
156
+ vtkMath . multiply3x3_vect3 ( volumeCoordinateSpace , _normal , _normal ) ;
157
+ let center = camera . getFocalPoint ( ) ;
158
+ let dist = camera . getDistance ( ) ;
159
+ let angle = camera . getViewAngle ( ) ;
160
+
161
+ if ( ! isCameraViewInitialized ( camera ) ) {
162
+ const bounds = model . volumeMapper . getBounds ( ) ;
163
+ // diagonal will be used as "width" of camera scene
164
+ const diagonal = Math . sqrt (
165
+ vtkMath . distance2BetweenPoints (
166
+ [ bounds [ 0 ] , bounds [ 2 ] , bounds [ 4 ] ] ,
167
+ [ bounds [ 1 ] , bounds [ 3 ] , bounds [ 5 ] ]
168
+ )
169
+ ) ;
170
+
171
+ // center will be used as initial focal point
172
+ center = [
173
+ ( bounds [ 0 ] + bounds [ 1 ] ) / 2.0 ,
174
+ ( bounds [ 2 ] + bounds [ 3 ] ) / 2.0 ,
175
+ ( bounds [ 4 ] + bounds [ 5 ] ) / 2.0 ,
176
+ ] ;
177
+
178
+ angle = 90 ;
179
+
180
+ // distance from camera to focal point
181
+ dist = diagonal / ( 2 * Math . tan ( ( angle / 360 ) * Math . PI ) ) ;
182
+ }
183
+
184
+ const cameraPos = [
185
+ center [ 0 ] - _normal [ 0 ] * dist ,
186
+ center [ 1 ] - _normal [ 1 ] * dist ,
187
+ center [ 2 ] - _normal [ 2 ] * dist ,
188
+ ] ;
189
+
190
+ // set viewUp based on DOP rotation
191
+ // const oldDop = camera.getDirectionOfProjection();
192
+ // const transform = vtkMatrixBuilder
193
+ // .buildFromDegree()
194
+ // .identity()
195
+ // .rotateFromDirections(oldDop, _normal);
196
+
197
+ // transform.apply(_viewUp);
198
+
199
+ const { slabThickness } = model ;
200
+
201
+ camera . setPosition ( ...cameraPos ) ;
202
+ camera . setDistance ( dist ) ;
203
+ // should be set after pos and distance
204
+ camera . setDirectionOfProjection ( ..._normal ) ;
205
+ camera . setViewAngle ( angle ) ;
206
+ camera . setClippingRange (
207
+ dist - slabThickness / 2 ,
208
+ dist + slabThickness / 2
209
+ ) ;
210
+
211
+ publicAPI . setCenterOfRotation ( center ) ;
212
+ }
213
+ }
214
+
100
215
publicAPI . setViewport = viewportData => {
101
216
if ( model . viewportData ) {
102
217
const oldWindow = model . viewportData . getEventWindow ( ) ;
@@ -111,20 +226,15 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
111
226
}
112
227
113
228
if ( viewportData ) {
114
- setSliceNormalInternal (
115
- viewportData . getInitialSliceNormal ( ) ,
116
- viewportData . getInitialViewUp ( )
117
- ) ;
229
+ setSliceNormalInternal ( viewportData . getInitialSliceNormal ( ) ) ;
230
+ setViewUpInternal ( viewportData . getInitialViewUp ( ) ) ;
231
+
118
232
viewportData
119
233
. getEventWindow ( )
120
234
. addEventListener ( EVENTS . VIEWPORT_ROTATED , onRotateChanged ) ;
121
235
}
122
236
} ;
123
237
124
- function onRotateChanged ( args ) {
125
- setSliceNormalInternal ( args . detail . sliceNormal , args . detail . sliceViewUp ) ;
126
- }
127
-
128
238
publicAPI . getViewport = ( ) => model . viewportData ;
129
239
130
240
let cameraSub = null ;
@@ -195,10 +305,8 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
195
305
const viewportData = publicAPI . getViewport ( ) ;
196
306
197
307
if ( viewportData ) {
198
- setSliceNormalInternal (
199
- viewportData . getInitialSliceNormal ( ) ,
200
- viewportData . getInitialViewUp ( )
201
- ) ;
308
+ setSliceNormalInternal ( viewportData . getInitialSliceNormal ( ) ) ;
309
+ setViewUpInternal ( viewportData . getInitialViewUp ( ) ) ;
202
310
}
203
311
204
312
updateScrollManipulator ( ) ;
@@ -327,111 +435,42 @@ function vtkInteractorStyleMPRSlice(publicAPI, model) {
327
435
return [ 0 , 0 , 0 ] ;
328
436
} ;
329
437
330
- function isCameraViewInitialized ( camera ) {
331
- const dist = camera . getDistance ( ) ;
332
-
333
- return (
334
- typeof dist === 'number' && dist === Number ( dist ) && Number . isFinite ( dist )
335
- ) ;
336
- }
337
-
338
- publicAPI . setSliceNormal = ( normal , viewUp = [ 0 , 1 , 0 ] ) => {
438
+ publicAPI . setSliceNormal = ( ...normal ) => {
339
439
const viewportData = publicAPI . getViewport ( ) ;
340
440
341
441
if ( viewportData ) {
342
- viewportData . setInitialOrientation ( normal , viewUp ) ;
442
+ viewportData . setInitialOrientation (
443
+ normal ,
444
+ viewportData . getInitialViewUp ( )
445
+ ) ;
343
446
}
344
447
345
- setSliceNormalInternal ( normal , viewUp ) ;
448
+ setSliceNormalInternal ( normal ) ;
346
449
} ;
347
450
348
- // in world space
349
- function setSliceNormalInternal ( normal , viewUp = [ 0 , 1 , 0 ] ) {
350
- const renderer = model . interactor . getCurrentRenderer ( ) ;
351
- const camera = renderer . getActiveCamera ( ) ;
352
-
353
- // Copy arguments to the model, so they can be GET-ed later
354
- model . sliceNormal = [ ...normal ] ;
355
- model . viewUp = [ ...viewUp ] ;
356
-
357
- //copy arguments for internal editing so we don't cause sideeffects
358
- const _normal = [ ...normal ] ;
359
- const _viewUp = [ ...viewUp ] ;
360
-
361
- if ( model . volumeMapper ) {
362
- vtkMath . normalize ( _normal ) ;
363
- let mapper = model . volumeMapper ;
364
- // get the mapper if the model is actually the actor, not the mapper
365
- if ( ! model . volumeMapper . getInputData && model . volumeMapper . getMapper ) {
366
- mapper = model . volumeMapper . getMapper ( ) ;
367
- }
368
- let volumeCoordinateSpace = vec9toMat3 (
369
- mapper . getInputData ( ) . getDirection ( )
370
- ) ;
371
- // Transpose the volume's coordinate space to create a transformation matrix
372
- vtkMath . transpose3x3 ( volumeCoordinateSpace , volumeCoordinateSpace ) ;
373
- // Convert the provided normal into the volume's space
374
- vtkMath . multiply3x3_vect3 ( volumeCoordinateSpace , _normal , _normal ) ;
375
- let center = camera . getFocalPoint ( ) ;
376
- let dist = camera . getDistance ( ) ;
377
- let angle = camera . getViewAngle ( ) ;
378
-
379
- if ( ! isCameraViewInitialized ( camera ) ) {
380
- const bounds = model . volumeMapper . getBounds ( ) ;
381
- // diagonal will be used as "width" of camera scene
382
- const diagonal = Math . sqrt (
383
- vtkMath . distance2BetweenPoints (
384
- [ bounds [ 0 ] , bounds [ 2 ] , bounds [ 4 ] ] ,
385
- [ bounds [ 1 ] , bounds [ 3 ] , bounds [ 5 ] ]
386
- )
387
- ) ;
388
-
389
- // center will be used as initial focal point
390
- center = [
391
- ( bounds [ 0 ] + bounds [ 1 ] ) / 2.0 ,
392
- ( bounds [ 2 ] + bounds [ 3 ] ) / 2.0 ,
393
- ( bounds [ 4 ] + bounds [ 5 ] ) / 2.0 ,
394
- ] ;
395
-
396
- angle = 90 ;
397
-
398
- // distance from camera to focal point
399
- dist = diagonal / ( 2 * Math . tan ( ( angle / 360 ) * Math . PI ) ) ;
400
- }
401
-
402
- const cameraPos = [
403
- center [ 0 ] - _normal [ 0 ] * dist ,
404
- center [ 1 ] - _normal [ 1 ] * dist ,
405
- center [ 2 ] - _normal [ 2 ] * dist ,
406
- ] ;
407
-
408
- // set viewUp based on DOP rotation
409
- // const oldDop = camera.getDirectionOfProjection();
410
- // const transform = vtkMatrixBuilder
411
- // .buildFromDegree()
412
- // .identity()
413
- // .rotateFromDirections(oldDop, _normal);
451
+ publicAPI . getViewUp = ( ) => {
452
+ if ( model . volumeMapper && model . interactor ) {
453
+ const renderer = model . interactor . getCurrentRenderer ( ) ;
454
+ const camera = renderer . getActiveCamera ( ) ;
414
455
415
- // transform.apply(_viewUp);
456
+ return camera . getViewUp ( ) ;
457
+ }
416
458
417
- vtkMath . multiply3x3_vect3 ( volumeCoordinateSpace , _viewUp , _viewUp ) ;
459
+ return [ 0 , 0 , 0 ] ;
460
+ } ;
418
461
419
- const { slabThickness } = model ;
462
+ publicAPI . setViewUp = ( ...viewUp ) => {
463
+ const viewportData = publicAPI . getViewport ( ) ;
420
464
421
- camera . setPosition ( ...cameraPos ) ;
422
- camera . setDistance ( dist ) ;
423
- // should be set after pos and distance
424
- camera . setDirectionOfProjection ( ..._normal ) ;
425
- camera . setViewUp ( ..._viewUp ) ;
426
- camera . setViewAngle ( angle ) ;
427
- camera . setClippingRange (
428
- dist - slabThickness / 2 ,
429
- dist + slabThickness / 2
465
+ if ( viewportData ) {
466
+ viewportData . setInitialOrientation (
467
+ viewportData . getInitialSliceNormal ( ) ,
468
+ viewUp
430
469
) ;
431
-
432
- publicAPI . setCenterOfRotation ( center ) ;
433
470
}
434
- }
471
+
472
+ setViewUpInternal ( viewUp ) ;
473
+ } ;
435
474
436
475
publicAPI . setSlabThickness = slabThickness => {
437
476
model . slabThickness = slabThickness ;
0 commit comments