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