1 // Copyright (C) 2014-2022 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>
44 //------------------------------------------------------------------------------
45 bool isStringInList(const list<string>& aList, const string& theName)
47 list<string>::const_iterator anIter;
48 for (anIter = aList.begin(); anIter != aList.end(); anIter++)
50 // Compares the values of the string.
51 if ( (*anIter).compare(theName) == 0)
57 //------------------------------------------------------------------------------
58 void add2List(const list<string>& theSource, list<string>& theDestination)
60 list<string>::const_iterator anIter;
61 for (anIter = theSource.begin(); anIter != theSource.end(); anIter++)
63 // Add the item to the list if it does not exist
64 if (!isStringInList(theDestination, *anIter))
65 theDestination.push_back(*anIter);
69 //------------------------------------------------------------------------------
70 double maximumElement(vector< complex<double> >& theList)
73 vector<double> tmpList;
74 vector< complex<double> >::iterator it;
75 for (it = theList.begin(); it != theList.end(); ++it)
77 tmpList.push_back(((*it)*conj(*it)).real());
79 aMaximum = *max_element(tmpList.begin(), tmpList.end());
83 //------------------------------------------------------------------------------
84 list<std::string> GetListOfFields(vtkDataObject* theObject)
88 if (theObject->IsA("vtkDataSet"))
90 vtkDataSet* aDataSet = vtkDataSet::SafeDownCast(theObject);
91 vtkPointData* aPntData = aDataSet->GetPointData();
93 // Add fields name on points
94 int aNbArrays = aPntData->GetNumberOfArrays();
95 for (int i = 0; i<aNbArrays; i++)
97 if( vtkDataArray* anArray = aPntData->GetArray(i) ) {
98 //Data array should contains at least 3 components (1 - DX, 2 - DY, 3 - DZ)
99 if( anArray->GetNumberOfComponents() >= 3 ) {
100 const char* aName = aPntData->GetArrayName(i);
101 aList.push_back(aName);
109 //------------------------------------------------------------------------------
110 vtkStandardNewMacro(vtkEllipseBuilderFilter)
112 //------------------------------------------------------------------------------
113 vtkEllipseBuilderFilter::vtkEllipseBuilderFilter() : vtkMultiBlockDataSetAlgorithm()
115 this->RealField = NULL;
116 this->ImagField = NULL;
117 this->FieldList = vtkStringArray::New();
120 //------------------------------------------------------------------------------
121 vtkEllipseBuilderFilter::~vtkEllipseBuilderFilter()
123 this->SetRealField(NULL);
124 this->SetRealField(NULL);
125 this->FieldList->Delete();
128 //------------------------------------------------------------------------------
129 int vtkEllipseBuilderFilter::RequestData(vtkInformation* vtkNotUsed(request),
130 vtkInformationVector** theInputVector,
131 vtkInformationVector* theOutputVector)
133 int aResolution = this->Resolution;
136 if( this->ScaleFactor == 0.0 )
139 int anAxis = this->Axis;
141 // Get the info objects
142 vtkMultiBlockDataSet* anInputMDSet = vtkMultiBlockDataSet::GetData(theInputVector[0], 0);
143 vtkMultiBlockDataSet* anOutputMDSet = vtkMultiBlockDataSet::GetData(theOutputVector, 0);
145 double a, b, z_point;
146 vector< complex<double> > circle;
149 double range, min, max, delta;
150 if(this->EndAngle > this->StartAngle) {
151 min = this->StartAngle;
152 max = this->EndAngle;
154 min = this->StartAngle;
155 max = this->EndAngle + 360.;
158 delta = range/(double)aResolution;
159 for (double iter = min; iter < max; iter+=delta)
161 a = cos(vtkMath::RadiansFromDegrees(iter));
162 b = sin(vtkMath::RadiansFromDegrees(iter));
163 complex<double> aVal(a, b);
164 circle.push_back(aVal);
169 aScaleFactor = 1./this->ScaleFactor;
171 vtkDataObjectTreeIterator* anIter = anInputMDSet->NewTreeIterator();
172 anIter->VisitOnlyLeavesOff();
173 bool created = false;
174 for (anIter->InitTraversal(); !anIter->IsDoneWithTraversal(); anIter->GoToNextItem())
176 vtkDataObject* anInputNode = anInputMDSet->GetDataSet(anIter);
177 if (anInputNode->IsA("vtkDataSet"))
179 vtkUnstructuredGrid* aSourceDS = vtkUnstructuredGrid::SafeDownCast(anInputNode);
180 if(!aSourceDS) continue;
182 vtkPointData* aPointData = aSourceDS->GetPointData();
183 if(!aPointData) continue;
185 int aNumberPoints = aSourceDS->GetNumberOfPoints();
187 vtkDataArray* aRealArray = vtkDataArray::SafeDownCast(aPointData->GetArray(this->RealField));
188 vtkDataArray* anImagArray = vtkDataArray::SafeDownCast(aPointData->GetArray(this->ImagField));
190 if(!aRealArray || !anImagArray) continue;
192 int aNumberOfRealComponents = aRealArray->GetNumberOfComponents();
193 int aNumberOfImagComponents = anImagArray->GetNumberOfComponents();
194 if (aNumberOfRealComponents >= 3 && aNumberOfImagComponents >= 3)
196 anOutputMDSet->CopyStructure(anInputMDSet);
197 vtkUnstructuredGrid* aCloneDS = aSourceDS->NewInstance();
198 vtkPoints* aClonePoints = vtkPoints::New();
199 aCloneDS->SetPoints(aClonePoints);
200 aClonePoints->Delete();
201 anOutputMDSet->SetDataSet(anIter, aCloneDS);
203 double rx, ry, ix, iy;
205 for (int j = 0; j < aNumberPoints; j++)
207 z_point = aSourceDS->GetPoint(j)[2];
209 if (anAxis == 2) // Z : DX and DY
211 rx = aRealArray->GetTuple(j)[0];
212 ry = aRealArray->GetTuple(j)[1];
213 ix = anImagArray->GetTuple(j)[0];
214 iy = anImagArray->GetTuple(j)[1];
216 else if (anAxis == 1) // Y : DX and DZ
218 rx = aRealArray->GetTuple(j)[0];
219 ry = aRealArray->GetTuple(j)[2];
220 ix = anImagArray->GetTuple(j)[0];
221 iy = anImagArray->GetTuple(j)[2];
223 else // X : DY and DZ
225 rx = aRealArray->GetTuple(j)[1];
226 ry = aRealArray->GetTuple(j)[2];
227 ix = anImagArray->GetTuple(j)[1];
228 iy = anImagArray->GetTuple(j)[2];
231 complex<double> x(rx, ix);
232 complex<double> y(ry, iy);
234 x = x / aScaleFactor;
235 y = y / aScaleFactor;
237 double x_point, y_point;
238 for (std::size_t r = 0; r < circle.size(); r++)
240 x_point = (x*circle[r]).real();
241 y_point = (y*circle[r]).real();
244 anId[0] = aClonePoints->InsertNextPoint(x_point, y_point, z_point);
245 else if (anAxis == 1)
246 anId[0] = aClonePoints->InsertNextPoint(x_point, z_point, y_point);
248 anId[0] = aClonePoints->InsertNextPoint(z_point, x_point, y_point);
249 aCloneDS->InsertNextCell(VTK_VERTEX, 1, anId);
265 //------------------------------------------------------------------------------
266 int vtkEllipseBuilderFilter::RequestInformation(vtkInformation* request,
267 vtkInformationVector **theInputVector,
268 vtkInformationVector *theOutputVector)
270 // Retrieve an instance of vtkMultiBlockDataSet class from an information object.
271 vtkMultiBlockDataSet* anInputMDataSet = vtkMultiBlockDataSet::GetData(theInputVector[0], 0);
274 vtkDataObjectTreeIterator* anIter = anInputMDataSet->NewTreeIterator();
275 anIter->VisitOnlyLeavesOff();
276 for (anIter->InitTraversal(); !anIter->IsDoneWithTraversal(); anIter->GoToNextItem())
278 vtkDataObject* anInputNode = anInputMDataSet->GetDataSet(anIter);
279 if (anInputNode->IsA("vtkDataSet"))
281 list<string> aSubList = GetListOfFields(anInputNode);
282 add2List(aSubList, aList);
287 this->FieldList->Reset();
288 this->FieldList->SetNumberOfValues((vtkIdType)aList.size());
289 list<string>::const_iterator anIterName;
291 for (anIterName = aList.begin(); anIterName != aList.end(); anIterName++)
293 this->FieldList->SetValue(i, *anIterName);
297 return this->Superclass::RequestInformation(request, theInputVector, theOutputVector);
301 //------------------------------------------------------------------------------
302 vtkStringArray* vtkEllipseBuilderFilter::GetFieldList()
304 return this->FieldList;
307 //------------------------------------------------------------------------------
308 void vtkEllipseBuilderFilter::PrintSelf(ostream& os, vtkIndent indent)
310 this->Superclass::PrintSelf(os, indent);
311 os << indent << "Real Field : " << this->RealField << endl;
312 os << indent << "Imag Field : " << this->ImagField << endl;
313 os << indent << "Start Angle : " << this->StartAngle << endl;
314 os << indent << "End Angle : " << this->EndAngle << endl;
315 os << indent << "Scale Factor : " << this->ScaleFactor << endl;
316 os << indent << "Scale Resolution : " << this->Resolution << endl;
317 os << indent << "Axis : " << this->Axis << endl;