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