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