--- /dev/null
+// VISU OBJECT : interactive object for VISU entities implementation
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File: VISU_XYPlotActor.cxx
+// Author: Roman KOZLOV
+// Module : VISU
+
+/*=========================================================================
+
+ Program: Visualization Toolkit
+ Module: $RCSfile$
+
+ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+ All rights reserved.
+ See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the above copyright notice for more information.
+
+=========================================================================*/
+#include "VISU_XYPlotActor.hxx"
+
+#include "vtkAppendPolyData.h"
+#include "vtkAxisActor2D.h"
+#include "vtkCellArray.h"
+#include "vtkDataObjectCollection.h"
+#include "vtkDataSetCollection.h"
+#include "vtkFieldData.h"
+#include "vtkDoubleArray.h"
+#include "vtkGlyph2D.h"
+#include "vtkGlyphSource2D.h"
+#include "vtkIntArray.h"
+#include "vtkLegendBoxActor.h"
+#include "vtkMath.h"
+#include "vtkObjectFactory.h"
+#include "vtkPlane.h"
+#include "vtkPlanes.h"
+#include "vtkPointData.h"
+#include "vtkPolyData.h"
+#include "vtkPolyDataMapper2D.h"
+#include "vtkProperty2D.h"
+#include "vtkTextMapper.h"
+#include "vtkTextProperty.h"
+#include "vtkViewport.h"
+#include "vtkTransformPolyDataFilter.h" // RKV
+#include "vtkTransform.h" // RKV
+
+#define VTK_MAX_PLOTS 50
+
+using namespace std;
+
+vtkCxxRevisionMacro(VISU_XYPlotActor, "$Revision$");
+vtkStandardNewMacro(VISU_XYPlotActor);
+
+vtkCxxSetObjectMacro(VISU_XYPlotActor,TitleTextProperty,vtkTextProperty);
+vtkCxxSetObjectMacro(VISU_XYPlotActor,AxisLabelTextProperty,vtkTextProperty);
+vtkCxxSetObjectMacro(VISU_XYPlotActor,AxisTitleTextProperty,vtkTextProperty);
+
+//----------------------------------------------------------------------------
+// Instantiate object
+VISU_XYPlotActor::VISU_XYPlotActor()
+{
+ this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
+ this->PositionCoordinate->SetValue(0.25,0.25);
+ this->Position2Coordinate->SetValue(0.5, 0.5);
+
+ this->InputList = vtkDataSetCollection::New();
+ this->SelectedInputScalars = NULL;
+ this->SelectedInputScalarsComponent = vtkIntArray::New();
+ this->DataObjectInputList = vtkDataObjectCollection::New();
+
+ this->Title = NULL;
+ this->XTitle = new char[7];
+ sprintf(this->XTitle,"%s","X Axis");
+ this->YTitle = new char[7];
+ sprintf(this->YTitle,"%s","Y Axis");
+
+ this->XValues = VTK_XYPLOT_INDEX;
+ this->PlotLocation = VISU_XYPLOT_BOTTOM; // RKV
+
+ this->NumberOfXLabels = 5;
+ this->NumberOfYLabels = 5;
+
+ this->TitleTextProperty = vtkTextProperty::New();
+ this->TitleTextProperty->SetBold(1);
+ this->TitleTextProperty->SetItalic(1);
+ this->TitleTextProperty->SetShadow(1);
+ this->TitleTextProperty->SetFontFamilyToArial();
+
+ this->AxisLabelTextProperty = vtkTextProperty::New();
+ this->AxisLabelTextProperty->ShallowCopy(this->TitleTextProperty);
+
+ this->AxisTitleTextProperty = vtkTextProperty::New();
+ this->AxisTitleTextProperty->ShallowCopy(this->AxisLabelTextProperty);
+
+ this->LabelFormat = new char[8];
+ sprintf(this->LabelFormat,"%s","%-#6.3g");
+
+ this->Logx = 0;
+
+ this->XRange[0] = 0.0;
+ this->XRange[1] = 0.0;
+ this->YRange[0] = 0.0;
+ this->YRange[1] = 0.0;
+
+ this->Border = 5;
+ this->PlotLines = 1;
+ this->PlotPoints = 0;
+ this->PlotCurveLines = 0;
+ this->PlotCurvePoints = 0;
+ this->ExchangeAxes = 0;
+ this->ReverseXAxis = 0;
+ this->ReverseYAxis = 0;
+
+ this->TitleMapper = vtkTextMapper::New();
+ this->TitleActor = vtkActor2D::New();
+ this->TitleActor->SetMapper(this->TitleMapper);
+ this->TitleActor->GetPositionCoordinate()->SetCoordinateSystemToViewport();
+
+ this->XAxis = vtkAxisActor2D::New();
+ this->XAxis->GetPositionCoordinate()->SetCoordinateSystemToViewport();
+ this->XAxis->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
+ this->XAxis->SetProperty(this->GetProperty());
+
+ this->YAxis = vtkAxisActor2D::New();
+ this->YAxis->GetPositionCoordinate()->SetCoordinateSystemToViewport();
+ this->YAxis->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
+ this->YAxis->SetProperty(this->GetProperty());
+
+ this->NumberOfInputs = 0;
+ this->PlotData = NULL;
+ this->PlotGlyph = NULL;
+ this->PlotAppend = NULL;
+ this->PlotTransform = NULL; // RKV
+ this->PlotMapper = NULL;
+ this->PlotActor = NULL;
+
+ this->ViewportCoordinate[0] = 0.0;
+ this->ViewportCoordinate[1] = 0.0;
+ this->PlotCoordinate[0] = 0.0;
+ this->PlotCoordinate[1] = 0.0;
+
+ this->DataObjectPlotMode = VTK_XYPLOT_COLUMN;
+ this->XComponent = vtkIntArray::New();
+ this->XComponent->SetNumberOfValues(VTK_MAX_PLOTS);
+ this->YComponent = vtkIntArray::New();
+ this->YComponent->SetNumberOfValues(VTK_MAX_PLOTS);
+
+ this->LinesOn = vtkIntArray::New();
+ this->LinesOn->SetNumberOfValues(VTK_MAX_PLOTS);
+ this->PointsOn = vtkIntArray::New();
+ this->PointsOn->SetNumberOfValues(VTK_MAX_PLOTS);
+ for (int i=0; i<VTK_MAX_PLOTS; i++)
+ {
+ this->XComponent->SetValue(i,0);
+ this->YComponent->SetValue(i,0);
+ this->LinesOn->SetValue(i,this->PlotLines);
+ this->PointsOn->SetValue(i,this->PlotPoints);
+ }
+
+ this->Legend = 0;
+ this->LegendPosition[0] = 0.85;
+ this->LegendPosition[1] = 0.75;
+ this->LegendPosition2[0] = 0.15;
+ this->LegendPosition2[1] = 0.20;
+ this->LegendActor = vtkLegendBoxActor::New();
+ this->LegendActor->GetPositionCoordinate()->SetCoordinateSystemToViewport();
+ this->LegendActor->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
+ this->LegendActor->GetPosition2Coordinate()->SetReferenceCoordinate(NULL);
+ this->LegendActor->BorderOff();
+ this->LegendActor->SetNumberOfEntries(VTK_MAX_PLOTS); //initial allocation
+ this->GlyphSource = vtkGlyphSource2D::New();
+ this->GlyphSource->SetGlyphTypeToNone();
+ this->GlyphSource->DashOn();
+ this->GlyphSource->FilledOff();
+ this->GlyphSize = 0.020;
+
+ this->ClipPlanes = vtkPlanes::New();
+ vtkPoints *pts = vtkPoints::New();
+ pts->SetNumberOfPoints(4);
+ this->ClipPlanes->SetPoints(pts);
+ pts->Delete();
+ vtkDoubleArray *n = vtkDoubleArray::New();
+ n->SetNumberOfComponents(3);
+ n->SetNumberOfTuples(4);
+ this->ClipPlanes->SetNormals(n);
+ n->Delete();
+
+ this->CachedSize[0] = 0;
+ this->CachedSize[1] = 0;
+}
+
+//----------------------------------------------------------------------------
+VISU_XYPlotActor::~VISU_XYPlotActor()
+{
+ // Get rid of the list of array names.
+ int num = this->InputList->GetNumberOfItems();
+ if (this->SelectedInputScalars)
+ {
+ for (int i = 0; i < num; ++i)
+ {
+ if (this->SelectedInputScalars[i])
+ {
+ delete [] this->SelectedInputScalars[i];
+ this->SelectedInputScalars[i] = NULL;
+ }
+ }
+ delete [] this->SelectedInputScalars;
+ this->SelectedInputScalars = NULL;
+ }
+ this->SelectedInputScalarsComponent->Delete();
+ this->SelectedInputScalarsComponent = NULL;
+
+ // Now we can get rid of the inputs.
+ this->InputList->Delete();
+ this->InputList = NULL;
+
+ this->DataObjectInputList->Delete();
+ this->DataObjectInputList = NULL;
+
+ this->TitleMapper->Delete();
+ this->TitleMapper = NULL;
+ this->TitleActor->Delete();
+ this->TitleActor = NULL;
+
+ this->SetTitle(0);
+ this->SetXTitle(0);
+ this->SetYTitle(0);
+ this->SetLabelFormat(0);
+
+ this->XAxis->Delete();
+ this->YAxis->Delete();
+
+ this->InitializeEntries();
+
+ this->LegendActor->Delete();
+ this->GlyphSource->Delete();
+ this->ClipPlanes->Delete();
+
+ this->XComponent->Delete();
+ this->YComponent->Delete();
+
+ this->LinesOn->Delete();
+ this->PointsOn->Delete();
+
+ this->SetTitleTextProperty(NULL);
+ this->SetAxisLabelTextProperty(NULL);
+ this->SetAxisTitleTextProperty(NULL);
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::InitializeEntries()
+{
+ if ( this->NumberOfInputs > 0 )
+ {
+ for (int i=0; i<this->NumberOfInputs; i++)
+ {
+ this->PlotData[i]->Delete();
+ this->PlotGlyph[i]->Delete();
+ this->PlotAppend[i]->Delete();
+ this->PlotTransform[i]->Delete(); // RKV
+ this->PlotMapper[i]->Delete();
+ this->PlotActor[i]->Delete();
+ }//for all entries
+ delete [] this->PlotData; this->PlotData = NULL;
+ delete [] this->PlotGlyph; this->PlotGlyph = NULL;
+ delete [] this->PlotAppend; this->PlotAppend = NULL;
+ delete [] this->PlotTransform; this->PlotTransform = NULL; // RKV
+ delete [] this->PlotMapper; this->PlotMapper = NULL;
+ delete [] this->PlotActor; this->PlotActor = NULL;
+ this->NumberOfInputs = 0;
+ }//if entries have been defined
+}
+
+//----------------------------------------------------------------------------
+// Add a dataset and array to the list of data to plot.
+void VISU_XYPlotActor::AddInput(vtkDataSet *ds, const char *arrayName, int component)
+{
+ int idx, num;
+ char** newNames;
+
+ // I cannot change the input list, because the user has direct
+ // access to the collection. I cannot store the index of the array,
+ // because the index might change from render to render ...
+ // I have to store the list of string array names.
+
+ // I believe idx starts at 1 and goes to "NumberOfItems".
+ idx = this->InputList->IsItemPresent(ds);
+ if (idx > 0)
+ { // Return if arrays are the same.
+ if (arrayName == NULL && this->SelectedInputScalars[idx-1] == NULL &&
+ component == this->SelectedInputScalarsComponent->GetValue(idx-1))
+ {
+ return;
+ }
+ if (arrayName != NULL && this->SelectedInputScalars[idx-1] != NULL &&
+ strcmp(arrayName, this->SelectedInputScalars[idx-1]) == 0 &&
+ component == this->SelectedInputScalarsComponent->GetValue(idx-1))
+ {
+ return;
+ }
+ }
+
+ // The input/array/component must be a unique combination. Add it to our input list.
+
+ // Now reallocate the list of strings and add the new value.
+ num = this->InputList->GetNumberOfItems();
+ newNames = new char*[num+1];
+ for (idx = 0; idx < num; ++idx)
+ {
+ newNames[idx] = this->SelectedInputScalars[idx];
+ }
+ if (arrayName == NULL)
+ {
+ newNames[num] = NULL;
+ }
+ else
+ {
+ newNames[num] = new char[strlen(arrayName)+1];
+ strcpy(newNames[num],arrayName);
+ }
+ delete [] this->SelectedInputScalars;
+ this->SelectedInputScalars = newNames;
+
+ // Save the component in the int array.
+ this->SelectedInputScalarsComponent->InsertValue(num, component);
+
+ // Add the data set to the collection
+ this->InputList->AddItem(ds);
+
+ // In case of multiple use of a XYPlotActor the NumberOfEntries could be set
+ // to n. Then when a call to SetEntryString(n+1, bla) was done the string was lost
+ // Need to update the number of entries for the legend actor
+ this->LegendActor->SetNumberOfEntries(this->LegendActor->GetNumberOfEntries()+1);
+
+ this->Modified();
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::RemoveAllInputs()
+{
+ int idx, num;
+
+ num = this->InputList->GetNumberOfItems();
+ this->InputList->RemoveAllItems();
+
+ for (idx = 0; idx < num; ++idx)
+ {
+ if (this->SelectedInputScalars[idx])
+ {
+ delete [] this->SelectedInputScalars[idx];
+ this->SelectedInputScalars[idx] = NULL;
+ }
+ }
+ this->SelectedInputScalarsComponent->Reset();
+
+ this->DataObjectInputList->RemoveAllItems();
+}
+
+//----------------------------------------------------------------------------
+// Remove a dataset from the list of data to plot.
+void VISU_XYPlotActor::RemoveInput(vtkDataSet *ds, const char *arrayName, int component)
+{
+ int idx, num;
+ vtkDataSet *input;
+ int found = -1;
+
+ // This is my own find routine, because the array names have to match also.
+ num = this->InputList->GetNumberOfItems();
+ vtkCollectionSimpleIterator dsit;
+ this->InputList->InitTraversal(dsit);
+ for (idx = 0; idx < num && found == -1; ++idx)
+ {
+ input = this->InputList->GetNextDataSet(dsit);
+ if (input == ds)
+ {
+ if (arrayName == NULL && this->SelectedInputScalars[idx] == NULL &&
+ component == this->SelectedInputScalarsComponent->GetValue(idx))
+ {
+ found = idx;
+ }
+ if (arrayName != NULL && this->SelectedInputScalars[idx] != NULL &&
+ strcmp(arrayName, this->SelectedInputScalars[idx]) == 0 &&
+ component == this->SelectedInputScalarsComponent->GetValue(idx))
+ {
+ found = idx;
+ }
+ }
+ }
+
+ if (found == -1)
+ {
+ return;
+ }
+
+ this->Modified();
+ // Collections index their items starting at 1.
+ this->InputList->RemoveItem(found);
+
+ // Do not bother reallocating the SelectedInputScalars
+ // string array to make it smaller.
+ if (this->SelectedInputScalars[found])
+ {
+ delete [] this->SelectedInputScalars[found];
+ this->SelectedInputScalars[found] = NULL;
+ }
+ for (idx = found+1; idx < num; ++idx)
+ {
+ this->SelectedInputScalars[idx-1] = this->SelectedInputScalars[idx];
+ this->SelectedInputScalarsComponent->SetValue(idx-1,
+ this->SelectedInputScalarsComponent->GetValue(idx));
+ }
+ // Reseting the last item is not really necessary,
+ // but to be clean we do it anyway.
+ this->SelectedInputScalarsComponent->SetValue(num-1, -1);
+ this->SelectedInputScalars[num-1] = NULL;
+}
+
+//----------------------------------------------------------------------------
+// Add a data object to the list of data to plot.
+void VISU_XYPlotActor::AddDataObjectInput(vtkDataObject *in)
+{
+ if ( ! this->DataObjectInputList->IsItemPresent(in) )
+ {
+ this->Modified();
+ this->DataObjectInputList->AddItem(in);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Remove a data object from the list of data to plot.
+void VISU_XYPlotActor::RemoveDataObjectInput(vtkDataObject *in)
+{
+ if ( this->DataObjectInputList->IsItemPresent(in) )
+ {
+ this->Modified();
+ this->DataObjectInputList->RemoveItem(in);
+ }
+}
+
+//----------------------------------------------------------------------------
+// Plot scalar data for each input dataset.
+int VISU_XYPlotActor::RenderOverlay(vtkViewport *viewport)
+{
+ int renderedSomething = 0;
+
+ // Make sure input is up to date.
+ if ( this->InputList->GetNumberOfItems() < 1 &&
+ this->DataObjectInputList->GetNumberOfItems() < 1 )
+ {
+ vtkErrorMacro(<< "Nothing to plot!");
+ return 0;
+ }
+
+ renderedSomething += this->XAxis->RenderOverlay(viewport);
+ renderedSomething += this->YAxis->RenderOverlay(viewport);
+ if ( this->Title )
+ {
+ renderedSomething += this->TitleActor->RenderOverlay(viewport);
+ }
+ for (int i=0; i < this->NumberOfInputs; i++)
+ {
+ renderedSomething += this->PlotActor[i]->RenderOverlay(viewport);
+ }
+ if ( this->Legend )
+ {
+ renderedSomething += this->LegendActor->RenderOverlay(viewport);
+ }
+
+ return renderedSomething;
+}
+
+//----------------------------------------------------------------------------
+// Plot scalar data for each input dataset.
+int VISU_XYPlotActor::RenderOpaqueGeometry(vtkViewport *viewport)
+{
+ unsigned long mtime, dsMtime;
+ vtkDataSet *ds;
+ vtkDataObject *dobj;
+ int numDS, numDO, renderedSomething=0;
+
+ // Initialize
+ // Make sure input is up to date.
+ numDS = this->InputList->GetNumberOfItems();
+ numDO = this->DataObjectInputList->GetNumberOfItems();
+ if ( numDS > 0 )
+ {
+ vtkDebugMacro(<<"Plotting input data sets");
+ vtkCollectionSimpleIterator dsit;
+ for (mtime=0, this->InputList->InitTraversal(dsit);
+ (ds = this->InputList->GetNextDataSet(dsit)); )
+ {
+ ds->Update();
+ dsMtime = ds->GetMTime();
+ if ( dsMtime > mtime )
+ {
+ mtime = dsMtime;
+ }
+ }
+ }
+ else if ( numDO > 0 )
+ {
+ vtkDebugMacro(<<"Plotting input data objects");
+ vtkCollectionSimpleIterator doit;
+ for (mtime=0, this->DataObjectInputList->InitTraversal(doit);
+ (dobj = this->DataObjectInputList->GetNextDataObject(doit)); )
+ {
+ dobj->Update();
+ dsMtime = dobj->GetMTime();
+ if ( dsMtime > mtime )
+ {
+ mtime = dsMtime;
+ }
+ }
+ }
+ else
+ {
+ vtkErrorMacro(<< "Nothing to plot!");
+ return 0;
+ }
+
+ if (this->Title && this->Title[0] && !this->TitleTextProperty)
+ {
+ vtkErrorMacro(<< "Need a title text property to render plot title");
+ return 0;
+ }
+
+ // Check modified time to see whether we have to rebuild.
+ // Pay attention that GetMTime() has been redefined (see below)
+
+ int *size=viewport->GetSize();
+ if (mtime > this->BuildTime ||
+ size[0] != this->CachedSize[0] || size[1] != this->CachedSize[1] ||
+ this->GetMTime() > this->BuildTime ||
+ (this->Title && this->Title[0] &&
+ this->TitleTextProperty->GetMTime() > this->BuildTime) ||
+ (this->AxisLabelTextProperty &&
+ this->AxisLabelTextProperty->GetMTime() > this->BuildTime) ||
+ (this->AxisTitleTextProperty &&
+ this->AxisTitleTextProperty->GetMTime() > this->BuildTime))
+ {
+ double range[2], yrange[2], xRange[2], yRange[2], interval, *lengths=NULL;
+ int pos[2], pos2[2], numTicks;
+ int stringSize[2];
+ int num = ( numDS > 0 ? numDS : numDO );
+
+ vtkDebugMacro(<<"Rebuilding plot");
+ this->CachedSize[0] = size[0];
+ this->CachedSize[1] = size[1];
+
+ // RKV : Begin
+ if ((this->PlotLocation == VISU_XYPLOT_RIGHT) || (this->PlotLocation == VISU_XYPLOT_LEFT))
+ this->ReverseYAxis = 1;
+ else
+ this->ReverseYAxis = 0;
+ // RKV : End
+
+ // manage legend
+ vtkDebugMacro(<<"Rebuilding legend");
+ if ( this->Legend )
+ {
+ int legPos[2], legPos2[2];
+ int *p1 = this->PositionCoordinate->GetComputedViewportValue(viewport);
+ int *p2 = this->Position2Coordinate->GetComputedViewportValue(viewport);
+ legPos[0] = (int)(p1[0] + this->LegendPosition[0]*(p2[0]-p1[0]));
+ legPos2[0] = (int)(legPos[0] + this->LegendPosition2[0]*(p2[0]-p1[0]));
+ legPos[1] = (int)(p1[1] + this->LegendPosition[1]*(p2[1]-p1[1]));
+ legPos2[1] = (int)(legPos[1] + this->LegendPosition2[1]*(p2[1]-p1[1]));
+
+ this->LegendActor->GetPositionCoordinate()->SetValue(
+ (double)legPos[0], (double)legPos[1]);
+ this->LegendActor->GetPosition2Coordinate()->SetValue(
+ (double)legPos2[0], (double)legPos2[1]);
+ this->LegendActor->SetNumberOfEntries(num);
+ for (int i=0; i<num; i++)
+ {
+ if ( ! this->LegendActor->GetEntrySymbol(i) )
+ {
+ this->LegendActor->SetEntrySymbol(i,this->GlyphSource->GetOutput());
+ }
+ if ( ! this->LegendActor->GetEntryString(i) )
+ {
+ static char legendString[12];
+ sprintf(legendString, "%s%d", "Curve ", i);
+ this->LegendActor->SetEntryString(i,legendString);
+ }
+ }
+
+ this->LegendActor->SetPadding(2);
+ this->LegendActor->GetProperty()->DeepCopy(this->GetProperty());
+ this->LegendActor->ScalarVisibilityOff();
+ }
+
+ // Rebuid text props
+ // Perform shallow copy here since each individual axis can be
+ // accessed through the class API (i.e. each individual axis text prop
+ // can be changed). Therefore, we can not just assign pointers otherwise
+ // each individual axis text prop would point to the same text prop.
+
+ if (this->AxisLabelTextProperty &&
+ this->AxisLabelTextProperty->GetMTime() > this->BuildTime)
+ {
+ if (this->XAxis->GetTitleTextProperty())
+ {
+ this->XAxis->GetLabelTextProperty()->ShallowCopy(
+ this->AxisLabelTextProperty);
+ }
+ if (this->YAxis->GetTitleTextProperty())
+ {
+ this->YAxis->GetLabelTextProperty()->ShallowCopy(
+ this->AxisLabelTextProperty);
+ }
+ }
+
+ if (this->AxisTitleTextProperty &&
+ this->AxisTitleTextProperty->GetMTime() > this->BuildTime)
+ {
+ if (this->XAxis->GetTitleTextProperty())
+ {
+ this->XAxis->GetTitleTextProperty()->ShallowCopy(
+ this->AxisTitleTextProperty);
+ }
+ if (this->YAxis->GetTitleTextProperty())
+ {
+ this->YAxis->GetTitleTextProperty()->ShallowCopy(
+ this->AxisTitleTextProperty);
+ }
+ }
+
+ // setup x-axis
+ vtkDebugMacro(<<"Rebuilding x-axis");
+
+ this->XAxis->SetTitle(this->XTitle);
+ this->XAxis->SetNumberOfLabels(this->NumberOfXLabels);
+ this->XAxis->SetProperty(this->GetProperty());
+
+ vtkDebugMacro(<<"xrange = (" << range[0] << ", " << range[1] << ")"); // RKV
+ lengths = new double[num];
+ if ( numDS > 0 ) //plotting data sets
+ {
+ this->ComputeXRange(range, lengths);
+ }
+ else
+ {
+ this->ComputeDORange(range, yrange, lengths);
+ }
+ if ( this->XRange[0] < this->XRange[1] )
+ {
+ range[0] = this->XRange[0];
+ range[1] = this->XRange[1];
+ }
+
+/* RKV vtkAxisActor2D::ComputeRange(range, xRange, this->NumberOfXLabels,
+ numTicks, interval);
+*/ // RKV : Begin
+ vtkDebugMacro(<<"XRange = (" << XRange[0] << ", " << XRange[1] << ")");
+ vtkDebugMacro(<<"xrange = (" << range[0] << ", " << range[1] << ")");
+ xRange[0] = range[0];
+ xRange[1] = range[1];
+ // RKV : End
+ if ( !this->ExchangeAxes )
+ {
+ this->XComputedRange[0] = xRange[0];
+ this->XComputedRange[1] = xRange[1];
+ if ( this->ReverseXAxis )
+ {
+ this->XAxis->SetRange(range[1],range[0]);
+ }
+ else
+ {
+ this->XAxis->SetRange(range[0],range[1]);
+ }
+ }
+ else
+ {
+ this->XComputedRange[1] = xRange[0];
+ this->XComputedRange[0] = xRange[1];
+ if ( this->ReverseYAxis )
+ {
+ this->XAxis->SetRange(range[0],range[1]);
+ }
+ else
+ {
+ this->XAxis->SetRange(range[1],range[0]);
+ }
+ }
+
+ // setup y-axis
+ vtkDebugMacro(<<"Rebuilding y-axis");
+ this->YAxis->SetTitle(this->YTitle);
+ this->YAxis->SetNumberOfLabels(this->NumberOfYLabels);
+
+ vtkDebugMacro(<<"yrange = (" << yrange[0] << ", " << yrange[1] << ")"); // RKV
+ if ( this->YRange[0] >= this->YRange[1] )
+ {
+ if ( numDS > 0 ) //plotting data sets
+ {
+ this->ComputeYRange(yrange);
+ }
+ }
+ else
+ {
+ yrange[0] = this->YRange[0];
+ yrange[1] = this->YRange[1];
+ }
+/* RKV vtkAxisActor2D::ComputeRange(yrange, yRange, this->NumberOfYLabels,
+ numTicks, interval);
+*/
+ // RKV : Begin
+ vtkDebugMacro(<<"YRange = (" << YRange[0] << ", " << YRange[1] << ")");
+ vtkDebugMacro(<<"yrange = (" << yrange[0] << ", " << yrange[1] << ")");
+ yRange[0] = yrange[0];
+ yRange[1] = yrange[1];
+ // RKV : End
+
+ if ( !this->ExchangeAxes )
+ {
+ this->YComputedRange[0] = yRange[0];
+ this->YComputedRange[1] = yRange[1];
+ if ( this->ReverseYAxis )
+ {
+ this->YAxis->SetRange(yrange[0],yrange[1]);
+ }
+ else
+ {
+ this->YAxis->SetRange(yrange[1],yrange[0]);
+ }
+ }
+ else
+ {
+ this->YComputedRange[1] = yRange[0];
+ this->YComputedRange[0] = yRange[1];
+ if ( this->ReverseXAxis )
+ {
+ this->YAxis->SetRange(yrange[1],yrange[0]);
+ }
+ else
+ {
+ this->YAxis->SetRange(yrange[0],yrange[1]);
+ }
+ }
+
+
+ this->PlaceAxes(viewport, size, pos, pos2);
+
+ // manage title
+ if (this->Title != NULL && this->Title[0])
+ {
+ this->TitleMapper->SetInput(this->Title);
+ if (this->TitleTextProperty->GetMTime() > this->BuildTime)
+ {
+ this->TitleMapper->GetTextProperty()->ShallowCopy(
+ this->TitleTextProperty);
+ }
+
+ vtkAxisActor2D::SetFontSize(viewport,
+ this->TitleMapper,
+ size,
+ 1.0,
+ stringSize);
+
+ this->TitleActor->GetPositionCoordinate()->SetValue(
+ pos[0] + 0.5 * (pos2[0] - pos[0]) - stringSize[0] / 2.0,
+ pos2[1] - stringSize[1] / 2.0);
+
+ this->TitleActor->SetProperty(this->GetProperty());
+ }
+
+ vtkDebugMacro(<<"Creating Plot Data");
+ // Okay, now create the plot data and set up the pipeline
+ this->CreatePlotData(pos, pos2, xRange, yRange, lengths, numDS, numDO);
+ delete [] lengths;
+
+ this->BuildTime.Modified();
+
+ }//if need to rebuild the plot
+
+ vtkDebugMacro(<<"Rendering Axes");
+ renderedSomething += this->XAxis->RenderOpaqueGeometry(viewport);
+ renderedSomething += this->YAxis->RenderOpaqueGeometry(viewport);
+ for (int i=0; i < this->NumberOfInputs; i++)
+ {
+ vtkDebugMacro(<<"Rendering plotactors");
+ renderedSomething += this->PlotActor[i]->RenderOpaqueGeometry(viewport);
+ }
+ if ( this->Title )
+ {
+ vtkDebugMacro(<<"Rendering titleactors");
+ renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
+ }
+ if ( this->Legend )
+ {
+ vtkDebugMacro(<<"Rendering legendeactors");
+ renderedSomething += this->LegendActor->RenderOpaqueGeometry(viewport);
+ }
+
+ return renderedSomething;
+}
+
+//----------------------------------------------------------------------------
+const char *VISU_XYPlotActor::GetXValuesAsString()
+{
+ switch (this->XValues)
+ {
+ case VTK_XYPLOT_INDEX:
+ return "Index";
+ case VTK_XYPLOT_ARC_LENGTH:
+ return "ArcLength";
+ case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
+ return "NormalizedArcLength";
+ default:
+ return "Value";
+ }
+}
+
+//----------------------------------------------------------------------------
+const char *VISU_XYPlotActor::GetDataObjectPlotModeAsString()
+{
+ if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
+ {
+ return "Plot Rows";
+ }
+ else
+ {
+ return "Plot Columns";
+ }
+}
+
+//----------------------------------------------------------------------------
+// Release any graphics resources that are being consumed by this actor.
+// The parameter window could be used to determine which graphic
+// resources to release.
+void VISU_XYPlotActor::ReleaseGraphicsResources(vtkWindow *win)
+{
+ this->TitleActor->ReleaseGraphicsResources(win);
+ this->XAxis->ReleaseGraphicsResources(win);
+ this->YAxis->ReleaseGraphicsResources(win);
+ for (int i=0; i < this->NumberOfInputs; i++)
+ {
+ this->PlotActor[i]->ReleaseGraphicsResources(win);
+ }
+ this->LegendActor->ReleaseGraphicsResources(win);
+}
+
+//----------------------------------------------------------------------------
+unsigned long VISU_XYPlotActor::GetMTime()
+{
+ unsigned long mtime, mtime2;
+ mtime = this->vtkActor2D::GetMTime();
+
+ if (this->Legend)
+ {
+ mtime2 = this->LegendActor->GetMTime();
+ if (mtime2 > mtime)
+ {
+ mtime = mtime2;
+ }
+ }
+
+ return mtime;
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::PrintSelf(ostream& os, vtkIndent indent)
+{
+ vtkIndent i2 = indent.GetNextIndent();
+ vtkDataSet *input;
+ char *array;
+ int component;
+ int idx, num;
+
+ this->Superclass::PrintSelf(os,indent);
+
+ vtkCollectionSimpleIterator dsit;
+ this->InputList->InitTraversal(dsit);
+ num = this->InputList->GetNumberOfItems();
+ os << indent << "DataSetInputs: " << endl;
+ for (idx = 0; idx < num; ++idx)
+ {
+ input = this->InputList->GetNextDataSet(dsit);
+ array = this->SelectedInputScalars[idx];
+ component = this->SelectedInputScalarsComponent->GetValue((vtkIdType)idx);
+ if (array == NULL)
+ {
+ os << i2 << "(" << input << ") Default Scalars, Component = " << component << endl;
+ }
+ else
+ {
+ os << i2 << "(" << input << ") " << array << ", Component = " << component << endl;
+ }
+ }
+
+ os << indent << "Input DataObjects:\n";
+ this->DataObjectInputList->PrintSelf(os,indent.GetNextIndent());
+
+ if (this->TitleTextProperty)
+ {
+ os << indent << "Title Text Property:\n";
+ this->TitleTextProperty->PrintSelf(os,indent.GetNextIndent());
+ }
+ else
+ {
+ os << indent << "Title Text Property: (none)\n";
+ }
+
+ if (this->AxisTitleTextProperty)
+ {
+ os << indent << "Axis Title Text Property:\n";
+ this->AxisTitleTextProperty->PrintSelf(os,indent.GetNextIndent());
+ }
+ else
+ {
+ os << indent << "Axis Title Text Property: (none)\n";
+ }
+
+ if (this->AxisLabelTextProperty)
+ {
+ os << indent << "Axis Label Text Property:\n";
+ this->AxisLabelTextProperty->PrintSelf(os,indent.GetNextIndent());
+ }
+ else
+ {
+ os << indent << "Axis Label Text Property: (none)\n";
+ }
+
+ os << indent << "Data Object Plot Mode: " << this->GetDataObjectPlotModeAsString() << endl;
+
+ os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
+ os << indent << "X Title: "
+ << (this->XTitle ? this->XTitle : "(none)") << "\n";
+ os << indent << "Y Title: "
+ << (this->YTitle ? this->YTitle : "(none)") << "\n";
+
+ os << indent << "X Values: " << this->GetXValuesAsString() << endl;
+ os << indent << "Log X Values: " << (this->Logx ? "On\n" : "Off\n");
+
+ os << indent << "Plot global-points: " << (this->PlotPoints ? "On\n" : "Off\n");
+ os << indent << "Plot global-lines: " << (this->PlotLines ? "On\n" : "Off\n");
+ os << indent << "Plot per-curve points: " << (this->PlotCurvePoints ? "On\n" : "Off\n");
+ os << indent << "Plot per-curve lines: " << (this->PlotCurveLines ? "On\n" : "Off\n");
+ os << indent << "Exchange Axes: " << (this->ExchangeAxes ? "On\n" : "Off\n");
+ os << indent << "Reverse X Axis: " << (this->ReverseXAxis ? "On\n" : "Off\n");
+ os << indent << "Reverse Y Axis: " << (this->ReverseYAxis ? "On\n" : "Off\n");
+
+ os << indent << "Number Of X Labels: " << this->NumberOfXLabels << "\n";
+ os << indent << "Number Of Y Labels: " << this->NumberOfYLabels << "\n";
+
+ os << indent << "Label Format: " << this->LabelFormat << "\n";
+ os << indent << "Border: " << this->Border << "\n";
+
+ os << indent << "X Range: ";
+ if ( this->XRange[0] >= this->XRange[1] )
+ {
+ os << indent << "(Automatically Computed)\n";
+ }
+ else
+ {
+ os << "(" << this->XRange[0] << ", " << this->XRange[1] << ")\n";
+ }
+
+ os << indent << "Y Range: ";
+ if ( this->XRange[0] >= this->YRange[1] )
+ {
+ os << indent << "(Automatically Computed)\n";
+ }
+ else
+ {
+ os << "(" << this->YRange[0] << ", " << this->YRange[1] << ")\n";
+ }
+
+ os << indent << "Viewport Coordinate: ("
+ << this->ViewportCoordinate[0] << ", "
+ << this->ViewportCoordinate[1] << ")\n";
+
+ os << indent << "Plot Coordinate: ("
+ << this->PlotCoordinate[0] << ", "
+ << this->PlotCoordinate[1] << ")\n";
+
+ os << indent << "Legend: " << (this->Legend ? "On\n" : "Off\n");
+ os << indent << "Legend Position: ("
+ << this->LegendPosition[0] << ", "
+ << this->LegendPosition[1] << ")\n";
+ os << indent << "Legend Position2: ("
+ << this->LegendPosition2[0] << ", "
+ << this->LegendPosition2[1] << ")\n";
+
+ os << indent << "Glyph Size: " << this->GlyphSize << endl;
+
+ os << indent << "Legend Actor:";
+ this->LegendActor->PrintSelf( os << endl, i2);
+ os << indent << "Glyph Source:";
+ this->GlyphSource->PrintSelf( os << endl, i2);
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::ComputeXRange(double range[2], double *lengths)
+{
+ int dsNum;
+ vtkIdType numPts, ptId, maxNum;
+ double maxLength=0.0, xPrev[3], x[3];
+ vtkDataSet *ds;
+
+ range[0] = VTK_DOUBLE_MAX, range[1] = VTK_DOUBLE_MIN;
+
+ vtkCollectionSimpleIterator dsit;
+ for ( dsNum=0, maxNum=0, this->InputList->InitTraversal(dsit);
+ (ds = this->InputList->GetNextDataSet(dsit)); dsNum++)
+ {
+ numPts = ds->GetNumberOfPoints();
+
+ if ( this->XValues != VTK_XYPLOT_INDEX )
+ {
+ ds->GetPoint(0, xPrev);
+ for ( lengths[dsNum]=0.0, ptId=0; ptId < numPts; ptId++ )
+ {
+ ds->GetPoint(ptId, x);
+ switch (this->XValues)
+ {
+ case VTK_XYPLOT_VALUE:
+ if (this->GetLogx() == 0)
+ {
+ if ( x[this->XComponent->GetValue(dsNum)] < range[0] )
+ {
+ range[0] = x[this->XComponent->GetValue(dsNum)];
+ }
+ if ( x[this->XComponent->GetValue(dsNum)] > range[1] )
+ {
+ range[1] = x[this->XComponent->GetValue(dsNum)];
+ }
+ }
+ else
+ {
+ //ensure range strictly > 0 for log
+ if ( (x[this->XComponent->GetValue(dsNum)]) < range[0] &&
+ (x[this->XComponent->GetValue(dsNum)] > 0))
+ {
+ range[0] = x[this->XComponent->GetValue(dsNum)];
+ }
+ if ( (x[this->XComponent->GetValue(dsNum)] > range[1]) &&
+ (x[this->XComponent->GetValue(dsNum)] > 0))
+ {
+ range[1] = x[this->XComponent->GetValue(dsNum)];
+ }
+ }
+ break;
+ default:
+ lengths[dsNum] += sqrt(vtkMath::Distance2BetweenPoints(x,xPrev));
+ xPrev[0] = x[0]; xPrev[1] = x[1]; xPrev[2] = x[2];
+ }
+ }//for all points
+ if ( lengths[dsNum] > maxLength )
+ {
+ maxLength = lengths[dsNum];
+ }
+ }//if need to visit all points
+
+ else //if ( this->XValues == VTK_XYPLOT_INDEX )
+ {
+ if ( numPts > maxNum )
+ {
+ maxNum = numPts;
+ }
+ }
+ }//over all datasets
+
+ // determine the range
+ switch (this->XValues)
+ {
+ case VTK_XYPLOT_ARC_LENGTH:
+ range[0] = 0.0;
+ range[1] = maxLength;
+ break;
+ case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
+ range[0] = 0.0;
+ range[1] = 1.0;
+ break;
+ case VTK_XYPLOT_INDEX:
+ range[0] = 0.0;
+ range[1] = (double)(maxNum - 1);
+ break;
+ case VTK_XYPLOT_VALUE:
+ if (this->GetLogx() == 1)
+ {
+ if (range[0] > range[1])
+ {
+ range[0] = 0;
+ range[1] = 0;
+ }
+ else
+ {
+ range[0] = log10(range[0]);
+ range[1] = log10(range[1]);
+ }
+ }
+ break; //range computed in for loop above
+ default:
+ vtkErrorMacro(<< "Unkown X-Value option.");
+ return;
+ }
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::ComputeYRange(double range[2])
+{
+ vtkDataSet *ds;
+ vtkDataArray *scalars;
+ double sRange[2];
+ int count;
+ int component;
+
+ range[0]=VTK_DOUBLE_MAX, range[1]=VTK_DOUBLE_MIN;
+
+ vtkCollectionSimpleIterator dsit;
+ for ( this->InputList->InitTraversal(dsit), count = 0;
+ (ds = this->InputList->GetNextDataSet(dsit)); ++count)
+ {
+ scalars = ds->GetPointData()->GetScalars(this->SelectedInputScalars[count]);
+ component = this->SelectedInputScalarsComponent->GetValue(count);
+ if ( !scalars)
+ {
+ vtkErrorMacro(<<"No scalar data to plot!");
+ continue;
+ }
+ if ( component < 0 || component >= scalars->GetNumberOfComponents())
+ {
+ vtkErrorMacro(<<"Bad component!");
+ continue;
+ }
+
+ scalars->GetRange(sRange, component);
+ if ( sRange[0] < range[0] )
+ {
+ range[0] = sRange[0];
+ }
+
+ if ( sRange[1] > range[1] )
+ {
+ range[1] = sRange[1];
+ }
+ }//over all datasets
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::ComputeDORange(double xrange[2], double yrange[2],
+ double *lengths)
+{
+ int i;
+ vtkDataObject *dobj;
+ vtkFieldData *field;
+ int doNum, numColumns;
+ vtkIdType numTuples, numRows, num, ptId, maxNum;
+ double maxLength=0.0, x, y, xPrev = 0.0;
+ vtkDataArray *array;
+
+ xrange[0] = yrange[0] = VTK_DOUBLE_MAX;
+ xrange[1] = yrange[1] = -VTK_DOUBLE_MAX;
+ vtkCollectionSimpleIterator doit;
+ for ( doNum=0, maxNum=0, this->DataObjectInputList->InitTraversal(doit);
+ (dobj = this->DataObjectInputList->GetNextDataObject(doit)); doNum++)
+ {
+ lengths[doNum] = 0.0;
+ field = dobj->GetFieldData();
+ numColumns = field->GetNumberOfComponents(); //number of "columns"
+ for (numRows = VTK_LARGE_ID, i=0; i<field->GetNumberOfArrays(); i++)
+ {
+ array = field->GetArray(i);
+ numTuples = array->GetNumberOfTuples();
+ if ( numTuples < numRows )
+ {
+ numRows = numTuples;
+ }
+ }
+
+ num = (this->DataObjectPlotMode == VTK_XYPLOT_ROW ?
+ numColumns : numRows);
+
+ if ( this->XValues != VTK_XYPLOT_INDEX )
+ {
+ // gather the information to form a plot
+ for ( ptId=0; ptId < num; ptId++ )
+ {
+ if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
+ {
+ x = field->GetComponent(this->XComponent->GetValue(doNum), ptId);
+ }
+ else //if ( this->DataObjectPlotMode == VTK_XYPLOT_COLUMN )
+ {
+ x = field->GetComponent(ptId, this->XComponent->GetValue(doNum));
+ }
+ if ( ptId == 0 )
+ {
+ xPrev = x;
+ }
+
+ switch (this->XValues)
+ {
+ case VTK_XYPLOT_VALUE:
+ if (this->GetLogx() == 0)
+ {
+ if ( x < xrange[0] )
+ {
+ xrange[0] = x;
+ }
+ if ( x > xrange[1] )
+ {
+ xrange[1] = x;
+ }
+ }
+ else //ensure positive values
+ {
+ if ( (x < xrange[0]) && (x > 0) )
+ {
+ xrange[0] = x;
+ }
+ if ( x > xrange[1] && (x > 0) )
+ {
+ xrange[1] = x;
+ }
+ }
+ break;
+ default:
+ lengths[doNum] += fabs(x-xPrev);
+ xPrev = x;
+ }
+ }//for all points
+ if ( lengths[doNum] > maxLength )
+ {
+ maxLength = lengths[doNum];
+ }
+ }//if all data has to be visited
+
+ else //if (this->XValues == VTK_XYPLOT_INDEX)
+ {
+ if ( num > maxNum )
+ {
+ maxNum = num;
+ }
+ }
+
+ // Get the y-values
+ for ( ptId=0; ptId < num; ptId++ )
+ {
+ if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
+ {
+ y = field->GetComponent(this->YComponent->GetValue(doNum), ptId);
+ }
+ else //if ( this->DataObjectPlotMode == VTK_XYPLOT_COLUMN )
+ {
+ y = field->GetComponent(ptId, this->YComponent->GetValue(doNum));
+ }
+ if ( y < yrange[0] )
+ {
+ yrange[0] = y;
+ }
+ if ( y > yrange[1] )
+ {
+ yrange[1] = y;
+ }
+ }//over all y values
+ }//over all dataobjects
+
+ // determine the range
+ switch (this->XValues)
+ {
+ case VTK_XYPLOT_ARC_LENGTH:
+ xrange[0] = 0.0;
+ xrange[1] = maxLength;
+ break;
+ case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
+ xrange[0] = 0.0;
+ xrange[1] = 1.0;
+ break;
+ case VTK_XYPLOT_INDEX:
+ xrange[0] = 0.0;
+ xrange[1] = (double)(maxNum - 1);
+ break;
+ case VTK_XYPLOT_VALUE:
+ if (this->GetLogx() == 1)
+ {
+ xrange[0] = log10(xrange[0]);
+ xrange[1] = log10(xrange[1]);
+ }
+ break;
+ default:
+ vtkErrorMacro(<< "Unknown X-Value option");
+ return;
+ }
+}
+
+//----------------------------------------------------------------------------
+/* RKV void VISU_XYPlotActor::CreatePlotData(int *pos, int *pos2, double xRange[2],
+ double yRange[2], double *lengths,
+ int numDS, int numDO) */
+// RKV : Begin
+void VISU_XYPlotActor::CreatePlotData(int *pos, int *pos2Extern, double xRange[2],
+ double yRange[2], double *lengths,
+ int numDS, int numDO)
+// RKV : End
+{
+ double xyz[3]; xyz[2] = 0.0;
+ int i, numLinePts, dsNum, doNum, num;
+ vtkIdType numPts, ptId, id;
+ double length, x[3], xPrev[3];
+ vtkDataArray *scalars;
+ int component;
+ vtkDataSet *ds;
+ vtkCellArray *lines;
+ vtkPoints *pts;
+ int clippingRequired = 0;
+
+ // Allocate resources for the polygonal plots
+ //
+ num = (numDS > numDO ? numDS : numDO);
+ this->InitializeEntries();
+ this->NumberOfInputs = num;
+ this->PlotData = new vtkPolyData* [num];
+ this->PlotGlyph = new vtkGlyph2D* [num];
+ this->PlotAppend = new vtkAppendPolyData* [num];
+ this->PlotTransform = new vtkTransformPolyDataFilter* [num]; // RKV
+ this->PlotMapper = new vtkPolyDataMapper2D* [num];
+ this->PlotActor = new vtkActor2D* [num];
+
+ // RKV : Begin
+ // Prepare the transformation of the curve according to the plot location
+ vtkTransform *tf = vtkTransform::New();
+ tf->Translate(pos[0], pos[1], 0);
+ if ((this->PlotLocation == VISU_XYPLOT_LEFT) || (this->PlotLocation == VISU_XYPLOT_RIGHT))
+ tf->RotateZ(90);
+ tf->Translate(-pos[0], -pos[1], 0);
+
+ // Compute the position2 to build the curve before the transformation
+ int pos2[2];
+ vtkDebugMacro(<< "pos = (" << pos[0] << ", " << pos[1] << ")");
+ vtkDebugMacro(<< "pos2 = (" << pos2Extern[0] << ", " << pos2Extern[1] << ")");
+ if ((this->PlotLocation == VISU_XYPLOT_LEFT) || (this->PlotLocation == VISU_XYPLOT_RIGHT))
+ {
+ pos2[0] = pos[0] + pos2Extern[1] - pos[1];
+ pos2[1] = pos[1] + pos[0] - pos2Extern[0];
+ }
+ else
+ {
+ pos2[0] = pos2Extern[0];
+ pos2[1] = pos2Extern[1];
+ }
+ // RKV : End
+
+ for (i=0; i<num; i++)
+ {
+ this->PlotData[i] = vtkPolyData::New();
+ this->PlotGlyph[i] = vtkGlyph2D::New();
+ this->PlotGlyph[i]->SetInput(this->PlotData[i]);
+ this->PlotGlyph[i]->SetScaleModeToDataScalingOff();
+ this->PlotAppend[i] = vtkAppendPolyData::New();
+ this->PlotAppend[i]->AddInput(this->PlotData[i]);
+ if ( this->LegendActor->GetEntrySymbol(i) != NULL &&
+ this->LegendActor->GetEntrySymbol(i) != this->GlyphSource->GetOutput() )
+ {
+ this->PlotGlyph[i]->SetSource(this->LegendActor->GetEntrySymbol(i));
+ this->PlotGlyph[i]->SetScaleFactor(this->ComputeGlyphScale(i,pos,pos2));
+ this->PlotAppend[i]->AddInput(this->PlotGlyph[i]->GetOutput());
+ }
+ this->PlotMapper[i] = vtkPolyDataMapper2D::New();
+
+ // RKV : Begin
+ // Insert a transformation filter into the pipeline to
+ // take into account a plot location.
+ this->PlotTransform[i] = vtkTransformPolyDataFilter::New();
+ this->PlotTransform[i]->SetInput(this->PlotAppend[i]->GetOutput());
+ this->PlotTransform[i]->SetTransform(tf);
+ this->PlotMapper[i]->SetInput(this->PlotTransform[i]->GetOutput());
+ // RKV : End
+
+// RKV this->PlotMapper[i]->SetInput(this->PlotAppend[i]->GetOutput());
+ this->PlotMapper[i]->ScalarVisibilityOff();
+ this->PlotActor[i] = vtkActor2D::New();
+ this->PlotActor[i]->SetMapper(this->PlotMapper[i]);
+ this->PlotActor[i]->GetProperty()->DeepCopy(this->GetProperty());
+ if ( this->LegendActor->GetEntryColor(i)[0] < 0.0 )
+ {
+ this->PlotActor[i]->GetProperty()->SetColor(
+ this->GetProperty()->GetColor());
+ }
+ else
+ {
+ this->PlotActor[i]->GetProperty()->SetColor(
+ this->LegendActor->GetEntryColor(i));
+ }
+ }
+
+ tf->Delete(); // RKV
+
+ // Prepare to receive data
+ this->GenerateClipPlanes(pos,pos2);
+ for (i=0; i<this->NumberOfInputs; i++)
+ {
+ lines = vtkCellArray::New();
+ pts = vtkPoints::New();
+
+ lines->Allocate(10,10);
+ pts->Allocate(10,10);
+ this->PlotData[i]->SetPoints(pts);
+ this->PlotData[i]->SetVerts(lines);
+ this->PlotData[i]->SetLines(lines);
+
+ pts->Delete();
+ lines->Delete();
+ }
+
+ // Okay, for each input generate plot data. Depending on the input
+ // we use either dataset or data object.
+ //
+ if ( numDS > 0 )
+ {
+ vtkCollectionSimpleIterator dsit;
+ for ( dsNum=0, this->InputList->InitTraversal(dsit);
+ (ds = this->InputList->GetNextDataSet(dsit)); dsNum++ )
+ {
+ clippingRequired = 0;
+ numPts = ds->GetNumberOfPoints();
+ scalars = ds->GetPointData()->GetScalars(this->SelectedInputScalars[dsNum]);
+ if ( !scalars)
+ {
+ continue;
+ }
+ component = this->SelectedInputScalarsComponent->GetValue(dsNum);
+ if ( component < 0 || component >= scalars->GetNumberOfComponents())
+ {
+ continue;
+ }
+
+ pts = this->PlotData[dsNum]->GetPoints();
+ lines = this->PlotData[dsNum]->GetLines();
+ lines->InsertNextCell(0); //update the count later
+
+ ds->GetPoint(0, xPrev);
+ for ( numLinePts=0, length=0.0, ptId=0; ptId < numPts; ptId++ )
+ {
+ xyz[1] = scalars->GetComponent(ptId, component);
+ ds->GetPoint(ptId, x);
+ switch (this->XValues)
+ {
+ case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
+ length += sqrt(vtkMath::Distance2BetweenPoints(x,xPrev));
+ xyz[0] = length / lengths[dsNum];
+ xPrev[0] = x[0]; xPrev[1] = x[1]; xPrev[2] = x[2];
+ break;
+ case VTK_XYPLOT_INDEX:
+ xyz[0] = (double)ptId;
+ break;
+ case VTK_XYPLOT_ARC_LENGTH:
+ length += sqrt(vtkMath::Distance2BetweenPoints(x,xPrev));
+ xyz[0] = length;
+ xPrev[0] = x[0]; xPrev[1] = x[1]; xPrev[2] = x[2];
+ break;
+ case VTK_XYPLOT_VALUE:
+ xyz[0] = x[this->XComponent->GetValue(dsNum)];
+ break;
+ default:
+ vtkErrorMacro(<< "Unknown X-Component option");
+ }
+
+ if ( this->GetLogx() == 1 )
+ {
+ if (xyz[0] > 0)
+ {
+ xyz[0] = log10(xyz[0]);
+ // normalize and position
+ if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
+ xyz[1] < yRange[0] || xyz[1] > yRange[1] )
+ {
+ clippingRequired = 1;
+ }
+
+ numLinePts++;
+ xyz[0] = pos[0] +
+ (xyz[0]-xRange[0])/(xRange[1]-xRange[0])*(pos2[0]-pos[0]);
+ xyz[1] = pos[1] +
+ (xyz[1]-yRange[0])/(yRange[1]-yRange[0])*(pos2[1]-pos[1]);
+ id = pts->InsertNextPoint(xyz);
+ lines->InsertCellPoint(id);
+ }
+ }
+ else
+ {
+ // normalize and position
+ if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
+ xyz[1] < yRange[0] || xyz[1] > yRange[1] )
+ {
+ clippingRequired = 1;
+ }
+
+ numLinePts++;
+ xyz[0] = pos[0] +
+ (xyz[0]-xRange[0])/(xRange[1]-xRange[0])*(pos2[0]-pos[0]);
+ xyz[1] = pos[1] +
+ (xyz[1]-yRange[0])/(yRange[1]-yRange[0])*(pos2[1]-pos[1]);
+ id = pts->InsertNextPoint(xyz);
+ lines->InsertCellPoint(id);
+ }
+ }//for all input points
+
+ lines->UpdateCellCount(numLinePts);
+ if ( clippingRequired )
+ {
+ this->ClipPlotData(pos,pos2,this->PlotData[dsNum]);
+ }
+ }//loop over all input data sets
+ }//if plotting datasets
+
+ else //plot data from data objects
+ {
+ vtkDataObject *dobj;
+ int numColumns;
+ vtkIdType numRows, numTuples;
+ vtkDataArray *array;
+ vtkFieldData *field;
+ vtkCollectionSimpleIterator doit;
+ for ( doNum=0, this->DataObjectInputList->InitTraversal(doit);
+ (dobj = this->DataObjectInputList->GetNextDataObject(doit));
+ doNum++ )
+ {
+ // determine the shape of the field
+ field = dobj->GetFieldData();
+ numColumns = field->GetNumberOfComponents(); //number of "columns"
+ for (numRows = VTK_LARGE_ID, i=0; i<field->GetNumberOfArrays(); i++)
+ {
+ array = field->GetArray(i);
+ numTuples = array->GetNumberOfTuples();
+ if ( numTuples < numRows )
+ {
+ numRows = numTuples;
+ }
+ }
+
+ pts = this->PlotData[doNum]->GetPoints();
+ lines = this->PlotData[doNum]->GetLines();
+ lines->InsertNextCell(0); //update the count later
+
+ numPts = (this->DataObjectPlotMode == VTK_XYPLOT_ROW ?
+ numColumns : numRows);
+
+ // gather the information to form a plot
+ for ( numLinePts=0, length=0.0, ptId=0; ptId < numPts; ptId++ )
+ {
+ if ( this->DataObjectPlotMode == VTK_XYPLOT_ROW )
+ {
+ x[0] = field->GetComponent(this->XComponent->GetValue(doNum),ptId);
+ xyz[1] = field->GetComponent(this->YComponent->GetValue(doNum),ptId);
+ }
+ else //if ( this->DataObjectPlotMode == VTK_XYPLOT_COLUMN )
+ {
+ x[0] = field->GetComponent(ptId, this->XComponent->GetValue(doNum));
+ xyz[1] = field->GetComponent(ptId, this->YComponent->GetValue(doNum));
+ }
+
+ switch (this->XValues)
+ {
+ case VTK_XYPLOT_NORMALIZED_ARC_LENGTH:
+ length += fabs(x[0]-xPrev[0]);
+ xyz[0] = length / lengths[doNum];
+ xPrev[0] = x[0];
+ break;
+ case VTK_XYPLOT_INDEX:
+ xyz[0] = (double)ptId;
+ break;
+ case VTK_XYPLOT_ARC_LENGTH:
+ length += fabs(x[0]-xPrev[0]);
+ xyz[0] = length;
+ xPrev[0] = x[0];
+ break;
+ case VTK_XYPLOT_VALUE:
+ xyz[0] = x[0];
+ break;
+ default:
+ vtkErrorMacro(<< "Unknown X-Value option");
+ }
+
+ if ( this->GetLogx() == 1 )
+ {
+ if (xyz[0] > 0)
+ {
+ xyz[0] = log10(xyz[0]);
+ // normalize and position
+ if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
+ xyz[1] < yRange[0] || xyz[1] > yRange[1] )
+ {
+ clippingRequired = 1;
+ }
+ numLinePts++;
+ xyz[0] = pos[0] +
+ (xyz[0]-xRange[0])/(xRange[1]-xRange[0])*(pos2[0]-pos[0]);
+ xyz[1] = pos[1] +
+ (xyz[1]-yRange[0])/(yRange[1]-yRange[0])*(pos2[1]-pos[1]);
+ id = pts->InsertNextPoint(xyz);
+ lines->InsertCellPoint(id);
+ }
+ }
+ else
+ {
+ // normalize and position
+ if ( xyz[0] < xRange[0] || xyz[0] > xRange[1] ||
+ xyz[1] < yRange[0] || xyz[1] > yRange[1] )
+ {
+ clippingRequired = 1;
+ }
+ numLinePts++;
+ xyz[0] = pos[0] +
+ (xyz[0]-xRange[0])/(xRange[1]-xRange[0])*(pos2[0]-pos[0]);
+ xyz[1] = pos[1] +
+ (xyz[1]-yRange[0])/(yRange[1]-yRange[0])*(pos2[1]-pos[1]);
+ id = pts->InsertNextPoint(xyz);
+ lines->InsertCellPoint(id);
+ }
+ }//for all input points
+
+ lines->UpdateCellCount(numLinePts);
+ if ( clippingRequired )
+ {
+ this->ClipPlotData(pos,pos2,this->PlotData[doNum]);
+ }
+ }//loop over all input data sets
+ }
+
+ // Remove points/lines as directed by the user
+ for ( i = 0; i < num; i++)
+ {
+ if (!this->PlotCurveLines)
+ {
+ if ( !this->PlotLines )
+ {
+ this->PlotData[i]->SetLines(NULL);
+ }
+ }
+ else
+ {
+ if ( this->GetPlotLines(i) == 0)
+ {
+ this->PlotData[i]->SetLines(NULL);
+ }
+ }
+
+ if (!this->PlotCurvePoints)
+ {
+ if ( !this->PlotPoints || (this->LegendActor->GetEntrySymbol(i) &&
+ this->LegendActor->GetEntrySymbol(i) !=
+ this->GlyphSource->GetOutput()))
+ {
+ this->PlotData[i]->SetVerts(NULL);
+ }
+ }
+ else
+ {
+ if ( this->GetPlotPoints(i) == 0 ||
+ (this->LegendActor->GetEntrySymbol(i) &&
+ this->LegendActor->GetEntrySymbol(i) !=
+ this->GlyphSource->GetOutput()))
+ {
+ this->PlotData[i]->SetVerts(NULL);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+// Position the axes taking into account the expected padding due to labels
+// and titles. We want the result to fit in the box specified. This method
+// knows something about how the vtkAxisActor2D functions, so it may have
+// to change if that class changes dramatically.
+//
+void VISU_XYPlotActor::PlaceAxes(vtkViewport *viewport, int *size,
+ int pos[2], int pos2[2])
+{
+ int titleSizeX[2], titleSizeY[2], labelSizeX[2], labelSizeY[2];
+ double labelFactorX, labelFactorY;
+ double fontFactorX, fontFactorY;
+ double tickOffsetX, tickOffsetY;
+ double tickLengthX, tickLengthY;
+
+ vtkAxisActor2D *axisX;
+ vtkAxisActor2D *axisY;
+
+ char str1[512], str2[512];
+
+ if (this->ExchangeAxes)
+ {
+ axisX = this->YAxis;
+ axisY = this->XAxis;
+ }
+ else
+ {
+ axisX = this->XAxis;
+ axisY = this->YAxis;
+ }
+
+ // RKV : Begin
+ // Take into account a location of the plot.
+ if ((this->PlotLocation == VISU_XYPLOT_LEFT) || (this->PlotLocation == VISU_XYPLOT_RIGHT))
+ {
+ vtkAxisActor2D *axisBid;
+ axisBid = axisX;
+ axisX = axisY;
+ axisY = axisBid;
+ }
+
+ // RKV : End
+
+ fontFactorY = axisY->GetFontFactor();
+ fontFactorX = axisX->GetFontFactor();
+
+ labelFactorY = axisY->GetLabelFactor();
+ labelFactorX = axisX->GetLabelFactor();
+
+ // Create a dummy text mapper for getting font sizes
+ vtkTextMapper *textMapper = vtkTextMapper::New();
+ vtkTextProperty *tprop = textMapper->GetTextProperty();
+
+ // Get the location of the corners of the box
+ int *p1 = this->PositionCoordinate->GetComputedViewportValue(viewport);
+ int *p2 = this->Position2Coordinate->GetComputedViewportValue(viewport);
+
+ // Estimate the padding around the X and Y axes
+ tprop->ShallowCopy(axisX->GetTitleTextProperty());
+ textMapper->SetInput(axisX->GetTitle());
+ vtkAxisActor2D::SetFontSize(
+ viewport, textMapper, size, fontFactorX, titleSizeX);
+
+ tprop->ShallowCopy(axisY->GetTitleTextProperty());
+ textMapper->SetInput(axisY->GetTitle());
+ vtkAxisActor2D::SetFontSize(
+ viewport, textMapper, size, fontFactorY, titleSizeY);
+
+ // At this point the thing to do would be to actually ask the Y axis
+ // actor to return the largest label.
+ // In the meantime, let's try with the min and max
+ sprintf(str1, axisY->GetLabelFormat(), axisY->GetAdjustedRange()[0]);
+ sprintf(str2, axisY->GetLabelFormat(), axisY->GetAdjustedRange()[1]);
+ tprop->ShallowCopy(axisY->GetLabelTextProperty());
+ textMapper->SetInput(strlen(str1) > strlen(str2) ? str1 : str2);
+ vtkAxisActor2D::SetFontSize(
+ viewport, textMapper, size, labelFactorY * fontFactorY, labelSizeY);
+
+ // We do only care of the height of the label in the X axis, so let's
+ // use the min for example
+ sprintf(str1, axisX->GetLabelFormat(), axisX->GetAdjustedRange()[0]);
+ tprop->ShallowCopy(axisX->GetLabelTextProperty());
+ textMapper->SetInput(str1);
+ vtkAxisActor2D::SetFontSize(
+ viewport, textMapper, size, labelFactorX * fontFactorX, labelSizeX);
+
+ tickOffsetX = axisX->GetTickOffset();
+ tickOffsetY = axisY->GetTickOffset();
+ tickLengthX = axisX->GetTickLength();
+ tickLengthY = axisY->GetTickLength();
+
+ // Okay, estimate the size
+/* RKV pos[0] = (int)(p1[0] + titleSizeY[0] + 2.0 * tickOffsetY + tickLengthY +
+ labelSizeY[0] + this->Border);
+
+ pos[1] = (int)(p1[1] + titleSizeX[1] + 2.0 * tickOffsetX + tickLengthX +
+ labelSizeX[1] + this->Border);
+
+ pos2[0] = (int)(p2[0] - labelSizeY[0] / 2 - tickOffsetY - this->Border);
+
+ pos2[1] = (int)(p2[1] - labelSizeX[1] / 2 - tickOffsetX - this->Border);
+ */
+ // RKV : Begin
+ pos[0] = (int)(p1[0]);
+
+ pos[1] = (int)(p1[1]);
+
+ pos2[0] = (int)(p2[0]);
+
+ pos2[1] = (int)(p2[1]);
+ // RKV : End
+
+ // Now specify the location of the axes
+ axisX->GetPositionCoordinate()->SetValue(
+ (double)pos[0], (double)pos[1]);
+ axisX->GetPosition2Coordinate()->SetValue(
+ (double)pos2[0], (double)pos[1]);
+ axisY->GetPositionCoordinate()->SetValue(
+ (double)pos[0], (double)pos2[1]);
+ axisY->GetPosition2Coordinate()->SetValue(
+ (double)pos[0], (double)pos[1]);
+
+ textMapper->Delete();
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::ViewportToPlotCoordinate(vtkViewport *viewport, double &u, double &v)
+{
+ int *p0, *p1, *p2;
+
+ // XAxis, YAxis are in viewport coordinates already
+ p0 = this->XAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
+ p1 = this->XAxis->GetPosition2Coordinate()->GetComputedViewportValue(viewport);
+ p2 = this->YAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
+
+ u = ((u - p0[0]) / (double)(p1[0] - p0[0]))
+ *(this->XComputedRange[1] - this->XComputedRange[0])
+ + this->XComputedRange[0];
+ v = ((v - p0[1]) / (double)(p2[1] - p0[1]))
+ *(this->YComputedRange[1] - this->YComputedRange[0])
+ + this->YComputedRange[0];
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::PlotToViewportCoordinate(vtkViewport *viewport,
+ double &u, double &v)
+{
+ int *p0, *p1, *p2;
+
+ // XAxis, YAxis are in viewport coordinates already
+ p0 = this->XAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
+ p1 = this->XAxis->GetPosition2Coordinate()->GetComputedViewportValue(viewport);
+ p2 = this->YAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
+
+ u = (((u - this->XComputedRange[0])
+ / (this->XComputedRange[1] - this->XComputedRange[0]))
+ * (double)(p1[0] - p0[0])) + p0[0];
+ v = (((v - this->YComputedRange[0])
+ / (this->YComputedRange[1] - this->YComputedRange[0]))
+ * (double)(p2[1] - p0[1])) + p0[1];
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::ViewportToPlotCoordinate(vtkViewport *viewport)
+{
+ this->ViewportToPlotCoordinate(viewport,
+ this->ViewportCoordinate[0],
+ this->ViewportCoordinate[1]);
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::PlotToViewportCoordinate(vtkViewport *viewport)
+{
+ this->PlotToViewportCoordinate(viewport,
+ this->PlotCoordinate[0],
+ this->PlotCoordinate[1]);
+}
+
+//----------------------------------------------------------------------------
+int VISU_XYPlotActor::IsInPlot(vtkViewport *viewport, double u, double v)
+{
+ int *p0, *p1, *p2;
+
+ // Bounds of the plot are based on the axes...
+ p0 = this->XAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
+ p1 = this->XAxis->GetPosition2Coordinate()->GetComputedViewportValue(viewport);
+ p2 = this->YAxis->GetPositionCoordinate()->GetComputedViewportValue(viewport);
+
+ if (u >= p0[0] && u <= p1[0] && v >= p0[1] && v <= p2[1])
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::SetPlotLines(int i, int isOn)
+{
+ i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
+ int val = this->LinesOn->GetValue(i);
+ if ( val != isOn )
+ {
+ this->Modified();
+ this->LinesOn->SetValue(i, isOn);
+ }
+}
+
+//----------------------------------------------------------------------------
+int VISU_XYPlotActor::GetPlotLines(int i)
+{
+ i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
+ return this->LinesOn->GetValue(i);
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::SetPlotPoints(int i, int isOn)
+{
+ i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
+ int val = this->PointsOn->GetValue(i);
+ if ( val != isOn )
+ {
+ this->Modified();
+ this->PointsOn->SetValue(i, isOn);
+ }
+}
+
+//----------------------------------------------------------------------------
+int VISU_XYPlotActor::GetPlotPoints(int i)
+{
+ i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
+ return this->PointsOn->GetValue(i);
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::SetPlotColor(int i, double r, double g, double b)
+{
+ this->LegendActor->SetEntryColor(i, r, g, b);
+}
+
+//----------------------------------------------------------------------------
+double *VISU_XYPlotActor::GetPlotColor(int i)
+{
+ return this->LegendActor->GetEntryColor(i);
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::SetPlotSymbol(int i,vtkPolyData *input)
+{
+ this->LegendActor->SetEntrySymbol(i, input);
+}
+
+//----------------------------------------------------------------------------
+vtkPolyData *VISU_XYPlotActor::GetPlotSymbol(int i)
+{
+ return this->LegendActor->GetEntrySymbol(i);
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::SetPlotLabel(int i, const char *label)
+{
+ this->LegendActor->SetEntryString(i, label);
+}
+
+//----------------------------------------------------------------------------
+const char *VISU_XYPlotActor::GetPlotLabel(int i)
+{
+ return this->LegendActor->GetEntryString(i);
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::GenerateClipPlanes(int *pos, int *pos2)
+{
+ double n[3], x[3];
+ vtkPoints *pts=this->ClipPlanes->GetPoints();
+ vtkDataArray *normals=this->ClipPlanes->GetNormals();
+
+ n[2] = x[2] = 0.0;
+
+ //first
+ n[0] = 0.0;
+ n[1] = -1.0;
+ normals->SetTuple(0,n);
+ x[0] = (double)0.5*(pos[0]+pos2[0]);
+ x[1] = (double)pos[1];
+ pts->SetPoint(0,x);
+
+ //second
+ n[0] = 1.0;
+ n[1] = 0.0;
+ normals->SetTuple(1,n);
+ x[0] = (double)pos2[0];
+ x[1] = (double)0.5*(pos[1]+pos2[1]);
+ pts->SetPoint(1,x);
+
+ //third
+ n[0] = 0.0;
+ n[1] = 1.0;
+ normals->SetTuple(2,n);
+ x[0] = (double)0.5*(pos[0]+pos2[0]);
+ x[1] = (double)pos2[1];
+ pts->SetPoint(2,x);
+
+ //fourth
+ n[0] = -1.0;
+ n[1] = 0.0;
+ normals->SetTuple(3,n);
+ x[0] = (double)pos[0];
+ x[1] = (double)0.5*(pos[1]+pos2[1]);
+ pts->SetPoint(3,x);
+}
+
+//----------------------------------------------------------------------------
+double VISU_XYPlotActor::ComputeGlyphScale(int i, int *pos, int *pos2)
+{
+ vtkPolyData *pd=this->LegendActor->GetEntrySymbol(i);
+ pd->Update();
+ double length=pd->GetLength();
+ double sf = this->GlyphSize * sqrt((double)(pos[0]-pos2[0])*(pos[0]-pos2[0]) +
+ (pos[1]-pos2[1])*(pos[1]-pos2[1])) / length;
+
+ return sf;
+}
+
+//----------------------------------------------------------------------------
+//This assumes that there are multiple polylines
+void VISU_XYPlotActor::ClipPlotData(int *pos, int *pos2, vtkPolyData *pd)
+{
+ vtkPoints *points=pd->GetPoints();
+ vtkPoints *newPoints;
+ vtkCellArray *lines=pd->GetLines();
+ vtkCellArray *newLines, *newVerts;
+ vtkIdType numPts=pd->GetNumberOfPoints();
+ vtkIdType npts = 0;
+ vtkIdType newPts[2];
+ vtkIdType *pts=0;
+ vtkIdType i, id;
+ int j;
+ double x1[3], x2[3], px[3], n[3], xint[3], t;
+ double p1[2], p2[2];
+
+ p1[0] = (double)pos[0]; p1[1] = (double)pos[1];
+ p2[0] = (double)pos2[0]; p2[1] = (double)pos2[1];
+
+ newPoints = vtkPoints::New();
+ newPoints->Allocate(numPts);
+ newVerts = vtkCellArray::New();
+ newVerts->Allocate(lines->GetSize());
+ newLines = vtkCellArray::New();
+ newLines->Allocate(2*lines->GetSize());
+ int *pointMap = new int [numPts];
+ for (i=0; i<numPts; i++)
+ {
+ pointMap[i] = -1;
+ }
+
+ //Loop over polyverts eliminating those that are outside
+ for ( lines->InitTraversal(); lines->GetNextCell(npts,pts); )
+ {
+ //loop over verts keeping only those that are not clipped
+ for (i=0; i<npts; i++)
+ {
+ points->GetPoint(pts[i], x1);
+
+ if (x1[0] >= p1[0] && x1[0] <= p2[0] && x1[1] >= p1[1] && x1[1] <= p2[1] )
+ {
+ id = newPoints->InsertNextPoint(x1);
+ pointMap[i] = id;
+ newPts[0] = id;
+ newVerts->InsertNextCell(1,newPts);
+ }
+ }
+ }
+
+ //Loop over polylines clipping each line segment
+ for ( lines->InitTraversal(); lines->GetNextCell(npts,pts); )
+ {
+ //loop over line segment making up the polyline
+ for (i=0; i<(npts-1); i++)
+ {
+ points->GetPoint(pts[i], x1);
+ points->GetPoint(pts[i+1], x2);
+
+ //intersect each segment with the four planes
+ if ( (x1[0] < p1[0] && x2[0] < p1[0]) || (x1[0] > p2[0] && x2[0] > p2[0]) ||
+ (x1[1] < p1[1] && x2[1] < p1[1]) || (x1[1] > p2[1] && x2[1] > p2[1]) )
+ {
+ ;//trivial rejection
+ }
+ else if (x1[0] >= p1[0] && x2[0] >= p1[0] && x1[0] <= p2[0] && x2[0] <= p2[0] &&
+ x1[1] >= p1[1] && x2[1] >= p1[1] && x1[1] <= p2[1] && x2[1] <= p2[1] )
+ {//trivial acceptance
+ newPts[0] = pointMap[pts[i]];
+ newPts[1] = pointMap[pts[i+1]];
+ newLines->InsertNextCell(2,newPts);
+ }
+ else
+ {
+ if (x1[0] >= p1[0] && x1[0] <= p2[0] && x1[1] >= p1[1] && x1[1] <= p2[1] )
+ {//first point in
+ newPts[0] = pointMap[pts[i]];
+ }
+ else
+ {//second point in
+ newPts[0] = pointMap[pts[i+1]];
+ }
+ for (j=0; j<4; j++)
+ {
+ this->ClipPlanes->GetPoints()->GetPoint(j, px);
+ this->ClipPlanes->GetNormals()->GetTuple(j, n);
+ if ( vtkPlane::IntersectWithLine(x1,x2,n,px,t,xint) && t >= 0 && t <= 1.0 )
+ {
+ newPts[1] = newPoints->InsertNextPoint(xint);
+ break;
+ }
+ }
+ newLines->InsertNextCell(2,newPts);
+ }
+ }
+ }
+ delete [] pointMap;
+
+ //Update the lines
+ pd->SetPoints(newPoints);
+ pd->SetVerts(newVerts);
+ pd->SetLines(newLines);
+
+ newPoints->Delete();
+ newVerts->Delete();
+ newLines->Delete();
+
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::SetDataObjectXComponent(int i, int comp)
+{
+ i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
+ int val=this->XComponent->GetValue(i);
+ if ( val != comp )
+ {
+ this->Modified();
+ this->XComponent->SetValue(i,comp);
+ }
+}
+
+//----------------------------------------------------------------------------
+int VISU_XYPlotActor::GetDataObjectXComponent(int i)
+{
+ i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
+ return this->XComponent->GetValue(i);
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::SetDataObjectYComponent(int i, int comp)
+{
+ i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
+ int val=this->YComponent->GetValue(i);
+ if ( val != comp )
+ {
+ this->Modified();
+ this->YComponent->SetValue(i,comp);
+ }
+}
+
+//----------------------------------------------------------------------------
+int VISU_XYPlotActor::GetDataObjectYComponent(int i)
+{
+ i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
+ return this->YComponent->GetValue(i);
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::SetPointComponent(int i, int comp)
+{
+ i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
+ int val = this->XComponent->GetValue(i);
+ if ( val != comp )
+ {
+ this->Modified();
+ this->XComponent->SetValue(i,comp);
+ }
+}
+
+//----------------------------------------------------------------------------
+int VISU_XYPlotActor::GetPointComponent(int i)
+{
+ i = ( i < 0 ? 0 : (i >=VTK_MAX_PLOTS ? VTK_MAX_PLOTS-1 : i));
+ return this->XComponent->GetValue(i);
+}
+
+//----------------------------------------------------------------------------
+double *VISU_XYPlotActor::TransformPoint(int pos[2], int pos2[2],
+ double x[3], double xNew[3])
+{
+ // First worry about exchanging axes
+ if ( this->ExchangeAxes )
+ {
+ double sx = (x[0]-pos[0]) / (pos2[0]-pos[0]);
+ double sy = (x[1]-pos[1]) / (pos2[1]-pos[1]);
+ xNew[0] = sy*(pos2[0]-pos[0]) + pos[0];
+ xNew[1] = sx*(pos2[1]-pos[1]) + pos[1];
+ xNew[2] = x[2];
+ }
+ else
+ {
+ xNew[0] = x[0];
+ xNew[1] = x[1];
+ xNew[2] = x[2];
+ }
+
+ // Okay, now swap the axes around if reverse is on
+ if ( this->ReverseXAxis )
+ {
+ xNew[0] = pos[0] + (pos2[0]-xNew[0]);
+ }
+ if ( this->ReverseYAxis )
+ {
+ xNew[1] = pos[1] + (pos2[1]-xNew[1]);
+ }
+
+ return xNew;
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::SetLabelFormat(const char* _arg)
+{
+ if (this->LabelFormat == NULL && _arg == NULL)
+ {
+ return;
+ }
+
+ if (this->LabelFormat && _arg && (!strcmp(this->LabelFormat,_arg)))
+ {
+ return;
+ }
+
+ if (this->LabelFormat)
+ {
+ delete [] this->LabelFormat;
+ }
+
+ if (_arg)
+ {
+ this->LabelFormat = new char[strlen(_arg)+1];
+ strcpy(this->LabelFormat,_arg);
+ }
+ else
+ {
+ this->LabelFormat = NULL;
+ }
+
+ this->XAxis->SetLabelFormat(this->LabelFormat);
+ this->YAxis->SetLabelFormat(this->LabelFormat);
+
+ this->Modified();
+}
+
+//----------------------------------------------------------------------------
+void VISU_XYPlotActor::PrintAsCSV(ostream &os)
+{
+ vtkDataArray *scalars;
+ vtkDataSet *ds;
+ vtkCollectionSimpleIterator dsit;
+ double s;
+ int dsNum,component;
+ for ( dsNum=0, this->InputList->InitTraversal(dsit);
+ (ds = this->InputList->GetNextDataSet(dsit)); dsNum++ )
+ {
+ vtkIdType numPts = ds->GetNumberOfPoints();
+ scalars = ds->GetPointData()->GetScalars(this->SelectedInputScalars[dsNum]);
+ component = this->SelectedInputScalarsComponent->GetValue(dsNum);
+ for ( vtkIdType ptId=0; ptId < numPts; ptId++ )
+ {
+ s = scalars->GetComponent(ptId, component);
+ if( ptId == 0 )
+ {
+ os << s;
+ }
+ else
+ {
+ os << "," << s;
+ }
+ }
+ os << endl;
+ }
+}
+
--- /dev/null
+// VISU OBJECT : interactive object for VISU entities implementation
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+// File: VISU_XYPlotActor.hxx
+// Author: Roman KOZLOV
+// Module : VISU
+
+#ifndef VISU_XYPLOTACTOR_HXX_
+#define VISU_XYPLOTACTOR_HXX_
+
+#include "VISUPipeline.hxx"
+
+/*=========================================================================
+
+ Program: Visualization Toolkit
+ Module: $RCSfile$
+
+ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+ All rights reserved.
+ See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the above copyright notice for more information.
+
+=========================================================================*/
+// .NAME vtkXYPlotActor - generate an x-y plot from input dataset(s) or field data
+// .SECTION Description
+// vtkXYPlotActor creates an x-y plot of data from one or more input data
+// sets or field data. The class plots dataset scalar values (y-axis) against
+// the points (x-axis). The x-axis values are generated by taking the point
+// ids, computing a cumulative arc length, or a normalized arc length. More
+// than one input data set can be specified to generate multiple plots.
+// Alternatively, if field data is supplied as input, the class plots one
+// component against another. (The user must specify which component to use
+// as the x-axis and which for the y-axis.)
+//
+// To use this class to plot dataset(s), you must specify one or more
+// input datasets containing scalar and point data. You'll probably also
+// want to invoke a method to control how the point coordinates are converted
+// into x values (by default point ids are used).
+//
+// To use this class to plot field data, you must specify one or more input
+// data objects with its associated field data. You'll also want to specify
+// which component to use as the x-axis and which to use as the y-axis.
+// Note that when plotting field data, the x and y values are used directly
+// (i.e., there are no options to normalize the components).
+//
+// Once you've set up the plot, you'll want to position it. The
+// PositionCoordinate defines the lower-left location of the x-y plot
+// (specified in normalized viewport coordinates) and the Position2Coordinate
+// define the upper-right corner. (Note: the Position2Coordinate is relative
+// to PositionCoordinate, so you can move the vtkXYPlotActor around the
+// viewport by setting just the PositionCoordinate.) The combination of the
+// two position coordinates specifies a rectangle in which the plot will lie.
+//
+// Optional features include the ability to specify axes labels, label
+// format and plot title. You can also
+// manually specify the x and y plot ranges (by default they are computed
+// automatically). The Border instance variable is used to create space
+// between the boundary of the plot window (specified by PositionCoordinate
+// and Position2Coordinate) and the plot itself.
+//
+// The font property of the plot title can be modified through the
+// TitleTextProperty attribute.
+// The font property of the axes titles and labels can be modified through the
+// AxisTitleTextProperty and AxisLabelTextProperty attributes. You may also
+// use the GetXAxisActor2D or GetYAxisActor2D methods
+// to access each individual axis actor to modify their font properties.
+// In the same way, the GetLegendBoxActor method can be used to access
+// the legend box actor to modify its font properties.
+//
+// There are several advanced features as well. You can assign per curve
+// properties (such as color and a plot symbol). (Note that each input
+// dataset and/or data object creates a single curve.) Another option is to
+// add a plot legend that graphically indicates the correspondance between
+// the curve, curve symbols, and the data source. You can also exchange the
+// x and y axes if you prefer you plot orientation that way.
+
+// .SECTION Caveats
+// If you are interested in plotting something other than scalar data, you
+// can use the vtk data shuffling filters (e.g.,
+// vtkAttributeDataToFieldDataFilter and vtkFieldDataToAttributeDataFilter)
+// to convert the data into scalar data and/or points.
+
+// .SECTION See Also
+// vtkActor2D vtkTextMapper vtkScalarBarActor vtkAxisActor2D vtkCubeAxesActor2D
+// vtkAttributeDataToFieldDataFilter vtkFieldDataToAttributeDataFilter
+// vtkTextProperty
+
+#include "vtkActor2D.h"
+#include "vtkTransformPolyDataFilter.h" // RKV
+
+#define VTK_XYPLOT_INDEX 0
+#define VTK_XYPLOT_ARC_LENGTH 1
+#define VTK_XYPLOT_NORMALIZED_ARC_LENGTH 2
+#define VTK_XYPLOT_VALUE 3
+
+#define VTK_XYPLOT_ROW 0
+#define VTK_XYPLOT_COLUMN 1
+
+class vtkAppendPolyData;
+class vtkAxisActor2D;
+class vtkDataObject;
+class vtkDataObjectCollection;
+class vtkDataSet;
+class vtkDataSetCollection;
+class vtkGlyph2D;
+class vtkGlyphSource2D;
+class vtkIntArray;
+class vtkLegendBoxActor;
+class vtkPlanes;
+class vtkPolyData;
+class vtkPolyDataMapper2D;
+class vtkTextMapper;
+class vtkTextProperty;
+
+// RKV : Begin
+/** Location of the actor in the viewport.
+ * Axes and a curve is plotted according to the selected side.
+ * Axes origin is plotted at:
+ * VISU_XYPLOT_BOTTOM - the left bottom corner,
+ * VISU_XYPLOT_TOP - the left upper corner (Y axis is directed to the bottom),
+ * VISU_XYPLOT_LEFT - the left bottom corner (axes are exchanged),
+ * VISU_XYPLOT_RIGHT - the right bottom corner (X axis is directed to the top, Y - to the left)
+ */
+enum VISU_XYPlotLocation { VISU_XYPLOT_BOTTOM = 0,
+ VISU_XYPLOT_TOP, VISU_XYPLOT_LEFT, VISU_XYPLOT_RIGHT };
+// RKV : End
+
+class VISU_PIPELINE_EXPORT VISU_XYPlotActor : public vtkActor2D
+{
+public:
+ vtkTypeRevisionMacro(VISU_XYPlotActor,vtkActor2D);
+ void PrintSelf(ostream& os, vtkIndent indent);
+
+ // Description:
+ // Instantiate object with autorange computation; bold, italic, and shadows
+ // on; arial font family; the number of labels set to 5 for the x and y
+ // axes; a label format of "%-#6.3g"; and x coordinates computed from point
+ // ids.
+ static VISU_XYPlotActor *New();
+
+ //---Data Set Input----------------------------------------------------------
+ // The following methods are used to plot input datasets. Datasets
+ // will be plotted if set as input; otherwise the input data objects
+ // will be plotted (if defined).
+
+ // Description:
+ // Add a dataset to the list of data to append. The array name specifies
+ // which point array to plot. If the array name is NULL, then the default
+ // scalars are used. The array can have multiple components, but only the
+ // first component is ploted.
+ void AddInput(vtkDataSet *in, const char* arrayName, int component);
+ void AddInput(vtkDataSet *in) {this->AddInput(in, NULL, 0);}
+
+ // Description:
+ // Remove a dataset from the list of data to append.
+ void RemoveInput(vtkDataSet *in, const char* arrayName, int component);
+ void RemoveInput(vtkDataSet *in) {this->RemoveInput(in, NULL, 0);}
+
+ // Description:
+ // This removes all of the data set inputs,
+ // but does not change the data object inputs.
+ void RemoveAllInputs();
+
+ // Description:
+ // Return the list of inputs to this filter.
+ vtkDataSetCollection *GetInputList() {return this->InputList;}
+
+ // Description:
+ // If plotting points by value, which component to use to determine the
+ // value. This sets a value per each input dataset (i.e., the ith dataset).
+ void SetPointComponent(int i, int comp);
+ int GetPointComponent(int i);
+ //---end Data Set Input-----------------------------------------------------
+
+ // Description:
+ // Specify how the independent (x) variable is computed from the points.
+ // The independent variable can be the scalar/point index (i.e., point id),
+ // the accumulated arc length along the points, the normalized arc length,
+ // or by component value. If plotting datasets (e.g., points), the value
+ // that is used is specified by the PointComponent ivar. (Note: these
+ // methods also control how field data is plotted. Field data is usually
+ // plotted by value or index, if plotting length 1-dimensional length
+ // measures are used.)
+ vtkSetClampMacro(XValues,int,VTK_XYPLOT_INDEX,VTK_XYPLOT_VALUE);
+ vtkGetMacro(XValues,int);
+ void SetXValuesToIndex(){this->SetXValues(VTK_XYPLOT_INDEX);};
+ void SetXValuesToArcLength() {this->SetXValues(VTK_XYPLOT_ARC_LENGTH);};
+ void SetXValuesToNormalizedArcLength()
+ {this->SetXValues(VTK_XYPLOT_NORMALIZED_ARC_LENGTH);};
+ void SetXValuesToValue() {this->SetXValues(VTK_XYPLOT_VALUE);};
+ const char *GetXValuesAsString();
+
+ //---Data Object Input------------------------------------------------------
+ // The following methods are used to plot input data objects. Datasets will
+ // be plotted in preference to data objects if set as input; otherwise the
+ // input data objects will be plotted (if defined).
+
+ // Description:
+ // Add a dataset to the list of data to append.
+ void AddDataObjectInput(vtkDataObject *in);
+
+ // Description:
+ // Remove a dataset from the list of data to append.
+ void RemoveDataObjectInput(vtkDataObject *in);
+
+ // Description:
+ // Return the list of inputs to this filter.
+ vtkDataObjectCollection *GetDataObjectInputList()
+ {return this->DataObjectInputList;}
+
+ // Description:
+ // Indicate whether to plot rows or columns. If plotting rows, then
+ // the dependent variables is taken from a specified row,
+ // versus rows (y).
+ vtkSetClampMacro(DataObjectPlotMode,int,VTK_XYPLOT_ROW,VTK_XYPLOT_COLUMN);
+ vtkGetMacro(DataObjectPlotMode,int);
+ void SetDataObjectPlotModeToRows()
+ {this->SetDataObjectPlotMode(VTK_XYPLOT_ROW);}
+ void SetDataObjectPlotModeToColumns()
+ {this->SetDataObjectPlotMode(VTK_XYPLOT_COLUMN);}
+ const char *GetDataObjectPlotModeAsString();
+
+ // Description:
+ // Specify which component of the input data object to use as the
+ // independent variable for the ith input data object. (This ivar is
+ // ignored if plotting the index.) Note that the value is interpreted
+ // differently depending on DataObjectPlotMode. If the mode is Rows, then
+ // the value of DataObjectXComponent is the row number; otherwise it's the
+ // column number.
+ void SetDataObjectXComponent(int i, int comp);
+ int GetDataObjectXComponent(int i);
+
+ // Description:
+ // Specify which component of the input data object to use as the
+ // dependent variable for the ith input data object. (This ivar is
+ // ignored if plotting the index.) Note that the value is interpreted
+ // differently depending on DataObjectPlotMode. If the mode is Rows, then
+ // the value of DataObjectYComponent is the row number; otherwise it's the
+ // column number.
+ void SetDataObjectYComponent(int i, int comp);
+ int GetDataObjectYComponent(int i);
+ //---end Data Object Input--------------------------------------------------
+
+ //---Per Curve Properties---------------------------------------------------
+ // The following methods are used to set properties on each curve that is
+ // plotted. Each input dataset (or data object) results in one curve. The
+ // methods that follow have an index i that corresponds to the input dataset
+ // or data object.
+ void SetPlotColor(int i, double r, double g, double b);
+ void SetPlotColor(int i, const double color[3]) {
+ this->SetPlotColor(i, color[0], color[1], color[2]); };
+ double *GetPlotColor(int i);
+ void SetPlotSymbol(int i,vtkPolyData *input);
+ vtkPolyData *GetPlotSymbol(int i);
+ void SetPlotLabel(int i, const char *label);
+ const char *GetPlotLabel(int i);
+
+ // Allow per-curve specification of line and point rendering. These override
+ // global settings PlotPoints and PlotLines. If not on, the default behavior
+ // is governed by PlotPoints and PlotLines ivars.
+ vtkGetMacro(PlotCurvePoints, int);
+ vtkSetMacro(PlotCurvePoints, int);
+ vtkBooleanMacro(PlotCurvePoints, int);
+
+ vtkGetMacro(PlotCurveLines, int);
+ vtkSetMacro(PlotCurveLines, int);
+ vtkBooleanMacro(PlotCurveLines, int);
+
+ void SetPlotLines(int i, int);
+ int GetPlotLines(int i);
+
+ void SetPlotPoints(int i, int);
+ int GetPlotPoints(int i);
+ //---end Per Curve Properties-----------------------------------------------
+
+ // Description:
+ // Enable/Disable exchange of the x-y axes (i.e., what was x becomes y, and
+ // vice-versa). Exchanging axes affects the labeling as well.
+ vtkSetMacro(ExchangeAxes, int);
+ vtkGetMacro(ExchangeAxes, int);
+ vtkBooleanMacro(ExchangeAxes, int);
+
+ // Description:
+ // Normally the x-axis is plotted from minimum to maximum. Setting this instance
+ // variable causes the x-axis to be plotted from maximum to minimum. Note that
+ // boolean always applies to the x-axis even if ExchangeAxes is set.
+ vtkSetMacro(ReverseXAxis, int);
+ vtkGetMacro(ReverseXAxis, int);
+ vtkBooleanMacro(ReverseXAxis, int);
+
+ // Description:
+ // Normally the y-axis is plotted from minimum to maximum. Setting this instance
+ // variable causes the y-axis to be plotted from maximum to minimum. Note that
+ // boolean always applies to the y-axis even if ExchangeAxes is set.
+ vtkSetMacro(ReverseYAxis, int);
+ vtkGetMacro(ReverseYAxis, int);
+ vtkBooleanMacro(ReverseYAxis, int);
+
+ // Description:
+ // Retrieve handles to the legend box and glyph source. This is useful
+ // if you would like to change the default behavior of the legend box
+ // or glyph source. For example, the default glyph can be changed from
+ // a line to a vertex plus line, etc.)
+ vtkGetObjectMacro(LegendActor,vtkLegendBoxActor);
+ vtkGetObjectMacro(GlyphSource,vtkGlyphSource2D);
+
+ // Description:
+ // Set/Get the title of the x-y plot, and the title along the
+ // x and y axes.
+ vtkSetStringMacro(Title);
+ vtkGetStringMacro(Title);
+ vtkSetStringMacro(XTitle);
+ vtkGetStringMacro(XTitle);
+ vtkSetStringMacro(YTitle);
+ vtkGetStringMacro(YTitle);
+
+ // Description:
+ // Retrieve handles to the X and Y axis (so that you can set their text
+ // properties for example)
+ vtkAxisActor2D *GetXAxisActor2D()
+ {return this->XAxis;}
+ vtkAxisActor2D *GetYAxisActor2D()
+ {return this->YAxis;}
+
+ // Description:
+ // Set the plot range (range of independent and dependent variables)
+ // to plot. Data outside of the range will be clipped. If the plot
+ // range of either the x or y variables is set to (v1,v2), where
+ // v1 == v2, then the range will be computed automatically. Note that
+ // the x-range values should be consistent with the way the independent
+ // variable is created (via INDEX, DISTANCE, or ARC_LENGTH).
+ vtkSetVector2Macro(XRange,double);
+ vtkGetVectorMacro(XRange,double,2);
+ vtkSetVector2Macro(YRange,double);
+ vtkGetVectorMacro(YRange,double,2);
+ void SetPlotRange(double xmin, double ymin, double xmax, double ymax)
+ {this->SetXRange(xmin,xmax); this->SetYRange(ymin,ymax);}
+
+ // Description:
+ // Set/Get the number of annotation labels to show along the x and y axes.
+ // This values is a suggestion: the number of labels may vary depending
+ // on the particulars of the data. The convenience method
+ // SetNumberOfLables() sets the number of x and y labels to the same value.
+ vtkSetClampMacro(NumberOfXLabels, int, 0, 50);
+ vtkGetMacro(NumberOfXLabels, int);
+ vtkSetClampMacro(NumberOfYLabels, int, 0, 50);
+ vtkGetMacro(NumberOfYLabels, int);
+ void SetNumberOfLabels(int num)
+ {this->SetNumberOfXLabels(num); this->SetNumberOfYLabels(num);}
+
+ // Description:
+ // Enable/Disable the creation of a legend. If on, the legend labels will
+ // be created automatically unless the per plot legend symbol has been
+ // set.
+ vtkSetMacro(Legend, int);
+ vtkGetMacro(Legend, int);
+ vtkBooleanMacro(Legend, int);
+
+ // Description:
+ // Use these methods to control the position of the legend. The variables
+ // LegendPosition and LegendPosition2 define the lower-left and upper-right
+ // position of the legend. The coordinates are expressed as normalized
+ // values with respect to the rectangle defined by PositionCoordinate and
+ // Position2Coordinate. Note that LegendPosition2 is relative to
+ // LegendPosition.
+ vtkSetVector2Macro(LegendPosition,double);
+ vtkGetVector2Macro(LegendPosition,double);
+ vtkSetVector2Macro(LegendPosition2,double);
+ vtkGetVector2Macro(LegendPosition2,double);
+
+ // Description:
+ // Set/Get the title text property.
+ virtual void SetTitleTextProperty(vtkTextProperty *p);
+ vtkGetObjectMacro(TitleTextProperty,vtkTextProperty);
+
+ // Description:
+ // Set/Get the title text property of all axes. Note that each axis can
+ // be controlled individually through the GetX/YAxisActor2D() methods.
+ virtual void SetAxisTitleTextProperty(vtkTextProperty *p);
+ vtkGetObjectMacro(AxisTitleTextProperty,vtkTextProperty);
+
+ // Description:
+ // Set/Get the labels text property of all axes. Note that each axis can
+ // be controlled individually through the GetX/YAxisActor2D() methods.
+ virtual void SetAxisLabelTextProperty(vtkTextProperty *p);
+ vtkGetObjectMacro(AxisLabelTextProperty,vtkTextProperty);
+
+ // Description:
+ // Enable/Disable plotting of Log of x-values.
+ vtkSetMacro(Logx, int);
+ vtkGetMacro(Logx, int);
+ vtkBooleanMacro(Logx, int);
+
+ // Description:
+ // Set/Get the format with which to print the labels on the scalar
+ // bar.
+ virtual void SetLabelFormat (const char* _arg);
+ vtkGetStringMacro(LabelFormat);
+
+ // Description:
+ // Set/Get the spacing between the plot window and the plot. The value
+ // is specified in pixels.
+ vtkSetClampMacro(Border, int, 0, 50);
+ vtkGetMacro(Border, int);
+
+ // Description:
+ // Set/Get whether the points are rendered. The point size can be set in
+ // the property object. This is a global flag which affects the plot only
+ // if per curve symbols are not defined.
+ vtkGetMacro(PlotPoints, int);
+ vtkSetMacro(PlotPoints, int);
+ vtkBooleanMacro(PlotPoints, int);
+
+ // Description:
+ // Set/Get whether the lines are rendered. The line width can be set in
+ // the property object.
+ vtkGetMacro(PlotLines, int);
+ vtkSetMacro(PlotLines, int);
+ vtkBooleanMacro(PlotLines, int);
+
+ // RKV : Begin
+ // Description:
+ // Set/Get the location in the viewport
+ vtkGetMacro(PlotLocation, VISU_XYPlotLocation);
+ vtkSetMacro(PlotLocation, VISU_XYPlotLocation);
+ // RKV : End
+
+ // Description:
+ // Set/Get the factor that controls how big glyphs are in the plot.
+ // The number is expressed as a fraction of the length of the diagonal
+ // of the plot bounding box.
+ vtkSetClampMacro(GlyphSize, double, 0.0, 0.2);
+ vtkGetMacro(GlyphSize, double);
+
+ // Description:
+ // Given a position within the viewport used by the plot, return the
+ // the plot coordinates (XAxis value, YAxis value)
+ void ViewportToPlotCoordinate(vtkViewport *viewport, double &u, double &v);
+
+ // Description:
+ // An alternate form of ViewportToPlotCoordinate() above. This method
+ // inputs the viewport coordinate pair (defined by the ivar
+ // ViewportCoordinate)and then stores them in the ivar PlotCoordinate.
+ void ViewportToPlotCoordinate(vtkViewport *viewport);
+ vtkSetVector2Macro(PlotCoordinate,double);
+ vtkGetVector2Macro(PlotCoordinate,double);
+
+ // Description:
+ // Given a plot coordinate, return the viewpoint position
+ void PlotToViewportCoordinate(vtkViewport *viewport, double &u, double &v);
+
+ // Description:
+ // An alternate form of PlotToViewportCoordinate() above. This method
+ // inputs the plot coordinate pair (defined in the ivar PlotCoordinate)
+ // and then stores them in the ivar ViewportCoordinate. (This method
+ // can be wrapped.)
+ void PlotToViewportCoordinate(vtkViewport *viewport);
+ vtkSetVector2Macro(ViewportCoordinate,double);
+ vtkGetVector2Macro(ViewportCoordinate,double);
+
+ // Description:
+ // Is the specified viewport position within the plot area (as opposed to the
+ // region used by the plot plus the labels)?
+ int IsInPlot(vtkViewport *viewport, double u, double v);
+
+ // Description:
+ // Take into account the modified time of internal helper classes.
+ unsigned long GetMTime();
+
+ // Description:
+ // Write the XY Ploat Actor as a CSV (comma separated value) representation.
+ void PrintAsCSV(ostream &os);
+
+//BTX
+ // Description:
+ // WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE
+ // DO NOT USE THIS METHOD OUTSIDE OF THE RENDERING PROCESS.
+ // Draw the x-y plot.
+ int RenderOpaqueGeometry(vtkViewport*);
+ int RenderOverlay(vtkViewport*);
+ int RenderTranslucentGeometry(vtkViewport *) {return 0;}
+
+ // Description:
+ // Release any graphics resources that are being consumed by this actor.
+ // The parameter window could be used to determine which graphic
+ // resources to release.
+ void ReleaseGraphicsResources(vtkWindow *);
+//ETX
+
+protected:
+ VISU_XYPlotActor();
+ ~VISU_XYPlotActor();
+
+ vtkDataSetCollection *InputList; //list of data sets to plot
+ char** SelectedInputScalars; // list of data set arrays to plot
+ vtkIntArray* SelectedInputScalarsComponent; // list of componenents
+ vtkDataObjectCollection *DataObjectInputList; //list of data objects to plot
+ char *Title;
+ char *XTitle;
+ char *YTitle;
+ int XValues;
+ int NumberOfXLabels;
+ int NumberOfYLabels;
+ int Logx;
+ char *LabelFormat;
+ double XRange[2];
+ double YRange[2];
+ double XComputedRange[2]; //range actually used by plot
+ double YComputedRange[2]; //range actually used by plot
+ int Border;
+ int PlotLines;
+ int PlotPoints;
+ int PlotCurveLines;
+ int PlotCurvePoints;
+ int ExchangeAxes;
+ int ReverseXAxis;
+ int ReverseYAxis;
+
+ vtkTextMapper *TitleMapper;
+ vtkActor2D *TitleActor;
+ vtkTextProperty *TitleTextProperty;
+
+ vtkAxisActor2D *XAxis;
+ vtkAxisActor2D *YAxis;
+
+ vtkTextProperty *AxisTitleTextProperty;
+ vtkTextProperty *AxisLabelTextProperty;
+
+ double ViewportCoordinate[2];
+ double PlotCoordinate[2];
+
+ //Handle data objects and datasets
+ int DataObjectPlotMode;
+ vtkIntArray *XComponent;
+ vtkIntArray *YComponent;
+ vtkIntArray *LinesOn;
+ vtkIntArray *PointsOn;
+
+ //The data drawn within the axes. Each curve is one polydata.
+ //color is controlled by scalar data. The curves are appended
+ //together, possibly glyphed with point symbols.
+ int NumberOfInputs;
+ vtkPolyData **PlotData;
+ vtkGlyph2D **PlotGlyph;
+ vtkAppendPolyData **PlotAppend;
+ vtkTransformPolyDataFilter **PlotTransform; // RKV
+ vtkPolyDataMapper2D **PlotMapper;
+ vtkActor2D **PlotActor;
+ void InitializeEntries();
+
+ // Legends and plot symbols. The legend also keeps track of
+ // the symbols and such.
+ int Legend;
+ double LegendPosition[2];
+ double LegendPosition2[2];
+ vtkLegendBoxActor *LegendActor;
+ vtkGlyphSource2D *GlyphSource;
+ vtkPlanes *ClipPlanes;
+ double GlyphSize;
+
+ // Keep track of changes.
+ VISU_XYPlotLocation PlotLocation; // RKV
+ int CachedSize[2];
+ vtkTimeStamp BuildTime;
+
+ void ComputeXRange(double range[2], double *lengths);
+ void ComputeYRange(double range[2]);
+ void ComputeDORange(double xrange[2], double yrange[2], double *lengths);
+
+ virtual void CreatePlotData(int *pos, int *pos2, double xRange[2],
+ double yRange[2], double *norms,
+ int numDS, int numDO);
+ void PlaceAxes(vtkViewport *viewport, int *size, int pos[2], int pos2[2]);
+ void GenerateClipPlanes(int *pos, int *pos2);
+ double ComputeGlyphScale(int i, int *pos, int *pos2);
+ void ClipPlotData(int *pos, int *pos2, vtkPolyData *pd);
+ double *TransformPoint(int pos[2], int pos2[2], double x[3], double xNew[3]);
+
+private:
+ VISU_XYPlotActor(const VISU_XYPlotActor&); // Not implemented.
+ void operator=(const VISU_XYPlotActor&); // Not implemented.
+};
+
+
+#endif /*VISU_XYPLOTACTOR_HXX_*/