1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkAbstractPolygonalHandleRepresentation3D.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 "vtkAbstractPolygonalHandleRepresentation3D.h"
16 #include "vtkCursor3D.h"
17 #include "vtkPolyDataMapper.h"
18 #include "vtkActor.h"
19 #include "vtkCellPicker.h"
20 #include "vtkRenderer.h"
21 #include "vtkRenderWindowInteractor.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkPickingManager.h"
24 #include "vtkProperty.h"
25 #include "vtkAssemblyPath.h"
26 #include "vtkMath.h"
27 #include "vtkInteractorObserver.h"
28 #include "vtkLine.h"
29 #include "vtkCoordinate.h"
30 #include "vtkRenderWindow.h"
31 #include "vtkFocalPlanePointPlacer.h"
32 #include "vtkCamera.h"
33 #include "vtkTransformPolyDataFilter.h"
34 #include "vtkMatrixToLinearTransform.h"
35 #include "vtkMatrix4x4.h"
36 #include "vtkVectorText.h"
37 #include "vtkFollower.h"
38 
39 vtkCxxSetObjectMacro(vtkAbstractPolygonalHandleRepresentation3D,Property,vtkProperty);
40 vtkCxxSetObjectMacro(vtkAbstractPolygonalHandleRepresentation3D,SelectedProperty,vtkProperty);
41 
42 //----------------------------------------------------------------------
43 vtkAbstractPolygonalHandleRepresentation3D
vtkAbstractPolygonalHandleRepresentation3D()44 ::vtkAbstractPolygonalHandleRepresentation3D()
45 {
46   this->InteractionState = vtkHandleRepresentation::Outside;
47 
48   this->HandleTransformFilter = vtkTransformPolyDataFilter::New();
49   this->HandleTransform       = vtkMatrixToLinearTransform::New();
50   this->HandleTransformMatrix = vtkMatrix4x4::New();
51   this->HandleTransformMatrix->Identity();
52   this->HandleTransform->SetInput( this->HandleTransformMatrix );
53   this->HandleTransformFilter->SetTransform( this->HandleTransform );
54 
55   // initialized because it is used in PrintSelf
56   this->LastPickPosition[0]=0.0;
57   this->LastPickPosition[1]=0.0;
58   this->LastPickPosition[2]=0.0;
59 
60   // initialized because it is used in PrintSelf
61   this->LastEventPosition[0]=0.0;
62   this->LastEventPosition[1]=0.0;
63 
64   this->Mapper = vtkPolyDataMapper::New();
65   this->Mapper->ScalarVisibilityOff();
66   this->Mapper->SetInputConnection(
67     this->HandleTransformFilter->GetOutputPort());
68 
69   // Set up the initial properties
70   this->CreateDefaultProperties();
71 
72   this->Actor = nullptr; // Created by subclass.vtkFollower::New();
73 
74   // Manage the picking stuff
75   this->HandlePicker = vtkCellPicker::New();
76   this->HandlePicker->PickFromListOn();
77   this->HandlePicker->SetTolerance(0.01); //need some fluff
78 
79   // Override superclass'
80   this->PlaceFactor = 1.0;
81   this->WaitingForMotion = 0;
82   this->ConstraintAxis = -1;
83 
84   vtkFocalPlanePointPlacer *pointPlacer = vtkFocalPlanePointPlacer::New();
85   this->SetPointPlacer( pointPlacer );
86   pointPlacer->Delete();
87 
88   // Label stuff.
89   this->LabelAnnotationTextScaleInitialized = false;
90   this->LabelVisibility = 0;
91   this->HandleVisibility = 1;
92   this->LabelTextInput = vtkVectorText::New();
93   this->LabelTextInput->SetText( "0" );
94   this->LabelTextMapper = vtkPolyDataMapper::New();
95   this->LabelTextMapper->SetInputConnection(
96     this->LabelTextInput->GetOutputPort());
97   this->LabelTextActor = vtkFollower::New();
98   this->LabelTextActor->SetMapper(this->LabelTextMapper);
99   this->LabelTextActor->GetProperty()->SetColor( 1.0, 0.1, 0.0 );
100 
101   this->SmoothMotion = 1;
102 }
103 
104 //----------------------------------------------------------------------
105 vtkAbstractPolygonalHandleRepresentation3D
~vtkAbstractPolygonalHandleRepresentation3D()106 ::~vtkAbstractPolygonalHandleRepresentation3D()
107 {
108   this->HandleTransformFilter->Delete();
109   this->HandleTransform->Delete();
110   this->HandleTransformMatrix->Delete();
111   this->HandlePicker->Delete();
112   this->Mapper->Delete();
113   this->Actor->Delete();
114   this->Property->Delete();
115   this->SelectedProperty->Delete();
116   this->LabelTextInput->Delete();
117   this->LabelTextMapper->Delete();
118   this->LabelTextActor->Delete();
119 }
120 
121 //----------------------------------------------------------------------
RegisterPickers()122 void vtkAbstractPolygonalHandleRepresentation3D::RegisterPickers()
123 {
124   vtkPickingManager* pm = this->GetPickingManager();
125   if (!pm)
126   {
127     return;
128   }
129   pm->AddPicker(this->HandlePicker, this);
130 }
131 
132 //----------------------------------------------------------------------
SetHandle(vtkPolyData * pd)133 void vtkAbstractPolygonalHandleRepresentation3D::SetHandle( vtkPolyData * pd )
134 {
135   this->HandleTransformFilter->SetInputData( pd );
136 }
137 
138 //----------------------------------------------------------------------
GetHandle()139 vtkPolyData * vtkAbstractPolygonalHandleRepresentation3D::GetHandle()
140 {
141   return vtkPolyData::SafeDownCast(this->HandleTransformFilter->GetInput());
142 }
143 
144 //-------------------------------------------------------------------------
SetWorldPosition(double p[3])145 void vtkAbstractPolygonalHandleRepresentation3D::SetWorldPosition(double p[3])
146 {
147   if (!this->Renderer || !this->PointPlacer ||
148                           this->PointPlacer->ValidateWorldPosition( p ))
149   {
150     this->WorldPosition->SetValue( p );
151     this->WorldPositionTime.Modified();
152     this->Modified();
153   }
154 }
155 
156 //-------------------------------------------------------------------------
SetDisplayPosition(double p[3])157 void vtkAbstractPolygonalHandleRepresentation3D::SetDisplayPosition(double p[3])
158 {
159   if (this->Renderer && this->PointPlacer)
160   {
161     if (this->PointPlacer->ValidateDisplayPosition( this->Renderer, p))
162     {
163       double worldPos[3], worldOrient[9];
164       if (this->PointPlacer->ComputeWorldPosition(
165             this->Renderer, p, worldPos, worldOrient ))
166       {
167         this->DisplayPosition->SetValue(p);
168         this->WorldPosition->SetValue(worldPos);
169         this->DisplayPositionTime.Modified();
170         this->SetWorldPosition(this->WorldPosition->GetValue());
171       }
172     }
173   }
174   else
175   {
176     this->DisplayPosition->SetValue(p);
177     this->DisplayPositionTime.Modified();
178   }
179 }
180 
181 //-------------------------------------------------------------------------
182 int vtkAbstractPolygonalHandleRepresentation3D
ComputeInteractionState(int X,int Y,int vtkNotUsed (modify))183 ::ComputeInteractionState(int X, int Y, int vtkNotUsed(modify))
184 {
185   this->VisibilityOn(); //actor must be on to be picked
186   vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
187 
188   if ( path != nullptr )
189   {
190     this->InteractionState = vtkHandleRepresentation::Nearby;
191   }
192   else
193   {
194     this->InteractionState = vtkHandleRepresentation::Outside;
195     if ( this->ActiveRepresentation )
196     {
197       this->VisibilityOff();
198     }
199   }
200 
201   return this->InteractionState;
202 }
203 
204 //-------------------------------------------------------------------------
DetermineConstraintAxis(int constraint,double * x,double * startPickPoint)205 int vtkAbstractPolygonalHandleRepresentation3D::DetermineConstraintAxis(
206   int constraint, double *x, double *startPickPoint)
207 {
208   // Look for trivial cases
209   if ( ! this->Constrained )
210   {
211     return -1;
212   }
213   else if ( constraint >= 0 && constraint < 3 )
214   {
215     return constraint;
216   }
217 
218   // Okay, figure out constraint. First see if the choice is
219   // outside the hot spot
220   if ( ! x )
221   {
222     double p[3];
223     this->HandlePicker->GetPickPosition(p);
224     if ( vtkMath::Distance2BetweenPoints(p,this->LastPickPosition) > 0.0)
225     {
226       this->WaitingForMotion = 0;
227       return 0;
228     }
229     else
230     {
231       this->WaitingForMotion = 1;
232       this->WaitCount = 0;
233       return -1;
234     }
235   }
236   else if (x)
237   {
238     this->WaitingForMotion = 0;
239     double v[3];
240     v[0] = fabs(x[0] - startPickPoint[0]);
241     v[1] = fabs(x[1] - startPickPoint[1]);
242     v[2] = fabs(x[2] - startPickPoint[2]);
243     return ( v[0]>v[1] ? (v[0]>v[2]?0:2) : (v[1]>v[2]?1:2));
244   }
245   else
246   {
247     return -1;
248   }
249 }
250 
251 //----------------------------------------------------------------------
252 // Record the current event position, and the rectilinear wipe position.
StartWidgetInteraction(double startEventPos[2])253 void vtkAbstractPolygonalHandleRepresentation3D::StartWidgetInteraction(double startEventPos[2])
254 {
255   this->StartEventPosition[0] = startEventPos[0];
256   this->StartEventPosition[1] = startEventPos[1];
257   this->StartEventPosition[2] = 0.0;
258 
259   this->LastEventPosition[0] = startEventPos[0];
260   this->LastEventPosition[1] = startEventPos[1];
261 
262   vtkAssemblyPath* path = this->GetAssemblyPath(
263     startEventPos[0], startEventPos[1], 0., this->HandlePicker);
264 
265   // Did we pick the handle ?
266   if ( path )
267   {
268     this->InteractionState = vtkHandleRepresentation::Nearby;
269     this->ConstraintAxis = -1;
270     this->HandlePicker->GetPickPosition(this->LastPickPosition);
271   }
272   else
273   {
274     this->InteractionState = vtkHandleRepresentation::Outside;
275     this->ConstraintAxis = -1;
276   }
277   this->WaitCount = 0;
278 }
279 
280 //----------------------------------------------------------------------
281 // Based on the displacement vector (computed in display coordinates) and
282 // the cursor state (which corresponds to which part of the widget has been
283 // selected), the widget points are modified.
284 // First construct a local coordinate system based on the display coordinates
285 // of the widget.
WidgetInteraction(double eventPos[2])286 void vtkAbstractPolygonalHandleRepresentation3D::WidgetInteraction(double eventPos[2])
287 {
288   // Do different things depending on state
289   // Calculations everybody does
290   double focalPoint[4], pickPoint[4], prevPickPoint[4], startPickPoint[4], z;
291 
292   // Compute the two points defining the motion vector
293   vtkInteractorObserver::ComputeWorldToDisplay(
294       this->Renderer,
295       this->LastPickPosition[0],
296       this->LastPickPosition[1],
297       this->LastPickPosition[2], focalPoint);
298   z = focalPoint[2];
299   vtkInteractorObserver::ComputeDisplayToWorld(
300       this->Renderer,
301       this->LastEventPosition[0],
302       this->LastEventPosition[1], z, prevPickPoint);
303   vtkInteractorObserver::ComputeDisplayToWorld(
304       this->Renderer, eventPos[0], eventPos[1], z, pickPoint);
305 
306   // Process the motion
307   if ( this->InteractionState == vtkHandleRepresentation::Selecting ||
308        this->InteractionState == vtkHandleRepresentation::Translating )
309   {
310     this->WaitCount++;
311 
312     if ( this->WaitCount > 3 || !this->Constrained )
313     {
314       vtkInteractorObserver::ComputeDisplayToWorld(
315           this->Renderer,
316           this->StartEventPosition[0],
317           this->StartEventPosition[1], z, startPickPoint);
318 
319       this->ConstraintAxis = this->DetermineConstraintAxis(
320           this->ConstraintAxis,pickPoint, startPickPoint);
321 
322       if (    this->InteractionState == vtkHandleRepresentation::Selecting )
323       {
324         // If we are doing axis constrained motion, igonore the placer.
325         // Can't have both the placer and an axis constraint dictating
326         // handle placement.
327         if (this->ConstraintAxis >= 0 || this->Constrained || !this->PointPlacer)
328         {
329           this->MoveFocus( prevPickPoint, pickPoint );
330         }
331         else
332         {
333           double newCenterPointRequested[3]; // displayPosition
334           double newCenterPoint[3], worldOrient[9];
335 
336           // Make a request for the new position.
337           this->MoveFocusRequest( prevPickPoint,
338                                   pickPoint,
339                                   eventPos,
340                                   newCenterPointRequested );
341 
342           vtkFocalPlanePointPlacer * fPlacer
343             = vtkFocalPlanePointPlacer::SafeDownCast( this->PointPlacer );
344           if (fPlacer)
345           {
346             // Offset the placer plane to one that passes through the current
347             // world position and is parallel to the focal plane. Offset =
348             // the distance currentWorldPos is from the focal plane
349             //
350             double currentWorldPos[3], projDir[3], fp[3];
351             this->GetWorldPosition( currentWorldPos );
352             this->Renderer->GetActiveCamera()->GetFocalPoint(fp);
353             double vec[3] = { currentWorldPos[0] - fp[0],
354                               currentWorldPos[1] - fp[1],
355                               currentWorldPos[2] - fp[2]};
356             this->Renderer->GetActiveCamera()->GetDirectionOfProjection(projDir);
357             fPlacer->SetOffset( vtkMath::Dot( vec, projDir ) );
358           }
359 
360 
361           // See what the placer says.
362           if (this->PointPlacer->ComputeWorldPosition(
363                 this->Renderer, newCenterPointRequested, newCenterPoint,
364                 worldOrient ))
365           {
366             // Once the placer has validated us, update the handle position
367             this->SetWorldPosition( newCenterPoint );
368           }
369         }
370       }
371       else
372       {
373         // If we are doing axis constrained motion, igonore the placer.
374         // Can't have both the placer and the axis constraint dictating
375         // handle placement.
376         if (this->ConstraintAxis >= 0 || this->Constrained || !this->PointPlacer)
377         {
378           this->Translate(prevPickPoint, pickPoint);
379         }
380         else
381         {
382           double newCenterPointRequested[3]; // displayPosition
383           double newCenterPoint[3], worldOrient[9];
384 
385           // Make a request for the new position.
386           this->MoveFocusRequest( prevPickPoint,
387                                   pickPoint,
388                                   eventPos,
389                                   newCenterPointRequested);
390 
391           vtkFocalPlanePointPlacer * fPlacer
392             = vtkFocalPlanePointPlacer::SafeDownCast( this->PointPlacer );
393           if (fPlacer)
394           {
395             // Offset the placer plane to one that passes through the current
396             // world position and is parallel to the focal plane. Offset =
397             // the distance currentWorldPos is from the focal plane
398             //
399             double currentWorldPos[3], projDir[3], fp[3];
400             this->GetWorldPosition( currentWorldPos );
401             this->Renderer->GetActiveCamera()->GetFocalPoint(fp);
402             double vec[3] = { currentWorldPos[0] - fp[0],
403                               currentWorldPos[1] - fp[1],
404                               currentWorldPos[2] - fp[2]};
405             this->Renderer->GetActiveCamera()->GetDirectionOfProjection(projDir);
406             fPlacer->SetOffset( vtkMath::Dot( vec, projDir ) );
407           }
408 
409           // See what the placer says.
410           if (this->PointPlacer->ComputeWorldPosition(
411                 this->Renderer, newCenterPointRequested, newCenterPoint,
412                 worldOrient ))
413           {
414             this->SetWorldPosition( newCenterPoint );
415           }
416         }
417       }
418     }
419   }
420 
421   else if ( this->InteractionState == vtkHandleRepresentation::Scaling )
422   {
423     // Scaling does not change the position of the handle, we needn't
424     // ask the placer..
425     this->Scale(prevPickPoint, pickPoint, eventPos);
426   }
427 
428   // Book keeping
429   this->LastEventPosition[0] = eventPos[0];
430   this->LastEventPosition[1] = eventPos[1];
431 
432   this->Modified();
433 }
434 
435 //----------------------------------------------------------------------
436 void vtkAbstractPolygonalHandleRepresentation3D
MoveFocusRequest(double * p1,double * p2,double currPos[2],double center[3])437 ::MoveFocusRequest(double *p1, double *p2,
438                    double currPos[2], double center[3])
439 {
440   if (this->SmoothMotion)
441   {
442     double focus[4];
443     this->GetWorldPosition(focus);
444 
445     // Move the center of the handle along the motion vector
446     focus[0] += (p2[0] - p1[0]);
447     focus[1] += (p2[1] - p1[1]);
448     focus[2] += (p2[2] - p1[2]);
449     focus[3] = 1.0;
450 
451     // Get the display position that this center would fall on.
452     this->Renderer->SetWorldPoint( focus );
453     this->Renderer->WorldToDisplay();
454     this->Renderer->GetDisplayPoint( center );
455   }
456   else
457   {
458     center[0] = currPos[0];
459     center[1] = currPos[1];
460     center[2] = 1.0;
461   }
462 }
463 
464 //----------------------------------------------------------------------
MoveFocus(double * p1,double * p2)465 void vtkAbstractPolygonalHandleRepresentation3D::MoveFocus(double *p1, double *p2)
466 {
467   //Get the motion vector
468   double v[3];
469   v[0] = p2[0] - p1[0];
470   v[1] = p2[1] - p1[1];
471   v[2] = p2[2] - p1[2];
472 
473   double focus[3];
474   this->GetWorldPosition( focus );
475   if ( this->ConstraintAxis >= 0 )
476   {
477     focus[this->ConstraintAxis] += v[this->ConstraintAxis];
478   }
479   else
480   {
481     focus[0] += v[0];
482     focus[1] += v[1];
483     focus[2] += v[2];
484   }
485 
486   this->SetWorldPosition(focus);
487 }
488 
489 //----------------------------------------------------------------------
490 // Translate everything
Translate(double * p1,double * p2)491 void vtkAbstractPolygonalHandleRepresentation3D::Translate(double *p1, double *p2)
492 {
493   //Get the motion vector
494   double v[3], pos[3];
495   v[0] = p2[0] - p1[0];
496   v[1] = p2[1] - p1[1];
497   v[2] = p2[2] - p1[2];
498 
499   this->GetWorldPosition( pos );
500   double newFocus[3];
501   int i;
502 
503   if ( this->ConstraintAxis >= 0 )
504   {//move along axis
505     for (i=0; i<3; i++)
506     {
507       if ( i != this->ConstraintAxis )
508       {
509         v[i] = 0.0;
510       }
511     }
512   }
513 
514   for (i=0; i<3; i++)
515   {
516     newFocus[i] = pos[i] + v[i];
517   }
518 
519   this->SetWorldPosition(newFocus);
520 }
521 
522 //----------------------------------------------------------------------
523 void vtkAbstractPolygonalHandleRepresentation3D
Scale(double *,double *,double eventPos[2])524 ::Scale(double *, double *, double eventPos[2])
525 {
526   double sf = 1.0 + (eventPos[1] - this->LastEventPosition[1])
527                    / this->Renderer->GetSize()[1];
528   if (sf == 1.0)
529   {
530     return;
531   }
532 
533   double handleSize = this->HandleTransformMatrix->GetElement(0,0) * sf;
534   handleSize = (handleSize < 0.001 ? 0.001 : handleSize);
535 
536   this->SetUniformScale( handleSize );
537 }
538 
539 //----------------------------------------------------------------------
540 void vtkAbstractPolygonalHandleRepresentation3D
SetUniformScale(double handleSize)541 ::SetUniformScale(double handleSize)
542 {
543   this->HandleTransformMatrix->SetElement(0, 0, handleSize);
544   this->HandleTransformMatrix->SetElement(1, 1, handleSize);
545   this->HandleTransformMatrix->SetElement(2, 2, handleSize);
546 }
547 
548 //----------------------------------------------------------------------
Highlight(int highlight)549 void vtkAbstractPolygonalHandleRepresentation3D::Highlight(int highlight)
550 {
551   this->Actor->SetProperty(highlight ? this->SelectedProperty : this->Property);
552 }
553 
554 //----------------------------------------------------------------------
CreateDefaultProperties()555 void vtkAbstractPolygonalHandleRepresentation3D::CreateDefaultProperties()
556 {
557   this->Property = vtkProperty::New();
558   this->Property->SetLineWidth(0.5);
559 
560   this->SelectedProperty = vtkProperty::New();
561   this->SelectedProperty->SetAmbient(1.0);
562   this->SelectedProperty->SetAmbientColor(0.0,1.0,0.0);
563   this->SelectedProperty->SetLineWidth(2.0);
564 }
565 
566 //----------------------------------------------------------------------
UpdateHandle()567 void vtkAbstractPolygonalHandleRepresentation3D::UpdateHandle()
568 {
569   // Subclasses should override this.
570   this->HandleTransformFilter->Update();
571 }
572 
573 //----------------------------------------------------------------------
BuildRepresentation()574 void vtkAbstractPolygonalHandleRepresentation3D::BuildRepresentation()
575 {
576   // The net effect is to resize the handle
577   if ( this->GetMTime() > this->BuildTime ||
578        (this->Renderer && this->Renderer->GetVTKWindow() &&
579         this->Renderer->GetVTKWindow()->GetMTime() > this->BuildTime) )
580   {
581 
582     // Update the handle.
583     this->UpdateHandle();
584 
585     // Update the label,
586     this->UpdateLabel();
587 
588     this->BuildTime.Modified();
589   }
590 }
591 
592 //----------------------------------------------------------------------
UpdateLabel()593 void vtkAbstractPolygonalHandleRepresentation3D::UpdateLabel()
594 {
595   // Display the label if needed.
596   if (this->LabelVisibility)
597   {
598     if (this->Renderer)
599     {
600       this->LabelTextActor->SetCamera( this->Renderer->GetActiveCamera() );
601     }
602     else
603     {
604       vtkErrorMacro("UpdateLabel: no renderer has been set!");
605       return;
606     }
607 
608     // Place the label on the North east of the handle. We need to take into
609     // account the viewup vector and the direction of the camera, so that we
610     // can bring it on the closest plane of the widget facing the camera.
611     double labelPosition[3], vup[3], directionOfProjection[3], xAxis[3], bounds[6];
612     this->Renderer->GetActiveCamera()->GetViewUp(vup);
613     this->Renderer->GetActiveCamera()->GetDirectionOfProjection(directionOfProjection);
614     vtkMath::Cross( directionOfProjection, vup, xAxis );
615     this->Mapper->GetBounds(bounds);
616     double width = sqrt( (bounds[1] - bounds[0]) * (bounds[1] - bounds[0]) +
617                          (bounds[3] - bounds[2]) * (bounds[3] - bounds[2]) +
618                          (bounds[5] - bounds[4]) * (bounds[5] - bounds[4]) );
619     this->GetWorldPosition(labelPosition);
620     labelPosition[0] += width/2.0 * xAxis[0];
621     labelPosition[1] += width/2.0 * xAxis[1];
622     labelPosition[2] += width/2.0 * xAxis[2];
623 
624     this->LabelTextActor->SetPosition(labelPosition);
625 
626     if (!this->LabelAnnotationTextScaleInitialized)
627     {
628       // If a font size hasn't been specified by the user, scale the text
629       // (font size) according to the size of the handle .
630       this->LabelTextActor->SetScale(
631           width/3.0, width/3.0, width/3.0 );
632     }
633   }
634 }
635 
636 //----------------------------------------------------------------------
ShallowCopy(vtkProp * prop)637 void vtkAbstractPolygonalHandleRepresentation3D::ShallowCopy(vtkProp *prop)
638 {
639   vtkAbstractPolygonalHandleRepresentation3D *rep =
640     vtkAbstractPolygonalHandleRepresentation3D::SafeDownCast(prop);
641   if ( rep )
642   {
643     this->SetProperty(rep->GetProperty());
644     this->SetSelectedProperty(rep->GetSelectedProperty());
645     this->Actor->SetProperty(this->Property);
646 
647     // copy the handle shape
648     this->HandleTransformFilter->SetInputConnection(
649       rep->HandleTransformFilter->GetInputConnection(0, 0));
650 
651     this->LabelVisibility = rep->LabelVisibility;
652     this->SetLabelText( rep->GetLabelText() );
653   }
654   this->Superclass::ShallowCopy(prop);
655 }
656 
657 //----------------------------------------------------------------------
DeepCopy(vtkProp * prop)658 void vtkAbstractPolygonalHandleRepresentation3D::DeepCopy(vtkProp *prop)
659 {
660   vtkAbstractPolygonalHandleRepresentation3D *rep =
661     vtkAbstractPolygonalHandleRepresentation3D::SafeDownCast(prop);
662   if ( rep )
663   {
664     this->Property->DeepCopy(rep->GetProperty());
665     this->SelectedProperty->DeepCopy(rep->GetSelectedProperty());
666     this->Actor->SetProperty(this->Property);
667 
668     // copy the handle shape
669     vtkPolyData *pd = vtkPolyData::New();
670     pd->DeepCopy( rep->HandleTransformFilter->GetInput() );
671     this->HandleTransformFilter->SetInputData(pd);
672     pd->Delete();
673 
674     this->LabelVisibility = rep->LabelVisibility;
675     this->SetLabelText( rep->GetLabelText() );
676   }
677   this->Superclass::DeepCopy(prop);
678 }
679 
680 //----------------------------------------------------------------------
GetActors(vtkPropCollection * pc)681 void vtkAbstractPolygonalHandleRepresentation3D::GetActors(vtkPropCollection *pc)
682 {
683   this->Actor->GetActors(pc);
684   this->LabelTextActor->GetActors(pc);
685 }
686 
687 //----------------------------------------------------------------------
ReleaseGraphicsResources(vtkWindow * win)688 void vtkAbstractPolygonalHandleRepresentation3D::ReleaseGraphicsResources(vtkWindow *win)
689 {
690   this->Actor->ReleaseGraphicsResources(win);
691   this->LabelTextActor->ReleaseGraphicsResources(win);
692 }
693 
694 //----------------------------------------------------------------------
RenderOpaqueGeometry(vtkViewport * viewport)695 int vtkAbstractPolygonalHandleRepresentation3D::RenderOpaqueGeometry(vtkViewport *viewport)
696 {
697   int count=0;
698   this->BuildRepresentation();
699   if (this->HandleVisibility)
700   {
701     count += this->Actor->RenderOpaqueGeometry(viewport);
702   }
703   if (this->LabelVisibility)
704   {
705     count += this->LabelTextActor->RenderOpaqueGeometry(viewport);
706   }
707   return count;
708 }
709 
710 //-----------------------------------------------------------------------------
RenderTranslucentPolygonalGeometry(vtkViewport * viewport)711 int vtkAbstractPolygonalHandleRepresentation3D::RenderTranslucentPolygonalGeometry(
712   vtkViewport *viewport)
713 {
714   // The internal actor needs to share property keys. This allows depth peeling
715   // etc to work.
716   this->Actor->SetPropertyKeys(this->GetPropertyKeys());
717 
718   int count=0;
719   if (this->HandleVisibility)
720   {
721     count += this->Actor->RenderTranslucentPolygonalGeometry(viewport);
722   }
723   if (this->LabelVisibility)
724   {
725     count += this->LabelTextActor->RenderTranslucentPolygonalGeometry(viewport);
726   }
727   return count;
728 }
729 
730 //-----------------------------------------------------------------------------
HasTranslucentPolygonalGeometry()731 vtkTypeBool vtkAbstractPolygonalHandleRepresentation3D::HasTranslucentPolygonalGeometry()
732 {
733   int result=0;
734   this->BuildRepresentation();
735   if (this->HandleVisibility)
736   {
737     result |= this->Actor->HasTranslucentPolygonalGeometry();
738   }
739   if (this->LabelVisibility)
740   {
741     result |= this->LabelTextActor->HasTranslucentPolygonalGeometry();
742   }
743   return result;
744 }
745 
746 //-----------------------------------------------------------------------------
GetBounds()747 double* vtkAbstractPolygonalHandleRepresentation3D::GetBounds()
748 {
749   this->BuildRepresentation();
750   return this->Actor ? this->Actor->GetBounds() : nullptr;
751 }
752 
753 //-----------------------------------------------------------------------------
GetTransform()754 vtkAbstractTransform* vtkAbstractPolygonalHandleRepresentation3D::GetTransform()
755 {
756   return this->HandleTransform;
757 }
758 
759 //----------------------------------------------------------------------
SetLabelText(const char * s)760 void vtkAbstractPolygonalHandleRepresentation3D::SetLabelText( const char *s )
761 {
762   this->LabelTextInput->SetText(s);
763 }
764 
765 //----------------------------------------------------------------------
GetLabelText()766 char * vtkAbstractPolygonalHandleRepresentation3D::GetLabelText()
767 {
768   return this->LabelTextInput->GetText();
769 }
770 
771 //----------------------------------------------------------------------
SetLabelTextScale(double scale[3])772 void vtkAbstractPolygonalHandleRepresentation3D::SetLabelTextScale( double scale[3] )
773 {
774   this->LabelTextActor->SetScale( scale );
775   this->LabelAnnotationTextScaleInitialized = true;
776 }
777 
778 //----------------------------------------------------------------------
GetLabelTextScale()779 double * vtkAbstractPolygonalHandleRepresentation3D::GetLabelTextScale()
780 {
781   return this->LabelTextActor->GetScale();
782 }
783 
784 //----------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)785 void vtkAbstractPolygonalHandleRepresentation3D::PrintSelf(ostream& os, vtkIndent indent)
786 {
787   this->Superclass::PrintSelf(os,indent);
788 
789   if ( this->Property )
790   {
791     os << indent << "Property: " << this->Property << "\n";
792   }
793   else
794   {
795     os << indent << "Property: (none)\n";
796   }
797   if ( this->SelectedProperty )
798   {
799     os << indent << "Selected Property: " << this->SelectedProperty << "\n";
800   }
801   else
802   {
803     os << indent << "Selected Property: (none)\n";
804   }
805   os << indent << "LabelVisibility: " << this->LabelVisibility << endl;
806   os << indent << "HandleVisibility: " << this->HandleVisibility << endl;
807   os << indent << "Actor: " << this->Actor << "\n";
808   this->Actor->PrintSelf(os,indent.GetNextIndent());
809   os << indent << "LabelTextActor: " << this->LabelTextActor << endl;
810   this->LabelTextActor->PrintSelf(os,indent.GetNextIndent());
811   os << indent << "Mapper: " << this->Mapper << "\n";
812   this->Mapper->PrintSelf(os,indent.GetNextIndent());
813   os << indent << "HandleTransformFilter: " << this->HandleTransformFilter << "\n";
814   this->HandleTransformFilter->PrintSelf(os,indent.GetNextIndent());
815   os << indent << "HandleTransform: " << this->HandleTransform << "\n";
816   this->HandleTransform->PrintSelf(os,indent.GetNextIndent());
817   os << indent << "HandleTransformMatrix: " << this->HandleTransformMatrix << "\n";
818   this->HandleTransformMatrix->PrintSelf(os,indent.GetNextIndent());
819   os << indent << "HandlePicker: " << this->HandlePicker << "\n";
820   this->HandlePicker->PrintSelf(os,indent.GetNextIndent());
821   os << indent << "LastPickPosition: (" << this->LastPickPosition[0]
822      << "," << this->LastPickPosition[1] << ")\n";
823   os << indent << "LastEventPosition: (" << this->LastEventPosition[0]
824      << "," << this->LastEventPosition[1] << ")\n";
825   os << indent << "SmoothMotion: " << this->SmoothMotion << endl;
826   // ConstraintAxis;
827   // WaitingForMotion;
828   // WaitCount;
829 }
830 
831