1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkImageCroppingRegionsWidget.h
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 "vtkImageCroppingRegionsWidget.h"
16 #include "vtkObjectFactory.h"
17 #include "vtkActor2D.h"
18 #include "vtkCallbackCommand.h"
19 #include "vtkRenderer.h"
20 #include "vtkRenderWindow.h"
21 #include "vtkRenderWindowInteractor.h"
22 #include "vtkImageData.h"
23 #include "vtkLineSource.h"
24 #include "vtkPolyDataMapper2D.h"
25 #include "vtkPolyData.h"
26 #include "vtkCoordinate.h"
27 #include "vtkProperty2D.h"
28 #include "vtkCamera.h"
29 #include "vtkVolumeMapper.h"
30 #include "vtkImageCroppingRegionsWidget.h"
31 
32 vtkStandardNewMacro(vtkImageCroppingRegionsWidget);
33 
34 
35 //----------------------------------------------------------------------------
vtkImageCroppingRegionsWidget()36 vtkImageCroppingRegionsWidget::vtkImageCroppingRegionsWidget()
37 {
38   this->PlaceFactor = 1.0;
39 
40   int i;
41 
42   this->EventCallbackCommand->SetCallback(
43     vtkImageCroppingRegionsWidget::ProcessEvents);
44 
45   for (i = 0; i < 4; i++)
46   {
47     this->LineSources[i] = vtkLineSource::New();
48     this->LineActors[i] = vtkActor2D::New();
49     vtkPolyDataMapper2D *pdm = vtkPolyDataMapper2D::New();
50     vtkCoordinate *tcoord = vtkCoordinate::New();
51     tcoord->SetCoordinateSystemToWorld();
52     pdm->SetTransformCoordinate(tcoord);
53     tcoord->Delete();
54     this->LineActors[i]->SetMapper(pdm);
55     this->LineActors[i]->GetProperty()->SetColor(1, 1, 1);
56     pdm->SetInputConnection(
57       this->LineSources[i]->GetOutputPort());
58     pdm->Delete();
59   }
60 
61   vtkPoints *points = vtkPoints::New();
62   points->Allocate(16);
63   for (i = 0; i < 16; i++)
64   {
65     points->InsertNextPoint(0.0, 0.0, 0.0);
66   }
67 
68   for (i = 0; i < 9; i++)
69   {
70     this->RegionPolyData[i] = vtkPolyData::New();
71     this->RegionPolyData[i]->Allocate(1, 1);
72     this->RegionPolyData[i]->SetPoints(points);
73   }
74 
75   points->Delete();
76 
77   vtkIdType ptIds[4];
78 
79   ptIds[0] = 0; ptIds[1] = 1; ptIds[2] = 5; ptIds[3] = 4;
80   this->RegionPolyData[0]->InsertNextCell(VTK_QUAD, 4, ptIds);
81 
82   ptIds[0] = 1; ptIds[1] = 2; ptIds[2] = 6; ptIds[3] = 5;
83   this->RegionPolyData[1]->InsertNextCell(VTK_QUAD, 4, ptIds);
84 
85   ptIds[0] = 2; ptIds[1] = 3; ptIds[2] = 7; ptIds[3] = 6;
86   this->RegionPolyData[2]->InsertNextCell(VTK_QUAD, 4, ptIds);
87 
88   ptIds[0] = 4; ptIds[1] = 5; ptIds[2] = 9; ptIds[3] = 8;
89   this->RegionPolyData[3]->InsertNextCell(VTK_QUAD, 4, ptIds);
90 
91   ptIds[0] = 5; ptIds[1] = 6; ptIds[2] = 10; ptIds[3] = 9;
92   this->RegionPolyData[4]->InsertNextCell(VTK_QUAD, 4, ptIds);
93 
94   ptIds[0] = 6; ptIds[1] = 7; ptIds[2] = 11; ptIds[3] = 10;
95   this->RegionPolyData[5]->InsertNextCell(VTK_QUAD, 4, ptIds);
96 
97   ptIds[0] = 8; ptIds[1] = 9; ptIds[2] = 13; ptIds[3] = 12;
98   this->RegionPolyData[6]->InsertNextCell(VTK_QUAD, 4, ptIds);
99 
100   ptIds[0] = 9; ptIds[1] = 10; ptIds[2] = 14; ptIds[3] = 13;
101   this->RegionPolyData[7]->InsertNextCell(VTK_QUAD, 4, ptIds);
102 
103   ptIds[0] = 10; ptIds[1] = 11; ptIds[2] = 15; ptIds[3] = 14;
104   this->RegionPolyData[8]->InsertNextCell(VTK_QUAD, 4, ptIds);
105 
106   for (i = 0; i < 9; i++)
107   {
108     vtkPolyDataMapper2D *pdm = vtkPolyDataMapper2D::New();
109     vtkCoordinate *tcoord = vtkCoordinate::New();
110     tcoord->SetCoordinateSystemToWorld();
111     pdm->SetTransformCoordinate(tcoord);
112     tcoord->Delete();
113 
114     this->RegionActors[i] = vtkActor2D::New();
115     this->RegionActors[i]->SetMapper(pdm);
116     this->RegionActors[i]->GetProperty()->SetColor(1, 1, 1);
117     this->RegionActors[i]->GetProperty()->SetOpacity(0.0);
118 
119     pdm->SetInputData(this->RegionPolyData[i]);
120     pdm->Delete();
121   }
122 
123   this->SliceOrientation = vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XY;
124   this->Slice = 0;
125   this->MouseCursorState = vtkImageCroppingRegionsWidget::NoLine;
126 
127   this->Moving = 0;
128   this->CroppingRegionFlags = 0;
129   this->VolumeMapper = nullptr;
130 
131   for (i = 0; i < 6; i += 2)
132   {
133     this->InitialBounds[i] = this->PlanePositions[i] = 0;
134     this->InitialBounds[i + 1] = this->PlanePositions[i + 1] = 1;
135   }
136 }
137 
138 //----------------------------------------------------------------------------
~vtkImageCroppingRegionsWidget()139 vtkImageCroppingRegionsWidget::~vtkImageCroppingRegionsWidget()
140 {
141   int i;
142 
143   for (i = 0; i < 4; i++)
144   {
145     this->LineSources[i]->Delete();
146     this->LineSources[i] = nullptr;
147     this->LineActors[i]->Delete();
148     this->LineActors[i] = nullptr;
149   }
150 
151   for (i = 0; i < 9; i++)
152   {
153     this->RegionPolyData[i]->Delete();
154     this->RegionPolyData[i]= nullptr;
155     this->RegionActors[i]->Delete();
156     this->RegionActors[i] = nullptr;
157   }
158 
159   this->SetVolumeMapper(nullptr);
160 }
161 
162 //----------------------------------------------------------------------------
SetCroppingRegionFlags(int flags)163 void vtkImageCroppingRegionsWidget::SetCroppingRegionFlags(int flags)
164 {
165   if (this->CroppingRegionFlags == flags ||
166       flags < 0x0 || flags > 0x7ffffff)
167   {
168     return;
169   }
170 
171   this->CroppingRegionFlags = flags;
172   this->Modified();
173 
174   this->UpdateOpacity();
175 }
176 
177 //----------------------------------------------------------------------------
GetSlicePosition()178 double vtkImageCroppingRegionsWidget::GetSlicePosition()
179 {
180   if (!this->VolumeMapper || !this->VolumeMapper->GetInput())
181   {
182     return 0.0;
183   }
184 
185   double *origin = this->VolumeMapper->GetInput()->GetOrigin();
186   double *spacing = this->VolumeMapper->GetInput()->GetSpacing();
187 
188   return (double)origin[this->SliceOrientation] +
189     ((double)this->Slice) * (double)spacing[this->SliceOrientation];
190 }
191 
192 //----------------------------------------------------------------------------
UpdateOpacity()193 void vtkImageCroppingRegionsWidget::UpdateOpacity()
194 {
195   if (!this->VolumeMapper || !this->VolumeMapper->GetInput())
196   {
197     return;
198   }
199 
200   static const int indices[][9] = {{ 0,  9, 18,  3, 12, 21,  6, 15, 24},
201                                    { 1, 10, 19,  4, 13, 22,  7, 16, 25},
202                                    { 2, 11, 20,  5, 14, 23,  8, 17, 26},
203                                    { 0,  1,  2,  9, 10, 11, 18, 19, 20},
204                                    { 3,  4,  5, 12, 13, 14, 21, 22, 23},
205                                    { 6,  7,  8, 15, 16, 17, 24, 25, 26},
206                                    { 0,  1,  2,  3,  4,  5,  6,  7,  8},
207                                    { 9, 10, 11, 12, 13, 14, 15, 16, 17},
208                                    {18, 19, 20, 21, 22, 23, 24, 25, 26}};
209 
210   double slice_pos = this->GetSlicePosition();
211 
212   int sliceId = this->SliceOrientation * 3;
213   if (slice_pos >= this->PlanePositions[this->SliceOrientation * 2] &&
214       slice_pos <= this->PlanePositions[this->SliceOrientation * 2 + 1])
215   {
216     sliceId += 1;
217   }
218   else if (slice_pos > this->PlanePositions[this->SliceOrientation * 2 + 1])
219   {
220     sliceId += 2;
221   }
222 
223   int compare = 1;
224   int i;
225   for (i = 0; i < 9; i++)
226   {
227     if ((compare << indices[sliceId][i]) & this->CroppingRegionFlags)
228     {
229       this->RegionActors[i]->GetProperty()->SetOpacity(0.0);
230     }
231     else
232     {
233       this->RegionActors[i]->GetProperty()->SetOpacity(0.3);
234     }
235   }
236 }
237 
238 //----------------------------------------------------------------------------
SetPlanePositions(double xMin,double xMax,double yMin,double yMax,double zMin,double zMax)239 void vtkImageCroppingRegionsWidget::SetPlanePositions(double xMin, double xMax,
240                                                    double yMin, double yMax,
241                                                    double zMin, double zMax)
242 {
243   double positions[6];
244   positions[0] = xMin;
245   positions[1] = xMax;
246   positions[2] = yMin;
247   positions[3] = yMax;
248   positions[4] = zMin;
249   positions[5] = zMax;
250 
251   this->ConstrainPlanePositions(positions);
252 
253   if (this->PlanePositions[0] == positions[0] &&
254       this->PlanePositions[1] == positions[1] &&
255       this->PlanePositions[2] == positions[2] &&
256       this->PlanePositions[3] == positions[3] &&
257       this->PlanePositions[4] == positions[4] &&
258       this->PlanePositions[5] == positions[5])
259   {
260     return;
261   }
262 
263   int i;
264   for (i = 0; i < 6; i++)
265   {
266     this->PlanePositions[i] = positions[i];
267   }
268 
269   this->VolumeMapper->SetCroppingRegionPlanes(this->PlanePositions);
270   this->UpdateGeometry();
271 }
272 
273 //----------------------------------------------------------------------------
ConstrainPlanePositions(double positions[6])274 void vtkImageCroppingRegionsWidget::ConstrainPlanePositions(double positions[6])
275 {
276   int i;
277   double tmp;
278 
279   for (i = 0; i < 6; i += 2)
280   {
281     if (positions[i] > positions[i + 1])
282     {
283       tmp = positions[i];
284       positions[i] = positions[i + 1];
285       positions[i + 1] = tmp;
286     }
287     if (positions[i] < this->InitialBounds[i] ||
288         positions[i] > this->InitialBounds[i + 1])
289     {
290       positions[i] = this->InitialBounds[i];
291     }
292     if (positions[i + 1] < this->InitialBounds[i] ||
293         positions[i + 1] > this->InitialBounds[i + 1])
294     {
295       positions[i + 1] = this->InitialBounds[i + 1];
296     }
297   }
298 }
299 
300 //----------------------------------------------------------------------------
UpdateGeometry()301 void vtkImageCroppingRegionsWidget::UpdateGeometry()
302 {
303   if (!this->VolumeMapper || !this->VolumeMapper->GetInput())
304   {
305     return;
306   }
307 
308   // Could use any of the 9 region poly data because they share points
309 
310   vtkPoints *points = this->RegionPolyData[0]->GetPoints();
311 
312   double slice_pos = this->GetSlicePosition();
313   double *plane_pos = this->PlanePositions;
314   double *bounds = this->InitialBounds;
315 
316   switch (this->SliceOrientation)
317   {
318     case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_YZ:
319       this->LineSources[0]->SetPoint1(slice_pos, plane_pos[2], bounds[4]);
320       this->LineSources[0]->SetPoint2(slice_pos, plane_pos[2], bounds[5]);
321       this->LineSources[1]->SetPoint1(slice_pos, plane_pos[3], bounds[4]);
322       this->LineSources[1]->SetPoint2(slice_pos, plane_pos[3], bounds[5]);
323       this->LineSources[2]->SetPoint1(slice_pos, bounds[2], plane_pos[4]);
324       this->LineSources[2]->SetPoint2(slice_pos, bounds[3], plane_pos[4]);
325       this->LineSources[3]->SetPoint1(slice_pos, bounds[2], plane_pos[5]);
326       this->LineSources[3]->SetPoint2(slice_pos, bounds[3], plane_pos[5]);
327 
328       points->SetPoint(0, slice_pos, bounds[2], bounds[4]);
329       points->SetPoint(1, slice_pos, plane_pos[2], bounds[4]);
330       points->SetPoint(2, slice_pos, plane_pos[3], bounds[4]);
331       points->SetPoint(3, slice_pos, bounds[3], bounds[4]);
332       points->SetPoint(4, slice_pos, bounds[2], plane_pos[4]);
333       points->SetPoint(5, slice_pos, plane_pos[2], plane_pos[4]);
334       points->SetPoint(6, slice_pos, plane_pos[3], plane_pos[4]);
335       points->SetPoint(7, slice_pos, bounds[3], plane_pos[4]);
336       points->SetPoint(8, slice_pos, bounds[2],plane_pos[5]);
337       points->SetPoint(9, slice_pos, plane_pos[2], plane_pos[5]);
338       points->SetPoint(10, slice_pos, plane_pos[3], plane_pos[5]);
339       points->SetPoint(11, slice_pos, bounds[3], plane_pos[5]);
340       points->SetPoint(12, slice_pos, bounds[2], bounds[5]);
341       points->SetPoint(13, slice_pos, plane_pos[2], bounds[5]);
342       points->SetPoint(14, slice_pos, plane_pos[3], bounds[5]);
343       points->SetPoint(15, slice_pos, bounds[3], bounds[5]);
344       break;
345 
346     case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XZ:
347       this->LineSources[0]->SetPoint1(plane_pos[0], slice_pos, bounds[4]);
348       this->LineSources[0]->SetPoint2(plane_pos[0], slice_pos, bounds[5]);
349       this->LineSources[1]->SetPoint1(plane_pos[1], slice_pos, bounds[4]);
350       this->LineSources[1]->SetPoint2(plane_pos[1], slice_pos, bounds[5]);
351       this->LineSources[2]->SetPoint1(bounds[0], slice_pos, plane_pos[4]);
352       this->LineSources[2]->SetPoint2(bounds[1], slice_pos, plane_pos[4]);
353       this->LineSources[3]->SetPoint1(bounds[0], slice_pos, plane_pos[5]);
354       this->LineSources[3]->SetPoint2(bounds[1], slice_pos, plane_pos[5]);
355 
356       points->SetPoint(0, bounds[0], slice_pos, bounds[4]);
357       points->SetPoint(1, plane_pos[0], slice_pos, bounds[4]);
358       points->SetPoint(2, plane_pos[1], slice_pos, bounds[4]);
359       points->SetPoint(3, bounds[1], slice_pos, bounds[4]);
360       points->SetPoint(4, bounds[0], slice_pos, plane_pos[4]);
361       points->SetPoint(5, plane_pos[0], slice_pos, plane_pos[4]);
362       points->SetPoint(6, plane_pos[1], slice_pos, plane_pos[4]);
363       points->SetPoint(7, bounds[1], slice_pos, plane_pos[4]);
364       points->SetPoint(8, bounds[0], slice_pos, plane_pos[5]);
365       points->SetPoint(9, plane_pos[0], slice_pos, plane_pos[5]);
366       points->SetPoint(10, plane_pos[1], slice_pos, plane_pos[5]);
367       points->SetPoint(11, bounds[1], slice_pos, plane_pos[5]);
368       points->SetPoint(12, bounds[0], slice_pos, bounds[5]);
369       points->SetPoint(13, plane_pos[0], slice_pos, bounds[5]);
370       points->SetPoint(14, plane_pos[1], slice_pos, bounds[5]);
371       points->SetPoint(15, bounds[1], slice_pos, bounds[5]);
372       break;
373 
374     case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XY:
375       this->LineSources[0]->SetPoint1(plane_pos[0], bounds[2], slice_pos);
376       this->LineSources[0]->SetPoint2(plane_pos[0], bounds[3], slice_pos);
377       this->LineSources[1]->SetPoint1(plane_pos[1], bounds[2], slice_pos);
378       this->LineSources[1]->SetPoint2(plane_pos[1], bounds[3], slice_pos);
379       this->LineSources[2]->SetPoint1(bounds[0], plane_pos[2], slice_pos);
380       this->LineSources[2]->SetPoint2(bounds[1], plane_pos[2], slice_pos);
381       this->LineSources[3]->SetPoint1(bounds[0], plane_pos[3], slice_pos);
382       this->LineSources[3]->SetPoint2(bounds[1], plane_pos[3], slice_pos);
383 
384       points->SetPoint(0, bounds[0], bounds[2], slice_pos);
385       points->SetPoint(1, plane_pos[0], bounds[2], slice_pos);
386       points->SetPoint(2, plane_pos[1], bounds[2], slice_pos);
387       points->SetPoint(3, bounds[1], bounds[2], slice_pos);
388       points->SetPoint(4, bounds[0], plane_pos[2], slice_pos);
389       points->SetPoint(5, plane_pos[0], plane_pos[2], slice_pos);
390       points->SetPoint(6, plane_pos[1], plane_pos[2], slice_pos);
391       points->SetPoint(7, bounds[1], plane_pos[2], slice_pos);
392       points->SetPoint(8, bounds[0], plane_pos[3], slice_pos);
393       points->SetPoint(9, plane_pos[0], plane_pos[3], slice_pos);
394       points->SetPoint(10, plane_pos[1], plane_pos[3], slice_pos);
395       points->SetPoint(11, bounds[1], plane_pos[3], slice_pos);
396       points->SetPoint(12, bounds[0], bounds[3], slice_pos);
397       points->SetPoint(13, plane_pos[0], bounds[3], slice_pos);
398       points->SetPoint(14, plane_pos[1], bounds[3], slice_pos);
399       points->SetPoint(15, bounds[1], bounds[3], slice_pos);
400       break;
401   }
402 
403   this->UpdateOpacity();
404 }
405 
406 //----------------------------------------------------------------------------
SetEnabled(int enabling)407 void vtkImageCroppingRegionsWidget::SetEnabled(int enabling)
408 {
409   if (!this->Interactor)
410   {
411     vtkErrorMacro(
412       <<"The interactor must be set prior to enabling/disabling widget");
413     return;
414   }
415 
416   if (this->Enabled == enabling)
417   {
418     return;
419   }
420 
421   int count;
422   if (enabling)
423   {
424     this->SetCurrentRenderer(
425       this->Interactor->FindPokedRenderer(
426         this->Interactor->GetLastEventPosition()[0],
427         this->Interactor->GetLastEventPosition()[1]));
428     if (this->CurrentRenderer == nullptr)
429     {
430       return;
431     }
432 
433     this->Enabled = 1;
434 
435     // Listen for the following events
436 
437     vtkRenderWindowInteractor *i = this->Interactor;
438     i->AddObserver(vtkCommand::MouseMoveEvent,
439                    this->EventCallbackCommand, this->Priority);
440     i->AddObserver(vtkCommand::LeftButtonPressEvent,
441                    this->EventCallbackCommand, this->Priority);
442     i->AddObserver(vtkCommand::LeftButtonReleaseEvent,
443                    this->EventCallbackCommand, this->Priority);
444     i->AddObserver(vtkCommand::MiddleButtonPressEvent,
445                    this->EventCallbackCommand, this->Priority);
446     i->AddObserver(vtkCommand::MiddleButtonReleaseEvent,
447                    this->EventCallbackCommand, this->Priority);
448     i->AddObserver(vtkCommand::RightButtonPressEvent,
449                    this->EventCallbackCommand, this->Priority);
450     i->AddObserver(vtkCommand::RightButtonReleaseEvent,
451                    this->EventCallbackCommand, this->Priority);
452 
453     // Add the cropping regions
454 
455     this->CurrentRenderer->AddViewProp(this->LineActors[0]);
456     this->CurrentRenderer->AddViewProp(this->LineActors[1]);
457     this->CurrentRenderer->AddViewProp(this->LineActors[2]);
458     this->CurrentRenderer->AddViewProp(this->LineActors[3]);
459     for (count = 0; count < 9; count++)
460     {
461       this->CurrentRenderer->AddViewProp(this->RegionActors[count]);
462     }
463 
464     this->InvokeEvent(vtkCommand::EnableEvent,nullptr);
465   }
466   else
467   {
468     this->Enabled = 0;
469 
470     // Don't listen for events any more
471 
472     this->Interactor->RemoveObserver(this->EventCallbackCommand);
473 
474     // Turn off the cropping regions
475 
476     if (this->CurrentRenderer)
477     {
478       this->CurrentRenderer->RemoveActor(this->LineActors[0]);
479       this->CurrentRenderer->RemoveActor(this->LineActors[1]);
480       this->CurrentRenderer->RemoveActor(this->LineActors[2]);
481       this->CurrentRenderer->RemoveActor(this->LineActors[3]);
482       for (count = 0; count < 9; count++)
483       {
484         this->CurrentRenderer->RemoveActor(this->RegionActors[count]);
485       }
486     }
487 
488     this->InvokeEvent(vtkCommand::DisableEvent,nullptr);
489   }
490 
491   this->Interactor->Render();
492 }
493 
494 //----------------------------------------------------------------------------
ProcessEvents(vtkObject * vtkNotUsed (object),unsigned long event,void * clientdata,void * vtkNotUsed (calldata))495 void vtkImageCroppingRegionsWidget::ProcessEvents(vtkObject* vtkNotUsed(object),
496                                                unsigned long event,
497                                                void* clientdata,
498                                                void* vtkNotUsed(calldata))
499 {
500   vtkImageCroppingRegionsWidget* self =
501     reinterpret_cast<vtkImageCroppingRegionsWidget *>(clientdata);
502 
503   switch (event)
504   {
505     case vtkCommand::LeftButtonPressEvent:
506     case vtkCommand::MiddleButtonPressEvent:
507     case vtkCommand::RightButtonPressEvent:
508       self->OnButtonPress();
509       break;
510     case vtkCommand::MouseMoveEvent:
511       self->OnMouseMove();
512       break;
513     case vtkCommand::LeftButtonReleaseEvent:
514     case vtkCommand::MiddleButtonReleaseEvent:
515     case vtkCommand::RightButtonReleaseEvent:
516       self->OnButtonRelease();
517       break;
518   }
519 }
520 
521 //----------------------------------------------------------------------------
OnButtonPress()522 void vtkImageCroppingRegionsWidget::OnButtonPress()
523 {
524   if (this->MouseCursorState == vtkImageCroppingRegionsWidget::NoLine)
525   {
526     return;
527   }
528 
529   this->Moving = 1;
530   this->EventCallbackCommand->SetAbortFlag(1);
531   this->StartInteraction();
532   this->InvokeEvent(vtkCommand::StartInteractionEvent, nullptr);
533   this->Interactor->Render();
534 }
535 
536 //----------------------------------------------------------------------------
OnButtonRelease()537 void vtkImageCroppingRegionsWidget::OnButtonRelease()
538 {
539   if (this->MouseCursorState == vtkImageCroppingRegionsWidget::NoLine)
540   {
541     return;
542   }
543 
544   this->Moving = 0;
545   this->EventCallbackCommand->SetAbortFlag(1);
546   this->EndInteraction();
547   this->InvokeEvent(vtkCommand::EndInteractionEvent, nullptr);
548 
549   this->MouseCursorState = vtkImageCroppingRegionsWidget::NoLine;
550   this->SetMouseCursor(this->MouseCursorState);
551 
552   this->Interactor->Render();
553 }
554 
555 //----------------------------------------------------------------------------
OnMouseMove()556 void vtkImageCroppingRegionsWidget::OnMouseMove()
557 {
558   if (this->Moving)
559   {
560     switch (this->MouseCursorState)
561     {
562       case vtkImageCroppingRegionsWidget::MovingH1:
563       case vtkImageCroppingRegionsWidget::MovingH2:
564         this->MoveHorizontalLine();
565         break;
566       case vtkImageCroppingRegionsWidget::MovingV1:
567       case vtkImageCroppingRegionsWidget::MovingV2:
568         this->MoveVerticalLine();
569         break;
570       case vtkImageCroppingRegionsWidget::MovingH1AndV1:
571       case vtkImageCroppingRegionsWidget::MovingH2AndV1:
572       case vtkImageCroppingRegionsWidget::MovingH1AndV2:
573       case vtkImageCroppingRegionsWidget::MovingH2AndV2:
574         this->MoveIntersectingLines();
575         break;
576     }
577     this->UpdateCursorIcon();
578     this->EventCallbackCommand->SetAbortFlag(1);
579     this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
580   }
581   else
582   {
583     this->UpdateCursorIcon();
584   }
585 }
586 
587 //----------------------------------------------------------------------------
MoveHorizontalLine()588 void vtkImageCroppingRegionsWidget::MoveHorizontalLine()
589 {
590   double newPosition[3];
591   float planes[6];
592   int i;
593 
594   for (i = 0; i < 6; i++)
595   {
596     planes[i] = this->PlanePositions[i];
597   }
598 
599   int x = this->Interactor->GetEventPosition()[0];
600   int y = this->Interactor->GetEventPosition()[1];
601 
602   if (!this->ComputeWorldCoordinate(x, y, newPosition))
603   {
604     return;
605   }
606 
607   if (this->MouseCursorState == vtkImageCroppingRegionsWidget::MovingH1)
608   {
609     switch (this->SliceOrientation)
610     {
611       case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_YZ:
612       case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XZ:
613         if (newPosition[2] < planes[5])
614         {
615           planes[4] = newPosition[2];
616         }
617         break;
618       case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XY:
619         if (newPosition[1] < planes[3])
620         {
621           planes[2] = newPosition[1];
622         }
623         break;
624     }
625 
626     this->SetPlanePositions(planes);
627     this->InvokeEvent(
628       vtkImageCroppingRegionsWidget::CroppingPlanesPositionChangedEvent, planes);
629     this->EventCallbackCommand->SetAbortFlag(1);
630     this->Interactor->Render();
631   }
632   else if (this->MouseCursorState == vtkImageCroppingRegionsWidget::MovingH2)
633   {
634     switch (this->SliceOrientation)
635     {
636       case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_YZ:
637       case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XZ:
638         if (newPosition[2] > planes[4])
639         {
640           planes[5] = newPosition[2];
641         }
642         break;
643       case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XY:
644         if (newPosition[1] > planes[2])
645         {
646           planes[3] = newPosition[1];
647         }
648         break;
649     }
650     this->SetPlanePositions(planes);
651     this->InvokeEvent(
652       vtkImageCroppingRegionsWidget::CroppingPlanesPositionChangedEvent, planes);
653     this->EventCallbackCommand->SetAbortFlag(1);
654     this->Interactor->Render();
655   }
656 }
657 
658 //----------------------------------------------------------------------------
MoveVerticalLine()659 void vtkImageCroppingRegionsWidget::MoveVerticalLine()
660 {
661   double newPosition[3];
662   float planes[6];
663   int i;
664 
665   for (i = 0; i < 6; i++)
666   {
667     planes[i] = this->PlanePositions[i];
668   }
669 
670   int x = this->Interactor->GetEventPosition()[0];
671   int y = this->Interactor->GetEventPosition()[1];
672 
673   if (!this->ComputeWorldCoordinate(x, y, newPosition))
674   {
675     return;
676   }
677 
678   if (this->MouseCursorState == vtkImageCroppingRegionsWidget::MovingV1)
679   {
680     switch (this->SliceOrientation)
681     {
682       case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_YZ:
683         if (newPosition[1] < planes[3])
684         {
685           planes[2] = newPosition[1];
686         }
687         break;
688       case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XZ:
689       case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XY:
690         if (newPosition[0] < planes[1])
691         {
692           planes[0] = newPosition[0];
693         }
694         break;
695     }
696     this->SetPlanePositions(planes);
697     this->InvokeEvent(
698       vtkImageCroppingRegionsWidget::CroppingPlanesPositionChangedEvent, planes);
699     this->EventCallbackCommand->SetAbortFlag(1);
700     this->Interactor->Render();
701   }
702   else if (this->MouseCursorState == vtkImageCroppingRegionsWidget::MovingV2)
703   {
704     switch (this->SliceOrientation)
705     {
706       case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_YZ:
707         if (newPosition[1] > planes[2])
708         {
709           planes[3] = newPosition[1];
710         }
711         break;
712       case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XZ:
713       case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XY:
714         if (newPosition[0] > planes[0])
715         {
716           planes[1] = newPosition[0];
717         }
718         break;
719     }
720 
721     this->SetPlanePositions(planes);
722     this->InvokeEvent(
723       vtkImageCroppingRegionsWidget::CroppingPlanesPositionChangedEvent, planes);
724     this->EventCallbackCommand->SetAbortFlag(1);
725     this->Interactor->Render();
726   }
727 }
728 
729 //----------------------------------------------------------------------------
MoveIntersectingLines()730 void vtkImageCroppingRegionsWidget::MoveIntersectingLines()
731 {
732   double newPosition[3];
733   float planes[6];
734   int i;
735 
736   for (i = 0; i < 6; i++)
737   {
738     planes[i] = this->PlanePositions[i];
739   }
740 
741   int x = this->Interactor->GetEventPosition()[0];
742   int y = this->Interactor->GetEventPosition()[1];
743 
744   if (!this->ComputeWorldCoordinate(x, y, newPosition))
745   {
746     return;
747   }
748 
749   switch (this->MouseCursorState)
750   {
751     case vtkImageCroppingRegionsWidget::MovingH1AndV1:
752       switch (this->SliceOrientation)
753       {
754         case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_YZ:
755           if (newPosition[1] < planes[3])
756           {
757             planes[2] = newPosition[1];
758           }
759           if (newPosition[2] < planes[5])
760           {
761             planes[4] = newPosition[2];
762           }
763           break;
764         case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XZ:
765           if (newPosition[0] < planes[1])
766           {
767             planes[0] = newPosition[0];
768           }
769           if (newPosition[2] < planes[5])
770           {
771             planes[4] = newPosition[2];
772           }
773           break;
774         case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XY:
775           if (newPosition[0] < planes[1])
776           {
777             planes[0] = newPosition[0];
778           }
779           if (newPosition[1] < planes[3])
780           {
781             planes[2] = newPosition[1];
782           }
783           break;
784       }
785 
786       this->SetPlanePositions(planes);
787       this->InvokeEvent(
788         vtkImageCroppingRegionsWidget::CroppingPlanesPositionChangedEvent, planes);
789       this->EventCallbackCommand->SetAbortFlag(1);
790       this->Interactor->Render();
791       break;
792     case vtkImageCroppingRegionsWidget::MovingH1AndV2:
793       switch (this->SliceOrientation)
794       {
795         case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_YZ:
796           if (newPosition[1] > planes[2])
797           {
798             planes[3] = newPosition[1];
799           }
800           if (newPosition[2] < planes[5])
801           {
802             planes[4] = newPosition[2];
803           }
804           break;
805         case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XZ:
806           if (newPosition[0] > planes[0])
807           {
808             planes[1] = newPosition[0];
809           }
810           if (newPosition[2] < planes[5])
811           {
812             planes[4] = newPosition[2];
813           }
814           break;
815         case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XY:
816           if (newPosition[0] > planes[0])
817           {
818             planes[1]  = newPosition[0];
819           }
820           if (newPosition[1] < planes[3])
821           {
822             planes[2] = newPosition[1];
823           }
824           break;
825       }
826 
827       this->SetPlanePositions(planes);
828       this->InvokeEvent(vtkImageCroppingRegionsWidget::CroppingPlanesPositionChangedEvent,
829                         planes);
830       this->EventCallbackCommand->SetAbortFlag(1);
831       this->Interactor->Render();
832       break;
833     case vtkImageCroppingRegionsWidget::MovingH2AndV1:
834       switch (this->SliceOrientation)
835       {
836         case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_YZ:
837           if (newPosition[1] < planes[3])
838           {
839             planes[2] = newPosition[1];
840           }
841           if (newPosition[2] > planes[4])
842           {
843             planes[5] = newPosition[2];
844           }
845           break;
846         case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XZ:
847           if (newPosition[0] < planes[1])
848           {
849             planes[0] = newPosition[0];
850           }
851           if (newPosition[2] > planes[4])
852           {
853             planes[5] = newPosition[2];
854           }
855           break;
856         case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XY:
857           if (newPosition[0] < planes[1])
858           {
859             planes[0] = newPosition[0];
860           }
861           if (newPosition[1] > planes[2])
862           {
863             planes[3] = newPosition[1];
864           }
865           break;
866       }
867 
868       this->SetPlanePositions(planes);
869       this->InvokeEvent(vtkImageCroppingRegionsWidget::CroppingPlanesPositionChangedEvent,
870                         planes);
871       this->EventCallbackCommand->SetAbortFlag(1);
872       this->Interactor->Render();
873       break;
874     case vtkImageCroppingRegionsWidget::MovingH2AndV2:
875       switch (this->SliceOrientation)
876       {
877         case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_YZ:
878           if (newPosition[1] > planes[2])
879           {
880             planes[3] = newPosition[1];
881           }
882           if (newPosition[2] > planes[4])
883           {
884             planes[5] = newPosition[2];
885           }
886           break;
887         case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XZ:
888           if (newPosition[0] > planes[0])
889           {
890             planes[1] = newPosition[0];
891           }
892           if (newPosition[2] > planes[4])
893           {
894             planes[5] = newPosition[2];
895           }
896           break;
897         case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XY:
898           if (newPosition[0] > planes[0])
899           {
900             planes[1] = newPosition[0];
901           }
902           if (newPosition[1] > planes[2])
903           {
904             planes[3] = newPosition[1];
905           }
906           break;
907       }
908 
909       this->SetPlanePositions(planes);
910       this->InvokeEvent(vtkImageCroppingRegionsWidget::CroppingPlanesPositionChangedEvent,
911                         planes);
912       this->EventCallbackCommand->SetAbortFlag(1);
913       this->Interactor->Render();
914       break;
915   }
916 }
917 
918 //----------------------------------------------------------------------------
UpdateCursorIcon()919 void vtkImageCroppingRegionsWidget::UpdateCursorIcon()
920 {
921   if (!this->Enabled)
922   {
923     this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_DEFAULT);
924     return;
925   }
926 
927   if (!this->CurrentRenderer || this->Moving)
928   {
929     return;
930   }
931 
932   double slice_pos = this->GetSlicePosition();
933   double *plane_pos = this->PlanePositions;
934   double *bounds = this->InitialBounds;
935 
936   int x = this->Interactor->GetEventPosition()[0];
937   int y = this->Interactor->GetEventPosition()[1];
938 
939   double lineX1 = 0.0;
940   double lineX2 = 0.0;
941   double lineY1 = 0.0;
942   double lineY2 = 0.0;
943 
944   switch (this->SliceOrientation)
945   {
946     case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_YZ:
947       this->CurrentRenderer->SetWorldPoint(
948         slice_pos, plane_pos[2], bounds[4], 1);
949       this->CurrentRenderer->WorldToDisplay();
950       lineX1 = this->CurrentRenderer->GetDisplayPoint()[0];
951       this->CurrentRenderer->SetWorldPoint(
952         slice_pos, plane_pos[3], bounds[4], 1);
953       this->CurrentRenderer->WorldToDisplay();
954       lineX2 = this->CurrentRenderer->GetDisplayPoint()[0];
955 
956       this->CurrentRenderer->SetWorldPoint(
957         slice_pos, bounds[2], plane_pos[4], 1);
958       this->CurrentRenderer->WorldToDisplay();
959       lineY1 = this->CurrentRenderer->GetDisplayPoint()[1];
960       this->CurrentRenderer->SetWorldPoint(
961         slice_pos, bounds[2], plane_pos[5], 1);
962       this->CurrentRenderer->WorldToDisplay();
963       lineY2 = this->CurrentRenderer->GetDisplayPoint()[1];
964       break;
965 
966     case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XZ:
967       this->CurrentRenderer->SetWorldPoint(
968         plane_pos[0], slice_pos, bounds[4], 1);
969       this->CurrentRenderer->WorldToDisplay();
970       lineX1 = this->CurrentRenderer->GetDisplayPoint()[0];
971       this->CurrentRenderer->SetWorldPoint(
972         plane_pos[1], slice_pos, bounds[4], 1);
973       this->CurrentRenderer->WorldToDisplay();
974       lineX2 = this->CurrentRenderer->GetDisplayPoint()[0];
975 
976       this->CurrentRenderer->SetWorldPoint(
977         bounds[0], slice_pos, plane_pos[4], 1);
978       this->CurrentRenderer->WorldToDisplay();
979       lineY1 = this->CurrentRenderer->GetDisplayPoint()[1];
980       this->CurrentRenderer->SetWorldPoint(
981         bounds[0], slice_pos, plane_pos[5], 1);
982       this->CurrentRenderer->WorldToDisplay();
983       lineY2 = this->CurrentRenderer->GetDisplayPoint()[1];
984       break;
985 
986     case vtkImageCroppingRegionsWidget::SLICE_ORIENTATION_XY:
987       this->CurrentRenderer->SetWorldPoint(
988         plane_pos[0], bounds[2], slice_pos, 1);
989       this->CurrentRenderer->WorldToDisplay();
990       lineX1 = this->CurrentRenderer->GetDisplayPoint()[0];
991       this->CurrentRenderer->SetWorldPoint(
992         plane_pos[1], bounds[2], slice_pos, 1);
993       this->CurrentRenderer->WorldToDisplay();
994       lineX2 = this->CurrentRenderer->GetDisplayPoint()[0];
995 
996       this->CurrentRenderer->SetWorldPoint(
997         bounds[0], plane_pos[2], slice_pos, 1);
998       this->CurrentRenderer->WorldToDisplay();
999       lineY1 = this->CurrentRenderer->GetDisplayPoint()[1];
1000       this->CurrentRenderer->SetWorldPoint(
1001         bounds[0], plane_pos[3], slice_pos, 1);
1002       this->CurrentRenderer->WorldToDisplay();
1003       lineY2 = this->CurrentRenderer->GetDisplayPoint()[1];
1004       break;
1005   }
1006 
1007   double xDist1 = fabs(x - lineX1);
1008   double xDist2 = fabs(x - lineX2);
1009   double yDist1 = fabs(y - lineY1);
1010   double yDist2 = fabs(y - lineY2);
1011 
1012   int pState = this->MouseCursorState;
1013 
1014   if (xDist1 < 3)
1015   {
1016     if (yDist1 < 3)
1017     {
1018       this->MouseCursorState = vtkImageCroppingRegionsWidget::MovingH1AndV1;
1019     }
1020     else if (yDist2 < 3)
1021     {
1022       this->MouseCursorState = vtkImageCroppingRegionsWidget::MovingH2AndV1;
1023     }
1024     else
1025     {
1026       this->MouseCursorState = vtkImageCroppingRegionsWidget::MovingV1;
1027     }
1028   }
1029   else if (xDist2 < 3)
1030   {
1031     if (yDist1 < 3)
1032     {
1033       this->MouseCursorState = vtkImageCroppingRegionsWidget::MovingH1AndV2;
1034     }
1035     else if (yDist2 < 3)
1036     {
1037       this->MouseCursorState = vtkImageCroppingRegionsWidget::MovingH2AndV2;
1038     }
1039     else
1040     {
1041       this->MouseCursorState = vtkImageCroppingRegionsWidget::MovingV2;
1042     }
1043   }
1044   else if (yDist1 < 3)
1045   {
1046     this->MouseCursorState = vtkImageCroppingRegionsWidget::MovingH1;
1047   }
1048   else if (yDist2 < 3)
1049   {
1050     this->MouseCursorState = vtkImageCroppingRegionsWidget::MovingH2;
1051   }
1052   else
1053   {
1054     this->MouseCursorState = vtkImageCroppingRegionsWidget::NoLine;
1055   }
1056 
1057   if (pState == this->MouseCursorState)
1058   {
1059     return;
1060   }
1061 
1062   this->SetMouseCursor(this->MouseCursorState);
1063 
1064 }
1065 
1066 //----------------------------------------------------------------------------
SetMouseCursor(int state)1067 void vtkImageCroppingRegionsWidget::SetMouseCursor(int state)
1068 {
1069   switch (state)
1070   {
1071     case vtkImageCroppingRegionsWidget::MovingH1AndV1:
1072     case vtkImageCroppingRegionsWidget::MovingH2AndV1:
1073     case vtkImageCroppingRegionsWidget::MovingH1AndV2:
1074     case vtkImageCroppingRegionsWidget::MovingH2AndV2:
1075       this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZEALL);
1076       break;
1077     case vtkImageCroppingRegionsWidget::MovingV1:
1078     case vtkImageCroppingRegionsWidget::MovingV2:
1079       this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZEWE);
1080       break;
1081     case vtkImageCroppingRegionsWidget::MovingH1:
1082     case vtkImageCroppingRegionsWidget::MovingH2:
1083       this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_SIZENS);
1084       break;
1085     case vtkImageCroppingRegionsWidget::NoLine:
1086       this->Interactor->GetRenderWindow()->SetCurrentCursor(VTK_CURSOR_DEFAULT);
1087       break;
1088   }
1089 }
1090 
1091 //----------------------------------------------------------------------------
ComputeWorldCoordinate(int x,int y,double * coord)1092 int vtkImageCroppingRegionsWidget::ComputeWorldCoordinate(
1093   int x, int y, double* coord)
1094 {
1095   if (!this->CurrentRenderer)
1096   {
1097     return 0;
1098   }
1099 
1100   this->CurrentRenderer->SetWorldPoint(
1101     this->InitialBounds[0], this->InitialBounds[2], this->InitialBounds[4], 1.0);
1102   this->CurrentRenderer->WorldToDisplay();
1103   double *dispPoint = this->CurrentRenderer->GetDisplayPoint();
1104 
1105   this->CurrentRenderer->SetDisplayPoint(x, y, dispPoint[2]);
1106   this->CurrentRenderer->DisplayToWorld();
1107   double *worldPoint = this->CurrentRenderer->GetWorldPoint();
1108   if (worldPoint[3] != 0.0)
1109   {
1110     worldPoint[0] = (double)((double)worldPoint[0] / (double)worldPoint[3]);
1111     worldPoint[1] = (double)((double)worldPoint[1] / (double)worldPoint[3]);
1112     worldPoint[2] = (double)((double)worldPoint[2] / (double)worldPoint[3]);
1113   }
1114 
1115   coord[0] = worldPoint[0];
1116   coord[1] = worldPoint[1];
1117   coord[2] = worldPoint[2];
1118 
1119   int idx1 = (this->SliceOrientation + 1) % 3;
1120   int idx2 = (this->SliceOrientation + 2) % 3;
1121 
1122   if (worldPoint[idx1] < this->InitialBounds[idx1 * 2] ||
1123       worldPoint[idx1] > this->InitialBounds[idx1 * 2 + 1] ||
1124       worldPoint[idx2] < this->InitialBounds[idx2 * 2] ||
1125       worldPoint[idx2] > this->InitialBounds[idx2 * 2 + 1])
1126   {
1127     return 0;
1128   }
1129 
1130   return 1;
1131 }
1132 
1133 //----------------------------------------------------------------------------
SetLine1Color(double r,double g,double b)1134 void vtkImageCroppingRegionsWidget::SetLine1Color(double r, double g, double b)
1135 {
1136   this->LineActors[0]->GetProperty()->SetColor(r, g, b);
1137   this->Interactor->Render();
1138 }
1139 
1140 //----------------------------------------------------------------------------
GetLine1Color()1141 double* vtkImageCroppingRegionsWidget::GetLine1Color()
1142 {
1143   return this->LineActors[0]->GetProperty()->GetColor();
1144 }
1145 
1146 //----------------------------------------------------------------------------
GetLine1Color(double rgb[3])1147 void vtkImageCroppingRegionsWidget::GetLine1Color(double rgb[3])
1148 {
1149   this->LineActors[0]->GetProperty()->GetColor(rgb);
1150 }
1151 
1152 //----------------------------------------------------------------------------
SetLine2Color(double r,double g,double b)1153 void vtkImageCroppingRegionsWidget::SetLine2Color(double r, double g, double b)
1154 {
1155   this->LineActors[1]->GetProperty()->SetColor(r, g, b);
1156   this->Interactor->Render();
1157 }
1158 
1159 //----------------------------------------------------------------------------
GetLine2Color()1160 double* vtkImageCroppingRegionsWidget::GetLine2Color()
1161 {
1162   return this->LineActors[1]->GetProperty()->GetColor();
1163 }
1164 
1165 //----------------------------------------------------------------------------
GetLine2Color(double rgb[3])1166 void vtkImageCroppingRegionsWidget::GetLine2Color(double rgb[3])
1167 {
1168   this->LineActors[1]->GetProperty()->GetColor(rgb);
1169 }
1170 
1171 //----------------------------------------------------------------------------
SetLine3Color(double r,double g,double b)1172 void vtkImageCroppingRegionsWidget::SetLine3Color(double r, double g, double b)
1173 {
1174   this->LineActors[2]->GetProperty()->SetColor(r, g, b);
1175   this->Interactor->Render();
1176 }
1177 
1178 //----------------------------------------------------------------------------
GetLine3Color()1179 double* vtkImageCroppingRegionsWidget::GetLine3Color()
1180 {
1181   return this->LineActors[2]->GetProperty()->GetColor();
1182 }
1183 
1184 //----------------------------------------------------------------------------
GetLine3Color(double rgb[3])1185 void vtkImageCroppingRegionsWidget::GetLine3Color(double rgb[3])
1186 {
1187   this->LineActors[2]->GetProperty()->GetColor(rgb);
1188 }
1189 
1190 //----------------------------------------------------------------------------
SetLine4Color(double r,double g,double b)1191 void vtkImageCroppingRegionsWidget::SetLine4Color(double r, double g, double b)
1192 {
1193   this->LineActors[3]->GetProperty()->SetColor(r, g, b);
1194   this->Interactor->Render();
1195 }
1196 
1197 //----------------------------------------------------------------------------
GetLine4Color()1198 double* vtkImageCroppingRegionsWidget::GetLine4Color()
1199 {
1200   return this->LineActors[3]->GetProperty()->GetColor();
1201 }
1202 
1203 //----------------------------------------------------------------------------
GetLine4Color(double rgb[3])1204 void vtkImageCroppingRegionsWidget::GetLine4Color(double rgb[3])
1205 {
1206   this->LineActors[3]->GetProperty()->GetColor(rgb);
1207 }
1208 
1209 //----------------------------------------------------------------------------
SetVolumeMapper(vtkVolumeMapper * arg)1210 void vtkImageCroppingRegionsWidget::SetVolumeMapper(vtkVolumeMapper *arg)
1211 {
1212   if (this->VolumeMapper == arg)
1213   {
1214     return;
1215   }
1216 
1217   if (this->VolumeMapper)
1218   {
1219     this->VolumeMapper->UnRegister(this);
1220   }
1221 
1222   this->VolumeMapper = arg;
1223 
1224   if (this->VolumeMapper)
1225   {
1226     this->VolumeMapper->Register(this);
1227   }
1228 
1229   this->Modified();
1230 
1231   // Update internal objects according to the new Input
1232 
1233   this->UpdateAccordingToInput();
1234 }
1235 
1236 //----------------------------------------------------------------------------
PlaceWidget(double bounds[6])1237 void vtkImageCroppingRegionsWidget::PlaceWidget(double bounds[6])
1238 {
1239   double center[6];
1240   this->AdjustBounds(bounds, this->InitialBounds, center);
1241 
1242   for (int i = 0; i < 3; i++)
1243   {
1244     if (this->InitialBounds[i * 2] > this->InitialBounds[i * 2 + 1])
1245     {
1246       double temp = this->InitialBounds[i * 2];
1247       this->InitialBounds[i * 2] = this->InitialBounds[i * 2 + 1];
1248       this->InitialBounds[i * 2 + 1] = temp;
1249     }
1250   }
1251 
1252   // Bounds have changed, let's try to place the plane at the same positions
1253   // and they will be constrain automatically
1254 
1255   this->SetPlanePositions(this->PlanePositions);
1256 }
1257 
1258 //----------------------------------------------------------------------------
UpdateAccordingToInput()1259 void vtkImageCroppingRegionsWidget::UpdateAccordingToInput()
1260 {
1261   vtkVolumeMapper *mapper = this->GetVolumeMapper();
1262   if (mapper)
1263   {
1264     this->PlaceWidget(mapper->GetBounds());
1265     this->SetPlanePositions(mapper->GetCroppingRegionPlanes());
1266     this->SetCroppingRegionFlags(mapper->GetCroppingRegionFlags());
1267   }
1268 }
1269 
1270 //----------------------------------------------------------------------------
SetSlice(int num)1271 void vtkImageCroppingRegionsWidget::SetSlice(int num)
1272 {
1273   this->Slice = num;
1274 
1275   this->Modified();
1276 
1277   this->UpdateGeometry();
1278 
1279   if (this->Interactor)
1280   {
1281     this->Interactor->Render();
1282   }
1283 }
1284 
1285 //----------------------------------------------------------------------------
SetSliceOrientation(int arg)1286 void vtkImageCroppingRegionsWidget::SetSliceOrientation(int arg)
1287 {
1288   if (this->SliceOrientation == arg)
1289   {
1290     return;
1291   }
1292 
1293   this->SliceOrientation = arg;
1294 
1295   this->UpdateGeometry();
1296 
1297   if (this->Interactor)
1298   {
1299     this->Interactor->Render();
1300   }
1301 }
1302 
1303 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)1304 void vtkImageCroppingRegionsWidget::PrintSelf(ostream& os, vtkIndent indent)
1305 {
1306   this->Superclass::PrintSelf(os, indent);
1307 
1308   os << indent << "CroppingRegionFlags: " << this->CroppingRegionFlags << endl;
1309   os << indent << "PlanePositions: " << endl
1310      << indent << "  In X: " << this->PlanePositions[0]
1311      << " to " << this->PlanePositions[1] << endl
1312      << indent << "  In Y: " << this->PlanePositions[2]
1313      << " to " << this->PlanePositions[3] << endl
1314      << indent << "  In Z: " << this->PlanePositions[4]
1315      << " to " << this->PlanePositions[5] << endl;
1316   os << indent << "Slice: " << this->Slice << endl;
1317   os << indent << "SliceOrientation: " << this->SliceOrientation << endl;
1318   os << indent << "VolumeMapper: " << this->VolumeMapper << endl;
1319 }
1320