1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkBoxRepresentation.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 
16 #include "vtkBoxRepresentation.h"
17 #include "vtkActor.h"
18 #include "vtkSphereSource.h"
19 #include "vtkPolyDataMapper.h"
20 #include "vtkPolyData.h"
21 #include "vtkCallbackCommand.h"
22 #include "vtkBox.h"
23 #include "vtkPickingManager.h"
24 #include "vtkPolyData.h"
25 #include "vtkProperty.h"
26 #include "vtkRenderWindow.h"
27 #include "vtkRenderWindowInteractor.h"
28 #include "vtkRenderer.h"
29 #include "vtkInteractorObserver.h"
30 #include "vtkMath.h"
31 #include "vtkCellArray.h"
32 #include "vtkCellPicker.h"
33 #include "vtkTransform.h"
34 #include "vtkDoubleArray.h"
35 #include "vtkBox.h"
36 #include "vtkPlanes.h"
37 #include "vtkCamera.h"
38 #include "vtkAssemblyPath.h"
39 #include "vtkWindow.h"
40 #include "vtkObjectFactory.h"
41 
42 
43 vtkStandardNewMacro(vtkBoxRepresentation);
44 
45 //----------------------------------------------------------------------------
vtkBoxRepresentation()46 vtkBoxRepresentation::vtkBoxRepresentation()
47 {
48   // The initial state
49   this->InteractionState = vtkBoxRepresentation::Outside;
50 
51   // Handle size is in pixels for this widget
52   this->HandleSize = 5.0;
53 
54   // Control orientation of normals
55   this->InsideOut = 0;
56   this->OutlineFaceWires = 0;
57   this->OutlineCursorWires = 1;
58 
59   // Set up the initial properties
60   this->CreateDefaultProperties();
61 
62   // Construct the poly data representing the hex
63   this->HexPolyData = vtkPolyData::New();
64   this->HexMapper = vtkPolyDataMapper::New();
65   this->HexMapper->SetInputData(HexPolyData);
66   this->HexActor = vtkActor::New();
67   this->HexActor->SetMapper(this->HexMapper);
68   this->HexActor->SetProperty(this->OutlineProperty);
69 
70   // Construct initial points
71   this->Points = vtkPoints::New(VTK_DOUBLE);
72   this->Points->SetNumberOfPoints(15);//8 corners; 6 faces; 1 center
73   this->HexPolyData->SetPoints(this->Points);
74 
75   // Construct connectivity for the faces. These are used to perform
76   // the picking.
77   int i;
78   vtkIdType pts[4];
79   vtkCellArray *cells = vtkCellArray::New();
80   cells->Allocate(cells->EstimateSize(6,4));
81   pts[0] = 3; pts[1] = 0; pts[2] = 4; pts[3] = 7;
82   cells->InsertNextCell(4,pts);
83   pts[0] = 1; pts[1] = 2; pts[2] = 6; pts[3] = 5;
84   cells->InsertNextCell(4,pts);
85   pts[0] = 0; pts[1] = 1; pts[2] = 5; pts[3] = 4;
86   cells->InsertNextCell(4,pts);
87   pts[0] = 2; pts[1] = 3; pts[2] = 7; pts[3] = 6;
88   cells->InsertNextCell(4,pts);
89   pts[0] = 0; pts[1] = 3; pts[2] = 2; pts[3] = 1;
90   cells->InsertNextCell(4,pts);
91   pts[0] = 4; pts[1] = 5; pts[2] = 6; pts[3] = 7;
92   cells->InsertNextCell(4,pts);
93   this->HexPolyData->SetPolys(cells);
94   cells->Delete();
95   this->HexPolyData->BuildCells();
96 
97   // The face of the hexahedra
98   cells = vtkCellArray::New();
99   cells->Allocate(cells->EstimateSize(1,4));
100   cells->InsertNextCell(4,pts); //temporary, replaced later
101   this->HexFacePolyData = vtkPolyData::New();
102   this->HexFacePolyData->SetPoints(this->Points);
103   this->HexFacePolyData->SetPolys(cells);
104   this->HexFaceMapper = vtkPolyDataMapper::New();
105   this->HexFaceMapper->SetInputData(HexFacePolyData);
106   this->HexFace = vtkActor::New();
107   this->HexFace->SetMapper(this->HexFaceMapper);
108   this->HexFace->SetProperty(this->FaceProperty);
109   cells->Delete();
110 
111   // Create the outline for the hex
112   this->OutlinePolyData = vtkPolyData::New();
113   this->OutlinePolyData->SetPoints(this->Points);
114   this->OutlineMapper = vtkPolyDataMapper::New();
115   this->OutlineMapper->SetInputData(this->OutlinePolyData);
116   this->HexOutline = vtkActor::New();
117   this->HexOutline->SetMapper(this->OutlineMapper);
118   this->HexOutline->SetProperty(this->OutlineProperty);
119   cells = vtkCellArray::New();
120   cells->Allocate(cells->EstimateSize(15,2));
121   this->OutlinePolyData->SetLines(cells);
122   cells->Delete();
123 
124   // Create the outline
125   this->GenerateOutline();
126 
127   // Create the handles
128   this->Handle = new vtkActor* [7];
129   this->HandleMapper = new vtkPolyDataMapper* [7];
130   this->HandleGeometry = new vtkSphereSource* [7];
131   for (i=0; i<7; i++)
132     {
133     this->HandleGeometry[i] = vtkSphereSource::New();
134     this->HandleGeometry[i]->SetThetaResolution(16);
135     this->HandleGeometry[i]->SetPhiResolution(8);
136     this->HandleMapper[i] = vtkPolyDataMapper::New();
137     this->HandleMapper[i]->SetInputConnection(
138       this->HandleGeometry[i]->GetOutputPort());
139     this->Handle[i] = vtkActor::New();
140     this->Handle[i]->SetMapper(this->HandleMapper[i]);
141     this->Handle[i]->SetProperty(this->HandleProperty);
142     }
143 
144   // Define the point coordinates
145   double bounds[6];
146   bounds[0] = -0.5;
147   bounds[1] = 0.5;
148   bounds[2] = -0.5;
149   bounds[3] = 0.5;
150   bounds[4] = -0.5;
151   bounds[5] = 0.5;
152   // Points 8-14 are down by PositionHandles();
153   this->BoundingBox = vtkBox::New();
154   this->PlaceWidget(bounds);
155 
156   //Manage the picking stuff
157   this->HandlePicker = vtkCellPicker::New();
158   this->HandlePicker->SetTolerance(0.001);
159   for (i=0; i<7; i++)
160     {
161     this->HandlePicker->AddPickList(this->Handle[i]);
162     }
163   this->HandlePicker->PickFromListOn();
164 
165   this->HexPicker = vtkCellPicker::New();
166   this->HexPicker->SetTolerance(0.001);
167   this->HexPicker->AddPickList(HexActor);
168   this->HexPicker->PickFromListOn();
169 
170   this->CurrentHandle = NULL;
171 
172   // Internal data memebers for performance
173   this->Transform = vtkTransform::New();
174   this->PlanePoints = vtkPoints::New(VTK_DOUBLE);
175   this->PlanePoints->SetNumberOfPoints(6);
176   this->PlaneNormals = vtkDoubleArray::New();
177   this->PlaneNormals->SetNumberOfComponents(3);
178   this->PlaneNormals->SetNumberOfTuples(6);
179   this->Matrix = vtkMatrix4x4::New();
180 }
181 
182 //----------------------------------------------------------------------------
~vtkBoxRepresentation()183 vtkBoxRepresentation::~vtkBoxRepresentation()
184 {
185   this->HexActor->Delete();
186   this->HexMapper->Delete();
187   this->HexPolyData->Delete();
188   this->Points->Delete();
189 
190   this->HexFace->Delete();
191   this->HexFaceMapper->Delete();
192   this->HexFacePolyData->Delete();
193 
194   this->HexOutline->Delete();
195   this->OutlineMapper->Delete();
196   this->OutlinePolyData->Delete();
197 
198   for (int i=0; i<7; i++)
199     {
200     this->HandleGeometry[i]->Delete();
201     this->HandleMapper[i]->Delete();
202     this->Handle[i]->Delete();
203     }
204   delete [] this->Handle;
205   delete [] this->HandleMapper;
206   delete [] this->HandleGeometry;
207 
208   this->HandlePicker->Delete();
209   this->HexPicker->Delete();
210 
211   this->Transform->Delete();
212   this->BoundingBox->Delete();
213   this->PlanePoints->Delete();
214   this->PlaneNormals->Delete();
215   this->Matrix->Delete();
216 
217   this->HandleProperty->Delete();
218   this->SelectedHandleProperty->Delete();
219   this->FaceProperty->Delete();
220   this->SelectedFaceProperty->Delete();
221   this->OutlineProperty->Delete();
222   this->SelectedOutlineProperty->Delete();
223 }
224 
225 //----------------------------------------------------------------------
GetPolyData(vtkPolyData * pd)226 void vtkBoxRepresentation::GetPolyData(vtkPolyData *pd)
227 {
228   pd->SetPoints(this->HexPolyData->GetPoints());
229   pd->SetPolys(this->HexPolyData->GetPolys());
230 }
231 
232 //----------------------------------------------------------------------
StartWidgetInteraction(double e[2])233 void vtkBoxRepresentation::StartWidgetInteraction(double e[2])
234 {
235   // Store the start position
236   this->StartEventPosition[0] = e[0];
237   this->StartEventPosition[1] = e[1];
238   this->StartEventPosition[2] = 0.0;
239 
240   // Store the start position
241   this->LastEventPosition[0] = e[0];
242   this->LastEventPosition[1] = e[1];
243   this->LastEventPosition[2] = 0.0;
244 
245   this->ComputeInteractionState(static_cast<int>(e[0]),static_cast<int>(e[1]),0);
246 }
247 
248 //----------------------------------------------------------------------
WidgetInteraction(double e[2])249 void vtkBoxRepresentation::WidgetInteraction(double e[2])
250 {
251   // Convert events to appropriate coordinate systems
252   vtkCamera *camera = this->Renderer->GetActiveCamera();
253   if ( !camera )
254     {
255     return;
256     }
257   double focalPoint[4], pickPoint[4], prevPickPoint[4];
258   double z, vpn[3];
259   camera->GetViewPlaneNormal(vpn);
260 
261   // Compute the two points defining the motion vector
262   double pos[3];
263   if ( this->LastPicker == this->HexPicker )
264     {
265     this->HexPicker->GetPickPosition(pos);
266     }
267   else
268     {
269     this->HandlePicker->GetPickPosition(pos);
270     }
271   vtkInteractorObserver::ComputeWorldToDisplay(this->Renderer,
272                                                pos[0], pos[1], pos[2],
273                                                focalPoint);
274   z = focalPoint[2];
275   vtkInteractorObserver::ComputeDisplayToWorld(this->Renderer,this->LastEventPosition[0],
276                                                this->LastEventPosition[1], z, prevPickPoint);
277   vtkInteractorObserver::ComputeDisplayToWorld(this->Renderer, e[0], e[1], z, pickPoint);
278 
279   // Process the motion
280   if ( this->InteractionState == vtkBoxRepresentation::MoveF0 )
281     {
282     this->MoveMinusXFace(prevPickPoint,pickPoint);
283     }
284 
285   else if ( this->InteractionState == vtkBoxRepresentation::MoveF1 )
286     {
287     this->MovePlusXFace(prevPickPoint,pickPoint);
288     }
289 
290   else if ( this->InteractionState == vtkBoxRepresentation::MoveF2 )
291     {
292     this->MoveMinusYFace(prevPickPoint,pickPoint);
293     }
294 
295   else if ( this->InteractionState == vtkBoxRepresentation::MoveF3 )
296     {
297     this->MovePlusYFace(prevPickPoint,pickPoint);
298     }
299 
300   else if ( this->InteractionState == vtkBoxRepresentation::MoveF4 )
301     {
302     this->MoveMinusZFace(prevPickPoint,pickPoint);
303     }
304 
305   else if ( this->InteractionState == vtkBoxRepresentation::MoveF5 )
306     {
307     this->MovePlusZFace(prevPickPoint,pickPoint);
308     }
309 
310   else if ( this->InteractionState == vtkBoxRepresentation::Translating )
311     {
312     this->Translate(prevPickPoint, pickPoint);
313     }
314 
315   else if ( this->InteractionState == vtkBoxRepresentation::Scaling )
316     {
317     this->Scale(prevPickPoint, pickPoint,
318                 static_cast<int>(e[0]), static_cast<int>(e[1]));
319     }
320 
321   else if ( this->InteractionState == vtkBoxRepresentation::Rotating )
322     {
323     this->Rotate(static_cast<int>(e[0]), static_cast<int>(e[1]), prevPickPoint, pickPoint, vpn);
324     }
325 
326   // Store the start position
327   this->LastEventPosition[0] = e[0];
328   this->LastEventPosition[1] = e[1];
329   this->LastEventPosition[2] = 0.0;
330 }
331 
332 //----------------------------------------------------------------------------
MoveFace(double * p1,double * p2,double * dir,double * x1,double * x2,double * x3,double * x4,double * x5)333 void vtkBoxRepresentation::MoveFace(double *p1, double *p2, double *dir,
334                                     double *x1, double *x2, double *x3, double *x4,
335                                     double *x5)
336   {
337   int i;
338   double v[3], v2[3];
339 
340   for (i=0; i<3; i++)
341     {
342     v[i] = p2[i] - p1[i];
343     v2[i] = dir[i];
344     }
345 
346   vtkMath::Normalize(v2);
347   double f = vtkMath::Dot(v,v2);
348 
349   for (i=0; i<3; i++)
350     {
351     v[i] = f*v2[i];
352 
353     x1[i] += v[i];
354     x2[i] += v[i];
355     x3[i] += v[i];
356     x4[i] += v[i];
357     x5[i] += v[i];
358     }
359   this->PositionHandles();
360 }
361 
362 //----------------------------------------------------------------------------
GetDirection(const double Nx[3],const double Ny[3],const double Nz[3],double dir[3])363 void vtkBoxRepresentation::GetDirection(const double Nx[3],const double Ny[3],
364                                         const double Nz[3], double dir[3])
365 {
366   double dotNy, dotNz;
367   double y[3];
368 
369   if(vtkMath::Dot(Nx,Nx)!=0)
370     {
371     dir[0] = Nx[0];
372     dir[1] = Nx[1];
373     dir[2] = Nx[2];
374     }
375   else
376     {
377     dotNy = vtkMath::Dot(Ny,Ny);
378     dotNz = vtkMath::Dot(Nz,Nz);
379     if(dotNy != 0 && dotNz != 0)
380       {
381       vtkMath::Cross(Ny,Nz,dir);
382       }
383     else if(dotNy != 0)
384       {
385       //dir must have been initialized to the
386       //corresponding coordinate direction before calling
387       //this method
388       vtkMath::Cross(Ny,dir,y);
389       vtkMath::Cross(y,Ny,dir);
390       }
391     else if(dotNz != 0)
392       {
393       //dir must have been initialized to the
394       //corresponding coordinate direction before calling
395       //this method
396       vtkMath::Cross(Nz,dir,y);
397       vtkMath::Cross(y,Nz,dir);
398       }
399     }
400 }
401 
402 //----------------------------------------------------------------------------
MovePlusXFace(double * p1,double * p2)403 void vtkBoxRepresentation::MovePlusXFace(double *p1, double *p2)
404 {
405   double *pts =
406     static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(0);
407 
408   double *h1 = pts + 3*9;
409 
410   double *x1 = pts + 3*1;
411   double *x2 = pts + 3*2;
412   double *x3 = pts + 3*5;
413   double *x4 = pts + 3*6;
414 
415   double dir[3] = { 1 , 0 , 0};
416   this->ComputeNormals();
417   this->GetDirection(this->N[1],this->N[3],this->N[5],dir);
418   this->MoveFace(p1,p2,dir,x1,x2,x3,x4,h1);
419 }
420 
421 //----------------------------------------------------------------------------
MoveMinusXFace(double * p1,double * p2)422 void vtkBoxRepresentation::MoveMinusXFace(double *p1, double *p2)
423 {
424   double *pts =
425     static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(0);
426 
427   double *h1 = pts + 3*8;
428 
429   double *x1 = pts + 3*0;
430   double *x2 = pts + 3*3;
431   double *x3 = pts + 3*4;
432   double *x4 = pts + 3*7;
433 
434   double dir[3]={-1,0,0};
435   this->ComputeNormals();
436   this->GetDirection(this->N[0],this->N[4],this->N[2],dir);
437 
438   this->MoveFace(p1,p2,dir,x1,x2,x3,x4,h1);
439 }
440 
441 //----------------------------------------------------------------------------
MovePlusYFace(double * p1,double * p2)442 void vtkBoxRepresentation::MovePlusYFace(double *p1, double *p2)
443 {
444   double *pts =
445      static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(0);
446 
447   double *h1 = pts + 3*11;
448 
449   double *x1 = pts + 3*2;
450   double *x2 = pts + 3*3;
451   double *x3 = pts + 3*6;
452   double *x4 = pts + 3*7;
453 
454   double dir[3]={0,1,0};
455   this->ComputeNormals();
456   this->GetDirection(this->N[3],this->N[5],this->N[1],dir);
457 
458   this->MoveFace(p1,p2,dir,x1,x2,x3,x4,h1);
459 }
460 
461 //----------------------------------------------------------------------------
MoveMinusYFace(double * p1,double * p2)462 void vtkBoxRepresentation::MoveMinusYFace(double *p1, double *p2)
463 {
464   double *pts =
465     static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(0);
466 
467   double *h1 = pts + 3*10;
468 
469   double *x1 = pts + 3*0;
470   double *x2 = pts + 3*1;
471   double *x3 = pts + 3*4;
472   double *x4 = pts + 3*5;
473 
474   double dir[3] = {0, -1, 0};
475   this->ComputeNormals();
476   this->GetDirection(this->N[2],this->N[0],this->N[4],dir);
477 
478   this->MoveFace(p1,p2,dir,x1,x2,x3,x4,h1);
479 }
480 
481 //----------------------------------------------------------------------------
MovePlusZFace(double * p1,double * p2)482 void vtkBoxRepresentation::MovePlusZFace(double *p1, double *p2)
483 {
484   double *pts =
485     static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(0);
486 
487   double *h1 = pts + 3*13;
488 
489   double *x1 = pts + 3*4;
490   double *x2 = pts + 3*5;
491   double *x3 = pts + 3*6;
492   double *x4 = pts + 3*7;
493 
494   double dir[3]={0,0,1};
495   this->ComputeNormals();
496   this->GetDirection(this->N[5],this->N[1],this->N[3],dir);
497 
498   this->MoveFace(p1,p2,dir,x1,x2,x3,x4,h1);
499 }
500 
501 //----------------------------------------------------------------------------
MoveMinusZFace(double * p1,double * p2)502 void vtkBoxRepresentation::MoveMinusZFace(double *p1, double *p2)
503 {
504   double *pts =
505     static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(0);
506 
507   double *h1 = pts + 3*12;
508 
509   double *x1 = pts + 3*0;
510   double *x2 = pts + 3*1;
511   double *x3 = pts + 3*2;
512   double *x4 = pts + 3*3;
513 
514   double dir[3]={0,0,-1};
515   this->ComputeNormals();
516   this->GetDirection(this->N[4],this->N[2],this->N[0],dir);
517 
518   this->MoveFace(p1,p2,dir,x1,x2,x3,x4,h1);
519 }
520 
521 //----------------------------------------------------------------------------
522 // Loop through all points and translate them
Translate(double * p1,double * p2)523 void vtkBoxRepresentation::Translate(double *p1, double *p2)
524 {
525   double *pts =
526     static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(0);
527   double v[3];
528 
529   v[0] = p2[0] - p1[0];
530   v[1] = p2[1] - p1[1];
531   v[2] = p2[2] - p1[2];
532 
533   // Move the corners
534   for (int i=0; i<8; i++)
535     {
536     *pts++ += v[0];
537     *pts++ += v[1];
538     *pts++ += v[2];
539     }
540   this->PositionHandles();
541 }
542 
543 //----------------------------------------------------------------------------
Scale(double * vtkNotUsed (p1),double * vtkNotUsed (p2),int vtkNotUsed (X),int Y)544 void vtkBoxRepresentation::Scale(double *vtkNotUsed(p1),
545                                  double *vtkNotUsed(p2),
546                                  int vtkNotUsed(X),
547                                  int Y)
548 {
549   double *pts =
550       static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(0);
551   double *center
552     = static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(3*14);
553   double sf;
554 
555   if ( Y > this->LastEventPosition[1] )
556     {
557     sf = 1.03;
558     }
559   else
560     {
561     sf = 0.97;
562     }
563 
564   // Move the corners
565   for (int i=0; i<8; i++, pts+=3)
566     {
567     pts[0] = sf * (pts[0] - center[0]) + center[0];
568     pts[1] = sf * (pts[1] - center[1]) + center[1];
569     pts[2] = sf * (pts[2] - center[2]) + center[2];
570     }
571   this->PositionHandles();
572 }
573 
574 //----------------------------------------------------------------------------
ComputeNormals()575 void vtkBoxRepresentation::ComputeNormals()
576 {
577   double *pts =
578      static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(0);
579   double *p0 = pts;
580   double *px = pts + 3*1;
581   double *py = pts + 3*3;
582   double *pz = pts + 3*4;
583   int i;
584 
585   for (i=0; i<3; i++)
586     {
587     this->N[0][i] = p0[i] - px[i];
588     this->N[2][i] = p0[i] - py[i];
589     this->N[4][i] = p0[i] - pz[i];
590     }
591   vtkMath::Normalize(this->N[0]);
592   vtkMath::Normalize(this->N[2]);
593   vtkMath::Normalize(this->N[4]);
594   for (i=0; i<3; i++)
595     {
596     this->N[1][i] = -this->N[0][i];
597     this->N[3][i] = -this->N[2][i];
598     this->N[5][i] = -this->N[4][i];
599     }
600 }
601 
602 //----------------------------------------------------------------------------
GetPlanes(vtkPlanes * planes)603 void vtkBoxRepresentation::GetPlanes(vtkPlanes *planes)
604 {
605   if ( ! planes )
606     {
607     return;
608     }
609 
610   this->ComputeNormals();
611 
612   // Set the normals and coordinate values
613   double factor = (this->InsideOut ? -1.0 : 1.0);
614   for (int i=0; i<6; i++)
615     {
616     this->PlanePoints->SetPoint(i,this->Points->GetPoint(8+i));
617     this->PlaneNormals->SetTuple3(i, factor*this->N[i][0],
618                                   factor*this->N[i][1], factor*this->N[i][2]);
619     }
620 
621   planes->SetPoints(this->PlanePoints);
622   planes->SetNormals(this->PlaneNormals);
623   planes->Modified();
624 }
625 
626 //----------------------------------------------------------------------------
Rotate(int X,int Y,double * p1,double * p2,double * vpn)627 void vtkBoxRepresentation::Rotate(int X,
628                                   int Y,
629                                   double *p1,
630                                   double *p2,
631                                   double *vpn)
632 {
633   double *pts =
634     static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(0);
635   double *center =
636     static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(3*14);
637   double v[3]; //vector of motion
638   double axis[3]; //axis of rotation
639   double theta; //rotation angle
640   int i;
641 
642   v[0] = p2[0] - p1[0];
643   v[1] = p2[1] - p1[1];
644   v[2] = p2[2] - p1[2];
645 
646   // Create axis of rotation and angle of rotation
647   vtkMath::Cross(vpn,v,axis);
648   if ( vtkMath::Normalize(axis) == 0.0 )
649     {
650     return;
651     }
652   int *size = this->Renderer->GetSize();
653   double l2 = (X-this->LastEventPosition[0])*(X-this->LastEventPosition[0])
654              + (Y-this->LastEventPosition[1])*(Y-this->LastEventPosition[1]);
655   theta = 360.0 * sqrt(l2/(size[0]*size[0]+size[1]*size[1]));
656 
657   //Manipulate the transform to reflect the rotation
658   this->Transform->Identity();
659   this->Transform->Translate(center[0],center[1],center[2]);
660   this->Transform->RotateWXYZ(theta,axis);
661   this->Transform->Translate(-center[0],-center[1],-center[2]);
662 
663   //Set the corners
664   vtkPoints *newPts = vtkPoints::New(VTK_DOUBLE);
665   this->Transform->TransformPoints(this->Points,newPts);
666 
667   for (i=0; i<8; i++, pts+=3)
668     {
669     this->Points->SetPoint(i, newPts->GetPoint(i));
670     }
671 
672   newPts->Delete();
673   this->PositionHandles();
674 }
675 
676 //----------------------------------------------------------------------------
CreateDefaultProperties()677 void vtkBoxRepresentation::CreateDefaultProperties()
678 {
679   // Handle properties
680   this->HandleProperty = vtkProperty::New();
681   this->HandleProperty->SetColor(1,1,1);
682 
683   this->SelectedHandleProperty = vtkProperty::New();
684   this->SelectedHandleProperty->SetColor(1,0,0);
685 
686   // Face properties
687   this->FaceProperty = vtkProperty::New();
688   this->FaceProperty->SetColor(1,1,1);
689   this->FaceProperty->SetOpacity(0.0);
690 
691   this->SelectedFaceProperty = vtkProperty::New();
692   this->SelectedFaceProperty->SetColor(1,1,0);
693   this->SelectedFaceProperty->SetOpacity(0.25);
694 
695   // Outline properties
696   this->OutlineProperty = vtkProperty::New();
697   this->OutlineProperty->SetRepresentationToWireframe();
698   this->OutlineProperty->SetAmbient(1.0);
699   this->OutlineProperty->SetAmbientColor(1.0,1.0,1.0);
700   this->OutlineProperty->SetLineWidth(2.0);
701 
702   this->SelectedOutlineProperty = vtkProperty::New();
703   this->SelectedOutlineProperty->SetRepresentationToWireframe();
704   this->SelectedOutlineProperty->SetAmbient(1.0);
705   this->SelectedOutlineProperty->SetAmbientColor(0.0,1.0,0.0);
706   this->SelectedOutlineProperty->SetLineWidth(2.0);
707 }
708 
709 //----------------------------------------------------------------------------
PlaceWidget(double bds[6])710 void vtkBoxRepresentation::PlaceWidget(double bds[6])
711 {
712   int i;
713   double bounds[6], center[3];
714 
715   this->AdjustBounds(bds,bounds,center);
716 
717   this->Points->SetPoint(0, bounds[0], bounds[2], bounds[4]);
718   this->Points->SetPoint(1, bounds[1], bounds[2], bounds[4]);
719   this->Points->SetPoint(2, bounds[1], bounds[3], bounds[4]);
720   this->Points->SetPoint(3, bounds[0], bounds[3], bounds[4]);
721   this->Points->SetPoint(4, bounds[0], bounds[2], bounds[5]);
722   this->Points->SetPoint(5, bounds[1], bounds[2], bounds[5]);
723   this->Points->SetPoint(6, bounds[1], bounds[3], bounds[5]);
724   this->Points->SetPoint(7, bounds[0], bounds[3], bounds[5]);
725 
726   for (i=0; i<6; i++)
727     {
728     this->InitialBounds[i] = bounds[i];
729     }
730   this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
731                              (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
732                              (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
733 
734   this->PositionHandles();
735   this->ComputeNormals();
736   this->ValidPick = 1; //since we have set up widget
737   this->SizeHandles();
738 }
739 
740 //----------------------------------------------------------------------------
GetTransform(vtkTransform * t)741 void vtkBoxRepresentation::GetTransform(vtkTransform *t)
742 {
743   double *pts =
744     static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(0);
745   double *p0 = pts;
746   double *p1 = pts + 3*1;
747   double *p3 = pts + 3*3;
748   double *p4 = pts + 3*4;
749   double *p14 = pts + 3*14;
750   double center[3], translate[3], scale[3], scaleVec[3][3];
751   double InitialCenter[3];
752   int i;
753 
754   // The transformation is relative to the initial bounds.
755   // Initial bounds are set when PlaceWidget() is invoked.
756   t->Identity();
757 
758   // Translation
759   for (i=0; i<3; i++)
760     {
761     InitialCenter[i] =
762       (this->InitialBounds[2*i+1]+this->InitialBounds[2*i]) / 2.0;
763     center[i] = p14[i] - InitialCenter[i];
764     }
765   translate[0] = center[0] + InitialCenter[0];
766   translate[1] = center[1] + InitialCenter[1];
767   translate[2] = center[2] + InitialCenter[2];
768   t->Translate(translate[0], translate[1], translate[2]);
769 
770   // Orientation
771   this->Matrix->Identity();
772   this->PositionHandles();
773   this->ComputeNormals();
774   for (i=0; i<3; i++)
775     {
776     this->Matrix->SetElement(i,0,this->N[1][i]);
777     this->Matrix->SetElement(i,1,this->N[3][i]);
778     this->Matrix->SetElement(i,2,this->N[5][i]);
779     }
780   t->Concatenate(this->Matrix);
781 
782   // Scale
783   for (i=0; i<3; i++)
784     {
785     scaleVec[0][i] = (p1[i] - p0[i]);
786     scaleVec[1][i] = (p3[i] - p0[i]);
787     scaleVec[2][i] = (p4[i] - p0[i]);
788     }
789 
790   scale[0] = vtkMath::Norm(scaleVec[0]);
791   if (this->InitialBounds[1] != this->InitialBounds[0])
792     {
793     scale[0] = scale[0] / (this->InitialBounds[1]-this->InitialBounds[0]);
794     }
795   scale[1] = vtkMath::Norm(scaleVec[1]);
796   if (this->InitialBounds[3] != this->InitialBounds[2])
797     {
798     scale[1] = scale[1] / (this->InitialBounds[3]-this->InitialBounds[2]);
799     }
800   scale[2] = vtkMath::Norm(scaleVec[2]);
801   if (this->InitialBounds[5] != this->InitialBounds[4])
802     {
803     scale[2] = scale[2] / (this->InitialBounds[5]-this->InitialBounds[4]);
804     }
805   t->Scale(scale[0],scale[1],scale[2]);
806 
807   // Add back in the contribution due to non-origin center
808   t->Translate(-InitialCenter[0], -InitialCenter[1], -InitialCenter[2]);
809 }
810 
811 //----------------------------------------------------------------------------
SetTransform(vtkTransform * t)812 void vtkBoxRepresentation::SetTransform(vtkTransform* t)
813 {
814   if (!t)
815     {
816     vtkErrorMacro(<<"vtkTransform t must be non-NULL");
817     return;
818     }
819 
820   double *pts =
821      static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(0);
822   double xIn[3];
823   // make sure the transform is up-to-date before using it
824   t->Update();
825 
826   // Position the eight points of the box and then update the
827   // position of the other handles.
828   double *bounds=this->InitialBounds;
829 
830   xIn[0] = bounds[0]; xIn[1] = bounds[2]; xIn[2] = bounds[4];
831   t->InternalTransformPoint(xIn,pts);
832 
833   xIn[0] = bounds[1]; xIn[1]= bounds[2]; xIn[2] = bounds[4];
834   t->InternalTransformPoint(xIn,pts+3);
835 
836   xIn[0] = bounds[1]; xIn[1]= bounds[3]; xIn[2] = bounds[4];
837   t->InternalTransformPoint(xIn,pts+6);
838 
839   xIn[0] = bounds[0]; xIn[1]= bounds[3]; xIn[2] = bounds[4];
840   t->InternalTransformPoint(xIn,pts+9);
841 
842   xIn[0] = bounds[0]; xIn[1]= bounds[2]; xIn[2] = bounds[5];
843   t->InternalTransformPoint(xIn,pts+12);
844 
845   xIn[0] = bounds[1]; xIn[1]= bounds[2]; xIn[2] = bounds[5];
846   t->InternalTransformPoint(xIn,pts+15);
847 
848   xIn[0] = bounds[1]; xIn[1]= bounds[3]; xIn[2] = bounds[5];
849   t->InternalTransformPoint(xIn,pts+18);
850 
851   xIn[0] = bounds[0]; xIn[1]= bounds[3]; xIn[2] = bounds[5];
852   t->InternalTransformPoint(xIn,pts+21);
853 
854   this->PositionHandles();
855 }
856 
857 //----------------------------------------------------------------------------
SetOutlineFaceWires(int newValue)858 void vtkBoxRepresentation::SetOutlineFaceWires(int newValue)
859 {
860   if (this->OutlineFaceWires != newValue)
861     {
862     this->OutlineFaceWires = newValue;
863     this->Modified();
864     // the outline is dependent on this value, so we have to regen
865     this->GenerateOutline();
866     }
867 }
868 
869 //----------------------------------------------------------------------------
SetOutlineCursorWires(int newValue)870 void vtkBoxRepresentation::SetOutlineCursorWires(int newValue)
871 {
872   if (this->OutlineCursorWires != newValue)
873     {
874     this->OutlineCursorWires = newValue;
875     this->Modified();
876     // the outline is dependent on this value, so we have to regen
877     this->GenerateOutline();
878     }
879 }
880 
881 //----------------------------------------------------------------------------
GenerateOutline()882 void vtkBoxRepresentation::GenerateOutline()
883 {
884   // Whatever the case may be, we have to reset the Lines of the
885   // OutlinePolyData (i.e. nuke all current line data)
886   vtkCellArray *cells = this->OutlinePolyData->GetLines();
887   cells->Reset();
888 
889   // Now the outline lines
890   if ( ! this->OutlineFaceWires && ! this->OutlineCursorWires )
891     {
892     return;
893     }
894 
895   vtkIdType pts[2];
896 
897   if ( this->OutlineFaceWires )
898     {
899     pts[0] = 0; pts[1] = 7;       //the -x face
900     cells->InsertNextCell(2,pts);
901     pts[0] = 3; pts[1] = 4;
902     cells->InsertNextCell(2,pts);
903     pts[0] = 1; pts[1] = 6;       //the +x face
904     cells->InsertNextCell(2,pts);
905     pts[0] = 2; pts[1] = 5;
906     cells->InsertNextCell(2,pts);
907     pts[0] = 1; pts[1] = 4;       //the -y face
908     cells->InsertNextCell(2,pts);
909     pts[0] = 0; pts[1] = 5;
910     cells->InsertNextCell(2,pts);
911     pts[0] = 3; pts[1] = 6;       //the +y face
912     cells->InsertNextCell(2,pts);
913     pts[0] = 2; pts[1] = 7;
914     cells->InsertNextCell(2,pts);
915     pts[0] = 0; pts[1] = 2;       //the -z face
916     cells->InsertNextCell(2,pts);
917     pts[0] = 1; pts[1] = 3;
918     cells->InsertNextCell(2,pts);
919     pts[0] = 4; pts[1] = 6;       //the +Z face
920     cells->InsertNextCell(2,pts);
921     pts[0] = 5; pts[1] = 7;
922     cells->InsertNextCell(2,pts);
923     }
924   if ( this->OutlineCursorWires )
925     {
926     pts[0] = 8; pts[1] = 9;         //the x cursor line
927     cells->InsertNextCell(2,pts);
928     pts[0] = 10; pts[1] = 11;       //the y cursor line
929     cells->InsertNextCell(2,pts);
930     pts[0] = 12; pts[1] = 13;       //the z cursor line
931     cells->InsertNextCell(2,pts);
932     }
933   this->OutlinePolyData->Modified();
934   if ( this->OutlineProperty)
935     {
936     this->OutlineProperty->SetRepresentationToWireframe();
937     this->SelectedOutlineProperty->SetRepresentationToWireframe();
938     }
939 }
940 
941 //----------------------------------------------------------------------------
ComputeInteractionState(int X,int Y,int modify)942 int vtkBoxRepresentation::ComputeInteractionState(int X, int Y, int modify)
943 {
944   // Okay, we can process this. Try to pick handles first;
945   // if no handles picked, then pick the bounding box.
946   if (!this->Renderer || !this->Renderer->IsInViewport(X, Y))
947     {
948     this->InteractionState = vtkBoxRepresentation::Outside;
949     return this->InteractionState;
950     }
951 
952   // Try and pick a handle first
953   this->LastPicker = NULL;
954   this->CurrentHandle = NULL;
955 
956   vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
957 
958   if ( path != NULL )
959     {
960     this->ValidPick = 1;
961     this->LastPicker = this->HandlePicker;
962     this->CurrentHandle =
963            reinterpret_cast<vtkActor *>(path->GetFirstNode()->GetViewProp());
964     if ( this->CurrentHandle == this->Handle[0] )
965       {
966       this->InteractionState = vtkBoxRepresentation::MoveF0;
967       }
968     else if ( this->CurrentHandle == this->Handle[1] )
969       {
970       this->InteractionState = vtkBoxRepresentation::MoveF1;
971       }
972     else if ( this->CurrentHandle == this->Handle[2] )
973       {
974       this->InteractionState = vtkBoxRepresentation::MoveF2;
975       }
976     else if ( this->CurrentHandle == this->Handle[3] )
977       {
978       this->InteractionState = vtkBoxRepresentation::MoveF3;
979       }
980     else if ( this->CurrentHandle == this->Handle[4] )
981       {
982       this->InteractionState = vtkBoxRepresentation::MoveF4;
983       }
984     else if ( this->CurrentHandle == this->Handle[5] )
985       {
986       this->InteractionState = vtkBoxRepresentation::MoveF5;
987       }
988     else if ( this->CurrentHandle == this->Handle[6] )
989       {
990       this->InteractionState = vtkBoxRepresentation::Translating;
991       }
992     }
993   else //see if the hex is picked
994     {
995     path = this->GetAssemblyPath(X, Y, 0., this->HexPicker);
996 
997     if ( path != NULL )
998       {
999       this->LastPicker = this->HexPicker;
1000       this->ValidPick = 1;
1001       if ( !modify )
1002         {
1003         this->InteractionState = vtkBoxRepresentation::Rotating;
1004         }
1005       else
1006         {
1007         this->CurrentHandle = this->Handle[6];
1008         this->InteractionState = vtkBoxRepresentation::Translating;
1009         }
1010       }
1011     else
1012       {
1013       this->InteractionState = vtkBoxRepresentation::Outside;
1014       }
1015     }
1016 
1017   return this->InteractionState;
1018 }
1019 
1020 //----------------------------------------------------------------------
SetInteractionState(int state)1021 void vtkBoxRepresentation::SetInteractionState(int state)
1022 {
1023   // Clamp to allowable values
1024   state = ( state < vtkBoxRepresentation::Outside ? vtkBoxRepresentation::Outside :
1025             (state > vtkBoxRepresentation::Scaling ? vtkBoxRepresentation::Scaling : state) );
1026 
1027   // Depending on state, highlight appropriate parts of representation
1028   int handle;
1029   this->InteractionState = state;
1030   switch (state)
1031     {
1032     case vtkBoxRepresentation::MoveF0:
1033     case vtkBoxRepresentation::MoveF1:
1034     case vtkBoxRepresentation::MoveF2:
1035     case vtkBoxRepresentation::MoveF3:
1036     case vtkBoxRepresentation::MoveF4:
1037     case vtkBoxRepresentation::MoveF5:
1038       this->HighlightOutline(0);
1039       handle = this->HighlightHandle(this->CurrentHandle);
1040       this->HighlightFace(handle);
1041       break;
1042     case vtkBoxRepresentation::Rotating:
1043       this->HighlightOutline(0);
1044       this->HighlightHandle(NULL);
1045       this->HighlightFace(this->HexPicker->GetCellId());
1046       break;
1047     case vtkBoxRepresentation::Translating:
1048     case vtkBoxRepresentation::Scaling:
1049       this->HighlightOutline(1);
1050       this->HighlightHandle(this->Handle[6]);
1051       this->HighlightFace(-1);
1052       break;
1053     default:
1054       this->HighlightOutline(0);
1055       this->HighlightHandle(NULL);
1056       this->HighlightFace(-1);
1057     }
1058 }
1059 
1060 //----------------------------------------------------------------------
GetBounds()1061 double *vtkBoxRepresentation::GetBounds()
1062 {
1063   this->BuildRepresentation();
1064   this->BoundingBox->SetBounds(this->HexActor->GetBounds());
1065   return this->BoundingBox->GetBounds();
1066 }
1067 
1068 //----------------------------------------------------------------------------
BuildRepresentation()1069 void vtkBoxRepresentation::BuildRepresentation()
1070 {
1071   // Rebuild only if necessary
1072   if ( this->GetMTime() > this->BuildTime ||
1073        (this->Renderer && this->Renderer->GetVTKWindow() &&
1074         (this->Renderer->GetVTKWindow()->GetMTime() > this->BuildTime ||
1075         this->Renderer->GetActiveCamera()->GetMTime() > this->BuildTime)) )
1076     {
1077     this->SizeHandles();
1078     this->BuildTime.Modified();
1079     }
1080 }
1081 
1082 //----------------------------------------------------------------------------
ReleaseGraphicsResources(vtkWindow * w)1083 void vtkBoxRepresentation::ReleaseGraphicsResources(vtkWindow *w)
1084 {
1085   this->HexActor->ReleaseGraphicsResources(w);
1086   this->HexOutline->ReleaseGraphicsResources(w);
1087   this->HexFace->ReleaseGraphicsResources(w);
1088   // render the handles
1089   for (int j=0; j<7; j++)
1090     {
1091     this->Handle[j]->ReleaseGraphicsResources(w);
1092     }
1093 
1094 }
1095 
1096 //----------------------------------------------------------------------------
RenderOpaqueGeometry(vtkViewport * v)1097 int vtkBoxRepresentation::RenderOpaqueGeometry(vtkViewport *v)
1098 {
1099   int count=0;
1100   this->BuildRepresentation();
1101 
1102   count += this->HexActor->RenderOpaqueGeometry(v);
1103   count += this->HexOutline->RenderOpaqueGeometry(v);
1104   count += this->HexFace->RenderOpaqueGeometry(v);
1105   // render the handles
1106   for (int j=0; j<7; j++)
1107     {
1108     if(this->Handle[j]->GetVisibility())
1109       {
1110       count += this->Handle[j]->RenderOpaqueGeometry(v);
1111       }
1112     }
1113 
1114   return count;
1115 }
1116 
1117 //----------------------------------------------------------------------------
RenderTranslucentPolygonalGeometry(vtkViewport * v)1118 int vtkBoxRepresentation::RenderTranslucentPolygonalGeometry(vtkViewport *v)
1119 {
1120   int count=0;
1121   this->BuildRepresentation();
1122 
1123   count += this->HexActor->RenderTranslucentPolygonalGeometry(v);
1124   count += this->HexOutline->RenderTranslucentPolygonalGeometry(v);
1125   count += this->HexFace->RenderTranslucentPolygonalGeometry(v);
1126   // render the handles
1127   for (int j=0; j<7; j++)
1128     {
1129     if(this->Handle[j]->GetVisibility())
1130       {
1131       count += this->Handle[j]->RenderTranslucentPolygonalGeometry(v);
1132       }
1133     }
1134 
1135   return count;
1136 }
1137 
1138 //----------------------------------------------------------------------------
HasTranslucentPolygonalGeometry()1139 int vtkBoxRepresentation::HasTranslucentPolygonalGeometry()
1140 {
1141   int result=0;
1142   this->BuildRepresentation();
1143 
1144   result |= this->HexActor->HasTranslucentPolygonalGeometry();
1145   result |= this->HexOutline->HasTranslucentPolygonalGeometry();
1146 
1147   // If the face is not selected, we are not really rendering translucent faces,
1148   // hence don't bother taking it's opacity into consideration.
1149   // Look at BUG #7301.
1150   if (this->HexFace->GetProperty() == this->SelectedFaceProperty)
1151     {
1152     result |= this->HexFace->HasTranslucentPolygonalGeometry();
1153     }
1154 
1155   // render the handles
1156   for (int j=0; j<7; j++)
1157     {
1158     result |= this->Handle[j]->HasTranslucentPolygonalGeometry();
1159     }
1160 
1161   return result;
1162 }
1163 
1164 #define VTK_AVERAGE(a,b,c) \
1165   c[0] = (a[0] + b[0])/2.0; \
1166   c[1] = (a[1] + b[1])/2.0; \
1167   c[2] = (a[2] + b[2])/2.0;
1168 
1169 //----------------------------------------------------------------------------
PositionHandles()1170 void vtkBoxRepresentation::PositionHandles()
1171 {
1172   double *pts =
1173      static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(0);
1174   double *p0 = pts;
1175   double *p1 = pts + 3*1;
1176   double *p2 = pts + 3*2;
1177   double *p3 = pts + 3*3;
1178   //double *p4 = pts + 3*4;
1179   double *p5 = pts + 3*5;
1180   double *p6 = pts + 3*6;
1181   double *p7 = pts + 3*7;
1182   double x[3];
1183 
1184   VTK_AVERAGE(p0,p7,x);
1185   this->Points->SetPoint(8, x);
1186   VTK_AVERAGE(p1,p6,x);
1187   this->Points->SetPoint(9, x);
1188   VTK_AVERAGE(p0,p5,x);
1189   this->Points->SetPoint(10, x);
1190   VTK_AVERAGE(p2,p7,x);
1191   this->Points->SetPoint(11, x);
1192   VTK_AVERAGE(p1,p3,x);
1193   this->Points->SetPoint(12, x);
1194   VTK_AVERAGE(p5,p7,x);
1195   this->Points->SetPoint(13, x);
1196   VTK_AVERAGE(p0,p6,x);
1197   this->Points->SetPoint(14, x);
1198 
1199   int i;
1200   for (i = 0; i < 7; ++i)
1201     {
1202     this->HandleGeometry[i]->SetCenter(this->Points->GetPoint(8+i));
1203     }
1204 
1205   this->Points->GetData()->Modified();
1206   this->HexFacePolyData->Modified();
1207   this->HexPolyData->Modified();
1208   this->GenerateOutline();
1209 }
1210 #undef VTK_AVERAGE
1211 
1212 //----------------------------------------------------------------------------
HandlesOn()1213 void vtkBoxRepresentation::HandlesOn()
1214 {
1215   for (int i=0; i<7; i++)
1216     {
1217     this->Handle[i]->VisibilityOn();
1218     }
1219 }
1220 
1221 //----------------------------------------------------------------------------
HandlesOff()1222 void vtkBoxRepresentation::HandlesOff()
1223 {
1224   for (int i=0; i<7; i++)
1225     {
1226     this->Handle[i]->VisibilityOff();
1227     }
1228 }
1229 
1230 //----------------------------------------------------------------------------
SizeHandles()1231 void vtkBoxRepresentation::SizeHandles()
1232 {
1233   double *center
1234     = static_cast<vtkDoubleArray *>(this->Points->GetData())->GetPointer(3*14);
1235   double radius =
1236       this->vtkWidgetRepresentation::SizeHandlesInPixels(1.5,center);
1237   for(int i=0; i<7; i++)
1238     {
1239     this->HandleGeometry[i]->SetRadius(radius);
1240     }
1241 }
1242 
1243 //----------------------------------------------------------------------------
HighlightHandle(vtkProp * prop)1244 int vtkBoxRepresentation::HighlightHandle(vtkProp *prop)
1245 {
1246   // first unhighlight anything picked
1247   this->HighlightOutline(0);
1248   if ( this->CurrentHandle )
1249     {
1250     this->CurrentHandle->SetProperty(this->HandleProperty);
1251     }
1252 
1253   this->CurrentHandle = static_cast<vtkActor *>(prop);
1254 
1255   if ( this->CurrentHandle )
1256     {
1257     this->CurrentHandle->SetProperty(this->SelectedHandleProperty);
1258     for (int i=0; i<6; i++) //find attached face
1259       {
1260       if ( this->CurrentHandle == this->Handle[i] )
1261         {
1262         return i;
1263         }
1264       }
1265     }
1266 
1267   if ( this->CurrentHandle == this->Handle[6] )
1268     {
1269     this->HighlightOutline(1);
1270     return 6;
1271     }
1272 
1273   return -1;
1274 }
1275 
1276 //----------------------------------------------------------------------------
HighlightFace(int cellId)1277 void vtkBoxRepresentation::HighlightFace(int cellId)
1278 {
1279   if ( cellId >= 0 )
1280     {
1281     vtkIdType npts;
1282     vtkIdType *pts;
1283     vtkCellArray *cells = this->HexFacePolyData->GetPolys();
1284     this->HexPolyData->GetCellPoints(cellId, npts, pts);
1285     this->HexFacePolyData->Modified();
1286     cells->ReplaceCell(0,npts,pts);
1287     this->CurrentHexFace = cellId;
1288     this->HexFace->SetProperty(this->SelectedFaceProperty);
1289     if ( !this->CurrentHandle )
1290       {
1291       this->CurrentHandle = this->HexFace;
1292       }
1293     }
1294   else
1295     {
1296     this->HexFace->SetProperty(this->FaceProperty);
1297     this->CurrentHexFace = -1;
1298     }
1299 }
1300 
1301 //----------------------------------------------------------------------------
HighlightOutline(int highlight)1302 void vtkBoxRepresentation::HighlightOutline(int highlight)
1303 {
1304   if ( highlight )
1305     {
1306     this->HexActor->SetProperty(this->SelectedOutlineProperty);
1307     this->HexOutline->SetProperty(this->SelectedOutlineProperty);
1308     }
1309   else
1310     {
1311     this->HexActor->SetProperty(this->OutlineProperty);
1312     this->HexOutline->SetProperty(this->OutlineProperty);
1313     }
1314 }
1315 
1316 //------------------------------------------------------------------------------
RegisterPickers()1317 void vtkBoxRepresentation::RegisterPickers()
1318 {
1319   this->Renderer->GetRenderWindow()->GetInteractor()->GetPickingManager()
1320     ->AddPicker(this->HandlePicker, this);
1321   this->Renderer->GetRenderWindow()->GetInteractor()->GetPickingManager()
1322     ->AddPicker(this->HexPicker, this);
1323 }
1324 
1325 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)1326 void vtkBoxRepresentation::PrintSelf(ostream& os, vtkIndent indent)
1327 {
1328   this->Superclass::PrintSelf(os,indent);
1329 
1330   double *bounds=this->InitialBounds;
1331   os << indent << "Initial Bounds: "
1332      << "(" << bounds[0] << "," << bounds[1] << ") "
1333      << "(" << bounds[2] << "," << bounds[3] << ") "
1334      << "(" << bounds[4] << "," << bounds[5] << ")\n";
1335 
1336   if ( this->HandleProperty )
1337     {
1338     os << indent << "Handle Property: " << this->HandleProperty << "\n";
1339     }
1340   else
1341     {
1342     os << indent << "Handle Property: (none)\n";
1343     }
1344   if ( this->SelectedHandleProperty )
1345     {
1346     os << indent << "Selected Handle Property: "
1347        << this->SelectedHandleProperty << "\n";
1348     }
1349   else
1350     {
1351     os << indent << "SelectedHandle Property: (none)\n";
1352     }
1353 
1354   if ( this->FaceProperty )
1355     {
1356     os << indent << "Face Property: " << this->FaceProperty << "\n";
1357     }
1358   else
1359     {
1360     os << indent << "Face Property: (none)\n";
1361     }
1362   if ( this->SelectedFaceProperty )
1363     {
1364     os << indent << "Selected Face Property: "
1365        << this->SelectedFaceProperty << "\n";
1366     }
1367   else
1368     {
1369     os << indent << "Selected Face Property: (none)\n";
1370     }
1371 
1372   if ( this->OutlineProperty )
1373     {
1374     os << indent << "Outline Property: " << this->OutlineProperty << "\n";
1375     }
1376   else
1377     {
1378     os << indent << "Outline Property: (none)\n";
1379     }
1380   if ( this->SelectedOutlineProperty )
1381     {
1382     os << indent << "Selected Outline Property: "
1383        << this->SelectedOutlineProperty << "\n";
1384     }
1385   else
1386     {
1387     os << indent << "Selected Outline Property: (none)\n";
1388     }
1389 
1390   os << indent << "Outline Face Wires: "
1391      << (this->OutlineFaceWires ? "On\n" : "Off\n");
1392   os << indent << "Outline Cursor Wires: "
1393      << (this->OutlineCursorWires ? "On\n" : "Off\n");
1394   os << indent << "Inside Out: " << (this->InsideOut ? "On\n" : "Off\n");
1395 }
1396