1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkImageActorPointPlacer.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkImageActorPointPlacer.h"
16 #include "vtkObjectFactory.h"
17 #include "vtkBoundedPlanePointPlacer.h"
18 #include "vtkPlane.h"
19 #include "vtkRenderer.h"
20 #include "vtkImageActor.h"
21 #include "vtkImageData.h"
22 
23 vtkStandardNewMacro(vtkImageActorPointPlacer);
24 
25 vtkCxxSetObjectMacro(vtkImageActorPointPlacer, ImageActor, vtkImageActor);
26 
27 //----------------------------------------------------------------------
vtkImageActorPointPlacer()28 vtkImageActorPointPlacer::vtkImageActorPointPlacer()
29 {
30   this->Placer = vtkBoundedPlanePointPlacer::New();
31   this->ImageActor = NULL;
32   this->SavedBounds[0] = 0.0;
33   this->SavedBounds[1] = 0.0;
34   this->SavedBounds[2] = 0.0;
35   this->SavedBounds[3] = 0.0;
36   this->SavedBounds[4] = 0.0;
37   this->SavedBounds[5] = 0.0;
38   this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = VTK_DOUBLE_MAX;
39   this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = VTK_DOUBLE_MIN;
40 }
41 
42 //----------------------------------------------------------------------
~vtkImageActorPointPlacer()43 vtkImageActorPointPlacer::~vtkImageActorPointPlacer()
44 {
45   this->Placer->Delete();
46   this->SetImageActor(NULL);
47 }
48 
49 
50 //----------------------------------------------------------------------
ComputeWorldPosition(vtkRenderer * ren,double displayPos[2],double * refWorldPos,double worldPos[3],double worldOrient[9])51 int vtkImageActorPointPlacer::ComputeWorldPosition( vtkRenderer *ren,
52                                                     double  displayPos[2],
53                                                     double *refWorldPos,
54                                                     double  worldPos[3],
55                                                     double  worldOrient[9] )
56 {
57   if ( !this->UpdateInternalState() )
58     {
59     return 0;
60     }
61 
62   return this->Placer->ComputeWorldPosition( ren, displayPos,
63                                              refWorldPos, worldPos,
64                                              worldOrient );
65 }
66 
67 //----------------------------------------------------------------------
ComputeWorldPosition(vtkRenderer * ren,double displayPos[2],double worldPos[3],double worldOrient[9])68 int vtkImageActorPointPlacer::ComputeWorldPosition( vtkRenderer *ren,
69                                                     double displayPos[2],
70                                                     double worldPos[3],
71                                                     double worldOrient[9] )
72 {
73   if ( !this->UpdateInternalState() )
74     {
75     return 0;
76     }
77 
78   return this->Placer->ComputeWorldPosition( ren, displayPos, worldPos, worldOrient );
79 }
80 
81 //----------------------------------------------------------------------
ValidateWorldPosition(double worldPos[3],double * worldOrient)82 int vtkImageActorPointPlacer::ValidateWorldPosition( double worldPos[3],
83                                                      double *worldOrient )
84 {
85   if ( !this->UpdateInternalState() )
86     {
87     return 0;
88     }
89 
90   return this->Placer->ValidateWorldPosition( worldPos, worldOrient );
91 }
92 
93 //----------------------------------------------------------------------
ValidateWorldPosition(double worldPos[3])94 int vtkImageActorPointPlacer::ValidateWorldPosition( double worldPos[3] )
95 {
96   if ( !this->UpdateInternalState() )
97     {
98     return 0;
99     }
100 
101   return this->Placer->ValidateWorldPosition( worldPos );
102 }
103 
104 //----------------------------------------------------------------------
UpdateWorldPosition(vtkRenderer * ren,double worldPos[3],double worldOrient[9])105 int vtkImageActorPointPlacer::UpdateWorldPosition( vtkRenderer *ren,
106                                                    double worldPos[3],
107                                                    double worldOrient[9] )
108 {
109   if ( !this->UpdateInternalState() )
110     {
111     return 0;
112     }
113 
114   return this->Placer->UpdateWorldPosition( ren,
115                                             worldPos,
116                                             worldOrient );
117 }
118 
119 //----------------------------------------------------------------------
UpdateInternalState()120 int vtkImageActorPointPlacer::UpdateInternalState()
121 {
122   if ( !this->ImageActor )
123     {
124     return 0;
125     }
126 
127   vtkImageData *input;
128   input = this->ImageActor->GetInput();
129   if ( !input )
130     {
131     return 0;
132     }
133 
134   double spacing[3];
135   input->GetSpacing(spacing);
136 
137   double origin[3];
138   input->GetOrigin(origin);
139 
140   double bounds[6];
141   this->ImageActor->GetBounds(bounds);
142   if (this->Bounds[0] != VTK_DOUBLE_MAX)
143     {
144     bounds[0] = (bounds[0] < this->Bounds[0]) ? this->Bounds[0] : bounds[0];
145     bounds[1] = (bounds[1] > this->Bounds[1]) ? this->Bounds[1] : bounds[1];
146     bounds[2] = (bounds[2] < this->Bounds[2]) ? this->Bounds[2] : bounds[2];
147     bounds[3] = (bounds[3] > this->Bounds[3]) ? this->Bounds[3] : bounds[3];
148     bounds[4] = (bounds[4] < this->Bounds[4]) ? this->Bounds[4] : bounds[4];
149     bounds[5] = (bounds[5] > this->Bounds[5]) ? this->Bounds[5] : bounds[5];
150     }
151 
152   int displayExtent[6];
153   this->ImageActor->GetDisplayExtent(displayExtent);
154 
155   int axis;
156   double position;
157   if ( displayExtent[0] == displayExtent[1] )
158     {
159     axis = vtkBoundedPlanePointPlacer::XAxis;
160     position = origin[0] + displayExtent[0]*spacing[0];
161     }
162   else if ( displayExtent[2] == displayExtent[3] )
163     {
164     axis = vtkBoundedPlanePointPlacer::YAxis;
165     position = origin[1] + displayExtent[2]*spacing[1];
166     }
167   else if ( displayExtent[4] == displayExtent[5] )
168     {
169     axis = vtkBoundedPlanePointPlacer::ZAxis;
170     position = origin[2] + displayExtent[4]*spacing[2];
171     }
172   else
173     {
174     vtkErrorMacro("Incorrect display extent in Image Actor");
175     return 0;
176     }
177 
178   if ( axis != this->Placer->GetProjectionNormal() ||
179        position != this->Placer->GetProjectionPosition() ||
180        bounds[0] != this->SavedBounds[0] ||
181        bounds[1] != this->SavedBounds[1] ||
182        bounds[2] != this->SavedBounds[2] ||
183        bounds[3] != this->SavedBounds[3] ||
184        bounds[4] != this->SavedBounds[4] ||
185        bounds[5] != this->SavedBounds[5] )
186     {
187     this->SavedBounds[0] = bounds[0];
188     this->SavedBounds[1] = bounds[1];
189     this->SavedBounds[2] = bounds[2];
190     this->SavedBounds[3] = bounds[3];
191     this->SavedBounds[4] = bounds[4];
192     this->SavedBounds[5] = bounds[5];
193 
194     this->Placer->SetProjectionNormal(axis);
195     this->Placer->SetProjectionPosition(position);
196 
197     this->Placer->RemoveAllBoundingPlanes();
198 
199     vtkPlane *plane;
200 
201     if ( axis != vtkBoundedPlanePointPlacer::XAxis )
202       {
203       plane = vtkPlane::New();
204       plane->SetOrigin( bounds[0], bounds[2], bounds[4] );
205       plane->SetNormal( 1.0, 0.0, 0.0 );
206       this->Placer->AddBoundingPlane( plane );
207       plane->Delete();
208 
209       plane = vtkPlane::New();
210       plane->SetOrigin( bounds[1], bounds[3], bounds[5] );
211       plane->SetNormal( -1.0, 0.0, 0.0 );
212       this->Placer->AddBoundingPlane( plane );
213       plane->Delete();
214       }
215 
216     if ( axis != vtkBoundedPlanePointPlacer::YAxis )
217       {
218       plane = vtkPlane::New();
219       plane->SetOrigin( bounds[0], bounds[2], bounds[4] );
220       plane->SetNormal( 0.0, 1.0, 0.0 );
221       this->Placer->AddBoundingPlane( plane );
222       plane->Delete();
223 
224       plane = vtkPlane::New();
225       plane->SetOrigin( bounds[1], bounds[3], bounds[5] );
226       plane->SetNormal( 0.0, -1.0, 0.0 );
227       this->Placer->AddBoundingPlane( plane );
228       plane->Delete();
229       }
230 
231     if ( axis != vtkBoundedPlanePointPlacer::ZAxis )
232       {
233       plane = vtkPlane::New();
234       plane->SetOrigin( bounds[0], bounds[2], bounds[4] );
235       plane->SetNormal( 0.0, 0.0, 1.0 );
236       this->Placer->AddBoundingPlane( plane );
237       plane->Delete();
238 
239       plane = vtkPlane::New();
240       plane->SetOrigin( bounds[1], bounds[3], bounds[5] );
241       plane->SetNormal( 0.0, 0.0, -1.0 );
242       this->Placer->AddBoundingPlane( plane );
243       plane->Delete();
244       }
245 
246     this->Modified();
247     }
248 
249   return 1;
250 }
251 
252 //----------------------------------------------------------------------
SetWorldTolerance(double tol)253 void vtkImageActorPointPlacer::SetWorldTolerance( double tol )
254 {
255   if (this->WorldTolerance !=
256       (tol<0.0?0.0:(tol>VTK_DOUBLE_MAX?VTK_DOUBLE_MAX:tol)))
257     {
258     this->WorldTolerance =
259       (tol<0.0?0.0:(tol>VTK_DOUBLE_MAX?VTK_DOUBLE_MAX:tol));
260     this->Placer->SetWorldTolerance(tol);
261     this->Modified();
262     }
263 }
264 
265 //----------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)266 void vtkImageActorPointPlacer::PrintSelf(ostream& os, vtkIndent indent)
267 {
268   this->Superclass::PrintSelf(os,indent);
269 
270   double *bounds = this->GetBounds();
271   if ( bounds != NULL )
272     {
273     os << indent << "Bounds: \n";
274     os << indent << "  Xmin,Xmax: ("
275        << this->Bounds[0] << ", " << this->Bounds[1] << ")\n";
276     os << indent << "  Ymin,Ymax: ("
277        << this->Bounds[2] << ", " << this->Bounds[3] << ")\n";
278     os << indent << "  Zmin,Zmax: ("
279        << this->Bounds[4] << ", " << this->Bounds[5] << ")\n";
280     }
281   else
282     {
283     os << indent << "Bounds: (not defined)\n";
284     }
285 
286   os << indent << "Image Actor: " << this->ImageActor << "\n";
287 }
288 
289