]> SALOME platform Git repositories - modules/visu.git/blob - src/PIPELINE/VISU_XYPlotActor.cxx
Salome HOME
bbdabd9b59074a7447657202a7ae2a518aa5fad1
[modules/visu.git] / src / PIPELINE / VISU_XYPlotActor.cxx
1 /*=========================================================================
2
3   Program:   Visualization Toolkit
4   Module:    $RCSfile$
5
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "VISU_XYPlotActor.hxx"
16
17 #include "vtkAppendPolyData.h"
18 #include "vtkAxisActor2D.h"
19 #include "vtkCellArray.h"
20 #include "vtkDataObjectCollection.h"
21 #include "vtkDataSetCollection.h"
22 #include "vtkFieldData.h"
23 #include "vtkDoubleArray.h"
24 #include "vtkGlyph2D.h"
25 #include "vtkGlyphSource2D.h"
26 #include "vtkIntArray.h"
27 #include "vtkLegendBoxActor.h"
28 #include "vtkMath.h"
29 #include "vtkObjectFactory.h"
30 #include "vtkPlane.h"
31 #include "vtkPlanes.h"
32 #include "vtkPointData.h"
33 #include "vtkPolyData.h"
34 #include "vtkPolyDataMapper2D.h"
35 #include "vtkProperty2D.h"
36 #include "vtkTextMapper.h"
37 #include "vtkTextProperty.h"
38 #include "vtkViewport.h"
39 #include "vtkTransformPolyDataFilter.h" // RKV
40 #include "vtkTransform.h" // RKV
41
42 #define VTK_MAX_PLOTS 50
43
44 #if !defined(VTK_XVERSION)
45 #define VTK_XVERSION (VTK_MAJOR_VERSION<<16)+(VTK_MINOR_VERSION<<8)+(VTK_BUILD_VERSION)
46 #endif
47
48 using namespace std;
49
50 vtkCxxRevisionMacro(VISU_XYPlotActor, "$Revision$");
51 vtkStandardNewMacro(VISU_XYPlotActor);
52
53 vtkCxxSetObjectMacro(VISU_XYPlotActor,TitleTextProperty,vtkTextProperty);
54 vtkCxxSetObjectMacro(VISU_XYPlotActor,AxisLabelTextProperty,vtkTextProperty);
55 vtkCxxSetObjectMacro(VISU_XYPlotActor,AxisTitleTextProperty,vtkTextProperty);
56
57 //----------------------------------------------------------------------------
58 // Instantiate object
59 VISU_XYPlotActor::VISU_XYPlotActor()
60 {
61   this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
62   this->PositionCoordinate->SetValue(0.25,0.25);
63   this->Position2Coordinate->SetValue(0.5, 0.5);
64
65   this->InputList = vtkDataSetCollection::New();
66   this->SelectedInputScalars = NULL;
67   this->SelectedInputScalarsComponent = vtkIntArray::New();
68   this->DataObjectInputList = vtkDataObjectCollection::New();
69
70   this->Title = NULL;
71   this->XTitle = new char[7];
72   sprintf(this->XTitle,"%s","X Axis");
73   this->YTitle = new char[7];
74   sprintf(this->YTitle,"%s","Y Axis");
75
76   this->XValues = VTK_XYPLOT_INDEX;
77   this->PlotLocation = VISU_XYPLOT_BOTTOM; // RKV
78
79   this->NumberOfXLabels = 5;
80   this->NumberOfYLabels = 5;
81
82   this->TitleTextProperty = vtkTextProperty::New();
83   this->TitleTextProperty->SetBold(1);
84   this->TitleTextProperty->SetItalic(1);
85   this->TitleTextProperty->SetShadow(1);
86   this->TitleTextProperty->SetFontFamilyToArial();
87
88   this->AxisLabelTextProperty = vtkTextProperty::New();
89   this->AxisLabelTextProperty->ShallowCopy(this->TitleTextProperty);
90
91   this->AxisTitleTextProperty = vtkTextProperty::New();
92   this->AxisTitleTextProperty->ShallowCopy(this->AxisLabelTextProperty);
93
94   this->LabelFormat = new char[8]; 
95   sprintf(this->LabelFormat,"%s","%-#6.3g");
96
97   this->Logx = 0;
98   
99   this->XRange[0] = 0.0;
100   this->XRange[1] = 0.0;
101   this->YRange[0] = 0.0;
102   this->YRange[1] = 0.0;
103
104   this->Border = 5;
105   this->PlotLines = 1;
106   this->PlotPoints = 0;
107   this->PlotCurveLines = 0;
108   this->PlotCurvePoints = 0;
109   this->ExchangeAxes = 0;
110   this->ReverseXAxis = 0;
111   this->ReverseYAxis = 0;
112
113   this->TitleMapper = vtkTextMapper::New();
114   this->TitleActor = vtkActor2D::New();
115   this->TitleActor->SetMapper(this->TitleMapper);
116   this->TitleActor->GetPositionCoordinate()->SetCoordinateSystemToViewport();
117
118   this->XAxis = vtkAxisActor2D::New();
119   this->XAxis->GetPositionCoordinate()->SetCoordinateSystemToViewport();
120   this->XAxis->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
121   this->XAxis->SetProperty(this->GetProperty());
122
123   this->YAxis = vtkAxisActor2D::New();
124   this->YAxis->GetPositionCoordinate()->SetCoordinateSystemToViewport();
125   this->YAxis->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
126   this->YAxis->SetProperty(this->GetProperty());
127   
128   this->NumberOfInputs = 0;
129   this->PlotData = NULL;
130   this->PlotGlyph = NULL;
131   this->PlotAppend = NULL;
132   this->PlotTransform = NULL; // RKV
133   this->PlotMapper = NULL;
134   this->PlotActor = NULL;
135
136   this->ViewportCoordinate[0] = 0.0;
137   this->ViewportCoordinate[1] = 0.0;
138   this->PlotCoordinate[0] = 0.0;
139   this->PlotCoordinate[1] = 0.0;
140
141   this->DataObjectPlotMode = VTK_XYPLOT_COLUMN;
142   this->XComponent = vtkIntArray::New();
143   this->XComponent->SetNumberOfValues(VTK_MAX_PLOTS);
144   this->YComponent = vtkIntArray::New();
145   this->YComponent->SetNumberOfValues(VTK_MAX_PLOTS);
146
147   this->LinesOn = vtkIntArray::New();
148   this->LinesOn->SetNumberOfValues(VTK_MAX_PLOTS);
149   this->PointsOn = vtkIntArray::New();
150   this->PointsOn->SetNumberOfValues(VTK_MAX_PLOTS);
151   for (int i=0; i<VTK_MAX_PLOTS; i++)
152     {
153     this->XComponent->SetValue(i,0);
154     this->YComponent->SetValue(i,0);
155     this->LinesOn->SetValue(i,this->PlotLines);
156     this->PointsOn->SetValue(i,this->PlotPoints);
157     }
158
159   this->Legend = 0;
160   this->LegendPosition[0] = 0.85;
161   this->LegendPosition[1] = 0.75;
162   this->LegendPosition2[0] = 0.15;
163   this->LegendPosition2[1] = 0.20;
164   this->LegendActor = vtkLegendBoxActor::New();
165   this->LegendActor->GetPositionCoordinate()->SetCoordinateSystemToViewport();
166   this->LegendActor->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
167   this->LegendActor->GetPosition2Coordinate()->SetReferenceCoordinate(NULL);
168   this->LegendActor->BorderOff();
169   this->LegendActor->SetNumberOfEntries(VTK_MAX_PLOTS); //initial allocation
170   this->GlyphSource = vtkGlyphSource2D::New();
171   this->GlyphSource->SetGlyphTypeToNone();
172   this->GlyphSource->DashOn();
173   this->GlyphSource->FilledOff();
174   this->GlyphSize = 0.020;
175
176   this->ClipPlanes = vtkPlanes::New();
177   vtkPoints *pts = vtkPoints::New();
178   pts->SetNumberOfPoints(4);
179   this->ClipPlanes->SetPoints(pts);
180   pts->Delete();
181   vtkDoubleArray *n = vtkDoubleArray::New();
182   n->SetNumberOfComponents(3);
183   n->SetNumberOfTuples(4);
184   this->ClipPlanes->SetNormals(n);
185   n->Delete();
186
187   this->CachedSize[0] = 0;
188   this->CachedSize[1] = 0;
189 }
190
191 //----------------------------------------------------------------------------
192 VISU_XYPlotActor::~VISU_XYPlotActor()
193 {
194   // Get rid of the list of array names.
195   int num = this->InputList->GetNumberOfItems();
196   if (this->SelectedInputScalars)
197     {
198     for (int i = 0; i < num; ++i)
199       {
200       if (this->SelectedInputScalars[i])
201         {
202         delete [] this->SelectedInputScalars[i];
203         this->SelectedInputScalars[i] = NULL;
204         }
205       }
206     delete [] this->SelectedInputScalars;
207     this->SelectedInputScalars = NULL;  
208     }
209   this->SelectedInputScalarsComponent->Delete();
210   this->SelectedInputScalarsComponent = NULL;
211
212   //  Now we can get rid of the inputs. 
213   this->InputList->Delete();
214   this->InputList = NULL;
215
216   this->DataObjectInputList->Delete();
217   this->DataObjectInputList = NULL;
218
219   this->TitleMapper->Delete();
220   this->TitleMapper = NULL;
221   this->TitleActor->Delete();
222   this->TitleActor = NULL;
223
224   this->SetTitle(0);
225   this->SetXTitle(0);
226   this->SetYTitle(0);
227   this->SetLabelFormat(0);
228
229   this->XAxis->Delete();
230   this->YAxis->Delete();
231   
232   this->InitializeEntries();
233
234   this->LegendActor->Delete();
235   this->GlyphSource->Delete();
236   this->ClipPlanes->Delete();
237   
238   this->XComponent->Delete();
239   this->YComponent->Delete();
240
241   this->LinesOn->Delete();
242   this->PointsOn->Delete();
243
244   this->SetTitleTextProperty(NULL);
245   this->SetAxisLabelTextProperty(NULL);
246   this->SetAxisTitleTextProperty(NULL);
247 }
248
249 //----------------------------------------------------------------------------
250 void VISU_XYPlotActor::InitializeEntries()
251 {
252   if ( this->NumberOfInputs > 0 )
253     {
254     for (int i=0; i<this->NumberOfInputs; i++)
255       {
256       this->PlotData[i]->Delete();
257       this->PlotGlyph[i]->Delete();
258       this->PlotAppend[i]->Delete();
259       this->PlotTransform[i]->Delete(); // RKV
260       this->PlotMapper[i]->Delete();
261       this->PlotActor[i]->Delete();
262       }//for all entries
263     delete [] this->PlotData; this->PlotData = NULL;
264     delete [] this->PlotGlyph; this->PlotGlyph = NULL;
265     delete [] this->PlotAppend; this->PlotAppend = NULL;
266     delete [] this->PlotTransform; this->PlotTransform = NULL; // RKV
267     delete [] this->PlotMapper; this->PlotMapper = NULL;
268     delete [] this->PlotActor; this->PlotActor = NULL;
269     this->NumberOfInputs = 0;
270     }//if entries have been defined
271 }
272   
273 //----------------------------------------------------------------------------
274 // Add a dataset and array to the list of data to plot.
275 void VISU_XYPlotActor::AddInput(vtkDataSet *ds, const char *arrayName, int component)
276 {
277   int idx, num;
278   char** newNames;
279
280   // I cannot change the input list, because the user has direct 
281   // access to the collection.  I cannot store the index of the array, 
282   // because the index might change from render to render ...
283   // I have to store the list of string array names.
284
285   // I believe idx starts at 1 and goes to "NumberOfItems".
286   idx = this->InputList->IsItemPresent(ds);
287   if (idx > 0)
288     { // Return if arrays are the same.
289     if (arrayName == NULL && this->SelectedInputScalars[idx-1] == NULL &&
290         component == this->SelectedInputScalarsComponent->GetValue(idx-1))
291       {
292       return;
293       }
294     if (arrayName != NULL && this->SelectedInputScalars[idx-1] != NULL &&
295         strcmp(arrayName, this->SelectedInputScalars[idx-1]) == 0 &&
296         component == this->SelectedInputScalarsComponent->GetValue(idx-1))
297       {
298       return;
299       }
300     }
301
302   // The input/array/component must be a unique combination.  Add it to our input list.
303
304   // Now reallocate the list of strings and add the new value.
305   num = this->InputList->GetNumberOfItems();
306   newNames = new char*[num+1];
307   for (idx = 0; idx < num; ++idx)
308     {
309     newNames[idx] = this->SelectedInputScalars[idx];
310     }
311   if (arrayName == NULL)
312     {
313     newNames[num] = NULL;
314     }
315   else
316     {
317     newNames[num] = new char[strlen(arrayName)+1];
318     strcpy(newNames[num],arrayName);
319     }
320   delete [] this->SelectedInputScalars;
321   this->SelectedInputScalars = newNames;
322
323   // Save the component in the int array.
324   this->SelectedInputScalarsComponent->InsertValue(num, component);
325
326   // Add the data set to the collection
327   this->InputList->AddItem(ds);
328
329   // In case of multiple use of a XYPlotActor the NumberOfEntries could be set
330   // to n. Then when a call to SetEntryString(n+1, bla) was done the string was lost
331   // Need to update the number of entries for the legend actor
332   this->LegendActor->SetNumberOfEntries(this->LegendActor->GetNumberOfEntries()+1);
333
334   this->Modified();
335 }
336
337 //----------------------------------------------------------------------------
338 void VISU_XYPlotActor::RemoveAllInputs()
339 {
340   int idx, num;
341
342   num = this->InputList->GetNumberOfItems();
343   this->InputList->RemoveAllItems();
344
345   for (idx = 0; idx < num; ++idx)
346     {
347     if (this->SelectedInputScalars[idx])
348       {
349       delete [] this->SelectedInputScalars[idx];
350       this->SelectedInputScalars[idx] = NULL;
351       }
352     }
353   this->SelectedInputScalarsComponent->Reset();
354
355   this->DataObjectInputList->RemoveAllItems();
356 }
357
358 //----------------------------------------------------------------------------
359 // Remove a dataset from the list of data to plot.
360 void VISU_XYPlotActor::RemoveInput(vtkDataSet *ds, const char *arrayName, int component)
361 {
362   int idx, num;
363   vtkDataSet *input;
364   int found = -1;
365
366   // This is my own find routine, because the array names have to match also.
367   num = this->InputList->GetNumberOfItems();
368   vtkCollectionSimpleIterator dsit;
369   this->InputList->InitTraversal(dsit);
370   for (idx = 0; idx < num && found == -1; ++idx)
371     {
372     input = this->InputList->GetNextDataSet(dsit);
373     if (input == ds)
374       {
375       if (arrayName == NULL && this->SelectedInputScalars[idx] == NULL &&
376           component == this->SelectedInputScalarsComponent->GetValue(idx))
377         {
378         found = idx;
379         }
380       if (arrayName != NULL && this->SelectedInputScalars[idx] != NULL &&
381           strcmp(arrayName, this->SelectedInputScalars[idx]) == 0 &&
382           component == this->SelectedInputScalarsComponent->GetValue(idx))
383         {
384         found = idx;
385         }
386       }
387     }
388
389   if (found == -1)
390     {
391     return;
392     }
393   
394   this->Modified();
395   // Collections index their items starting at 1.
396   this->InputList->RemoveItem(found);
397
398   // Do not bother reallocating the SelectedInputScalars 
399   // string array to make it smaller.
400   if (this->SelectedInputScalars[found])
401     {
402     delete [] this->SelectedInputScalars[found];
403     this->SelectedInputScalars[found] = NULL;
404     }
405   for (idx = found+1; idx < num; ++idx)
406     {
407     this->SelectedInputScalars[idx-1] = this->SelectedInputScalars[idx];
408     this->SelectedInputScalarsComponent->SetValue(idx-1, 
409                           this->SelectedInputScalarsComponent->GetValue(idx));
410     }
411   // Reseting the last item is not really necessary, 
412   // but to be clean we do it anyway.
413   this->SelectedInputScalarsComponent->SetValue(num-1, -1); 
414   this->SelectedInputScalars[num-1] = NULL;
415 }
416
417 //----------------------------------------------------------------------------
418 // Add a data object to the list of data to plot.
419 void VISU_XYPlotActor::AddDataObjectInput(vtkDataObject *in)
420 {
421   if ( ! this->DataObjectInputList->IsItemPresent(in) )
422     {
423     this->Modified();
424     this->DataObjectInputList->AddItem(in);
425     }
426 }
427
428 //----------------------------------------------------------------------------
429 // Remove a data object from the list of data to plot.
430 void VISU_XYPlotActor::RemoveDataObjectInput(vtkDataObject *in)
431 {
432   if ( this->DataObjectInputList->IsItemPresent(in) )
433     {
434     this->Modified();
435     this->DataObjectInputList->RemoveItem(in);
436     }
437 }
438
439 //----------------------------------------------------------------------------
440 // Plot scalar data for each input dataset.
441 int VISU_XYPlotActor::RenderOverlay(vtkViewport *viewport)
442 {
443   int renderedSomething = 0;
444
445   // Make sure input is up to date.
446   if ( this->InputList->GetNumberOfItems() < 1 && 
447        this->DataObjectInputList->GetNumberOfItems() < 1 )
448     {
449     vtkErrorMacro(<< "Nothing to plot!");
450     return 0;
451     }
452
453   renderedSomething += this->XAxis->RenderOverlay(viewport);
454   renderedSomething += this->YAxis->RenderOverlay(viewport);
455   if ( this->Title )
456     {
457     renderedSomething += this->TitleActor->RenderOverlay(viewport);
458     }
459   for (int i=0; i < this->NumberOfInputs; i++)
460     {
461     renderedSomething += this->PlotActor[i]->RenderOverlay(viewport);
462     }
463   if ( this->Legend )
464     {
465     renderedSomething += this->LegendActor->RenderOverlay(viewport);
466     }
467
468   return renderedSomething;
469 }
470
471 //----------------------------------------------------------------------------
472 // Plot scalar data for each input dataset.
473 int VISU_XYPlotActor::RenderOpaqueGeometry(vtkViewport *viewport)
474 {
475   unsigned long mtime, dsMtime;
476   vtkDataSet *ds;
477   vtkDataObject *dobj;
478   int numDS, numDO, renderedSomething=0;
479
480   // Initialize
481   // Make sure input is up to date.
482   numDS = this->InputList->GetNumberOfItems();
483   numDO = this->DataObjectInputList->GetNumberOfItems();
484   if ( numDS > 0 )
485     {
486     vtkDebugMacro(<<"Plotting input data sets");
487     vtkCollectionSimpleIterator dsit;
488     for (mtime=0, this->InputList->InitTraversal(dsit); 
489          (ds = this->InputList->GetNextDataSet(dsit)); )
490       {
491       ds->Update();
492       dsMtime = ds->GetMTime();
493       if ( dsMtime > mtime )
494         {
495         mtime = dsMtime;
496         }
497       }
498     }
499   else if ( numDO > 0 )
500     {
501     vtkDebugMacro(<<"Plotting input data objects");
502     vtkCollectionSimpleIterator doit;
503     for (mtime=0, this->DataObjectInputList->InitTraversal(doit); 
504          (dobj = this->DataObjectInputList->GetNextDataObject(doit)); )
505       {
506       dobj->Update();
507       dsMtime = dobj->GetMTime();
508       if ( dsMtime > mtime )
509         {
510         mtime = dsMtime;
511         }
512       }
513     }
514   else
515     {
516     vtkErrorMacro(<< "Nothing to plot!");
517     return 0;
518     }
519
520   if (this->Title && this->Title[0] && !this->TitleTextProperty)
521     {
522     vtkErrorMacro(<< "Need a title text property to render plot title");
523     return 0;
524     }
525
526   // Check modified time to see whether we have to rebuild.
527   // Pay attention that GetMTime() has been redefined (see below)
528
529   int *size=viewport->GetSize();
530   if (mtime > this->BuildTime || 
531       size[0] != this->CachedSize[0] || size[1] != this->CachedSize[1] ||
532       this->GetMTime() > this->BuildTime ||
533       (this->Title && this->Title[0] && 
534        this->TitleTextProperty->GetMTime() > this->BuildTime) ||
535       (this->AxisLabelTextProperty &&
536        this->AxisLabelTextProperty->GetMTime() > this->BuildTime) ||
537       (this->AxisTitleTextProperty &&
538        this->AxisTitleTextProperty->GetMTime() > this->BuildTime))
539     {
540     double range[2], yrange[2], xRange[2], yRange[2], interval, *lengths=NULL;
541     int pos[2], pos2[2], numTicks;
542     int stringSize[2];
543     int num = ( numDS > 0 ? numDS : numDO );
544
545     vtkDebugMacro(<<"Rebuilding plot");
546     this->CachedSize[0] = size[0];
547     this->CachedSize[1] = size[1];
548
549     // RKV : Begin
550     if ((this->PlotLocation == VISU_XYPLOT_RIGHT) || (this->PlotLocation == VISU_XYPLOT_LEFT))
551       this->ReverseYAxis = 1;
552     else
553       this->ReverseYAxis = 0;
554     // RKV : End
555
556     // manage legend
557     vtkDebugMacro(<<"Rebuilding legend");
558     if ( this->Legend )
559       {
560       int legPos[2], legPos2[2];
561       int *p1 = this->PositionCoordinate->GetComputedViewportValue(viewport);
562       int *p2 = this->Position2Coordinate->GetComputedViewportValue(viewport);
563       legPos[0] = (int)(p1[0] + this->LegendPosition[0]*(p2[0]-p1[0]));
564       legPos2[0] = (int)(legPos[0] + this->LegendPosition2[0]*(p2[0]-p1[0]));
565       legPos[1] = (int)(p1[1] + this->LegendPosition[1]*(p2[1]-p1[1]));
566       legPos2[1] = (int)(legPos[1] + this->LegendPosition2[1]*(p2[1]-p1[1]));
567       
568       this->LegendActor->GetPositionCoordinate()->SetValue(
569         (double)legPos[0], (double)legPos[1]);
570       this->LegendActor->GetPosition2Coordinate()->SetValue(
571         (double)legPos2[0], (double)legPos2[1]);
572       this->LegendActor->SetNumberOfEntries(num);
573       for (int i=0; i<num; i++)
574         {
575         if ( ! this->LegendActor->GetEntrySymbol(i) )
576           {
577           this->LegendActor->SetEntrySymbol(i,this->GlyphSource->GetOutput());
578           }
579         if ( ! this->LegendActor->GetEntryString(i) )
580           {
581           static char legendString[12];
582           sprintf(legendString, "%s%d", "Curve ", i);
583           this->LegendActor->SetEntryString(i,legendString);
584           }
585         }
586
587       this->LegendActor->SetPadding(2);
588       this->LegendActor->GetProperty()->DeepCopy(this->GetProperty());
589       this->LegendActor->ScalarVisibilityOff();
590       }
591
592     // Rebuid text props
593     // Perform shallow copy here since each individual axis can be
594     // accessed through the class API (i.e. each individual axis text prop
595     // can be changed). Therefore, we can not just assign pointers otherwise
596     // each individual axis text prop would point to the same text prop.
597
598     if (this->AxisLabelTextProperty &&
599         this->AxisLabelTextProperty->GetMTime() > this->BuildTime)
600       {
601       if (this->XAxis->GetTitleTextProperty())
602         {
603         this->XAxis->GetLabelTextProperty()->ShallowCopy(
604           this->AxisLabelTextProperty);
605         }
606       if (this->YAxis->GetTitleTextProperty())
607         {
608         this->YAxis->GetLabelTextProperty()->ShallowCopy(
609           this->AxisLabelTextProperty);
610         }
611       }
612     
613     if (this->AxisTitleTextProperty &&
614         this->AxisTitleTextProperty->GetMTime() > this->BuildTime)
615       {
616       if (this->XAxis->GetTitleTextProperty())
617         {
618         this->XAxis->GetTitleTextProperty()->ShallowCopy(
619           this->AxisTitleTextProperty);
620         }
621       if (this->YAxis->GetTitleTextProperty())
622         {
623         this->YAxis->GetTitleTextProperty()->ShallowCopy(
624           this->AxisTitleTextProperty);
625         }
626       }
627     
628     // setup x-axis
629     vtkDebugMacro(<<"Rebuilding x-axis");
630     
631     this->XAxis->SetTitle(this->XTitle);
632     this->XAxis->SetNumberOfLabels(this->NumberOfXLabels);
633     this->XAxis->SetProperty(this->GetProperty());
634
635     vtkDebugMacro(<<"xrange = (" << range[0] << ", " << range[1] << ")"); // RKV
636     lengths = new double[num];
637     if ( numDS > 0 ) //plotting data sets
638       {
639       this->ComputeXRange(range, lengths);
640       }
641     else
642       {
643       this->ComputeDORange(range, yrange, lengths);
644       }
645     if ( this->XRange[0] < this->XRange[1] )
646       {
647       range[0] = this->XRange[0];
648       range[1] = this->XRange[1];
649       }
650
651 /* RKV    vtkAxisActor2D::ComputeRange(range, xRange, this->NumberOfXLabels,
652                                  numTicks, interval);
653 */    // RKV : Begin
654     vtkDebugMacro(<<"XRange = (" << XRange[0] << ", " << XRange[1] << ")");
655     vtkDebugMacro(<<"xrange = (" << range[0] << ", " << range[1] << ")");
656     xRange[0] = range[0];
657     xRange[1] = range[1];
658     // RKV : End
659     if ( !this->ExchangeAxes )
660       {
661       this->XComputedRange[0] = xRange[0];
662       this->XComputedRange[1] = xRange[1];
663       if ( this->ReverseXAxis )
664         {
665         this->XAxis->SetRange(range[1],range[0]);
666         }
667       else
668         {
669         this->XAxis->SetRange(range[0],range[1]);
670         }
671       }
672     else
673       {
674       this->XComputedRange[1] = xRange[0];
675       this->XComputedRange[0] = xRange[1];
676       if ( this->ReverseYAxis )
677         {
678         this->XAxis->SetRange(range[0],range[1]);
679         }
680       else
681         {
682         this->XAxis->SetRange(range[1],range[0]);
683         }
684       }
685     
686     // setup y-axis
687     vtkDebugMacro(<<"Rebuilding y-axis");
688     this->YAxis->SetTitle(this->YTitle);
689     this->YAxis->SetNumberOfLabels(this->NumberOfYLabels);
690
691     vtkDebugMacro(<<"yrange = (" << yrange[0] << ", " << yrange[1] << ")"); // RKV
692     if ( this->YRange[0] >= this->YRange[1] )
693       {
694       if ( numDS > 0 ) //plotting data sets
695         {
696         this->ComputeYRange(yrange);
697         }
698       }
699     else
700       {
701       yrange[0] = this->YRange[0];
702       yrange[1] = this->YRange[1];
703       }
704 /* RKV   vtkAxisActor2D::ComputeRange(yrange, yRange, this->NumberOfYLabels,
705                                  numTicks, interval);
706 */
707     // RKV : Begin
708     vtkDebugMacro(<<"YRange = (" << YRange[0] << ", " << YRange[1] << ")");
709     vtkDebugMacro(<<"yrange = (" << yrange[0] << ", " << yrange[1] << ")");
710     yRange[0] = yrange[0];
711     yRange[1] = yrange[1];
712     // RKV : End
713     
714     if ( !this->ExchangeAxes )
715       {
716       this->YComputedRange[0] = yRange[0];
717       this->YComputedRange[1] = yRange[1];
718       if ( this->ReverseYAxis )
719         {
720         this->YAxis->SetRange(yrange[0],yrange[1]);
721         }
722       else
723         {
724         this->YAxis->SetRange(yrange[1],yrange[0]);
725         }
726       }
727     else
728       {
729       this->YComputedRange[1] = yRange[0];
730       this->YComputedRange[0] = yRange[1];
731       if ( this->ReverseXAxis )
732         {
733         this->YAxis->SetRange(yrange[1],yrange[0]);
734         }
735       else
736         {
737         this->YAxis->SetRange(yrange[0],yrange[1]);
738         }
739       }
740       
741
742     this->PlaceAxes(viewport, size, pos, pos2);
743     
744     // manage title
745     if (this->Title != NULL && this->Title[0])
746       {
747       this->TitleMapper->SetInput(this->Title);
748       if (this->TitleTextProperty->GetMTime() > this->BuildTime)
749         {
750         this->TitleMapper->GetTextProperty()->ShallowCopy(
751           this->TitleTextProperty);
752         }
753
754       
755 #if (VTK_XVERSION < 0x050100)
756       //VSV:  Function is not supported in VTK 5.2 and high
757       vtkAxisActor2D::SetFontSize(viewport, 
758                                   this->TitleMapper, 
759                                   size, 
760                                   1.0,
761                                   stringSize);
762 #endif
763       
764       this->TitleActor->GetPositionCoordinate()->SetValue(
765         pos[0] + 0.5 * (pos2[0] - pos[0]) - stringSize[0] / 2.0, 
766         pos2[1] - stringSize[1] / 2.0);
767
768       this->TitleActor->SetProperty(this->GetProperty());
769       }
770
771     vtkDebugMacro(<<"Creating Plot Data");
772     // Okay, now create the plot data and set up the pipeline
773     this->CreatePlotData(pos, pos2, xRange, yRange, lengths, numDS, numDO);
774     delete [] lengths;
775     
776     this->BuildTime.Modified();
777
778     }//if need to rebuild the plot
779
780   vtkDebugMacro(<<"Rendering Axes");
781   renderedSomething += this->XAxis->RenderOpaqueGeometry(viewport);
782   renderedSomething += this->YAxis->RenderOpaqueGeometry(viewport);
783   for (int i=0; i < this->NumberOfInputs; i++)
784     {
785     vtkDebugMacro(<<"Rendering plotactors");
786     renderedSomething += this->PlotActor[i]->RenderOpaqueGeometry(viewport);
787     }
788   if ( this->Title )
789     {
790     vtkDebugMacro(<<"Rendering titleactors");
791     renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
792     }
793   if ( this->Legend )
794     {
795     vtkDebugMacro(<<"Rendering legendeactors");
796     renderedSomething += this->LegendActor->RenderOpaqueGeometry(viewport);
797     }
798
799   return renderedSomething;
800 }
801
802 //----------------------------------------------------------------------------
803 const char *VISU_XYPlotActor::GetXValuesAsString()
804 {
805   switch (this->XValues)
806     {
807     case VTK_XYPLOT_INDEX:
808       return "Index";
809     case VTK_XYPLOT_ARC_LENGTH:
810       return "ArcLength";
811     case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
812       return "NormalizedArcLength";
813     default:
814       return "Value";
815     }
816 }
817
818 //----------------------------------------------------------------------------
819 const char *VISU_XYPlotActor::GetDataObjectPlotModeAsString()
820 {
821   if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
822     {
823     return "Plot Rows";
824     }
825   else 
826     {
827     return "Plot Columns";
828     }
829 }
830
831 //----------------------------------------------------------------------------
832 // Release any graphics resources that are being consumed by this actor.
833 // The parameter window could be used to determine which graphic
834 // resources to release.
835 void VISU_XYPlotActor::ReleaseGraphicsResources(vtkWindow *win)
836 {
837   this->TitleActor->ReleaseGraphicsResources(win);
838   this->XAxis->ReleaseGraphicsResources(win);
839   this->YAxis->ReleaseGraphicsResources(win);
840   for (int i=0; i < this->NumberOfInputs; i++)
841     {
842     this->PlotActor[i]->ReleaseGraphicsResources(win);
843     }
844   this->LegendActor->ReleaseGraphicsResources(win);
845 }
846
847 //----------------------------------------------------------------------------
848 unsigned long VISU_XYPlotActor::GetMTime()
849 {
850   unsigned long mtime, mtime2;
851   mtime = this->vtkActor2D::GetMTime();
852
853   if (this->Legend)
854     {
855     mtime2 = this->LegendActor->GetMTime();
856     if (mtime2 > mtime)
857       {
858       mtime = mtime2;
859       }
860     }
861
862   return mtime;
863 }
864
865 //----------------------------------------------------------------------------
866 void VISU_XYPlotActor::PrintSelf(ostream& os, vtkIndent indent)
867 {
868   vtkIndent i2 = indent.GetNextIndent();
869   vtkDataSet *input;
870   char *array;
871   int component;
872   int idx, num;
873
874   this->Superclass::PrintSelf(os,indent);
875
876   vtkCollectionSimpleIterator dsit;
877   this->InputList->InitTraversal(dsit);
878   num = this->InputList->GetNumberOfItems();
879   os << indent << "DataSetInputs: " << endl;
880   for (idx = 0; idx < num; ++idx)
881     {
882     input = this->InputList->GetNextDataSet(dsit);
883     array = this->SelectedInputScalars[idx];
884     component = this->SelectedInputScalarsComponent->GetValue((vtkIdType)idx);
885     if (array == NULL)
886       {
887       os << i2 << "(" << input << ") Default Scalars,  Component = " << component << endl;
888       }
889     else
890       {
891       os << i2 << "(" << input << ") " << array << ",  Component = " << component << endl;
892       }
893     }
894
895   os << indent << "Input DataObjects:\n";
896   this->DataObjectInputList->PrintSelf(os,indent.GetNextIndent());
897   
898   if (this->TitleTextProperty)
899     {
900     os << indent << "Title Text Property:\n";
901     this->TitleTextProperty->PrintSelf(os,indent.GetNextIndent());
902     }
903   else
904     {
905     os << indent << "Title Text Property: (none)\n";
906     }
907
908   if (this->AxisTitleTextProperty)
909     {
910     os << indent << "Axis Title Text Property:\n";
911     this->AxisTitleTextProperty->PrintSelf(os,indent.GetNextIndent());
912     }
913   else
914     {
915     os << indent << "Axis Title Text Property: (none)\n";
916     }
917
918   if (this->AxisLabelTextProperty)
919     {
920     os << indent << "Axis Label Text Property:\n";
921     this->AxisLabelTextProperty->PrintSelf(os,indent.GetNextIndent());
922     }
923   else
924     {
925     os << indent << "Axis Label Text Property: (none)\n";
926     }
927
928   os << indent << "Data Object Plot Mode: " << this->GetDataObjectPlotModeAsString() << endl;
929
930   os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
931   os << indent << "X Title: " 
932      << (this->XTitle ? this->XTitle : "(none)") << "\n";
933   os << indent << "Y Title: " 
934      << (this->YTitle ? this->YTitle : "(none)") << "\n";
935  
936   os << indent << "X Values: " << this->GetXValuesAsString() << endl;
937   os << indent << "Log X Values: " << (this->Logx ? "On\n" : "Off\n");
938
939   os << indent << "Plot global-points: " << (this->PlotPoints ? "On\n" : "Off\n");
940   os << indent << "Plot global-lines: " << (this->PlotLines ? "On\n" : "Off\n");
941   os << indent << "Plot per-curve points: " << (this->PlotCurvePoints ? "On\n" : "Off\n");
942   os << indent << "Plot per-curve lines: " << (this->PlotCurveLines ? "On\n" : "Off\n");
943   os << indent << "Exchange Axes: " << (this->ExchangeAxes ? "On\n" : "Off\n");
944   os << indent << "Reverse X Axis: " << (this->ReverseXAxis ? "On\n" : "Off\n");
945   os << indent << "Reverse Y Axis: " << (this->ReverseYAxis ? "On\n" : "Off\n");
946
947   os << indent << "Number Of X Labels: " << this->NumberOfXLabels << "\n";
948   os << indent << "Number Of Y Labels: " << this->NumberOfYLabels << "\n";
949
950   os << indent << "Label Format: " << this->LabelFormat << "\n";
951   os << indent << "Border: " << this->Border << "\n";
952   
953   os << indent << "X Range: ";
954   if ( this->XRange[0] >= this->XRange[1] )
955     {
956     os << indent << "(Automatically Computed)\n";
957     }
958   else
959     {
960     os << "(" << this->XRange[0] << ", " << this->XRange[1] << ")\n";
961     }
962
963   os << indent << "Y Range: ";
964   if ( this->XRange[0] >= this->YRange[1] )
965     {
966     os << indent << "(Automatically Computed)\n";
967     }
968   else
969     {
970     os << "(" << this->YRange[0] << ", " << this->YRange[1] << ")\n";
971     }
972
973   os << indent << "Viewport Coordinate: ("
974      << this->ViewportCoordinate[0] << ", " 
975      << this->ViewportCoordinate[1] << ")\n";
976
977   os << indent << "Plot Coordinate: ("
978      << this->PlotCoordinate[0] << ", " 
979      << this->PlotCoordinate[1] << ")\n";
980
981   os << indent << "Legend: " << (this->Legend ? "On\n" : "Off\n");
982   os << indent << "Legend Position: ("
983      << this->LegendPosition[0] << ", " 
984      << this->LegendPosition[1] << ")\n";
985   os << indent << "Legend Position2: ("
986      << this->LegendPosition2[0] << ", " 
987      << this->LegendPosition2[1] << ")\n";
988
989   os << indent << "Glyph Size: " << this->GlyphSize << endl;
990
991   os << indent << "Legend Actor:";
992   this->LegendActor->PrintSelf( os << endl, i2);
993   os << indent << "Glyph Source:";
994   this->GlyphSource->PrintSelf( os << endl, i2);
995 }
996
997 //----------------------------------------------------------------------------
998 void VISU_XYPlotActor::ComputeXRange(double range[2], double *lengths)
999 {
1000   int dsNum;
1001   vtkIdType numPts, ptId, maxNum;
1002   double maxLength=0.0, xPrev[3], x[3];
1003   vtkDataSet *ds;
1004
1005   range[0] = VTK_DOUBLE_MAX, range[1] = VTK_DOUBLE_MIN;
1006
1007   vtkCollectionSimpleIterator dsit;
1008   for ( dsNum=0, maxNum=0, this->InputList->InitTraversal(dsit); 
1009         (ds = this->InputList->GetNextDataSet(dsit)); dsNum++)
1010     {
1011     numPts = ds->GetNumberOfPoints();
1012
1013     if ( this->XValues != VTK_XYPLOT_INDEX )
1014       {
1015       ds->GetPoint(0, xPrev);
1016       for ( lengths[dsNum]=0.0, ptId=0; ptId < numPts; ptId++ )
1017         {
1018         ds->GetPoint(ptId, x);
1019         switch (this->XValues)
1020           {
1021           case VTK_XYPLOT_VALUE:
1022             if (this->GetLogx() == 0)
1023               {
1024               if ( x[this->XComponent->GetValue(dsNum)] < range[0] )
1025                 {
1026                 range[0] = x[this->XComponent->GetValue(dsNum)];
1027                 }
1028               if ( x[this->XComponent->GetValue(dsNum)] > range[1] )
1029                 {
1030                 range[1] = x[this->XComponent->GetValue(dsNum)];
1031                 }
1032               }
1033             else
1034               {
1035               //ensure range strictly > 0 for log
1036               if ( (x[this->XComponent->GetValue(dsNum)]) < range[0] && 
1037                    (x[this->XComponent->GetValue(dsNum)] > 0))
1038                 {
1039                 range[0] = x[this->XComponent->GetValue(dsNum)];
1040                 }
1041               if ( (x[this->XComponent->GetValue(dsNum)] > range[1]) && 
1042                    (x[this->XComponent->GetValue(dsNum)] > 0))
1043                 {
1044                 range[1] = x[this->XComponent->GetValue(dsNum)];
1045                 }
1046               }
1047             break;
1048           default:
1049             lengths[dsNum] += sqrt(vtkMath::Distance2BetweenPoints(x,xPrev));
1050             xPrev[0] = x[0]; xPrev[1] = x[1]; xPrev[2] = x[2];
1051           }
1052         }//for all points
1053       if ( lengths[dsNum] > maxLength )
1054         {
1055         maxLength = lengths[dsNum];
1056         }
1057       }//if need to visit all points
1058     
1059     else //if ( this->XValues == VTK_XYPLOT_INDEX )
1060       {
1061       if ( numPts > maxNum )
1062         {
1063         maxNum = numPts;
1064         }
1065       }
1066     }//over all datasets
1067
1068   // determine the range
1069   switch (this->XValues)
1070     {
1071     case VTK_XYPLOT_ARC_LENGTH:
1072       range[0] = 0.0;
1073       range[1] = maxLength;
1074       break;
1075     case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
1076       range[0] = 0.0;
1077       range[1] = 1.0;
1078       break;
1079     case VTK_XYPLOT_INDEX:
1080       range[0] = 0.0;
1081       range[1] = (double)(maxNum - 1);
1082       break;
1083     case VTK_XYPLOT_VALUE:
1084       if (this->GetLogx() == 1)
1085         {
1086         if (range[0] > range[1]) 
1087           {
1088           range[0] = 0;
1089           range[1] = 0;
1090           }
1091         else
1092           {
1093           range[0] = log10(range[0]);
1094           range[1] = log10(range[1]);
1095           }
1096         }
1097       break; //range computed in for loop above
1098     default:
1099       vtkErrorMacro(<< "Unkown X-Value option.");
1100       return;
1101     }
1102 }
1103
1104 //----------------------------------------------------------------------------
1105 void VISU_XYPlotActor::ComputeYRange(double range[2])
1106 {
1107   vtkDataSet *ds;
1108   vtkDataArray *scalars;
1109   double sRange[2];
1110   int count;
1111   int component;
1112
1113   range[0]=VTK_DOUBLE_MAX, range[1]=VTK_DOUBLE_MIN;
1114
1115   vtkCollectionSimpleIterator dsit;
1116   for ( this->InputList->InitTraversal(dsit), count = 0; 
1117         (ds = this->InputList->GetNextDataSet(dsit)); ++count)
1118     {
1119     scalars = ds->GetPointData()->GetScalars(this->SelectedInputScalars[count]);
1120     component = this->SelectedInputScalarsComponent->GetValue(count);
1121     if ( !scalars)
1122       {
1123       vtkErrorMacro(<<"No scalar data to plot!");
1124       continue;
1125       }
1126     if ( component < 0 || component >= scalars->GetNumberOfComponents())
1127       {
1128       vtkErrorMacro(<<"Bad component!");
1129       continue;
1130       }
1131     
1132     scalars->GetRange(sRange, component);
1133     if ( sRange[0] < range[0] )
1134       {
1135       range[0] = sRange[0];
1136       }
1137
1138     if ( sRange[1] > range[1] )
1139       {
1140       range[1] = sRange[1];
1141       }
1142     }//over all datasets
1143 }
1144
1145 //----------------------------------------------------------------------------
1146 void VISU_XYPlotActor::ComputeDORange(double xrange[2], double yrange[2], 
1147                                     double *lengths)
1148 {
1149   int i;
1150   vtkDataObject *dobj;
1151   vtkFieldData *field;
1152   int doNum, numColumns;
1153   vtkIdType numTuples, numRows, num, ptId, maxNum;
1154   double maxLength=0.0, x, y, xPrev = 0.0;
1155   vtkDataArray *array;
1156
1157   xrange[0] = yrange[0] = VTK_DOUBLE_MAX;
1158   xrange[1] = yrange[1] = -VTK_DOUBLE_MAX;
1159   vtkCollectionSimpleIterator doit;
1160   for ( doNum=0, maxNum=0, this->DataObjectInputList->InitTraversal(doit); 
1161         (dobj = this->DataObjectInputList->GetNextDataObject(doit)); doNum++)
1162     {
1163     lengths[doNum] = 0.0;
1164     field = dobj->GetFieldData();
1165     numColumns = field->GetNumberOfComponents(); //number of "columns"
1166     for (numRows = VTK_LARGE_ID, i=0; i<field->GetNumberOfArrays(); i++)
1167       {
1168       array = field->GetArray(i);
1169       numTuples = array->GetNumberOfTuples();
1170       if ( numTuples < numRows )
1171         {
1172         numRows = numTuples;
1173         }
1174       }
1175
1176     num = (this->DataObjectPlotMode == VTK_XYPLOT_ROW ? 
1177            numColumns : numRows);
1178
1179     if ( this->XValues != VTK_XYPLOT_INDEX )
1180       {
1181       // gather the information to form a plot
1182       for ( ptId=0; ptId < num; ptId++ )
1183         {
1184         if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
1185           {
1186           x = field->GetComponent(this->XComponent->GetValue(doNum), ptId);
1187           }
1188         else //if ( this->DataObjectPlotMode == VTK_XYPLOT_COLUMN )
1189           {
1190           x = field->GetComponent(ptId, this->XComponent->GetValue(doNum));
1191           }
1192         if ( ptId == 0 )
1193           {
1194           xPrev = x;
1195           }
1196               
1197         switch (this->XValues)
1198           {
1199           case VTK_XYPLOT_VALUE:
1200             if (this->GetLogx() == 0)
1201               {
1202               if ( x < xrange[0] )
1203                 {
1204                 xrange[0] = x;
1205                 }
1206               if ( x > xrange[1] )
1207                 {
1208                 xrange[1] = x;
1209                 }
1210               }
1211             else //ensure positive values
1212               {
1213               if ( (x < xrange[0]) && (x > 0) )
1214                 {
1215                 xrange[0] = x;
1216                 }
1217               if ( x > xrange[1]  && (x > 0) )
1218                 {
1219                 xrange[1] = x;
1220                 }
1221               }
1222             break;
1223           default:
1224             lengths[doNum] += fabs(x-xPrev);
1225             xPrev = x;
1226           }
1227         }//for all points
1228       if ( lengths[doNum] > maxLength )
1229         {
1230         maxLength = lengths[doNum];
1231         }
1232       }//if all data has to be visited
1233     
1234     else //if (this->XValues == VTK_XYPLOT_INDEX)
1235       {
1236       if ( num > maxNum )
1237         {
1238         maxNum = num;
1239         }
1240       }
1241
1242     // Get the y-values
1243     for ( ptId=0; ptId < num; ptId++ )
1244       {
1245       if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
1246         {
1247         y = field->GetComponent(this->YComponent->GetValue(doNum), ptId);
1248         }
1249       else //if ( this->DataObjectPlotMode == VTK_XYPLOT_COLUMN )
1250         {
1251         y = field->GetComponent(ptId, this->YComponent->GetValue(doNum));
1252         }
1253       if ( y < yrange[0] )
1254         {
1255         yrange[0] = y;
1256         }
1257       if ( y > yrange[1] )
1258         {
1259         yrange[1] = y;
1260         }
1261       }//over all y values
1262     }//over all dataobjects
1263
1264   // determine the range
1265   switch (this->XValues)
1266     {
1267     case VTK_XYPLOT_ARC_LENGTH:
1268       xrange[0] = 0.0;
1269       xrange[1] = maxLength;
1270       break;
1271     case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
1272       xrange[0] = 0.0;
1273       xrange[1] = 1.0;
1274       break;
1275     case VTK_XYPLOT_INDEX:
1276       xrange[0] = 0.0;
1277       xrange[1] = (double)(maxNum - 1);
1278       break;
1279     case VTK_XYPLOT_VALUE:
1280       if (this->GetLogx() == 1)
1281         {
1282         xrange[0] = log10(xrange[0]);
1283         xrange[1] = log10(xrange[1]);
1284         }
1285       break;
1286     default:
1287       vtkErrorMacro(<< "Unknown X-Value option");
1288       return;
1289     }
1290 }
1291
1292 //----------------------------------------------------------------------------
1293 /* RKV void VISU_XYPlotActor::CreatePlotData(int *pos, int *pos2, double xRange[2], 
1294                                     double yRange[2], double *lengths,
1295                                     int numDS, int numDO) */
1296 // RKV : Begin
1297 void VISU_XYPlotActor::CreatePlotData(int *pos, int *pos2Extern, double xRange[2], 
1298                                     double yRange[2], double *lengths,
1299                                     int numDS, int numDO)
1300 // RKV : End
1301 {
1302   double xyz[3]; xyz[2] = 0.0;
1303   int i, numLinePts, dsNum, doNum, num;
1304   vtkIdType numPts, ptId, id;
1305   double length, x[3], xPrev[3];
1306   vtkDataArray *scalars;
1307   int component;
1308   vtkDataSet *ds;
1309   vtkCellArray *lines;
1310   vtkPoints *pts;
1311   int clippingRequired = 0;
1312
1313   // Allocate resources for the polygonal plots
1314   //
1315   num = (numDS > numDO ? numDS : numDO);
1316   this->InitializeEntries();
1317   this->NumberOfInputs = num;
1318   this->PlotData = new vtkPolyData* [num];
1319   this->PlotGlyph = new vtkGlyph2D* [num];
1320   this->PlotAppend = new vtkAppendPolyData* [num];
1321   this->PlotTransform = new vtkTransformPolyDataFilter* [num]; // RKV
1322   this->PlotMapper = new vtkPolyDataMapper2D* [num];
1323   this->PlotActor = new vtkActor2D* [num];
1324   
1325   // RKV : Begin
1326   // Prepare the transformation of the curve according to the plot location
1327   vtkTransform *tf = vtkTransform::New();
1328   tf->Translate(pos[0], pos[1], 0);
1329   if ((this->PlotLocation == VISU_XYPLOT_LEFT) || (this->PlotLocation == VISU_XYPLOT_RIGHT))
1330     tf->RotateZ(90);
1331   tf->Translate(-pos[0], -pos[1], 0);
1332   
1333   // Compute the position2 to build the curve before the transformation
1334   int pos2[2];
1335   vtkDebugMacro(<< "pos = (" << pos[0] << ", " << pos[1] << ")"); 
1336   vtkDebugMacro(<< "pos2 = (" << pos2Extern[0] << ", " << pos2Extern[1] << ")"); 
1337   if ((this->PlotLocation == VISU_XYPLOT_LEFT) || (this->PlotLocation == VISU_XYPLOT_RIGHT))
1338     {
1339     pos2[0] = pos[0] + pos2Extern[1] - pos[1];
1340     pos2[1] = pos[1] + pos[0] - pos2Extern[0];
1341     }
1342   else
1343     {
1344     pos2[0] = pos2Extern[0];
1345     pos2[1] = pos2Extern[1];
1346     }
1347   // RKV : End
1348   
1349   for (i=0; i<num; i++)
1350     {
1351     this->PlotData[i] = vtkPolyData::New();
1352     this->PlotGlyph[i] = vtkGlyph2D::New();
1353     this->PlotGlyph[i]->SetInput(this->PlotData[i]);
1354     this->PlotGlyph[i]->SetScaleModeToDataScalingOff();
1355     this->PlotAppend[i] = vtkAppendPolyData::New();
1356     this->PlotAppend[i]->AddInput(this->PlotData[i]);
1357     if ( this->LegendActor->GetEntrySymbol(i) != NULL &&
1358          this->LegendActor->GetEntrySymbol(i) != this->GlyphSource->GetOutput() )
1359       {
1360       this->PlotGlyph[i]->SetSource(this->LegendActor->GetEntrySymbol(i));
1361       this->PlotGlyph[i]->SetScaleFactor(this->ComputeGlyphScale(i,pos,pos2));
1362       this->PlotAppend[i]->AddInput(this->PlotGlyph[i]->GetOutput());
1363       }
1364     this->PlotMapper[i] = vtkPolyDataMapper2D::New();
1365     
1366     // RKV : Begin
1367     // Insert a transformation filter into the pipeline to 
1368     // take into account a plot location.
1369     this->PlotTransform[i] = vtkTransformPolyDataFilter::New();
1370     this->PlotTransform[i]->SetInput(this->PlotAppend[i]->GetOutput());
1371     this->PlotTransform[i]->SetTransform(tf); 
1372     this->PlotMapper[i]->SetInput(this->PlotTransform[i]->GetOutput());
1373     // RKV : End
1374     
1375 // RKV    this->PlotMapper[i]->SetInput(this->PlotAppend[i]->GetOutput());
1376     this->PlotMapper[i]->ScalarVisibilityOff();
1377     this->PlotActor[i] = vtkActor2D::New();
1378     this->PlotActor[i]->SetMapper(this->PlotMapper[i]);
1379     this->PlotActor[i]->GetProperty()->DeepCopy(this->GetProperty());
1380     if ( this->LegendActor->GetEntryColor(i)[0] < 0.0 )
1381       {
1382       this->PlotActor[i]->GetProperty()->SetColor(
1383         this->GetProperty()->GetColor());
1384       }
1385     else
1386       {
1387       this->PlotActor[i]->GetProperty()->SetColor(
1388         this->LegendActor->GetEntryColor(i));
1389       }
1390     }
1391     
1392   tf->Delete(); // RKV
1393
1394   // Prepare to receive data
1395   this->GenerateClipPlanes(pos,pos2);
1396   for (i=0; i<this->NumberOfInputs; i++)
1397     {
1398     lines = vtkCellArray::New();
1399     pts = vtkPoints::New();
1400
1401     lines->Allocate(10,10);
1402     pts->Allocate(10,10);
1403     this->PlotData[i]->SetPoints(pts);
1404     this->PlotData[i]->SetVerts(lines);
1405     this->PlotData[i]->SetLines(lines);
1406
1407     pts->Delete();
1408     lines->Delete();
1409     }
1410    
1411   // Okay, for each input generate plot data. Depending on the input
1412   // we use either dataset or data object.
1413   //
1414   if ( numDS > 0 )
1415     {
1416     vtkCollectionSimpleIterator dsit;
1417     for ( dsNum=0, this->InputList->InitTraversal(dsit); 
1418           (ds = this->InputList->GetNextDataSet(dsit)); dsNum++ )
1419       {
1420       clippingRequired = 0;
1421       numPts = ds->GetNumberOfPoints();
1422       scalars = ds->GetPointData()->GetScalars(this->SelectedInputScalars[dsNum]);
1423       if ( !scalars)
1424         {
1425         continue;
1426         }
1427       component = this->SelectedInputScalarsComponent->GetValue(dsNum);
1428       if ( component < 0 || component >= scalars->GetNumberOfComponents())
1429         {
1430         continue;
1431         }
1432
1433       pts = this->PlotData[dsNum]->GetPoints();
1434       lines = this->PlotData[dsNum]->GetLines();
1435       lines->InsertNextCell(0); //update the count later
1436
1437       ds->GetPoint(0, xPrev);
1438       for ( numLinePts=0, length=0.0, ptId=0; ptId < numPts; ptId++ )
1439         {
1440         xyz[1] = scalars->GetComponent(ptId, component);
1441         ds->GetPoint(ptId, x);
1442         switch (this->XValues)
1443           {
1444           case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
1445             length += sqrt(vtkMath::Distance2BetweenPoints(x,xPrev));
1446             xyz[0] = length / lengths[dsNum];
1447             xPrev[0] = x[0]; xPrev[1] = x[1]; xPrev[2] = x[2];
1448             break;
1449           case VTK_XYPLOT_INDEX:
1450             xyz[0] = (double)ptId;
1451             break;
1452           case VTK_XYPLOT_ARC_LENGTH:
1453             length += sqrt(vtkMath::Distance2BetweenPoints(x,xPrev));
1454             xyz[0] = length;
1455             xPrev[0] = x[0]; xPrev[1] = x[1]; xPrev[2] = x[2];
1456             break;
1457           case VTK_XYPLOT_VALUE:
1458             xyz[0] = x[this->XComponent->GetValue(dsNum)];
1459             break;
1460           default:
1461             vtkErrorMacro(<< "Unknown X-Component option");
1462           }
1463         
1464         if ( this->GetLogx() == 1 )
1465           {
1466           if (xyz[0] > 0)
1467             {
1468             xyz[0] = log10(xyz[0]);
1469             // normalize and position
1470             if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
1471                  xyz[1] < yRange[0] || xyz[1] > yRange[1] )
1472               {
1473               clippingRequired = 1;
1474               }
1475
1476             numLinePts++;
1477             xyz[0] = fabs( xRange[1] - xRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[0] : pos[0] + 
1478               (xyz[0]-xRange[0])/(xRange[1]-xRange[0])*(pos2[0]-pos[0]);
1479             xyz[1] = fabs( yRange[1] - yRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[1] : pos[1] + 
1480               (xyz[1]-yRange[0])/(yRange[1]-yRange[0])*(pos2[1]-pos[1]);
1481             id = pts->InsertNextPoint(xyz);
1482             lines->InsertCellPoint(id);
1483             }
1484           } 
1485         else
1486           {
1487           // normalize and position
1488           if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
1489                xyz[1] < yRange[0] || xyz[1] > yRange[1] )
1490             {
1491             clippingRequired = 1;
1492             }
1493
1494           numLinePts++;
1495           xyz[0] = fabs( xRange[1] - xRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[0] : pos[0] + 
1496             (xyz[0]-xRange[0])/(xRange[1]-xRange[0])*(pos2[0]-pos[0]);
1497           xyz[1] = fabs( yRange[1] - yRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[1] : pos[1] + 
1498             (xyz[1]-yRange[0])/(yRange[1]-yRange[0])*(pos2[1]-pos[1]);
1499           id = pts->InsertNextPoint(xyz);
1500           lines->InsertCellPoint(id);
1501           }
1502         }//for all input points
1503
1504       lines->UpdateCellCount(numLinePts);
1505       if ( clippingRequired )
1506         {
1507         this->ClipPlotData(pos,pos2,this->PlotData[dsNum]);
1508         }
1509       }//loop over all input data sets
1510     }//if plotting datasets
1511
1512   else //plot data from data objects
1513     {
1514     vtkDataObject *dobj;
1515     int numColumns;
1516     vtkIdType numRows, numTuples;
1517     vtkDataArray *array;
1518     vtkFieldData *field;
1519     vtkCollectionSimpleIterator doit;
1520     for ( doNum=0, this->DataObjectInputList->InitTraversal(doit); 
1521           (dobj = this->DataObjectInputList->GetNextDataObject(doit)); 
1522           doNum++ )
1523       {
1524       // determine the shape of the field
1525       field = dobj->GetFieldData();
1526       numColumns = field->GetNumberOfComponents(); //number of "columns"
1527       for (numRows = VTK_LARGE_ID, i=0; i<field->GetNumberOfArrays(); i++)
1528         {
1529         array = field->GetArray(i);
1530         numTuples = array->GetNumberOfTuples();
1531         if ( numTuples < numRows )
1532           {
1533           numRows = numTuples;
1534           }
1535         }
1536
1537       pts = this->PlotData[doNum]->GetPoints();
1538       lines = this->PlotData[doNum]->GetLines();
1539       lines->InsertNextCell(0); //update the count later
1540
1541       numPts = (this->DataObjectPlotMode == VTK_XYPLOT_ROW ? 
1542                 numColumns : numRows);
1543
1544       // gather the information to form a plot
1545       for ( numLinePts=0, length=0.0, ptId=0; ptId < numPts; ptId++ )
1546         {
1547         if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
1548           {
1549           x[0] = field->GetComponent(this->XComponent->GetValue(doNum),ptId);
1550           xyz[1] = field->GetComponent(this->YComponent->GetValue(doNum),ptId);
1551           }
1552         else //if ( this->DataObjectPlotMode == VTK_XYPLOT_COLUMN )
1553           {
1554           x[0] = field->GetComponent(ptId, this->XComponent->GetValue(doNum));
1555           xyz[1] = field->GetComponent(ptId, this->YComponent->GetValue(doNum));
1556           }
1557
1558         switch (this->XValues)
1559           {
1560           case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
1561             length += fabs(x[0]-xPrev[0]);
1562             xyz[0] = length / lengths[doNum];
1563             xPrev[0] = x[0];
1564             break;
1565           case VTK_XYPLOT_INDEX:
1566             xyz[0] = (double)ptId;
1567             break;
1568           case VTK_XYPLOT_ARC_LENGTH:
1569             length += fabs(x[0]-xPrev[0]);
1570             xyz[0] = length;
1571             xPrev[0] = x[0];
1572             break;
1573           case VTK_XYPLOT_VALUE:
1574             xyz[0] = x[0];
1575             break;
1576           default:
1577             vtkErrorMacro(<< "Unknown X-Value option");
1578           }
1579
1580         if ( this->GetLogx() == 1 )
1581           {
1582           if (xyz[0] > 0)
1583             {
1584             xyz[0] = log10(xyz[0]);
1585             // normalize and position
1586             if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
1587                  xyz[1] < yRange[0] || xyz[1] > yRange[1] )
1588               {
1589               clippingRequired = 1;
1590               }
1591             numLinePts++;
1592             xyz[0] = fabs( xRange[1] - xRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[0] : pos[0] + 
1593               (xyz[0]-xRange[0])/(xRange[1]-xRange[0])*(pos2[0]-pos[0]);
1594             xyz[1] = fabs( yRange[1] - yRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[1] : pos[1] + 
1595               (xyz[1]-yRange[0])/(yRange[1]-yRange[0])*(pos2[1]-pos[1]);
1596             id = pts->InsertNextPoint(xyz);
1597             lines->InsertCellPoint(id);
1598             }
1599           } 
1600         else
1601           {
1602           // normalize and position
1603           if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
1604                xyz[1] < yRange[0] || xyz[1] > yRange[1] )
1605             {
1606             clippingRequired = 1;
1607             }    
1608           numLinePts++;
1609           xyz[0] = fabs( xRange[1] - xRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[0] : pos[0] +
1610             (xyz[0]-xRange[0])/(xRange[1]-xRange[0])*(pos2[0]-pos[0]);
1611           xyz[1] = fabs( yRange[1] - yRange[0] ) < 1.0 / VTK_LARGE_FLOAT ? pos[1] : pos[1] +
1612             (xyz[1]-yRange[0])/(yRange[1]-yRange[0])*(pos2[1]-pos[1]);
1613           id = pts->InsertNextPoint(xyz);
1614           lines->InsertCellPoint(id);
1615           }
1616         }//for all input points
1617
1618       lines->UpdateCellCount(numLinePts);
1619       if ( clippingRequired )
1620         {
1621         this->ClipPlotData(pos,pos2,this->PlotData[doNum]);
1622         }
1623       }//loop over all input data sets
1624     }
1625   
1626   // Remove points/lines as directed by the user
1627   for ( i = 0; i < num; i++)
1628     {
1629     if (!this->PlotCurveLines) 
1630       {
1631       if ( !this->PlotLines ) 
1632         {
1633         this->PlotData[i]->SetLines(NULL);
1634         }
1635       }
1636     else
1637       {
1638       if ( this->GetPlotLines(i) == 0)
1639         {
1640         this->PlotData[i]->SetLines(NULL);
1641         }
1642       }
1643
1644     if (!this->PlotCurvePoints) 
1645       {
1646       if ( !this->PlotPoints || (this->LegendActor->GetEntrySymbol(i) &&
1647                                  this->LegendActor->GetEntrySymbol(i) != 
1648                                  this->GlyphSource->GetOutput()))
1649         {
1650         this->PlotData[i]->SetVerts(NULL);
1651         }
1652       }
1653     else
1654       {
1655       if ( this->GetPlotPoints(i) == 0 || 
1656           (this->LegendActor->GetEntrySymbol(i) &&
1657            this->LegendActor->GetEntrySymbol(i) != 
1658            this->GlyphSource->GetOutput()))
1659         {
1660         this->PlotData[i]->SetVerts(NULL);
1661         }
1662       }
1663     }
1664 }
1665
1666 //----------------------------------------------------------------------------
1667 // Position the axes taking into account the expected padding due to labels
1668 // and titles. We want the result to fit in the box specified. This method
1669 // knows something about how the vtkAxisActor2D functions, so it may have 
1670 // to change if that class changes dramatically.
1671 //
1672 void VISU_XYPlotActor::PlaceAxes(vtkViewport *viewport, int *size,
1673                                int pos[2], int pos2[2])
1674 {
1675   int titleSizeX[2], titleSizeY[2], labelSizeX[2], labelSizeY[2];
1676   double labelFactorX, labelFactorY;
1677   double fontFactorX, fontFactorY;
1678   double tickOffsetX, tickOffsetY;
1679   double tickLengthX, tickLengthY;
1680
1681   vtkAxisActor2D *axisX;
1682   vtkAxisActor2D *axisY;
1683
1684   char str1[512], str2[512];
1685
1686   if (this->ExchangeAxes)
1687     {
1688     axisX = this->YAxis;
1689     axisY = this->XAxis;
1690     }
1691   else
1692     {
1693     axisX = this->XAxis;
1694     axisY = this->YAxis;
1695     }
1696
1697   // RKV : Begin
1698   // Take into account a location of the plot.
1699   if ((this->PlotLocation == VISU_XYPLOT_LEFT) || (this->PlotLocation == VISU_XYPLOT_RIGHT))
1700     {
1701     vtkAxisActor2D *axisBid;
1702     axisBid = axisX;
1703     axisX = axisY;
1704     axisY = axisBid;
1705     }
1706     
1707   // RKV : End
1708   
1709   fontFactorY = axisY->GetFontFactor();
1710   fontFactorX = axisX->GetFontFactor();
1711
1712   labelFactorY = axisY->GetLabelFactor();
1713   labelFactorX = axisX->GetLabelFactor();
1714
1715   // Create a dummy text mapper for getting font sizes
1716   vtkTextMapper *textMapper = vtkTextMapper::New();
1717   vtkTextProperty *tprop = textMapper->GetTextProperty();
1718
1719   // Get the location of the corners of the box
1720   int *p1 = this->PositionCoordinate->GetComputedViewportValue(viewport);
1721   int *p2 = this->Position2Coordinate->GetComputedViewportValue(viewport);
1722
1723   // Estimate the padding around the X and Y axes
1724   tprop->ShallowCopy(axisX->GetTitleTextProperty());
1725   textMapper->SetInput(axisX->GetTitle());
1726     
1727 #if (VTK_XVERSION < 0x050100)
1728   //VSV:  Function is not supported in VTK 5.2 and high
1729   vtkAxisActor2D::SetFontSize(
1730     viewport, textMapper, size, fontFactorX, titleSizeX);
1731 #endif
1732       
1733   tprop->ShallowCopy(axisY->GetTitleTextProperty());
1734   textMapper->SetInput(axisY->GetTitle());
1735      
1736 #if (VTK_XVERSION < 0x050100)
1737   //VSV:  Function is not supported in VTK 5.2 and high
1738   vtkAxisActor2D::SetFontSize(
1739     viewport, textMapper, size, fontFactorY, titleSizeY);
1740 #endif
1741       
1742   // At this point the thing to do would be to actually ask the Y axis
1743   // actor to return the largest label.
1744   // In the meantime, let's try with the min and max
1745   sprintf(str1, axisY->GetLabelFormat(), axisY->GetAdjustedRange()[0]);
1746   sprintf(str2, axisY->GetLabelFormat(), axisY->GetAdjustedRange()[1]);
1747   tprop->ShallowCopy(axisY->GetLabelTextProperty());
1748   textMapper->SetInput(strlen(str1) > strlen(str2) ? str1 : str2);
1749       
1750 #if (VTK_XVERSION < 0x050100)
1751   //VSV:  Function is not supported in VTK 5.2 and high
1752   vtkAxisActor2D::SetFontSize(
1753     viewport, textMapper, size, labelFactorY * fontFactorY, labelSizeY);
1754 #endif
1755       
1756   // We do only care of the height of the label in the X axis, so let's
1757   // use the min for example
1758   sprintf(str1, axisX->GetLabelFormat(), axisX->GetAdjustedRange()[0]);
1759   tprop->ShallowCopy(axisX->GetLabelTextProperty());
1760   textMapper->SetInput(str1);
1761       
1762 #if (VTK_XVERSION < 0x050100)
1763   //VSV:  Function is not supported in VTK 5.2 and high
1764   vtkAxisActor2D::SetFontSize(
1765     viewport, textMapper, size, labelFactorX * fontFactorX, labelSizeX);
1766 #endif
1767      
1768   tickOffsetX = axisX->GetTickOffset();
1769   tickOffsetY = axisY->GetTickOffset();
1770   tickLengthX = axisX->GetTickLength();
1771   tickLengthY = axisY->GetTickLength();
1772
1773   // Okay, estimate the size
1774 /* RKV  pos[0] = (int)(p1[0] + titleSizeY[0] + 2.0 * tickOffsetY + tickLengthY + 
1775                  labelSizeY[0] + this->Border);
1776
1777   pos[1] = (int)(p1[1] + titleSizeX[1] + 2.0 * tickOffsetX + tickLengthX + 
1778                  labelSizeX[1] + this->Border);
1779
1780   pos2[0] = (int)(p2[0] - labelSizeY[0] / 2 - tickOffsetY - this->Border);
1781
1782   pos2[1] = (int)(p2[1] - labelSizeX[1] / 2 - tickOffsetX - this->Border);
1783   */
1784   // RKV : Begin
1785   pos[0] = (int)(p1[0]);
1786
1787   pos[1] = (int)(p1[1]);
1788
1789   pos2[0] = (int)(p2[0]);
1790
1791   pos2[1] = (int)(p2[1]);
1792   // RKV : End
1793
1794   // Now specify the location of the axes
1795   axisX->GetPositionCoordinate()->SetValue(
1796     (double)pos[0], (double)pos[1]);
1797   axisX->GetPosition2Coordinate()->SetValue(
1798     (double)pos2[0], (double)pos[1]);
1799   axisY->GetPositionCoordinate()->SetValue(
1800     (double)pos[0], (double)pos2[1]);
1801   axisY->GetPosition2Coordinate()->SetValue(
1802     (double)pos[0], (double)pos[1]);
1803     
1804   textMapper->Delete();
1805 }
1806
1807 //----------------------------------------------------------------------------
1808 void VISU_XYPlotActor::ViewportToPlotCoordinate(vtkViewport *viewport, double &u, double &v)
1809 {
1810   int *p0, *p1, *p2;
1811
1812   // XAxis, YAxis are in viewport coordinates already
1813   p0 = this->XAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
1814   p1 = this->XAxis->GetPosition2Coordinate()->GetComputedViewportValue(viewport);
1815   p2 = this->YAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
1816
1817   u = ((u - p0[0]) / (double)(p1[0] - p0[0]))
1818     *(this->XComputedRange[1] - this->XComputedRange[0])
1819     + this->XComputedRange[0];
1820   v = ((v - p0[1]) / (double)(p2[1] - p0[1]))
1821     *(this->YComputedRange[1] - this->YComputedRange[0])
1822     + this->YComputedRange[0];
1823 }
1824
1825 //----------------------------------------------------------------------------
1826 void VISU_XYPlotActor::PlotToViewportCoordinate(vtkViewport *viewport,
1827                                               double &u, double &v)
1828 {
1829   int *p0, *p1, *p2;
1830
1831   // XAxis, YAxis are in viewport coordinates already
1832   p0 = this->XAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
1833   p1 = this->XAxis->GetPosition2Coordinate()->GetComputedViewportValue(viewport);
1834   p2 = this->YAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
1835
1836   u = (((u - this->XComputedRange[0])
1837         / (this->XComputedRange[1] - this->XComputedRange[0]))
1838        * (double)(p1[0] - p0[0])) + p0[0];
1839   v = (((v - this->YComputedRange[0])
1840         / (this->YComputedRange[1] - this->YComputedRange[0]))
1841        * (double)(p2[1] - p0[1])) + p0[1];
1842 }
1843
1844 //----------------------------------------------------------------------------
1845 void VISU_XYPlotActor::ViewportToPlotCoordinate(vtkViewport *viewport)
1846 {
1847   this->ViewportToPlotCoordinate(viewport, 
1848                                  this->ViewportCoordinate[0],
1849                                  this->ViewportCoordinate[1]);
1850 }
1851
1852 //----------------------------------------------------------------------------
1853 void VISU_XYPlotActor::PlotToViewportCoordinate(vtkViewport *viewport)
1854 {
1855   this->PlotToViewportCoordinate(viewport, 
1856                                  this->PlotCoordinate[0],
1857                                  this->PlotCoordinate[1]);
1858 }
1859
1860 //----------------------------------------------------------------------------
1861 int VISU_XYPlotActor::IsInPlot(vtkViewport *viewport, double u, double v)
1862 {
1863   int *p0, *p1, *p2;
1864
1865   // Bounds of the plot are based on the axes...
1866   p0 = this->XAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
1867   p1 = this->XAxis->GetPosition2Coordinate()->GetComputedViewportValue(viewport);
1868   p2 = this->YAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
1869   
1870   if (u >= p0[0] && u <= p1[0] && v >= p0[1] && v <= p2[1])
1871     {
1872     return 1;
1873     }
1874
1875   return 0;
1876 }
1877
1878 //----------------------------------------------------------------------------
1879 void VISU_XYPlotActor::SetPlotLines(int i, int isOn)
1880 {
1881   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
1882   int val = this->LinesOn->GetValue(i);
1883   if ( val != isOn )
1884     {
1885     this->Modified();
1886     this->LinesOn->SetValue(i, isOn);
1887     }
1888 }
1889
1890 //----------------------------------------------------------------------------
1891 int VISU_XYPlotActor::GetPlotLines(int i)
1892 {
1893   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
1894   return this->LinesOn->GetValue(i);
1895 }
1896
1897 //----------------------------------------------------------------------------
1898 void VISU_XYPlotActor::SetPlotPoints(int i, int isOn)
1899 {
1900   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
1901   int val = this->PointsOn->GetValue(i);
1902   if ( val != isOn )
1903     {
1904     this->Modified();
1905     this->PointsOn->SetValue(i, isOn);
1906     }
1907 }
1908
1909 //----------------------------------------------------------------------------
1910 int VISU_XYPlotActor::GetPlotPoints(int i)
1911 {
1912   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
1913   return this->PointsOn->GetValue(i);
1914 }
1915
1916 //----------------------------------------------------------------------------
1917 void VISU_XYPlotActor::SetPlotColor(int i, double r, double g, double b)
1918 {
1919   this->LegendActor->SetEntryColor(i, r, g, b);
1920 }
1921
1922 //----------------------------------------------------------------------------
1923 double *VISU_XYPlotActor::GetPlotColor(int i)
1924 {
1925   return this->LegendActor->GetEntryColor(i);
1926 }
1927
1928 //----------------------------------------------------------------------------
1929 void VISU_XYPlotActor::SetPlotSymbol(int i,vtkPolyData *input)
1930 {
1931   this->LegendActor->SetEntrySymbol(i, input);
1932 }
1933
1934 //----------------------------------------------------------------------------
1935 vtkPolyData *VISU_XYPlotActor::GetPlotSymbol(int i)
1936 {
1937   return this->LegendActor->GetEntrySymbol(i);
1938 }
1939
1940 //----------------------------------------------------------------------------
1941 void VISU_XYPlotActor::SetPlotLabel(int i, const char *label)
1942 {
1943   this->LegendActor->SetEntryString(i, label);
1944 }
1945
1946 //----------------------------------------------------------------------------
1947 const char *VISU_XYPlotActor::GetPlotLabel(int i)
1948 {
1949   return this->LegendActor->GetEntryString(i);
1950 }
1951
1952 //----------------------------------------------------------------------------
1953 void VISU_XYPlotActor::GenerateClipPlanes(int *pos, int *pos2)
1954 {
1955   double n[3], x[3];
1956   vtkPoints *pts=this->ClipPlanes->GetPoints();
1957   vtkDataArray *normals=this->ClipPlanes->GetNormals();
1958   
1959   n[2] = x[2] = 0.0;
1960   
1961   //first
1962   n[0] = 0.0;
1963   n[1] = -1.0;
1964   normals->SetTuple(0,n);
1965   x[0] = (double)0.5*(pos[0]+pos2[0]);
1966   x[1] = (double)pos[1];
1967   pts->SetPoint(0,x);
1968   
1969   //second
1970   n[0] = 1.0;
1971   n[1] = 0.0;
1972   normals->SetTuple(1,n);
1973   x[0] = (double)pos2[0];
1974   x[1] = (double)0.5*(pos[1]+pos2[1]);
1975   pts->SetPoint(1,x);
1976   
1977   //third
1978   n[0] = 0.0;
1979   n[1] = 1.0;
1980   normals->SetTuple(2,n);
1981   x[0] = (double)0.5*(pos[0]+pos2[0]);
1982   x[1] = (double)pos2[1];
1983   pts->SetPoint(2,x);
1984   
1985   //fourth
1986   n[0] = -1.0;
1987   n[1] = 0.0;
1988   normals->SetTuple(3,n);
1989   x[0] = (double)pos[0];
1990   x[1] = (double)0.5*(pos[1]+pos2[1]);
1991   pts->SetPoint(3,x);
1992 }
1993
1994 //----------------------------------------------------------------------------
1995 double VISU_XYPlotActor::ComputeGlyphScale(int i, int *pos, int *pos2)
1996 {
1997   vtkPolyData *pd=this->LegendActor->GetEntrySymbol(i);
1998   pd->Update();
1999   double length=pd->GetLength();
2000   double sf = this->GlyphSize * sqrt((double)(pos[0]-pos2[0])*(pos[0]-pos2[0]) + 
2001                                     (pos[1]-pos2[1])*(pos[1]-pos2[1])) / length;
2002
2003   return sf;
2004 }
2005
2006 //----------------------------------------------------------------------------
2007 //This assumes that there are multiple polylines
2008 void VISU_XYPlotActor::ClipPlotData(int *pos, int *pos2, vtkPolyData *pd)
2009 {
2010   vtkPoints *points=pd->GetPoints();
2011   vtkPoints *newPoints;
2012   vtkCellArray *lines=pd->GetLines();
2013   vtkCellArray *newLines, *newVerts;
2014   vtkIdType numPts=pd->GetNumberOfPoints();
2015   vtkIdType npts = 0;
2016   vtkIdType newPts[2];
2017   vtkIdType *pts=0;
2018   vtkIdType i, id;
2019   int j;
2020   double x1[3], x2[3], px[3], n[3], xint[3], t;
2021   double p1[2], p2[2];
2022
2023   p1[0] = (double)pos[0]; p1[1] = (double)pos[1];
2024   p2[0] = (double)pos2[0]; p2[1] = (double)pos2[1];
2025   
2026   newPoints = vtkPoints::New();
2027   newPoints->Allocate(numPts);
2028   newVerts = vtkCellArray::New();
2029   newVerts->Allocate(lines->GetSize());
2030   newLines = vtkCellArray::New();
2031   newLines->Allocate(2*lines->GetSize());
2032   int *pointMap = new int [numPts];
2033   for (i=0; i<numPts; i++)
2034     {
2035     pointMap[i] = -1;
2036     }
2037   
2038   //Loop over polyverts eliminating those that are outside
2039   for ( lines->InitTraversal(); lines->GetNextCell(npts,pts); )
2040     {
2041     //loop over verts keeping only those that are not clipped
2042     for (i=0; i<npts; i++)
2043       {
2044       points->GetPoint(pts[i], x1);
2045
2046       if (x1[0] >= p1[0] && x1[0] <= p2[0] && x1[1] >= p1[1] && x1[1] <= p2[1] )
2047         {
2048         id = newPoints->InsertNextPoint(x1);
2049         pointMap[i] = id;
2050         newPts[0] = id;
2051         newVerts->InsertNextCell(1,newPts);
2052         }
2053       }
2054     }
2055
2056   //Loop over polylines clipping each line segment
2057   for ( lines->InitTraversal(); lines->GetNextCell(npts,pts); )
2058     {
2059     //loop over line segment making up the polyline
2060     for (i=0; i<(npts-1); i++)
2061       {
2062       points->GetPoint(pts[i], x1);
2063       points->GetPoint(pts[i+1], x2);
2064
2065       //intersect each segment with the four planes
2066       if ( (x1[0] < p1[0] && x2[0] < p1[0]) || (x1[0] > p2[0] && x2[0] > p2[0]) ||
2067            (x1[1] < p1[1] && x2[1] < p1[1]) || (x1[1] > p2[1] && x2[1] > p2[1]) )
2068         {
2069         ;//trivial rejection
2070         }
2071       else if (x1[0] >= p1[0] && x2[0] >= p1[0] && x1[0] <= p2[0] && x2[0] <= p2[0] &&
2072                x1[1] >= p1[1] && x2[1] >= p1[1] && x1[1] <= p2[1] && x2[1] <= p2[1] )
2073         {//trivial acceptance
2074         newPts[0] = pointMap[pts[i]];
2075         newPts[1] = pointMap[pts[i+1]];
2076         newLines->InsertNextCell(2,newPts);
2077         }
2078       else
2079         {
2080         if (x1[0] >= p1[0] && x1[0] <= p2[0] && x1[1] >= p1[1] && x1[1] <= p2[1] )
2081           {//first point in
2082           newPts[0] = pointMap[pts[i]];
2083           }
2084         else
2085           {//second point in
2086           newPts[0] = pointMap[pts[i+1]];
2087           }
2088         for (j=0; j<4; j++)
2089           {
2090           this->ClipPlanes->GetPoints()->GetPoint(j, px);
2091           this->ClipPlanes->GetNormals()->GetTuple(j, n);
2092           if ( vtkPlane::IntersectWithLine(x1,x2,n,px,t,xint) && t >= 0 && t <= 1.0 )
2093             {
2094             newPts[1] = newPoints->InsertNextPoint(xint);
2095             break;
2096             }
2097           }
2098         newLines->InsertNextCell(2,newPts);
2099         }
2100       }
2101     }
2102   delete [] pointMap;
2103   
2104   //Update the lines
2105   pd->SetPoints(newPoints);
2106   pd->SetVerts(newVerts);
2107   pd->SetLines(newLines);
2108   
2109   newPoints->Delete();
2110   newVerts->Delete();
2111   newLines->Delete();
2112   
2113 }
2114
2115 //----------------------------------------------------------------------------
2116 void VISU_XYPlotActor::SetDataObjectXComponent(int i, int comp)
2117 {
2118   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
2119   int val=this->XComponent->GetValue(i);
2120   if ( val != comp )
2121     {
2122     this->Modified();
2123     this->XComponent->SetValue(i,comp);
2124     }
2125 }
2126
2127 //----------------------------------------------------------------------------
2128 int VISU_XYPlotActor::GetDataObjectXComponent(int i)
2129 {
2130   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
2131   return this->XComponent->GetValue(i);
2132 }
2133
2134 //----------------------------------------------------------------------------
2135 void VISU_XYPlotActor::SetDataObjectYComponent(int i, int comp)
2136 {
2137   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
2138   int val=this->YComponent->GetValue(i);
2139   if ( val != comp )
2140     {
2141     this->Modified();
2142     this->YComponent->SetValue(i,comp);
2143     }
2144 }
2145
2146 //----------------------------------------------------------------------------
2147 int VISU_XYPlotActor::GetDataObjectYComponent(int i)
2148 {
2149   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
2150   return this->YComponent->GetValue(i);
2151 }
2152
2153 //----------------------------------------------------------------------------
2154 void VISU_XYPlotActor::SetPointComponent(int i, int comp)
2155 {
2156   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
2157   int val = this->XComponent->GetValue(i);
2158   if ( val != comp )
2159     {
2160     this->Modified();
2161     this->XComponent->SetValue(i,comp);
2162     }
2163 }
2164
2165 //----------------------------------------------------------------------------
2166 int VISU_XYPlotActor::GetPointComponent(int i)
2167 {
2168   i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
2169   return this->XComponent->GetValue(i);
2170 }
2171
2172 //----------------------------------------------------------------------------
2173 double *VISU_XYPlotActor::TransformPoint(int pos[2], int pos2[2],
2174                                        double x[3], double xNew[3])
2175 {
2176   // First worry about exchanging axes
2177   if ( this->ExchangeAxes )
2178     {
2179     double sx = (x[0]-pos[0]) / (pos2[0]-pos[0]);
2180     double sy = (x[1]-pos[1]) / (pos2[1]-pos[1]);
2181     xNew[0] = sy*(pos2[0]-pos[0]) + pos[0];
2182     xNew[1] = sx*(pos2[1]-pos[1]) + pos[1];
2183     xNew[2] = x[2];
2184     }
2185   else
2186     {
2187     xNew[0] = x[0];
2188     xNew[1] = x[1];
2189     xNew[2] = x[2];
2190     }
2191
2192   // Okay, now swap the axes around if reverse is on
2193   if ( this->ReverseXAxis )
2194     {
2195     xNew[0] = pos[0] + (pos2[0]-xNew[0]);
2196     }
2197   if ( this->ReverseYAxis )
2198     {
2199     xNew[1] = pos[1] + (pos2[1]-xNew[1]);
2200     }
2201
2202   return xNew;
2203 }
2204     
2205 //----------------------------------------------------------------------------
2206 void VISU_XYPlotActor::SetLabelFormat(const char* _arg)
2207 {
2208   if (this->LabelFormat == NULL && _arg == NULL) 
2209     { 
2210     return;
2211     }
2212
2213   if (this->LabelFormat && _arg && (!strcmp(this->LabelFormat,_arg))) 
2214     { 
2215     return;
2216     }
2217
2218   if (this->LabelFormat) 
2219     { 
2220     delete [] this->LabelFormat; 
2221     }
2222
2223   if (_arg)
2224     {
2225     this->LabelFormat = new char[strlen(_arg)+1];
2226     strcpy(this->LabelFormat,_arg);
2227     }
2228   else
2229     {
2230     this->LabelFormat = NULL;
2231     }
2232
2233   this->XAxis->SetLabelFormat(this->LabelFormat);
2234   this->YAxis->SetLabelFormat(this->LabelFormat);
2235
2236   this->Modified();
2237 }
2238
2239 //----------------------------------------------------------------------------
2240 void VISU_XYPlotActor::PrintAsCSV(ostream &os)
2241 {
2242   vtkDataArray *scalars;
2243   vtkDataSet *ds;
2244   vtkCollectionSimpleIterator dsit;
2245   double s;
2246   int dsNum,component;
2247   for ( dsNum=0, this->InputList->InitTraversal(dsit); 
2248     (ds = this->InputList->GetNextDataSet(dsit)); dsNum++ )
2249     {
2250     vtkIdType numPts = ds->GetNumberOfPoints();
2251     scalars = ds->GetPointData()->GetScalars(this->SelectedInputScalars[dsNum]);
2252     component = this->SelectedInputScalarsComponent->GetValue(dsNum);
2253     for ( vtkIdType ptId=0; ptId < numPts; ptId++ )
2254       {
2255       s = scalars->GetComponent(ptId, component);
2256       if( ptId == 0 )
2257         {
2258         os << s;
2259         }
2260       else
2261         {
2262         os << "," << s;
2263         }
2264       }
2265     os << endl;
2266     }
2267 }
2268