1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkImplicitPlaneWidget.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 "vtkImplicitPlaneWidget.h"
16 
17 #include "vtkActor.h"
18 #include "vtkAssemblyNode.h"
19 #include "vtkAssemblyPath.h"
20 #include "vtkCallbackCommand.h"
21 #include "vtkCamera.h"
22 #include "vtkCellPicker.h"
23 #include "vtkConeSource.h"
24 #include "vtkCutter.h"
25 #include "vtkFeatureEdges.h"
26 #include "vtkImageData.h"
27 #include "vtkLineSource.h"
28 #include "vtkMath.h"
29 #include "vtkObjectFactory.h"
30 #include "vtkOutlineFilter.h"
31 #include "vtkPickingManager.h"
32 #include "vtkPlane.h"
33 #include "vtkPolyData.h"
34 #include "vtkPolyDataMapper.h"
35 #include "vtkProperty.h"
36 #include "vtkRenderWindowInteractor.h"
37 #include "vtkRenderer.h"
38 #include "vtkSphereSource.h"
39 #include "vtkTransform.h"
40 #include "vtkTubeFilter.h"
41 
42 vtkStandardNewMacro(vtkImplicitPlaneWidget);
43 
44 //----------------------------------------------------------------------------
vtkImplicitPlaneWidget()45 vtkImplicitPlaneWidget::vtkImplicitPlaneWidget() : vtkPolyDataSourceWidget()
46 {
47   this->DiagonalRatio = 0.3;
48   this->State = vtkImplicitPlaneWidget::Start;
49   this->EventCallbackCommand->SetCallback(vtkImplicitPlaneWidget::ProcessEvents);
50 
51   this->NormalToXAxis = 0;
52   this->NormalToYAxis = 0;
53   this->NormalToZAxis = 0;
54 
55   // Build the representation of the widget
56   //
57   this->Plane = vtkPlane::New();
58   this->Plane->SetNormal(0,0,1);
59   this->Plane->SetOrigin(0,0,0);
60 
61   this->Box = vtkImageData::New();
62   this->Box->SetDimensions(2,2,2);
63   this->Outline = vtkOutlineFilter::New();
64   this->Outline->SetInputData(this->Box);
65   this->OutlineMapper = vtkPolyDataMapper::New();
66   this->OutlineMapper->SetInputConnection(
67     this->Outline->GetOutputPort());
68   this->OutlineActor = vtkActor::New();
69   this->OutlineActor->SetMapper(this->OutlineMapper);
70   this->OutlineTranslation = 1;
71   this->ScaleEnabled = 1;
72   this->OutsideBounds = 1;
73 
74   this->Cutter = vtkCutter::New();
75   this->Cutter->SetInputData(this->Box);
76   this->Cutter->SetCutFunction(this->Plane);
77   this->CutMapper = vtkPolyDataMapper::New();
78   this->CutMapper->SetInputConnection(
79     this->Cutter->GetOutputPort());
80   this->CutActor = vtkActor::New();
81   this->CutActor->SetMapper(this->CutMapper);
82   this->DrawPlane = 1;
83 
84   this->Edges = vtkFeatureEdges::New();
85   this->Edges->SetInputConnection(
86     this->Cutter->GetOutputPort());
87   this->EdgesTuber = vtkTubeFilter::New();
88   this->EdgesTuber->SetInputConnection(
89     this->Edges->GetOutputPort());
90   this->EdgesTuber->SetNumberOfSides(12);
91   this->EdgesMapper = vtkPolyDataMapper::New();
92   this->EdgesMapper->SetInputConnection(
93     this->EdgesTuber->GetOutputPort());
94   this->EdgesActor = vtkActor::New();
95   this->EdgesActor->SetMapper(this->EdgesMapper);
96   this->Tubing = 1; //control whether tubing is on
97 
98   // Create the + plane normal
99   this->LineSource = vtkLineSource::New();
100   this->LineSource->SetResolution(1);
101   this->LineMapper = vtkPolyDataMapper::New();
102   this->LineMapper->SetInputConnection(
103     this->LineSource->GetOutputPort());
104   this->LineActor = vtkActor::New();
105   this->LineActor->SetMapper(this->LineMapper);
106 
107   this->ConeSource = vtkConeSource::New();
108   this->ConeSource->SetResolution(12);
109   this->ConeSource->SetAngle(25.0);
110   this->ConeMapper = vtkPolyDataMapper::New();
111   this->ConeMapper->SetInputConnection(
112     this->ConeSource->GetOutputPort());
113   this->ConeActor = vtkActor::New();
114   this->ConeActor->SetMapper(this->ConeMapper);
115 
116   // Create the - plane normal
117   this->LineSource2 = vtkLineSource::New();
118   this->LineSource2->SetResolution(1);
119   this->LineMapper2 = vtkPolyDataMapper::New();
120   this->LineMapper2->SetInputConnection(
121     this->LineSource2->GetOutputPort());
122   this->LineActor2 = vtkActor::New();
123   this->LineActor2->SetMapper(this->LineMapper2);
124 
125   this->ConeSource2 = vtkConeSource::New();
126   this->ConeSource2->SetResolution(12);
127   this->ConeSource2->SetAngle(25.0);
128   this->ConeMapper2 = vtkPolyDataMapper::New();
129   this->ConeMapper2->SetInputConnection(
130     this->ConeSource2->GetOutputPort());
131   this->ConeActor2 = vtkActor::New();
132   this->ConeActor2->SetMapper(this->ConeMapper2);
133 
134   // Create the origin handle
135   this->Sphere = vtkSphereSource::New();
136   this->Sphere->SetThetaResolution(16);
137   this->Sphere->SetPhiResolution(8);
138   this->SphereMapper = vtkPolyDataMapper::New();
139   this->SphereMapper->SetInputConnection(
140     this->Sphere->GetOutputPort());
141   this->SphereActor = vtkActor::New();
142   this->SphereActor->SetMapper(this->SphereMapper);
143   this->OriginTranslation = 1;
144 
145   this->Transform = vtkTransform::New();
146 
147   // Define the point coordinates
148   double bounds[6];
149   bounds[0] = -0.5;
150   bounds[1] = 0.5;
151   bounds[2] = -0.5;
152   bounds[3] = 0.5;
153   bounds[4] = -0.5;
154   bounds[5] = 0.5;
155 
156   // Initial creation of the widget, serves to initialize it
157   this->PlaceWidget(bounds);
158 
159   //Manage the picking stuff
160   this->Picker = vtkCellPicker::New();
161   this->Picker->SetTolerance(0.005);
162   this->Picker->AddPickList(this->CutActor);
163   this->Picker->AddPickList(this->LineActor);
164   this->Picker->AddPickList(this->ConeActor);
165   this->Picker->AddPickList(this->LineActor2);
166   this->Picker->AddPickList(this->ConeActor2);
167   this->Picker->AddPickList(this->SphereActor);
168   this->Picker->AddPickList(this->OutlineActor);
169   this->Picker->PickFromListOn();
170 
171   // Set up the initial properties
172   this->CreateDefaultProperties();
173 }
174 
175 //----------------------------------------------------------------------------
~vtkImplicitPlaneWidget()176 vtkImplicitPlaneWidget::~vtkImplicitPlaneWidget()
177 {
178   this->Plane->Delete();
179   this->Box->Delete();
180   this->Outline->Delete();
181   this->OutlineMapper->Delete();
182   this->OutlineActor->Delete();
183 
184   this->Cutter->Delete();
185   this->CutMapper->Delete();
186   this->CutActor->Delete();
187 
188   this->Edges->Delete();
189   this->EdgesTuber->Delete();
190   this->EdgesMapper->Delete();
191   this->EdgesActor->Delete();
192 
193   this->LineSource->Delete();
194   this->LineMapper->Delete();
195   this->LineActor->Delete();
196 
197   this->ConeSource->Delete();
198   this->ConeMapper->Delete();
199   this->ConeActor->Delete();
200 
201   this->LineSource2->Delete();
202   this->LineMapper2->Delete();
203   this->LineActor2->Delete();
204 
205   this->ConeSource2->Delete();
206   this->ConeMapper2->Delete();
207   this->ConeActor2->Delete();
208 
209   this->Sphere->Delete();
210   this->SphereMapper->Delete();
211   this->SphereActor->Delete();
212 
213   this->Transform->Delete();
214 
215   this->Picker->Delete();
216 
217   this->NormalProperty->Delete();
218   this->SelectedNormalProperty->Delete();
219   this->PlaneProperty->Delete();
220   this->SelectedPlaneProperty->Delete();
221   this->OutlineProperty->Delete();
222   this->SelectedOutlineProperty->Delete();
223   this->EdgesProperty->Delete();
224 }
225 
226 //----------------------------------------------------------------------------
SetEnabled(int enabling)227 void vtkImplicitPlaneWidget::SetEnabled(int enabling)
228 {
229   if ( ! this->Interactor )
230     {
231     vtkErrorMacro(<<"The interactor must be set prior to enabling/disabling widget");
232     return;
233     }
234 
235   if ( enabling ) //------------------------------------------------------------
236     {
237     vtkDebugMacro(<<"Enabling plane widget");
238 
239     if ( this->Enabled ) //already enabled, just return
240       {
241       return;
242       }
243 
244     if ( ! this->CurrentRenderer )
245       {
246       this->SetCurrentRenderer(this->Interactor->FindPokedRenderer(
247         this->Interactor->GetLastEventPosition()[0],
248         this->Interactor->GetLastEventPosition()[1]));
249       if (this->CurrentRenderer == NULL)
250         {
251         return;
252         }
253       }
254 
255     this->Enabled = 1;
256 
257     // listen for the following events
258     vtkRenderWindowInteractor *i = this->Interactor;
259     i->AddObserver(vtkCommand::MouseMoveEvent, this->EventCallbackCommand,
260                    this->Priority);
261     i->AddObserver(vtkCommand::LeftButtonPressEvent,
262                    this->EventCallbackCommand, this->Priority);
263     i->AddObserver(vtkCommand::LeftButtonReleaseEvent,
264                    this->EventCallbackCommand, this->Priority);
265     i->AddObserver(vtkCommand::MiddleButtonPressEvent,
266                    this->EventCallbackCommand, this->Priority);
267     i->AddObserver(vtkCommand::MiddleButtonReleaseEvent,
268                    this->EventCallbackCommand, this->Priority);
269     i->AddObserver(vtkCommand::RightButtonPressEvent,
270                    this->EventCallbackCommand, this->Priority);
271     i->AddObserver(vtkCommand::RightButtonReleaseEvent,
272                    this->EventCallbackCommand, this->Priority);
273 
274     // add the outline
275     this->CurrentRenderer->AddActor(this->OutlineActor);
276     this->OutlineActor->SetProperty(this->OutlineProperty);
277 
278     // add the edges
279     this->CurrentRenderer->AddActor(this->EdgesActor);
280     this->EdgesActor->SetProperty(this->EdgesProperty);
281 
282     // add the normal vector
283     this->CurrentRenderer->AddActor(this->LineActor);
284     this->LineActor->SetProperty(this->NormalProperty);
285     this->CurrentRenderer->AddActor(this->ConeActor);
286     this->ConeActor->SetProperty(this->NormalProperty);
287 
288     this->CurrentRenderer->AddActor(this->LineActor2);
289     this->LineActor2->SetProperty(this->NormalProperty);
290     this->CurrentRenderer->AddActor(this->ConeActor2);
291     this->ConeActor2->SetProperty(this->NormalProperty);
292 
293     // add the origin handle
294     this->CurrentRenderer->AddActor(this->SphereActor);
295     this->SphereActor->SetProperty(this->NormalProperty);
296 
297     // add the plane (if desired)
298     if ( this->DrawPlane )
299       {
300       this->CurrentRenderer->AddActor(this->CutActor);
301       }
302     this->CutActor->SetProperty(this->PlaneProperty);
303 
304     this->UpdateRepresentation();
305     this->SizeHandles();
306     this->InvokeEvent(vtkCommand::EnableEvent,NULL);
307     }
308 
309   else //disabling----------------------------------------------------------
310     {
311     vtkDebugMacro(<<"Disabling plane widget");
312 
313     if ( ! this->Enabled ) //already disabled, just return
314       {
315       return;
316       }
317 
318     this->Enabled = 0;
319 
320     // don't listen for events any more
321     this->Interactor->RemoveObserver(this->EventCallbackCommand);
322 
323     // turn off the various actors
324     this->CurrentRenderer->RemoveActor(this->OutlineActor);
325     this->CurrentRenderer->RemoveActor(this->EdgesActor);
326     this->CurrentRenderer->RemoveActor(this->LineActor);
327     this->CurrentRenderer->RemoveActor(this->ConeActor);
328     this->CurrentRenderer->RemoveActor(this->LineActor2);
329     this->CurrentRenderer->RemoveActor(this->ConeActor2);
330     this->CurrentRenderer->RemoveActor(this->SphereActor);
331     this->CurrentRenderer->RemoveActor(this->CutActor);
332 
333     this->InvokeEvent(vtkCommand::DisableEvent,NULL);
334     this->SetCurrentRenderer(NULL);
335     }
336 
337   this->Interactor->Render();
338 }
339 
340 //----------------------------------------------------------------------------
ProcessEvents(vtkObject * vtkNotUsed (object),unsigned long event,void * clientdata,void * vtkNotUsed (calldata))341 void vtkImplicitPlaneWidget::ProcessEvents(vtkObject* vtkNotUsed(object),
342                                            unsigned long event,
343                                            void* clientdata,
344                                            void* vtkNotUsed(calldata))
345 {
346   vtkImplicitPlaneWidget* self =
347     reinterpret_cast<vtkImplicitPlaneWidget *>( clientdata );
348 
349   //okay, let's do the right thing
350   switch(event)
351     {
352     case vtkCommand::LeftButtonPressEvent:
353       self->OnLeftButtonDown();
354       break;
355     case vtkCommand::LeftButtonReleaseEvent:
356       self->OnLeftButtonUp();
357       break;
358     case vtkCommand::MiddleButtonPressEvent:
359       self->OnMiddleButtonDown();
360       break;
361     case vtkCommand::MiddleButtonReleaseEvent:
362       self->OnMiddleButtonUp();
363       break;
364     case vtkCommand::RightButtonPressEvent:
365       self->OnRightButtonDown();
366       break;
367     case vtkCommand::RightButtonReleaseEvent:
368       self->OnRightButtonUp();
369       break;
370     case vtkCommand::MouseMoveEvent:
371       self->OnMouseMove();
372       break;
373     }
374 }
375 
376 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)377 void vtkImplicitPlaneWidget::PrintSelf(ostream& os, vtkIndent indent)
378 {
379   this->Superclass::PrintSelf(os,indent);
380 
381   if ( this->NormalProperty )
382     {
383     os << indent << "Normal Property: " << this->NormalProperty << "\n";
384     }
385   else
386     {
387     os << indent << "Normal Property: (none)\n";
388     }
389   if ( this->SelectedNormalProperty )
390     {
391     os << indent << "Selected Normal Property: "
392        << this->SelectedNormalProperty << "\n";
393     }
394   else
395     {
396     os << indent << "Selected Normal Property: (none)\n";
397     }
398 
399   if ( this->PlaneProperty )
400     {
401     os << indent << "Plane Property: " << this->PlaneProperty << "\n";
402     }
403   else
404     {
405     os << indent << "Plane Property: (none)\n";
406     }
407   if ( this->SelectedPlaneProperty )
408     {
409     os << indent << "Selected Plane Property: "
410        << this->SelectedPlaneProperty << "\n";
411     }
412   else
413     {
414     os << indent << "Selected Plane Property: (none)\n";
415     }
416 
417   if ( this->OutlineProperty )
418     {
419     os << indent << "Outline Property: " << this->OutlineProperty << "\n";
420     }
421   else
422     {
423     os << indent << "Outline Property: (none)\n";
424     }
425   if ( this->SelectedOutlineProperty )
426     {
427     os << indent << "Selected Outline Property: "
428        << this->SelectedOutlineProperty << "\n";
429     }
430   else
431     {
432     os << indent << "Selected Outline Property: (none)\n";
433     }
434 
435   if ( this->EdgesProperty )
436     {
437     os << indent << "Edges Property: " << this->EdgesProperty << "\n";
438     }
439   else
440     {
441     os << indent << "Edges Property: (none)\n";
442     }
443 
444   os << indent << "Normal To X Axis: "
445      << (this->NormalToXAxis ? "On" : "Off") << "\n";
446   os << indent << "Normal To Y Axis: "
447      << (this->NormalToYAxis ? "On" : "Off") << "\n";
448   os << indent << "Normal To Z Axis: "
449      << (this->NormalToZAxis ? "On" : "Off") << "\n";
450 
451   os << indent << "Tubing: " << (this->Tubing ? "On" : "Off") << "\n";
452   os << indent << "Origin Translation: "
453      << (this->OriginTranslation ? "On" : "Off") << "\n";
454   os << indent << "Outline Translation: "
455      << (this->OutlineTranslation ? "On" : "Off") << "\n";
456   os << indent << "Outside Bounds: "
457      << (this->OutsideBounds ? "On" : "Off") << "\n";
458   os << indent << "Scale Enabled: "
459      << (this->ScaleEnabled ? "On" : "Off") << "\n";
460   os << indent << "Draw Plane: " << (this->DrawPlane ? "On" : "Off") << "\n";
461 
462   os << indent << "Diagonal Ratio: " << this->DiagonalRatio << "\n";
463 }
464 
465 
466 //----------------------------------------------------------------------------
HighlightNormal(int highlight)467 void vtkImplicitPlaneWidget::HighlightNormal(int highlight)
468 {
469   if ( highlight )
470     {
471     this->LineActor->SetProperty(this->SelectedNormalProperty);
472     this->ConeActor->SetProperty(this->SelectedNormalProperty);
473     this->LineActor2->SetProperty(this->SelectedNormalProperty);
474     this->ConeActor2->SetProperty(this->SelectedNormalProperty);
475     this->SphereActor->SetProperty(this->SelectedNormalProperty);
476     }
477   else
478     {
479     this->LineActor->SetProperty(this->NormalProperty);
480     this->ConeActor->SetProperty(this->NormalProperty);
481     this->LineActor2->SetProperty(this->NormalProperty);
482     this->ConeActor2->SetProperty(this->NormalProperty);
483     this->SphereActor->SetProperty(this->NormalProperty);
484     }
485 }
486 
487 
488 //----------------------------------------------------------------------------
HighlightPlane(int highlight)489 void vtkImplicitPlaneWidget::HighlightPlane(int highlight)
490 {
491   if ( highlight )
492     {
493     this->CutActor->SetProperty(this->SelectedPlaneProperty);
494     }
495   else
496     {
497     this->CutActor->SetProperty(this->PlaneProperty);
498     }
499 }
500 
501 
502 //----------------------------------------------------------------------------
HighlightOutline(int highlight)503 void vtkImplicitPlaneWidget::HighlightOutline(int highlight)
504 {
505   if ( highlight )
506     {
507     this->OutlineActor->SetProperty(this->SelectedOutlineProperty);
508     }
509   else
510     {
511     this->OutlineActor->SetProperty(this->OutlineProperty);
512     }
513 }
514 
515 
516 //----------------------------------------------------------------------------
OnLeftButtonDown()517 void vtkImplicitPlaneWidget::OnLeftButtonDown()
518 {
519   // We're only here if we are enabled
520   int X = this->Interactor->GetEventPosition()[0];
521   int Y = this->Interactor->GetEventPosition()[1];
522 
523   // Okay, we can process this. See if we've picked anything.
524   // Make sure it's in the activated renderer
525   if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
526     {
527     this->State = vtkImplicitPlaneWidget::Outside;
528     return;
529     }
530 
531   vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->Picker);
532 
533   if ( path == NULL ) //not picking this widget
534     {
535     this->HighlightPlane(0);
536     this->HighlightNormal(0);
537     this->HighlightOutline(0);
538     this->State = vtkImplicitPlaneWidget::Outside;
539     return;
540     }
541 
542   vtkProp *prop = path->GetFirstNode()->GetViewProp();
543   this->ValidPick = 1;
544   this->Picker->GetPickPosition(this->LastPickPosition);
545   if ( prop == this->ConeActor || prop == this->LineActor ||
546        prop == this->ConeActor2 || prop == this->LineActor2 )
547     {
548     this->HighlightPlane(1);
549     this->HighlightNormal(1);
550     this->State = vtkImplicitPlaneWidget::Rotating;
551     }
552   else if ( prop == this->CutActor )
553     {
554     this->HighlightPlane(1);
555     this->State = vtkImplicitPlaneWidget::Pushing;
556     }
557   else if ( prop == this->SphereActor )
558     {
559     if ( this->OriginTranslation )
560       {
561       this->HighlightNormal(1);
562       this->State = vtkImplicitPlaneWidget::MovingOrigin;
563       }
564     else
565       {
566       return;
567       }
568     }
569   else
570     {
571     if ( this->OutlineTranslation )
572       {
573       this->HighlightOutline(1);
574       this->State = vtkImplicitPlaneWidget::MovingOutline;
575       }
576     else
577       {
578       return;
579       }
580     }
581 
582   this->EventCallbackCommand->SetAbortFlag(1);
583   this->StartInteraction();
584   this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
585   this->Interactor->Render();
586 }
587 
588 //----------------------------------------------------------------------------
OnLeftButtonUp()589 void vtkImplicitPlaneWidget::OnLeftButtonUp()
590 {
591   if ( this->State == vtkImplicitPlaneWidget::Outside )
592     {
593     return;
594     }
595 
596   this->State = vtkImplicitPlaneWidget::Start;
597   this->HighlightPlane(0);
598   this->HighlightOutline(0);
599   this->HighlightNormal(0);
600   this->SizeHandles();
601 
602   this->EventCallbackCommand->SetAbortFlag(1);
603   this->EndInteraction();
604   this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
605   this->Interactor->Render();
606 }
607 
608 //----------------------------------------------------------------------------
OnMiddleButtonDown()609 void vtkImplicitPlaneWidget::OnMiddleButtonDown()
610 {
611   int X = this->Interactor->GetEventPosition()[0];
612   int Y = this->Interactor->GetEventPosition()[1];
613 
614   // Okay, we can process this. See if we've picked anything.
615   // Make sure it's in the activated renderer
616   if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
617     {
618     this->State = vtkImplicitPlaneWidget::Outside;
619     return;
620     }
621 
622   // Okay, we can process this.
623   vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->Picker);
624 
625   if ( path == NULL ) //nothing picked
626     {
627     this->State = vtkImplicitPlaneWidget::Outside;
628     return;
629     }
630 
631   this->ValidPick = 1;
632   this->Picker->GetPickPosition(this->LastPickPosition);
633   this->State = vtkImplicitPlaneWidget::MovingPlane;
634   this->HighlightNormal(1);
635   this->HighlightPlane(1);
636 
637   this->EventCallbackCommand->SetAbortFlag(1);
638   this->StartInteraction();
639   this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
640   this->Interactor->Render();
641 }
642 
643 //----------------------------------------------------------------------------
OnMiddleButtonUp()644 void vtkImplicitPlaneWidget::OnMiddleButtonUp()
645 {
646   if ( this->State == vtkImplicitPlaneWidget::Outside )
647     {
648     return;
649     }
650 
651   this->State = vtkImplicitPlaneWidget::Start;
652   this->HighlightPlane(0);
653   this->HighlightOutline(0);
654   this->HighlightNormal(0);
655   this->SizeHandles();
656 
657   this->EventCallbackCommand->SetAbortFlag(1);
658   this->EndInteraction();
659   this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
660   this->Interactor->Render();
661 }
662 
663 //----------------------------------------------------------------------------
OnRightButtonDown()664 void vtkImplicitPlaneWidget::OnRightButtonDown()
665 {
666   if ( this->ScaleEnabled )
667     {
668     this->State = vtkImplicitPlaneWidget::Scaling;
669 
670     int X = this->Interactor->GetEventPosition()[0];
671     int Y = this->Interactor->GetEventPosition()[1];
672 
673     // Okay, we can process this. See if we've picked anything.
674     // Make sure it's in the activated renderer
675     if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
676       {
677       this->State = vtkImplicitPlaneWidget::Outside;
678       return;
679       }
680 
681     // Okay, we can process this. Try to pick handles first;
682     // if no handles picked, then pick the bounding box.
683     vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->Picker);
684 
685     if ( path == NULL ) //nothing picked
686       {
687       this->State = vtkImplicitPlaneWidget::Outside;
688       return;
689       }
690 
691     this->ValidPick = 1;
692     this->Picker->GetPickPosition(this->LastPickPosition);
693     this->HighlightPlane(1);
694     this->HighlightOutline(1);
695     this->HighlightNormal(1);
696 
697     this->EventCallbackCommand->SetAbortFlag(1);
698     this->StartInteraction();
699     this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
700     this->Interactor->Render();
701   }
702 }
703 
704 //----------------------------------------------------------------------------
OnRightButtonUp()705 void vtkImplicitPlaneWidget::OnRightButtonUp()
706 {
707   if ( this->State == vtkImplicitPlaneWidget::Outside )
708     {
709     return;
710     }
711 
712   this->State = vtkImplicitPlaneWidget::Start;
713   this->HighlightPlane(0);
714   this->HighlightOutline(0);
715   this->HighlightNormal(0);
716   this->SizeHandles();
717 
718   this->EventCallbackCommand->SetAbortFlag(1);
719   this->EndInteraction();
720   this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
721   this->Interactor->Render();
722 }
723 
724 //----------------------------------------------------------------------------
OnMouseMove()725 void vtkImplicitPlaneWidget::OnMouseMove()
726 {
727   // See whether we're active
728   if ( this->State == vtkImplicitPlaneWidget::Outside ||
729        this->State == vtkImplicitPlaneWidget::Start )
730     {
731     return;
732     }
733 
734   int X = this->Interactor->GetEventPosition()[0];
735   int Y = this->Interactor->GetEventPosition()[1];
736 
737   // Do different things depending on state
738   // Calculations everybody does
739   double focalPoint[4], pickPoint[4], prevPickPoint[4];
740   double z, vpn[3];
741 
742   vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
743   if ( !camera )
744     {
745     return;
746     }
747 
748   // Compute the two points defining the motion vector
749   this->ComputeWorldToDisplay(this->LastPickPosition[0], this->LastPickPosition[1],
750                               this->LastPickPosition[2], focalPoint);
751   z = focalPoint[2];
752   this->ComputeDisplayToWorld(double(this->Interactor->GetLastEventPosition()[0]),
753                               double(this->Interactor->GetLastEventPosition()[1]),
754                               z, prevPickPoint);
755   this->ComputeDisplayToWorld(double(X), double(Y), z, pickPoint);
756 
757   // Process the motion
758   if ( this->State == vtkImplicitPlaneWidget::MovingPlane )
759     {
760     this->TranslatePlane(prevPickPoint, pickPoint);
761     }
762   else if ( this->State == vtkImplicitPlaneWidget::MovingOutline )
763     {
764     this->TranslateOutline(prevPickPoint, pickPoint);
765     }
766   else if ( this->State == vtkImplicitPlaneWidget::MovingOrigin )
767     {
768     this->TranslateOrigin(prevPickPoint, pickPoint);
769     }
770   else if ( this->State == vtkImplicitPlaneWidget::Pushing )
771     {
772     this->Push(prevPickPoint, pickPoint);
773     }
774   else if ( this->State == vtkImplicitPlaneWidget::Scaling )
775     {
776     this->Scale(prevPickPoint, pickPoint, X, Y);
777     }
778   else if ( this->State == vtkImplicitPlaneWidget::Rotating )
779     {
780     camera->GetViewPlaneNormal(vpn);
781     this->Rotate(X, Y, prevPickPoint, pickPoint, vpn);
782     }
783 
784   // Interact, if desired
785   this->EventCallbackCommand->SetAbortFlag(1);
786   this->InvokeEvent(vtkCommand::InteractionEvent,NULL);
787 
788   this->Interactor->Render();
789 }
790 
791 //----------------------------------------------------------------------------
Rotate(int X,int Y,double * p1,double * p2,double * vpn)792 void vtkImplicitPlaneWidget::Rotate(int X, int Y, double *p1, double *p2, double *vpn)
793 {
794   double v[3]; //vector of motion
795   double axis[3]; //axis of rotation
796   double theta; //rotation angle
797 
798   // mouse motion vector in world space
799   v[0] = p2[0] - p1[0];
800   v[1] = p2[1] - p1[1];
801   v[2] = p2[2] - p1[2];
802 
803   double *origin = this->Plane->GetOrigin();
804   double *normal = this->Plane->GetNormal();
805 
806   // Create axis of rotation and angle of rotation
807   vtkMath::Cross(vpn,v,axis);
808   if ( vtkMath::Normalize(axis) == 0.0 )
809     {
810     return;
811     }
812   int *size = this->CurrentRenderer->GetSize();
813   double l2 = (X-this->Interactor->GetLastEventPosition()[0])
814              *(X-this->Interactor->GetLastEventPosition()[0])
815              +(Y-this->Interactor->GetLastEventPosition()[1])
816              *(Y-this->Interactor->GetLastEventPosition()[1]);
817   theta = 360.0 * sqrt(l2/(size[0]*size[0]+size[1]*size[1]));
818 
819   //Manipulate the transform to reflect the rotation
820   this->Transform->Identity();
821   this->Transform->Translate(origin[0],origin[1],origin[2]);
822   this->Transform->RotateWXYZ(theta,axis);
823   this->Transform->Translate(-origin[0],-origin[1],-origin[2]);
824 
825   //Set the new normal
826   double nNew[3];
827   this->Transform->TransformNormal(normal,nNew);
828   this->Plane->SetNormal(nNew);
829 
830   this->UpdateRepresentation();
831 }
832 
833 //----------------------------------------------------------------------------
834 // Loop through all points and translate them
TranslatePlane(double * p1,double * p2)835 void vtkImplicitPlaneWidget::TranslatePlane(double *p1, double *p2)
836 {
837   //Get the motion vector
838   double v[3];
839   v[0] = p2[0] - p1[0];
840   v[1] = p2[1] - p1[1];
841   v[2] = p2[2] - p1[2];
842 
843   //Translate the plane
844   double oNew[3];
845   double *origin = this->Plane->GetOrigin();
846   oNew[0] = origin[0] + v[0];
847   oNew[1] = origin[1] + v[1];
848   oNew[2] = origin[2] + v[2];
849   this->Plane->SetOrigin(oNew);
850 
851   this->UpdateRepresentation();
852 }
853 
854 //----------------------------------------------------------------------------
855 // Loop through all points and translate them
TranslateOutline(double * p1,double * p2)856 void vtkImplicitPlaneWidget::TranslateOutline(double *p1, double *p2)
857 {
858   //Get the motion vector
859   double v[3];
860   v[0] = p2[0] - p1[0];
861   v[1] = p2[1] - p1[1];
862   v[2] = p2[2] - p1[2];
863 
864   //Translate the bounding box
865   double *origin = this->Box->GetOrigin();
866   double oNew[3];
867   oNew[0] = origin[0] + v[0];
868   oNew[1] = origin[1] + v[1];
869   oNew[2] = origin[2] + v[2];
870   this->Box->SetOrigin(oNew);
871 
872   //Translate the plane
873   origin = this->Plane->GetOrigin();
874   oNew[0] = origin[0] + v[0];
875   oNew[1] = origin[1] + v[1];
876   oNew[2] = origin[2] + v[2];
877   this->Plane->SetOrigin(oNew);
878 
879   this->UpdateRepresentation();
880 }
881 
882 //----------------------------------------------------------------------------
883 // Loop through all points and translate them
TranslateOrigin(double * p1,double * p2)884 void vtkImplicitPlaneWidget::TranslateOrigin(double *p1, double *p2)
885 {
886   //Get the motion vector
887   double v[3];
888   v[0] = p2[0] - p1[0];
889   v[1] = p2[1] - p1[1];
890   v[2] = p2[2] - p1[2];
891 
892   //Add to the current point, project back down onto plane
893   double *o = this->Plane->GetOrigin();
894   double *n = this->Plane->GetNormal();
895   double newOrigin[3];
896 
897   newOrigin[0] = o[0] + v[0];
898   newOrigin[1] = o[1] + v[1];
899   newOrigin[2] = o[2] + v[2];
900 
901   vtkPlane::ProjectPoint(newOrigin,o,n,newOrigin);
902   this->SetOrigin(newOrigin[0],newOrigin[1],newOrigin[2]);
903   this->UpdateRepresentation();
904 }
905 
906 //----------------------------------------------------------------------------
Scale(double * p1,double * p2,int vtkNotUsed (X),int Y)907 void vtkImplicitPlaneWidget::Scale(double *p1, double *p2,
908                                    int vtkNotUsed(X), int Y)
909 {
910   //Get the motion vector
911   double v[3];
912   v[0] = p2[0] - p1[0];
913   v[1] = p2[1] - p1[1];
914   v[2] = p2[2] - p1[2];
915 
916   double *o = this->Plane->GetOrigin();
917 
918   // Compute the scale factor
919   double sf = vtkMath::Norm(v) / this->Outline->GetOutput()->GetLength();
920   if ( Y > this->Interactor->GetLastEventPosition()[1] )
921     {
922     sf = 1.0 + sf;
923     }
924   else
925     {
926     sf = 1.0 - sf;
927     }
928 
929   this->Transform->Identity();
930   this->Transform->Translate(o[0],o[1],o[2]);
931   this->Transform->Scale(sf,sf,sf);
932   this->Transform->Translate(-o[0],-o[1],-o[2]);
933 
934   double *origin = this->Box->GetOrigin();
935   double *spacing = this->Box->GetSpacing();
936   double oNew[3], p[3], pNew[3];
937   p[0] = origin[0] + spacing[0];
938   p[1] = origin[1] + spacing[1];
939   p[2] = origin[2] + spacing[2];
940 
941   this->Transform->TransformPoint(origin,oNew);
942   this->Transform->TransformPoint(p,pNew);
943 
944   this->Box->SetOrigin(oNew);
945   this->Box->SetSpacing( (pNew[0]-oNew[0]),
946                          (pNew[1]-oNew[1]),
947                          (pNew[2]-oNew[2]) );
948 
949   this->UpdateRepresentation();
950 }
951 
952 //----------------------------------------------------------------------------
Push(double * p1,double * p2)953 void vtkImplicitPlaneWidget::Push(double *p1, double *p2)
954 {
955   //Get the motion vector
956   double v[3];
957   v[0] = p2[0] - p1[0];
958   v[1] = p2[1] - p1[1];
959   v[2] = p2[2] - p1[2];
960 
961   this->Plane->Push( vtkMath::Dot(v,this->Plane->GetNormal()) );
962   this->SetOrigin(this->Plane->GetOrigin());
963   this->UpdateRepresentation();
964 }
965 
966 //----------------------------------------------------------------------------
CreateDefaultProperties()967 void vtkImplicitPlaneWidget::CreateDefaultProperties()
968 {
969   // Normal properties
970   this->NormalProperty = vtkProperty::New();
971   this->NormalProperty->SetColor(1,1,1);
972   this->NormalProperty->SetLineWidth(2);
973 
974   this->SelectedNormalProperty = vtkProperty::New();
975   this->SelectedNormalProperty->SetColor(1,0,0);
976   this->NormalProperty->SetLineWidth(2);
977 
978   // Plane properties
979   this->PlaneProperty = vtkProperty::New();
980   this->PlaneProperty->SetAmbient(1.0);
981   this->PlaneProperty->SetAmbientColor(1.0,1.0,1.0);
982 
983   this->SelectedPlaneProperty = vtkProperty::New();
984   this->SelectedPlaneProperty->SetAmbient(1.0);
985   this->SelectedPlaneProperty->SetAmbientColor(0.0,1.0,0.0);
986   this->SelectedPlaneProperty->SetOpacity(0.25);
987 
988   // Outline properties
989   this->OutlineProperty = vtkProperty::New();
990   this->OutlineProperty->SetAmbient(1.0);
991   this->OutlineProperty->SetAmbientColor(1.0,1.0,1.0);
992 
993   this->SelectedOutlineProperty = vtkProperty::New();
994   this->SelectedOutlineProperty->SetAmbient(1.0);
995   this->SelectedOutlineProperty->SetAmbientColor(0.0,1.0,0.0);
996 
997   // Edge property
998   this->EdgesProperty = vtkProperty::New();
999 }
1000 
1001 //------------------------------------------------------------------------------
RegisterPickers()1002 void vtkImplicitPlaneWidget::RegisterPickers()
1003 {
1004   this->Interactor->GetPickingManager()->AddPicker(this->Picker, this);
1005 }
1006 
1007 //----------------------------------------------------------------------------
PlaceWidget(double bds[6])1008 void vtkImplicitPlaneWidget::PlaceWidget(double bds[6])
1009 {
1010   int i;
1011   double bounds[6], origin[3];
1012 
1013   this->AdjustBounds(bds, bounds, origin);
1014 
1015   // Set up the bounding box
1016   this->Box->SetOrigin(bounds[0],bounds[2],bounds[4]);
1017   this->Box->SetSpacing((bounds[1]-bounds[0]),(bounds[3]-bounds[2]),
1018                         (bounds[5]-bounds[4]));
1019   this->Outline->Update();
1020 
1021   this->LineSource->SetPoint1(this->Plane->GetOrigin());
1022   if ( this->NormalToYAxis )
1023     {
1024     this->Plane->SetNormal(0,1,0);
1025     this->LineSource->SetPoint2(0,1,0);
1026     }
1027   else if ( this->NormalToZAxis )
1028     {
1029     this->Plane->SetNormal(0,0,1);
1030     this->LineSource->SetPoint2(0,0,1);
1031     }
1032   else //default or x-normal
1033     {
1034     this->Plane->SetNormal(1,0,0);
1035     this->LineSource->SetPoint2(1,0,0);
1036     }
1037 
1038   for (i=0; i<6; i++)
1039     {
1040     this->InitialBounds[i] = bounds[i];
1041     }
1042 
1043   this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
1044                              (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
1045                              (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
1046 
1047   this->UpdateRepresentation();
1048 
1049   this->SizeHandles();
1050 }
1051 
1052 //----------------------------------------------------------------------------
1053 // Description:
1054 // Set the origin of the plane.
SetOrigin(double x,double y,double z)1055 void vtkImplicitPlaneWidget::SetOrigin(double x, double y, double z)
1056 {
1057   double origin[3];
1058   origin[0] = x;
1059   origin[1] = y;
1060   origin[2] = z;
1061   this->SetOrigin(origin);
1062 }
1063 
1064 //----------------------------------------------------------------------------
1065 // Description:
1066 // Set the origin of the plane.
SetOrigin(double x[3])1067 void vtkImplicitPlaneWidget::SetOrigin(double x[3])
1068 {
1069   double *bounds = this->Outline->GetOutput()->GetBounds();
1070   for (int i=0; i<3; i++)
1071     {
1072     if ( x[i] < bounds[2*i] )
1073       {
1074       x[i] = bounds[2*i];
1075       }
1076     else if ( x[i] > bounds[2*i+1] )
1077       {
1078       x[i] = bounds[2*i+1];
1079       }
1080     }
1081   this->Plane->SetOrigin(x);
1082   this->UpdateRepresentation();
1083 }
1084 
1085 //----------------------------------------------------------------------------
1086 // Description:
1087 // Get the origin of the plane.
GetOrigin()1088 double* vtkImplicitPlaneWidget::GetOrigin()
1089 {
1090   return this->Plane->GetOrigin();
1091 }
1092 
1093 //----------------------------------------------------------------------------
GetOrigin(double xyz[3])1094 void vtkImplicitPlaneWidget::GetOrigin(double xyz[3])
1095 {
1096   this->Plane->GetOrigin(xyz);
1097 }
1098 
1099 //----------------------------------------------------------------------------
1100 // Description:
1101 // Set the normal to the plane.
SetNormal(double x,double y,double z)1102 void vtkImplicitPlaneWidget::SetNormal(double x, double y, double z)
1103 {
1104   double n[3];
1105   n[0] = x;
1106   n[1] = y;
1107   n[2] = z;
1108   vtkMath::Normalize(n);
1109   this->Plane->SetNormal(n);
1110   this->UpdateRepresentation();
1111 }
1112 
1113 //----------------------------------------------------------------------------
1114 // Description:
1115 // Set the normal to the plane.
SetNormal(double n[3])1116 void vtkImplicitPlaneWidget::SetNormal(double n[3])
1117 {
1118   this->SetNormal(n[0], n[1], n[2]);
1119 }
1120 
1121 //----------------------------------------------------------------------------
1122 // Description:
1123 // Get the normal to the plane.
GetNormal()1124 double* vtkImplicitPlaneWidget::GetNormal()
1125 {
1126   return this->Plane->GetNormal();
1127 }
1128 
1129 //----------------------------------------------------------------------------
GetNormal(double xyz[3])1130 void vtkImplicitPlaneWidget::GetNormal(double xyz[3])
1131 {
1132   this->Plane->GetNormal(xyz);
1133 }
1134 
1135 //----------------------------------------------------------------------------
SetDrawPlane(int drawPlane)1136 void vtkImplicitPlaneWidget::SetDrawPlane(int drawPlane)
1137 {
1138   if ( drawPlane == this->DrawPlane )
1139     {
1140     return;
1141     }
1142 
1143   this->Modified();
1144   this->DrawPlane = drawPlane;
1145   if ( this->Enabled )
1146     {
1147     if ( drawPlane )
1148       {
1149       this->CurrentRenderer->AddActor(this->CutActor);
1150       }
1151     else
1152       {
1153       this->CurrentRenderer->RemoveActor(this->CutActor);
1154       }
1155     this->Interactor->Render();
1156     }
1157 }
1158 
1159 //----------------------------------------------------------------------------
SetNormalToXAxis(int var)1160 void vtkImplicitPlaneWidget::SetNormalToXAxis (int var)
1161 {
1162   if (this->NormalToXAxis != var)
1163     {
1164     this->NormalToXAxis = var;
1165     this->Modified();
1166     }
1167   if (var)
1168     {
1169     this->NormalToYAxisOff();
1170     this->NormalToZAxisOff();
1171     }
1172 }
1173 
1174 //----------------------------------------------------------------------------
SetNormalToYAxis(int var)1175 void vtkImplicitPlaneWidget::SetNormalToYAxis (int var)
1176 {
1177   if (this->NormalToYAxis != var)
1178     {
1179     this->NormalToYAxis = var;
1180     this->Modified();
1181     }
1182   if (var)
1183     {
1184     this->NormalToXAxisOff();
1185     this->NormalToZAxisOff();
1186     }
1187 }
1188 
1189 //----------------------------------------------------------------------------
SetNormalToZAxis(int var)1190 void vtkImplicitPlaneWidget::SetNormalToZAxis (int var)
1191 {
1192   if (this->NormalToZAxis != var)
1193     {
1194     this->NormalToZAxis = var;
1195     this->Modified();
1196     }
1197   if (var)
1198     {
1199     this->NormalToXAxisOff();
1200     this->NormalToYAxisOff();
1201     }
1202 }
1203 
1204 //----------------------------------------------------------------------------
GetPolyData(vtkPolyData * pd)1205 void vtkImplicitPlaneWidget::GetPolyData(vtkPolyData *pd)
1206 {
1207   pd->ShallowCopy(this->Cutter->GetOutput());
1208 }
1209 
1210 //----------------------------------------------------------------------------
GetPolyDataAlgorithm()1211 vtkPolyDataAlgorithm *vtkImplicitPlaneWidget::GetPolyDataAlgorithm()
1212 {
1213   return this->Cutter;
1214 }
1215 
1216 //----------------------------------------------------------------------------
GetPlane(vtkPlane * plane)1217 void vtkImplicitPlaneWidget::GetPlane(vtkPlane *plane)
1218 {
1219   if ( plane == NULL )
1220     {
1221     return;
1222     }
1223 
1224   plane->SetNormal(this->Plane->GetNormal());
1225   plane->SetOrigin(this->Plane->GetOrigin());
1226 }
1227 
1228 //----------------------------------------------------------------------------
UpdatePlacement()1229 void vtkImplicitPlaneWidget::UpdatePlacement()
1230 {
1231   this->Outline->Update();
1232   this->Cutter->Update();
1233   this->Edges->Update();
1234   this->UpdateRepresentation();
1235 }
1236 
1237 //----------------------------------------------------------------------------
UpdateRepresentation()1238 void vtkImplicitPlaneWidget::UpdateRepresentation()
1239 {
1240   if ( ! this->CurrentRenderer )
1241     {
1242     return;
1243     }
1244 
1245   double *origin = this->Plane->GetOrigin();
1246   double *normal = this->Plane->GetNormal();
1247   double p2[3];
1248   if( !this->OutsideBounds )
1249     {
1250     double *bounds = this->GetInput()->GetBounds();
1251     for (int i=0; i<3; i++)
1252       {
1253       if ( origin[i] < bounds[2*i] )
1254         {
1255         origin[i] = bounds[2*i];
1256         }
1257       else if ( origin[i] > bounds[2*i+1] )
1258         {
1259         origin[i] = bounds[2*i+1];
1260         }
1261       }
1262     }
1263 
1264   // Setup the plane normal
1265   double d = this->Outline->GetOutput()->GetLength();
1266 
1267   const double ratio = this->DiagonalRatio;
1268   p2[0] = origin[0] + ratio * d * normal[0];
1269   p2[1] = origin[1] + ratio * d * normal[1];
1270   p2[2] = origin[2] + ratio * d * normal[2];
1271 
1272   this->LineSource->SetPoint1(origin);
1273   this->LineSource->SetPoint2(p2);
1274   this->ConeSource->SetCenter(p2);
1275   this->ConeSource->SetDirection(normal);
1276 
1277   p2[0] = origin[0] - ratio * d * normal[0];
1278   p2[1] = origin[1] - ratio * d * normal[1];
1279   p2[2] = origin[2] - ratio * d * normal[2];
1280 
1281   this->LineSource2->SetPoint1(origin[0],origin[1],origin[2]);
1282   this->LineSource2->SetPoint2(p2);
1283   this->ConeSource2->SetCenter(p2);
1284   this->ConeSource2->SetDirection(normal[0],normal[1],normal[2]);
1285 
1286   // Set up the position handle
1287   this->Sphere->SetCenter(origin[0],origin[1],origin[2]);
1288 
1289   // Control the look of the edges
1290   if ( this->Tubing )
1291     {
1292     this->EdgesMapper->SetInputConnection(
1293       this->EdgesTuber->GetOutputPort());
1294     }
1295   else
1296     {
1297     this->EdgesMapper->SetInputConnection(
1298       this->Edges->GetOutputPort());
1299     }
1300 }
1301 
1302 //----------------------------------------------------------------------------
SizeHandles()1303 void vtkImplicitPlaneWidget::SizeHandles()
1304 {
1305   double radius = this->vtk3DWidget::SizeHandles(1.35);
1306 
1307   this->ConeSource->SetHeight(2.0*radius);
1308   this->ConeSource->SetRadius(radius);
1309   this->ConeSource2->SetHeight(2.0*radius);
1310   this->ConeSource2->SetRadius(radius);
1311 
1312   this->Sphere->SetRadius(radius);
1313 
1314   this->EdgesTuber->SetRadius(0.25*radius);
1315 }
1316