Salome HOME
Merge with branch V2_2_0_VISU_improvement
[modules/gui.git] / src / SVTK / SVTK_CubeAxesActor2D.cxx
1 //  SALOME OBJECT : kernel of SALOME component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SVTK_CubeAxesActor2D.cxx
25 //  Author : Eugeny Nikolaev
26 //  Module : SALOME
27 //  $Header$
28
29 #include "SVTK_CubeAxesActor2D.h"
30 #include "VTKViewer_Transform.h"
31
32 #include <vtkPolyDataMapper.h>
33 #include <vtkRectilinearGridGeometryFilter.h>
34 #include <vtkActor.h>
35 #include <vtkCubeAxesActor2D.h>
36 #include <vtkAxisActor2D.h>
37 #include <vtkCamera.h>
38 #include <vtkDataSet.h>
39 #include <vtkMath.h>
40 #include <vtkObjectFactory.h>
41 #include <vtkTextProperty.h>
42 #include <vtkViewport.h>
43 #include <vtkFloatArray.h>
44 #include <vtkRectilinearGrid.h>
45 #include <vtkProperty.h>
46 #include <vtkProperty2D.h>
47
48 vtkCxxRevisionMacro(SVTK_CubeAxesActor2D, "$Revision$");
49 vtkStandardNewMacro(SVTK_CubeAxesActor2D);
50
51 //----------------------------------------------------------------------------
52 // Instantiate this object.
53 SVTK_CubeAxesActor2D::SVTK_CubeAxesActor2D()
54 {
55   this->wireActorXY = vtkActor::New();
56   this->wireActorYZ = vtkActor::New();
57   this->wireActorXZ = vtkActor::New();
58
59   this->planeXY = vtkRectilinearGridGeometryFilter::New();
60   this->planeYZ = vtkRectilinearGridGeometryFilter::New();
61   this->planeXZ = vtkRectilinearGridGeometryFilter::New();
62
63   this->rgridMapperXY = vtkPolyDataMapper::New();
64   this->rgridMapperYZ = vtkPolyDataMapper::New();
65   this->rgridMapperXZ = vtkPolyDataMapper::New();
66
67   this->rgridMapperXY->SetInput(this->planeXY->GetOutput());
68   this->rgridMapperYZ->SetInput(this->planeYZ->GetOutput());
69   this->rgridMapperXZ->SetInput(this->planeXZ->GetOutput());
70
71   this->wireActorXY->SetMapper(rgridMapperXY);
72   this->wireActorYZ->SetMapper(rgridMapperYZ);
73   this->wireActorXZ->SetMapper(rgridMapperXZ);
74
75   this->wireActorXY->GetProperty()->SetRepresentationToWireframe();
76   this->wireActorYZ->GetProperty()->SetRepresentationToWireframe();
77   this->wireActorXZ->GetProperty()->SetRepresentationToWireframe();
78
79   // setting ambient to 1 (if no - incorrect reaction on light)
80   this->wireActorXY->GetProperty()->SetAmbient(1);
81   this->wireActorYZ->GetProperty()->SetAmbient(1);
82   this->wireActorXZ->GetProperty()->SetAmbient(1);
83
84   this->XAxis->SetTitle(this->XLabel);
85   this->YAxis->SetTitle(this->YLabel);
86   this->ZAxis->SetTitle(this->ZLabel);
87   
88   this->XAxis->SetNumberOfLabels(this->NumberOfLabels);
89   this->YAxis->SetNumberOfLabels(this->NumberOfLabels);
90   this->ZAxis->SetNumberOfLabels(this->NumberOfLabels);
91  
92   this->XAxis->SetLabelFormat(this->LabelFormat);
93   this->YAxis->SetLabelFormat(this->LabelFormat);
94   this->ZAxis->SetLabelFormat(this->LabelFormat);
95   
96   this->XAxis->SetFontFactor(this->FontFactor);
97   this->YAxis->SetFontFactor(this->FontFactor);
98   this->ZAxis->SetFontFactor(this->FontFactor);
99   
100   this->XAxis->SetProperty(this->GetProperty());
101   this->YAxis->SetProperty(this->GetProperty());
102   this->ZAxis->SetProperty(this->GetProperty());
103
104   vtkTextProperty* aTLProp = vtkTextProperty::New();
105   aTLProp->SetBold(0);
106   aTLProp->SetItalic(0);
107   aTLProp->SetShadow(0);
108   aTLProp->SetFontFamilyToArial();
109   aTLProp->SetColor(1,0,0);
110   if (this->XAxis->GetLabelTextProperty())
111     this->XAxis->GetLabelTextProperty()->ShallowCopy(aTLProp);
112   aTLProp->SetColor(0,1,0);
113   if (this->YAxis->GetLabelTextProperty())
114     this->YAxis->GetLabelTextProperty()->ShallowCopy(aTLProp);
115   aTLProp->SetColor(0,0,1);
116   if (this->ZAxis->GetLabelTextProperty())
117     this->ZAxis->GetLabelTextProperty()->ShallowCopy(aTLProp);;
118
119   aTLProp->SetColor(1,0,0);
120   if (this->XAxis->GetLabelTextProperty())
121     this->XAxis->GetTitleTextProperty()->ShallowCopy(aTLProp);
122   aTLProp->SetColor(0,1,0);
123   if (this->YAxis->GetLabelTextProperty())
124     this->YAxis->GetTitleTextProperty()->ShallowCopy(aTLProp);
125   aTLProp->SetColor(0,0,1);
126   if (this->ZAxis->GetLabelTextProperty())
127     this->ZAxis->GetTitleTextProperty()->ShallowCopy(aTLProp);
128   
129   aTLProp->Delete();
130   
131 }
132
133 //----------------------------------------------------------------------------
134 SVTK_CubeAxesActor2D::~SVTK_CubeAxesActor2D()
135 {
136   this->wireActorXY->Delete();
137   this->wireActorYZ->Delete();
138   this->wireActorXZ->Delete();
139
140   this->planeXY->Delete();
141   this->planeYZ->Delete();
142   this->planeXZ->Delete();
143
144   this->rgridMapperXY->Delete();
145   this->rgridMapperYZ->Delete();
146   this->rgridMapperXZ->Delete();
147 }
148
149 //----------------------------------------------------------------------------
150 // Static variable describes connections in cube.
151 static int Conn[8][3] = {{1,2,4}, {0,3,5}, {3,0,6}, {2,1,7},
152                          {5,6,0}, {4,7,1}, {7,4,2}, {6,5,3}};
153
154 //----------------------------------------------------------------------------
155 // Project the bounding box and compute edges on the border of the bounding
156 // cube. Determine which parts of the edges are visible via intersection 
157 // with the boundary of the viewport (minus borders).
158 int SVTK_CubeAxesActor2D::RenderOverlay(vtkViewport *viewport)
159 {
160   int renderedSomething=0;
161
162   // Initialization
163   if ( ! this->RenderSomething )
164     {
165     return 0;
166     }
167   
168   //Render the axes
169   if ( this->XAxisVisibility )
170     {
171     renderedSomething += this->XAxis->RenderOverlay(viewport);
172     }
173   if ( this->YAxisVisibility )
174     {
175     renderedSomething += this->YAxis->RenderOverlay(viewport);
176     }
177   if ( this->ZAxisVisibility )
178     {
179     renderedSomething += this->ZAxis->RenderOverlay(viewport);
180     }
181   
182   bool RX=false,RY=false;
183   if (this->XAxisVisibility){
184     this->wireActorXY->RenderOverlay(viewport);
185     this->wireActorXZ->RenderOverlay(viewport);
186     RX = true;
187   }
188   if (this->YAxisVisibility){
189     if(!RX) this->wireActorXY->RenderOverlay(viewport);
190     this->wireActorYZ->RenderOverlay(viewport);
191     RY = true;
192   }
193   if (this->ZAxisVisibility){
194     if(!RX) this->wireActorXZ->RenderOverlay(viewport);
195     if(!RY) this->wireActorYZ->RenderOverlay(viewport);
196   }
197
198   return renderedSomething;
199 }
200
201 static void ChangeValues(float* aArray1,float* aArray2,float *aRange1,float* aRange2,bool theY){
202   float tmp=-1000;
203   if (!theY){
204     for (int i=0; i<4; i++){
205       tmp = aArray1[i]; aArray1[i] = aArray2[i]; aArray2[i] = tmp;
206     }
207     for(int i=0;i<2; i++){
208       tmp = aRange1[i]; aRange1[i] = aRange2[i]; aRange2[i] = tmp;
209     }
210   }
211   else{
212     tmp = aArray1[2]; aArray1[2] = aArray2[0]; aArray2[0] = tmp;
213     tmp = aArray1[3]; aArray1[3] = aArray2[1]; aArray2[1] = tmp;
214     tmp = aArray1[0]; aArray1[0] = aArray2[2]; aArray2[2] = tmp;
215     tmp = aArray1[1]; aArray1[1] = aArray2[3]; aArray2[3] = tmp;
216
217     tmp = aRange1[0]; aRange1[0] = aRange2[1]; aRange2[1] = tmp;
218     tmp = aRange1[1]; aRange1[1] = aRange2[0]; aRange2[0] = tmp;
219   }
220 }
221
222 static void ChangeArrays(float* xCoords,float* yCoords,float* zCoords,
223                          float* xRange,float* yRange,float* zRange,
224                          const int xAxes,const int yAxes, const int zAxes)
225 {
226   if ( xAxes == 0 && yAxes == 2 && zAxes == 1)
227     ChangeValues(yCoords,zCoords,yRange,zRange,true);
228   else if (xAxes == 1 && yAxes == 0 && zAxes == 2)
229     ChangeValues(xCoords,yCoords,xRange,yRange,true);
230   else if (xAxes == 1 && yAxes == 2 && zAxes == 0){
231     ChangeValues(xCoords,zCoords,xRange,zRange,false);
232     // xAxes == 0 && yAxes == 2 && zAxes == 1
233     ChangeValues(yCoords,zCoords,yRange,zRange,true);
234   } else if (xAxes == 2 && yAxes == 0 && zAxes == 1){
235     ChangeValues(xCoords,yCoords,xRange,yRange,true);
236     // xAxes == 0 && yAxes == 2 && zAxes == 1
237     ChangeValues(zCoords,yCoords,zRange,yRange,true);
238   } else if (xAxes == 2 && yAxes == 1 && zAxes == 0)
239     ChangeValues(zCoords,xCoords,zRange,xRange,false);
240 }
241
242 //----------------------------------------------------------------------------
243 // Project the bounding box and compute edges on the border of the bounding
244 // cube. Determine which parts of the edges are visible via intersection 
245 // with the boundary of the viewport (minus borders).
246 int SVTK_CubeAxesActor2D::RenderOpaqueGeometry(vtkViewport *viewport)
247 {
248   float bounds[6], slope = 0.0, minSlope, num, den;
249   float pts[8][3], d2, d2Min, min;
250   int i, idx = 0;
251   int xIdx, yIdx = 0, zIdx = 0, zIdx2, renderedSomething=0;
252   int xAxes = 0, yAxes, zAxes;
253
254   // Initialization
255   if ( !this->Camera )
256     {
257     vtkErrorMacro(<<"No camera!");
258     this->RenderSomething = 0;
259     return 0;
260     }
261   
262   this->RenderSomething = 1;
263
264   // determine the bounds to use
265   this->GetBounds(bounds);
266
267   // Build the axes (almost always needed so we don't check mtime)
268   // Transform all points into display coordinates
269   this->TransformBounds(viewport, bounds, pts);
270
271   // Find the portion of the bounding box that fits within the viewport,
272   if ( this->ClipBounds(viewport, pts, bounds) == 0 )
273     {
274     this->RenderSomething = 0;
275     return 0;
276     }
277
278   // Take into account the inertia. Process only so often.
279   if ( this->RenderCount++ == 0 || !(this->RenderCount % this->Inertia) )
280     {
281     // Okay, we have a bounding box, maybe clipped and scaled, that is visible.
282     // We setup the axes depending on the fly mode.
283     if ( this->FlyMode == VTK_FLY_CLOSEST_TRIAD )
284       {
285       // Loop over points and find the closest point to the camera
286       min = VTK_LARGE_FLOAT;
287       for (i=0; i < 8; i++)
288         {
289         if ( pts[i][2] < min )
290           {
291           idx = i;
292           min = pts[i][2];
293           }
294         }
295
296       // Setup the three axes to be drawn
297       xAxes = 0;
298       xIdx = Conn[idx][0];
299       yAxes = 1;
300       yIdx = Conn[idx][1];
301       zAxes = 2;
302       zIdx = idx;
303       zIdx2 = Conn[idx][2];
304       }
305     else
306       {
307       float e1[2], e2[2], e3[2];
308
309       // Find distance to origin
310       d2Min = VTK_LARGE_FLOAT;
311       for (i=0; i < 8; i++)
312         {
313         d2 = pts[i][0]*pts[i][0] + pts[i][1]*pts[i][1];
314         if ( d2 < d2Min )
315           {
316           d2Min = d2;
317           idx = i;
318           }
319         }
320
321       // find minimum slope point connected to closest point and on 
322       // right side (in projected coordinates). This is the first edge.
323       minSlope = VTK_LARGE_FLOAT;
324       for (xIdx=0, i=0; i<3; i++)
325         {
326         num = (pts[Conn[idx][i]][1] - pts[idx][1]);
327         den = (pts[Conn[idx][i]][0] - pts[idx][0]);
328         if ( den != 0.0 )
329           {
330           slope = num / den;
331           }
332         if ( slope < minSlope && den > 0 )
333           {
334           xIdx = Conn[idx][i];
335           yIdx = Conn[idx][(i+1)%3];
336           zIdx = Conn[idx][(i+2)%3];
337           xAxes = i;
338           minSlope = slope;
339           }
340         }
341
342       // find edge (connected to closest point) on opposite side
343       for ( i=0; i<2; i++)
344         {
345         e1[i] = (pts[xIdx][i] - pts[idx][i]);
346         e2[i] = (pts[yIdx][i] - pts[idx][i]);
347         e3[i] = (pts[zIdx][i] - pts[idx][i]);
348         }
349       vtkMath::Normalize2D(e1);
350       vtkMath::Normalize2D(e2);
351       vtkMath::Normalize2D(e3);
352
353       if ( vtkMath::Dot2D(e1,e2) < vtkMath::Dot2D(e1,e3) )
354         {
355         yAxes = (xAxes + 1) % 3;
356         }
357       else
358         {
359         yIdx = zIdx;
360         yAxes = (xAxes + 2) % 3;
361         }
362
363       // Find the final point by determining which global x-y-z axes have not 
364       // been represented, and then determine the point closest to the viewer.
365       zAxes = (xAxes != 0 && yAxes != 0 ? 0 :
366               (xAxes != 1 && yAxes != 1 ? 1 : 2));
367       if ( pts[Conn[xIdx][zAxes]][2] < pts[Conn[yIdx][zAxes]][2] )
368         {
369         zIdx = xIdx;
370         zIdx2 = Conn[xIdx][zAxes];
371         }
372       else
373         {
374         zIdx = yIdx;
375         zIdx2 = Conn[yIdx][zAxes];
376         }
377       }//else boundary edges fly mode
378     this->InertiaAxes[0] = idx;
379     this->InertiaAxes[1] = xIdx;
380     this->InertiaAxes[2] = yIdx;
381     this->InertiaAxes[3] = zIdx;
382     this->InertiaAxes[4] = zIdx2;
383     this->InertiaAxes[5] = xAxes;
384     this->InertiaAxes[6] = yAxes;
385     this->InertiaAxes[7] = zAxes;
386     } //inertia
387   else
388     {
389     idx = this->InertiaAxes[0];
390     xIdx = this->InertiaAxes[1];
391     yIdx = this->InertiaAxes[2];
392     zIdx = this->InertiaAxes[3];
393     zIdx2 = this->InertiaAxes[4];
394     xAxes = this->InertiaAxes[5];
395     yAxes = this->InertiaAxes[6];
396     zAxes = this->InertiaAxes[7];
397     }
398
399   // Setup the axes for plotting
400   float xCoords[4], yCoords[4], zCoords[4], xRange[2], yRange[2], zRange[2];
401   this->AdjustAxes(pts, bounds, idx, xIdx, yIdx, zIdx, zIdx2, 
402                    xAxes, yAxes, zAxes, 
403                    xCoords, yCoords, zCoords, xRange, yRange, zRange);
404
405   // Upate axes
406   this->Labels[0] = this->XLabel;
407   this->Labels[1] = this->YLabel;
408   this->Labels[2] = this->ZLabel;
409
410   // correct XAxis, YAxis, ZAxis, which must be 
411   // parallel OX, OY, OZ system coordinates
412   // if xAxes=0 yAxes=1 zAxes=2 - good situation
413   if (!(xAxes == 0 && yAxes == 1 && zAxes == 2))
414     ChangeArrays(xCoords,yCoords,zCoords,
415                  xRange,yRange,zRange,
416                  xAxes,yAxes,zAxes);
417
418   double aTScale[3];
419   if(m_Transform.GetPointer() != NULL)
420     m_Transform->GetMatrixScale(aTScale);
421
422   this->XAxis->GetPositionCoordinate()->SetValue(xCoords[0], xCoords[1]);
423   this->XAxis->GetPosition2Coordinate()->SetValue(xCoords[2], xCoords[3]);
424   if(m_Transform.GetPointer() != NULL) this->XAxis->SetRange(xRange[0]/aTScale[0], xRange[1]/aTScale[0]);
425   else this->XAxis->SetRange(xRange[0], xRange[1]);
426
427   this->YAxis->GetPositionCoordinate()->SetValue(yCoords[2], yCoords[3]);
428   this->YAxis->GetPosition2Coordinate()->SetValue(yCoords[0], yCoords[1]);
429   if(m_Transform.GetPointer() != NULL) this->YAxis->SetRange(yRange[1]/aTScale[1], yRange[0]/aTScale[1]);
430   else this->YAxis->SetRange(yRange[1], yRange[0]);
431
432   this->ZAxis->GetPositionCoordinate()->SetValue(zCoords[0], zCoords[1]);
433   this->ZAxis->GetPosition2Coordinate()->SetValue(zCoords[2], zCoords[3]);
434   if(m_Transform.GetPointer() != NULL) this->ZAxis->SetRange(zRange[0]/aTScale[2], zRange[1]/aTScale[2]);
435   else this->ZAxis->SetRange(zRange[0], zRange[1]);
436
437   int numOfLabelsX = this->XAxis->GetNumberOfLabels();
438   int numOfLabelsY = this->YAxis->GetNumberOfLabels();
439   int numOfLabelsZ = this->ZAxis->GetNumberOfLabels();
440
441   // XCoords coordinates for X grid
442   vtkFloatArray *XCoords = vtkFloatArray::New();
443   for(int i=0;i<numOfLabelsX;i++){
444     float val = bounds[0]+i*(bounds[1]-bounds[0])/(numOfLabelsX-1);
445     XCoords->InsertNextValue(val);
446   }
447   // YCoords coordinates for Y grid
448   vtkFloatArray *YCoords = vtkFloatArray::New();
449   for(int i=0;i<numOfLabelsX;i++){
450     float val = bounds[2]+i*(bounds[3]-bounds[2])/(numOfLabelsY-1);
451     YCoords->InsertNextValue(val);
452   }
453   // ZCoords coordinates for Z grid
454   vtkFloatArray *ZCoords = vtkFloatArray::New();
455   for(int i=0;i<numOfLabelsZ;i++){
456     float val = bounds[4]+i*(bounds[5]-bounds[4])/(numOfLabelsZ-1);
457     ZCoords->InsertNextValue(val);
458   }
459
460   vtkRectilinearGrid *rgrid = vtkRectilinearGrid::New();
461   rgrid->SetDimensions(numOfLabelsX,numOfLabelsY,numOfLabelsZ);
462   rgrid->SetXCoordinates(XCoords);
463   rgrid->SetYCoordinates(YCoords);
464   rgrid->SetZCoordinates(ZCoords);
465
466   this->planeXY->SetInput(rgrid);
467   this->planeYZ->SetInput(rgrid);
468   this->planeXZ->SetInput(rgrid);
469
470   rgrid->Delete();
471
472   float aCPosition[3];
473   float aCDirection[3];
474   this->Camera->GetPosition(aCPosition);
475   this->Camera->GetDirectionOfProjection(aCDirection);
476
477   // culculate placement of XY
478   bool replaceXY=false;
479   bool replaceYZ=false;
480   bool replaceXZ=false;
481   float p[6][3]; // centers of planes
482   float vecs[6][3]; // 6 vectors from camera position to centers
483
484   float aMiddleX = (XCoords->GetValue(0) + XCoords->GetValue(numOfLabelsX-1))/2;
485   float aMiddleY = (YCoords->GetValue(0) + YCoords->GetValue(numOfLabelsY-1))/2;
486   float aMiddleZ = (ZCoords->GetValue(0) + ZCoords->GetValue(numOfLabelsZ-1))/2;
487
488   // plane XY
489   p[0][0] = aMiddleX; // plane X=0.5 Y=0.5 Z=0
490   p[0][1] = aMiddleY;
491   p[0][2] = ZCoords->GetValue(0);
492
493   p[1][0] = aMiddleX; // plane X=0.5 Y=0.5 Z=1
494   p[1][1] = aMiddleY;
495   p[1][2] = ZCoords->GetValue(numOfLabelsZ-1);
496
497   // plane YZ
498   p[2][0] = XCoords->GetValue(0); // plane X=0 Y=0.5 Z=0.5
499   p[2][1] = aMiddleY;
500   p[2][2] = aMiddleZ;
501
502   p[3][0] = XCoords->GetValue(numOfLabelsX-1);
503   p[3][1] = aMiddleY;
504   p[3][2] = aMiddleZ;
505
506   // plane XZ
507   p[4][0] = aMiddleX; // plane X=0.5 Y=0 Z=0.5
508   p[4][1] = YCoords->GetValue(0);
509   p[4][2] = aMiddleZ;
510
511   p[5][0] = aMiddleX; // plane X=0.5 Y=1 Z=0.5
512   p[5][1] = YCoords->GetValue(numOfLabelsY-1);
513   p[5][2] = aMiddleZ;
514
515   for(int i=0;i<3;i++) 
516     for(int j=0;j<6;j++) vecs[j][i] = p[j][i] - aCPosition[i];
517
518   if ( vtkMath::Dot(vecs[0],aCDirection) < vtkMath::Dot(vecs[1],aCDirection))
519     replaceXY = true;
520   if ( vtkMath::Dot(vecs[2],aCDirection) < vtkMath::Dot(vecs[3],aCDirection))
521     replaceYZ = true;
522   if ( vtkMath::Dot(vecs[4],aCDirection) < vtkMath::Dot(vecs[5],aCDirection))
523     replaceXZ = true;
524
525   if(replaceXY) this->planeXY->SetExtent(0,numOfLabelsX, 0,numOfLabelsY, numOfLabelsZ,numOfLabelsZ);
526   else this->planeXY->SetExtent(0,numOfLabelsX, 0,numOfLabelsY, 0,0);
527
528   if(replaceYZ) this->planeYZ->SetExtent(numOfLabelsX,numOfLabelsX, 0,numOfLabelsY, 0,numOfLabelsZ);
529   else this->planeYZ->SetExtent(0,0, 0,numOfLabelsY, 0,numOfLabelsZ);
530
531   if(replaceXZ) this->planeXZ->SetExtent(0,numOfLabelsX, numOfLabelsY,numOfLabelsY, 0,numOfLabelsZ);
532   else this->planeXZ->SetExtent(0,numOfLabelsX, 0,0, 0,numOfLabelsZ);
533
534   XCoords->Delete();
535   YCoords->Delete();
536   ZCoords->Delete();
537
538   float color[3];
539
540   this->GetProperty()->GetColor(color);
541   this->wireActorXY->GetProperty()->SetColor(color);
542   this->wireActorYZ->GetProperty()->SetColor(color);
543   this->wireActorXZ->GetProperty()->SetColor(color);
544
545   /*
546   // Rebuid text props
547   // Perform shallow copy here since each individual axis can be
548   // accessed through the class API (i.e. each individual axis text prop
549   // can be changed). Therefore, we can not just assign pointers otherwise
550   // each individual axis text prop would point to the same text prop.
551
552   if (this->AxisLabelTextProperty &&
553       this->AxisLabelTextProperty->GetMTime() > this->BuildTime)
554     {
555     if (this->XAxis->GetLabelTextProperty())
556       {
557       this->XAxis->GetLabelTextProperty()->ShallowCopy(
558         this->AxisLabelTextProperty);
559       }
560     if (this->YAxis->GetLabelTextProperty())
561       {
562       this->YAxis->GetLabelTextProperty()->ShallowCopy(
563         this->AxisLabelTextProperty);
564       }
565     if (this->ZAxis->GetLabelTextProperty())
566       {
567       this->ZAxis->GetLabelTextProperty()->ShallowCopy(
568         this->AxisLabelTextProperty);
569       }
570     }
571
572   if (this->AxisTitleTextProperty &&
573       this->AxisTitleTextProperty->GetMTime() > this->BuildTime)
574     {
575     if (this->XAxis->GetLabelTextProperty())
576       {
577       this->XAxis->GetTitleTextProperty()->ShallowCopy(
578         this->AxisTitleTextProperty);
579       }
580     if (this->YAxis->GetLabelTextProperty())
581       {
582       this->YAxis->GetTitleTextProperty()->ShallowCopy(
583         this->AxisTitleTextProperty);
584       }
585     if (this->ZAxis->GetLabelTextProperty())
586       {
587       this->ZAxis->GetTitleTextProperty()->ShallowCopy(
588         this->AxisTitleTextProperty);
589       }
590     }
591   */  
592   this->BuildTime.Modified();
593
594   //Render the axes
595   if ( this->XAxisVisibility )
596   {
597     renderedSomething += this->XAxis->RenderOpaqueGeometry(viewport);
598   }
599   if ( this->YAxisVisibility )
600   {
601     renderedSomething += this->YAxis->RenderOpaqueGeometry(viewport);
602   }
603   if ( this->ZAxisVisibility )
604   {
605     renderedSomething += this->ZAxis->RenderOpaqueGeometry(viewport);
606   }
607
608   bool RX=false,RY=false;
609   if (this->XAxisVisibility){
610     this->wireActorXY->RenderOpaqueGeometry(viewport);
611     this->wireActorXZ->RenderOpaqueGeometry(viewport);
612     RX = true;
613   }
614   if (this->YAxisVisibility){
615     if(!RX) this->wireActorXY->RenderOpaqueGeometry(viewport);
616     this->wireActorYZ->RenderOpaqueGeometry(viewport);
617     RY = true;
618   }
619   if (this->ZAxisVisibility){
620     if(!RX) this->wireActorXZ->RenderOpaqueGeometry(viewport);
621     if(!RY) this->wireActorYZ->RenderOpaqueGeometry(viewport);
622   }
623
624   return renderedSomething;
625 }
626
627 //----------------------------------------------------------------------------
628 // Release any graphics resources that are being consumed by this actor.
629 // The parameter window could be used to determine which graphic
630 // resources to release.
631 void SVTK_CubeAxesActor2D::ReleaseGraphicsResources(vtkWindow *win)
632 {
633   this->XAxis->ReleaseGraphicsResources(win);
634   this->YAxis->ReleaseGraphicsResources(win);
635   this->ZAxis->ReleaseGraphicsResources(win);
636
637   this->wireActorXY->ReleaseGraphicsResources(win);
638   this->wireActorYZ->ReleaseGraphicsResources(win);
639   this->wireActorXZ->ReleaseGraphicsResources(win);
640 }
641
642 void SVTK_CubeAxesActor2D::SetTransform(VTKViewer_Transform* theTransform){
643   this->m_Transform = theTransform;
644 }
645
646 VTKViewer_Transform* SVTK_CubeAxesActor2D::GetTransform(){
647   return (this->m_Transform.GetPointer());
648 }