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