1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkFinitePlaneRepresentation.cxx
5 
6   Copyright (c)
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 
16 #include "vtkFinitePlaneRepresentation.h"
17 
18 #include "vtkActor.h"
19 #include "vtkAssemblyPath.h"
20 #include "vtkBox.h"
21 #include "vtkCamera.h"
22 #include "vtkCellArray.h"
23 #include "vtkCellPicker.h"
24 #include "vtkConeSource.h"
25 #include "vtkDoubleArray.h"
26 #include "vtkFeatureEdges.h"
27 #include "vtkInteractorObserver.h"
28 #include "vtkLineSource.h"
29 #include "vtkMath.h"
30 #include "vtkNew.h"
31 #include "vtkObjectFactory.h"
32 #include "vtkPickingManager.h"
33 #include "vtkPolyData.h"
34 #include "vtkPolyDataMapper.h"
35 #include "vtkProperty.h"
36 #include "vtkRenderer.h"
37 #include "vtkRenderWindow.h"
38 #include "vtkRenderWindowInteractor.h"
39 #include "vtkSphereSource.h"
40 #include "vtkTransform.h"
41 #include "vtkTubeFilter.h"
42 #include "vtkWindow.h"
43 
44 vtkStandardNewMacro(vtkFinitePlaneRepresentation);
45 
46 //----------------------------------------------------------------------------
vtkFinitePlaneRepresentation()47 vtkFinitePlaneRepresentation::vtkFinitePlaneRepresentation()
48 {
49   // The initial state
50   this->InteractionState = vtkFinitePlaneRepresentation::Outside;
51 
52   // Handle size is in pixels for this widget
53   this->HandleSize = 5.;
54 
55   // Set up the initial properties
56   this->CreateDefaultProperties();
57 
58   this->Origin[0] = 0.;
59   this->Origin[1] = 0.;
60   this->Origin[2] = 0.;
61 
62   this->Normal[0] = 0.;
63   this->Normal[1] = 0.;
64   this->Normal[2] = 1.;
65 
66   this->PreviousNormal[0] = 0.;
67   this->PreviousNormal[1] = 0.;
68   this->PreviousNormal[2] = 1.;
69   this->Transform = vtkTransform::New();
70   this->Transform->Identity();
71 
72   this->V1[0] = 1.;
73   this->V1[1] = 0.;
74   this->V1[2] = 0.;
75   this->V2[0] = 0.;
76   this->V2[1] = 1.;
77   this->V2[2] = 0.;
78 
79   double p1[3];
80   p1[0] = this->Origin[0] + this->V1[0];
81   p1[1] = this->Origin[1] + this->V1[1];
82   p1[2] = this->Origin[2] + this->V1[2];
83 
84   double p2[3];
85   p2[0] = this->Origin[0] + this->V2[0];
86   p2[1] = this->Origin[1] + this->V2[1];
87   p2[2] = this->Origin[2] + this->V2[2];
88 
89   // the origin
90   this->OriginGeometry = vtkSphereSource::New();
91   this->OriginGeometry->SetCenter(this->Origin);
92   this->OriginGeometry->Update();
93   this->OriginMapper = vtkPolyDataMapper::New();
94   this->OriginMapper->SetInputConnection(this->OriginGeometry->GetOutputPort());
95   this->OriginActor = vtkActor::New();
96   this->OriginActor->SetMapper(this->OriginMapper);
97 
98   // the X Vector
99   this->V1Geometry = vtkSphereSource::New();
100   this->V1Geometry->SetCenter(p1);
101   this->V1Geometry->Update();
102   this->V1Mapper = vtkPolyDataMapper::New();
103   this->V1Mapper->SetInputConnection(this->V1Geometry->GetOutputPort());
104   this->V1Actor = vtkActor::New();
105   this->V1Actor->SetMapper(this->V1Mapper);
106 
107   // the Y Vector
108   this->V2Geometry = vtkSphereSource::New();
109   this->V2Geometry->SetCenter(p2);
110   this->V2Geometry->Update();
111   this->V2Mapper = vtkPolyDataMapper::New();
112   this->V2Mapper->SetInputConnection(this->V2Geometry->GetOutputPort());
113   this->V2Actor = vtkActor::New();
114   this->V2Actor->SetMapper(this->V2Mapper);
115 
116  // Create the + plane normal
117   this->LineSource = vtkLineSource::New();
118   this->LineSource->SetResolution(1);
119   this->LineMapper = vtkPolyDataMapper::New();
120   this->LineMapper->SetInputConnection(this->LineSource->GetOutputPort());
121   this->LineActor = vtkActor::New();
122   this->LineActor->SetMapper(this->LineMapper);
123 
124   this->ConeSource = vtkConeSource::New();
125   this->ConeSource->SetResolution(12);
126   this->ConeSource->SetAngle(25.0);
127   this->ConeMapper = vtkPolyDataMapper::New();
128   this->ConeMapper->SetInputConnection(this->ConeSource->GetOutputPort());
129   this->ConeActor = vtkActor::New();
130   this->ConeActor->SetMapper(this->ConeMapper);
131 
132   // Create the - plane normal
133   this->LineSource2 = vtkLineSource::New();
134   this->LineSource2->SetResolution(1);
135   this->LineMapper2 = vtkPolyDataMapper::New();
136   this->LineMapper2->SetInputConnection(this->LineSource2->GetOutputPort());
137   this->LineActor2 = vtkActor::New();
138   this->LineActor2->SetMapper(this->LineMapper2);
139 
140   this->ConeSource2 = vtkConeSource::New();
141   this->ConeSource2->SetResolution(12);
142   this->ConeSource2->SetAngle(25.0);
143   this->ConeMapper2 = vtkPolyDataMapper::New();
144   this->ConeMapper2->SetInputConnection(this->ConeSource2->GetOutputPort());
145   this->ConeActor2 = vtkActor::New();
146   this->ConeActor2->SetMapper(this->ConeMapper2);
147 
148   // The finite plane
149   this->PlanePolyData  = vtkPolyData::New();
150 
151   // Construct initial points
152   vtkNew<vtkPoints> points;
153   points->SetDataTypeToDouble();
154   points->SetNumberOfPoints(4);
155   this->PlanePolyData->SetPoints(points);
156   for (int i = 0; i < 4; i++)
157   {
158     points->SetPoint(i, this->Origin);
159   }
160 
161   // Construct plane geometry
162   vtkNew<vtkCellArray> cell;
163   cell->Allocate(5);
164   vtkIdType pts[4] = { 0, 1, 2, 3 };
165   cell->InsertNextCell(4, pts);
166   this->PlanePolyData->SetPolys(cell);
167   this->PlanePolyData->BuildCells();
168 
169   this->PlaneMapper = vtkPolyDataMapper::New();
170   this->PlaneMapper->SetInputData(this->PlanePolyData);
171   this->PlaneActor = vtkActor::New();
172   this->PlaneActor->SetMapper(this->PlaneMapper);
173 
174   this->Edges = vtkFeatureEdges::New();
175   this->Edges->SetInputData(this->PlanePolyData);
176 
177   this->EdgesTuber = vtkTubeFilter::New();
178   this->EdgesTuber->SetInputConnection(this->Edges->GetOutputPort());
179   this->EdgesTuber->SetNumberOfSides(12);
180   this->EdgesMapper = vtkPolyDataMapper::New();
181   this->EdgesMapper->SetInputConnection(this->EdgesTuber->GetOutputPort());
182   this->EdgesActor = vtkActor::New();
183   this->EdgesActor->SetMapper(this->EdgesMapper);
184   this->Tubing = true; //control whether tubing is on
185   this->DrawPlane = true; //control whether draw plane is on
186   this->CurrentHandle = nullptr;
187 
188   // Initial creation of the widget, serves to initialize it
189   double bounds[6] = { -0.5, 0.5, -0.5, 0.5, -0.5, 0.5 };
190   this->PlaceWidget(bounds);
191 
192   //Manage the picking stuff
193   this->HandlePicker = vtkCellPicker::New();
194   this->HandlePicker->SetTolerance(0.001);
195 
196   this->HandlePicker->AddPickList(OriginActor);
197   this->HandlePicker->AddPickList(V1Actor);
198   this->HandlePicker->AddPickList(V2Actor);
199   this->HandlePicker->AddPickList(LineActor);
200   this->HandlePicker->AddPickList(ConeActor);
201   this->HandlePicker->AddPickList(LineActor2);
202   this->HandlePicker->AddPickList(ConeActor2);
203   this->HandlePicker->AddPickList(PlaneActor);
204 
205   this->HandlePicker->PickFromListOn();
206 
207   // The bounding box
208   this->BoundingBox = vtkBox::New();
209 
210   this->RepresentationState = vtkFinitePlaneRepresentation::Outside;
211 
212   // Pass the initial properties to the actors.
213   this->LineActor->SetProperty(this->NormalProperty);
214   this->ConeActor->SetProperty(this->NormalProperty);
215   this->LineActor2->SetProperty(this->NormalProperty);
216   this->ConeActor2->SetProperty(this->NormalProperty);
217   this->PlaneActor->SetProperty(this->PlaneProperty);
218   this->V1Actor->SetProperty(this->V1HandleProperty);
219   this->V2Actor->SetProperty(this->V2HandleProperty);
220   this->OriginActor->SetProperty(this->OriginHandleProperty);
221 
222   // Internal data members for performance
223   this->TransformRotation = vtkTransform::New();
224 }
225 
226 //----------------------------------------------------------------------------
~vtkFinitePlaneRepresentation()227 vtkFinitePlaneRepresentation::~vtkFinitePlaneRepresentation()
228 {
229   this->OriginGeometry->Delete();
230   this->OriginMapper->Delete();
231   this->OriginActor->Delete();
232 
233   // the X Vector
234   this->V1Geometry->Delete();
235   this->V1Mapper->Delete();
236   this->V1Actor->Delete();
237 
238   // the Y Vector
239   this->V2Geometry->Delete();
240   this->V2Mapper->Delete();
241   this->V2Actor->Delete();
242 
243   // The + normal cone
244   this->ConeSource->Delete();
245   this->ConeMapper->Delete();
246   this->ConeActor->Delete();
247 
248   // The + normal line
249   this->LineSource->Delete();
250   this->LineMapper->Delete();
251   this->LineActor->Delete();
252 
253   // The - normal cone
254   this->ConeSource2->Delete();
255   this->ConeMapper2->Delete();
256   this->ConeActor2->Delete();
257 
258   // The - normal line
259   this->LineSource2->Delete();
260   this->LineMapper2->Delete();
261   this->LineActor2->Delete();
262 
263   // The finite plane
264   this->PlanePolyData->Delete();
265   this->PlaneMapper->Delete();
266   this->PlaneActor->Delete();
267 
268   this->Edges->Delete();
269   this->EdgesTuber->Delete();
270   this->EdgesMapper->Delete();
271   this->EdgesActor->Delete();
272 
273   this->BoundingBox->Delete();
274 
275   this->NormalProperty->Delete();
276   this->SelectedNormalProperty->Delete();
277 
278   this->HandlePicker->Delete();
279 
280   this->TransformRotation->Delete();
281   this->Transform->Delete();
282 
283   this->OriginHandleProperty->Delete();
284   this->V1HandleProperty->Delete();
285   this->V2HandleProperty->Delete();
286   this->SelectedHandleProperty->Delete();
287   this->PlaneProperty->Delete();
288   this->SelectedPlaneProperty->Delete();
289 }
290 
291 //----------------------------------------------------------------------
GetPolyData(vtkPolyData * pd)292 void vtkFinitePlaneRepresentation::GetPolyData(vtkPolyData *pd)
293 {
294   pd->ShallowCopy(this->PlanePolyData);
295 }
296 
297 //----------------------------------------------------------------------
StartWidgetInteraction(double e[2])298 void vtkFinitePlaneRepresentation::StartWidgetInteraction(double e[2])
299 {
300   // Store the start position
301   this->StartEventPosition[0] = e[0];
302   this->StartEventPosition[1] = e[1];
303   this->StartEventPosition[2] = 0.0;
304 
305   // Store the start position
306   this->LastEventPosition[0] = e[0];
307   this->LastEventPosition[1] = e[1];
308   this->LastEventPosition[2] = 0.0;
309 }
310 
311 //----------------------------------------------------------------------
WidgetInteraction(double e[2])312 void vtkFinitePlaneRepresentation::WidgetInteraction(double e[2])
313 {
314   // Do different things depending on state
315   // Calculations everybody does
316   double focalPoint[4], pickPoint[4], prevPickPoint[4];
317   double z, vpn[3];
318 
319   vtkCamera *camera = this->Renderer->GetActiveCamera();
320   if (!camera)
321   {
322     return;
323   }
324 
325   // Compute the two points defining the motion vector
326   double pos[3];
327   this->HandlePicker->GetPickPosition(pos);
328 
329   vtkInteractorObserver::ComputeWorldToDisplay(
330     this->Renderer, pos[0], pos[1], pos[2], focalPoint);
331 
332   z = focalPoint[2];
333   vtkInteractorObserver::ComputeDisplayToWorld(
334     this->Renderer, this->LastEventPosition[0],
335     this->LastEventPosition[1], z, prevPickPoint);
336   vtkInteractorObserver::ComputeDisplayToWorld(
337     this->Renderer, e[0], e[1], z, pickPoint);
338 
339   // Process the motion
340   if (this->InteractionState == vtkFinitePlaneRepresentation::MoveOrigin)
341   {
342     this->TranslateOrigin(prevPickPoint, pickPoint);
343   }
344   else if (this->InteractionState == vtkFinitePlaneRepresentation::ModifyV1)
345   {
346     this->MovePoint1(prevPickPoint, pickPoint);
347   }
348   else if (this->InteractionState == vtkFinitePlaneRepresentation::ModifyV2)
349   {
350     this->MovePoint2(prevPickPoint, pickPoint);
351   }
352   else if (this->InteractionState == vtkFinitePlaneRepresentation::Rotating)
353   {
354     camera->GetViewPlaneNormal(vpn);
355     this->Rotate(e[0], e[1], prevPickPoint, pickPoint, vpn);
356   }
357   else if (this->InteractionState == vtkFinitePlaneRepresentation::Pushing)
358   {
359     this->Push(prevPickPoint, pickPoint);
360   }
361 
362   // Store the start position
363   this->LastEventPosition[0] = e[0];
364   this->LastEventPosition[1] = e[1];
365   this->LastEventPosition[2] = 0.0;
366 }
367 
368 //----------------------------------------------------------------------------
Rotate(int X,int Y,double * p1,double * p2,double * vpn)369 void vtkFinitePlaneRepresentation::Rotate(int X, int Y,
370                                           double *p1, double *p2, double *vpn)
371 {
372   double v[3];    //vector of motion
373   double axis[3]; //axis of rotation
374 
375   // Mouse motion vector in world space
376   v[0] = p2[0] - p1[0];
377   v[1] = p2[1] - p1[1];
378   v[2] = p2[2] - p1[2];
379 
380   // Create axis of rotation and angle of rotation
381   vtkMath::Cross(vpn, v, axis);
382   if (vtkMath::Normalize(axis) == 0.0)
383   {
384     return;
385   }
386   int *size = this->Renderer->GetSize();
387   double l2 = (X - this->LastEventPosition[0]) *
388     (X - this->LastEventPosition[0]) +
389     (Y - this->LastEventPosition[1]) * (Y - this->LastEventPosition[1]);
390   double theta = 360.0 * sqrt(l2 / (size[0] * size[0] + size[1] * size[1]));
391 
392   //Manipulate the transform to reflect the rotation
393   this->TransformRotation->Identity();
394   this->TransformRotation->Translate(this->Origin);
395   this->TransformRotation->RotateWXYZ(theta, axis);
396   this->TransformRotation->Translate(
397     -this->Origin[0], -this->Origin[1], -this->Origin[2]);
398 
399   //Set the new normal
400   double nNew[3];
401   this->TransformRotation->TransformNormal(this->Normal, nNew);
402   this->SetNormal(nNew);
403 }
404 
405 //----------------------------------------------------------------------------
CreateDefaultProperties()406 void vtkFinitePlaneRepresentation::CreateDefaultProperties()
407 {
408   // Normal properties
409   this->NormalProperty = vtkProperty::New();
410   this->NormalProperty->SetColor(1.0, 1.0, 1.0);
411   this->NormalProperty->SetLineWidth(2.0);
412 
413   this->SelectedNormalProperty = vtkProperty::New();
414   this->SelectedNormalProperty->SetColor(1.0, 0.0, 0.0);
415   this->NormalProperty->SetLineWidth(2.0);
416 
417   // Origin Handle properties
418   this->OriginHandleProperty = vtkProperty::New();
419   this->OriginHandleProperty->SetColor(1.0, 1.0, 1.0);
420 
421   // P1 Handle properties
422   this->V1HandleProperty = vtkProperty::New();
423   this->V1HandleProperty->SetColor(1.0, 0.0, 0.0);
424 
425   // P2 Handle properties
426   this->V2HandleProperty = vtkProperty::New();
427   this->V2HandleProperty->SetColor(0.0, 1.0, 0.0);
428 
429   this->SelectedHandleProperty = vtkProperty::New();
430   this->SelectedHandleProperty->SetColor(1.0, 1.0, 0.0);
431 
432   // Plane properties
433   this->PlaneProperty = vtkProperty::New();
434   this->PlaneProperty->SetAmbient(1.0);
435   this->PlaneProperty->SetAmbientColor(1.0, 1.0, 1.0);
436   this->PlaneProperty->SetOpacity(0.5);
437 
438   this->SelectedPlaneProperty = vtkProperty::New();
439   this->SelectedPlaneProperty->SetAmbient(1.0);
440   this->SelectedPlaneProperty->SetColor(0.0, 1.0, 0.0);
441   this->SelectedPlaneProperty->SetOpacity(0.25);
442 }
443 
444 //----------------------------------------------------------------------------
PlaceWidget(double bnds[6])445 void vtkFinitePlaneRepresentation::PlaceWidget(double bnds[6])
446 {
447   this->Normal[0] = 0.0;
448   this->Normal[1] = 0.0;
449   this->Normal[2] = 1.0;
450 
451   this->Origin[0] = ((bnds[1] - bnds[0]) * 0.5) + bnds[0];
452   this->Origin[1] = ((bnds[3] - bnds[2]) * 0.5) + bnds[2];
453   this->Origin[2] = ((bnds[5] - bnds[4]) * 0.5) + bnds[4];
454 
455   this->V1[0] = ((bnds[1] - bnds[0]) * 0.5);
456   this->V1[1] = 0.0;
457   this->V1[2] = 0.0;
458 
459   this->V2[0] = 0.0;
460   this->V2[1] = ((bnds[3] - bnds[2]) * 0.5);
461   this->V2[2] = 0.0;
462 
463   this->InitialLength =
464     sqrt((bnds[1] - bnds[0]) * (bnds[1] - bnds[0]) +
465          (bnds[3] - bnds[2]) * (bnds[3] - bnds[2]) +
466          (bnds[5] - bnds[4]) * (bnds[5] - bnds[4]));
467 
468   this->ValidPick = 1; // since we have positioned the widget successfully
469   this->BuildRepresentation();
470 }
471 
472 //----------------------------------------------------------------------------
ComputeInteractionState(int X,int Y,int vtkNotUsed (modify))473 int vtkFinitePlaneRepresentation::ComputeInteractionState(int X, int Y,
474                                                           int vtkNotUsed(modify))
475 {
476   // Okay, we can process this. Try to pick handles first;
477   // if no handles picked, then pick the bounding box.
478   if (!this->Renderer || !this->Renderer->IsInViewport(X, Y))
479   {
480     this->SetRepresentationState(vtkFinitePlaneRepresentation::Outside);
481     this->InteractionState = vtkFinitePlaneRepresentation::Outside;
482     return this->InteractionState;
483   }
484 
485   this->SetHighlightNormal(0);
486   this->SetHighlightPlane(0);
487   this->SetHighlightHandle(nullptr);
488 
489   // See if anything has been selected
490   vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
491 
492   if (path == nullptr) // Not picking this widget
493   {
494     this->SetRepresentationState(vtkFinitePlaneRepresentation::Outside);
495     this->InteractionState = vtkFinitePlaneRepresentation::Outside;
496     return this->InteractionState;
497   }
498 
499   // Something picked, continue
500   this->ValidPick = 1;
501   vtkProp *prop = path->GetFirstNode()->GetViewProp();
502 
503   if (prop == this->PlaneActor)
504   {
505     this->SetRepresentationState(vtkFinitePlaneRepresentation::Pushing);
506     this->InteractionState = vtkFinitePlaneRepresentation::Pushing;
507     this->SetHighlightNormal(0);
508     this->SetHighlightPlane(1);
509     this->SetHighlightHandle(nullptr);
510   }
511   else if ((prop == this->ConeActor) || (prop == this->ConeActor2) ||
512     (prop == this->LineActor) || (prop == this->LineActor2))
513   {
514     this->SetRepresentationState(vtkFinitePlaneRepresentation::Rotating);
515     this->InteractionState = vtkFinitePlaneRepresentation::Rotating;
516 
517     this->SetHighlightNormal(1);
518     this->SetHighlightPlane(1);
519     this->SetHighlightHandle(nullptr);
520   }
521   else if (prop == this->OriginActor)
522   {
523     this->SetRepresentationState(vtkFinitePlaneRepresentation::MoveOrigin);
524     this->InteractionState = vtkFinitePlaneRepresentation::MoveOrigin;
525 
526     this->SetHighlightNormal(1);
527     this->SetHighlightPlane(1);
528     this->SetHighlightHandle(prop);
529   }
530   else if (prop == this->V1Actor)
531   {
532     this->SetRepresentationState(vtkFinitePlaneRepresentation::ModifyV1);
533     this->InteractionState = vtkFinitePlaneRepresentation::ModifyV1;
534 
535     this->SetHighlightNormal(0);
536     this->SetHighlightPlane(0);
537     this->SetHighlightHandle(prop);
538   }
539   else if (prop == this->V2Actor)
540   {
541     this->SetRepresentationState(vtkFinitePlaneRepresentation::ModifyV2);
542     this->InteractionState = vtkFinitePlaneRepresentation::ModifyV2;
543 
544     this->SetHighlightNormal(0);
545     this->SetHighlightPlane(0);
546     this->SetHighlightHandle(prop);
547   }
548 
549   return this->InteractionState;
550 }
551 
552 //----------------------------------------------------------------------
GetBounds()553 double *vtkFinitePlaneRepresentation::GetBounds()
554 {
555   this->BuildRepresentation();
556 
557   this->BoundingBox->SetBounds(this->OriginActor->GetBounds());
558   this->BoundingBox->AddBounds(this->V1Actor->GetBounds());
559   this->BoundingBox->AddBounds(this->V2Actor->GetBounds());
560   this->BoundingBox->AddBounds(this->EdgesActor->GetBounds());
561   this->BoundingBox->AddBounds(this->PlaneActor->GetBounds());
562   this->BoundingBox->AddBounds(this->ConeActor->GetBounds());
563   this->BoundingBox->AddBounds(this->LineActor->GetBounds());
564   this->BoundingBox->AddBounds(this->ConeActor2->GetBounds());
565   this->BoundingBox->AddBounds(this->LineActor2->GetBounds());
566 
567   return this->BoundingBox->GetBounds();
568 }
569 
570 //----------------------------------------------------------------------------
BuildRepresentation()571 void vtkFinitePlaneRepresentation::BuildRepresentation()
572 {
573   this->SizeHandles();
574 
575   if (this->GetMTime() < this->BuildTime &&
576       this->PlanePolyData->GetMTime() < this->BuildTime)
577   {
578     return;
579   }
580 
581   double *origin = this->GetOrigin();
582   double *normal = this->GetNormal();
583 
584   // Setup the plane normal
585   double d = this->PlanePolyData->GetLength() *1.2;
586 
587   double p2Line[3];
588   p2Line[0] = origin[0] + 0.30 * d * normal[0];
589   p2Line[1] = origin[1] + 0.30 * d * normal[1];
590   p2Line[2] = origin[2] + 0.30 * d * normal[2];
591 
592   this->LineSource->SetPoint1(origin);
593   this->LineSource->SetPoint2(p2Line);
594   this->ConeSource->SetCenter(p2Line);
595   this->ConeSource->SetDirection(normal);
596 
597   p2Line[0] = origin[0] - 0.30 * d * normal[0];
598   p2Line[1] = origin[1] - 0.30 * d * normal[1];
599   p2Line[2] = origin[2] - 0.30 * d * normal[2];
600 
601   this->LineSource2->SetPoint1(origin);
602   this->LineSource2->SetPoint2(p2Line);
603   this->ConeSource2->SetCenter(p2Line);
604   this->ConeSource2->SetDirection(normal);
605 
606   // Set up the position handle
607   this->OriginGeometry->SetCenter(origin);
608 
609   double vector1[3] = { this->V1[0], this->V1[1], this->V1[2] };
610   this->Transform->TransformVector(vector1, vector1);
611 
612   double position[3];
613   this->Transform->GetPosition(position);
614 
615   double point1[3];
616   point1[0] = origin[0] + vector1[0];
617   point1[1] = origin[1] + vector1[1];
618   point1[2] = origin[2] + vector1[2];
619   this->V1Geometry->SetCenter(point1);
620 
621   double vector2[3] = { this->V2[0], this->V2[1], this->V2[2] };
622   this->Transform->TransformPoint(vector2, vector2);
623 
624   double point2[3];
625   point2[0] = origin[0] + vector2[0];
626   point2[1] = origin[1] + vector2[1];
627   point2[2] = origin[2] + vector2[2];
628   this->V2Geometry->SetCenter(point2);
629 
630   // Build Plane polydata
631   vtkPoints *points = this->PlanePolyData->GetPoints();
632   points->SetPoint(0,
633     origin[0] - vector1[0] - vector2[0],
634     origin[1] - vector1[1] - vector2[1],
635     origin[2] - vector1[2] - vector2[2]);
636   points->SetPoint(1,
637     origin[0] - vector1[0] + vector2[0],
638     origin[1] - vector1[1] + vector2[1],
639     origin[2] - vector1[2] + vector2[2]);
640   points->SetPoint(2,
641     origin[0] + vector1[0] + vector2[0],
642     origin[1] + vector1[1] + vector2[1],
643     origin[2] + vector1[2] + vector2[2]);
644   points->SetPoint(3,
645     origin[0] + vector1[0] - vector2[0],
646     origin[1] + vector1[1] - vector2[1],
647     origin[2] + vector1[2] - vector2[2]);
648   points->Modified();
649 
650   this->PlanePolyData->Modified();
651 
652   // Control the look of the edges
653   this->EdgesMapper->SetInputConnection(this->Tubing ?
654     this->EdgesTuber->GetOutputPort(): this->Edges->GetOutputPort());
655 
656   this->SizeHandles();
657   this->BuildTime.Modified();
658 }
659 
660 //----------------------------------------------------------------------------
ReleaseGraphicsResources(vtkWindow * w)661 void vtkFinitePlaneRepresentation::ReleaseGraphicsResources(vtkWindow *w)
662 {
663   this->OriginActor->ReleaseGraphicsResources(w);
664   this->V1Actor->ReleaseGraphicsResources(w);
665   this->V2Actor->ReleaseGraphicsResources(w);
666   this->PlaneActor->ReleaseGraphicsResources(w);
667   this->EdgesActor->ReleaseGraphicsResources(w);
668   this->ConeActor->ReleaseGraphicsResources(w);
669   this->LineActor->ReleaseGraphicsResources(w);
670   this->ConeActor2->ReleaseGraphicsResources(w);
671   this->LineActor2->ReleaseGraphicsResources(w);
672 }
673 
674 //----------------------------------------------------------------------------
RenderOpaqueGeometry(vtkViewport * v)675 int vtkFinitePlaneRepresentation::RenderOpaqueGeometry(vtkViewport *v)
676 {
677   int count = 0;
678   this->BuildRepresentation();
679 
680   if (this->OriginActor->GetVisibility())
681   {
682     count += this->OriginActor->RenderOpaqueGeometry(v);
683   }
684   if (this->V1Actor->GetVisibility())
685   {
686     count += this->V1Actor->RenderOpaqueGeometry(v);
687   }
688   if (this->V2Actor->GetVisibility())
689   {
690     count += this->V2Actor->RenderOpaqueGeometry(v);
691   }
692   count += this->EdgesActor->RenderOpaqueGeometry(v);
693   count += this->ConeActor->RenderOpaqueGeometry(v);
694   count += this->LineActor->RenderOpaqueGeometry(v);
695   count += this->ConeActor2->RenderOpaqueGeometry(v);
696   count += this->LineActor2->RenderOpaqueGeometry(v);
697 
698   if (this->DrawPlane)
699   {
700     count += this->PlaneActor->RenderOpaqueGeometry(v);
701   }
702 
703   return count;
704 }
705 
706 //----------------------------------------------------------------------------
RenderTranslucentPolygonalGeometry(vtkViewport * v)707 int vtkFinitePlaneRepresentation::RenderTranslucentPolygonalGeometry(vtkViewport *v)
708 {
709   int count = 0;
710   this->BuildRepresentation();
711 
712   if (this->OriginActor->GetVisibility())
713   {
714     count += this->OriginActor->RenderTranslucentPolygonalGeometry(v);
715   }
716   if (this->V1Actor->GetVisibility())
717   {
718     count += this->V1Actor->RenderTranslucentPolygonalGeometry(v);
719   }
720   if (this->V2Actor->GetVisibility())
721   {
722     count += this->V2Actor->RenderTranslucentPolygonalGeometry(v);
723   }
724 
725   count += this->EdgesActor->RenderTranslucentPolygonalGeometry(v);
726   count += this->ConeActor->RenderTranslucentPolygonalGeometry(v);
727   count += this->LineActor->RenderTranslucentPolygonalGeometry(v);
728   count += this->ConeActor2->RenderTranslucentPolygonalGeometry(v);
729   count += this->LineActor2->RenderTranslucentPolygonalGeometry(v);
730 
731   if (this->DrawPlane)
732   {
733     count += this->PlaneActor->RenderTranslucentPolygonalGeometry(v);
734   }
735 
736   return count;
737 }
738 
739 //----------------------------------------------------------------------------
HasTranslucentPolygonalGeometry()740 vtkTypeBool vtkFinitePlaneRepresentation::HasTranslucentPolygonalGeometry()
741 {
742   int result = 0;
743   this->BuildRepresentation();
744 
745   if (this->OriginActor->GetVisibility())
746   {
747     result |= this->OriginActor->HasTranslucentPolygonalGeometry();
748   }
749   if (this->V1Actor->GetVisibility())
750   {
751     result |= this->V1Actor->HasTranslucentPolygonalGeometry();
752   }
753   if (this->V2Actor->GetVisibility())
754   {
755     result |= this->V2Actor->HasTranslucentPolygonalGeometry();
756   }
757 
758   result |= this->EdgesActor->HasTranslucentPolygonalGeometry();
759   result |= this->ConeActor->HasTranslucentPolygonalGeometry();
760   result |= this->LineActor->HasTranslucentPolygonalGeometry();
761   result |= this->ConeActor2->HasTranslucentPolygonalGeometry();
762   result |= this->LineActor2->HasTranslucentPolygonalGeometry();
763 
764   if (this->DrawPlane)
765   {
766     result |= this->PlaneActor->HasTranslucentPolygonalGeometry();
767   }
768 
769   return result;
770 }
771 
772 //----------------------------------------------------------------------------
SetHandles(bool handles)773 void vtkFinitePlaneRepresentation::SetHandles(bool handles)
774 {
775   int h = handles ? 1 : 0;
776   if (this->V1Actor->GetVisibility() == h)
777   {
778     return;
779   }
780   this->V1Actor->SetVisibility(h);
781   this->V2Actor->SetVisibility(h);
782   this->OriginActor->SetVisibility(h);
783   this->Modified();
784 }
785 
786 //----------------------------------------------------------------------------
HandlesOn()787 void vtkFinitePlaneRepresentation::HandlesOn()
788 {
789   this->SetHandles(true);
790 }
791 
792 //----------------------------------------------------------------------------
HandlesOff()793 void vtkFinitePlaneRepresentation::HandlesOff()
794 {
795   this->SetHandles(false);
796 }
797 
798 //----------------------------------------------------------------------------
SizeHandles()799 void vtkFinitePlaneRepresentation::SizeHandles()
800 {
801   double radius =
802     this->vtkWidgetRepresentation::SizeHandlesInPixels(1.5, this->GetOrigin());
803 
804   this->OriginGeometry->SetRadius(radius);
805   this->V1Geometry->SetRadius(radius);
806   this->V2Geometry->SetRadius(radius);
807 
808   this->ConeSource->SetHeight(radius * 2.0);
809   this->ConeSource->SetRadius(radius);
810   this->ConeSource2->SetHeight(radius * 2.0);
811   this->ConeSource2->SetRadius(radius);
812 
813   this->EdgesTuber->SetRadius(radius * 0.25);
814 }
815 
816 //----------------------------------------------------------------------------
SetHighlightHandle(vtkProp * prop)817 void vtkFinitePlaneRepresentation::SetHighlightHandle(vtkProp *prop)
818 {
819   if (this->CurrentHandle == this->OriginActor)
820   {
821     this->OriginActor->SetProperty(this->OriginHandleProperty);
822   }
823   else if (this->CurrentHandle == this->V1Actor)
824   {
825     this->CurrentHandle->SetProperty(this->V1HandleProperty);
826   }
827   else if (this->CurrentHandle == this->V2Actor)
828   {
829     this->CurrentHandle->SetProperty(this->V2HandleProperty);
830   }
831 
832   this->CurrentHandle = dynamic_cast<vtkActor*>(prop);
833 
834   if (this->CurrentHandle)
835   {
836     this->CurrentHandle->SetProperty(this->SelectedHandleProperty);
837   }
838 }
839 
840 //------------------------------------------------------------------------------
RegisterPickers()841 void vtkFinitePlaneRepresentation::RegisterPickers()
842 {
843   vtkPickingManager* pm = this->GetPickingManager();
844   if (!pm)
845   {
846     return;
847   }
848   pm->AddPicker(this->HandlePicker, this);
849 }
850 
851 //----------------------------------------------------------------------------
SetOrigin(double x,double y,double z)852 void vtkFinitePlaneRepresentation::SetOrigin(double x, double y, double z)
853 {
854   double origin[3] = { x, y, z };
855   this->SetOrigin(origin);
856 }
857 
858 //----------------------------------------------------------------------------
SetOrigin(double x[3])859 void vtkFinitePlaneRepresentation::SetOrigin(double x[3])
860 {
861   if (this->Origin[0] != x[0] ||
862       this->Origin[1] != x[1] ||
863       this->Origin[2] != x[2])
864   {
865     this->Origin[0] = x[0];
866     this->Origin[1] = x[1];
867     this->Origin[2] = x[2];
868 
869     this->Modified();
870     this->BuildRepresentation();
871   }
872 }
873 
874 //----------------------------------------------------------------------------
SetV1(double x,double y)875 void vtkFinitePlaneRepresentation::SetV1(double x, double y)
876 {
877   double v1[2] = { x, y };
878   this->SetV1(v1);
879 }
880 
881 //----------------------------------------------------------------------------
SetV1(double x[2])882 void vtkFinitePlaneRepresentation::SetV1(double x[2])
883 {
884   if (this->V1[0] != x[0] ||
885       this->V1[1] != x[1])
886   {
887     this->V1[0] = x[0];
888     this->V1[1] = x[1];
889 
890     this->Modified();
891     this->BuildRepresentation();
892   }
893 }
894 
895 //----------------------------------------------------------------------------
SetV2(double x,double y)896 void vtkFinitePlaneRepresentation::SetV2(double x, double y)
897 {
898   double v2[2] = { x, y };
899   this->SetV2(v2);
900 }
901 
902 //----------------------------------------------------------------------------
SetV2(double x[2])903 void vtkFinitePlaneRepresentation::SetV2(double x[2])
904 {
905   if (this->V2[0] != x[0] ||
906       this->V2[1] != x[1])
907   {
908     this->V2[0] = x[0];
909     this->V2[1] = x[1];
910 
911     this->Modified();
912     this->BuildRepresentation();
913   }
914 }
915 
916 //----------------------------------------------------------------------------
SetNormal(double x,double y,double z)917 void vtkFinitePlaneRepresentation::SetNormal(double x, double y, double z)
918 {
919   double n[3] = { x, y, z };
920   vtkMath::Normalize(n);
921 
922   this->PreviousNormal[0] = this->Normal[0];
923   this->PreviousNormal[1] = this->Normal[1];
924   this->PreviousNormal[2] = this->Normal[2];
925 
926   if (n[0] != this->Normal[0] || n[1] != this->Normal[1] || n[2] != this->Normal[2])
927   {
928     this->Normal[0] = n[0];
929     this->Normal[1] = n[1];
930     this->Normal[2] = n[2];
931 
932     double RotationAxis[3];
933     vtkMath::Cross(this->PreviousNormal, this->Normal, RotationAxis);
934     vtkMath::Normalize(RotationAxis);
935     double RotationAngle = vtkMath::DegreesFromRadians(
936       acos(vtkMath::Dot(this->PreviousNormal, this->Normal)));
937 
938     this->Transform->PostMultiply();
939     this->Transform->RotateWXYZ(RotationAngle,
940       RotationAxis[0], RotationAxis[1], RotationAxis[2]);
941 
942     this->Modified();
943     this->BuildRepresentation();
944   }
945 }
946 
947 //----------------------------------------------------------------------------
SetNormal(double n[3])948 void vtkFinitePlaneRepresentation::SetNormal(double n[3])
949 {
950   this->SetNormal(n[0], n[1], n[2]);
951 }
952 
953 //----------------------------------------------------------------------------
SetDrawPlane(bool drawPlane)954 void vtkFinitePlaneRepresentation::SetDrawPlane(bool drawPlane)
955 {
956   if (drawPlane == this->DrawPlane)
957   {
958     return;
959   }
960 
961   this->DrawPlane = drawPlane;
962   this->Modified();
963   this->BuildRepresentation();
964 }
965 
966 //----------------------------------------------------------------------------
SetHighlightPlane(int highlight)967 void vtkFinitePlaneRepresentation::SetHighlightPlane(int highlight)
968 {
969   this->PlaneActor->SetProperty(
970     highlight ? this->SelectedPlaneProperty : this->PlaneProperty);
971 }
972 
973 //----------------------------------------------------------------------------
SetHighlightNormal(int highlight)974 void vtkFinitePlaneRepresentation::SetHighlightNormal(int highlight)
975 {
976   vtkProperty* p =
977     highlight ? this->SelectedNormalProperty : this->NormalProperty;
978   this->LineActor->SetProperty(p);
979   this->ConeActor->SetProperty(p);
980   this->LineActor2->SetProperty(p);
981   this->ConeActor2->SetProperty(p);
982   this->OriginActor->SetProperty(p);
983 }
984 
985 //----------------------------------------------------------------------------
SetRepresentationState(int state)986 void vtkFinitePlaneRepresentation::SetRepresentationState(int state)
987 {
988   if (this->RepresentationState == state)
989   {
990     return;
991   }
992 
993   // Clamp the state
994   state = (state < vtkFinitePlaneRepresentation::Outside ?
995     vtkFinitePlaneRepresentation::Outside :
996     (state > vtkFinitePlaneRepresentation::Pushing ?
997     vtkFinitePlaneRepresentation::Pushing : state));
998 
999   this->RepresentationState = state;
1000   this->Modified();
1001 }
1002 
1003 //----------------------------------------------------------------------------
1004 // translate origin of plane
TranslateOrigin(double * p1,double * p2)1005 void vtkFinitePlaneRepresentation::TranslateOrigin(double *p1, double *p2)
1006 {
1007   // Get the motion vector
1008   double v[3];
1009   v[0] = p2[0] - p1[0];
1010   v[1] = p2[1] - p1[1];
1011   v[2] = p2[2] - p1[2];
1012 
1013   // Add to the current point
1014   this->SetOrigin(
1015     this->Origin[0] + v[0],
1016     this->Origin[1] + v[1],
1017     this->Origin[2] + v[2]);
1018 }
1019 
1020 //----------------------------------------------------------------------------
1021 // Move Point 1
MovePoint1(double * p1,double * p2)1022 void vtkFinitePlaneRepresentation::MovePoint1(double *p1, double *p2)
1023 {
1024   //Get the motion vector
1025   double v[3];
1026   v[0] = p2[0] - p1[0];
1027   v[1] = p2[1] - p1[1];
1028   v[2] = p2[2] - p1[2];
1029 
1030   vtkNew<vtkMatrix4x4> mat;
1031   this->Transform->GetInverse(mat);
1032 
1033   vtkNew<vtkTransform> t;
1034   t->SetMatrix(mat);
1035   t->TransformVector(v, v);
1036 
1037   double *v1 = this->GetV1();
1038 
1039   double newV1[2];
1040   newV1[0] = v1[0] + v[0];
1041   newV1[1] = v1[1] + v[1];
1042 
1043   this->SetV1(newV1[0], newV1[1]);
1044 }
1045 
1046 //----------------------------------------------------------------------------
1047 // Modified Vector v2
MovePoint2(double * p1,double * p2)1048 void vtkFinitePlaneRepresentation::MovePoint2(double *p1, double *p2)
1049 {
1050   //Get the motion vector
1051   double v[3];
1052   v[0] = p2[0] - p1[0];
1053   v[1] = p2[1] - p1[1];
1054   v[2] = p2[2] - p1[2];
1055 
1056   vtkNew<vtkMatrix4x4> mat;
1057   this->Transform->GetInverse(mat);
1058 
1059   vtkNew<vtkTransform> t;
1060   t->SetMatrix(mat);
1061   t->TransformVector(v, v);
1062 
1063   double *v2 = this->GetV2();
1064 
1065   double newV2[2];
1066   newV2[0] = v2[0] + v[0];
1067   newV2[1] = v2[1] + v[1];
1068 
1069   this->SetV2(newV2[0], newV2[1]);
1070 }
1071 
1072 //----------------------------------------------------------------------------
1073 // Push Face
Push(double * p1,double * p2)1074 void vtkFinitePlaneRepresentation::Push(double *p1, double *p2)
1075 {
1076   //Get the motion vector
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 distance = vtkMath::Dot(v, this->Normal);
1083 
1084   if (distance == 0.0)
1085   {
1086     return;
1087   }
1088 
1089   double origin[3];
1090   this->GetOrigin(origin);
1091   origin[0] += distance * this->Normal[0];
1092   origin[1] += distance * this->Normal[1];
1093   origin[2] += distance * this->Normal[2];
1094 
1095   this->SetOrigin(origin);
1096 }
1097 
1098 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)1099 void vtkFinitePlaneRepresentation::PrintSelf(ostream& os, vtkIndent indent)
1100 {
1101   this->Superclass::PrintSelf(os, indent);
1102 
1103   double *bounds = this->InitialBounds;
1104   os << indent << "Initial Bounds: "
1105      << "(" << bounds[0] << ", " << bounds[1] << ") "
1106      << "(" << bounds[2] << ", " << bounds[3] << ") "
1107      << "(" << bounds[4] << ", " << bounds[5] << ")\n";
1108 
1109   if (this->OriginHandleProperty)
1110   {
1111     os << indent << "Origin Handle Property: " << this->OriginHandleProperty << "\n";
1112   }
1113   else
1114   {
1115     os << indent << "Origin Handle Property: (none)\n";
1116   }
1117   if (this->V1HandleProperty)
1118   {
1119     os << indent << "P1 Handle Property: " << this->V1HandleProperty << "\n";
1120   }
1121   else
1122   {
1123     os << indent << "P1 Handle Property: (none)\n";
1124   }
1125   if (this->V2HandleProperty)
1126   {
1127     os << indent << "P2 Handle Property: " << this->V2HandleProperty << "\n";
1128   }
1129   else
1130   {
1131     os << indent << "P2 Handle Property: (none)\n";
1132   }
1133   if (this->SelectedHandleProperty)
1134   {
1135     os << indent << "Selected Handle Property: "
1136        << this->SelectedHandleProperty << "\n";
1137   }
1138   else
1139   {
1140     os << indent << "SelectedHandle Property: (none)\n";
1141   }
1142 
1143   if (this->PlaneProperty)
1144   {
1145     os << indent << "Plane Property: " << this->PlaneProperty << "\n";
1146   }
1147   else
1148   {
1149     os << indent << "Plane Property: (none)\n";
1150   }
1151   if (this->SelectedPlaneProperty)
1152   {
1153     os << indent << "Selected Plane Property: "
1154        << this->SelectedPlaneProperty << "\n";
1155   }
1156   else
1157   {
1158     os << indent << "Selected Plane Property: (none)\n";
1159   }
1160 
1161   os << indent << "Tubing: " << (this->Tubing ? "On" : "Off") << "\n";
1162   os << indent << "Draw Plane: " << (this->DrawPlane ? "On" : "Off") << "\n";
1163 }
1164