source: vtkvis/trunk/vtkRpAxisActor.cpp @ 4607

Last change on this file since 4607 was 3549, checked in by ldelgass, 12 years ago

Fix for oversized axis labels. AutoScale? computation in CubeAxesActor? happens
before label positions may be rebuilt (when rendering each AxisActor?), so
recompute AutoScale? in AxisActor? when rebuilding the axis.

  • Property svn:eol-style set to native
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.