1 // Copyright (C) 2014-2019 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
20 #include "vtkEllipseBuilderFilter.h"
22 #include <vtkObjectFactory.h>
23 #include <vtkInformation.h>
24 #include <vtkInformationVector.h>
25 #include <vtkMultiBlockDataSet.h>
26 #include <vtkDataObjectTreeIterator.h>
27 #include <vtkDataSet.h>
28 #include <vtkPoints.h>
29 #include <vtkPointData.h>
30 #include <vtkDataArray.h>
31 #include <vtkStringArray.h>
32 #include <vtkUnstructuredGrid.h>
33 #include <vtkPolyVertex.h>
43 //------------------------------------------------------------------------------
44 bool isStringInList(const list<string>& aList, const string& theName)
46 list<string>::const_iterator anIter;
47 for (anIter = aList.begin(); anIter != aList.end(); anIter++)
49 // Compares the values of the string.
50 if ( (*anIter).compare(theName) == 0)
56 //------------------------------------------------------------------------------
57 void add2List(const list<string>& theSource, list<string>& theDestination)
59 list<string>::const_iterator anIter;
60 for (anIter = theSource.begin(); anIter != theSource.end(); anIter++)
62 // Add the item to the list if it does not exist
63 if (!isStringInList(theDestination, *anIter))
64 theDestination.push_back(*anIter);
68 //------------------------------------------------------------------------------
69 double maximumElement(vector< complex<double> >& theList)
72 vector<double> tmpList;
73 vector< complex<double> >::iterator it;
74 for (it = theList.begin(); it != theList.end(); ++it)
76 tmpList.push_back(((*it)*conj(*it)).real());
78 aMaximum = *max_element(tmpList.begin(), tmpList.end());
82 //------------------------------------------------------------------------------
83 list<std::string> GetListOfFields(vtkDataObject* theObject)
87 if (theObject->IsA("vtkDataSet"))
89 vtkDataSet* aDataSet = vtkDataSet::SafeDownCast(theObject);
90 vtkPointData* aPntData = aDataSet->GetPointData();
92 // Add fields name on points
93 int aNbArrays = aPntData->GetNumberOfArrays();
94 for (int i = 0; i<aNbArrays; i++)
96 if( vtkDataArray* anArray = aPntData->GetArray(i) ) {
97 //Data array should contains at least 3 components (1 - DX, 2 - DY, 3 - DZ)
98 if( anArray->GetNumberOfComponents() >= 3 ) {
99 const char* aName = aPntData->GetArrayName(i);
100 aList.push_back(aName);
108 //------------------------------------------------------------------------------
109 vtkStandardNewMacro(vtkEllipseBuilderFilter);
111 //------------------------------------------------------------------------------
112 vtkEllipseBuilderFilter::vtkEllipseBuilderFilter() : vtkMultiBlockDataSetAlgorithm()
114 this->RealField = NULL;
115 this->ImagField = NULL;
116 this->FieldList = vtkStringArray::New();
119 //------------------------------------------------------------------------------
120 vtkEllipseBuilderFilter::~vtkEllipseBuilderFilter()
122 this->SetRealField(NULL);
123 this->SetRealField(NULL);
124 this->FieldList->Delete();
127 //------------------------------------------------------------------------------
128 int vtkEllipseBuilderFilter::RequestData(vtkInformation* vtkNotUsed(request),
129 vtkInformationVector** theInputVector,
130 vtkInformationVector* theOutputVector)
132 int aResolution = this->Resolution;
135 if( this->ScaleFactor == 0.0 )
138 int anAxis = this->Axis;
140 // Get the info objects
141 vtkMultiBlockDataSet* anInputMDSet = vtkMultiBlockDataSet::GetData(theInputVector[0], 0);
142 vtkMultiBlockDataSet* anOutputMDSet = vtkMultiBlockDataSet::GetData(theOutputVector, 0);
144 double a, b, z_point;
145 vector< complex<double> > circle;
148 double range, min, max, delta;
149 if(this->EndAngle > this->StartAngle) {
150 min = this->StartAngle;
151 max = this->EndAngle;
153 min = this->StartAngle;
154 max = this->EndAngle + 360.;
157 delta = range/(double)aResolution;
158 for (double iter = min; iter < max; iter+=delta)
160 a = cos(vtkMath::RadiansFromDegrees(iter));
161 b = sin(vtkMath::RadiansFromDegrees(iter));
162 complex<double> aVal(a, b);
163 circle.push_back(aVal);
168 aScaleFactor = 1./this->ScaleFactor;
170 vtkDataObjectTreeIterator* anIter = anInputMDSet->NewTreeIterator();
171 anIter->VisitOnlyLeavesOff();
172 bool created = false;
173 for (anIter->InitTraversal(); !anIter->IsDoneWithTraversal(); anIter->GoToNextItem())
175 vtkDataObject* anInputNode = anInputMDSet->GetDataSet(anIter);
176 if (anInputNode->IsA("vtkDataSet"))
178 vtkUnstructuredGrid* aSourceDS = vtkUnstructuredGrid::SafeDownCast(anInputNode);
179 if(!aSourceDS) continue;
181 vtkPointData* aPointData = aSourceDS->GetPointData();
182 if(!aPointData) continue;
184 int aNumberPoints = aSourceDS->GetNumberOfPoints();
186 vtkDataArray* aRealArray = vtkDataArray::SafeDownCast(aPointData->GetArray(this->RealField));
187 vtkDataArray* anImagArray = vtkDataArray::SafeDownCast(aPointData->GetArray(this->ImagField));
189 if(!aRealArray || !anImagArray) continue;
191 int aNumberOfRealComponents = aRealArray->GetNumberOfComponents();
192 int aNumberOfImagComponents = anImagArray->GetNumberOfComponents();
193 if (aNumberOfRealComponents >= 3 && aNumberOfImagComponents >= 3)
195 anOutputMDSet->CopyStructure(anInputMDSet);
196 vtkUnstructuredGrid* aCloneDS = aSourceDS->NewInstance();
197 vtkPoints* aClonePoints = vtkPoints::New();
198 aCloneDS->SetPoints(aClonePoints);
199 aClonePoints->Delete();
200 anOutputMDSet->SetDataSet(anIter, aCloneDS);
202 double rx, ry, ix, iy;
204 for (int j = 0; j < aNumberPoints; j++)
206 z_point = aSourceDS->GetPoint(j)[2];
208 if (anAxis == 2) // Z : DX and DY
210 rx = aRealArray->GetTuple(j)[0];
211 ry = aRealArray->GetTuple(j)[1];
212 ix = anImagArray->GetTuple(j)[0];
213 iy = anImagArray->GetTuple(j)[1];
215 else if (anAxis == 1) // Y : DX and DZ
217 rx = aRealArray->GetTuple(j)[0];
218 ry = aRealArray->GetTuple(j)[2];
219 ix = anImagArray->GetTuple(j)[0];
220 iy = anImagArray->GetTuple(j)[2];
222 else // X : DY and DZ
224 rx = aRealArray->GetTuple(j)[1];
225 ry = aRealArray->GetTuple(j)[2];
226 ix = anImagArray->GetTuple(j)[1];
227 iy = anImagArray->GetTuple(j)[2];
230 complex<double> x(rx, ix);
231 complex<double> y(ry, iy);
233 x = x / aScaleFactor;
234 y = y / aScaleFactor;
236 double x_point, y_point;
237 for (int r = 0; r < circle.size(); r++)
239 x_point = (x*circle[r]).real();
240 y_point = (y*circle[r]).real();
243 anId[0] = aClonePoints->InsertNextPoint(x_point, y_point, z_point);
244 else if (anAxis == 1)
245 anId[0] = aClonePoints->InsertNextPoint(x_point, z_point, y_point);
247 anId[0] = aClonePoints->InsertNextPoint(z_point, x_point, y_point);
248 aCloneDS->InsertNextCell(VTK_VERTEX, 1, anId);
264 //------------------------------------------------------------------------------
265 int vtkEllipseBuilderFilter::RequestInformation(vtkInformation* request,
266 vtkInformationVector **theInputVector,
267 vtkInformationVector *theOutputVector)
269 // Retrieve an instance of vtkMultiBlockDataSet class from an information object.
270 vtkMultiBlockDataSet* anInputMDataSet = vtkMultiBlockDataSet::GetData(theInputVector[0], 0);
273 vtkDataObjectTreeIterator* anIter = anInputMDataSet->NewTreeIterator();
274 anIter->VisitOnlyLeavesOff();
275 for (anIter->InitTraversal(); !anIter->IsDoneWithTraversal(); anIter->GoToNextItem())
277 vtkDataObject* anInputNode = anInputMDataSet->GetDataSet(anIter);
278 if (anInputNode->IsA("vtkDataSet"))
280 list<string> aSubList = GetListOfFields(anInputNode);
281 add2List(aSubList, aList);
286 this->FieldList->Reset();
287 this->FieldList->SetNumberOfValues(aList.size());
288 list<string>::const_iterator anIterName;
290 for (anIterName = aList.begin(); anIterName != aList.end(); anIterName++)
292 this->FieldList->SetValue(i, *anIterName);
296 return this->Superclass::RequestInformation(request, theInputVector, theOutputVector);
300 //------------------------------------------------------------------------------
301 vtkStringArray* vtkEllipseBuilderFilter::GetFieldList()
303 return this->FieldList;
306 //------------------------------------------------------------------------------
307 void vtkEllipseBuilderFilter::PrintSelf(ostream& os, vtkIndent indent)
309 this->Superclass::PrintSelf(os, indent);
310 os << indent << "Real Field : " << this->RealField << endl;
311 os << indent << "Imag Field : " << this->ImagField << endl;
312 os << indent << "Start Angle : " << this->StartAngle << endl;
313 os << indent << "End Angle : " << this->EndAngle << endl;
314 os << indent << "Scale Factor : " << this->ScaleFactor << endl;
315 os << indent << "Scale Resolution : " << this->Resolution << endl;
316 os << indent << "Axis : " << this->Axis << endl;