@@ -7,6 +7,7 @@ import '@kitware/vtk.js/Rendering/Profiles/All';
77import '@kitware/vtk.js/IO/Core/DataAccessHelper/HttpDataAccessHelper' ;
88
99import { radiansFromDegrees } from 'vtk.js/Sources/Common/Core/Math' ;
10+ import { updateState } from 'vtk.js/Sources/Widgets/Widgets3D/ResliceCursorWidget/helpers' ;
1011import { vec3 , mat3 , mat4 } from 'gl-matrix' ;
1112import { ViewTypes } from '@kitware/vtk.js/Widgets/Core/WidgetManager/Constants' ;
1213import vtkCPRManipulator from '@kitware/vtk.js/Widgets/Manipulators/CPRManipulator' ;
@@ -39,7 +40,11 @@ const centerlineKeys = Object.keys(centerlineJsons);
3940const fullScreenRenderer = vtkFullScreenRenderWindow . newInstance ( ) ;
4041const stretchRenderer = fullScreenRenderer . getRenderer ( ) ;
4142const renderWindow = fullScreenRenderer . getRenderWindow ( ) ;
43+
4244fullScreenRenderer . addController ( controlPanel ) ;
45+ const angleEl = document . getElementById ( 'angle' ) ;
46+ const centerlineEl = document . getElementById ( 'centerline' ) ;
47+
4348const interactor = renderWindow . getInteractor ( ) ;
4449interactor . setInteractorStyle ( vtkInteractorStyleImage . newInstance ( ) ) ;
4550interactor . setDesiredUpdateRate ( 15.0 ) ;
@@ -122,6 +127,8 @@ function updateDistanceAndDirection() {
122127 const widgetPlanes = widgetState . getPlanes ( ) ;
123128 const worldBitangent = widgetPlanes [ stretchViewType ] . normal ;
124129 const worldNormal = widgetPlanes [ stretchViewType ] . viewUp ;
130+ widgetPlanes [ crossViewType ] . normal = worldNormal ;
131+ widgetPlanes [ crossViewType ] . viewUp = worldBitangent ;
125132 const worldTangent = vec3 . cross ( [ ] , worldBitangent , worldNormal ) ;
126133 vec3 . normalize ( worldTangent , worldTangent ) ;
127134 const worldWidgetCenter = widgetState . getCenter ( ) ;
@@ -144,21 +151,13 @@ function updateDistanceAndDirection() {
144151 distance - height
145152 ) ;
146153 const worldActorTransform = mat4 . fromValues (
147- worldTangent [ 0 ] ,
148- worldTangent [ 1 ] ,
149- worldTangent [ 2 ] ,
154+ ...worldTangent ,
150155 0 ,
151- worldNormal [ 0 ] ,
152- worldNormal [ 1 ] ,
153- worldNormal [ 2 ] ,
156+ ...worldNormal ,
154157 0 ,
155- - worldBitangent [ 0 ] ,
156- - worldBitangent [ 1 ] ,
157- - worldBitangent [ 2 ] ,
158+ ...vec3 . scale ( [ ] , worldBitangent , - 1 ) ,
158159 0 ,
159- worldActorTranslation [ 0 ] ,
160- worldActorTranslation [ 1 ] ,
161- worldActorTranslation [ 2 ] ,
160+ ...worldActorTranslation ,
162161 1
163162 ) ;
164163 actor . setUserMatrix ( worldActorTransform ) ;
@@ -195,15 +194,9 @@ function updateDistanceAndDirection() {
195194 const modelDirections = mat3 . fromQuat ( [ ] , orientation ) ;
196195 const inverseModelDirections = mat3 . invert ( [ ] , modelDirections ) ;
197196 const worldDirections = mat3 . fromValues (
198- worldTangent [ 0 ] ,
199- worldTangent [ 1 ] ,
200- worldTangent [ 2 ] ,
201- worldBitangent [ 0 ] ,
202- worldBitangent [ 1 ] ,
203- worldBitangent [ 2 ] ,
204- worldNormal [ 0 ] ,
205- worldNormal [ 1 ] ,
206- worldNormal [ 2 ]
197+ ...worldTangent ,
198+ ...worldBitangent ,
199+ ...worldNormal
207200 ) ;
208201 const baseDirections = mat3 . mul ( [ ] , inverseModelDirections , worldDirections ) ;
209202 mapper . setDirectionMatrix ( baseDirections ) ;
@@ -222,6 +215,18 @@ function updateDistanceAndDirection() {
222215 // Update plane manipulator origin / normal for the cross view
223216 planeManipulator . setUserOrigin ( worldWidgetCenter ) ;
224217 planeManipulator . setUserNormal ( worldNormal ) ;
218+
219+ // Find the angle
220+ const signedRadAngle = Math . atan2 ( baseDirections [ 1 ] , baseDirections [ 0 ] ) ;
221+ const signedDegAngle = ( signedRadAngle * 180 ) / Math . PI ;
222+ const degAngle = signedDegAngle > 0 ? signedDegAngle : 360 + signedDegAngle ;
223+ angleEl . value = degAngle ;
224+ updateState (
225+ widgetState ,
226+ widget . getScaleInPixels ( ) ,
227+ widget . getRotationHandlePosition ( )
228+ ) ;
229+ renderWindow . render ( ) ;
225230}
226231
227232// The centerline JSON contains positions (vec3) and orientations (mat4)
@@ -272,7 +277,6 @@ function setCenterlineKey(centerlineKey) {
272277}
273278
274279// Create an option for each centerline
275- const centerlineEl = document . getElementById ( 'centerline' ) ;
276280for ( let i = 0 ; i < centerlineKeys . length ; ++ i ) {
277281 const name = centerlineKeys [ i ] ;
278282 const optionEl = document . createElement ( 'option' ) ;
@@ -291,7 +295,6 @@ reader.setUrl(volumePath).then(() => {
291295 widget . setImage ( image ) ;
292296 const imageDimensions = image . getDimensions ( ) ;
293297 const imageSpacing = image . getSpacing ( ) ;
294- cprManipulator . setDistanceStep ( Math . min ( ...imageSpacing ) ) ;
295298 const diagonal = vec3 . mul ( [ ] , imageDimensions , imageSpacing ) ;
296299 mapper . setWidth ( 2 * vec3 . len ( diagonal ) ) ;
297300
@@ -318,6 +321,35 @@ reader.setUrl(volumePath).then(() => {
318321 } ) ;
319322} ) ;
320323
324+ function setAngleFromSlider ( radAngle ) {
325+ // Compute normal and bitangent directions from angle
326+ const origin = [ 0 , 0 , 0 ] ;
327+ const normalDir = [ 0 , 0 , 1 ] ;
328+ const bitangentDir = [ 0 , 1 , 0 ] ;
329+ vec3 . rotateZ ( bitangentDir , bitangentDir , origin , radAngle ) ;
330+
331+ // Get orientation from distance
332+ const distance = cprManipulator . getCurrentDistance ( ) ;
333+ const { orientation } = mapper . getCenterlinePositionAndOrientation ( distance ) ;
334+ const modelDirections = mat3 . fromQuat ( [ ] , orientation ) ;
335+
336+ // Set widget normal and viewUp from orientation and directions
337+ const worldBitangent = vec3 . transformMat3 ( [ ] , bitangentDir , modelDirections ) ;
338+ const worldNormal = vec3 . transformMat3 ( [ ] , normalDir , modelDirections ) ;
339+ const widgetPlanes = widgetState . getPlanes ( ) ;
340+ widgetPlanes [ stretchViewType ] . normal = worldBitangent ;
341+ widgetPlanes [ stretchViewType ] . viewUp = worldNormal ;
342+ widgetPlanes [ crossViewType ] . normal = worldNormal ;
343+ widgetPlanes [ crossViewType ] . viewUp = worldBitangent ;
344+ widgetState . setPlanes ( widgetPlanes ) ;
345+
346+ updateDistanceAndDirection ( ) ;
347+ }
348+
349+ angleEl . addEventListener ( 'input' , ( ) =>
350+ setAngleFromSlider ( radiansFromDegrees ( Number . parseFloat ( angleEl . value , 10 ) ) )
351+ ) ;
352+
321353stretchViewWidgetInstance . onInteractionEvent ( updateDistanceAndDirection ) ;
322354crossViewWidgetInstance . onInteractionEvent ( updateDistanceAndDirection ) ;
323355
0 commit comments