source: branches/vtkvis_threaded/vtkRpCubeAxesActor2D.cpp @ 2495

Last change on this file since 2495 was 2423, checked in by ldelgass, 13 years ago

Handle 2D datasets with offset from origin or in principal planes other than XY.
Add return value for many methods, e.g. creating graphics objects
Add query for server's current list of datasets
Add pixel/world coordinate query of vector fields
Add pixel coordinate support for setting image camera zoom region
Add Heightmap wireframe, surface visibility toggles
Add Point size setting for polydata
Use custom version of 2D axes, fixes tick/label direction in XZ view
Put contour isolines through stripper to remove gaps in line rasterization

  • Property svn:eol-style set to native
File size: 33.1 KB
Line 
1/*=========================================================================
2
3  Program:   Visualization Toolkit
4  Module:    vtkCubeAxesActor2D.cxx
5
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10     This software is distributed WITHOUT ANY WARRANTY; without even
11     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12     PURPOSE.  See the above copyright notice for more information.
13
14=========================================================================*/
15#include "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.