1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkResliceCursor.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 "vtkResliceCursor.h"
16 #include "vtkCellArray.h"
17 #include "vtkImageData.h"
18 #include "vtkMath.h"
19 #include "vtkObjectFactory.h"
20 #include "vtkPlane.h"
21 #include "vtkPlaneCollection.h"
22 #include "vtkPoints.h"
23 #include "vtkPolyData.h"
24 #include "vtkSmartPointer.h"
25 
26 #include <cmath>
27 
28 //------------------------------------------------------------------------------
29 vtkStandardNewMacro(vtkResliceCursor);
30 vtkCxxSetObjectMacro(vtkResliceCursor, Image, vtkImageData);
31 
32 //------------------------------------------------------------------------------
vtkResliceCursor()33 vtkResliceCursor::vtkResliceCursor()
34 {
35   this->XAxis[0] = 1.0;
36   this->XAxis[1] = 0.0;
37   this->XAxis[2] = 0.0;
38 
39   this->YAxis[0] = 0.0;
40   this->YAxis[1] = 1.0;
41   this->YAxis[2] = 0.0;
42 
43   this->ZAxis[0] = 0.0;
44   this->ZAxis[1] = 0.0;
45   this->ZAxis[2] = 1.0;
46 
47   this->XViewUp[0] = 0.0;
48   this->XViewUp[1] = 0.0;
49   this->XViewUp[2] = 1.0;
50 
51   this->YViewUp[0] = 0.0;
52   this->YViewUp[1] = 0.0;
53   this->YViewUp[2] = 1.0;
54 
55   this->ZViewUp[0] = 0.0;
56   this->ZViewUp[1] = -1.0;
57   this->ZViewUp[2] = 0.0;
58 
59   this->Center[0] = 0.0;
60   this->Center[1] = 0.0;
61   this->Center[2] = 0.0;
62 
63   this->Thickness[0] = 0.0;
64   this->Thickness[1] = 0.0;
65   this->Thickness[2] = 0.0;
66 
67   this->HoleWidth = 5.0;
68   this->HoleWidthInPixels = 16.0;
69   this->Hole = 1;
70 
71   this->ThickMode = 1;
72 
73   this->Image = nullptr;
74 
75   this->PolyData = vtkPolyData::New();
76   vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
77   vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
78   this->PolyData->SetPoints(points);
79   this->PolyData->SetLines(lines);
80 
81   this->ReslicePlanes = vtkPlaneCollection::New();
82 
83   // Reslice planes along the X, Y and Z axes. And the centerline and slab
84   // polydata.
85 
86   for (int i = 0; i < 3; i++)
87   {
88     vtkSmartPointer<vtkPlane> plane = vtkSmartPointer<vtkPlane>::New();
89     this->ReslicePlanes->AddItem(plane);
90 
91     // Centerline polydata.
92 
93     this->CenterlineAxis[i] = vtkPolyData::New();
94 
95     vtkSmartPointer<vtkPoints> pointsc = vtkSmartPointer<vtkPoints>::New();
96     vtkSmartPointer<vtkCellArray> linesc = vtkSmartPointer<vtkCellArray>::New();
97 
98     this->CenterlineAxis[i]->SetPoints(pointsc);
99     this->CenterlineAxis[i]->SetLines(linesc);
100   }
101 
102   this->ReslicePlanes->GetItem(0)->SetNormal(1, 0, 0);
103   this->ReslicePlanes->GetItem(1)->SetNormal(0, -1, 0);
104   this->ReslicePlanes->GetItem(2)->SetNormal(0, 0, 1);
105 
106   this->BuildCursorTopology();
107 }
108 
109 //------------------------------------------------------------------------------
~vtkResliceCursor()110 vtkResliceCursor::~vtkResliceCursor()
111 {
112   this->SetImage(nullptr);
113   this->PolyData->Delete();
114   this->ReslicePlanes->Delete();
115 
116   for (int i = 0; i < 3; i++)
117   {
118     this->CenterlineAxis[i]->Delete();
119   }
120 }
121 
122 //------------------------------------------------------------------------------
BuildCursorTopology()123 void vtkResliceCursor::BuildCursorTopology()
124 {
125   if (this->Hole)
126   {
127     this->BuildCursorTopologyWithHole();
128   }
129   else
130   {
131     this->BuildCursorTopologyWithoutHole();
132   }
133 }
134 
135 //------------------------------------------------------------------------------
BuildCursorTopologyWithoutHole()136 void vtkResliceCursor::BuildCursorTopologyWithoutHole()
137 {
138   vtkIdType ptIds[2];
139 
140   for (int i = 0; i < 3; i++)
141   {
142     this->CenterlineAxis[i]->GetPoints()->SetNumberOfPoints(2);
143     this->CenterlineAxis[i]->GetLines()->Reset();
144 
145     ptIds[0] = 0;
146     ptIds[1] = 1;
147     this->CenterlineAxis[i]->GetLines()->InsertNextCell(2, ptIds);
148   }
149 }
150 
151 //------------------------------------------------------------------------------
BuildCursorTopologyWithHole()152 void vtkResliceCursor::BuildCursorTopologyWithHole()
153 {
154   vtkIdType ptIds[2];
155 
156   for (int i = 0; i < 3; i++)
157   {
158     this->CenterlineAxis[i]->GetPoints()->SetNumberOfPoints(4);
159     this->CenterlineAxis[i]->GetLines()->Reset();
160 
161     ptIds[0] = 0;
162     ptIds[1] = 1;
163     this->CenterlineAxis[i]->GetLines()->InsertNextCell(2, ptIds);
164     ptIds[0] = 2;
165     ptIds[1] = 3;
166     this->CenterlineAxis[i]->GetLines()->InsertNextCell(2, ptIds);
167   }
168 }
169 
170 //------------------------------------------------------------------------------
171 // Reset the cursor to the default position, ie with the axes, normal
172 // to each other and axis aligned and with the cursor pointed at the
173 // center of the image.
174 //
Reset()175 void vtkResliceCursor::Reset()
176 {
177   this->XAxis[0] = 1.0;
178   this->XAxis[1] = 0.0;
179   this->XAxis[2] = 0.0;
180 
181   this->YAxis[0] = 0.0;
182   this->YAxis[1] = 1.0;
183   this->YAxis[2] = 0.0;
184 
185   this->ZAxis[0] = 0.0;
186   this->ZAxis[1] = 0.0;
187   this->ZAxis[2] = 1.0;
188 
189   this->XViewUp[0] = 0.0;
190   this->XViewUp[1] = 0.0;
191   this->XViewUp[2] = 1.0;
192 
193   this->YViewUp[0] = 0.0;
194   this->YViewUp[1] = 0.0;
195   this->YViewUp[2] = 1.0;
196 
197   this->ZViewUp[0] = 0.0;
198   this->ZViewUp[1] = -1.0;
199   this->ZViewUp[2] = 0.0;
200 
201   if (this->GetImage())
202   {
203     this->GetImage()->GetCenter(this->Center);
204   }
205   else
206   {
207     this->Center[0] = 0.0;
208     this->Center[1] = 0.0;
209     this->Center[2] = 0.0;
210   }
211 
212   for (int i = 0; i < 3; i++)
213   {
214     this->GetPlane(i)->SetOrigin(this->Center);
215   }
216 
217   this->ReslicePlanes->GetItem(0)->SetNormal(1, 0, 0);
218   this->ReslicePlanes->GetItem(1)->SetNormal(0, -1, 0);
219   this->ReslicePlanes->GetItem(2)->SetNormal(0, 0, 1);
220 
221   this->BuildCursorTopology();
222   this->BuildCursorGeometry();
223 
224   this->Modified();
225 }
226 
227 //------------------------------------------------------------------------------
GetPlane(int i)228 vtkPlane* vtkResliceCursor::GetPlane(int i)
229 {
230   return this->ReslicePlanes->GetItem(i);
231 }
232 
233 //------------------------------------------------------------------------------
GetPolyData()234 vtkPolyData* vtkResliceCursor::GetPolyData()
235 {
236   this->Update();
237   return this->PolyData;
238 }
239 
240 //------------------------------------------------------------------------------
Update()241 void vtkResliceCursor::Update()
242 {
243   if (!this->Image)
244   {
245     vtkErrorMacro(<< "Image not set !");
246     return;
247   }
248 
249   if (this->GetMTime() > this->PolyDataBuildTime)
250   {
251     this->BuildCursorTopology();
252     this->BuildCursorGeometry();
253   }
254 }
255 
256 //------------------------------------------------------------------------------
ComputeAxes()257 void vtkResliceCursor::ComputeAxes()
258 {
259   double normals[3][3];
260   for (int i = 0; i < 3; i++)
261   {
262     this->GetPlane(i)->GetNormal(normals[i]);
263   }
264 
265   // The axes are the intersections of the plane normals.
266 
267   vtkMath::Cross(normals[0], normals[1], this->ZAxis);
268   vtkMath::Cross(normals[1], normals[2], this->XAxis);
269   vtkMath::Cross(normals[2], normals[0], this->YAxis);
270 }
271 
272 //------------------------------------------------------------------------------
BuildCursorGeometryWithHole()273 void vtkResliceCursor::BuildCursorGeometryWithHole()
274 {
275   this->ComputeAxes();
276 
277   double bounds[6];
278   this->Image->GetBounds(bounds);
279 
280   // Length of the principal diagonal.
281   const double pdLength = 20 * 0.5 *
282     sqrt((bounds[1] - bounds[0]) * (bounds[1] - bounds[0]) +
283       (bounds[3] - bounds[2]) * (bounds[3] - bounds[2]) +
284       (bounds[5] - bounds[4]) * (bounds[5] - bounds[4]));
285 
286   // Precompute prior to use within the loop.
287   const double holeHalfWidth = this->HoleWidth / 2.0;
288 
289   double pts[12][3];
290   for (int i = 0; i < 3; i++)
291   {
292     pts[0][i] = this->Center[i] - pdLength * this->XAxis[i];
293     pts[1][i] = this->Center[i] + pdLength * this->XAxis[i];
294     pts[2][i] = this->Center[i] - pdLength * this->YAxis[i];
295     pts[3][i] = this->Center[i] + pdLength * this->YAxis[i];
296     pts[4][i] = this->Center[i] - pdLength * this->ZAxis[i];
297     pts[5][i] = this->Center[i] + pdLength * this->ZAxis[i];
298 
299     // Break in the polydata to satisfy the hole
300 
301     pts[6][i] = this->Center[i] - holeHalfWidth * this->XAxis[i];
302     pts[7][i] = this->Center[i] + holeHalfWidth * this->XAxis[i];
303     pts[8][i] = this->Center[i] - holeHalfWidth * this->YAxis[i];
304     pts[9][i] = this->Center[i] + holeHalfWidth * this->YAxis[i];
305     pts[10][i] = this->Center[i] - holeHalfWidth * this->ZAxis[i];
306     pts[11][i] = this->Center[i] + holeHalfWidth * this->ZAxis[i];
307   }
308 
309   for (int j = 0; j < 3; j++)
310   {
311     vtkPoints* centerlinePoints = this->CenterlineAxis[j]->GetPoints();
312     centerlinePoints->SetPoint(0, pts[2 * j]);
313     centerlinePoints->SetPoint(1, pts[6 + 2 * j]);
314     centerlinePoints->SetPoint(2, pts[6 + 2 * j + 1]);
315     centerlinePoints->SetPoint(3, pts[2 * j + 1]);
316 
317     this->CenterlineAxis[j]->Modified();
318   }
319 
320   this->PolyDataBuildTime.Modified();
321 }
322 
323 //------------------------------------------------------------------------------
BuildCursorGeometryWithoutHole()324 void vtkResliceCursor::BuildCursorGeometryWithoutHole()
325 {
326   this->ComputeAxes();
327 
328   double bounds[6];
329   this->Image->GetBounds(bounds);
330 
331   // Length of the principal diagonal.
332   const double pdLength = 20 * 0.5 *
333     sqrt((bounds[1] - bounds[0]) * (bounds[1] - bounds[0]) +
334       (bounds[3] - bounds[2]) * (bounds[3] - bounds[2]) +
335       (bounds[5] - bounds[4]) * (bounds[5] - bounds[4]));
336 
337   // Precompute prior to use within the loop.
338   double pts[6][3];
339   for (int i = 0; i < 3; i++)
340   {
341     pts[0][i] = this->Center[i] - pdLength * this->XAxis[i];
342     pts[1][i] = this->Center[i] + pdLength * this->XAxis[i];
343     pts[2][i] = this->Center[i] - pdLength * this->YAxis[i];
344     pts[3][i] = this->Center[i] + pdLength * this->YAxis[i];
345     pts[4][i] = this->Center[i] - pdLength * this->ZAxis[i];
346     pts[5][i] = this->Center[i] + pdLength * this->ZAxis[i];
347   }
348 
349   for (int j = 0; j < 3; j++)
350   {
351     vtkPoints* centerlinePoints = this->CenterlineAxis[j]->GetPoints();
352     centerlinePoints->SetPoint(0, pts[2 * j]);
353     centerlinePoints->SetPoint(1, pts[2 * j + 1]);
354 
355     this->CenterlineAxis[j]->Modified();
356   }
357 
358   this->PolyDataBuildTime.Modified();
359 }
360 
361 //------------------------------------------------------------------------------
BuildCursorGeometry()362 void vtkResliceCursor::BuildCursorGeometry()
363 {
364   if (this->Hole)
365   {
366     this->BuildCursorGeometryWithHole();
367   }
368   else
369   {
370     this->BuildCursorGeometryWithoutHole();
371   }
372 }
373 
374 //------------------------------------------------------------------------------
BuildPolyData()375 void vtkResliceCursor::BuildPolyData()
376 {
377   this->ComputeAxes();
378 
379   double bounds[6];
380   this->Image->GetBounds(bounds);
381 
382   // Length of the principal diagonal.
383   const double pdLength = 20 * 0.5 *
384     sqrt((bounds[1] - bounds[0]) * (bounds[1] - bounds[0]) +
385       (bounds[3] - bounds[2]) * (bounds[3] - bounds[2]) +
386       (bounds[5] - bounds[4]) * (bounds[5] - bounds[4]));
387 
388   vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
389   vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
390 
391   // Precompute the half thickness prior to use within the loop.
392   const double ht[3] = { this->Thickness[0] / 2.0, this->Thickness[1] / 2.0,
393     this->Thickness[2] / 2.0 };
394 
395   points->Allocate(24);
396   lines->AllocateEstimate(18, 4);
397 
398   double pts[30][3];
399   for (int i = 0; i < 3; i++)
400   {
401     pts[0][i] = this->Center[i] - pdLength * this->XAxis[i];
402     pts[1][i] = this->Center[i] + pdLength * this->XAxis[i];
403     pts[2][i] = pts[0][i] - ht[1] * this->YAxis[i] - ht[2] * this->ZAxis[i];
404     pts[3][i] = pts[1][i] - ht[1] * this->YAxis[i] - ht[2] * this->ZAxis[i];
405     pts[4][i] = pts[0][i] + ht[1] * this->YAxis[i] - ht[2] * this->ZAxis[i];
406     pts[5][i] = pts[1][i] + ht[1] * this->YAxis[i] - ht[2] * this->ZAxis[i];
407     pts[6][i] = pts[0][i] + ht[1] * this->YAxis[i] + ht[2] * this->ZAxis[i];
408     pts[7][i] = pts[1][i] + ht[1] * this->YAxis[i] + ht[2] * this->ZAxis[i];
409     pts[8][i] = pts[0][i] - ht[1] * this->YAxis[i] + ht[2] * this->ZAxis[i];
410     pts[9][i] = pts[1][i] - ht[1] * this->YAxis[i] + ht[2] * this->ZAxis[i];
411 
412     pts[10][i] = this->Center[i] - pdLength * this->YAxis[i];
413     pts[11][i] = this->Center[i] + pdLength * this->YAxis[i];
414     pts[12][i] = pts[10][i] - ht[0] * this->XAxis[i] - ht[2] * this->ZAxis[i];
415     pts[13][i] = pts[11][i] - ht[0] * this->XAxis[i] - ht[2] * this->ZAxis[i];
416     pts[14][i] = pts[10][i] + ht[0] * this->XAxis[i] - ht[2] * this->ZAxis[i];
417     pts[15][i] = pts[11][i] + ht[0] * this->XAxis[i] - ht[2] * this->ZAxis[i];
418     pts[16][i] = pts[10][i] + ht[0] * this->XAxis[i] + ht[2] * this->ZAxis[i];
419     pts[17][i] = pts[11][i] + ht[0] * this->XAxis[i] + ht[2] * this->ZAxis[i];
420     pts[18][i] = pts[10][i] - ht[0] * this->XAxis[i] + ht[2] * this->ZAxis[i];
421     pts[19][i] = pts[11][i] - ht[0] * this->XAxis[i] + ht[2] * this->ZAxis[i];
422 
423     pts[20][i] = this->Center[i] - pdLength * this->ZAxis[i];
424     pts[21][i] = this->Center[i] + pdLength * this->ZAxis[i];
425     pts[22][i] = pts[20][i] - ht[1] * this->YAxis[i] - ht[0] * this->XAxis[i];
426     pts[23][i] = pts[21][i] - ht[1] * this->YAxis[i] - ht[0] * this->XAxis[i];
427     pts[24][i] = pts[20][i] + ht[1] * this->YAxis[i] - ht[0] * this->XAxis[i];
428     pts[25][i] = pts[21][i] + ht[1] * this->YAxis[i] - ht[0] * this->XAxis[i];
429     pts[26][i] = pts[20][i] + ht[1] * this->YAxis[i] + ht[0] * this->XAxis[i];
430     pts[27][i] = pts[21][i] + ht[1] * this->YAxis[i] + ht[0] * this->XAxis[i];
431     pts[28][i] = pts[20][i] - ht[1] * this->YAxis[i] + ht[0] * this->XAxis[i];
432     pts[29][i] = pts[21][i] - ht[1] * this->YAxis[i] + ht[0] * this->XAxis[i];
433   }
434 
435   vtkIdType ptIds[2];
436 
437   vtkIdType facePtIds[6][4] = { { 0, 2, 4, 6 }, { 1, 7, 5, 3 }, { 1, 3, 2, 0 }, { 0, 6, 7, 1 },
438     { 2, 3, 5, 4 }, { 6, 4, 5, 7 } };
439 
440   for (int j = 0; j < 3; j++)
441   {
442 
443     vtkPoints* centerlinePoints = this->CenterlineAxis[j]->GetPoints();
444 
445     for (int i = 0; i < 4; i++)
446     {
447       ptIds[0] = 10 * j + 2 + 2 * i;
448       ptIds[1] = ptIds[0] + 1;
449 
450       points->InsertNextPoint(pts[ptIds[0]]);
451       points->InsertNextPoint(pts[ptIds[1]]);
452     }
453 
454     centerlinePoints->SetPoint(0, pts[10 * j]);
455     centerlinePoints->SetPoint(1, pts[10 * j + 1]);
456 
457     vtkSmartPointer<vtkCellArray> slabPolys = vtkSmartPointer<vtkCellArray>::New();
458     slabPolys->AllocateEstimate(6, 4);
459 
460     for (int i = 0; i < 6; i++)
461     {
462       vtkIdType currFacePtIds[4] = { facePtIds[i][0] + 8 * j, facePtIds[i][1] + 8 * j,
463         facePtIds[i][2] + 8 * j, facePtIds[i][3] + 8 * j };
464       lines->InsertNextCell(4, currFacePtIds);
465       slabPolys->InsertNextCell(4, facePtIds[i]);
466     }
467 
468     this->CenterlineAxis[j]->Modified();
469   }
470 
471   this->PolyData->SetPolys(lines);
472 
473   this->PolyData->SetPoints(points);
474   this->PolyData->Modified();
475 
476   this->PolyDataBuildTime.Modified();
477 }
478 
479 //------------------------------------------------------------------------------
SetCenter(double _arg1,double _arg2,double _arg3)480 void vtkResliceCursor::SetCenter(double _arg1, double _arg2, double _arg3)
481 {
482   if ((this->Center[0] != _arg1) || (this->Center[1] != _arg2) || (this->Center[2] != _arg3))
483   {
484 
485     // Ensure that the center of the cursor lies within the image bounds.
486 
487     if (this->Image)
488     {
489       double bounds[6];
490       this->Image->GetBounds(bounds);
491       if (_arg1 < bounds[0] || _arg1 > bounds[1] || _arg2 < bounds[2] || _arg2 > bounds[3] ||
492         _arg3 < bounds[4] || _arg3 > bounds[5])
493       {
494         return;
495       }
496     }
497 
498     this->Center[0] = _arg1;
499     this->Center[1] = _arg2;
500     this->Center[2] = _arg3;
501     this->Modified();
502 
503     this->GetPlane(0)->SetOrigin(this->Center);
504     this->GetPlane(1)->SetOrigin(this->Center);
505     this->GetPlane(2)->SetOrigin(this->Center);
506   }
507 }
508 
509 //------------------------------------------------------------------------------
SetCenter(double _arg[3])510 void vtkResliceCursor::SetCenter(double _arg[3])
511 {
512   this->SetCenter(_arg[0], _arg[1], _arg[2]);
513 }
514 
515 //------------------------------------------------------------------------------
GetCenterlineAxisPolyData(int axis)516 vtkPolyData* vtkResliceCursor::GetCenterlineAxisPolyData(int axis)
517 {
518   this->Update();
519   return this->CenterlineAxis[axis];
520 }
521 
522 //------------------------------------------------------------------------------
GetAxis(int i)523 double* vtkResliceCursor::GetAxis(int i)
524 {
525   if (i == 0)
526   {
527     return this->XAxis;
528   }
529   else if (i == 1)
530   {
531     return this->YAxis;
532   }
533   else
534   {
535     return this->ZAxis;
536   }
537 }
538 
539 //------------------------------------------------------------------------------
GetViewUp(int i)540 double* vtkResliceCursor::GetViewUp(int i)
541 {
542   if (i == 0)
543   {
544     return this->XViewUp;
545   }
546   else if (i == 1)
547   {
548     return this->YViewUp;
549   }
550   else
551   {
552     return this->ZViewUp;
553   }
554 }
555 
556 //------------------------------------------------------------------------------
GetMTime()557 vtkMTimeType vtkResliceCursor::GetMTime()
558 {
559   vtkMTimeType mTime = this->Superclass::GetMTime();
560   for (int i = 0; i < 3; i++)
561   {
562     vtkMTimeType time = this->GetPlane(i)->GetMTime();
563     if (time > mTime)
564     {
565       mTime = time;
566     }
567   }
568 
569   return mTime;
570 }
571 
572 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)573 void vtkResliceCursor::PrintSelf(ostream& os, vtkIndent indent)
574 {
575   this->Superclass::PrintSelf(os, indent);
576 
577   os << indent << "Hole: ";
578   if (this->Hole)
579   {
580     os << indent << "On"
581        << "\n";
582   }
583   else
584   {
585     os << indent << "Off"
586        << "\n";
587   }
588   os << indent << "ThickMode: ";
589   if (this->ThickMode)
590   {
591     os << indent << "On"
592        << "\n";
593   }
594   else
595   {
596     os << indent << "Off"
597        << "\n";
598   }
599   os << indent << "HoleWidth: " << this->HoleWidth << endl;
600   os << indent << "HoleWidthInPixels: " << this->HoleWidthInPixels << endl;
601   os << indent << "Thickness: (" << this->Thickness[0] << "," << this->Thickness[1] << ","
602      << this->Thickness[2] << ")" << endl;
603   os << indent << "Center: (" << this->Center[0] << "," << this->Center[1] << this->Center[2]
604      << endl;
605   os << indent << "XAxis: (" << this->XAxis[0] << "," << this->XAxis[1] << this->XAxis[2] << endl;
606   os << indent << "YAxis: (" << this->YAxis[0] << "," << this->YAxis[1] << this->YAxis[2] << endl;
607   os << indent << "ZAxis: (" << this->ZAxis[0] << "," << this->ZAxis[1] << this->ZAxis[2] << endl;
608   os << indent << "XViewUp: (" << this->XViewUp[0] << "," << this->XViewUp[1] << this->XViewUp[2]
609      << endl;
610   os << indent << "YViewUp: (" << this->YViewUp[0] << "," << this->YViewUp[1] << this->YViewUp[2]
611      << endl;
612   os << indent << "ZViewUp: (" << this->ZViewUp[0] << "," << this->ZViewUp[1] << this->ZViewUp[2]
613      << endl;
614   os << indent << "Center: (" << this->Center[0] << "," << this->Center[1] << this->Center[2]
615      << endl;
616   os << indent << "Image: " << this->Image << "\n";
617   if (this->Image)
618   {
619     this->Image->PrintSelf(os, indent);
620   }
621   os << indent << "PolyData: " << this->PolyData << "\n";
622   if (this->PolyData)
623   {
624     this->PolyData->PrintSelf(os, indent);
625   }
626   os << indent << "ReslicePlanes: " << this->ReslicePlanes << "\n";
627   if (this->ReslicePlanes)
628   {
629     this->ReslicePlanes->PrintSelf(os, indent);
630   }
631 
632   // this->PolyDataBuildTime;
633   // this->CenterlineAxis[3];
634 }
635