1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkPointHandleRepresentation3D.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 "vtkPointHandleRepresentation3D.h"
16 #include "vtkCursor3D.h"
17 #include "vtkPolyDataMapper.h"
18 #include "vtkActor.h"
19 #include "vtkCellPicker.h"
20 #include "vtkPickingManager.h"
21 #include "vtkRenderer.h"
22 #include "vtkRenderWindowInteractor.h"
23 #include "vtkObjectFactory.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 
34 vtkStandardNewMacro(vtkPointHandleRepresentation3D);
35 
36 vtkCxxSetObjectMacro(vtkPointHandleRepresentation3D,Property,vtkProperty);
37 vtkCxxSetObjectMacro(vtkPointHandleRepresentation3D,SelectedProperty,vtkProperty);
38 
39 
40 //----------------------------------------------------------------------
vtkPointHandleRepresentation3D()41 vtkPointHandleRepresentation3D::vtkPointHandleRepresentation3D()
42 {
43   // Initialize state
44   this->InteractionState = vtkHandleRepresentation::Outside;
45 
46   // Represent the line
47   this->Cursor3D = vtkCursor3D::New();
48   this->Cursor3D->AllOff();
49   this->Cursor3D->AxesOn();
50   this->Cursor3D->TranslationModeOn();
51 
52   this->Mapper = vtkPolyDataMapper::New();
53   this->Mapper->SetInputConnection(
54     this->Cursor3D->GetOutputPort());
55 
56   // Set up the initial properties
57   this->CreateDefaultProperties();
58 
59   this->Actor = vtkActor::New();
60   this->Actor->SetMapper(this->Mapper);
61   this->Actor->SetProperty(this->Property);
62 
63   //Manage the picking stuff
64   this->CursorPicker = vtkCellPicker::New();
65   this->CursorPicker->PickFromListOn();
66   this->CursorPicker->AddPickList(this->Actor);
67   this->CursorPicker->SetTolerance(0.01); //need some fluff
68 
69   // Override superclass'
70   this->PlaceFactor = 1.0;
71 
72   // The size of the hot spot
73   this->HotSpotSize = 0.05;
74   this->WaitingForMotion = 0;
75   this->ConstraintAxis = -1;
76 
77   // Current handle size
78   this->HandleSize = 15.0; //in pixels
79   this->CurrentHandleSize = this->HandleSize;
80 
81   // Translation control
82   this->TranslationMode = 1;
83 
84   vtkFocalPlanePointPlacer *pointPlacer = vtkFocalPlanePointPlacer::New();
85   this->SetPointPlacer( pointPlacer );
86   pointPlacer->Delete();
87 
88   // Continuous moves
89   this->SmoothMotion = 1;
90 }
91 
92 //----------------------------------------------------------------------
~vtkPointHandleRepresentation3D()93 vtkPointHandleRepresentation3D::~vtkPointHandleRepresentation3D()
94 {
95   this->Cursor3D->Delete();
96   this->CursorPicker->Delete();
97   this->Mapper->Delete();
98   this->Actor->Delete();
99   this->Property->Delete();
100   this->SelectedProperty->Delete();
101 }
102 
103 //----------------------------------------------------------------------
RegisterPickers()104 void vtkPointHandleRepresentation3D::RegisterPickers()
105 {
106   this->Renderer->GetRenderWindow()->GetInteractor()->GetPickingManager()
107     ->AddPicker(this->CursorPicker, this);
108 }
109 
110 //-------------------------------------------------------------------------
PlaceWidget(double bds[6])111 void vtkPointHandleRepresentation3D::PlaceWidget(double bds[6])
112 {
113   int i;
114   double bounds[6], center[3];
115 
116   this->AdjustBounds(bds, bounds, center);
117 
118   this->Cursor3D->SetModelBounds(bounds);
119   this->SetWorldPosition(center);
120 
121   for (i=0; i<6; i++)
122     {
123     this->InitialBounds[i] = bounds[i];
124     }
125   this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
126                              (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
127                              (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
128 }
129 
130 //-------------------------------------------------------------------------
GetBounds()131 double* vtkPointHandleRepresentation3D::GetBounds()
132 {
133   return this->Cursor3D->GetModelBounds();
134 }
135 
136 //-------------------------------------------------------------------------
SetWorldPosition(double p[3])137 void vtkPointHandleRepresentation3D::SetWorldPosition(double p[3])
138 {
139   if (this->Renderer && this->PointPlacer)
140     {
141     if (this->PointPlacer->ValidateWorldPosition( p ))
142       {
143       this->Cursor3D->SetFocalPoint(p); //this may clamp the point
144       this->WorldPosition->SetValue(this->Cursor3D->GetFocalPoint());
145       this->WorldPositionTime.Modified();
146       }
147     }
148   else
149     {
150     this->Cursor3D->SetFocalPoint(p); //this may clamp the point
151     this->WorldPosition->SetValue(this->Cursor3D->GetFocalPoint());
152     this->WorldPositionTime.Modified();
153     }
154 }
155 
156 //-------------------------------------------------------------------------
SetDisplayPosition(double p[3])157 void vtkPointHandleRepresentation3D::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 //-------------------------------------------------------------------------
SetHandleSize(double size)182 void vtkPointHandleRepresentation3D::SetHandleSize(double size)
183 {
184   this->Superclass::SetHandleSize(size);
185   this->CurrentHandleSize = this->HandleSize;
186 }
187 
188 //-------------------------------------------------------------------------
189 int vtkPointHandleRepresentation3D
ComputeInteractionState(int X,int Y,int vtkNotUsed (modify))190 ::ComputeInteractionState(int X, int Y, int vtkNotUsed(modify))
191 {
192   this->VisibilityOn(); //actor must be on to be picked
193 
194   vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->CursorPicker);
195 
196   double focus[3];
197   this->Cursor3D->GetFocalPoint(focus);
198   double d[3];
199   this->GetDisplayPosition(d);
200 
201   if ( path != NULL )
202     {
203     this->InteractionState = vtkHandleRepresentation::Nearby;
204     }
205   else
206     {
207     this->InteractionState = vtkHandleRepresentation::Outside;
208     if ( this->ActiveRepresentation )
209       {
210       this->VisibilityOff();
211       }
212     }
213 
214   return this->InteractionState;
215 }
216 
217 //-------------------------------------------------------------------------
DetermineConstraintAxis(int constraint,double * x,double * startPickPoint)218 int vtkPointHandleRepresentation3D::DetermineConstraintAxis(
219   int constraint, double *x, double *startPickPoint)
220 {
221   // Look for trivial cases
222   if ( ! this->Constrained )
223     {
224     return -1;
225     }
226   else if ( constraint >= 0 && constraint < 3 )
227     {
228     return constraint;
229     }
230 
231   // Okay, figure out constraint. First see if the choice is
232   // outside the hot spot
233   if ( ! x )
234     {
235     double p[3], d2, tol;
236     this->CursorPicker->GetPickPosition(p);
237     d2 = vtkMath::Distance2BetweenPoints(p,this->LastPickPosition);
238     tol = this->HotSpotSize*this->InitialLength;
239     if ( d2 > (tol*tol))
240       {
241       this->WaitingForMotion = 0;
242       return this->CursorPicker->GetCellId();
243       }
244     else
245       {
246       this->WaitingForMotion = 1;
247       this->WaitCount = 0;
248       return -1;
249       }
250     }
251   else if ( x)
252     {
253     this->WaitingForMotion = 0;
254     double v[3];
255     v[0] = fabs(x[0] - startPickPoint[0]);
256     v[1] = fabs(x[1] - startPickPoint[1]);
257     v[2] = fabs(x[2] - startPickPoint[2]);
258     return ( v[0]>v[1] ? (v[0]>v[2]?0:2) : (v[1]>v[2]?1:2));
259     }
260   else
261     {
262     return -1;
263     }
264 }
265 
266 //----------------------------------------------------------------------
267 // Record the current event position, and the rectilinear wipe position.
StartWidgetInteraction(double startEventPos[2])268 void vtkPointHandleRepresentation3D::StartWidgetInteraction(double startEventPos[2])
269 {
270   this->StartEventPosition[0] = startEventPos[0];
271   this->StartEventPosition[1] = startEventPos[1];
272   this->StartEventPosition[2] = 0.0;
273 
274   this->LastEventPosition[0] = startEventPos[0];
275   this->LastEventPosition[1] = startEventPos[1];
276 
277   vtkAssemblyPath* path = this->GetAssemblyPath(
278     startEventPos[0], startEventPos[1], 0., this->CursorPicker);
279 
280   path = this->CursorPicker->GetPath();
281   if ( path != NULL )
282     {
283     this->InteractionState = vtkHandleRepresentation::Nearby;
284     this->ConstraintAxis = -1;
285     this->CursorPicker->GetPickPosition(this->LastPickPosition);
286     }
287   else
288     {
289     this->InteractionState = vtkHandleRepresentation::Outside;
290     this->ConstraintAxis = -1;
291     }
292   this->Cursor3D->SetTranslationMode(this->TranslationMode);
293   this->WaitCount = 0;
294 }
295 
296 
297 //----------------------------------------------------------------------
298 // Based on the displacement vector (computed in display coordinates) and
299 // the cursor state (which corresponds to which part of the widget has been
300 // selected), the widget points are modified.
301 // First construct a local coordinate system based on the display coordinates
302 // of the widget.
WidgetInteraction(double eventPos[2])303 void vtkPointHandleRepresentation3D::WidgetInteraction(double eventPos[2])
304 {
305   // Do different things depending on state
306   // Calculations everybody does
307   double focalPoint[4], pickPoint[4], prevPickPoint[4], startPickPoint[4], z;
308 
309   // Compute the two points defining the motion vector
310   vtkInteractorObserver::ComputeWorldToDisplay(
311       this->Renderer,
312       this->LastPickPosition[0],
313       this->LastPickPosition[1],
314       this->LastPickPosition[2], focalPoint);
315   z = focalPoint[2];
316   vtkInteractorObserver::ComputeDisplayToWorld(
317       this->Renderer,
318       this->LastEventPosition[0],
319       this->LastEventPosition[1], z, prevPickPoint);
320   vtkInteractorObserver::ComputeDisplayToWorld(
321       this->Renderer, eventPos[0], eventPos[1], z, pickPoint);
322 
323   // Process the motion
324   if ( this->InteractionState == vtkHandleRepresentation::Selecting ||
325        this->InteractionState == vtkHandleRepresentation::Translating )
326     {
327     this->WaitCount++;
328 
329     if ( this->WaitCount > 3 || !this->Constrained )
330       {
331       vtkInteractorObserver::ComputeDisplayToWorld(
332           this->Renderer,
333           this->StartEventPosition[0],
334           this->StartEventPosition[1], z, startPickPoint);
335 
336       this->ConstraintAxis = this->DetermineConstraintAxis(
337           this->ConstraintAxis,pickPoint, startPickPoint);
338 
339       if (    this->InteractionState == vtkHandleRepresentation::Selecting
340           && !this->TranslationMode )
341         {
342         vtkDebugMacro( << "Processing widget interaction for Select mode" );
343 
344         // If we are doing axis constrained motion, igonore the placer.
345         // Can't have both the placer and an axis constraint dictating
346         // handle placement.
347         if (this->ConstraintAxis >= 0 || this->Constrained || !this->PointPlacer)
348           {
349           this->MoveFocus( prevPickPoint, pickPoint );
350           }
351         else
352           {
353           double newCenterPointRequested[3]; // displayPosition
354           double newCenterPoint[3], worldOrient[9];
355 
356           // Make a request for the new position.
357           this->MoveFocusRequest( prevPickPoint,
358                                   pickPoint,
359                                   eventPos,
360                                   newCenterPointRequested );
361 
362           vtkFocalPlanePointPlacer * fPlacer
363             = vtkFocalPlanePointPlacer::SafeDownCast( this->PointPlacer );
364           if (fPlacer)
365             {
366             // Offset the placer plane to one that passes through the current
367             // world position and is parallel to the focal plane. Offset =
368             // the distance currentWorldPos is from the focal plane
369             //
370             double currentWorldPos[3], projDir[3], fp[3];
371             this->GetWorldPosition( currentWorldPos );
372             this->Renderer->GetActiveCamera()->GetFocalPoint(fp);
373             double vec[3] = { currentWorldPos[0] - fp[0],
374                               currentWorldPos[1] - fp[1],
375                               currentWorldPos[2] - fp[2]};
376             this->Renderer->GetActiveCamera()->GetDirectionOfProjection(projDir);
377             fPlacer->SetOffset( vtkMath::Dot( vec, projDir ) );
378             }
379 
380           vtkDebugMacro( << "Request for computing world position at "
381             << "display position of " << newCenterPointRequested[0]
382             << "," << newCenterPointRequested[1] );
383 
384           // See what the placer says.
385           if (this->PointPlacer->ComputeWorldPosition(
386                 this->Renderer, newCenterPointRequested, newCenterPoint,
387                 worldOrient ))
388             {
389             // Once the placer has validated us, update the handle position
390             this->SetWorldPosition( newCenterPoint );
391             }
392           }
393         }
394       else
395         {
396         vtkDebugMacro( << "Processing widget interaction for translate" );
397 
398         // If we are doing axis constrained motion, igonore the placer.
399         // Can't have both the placer and the axis constraint dictating
400         // handle placement.
401         if (this->ConstraintAxis >= 0 || this->Constrained || !this->PointPlacer)
402           {
403           this->Translate(prevPickPoint, pickPoint);
404           }
405         else
406           {
407           double newCenterPointRequested[3]; // displayPosition
408           double newCenterPoint[3], worldOrient[9];
409 
410           // Make a request for the new position.
411           this->MoveFocusRequest( prevPickPoint,
412                                   pickPoint,
413                                   eventPos,
414                                   newCenterPointRequested);
415 
416           vtkFocalPlanePointPlacer * fPlacer
417             = vtkFocalPlanePointPlacer::SafeDownCast( this->PointPlacer );
418           if (fPlacer)
419             {
420             // Offset the placer plane to one that passes through the current
421             // world position and is parallel to the focal plane. Offset =
422             // the distance currentWorldPos is from the focal plane
423             //
424             double currentWorldPos[3], projDir[3], fp[3];
425             this->GetWorldPosition( currentWorldPos );
426             this->Renderer->GetActiveCamera()->GetFocalPoint(fp);
427             double vec[3] = { currentWorldPos[0] - fp[0],
428                               currentWorldPos[1] - fp[1],
429                               currentWorldPos[2] - fp[2]};
430             this->Renderer->GetActiveCamera()->GetDirectionOfProjection(projDir);
431             fPlacer->SetOffset( vtkMath::Dot( vec, projDir ) );
432             }
433 
434           vtkDebugMacro( << "Request for computing world position at "
435             << "display position of " << newCenterPointRequested[0]
436             << "," << newCenterPointRequested[1] );
437 
438           // See what the placer says.
439           if (this->PointPlacer->ComputeWorldPosition(
440                 this->Renderer, newCenterPointRequested, newCenterPoint,
441                 worldOrient ))
442             {
443 
444             // Once the placer has validated us, update the handle
445             // position and its bounds.
446             double *p = this->GetWorldPosition();
447 
448             //Get the motion vector
449             double v[3] = { newCenterPoint[0] - p[0],
450                             newCenterPoint[1] - p[1],
451                             newCenterPoint[2] - p[2] };
452             double *bounds = this->Cursor3D->GetModelBounds(), newBounds[6];
453             for (int i=0; i<3; i++)
454               {
455               newBounds[2*i]   = bounds[2*i]   + v[i];
456               newBounds[2*i+1] = bounds[2*i+1] + v[i];
457               }
458 
459             this->Cursor3D->SetModelBounds(newBounds);
460             this->SetWorldPosition( newCenterPoint );
461             }
462           }
463         }
464       }
465     }
466 
467   else if ( this->InteractionState == vtkHandleRepresentation::Scaling )
468     {
469     // Scaling does not change the position of the handle, we needn't
470     // ask the placer..
471     this->Scale(prevPickPoint, pickPoint, eventPos);
472     }
473 
474   // Book keeping
475   this->LastEventPosition[0] = eventPos[0];
476   this->LastEventPosition[1] = eventPos[1];
477 
478   this->Modified();
479 }
480 
481 //----------------------------------------------------------------------
482 void vtkPointHandleRepresentation3D
MoveFocusRequest(double * p1,double * p2,double currPos[2],double center[3])483 ::MoveFocusRequest(double *p1, double *p2,
484                    double currPos[2], double center[3])
485 {
486   if (this->SmoothMotion)
487     {
488     double focus[4];
489     this->Cursor3D->GetFocalPoint(focus);
490 
491     // Move the center of the handle along the motion vector
492     focus[0] += (p2[0] - p1[0]);
493     focus[1] += (p2[1] - p1[1]);
494     focus[2] += (p2[2] - p1[2]);
495     focus[3] = 1.0;
496 
497     // Get the display position that this center would fall on.
498     this->Renderer->SetWorldPoint( focus );
499     this->Renderer->WorldToDisplay();
500     this->Renderer->GetDisplayPoint( center );
501     }
502   else
503     {
504     center[0] = currPos[0];
505     center[1] = currPos[1];
506     center[2] = 1.0;
507     }
508 }
509 
510 //----------------------------------------------------------------------
MoveFocus(double * p1,double * p2)511 void vtkPointHandleRepresentation3D::MoveFocus(double *p1, double *p2)
512 {
513   //Get the motion vector
514   double v[3];
515   v[0] = p2[0] - p1[0];
516   v[1] = p2[1] - p1[1];
517   v[2] = p2[2] - p1[2];
518 
519   double focus[3];
520   this->Cursor3D->GetFocalPoint(focus);
521   if ( this->ConstraintAxis >= 0 )
522     {
523     focus[this->ConstraintAxis] += v[this->ConstraintAxis];
524     }
525   else
526     {
527     focus[0] += v[0];
528     focus[1] += v[1];
529     focus[2] += v[2];
530     }
531 
532   this->SetWorldPosition(focus);
533 }
534 
535 //----------------------------------------------------------------------
SetTranslationMode(int mode)536 void vtkPointHandleRepresentation3D::SetTranslationMode(int mode)
537 {
538   if (this->TranslationMode != mode)
539     {
540     this->TranslationMode = mode;
541     // Pass new setting to Cursor3D, otherwise PlaceWidget will not work
542     // as it should when TranslationMode is off.
543     this->Cursor3D->SetTranslationMode(mode);
544     this->Modified();
545     }
546 }
547 
548 //----------------------------------------------------------------------
549 // Translate everything
Translate(double * p1,double * p2)550 void vtkPointHandleRepresentation3D::Translate(double *p1, double *p2)
551 {
552   //Get the motion vector
553   double v[3];
554   v[0] = p2[0] - p1[0];
555   v[1] = p2[1] - p1[1];
556   v[2] = p2[2] - p1[2];
557 
558   double *bounds = this->Cursor3D->GetModelBounds();
559   double *pos = this->Cursor3D->GetFocalPoint();
560   double newBounds[6], newFocus[3];
561   int i;
562 
563   if ( this->ConstraintAxis >= 0 )
564     {//move along axis
565     for (i=0; i<3; i++)
566       {
567       if ( i != this->ConstraintAxis )
568         {
569         v[i] = 0.0;
570         }
571       }
572     }
573 
574   for (i=0; i<3; i++)
575     {
576     newBounds[2*i] = bounds[2*i] + v[i];
577     newBounds[2*i+1] = bounds[2*i+1] + v[i];
578     newFocus[i] = pos[i] + v[i];
579     }
580 
581   this->Cursor3D->SetModelBounds(newBounds);
582   this->SetWorldPosition(newFocus);
583 }
584 
585 //----------------------------------------------------------------------
SizeBounds()586 void vtkPointHandleRepresentation3D::SizeBounds()
587 {
588   // Only change the size of the bounding box if translation mode is on.
589   if ( this->TranslationMode )
590     {
591     double center[3], newBounds[6];
592     this->Cursor3D->GetFocalPoint(center);
593     double radius = this->SizeHandlesInPixels(1.0,center);
594     radius *= this->CurrentHandleSize / this->HandleSize;
595 
596     for (int i=0; i<3; i++)
597       {
598       newBounds[2*i] = center[i] - radius;
599       newBounds[2*i+1] = center[i] + radius;
600       }
601     this->Cursor3D->SetModelBounds(newBounds);
602     }
603 }
604 
605 //----------------------------------------------------------------------
Scale(double * p1,double * p2,double eventPos[2])606 void vtkPointHandleRepresentation3D::Scale(double *p1, double *p2, double eventPos[2])
607 {
608   //Get the motion vector
609   double v[3];
610   v[0] = p2[0] - p1[0];
611   v[1] = p2[1] - p1[1];
612   v[2] = p2[2] - p1[2];
613 
614   double *bounds = this->Cursor3D->GetModelBounds();
615 
616   // Compute the scale factor
617   double sf = vtkMath::Norm(v) /
618     sqrt( (bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
619           (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
620           (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
621 
622   if ( eventPos[1] > this->LastEventPosition[1] )
623     {
624     sf = 1.0 + sf;
625     }
626   else
627     {
628     sf = 1.0 - sf;
629     }
630 
631   this->CurrentHandleSize *= sf;
632   this->CurrentHandleSize = (this->CurrentHandleSize < 0.001 ? 0.001 : this->CurrentHandleSize);
633 
634   this->SizeBounds();
635 }
636 
637 //----------------------------------------------------------------------
Highlight(int highlight)638 void vtkPointHandleRepresentation3D::Highlight(int highlight)
639 {
640   if ( highlight )
641     {
642     this->Actor->SetProperty(this->SelectedProperty);
643     }
644   else
645     {
646     this->Actor->SetProperty(this->Property);
647     }
648 }
649 
650 //----------------------------------------------------------------------
CreateDefaultProperties()651 void vtkPointHandleRepresentation3D::CreateDefaultProperties()
652 {
653   this->Property = vtkProperty::New();
654   this->Property->SetAmbient(1.0);
655   this->Property->SetAmbientColor(1.0,1.0,1.0);
656   this->Property->SetLineWidth(0.5);
657 
658   this->SelectedProperty = vtkProperty::New();
659   this->SelectedProperty->SetAmbient(1.0);
660   this->SelectedProperty->SetAmbientColor(0.0,1.0,0.0);
661   this->SelectedProperty->SetLineWidth(2.0);
662 }
663 
664 //----------------------------------------------------------------------
BuildRepresentation()665 void vtkPointHandleRepresentation3D::BuildRepresentation()
666 {
667   // The net effect is to resize the handle
668   if ( this->GetMTime() > this->BuildTime ||
669        (this->Renderer && this->Renderer->GetVTKWindow() &&
670         this->Renderer->GetVTKWindow()->GetMTime() > this->BuildTime) )
671     {
672     if ( ! this->Placed )
673       {
674       this->ValidPick = 1;
675       this->Placed = 1;
676       }
677 
678     this->SizeBounds();
679     this->Cursor3D->Update();
680     this->BuildTime.Modified();
681     }
682 }
683 
684 //----------------------------------------------------------------------
ShallowCopy(vtkProp * prop)685 void vtkPointHandleRepresentation3D::ShallowCopy(vtkProp *prop)
686 {
687   vtkPointHandleRepresentation3D *rep =
688     vtkPointHandleRepresentation3D::SafeDownCast(prop);
689   if ( rep )
690     {
691     this->SetOutline(rep->GetOutline());
692     this->SetXShadows(rep->GetXShadows());
693     this->SetYShadows(rep->GetYShadows());
694     this->SetZShadows(rep->GetZShadows());
695     this->SetTranslationMode(rep->GetTranslationMode());
696     this->SetProperty(rep->GetProperty());
697     this->Actor->SetProperty(rep->GetProperty());
698     this->SetSelectedProperty(rep->GetSelectedProperty());
699     this->SetHotSpotSize(rep->GetHotSpotSize());
700     }
701   this->Superclass::ShallowCopy(prop);
702 }
703 
704 //----------------------------------------------------------------------
DeepCopy(vtkProp * prop)705 void vtkPointHandleRepresentation3D::DeepCopy(vtkProp *prop)
706 {
707   vtkPointHandleRepresentation3D *rep =
708     vtkPointHandleRepresentation3D::SafeDownCast(prop);
709   if ( rep )
710     {
711     this->SetOutline(rep->GetOutline());
712     this->SetXShadows(rep->GetXShadows());
713     this->SetYShadows(rep->GetYShadows());
714     this->SetZShadows(rep->GetZShadows());
715     this->SetTranslationMode(rep->GetTranslationMode());
716     this->SetProperty(rep->GetProperty());
717     this->Actor->SetProperty(rep->GetProperty());
718     this->SetSelectedProperty(rep->GetSelectedProperty());
719     this->SetHotSpotSize(rep->GetHotSpotSize());
720     }
721   this->Superclass::DeepCopy(prop);
722 }
723 
724 //----------------------------------------------------------------------
GetActors(vtkPropCollection * pc)725 void vtkPointHandleRepresentation3D::GetActors(vtkPropCollection *pc)
726 {
727   this->Actor->GetActors(pc);
728 }
729 
730 //----------------------------------------------------------------------
ReleaseGraphicsResources(vtkWindow * win)731 void vtkPointHandleRepresentation3D::ReleaseGraphicsResources(vtkWindow *win)
732 {
733   this->Actor->ReleaseGraphicsResources(win);
734 }
735 
736 //----------------------------------------------------------------------
RenderOpaqueGeometry(vtkViewport * viewport)737 int vtkPointHandleRepresentation3D::RenderOpaqueGeometry(vtkViewport *viewport)
738 {
739   this->BuildRepresentation();
740 
741   // Sanity check
742   double worldPos[3];
743   this->GetWorldPosition( worldPos );
744   if (worldPos[0] == VTK_DOUBLE_MAX)
745     {
746     return 0;
747     }
748 
749   return this->Actor->RenderOpaqueGeometry(viewport);
750 }
751 
752 //-----------------------------------------------------------------------------
RenderTranslucentPolygonalGeometry(vtkViewport * viewport)753 int vtkPointHandleRepresentation3D::RenderTranslucentPolygonalGeometry(
754   vtkViewport *viewport)
755 {
756   this->BuildRepresentation();
757 
758   // Sanity check
759   double worldPos[3];
760   this->GetWorldPosition( worldPos );
761   if (worldPos[0] == VTK_DOUBLE_MAX)
762     {
763     return 0;
764     }
765 
766   return this->Actor->RenderTranslucentPolygonalGeometry(viewport);
767 }
768 //-----------------------------------------------------------------------------
HasTranslucentPolygonalGeometry()769 int vtkPointHandleRepresentation3D::HasTranslucentPolygonalGeometry()
770 {
771   this->BuildRepresentation();
772   return this->Actor->HasTranslucentPolygonalGeometry();
773 }
774 
775 
776 //----------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)777 void vtkPointHandleRepresentation3D::PrintSelf(ostream& os, vtkIndent indent)
778 {
779   //Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h
780   this->Superclass::PrintSelf(os,indent);
781 
782   os << indent << "Hot Spot Size: " << this->HotSpotSize << "\n";
783   if ( this->Property )
784     {
785     os << indent << "Property: " << this->Property << "\n";
786     }
787   else
788     {
789     os << indent << "Property: (none)\n";
790     }
791   if ( this->SelectedProperty )
792     {
793     os << indent << "Selected Property: " << this->SelectedProperty << "\n";
794     }
795   else
796     {
797     os << indent << "Selected Property: (none)\n";
798     }
799 
800   os << indent << "Outline: " << (this->GetOutline() ? "On\n" : "Off\n");
801   os << indent << "XShadows: " << (this->GetXShadows() ? "On\n" : "Off\n");
802   os << indent << "YShadows: " << (this->GetYShadows() ? "On\n" : "Off\n");
803   os << indent << "ZShadows: " << (this->GetZShadows() ? "On\n" : "Off\n");
804 
805   os << indent << "Translation Mode: " << (this->TranslationMode ? "On\n" : "Off\n");
806   os << indent << "SmoothMotion: " << this->SmoothMotion << endl;
807 }
808