source: branches/blt4/packages/vizservers/vtkvis/vtkRpAxisActor.cpp

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