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 = nullptr;
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 = nullptr;
219   }
220 
221   if (this->SelectedHandleProperty)
222   {
223     this->SelectedHandleProperty->Delete();
224     this->SelectedHandleProperty = nullptr;
225   }
226 
227   if (this->PlaneProperty)
228   {
229     this->PlaneProperty->Delete();
230     this->PlaneProperty = nullptr;
231   }
232 
233   if (this->SelectedPlaneProperty)
234   {
235     this->SelectedPlaneProperty->Delete();
236     this->SelectedPlaneProperty = nullptr;
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 == nullptr)
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     i->AddObserver(vtkCommand::StartPinchEvent,
289                    this->EventCallbackCommand, this->Priority);
290     i->AddObserver(vtkCommand::PinchEvent,
291                    this->EventCallbackCommand, this->Priority);
292     i->AddObserver(vtkCommand::EndPinchEvent,
293                    this->EventCallbackCommand, this->Priority);
294 
295     // Add the plane
296     this->CurrentRenderer->AddActor(this->PlaneActor);
297     this->PlaneActor->SetProperty(this->PlaneProperty);
298 
299     // turn on the handles
300     for (int j=0; j<4; j++)
301     {
302       this->CurrentRenderer->AddActor(this->Handle[j]);
303       this->Handle[j]->SetProperty(this->HandleProperty);
304     }
305 
306     // add the normal vector
307     this->CurrentRenderer->AddActor(this->LineActor);
308     this->LineActor->SetProperty(this->HandleProperty);
309     this->CurrentRenderer->AddActor(this->ConeActor);
310     this->ConeActor->SetProperty(this->HandleProperty);
311     this->CurrentRenderer->AddActor(this->LineActor2);
312     this->LineActor2->SetProperty(this->HandleProperty);
313     this->CurrentRenderer->AddActor(this->ConeActor2);
314     this->ConeActor2->SetProperty(this->HandleProperty);
315 
316     this->SelectRepresentation();
317     this->RegisterPickers();
318     this->InvokeEvent(vtkCommand::EnableEvent,nullptr);
319   }
320 
321   else //disabling----------------------------------------------------------
322   {
323     vtkDebugMacro(<<"Disabling plane widget");
324 
325     if ( ! this->Enabled ) //already disabled, just return
326     {
327       return;
328     }
329 
330     this->Enabled = 0;
331 
332     // don't listen for events any more
333     this->Interactor->RemoveObserver(this->EventCallbackCommand);
334 
335     // turn off the plane
336     this->CurrentRenderer->RemoveActor(this->PlaneActor);
337 
338     // turn off the handles
339     for (int i=0; i<4; i++)
340     {
341       this->CurrentRenderer->RemoveActor(this->Handle[i]);
342     }
343 
344     // turn off the normal vector
345     this->CurrentRenderer->RemoveActor(this->LineActor);
346     this->CurrentRenderer->RemoveActor(this->ConeActor);
347     this->CurrentRenderer->RemoveActor(this->LineActor2);
348     this->CurrentRenderer->RemoveActor(this->ConeActor2);
349 
350     this->CurrentHandle = nullptr;
351     this->InvokeEvent(vtkCommand::DisableEvent,nullptr);
352     this->SetCurrentRenderer(nullptr);
353     this->UnRegisterPickers();
354   }
355 
356   this->Interactor->Render();
357 }
358 
359 //------------------------------------------------------------------------------
RegisterPickers()360 void vtkPlaneWidget::RegisterPickers()
361 {
362   vtkPickingManager* pm = this->GetPickingManager();
363   if (!pm)
364   {
365     return;
366   }
367   pm->AddPicker(this->HandlePicker, this);
368   pm->AddPicker(this->PlanePicker, this);
369 }
370 
ProcessEvents(vtkObject * vtkNotUsed (object),unsigned long event,void * clientdata,void * vtkNotUsed (calldata))371 void vtkPlaneWidget::ProcessEvents(vtkObject* vtkNotUsed(object),
372                                    unsigned long event,
373                                    void* clientdata,
374                                    void* vtkNotUsed(calldata))
375 {
376   vtkPlaneWidget* self = reinterpret_cast<vtkPlaneWidget *>( clientdata );
377 
378   //okay, let's do the right thing
379   switch(event)
380   {
381     case vtkCommand::LeftButtonPressEvent:
382       self->OnLeftButtonDown();
383       break;
384     case vtkCommand::LeftButtonReleaseEvent:
385       self->OnLeftButtonUp();
386       break;
387     case vtkCommand::MiddleButtonPressEvent:
388       self->OnMiddleButtonDown();
389       break;
390     case vtkCommand::MiddleButtonReleaseEvent:
391       self->OnMiddleButtonUp();
392       break;
393     case vtkCommand::RightButtonPressEvent:
394       self->OnRightButtonDown();
395       break;
396     case vtkCommand::RightButtonReleaseEvent:
397       self->OnRightButtonUp();
398       break;
399     case vtkCommand::MouseMoveEvent:
400       self->OnMouseMove();
401       break;
402     case vtkCommand::StartPinchEvent:
403       self->OnStartPinch();
404       break;
405     case vtkCommand::PinchEvent:
406       self->OnPinch();
407       break;
408     case vtkCommand::EndPinchEvent:
409       self->OnEndPinch();
410       break;
411   }
412 }
413 
PrintSelf(ostream & os,vtkIndent indent)414 void vtkPlaneWidget::PrintSelf(ostream& os, vtkIndent indent)
415 {
416   this->Superclass::PrintSelf(os,indent);
417 
418   if ( this->HandleProperty )
419   {
420     os << indent << "Handle Property: " << this->HandleProperty << "\n";
421   }
422   else
423   {
424     os << indent << "Handle Property: (none)\n";
425   }
426   if ( this->SelectedHandleProperty )
427   {
428     os << indent << "Selected Handle Property: "
429        << this->SelectedHandleProperty << "\n";
430   }
431   else
432   {
433     os << indent << "SelectedHandle Property: (none)\n";
434   }
435 
436   if ( this->PlaneProperty )
437   {
438     os << indent << "Plane Property: " << this->PlaneProperty << "\n";
439   }
440   else
441   {
442     os << indent << "Plane Property: (none)\n";
443   }
444   if ( this->SelectedPlaneProperty )
445   {
446     os << indent << "Selected Plane Property: "
447        << this->SelectedPlaneProperty << "\n";
448   }
449   else
450   {
451     os << indent << "Selected Plane Property: (none)\n";
452   }
453 
454   os << indent << "Plane Representation: ";
455   if ( this->Representation == VTK_PLANE_WIREFRAME )
456   {
457     os << "Wireframe\n";
458   }
459   else if ( this->Representation == VTK_PLANE_SURFACE )
460   {
461     os << "Surface\n";
462   }
463   else //( this->Representation == VTK_PLANE_OUTLINE )
464   {
465     os << "Outline\n";
466   }
467 
468   os << indent << "Normal To X Axis: "
469      << (this->NormalToXAxis ? "On" : "Off") << "\n";
470   os << indent << "Normal To Y Axis: "
471      << (this->NormalToYAxis ? "On" : "Off") << "\n";
472   os << indent << "Normal To Z Axis: "
473      << (this->NormalToZAxis ? "On" : "Off") << "\n";
474 
475   int res = this->PlaneSource->GetXResolution();
476   double *o = this->PlaneSource->GetOrigin();
477   double *pt1 = this->PlaneSource->GetPoint1();
478   double *pt2 = this->PlaneSource->GetPoint2();
479 
480   os << indent << "Resolution: " << res << "\n";
481   os << indent << "Origin: (" << o[0] << ", "
482      << o[1] << ", "
483      << o[2] << ")\n";
484   os << indent << "Point 1: (" << pt1[0] << ", "
485      << pt1[1] << ", "
486      << pt1[2] << ")\n";
487   os << indent << "Point 2: (" << pt2[0] << ", "
488      << pt2[1] << ", "
489      << pt2[2] << ")\n";
490 }
491 
PositionHandles()492 void vtkPlaneWidget::PositionHandles()
493 {
494   double *o = this->PlaneSource->GetOrigin();
495   double *pt1 = this->PlaneSource->GetPoint1();
496   double *pt2 = this->PlaneSource->GetPoint2();
497 
498   this->HandleGeometry[0]->SetCenter(o);
499   this->HandleGeometry[1]->SetCenter(pt1);
500   this->HandleGeometry[2]->SetCenter(pt2);
501 
502   double x[3];
503   x[0] = pt1[0] + pt2[0] - o[0];
504   x[1] = pt1[1] + pt2[1] - o[1];
505   x[2] = pt1[2] + pt2[2] - o[2];
506   this->HandleGeometry[3]->SetCenter(x); //far corner
507 
508   // set up the outline
509   if ( this->Representation == VTK_PLANE_OUTLINE )
510   {
511     this->PlaneOutline->GetPoints()->SetPoint(0,o);
512     this->PlaneOutline->GetPoints()->SetPoint(1,pt1);
513     this->PlaneOutline->GetPoints()->SetPoint(2,x);
514     this->PlaneOutline->GetPoints()->SetPoint(3,pt2);
515     this->PlaneOutline->GetPoints()->Modified();
516   }
517   this->SelectRepresentation();
518 
519   // Create the normal vector
520   double center[3];
521   this->PlaneSource->GetCenter(center);
522   this->LineSource->SetPoint1(center);
523   this->LineSource2->SetPoint1(center);
524   double p2[3];
525   this->PlaneSource->GetNormal(this->Normal);
526   vtkMath::Normalize(this->Normal);
527   double d = sqrt(
528     vtkMath::Distance2BetweenPoints(
529       this->PlaneSource->GetPoint1(),this->PlaneSource->GetPoint2()) );
530 
531   p2[0] = center[0] + 0.35 * d * this->Normal[0];
532   p2[1] = center[1] + 0.35 * d * this->Normal[1];
533   p2[2] = center[2] + 0.35 * d * this->Normal[2];
534   this->LineSource->SetPoint2(p2);
535   this->ConeSource->SetCenter(p2);
536   this->ConeSource->SetDirection(this->Normal);
537 
538   p2[0] = center[0] - 0.35 * d * this->Normal[0];
539   p2[1] = center[1] - 0.35 * d * this->Normal[1];
540   p2[2] = center[2] - 0.35 * d * this->Normal[2];
541   this->LineSource2->SetPoint2(p2);
542   this->ConeSource2->SetCenter(p2);
543   this->ConeSource2->SetDirection(this->Normal);
544 }
545 
HighlightHandle(vtkProp * prop)546 int vtkPlaneWidget::HighlightHandle(vtkProp *prop)
547 {
548   // first unhighlight anything picked
549   if ( this->CurrentHandle )
550   {
551     this->CurrentHandle->SetProperty(this->HandleProperty);
552   }
553 
554   this->CurrentHandle = static_cast<vtkActor *>(prop);
555 
556   if ( this->CurrentHandle )
557   {
558     this->ValidPick = 1;
559     this->HandlePicker->GetPickPosition(this->LastPickPosition);
560     this->CurrentHandle->SetProperty(this->SelectedHandleProperty);
561     for (int i=0; i<4; i++) //find handle
562     {
563       if ( this->CurrentHandle == this->Handle[i] )
564       {
565         return i;
566       }
567     }
568   }
569 
570   return -1;
571 }
572 
HighlightNormal(int highlight)573 void vtkPlaneWidget::HighlightNormal(int highlight)
574 {
575   if ( highlight )
576   {
577     this->ValidPick = 1;
578     this->PlanePicker->GetPickPosition(this->LastPickPosition);
579     this->LineActor->SetProperty(this->SelectedHandleProperty);
580     this->ConeActor->SetProperty(this->SelectedHandleProperty);
581     this->LineActor2->SetProperty(this->SelectedHandleProperty);
582     this->ConeActor2->SetProperty(this->SelectedHandleProperty);
583   }
584   else
585   {
586     this->LineActor->SetProperty(this->HandleProperty);
587     this->ConeActor->SetProperty(this->HandleProperty);
588     this->LineActor2->SetProperty(this->HandleProperty);
589     this->ConeActor2->SetProperty(this->HandleProperty);
590   }
591 }
592 
HighlightPlane(int highlight)593 void vtkPlaneWidget::HighlightPlane(int highlight)
594 {
595   if ( highlight )
596   {
597     this->ValidPick = 1;
598     this->PlanePicker->GetPickPosition(this->LastPickPosition);
599     this->PlaneActor->SetProperty(this->SelectedPlaneProperty);
600   }
601   else
602   {
603     this->PlaneActor->SetProperty(this->PlaneProperty);
604   }
605 }
606 
OnStartPinch()607 void vtkPlaneWidget::OnStartPinch()
608 {
609   int X = this->Interactor->GetEventPosition()[0];
610   int Y = this->Interactor->GetEventPosition()[1];
611 
612   // Okay, make sure that the pick is in the current renderer
613   if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
614   {
615     this->State = vtkPlaneWidget::Outside;
616     return;
617   }
618 
619   // Okay, we can process this. try to pick the plane.
620   vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
621 
622   if ( path != nullptr )
623   {
624     this->State = vtkPlaneWidget::Pinching;
625     this->HighlightPlane(1);
626     this->StartInteraction();
627     this->InvokeEvent(vtkCommand::StartInteractionEvent,nullptr);
628   }
629 }
630 
OnPinch()631 void vtkPlaneWidget::OnPinch()
632 {
633   if ( this->State != vtkPlaneWidget::Pinching)
634   {
635     return;
636   }
637 
638   double sf = this->Interactor->GetScale()/this->Interactor->GetLastScale();
639   double *o = this->PlaneSource->GetOrigin();
640   double *pt1 = this->PlaneSource->GetPoint1();
641   double *pt2 = this->PlaneSource->GetPoint2();
642 
643   double center[3];
644   center[0] = 0.5 * ( pt1[0] + pt2[0] );
645   center[1] = 0.5 * ( pt1[1] + pt2[1] );
646   center[2] = 0.5 * ( pt1[2] + pt2[2] );
647 
648   // Move the corner points
649   double origin[3], point1[3], point2[3];
650   for (int i=0; i<3; i++)
651   {
652     origin[i] = sf * (o[i] - center[i]) + center[i];
653     point1[i] = sf * (pt1[i] - center[i]) + center[i];
654     point2[i] = sf * (pt2[i] - center[i]) + center[i];
655   }
656 
657   this->PlaneSource->SetOrigin(origin);
658   this->PlaneSource->SetPoint1(point1);
659   this->PlaneSource->SetPoint2(point2);
660   this->PlaneSource->Update();
661 
662   this->PositionHandles();
663 
664   this->EventCallbackCommand->SetAbortFlag(1);
665   this->InvokeEvent(vtkCommand::InteractionEvent,nullptr);
666   this->Interactor->Render();
667 }
668 
OnEndPinch()669 void vtkPlaneWidget::OnEndPinch()
670 {
671   if ( this->State != vtkPlaneWidget::Pinching)
672   {
673     return;
674   }
675 
676   this->State = vtkPlaneWidget::Start;
677   this->HighlightHandle(nullptr);
678   this->HighlightPlane(0);
679   this->HighlightNormal(0);
680   this->SizeHandles();
681 
682   this->EventCallbackCommand->SetAbortFlag(1);
683   this->EndInteraction();
684   this->InvokeEvent(vtkCommand::EndInteractionEvent,nullptr);
685   this->Interactor->Render();
686 }
687 
OnLeftButtonDown()688 void vtkPlaneWidget::OnLeftButtonDown()
689 {
690   int X = this->Interactor->GetEventPosition()[0];
691   int Y = this->Interactor->GetEventPosition()[1];
692 
693   // Okay, make sure that the pick is in the current renderer
694   if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
695   {
696     this->State = vtkPlaneWidget::Outside;
697     return;
698   }
699 
700   // Okay, we can process this. Try to pick handles first;
701   // if no handles picked, then try to pick the plane.
702   vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
703 
704   if ( path != nullptr )
705   {
706     this->State = vtkPlaneWidget::Moving;
707     this->HighlightHandle(path->GetFirstNode()->GetViewProp());
708   }
709   else
710   {
711     path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
712 
713     if ( path != nullptr )
714     {
715       vtkProp *prop = path->GetFirstNode()->GetViewProp();
716       if ( prop == this->ConeActor || prop == this->LineActor ||
717            prop == this->ConeActor2 || prop == this->LineActor2 )
718       {
719         this->State = vtkPlaneWidget::Rotating;
720         this->HighlightNormal(1);
721       }
722       else if (this->Interactor->GetControlKey())
723       {
724         this->State = vtkPlaneWidget::Spinning;
725         this->HighlightNormal(1);
726       }
727       else
728       {
729         this->State = vtkPlaneWidget::Moving;
730         this->HighlightPlane(1);
731       }
732     }
733     else
734     {
735       this->State = vtkPlaneWidget::Outside;
736       this->HighlightHandle(nullptr);
737       return;
738     }
739   }
740 
741   this->EventCallbackCommand->SetAbortFlag(1);
742   this->StartInteraction();
743   this->InvokeEvent(vtkCommand::StartInteractionEvent,nullptr);
744   this->Interactor->Render();
745 }
746 
OnLeftButtonUp()747 void vtkPlaneWidget::OnLeftButtonUp()
748 {
749   if ( this->State == vtkPlaneWidget::Outside ||
750        this->State == vtkPlaneWidget::Start )
751   {
752     return;
753   }
754 
755   this->State = vtkPlaneWidget::Start;
756   this->HighlightHandle(nullptr);
757   this->HighlightPlane(0);
758   this->HighlightNormal(0);
759   this->SizeHandles();
760 
761   this->EventCallbackCommand->SetAbortFlag(1);
762   this->EndInteraction();
763   this->InvokeEvent(vtkCommand::EndInteractionEvent,nullptr);
764   this->Interactor->Render();
765 }
766 
OnMiddleButtonDown()767 void vtkPlaneWidget::OnMiddleButtonDown()
768 {
769   int X = this->Interactor->GetEventPosition()[0];
770   int Y = this->Interactor->GetEventPosition()[1];
771 
772   // Okay, make sure that the pick is in the current renderer
773   if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
774   {
775     this->State = vtkPlaneWidget::Outside;
776     return;
777   }
778 
779   // Okay, we can process this. If anything is picked, then we
780   // can start pushing the plane.
781   vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
782 
783   if ( path != nullptr )
784   {
785     this->State = vtkPlaneWidget::Pushing;
786     this->HighlightPlane(1);
787     this->HighlightNormal(1);
788     this->HighlightHandle(path->GetFirstNode()->GetViewProp());
789   }
790   else
791   {
792     path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
793 
794     if ( path == nullptr ) //nothing picked
795     {
796       this->State = vtkPlaneWidget::Outside;
797       return;
798     }
799     else
800     {
801       this->State = vtkPlaneWidget::Pushing;
802       this->HighlightNormal(1);
803       this->HighlightPlane(1);
804     }
805   }
806 
807   this->EventCallbackCommand->SetAbortFlag(1);
808   this->StartInteraction();
809   this->InvokeEvent(vtkCommand::StartInteractionEvent,nullptr);
810   this->Interactor->Render();
811 }
812 
OnMiddleButtonUp()813 void vtkPlaneWidget::OnMiddleButtonUp()
814 {
815   if ( this->State == vtkPlaneWidget::Outside ||
816        this->State == vtkPlaneWidget::Start )
817   {
818     return;
819   }
820 
821   this->State = vtkPlaneWidget::Start;
822   this->HighlightPlane(0);
823   this->HighlightNormal(0);
824   this->HighlightHandle(nullptr);
825   this->SizeHandles();
826 
827   this->EventCallbackCommand->SetAbortFlag(1);
828   this->EndInteraction();
829   this->InvokeEvent(vtkCommand::EndInteractionEvent,nullptr);
830   this->Interactor->Render();
831 }
832 
OnRightButtonDown()833 void vtkPlaneWidget::OnRightButtonDown()
834 {
835   int X = this->Interactor->GetEventPosition()[0];
836   int Y = this->Interactor->GetEventPosition()[1];
837 
838   // Okay, make sure that the pick is in the current renderer
839   if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
840   {
841     this->State = vtkPlaneWidget::Outside;
842     return;
843   }
844 
845   // Okay, we can process this. Try to pick handles first;
846   // if no handles picked, then pick the bounding box.
847   vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
848 
849   if ( path != nullptr )
850   {
851     this->State = vtkPlaneWidget::Scaling;
852     this->HighlightPlane(1);
853     this->HighlightHandle(path->GetFirstNode()->GetViewProp());
854   }
855   else //see if we picked the plane or a normal
856   {
857     path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
858 
859     if ( path == nullptr )
860     {
861       this->State = vtkPlaneWidget::Outside;
862       return;
863     }
864     else
865     {
866       this->State = vtkPlaneWidget::Scaling;
867       this->HighlightPlane(1);
868     }
869   }
870 
871   this->EventCallbackCommand->SetAbortFlag(1);
872   this->StartInteraction();
873   this->InvokeEvent(vtkCommand::StartInteractionEvent,nullptr);
874   this->Interactor->Render();
875 }
876 
OnRightButtonUp()877 void vtkPlaneWidget::OnRightButtonUp()
878 {
879   if ( this->State == vtkPlaneWidget::Outside ||
880        this->State == vtkPlaneWidget::Start )
881   {
882     return;
883   }
884 
885   this->State = vtkPlaneWidget::Start;
886   this->HighlightPlane(0);
887   this->SizeHandles();
888 
889   this->EventCallbackCommand->SetAbortFlag(1);
890   this->EndInteraction();
891   this->InvokeEvent(vtkCommand::EndInteractionEvent,nullptr);
892   this->Interactor->Render();
893 }
894 
OnMouseMove()895 void vtkPlaneWidget::OnMouseMove()
896 {
897   // See whether we're active
898   if ( this->State == vtkPlaneWidget::Outside ||
899        this->State == vtkPlaneWidget::Start )
900   {
901     return;
902   }
903 
904   int X = this->Interactor->GetEventPosition()[0];
905   int Y = this->Interactor->GetEventPosition()[1];
906 
907   // Do different things depending on state
908   // Calculations everybody does
909   double focalPoint[4], pickPoint[4], prevPickPoint[4];
910   double z, vpn[3];
911 
912   vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
913   if ( !camera )
914   {
915     return;
916   }
917 
918   // Compute the two points defining the motion vector
919   this->ComputeWorldToDisplay(this->LastPickPosition[0],
920                               this->LastPickPosition[1],
921                               this->LastPickPosition[2], focalPoint);
922   z = focalPoint[2];
923   this->ComputeDisplayToWorld(
924     double(this->Interactor->GetLastEventPosition()[0]),
925     double(this->Interactor->GetLastEventPosition()[1]),
926     z, prevPickPoint);
927   this->ComputeDisplayToWorld(double(X), double(Y), z, pickPoint);
928 
929   // Process the motion
930   if ( this->State == vtkPlaneWidget::Moving )
931   {
932     // Okay to process
933     if ( this->CurrentHandle )
934     {
935       if ( this->CurrentHandle == this->Handle[0] )
936       {
937         this->MoveOrigin(prevPickPoint, pickPoint);
938       }
939       else if ( this->CurrentHandle == this->Handle[1] )
940       {
941         this->MovePoint1(prevPickPoint, pickPoint);
942       }
943       else if ( this->CurrentHandle == this->Handle[2] )
944       {
945         this->MovePoint2(prevPickPoint, pickPoint);
946       }
947       else if ( this->CurrentHandle == this->Handle[3] )
948       {
949         this->MovePoint3(prevPickPoint, pickPoint);
950       }
951     }
952     else //must be moving the plane
953     {
954       this->Translate(prevPickPoint, pickPoint);
955     }
956   }
957   else if ( this->State == vtkPlaneWidget::Scaling )
958   {
959     this->Scale(prevPickPoint, pickPoint, X, Y);
960   }
961   else if ( this->State == vtkPlaneWidget::Pushing )
962   {
963     this->Push(prevPickPoint, pickPoint);
964   }
965   else if ( this->State == vtkPlaneWidget::Rotating )
966   {
967     camera->GetViewPlaneNormal(vpn);
968     this->Rotate(X, Y, prevPickPoint, pickPoint, vpn);
969   }
970   else if ( this->State == vtkPlaneWidget::Spinning )
971   {
972     this->Spin(prevPickPoint, pickPoint);
973   }
974 
975 
976   // Interact, if desired
977   this->EventCallbackCommand->SetAbortFlag(1);
978   this->InvokeEvent(vtkCommand::InteractionEvent,nullptr);
979 
980   this->Interactor->Render();
981 }
982 
MoveOrigin(double * p1,double * p2)983 void vtkPlaneWidget::MoveOrigin(double *p1, double *p2)
984 {
985   //Get the plane definition
986   double *o = this->PlaneSource->GetOrigin();
987   double *pt1 = this->PlaneSource->GetPoint1();
988   double *pt2 = this->PlaneSource->GetPoint2();
989 
990   //Get the vector of motion
991   double v[3];
992   v[0] = p2[0] - p1[0];
993   v[1] = p2[1] - p1[1];
994   v[2] = p2[2] - p1[2];
995 
996   // The point opposite the origin (pt3) stays fixed
997   double pt3[3];
998   pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]);
999   pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]);
1000   pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]);
1001 
1002   // Define vectors from point pt3
1003   double p13[3], p23[3];
1004   p13[0] = pt1[0] - pt3[0];
1005   p13[1] = pt1[1] - pt3[1];
1006   p13[2] = pt1[2] - pt3[2];
1007   p23[0] = pt2[0] - pt3[0];
1008   p23[1] = pt2[1] - pt3[1];
1009   p23[2] = pt2[2] - pt3[2];
1010 
1011   double vN = vtkMath::Norm(v);
1012   double n13 = vtkMath::Norm(p13);
1013   double n23 = vtkMath::Norm(p23);
1014 
1015   // Project v onto these vector to determine the amount of motion
1016   // Scale it by the relative size of the motion to the vector length
1017   double d1 = (vN/n13) * vtkMath::Dot(v,p13) / (vN*n13);
1018   double d2 = (vN/n23) * vtkMath::Dot(v,p23) / (vN*n23);
1019 
1020   double point1[3], point2[3], origin[3];
1021   for (int i=0; i<3; i++)
1022   {
1023     point1[i] = pt3[i] + (1.0+d1)*p13[i];
1024     point2[i] = pt3[i] + (1.0+d2)*p23[i];
1025     origin[i] = pt3[i] + (1.0+d1)*p13[i] + (1.0+d2)*p23[i];
1026   }
1027 
1028   this->PlaneSource->SetOrigin(origin);
1029   this->PlaneSource->SetPoint1(point1);
1030   this->PlaneSource->SetPoint2(point2);
1031   this->PlaneSource->Update();
1032 
1033   this->PositionHandles();
1034 }
1035 
MovePoint1(double * p1,double * p2)1036 void vtkPlaneWidget::MovePoint1(double *p1, double *p2)
1037 {
1038   //Get the plane definition
1039   double *o = this->PlaneSource->GetOrigin();
1040   double *pt1 = this->PlaneSource->GetPoint1();
1041   double *pt2 = this->PlaneSource->GetPoint2();
1042 
1043   //Get the vector of motion
1044   double v[3];
1045   v[0] = p2[0] - p1[0];
1046   v[1] = p2[1] - p1[1];
1047   v[2] = p2[2] - p1[2];
1048 
1049   // Need the point opposite the origin (pt3)
1050   double pt3[3];
1051   pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]);
1052   pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]);
1053   pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]);
1054 
1055   // Define vectors from point pt2
1056   double p32[3], p02[3];
1057   p02[0] = o[0] - pt2[0];
1058   p02[1] = o[1] - pt2[1];
1059   p02[2] = o[2] - pt2[2];
1060   p32[0] = pt3[0] - pt2[0];
1061   p32[1] = pt3[1] - pt2[1];
1062   p32[2] = pt3[2] - pt2[2];
1063 
1064   double vN = vtkMath::Norm(v);
1065   double n02 = vtkMath::Norm(p02);
1066   double n32 = vtkMath::Norm(p32);
1067 
1068   // if there is no motion then return
1069   if (vN == 0.0)
1070   {
1071     return;
1072   }
1073 
1074   // Project v onto these vector to determine the amount of motion
1075   // Scale it by the relative size of the motion to the vector length
1076   double d1 = (vN/n02) * vtkMath::Dot(v,p02) / (vN*n02);
1077   double d2 = (vN/n32) * vtkMath::Dot(v,p32) / (vN*n32);
1078 
1079   double point1[3], origin[3];
1080   for (int i=0; i<3; i++)
1081   {
1082     origin[i] = pt2[i] + (1.0+d1)*p02[i];
1083     point1[i] = pt2[i] + (1.0+d1)*p02[i] + (1.0+d2)*p32[i];
1084   }
1085 
1086   this->PlaneSource->SetOrigin(origin);
1087   this->PlaneSource->SetPoint1(point1);
1088   this->PlaneSource->Update();
1089 
1090   this->PositionHandles();
1091 }
1092 
MovePoint2(double * p1,double * p2)1093 void vtkPlaneWidget::MovePoint2(double *p1, double *p2)
1094 {
1095   //Get the plane definition
1096   double *o = this->PlaneSource->GetOrigin();
1097   double *pt1 = this->PlaneSource->GetPoint1();
1098   double *pt2 = this->PlaneSource->GetPoint2();
1099 
1100   //Get the vector of motion
1101   double v[3];
1102   v[0] = p2[0] - p1[0];
1103   v[1] = p2[1] - p1[1];
1104   v[2] = p2[2] - p1[2];
1105 
1106   // The point opposite point2 (pt1) stays fixed
1107   double pt3[3];
1108   pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]);
1109   pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]);
1110   pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]);
1111 
1112   // Define vectors from point pt1
1113   double p01[3], p31[3];
1114   p31[0] = pt3[0] - pt1[0];
1115   p31[1] = pt3[1] - pt1[1];
1116   p31[2] = pt3[2] - pt1[2];
1117   p01[0] = o[0] - pt1[0];
1118   p01[1] = o[1] - pt1[1];
1119   p01[2] = o[2] - pt1[2];
1120 
1121   double vN = vtkMath::Norm(v);
1122   double n31 = vtkMath::Norm(p31);
1123   double n01 = vtkMath::Norm(p01);
1124 
1125   // if there is no motion then return
1126   if (vN == 0.0)
1127   {
1128     return;
1129   }
1130 
1131   // Project v onto these vector to determine the amount of motion
1132   // Scale it by the relative size of the motion to the vector length
1133   double d1 = (vN/n31) * vtkMath::Dot(v,p31) / (vN*n31);
1134   double d2 = (vN/n01) * vtkMath::Dot(v,p01) / (vN*n01);
1135 
1136   double point2[3], origin[3];
1137   for (int i=0; i<3; i++)
1138   {
1139     point2[i] = pt1[i] + (1.0+d1)*p31[i] + (1.0+d2)*p01[i];
1140     origin[i] = pt1[i] + (1.0+d2)*p01[i];
1141   }
1142 
1143   this->PlaneSource->SetOrigin(origin);
1144   this->PlaneSource->SetPoint2(point2);
1145   this->PlaneSource->Update();
1146 
1147   this->PositionHandles();
1148 }
1149 
MovePoint3(double * p1,double * p2)1150 void vtkPlaneWidget::MovePoint3(double *p1, double *p2)
1151 {
1152   //Get the plane definition
1153   double *o = this->PlaneSource->GetOrigin();
1154   double *pt1 = this->PlaneSource->GetPoint1();
1155   double *pt2 = this->PlaneSource->GetPoint2();
1156 
1157   //Get the vector of motion
1158   double v[3];
1159   v[0] = p2[0] - p1[0];
1160   v[1] = p2[1] - p1[1];
1161   v[2] = p2[2] - p1[2];
1162 
1163   // Define vectors from point pt3
1164   double p10[3], p20[3];
1165   p10[0] = pt1[0] - o[0];
1166   p10[1] = pt1[1] - o[1];
1167   p10[2] = pt1[2] - o[2];
1168   p20[0] = pt2[0] - o[0];
1169   p20[1] = pt2[1] - o[1];
1170   p20[2] = pt2[2] - o[2];
1171 
1172   double vN = vtkMath::Norm(v);
1173   double n10 = vtkMath::Norm(p10);
1174   double n20 = vtkMath::Norm(p20);
1175 
1176   // if there is no motion then return
1177   if (vN == 0.0)
1178   {
1179     return;
1180   }
1181 
1182   // Project v onto these vector to determine the amount of motion
1183   // Scale it by the relative size of the motion to the vector length
1184   double d1 = (vN/n10) * vtkMath::Dot(v,p10) / (vN*n10);
1185   double d2 = (vN/n20) * vtkMath::Dot(v,p20) / (vN*n20);
1186 
1187   double point1[3], point2[3];
1188   for (int i=0; i<3; i++)
1189   {
1190     point1[i] = o[i] + (1.0+d1)*p10[i];
1191     point2[i] = o[i] + (1.0+d2)*p20[i];
1192   }
1193 
1194   this->PlaneSource->SetPoint1(point1);
1195   this->PlaneSource->SetPoint2(point2);
1196   this->PlaneSource->Update();
1197 
1198   this->PositionHandles();
1199 }
1200 
Rotate(int X,int Y,double * p1,double * p2,double * vpn)1201 void vtkPlaneWidget::Rotate(int X, int Y, double *p1, double *p2, double *vpn)
1202 {
1203   double *o = this->PlaneSource->GetOrigin();
1204   double *pt1 = this->PlaneSource->GetPoint1();
1205   double *pt2 = this->PlaneSource->GetPoint2();
1206   double *center = this->PlaneSource->GetCenter();
1207 
1208   double v[3]; //vector of motion
1209   double axis[3]; //axis of rotation
1210   double theta; //rotation angle
1211 
1212   // mouse motion vector in world space
1213   v[0] = p2[0] - p1[0];
1214   v[1] = p2[1] - p1[1];
1215   v[2] = p2[2] - p1[2];
1216 
1217   // Create axis of rotation and angle of rotation
1218   vtkMath::Cross(vpn,v,axis);
1219   if ( vtkMath::Normalize(axis) == 0.0 )
1220   {
1221     return;
1222   }
1223   int *size = this->CurrentRenderer->GetSize();
1224   double l2 =
1225     (X-this->Interactor->GetLastEventPosition()[0])*
1226     (X-this->Interactor->GetLastEventPosition()[0]) +
1227     (Y-this->Interactor->GetLastEventPosition()[1])*
1228     (Y-this->Interactor->GetLastEventPosition()[1]);
1229   theta = 360.0 * sqrt(l2/(size[0]*size[0]+size[1]*size[1]));
1230 
1231   //Manipulate the transform to reflect the rotation
1232   this->Transform->Identity();
1233   this->Transform->Translate(center[0],center[1],center[2]);
1234   this->Transform->RotateWXYZ(theta,axis);
1235   this->Transform->Translate(-center[0],-center[1],-center[2]);
1236 
1237   //Set the corners
1238   double oNew[3], pt1New[3], pt2New[3];
1239   this->Transform->TransformPoint(o,oNew);
1240   this->Transform->TransformPoint(pt1,pt1New);
1241   this->Transform->TransformPoint(pt2,pt2New);
1242 
1243   this->PlaneSource->SetOrigin(oNew);
1244   this->PlaneSource->SetPoint1(pt1New);
1245   this->PlaneSource->SetPoint2(pt2New);
1246   this->PlaneSource->Update();
1247 
1248   this->PositionHandles();
1249 }
1250 
Spin(double * p1,double * p2)1251 void vtkPlaneWidget::Spin(double *p1, double *p2)
1252 {
1253   // Mouse motion vector in world space
1254   double v[3];
1255   v[0] = p2[0] - p1[0];
1256   v[1] = p2[1] - p1[1];
1257   v[2] = p2[2] - p1[2];
1258 
1259   double* normal = this->PlaneSource->GetNormal();
1260   // Axis of rotation
1261   double axis[3] = { normal[0], normal[1], normal[2] };
1262   vtkMath::Normalize(axis);
1263 
1264   double *o = this->PlaneSource->GetOrigin();
1265   double *pt1 = this->PlaneSource->GetPoint1();
1266   double *pt2 = this->PlaneSource->GetPoint2();
1267   double *center = this->PlaneSource->GetCenter();
1268 
1269   // Radius vector (from center to cursor position)
1270   double rv[3] = {p2[0] - center[0],
1271                   p2[1] - center[1],
1272                   p2[2] - center[2]};
1273 
1274   // Distance between center and cursor location
1275   double rs = vtkMath::Normalize(rv);
1276 
1277   // Spin direction
1278   double ax_cross_rv[3];
1279   vtkMath::Cross(axis,rv,ax_cross_rv);
1280 
1281   // Spin angle
1282   double theta = vtkMath::DegreesFromRadians( vtkMath::Dot( v, ax_cross_rv ) / rs );
1283 
1284   // Manipulate the transform to reflect the rotation
1285   this->Transform->Identity();
1286   this->Transform->Translate(center[0],center[1],center[2]);
1287   this->Transform->RotateWXYZ(theta,axis);
1288   this->Transform->Translate(-center[0],-center[1],-center[2]);
1289 
1290   //Set the corners
1291   double oNew[3], pt1New[3], pt2New[3];
1292   this->Transform->TransformPoint(o,oNew);
1293   this->Transform->TransformPoint(pt1,pt1New);
1294   this->Transform->TransformPoint(pt2,pt2New);
1295 
1296   this->PlaneSource->SetOrigin(oNew);
1297   this->PlaneSource->SetPoint1(pt1New);
1298   this->PlaneSource->SetPoint2(pt2New);
1299   this->PlaneSource->Update();
1300 
1301   this->PositionHandles();
1302 }
1303 
1304 // Loop through all points and translate them
Translate(double * p1,double * p2)1305 void vtkPlaneWidget::Translate(double *p1, double *p2)
1306 {
1307   //Get the motion vector
1308   double v[3];
1309   v[0] = p2[0] - p1[0];
1310   v[1] = p2[1] - p1[1];
1311   v[2] = p2[2] - p1[2];
1312 
1313   //int res = this->PlaneSource->GetXResolution();
1314   double *o = this->PlaneSource->GetOrigin();
1315   double *pt1 = this->PlaneSource->GetPoint1();
1316   double *pt2 = this->PlaneSource->GetPoint2();
1317 
1318   double origin[3], point1[3], point2[3];
1319   for (int i=0; i<3; i++)
1320   {
1321     origin[i] = o[i] + v[i];
1322     point1[i] = pt1[i] + v[i];
1323     point2[i] = pt2[i] + v[i];
1324   }
1325 
1326   this->PlaneSource->SetOrigin(origin);
1327   this->PlaneSource->SetPoint1(point1);
1328   this->PlaneSource->SetPoint2(point2);
1329   this->PlaneSource->Update();
1330 
1331   this->PositionHandles();
1332 }
1333 
Scale(double * p1,double * p2,int vtkNotUsed (X),int Y)1334 void vtkPlaneWidget::Scale(double *p1, double *p2, int vtkNotUsed(X), int Y)
1335 {
1336   //Get the motion vector
1337   double v[3];
1338   v[0] = p2[0] - p1[0];
1339   v[1] = p2[1] - p1[1];
1340   v[2] = p2[2] - p1[2];
1341 
1342   //int res = this->PlaneSource->GetXResolution();
1343   double *o = this->PlaneSource->GetOrigin();
1344   double *pt1 = this->PlaneSource->GetPoint1();
1345   double *pt2 = this->PlaneSource->GetPoint2();
1346 
1347   double center[3];
1348   center[0] = 0.5 * ( pt1[0] + pt2[0] );
1349   center[1] = 0.5 * ( pt1[1] + pt2[1] );
1350   center[2] = 0.5 * ( pt1[2] + pt2[2] );
1351 
1352   // Compute the scale factor
1353   double sf =
1354     vtkMath::Norm(v) / sqrt(vtkMath::Distance2BetweenPoints(pt1,pt2));
1355   if ( Y > this->Interactor->GetLastEventPosition()[1] )
1356   {
1357     sf = 1.0 + sf;
1358   }
1359   else
1360   {
1361     sf = 1.0 - sf;
1362   }
1363 
1364   // Move the corner points
1365   double origin[3], point1[3], point2[3];
1366   for (int i=0; i<3; i++)
1367   {
1368     origin[i] = sf * (o[i] - center[i]) + center[i];
1369     point1[i] = sf * (pt1[i] - center[i]) + center[i];
1370     point2[i] = sf * (pt2[i] - center[i]) + center[i];
1371   }
1372 
1373   this->PlaneSource->SetOrigin(origin);
1374   this->PlaneSource->SetPoint1(point1);
1375   this->PlaneSource->SetPoint2(point2);
1376   this->PlaneSource->Update();
1377 
1378   this->PositionHandles();
1379 }
1380 
Push(double * p1,double * p2)1381 void vtkPlaneWidget::Push(double *p1, double *p2)
1382 {
1383   //Get the motion vector
1384   double v[3];
1385   v[0] = p2[0] - p1[0];
1386   v[1] = p2[1] - p1[1];
1387   v[2] = p2[2] - p1[2];
1388 
1389   this->PlaneSource->Push( vtkMath::Dot(v,this->Normal) );
1390   this->PlaneSource->Update();
1391   this->PositionHandles();
1392 }
1393 
CreateDefaultProperties()1394 void vtkPlaneWidget::CreateDefaultProperties()
1395 {
1396   // Handle properties
1397   this->HandleProperty = vtkProperty::New();
1398   this->HandleProperty->SetColor(1,1,1);
1399 
1400   this->SelectedHandleProperty = vtkProperty::New();
1401   this->SelectedHandleProperty->SetColor(1,0,0);
1402 
1403   // Plane properties
1404   this->PlaneProperty = vtkProperty::New();
1405   this->PlaneProperty->SetAmbient(1.0);
1406   this->PlaneProperty->SetAmbientColor(1.0,1.0,1.0);
1407 
1408   this->SelectedPlaneProperty = vtkProperty::New();
1409   this->SelectRepresentation();
1410   this->SelectedPlaneProperty->SetAmbient(1.0);
1411   this->SelectedPlaneProperty->SetAmbientColor(0.0,1.0,0.0);
1412 }
1413 
PlaceWidget(double bds[6])1414 void vtkPlaneWidget::PlaceWidget(double bds[6])
1415 {
1416   int i;
1417   double bounds[6], center[3];
1418 
1419   this->AdjustBounds(bds, bounds, center);
1420 
1421   if (this->GetInput() || this->Prop3D)
1422   {
1423     if ( this->NormalToYAxis )
1424     {
1425       this->PlaneSource->SetOrigin(bounds[0],center[1],bounds[4]);
1426       this->PlaneSource->SetPoint1(bounds[1],center[1],bounds[4]);
1427       this->PlaneSource->SetPoint2(bounds[0],center[1],bounds[5]);
1428     }
1429     else if ( this->NormalToZAxis )
1430     {
1431       this->PlaneSource->SetOrigin(bounds[0],bounds[2],center[2]);
1432       this->PlaneSource->SetPoint1(bounds[1],bounds[2],center[2]);
1433       this->PlaneSource->SetPoint2(bounds[0],bounds[3],center[2]);
1434     }
1435     else //default or x-normal
1436     {
1437       this->PlaneSource->SetOrigin(center[0],bounds[2],bounds[4]);
1438       this->PlaneSource->SetPoint1(center[0],bounds[3],bounds[4]);
1439       this->PlaneSource->SetPoint2(center[0],bounds[2],bounds[5]);
1440     }
1441   }
1442 
1443   this->PlaneSource->Update();
1444 
1445   // Position the handles at the end of the planes
1446   this->PositionHandles();
1447 
1448   for (i=0; i<6; i++)
1449   {
1450     this->InitialBounds[i] = bounds[i];
1451   }
1452 
1453 
1454   if (this->GetInput() || this->Prop3D)
1455   {
1456     this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
1457                                (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
1458                                (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
1459   }
1460   else
1461   {
1462     // this means we have to make use of the PolyDataSource, so
1463     // we just calculate the magnitude of the longest diagonal on
1464     // the plane and use that as InitialLength
1465     double origin[3], point1[3], point2[3];
1466     this->PlaneSource->GetOrigin(origin);
1467     this->PlaneSource->GetPoint1(point1);
1468     this->PlaneSource->GetPoint2(point2);
1469     double sqr1 = 0, sqr2 = 0;
1470     for (i = 0; i < 3; i++)
1471     {
1472       sqr1 += (point1[i] - origin[i]) * (point1[i] - origin[i]);
1473       sqr2 += (point2[i] - origin[i]) * (point2[i] - origin[i]);
1474     }
1475 
1476     this->InitialLength = sqrt(sqr1 + sqr2);
1477   }
1478 
1479   // Set the radius on the sphere handles
1480   this->SizeHandles();
1481 }
1482 
SizeHandles()1483 void vtkPlaneWidget::SizeHandles()
1484 {
1485   double radius = this->vtk3DWidget::SizeHandles(this->HandleSizeFactor);
1486 
1487   if (this->ValidPick && !this->LastPickValid)
1488   {
1489     // Adjust factor to preserve old radius.
1490     double oldradius = this->HandleGeometry[0]->GetRadius();
1491     if (oldradius != 0 && radius != 0)
1492     {
1493       this->HandleSizeFactor = oldradius / radius;
1494       radius = oldradius;
1495     }
1496   }
1497 
1498   this->LastPickValid = this->ValidPick;
1499 
1500   for(int i=0; i<4; i++)
1501   {
1502     this->HandleGeometry[i]->SetRadius(radius);
1503   }
1504 
1505   // Set the height and radius of the cone
1506   this->ConeSource->SetHeight(2.0*radius);
1507   this->ConeSource->SetRadius(radius);
1508   this->ConeSource2->SetHeight(2.0*radius);
1509   this->ConeSource2->SetRadius(radius);
1510 
1511 }
1512 
1513 
SelectRepresentation()1514 void vtkPlaneWidget::SelectRepresentation()
1515 {
1516   if ( ! this->CurrentRenderer )
1517   {
1518     return;
1519   }
1520 
1521   if ( this->Representation == VTK_PLANE_OFF )
1522   {
1523     this->CurrentRenderer->RemoveActor(this->PlaneActor);
1524   }
1525   else if ( this->Representation == VTK_PLANE_OUTLINE )
1526   {
1527     this->CurrentRenderer->RemoveActor(this->PlaneActor);
1528     this->CurrentRenderer->AddActor(this->PlaneActor);
1529     this->PlaneMapper->SetInputData( this->PlaneOutline );
1530     this->PlaneActor->GetProperty()->SetRepresentationToWireframe();
1531   }
1532   else if ( this->Representation == VTK_PLANE_SURFACE )
1533   {
1534     this->CurrentRenderer->RemoveActor(this->PlaneActor);
1535     this->CurrentRenderer->AddActor(this->PlaneActor);
1536     this->PlaneMapper->SetInputConnection( this->PlaneSource->GetOutputPort() );
1537     this->PlaneActor->GetProperty()->SetRepresentationToSurface();
1538   }
1539   else //( this->Representation == VTK_PLANE_WIREFRAME )
1540   {
1541     this->CurrentRenderer->RemoveActor(this->PlaneActor);
1542     this->CurrentRenderer->AddActor(this->PlaneActor);
1543     this->PlaneMapper->SetInputConnection( this->PlaneSource->GetOutputPort() );
1544     this->PlaneActor->GetProperty()->SetRepresentationToWireframe();
1545   }
1546 }
1547 
1548 // Description:
1549 // Set/Get the resolution (number of subdivisions) of the plane.
SetResolution(int r)1550 void vtkPlaneWidget::SetResolution(int r)
1551 {
1552   this->PlaneSource->SetXResolution(r);
1553   this->PlaneSource->SetYResolution(r);
1554 }
1555 
GetResolution()1556 int vtkPlaneWidget::GetResolution()
1557 {
1558   return this->PlaneSource->GetXResolution();
1559 }
1560 
1561 // Description:
1562 // Set/Get the origin of the plane.
SetOrigin(double x,double y,double z)1563 void vtkPlaneWidget::SetOrigin(double x, double y, double z)
1564 {
1565   this->PlaneSource->SetOrigin(x,y,z);
1566   this->PositionHandles();
1567 }
1568 
SetOrigin(double x[3])1569 void vtkPlaneWidget::SetOrigin(double x[3])
1570 {
1571   this->SetOrigin(x[0], x[1], x[2]);
1572 }
1573 
GetOrigin()1574 double* vtkPlaneWidget::GetOrigin()
1575 {
1576   return this->PlaneSource->GetOrigin();
1577 }
1578 
GetOrigin(double xyz[3])1579 void vtkPlaneWidget::GetOrigin(double xyz[3])
1580 {
1581   this->PlaneSource->GetOrigin(xyz);
1582 }
1583 
1584 // Description:
1585 // Set/Get the position of the point defining the first axis of the plane.
SetPoint1(double x,double y,double z)1586 void vtkPlaneWidget::SetPoint1(double x, double y, double z)
1587 {
1588   this->PlaneSource->SetPoint1(x,y,z);
1589   this->PositionHandles();
1590 }
1591 
SetPoint1(double x[3])1592 void vtkPlaneWidget::SetPoint1(double x[3])
1593 {
1594   this->SetPoint1(x[0], x[1], x[2]);
1595 }
1596 
GetPoint1()1597 double* vtkPlaneWidget::GetPoint1()
1598 {
1599   return this->PlaneSource->GetPoint1();
1600 }
1601 
GetPoint1(double xyz[3])1602 void vtkPlaneWidget::GetPoint1(double xyz[3])
1603 {
1604   this->PlaneSource->GetPoint1(xyz);
1605 }
1606 
1607 // Description:
1608 // Set/Get the position of the point defining the second axis of the plane.
SetPoint2(double x,double y,double z)1609 void vtkPlaneWidget::SetPoint2(double x, double y, double z)
1610 {
1611   this->PlaneSource->SetPoint2(x,y,z);
1612   this->PositionHandles();
1613 }
1614 
SetPoint2(double x[3])1615 void vtkPlaneWidget::SetPoint2(double x[3])
1616 {
1617   this->SetPoint2(x[0], x[1], x[2]);
1618 }
1619 
GetPoint2()1620 double* vtkPlaneWidget::GetPoint2()
1621 {
1622   return this->PlaneSource->GetPoint2();
1623 }
1624 
GetPoint2(double xyz[3])1625 void vtkPlaneWidget::GetPoint2(double xyz[3])
1626 {
1627   this->PlaneSource->GetPoint2(xyz);
1628 }
1629 
1630 // Description:
1631 // Set the center of the plane.
SetCenter(double x,double y,double z)1632 void vtkPlaneWidget::SetCenter(double x, double y, double z)
1633 {
1634   this->PlaneSource->SetCenter(x, y, z);
1635   this->PositionHandles();
1636 }
1637 
1638 // Description:
1639 // Set the center of the plane.
SetCenter(double c[3])1640 void vtkPlaneWidget::SetCenter(double c[3])
1641 {
1642   this->SetCenter(c[0], c[1], c[2]);
1643 }
1644 
1645 // Description:
1646 // Get the center of the plane.
GetCenter()1647 double* vtkPlaneWidget::GetCenter()
1648 {
1649   return this->PlaneSource->GetCenter();
1650 }
1651 
GetCenter(double xyz[3])1652 void vtkPlaneWidget::GetCenter(double xyz[3])
1653 {
1654   this->PlaneSource->GetCenter(xyz);
1655 }
1656 
1657 // Description:
1658 // Set the normal to the plane.
SetNormal(double x,double y,double z)1659 void vtkPlaneWidget::SetNormal(double x, double y, double z)
1660 {
1661   this->PlaneSource->SetNormal(x, y, z);
1662   this->PositionHandles();
1663 }
1664 
1665 // Description:
1666 // Set the normal to the plane.
SetNormal(double n[3])1667 void vtkPlaneWidget::SetNormal(double n[3])
1668 {
1669   this->SetNormal(n[0], n[1], n[2]);
1670 }
1671 
1672 // Description:
1673 // Get the normal to the plane.
GetNormal()1674 double* vtkPlaneWidget::GetNormal()
1675 {
1676   return this->PlaneSource->GetNormal();
1677 }
1678 
GetNormal(double xyz[3])1679 void vtkPlaneWidget::GetNormal(double xyz[3])
1680 {
1681   this->PlaneSource->GetNormal(xyz);
1682 }
1683 
GetPolyData(vtkPolyData * pd)1684 void vtkPlaneWidget::GetPolyData(vtkPolyData *pd)
1685 {
1686   pd->ShallowCopy(this->PlaneSource->GetOutput());
1687 }
1688 
GetPolyDataAlgorithm()1689 vtkPolyDataAlgorithm *vtkPlaneWidget::GetPolyDataAlgorithm()
1690 {
1691   return this->PlaneSource;
1692 }
1693 
GetPlane(vtkPlane * plane)1694 void vtkPlaneWidget::GetPlane(vtkPlane *plane)
1695 {
1696   if ( plane == nullptr )
1697   {
1698     return;
1699   }
1700 
1701   plane->SetNormal(this->GetNormal());
1702   plane->SetOrigin(this->GetCenter());
1703 }
1704 
UpdatePlacement(void)1705 void vtkPlaneWidget::UpdatePlacement(void)
1706 {
1707   this->PlaneSource->Update();
1708   this->PositionHandles();
1709 }
1710