1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkPlaneWidget.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 "vtkPlaneWidget.h"
16 
17 #include "vtkActor.h"
18 #include "vtkAssemblyNode.h"
19 #include "vtkAssemblyPath.h"
20 #include "vtkCallbackCommand.h"
21 #include "vtkCamera.h"
22 #include "vtkCellArray.h"
23 #include "vtkCellPicker.h"
24 #include "vtkConeSource.h"
25 #include "vtkDoubleArray.h"
26 #include "vtkFloatArray.h"
27 #include "vtkLineSource.h"
28 #include "vtkMath.h"
29 #include "vtkObjectFactory.h"
30 #include "vtkPickingManager.h"
31 #include "vtkPlane.h"
32 #include "vtkPlaneSource.h"
33 #include "vtkPlanes.h"
34 #include "vtkPolyData.h"
35 #include "vtkPolyDataMapper.h"
36 #include "vtkProperty.h"
37 #include "vtkRenderWindowInteractor.h"
38 #include "vtkRenderer.h"
39 #include "vtkSphereSource.h"
40 #include "vtkTransform.h"
41 
42 vtkStandardNewMacro(vtkPlaneWidget);
43 
44 vtkCxxSetObjectMacro(vtkPlaneWidget,PlaneProperty,vtkProperty);
45 
vtkPlaneWidget()46 vtkPlaneWidget::vtkPlaneWidget() : vtkPolyDataSourceWidget()
47 {
48   this->State = vtkPlaneWidget::Start;
49   this->EventCallbackCommand->SetCallback(vtkPlaneWidget::ProcessEvents);
50 
51   this->NormalToXAxis = 0;
52   this->NormalToYAxis = 0;
53   this->NormalToZAxis = 0;
54   this->Representation = VTK_PLANE_WIREFRAME;
55 
56   //Build the representation of the widget
57   int i;
58   // Represent the plane
59   this->PlaneSource = vtkPlaneSource::New();
60   this->PlaneSource->SetXResolution(4);
61   this->PlaneSource->SetYResolution(4);
62   this->PlaneOutline = vtkPolyData::New();
63   vtkPoints *pts = vtkPoints::New();
64   pts->SetNumberOfPoints(4);
65   vtkCellArray *outline = vtkCellArray::New();
66   outline->InsertNextCell(4);
67   outline->InsertCellPoint(0);
68   outline->InsertCellPoint(1);
69   outline->InsertCellPoint(2);
70   outline->InsertCellPoint(3);
71   this->PlaneOutline->SetPoints(pts);
72   pts->Delete();
73   this->PlaneOutline->SetPolys(outline);
74   outline->Delete();
75   this->PlaneMapper = vtkPolyDataMapper::New();
76   this->PlaneMapper->SetInputConnection(
77     this->PlaneSource->GetOutputPort());
78   this->PlaneActor = vtkActor::New();
79   this->PlaneActor->SetMapper(this->PlaneMapper);
80 
81   // Create the handles
82   this->Handle = new vtkActor* [4];
83   this->HandleMapper = new vtkPolyDataMapper* [4];
84   this->HandleGeometry = new vtkSphereSource* [4];
85   for (i=0; i<4; i++)
86     {
87     this->HandleGeometry[i] = vtkSphereSource::New();
88     this->HandleGeometry[i]->SetThetaResolution(16);
89     this->HandleGeometry[i]->SetPhiResolution(8);
90     this->HandleMapper[i] = vtkPolyDataMapper::New();
91     this->HandleMapper[i]->SetInputConnection(
92       this->HandleGeometry[i]->GetOutputPort());
93     this->Handle[i] = vtkActor::New();
94     this->Handle[i]->SetMapper(this->HandleMapper[i]);
95     }
96 
97   // Create the + plane normal
98   this->LineSource = vtkLineSource::New();
99   this->LineSource->SetResolution(1);
100   this->LineMapper = vtkPolyDataMapper::New();
101   this->LineMapper->SetInputConnection(
102     this->LineSource->GetOutputPort());
103   this->LineActor = vtkActor::New();
104   this->LineActor->SetMapper(this->LineMapper);
105 
106   this->ConeSource = vtkConeSource::New();
107   this->ConeSource->SetResolution(12);
108   this->ConeSource->SetAngle(25.0);
109   this->ConeMapper = vtkPolyDataMapper::New();
110   this->ConeMapper->SetInputConnection(
111     this->ConeSource->GetOutputPort());
112   this->ConeActor = vtkActor::New();
113   this->ConeActor->SetMapper(this->ConeMapper);
114 
115   // Create the - plane normal
116   this->LineSource2 = vtkLineSource::New();
117   this->LineSource2->SetResolution(1);
118   this->LineMapper2 = vtkPolyDataMapper::New();
119   this->LineMapper2->SetInputConnection(
120     this->LineSource2->GetOutputPort());
121   this->LineActor2 = vtkActor::New();
122   this->LineActor2->SetMapper(this->LineMapper2);
123 
124   this->ConeSource2 = vtkConeSource::New();
125   this->ConeSource2->SetResolution(12);
126   this->ConeSource2->SetAngle(25.0);
127   this->ConeMapper2 = vtkPolyDataMapper::New();
128   this->ConeMapper2->SetInputConnection(
129     this->ConeSource2->GetOutputPort());
130   this->ConeActor2 = vtkActor::New();
131   this->ConeActor2->SetMapper(this->ConeMapper2);
132 
133   this->Transform = vtkTransform::New();
134 
135   // Define the point coordinates
136   double bounds[6];
137   bounds[0] = -0.5;
138   bounds[1] = 0.5;
139   bounds[2] = -0.5;
140   bounds[3] = 0.5;
141   bounds[4] = -0.5;
142   bounds[5] = 0.5;
143 
144   //Manage the picking stuff
145   this->HandlePicker = vtkCellPicker::New();
146   this->HandlePicker->SetTolerance(0.001);
147   for (i=0; i<4; i++)
148     {
149     this->HandlePicker->AddPickList(this->Handle[i]);
150     }
151   this->HandlePicker->PickFromListOn();
152 
153   this->PlanePicker = vtkCellPicker::New();
154   this->PlanePicker->SetTolerance(0.005); //need some fluff
155   this->PlanePicker->AddPickList(this->PlaneActor);
156   this->PlanePicker->AddPickList(this->ConeActor);
157   this->PlanePicker->AddPickList(this->LineActor);
158   this->PlanePicker->AddPickList(this->ConeActor2);
159   this->PlanePicker->AddPickList(this->LineActor2);
160   this->PlanePicker->PickFromListOn();
161 
162   this->CurrentHandle = NULL;
163 
164   this->LastPickValid = 0;
165   this->HandleSizeFactor = 1.25;
166   this->SetHandleSize( 0.05 );
167 
168   // Set up the initial properties
169   this->CreateDefaultProperties();
170 
171   this->SelectRepresentation();
172 
173   // Initial creation of the widget, serves to initialize it
174   // Call PlaceWidget() LAST in the constructor as it depends on ivar
175   // values.
176   this->PlaceWidget(bounds);
177 }
178 
~vtkPlaneWidget()179 vtkPlaneWidget::~vtkPlaneWidget()
180 {
181   this->PlaneActor->Delete();
182   this->PlaneMapper->Delete();
183   this->PlaneSource->Delete();
184   this->PlaneOutline->Delete();
185 
186   for (int i=0; i<4; i++)
187     {
188     this->HandleGeometry[i]->Delete();
189     this->HandleMapper[i]->Delete();
190     this->Handle[i]->Delete();
191     }
192   delete [] this->Handle;
193   delete [] this->HandleMapper;
194   delete [] this->HandleGeometry;
195 
196   this->ConeActor->Delete();
197   this->ConeMapper->Delete();
198   this->ConeSource->Delete();
199 
200   this->LineActor->Delete();
201   this->LineMapper->Delete();
202   this->LineSource->Delete();
203 
204   this->ConeActor2->Delete();
205   this->ConeMapper2->Delete();
206   this->ConeSource2->Delete();
207 
208   this->LineActor2->Delete();
209   this->LineMapper2->Delete();
210   this->LineSource2->Delete();
211 
212   this->HandlePicker->Delete();
213   this->PlanePicker->Delete();
214 
215   if (this->HandleProperty)
216     {
217     this->HandleProperty->Delete();
218     this->HandleProperty = 0;
219     }
220 
221   if (this->SelectedHandleProperty)
222     {
223     this->SelectedHandleProperty->Delete();
224     this->SelectedHandleProperty = 0;
225     }
226 
227   if (this->PlaneProperty)
228     {
229     this->PlaneProperty->Delete();
230     this->PlaneProperty = 0;
231     }
232 
233   if (this->SelectedPlaneProperty)
234     {
235     this->SelectedPlaneProperty->Delete();
236     this->SelectedPlaneProperty = 0;
237     }
238 
239   this->Transform->Delete();
240 }
241 
SetEnabled(int enabling)242 void vtkPlaneWidget::SetEnabled(int enabling)
243 {
244   if ( ! this->Interactor )
245     {
246     vtkErrorMacro(<<"The interactor must be set prior to enabling/disabling widget");
247     return;
248     }
249 
250   if ( enabling ) //-----------------------------------------------------------
251     {
252     vtkDebugMacro(<<"Enabling plane widget");
253 
254     if ( this->Enabled ) //already enabled, just return
255       {
256       return;
257       }
258 
259     if ( ! this->CurrentRenderer )
260       {
261       this->SetCurrentRenderer(this->Interactor->FindPokedRenderer(
262         this->Interactor->GetLastEventPosition()[0],
263         this->Interactor->GetLastEventPosition()[1]));
264       if (this->CurrentRenderer == NULL)
265         {
266         return;
267         }
268       }
269 
270     this->Enabled = 1;
271 
272     // listen for the following events
273     vtkRenderWindowInteractor *i = this->Interactor;
274     i->AddObserver(vtkCommand::MouseMoveEvent, this->EventCallbackCommand,
275                    this->Priority);
276     i->AddObserver(vtkCommand::LeftButtonPressEvent,
277                    this->EventCallbackCommand, this->Priority);
278     i->AddObserver(vtkCommand::LeftButtonReleaseEvent,
279                    this->EventCallbackCommand, this->Priority);
280     i->AddObserver(vtkCommand::MiddleButtonPressEvent,
281                    this->EventCallbackCommand, this->Priority);
282     i->AddObserver(vtkCommand::MiddleButtonReleaseEvent,
283                    this->EventCallbackCommand, this->Priority);
284     i->AddObserver(vtkCommand::RightButtonPressEvent,
285                    this->EventCallbackCommand, this->Priority);
286     i->AddObserver(vtkCommand::RightButtonReleaseEvent,
287                    this->EventCallbackCommand, this->Priority);
288 
289     // Add the plane
290     this->CurrentRenderer->AddActor(this->PlaneActor);
291     this->PlaneActor->SetProperty(this->PlaneProperty);
292 
293     // turn on the handles
294     for (int j=0; j<4; j++)
295       {
296       this->CurrentRenderer->AddActor(this->Handle[j]);
297       this->Handle[j]->SetProperty(this->HandleProperty);
298       }
299 
300     // add the normal vector
301     this->CurrentRenderer->AddActor(this->LineActor);
302     this->LineActor->SetProperty(this->HandleProperty);
303     this->CurrentRenderer->AddActor(this->ConeActor);
304     this->ConeActor->SetProperty(this->HandleProperty);
305     this->CurrentRenderer->AddActor(this->LineActor2);
306     this->LineActor2->SetProperty(this->HandleProperty);
307     this->CurrentRenderer->AddActor(this->ConeActor2);
308     this->ConeActor2->SetProperty(this->HandleProperty);
309 
310     this->SelectRepresentation();
311     this->InvokeEvent(vtkCommand::EnableEvent,NULL);
312     }
313 
314   else //disabling----------------------------------------------------------
315     {
316     vtkDebugMacro(<<"Disabling plane widget");
317 
318     if ( ! this->Enabled ) //already disabled, just return
319       {
320       return;
321       }
322 
323     this->Enabled = 0;
324 
325     // don't listen for events any more
326     this->Interactor->RemoveObserver(this->EventCallbackCommand);
327 
328     // turn off the plane
329     this->CurrentRenderer->RemoveActor(this->PlaneActor);
330 
331     // turn off the handles
332     for (int i=0; i<4; i++)
333       {
334       this->CurrentRenderer->RemoveActor(this->Handle[i]);
335       }
336 
337     // turn off the normal vector
338     this->CurrentRenderer->RemoveActor(this->LineActor);
339     this->CurrentRenderer->RemoveActor(this->ConeActor);
340     this->CurrentRenderer->RemoveActor(this->LineActor2);
341     this->CurrentRenderer->RemoveActor(this->ConeActor2);
342 
343     this->CurrentHandle = NULL;
344     this->InvokeEvent(vtkCommand::DisableEvent,NULL);
345     this->SetCurrentRenderer(NULL);
346     }
347 
348   this->Interactor->Render();
349 }
350 
351 //------------------------------------------------------------------------------
RegisterPickers()352 void vtkPlaneWidget::RegisterPickers()
353 {
354   this->Interactor->GetPickingManager()->AddPicker(this->HandlePicker, this);
355   this->Interactor->GetPickingManager()->AddPicker(this->PlanePicker, this);
356 }
357 
ProcessEvents(vtkObject * vtkNotUsed (object),unsigned long event,void * clientdata,void * vtkNotUsed (calldata))358 void vtkPlaneWidget::ProcessEvents(vtkObject* vtkNotUsed(object),
359                                    unsigned long event,
360                                    void* clientdata,
361                                    void* vtkNotUsed(calldata))
362 {
363   vtkPlaneWidget* self = reinterpret_cast<vtkPlaneWidget *>( clientdata );
364 
365   //okay, let's do the right thing
366   switch(event)
367     {
368     case vtkCommand::LeftButtonPressEvent:
369       self->OnLeftButtonDown();
370       break;
371     case vtkCommand::LeftButtonReleaseEvent:
372       self->OnLeftButtonUp();
373       break;
374     case vtkCommand::MiddleButtonPressEvent:
375       self->OnMiddleButtonDown();
376       break;
377     case vtkCommand::MiddleButtonReleaseEvent:
378       self->OnMiddleButtonUp();
379       break;
380     case vtkCommand::RightButtonPressEvent:
381       self->OnRightButtonDown();
382       break;
383     case vtkCommand::RightButtonReleaseEvent:
384       self->OnRightButtonUp();
385       break;
386     case vtkCommand::MouseMoveEvent:
387       self->OnMouseMove();
388       break;
389     }
390 }
391 
PrintSelf(ostream & os,vtkIndent indent)392 void vtkPlaneWidget::PrintSelf(ostream& os, vtkIndent indent)
393 {
394   this->Superclass::PrintSelf(os,indent);
395 
396   if ( this->HandleProperty )
397     {
398     os << indent << "Handle Property: " << this->HandleProperty << "\n";
399     }
400   else
401     {
402     os << indent << "Handle Property: (none)\n";
403     }
404   if ( this->SelectedHandleProperty )
405     {
406     os << indent << "Selected Handle Property: "
407        << this->SelectedHandleProperty << "\n";
408     }
409   else
410     {
411     os << indent << "SelectedHandle Property: (none)\n";
412     }
413 
414   if ( this->PlaneProperty )
415     {
416     os << indent << "Plane Property: " << this->PlaneProperty << "\n";
417     }
418   else
419     {
420     os << indent << "Plane Property: (none)\n";
421     }
422   if ( this->SelectedPlaneProperty )
423     {
424     os << indent << "Selected Plane Property: "
425        << this->SelectedPlaneProperty << "\n";
426     }
427   else
428     {
429     os << indent << "Selected Plane Property: (none)\n";
430     }
431 
432   os << indent << "Plane Representation: ";
433   if ( this->Representation == VTK_PLANE_WIREFRAME )
434     {
435     os << "Wireframe\n";
436     }
437   else if ( this->Representation == VTK_PLANE_SURFACE )
438     {
439     os << "Surface\n";
440     }
441   else //( this->Representation == VTK_PLANE_OUTLINE )
442     {
443     os << "Outline\n";
444     }
445 
446   os << indent << "Normal To X Axis: "
447      << (this->NormalToXAxis ? "On" : "Off") << "\n";
448   os << indent << "Normal To Y Axis: "
449      << (this->NormalToYAxis ? "On" : "Off") << "\n";
450   os << indent << "Normal To Z Axis: "
451      << (this->NormalToZAxis ? "On" : "Off") << "\n";
452 
453   int res = this->PlaneSource->GetXResolution();
454   double *o = this->PlaneSource->GetOrigin();
455   double *pt1 = this->PlaneSource->GetPoint1();
456   double *pt2 = this->PlaneSource->GetPoint2();
457 
458   os << indent << "Resolution: " << res << "\n";
459   os << indent << "Origin: (" << o[0] << ", "
460      << o[1] << ", "
461      << o[2] << ")\n";
462   os << indent << "Point 1: (" << pt1[0] << ", "
463      << pt1[1] << ", "
464      << pt1[2] << ")\n";
465   os << indent << "Point 2: (" << pt2[0] << ", "
466      << pt2[1] << ", "
467      << pt2[2] << ")\n";
468 }
469 
PositionHandles()470 void vtkPlaneWidget::PositionHandles()
471 {
472   double *o = this->PlaneSource->GetOrigin();
473   double *pt1 = this->PlaneSource->GetPoint1();
474   double *pt2 = this->PlaneSource->GetPoint2();
475 
476   this->HandleGeometry[0]->SetCenter(o);
477   this->HandleGeometry[1]->SetCenter(pt1);
478   this->HandleGeometry[2]->SetCenter(pt2);
479 
480   double x[3];
481   x[0] = pt1[0] + pt2[0] - o[0];
482   x[1] = pt1[1] + pt2[1] - o[1];
483   x[2] = pt1[2] + pt2[2] - o[2];
484   this->HandleGeometry[3]->SetCenter(x); //far corner
485 
486   // set up the outline
487   if ( this->Representation == VTK_PLANE_OUTLINE )
488     {
489     this->PlaneOutline->GetPoints()->SetPoint(0,o);
490     this->PlaneOutline->GetPoints()->SetPoint(1,pt1);
491     this->PlaneOutline->GetPoints()->SetPoint(2,x);
492     this->PlaneOutline->GetPoints()->SetPoint(3,pt2);
493     this->PlaneOutline->Modified();
494     }
495   this->SelectRepresentation();
496 
497   // Create the normal vector
498   double center[3];
499   this->PlaneSource->GetCenter(center);
500   this->LineSource->SetPoint1(center);
501   this->LineSource2->SetPoint1(center);
502   double p2[3];
503   this->PlaneSource->GetNormal(this->Normal);
504   vtkMath::Normalize(this->Normal);
505   double d = sqrt(
506     vtkMath::Distance2BetweenPoints(
507       this->PlaneSource->GetPoint1(),this->PlaneSource->GetPoint2()) );
508 
509   p2[0] = center[0] + 0.35 * d * this->Normal[0];
510   p2[1] = center[1] + 0.35 * d * this->Normal[1];
511   p2[2] = center[2] + 0.35 * d * this->Normal[2];
512   this->LineSource->SetPoint2(p2);
513   this->ConeSource->SetCenter(p2);
514   this->ConeSource->SetDirection(this->Normal);
515 
516   p2[0] = center[0] - 0.35 * d * this->Normal[0];
517   p2[1] = center[1] - 0.35 * d * this->Normal[1];
518   p2[2] = center[2] - 0.35 * d * this->Normal[2];
519   this->LineSource2->SetPoint2(p2);
520   this->ConeSource2->SetCenter(p2);
521   this->ConeSource2->SetDirection(this->Normal);
522 }
523 
HighlightHandle(vtkProp * prop)524 int vtkPlaneWidget::HighlightHandle(vtkProp *prop)
525 {
526   // first unhighlight anything picked
527   if ( this->CurrentHandle )
528     {
529     this->CurrentHandle->SetProperty(this->HandleProperty);
530     }
531 
532   this->CurrentHandle = static_cast<vtkActor *>(prop);
533 
534   if ( this->CurrentHandle )
535     {
536     this->ValidPick = 1;
537     this->HandlePicker->GetPickPosition(this->LastPickPosition);
538     this->CurrentHandle->SetProperty(this->SelectedHandleProperty);
539     for (int i=0; i<4; i++) //find handle
540       {
541       if ( this->CurrentHandle == this->Handle[i] )
542         {
543         return i;
544         }
545       }
546     }
547 
548   return -1;
549 }
550 
HighlightNormal(int highlight)551 void vtkPlaneWidget::HighlightNormal(int highlight)
552 {
553   if ( highlight )
554     {
555     this->ValidPick = 1;
556     this->PlanePicker->GetPickPosition(this->LastPickPosition);
557     this->LineActor->SetProperty(this->SelectedHandleProperty);
558     this->ConeActor->SetProperty(this->SelectedHandleProperty);
559     this->LineActor2->SetProperty(this->SelectedHandleProperty);
560     this->ConeActor2->SetProperty(this->SelectedHandleProperty);
561     }
562   else
563     {
564     this->LineActor->SetProperty(this->HandleProperty);
565     this->ConeActor->SetProperty(this->HandleProperty);
566     this->LineActor2->SetProperty(this->HandleProperty);
567     this->ConeActor2->SetProperty(this->HandleProperty);
568     }
569 }
570 
HighlightPlane(int highlight)571 void vtkPlaneWidget::HighlightPlane(int highlight)
572 {
573   if ( highlight )
574     {
575     this->ValidPick = 1;
576     this->PlanePicker->GetPickPosition(this->LastPickPosition);
577     this->PlaneActor->SetProperty(this->SelectedPlaneProperty);
578     }
579   else
580     {
581     this->PlaneActor->SetProperty(this->PlaneProperty);
582     }
583 }
584 
OnLeftButtonDown()585 void vtkPlaneWidget::OnLeftButtonDown()
586 {
587   int X = this->Interactor->GetEventPosition()[0];
588   int Y = this->Interactor->GetEventPosition()[1];
589 
590   // Okay, make sure that the pick is in the current renderer
591   if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
592     {
593     this->State = vtkPlaneWidget::Outside;
594     return;
595     }
596 
597   // Okay, we can process this. Try to pick handles first;
598   // if no handles picked, then try to pick the plane.
599   vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
600 
601   if ( path != NULL )
602     {
603     this->State = vtkPlaneWidget::Moving;
604     this->HighlightHandle(path->GetFirstNode()->GetViewProp());
605     }
606   else
607     {
608     path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
609 
610     if ( path != NULL )
611       {
612       vtkProp *prop = path->GetFirstNode()->GetViewProp();
613       if ( prop == this->ConeActor || prop == this->LineActor ||
614            prop == this->ConeActor2 || prop == this->LineActor2 )
615         {
616         this->State = vtkPlaneWidget::Rotating;
617         this->HighlightNormal(1);
618         }
619       else if (this->Interactor->GetControlKey())
620         {
621         this->State = vtkPlaneWidget::Spinning;
622         this->HighlightNormal(1);
623         }
624       else
625         {
626         this->State = vtkPlaneWidget::Moving;
627         this->HighlightPlane(1);
628         }
629       }
630     else
631       {
632       this->State = vtkPlaneWidget::Outside;
633       this->HighlightHandle(NULL);
634       return;
635       }
636     }
637 
638   this->EventCallbackCommand->SetAbortFlag(1);
639   this->StartInteraction();
640   this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
641   this->Interactor->Render();
642 }
643 
OnLeftButtonUp()644 void vtkPlaneWidget::OnLeftButtonUp()
645 {
646   if ( this->State == vtkPlaneWidget::Outside ||
647        this->State == vtkPlaneWidget::Start )
648     {
649     return;
650     }
651 
652   this->State = vtkPlaneWidget::Start;
653   this->HighlightHandle(NULL);
654   this->HighlightPlane(0);
655   this->HighlightNormal(0);
656   this->SizeHandles();
657 
658   this->EventCallbackCommand->SetAbortFlag(1);
659   this->EndInteraction();
660   this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
661   this->Interactor->Render();
662 }
663 
OnMiddleButtonDown()664 void vtkPlaneWidget::OnMiddleButtonDown()
665 {
666   int X = this->Interactor->GetEventPosition()[0];
667   int Y = this->Interactor->GetEventPosition()[1];
668 
669   // Okay, make sure that the pick is in the current renderer
670   if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
671     {
672     this->State = vtkPlaneWidget::Outside;
673     return;
674     }
675 
676   // Okay, we can process this. If anything is picked, then we
677   // can start pushing the plane.
678   vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
679 
680   if ( path != NULL )
681     {
682     this->State = vtkPlaneWidget::Pushing;
683     this->HighlightPlane(1);
684     this->HighlightNormal(1);
685     this->HighlightHandle(path->GetFirstNode()->GetViewProp());
686     }
687   else
688     {
689     path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
690 
691     if ( path == NULL ) //nothing picked
692       {
693       this->State = vtkPlaneWidget::Outside;
694       return;
695       }
696     else
697       {
698       this->State = vtkPlaneWidget::Pushing;
699       this->HighlightNormal(1);
700       this->HighlightPlane(1);
701       }
702     }
703 
704   this->EventCallbackCommand->SetAbortFlag(1);
705   this->StartInteraction();
706   this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
707   this->Interactor->Render();
708 }
709 
OnMiddleButtonUp()710 void vtkPlaneWidget::OnMiddleButtonUp()
711 {
712   if ( this->State == vtkPlaneWidget::Outside ||
713        this->State == vtkPlaneWidget::Start )
714     {
715     return;
716     }
717 
718   this->State = vtkPlaneWidget::Start;
719   this->HighlightPlane(0);
720   this->HighlightNormal(0);
721   this->HighlightHandle(NULL);
722   this->SizeHandles();
723 
724   this->EventCallbackCommand->SetAbortFlag(1);
725   this->EndInteraction();
726   this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
727   this->Interactor->Render();
728 }
729 
OnRightButtonDown()730 void vtkPlaneWidget::OnRightButtonDown()
731 {
732   int X = this->Interactor->GetEventPosition()[0];
733   int Y = this->Interactor->GetEventPosition()[1];
734 
735   // Okay, make sure that the pick is in the current renderer
736   if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
737     {
738     this->State = vtkPlaneWidget::Outside;
739     return;
740     }
741 
742   // Okay, we can process this. Try to pick handles first;
743   // if no handles picked, then pick the bounding box.
744   vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
745 
746   if ( path != NULL )
747     {
748     this->State = vtkPlaneWidget::Scaling;
749     this->HighlightPlane(1);
750     this->HighlightHandle(path->GetFirstNode()->GetViewProp());
751     }
752   else //see if we picked the plane or a normal
753     {
754     path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
755 
756     if ( path == NULL )
757       {
758       this->State = vtkPlaneWidget::Outside;
759       return;
760       }
761     else
762       {
763       this->State = vtkPlaneWidget::Scaling;
764       this->HighlightPlane(1);
765       }
766     }
767 
768   this->EventCallbackCommand->SetAbortFlag(1);
769   this->StartInteraction();
770   this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
771   this->Interactor->Render();
772 }
773 
OnRightButtonUp()774 void vtkPlaneWidget::OnRightButtonUp()
775 {
776   if ( this->State == vtkPlaneWidget::Outside ||
777        this->State == vtkPlaneWidget::Start )
778     {
779     return;
780     }
781 
782   this->State = vtkPlaneWidget::Start;
783   this->HighlightPlane(0);
784   this->SizeHandles();
785 
786   this->EventCallbackCommand->SetAbortFlag(1);
787   this->EndInteraction();
788   this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
789   this->Interactor->Render();
790 }
791 
OnMouseMove()792 void vtkPlaneWidget::OnMouseMove()
793 {
794   // See whether we're active
795   if ( this->State == vtkPlaneWidget::Outside ||
796        this->State == vtkPlaneWidget::Start )
797     {
798     return;
799     }
800 
801   int X = this->Interactor->GetEventPosition()[0];
802   int Y = this->Interactor->GetEventPosition()[1];
803 
804   // Do different things depending on state
805   // Calculations everybody does
806   double focalPoint[4], pickPoint[4], prevPickPoint[4];
807   double z, vpn[3];
808 
809   vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
810   if ( !camera )
811     {
812     return;
813     }
814 
815   // Compute the two points defining the motion vector
816   this->ComputeWorldToDisplay(this->LastPickPosition[0],
817                               this->LastPickPosition[1],
818                               this->LastPickPosition[2], focalPoint);
819   z = focalPoint[2];
820   this->ComputeDisplayToWorld(
821     double(this->Interactor->GetLastEventPosition()[0]),
822     double(this->Interactor->GetLastEventPosition()[1]),
823     z, prevPickPoint);
824   this->ComputeDisplayToWorld(double(X), double(Y), z, pickPoint);
825 
826   // Process the motion
827   if ( this->State == vtkPlaneWidget::Moving )
828     {
829     // Okay to process
830     if ( this->CurrentHandle )
831       {
832       if ( this->CurrentHandle == this->Handle[0] )
833         {
834         this->MoveOrigin(prevPickPoint, pickPoint);
835         }
836       else if ( this->CurrentHandle == this->Handle[1] )
837         {
838         this->MovePoint1(prevPickPoint, pickPoint);
839         }
840       else if ( this->CurrentHandle == this->Handle[2] )
841         {
842         this->MovePoint2(prevPickPoint, pickPoint);
843         }
844       else if ( this->CurrentHandle == this->Handle[3] )
845         {
846         this->MovePoint3(prevPickPoint, pickPoint);
847         }
848       }
849     else //must be moving the plane
850       {
851       this->Translate(prevPickPoint, pickPoint);
852       }
853     }
854   else if ( this->State == vtkPlaneWidget::Scaling )
855     {
856     this->Scale(prevPickPoint, pickPoint, X, Y);
857     }
858   else if ( this->State == vtkPlaneWidget::Pushing )
859     {
860     this->Push(prevPickPoint, pickPoint);
861     }
862   else if ( this->State == vtkPlaneWidget::Rotating )
863     {
864     camera->GetViewPlaneNormal(vpn);
865     this->Rotate(X, Y, prevPickPoint, pickPoint, vpn);
866     }
867   else if ( this->State == vtkPlaneWidget::Spinning )
868     {
869     this->Spin(prevPickPoint, pickPoint);
870     }
871 
872 
873   // Interact, if desired
874   this->EventCallbackCommand->SetAbortFlag(1);
875   this->InvokeEvent(vtkCommand::InteractionEvent,NULL);
876 
877   this->Interactor->Render();
878 }
879 
MoveOrigin(double * p1,double * p2)880 void vtkPlaneWidget::MoveOrigin(double *p1, double *p2)
881 {
882   //Get the plane definition
883   double *o = this->PlaneSource->GetOrigin();
884   double *pt1 = this->PlaneSource->GetPoint1();
885   double *pt2 = this->PlaneSource->GetPoint2();
886 
887   //Get the vector of motion
888   double v[3];
889   v[0] = p2[0] - p1[0];
890   v[1] = p2[1] - p1[1];
891   v[2] = p2[2] - p1[2];
892 
893   // The point opposite the origin (pt3) stays fixed
894   double pt3[3];
895   pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]);
896   pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]);
897   pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]);
898 
899   // Define vectors from point pt3
900   double p13[3], p23[3];
901   p13[0] = pt1[0] - pt3[0];
902   p13[1] = pt1[1] - pt3[1];
903   p13[2] = pt1[2] - pt3[2];
904   p23[0] = pt2[0] - pt3[0];
905   p23[1] = pt2[1] - pt3[1];
906   p23[2] = pt2[2] - pt3[2];
907 
908   double vN = vtkMath::Norm(v);
909   double n13 = vtkMath::Norm(p13);
910   double n23 = vtkMath::Norm(p23);
911 
912   // Project v onto these vector to determine the amount of motion
913   // Scale it by the relative size of the motion to the vector length
914   double d1 = (vN/n13) * vtkMath::Dot(v,p13) / (vN*n13);
915   double d2 = (vN/n23) * vtkMath::Dot(v,p23) / (vN*n23);
916 
917   double point1[3], point2[3], origin[3];
918   for (int i=0; i<3; i++)
919     {
920     point1[i] = pt3[i] + (1.0+d1)*p13[i];
921     point2[i] = pt3[i] + (1.0+d2)*p23[i];
922     origin[i] = pt3[i] + (1.0+d1)*p13[i] + (1.0+d2)*p23[i];
923     }
924 
925   this->PlaneSource->SetOrigin(origin);
926   this->PlaneSource->SetPoint1(point1);
927   this->PlaneSource->SetPoint2(point2);
928   this->PlaneSource->Update();
929 
930   this->PositionHandles();
931 }
932 
MovePoint1(double * p1,double * p2)933 void vtkPlaneWidget::MovePoint1(double *p1, double *p2)
934 {
935   //Get the plane definition
936   double *o = this->PlaneSource->GetOrigin();
937   double *pt1 = this->PlaneSource->GetPoint1();
938   double *pt2 = this->PlaneSource->GetPoint2();
939 
940   //Get the vector of motion
941   double v[3];
942   v[0] = p2[0] - p1[0];
943   v[1] = p2[1] - p1[1];
944   v[2] = p2[2] - p1[2];
945 
946   // Need the point opposite the origin (pt3)
947   double pt3[3];
948   pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]);
949   pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]);
950   pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]);
951 
952   // Define vectors from point pt2
953   double p32[3], p02[3];
954   p02[0] = o[0] - pt2[0];
955   p02[1] = o[1] - pt2[1];
956   p02[2] = o[2] - pt2[2];
957   p32[0] = pt3[0] - pt2[0];
958   p32[1] = pt3[1] - pt2[1];
959   p32[2] = pt3[2] - pt2[2];
960 
961   double vN = vtkMath::Norm(v);
962   double n02 = vtkMath::Norm(p02);
963   double n32 = vtkMath::Norm(p32);
964 
965   // Project v onto these vector to determine the amount of motion
966   // Scale it by the relative size of the motion to the vector length
967   double d1 = (vN/n02) * vtkMath::Dot(v,p02) / (vN*n02);
968   double d2 = (vN/n32) * vtkMath::Dot(v,p32) / (vN*n32);
969 
970   double point1[3], origin[3];
971   for (int i=0; i<3; i++)
972     {
973     origin[i] = pt2[i] + (1.0+d1)*p02[i];
974     point1[i] = pt2[i] + (1.0+d1)*p02[i] + (1.0+d2)*p32[i];
975     }
976 
977   this->PlaneSource->SetOrigin(origin);
978   this->PlaneSource->SetPoint1(point1);
979   this->PlaneSource->Update();
980 
981   this->PositionHandles();
982 }
983 
MovePoint2(double * p1,double * p2)984 void vtkPlaneWidget::MovePoint2(double *p1, double *p2)
985 {
986   //Get the plane definition
987   double *o = this->PlaneSource->GetOrigin();
988   double *pt1 = this->PlaneSource->GetPoint1();
989   double *pt2 = this->PlaneSource->GetPoint2();
990 
991   //Get the vector of motion
992   double v[3];
993   v[0] = p2[0] - p1[0];
994   v[1] = p2[1] - p1[1];
995   v[2] = p2[2] - p1[2];
996 
997   // The point opposite point2 (pt1) stays fixed
998   double pt3[3];
999   pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]);
1000   pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]);
1001   pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]);
1002 
1003   // Define vectors from point pt1
1004   double p01[3], p31[3];
1005   p31[0] = pt3[0] - pt1[0];
1006   p31[1] = pt3[1] - pt1[1];
1007   p31[2] = pt3[2] - pt1[2];
1008   p01[0] = o[0] - pt1[0];
1009   p01[1] = o[1] - pt1[1];
1010   p01[2] = o[2] - pt1[2];
1011 
1012   double vN = vtkMath::Norm(v);
1013   double n31 = vtkMath::Norm(p31);
1014   double n01 = vtkMath::Norm(p01);
1015 
1016   // Project v onto these vector to determine the amount of motion
1017   // Scale it by the relative size of the motion to the vector length
1018   double d1 = (vN/n31) * vtkMath::Dot(v,p31) / (vN*n31);
1019   double d2 = (vN/n01) * vtkMath::Dot(v,p01) / (vN*n01);
1020 
1021   double point2[3], origin[3];
1022   for (int i=0; i<3; i++)
1023     {
1024     point2[i] = pt1[i] + (1.0+d1)*p31[i] + (1.0+d2)*p01[i];
1025     origin[i] = pt1[i] + (1.0+d2)*p01[i];
1026     }
1027 
1028   this->PlaneSource->SetOrigin(origin);
1029   this->PlaneSource->SetPoint2(point2);
1030   this->PlaneSource->Update();
1031 
1032   this->PositionHandles();
1033 }
1034 
MovePoint3(double * p1,double * p2)1035 void vtkPlaneWidget::MovePoint3(double *p1, double *p2)
1036 {
1037   //Get the plane definition
1038   double *o = this->PlaneSource->GetOrigin();
1039   double *pt1 = this->PlaneSource->GetPoint1();
1040   double *pt2 = this->PlaneSource->GetPoint2();
1041 
1042   //Get the vector of motion
1043   double v[3];
1044   v[0] = p2[0] - p1[0];
1045   v[1] = p2[1] - p1[1];
1046   v[2] = p2[2] - p1[2];
1047 
1048   // Define vectors from point pt3
1049   double p10[3], p20[3];
1050   p10[0] = pt1[0] - o[0];
1051   p10[1] = pt1[1] - o[1];
1052   p10[2] = pt1[2] - o[2];
1053   p20[0] = pt2[0] - o[0];
1054   p20[1] = pt2[1] - o[1];
1055   p20[2] = pt2[2] - o[2];
1056 
1057   double vN = vtkMath::Norm(v);
1058   double n10 = vtkMath::Norm(p10);
1059   double n20 = vtkMath::Norm(p20);
1060 
1061   // Project v onto these vector to determine the amount of motion
1062   // Scale it by the relative size of the motion to the vector length
1063   double d1 = (vN/n10) * vtkMath::Dot(v,p10) / (vN*n10);
1064   double d2 = (vN/n20) * vtkMath::Dot(v,p20) / (vN*n20);
1065 
1066   double point1[3], point2[3];
1067   for (int i=0; i<3; i++)
1068     {
1069     point1[i] = o[i] + (1.0+d1)*p10[i];
1070     point2[i] = o[i] + (1.0+d2)*p20[i];
1071     }
1072 
1073   this->PlaneSource->SetPoint1(point1);
1074   this->PlaneSource->SetPoint2(point2);
1075   this->PlaneSource->Update();
1076 
1077   this->PositionHandles();
1078 }
1079 
Rotate(int X,int Y,double * p1,double * p2,double * vpn)1080 void vtkPlaneWidget::Rotate(int X, int Y, double *p1, double *p2, double *vpn)
1081 {
1082   double *o = this->PlaneSource->GetOrigin();
1083   double *pt1 = this->PlaneSource->GetPoint1();
1084   double *pt2 = this->PlaneSource->GetPoint2();
1085   double *center = this->PlaneSource->GetCenter();
1086 
1087   double v[3]; //vector of motion
1088   double axis[3]; //axis of rotation
1089   double theta; //rotation angle
1090 
1091   // mouse motion vector in world space
1092   v[0] = p2[0] - p1[0];
1093   v[1] = p2[1] - p1[1];
1094   v[2] = p2[2] - p1[2];
1095 
1096   // Create axis of rotation and angle of rotation
1097   vtkMath::Cross(vpn,v,axis);
1098   if ( vtkMath::Normalize(axis) == 0.0 )
1099     {
1100     return;
1101     }
1102   int *size = this->CurrentRenderer->GetSize();
1103   double l2 =
1104     (X-this->Interactor->GetLastEventPosition()[0])*
1105     (X-this->Interactor->GetLastEventPosition()[0]) +
1106     (Y-this->Interactor->GetLastEventPosition()[1])*
1107     (Y-this->Interactor->GetLastEventPosition()[1]);
1108   theta = 360.0 * sqrt(l2/(size[0]*size[0]+size[1]*size[1]));
1109 
1110   //Manipulate the transform to reflect the rotation
1111   this->Transform->Identity();
1112   this->Transform->Translate(center[0],center[1],center[2]);
1113   this->Transform->RotateWXYZ(theta,axis);
1114   this->Transform->Translate(-center[0],-center[1],-center[2]);
1115 
1116   //Set the corners
1117   double oNew[3], pt1New[3], pt2New[3];
1118   this->Transform->TransformPoint(o,oNew);
1119   this->Transform->TransformPoint(pt1,pt1New);
1120   this->Transform->TransformPoint(pt2,pt2New);
1121 
1122   this->PlaneSource->SetOrigin(oNew);
1123   this->PlaneSource->SetPoint1(pt1New);
1124   this->PlaneSource->SetPoint2(pt2New);
1125   this->PlaneSource->Update();
1126 
1127   this->PositionHandles();
1128 }
1129 
Spin(double * p1,double * p2)1130 void vtkPlaneWidget::Spin(double *p1, double *p2)
1131 {
1132   // Mouse motion vector in world space
1133   double v[3];
1134   v[0] = p2[0] - p1[0];
1135   v[1] = p2[1] - p1[1];
1136   v[2] = p2[2] - p1[2];
1137 
1138   double* normal = this->PlaneSource->GetNormal();
1139   // Axis of rotation
1140   double axis[3] = { normal[0], normal[1], normal[2] };
1141   vtkMath::Normalize(axis);
1142 
1143   double *o = this->PlaneSource->GetOrigin();
1144   double *pt1 = this->PlaneSource->GetPoint1();
1145   double *pt2 = this->PlaneSource->GetPoint2();
1146   double *center = this->PlaneSource->GetCenter();
1147 
1148   // Radius vector (from center to cursor position)
1149   double rv[3] = {p2[0] - center[0],
1150                   p2[1] - center[1],
1151                   p2[2] - center[2]};
1152 
1153   // Distance between center and cursor location
1154   double rs = vtkMath::Normalize(rv);
1155 
1156   // Spin direction
1157   double ax_cross_rv[3];
1158   vtkMath::Cross(axis,rv,ax_cross_rv);
1159 
1160   // Spin angle
1161   double theta = vtkMath::DegreesFromRadians( vtkMath::Dot( v, ax_cross_rv ) / rs );
1162 
1163   // Manipulate the transform to reflect the rotation
1164   this->Transform->Identity();
1165   this->Transform->Translate(center[0],center[1],center[2]);
1166   this->Transform->RotateWXYZ(theta,axis);
1167   this->Transform->Translate(-center[0],-center[1],-center[2]);
1168 
1169   //Set the corners
1170   double oNew[3], pt1New[3], pt2New[3];
1171   this->Transform->TransformPoint(o,oNew);
1172   this->Transform->TransformPoint(pt1,pt1New);
1173   this->Transform->TransformPoint(pt2,pt2New);
1174 
1175   this->PlaneSource->SetOrigin(oNew);
1176   this->PlaneSource->SetPoint1(pt1New);
1177   this->PlaneSource->SetPoint2(pt2New);
1178   this->PlaneSource->Update();
1179 
1180   this->PositionHandles();
1181 }
1182 
1183 // Loop through all points and translate them
Translate(double * p1,double * p2)1184 void vtkPlaneWidget::Translate(double *p1, double *p2)
1185 {
1186   //Get the motion vector
1187   double v[3];
1188   v[0] = p2[0] - p1[0];
1189   v[1] = p2[1] - p1[1];
1190   v[2] = p2[2] - p1[2];
1191 
1192   //int res = this->PlaneSource->GetXResolution();
1193   double *o = this->PlaneSource->GetOrigin();
1194   double *pt1 = this->PlaneSource->GetPoint1();
1195   double *pt2 = this->PlaneSource->GetPoint2();
1196 
1197   double origin[3], point1[3], point2[3];
1198   for (int i=0; i<3; i++)
1199     {
1200     origin[i] = o[i] + v[i];
1201     point1[i] = pt1[i] + v[i];
1202     point2[i] = pt2[i] + v[i];
1203     }
1204 
1205   this->PlaneSource->SetOrigin(origin);
1206   this->PlaneSource->SetPoint1(point1);
1207   this->PlaneSource->SetPoint2(point2);
1208   this->PlaneSource->Update();
1209 
1210   this->PositionHandles();
1211 }
1212 
Scale(double * p1,double * p2,int vtkNotUsed (X),int Y)1213 void vtkPlaneWidget::Scale(double *p1, double *p2, int vtkNotUsed(X), int Y)
1214 {
1215   //Get the motion vector
1216   double v[3];
1217   v[0] = p2[0] - p1[0];
1218   v[1] = p2[1] - p1[1];
1219   v[2] = p2[2] - p1[2];
1220 
1221   //int res = this->PlaneSource->GetXResolution();
1222   double *o = this->PlaneSource->GetOrigin();
1223   double *pt1 = this->PlaneSource->GetPoint1();
1224   double *pt2 = this->PlaneSource->GetPoint2();
1225 
1226   double center[3];
1227   center[0] = 0.5 * ( pt1[0] + pt2[0] );
1228   center[1] = 0.5 * ( pt1[1] + pt2[1] );
1229   center[2] = 0.5 * ( pt1[2] + pt2[2] );
1230 
1231   // Compute the scale factor
1232   double sf =
1233     vtkMath::Norm(v) / sqrt(vtkMath::Distance2BetweenPoints(pt1,pt2));
1234   if ( Y > this->Interactor->GetLastEventPosition()[1] )
1235     {
1236     sf = 1.0 + sf;
1237     }
1238   else
1239     {
1240     sf = 1.0 - sf;
1241     }
1242 
1243   // Move the corner points
1244   double origin[3], point1[3], point2[3];
1245   for (int i=0; i<3; i++)
1246     {
1247     origin[i] = sf * (o[i] - center[i]) + center[i];
1248     point1[i] = sf * (pt1[i] - center[i]) + center[i];
1249     point2[i] = sf * (pt2[i] - center[i]) + center[i];
1250     }
1251 
1252   this->PlaneSource->SetOrigin(origin);
1253   this->PlaneSource->SetPoint1(point1);
1254   this->PlaneSource->SetPoint2(point2);
1255   this->PlaneSource->Update();
1256 
1257   this->PositionHandles();
1258 }
1259 
Push(double * p1,double * p2)1260 void vtkPlaneWidget::Push(double *p1, double *p2)
1261 {
1262   //Get the motion vector
1263   double v[3];
1264   v[0] = p2[0] - p1[0];
1265   v[1] = p2[1] - p1[1];
1266   v[2] = p2[2] - p1[2];
1267 
1268   this->PlaneSource->Push( vtkMath::Dot(v,this->Normal) );
1269   this->PlaneSource->Update();
1270   this->PositionHandles();
1271 }
1272 
CreateDefaultProperties()1273 void vtkPlaneWidget::CreateDefaultProperties()
1274 {
1275   // Handle properties
1276   this->HandleProperty = vtkProperty::New();
1277   this->HandleProperty->SetColor(1,1,1);
1278 
1279   this->SelectedHandleProperty = vtkProperty::New();
1280   this->SelectedHandleProperty->SetColor(1,0,0);
1281 
1282   // Plane properties
1283   this->PlaneProperty = vtkProperty::New();
1284   this->PlaneProperty->SetAmbient(1.0);
1285   this->PlaneProperty->SetAmbientColor(1.0,1.0,1.0);
1286 
1287   this->SelectedPlaneProperty = vtkProperty::New();
1288   this->SelectRepresentation();
1289   this->SelectedPlaneProperty->SetAmbient(1.0);
1290   this->SelectedPlaneProperty->SetAmbientColor(0.0,1.0,0.0);
1291 }
1292 
PlaceWidget(double bds[6])1293 void vtkPlaneWidget::PlaceWidget(double bds[6])
1294 {
1295   int i;
1296   double bounds[6], center[3];
1297 
1298   this->AdjustBounds(bds, bounds, center);
1299 
1300   if (this->GetInput() || this->Prop3D)
1301     {
1302     if ( this->NormalToYAxis )
1303       {
1304       this->PlaneSource->SetOrigin(bounds[0],center[1],bounds[4]);
1305       this->PlaneSource->SetPoint1(bounds[1],center[1],bounds[4]);
1306       this->PlaneSource->SetPoint2(bounds[0],center[1],bounds[5]);
1307       }
1308     else if ( this->NormalToZAxis )
1309       {
1310       this->PlaneSource->SetOrigin(bounds[0],bounds[2],center[2]);
1311       this->PlaneSource->SetPoint1(bounds[1],bounds[2],center[2]);
1312       this->PlaneSource->SetPoint2(bounds[0],bounds[3],center[2]);
1313       }
1314     else //default or x-normal
1315       {
1316       this->PlaneSource->SetOrigin(center[0],bounds[2],bounds[4]);
1317       this->PlaneSource->SetPoint1(center[0],bounds[3],bounds[4]);
1318       this->PlaneSource->SetPoint2(center[0],bounds[2],bounds[5]);
1319       }
1320     }
1321 
1322   this->PlaneSource->Update();
1323 
1324   // Position the handles at the end of the planes
1325   this->PositionHandles();
1326 
1327   for (i=0; i<6; i++)
1328     {
1329     this->InitialBounds[i] = bounds[i];
1330     }
1331 
1332 
1333   if (this->GetInput() || this->Prop3D)
1334     {
1335     this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
1336                                (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
1337                                (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
1338     }
1339   else
1340     {
1341     // this means we have to make use of the PolyDataSource, so
1342     // we just calculate the magnitude of the longest diagonal on
1343     // the plane and use that as InitialLength
1344     double origin[3], point1[3], point2[3];
1345     this->PlaneSource->GetOrigin(origin);
1346     this->PlaneSource->GetPoint1(point1);
1347     this->PlaneSource->GetPoint2(point2);
1348     double sqr1 = 0, sqr2 = 0;
1349     for (i = 0; i < 3; i++)
1350       {
1351       sqr1 += (point1[i] - origin[i]) * (point1[i] - origin[i]);
1352       sqr2 += (point2[i] - origin[i]) * (point2[i] - origin[i]);
1353       }
1354 
1355     this->InitialLength = sqrt(sqr1 + sqr2);
1356     }
1357 
1358   // Set the radius on the sphere handles
1359   this->SizeHandles();
1360 }
1361 
SizeHandles()1362 void vtkPlaneWidget::SizeHandles()
1363 {
1364   double radius = this->vtk3DWidget::SizeHandles(this->HandleSizeFactor);
1365 
1366   if (this->ValidPick && !this->LastPickValid)
1367     {
1368     // Adjust factor to preserve old radius.
1369     double oldradius = this->HandleGeometry[0]->GetRadius();
1370     if (oldradius != 0 && radius != 0)
1371       {
1372       this->HandleSizeFactor = oldradius / radius;
1373       radius = oldradius;
1374       }
1375     }
1376 
1377   this->LastPickValid = this->ValidPick;
1378 
1379   for(int i=0; i<4; i++)
1380     {
1381     this->HandleGeometry[i]->SetRadius(radius);
1382     }
1383 
1384   // Set the height and radius of the cone
1385   this->ConeSource->SetHeight(2.0*radius);
1386   this->ConeSource->SetRadius(radius);
1387   this->ConeSource2->SetHeight(2.0*radius);
1388   this->ConeSource2->SetRadius(radius);
1389 
1390 }
1391 
1392 
SelectRepresentation()1393 void vtkPlaneWidget::SelectRepresentation()
1394 {
1395   if ( ! this->CurrentRenderer )
1396     {
1397     return;
1398     }
1399 
1400   if ( this->Representation == VTK_PLANE_OFF )
1401     {
1402     this->CurrentRenderer->RemoveActor(this->PlaneActor);
1403     }
1404   else if ( this->Representation == VTK_PLANE_OUTLINE )
1405     {
1406     this->CurrentRenderer->RemoveActor(this->PlaneActor);
1407     this->CurrentRenderer->AddActor(this->PlaneActor);
1408     this->PlaneMapper->SetInputData( this->PlaneOutline );
1409     this->PlaneActor->GetProperty()->SetRepresentationToWireframe();
1410     }
1411   else if ( this->Representation == VTK_PLANE_SURFACE )
1412     {
1413     this->CurrentRenderer->RemoveActor(this->PlaneActor);
1414     this->CurrentRenderer->AddActor(this->PlaneActor);
1415     this->PlaneMapper->SetInputConnection( this->PlaneSource->GetOutputPort() );
1416     this->PlaneActor->GetProperty()->SetRepresentationToSurface();
1417     }
1418   else //( this->Representation == VTK_PLANE_WIREFRAME )
1419     {
1420     this->CurrentRenderer->RemoveActor(this->PlaneActor);
1421     this->CurrentRenderer->AddActor(this->PlaneActor);
1422     this->PlaneMapper->SetInputConnection( this->PlaneSource->GetOutputPort() );
1423     this->PlaneActor->GetProperty()->SetRepresentationToWireframe();
1424     }
1425 }
1426 
1427 // Description:
1428 // Set/Get the resolution (number of subdivisions) of the plane.
SetResolution(int r)1429 void vtkPlaneWidget::SetResolution(int r)
1430 {
1431   this->PlaneSource->SetXResolution(r);
1432   this->PlaneSource->SetYResolution(r);
1433 }
1434 
GetResolution()1435 int vtkPlaneWidget::GetResolution()
1436 {
1437   return this->PlaneSource->GetXResolution();
1438 }
1439 
1440 // Description:
1441 // Set/Get the origin of the plane.
SetOrigin(double x,double y,double z)1442 void vtkPlaneWidget::SetOrigin(double x, double y, double z)
1443 {
1444   this->PlaneSource->SetOrigin(x,y,z);
1445   this->PositionHandles();
1446 }
1447 
SetOrigin(double x[3])1448 void vtkPlaneWidget::SetOrigin(double x[3])
1449 {
1450   this->SetOrigin(x[0], x[1], x[2]);
1451 }
1452 
GetOrigin()1453 double* vtkPlaneWidget::GetOrigin()
1454 {
1455   return this->PlaneSource->GetOrigin();
1456 }
1457 
GetOrigin(double xyz[3])1458 void vtkPlaneWidget::GetOrigin(double xyz[3])
1459 {
1460   this->PlaneSource->GetOrigin(xyz);
1461 }
1462 
1463 // Description:
1464 // Set/Get the position of the point defining the first axis of the plane.
SetPoint1(double x,double y,double z)1465 void vtkPlaneWidget::SetPoint1(double x, double y, double z)
1466 {
1467   this->PlaneSource->SetPoint1(x,y,z);
1468   this->PositionHandles();
1469 }
1470 
SetPoint1(double x[3])1471 void vtkPlaneWidget::SetPoint1(double x[3])
1472 {
1473   this->SetPoint1(x[0], x[1], x[2]);
1474 }
1475 
GetPoint1()1476 double* vtkPlaneWidget::GetPoint1()
1477 {
1478   return this->PlaneSource->GetPoint1();
1479 }
1480 
GetPoint1(double xyz[3])1481 void vtkPlaneWidget::GetPoint1(double xyz[3])
1482 {
1483   this->PlaneSource->GetPoint1(xyz);
1484 }
1485 
1486 // Description:
1487 // Set/Get the position of the point defining the second axis of the plane.
SetPoint2(double x,double y,double z)1488 void vtkPlaneWidget::SetPoint2(double x, double y, double z)
1489 {
1490   this->PlaneSource->SetPoint2(x,y,z);
1491   this->PositionHandles();
1492 }
1493 
SetPoint2(double x[3])1494 void vtkPlaneWidget::SetPoint2(double x[3])
1495 {
1496   this->SetPoint2(x[0], x[1], x[2]);
1497 }
1498 
GetPoint2()1499 double* vtkPlaneWidget::GetPoint2()
1500 {
1501   return this->PlaneSource->GetPoint2();
1502 }
1503 
GetPoint2(double xyz[3])1504 void vtkPlaneWidget::GetPoint2(double xyz[3])
1505 {
1506   this->PlaneSource->GetPoint2(xyz);
1507 }
1508 
1509 // Description:
1510 // Set the center of the plane.
SetCenter(double x,double y,double z)1511 void vtkPlaneWidget::SetCenter(double x, double y, double z)
1512 {
1513   this->PlaneSource->SetCenter(x, y, z);
1514   this->PositionHandles();
1515 }
1516 
1517 // Description:
1518 // Set the center of the plane.
SetCenter(double c[3])1519 void vtkPlaneWidget::SetCenter(double c[3])
1520 {
1521   this->SetCenter(c[0], c[1], c[2]);
1522 }
1523 
1524 // Description:
1525 // Get the center of the plane.
GetCenter()1526 double* vtkPlaneWidget::GetCenter()
1527 {
1528   return this->PlaneSource->GetCenter();
1529 }
1530 
GetCenter(double xyz[3])1531 void vtkPlaneWidget::GetCenter(double xyz[3])
1532 {
1533   this->PlaneSource->GetCenter(xyz);
1534 }
1535 
1536 // Description:
1537 // Set the normal to the plane.
SetNormal(double x,double y,double z)1538 void vtkPlaneWidget::SetNormal(double x, double y, double z)
1539 {
1540   this->PlaneSource->SetNormal(x, y, z);
1541   this->PositionHandles();
1542 }
1543 
1544 // Description:
1545 // Set the normal to the plane.
SetNormal(double n[3])1546 void vtkPlaneWidget::SetNormal(double n[3])
1547 {
1548   this->SetNormal(n[0], n[1], n[2]);
1549 }
1550 
1551 // Description:
1552 // Get the normal to the plane.
GetNormal()1553 double* vtkPlaneWidget::GetNormal()
1554 {
1555   return this->PlaneSource->GetNormal();
1556 }
1557 
GetNormal(double xyz[3])1558 void vtkPlaneWidget::GetNormal(double xyz[3])
1559 {
1560   this->PlaneSource->GetNormal(xyz);
1561 }
1562 
GetPolyData(vtkPolyData * pd)1563 void vtkPlaneWidget::GetPolyData(vtkPolyData *pd)
1564 {
1565   pd->ShallowCopy(this->PlaneSource->GetOutput());
1566 }
1567 
GetPolyDataAlgorithm()1568 vtkPolyDataAlgorithm *vtkPlaneWidget::GetPolyDataAlgorithm()
1569 {
1570   return this->PlaneSource;
1571 }
1572 
GetPlane(vtkPlane * plane)1573 void vtkPlaneWidget::GetPlane(vtkPlane *plane)
1574 {
1575   if ( plane == NULL )
1576     {
1577     return;
1578     }
1579 
1580   plane->SetNormal(this->GetNormal());
1581   plane->SetOrigin(this->GetCenter());
1582 }
1583 
UpdatePlacement(void)1584 void vtkPlaneWidget::UpdatePlacement(void)
1585 {
1586   this->PlaneSource->Update();
1587   this->PositionHandles();
1588 }
1589