1 // Copyright (C) 2014 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "vtkEllipseBuilderFilter.h"
21 #include <vtkObjectFactory.h>
22 #include <vtkInformation.h>
23 #include <vtkInformationVector.h>
24 #include <vtkMultiBlockDataSet.h>
25 #include <vtkDataObjectTreeIterator.h>
26 #include <vtkDataSet.h>
27 #include <vtkPoints.h>
28 #include <vtkPointData.h>
29 #include <vtkDataArray.h>
30 #include <vtkStringArray.h>
31 #include <vtkUnstructuredGrid.h>
32 #include <vtkPolyVertex.h>
42 //------------------------------------------------------------------------------
43 bool isStringInList(const list<string>& aList, const string& theName)
45 list<string>::const_iterator anIter;
46 for (anIter = aList.begin(); anIter != aList.end(); anIter++)
48 // Compares the values of the string.
49 if ( (*anIter).compare(theName) == 0)
55 //------------------------------------------------------------------------------
56 void add2List(const list<string>& theSource, list<string>& theDestination)
58 list<string>::const_iterator anIter;
59 for (anIter = theSource.begin(); anIter != theSource.end(); anIter++)
61 // Add the item to the list if it does not exist
62 if (!isStringInList(theDestination, *anIter))
63 theDestination.push_back(*anIter);
67 //------------------------------------------------------------------------------
68 double maximumElement(vector< complex<double> >& theList)
71 vector<double> tmpList;
72 vector< complex<double> >::iterator it;
73 for (it = theList.begin(); it != theList.end(); ++it)
75 tmpList.push_back(((*it)*conj(*it)).real());
77 aMaximum = *max_element(tmpList.begin(), tmpList.end());
81 //------------------------------------------------------------------------------
82 list<std::string> GetListOfFields(vtkDataObject* theObject)
86 if (theObject->IsA("vtkDataSet"))
88 vtkDataSet* aDataSet = vtkDataSet::SafeDownCast(theObject);
89 vtkPointData* aPntData = aDataSet->GetPointData();
91 // Add fields name on points
92 int aNbArrays = aPntData->GetNumberOfArrays();
93 for (int i = 0; i<aNbArrays; i++)
95 if( vtkDataArray* anArray = aPntData->GetArray(i) ) {
96 //Data array should contains at least 3 components (1 - DX, 2 - DY, 3 - DZ)
97 if( anArray->GetNumberOfComponents() >= 3 ) {
98 const char* aName = aPntData->GetArrayName(i);
99 aList.push_back(aName);
107 //------------------------------------------------------------------------------
108 vtkStandardNewMacro(vtkEllipseBuilderFilter);
110 //------------------------------------------------------------------------------
111 vtkEllipseBuilderFilter::vtkEllipseBuilderFilter() : vtkMultiBlockDataSetAlgorithm()
113 this->RealField = NULL;
114 this->ImagField = NULL;
115 this->FieldList = vtkStringArray::New();
118 //------------------------------------------------------------------------------
119 vtkEllipseBuilderFilter::~vtkEllipseBuilderFilter()
121 this->SetRealField(NULL);
122 this->SetRealField(NULL);
123 this->FieldList->Delete();
126 //------------------------------------------------------------------------------
127 int vtkEllipseBuilderFilter::RequestData(vtkInformation* vtkNotUsed(request),
128 vtkInformationVector** theInputVector,
129 vtkInformationVector* theOutputVector)
131 int aResolution = this->Resolution;
134 if( this->ScaleFactor == 0.0 )
137 int anAxis = this->Axis;
139 // Get the info objects
140 vtkMultiBlockDataSet* anInputMDSet = vtkMultiBlockDataSet::GetData(theInputVector[0], 0);
141 vtkMultiBlockDataSet* anOutputMDSet = vtkMultiBlockDataSet::GetData(theOutputVector, 0);
143 double a, b, z_point;
144 vector< complex<double> > circle;
147 double range, min, max, delta;
148 if(this->EndAngle > this->StartAngle) {
149 min = this->StartAngle;
150 max = this->EndAngle;
152 min = this->StartAngle;
153 max = this->EndAngle + 360.;
156 delta = range/(double)aResolution;
157 for (double iter = min; iter < max; iter+=delta)
159 a = cos(vtkMath::RadiansFromDegrees(iter));
160 b = sin(vtkMath::RadiansFromDegrees(iter));
161 complex<double> aVal(a, b);
162 circle.push_back(aVal);
167 aScaleFactor = 1./this->ScaleFactor;
169 vtkDataObjectTreeIterator* anIter = anInputMDSet->NewTreeIterator();
170 anIter->VisitOnlyLeavesOff();
171 bool created = false;
172 for (anIter->InitTraversal(); !anIter->IsDoneWithTraversal(); anIter->GoToNextItem())
174 vtkDataObject* anInputNode = anInputMDSet->GetDataSet(anIter);
175 if (anInputNode->IsA("vtkDataSet"))
177 vtkUnstructuredGrid* aSourceDS = vtkUnstructuredGrid::SafeDownCast(anInputNode);
178 if(!aSourceDS) continue;
180 vtkPointData* aPointData = aSourceDS->GetPointData();
181 if(!aPointData) continue;
183 int aNumberPoints = aSourceDS->GetNumberOfPoints();
185 vtkDataArray* aRealArray = vtkDataArray::SafeDownCast(aPointData->GetArray(this->RealField));
186 vtkDataArray* anImagArray = vtkDataArray::SafeDownCast(aPointData->GetArray(this->ImagField));
188 if(!aRealArray || !anImagArray) continue;
190 int aNumberOfRealComponents = aRealArray->GetNumberOfComponents();
191 int aNumberOfImagComponents = anImagArray->GetNumberOfComponents();
192 if (aNumberOfRealComponents >= 3 and aNumberOfImagComponents >= 3)
194 anOutputMDSet->CopyStructure(anInputMDSet);
195 vtkUnstructuredGrid* aCloneDS = aSourceDS->NewInstance();
196 vtkPoints* aClonePoints = vtkPoints::New();
197 aCloneDS->SetPoints(aClonePoints);
198 aClonePoints->Delete();
199 anOutputMDSet->SetDataSet(anIter, aCloneDS);
201 double rx, ry, ix, iy;
203 for (int j = 0; j < aNumberPoints; j++)
205 z_point = aSourceDS->GetPoint(j)[2];
207 if (anAxis == 2) // Z : DX and DY
209 rx = aRealArray->GetTuple(j)[0];
210 ry = aRealArray->GetTuple(j)[1];
211 ix = anImagArray->GetTuple(j)[0];
212 iy = anImagArray->GetTuple(j)[1];
214 else if (anAxis == 1) // Y : DX and DZ
216 rx = aRealArray->GetTuple(j)[0];
217 ry = aRealArray->GetTuple(j)[2];
218 ix = anImagArray->GetTuple(j)[0];
219 iy = anImagArray->GetTuple(j)[2];
221 else // X : DY and DZ
223 rx = aRealArray->GetTuple(j)[1];
224 ry = aRealArray->GetTuple(j)[2];
225 ix = anImagArray->GetTuple(j)[1];
226 iy = anImagArray->GetTuple(j)[2];
229 complex<double> x(rx, ix);
230 complex<double> y(ry, iy);
232 x = x / aScaleFactor;
233 y = y / aScaleFactor;
235 double x_point, y_point;
236 for (int r = 0; r < circle.size(); r++)
238 x_point = (x*circle[r]).real();
239 y_point = (y*circle[r]).real();
242 anId[0] = aClonePoints->InsertNextPoint(x_point, y_point, z_point);
243 else if (anAxis == 1)
244 anId[0] = aClonePoints->InsertNextPoint(x_point, z_point, y_point);
246 anId[0] = aClonePoints->InsertNextPoint(z_point, x_point, y_point);
247 aCloneDS->InsertNextCell(VTK_VERTEX, 1, anId);
263 //------------------------------------------------------------------------------
264 int vtkEllipseBuilderFilter::RequestInformation(vtkInformation* request,
265 vtkInformationVector **theInputVector,
266 vtkInformationVector *theOutputVector)
268 // Retrieve an instance of vtkMultiBlockDataSet class from an information object.
269 vtkMultiBlockDataSet* anInputMDataSet = vtkMultiBlockDataSet::GetData(theInputVector[0], 0);
272 vtkDataObjectTreeIterator* anIter = anInputMDataSet->NewTreeIterator();
273 anIter->VisitOnlyLeavesOff();
274 for (anIter->InitTraversal(); !anIter->IsDoneWithTraversal(); anIter->GoToNextItem())
276 vtkDataObject* anInputNode = anInputMDataSet->GetDataSet(anIter);
277 if (anInputNode->IsA("vtkDataSet"))
279 list<string> aSubList = GetListOfFields(anInputNode);
280 add2List(aSubList, aList);
285 this->FieldList->Reset();
286 this->FieldList->SetNumberOfValues(aList.size());
287 list<string>::const_iterator anIterName;
289 for (anIterName = aList.begin(); anIterName != aList.end(); anIterName++)
291 this->FieldList->SetValue(i, *anIterName);
295 return this->Superclass::RequestInformation(request, theInputVector, theOutputVector);
299 //------------------------------------------------------------------------------
300 vtkStringArray* vtkEllipseBuilderFilter::GetFieldList()
302 return this->FieldList;
305 //------------------------------------------------------------------------------
306 void vtkEllipseBuilderFilter::PrintSelf(ostream& os, vtkIndent indent)
308 this->Superclass::PrintSelf(os, indent);
309 os << indent << "Real Field : " << this->RealField << endl;
310 os << indent << "Imag Field : " << this->ImagField << endl;
311 os << indent << "Start Angle : " << this->StartAngle << endl;
312 os << indent << "End Angle : " << this->EndAngle << endl;
313 os << indent << "Scale Factor : " << this->ScaleFactor << endl;
314 os << indent << "Scale Resolution : " << this->Resolution << endl;
315 os << indent << "Axis : " << this->Axis << endl;