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