source: vtkvis/trunk/vtkRpAxisActor.cpp @ 6307

Last change on this file since 6307 was 5802, checked in by ldelgass, 9 years ago

Update custom cube axes: rebase on version in VTK 6.1.0 plus backported fixes
from 6.3.0rc1, but without TextActor3D option.

  • Property svn:eol-style set to native
File size: 66.1 KB
Line 
1/*=========================================================================
2
3  Program:   Visualization Toolkit
4  Module:    vtkRpAxisActor.cxx
5  Thanks:    Kathleen Bonnell, B Division, Lawrence Livermore Nat'l Laboratory
6
7  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
8  All rights reserved.
9  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
10
11     This software is distributed WITHOUT ANY WARRANTY; without even
12     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13     PURPOSE.  See the above copyright notice for more information.
14=========================================================================*/
15#include "vtkRpAxisActor.h"
16
17#include "vtkRpAxisFollower.h"
18#include "vtkCamera.h"
19#include "vtkCellArray.h"
20#include "vtkCoordinate.h"
21#include "vtkFollower.h"
22#include "vtkTextRenderer.h"
23#include "vtkMath.h"
24#include "vtkObjectFactory.h"
25#include "vtkPolyData.h"
26#include "vtkPolyDataMapper.h"
27#include "vtkProperty.h"
28#include "vtkProperty2D.h"
29#include "vtkStringArray.h"
30#include "vtkTextActor.h"
31#include "vtkTextProperty.h"
32#include "vtkVectorText.h"
33#include "vtkViewport.h"
34#include "vtkVersion.h"
35#include "vtkWindow.h"
36
37vtkStandardNewMacro(vtkRpAxisActor);
38vtkCxxSetObjectMacro(vtkRpAxisActor, Camera, vtkCamera);
39vtkCxxSetObjectMacro(vtkRpAxisActor,LabelTextProperty,vtkTextProperty);
40vtkCxxSetObjectMacro(vtkRpAxisActor,TitleTextProperty,vtkTextProperty);
41
42// ****************************************************************
43// Instantiate this object.
44// ****************************************************************
45
46vtkRpAxisActor::vtkRpAxisActor()
47{
48  this->Point1Coordinate = vtkCoordinate::New();
49  this->Point1Coordinate->SetCoordinateSystemToWorld();
50  this->Point1Coordinate->SetValue(0.0, 0.0, 0.0);
51
52  this->Point2Coordinate = vtkCoordinate::New();
53  this->Point2Coordinate->SetCoordinateSystemToWorld();
54  this->Point2Coordinate->SetValue(0.75, 0.0, 0.0);
55
56  this->Camera = NULL;
57  this->Title = NULL;
58  this->MinorTicksVisible = 1;
59  this->MajorTickSize = 1.0;
60  this->MinorTickSize = 0.5;
61  this->TickLocation = VTK_TICKS_INSIDE;
62  this->Range[0] = 0.0;
63  this->Range[1] = 1.0;
64  this->ScreenSize = 10.;
65  this->LabelOffset = 20.;
66  this->TitleOffset = 20.;
67
68  this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = -1;
69  this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = 1;
70
71  this->LabelFormat = new char[8];
72  sprintf(this->LabelFormat, "%s", "%-#6.3g");
73
74  this->TitleTextProperty = vtkTextProperty::New();
75  this->TitleTextProperty->SetColor(0.,0.,0.);
76  this->TitleTextProperty->SetFontFamilyToArial();
77  this->TitleTextProperty->SetFontSize(18);
78  this->TitleTextProperty->SetVerticalJustificationToCentered();
79  this->TitleTextProperty->SetJustificationToCentered();
80
81  this->TitleVector = vtkVectorText::New();
82  this->TitleMapper = vtkPolyDataMapper::New();
83  this->TitleMapper->SetInputConnection(
84    this->TitleVector->GetOutputPort());
85  this->TitleActor = vtkRpAxisFollower::New();
86  this->TitleActor->SetAxis(this);
87  this->TitleActor->SetMapper(this->TitleMapper);
88  this->TitleActor->SetEnableDistanceLOD(0);
89  this->TitleActor2D = vtkTextActor::New();
90
91  this->NumberOfLabelsBuilt = 0;
92  this->LabelVectors = NULL;
93  this->LabelMappers = NULL;
94  this->LabelActors = NULL;
95  this->LabelActors2D = NULL;
96
97  this->LabelTextProperty = vtkTextProperty::New();
98  this->LabelTextProperty->SetColor(0.,0.,0.);
99  this->LabelTextProperty->SetFontFamilyToArial();
100  this->LabelTextProperty->SetFontSize(14);
101  this->LabelTextProperty->SetVerticalJustificationToBottom();
102  this->LabelTextProperty->SetJustificationToLeft();
103
104  this->AxisLines = vtkPolyData::New();
105  this->AxisLinesMapper = vtkPolyDataMapper::New();
106  this->AxisLinesMapper->SetInputData(this->AxisLines);
107  this->AxisLinesActor = vtkActor::New();
108  this->AxisLinesActor->SetMapper(this->AxisLinesMapper);
109  this->Gridlines = vtkPolyData::New();
110  this->GridlinesMapper = vtkPolyDataMapper::New();
111  this->GridlinesMapper->SetInputData(this->Gridlines);
112  this->GridlinesActor = vtkActor::New();
113  this->GridlinesActor->SetMapper(this->GridlinesMapper);
114  this->InnerGridlines = vtkPolyData::New();
115  this->InnerGridlinesMapper = vtkPolyDataMapper::New();
116  this->InnerGridlinesMapper->SetInputData(this->InnerGridlines);
117  this->InnerGridlinesActor = vtkActor::New();
118  this->InnerGridlinesActor->SetMapper(this->InnerGridlinesMapper);
119  this->Gridpolys = vtkPolyData::New();
120  this->GridpolysMapper = vtkPolyDataMapper::New();
121  this->GridpolysMapper->SetInputData(this->Gridpolys);
122  this->GridpolysActor = vtkActor::New();
123  this->GridpolysActor->SetMapper(this->GridpolysMapper);
124
125  this->AxisVisibility = 1;
126  this->TickVisibility = 1;
127  this->LabelVisibility = 1;
128  this->TitleVisibility = 1;
129
130  this->DrawGridlines = 0;
131  this->DrawGridlinesOnly = 0;
132  this->GridlineXLength = 1.;
133  this->GridlineYLength = 1.;
134  this->GridlineZLength = 1.;
135
136  this->DrawInnerGridlines = 0;
137
138  this->DrawGridpolys = 0;
139
140  this->AxisType = VTK_AXIS_TYPE_X;
141  //
142  // AxisPosition denotes which of the four possibilities in relation
143  // to the bounding box.  An x-Type axis with min min, means the x-axis
144  // at minimum y and minimum z values of the bbox.
145  //
146  this->AxisPosition = VTK_AXIS_POS_MINMIN;
147
148  this->LastLabelStart = 100000;
149
150  this->LastAxisPosition = -1;
151  this->LastTickLocation = -1;
152  this->LastTickVisibility = -1;
153  this->LastDrawGridlines = -1;
154  this->LastDrawInnerGridlines = -1;
155  this->LastDrawGridpolys = -1;
156  this->LastMinorTicksVisible = -1;
157  this->LastRange[0] = -1.0;
158  this->LastRange[1] = -1.0;
159
160  this->MinorTickPts = vtkPoints::New();
161  this->MajorTickPts = vtkPoints::New();
162  this->GridlinePts  = vtkPoints::New();
163  this->InnerGridlinePts  = vtkPoints::New();
164  this->GridpolyPts  = vtkPoints::New();
165
166  this->AxisHasZeroLength = false;
167
168  this->MinorStart = 0.;
169  //this->MajorStart = 0.;
170  for(int i=0;i<3;i++)
171    {
172    this->MajorStart[i] = 0.;
173    }
174  this->DeltaMinor = 1.;
175  //this->DeltaMajor = 1.;
176  for(int i=0;i<3;i++)
177    {
178    this->DeltaMajor[i] = 1.;
179    }
180
181  this->MinorRangeStart = 0.;
182  this->MajorRangeStart = 0.;
183  this->DeltaRangeMinor = 1.;
184  this->DeltaRangeMajor = 1.;
185
186  this->CalculateTitleOffset = 1;
187  this->CalculateLabelOffset = 1;
188
189  // Instance variables specific to 2D mode
190  this->Use2DMode = 0;
191  this->SaveTitlePosition = 0;
192  this->TitleConstantPosition[0] = this->TitleConstantPosition[1] = 0.;
193  this->VerticalOffsetXTitle2D = -40.;
194  this->HorizontalOffsetYTitle2D = -50.;
195  this->LastMinDisplayCoordinate[0] = 0;
196  this->LastMinDisplayCoordinate[1] = 0;
197  this->LastMinDisplayCoordinate[2] = 0;
198  this->LastMaxDisplayCoordinate[0] = 0;
199  this->LastMaxDisplayCoordinate[1] = 0;
200  this->LastMaxDisplayCoordinate[2] = 0;
201
202   // 0: All locations
203  this->DrawGridlinesLocation = this->LastDrawGridlinesLocation = 0;
204
205  // reset the base
206  for(int i=0;i<3;i++)
207    {
208    this->AxisBaseForX[i] = this->AxisBaseForY[i] = this->AxisBaseForZ[i] = 0.0;
209    }
210  this->AxisBaseForX[0] = this->AxisBaseForY[1] = this->AxisBaseForZ[2] = 1.0;
211  this->AxisOnOrigin = 0;
212}
213
214// ****************************************************************
215vtkRpAxisActor::~vtkRpAxisActor()
216{
217  this->SetCamera(NULL);
218
219  if (this->Point1Coordinate)
220    {
221    this->Point1Coordinate->Delete();
222    this->Point1Coordinate = NULL;
223    }
224
225  if (this->Point2Coordinate)
226    {
227    this->Point2Coordinate->Delete();
228    this->Point2Coordinate = NULL;
229    }
230
231  delete [] this->LabelFormat;
232  this->LabelFormat = NULL;
233
234  if (this->TitleVector)
235    {
236    this->TitleVector->Delete();
237    this->TitleVector = NULL;
238    }
239  if (this->TitleMapper)
240    {
241    this->TitleMapper->Delete();
242    this->TitleMapper = NULL;
243    }
244  if (this->TitleActor)
245    {
246    this->TitleActor->Delete();
247    this->TitleActor = NULL;
248    }
249  if (this->TitleActor2D)
250    {
251    this->TitleActor2D->Delete();
252    this->TitleActor2D = NULL;
253    }
254
255  delete [] this->Title;
256  this->Title = NULL;
257
258  if (this->TitleTextProperty)
259    {
260    this->TitleTextProperty->Delete();
261    this->TitleTextProperty = NULL;
262    }
263
264  if (this->LabelMappers != NULL)
265    {
266    for (int i=0; i < this->NumberOfLabelsBuilt; i++)
267      {
268      this->LabelVectors[i]->Delete();
269      this->LabelMappers[i]->Delete();
270      this->LabelActors[i]->Delete();
271      this->LabelActors2D[i]->Delete();
272      }
273    this->NumberOfLabelsBuilt = 0;
274    delete [] this->LabelVectors;
275    delete [] this->LabelMappers;
276    delete [] this->LabelActors;
277    delete [] this->LabelActors2D;
278    this->LabelVectors = NULL;
279    this->LabelMappers = NULL;
280    this->LabelActors = NULL;
281    this->LabelActors2D = NULL;
282    }
283  if (this->LabelTextProperty)
284    {
285    this->LabelTextProperty->Delete();
286    this->LabelTextProperty = NULL;
287    }
288
289  if (this->AxisLines)
290    {
291    this->AxisLines->Delete();
292    this->AxisLines = NULL;
293    }
294  if (this->AxisLinesMapper)
295    {
296    this->AxisLinesMapper->Delete();
297    this->AxisLinesMapper = NULL;
298    }
299  if (this->AxisLinesActor)
300    {
301    this->AxisLinesActor->Delete();
302    this->AxisLinesActor = NULL;
303    }
304
305  if (this->Gridlines)
306    {
307    this->Gridlines->Delete();
308    this->Gridlines = NULL;
309    }
310  if (this->GridlinesMapper)
311    {
312    this->GridlinesMapper->Delete();
313    this->GridlinesMapper = NULL;
314    }
315  if (this->GridlinesActor)
316    {
317    this->GridlinesActor->Delete();
318    this->GridlinesActor = NULL;
319    }
320
321  if (this->InnerGridlines)
322    {
323    this->InnerGridlines->Delete();
324    this->InnerGridlines = NULL;
325    }
326  if (this->InnerGridlinesMapper)
327    {
328    this->InnerGridlinesMapper->Delete();
329    this->InnerGridlinesMapper = NULL;
330    }
331  if (this->InnerGridlinesActor)
332    {
333    this->InnerGridlinesActor->Delete();
334    this->InnerGridlinesActor = NULL;
335    }
336
337  if (this->Gridpolys)
338    {
339    this->Gridpolys->Delete();
340    this->Gridpolys = NULL;
341    }
342  if (this->GridpolysMapper)
343    {
344    this->GridpolysMapper->Delete();
345    this->GridpolysMapper = NULL;
346    }
347  if (this->GridpolysActor)
348    {
349    this->GridpolysActor->Delete();
350    this->GridpolysActor = NULL;
351    }
352
353  if (this->MinorTickPts)
354    {
355    this->MinorTickPts ->Delete();
356    this->MinorTickPts = NULL;
357    }
358  if (this->MajorTickPts)
359    {
360    this->MajorTickPts->Delete();
361    this->MajorTickPts = NULL;
362    }
363  if (this->GridlinePts)
364    {
365    this->GridlinePts->Delete();
366    this->GridlinePts = NULL;
367    }
368  if (this->InnerGridlinePts)
369    {
370    this->InnerGridlinePts->Delete();
371    this->InnerGridlinePts = NULL;
372    }
373  if (this->GridpolyPts)
374    {
375    this->GridpolyPts->Delete();
376    this->GridpolyPts = NULL;
377    }
378}
379
380// ****************************************************************
381void vtkRpAxisActor::ReleaseGraphicsResources(vtkWindow *win)
382{
383  this->TitleActor->ReleaseGraphicsResources(win);
384  this->TitleActor2D->ReleaseGraphicsResources(win);
385  for (int i=0; i < this->NumberOfLabelsBuilt; i++)
386    {
387    this->LabelActors[i]->ReleaseGraphicsResources(win);
388    this->LabelActors2D[i]->ReleaseGraphicsResources(win);
389    }
390  this->AxisLinesActor->ReleaseGraphicsResources(win);
391  this->GridlinesActor->ReleaseGraphicsResources(win);
392  this->InnerGridlinesActor->ReleaseGraphicsResources(win);
393  this->GridpolysActor->ReleaseGraphicsResources(win);
394}
395
396// ****************************************************************
397int vtkRpAxisActor::RenderOpaqueGeometry(vtkViewport *viewport)
398{
399  int i, renderedSomething=0;
400
401  this->BuildAxis(viewport, false);
402
403  // Everything is built, just have to render
404
405  if (!this->AxisHasZeroLength)
406    {
407    if(this->DrawGridlinesOnly && this->DrawGridlines)
408      {
409      // Exit !!!!
410      return this->GridlinesActor->RenderOpaqueGeometry(viewport);
411      }
412    if (this->Title != NULL && this->Title[0] != 0 && this->TitleVisibility)
413      {
414      if (this->Use2DMode)
415        {
416        renderedSomething += this->TitleActor2D->RenderOpaqueGeometry(viewport);
417        }
418      else
419        {
420        renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
421        }
422      }
423    if (this->AxisVisibility || this->TickVisibility)
424      {
425      renderedSomething += this->AxisLinesActor->RenderOpaqueGeometry(viewport);
426      }
427    if(this->DrawGridlines)
428      {
429      renderedSomething += this->GridlinesActor->RenderOpaqueGeometry(viewport);
430      }
431    if(this->DrawInnerGridlines)
432      {
433      renderedSomething += this->InnerGridlinesActor->RenderOpaqueGeometry(viewport);
434      }
435    if (this->LabelVisibility)
436      {
437      for (i=0; i<this->NumberOfLabelsBuilt; i++)
438        {
439        if (this->Use2DMode)
440          {
441          renderedSomething +=
442            this->LabelActors2D[i]->RenderOpaqueGeometry(viewport);
443          }
444        else
445          {
446          renderedSomething +=
447            this->LabelActors[i]->RenderOpaqueGeometry(viewport);
448          }
449        }
450      }
451    }
452
453  return renderedSomething;
454}
455
456// ****************************************************************
457// Build the translucent poly actors and render.
458// ****************************************************************
459int vtkRpAxisActor::RenderTranslucentGeometry(vtkViewport *viewport)
460{
461  return this->RenderTranslucentPolygonalGeometry(viewport);
462}
463
464// ****************************************************************
465// Build the translucent poly actors and render.
466// ****************************************************************
467int vtkRpAxisActor::RenderTranslucentPolygonalGeometry(vtkViewport *viewport)
468{
469
470  int renderedSomething=0;
471
472  this->BuildAxis(viewport, false);
473
474  // Everything is built, just have to render
475
476  if (!this->AxisHasZeroLength && !this->DrawGridlinesOnly)
477    {
478    if(this->DrawGridpolys)
479      {
480      renderedSomething += this->GridpolysActor->RenderTranslucentPolygonalGeometry(viewport);
481      }
482    if (this->Title != NULL && this->Title[0] != 0 && this->TitleVisibility)
483      {
484      if (this->Use2DMode)
485        {
486        renderedSomething += this->TitleActor2D->RenderTranslucentPolygonalGeometry(viewport);
487        }
488      else
489        {
490        renderedSomething += this->TitleActor->RenderTranslucentPolygonalGeometry(viewport);
491        }
492      }
493    if (this->LabelVisibility)
494      {
495      for (int i=0; i<this->NumberOfLabelsBuilt; i++)
496        {
497        if (this->Use2DMode)
498          {
499          renderedSomething +=
500            this->LabelActors2D[i]->RenderTranslucentPolygonalGeometry(viewport);
501          }
502        else
503          {
504          renderedSomething +=
505            this->LabelActors[i]->RenderTranslucentPolygonalGeometry(viewport);
506          }
507        }
508      }
509    }
510  return renderedSomething;
511}
512
513// ****************************************************************
514// Render the 2d annotations.
515// ****************************************************************
516int vtkRpAxisActor::RenderOverlay(vtkViewport *viewport)
517{
518  int i, renderedSomething=0;
519
520  // Everything is built, just have to render
521  if (!this->AxisHasZeroLength && !this->DrawGridlinesOnly)
522    {
523    if (this->Use2DMode)
524      {
525      renderedSomething += this->TitleActor2D->RenderOverlay(viewport);
526      }
527    else
528      {
529      renderedSomething += this->TitleActor->RenderOverlay(viewport);
530      }
531    if (this->LabelVisibility)
532      {
533      for (i=0; i<this->NumberOfLabelsBuilt; i++)
534        {
535        if (this->Use2DMode)
536          {
537          renderedSomething += this->LabelActors2D[i]->RenderOverlay(viewport);
538          }
539        else
540          {
541          renderedSomething += this->LabelActors[i]->RenderOverlay(viewport);
542          }
543        }
544      }
545    }
546
547  return renderedSomething;
548}
549
550// **************************************************************************
551int vtkRpAxisActor::HasTranslucentPolygonalGeometry()
552{
553  if (this->Visibility && !this->AxisHasZeroLength)
554    {
555
556    if (this->TitleVisibility)
557      {
558      if (this->Use2DMode)
559        {
560        if (this->TitleActor2D->HasTranslucentPolygonalGeometry())
561          {
562          return 1;
563          }
564        }
565      else
566        {
567        if (this->TitleActor->HasTranslucentPolygonalGeometry())
568          {
569          return 1;
570          }
571        }
572      }
573
574    if (this->LabelVisibility)
575      {
576      if (this->Use2DMode)
577        {
578        for (int i = 0; i < this->NumberOfLabelsBuilt; ++i)
579          {
580          if (this->LabelActors2D[i]->HasTranslucentPolygonalGeometry())
581            {
582            return 1;
583            } // end if
584          } // end for
585        } // end 2D
586      else
587        {
588        for (int i = 0; i < this->NumberOfLabelsBuilt; ++i)
589          {
590          if (this->LabelActors[i]->HasTranslucentPolygonalGeometry())
591            {
592            return 1;
593            } // end if
594          } // end for
595        } // end 3D
596      } // end label vis
597
598    if (this->AxisLinesActor->HasTranslucentPolygonalGeometry())
599      {
600      return 1;
601      }
602
603    if (this->DrawGridlines &&
604        this->GridlinesActor->HasTranslucentPolygonalGeometry())
605      {
606      return 1;
607      }
608
609    if (this->DrawInnerGridlines &&
610        this->InnerGridlinesActor->HasTranslucentPolygonalGeometry())
611      {
612      return 1;
613      }
614
615    if (this->DrawGridpolys &&
616        this->GridpolysActor->HasTranslucentPolygonalGeometry())
617      {
618      return 1;
619      }
620
621    return this->Superclass::HasTranslucentPolygonalGeometry();
622
623    } // end this vis
624
625  return 0;
626}
627
628// **************************************************************************
629// Perform some initialization, determine which Axis type we are
630// **************************************************************************
631void vtkRpAxisActor::BuildAxis(vtkViewport *viewport, bool force)
632{
633  // We'll do our computation in world coordinates. First determine the
634  // location of the endpoints.
635  double *x, p1[3], p2[3];
636  x = this->Point1Coordinate->GetValue();
637  p1[0] = x[0]; p1[1] = x[1]; p1[2] = x[2];
638  x = this->Point2Coordinate->GetValue();
639  p2[0] = x[0]; p2[1] = x[1]; p2[2] = x[2];
640
641  //
642  //  Test for axis of zero length.
643  //
644  if (p1[0] == p2[0] && p1[1] == p2[1] && p1[2] == p2[2])
645    {
646    vtkDebugMacro(<<"Axis has zero length, not building.");
647    this->AxisHasZeroLength = true;
648    return;
649    }
650  this->AxisHasZeroLength = false;
651
652  if (!force && this->GetMTime() < this->BuildTime.GetMTime() &&
653      viewport->GetMTime() < this->BuildTime.GetMTime())
654    {
655    return; //already built
656    }
657
658  vtkDebugMacro(<<"Rebuilding axis");
659
660  if (force || this->GetProperty()->GetMTime() > this->BuildTime.GetMTime())
661    {
662      //this->AxisLinesActor->SetProperty(this->GetProperty());
663    this->TitleActor->SetProperty(this->GetProperty());
664    this->TitleActor->GetProperty()->SetColor(this->TitleTextProperty->GetColor());
665    this->TitleActor->GetProperty()->SetOpacity(this->TitleTextProperty->GetOpacity());
666    }
667
668  //
669  // Generate the axis and tick marks.
670  //
671  bool ticksRebuilt;
672  ticksRebuilt = this->BuildTickPoints(p1, p2, force);
673
674  bool tickVisChanged = this->TickVisibilityChanged();
675
676  if (force || ticksRebuilt || tickVisChanged || this->LastDrawGridlinesLocation != this->DrawGridlinesLocation)
677    {
678    this->LastDrawGridlinesLocation = this->DrawGridlinesLocation;
679    this->SetAxisPointsAndLines();
680    }
681
682  // If the ticks have been rebuilt it is more than likely
683  // that the labels should follow...
684  this->BuildLabels(viewport, force || ticksRebuilt);
685  if (this->Use2DMode == 1)
686    {
687    this->BuildLabels2D(viewport, force || ticksRebuilt);
688    }
689
690  if (this->Title != NULL && this->Title[0] != 0)
691    {
692    this->BuildTitle(force || ticksRebuilt);
693    if( this->Use2DMode == 1 )
694      {
695      this->BuildTitle2D(viewport, force || ticksRebuilt);
696      }
697    }
698
699  this->LastAxisPosition = this->AxisPosition;
700
701  this->LastRange[0] = this->Range[0];
702  this->LastRange[1] = this->Range[1];
703  this->BuildTime.Modified();
704}
705
706// ****************************************************************
707//  Set label values and properties.
708// ****************************************************************
709void
710vtkRpAxisActor::BuildLabels(vtkViewport *viewport, bool force)
711{
712  if (!force && !this->LabelVisibility)
713    {
714    return;
715    }
716
717  for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
718    {
719    this->LabelActors[i]->SetCamera(this->Camera);
720    this->LabelActors[i]->SetProperty(this->GetProperty());
721    this->LabelActors[i]->GetProperty()->SetColor(this->LabelTextProperty->GetColor());
722    this->LabelActors[i]->GetProperty()->SetOpacity(this->LabelTextProperty->GetOpacity());
723    this->LabelActors[i]->SetOrientation(0., 0., this->LabelTextProperty->GetOrientation());
724
725    if(!this->GetCalculateLabelOffset())
726      {
727      this->LabelActors[i]->SetAutoCenter(1);
728      }
729    }
730
731  if (force || this->BuildTime.GetMTime() <  this->BoundsTime.GetMTime() ||
732      this->AxisPosition != this->LastAxisPosition ||
733      this->LastRange[0] != this->Range[0] ||
734      this->LastRange[1] != this->Range[1])
735    {
736    this->SetLabelPositions(viewport, force);
737    }
738}
739
740static const int vtkRpAxisActorMultiplierTable1[4] = { -1, -1, 1,  1};
741static const int vtkRpAxisActorMultiplierTable2[4] = { -1,  1, 1, -1};
742
743// *******************************************************************
744// Determine and set scale factor and position for labels.
745// *******************************************************************
746void vtkRpAxisActor::SetLabelPositions(vtkViewport *viewport, bool force)
747{
748  if (!force && (!this->LabelVisibility || this->NumberOfLabelsBuilt == 0))
749    {
750    return;
751    }
752
753  double bounds[6], center[3], tick[3], pos[3];
754  int i = 0;
755  int xmult = 0;
756  int ymult = 0;
757  double labelAngle = vtkMath::RadiansFromDegrees(this->LabelTextProperty->GetOrientation());
758  double labelCos = fabs(cos(labelAngle));
759  double labelSin = fabs(sin(labelAngle));
760
761
762  switch (this->AxisType)
763    {
764    case VTK_AXIS_TYPE_X :
765      xmult = 0;
766      ymult = vtkRpAxisActorMultiplierTable1[this->AxisPosition];
767      break;
768    case VTK_AXIS_TYPE_Y :
769      xmult = vtkRpAxisActorMultiplierTable1[this->AxisPosition];
770      ymult = 0;
771      break;
772    case VTK_AXIS_TYPE_Z :
773      xmult = vtkRpAxisActorMultiplierTable1[this->AxisPosition];
774      ymult = vtkRpAxisActorMultiplierTable2[this->AxisPosition];
775      break;
776    }
777
778  int ptIdx;
779  //
780  // xadjust & yadjust are used for positioning the label correctly
781  // depending upon the 'orientation' of the axis as determined
782  // by its position in view space (via transformed bounds).
783  //
784  double displayBounds[6] = { 0., 0., 0., 0., 0., 0.};
785  this->TransformBounds(viewport, displayBounds);
786  double xadjust = (displayBounds[0] > displayBounds[1] ? -1 : 1);
787  double yadjust = (displayBounds[2] > displayBounds[3] ? -1 : 1);
788
789  for (i=0; i < this->NumberOfLabelsBuilt &&
790    i < this->MajorTickPts->GetNumberOfPoints(); i++)
791    {
792    ptIdx = 4*i + 1;
793    this->MajorTickPts->GetPoint(ptIdx, tick);
794
795    this->LabelActors[i]->GetMapper()->GetBounds(bounds);
796
797    if(this->CalculateLabelOffset)
798      {
799      double halfWidth  = 0.5 * ((bounds[1] - bounds[0]) * labelCos + (bounds[3] - bounds[2]) * labelSin);
800      double halfHeight = 0.5 * ((bounds[1] - bounds[0]) * labelSin + (bounds[3] - bounds[2]) * labelCos);
801
802      center[0] = tick[0] + xmult * (halfWidth  + this->MinorTickSize);
803      center[1] = tick[1] + ymult * (halfHeight + this->MinorTickSize);
804      center[2] = tick[2];
805
806      pos[0] = (center[0] - xadjust *halfWidth);
807      pos[1] = (center[1] - yadjust *halfHeight);
808      pos[2] =  center[2];
809      }
810    else
811      {
812      pos[0] = tick[0];
813      pos[1] = tick[1];
814      pos[2] = tick[2];
815
816      double delta  = 0.5 * ((bounds[1] - bounds[0]) * labelSin + (bounds[3] - bounds[2]) * labelCos);
817      this->LabelActors[i]->SetScreenOffset(this->LabelOffset + (delta) * this->ScreenSize);
818      }
819
820    this->LabelActors[i]->SetPosition(pos[0], pos[1], pos[2]);
821    }
822}
823
824// *******************************************************************
825//  Set 2D label values and properties.
826// *******************************************************************
827void
828vtkRpAxisActor::BuildLabels2D(vtkViewport *viewport, bool force)
829{
830  if (!force && (!this->LabelVisibility || this->NumberOfLabelsBuilt == 0))
831    return;
832
833  for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
834    {
835    this->LabelActors2D[i]->GetProperty()->SetColor(this->LabelTextProperty->GetColor());
836    this->LabelActors2D[i]->GetProperty()->SetOpacity(this->LabelTextProperty->GetOpacity());
837    this->LabelActors2D[i]->GetTextProperty()->ShallowCopy(this->LabelTextProperty);
838    }
839
840  this->NeedBuild2D = this->BoundsDisplayCoordinateChanged(viewport);
841  if (force || this->NeedBuild2D)
842    {
843    this->SetLabelPositions2D(viewport, force);
844    }
845}
846
847
848// *******************************************************************
849// Determine and set scale factor and position for 2D labels.
850// *******************************************************************
851void
852vtkRpAxisActor::SetLabelPositions2D(vtkViewport *viewport, bool force)
853{
854  if (!force && (!this->LabelVisibility || this->NumberOfLabelsBuilt == 0) )
855    return;
856
857  int xmult = 0;
858  int ymult = 0;
859  double xcoeff = 0.;
860  double ycoeff = 0.;
861
862  // we are in 2D mode, so no Z axis
863  switch (this->AxisType)
864    {
865    case VTK_AXIS_TYPE_X :
866      xmult = 0;
867      ymult = vtkRpAxisActorMultiplierTable1[this->AxisPosition];
868      xcoeff = 0.5;
869      ycoeff = 1.0;
870      break;
871    case VTK_AXIS_TYPE_Y :
872      xmult = vtkRpAxisActorMultiplierTable1[this->AxisPosition];
873      ymult = 0;
874      xcoeff = 1.0;
875      ycoeff = 0.5;
876      break;
877    }
878
879
880  int ptIdx;
881  //
882  // xadjust & yadjust are used for positioning the label correctly
883  // depending upon the 'orientation' of the axis as determined
884  // by its position in view space (via transformed bounds).
885  //
886  double displayBounds[6] = { 0., 0., 0., 0., 0., 0.};
887  this->TransformBounds(viewport, displayBounds);
888  double xadjust = (displayBounds[0] > displayBounds[1] ? -1 : 1);
889  double yadjust = (displayBounds[2] > displayBounds[3] ? -1 : 1);
890  double transpos[3] = {0., 0., 0.};
891  double center[3], tick[3], pos[2];
892
893  vtkTextRenderer *tren = vtkTextRenderer::GetInstance();
894  if (!tren)
895    {
896    vtkErrorMacro(<< "Unable to obtain the vtkTextRenderer instance!");
897    return;
898    }
899#if VTK_MAJOR_VERSION == 6 && VTK_MINOR_VERSION >= 3
900  vtkWindow *win = viewport->GetVTKWindow();
901  if (!win)
902    {
903    vtkErrorMacro(<<"No render window available: cannot determine DPI.");
904    return;
905    }
906
907#endif
908  for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
909    {
910    ptIdx = 4*i + 1;
911
912    this->MajorTickPts->GetPoint(ptIdx, tick);
913
914    center[0] = tick[0] + xmult * this->MinorTickSize;
915    center[1] = tick[1] + ymult * this->MinorTickSize;
916    center[2] = tick[2];
917
918    viewport->SetWorldPoint(center[0], center[1], center[2], 1.0);
919    viewport->WorldToDisplay();
920    viewport->GetDisplayPoint(transpos);
921
922    int bbox[4];
923    if (!tren->GetBoundingBox(this->LabelActors2D[i]->GetTextProperty(),
924#if VTK_MAJOR_VERSION == 6 && VTK_MINOR_VERSION >= 3
925                              this->LabelActors2D[i]->GetInput(), bbox,
926                              win->GetDPI()))
927#else
928                              this->LabelActors2D[i]->GetInput(), bbox))
929#endif
930      {
931      vtkErrorMacro(<< "Unable to calculate bounding box for label "
932                    << this->LabelActors2D[i]->GetInput());
933      continue;
934      }
935
936    double width  = (bbox[1]-bbox[0]);
937    double height = (bbox[3]-bbox[2]);
938
939    pos[0] = (transpos[0] - xadjust*width*xcoeff);
940    pos[1] = (transpos[1] - yadjust*height*ycoeff);
941    this->LabelActors2D[i]->SetPosition( pos[0], pos[1] );
942    }
943}
944
945
946// **********************************************************************
947//  Determines scale and position for the Title.  Currently,
948//  title can only be centered with respect to its axis.
949// **********************************************************************
950void vtkRpAxisActor::BuildTitle(bool force)
951{
952  this->NeedBuild2D = false;
953  if (!force && !this->TitleVisibility)
954    {
955    return;
956    }
957  double labBounds[6], titleBounds[6], center[3], pos[3];
958  double labHeight, maxHeight = 0, labWidth, maxWidth = 0;
959  double halfTitleWidth, halfTitleHeight;
960  double labelAngle = vtkMath::RadiansFromDegrees(this->LabelTextProperty->GetOrientation());
961  double labelCos = fabs(cos(labelAngle));
962  double labelSin = fabs(sin(labelAngle));
963
964  double *p1 = this->Point1Coordinate->GetValue();
965  double *p2 = this->Point2Coordinate->GetValue();
966  int xmult = 0;
967  int ymult = 0;
968
969  if (!force && this->LabelBuildTime.GetMTime() < this->BuildTime.GetMTime() &&
970      this->BoundsTime.GetMTime() < this->BuildTime.GetMTime() &&
971      this->AxisPosition == this->LastAxisPosition &&
972      this->TitleTextTime.GetMTime() < this->BuildTime.GetMTime())
973    {
974    return;
975    }
976
977  this->NeedBuild2D = true;
978  switch (this->AxisType)
979    {
980    case VTK_AXIS_TYPE_X :
981      xmult = 0;
982      ymult = vtkRpAxisActorMultiplierTable1[this->AxisPosition];
983      break;
984    case VTK_AXIS_TYPE_Y :
985      xmult = vtkRpAxisActorMultiplierTable1[this->AxisPosition];
986      ymult = 0;
987      break;
988    case VTK_AXIS_TYPE_Z :
989      xmult = vtkRpAxisActorMultiplierTable1[this->AxisPosition];
990      ymult = vtkRpAxisActorMultiplierTable2[this->AxisPosition];
991      break;
992    }
993  //
994  //  Title should be in relation to labels (if any)
995  //  so find out information about them.
996  //
997  for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
998    {
999    this->LabelActors[i]->GetMapper()->GetBounds(labBounds);
1000    labWidth = (labBounds[1] - labBounds[0]) * labelCos + (labBounds[3] - labBounds[2]) * labelSin;
1001    maxWidth = (labWidth > maxWidth ? labWidth : maxWidth);
1002    labHeight = (labBounds[1] - labBounds[0]) * labelSin + (labBounds[3] - labBounds[2]) * labelCos;
1003    maxHeight = (labHeight > maxHeight ? labHeight : maxHeight);
1004    }
1005
1006  this->TitleVector->SetText(this->Title);
1007
1008  this->TitleActor->GetProperty()->SetColor(this->TitleTextProperty->GetColor());
1009  this->TitleActor->SetCamera(this->Camera);
1010  this->TitleActor->GetMapper()->GetBounds(titleBounds);
1011
1012  if(!this->GetCalculateTitleOffset())
1013    {
1014    this->TitleActor->SetAutoCenter(1);
1015    }
1016
1017  center[0] = p1[0] + (p2[0] - p1[0]) / 2.0;
1018  center[1] = p1[1] + (p2[1] - p1[1]) / 2.0;
1019  center[2] = p1[2] + (p2[2] - p1[2]) / 2.0;
1020
1021  halfTitleHeight = (titleBounds[3] - titleBounds[2]) * 0.5;
1022  if(this->CalculateTitleOffset)
1023    {
1024    halfTitleWidth  = (titleBounds[1] - titleBounds[0]) * 0.5;
1025    center[0] += xmult * (halfTitleWidth + maxWidth);
1026    center[1] += ymult * (halfTitleHeight + 2*maxHeight);
1027    }
1028  else
1029    {
1030    this->TitleActor->SetScreenOffset(this->TitleOffset +
1031      this->LabelOffset + this->ScreenSize * (maxHeight + halfTitleHeight));
1032    }
1033
1034  pos[0] = center[0];
1035  pos[1] = center[1];
1036  pos[2] = center[2];
1037
1038  this->TitleActor->SetPosition(pos[0], pos[1], pos[2]);
1039}
1040
1041// **********************************************************************
1042//  Determines scale and position for the 2D Title.  Currently,
1043//  title can only be centered with respect to its axis.
1044// **********************************************************************
1045void
1046vtkRpAxisActor::BuildTitle2D(vtkViewport *viewport, bool force)
1047{
1048  if (!this->NeedBuild2D && !force && !this->TitleVisibility)
1049    {
1050    return;
1051    }
1052
1053  // for textactor instead of follower
1054  this->TitleActor2D->SetInput( this->TitleVector->GetText() );
1055  this->TitleActor2D->GetProperty()->SetColor( this->TitleTextProperty->GetColor() );
1056  this->TitleActor2D->GetProperty()->SetOpacity( this->TitleTextProperty->GetOpacity() );
1057  this->TitleActor2D->GetTextProperty()->ShallowCopy(this->TitleTextProperty);
1058
1059  if (this->AxisType == VTK_AXIS_TYPE_Y)
1060    {
1061    if (strlen(this->TitleActor2D->GetInput()) > 2)
1062      {
1063      // warning : orientation have to be set on vtkTextActor and not on the vtkTextActor's vtkTextProperty
1064      // otherwise there is a strange effect (first letter is not align with the others)
1065      this->TitleActor2D->SetOrientation(90);
1066      }
1067    else
1068      {
1069      // if in the previous rendering, the orientation was set.
1070      this->TitleActor2D->SetOrientation(0);
1071      }
1072    }
1073
1074  // stuff for 2D axis with TextActor
1075  double transpos[3];
1076  double* pos = this->TitleActor->GetPosition();
1077  viewport->SetWorldPoint(pos[0], pos[1],  pos[2], 1.0);
1078  viewport->WorldToDisplay();
1079  viewport->GetDisplayPoint(transpos);
1080  if (this->AxisType == VTK_AXIS_TYPE_X)
1081    {
1082    transpos[1] += this->VerticalOffsetXTitle2D;
1083    }
1084  else if (this->AxisType == VTK_AXIS_TYPE_Y)
1085    {
1086    transpos[0] += this->HorizontalOffsetYTitle2D;
1087    }
1088  if (transpos[1] < 10.) transpos[1] = 10.;
1089  if (transpos[0] < 10.) transpos[0] = 10.;
1090  if (this->SaveTitlePosition == 0)
1091    {
1092    this->TitleActor2D->SetPosition(transpos[0], transpos[1]);
1093    }
1094  else
1095    {
1096    if (this->SaveTitlePosition == 1)
1097      {
1098      TitleConstantPosition[0] = transpos[0];
1099      TitleConstantPosition[1] = transpos[1];
1100      this->SaveTitlePosition = 2;
1101      }
1102    this->TitleActor2D->SetPosition(TitleConstantPosition[0], TitleConstantPosition[1]);
1103    }
1104}
1105
1106//
1107//  Transform the bounding box to display coordinates.  Used
1108//  in determining orientation of the axis.
1109//
1110void vtkRpAxisActor::TransformBounds(vtkViewport *viewport, double bnds[6])
1111{
1112  double minPt[3], maxPt[3], transMinPt[3], transMaxPt[3];
1113  minPt[0] = this->Bounds[0];
1114  minPt[1] = this->Bounds[2];
1115  minPt[2] = this->Bounds[4];
1116  maxPt[0] = this->Bounds[1];
1117  maxPt[1] = this->Bounds[3];
1118  maxPt[2] = this->Bounds[5];
1119
1120  viewport->SetWorldPoint(minPt[0], minPt[1], minPt[2], 1.0);
1121  viewport->WorldToDisplay();
1122  viewport->GetDisplayPoint(transMinPt);
1123  viewport->SetWorldPoint(maxPt[0], maxPt[1], maxPt[2], 1.0);
1124  viewport->WorldToDisplay();
1125  viewport->GetDisplayPoint(transMaxPt);
1126
1127  bnds[0] = transMinPt[0];
1128  bnds[2] = transMinPt[1];
1129  bnds[4] = transMinPt[2];
1130  bnds[1] = transMaxPt[0];
1131  bnds[3] = transMaxPt[1];
1132  bnds[5] = transMaxPt[2];
1133}
1134
1135inline double ffix(double value)
1136{
1137  int ivalue = static_cast<int>(value);
1138  return static_cast<double>(ivalue);
1139}
1140
1141inline double fsign(double value, double sign)
1142{
1143  value = fabs(value);
1144  if (sign < 0.)
1145    {
1146    value *= -1.;
1147    }
1148  return value;
1149}
1150
1151// ****************************************************************
1152void vtkRpAxisActor::PrintSelf(ostream& os, vtkIndent indent)
1153{
1154  this->Superclass::PrintSelf(os,indent);
1155
1156  os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
1157  os << indent << "Number Of Labels Built: "
1158     << this->NumberOfLabelsBuilt << "\n";
1159  os << indent << "Range: ("
1160     << this->Range[0] << ", "
1161     << this->Range[1] << ")\n";
1162
1163  os << indent << "Label Format: " << this->LabelFormat << "\n";
1164
1165  os << indent << "Axis Visibility: "
1166     << (this->AxisVisibility ? "On\n" : "Off\n");
1167
1168  os << indent << "Tick Visibility: "
1169     << (this->TickVisibility ? "On\n" : "Off\n");
1170
1171  os << indent << "Label Visibility: "
1172     << (this->LabelVisibility ? "On\n" : "Off\n");
1173
1174  os << indent << "Title Visibility: "
1175     << (this->TitleVisibility ? "On\n" : "Off\n");
1176
1177  os << indent << "Point1 Coordinate: " << this->Point1Coordinate << "\n";
1178  this->Point1Coordinate->PrintSelf(os, indent.GetNextIndent());
1179
1180  os << indent << "Point2 Coordinate: " << this->Point2Coordinate << "\n";
1181  this->Point2Coordinate->PrintSelf(os, indent.GetNextIndent());
1182
1183  os << indent << "AxisType: ";
1184  switch (this->AxisType)
1185    {
1186    case VTK_AXIS_TYPE_X:
1187      os << "X Axis" << endl;
1188      break;
1189    case VTK_AXIS_TYPE_Y:
1190      os << "Y Axis" << endl;
1191      break;
1192    case VTK_AXIS_TYPE_Z:
1193      os << "Z Axis" << endl;
1194      break;
1195    default:
1196      // shouldn't get here
1197      ;
1198    }
1199
1200  os << indent << "DeltaMajor: "
1201     << this->DeltaMajor[0] << ","
1202     << this->DeltaMajor[1] << ","
1203     << this->DeltaMajor[2] << endl;
1204  os << indent << "DeltaMinor: " << this->DeltaMinor << endl;
1205  os << indent << "DeltaRangeMajor: " << this->DeltaRangeMajor << endl;
1206  os << indent << "DeltaRangeMinor: " << this->DeltaRangeMinor << endl;
1207  os << indent << "MajorRangeStart: " << this->MajorRangeStart << endl;
1208  os << indent << "MinorRangeStart: " << this->MinorRangeStart << endl;
1209
1210  os << indent << "MinorTicksVisible: " << this->MinorTicksVisible << endl;
1211
1212  os << indent << "TitleActor: ";
1213  if(this->TitleActor)
1214    {
1215    os << indent << "TitleActor: (" << this->TitleActor << ")\n";
1216    }
1217  else
1218    {
1219    os << "(none)" << endl;
1220    }
1221
1222  os << indent << "Camera: ";
1223  if (this->Camera)
1224    {
1225    this->Camera->PrintSelf(os, indent);
1226    }
1227  else
1228    {
1229    os << "(none)" << endl;
1230    }
1231
1232  os << indent << "MajorTickSize: " << this->MajorTickSize << endl;
1233  os << indent << "MinorTickSize: " << this->MinorTickSize << endl;
1234
1235  os << indent << "DrawGridlines: " << this->DrawGridlines << endl;
1236
1237  os << indent << "MajorStart: "
1238     << this->MajorStart[0] << ","
1239     << this->MajorStart[1] << ","
1240     << this->MajorStart[2] << endl;
1241
1242  os << indent << "AxisPosition: " << this->AxisPosition << endl;
1243
1244  os << indent << "GridlineXLength: " << this->GridlineXLength << endl;
1245  os << indent << "GridlineYLength: " << this->GridlineYLength << endl;
1246  os << indent << "GridlineZLength: " << this->GridlineZLength << endl;
1247
1248  os << indent << "DrawInnerGridpolys: " << this->DrawGridpolys << endl;
1249  os << indent << "DrawInnerGridlines: " << this->DrawInnerGridlines << endl;
1250
1251  os << indent << "TickLocation: " << this->TickLocation << endl;
1252
1253  os << indent << "CalculateLabelOffset: " << this->CalculateLabelOffset << std::endl;
1254  os << indent << "CalculateTitleOffset: " << this->CalculateTitleOffset << std::endl;
1255
1256  os << indent << "LabelTextProperty: " << this->LabelTextProperty << endl;
1257  os << indent << "TitleTextProperty: " << this->TitleTextProperty << endl;
1258
1259  os << indent << "Use2DMode: " << this->Use2DMode << endl;
1260  os << indent << "SaveTitlePosition: " << this->SaveTitlePosition << endl;
1261  os << indent << "VerticalOffsetXTitle2D" << this->VerticalOffsetXTitle2D << endl;
1262  os << indent << "HorizontalOffsetYTitle2D" << this->HorizontalOffsetYTitle2D << endl;
1263  os << indent << "LastMinDisplayCoordinates: ("
1264     << this->LastMinDisplayCoordinate[0] << ", "
1265     << this->LastMinDisplayCoordinate[1] << ", "
1266     << this->LastMinDisplayCoordinate[2] << ")" << endl;
1267  os << indent << "LastMaxDisplayCoordinates: ("
1268     << this->LastMaxDisplayCoordinate[0] << ", "
1269     << this->LastMaxDisplayCoordinate[1] << ", "
1270     << this->LastMaxDisplayCoordinate[2] << ")" << endl;
1271  }
1272
1273// **************************************************************************
1274// Sets text string for label vectors.  Allocates memory if necessary.
1275// **************************************************************************
1276void vtkRpAxisActor::SetLabels(vtkStringArray *labels)
1277{
1278  //
1279  // If the number of labels has changed, re-allocate the correct
1280  // amount of memory.
1281  //
1282  int i, numLabels = labels->GetNumberOfValues();
1283  if (numLabels < 0)
1284    {
1285    vtkErrorMacro(<< "Number of labels " << numLabels << " is invalid");
1286    return;
1287    }
1288  if (this->NumberOfLabelsBuilt != numLabels)
1289    {
1290    if (this->LabelMappers != NULL)
1291      {
1292      for (i = 0; i < this->NumberOfLabelsBuilt; i++)
1293        {
1294        this->LabelVectors[i]->Delete();
1295        this->LabelMappers[i]->Delete();
1296        this->LabelActors[i]->Delete();
1297        this->LabelActors2D[i]->Delete();
1298        }
1299      delete [] this->LabelVectors;
1300      delete [] this->LabelMappers;
1301      delete [] this->LabelActors;
1302      delete [] this->LabelActors2D;
1303      }
1304
1305    this->LabelVectors = new vtkVectorText * [numLabels];
1306    this->LabelMappers = new vtkPolyDataMapper * [numLabels];
1307    this->LabelActors  = new vtkRpAxisFollower * [numLabels];
1308    this->LabelActors2D = new vtkTextActor * [numLabels];
1309
1310    for (i = 0; i < numLabels; i++)
1311      {
1312      this->LabelVectors[i] = vtkVectorText::New();
1313      this->LabelMappers[i] = vtkPolyDataMapper::New();
1314      this->LabelMappers[i]->SetInputConnection(
1315        this->LabelVectors[i]->GetOutputPort());
1316      this->LabelActors[i] = vtkRpAxisFollower::New();
1317      this->LabelActors[i]->SetAxis(this);
1318      this->LabelActors[i]->SetMapper(this->LabelMappers[i]);
1319      this->LabelActors[i]->SetEnableDistanceLOD(0);
1320      this->LabelActors[i]->GetProperty()->SetAmbient(1.);
1321      this->LabelActors[i]->GetProperty()->SetDiffuse(0.);
1322      this->LabelActors[i]->GetProperty()->SetColor(this->LabelTextProperty->GetColor());
1323      this->LabelActors[i]->GetProperty()->SetOpacity(this->LabelTextProperty->GetOpacity());
1324      this->LabelActors2D[i] = vtkTextActor::New();
1325      }
1326    }
1327
1328  //
1329  // Set the label vector text.
1330  //
1331  for (i = 0; i < numLabels; i++)
1332    {
1333    this->LabelVectors[i]->SetText(labels->GetValue(i).c_str());
1334    this->LabelActors2D[i]->SetInput(this->LabelVectors[i]->GetText());
1335    }
1336  this->NumberOfLabelsBuilt = numLabels;
1337  this->LabelBuildTime.Modified();
1338}
1339
1340// **************************************************************************
1341// Creates Poly data (lines) from tickmarks (minor/major), gridlines, and axis.
1342// **************************************************************************
1343void vtkRpAxisActor::SetAxisPointsAndLines()
1344{
1345  vtkPoints *pts = vtkPoints::New();
1346  vtkCellArray *lines = vtkCellArray::New();
1347  vtkCellArray *gridlines = vtkCellArray::New();
1348  vtkCellArray *innerGridlines = vtkCellArray::New();
1349  vtkCellArray *polys = vtkCellArray::New();
1350  this->AxisLines->SetPoints(pts);
1351  this->AxisLines->SetLines(lines);
1352  this->Gridlines->SetPoints(this->GridlinePts);
1353  this->Gridlines->SetLines(gridlines);
1354  this->InnerGridlines->SetPoints(this->InnerGridlinePts);
1355  this->InnerGridlines->SetLines(innerGridlines);
1356  this->Gridpolys->SetPoints(this->GridpolyPts);
1357  this->Gridpolys->SetPolys(polys);
1358  pts->Delete();
1359  lines->Delete();
1360  gridlines->Delete();
1361  innerGridlines->Delete();
1362  polys->Delete();
1363  int i, numMinorTickPts, numGridlines, numInnerGridlines, numMajorTickPts, numGridpolys, numLines;
1364  vtkIdType ptIds[2];
1365  vtkIdType polyPtIds[4];
1366
1367  if (this->TickVisibility)
1368    {
1369    if (this->MinorTicksVisible)
1370      {
1371      // In 2D mode, the minorTickPts for yz portion or xz portion have been removed.
1372      numMinorTickPts = this->MinorTickPts->GetNumberOfPoints();
1373      for (i = 0; i < numMinorTickPts; i++)
1374        {
1375        pts->InsertNextPoint(this->MinorTickPts->GetPoint(i));
1376        }
1377      }
1378    numMajorTickPts = this->MajorTickPts->GetNumberOfPoints();
1379    if (this->Use2DMode == 0)
1380      {
1381      for (i = 0; i < numMajorTickPts; i++)
1382        {
1383        pts->InsertNextPoint(this->MajorTickPts->GetPoint(i));
1384        }
1385      }
1386    else
1387      {
1388      // In 2D mode, we don't need the pts for the xz portion or yz portion of the major tickmarks
1389      // majorTickPts not modified because all points are used for labels' positions.
1390      for (i = 0; i < numMajorTickPts; i+=4)
1391        {
1392        pts->InsertNextPoint(this->MajorTickPts->GetPoint(i));
1393        pts->InsertNextPoint(this->MajorTickPts->GetPoint(i+1));
1394        }
1395      }
1396    }
1397
1398  // create lines
1399  numLines = pts->GetNumberOfPoints() / 2;
1400  for (i=0; i < numLines; i++)
1401    {
1402    ptIds[0] = 2*i;
1403    ptIds[1] = 2*i + 1;
1404    lines->InsertNextCell(2, ptIds);
1405    }
1406
1407  if (this->AxisVisibility)
1408    {
1409    //first axis point
1410    ptIds[0] = pts->InsertNextPoint(this->Point1Coordinate->GetValue());
1411    //last axis point
1412    ptIds[1] = pts->InsertNextPoint(this->Point2Coordinate->GetValue());
1413    lines->InsertNextCell(2, ptIds);
1414    }
1415  // create grid lines
1416  if (this->DrawGridlines && this->AxisOnOrigin == 0)
1417    {
1418    numGridlines = this->GridlinePts->GetNumberOfPoints()/2;
1419    int start =
1420        (this->DrawGridlinesLocation == 0 || this->DrawGridlinesLocation == 1)
1421        ? 0 : 1;
1422    int increment = (this->DrawGridlinesLocation == 0) ? 1 : 2;
1423    for (i = start; i < numGridlines; i+=increment)
1424      {
1425      ptIds[0] = 2*i;
1426      ptIds[1] = 2*i + 1;
1427      gridlines->InsertNextCell(2, ptIds);
1428      }
1429    }
1430
1431  // create inner grid lines
1432  if (this->DrawInnerGridlines && this->AxisOnOrigin == 0)
1433    {
1434    numInnerGridlines = this->InnerGridlinePts->GetNumberOfPoints()/2;
1435    for (i=0; i < numInnerGridlines; i++)
1436      {
1437      ptIds[0] = 2*i;
1438      ptIds[1] = 2*i + 1;
1439      innerGridlines->InsertNextCell(2, ptIds);
1440      }
1441    }
1442
1443  // create polys (grid polys)
1444  if (this->DrawGridpolys && this->AxisOnOrigin == 0)
1445    {
1446    numGridpolys = this->GridpolyPts->GetNumberOfPoints()/4;
1447    for (i = 0; i < numGridpolys; i++)
1448      {
1449      polyPtIds[0] = 4*i;
1450      polyPtIds[1] = 4*i + 1;
1451      polyPtIds[2] = 4*i + 2;
1452      polyPtIds[3] = 4*i + 3;
1453      polys->InsertNextCell(4,polyPtIds);
1454      }
1455    }
1456}
1457
1458// *********************************************************************
1459// Returns true if any tick vis attribute has changed since last check.
1460// *********************************************************************
1461bool vtkRpAxisActor::TickVisibilityChanged()
1462{
1463  bool retVal = (this->TickVisibility != this->LastTickVisibility) ||
1464                (this->DrawGridlines != this->LastDrawGridlines)   ||
1465                (this->MinorTicksVisible != this->LastMinorTicksVisible);
1466
1467  this->LastTickVisibility = this->TickVisibility;
1468  this->LastDrawGridlines = this->DrawGridlines;
1469  this->LastMinorTicksVisible = this->MinorTicksVisible;
1470
1471  return retVal;
1472}
1473
1474// *********************************************************************
1475// Set the bounds for this actor to use.  Sets timestamp BoundsModified.
1476// *********************************************************************
1477void
1478vtkRpAxisActor::SetBounds(const double b[6])
1479{
1480  if ((this->Bounds[0] != b[0]) ||
1481      (this->Bounds[1] != b[1]) ||
1482      (this->Bounds[2] != b[2]) ||
1483      (this->Bounds[3] != b[3]) ||
1484      (this->Bounds[4] != b[4]) ||
1485      (this->Bounds[5] != b[5]) )
1486    {
1487    for (int i = 0; i < 6; i++)
1488      {
1489      this->Bounds[i] = b[i];
1490      }
1491    this->BoundsTime.Modified();
1492    }
1493}
1494
1495// *********************************************************************
1496// Retrieves the bounds of this actor.
1497// *********************************************************************
1498void vtkRpAxisActor::
1499SetBounds(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax)
1500{
1501  if ((this->Bounds[0] != xmin) ||
1502      (this->Bounds[1] != xmax) ||
1503      (this->Bounds[2] != ymin) ||
1504      (this->Bounds[3] != ymax) ||
1505      (this->Bounds[4] != zmin) ||
1506      (this->Bounds[5] != zmax) )
1507    {
1508    this->Bounds[0] = xmin;
1509    this->Bounds[1] = xmax;
1510    this->Bounds[2] = ymin;
1511    this->Bounds[3] = ymax;
1512    this->Bounds[4] = zmin;
1513    this->Bounds[5] = zmax;
1514
1515    this->BoundsTime.Modified();
1516    }
1517}
1518
1519// *********************************************************************
1520// Retrieves the bounds of this actor.
1521// *********************************************************************
1522double* vtkRpAxisActor::GetBounds()
1523{
1524  return this->Bounds;
1525}
1526
1527// *********************************************************************
1528// Retrieves the bounds of this actor.
1529// *********************************************************************
1530
1531void vtkRpAxisActor::GetBounds(double b[6])
1532{
1533  for (int i = 0; i < 6; i++)
1534    {
1535    b[i] = this->Bounds[i];
1536    }
1537}
1538
1539// *********************************************************************
1540// Method:  vtkRpAxisActor::ComputeMaxLabelLength
1541// *********************************************************************
1542double vtkRpAxisActor::ComputeMaxLabelLength(const double vtkNotUsed(center)[3])
1543{
1544  double bounds[6];
1545  double xsize, ysize;
1546  vtkProperty *newProp = this->NewLabelProperty();
1547  double maxXSize = 0;
1548  double maxYSize = 0;
1549  for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
1550    {
1551    this->LabelActors[i]->SetCamera(this->Camera);
1552    this->LabelActors[i]->SetProperty(newProp);
1553    this->LabelActors[i]->GetMapper()->GetBounds(bounds);
1554    xsize = bounds[1] - bounds[0];
1555    ysize = bounds[3] - bounds[2];
1556    maxXSize = (xsize > maxXSize ? xsize : maxXSize);
1557    maxYSize = (ysize > maxYSize ? ysize : maxYSize);
1558    }
1559  newProp->Delete();
1560  return sqrt(maxXSize*maxXSize + maxYSize*maxYSize);
1561}
1562
1563// *********************************************************************
1564// Method:  vtkRpAxisActor::ComputeTitleLength
1565// *********************************************************************
1566double vtkRpAxisActor::ComputeTitleLength(const double vtkNotUsed(center)[3])
1567{
1568  double bounds[6];
1569  double xsize, ysize;
1570  double length;
1571
1572  this->TitleVector->SetText(this->Title);
1573  this->TitleActor->SetCamera(this->Camera);
1574  vtkProperty * newProp = this->NewTitleProperty();
1575  this->TitleActor->SetProperty(newProp);
1576  newProp->Delete();
1577  this->TitleActor->GetMapper()->GetBounds(bounds);
1578  xsize = bounds[1] - bounds[0];
1579  ysize = bounds[3] - bounds[2];
1580  length = sqrt(xsize*xsize + ysize*ysize);
1581
1582  return length;
1583}
1584
1585// *********************************************************************
1586void vtkRpAxisActor::SetLabelScale(const double s)
1587{
1588  for (int i=0; i < this->NumberOfLabelsBuilt; i++)
1589    {
1590    this->SetLabelScale(i, s);
1591    }
1592}
1593
1594// *********************************************************************
1595void vtkRpAxisActor::SetLabelScale(int label, const double s)
1596{
1597  this->LabelActors[label]->SetScale(s);
1598}
1599
1600// *********************************************************************
1601void vtkRpAxisActor::SetTitleScale(const double s)
1602{
1603  this->TitleActor->SetScale(s);
1604}
1605
1606// *********************************************************************
1607void vtkRpAxisActor::SetTitle(const char *t)
1608{
1609  if (this->Title == NULL && t == NULL)
1610    {
1611    return;
1612    }
1613  if (this->Title && (!strcmp(this->Title, t)))
1614    {
1615    return;
1616    }
1617  delete [] this->Title;
1618  if (t)
1619    {
1620    this->Title = new char[strlen(t)+1];
1621    strcpy(this->Title, t);
1622    }
1623  else
1624    {
1625    this->Title = NULL;
1626    }
1627  this->TitleTextTime.Modified();
1628  this->Modified();
1629}
1630
1631// ****************************************************************************
1632void vtkRpAxisActor::SetAxisLinesProperty(vtkProperty *prop)
1633{
1634  this->AxisLinesActor->SetProperty(prop);
1635  this->Modified();
1636}
1637
1638// ****************************************************************************
1639vtkProperty* vtkRpAxisActor::GetAxisLinesProperty()
1640{
1641  return this->AxisLinesActor->GetProperty();
1642}
1643
1644// ****************************************************************************
1645void vtkRpAxisActor::SetGridlinesProperty(vtkProperty *prop)
1646{
1647  this->GridlinesActor->SetProperty(prop);
1648  this->Modified();
1649}
1650
1651// ****************************************************************************
1652vtkProperty* vtkRpAxisActor::GetGridlinesProperty()
1653{
1654  return this->GridlinesActor->GetProperty();
1655}
1656
1657// ****************************************************************************
1658void vtkRpAxisActor::SetInnerGridlinesProperty(vtkProperty *prop)
1659{
1660  this->InnerGridlinesActor->SetProperty(prop);
1661  this->Modified();
1662}
1663
1664// ****************************************************************************
1665vtkProperty* vtkRpAxisActor::GetInnerGridlinesProperty()
1666{
1667  return this->InnerGridlinesActor->GetProperty();
1668}
1669
1670// ****************************************************************************
1671void vtkRpAxisActor::SetGridpolysProperty(vtkProperty *prop)
1672{
1673  this->GridpolysActor->SetProperty(prop);
1674  this->Modified();
1675}
1676
1677// ****************************************************************************
1678vtkProperty* vtkRpAxisActor::GetGridpolysProperty()
1679{
1680  return this->GridpolysActor->GetProperty();
1681}
1682
1683// ****************************************************************************
1684vtkProperty* vtkRpAxisActor::NewTitleProperty()
1685{
1686  vtkProperty *newProp = vtkProperty::New();
1687  newProp->DeepCopy(this->GetProperty());
1688  newProp->SetColor(this->TitleTextProperty->GetColor());
1689  // We pass the opacity in the line offset.
1690  //newProp->SetOpacity(this->TitleTextProperty->GetLineOffset());
1691  return newProp;
1692}
1693
1694// ****************************************************************************
1695vtkProperty* vtkRpAxisActor::NewLabelProperty()
1696{
1697  vtkProperty *newProp = vtkProperty::New();
1698  newProp->DeepCopy(this->GetProperty());
1699  newProp->SetColor(this->LabelTextProperty->GetColor());
1700  // We pass the opacity in the line offset.
1701  //newProp->SetOpacity(this->LabelTextProperty->GetLineOffset());
1702  return newProp;
1703}
1704
1705
1706// ****************************************************************************
1707double vtkRpAxisActor::GetDeltaMajor(int axis){
1708  if(axis>=0 && axis<=2)
1709    {
1710    return (this->DeltaMajor[axis]);
1711    }
1712  return 0;
1713}
1714
1715void vtkRpAxisActor::SetDeltaMajor(int axis, double value){
1716  if(axis>=0 && axis<=2)
1717    {
1718    this->DeltaMajor[axis] = value;
1719    }
1720}
1721
1722// ****************************************************************************
1723double vtkRpAxisActor::GetMajorStart(int axis){
1724  if(axis>=0 && axis<=2)
1725    {
1726    return (this->MajorStart[axis]);
1727    }
1728  return 0;
1729}
1730
1731// ****************************************************************************
1732void vtkRpAxisActor::SetMajorStart(int axis, double value){
1733  if(axis>=0 && axis<=2)
1734    {
1735    this->MajorStart[axis] = value;
1736    }
1737}
1738
1739// ****************************************************************************
1740bool vtkRpAxisActor::BoundsDisplayCoordinateChanged(vtkViewport *viewport)
1741{
1742  double transMinPt[3], transMaxPt[3];
1743  viewport->SetWorldPoint(this->Bounds[0], this->Bounds[2], this->Bounds[4], 1.0);
1744  viewport->WorldToDisplay();
1745  viewport->GetDisplayPoint(transMinPt);
1746  viewport->SetWorldPoint(this->Bounds[1], this->Bounds[3], this->Bounds[5], 1.0);
1747  viewport->WorldToDisplay();
1748  viewport->GetDisplayPoint(transMaxPt);
1749
1750  if( this->LastMinDisplayCoordinate[0] != transMinPt[0]
1751      || this->LastMinDisplayCoordinate[1] != transMinPt[1]
1752      || this->LastMinDisplayCoordinate[2] != transMinPt[2]
1753      || this->LastMaxDisplayCoordinate[0] != transMaxPt[0]
1754      || this->LastMaxDisplayCoordinate[1] != transMaxPt[1]
1755      || this->LastMaxDisplayCoordinate[2] != transMaxPt[2] )
1756    {
1757    int i = 0;
1758    for( i=0 ; i<3 ; ++i )
1759      {
1760      this->LastMinDisplayCoordinate[i] = transMinPt[i];
1761      this->LastMaxDisplayCoordinate[i] = transMaxPt[i];
1762      }
1763    return true;
1764    }
1765
1766  return false;
1767}
1768//---------------------------------------------------------------------------
1769// endpoint-related methods
1770vtkCoordinate* vtkRpAxisActor::GetPoint1Coordinate()
1771{
1772  vtkDebugMacro(<< this->GetClassName() << " (" << this
1773                << "): returning Point1 Coordinate address "
1774                << this->Point1Coordinate );
1775  return this->Point1Coordinate;
1776}
1777
1778//---------------------------------------------------------------------------
1779vtkCoordinate* vtkRpAxisActor::GetPoint2Coordinate()
1780{
1781  vtkDebugMacro(<< this->GetClassName() << " (" << this
1782                << "): returning Point2 Coordinate address "
1783                << this->Point2Coordinate );
1784  return this->Point2Coordinate;
1785}
1786
1787//---------------------------------------------------------------------------
1788void vtkRpAxisActor::SetPoint1(double x, double y, double z)
1789{
1790  this->Point1Coordinate->SetValue(x, y, z);
1791}
1792
1793//---------------------------------------------------------------------------
1794void vtkRpAxisActor::SetPoint2(double x, double y, double z)
1795{
1796  this->Point2Coordinate->SetValue(x, y, z);
1797}
1798
1799//---------------------------------------------------------------------------
1800double* vtkRpAxisActor::GetPoint1()
1801{
1802  return this->Point1Coordinate->GetValue();
1803}
1804
1805//---------------------------------------------------------------------------
1806double* vtkRpAxisActor::GetPoint2()
1807{
1808  return this->Point2Coordinate->GetValue();
1809}
1810// **************************************************************************
1811// Creates points for ticks (minor, major, gridlines) in correct position
1812// for a generic axis.
1813// **************************************************************************
1814bool vtkRpAxisActor::BuildTickPoints(double p1[3], double p2[3], bool force)
1815{
1816  // Prevent any unwanted computation
1817  if (!force && (this->AxisPosition == this->LastAxisPosition) &&
1818      (this->TickLocation == this->LastTickLocation ) &&
1819      (this->BoundsTime.GetMTime() < this->BuildTime.GetMTime()) &&
1820      (this->Point1Coordinate->GetMTime() < this->BuildTickPointsTime.GetMTime()) &&
1821      (this->Point2Coordinate->GetMTime() < this->BuildTickPointsTime.GetMTime()) &&
1822      (this->Range[0] == this->LastRange[0]) &&
1823      (this->Range[1] == this->LastRange[1]))
1824    {
1825    return false;
1826    }
1827
1828  // Local tmp vars
1829  double uPointInside[3], vPointInside[3], uPointOutside[3], vPointOutside[3];
1830  double gridPointClosest[3], gridPointFarest[3], gridPointU[3], gridPointV[3];
1831  double innerGridPointClosestU[3], innerGridPointClosestV[3];
1832  double innerGridPointFarestU[3], innerGridPointFarestV[3];
1833  double deltaVector[3];
1834  double axisLength, axisShift, rangeScale, nbIterationAsDouble;
1835  int nbTicks, i, nbIteration, uIndex, vIndex;
1836  uIndex = vIndex = 0;
1837  bool hasOrthogonalVectorBase =
1838      (this->AxisBaseForX[0] == 1 && this->AxisBaseForX[1] == 0 && this->AxisBaseForX[2] == 0
1839       && this->AxisBaseForY[0] == 0 && this->AxisBaseForY[1] == 1 && this->AxisBaseForY[2] == 0
1840       && this->AxisBaseForZ[0] == 0 && this->AxisBaseForZ[1] == 0 && this->AxisBaseForZ[2] == 1);
1841
1842  // Reset previous objects
1843  this->MinorTickPts->Reset();
1844  this->MajorTickPts->Reset();
1845  this->GridlinePts->Reset();
1846  this->InnerGridlinePts->Reset();
1847  this->GridpolyPts->Reset();
1848
1849  // As we assume that the Axis is not necessery alined to the absolute X/Y/Z
1850  // axis, we will convert the absolut XYZ information to relative one
1851  // using a base composed as follow (axis, u, v)
1852  double uGridLength, vGridLength;
1853  uGridLength = vGridLength = 0;
1854  double *axisVector, *uVector, *vVector;
1855  axisVector = uVector = vVector = NULL;
1856  int uMult = vtkRpAxisActorMultiplierTable1[this->AxisPosition];
1857  int vMult = vtkRpAxisActorMultiplierTable2[this->AxisPosition];
1858
1859  switch(this->AxisType)
1860    {
1861  case VTK_AXIS_TYPE_X:
1862    uGridLength = this->GridlineYLength;
1863    vGridLength = this->GridlineZLength;
1864    axisVector = this->AxisBaseForX;
1865    uVector = this->AxisBaseForY;
1866    vVector = this->AxisBaseForZ;
1867    uIndex = 1; vIndex = 2;
1868    break;
1869  case VTK_AXIS_TYPE_Y:
1870    uGridLength = this->GridlineXLength;
1871    vGridLength = this->GridlineZLength;
1872    uVector = this->AxisBaseForX;
1873    axisVector = this->AxisBaseForY;
1874    vVector = this->AxisBaseForZ;
1875    uIndex = 0; vIndex = 2;
1876    break;
1877  case VTK_AXIS_TYPE_Z:
1878    uGridLength = this->GridlineXLength;
1879    vGridLength = this->GridlineYLength;
1880    uVector = this->AxisBaseForX;
1881    vVector = this->AxisBaseForY;
1882    axisVector = this->AxisBaseForZ;
1883    uIndex = 0; vIndex = 1;
1884    break;
1885    }
1886
1887  // **************************************************************************
1888  // Build Minor Ticks
1889  // **************************************************************************
1890  {
1891  // - Initialize all points to be on the axis
1892  for(i=0;i<3;i++)
1893    {
1894    uPointInside[i] = vPointInside[i] = uPointOutside[i] = vPointOutside[i] = p1[i];
1895    deltaVector[i] = (p2[i] - p1[i]);
1896    }
1897  axisLength = vtkMath::Norm(deltaVector);
1898  rangeScale = axisLength/(this->Range[1] - this->Range[0]);
1899
1900  // - Reduce the deltaVector to correspond to a tick step
1901  vtkMath::Normalize(deltaVector);
1902  for(i=0;i<3;i++)
1903    {
1904    deltaVector[i] *= this->DeltaMinor;
1905    }
1906
1907  // - Move outside points if needed (Axis -> Outside)
1908  if (this->TickLocation == VTK_TICKS_OUTSIDE || this->TickLocation == VTK_TICKS_BOTH)
1909    {
1910    for(i=0;i<3;i++)
1911      {
1912      uPointOutside[i] += uVector[i] * uMult * this->MinorTickSize;
1913      vPointOutside[i] += vVector[i] * vMult * this->MinorTickSize;
1914      }
1915    }
1916
1917  // - Move inside points if needed (Axis -> Inside)
1918  if (this->TickLocation == VTK_TICKS_INSIDE || this->TickLocation == VTK_TICKS_BOTH)
1919    {
1920    for(i=0;i<3;i++)
1921      {
1922      uPointInside[i] -= uVector[i] * uMult * this->MinorTickSize;
1923      vPointInside[i] -= vVector[i] * vMult * this->MinorTickSize;
1924      }
1925    }
1926
1927  // - Add the initial shift if any
1928  axisShift = (this->MinorRangeStart - this->Range[0])*rangeScale;
1929  for(i=0;i<3;i++)
1930    {
1931    uPointInside[i] += axisVector[i] * axisShift;
1932    vPointInside[i] += axisVector[i] * axisShift;
1933    uPointOutside[i] += axisVector[i] * axisShift;
1934    vPointOutside[i] += axisVector[i] * axisShift;
1935    }
1936
1937  // - Insert tick points along the axis using the deltaVector
1938  nbIterationAsDouble = axisLength / vtkMath::Norm(deltaVector);
1939  nbIteration = vtkMath::Floor(nbIterationAsDouble+2*DBL_EPSILON);
1940  nbIteration = (nbIteration < VTK_MAX_TICKS) ? nbIteration : VTK_MAX_TICKS;
1941  for (nbTicks = 0; nbTicks < nbIteration; nbTicks++)
1942    {
1943    // axis/u side
1944    this->MinorTickPts->InsertNextPoint(uPointInside);
1945    this->MinorTickPts->InsertNextPoint(uPointOutside);
1946    vtkMath::Add(deltaVector, uPointInside, uPointInside);
1947    vtkMath::Add(deltaVector, uPointOutside, uPointOutside);
1948    if( this->Use2DMode == 0 )
1949      {
1950      // axis/v side
1951      this->MinorTickPts->InsertNextPoint(vPointInside);
1952      this->MinorTickPts->InsertNextPoint(vPointOutside);
1953      vtkMath::Add(deltaVector, vPointInside, vPointInside);
1954      vtkMath::Add(deltaVector, vPointOutside, vPointOutside);
1955      }
1956    }
1957  }
1958  // **************************************************************************
1959  // Build Gridline + GridPoly points + InnerGrid (Only for Orthonormal base)
1960  // **************************************************************************
1961  {
1962  // - Initialize all points to be on the axis
1963  for(i=0;i<3;i++)
1964    {
1965    gridPointClosest[i] = gridPointFarest[i] = gridPointU[i] = gridPointV[i] = p1[i];
1966    deltaVector[i] = (p2[i] - p1[i]);
1967    }
1968
1969  // - Reduce the deltaVector to correspond to a major tick step
1970  vtkMath::Normalize(deltaVector);
1971  for(i=0;i<3;i++)
1972    {
1973    deltaVector[i] *= this->DeltaMajor[this->AxisType];
1974    }
1975
1976  // - Move base points
1977  for(i=0;i<3;i++)
1978    {
1979    gridPointU[i] -= uVector[i] * uMult * uGridLength;
1980    gridPointV[i] -= vVector[i] * vMult * vGridLength;
1981    gridPointFarest[i] -= uVector[i] * uMult * uGridLength + vVector[i] * vMult * vGridLength;
1982    }
1983
1984  // - Add the initial shift if any
1985  axisShift = (this->MajorRangeStart - this->Range[0])*rangeScale;
1986  for(i=0;i<3;i++)
1987    {
1988    gridPointU[i] += axisVector[i] * axisShift;
1989    gridPointV[i] += axisVector[i] * axisShift;
1990    gridPointFarest[i] += axisVector[i] * axisShift;
1991    gridPointClosest[i] += axisVector[i] * axisShift;
1992    }
1993
1994  // - Insert Gridlines points along the axis using the DeltaMajor vector
1995  nbIterationAsDouble = (axisLength - axisShift) / vtkMath::Norm(deltaVector);
1996  nbIteration = vtkMath::Floor(nbIterationAsDouble+2*FLT_EPSILON) + 1;
1997  nbIteration = (nbIteration < VTK_MAX_TICKS) ? nbIteration : VTK_MAX_TICKS;
1998  for (nbTicks = 0; nbTicks < nbIteration; nbTicks++)
1999    {
2000    // Closest U
2001    this->GridlinePts->InsertNextPoint(gridPointClosest);
2002    this->GridlinePts->InsertNextPoint(gridPointU);
2003
2004    // Farest U
2005    this->GridlinePts->InsertNextPoint(gridPointFarest);
2006    this->GridlinePts->InsertNextPoint(gridPointU);
2007
2008    // Closest V
2009    this->GridlinePts->InsertNextPoint(gridPointClosest);
2010    this->GridlinePts->InsertNextPoint(gridPointV);
2011
2012    // Farest V
2013    this->GridlinePts->InsertNextPoint(gridPointFarest);
2014    this->GridlinePts->InsertNextPoint(gridPointV);
2015
2016    // PolyPoints
2017    this->GridpolyPts->InsertNextPoint(gridPointClosest);
2018    this->GridpolyPts->InsertNextPoint(gridPointU);
2019    this->GridpolyPts->InsertNextPoint(gridPointFarest);
2020    this->GridpolyPts->InsertNextPoint(gridPointV);
2021
2022    // Move forward along the axis
2023    for(i=0;i<3;i++)
2024      {
2025      gridPointClosest[i] += deltaVector[i];
2026      gridPointU[i] += deltaVector[i];
2027      gridPointFarest[i] += deltaVector[i];
2028      gridPointV[i] += deltaVector[i];
2029      }
2030    }
2031
2032  // - Insert InnerGridLines points
2033
2034  // We can only handle inner grid line with orthonormal base, otherwise
2035  // we would need to change the API of AxisActor which we don't want for
2036  // backward compatibility.
2037  if(hasOrthogonalVectorBase)
2038    {
2039    double axis, u, v;
2040    axis = this->MajorStart[this->AxisType];
2041    innerGridPointClosestU[vIndex] = this->GetBounds()[vIndex*2];
2042    innerGridPointFarestU[vIndex] = this->GetBounds()[vIndex*2+1];
2043    innerGridPointClosestV[uIndex] = this->GetBounds()[uIndex*2];
2044    innerGridPointFarestV[uIndex] = this->GetBounds()[uIndex*2+1];
2045    while (axis <= p2[this->AxisType])
2046        {
2047        innerGridPointClosestU[this->AxisType]
2048            = innerGridPointClosestV[this->AxisType]
2049            = innerGridPointFarestU[this->AxisType]
2050            = innerGridPointFarestV[this->AxisType]
2051            = axis;
2052
2053        // u lines
2054        u = this->MajorStart[uIndex];
2055        while (u <= p2[uIndex] && this->DeltaMajor[uIndex] > 0)
2056          {
2057          innerGridPointClosestU[uIndex]
2058              = innerGridPointFarestU[uIndex]
2059              = u;
2060          this->InnerGridlinePts->InsertNextPoint(innerGridPointClosestU);
2061          this->InnerGridlinePts->InsertNextPoint(innerGridPointFarestU);
2062          u += this->DeltaMajor[uIndex];
2063          }
2064
2065        // v lines
2066        v = this->MajorStart[vIndex];
2067        while (v <= p2[vIndex] && this->DeltaMajor[vIndex] > 0)
2068          {
2069          innerGridPointClosestV[vIndex]
2070              = innerGridPointFarestV[vIndex]
2071              = v;
2072          this->InnerGridlinePts->InsertNextPoint(innerGridPointClosestV);
2073          this->InnerGridlinePts->InsertNextPoint(innerGridPointFarestV);
2074          v += this->DeltaMajor[vIndex];
2075          }
2076
2077        axis += this->DeltaMajor[this->AxisType];
2078        }
2079    }
2080  }
2081  // **************************************************************************
2082  // Build Major ticks
2083  // **************************************************************************
2084  {
2085  // Delta vector is already initialized with the Major tick scale
2086  // - Initialize all points to be on the axis
2087  for(i=0;i<3;i++)
2088    {
2089    uPointInside[i] = vPointInside[i] = uPointOutside[i] = vPointOutside[i] = p1[i];
2090    }
2091
2092  // - Move outside points if needed (Axis -> Outside)
2093  if (this->TickLocation == VTK_TICKS_OUTSIDE || this->TickLocation == VTK_TICKS_BOTH)
2094    {
2095    for(i=0;i<3;i++)
2096      {
2097      uPointOutside[i] += uVector[i] * uMult * this->MajorTickSize;
2098      vPointOutside[i] += vVector[i] * vMult * this->MajorTickSize;
2099      }
2100    }
2101
2102  // - Move inside points if needed (Axis -> Inside)
2103  if (this->TickLocation == VTK_TICKS_INSIDE || this->TickLocation == VTK_TICKS_BOTH)
2104    {
2105    for(i=0;i<3;i++)
2106      {
2107      uPointInside[i] -= uVector[i] * uMult * this->MajorTickSize;
2108      vPointInside[i] -= vVector[i] * vMult * this->MajorTickSize;
2109      }
2110    }
2111
2112  // - Add the initial shift if any
2113  for(i=0;i<3;i++)
2114    {
2115    uPointInside[i] += axisVector[i] * axisShift;
2116    vPointInside[i] += axisVector[i] * axisShift;
2117    uPointOutside[i] += axisVector[i] * axisShift;
2118    vPointOutside[i] += axisVector[i] * axisShift;
2119    }
2120
2121  // - Insert tick points along the axis using the deltaVector
2122  for (nbTicks = 0; nbTicks < nbIteration; nbTicks++)
2123    {
2124    // axis/u side
2125    this->MajorTickPts->InsertNextPoint(uPointInside);
2126    this->MajorTickPts->InsertNextPoint(uPointOutside);
2127    vtkMath::Add(deltaVector, uPointInside, uPointInside);
2128    vtkMath::Add(deltaVector, uPointOutside, uPointOutside);
2129
2130    // axis/v side
2131    this->MajorTickPts->InsertNextPoint(vPointInside);
2132    this->MajorTickPts->InsertNextPoint(vPointOutside);
2133    vtkMath::Add(deltaVector, vPointInside, vPointInside);
2134    vtkMath::Add(deltaVector, vPointOutside, vPointOutside);
2135    }
2136  }
2137
2138  this->BuildTickPointsTime.Modified();
2139  this->LastTickLocation = this->TickLocation;
2140  return true;
2141}
Note: See TracBrowser for help on using the repository browser.