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