1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkSphereRepresentation.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 "vtkSphereRepresentation.h"
16 #include "vtkActor.h"
17 #include "vtkSphere.h"
18 #include "vtkSphereSource.h"
19 #include "vtkPickingManager.h"
20 #include "vtkPolyDataMapper.h"
21 #include "vtkPolyData.h"
22 #include "vtkCallbackCommand.h"
23 #include "vtkPolyData.h"
24 #include "vtkProperty.h"
25 #include "vtkRenderWindow.h"
26 #include "vtkRenderWindowInteractor.h"
27 #include "vtkRenderer.h"
28 #include "vtkInteractorObserver.h"
29 #include "vtkMath.h"
30 #include "vtkCellArray.h"
31 #include "vtkCellPicker.h"
32 #include "vtkTransform.h"
33 #include "vtkDoubleArray.h"
34 #include "vtkSphere.h"
35 #include "vtkCamera.h"
36 #include "vtkAssemblyPath.h"
37 #include "vtkTextMapper.h"
38 #include "vtkActor2D.h"
39 #include "vtkTextProperty.h"
40 #include "vtkLineSource.h"
41 #include "vtkWindow.h"
42 #include "vtkObjectFactory.h"
43 
44 
45 vtkStandardNewMacro(vtkSphereRepresentation);
46 
47 //----------------------------------------------------------------------------
vtkSphereRepresentation()48 vtkSphereRepresentation::vtkSphereRepresentation()
49 {
50   // The initial state
51   this->InteractionState = vtkSphereRepresentation::Outside;
52 
53   // Handle size is in pixels for this widget
54   this->HandleSize = 10.0;
55 
56   // Set up the initial representation
57   this->Representation = VTK_SPHERE_WIREFRAME;
58 
59   // Set up the initial properties
60   this->SphereProperty = NULL;
61   this->SelectedSphereProperty = NULL;
62   this->HandleProperty = NULL;
63   this->SelectedHandleProperty = NULL;
64   this->HandleTextProperty = NULL;
65   this->RadialLineProperty = NULL;
66   this->CreateDefaultProperties();
67 
68   // Build the representation of the widget
69   // Represent the sphere
70   this->SphereSource = vtkSphereSource::New();
71   this->SphereSource->SetThetaResolution(16);
72   this->SphereSource->SetPhiResolution(8);
73   this->SphereSource->LatLongTessellationOn();
74   this->SphereMapper = vtkPolyDataMapper::New();
75   this->SphereMapper->SetInputConnection(
76     this->SphereSource->GetOutputPort());
77   this->SphereActor = vtkActor::New();
78   this->SphereActor->SetMapper(this->SphereMapper);
79 
80   // the handle
81   this->HandleVisibility = 0;
82   this->HandleDirection[0] = 1.0;
83   this->HandleDirection[1] = 0.0;
84   this->HandleDirection[2] = 0.0;
85   this->HandleSource = vtkSphereSource::New();
86   this->HandleSource->SetThetaResolution(16);
87   this->HandleSource->SetPhiResolution(8);
88   this->HandleMapper = vtkPolyDataMapper::New();
89   this->HandleMapper->SetInputConnection(
90     this->HandleSource->GetOutputPort());
91   this->HandleActor = vtkActor::New();
92   this->HandleActor->SetMapper(this->HandleMapper);
93 
94 
95   // Manage the handle label
96   this->HandleText = 1;
97   this->HandleTextMapper = vtkTextMapper::New();
98   this->HandleTextMapper->SetTextProperty(this->HandleTextProperty);
99   this->HandleTextActor = vtkActor2D::New();
100   this->HandleTextActor->SetMapper(this->HandleTextMapper);
101   this->HandleTextActor->GetPositionCoordinate()->SetCoordinateSystemToDisplay();
102 
103   // Manage the radial line segment
104   this->RadialLine = 1;
105   this->RadialLineSource = vtkLineSource::New();
106   this->RadialLineSource->SetResolution(1);
107   this->RadialLineMapper = vtkPolyDataMapper::New();
108   this->RadialLineMapper->SetInputConnection(this->RadialLineSource->GetOutputPort());
109   this->RadialLineActor = vtkActor::New();
110   this->RadialLineActor->SetMapper(this->RadialLineMapper);
111   this->RadialLineActor->SetProperty(this->RadialLineProperty);
112 
113   // Define the point coordinates
114   double bounds[6];
115   bounds[0] = -0.5;
116   bounds[1] = 0.5;
117   bounds[2] = -0.5;
118   bounds[3] = 0.5;
119   bounds[4] = -0.5;
120   bounds[5] = 0.5;
121 
122   // First creation of the widget, serves to initialize it
123   this->PlaceWidget(bounds);
124 
125   // Manage the picking stuff
126   this->HandlePicker = vtkCellPicker::New();
127   this->HandlePicker->SetTolerance(0.005); //need some fluff
128   this->HandlePicker->AddPickList(this->HandleActor);
129   this->HandlePicker->PickFromListOn();
130 
131   this->SpherePicker = vtkCellPicker::New();
132   this->SpherePicker->SetTolerance(0.005);
133   this->SpherePicker->AddPickList(this->SphereActor);
134   this->SpherePicker->PickFromListOn();
135 
136   this->SphereActor->SetProperty(this->SphereProperty);
137   this->HandleActor->SetProperty(this->HandleProperty);
138 }
139 
140 //----------------------------------------------------------------------------
~vtkSphereRepresentation()141 vtkSphereRepresentation::~vtkSphereRepresentation()
142 {
143   this->SphereActor->Delete();
144   this->SphereMapper->Delete();
145   this->SphereSource->Delete();
146 
147   this->HandlePicker->Delete();
148   this->SpherePicker->Delete();
149 
150   this->HandleSource->Delete();
151   this->HandleMapper->Delete();
152   this->HandleActor->Delete();
153 
154   // the handle
155   this->HandleTextProperty->Delete();
156   this->HandleTextMapper->Delete();
157   this->HandleTextActor->Delete();
158 
159   // the text
160   this->RadialLineProperty->Delete();
161   this->RadialLineSource->Delete();
162   this->RadialLineMapper->Delete();
163   this->RadialLineActor->Delete();
164 
165   if ( this->SphereProperty )
166     {
167     this->SphereProperty->Delete();
168     }
169   if ( this->SelectedSphereProperty )
170     {
171     this->SelectedSphereProperty->Delete();
172     }
173   if ( this->HandleProperty )
174     {
175     this->HandleProperty->Delete();
176     }
177   if ( this->SelectedHandleProperty )
178     {
179     this->SelectedHandleProperty->Delete();
180     }
181 }
182 
183 //----------------------------------------------------------------------
GetPolyData(vtkPolyData * pd)184 void vtkSphereRepresentation::GetPolyData(vtkPolyData *pd)
185 {
186   pd->ShallowCopy(this->SphereSource->GetOutput());
187 }
188 
189 //----------------------------------------------------------------------
GetSphere(vtkSphere * sphere)190 void vtkSphereRepresentation::GetSphere(vtkSphere *sphere)
191 {
192   sphere->SetRadius(this->SphereSource->GetRadius());
193   sphere->SetCenter(this->SphereSource->GetCenter());
194 }
195 
196 //----------------------------------------------------------------------
HighlightSphere(int highlight)197 void vtkSphereRepresentation::HighlightSphere(int highlight)
198 {
199   if ( highlight )
200     {
201     this->ValidPick = 1;
202     this->SphereActor->SetProperty(this->SelectedSphereProperty);
203     }
204   else
205     {
206     this->SphereActor->SetProperty(this->SphereProperty);
207     }
208 }
209 
210 //----------------------------------------------------------------------
HighlightHandle(int highlight)211 void vtkSphereRepresentation::HighlightHandle(int highlight)
212 {
213   if ( highlight )
214     {
215     this->ValidPick = 1;
216     this->HandleActor->SetProperty(this->SelectedHandleProperty);
217     }
218   else
219     {
220     this->HandleActor->SetProperty(this->HandleProperty);
221     }
222 }
223 
224 //------------------------------------------------------------------------------
RegisterPickers()225 void vtkSphereRepresentation::RegisterPickers()
226 {
227   this->Renderer->GetRenderWindow()->GetInteractor()->GetPickingManager()
228     ->AddPicker(this->HandlePicker, this);
229   this->Renderer->GetRenderWindow()->GetInteractor()->GetPickingManager()
230     ->AddPicker(this->SpherePicker, this);
231 }
232 
233 //----------------------------------------------------------------------
Scale(double * p1,double * p2,int vtkNotUsed (X),int Y)234 void vtkSphereRepresentation::Scale(double *p1, double *p2,
235                                     int vtkNotUsed(X), int Y)
236 {
237   //Get the motion vector
238   double v[3];
239   v[0] = p2[0] - p1[0];
240   v[1] = p2[1] - p1[1];
241   v[2] = p2[2] - p1[2];
242 
243   double radius = this->SphereSource->GetRadius();
244   double *c = this->SphereSource->GetCenter();
245 
246   // Compute the scale factor
247   double sf = vtkMath::Norm(v) / radius;
248   if ( Y > this->LastEventPosition[1] )
249     {
250     sf = 1.0 + sf;
251     }
252   else
253     {
254     sf = 1.0 - sf;
255     }
256 
257   // Make sure that the radius is valid; don't let it shrink further
258   // but it can still grow in radius.
259   if ( Y <= this->LastEventPosition[1] && sf*radius < 1.0e-06*this->InitialLength )
260     {
261     return;
262     }
263 
264   // Need to prevent radius going to zero
265   this->SphereSource->SetRadius(sf*radius);
266   this->HandlePosition[0] = c[0]+sf*(this->HandlePosition[0]-c[0]);
267   this->HandlePosition[1] = c[1]+sf*(this->HandlePosition[1]-c[1]);
268   this->HandlePosition[2] = c[2]+sf*(this->HandlePosition[2]-c[2]);
269   this->HandleSource->SetCenter(this->HandlePosition);
270 }
271 
272 //----------------------------------------------------------------------
StartWidgetInteraction(double e[2])273 void vtkSphereRepresentation::StartWidgetInteraction(double e[2])
274 {
275   // Store the start position
276   this->StartEventPosition[0] = e[0];
277   this->StartEventPosition[1] = e[1];
278   this->StartEventPosition[2] = 0.0;
279 
280   // Store the start position
281   this->LastEventPosition[0] = e[0];
282   this->LastEventPosition[1] = e[1];
283   this->LastEventPosition[2] = 0.0;
284 
285   this->ComputeInteractionState(static_cast<int>(e[0]),static_cast<int>(e[1]),0);
286 }
287 
288 //----------------------------------------------------------------------
WidgetInteraction(double e[2])289 void vtkSphereRepresentation::WidgetInteraction(double e[2])
290 {
291   // Convert events to appropriate coordinate systems
292   vtkCamera *camera = this->Renderer->GetActiveCamera();
293   if ( !camera )
294     {
295     return;
296     }
297   double focalPoint[4], pickPoint[4], prevPickPoint[4];
298   double z, vpn[3];
299   camera->GetViewPlaneNormal(vpn);
300 
301   // Compute the two points defining the motion vector
302   vtkInteractorObserver::ComputeWorldToDisplay(this->Renderer,
303                                                this->LastPickPosition[0], this->LastPickPosition[1], this->LastPickPosition[2],
304                                                focalPoint);
305   z = focalPoint[2];
306   vtkInteractorObserver::ComputeDisplayToWorld(this->Renderer,this->LastEventPosition[0],
307                                                this->LastEventPosition[1], z, prevPickPoint);
308   vtkInteractorObserver::ComputeDisplayToWorld(this->Renderer, e[0], e[1], z, pickPoint);
309 
310   // Process the motion
311   if ( this->InteractionState == vtkSphereRepresentation::Translating )
312     {
313     this->Translate(prevPickPoint, pickPoint);
314     }
315 
316   else if ( this->InteractionState == vtkSphereRepresentation::Scaling )
317     {
318     this->Scale(prevPickPoint, pickPoint,
319                 static_cast<int>(e[0]), static_cast<int>(e[1]));
320     }
321   else if ( this->InteractionState == vtkSphereRepresentation::MovingHandle )
322     {
323     vtkAssemblyPath* path = this->GetAssemblyPath(e[0], e[1], 0.,
324                                                   this->SpherePicker);
325 
326     if ( path != NULL )
327       {
328       this->HandleSource->SetCenter(this->SpherePicker->GetPickPosition());
329       this->SpherePicker->GetPickPosition(this->HandlePosition);
330       }
331     }
332 
333   // Store the position
334   this->LastEventPosition[0] = e[0];
335   this->LastEventPosition[1] = e[1];
336   this->LastEventPosition[2] = 0.0;
337 }
338 
339 //----------------------------------------------------------------------------
340 // Loop through all points and translate them
Translate(double * p1,double * p2)341 void vtkSphereRepresentation::Translate(double *p1, double *p2)
342 {
343   //Get the motion vector
344   double v[3];
345   v[0] = p2[0] - p1[0];
346   v[1] = p2[1] - p1[1];
347   v[2] = p2[2] - p1[2];
348 
349   //int res = this->SphereSource->GetResolution();
350   double *center = this->SphereSource->GetCenter();
351 
352   double center1[3];
353   for (int i=0; i<3; i++)
354     {
355     center1[i] = center[i] + v[i];
356     this->HandlePosition[i] += v[i];
357     }
358 
359   this->SphereSource->SetCenter(center1);
360   this->HandleSource->SetCenter(HandlePosition);
361 }
362 
363 //----------------------------------------------------------------------------
CreateDefaultProperties()364 void vtkSphereRepresentation::CreateDefaultProperties()
365 {
366   if ( ! this->SphereProperty )
367     {
368     this->SphereProperty = vtkProperty::New();
369     }
370   if ( ! this->SelectedSphereProperty )
371     {
372     this->SelectedSphereProperty = vtkProperty::New();
373     }
374 
375   if ( ! this->HandleProperty )
376     {
377     this->HandleProperty = vtkProperty::New();
378     this->HandleProperty->SetColor(1,1,1);
379     }
380   if ( ! this->SelectedHandleProperty )
381     {
382     this->SelectedHandleProperty = vtkProperty::New();
383     this->SelectedHandleProperty->SetColor(1,0,0);
384     }
385 
386   if ( ! this->HandleTextProperty )
387     {
388     this->HandleTextProperty = vtkTextProperty::New();
389     this->HandleTextProperty->SetFontSize(12);
390     this->HandleTextProperty->SetBold(1);
391     this->HandleTextProperty->SetItalic(1);
392     this->HandleTextProperty->SetShadow(1);
393     this->HandleTextProperty->SetFontFamilyToArial();
394     }
395 
396   if ( ! this->RadialLineProperty )
397     {
398     this->RadialLineProperty = vtkProperty::New();
399     this->RadialLineProperty->SetColor(1,0,0);
400     }
401 }
402 
403 //----------------------------------------------------------------------------
PlaceWidget(double center[3],double handle[3])404 void vtkSphereRepresentation::PlaceWidget(double center[3], double handle[3])
405 {
406   double r = vtkMath::Distance2BetweenPoints(center,handle);
407   this->SphereSource->SetCenter(center);
408   this->SphereSource->SetRadius(r);
409   this->SphereSource->Update();
410 
411   this->HandlePosition[0] = handle[0];
412   this->HandlePosition[1] = handle[1];
413   this->HandlePosition[2] = handle[2];
414   this->HandleSource->SetCenter(handle);
415   this->HandleSource->Update();
416 
417   this->HandleDirection[0] = handle[0] - center[0];
418   this->HandleDirection[1] = handle[1] - center[1];
419   this->HandleDirection[2] = handle[2] - center[2];
420 
421   this->InitialLength = r;
422   this->InitialBounds[0] = center[0] - r;
423   this->InitialBounds[1] = center[0] + r;
424   this->InitialBounds[2] = center[1] - r;
425   this->InitialBounds[3] = center[1] + r;
426   this->InitialBounds[4] = center[2] - r;
427   this->InitialBounds[5] = center[2] + r;
428 
429   this->ValidPick = 1;
430   this->BuildRepresentation();
431 }
432 
433 //----------------------------------------------------------------------------
SetCenter(double center[3])434 void vtkSphereRepresentation::SetCenter(double center[3])
435 {
436   double c[3];
437   this->SphereSource->GetCenter(c);
438   if ( c[0] != center[0] || c[1] != center[1] || c[2] != center[2] )
439     {
440     double handle[3];
441     this->SphereSource->SetCenter(center);
442 
443     if(this->GetHandleVisibility())
444       {
445       this->HandleSource->GetCenter(handle);
446       this->HandleDirection[0] = handle[0] - center[0];
447       this->HandleDirection[1] = handle[1] - center[1];
448       this->HandleDirection[2] = handle[2] - center[2];
449       double r = static_cast<double>(
450         vtkMath::Distance2BetweenPoints(handle,center) );
451       this->SphereSource->SetRadius(r);
452       }
453 
454     this->SphereSource->Update();
455     this->Modified();
456     }
457 }
458 
459 //----------------------------------------------------------------------------
SetRadius(double r)460 void vtkSphereRepresentation::SetRadius(double r)
461 {
462   r = (r <= this->InitialLength*1.0e-04 ? this->InitialLength*1.0e-04 : r);
463   if ( r != this->SphereSource->GetRadius() )
464     {
465     double center[3];
466     this->SphereSource->SetRadius(r);
467     this->SphereSource->GetCenter(center);
468     this->PlaceHandle(center,r);
469     this->SphereSource->Update();
470     this->Modified();
471     }
472 }
473 
474 //----------------------------------------------------------------------------
SetHandlePosition(double handle[3])475 void vtkSphereRepresentation::SetHandlePosition(double handle[3])
476 {
477   double h[3];
478   this->HandleSource->GetCenter(h);
479   if ( h[0] != handle[0] || h[1] != handle[1] || h[2] != handle[2] )
480     {
481     double c[3];
482     this->HandleSource->SetCenter(handle);
483     this->SphereSource->GetCenter(c);
484     this->HandleDirection[0] = handle[0] - c[0];
485     this->HandleDirection[1] = handle[1] - c[1];
486     this->HandleDirection[2] = handle[2] - c[2];
487     double r = static_cast<double>(
488       vtkMath::Distance2BetweenPoints(handle,c) );
489     this->SphereSource->SetRadius(r);
490     this->SphereSource->Update();
491     this->HandleSource->Update();
492     this->Modified();
493     }
494 }
495 
496 //----------------------------------------------------------------------------
SetHandleDirection(double dir[3])497 void vtkSphereRepresentation::SetHandleDirection(double dir[3])
498 {
499   double *d = this->HandleDirection;
500   if ( d[0] != dir[0] || d[1] != dir[1] || d[2] != dir[2] )
501     {
502     double c[3], handle[3];
503     this->SphereSource->GetCenter(c);
504     handle[0] = c[0] + dir[0];
505     handle[1] = c[1] + dir[1];
506     handle[2] = c[2] + dir[2];
507     this->HandleSource->SetCenter(handle);
508     this->HandleDirection[0] = dir[0];
509     this->HandleDirection[1] = dir[1];
510     this->HandleDirection[2] = dir[2];
511     double r = static_cast<double>(
512       vtkMath::Distance2BetweenPoints(handle,c) );
513     this->SphereSource->SetRadius(r);
514     this->SphereSource->Update();
515     this->HandleSource->Update();
516     this->Modified();
517     }
518 }
519 
520 //----------------------------------------------------------------------------
PlaceWidget(double bds[6])521 void vtkSphereRepresentation::PlaceWidget(double bds[6])
522 {
523   double bounds[6], center[3], radius;
524 
525   this->AdjustBounds(bds, bounds, center);
526 
527   radius = (bounds[1]-bounds[0]) / 2.0;
528   if ( radius > ((bounds[3]-bounds[2])/2.0) )
529     {
530     radius = (bounds[3]-bounds[2])/2.0;
531     }
532   radius = (bounds[1]-bounds[0]) / 2.0;
533   if ( radius > ((bounds[5]-bounds[4])/2.0) )
534     {
535     radius = (bounds[5]-bounds[4])/2.0;
536     }
537 
538   this->SphereSource->SetCenter(center);
539   this->SphereSource->SetRadius(radius);
540   this->SphereSource->Update();
541 
542   // place the handle
543   this->PlaceHandle(center,radius);
544 
545   for (int i=0; i<6; i++)
546     {
547     this->InitialBounds[i] = bounds[i];
548     }
549   this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
550                              (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
551                              (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
552 
553   this->ValidPick = 1; // since we have set up widget properly
554   this->SizeHandles();
555 }
556 
557 //----------------------------------------------------------------------------
PlaceHandle(double * center,double radius)558 void vtkSphereRepresentation::PlaceHandle(double *center, double radius)
559 {
560   double sf = radius / vtkMath::Norm(this->HandleDirection);
561 
562   this->HandlePosition[0] = center[0] + sf*this->HandleDirection[0];
563   this->HandlePosition[1] = center[1] + sf*this->HandleDirection[1];
564   this->HandlePosition[2] = center[2] + sf*this->HandleDirection[2];
565   this->HandleSource->SetCenter(this->HandlePosition);
566   this->HandleSource->Update();
567 }
568 
569 //----------------------------------------------------------------------------
ComputeInteractionState(int X,int Y,int vtkNotUsed (modify))570 int vtkSphereRepresentation::ComputeInteractionState(int X, int Y, int vtkNotUsed(modify))
571 {
572   // Okay, we can process this. Try to pick handles first;
573   // if no handles picked, then pick the bounding box.
574   this->InteractionState = vtkSphereRepresentation::Outside;
575   if (!this->Renderer || !this->Renderer->IsInViewport(X, Y))
576     {
577     return this->InteractionState;
578     }
579 
580   // Try and pick a handle first. This allows the picking of the handle even
581   // if it is "behind" the sphere.
582   vtkAssemblyPath *path;
583   int handlePicked = 0;
584   if ( this->HandleVisibility || this->HandleText || this->RadialLine )
585     {
586     path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
587 
588     if ( path != NULL )
589       {
590       this->ValidPick = 1;
591       this->InteractionState = vtkSphereRepresentation::MovingHandle;
592       this->HandleSource->GetCenter(this->LastPickPosition);
593       this->HandleSource->GetCenter(this->HandlePosition);
594       handlePicked = 1;
595       }
596     }
597 
598   if ( ! handlePicked )
599     {
600     path = this->GetAssemblyPath(X, Y, 0., this->SpherePicker);
601 
602     if ( path != NULL )
603       {
604       this->ValidPick = 1;
605       this->InteractionState = vtkSphereRepresentation::OnSphere;
606       this->SpherePicker->GetPickPosition(this->LastPickPosition);
607       }
608     }
609 
610   return this->InteractionState;
611 }
612 
613 //----------------------------------------------------------------------
SetInteractionState(int state)614 void vtkSphereRepresentation::SetInteractionState(int state)
615 {
616   // Clamp to allowable values
617   state = ( state < vtkSphereRepresentation::Outside ? vtkSphereRepresentation::Outside :
618             (state > vtkSphereRepresentation::Scaling ? vtkSphereRepresentation::Scaling : state) );
619 
620   // Depending on state, highlight appropriate parts of representation
621   this->InteractionState = state;
622 }
623 
624 //----------------------------------------------------------------------
GetBounds()625 double *vtkSphereRepresentation::GetBounds()
626 {
627   this->BuildRepresentation();
628   return this->SphereSource->GetOutput()->GetBounds();
629 }
630 
631 //----------------------------------------------------------------------------
BuildRepresentation()632 void vtkSphereRepresentation::BuildRepresentation()
633 {
634   // Always rebuild, it's not worth keeping track of modified
635   switch ( this->Representation )
636     {
637     case VTK_SPHERE_OFF:
638       break;
639     case VTK_SPHERE_WIREFRAME:
640       this->SphereProperty->SetRepresentationToWireframe();
641       this->SelectedSphereProperty->SetRepresentationToWireframe();
642       break;
643     case VTK_SPHERE_SURFACE:
644       this->SphereProperty->SetRepresentationToSurface();
645       this->SelectedSphereProperty->SetRepresentationToSurface();
646       break;
647     }
648   this->SphereSource->Update();
649   this->SizeHandles();
650 
651   // Now the annotations
652   if ( this->RadialLine )
653     {
654     this->RadialLineSource->SetPoint1(this->SphereSource->GetCenter());
655     this->RadialLineSource->SetPoint2(this->HandleSource->GetCenter());
656     this->RadialLineSource->Update();
657     }
658 
659   if ( this->HandleText && this->Renderer )
660     {
661     char str[256];
662     double c[3], hc[3], tc[4];
663     this->SphereSource->GetCenter(c);
664     this->HandleSource->GetCenter(hc);
665     double r = sqrt( static_cast<double>(vtkMath::Distance2BetweenPoints(c,hc)) );
666     r = (r<=0.0 ? 1.0 : r);
667     double theta = vtkMath::DegreesFromRadians( atan2( ( hc[1] - c[1] ), ( hc[0] - c[0] ) ) );
668     double phi   = vtkMath::DegreesFromRadians( acos( ( hc[2] - c[2] ) / r ) );
669     sprintf(str,"(%0.2g, %1.1f, %1.1f)", r, theta, phi);
670     this->HandleTextMapper->SetInput(str);
671     vtkInteractorObserver::ComputeWorldToDisplay(this->Renderer, hc[0], hc[1], hc[2], tc);
672     this->HandleTextActor->GetPositionCoordinate()->SetValue(tc[0]+10,tc[1]+10);
673     }
674 }
675 
676 //----------------------------------------------------------------------------
ReleaseGraphicsResources(vtkWindow * w)677 void vtkSphereRepresentation::ReleaseGraphicsResources(vtkWindow *w)
678 {
679   this->SphereActor->ReleaseGraphicsResources(w);
680   this->HandleActor->ReleaseGraphicsResources(w);
681   this->HandleTextActor->ReleaseGraphicsResources(w);
682   this->RadialLineActor->ReleaseGraphicsResources(w);
683 }
684 
685 //----------------------------------------------------------------------------
RenderOpaqueGeometry(vtkViewport * v)686 int vtkSphereRepresentation::RenderOpaqueGeometry(vtkViewport *v)
687 {
688   int count=0;
689   this->BuildRepresentation();
690 
691   if ( this->Representation != VTK_SPHERE_OFF )
692     {
693     count += this->SphereActor->RenderOpaqueGeometry(v);
694     }
695   if ( this->HandleVisibility )
696     {
697     count += this->HandleActor->RenderOpaqueGeometry(v);
698     }
699   if ( this->RadialLine )
700     {
701     count += this->RadialLineActor->RenderOpaqueGeometry(v);
702     }
703 
704   return count;
705 }
706 
707 //----------------------------------------------------------------------------
RenderTranslucentPolygonalGeometry(vtkViewport * v)708 int vtkSphereRepresentation::RenderTranslucentPolygonalGeometry(vtkViewport *v)
709 {
710   int count=0;
711 
712   if ( this->Representation != VTK_SPHERE_OFF )
713     {
714     count += this->SphereActor->RenderTranslucentPolygonalGeometry(v);
715     }
716   if ( this->HandleVisibility )
717     {
718     count += this->HandleActor->RenderTranslucentPolygonalGeometry(v);
719     }
720   if ( this->RadialLine )
721     {
722     count += this->RadialLineActor->RenderTranslucentPolygonalGeometry(v);
723     }
724 
725   return count;
726 }
727 
728 //----------------------------------------------------------------------------
RenderOverlay(vtkViewport * v)729 int vtkSphereRepresentation::RenderOverlay(vtkViewport *v)
730 {
731   int count=0;
732 
733   if ( this->HandleText )
734     {
735     count += this->HandleTextActor->RenderOverlay(v);
736     }
737 
738   return count;
739 }
740 
741 //----------------------------------------------------------------------------
HasTranslucentPolygonalGeometry()742 int vtkSphereRepresentation::HasTranslucentPolygonalGeometry()
743 {
744   int result=0;
745   this->BuildRepresentation();
746 
747   if ( this->Representation != VTK_SPHERE_OFF )
748     {
749     result |= this->SphereActor->HasTranslucentPolygonalGeometry();
750     }
751   if ( this->HandleVisibility )
752     {
753     result |= this->HandleActor->HasTranslucentPolygonalGeometry();
754     }
755   if ( this->HandleText )
756     {
757     result |= this->HandleTextActor->HasTranslucentPolygonalGeometry();
758     }
759   if ( this->RadialLine )
760     {
761     result |= this->RadialLineActor->HasTranslucentPolygonalGeometry();
762     }
763 
764   return result;
765 }
766 
767 
768 //----------------------------------------------------------------------------
SizeHandles()769 void vtkSphereRepresentation::SizeHandles()
770 {
771   double radius = this->vtkWidgetRepresentation::
772     SizeHandlesInPixels(1.5,this->HandleSource->GetOutput()->GetCenter());
773   this->HandleSource->SetRadius(radius);
774 }
775 
776 
777 
778 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)779 void vtkSphereRepresentation::PrintSelf(ostream& os, vtkIndent indent)
780 {
781   this->Superclass::PrintSelf(os,indent);
782 
783   os << indent << "Sphere Representation: ";
784   if ( this->Representation == VTK_SPHERE_OFF )
785     {
786     os << "Off\n";
787     }
788   else if ( this->Representation == VTK_SPHERE_WIREFRAME )
789     {
790     os << "Wireframe\n";
791     }
792   else //if ( this->Representation == VTK_SPHERE_SURFACE )
793     {
794     os << "Surface\n";
795     }
796 
797   if ( this->SphereProperty )
798     {
799     os << indent << "Sphere Property: " << this->SphereProperty << "\n";
800     }
801   else
802     {
803     os << indent << "Sphere Property: (none)\n";
804     }
805   if ( this->SelectedSphereProperty )
806     {
807     os << indent << "Selected Sphere Property: "
808        << this->SelectedSphereProperty << "\n";
809     }
810   else
811     {
812     os << indent << "Selected Sphere Property: (none)\n";
813     }
814 
815   if ( this->HandleProperty )
816     {
817     os << indent << "Handle Property: " << this->HandleProperty << "\n";
818     }
819   else
820     {
821     os << indent << "Handle Property: (none)\n";
822     }
823   if ( this->SelectedHandleProperty )
824     {
825     os << indent << "Selected Handle Property: "
826        << this->SelectedHandleProperty << "\n";
827     }
828   else
829     {
830     os << indent << "Selected Handle Property: (none)\n";
831     }
832 
833   os << indent << "Handle Visibility: "
834      << (this->HandleVisibility ? "On\n" : "Off\n");
835   os << indent << "Handle Direction: (" << this->HandleDirection[0] << ", "
836      << this->HandleDirection[1] << ", "
837      << this->HandleDirection[2] << ")\n";
838   os << indent << "Handle Position: (" << this->HandlePosition[0] << ", "
839      << this->HandlePosition[1] << ", "
840      << this->HandlePosition[2] << ")\n";
841 
842   int thetaRes = this->SphereSource->GetThetaResolution();
843   int phiRes = this->SphereSource->GetPhiResolution();
844   double *center = this->SphereSource->GetCenter();
845   double r = this->SphereSource->GetRadius();
846 
847   os << indent << "Theta Resolution: " << thetaRes << "\n";
848   os << indent << "Phi Resolution: " << phiRes << "\n";
849   os << indent << "Center: (" << center[0] << ", "
850      << center[1] << ", " << center[2] << ")\n";
851   os << indent << "Radius: " << r << "\n";
852 
853   os << indent << "Handle Text: " << this->HandleText << "\n";
854   os << indent << "Radial Line: " << this->RadialLine << "\n";
855 
856   if ( this->HandleTextProperty )
857     {
858     os << indent << "Handle Text Property: " << this->HandleTextProperty << "\n";
859     }
860   else
861     {
862     os << indent << "Handle Text Property: (none)\n";
863     }
864 
865   if ( this->RadialLineProperty )
866     {
867     os << indent << "Radial Line Property: " << this->RadialLineProperty << "\n";
868     }
869   else
870     {
871     os << indent << "Radial Line Property: (none)\n";
872     }
873 }
874 
875 
876