]> Creatis software - cpPlugins.git/blob - lib/cpExtensions/Interaction/ImageSlicePointPlacer.cxx
yet another refactoring
[cpPlugins.git] / lib / cpExtensions / Interaction / ImageSlicePointPlacer.cxx
1 #include <cpExtensions/Interaction/ImageSlicePointPlacer.h>
2 #include <cpExtensions/Visualization/ImageSliceMapper.h>
3 #include <vtkBoundedPlanePointPlacer.h>
4 #include <vtkImageData.h>
5 #include <vtkImageMapper3D.h>
6 #include <vtkImageSlice.h>
7 #include <vtkPlane.h>
8
9 // -------------------------------------------------------------------------
10 vtkCxxSetObjectMacro(
11   cpExtensions::Interaction::ImageSlicePointPlacer, ImageSlice, vtkImageSlice
12   );
13
14 // -------------------------------------------------------------------------
15 cpExtensions::Interaction::ImageSlicePointPlacer::
16 Self* cpExtensions::Interaction::ImageSlicePointPlacer::
17 New( )
18 {
19   return( new Self( ) );
20 }
21
22 // -------------------------------------------------------------------------
23 int cpExtensions::Interaction::ImageSlicePointPlacer::
24 ComputeWorldPosition(
25   vtkRenderer* ren,
26   double displayPos[ 2 ],
27   double worldPos[ 3 ],
28   double worldOrient[ 9 ]
29   )
30 {
31   if( !this->UpdateInternalState( ) )
32     return( 0 );
33   return(
34     this->Placer->ComputeWorldPosition(
35       ren, displayPos, worldPos, worldOrient
36       )
37     );
38 }
39
40 // -------------------------------------------------------------------------
41 int cpExtensions::Interaction::ImageSlicePointPlacer::
42 ComputeWorldPosition(
43   vtkRenderer* ren,
44   double displayPos[ 2 ],
45   double refWorldPos[ 2 ],
46   double worldPos[ 3 ],
47   double worldOrient[ 9 ]
48   )
49 {
50   if( !this->UpdateInternalState( ) )
51     return( 0 );
52   return(
53     this->Placer->ComputeWorldPosition(
54       ren, displayPos, refWorldPos, worldPos, worldOrient
55       )
56     );
57 }
58
59 // -------------------------------------------------------------------------
60 int cpExtensions::Interaction::ImageSlicePointPlacer::
61 ValidateWorldPosition( double worldPos[ 3 ] )
62 {
63   if( !this->UpdateInternalState( ) )
64     return( 0 );
65   return( this->Placer->ValidateWorldPosition( worldPos ) );
66 }
67
68 // -------------------------------------------------------------------------
69 int cpExtensions::Interaction::ImageSlicePointPlacer::
70 ValidateWorldPosition( double worldPos[ 3 ], double worldOrient[ 9 ] )
71 {
72   if( !this->UpdateInternalState( ) )
73     return( 0 );
74   return( this->Placer->ValidateWorldPosition( worldPos, worldOrient ) );
75 }
76
77 // -------------------------------------------------------------------------
78 int cpExtensions::Interaction::ImageSlicePointPlacer::
79 UpdateWorldPosition(
80   vtkRenderer* ren, double worldPos[ 3 ], double worldOrient[ 9 ]
81   )
82 {
83   if( !this->UpdateInternalState( ) )
84     return( 0 );
85   return( this->Placer->UpdateWorldPosition( ren, worldPos, worldOrient ) );
86 }
87
88 // -------------------------------------------------------------------------
89 int cpExtensions::Interaction::ImageSlicePointPlacer::
90 UpdateInternalState( )
91 {
92   if( !this->ImageSlice )
93     return( 0 );
94
95   vtkImageData* input = this->ImageSlice->GetMapper( )->GetInput( );
96   if( !input )
97     return( 0 );
98
99   double spacing[ 3 ];
100   input->GetSpacing( spacing );
101
102   double origin[ 3 ];
103   input->GetOrigin( origin );
104
105   double b[ 6 ];
106   this->ImageSlice->GetBounds( b );
107   if( this->Bounds[ 0 ] != VTK_DOUBLE_MAX)
108   {
109     b[ 0 ] = ( b[ 0 ] < this->Bounds[ 0 ] )? this->Bounds[ 0 ] : b[ 0 ];
110     b[ 1 ] = ( b[ 1 ] > this->Bounds[ 1 ] )? this->Bounds[ 1 ] : b[ 1 ];
111     b[ 2 ] = ( b[ 2 ] < this->Bounds[ 2 ] )? this->Bounds[ 2 ] : b[ 2 ];
112     b[ 3 ] = ( b[ 3 ] > this->Bounds[ 3 ] )? this->Bounds[ 3 ] : b[ 3 ];
113     b[ 4 ] = ( b[ 4 ] < this->Bounds[ 4 ] )? this->Bounds[ 4 ] : b[ 4 ];
114     b[ 5 ] = ( b[ 5 ] > this->Bounds[ 5 ] )? this->Bounds[ 5 ] : b[ 5 ];
115
116   } // fi
117
118   int displayExtent[ 6 ] = { 0, 1, 0, 1, 0, 1 };
119   input->GetExtent( displayExtent );
120   auto mapper =
121     dynamic_cast< cpExtensions::Visualization::ImageSliceMapper* >(
122       this->ImageSlice->GetMapper( )
123       );
124   if( mapper != NULL )
125   {
126     auto ori = mapper->GetOrientation( );
127     displayExtent[ ( ori << 1 ) + 1 ] =
128       displayExtent[ ori << 1 ] =
129       mapper->GetSliceNumber( );
130
131   } // fi
132
133   int axis;
134   double position;
135   if( displayExtent[ 0 ] == displayExtent[ 1 ] )
136   {
137     axis = vtkBoundedPlanePointPlacer::XAxis;
138     position = origin[ 0 ] + displayExtent[ 0 ] * spacing[ 0 ];
139   }
140   else if( displayExtent[ 2 ] == displayExtent[ 3 ] )
141   {
142     axis = vtkBoundedPlanePointPlacer::YAxis;
143     position = origin[ 1 ] + displayExtent[ 2 ] * spacing[ 1 ];
144   }
145   else if( displayExtent[ 4 ] == displayExtent[ 5 ] )
146   {
147     axis = vtkBoundedPlanePointPlacer::ZAxis;
148     position = origin[ 2 ] + displayExtent[ 4 ] * spacing[ 2 ];
149   }
150   else
151   {
152     vtkErrorMacro( "Incorrect display extent in Image Slice" );
153     return( 0 );
154
155   } // fi
156
157   if(
158     axis != this->Placer->GetProjectionNormal( ) ||
159     position != this->Placer->GetProjectionPosition( ) ||
160     b[ 0 ] != this->SavedBounds[ 0 ] ||
161     b[ 1 ] != this->SavedBounds[ 1 ] ||
162     b[ 2 ] != this->SavedBounds[ 2 ] ||
163     b[ 3 ] != this->SavedBounds[ 3 ] ||
164     b[ 4 ] != this->SavedBounds[ 4 ] ||
165     b[ 5 ] != this->SavedBounds[ 5 ]
166     )
167   {
168     this->SavedBounds[ 0 ] = b[ 0 ];
169     this->SavedBounds[ 1 ] = b[ 1 ];
170     this->SavedBounds[ 2 ] = b[ 2 ];
171     this->SavedBounds[ 3 ] = b[ 3 ];
172     this->SavedBounds[ 4 ] = b[ 4 ];
173     this->SavedBounds[ 5 ] = b[ 5 ];
174
175     this->Placer->SetProjectionNormal( axis );
176     this->Placer->SetProjectionPosition( position );
177
178     this->Placer->RemoveAllBoundingPlanes( );
179
180     vtkPlane* plane;
181     if( axis != vtkBoundedPlanePointPlacer::XAxis )
182     {
183       plane = vtkPlane::New( );
184       plane->SetOrigin( b[ 0 ], b[ 2 ], b[ 4 ] );
185       plane->SetNormal( 1.0, 0.0, 0.0 );
186       this->Placer->AddBoundingPlane( plane );
187       plane->Delete( );
188
189       plane = vtkPlane::New();
190       plane->SetOrigin( b[ 1 ], b[ 3 ], b[ 5 ] );
191       plane->SetNormal( -1.0, 0.0, 0.0 );
192       this->Placer->AddBoundingPlane( plane );
193       plane->Delete( );
194
195     } // fi
196
197     if( axis != vtkBoundedPlanePointPlacer::YAxis )
198     {
199       plane = vtkPlane::New( );
200       plane->SetOrigin( b[ 0 ], b[ 2 ], b[ 4 ] );
201       plane->SetNormal( 0.0, 1.0, 0.0 );
202       this->Placer->AddBoundingPlane( plane );
203       plane->Delete( );
204
205       plane = vtkPlane::New( );
206       plane->SetOrigin( b[ 1 ], b[ 3 ], b[ 5 ] );
207       plane->SetNormal( 0.0, -1.0, 0.0 );
208       this->Placer->AddBoundingPlane( plane );
209       plane->Delete( );
210
211     } // fi
212
213     if( axis != vtkBoundedPlanePointPlacer::ZAxis )
214     {
215       plane = vtkPlane::New( );
216       plane->SetOrigin( b[ 0 ], b[ 2 ], b[ 4 ] );
217       plane->SetNormal( 0.0, 0.0, 1.0 );
218       this->Placer->AddBoundingPlane( plane );
219       plane->Delete( );
220
221       plane = vtkPlane::New( );
222       plane->SetOrigin( b[ 1 ], b[ 3 ], b[ 5 ] );
223       plane->SetNormal( 0.0, 0.0, -1.0 );
224       this->Placer->AddBoundingPlane( plane );
225       plane->Delete( );
226
227     } // fi
228
229     this->Modified( );
230
231   } // fi
232   return( 1 );
233 }
234
235 // -------------------------------------------------------------------------
236 void cpExtensions::Interaction::ImageSlicePointPlacer::
237 SetWorldTolerance( double tol )
238 {
239   double t =
240     ( tol < 0.0 )? 0.0: ( ( tol > VTK_DOUBLE_MAX )? VTK_DOUBLE_MAX: tol );
241   if( this->WorldTolerance != t )
242   {
243     this->WorldTolerance = t;
244     this->Placer->SetWorldTolerance( tol );
245     this->Modified( );
246
247   } // fi
248 }
249
250 // -------------------------------------------------------------------------
251 cpExtensions::Interaction::ImageSlicePointPlacer::
252 ImageSlicePointPlacer( )
253   : Superclass( )
254 {
255   this->Placer = vtkBoundedPlanePointPlacer::New( );
256   this->ImageSlice = NULL;
257   this->SavedBounds[ 0 ] = 0.0;
258   this->SavedBounds[ 1 ] = 0.0;
259   this->SavedBounds[ 2 ] = 0.0;
260   this->SavedBounds[ 3 ] = 0.0;
261   this->SavedBounds[ 4 ] = 0.0;
262   this->SavedBounds[ 5 ] = 0.0;
263   this->Bounds[ 0 ] = this->Bounds[ 2 ] = this->Bounds[ 4 ] = VTK_DOUBLE_MAX;
264   this->Bounds[ 1 ] = this->Bounds[ 3 ] = this->Bounds[ 5 ] = VTK_DOUBLE_MIN;
265 }
266
267 // -------------------------------------------------------------------------
268 cpExtensions::Interaction::ImageSlicePointPlacer::
269 ~ImageSlicePointPlacer( )
270 {
271   this->Placer->Delete( );
272   this->SetImageSlice( NULL );
273 }
274
275 // eof - $RCSfile$