source: trunk/packages/vizservers/vtkvis/vtkRpCubeAxesActor2D.cpp @ 2507

Last change on this file since 2507 was 2492, checked in by ldelgass, 13 years ago

Add constant color, colormode options for pseudocolor: color by scalar, vector
magnitude, vector component, or constant. Add 'normscale' command to glyphs to
toggle clamping/normalizing data values to [0,1] range before applying scale
factor.

  • Property svn:eol-style set to native
File size: 33.1 KB
Line 
1/*=========================================================================
2
3  Program:   Visualization Toolkit
4  Module:    vtkCubeAxesActor2D.cpp
5
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10     This software is distributed WITHOUT ANY WARRANTY; without even
11     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12     PURPOSE.  See the above copyright notice for more information.
13
14=========================================================================*/
15#include "vtkRpCubeAxesActor2D.h"
16
17#include "vtkAxisActor2D.h"
18#include "vtkCamera.h"
19#include "vtkDataSet.h"
20#include "vtkMath.h"
21#include "vtkObjectFactory.h"
22#include "vtkTextProperty.h"
23#include "vtkViewport.h"
24
25vtkStandardNewMacro(vtkRpCubeAxesActor2D);
26
27vtkCxxSetObjectMacro(vtkRpCubeAxesActor2D,Input, vtkDataSet);
28vtkCxxSetObjectMacro(vtkRpCubeAxesActor2D,Camera,vtkCamera);
29vtkCxxSetObjectMacro(vtkRpCubeAxesActor2D,ViewProp,vtkProp);
30vtkCxxSetObjectMacro(vtkRpCubeAxesActor2D,AxisLabelTextProperty,vtkTextProperty);
31vtkCxxSetObjectMacro(vtkRpCubeAxesActor2D,AxisTitleTextProperty,vtkTextProperty);
32
33//----------------------------------------------------------------------------
34// Instantiate this object.
35vtkRpCubeAxesActor2D::vtkRpCubeAxesActor2D()
36{
37  this->Input = NULL;
38  this->ViewProp = NULL;
39  this->Bounds[0] = -1.0; this->Bounds[1] = 1.0;
40  this->Bounds[2] = -1.0; this->Bounds[3] = 1.0;
41  this->Bounds[4] = -1.0; this->Bounds[5] = 1.0;
42
43  this->UseRanges = 0;
44  this->Ranges[0] = 0; this->Ranges[1] = 0;
45  this->Ranges[2] = 0; this->Ranges[3] = 0;
46  this->Ranges[4] = 0; this->Ranges[5] = 0;
47
48  this->Camera = NULL;
49  this->FlyMode = VTK_FLY_CLOSEST_TRIAD;
50  this->Scaling = 1;
51
52  this->XAxis = vtkAxisActor2D::New();
53  this->XAxis->GetPositionCoordinate()->SetCoordinateSystemToDisplay();
54  this->XAxis->GetPosition2Coordinate()->SetCoordinateSystemToDisplay();
55  this->XAxis->AdjustLabelsOff();
56
57  this->YAxis = vtkAxisActor2D::New();
58  this->YAxis->GetPositionCoordinate()->SetCoordinateSystemToDisplay();
59  this->YAxis->GetPosition2Coordinate()->SetCoordinateSystemToDisplay();
60  this->YAxis->AdjustLabelsOff();
61
62  this->ZAxis = vtkAxisActor2D::New();
63  this->ZAxis->GetPositionCoordinate()->SetCoordinateSystemToDisplay();
64  this->ZAxis->GetPosition2Coordinate()->SetCoordinateSystemToDisplay();
65  this->ZAxis->AdjustLabelsOff();
66
67  this->NumberOfLabels = 3;
68
69  this->AxisLabelTextProperty = vtkTextProperty::New();
70  this->AxisLabelTextProperty->SetBold(1);
71  this->AxisLabelTextProperty->SetItalic(1);
72  this->AxisLabelTextProperty->SetShadow(1);
73  this->AxisLabelTextProperty->SetFontFamilyToArial();
74
75  this->AxisTitleTextProperty = vtkTextProperty::New();
76  this->AxisTitleTextProperty->ShallowCopy(this->AxisLabelTextProperty);
77
78  this->LabelFormat = new char[8];
79  sprintf(this->LabelFormat,"%s","%-#6.3g");
80  this->FontFactor = 1.0;
81  this->CornerOffset = 0.05;
82  this->Inertia = 1;
83  this->ShowActualBounds = 1;
84  this->RenderCount = 0;
85
86  this->XAxisVisibility = 1;
87  this->YAxisVisibility = 1;
88  this->ZAxisVisibility = 1;
89
90  this->XLabel = new char[2];
91  sprintf(this->XLabel,"%s","X");
92  this->YLabel = new char[2];
93  sprintf(this->YLabel,"%s","Y");
94  this->ZLabel = new char[2];
95  sprintf(this->ZLabel,"%s","Z");
96
97  // Allow the user to specify an origin for the axes. The axes will then run
98  // from this origin to the bounds and will cross over at this origin. 
99  this->XOrigin = VTK_DOUBLE_MAX; 
100  this->YOrigin = VTK_DOUBLE_MAX; 
101  this->ZOrigin = VTK_DOUBLE_MAX; 
102}
103
104//----------------------------------------------------------------------------
105// Shallow copy of an actor.
106void vtkRpCubeAxesActor2D::ShallowCopy(vtkRpCubeAxesActor2D *actor)
107{
108  this->vtkActor2D::ShallowCopy(actor);
109  this->SetAxisLabelTextProperty(actor->GetAxisLabelTextProperty());
110  this->SetAxisTitleTextProperty(actor->GetAxisTitleTextProperty());
111  this->SetLabelFormat(actor->GetLabelFormat());
112  this->SetFontFactor(actor->GetFontFactor());
113  this->SetCornerOffset(actor->GetCornerOffset());
114  this->SetInertia(static_cast<int>(actor->GetInertia()));
115  this->SetXLabel(actor->GetXLabel());
116  this->SetYLabel(actor->GetYLabel());
117  this->SetZLabel(actor->GetZLabel());
118  this->SetFlyMode(actor->GetFlyMode());
119  this->SetInput(actor->GetInput());
120  this->SetViewProp(actor->GetViewProp());
121  this->SetCamera(actor->GetCamera());
122}
123
124//----------------------------------------------------------------------------
125vtkRpCubeAxesActor2D::~vtkRpCubeAxesActor2D()
126{
127  if ( this->Input )
128    {
129    this->Input->Delete();
130    }
131
132  if ( this->ViewProp )
133    {
134    this->ViewProp->Delete();
135    }
136
137  if ( this->Camera )
138    {
139    this->Camera->UnRegister(this);
140    }
141
142  this->XAxis->Delete();
143  this->YAxis->Delete();
144  this->ZAxis->Delete();
145 
146  if (this->LabelFormat)
147    {
148    delete [] this->LabelFormat;
149    this->LabelFormat = NULL;
150    }
151 
152  if ( this->XLabel )
153    {
154    delete [] this->XLabel;
155    }
156  if ( this->YLabel )
157    {
158    delete [] this->YLabel;
159    }
160  if ( this->ZLabel )
161    {
162    delete [] this->ZLabel;
163    }
164
165  this->SetAxisLabelTextProperty(NULL);
166  this->SetAxisTitleTextProperty(NULL);
167}
168
169//----------------------------------------------------------------------------
170// Static variable describes connections in cube.
171static int Conn[8][3] = {{1,2,4}, {0,3,5}, {3,0,6}, {2,1,7},
172                         {5,6,0}, {4,7,1}, {7,4,2}, {6,5,3}};
173
174//----------------------------------------------------------------------------
175// Project the bounding box and compute edges on the border of the bounding
176// cube. Determine which parts of the edges are visible via intersection
177// with the boundary of the viewport (minus borders).
178int vtkRpCubeAxesActor2D::RenderOverlay(vtkViewport *viewport)
179{
180  int renderedSomething=0;
181
182  // Initialization
183  if ( ! this->RenderSomething )
184    {
185    return 0;
186    }
187 
188  //Render the axes
189  if ( this->XAxisVisibility )
190    {
191    renderedSomething += this->XAxis->RenderOverlay(viewport);
192    }
193  if ( this->YAxisVisibility )
194    {
195    renderedSomething += this->YAxis->RenderOverlay(viewport);
196    }
197  if ( this->ZAxisVisibility )
198    {
199    renderedSomething += this->ZAxis->RenderOverlay(viewport);
200    }
201
202  return renderedSomething;
203}
204
205//----------------------------------------------------------------------------
206// Project the bounding box and compute edges on the border of the bounding
207// cube. Determine which parts of the edges are visible via intersection
208// with the boundary of the viewport (minus borders).
209int vtkRpCubeAxesActor2D::RenderOpaqueGeometry(vtkViewport *viewport)
210{
211  double bounds[6];
212  double slope = 0.0, minSlope, num, den;
213  double pts[8][3], d2, d2Min, min;
214  int i, idx = 0;
215  int xIdx = 0, yIdx = 0, zIdx = 0, zIdx2 = 0, renderedSomething=0;
216  int xAxes = 0, yAxes = 0, zAxes = 0;
217
218  // Initialization
219  if ( !this->Camera )
220    {
221    vtkErrorMacro(<<"No camera!");
222    this->RenderSomething = 0;
223    return 0;
224    }
225 
226  this->RenderSomething = 1;
227
228  // determine the bounds to use
229  this->GetBounds(bounds);
230
231  // Check for user specified origins. By default, these are placed at a corner of the
232  // bounding box of the dataset (corner is based on the fly mode)
233  if (this->XOrigin != VTK_DOUBLE_MAX)
234    {
235    bounds[0] = this->XOrigin;
236    }
237  if (this->YOrigin != VTK_DOUBLE_MAX)
238    {
239    bounds[2] = this->YOrigin;
240    }
241  if (this->ZOrigin != VTK_DOUBLE_MAX)
242    {
243    bounds[4] = this->ZOrigin;
244    }
245
246  // Build the axes (almost always needed so we don't check mtime)
247  // Transform all points into display coordinates
248  this->TransformBounds(viewport, bounds, pts);
249
250  // Find the portion of the bounding box that fits within the viewport,
251  if ( !this->ShowActualBounds && (this->ClipBounds(viewport, pts, bounds) == 0) )
252    {
253    this->RenderSomething = 0;
254    return 0;
255    }
256
257  // Take into account the inertia. Process only so often.
258  if ( this->RenderCount++ == 0 || !(this->RenderCount % this->Inertia) )
259    {
260    // Okay, we have a bounding box, maybe clipped and scaled, that is visible.
261    // We setup the axes depending on the fly mode.
262    if (this->FlyMode == VTK_FLY_NONE)
263      {
264      idx = 2; // Just use the default axis orientation.
265      xAxes = 0;
266      xIdx = Conn[idx][0];
267      yAxes = 1;
268      yIdx = Conn[idx][1];
269      zAxes = 2;
270      zIdx = idx;
271      zIdx2 = Conn[idx][2];
272      }
273    else if ( this->FlyMode == VTK_FLY_CLOSEST_TRIAD )
274      {
275      // Loop over points and find the closest point to the camera
276      min = VTK_DOUBLE_MAX;
277      for (i=0; i < 8; i++)
278        {
279        if ( pts[i][2] < min )
280          {
281          idx = i;
282          min = pts[i][2];
283          }
284        }
285
286      // Setup the three axes to be drawn
287      xAxes = 0;
288      xIdx = Conn[idx][0];
289      yAxes = 1;
290      yIdx = Conn[idx][1];
291      zAxes = 2;
292      zIdx = idx;
293      zIdx2 = Conn[idx][2];
294      }
295    else if (this->FlyMode == VTK_FLY_OUTER_EDGES)
296      {
297      double e1[2], e2[2], e3[2];
298
299      // Find distance to origin
300      d2Min = VTK_DOUBLE_MAX;
301      for (i=0; i < 8; i++)
302        {
303        d2 = pts[i][0]*pts[i][0] + pts[i][1]*pts[i][1];
304        if ( d2 < d2Min )
305          {
306          d2Min = d2;
307          idx = i;
308          }
309        }
310
311      // find minimum slope point connected to closest point and on
312      // right side (in projected coordinates). This is the first edge.
313      minSlope = VTK_DOUBLE_MAX;
314      for (xIdx=0, i=0; i<3; i++)
315        {
316        num = (pts[Conn[idx][i]][1] - pts[idx][1]);
317        den = (pts[Conn[idx][i]][0] - pts[idx][0]);
318        if ( den != 0.0 )
319          {
320          slope = num / den;
321          }
322        if ( slope < minSlope && den > 0 )
323          {
324          xIdx = Conn[idx][i];
325          yIdx = Conn[idx][(i+1)%3];
326          zIdx = Conn[idx][(i+2)%3];
327          xAxes = i;
328          minSlope = slope;
329          }
330        }
331
332      // find edge (connected to closest point) on opposite side
333      for ( i=0; i<2; i++)
334        {
335        e1[i] = (pts[xIdx][i] - pts[idx][i]);
336        e2[i] = (pts[yIdx][i] - pts[idx][i]);
337        e3[i] = (pts[zIdx][i] - pts[idx][i]);
338        }
339      vtkMath::Normalize2D(e1);
340      vtkMath::Normalize2D(e2);
341      vtkMath::Normalize2D(e3);
342
343      if ( vtkMath::Dot2D(e1,e2) < vtkMath::Dot2D(e1,e3) )
344        {
345        yAxes = (xAxes + 1) % 3;
346        }
347      else
348        {
349        yIdx = zIdx;
350        yAxes = (xAxes + 2) % 3;
351        }
352
353      // Find the final point by determining which global x-y-z axes have not
354      // been represented, and then determine the point closest to the viewer.
355      zAxes = (xAxes != 0 && yAxes != 0 ? 0 :
356              (xAxes != 1 && yAxes != 1 ? 1 : 2));
357      if ( pts[Conn[xIdx][zAxes]][2] < pts[Conn[yIdx][zAxes]][2] )
358        {
359        zIdx = xIdx;
360        zIdx2 = Conn[xIdx][zAxes];
361        }
362      else
363        {
364        zIdx = yIdx;
365        zIdx2 = Conn[yIdx][zAxes];
366        }
367      }//else boundary edges fly mode
368    this->InertiaAxes[0] = idx;
369    this->InertiaAxes[1] = xIdx;
370    this->InertiaAxes[2] = yIdx;
371    this->InertiaAxes[3] = zIdx;
372    this->InertiaAxes[4] = zIdx2;
373    this->InertiaAxes[5] = xAxes;
374    this->InertiaAxes[6] = yAxes;
375    this->InertiaAxes[7] = zAxes;
376    } //inertia
377  else
378    {
379    idx = this->InertiaAxes[0];
380    xIdx = this->InertiaAxes[1];
381    yIdx = this->InertiaAxes[2];
382    zIdx = this->InertiaAxes[3];
383    zIdx2 = this->InertiaAxes[4];
384    xAxes = this->InertiaAxes[5];
385    yAxes = this->InertiaAxes[6];
386    zAxes = this->InertiaAxes[7];
387    }
388 
389  // Setup the axes for plotting
390  double xCoords[4], yCoords[4], zCoords[4], xRange[2], yRange[2], zRange[2];
391  this->AdjustAxes(pts, bounds, idx, xIdx, yIdx, zIdx, zIdx2,
392                   xAxes, yAxes, zAxes,
393                   xCoords, yCoords, zCoords, xRange, yRange, zRange);
394                   
395  // Sorry for ugly hack. I find the fonts slightly too large on the axis. BNW
396  double AxisFontFactor = this->FontFactor*.75;
397 
398
399  // Upate axes
400  this->Labels[0] = this->XLabel;
401  this->Labels[1] = this->YLabel;
402  this->Labels[2] = this->ZLabel;
403
404  this->XAxis->GetPositionCoordinate()->SetValue(xCoords[0], xCoords[1]);
405  this->XAxis->GetPosition2Coordinate()->SetValue(xCoords[2], xCoords[3]);
406  this->XAxis->SetRange(xRange[0], xRange[1]);
407  this->XAxis->SetTitle(this->Labels[xAxes]);
408  this->XAxis->SetNumberOfLabels(this->NumberOfLabels);
409  this->XAxis->SetLabelFormat(this->LabelFormat);
410  this->XAxis->SetFontFactor(AxisFontFactor);
411  this->XAxis->SetProperty(this->GetProperty());
412
413  this->YAxis->GetPositionCoordinate()->SetValue(yCoords[2], yCoords[3]);
414  this->YAxis->GetPosition2Coordinate()->SetValue(yCoords[0], yCoords[1]);
415  this->YAxis->SetRange(yRange[1], yRange[0]);
416  this->YAxis->SetTitle(this->Labels[yAxes]);
417  this->YAxis->SetNumberOfLabels(this->NumberOfLabels);
418  this->YAxis->SetLabelFormat(this->LabelFormat);
419  this->YAxis->SetFontFactor(AxisFontFactor);
420  this->YAxis->SetProperty(this->GetProperty());
421  if ( this->YAxisVisibility ) {
422      this->ZAxis->GetPositionCoordinate()->SetValue(zCoords[0], zCoords[1]);
423      this->ZAxis->GetPosition2Coordinate()->SetValue(zCoords[2], zCoords[3]);
424      this->ZAxis->SetRange(zRange[0], zRange[1]);
425  } else {
426      this->ZAxis->GetPositionCoordinate()->SetValue(zCoords[2], zCoords[3]);
427      this->ZAxis->GetPosition2Coordinate()->SetValue(zCoords[0], zCoords[1]);
428      this->ZAxis->SetRange(zRange[1], zRange[0]);
429  }
430  this->ZAxis->SetTitle(this->Labels[zAxes]);
431  this->ZAxis->SetNumberOfLabels(this->NumberOfLabels);
432  this->ZAxis->SetLabelFormat(this->LabelFormat);
433  this->ZAxis->SetFontFactor(AxisFontFactor);
434  this->ZAxis->SetProperty(this->GetProperty());
435
436  // Rebuid text props
437  // Perform shallow copy here since each individual axis can be
438  // accessed through the class API (i.e. each individual axis text prop
439  // can be changed). Therefore, we can not just assign pointers otherwise
440  // each individual axis text prop would point to the same text prop.
441#ifdef notdef
442  if (this->AxisLabelTextProperty &&
443      this->AxisLabelTextProperty->GetMTime() > this->BuildTime)
444    {
445    if (this->XAxis->GetLabelTextProperty())
446      {
447      this->XAxis->GetLabelTextProperty()->ShallowCopy(
448        this->AxisLabelTextProperty);
449      }
450    if (this->YAxis->GetLabelTextProperty())
451      {
452      this->YAxis->GetLabelTextProperty()->ShallowCopy(
453        this->AxisLabelTextProperty);
454      }
455    if (this->ZAxis->GetLabelTextProperty())
456      {
457      this->ZAxis->GetLabelTextProperty()->ShallowCopy(
458        this->AxisLabelTextProperty);
459      }
460    }
461
462  if (this->AxisTitleTextProperty &&
463      this->AxisTitleTextProperty->GetMTime() > this->BuildTime)
464    {
465    if (this->XAxis->GetLabelTextProperty())
466      {
467      this->XAxis->GetTitleTextProperty()->ShallowCopy(
468        this->AxisTitleTextProperty);
469      }
470    if (this->YAxis->GetLabelTextProperty())
471      {
472      this->YAxis->GetTitleTextProperty()->ShallowCopy(
473        this->AxisTitleTextProperty);
474      }
475    if (this->ZAxis->GetLabelTextProperty())
476      {
477      this->ZAxis->GetTitleTextProperty()->ShallowCopy(
478        this->AxisTitleTextProperty);
479      }
480    }
481#endif
482  this->BuildTime.Modified();
483
484  //Render the axes
485  if ( this->XAxisVisibility )
486    {
487    renderedSomething += this->XAxis->RenderOpaqueGeometry(viewport);
488    }
489  if ( this->YAxisVisibility )
490    {
491    renderedSomething += this->YAxis->RenderOpaqueGeometry(viewport);
492    }
493  if ( this->ZAxisVisibility )
494    {
495    renderedSomething += this->ZAxis->RenderOpaqueGeometry(viewport);
496    }
497
498  return renderedSomething;
499}
500
501//-----------------------------------------------------------------------------
502// Description:
503// Does this prop have some translucent polygonal geometry?
504int vtkRpCubeAxesActor2D::HasTranslucentPolygonalGeometry()
505{
506  return 0;
507}
508
509//----------------------------------------------------------------------------
510// Do final adjustment of axes to control offset, etc.
511void vtkRpCubeAxesActor2D::AdjustAxes(double pts[8][3], double bounds[6],
512                                      int idx, int xIdx, int yIdx, int zIdx, int zIdx2,
513                                      int xAxes, int yAxes, int zAxes,
514                                      double xCoords[4], double yCoords[4], double zCoords[4],
515                                      double xRange[2], double yRange[2], double zRange[2])
516{
517  double *internal_bounds;
518  if ( this->UseRanges )
519  {
520    internal_bounds = this->Ranges;
521  }
522  else
523  {
524    internal_bounds = bounds;
525  }
526 
527  // The x-axis
528  xCoords[0] = pts[idx][0];
529  xCoords[1] = pts[idx][1];
530  xCoords[2] = pts[xIdx][0];
531  xCoords[3] = pts[xIdx][1];
532  if ( idx < xIdx )
533    {
534      xRange[0] = internal_bounds[2*xAxes];
535      xRange[1] = internal_bounds[2*xAxes+1];
536    }
537  else
538    {
539      xRange[0] = internal_bounds[2*xAxes+1];
540      xRange[1] = internal_bounds[2*xAxes];
541    }
542 
543  // The y-axis
544  yCoords[0] = pts[idx][0];
545  yCoords[1] = pts[idx][1];
546  yCoords[2] = pts[yIdx][0];
547  yCoords[3] = pts[yIdx][1];
548  if ( idx < yIdx )
549    {
550      yRange[0] = internal_bounds[2*yAxes];
551      yRange[1] = internal_bounds[2*yAxes+1];
552    }
553  else
554    {
555      yRange[0] = internal_bounds[2*yAxes+1];
556      yRange[1] = internal_bounds[2*yAxes];
557    }
558
559  // The z-axis
560  if ( zIdx != xIdx && zIdx != idx ) //rearrange for labels
561    {
562    zIdx = zIdx2;
563    zIdx2 = yIdx;
564    }
565 
566  zCoords[0] = pts[zIdx][0];
567  zCoords[1] = pts[zIdx][1];
568  zCoords[2] = pts[zIdx2][0];
569  zCoords[3] = pts[zIdx2][1];
570  if ( zIdx < zIdx2 )
571    {
572      zRange[0] = internal_bounds[2*zAxes];
573      zRange[1] = internal_bounds[2*zAxes+1];
574    }
575  else
576    {
577      zRange[0] = internal_bounds[2*zAxes+1];
578      zRange[1] = internal_bounds[2*zAxes];
579    }
580 
581  // Pull back the corners if specified
582  if ( this->CornerOffset > 0.0 )
583    {
584    double ave;
585
586    // x-axis
587    ave = (xCoords[0] + xCoords[2]) / 2.0;
588    xCoords[0] = xCoords[0] - this->CornerOffset * (xCoords[0] - ave);
589    xCoords[2] = xCoords[2] - this->CornerOffset * (xCoords[2] - ave);
590   
591    ave = (xCoords[1] + xCoords[3]) / 2.0;
592    xCoords[1] = xCoords[1] - this->CornerOffset * (xCoords[1] - ave);
593    xCoords[3] = xCoords[3] - this->CornerOffset * (xCoords[3] - ave);
594
595    ave = (xRange[1] + xRange[0]) / 2.0;
596    if (!this->ShowActualBounds)
597      {
598      xRange[0] = xRange[0] - this->CornerOffset * (xRange[0] - ave);
599      xRange[1] = xRange[1] - this->CornerOffset * (xRange[1] - ave);
600      }
601   
602    // y-axis
603    ave = (yCoords[0] + yCoords[2]) / 2.0;
604    yCoords[0] = yCoords[0] - this->CornerOffset * (yCoords[0] - ave);
605    yCoords[2] = yCoords[2] - this->CornerOffset * (yCoords[2] - ave);
606   
607    ave = (yCoords[1] + yCoords[3]) / 2.0;
608    yCoords[1] = yCoords[1] - this->CornerOffset * (yCoords[1] - ave);
609    yCoords[3] = yCoords[3] - this->CornerOffset * (yCoords[3] - ave);
610
611    ave = (yRange[1] + yRange[0]) / 2.0;
612    if (!this->ShowActualBounds)
613      {
614      yRange[0] = yRange[0] - this->CornerOffset * (yRange[0] - ave);
615      yRange[1] = yRange[1] - this->CornerOffset * (yRange[1] - ave);
616      }
617   
618    // z-axis
619    ave = (zCoords[0] + zCoords[2]) / 2.0;
620    zCoords[0] = zCoords[0] - this->CornerOffset * (zCoords[0] - ave);
621    zCoords[2] = zCoords[2] - this->CornerOffset * (zCoords[2] - ave);
622   
623    ave = (zCoords[1] + zCoords[3]) / 2.0;
624    zCoords[1] = zCoords[1] - this->CornerOffset * (zCoords[1] - ave);
625    zCoords[3] = zCoords[3] - this->CornerOffset * (zCoords[3] - ave);
626
627    ave = (zRange[1] + zRange[0]) / 2.0;
628    if (!this->ShowActualBounds)
629      {
630      zRange[0] = zRange[0] - this->CornerOffset * (zRange[0] - ave);
631      zRange[1] = zRange[1] - this->CornerOffset * (zRange[1] - ave);
632      }
633    }
634}
635
636//----------------------------------------------------------------------------
637// Release any graphics resources that are being consumed by this actor.
638// The parameter window could be used to determine which graphic
639// resources to release.
640void vtkRpCubeAxesActor2D::ReleaseGraphicsResources(vtkWindow *win)
641{
642  this->XAxis->ReleaseGraphicsResources(win);
643  this->YAxis->ReleaseGraphicsResources(win);
644  this->ZAxis->ReleaseGraphicsResources(win);
645}
646
647//----------------------------------------------------------------------------
648// Return the ranges
649void vtkRpCubeAxesActor2D::GetRanges(double ranges[6])
650{
651  int i;
652  for ( i=0; i<6; i++ )
653    {
654    ranges[i] = this->Ranges[i];
655    }
656}
657
658//----------------------------------------------------------------------------
659// Compute the ranges
660void vtkRpCubeAxesActor2D::GetRanges(double& xmin, double& xmax,
661                                     double& ymin, double& ymax,
662                                     double& zmin, double& zmax)
663{
664  double ranges[6];
665  this->GetRanges(ranges);
666  xmin = ranges[0];
667  xmax = ranges[1];
668  ymin = ranges[2];
669  ymax = ranges[3];
670  zmin = ranges[4];
671  zmax = ranges[5];
672}
673
674//----------------------------------------------------------------------------
675// Compute the bounds
676double *vtkRpCubeAxesActor2D::GetRanges()
677{
678  double ranges[6];
679  this->GetRanges(ranges);
680  return this->Ranges;
681}
682
683//----------------------------------------------------------------------------
684// Compute the bounds
685void vtkRpCubeAxesActor2D::GetBounds(double bounds[6])
686{
687  double *propBounds;
688  int i;
689
690  if ( this->Input )
691    {
692    this->Input->Update();
693    this->Input->GetBounds(bounds);
694    for (i=0; i< 6; i++)
695      {
696      this->Bounds[i] = bounds[i];
697      }
698    }
699  else if ( this->ViewProp &&
700            ((propBounds = this->ViewProp->GetBounds()) && propBounds != NULL) )
701    {
702    for (i=0; i< 6; i++)
703      {
704      bounds[i] = this->Bounds[i] = propBounds[i];
705      }
706    }
707  else
708    {
709    for (i=0; i< 6; i++)
710      {
711      bounds[i] = this->Bounds[i];
712      }
713    }
714}
715
716//----------------------------------------------------------------------------
717// Compute the bounds
718void vtkRpCubeAxesActor2D::GetBounds(double& xmin, double& xmax,
719                                     double& ymin, double& ymax,
720                                     double& zmin, double& zmax)
721{
722  double bounds[6];
723  this->GetBounds(bounds);
724  xmin = bounds[0];
725  xmax = bounds[1];
726  ymin = bounds[2];
727  ymax = bounds[3];
728  zmin = bounds[4];
729  zmax = bounds[5];
730}
731
732//----------------------------------------------------------------------------
733// Compute the bounds
734double *vtkRpCubeAxesActor2D::GetBounds()
735{
736  this->GetBounds(this->Bounds);
737  return this->Bounds;
738}
739
740//----------------------------------------------------------------------------
741void vtkRpCubeAxesActor2D::PrintSelf(ostream& os, vtkIndent indent)
742{
743  this->Superclass::PrintSelf(os,indent);
744
745  if ( this->Input )
746    {
747    os << indent << "Input: (" << (void *)this->Input << ")\n";
748    }
749  else
750    {
751    os << indent << "Input: (none)\n";
752    }
753
754  if ( this->ViewProp )
755    {
756    os << indent << "ViewProp: (" << (void *)this->ViewProp << ")\n";
757    }
758  else
759    {
760    os << indent << "ViewProp: (none)\n";
761    }
762
763  os << indent << "Bounds: \n";
764  os << indent << "  Xmin,Xmax: (" << this->Bounds[0] << ", "
765     << this->Bounds[1] << ")\n";
766  os << indent << "  Ymin,Ymax: (" << this->Bounds[2] << ", "
767     << this->Bounds[3] << ")\n";
768  os << indent << "  Zmin,Zmax: (" << this->Bounds[4] << ", "
769     << this->Bounds[5] << ")\n";
770 
771  if ( this->Camera )
772    {
773    os << indent << "Camera:\n";
774    this->Camera->PrintSelf(os,indent.GetNextIndent());
775    }
776  else
777    {
778    os << indent << "Camera: (none)\n";
779    }
780
781  if (this->AxisTitleTextProperty)
782    {
783    os << indent << "Axis Title Text Property:\n";
784    this->AxisTitleTextProperty->PrintSelf(os,indent.GetNextIndent());
785    }
786  else
787    {
788    os << indent << "Axis Title Text Property: (none)\n";
789    }
790
791  if (this->AxisLabelTextProperty)
792    {
793    os << indent << "Axis Label Text Property:\n";
794    this->AxisLabelTextProperty->PrintSelf(os,indent.GetNextIndent());
795    }
796  else
797    {
798    os << indent << "Axis Label Text Property: (none)\n";
799    }
800
801  if ( this->FlyMode == VTK_FLY_CLOSEST_TRIAD )
802    {
803    os << indent << "Fly Mode: CLOSEST_TRIAD\n";
804    }
805  else if (this->FlyMode == VTK_FLY_OUTER_EDGES)
806    {
807    os << indent << "Fly Mode: OUTER_EDGES\n";
808    }
809  else if (this->FlyMode == VTK_FLY_NONE)
810    {
811    os << indent << "Fly Mode: Disabled\n";
812    }
813 
814  os << indent << "Scaling: " << (this->Scaling ? "On\n" : "Off\n");
815  os << indent << "UseRanges: " << (this->UseRanges ? "On\n" : "Off\n");
816  os << indent << "Ranges: \n";
817  os << indent << "  Xmin,Xmax: (" << this->Ranges[0] << ", "
818     << this->Ranges[1] << ")\n";
819  os << indent << "  Ymin,Ymax: (" << this->Ranges[2] << ", "
820     << this->Ranges[3] << ")\n";
821  os << indent << "  Zmin,Zmax: (" << this->Ranges[4] << ", "
822     << this->Ranges[5] << ")\n";
823
824  os << indent << "Number Of Labels: " << this->NumberOfLabels << "\n";
825  os << indent << "X Label: " << this->XLabel << "\n";
826  os << indent << "Y Label: " << this->YLabel << "\n";
827  os << indent << "Z Label: " << this->ZLabel << "\n";
828 
829  os << indent << "X Axis Visibility: " << (this->XAxisVisibility ? "On\n" : "Off\n");
830  os << indent << "Y Axis Visibility: " << (this->YAxisVisibility ? "On\n" : "Off\n");
831  os << indent << "Z Axis Visibility: " << (this->ZAxisVisibility ? "On\n" : "Off\n");
832
833  os << indent << "Label Format: " << this->LabelFormat << "\n";
834  os << indent << "Font Factor: " << this->FontFactor << "\n";
835  os << indent << "Inertia: " << this->Inertia << "\n";
836  os << indent << "Corner Offset: " << this->CornerOffset << "\n";
837  os << indent << "UseRanges: " << (this->UseRanges ? "On" : "Off") << "\n";
838  os << indent << "Ranges: "
839     << this->Ranges[0] << ", " << this->Ranges[1] << ", "
840     << this->Ranges[2] << ", " << this->Ranges[3] << ", "
841     << this->Ranges[4] << ", " << this->Ranges[5] << "\n";
842  os << indent << "Show Actual Bounds: " << (this->ShowActualBounds ? "On\n" : "Off\n");
843  if (this->XOrigin != VTK_DOUBLE_MAX)
844    {
845    os << indent << "User specified X Origin: " << this->XOrigin << endl;
846    }
847  if (this->YOrigin != VTK_DOUBLE_MAX)
848    {
849    os << indent << "User specified Y Origin: " << this->YOrigin << endl;
850    }
851  if (this->ZOrigin != VTK_DOUBLE_MAX)
852    {
853    os << indent << "User specified Z Origin: " << this->ZOrigin << endl;
854    }
855}
856
857//----------------------------------------------------------------------------
858static int IsInBounds(double x[3], double bounds[6]);
859
860// Clip the axes to fit into the viewport. Do this clipping each of the three
861// axes to determine which part of the cube is in view. Returns 0 if
862// nothing should be drawn.
863#define VTK_DIVS 10
864int vtkRpCubeAxesActor2D::ClipBounds(vtkViewport *viewport, double pts[8][3],
865                                     double bounds[6])
866{
867  int i, j, k, numIters;
868  double planes[24];
869  double x[3];
870  double val, maxVal=0, anchor[3], scale;
871  double delX, delY, delZ;
872  double bounds2[6];
873  double scale2, newScale, origin[3];
874  double aspect[2];
875
876  // Only do this mojo if scaling is required
877  if ( ! this->Scaling )
878    {
879    return 1;
880    }
881
882  // Get the 6 planes defining the view frustrum
883  viewport->GetAspect( aspect );
884  this->Camera->GetFrustumPlanes((aspect[0] / aspect[1]), planes);
885
886  // Hunt for the point in the bounds furthest inside the frustum
887  // Iteratively loop over points in bounding box and evaluate the
888  // maximum minimum distance. Find the point furthest inside of the
889  // bounding box. Use this as an anchor point to scale to. Repeat
890  // the process to hone in on the best point.
891  delX = (bounds[1]-bounds[0]) / (VTK_DIVS-1);
892  delY = (bounds[3]-bounds[2]) / (VTK_DIVS-1);
893  delZ = (bounds[5]-bounds[4]) / (VTK_DIVS-1);
894  anchor[0] = (bounds[1]+bounds[0])/2.0;
895  anchor[1] = (bounds[3]+bounds[2])/2.0;
896  anchor[2] = (bounds[5]+bounds[4])/2.0;
897
898  for ( numIters=0; numIters < 8; numIters++)
899    {
900    origin[0] = anchor[0] - delX*(VTK_DIVS-1)/2.0;
901    origin[1] = anchor[1] - delY*(VTK_DIVS-1)/2.0;
902    origin[2] = anchor[2] - delZ*(VTK_DIVS-1)/2.0;
903
904    for (maxVal=0.0, k=0; k<VTK_DIVS; k++)
905      {
906      x[2] = origin[2] + k * delZ;
907      for (j=0; j<VTK_DIVS; j++)
908        {
909        x[1] = origin[1] + j * delY;
910        for (i=0; i<VTK_DIVS; i++)
911          {
912          x[0] = origin[0] + i * delX;
913          if ( IsInBounds(x,bounds) )
914            {
915            val = this->EvaluatePoint(planes, x);
916            if ( val > maxVal )
917              {
918              anchor[0] = x[0];
919              anchor[1] = x[1];
920              anchor[2] = x[2];
921              maxVal = val;
922              }
923            }//if in bounding box
924          }//i
925        }//j
926      }//k
927
928    delX /= (VTK_DIVS-1) * 1.414;
929    delY /= (VTK_DIVS-1) * 1.414;
930    delZ /= (VTK_DIVS-1) * 1.414;
931    }//Iteratively find anchor point
932
933  if ( maxVal <= 0.0 )
934    {
935    return 0; //couldn't find a point inside
936    }
937
938  // Now  iteratively scale the bounding box until all points are inside
939  // the frustrum. Use bisection method.
940  scale = 1.0;
941  scale2 = 0.00001;
942  val = this->EvaluateBounds(planes, bounds);
943
944  // Get other end point for bisection technique
945  for (i=0; i<3; i++)
946    {
947    bounds2[2*i] = (bounds[2*i]-anchor[i])*scale2 + anchor[i];
948    bounds2[2*i+1] = (bounds[2*i+1]-anchor[i])*scale2 + anchor[i];
949    }
950  val = this->EvaluateBounds(planes, bounds2);
951  if ( val <= 0.0 )
952    {
953    return 0; //not worth drawing - too small
954    }
955 
956  for ( numIters=0; numIters < 10; numIters++)
957    {
958    newScale = (scale + scale2) / 2.0;
959    for (i=0; i<3; i++)
960      {
961      bounds2[2*i] = (bounds[2*i]-anchor[i])*newScale + anchor[i];
962      bounds2[2*i+1] = (bounds[2*i+1]-anchor[i])*newScale + anchor[i];
963      }
964    val = this->EvaluateBounds(planes, bounds2);
965
966    if ( val > 0.0 )
967      {
968      scale2 = newScale;
969      }
970    else
971      {
972      scale = newScale;
973      }
974    }//for converged
975
976  for (i=0; i<6; i++) //copy the result
977    {
978    bounds[i] = bounds2[i];
979    }
980
981  this->TransformBounds(viewport, bounds, pts);
982
983  return 1;
984}
985#undef VTK_DIVS
986
987//----------------------------------------------------------------------------
988void vtkRpCubeAxesActor2D::TransformBounds(vtkViewport *viewport,
989                                           double bounds[6], double pts[8][3])
990{
991  int i, j, k, idx;
992  double x[3];
993
994  //loop over verts of bounding box
995  for (k=0; k<2; k++)
996    {
997    x[2] = bounds[4+k];
998    for (j=0; j<2; j++)
999      {
1000      x[1] = bounds[2+j];
1001      for (i=0; i<2; i++)
1002        {
1003        idx = i + 2*j + 4*k;
1004        x[0] = bounds[i];
1005        viewport->SetWorldPoint(x[0],x[1],x[2],1.0);
1006        viewport->WorldToDisplay();
1007        viewport->GetDisplayPoint(pts[idx]);
1008        }
1009      }
1010    }
1011}
1012
1013//----------------------------------------------------------------------------
1014// Return smallest value of point evaluated against frustum planes. Also
1015// sets the closest point coordinates in xyz.
1016double vtkRpCubeAxesActor2D::EvaluatePoint(double planes[24], double x[3])
1017{
1018  int kk;
1019  double *plane;
1020  double val, minPlanesValue;
1021
1022  for (minPlanesValue=VTK_DOUBLE_MAX, kk=0; kk<6 ; kk++)
1023    {
1024    plane = planes + kk*4;
1025    val = plane[0]*x[0] + plane[1]*x[1] + plane[2]*x[2] + plane[3];
1026   
1027    if ( val < minPlanesValue )
1028      {
1029      minPlanesValue = val;
1030      }
1031    }//for all planes
1032
1033  return minPlanesValue;
1034}
1035 
1036//----------------------------------------------------------------------------
1037// Return the smallest point of the bounding box evaluated against the
1038// frustum planes.
1039double vtkRpCubeAxesActor2D::EvaluateBounds(double planes[24], double bounds[6])
1040{
1041  double val, minVal, x[3];
1042  int i, j, k;
1043
1044  for (minVal=VTK_DOUBLE_MAX, k=0; k<2; k++)
1045    {
1046    x[2] = bounds[4+k];
1047    for (j=0; j<2; j++)
1048      {
1049      x[1] = bounds[2+j];
1050      for (i=0; i<2; i++)
1051        {
1052        x[0] = bounds[i];
1053        val = this->EvaluatePoint(planes, x);
1054        if ( val < minVal )
1055          {
1056          minVal = val;
1057          }
1058        }
1059      }
1060    }//loop over verts of bounding box
1061 
1062  return minVal;
1063}
1064
1065//----------------------------------------------------------------------------
1066static int IsInBounds(double x[3], double bounds[6])
1067{
1068  if ( x[0] < bounds[0] || x[0] > bounds[1] ||
1069       x[1] < bounds[2] || x[1] > bounds[3] ||
1070       x[2] < bounds[4] || x[2] > bounds[5])
1071    {
1072    return 0;
1073    }
1074  else
1075    {
1076    return 1;
1077    }
1078}
1079
1080//----------------------------------------------------------------------------
1081
1082// Disable warnings about qualifiers on return types.
1083#if defined(_COMPILER_VERSION)
1084# pragma set woff 3303
1085#endif
1086#if defined(__INTEL_COMPILER)
1087# pragma warning (disable:858)
1088#endif
1089
1090#ifndef VTK_LEGACY_REMOVE
1091# ifdef VTK_WORKAROUND_WINDOWS_MANGLE
1092#  undef SetProp
1093#  undef GetProp
1094void vtkRpCubeAxesActor2D::SetPropA(vtkProp* prop)
1095{
1096  VTK_LEGACY_REPLACED_BODY(vtkRpCubeAxesActor2D::SetProp, "VTK 5.0",
1097                           vtkRpCubeAxesActor2D::SetViewProp);
1098  this->SetViewProp(prop);
1099}
1100void vtkRpCubeAxesActor2D::SetPropW(vtkProp* prop)
1101{
1102  VTK_LEGACY_REPLACED_BODY(vtkRpCubeAxesActor2D::SetProp, "VTK 5.0",
1103                           vtkRpCubeAxesActor2D::SetViewProp);
1104  this->SetViewProp(prop);
1105}
1106vtkProp* vtkRpCubeAxesActor2D::GetPropA()
1107{
1108  VTK_LEGACY_REPLACED_BODY(vtkRpCubeAxesActor2D::GetProp, "VTK 5.0",
1109                           vtkRpCubeAxesActor2D::GetViewProp);
1110  return this->GetViewProp();
1111}
1112vtkProp* vtkRpCubeAxesActor2D::GetPropW()
1113{
1114  VTK_LEGACY_REPLACED_BODY(vtkRpCubeAxesActor2D::GetProp, "VTK 5.0",
1115                           vtkRpCubeAxesActor2D::GetViewProp);
1116  return this->GetViewProp();
1117}
1118# endif
1119void vtkRpCubeAxesActor2D::SetProp(vtkProp* prop)
1120{
1121  VTK_LEGACY_REPLACED_BODY(vtkRpCubeAxesActor2D::SetProp, "VTK 5.0",
1122                           vtkRpCubeAxesActor2D::SetViewProp);
1123  this->SetViewProp(prop);
1124}
1125vtkProp* vtkRpCubeAxesActor2D::GetProp()
1126{
1127  VTK_LEGACY_REPLACED_BODY(vtkRpCubeAxesActor2D::GetProp, "VTK 5.0",
1128                           vtkRpCubeAxesActor2D::GetViewProp);
1129  return this->GetViewProp();
1130}
1131#endif
Note: See TracBrowser for help on using the repository browser.