Salome HOME
Copyright update 2022
[modules/paravis.git] / src / Plugins / EllipseBuilder / plugin / EllipseBuilderModule / vtkEllipseBuilderFilter.cxx
1 // Copyright (C) 2014-2022  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "vtkEllipseBuilderFilter.h"
21
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>
34 #include <vtkMath.h>
35
36 #include <complex>
37 #include <algorithm>
38 #include <vector>
39 #include <cmath>
40 #include <list>
41
42 using namespace std;
43
44 //------------------------------------------------------------------------------
45 bool isStringInList(const list<string>& aList, const string& theName)
46 {
47   list<string>::const_iterator anIter;
48   for (anIter = aList.begin(); anIter != aList.end(); anIter++)
49     {
50       // Compares the values of the string.
51       if ( (*anIter).compare(theName) == 0)
52         return true;
53     }
54   return false;
55 }
56
57 //------------------------------------------------------------------------------
58 void add2List(const list<string>& theSource, list<string>& theDestination)
59 {
60   list<string>::const_iterator anIter;
61   for (anIter = theSource.begin(); anIter != theSource.end(); anIter++)
62     {
63       // Add the item to the list if it does not exist
64       if (!isStringInList(theDestination, *anIter))
65         theDestination.push_back(*anIter);
66     }
67 }
68
69 //------------------------------------------------------------------------------
70 double maximumElement(vector< complex<double> >& theList)
71 {
72   double aMaximum;
73   vector<double> tmpList;
74   vector< complex<double> >::iterator it;
75   for (it = theList.begin(); it != theList.end(); ++it)
76     {
77       tmpList.push_back(((*it)*conj(*it)).real());
78     }
79   aMaximum = *max_element(tmpList.begin(), tmpList.end());
80   return aMaximum;
81 }
82
83 //------------------------------------------------------------------------------
84 list<std::string> GetListOfFields(vtkDataObject* theObject)
85 {
86   list<string> aList;
87   
88   if (theObject->IsA("vtkDataSet"))
89     {
90       vtkDataSet* aDataSet = vtkDataSet::SafeDownCast(theObject);
91       vtkPointData* aPntData = aDataSet->GetPointData();
92       
93       // Add fields name on points
94       int aNbArrays = aPntData->GetNumberOfArrays();
95       for (int i = 0; i<aNbArrays; i++)
96         {
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);
102             }
103           }
104         }
105     }
106   return aList;
107 }
108
109 //------------------------------------------------------------------------------
110 vtkStandardNewMacro(vtkEllipseBuilderFilter)
111
112 //------------------------------------------------------------------------------
113 vtkEllipseBuilderFilter::vtkEllipseBuilderFilter() : vtkMultiBlockDataSetAlgorithm()
114 {
115   this->RealField = NULL;
116   this->ImagField = NULL;
117   this->FieldList = vtkStringArray::New();
118 }
119
120 //------------------------------------------------------------------------------
121 vtkEllipseBuilderFilter::~vtkEllipseBuilderFilter()
122 {
123   this->SetRealField(NULL);
124   this->SetRealField(NULL);
125   this->FieldList->Delete();
126 }
127
128 //------------------------------------------------------------------------------
129 int vtkEllipseBuilderFilter::RequestData(vtkInformation* vtkNotUsed(request),
130                                          vtkInformationVector** theInputVector,
131                                          vtkInformationVector* theOutputVector)
132 {
133   int aResolution = this->Resolution;
134   if(aResolution <=0 )
135     return 0;
136   if( this->ScaleFactor == 0.0 )
137     return 0;
138
139   int anAxis = this->Axis;
140   
141   // Get the info objects
142   vtkMultiBlockDataSet* anInputMDSet = vtkMultiBlockDataSet::GetData(theInputVector[0], 0);
143   vtkMultiBlockDataSet* anOutputMDSet = vtkMultiBlockDataSet::GetData(theOutputVector, 0);
144   
145   double a, b, z_point;
146   vector< complex<double> > circle;
147
148   // Points Ellipses
149   double range, min, max, delta;
150   if(this->EndAngle > this->StartAngle) {
151     min = this->StartAngle;
152     max = this->EndAngle;
153   } else {
154     min = this->StartAngle;
155     max = this->EndAngle + 360.;
156   }
157   range = max-min;
158   delta = range/(double)aResolution;
159   for (double iter = min;  iter < max; iter+=delta)
160     {
161       a = cos(vtkMath::RadiansFromDegrees(iter));
162       b = sin(vtkMath::RadiansFromDegrees(iter));
163       complex<double> aVal(a, b);
164       circle.push_back(aVal);
165     }
166   
167   //Scale Factor    
168   double aScaleFactor;
169   aScaleFactor = 1./this->ScaleFactor;  
170     
171   vtkDataObjectTreeIterator* anIter = anInputMDSet->NewTreeIterator();
172   anIter->VisitOnlyLeavesOff();
173   bool created = false;
174   for (anIter->InitTraversal(); !anIter->IsDoneWithTraversal(); anIter->GoToNextItem())
175     {
176       vtkDataObject* anInputNode = anInputMDSet->GetDataSet(anIter);
177       if (anInputNode->IsA("vtkDataSet"))
178         {
179           vtkUnstructuredGrid* aSourceDS = vtkUnstructuredGrid::SafeDownCast(anInputNode);
180           if(!aSourceDS) continue;
181           
182           vtkPointData* aPointData = aSourceDS->GetPointData();
183           if(!aPointData) continue;
184           
185           int aNumberPoints = aSourceDS->GetNumberOfPoints();
186           
187           vtkDataArray* aRealArray = vtkDataArray::SafeDownCast(aPointData->GetArray(this->RealField));
188           vtkDataArray* anImagArray = vtkDataArray::SafeDownCast(aPointData->GetArray(this->ImagField));
189           
190           if(!aRealArray || !anImagArray) continue;
191           
192           int aNumberOfRealComponents = aRealArray->GetNumberOfComponents();
193           int aNumberOfImagComponents = anImagArray->GetNumberOfComponents();              
194           if (aNumberOfRealComponents >= 3 && aNumberOfImagComponents >= 3)
195             {
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);
202               aCloneDS->Delete();             
203               double rx, ry, ix, iy;
204               created = true;
205               for (int j = 0; j < aNumberPoints; j++)
206                 {
207                   z_point = aSourceDS->GetPoint(j)[2];
208                   
209                   if (anAxis == 2)      // Z : DX and DY
210                     {
211                       rx = aRealArray->GetTuple(j)[0];
212                       ry = aRealArray->GetTuple(j)[1];
213                       ix = anImagArray->GetTuple(j)[0];
214                       iy = anImagArray->GetTuple(j)[1];
215                     }
216                   else if (anAxis == 1) // Y : DX and DZ
217                     {
218                       rx = aRealArray->GetTuple(j)[0];
219                       ry = aRealArray->GetTuple(j)[2];
220                       ix = anImagArray->GetTuple(j)[0];
221                       iy = anImagArray->GetTuple(j)[2];
222                     }
223                   else                  // X : DY and DZ
224                     {
225                       rx = aRealArray->GetTuple(j)[1];
226                       ry = aRealArray->GetTuple(j)[2];
227                       ix = anImagArray->GetTuple(j)[1];
228                       iy = anImagArray->GetTuple(j)[2];
229                     }
230                   
231                   complex<double> x(rx, ix);
232                   complex<double> y(ry, iy);               
233                   
234                   x = x / aScaleFactor;
235                   y = y / aScaleFactor;             
236
237                   double x_point, y_point;
238                   for (std::size_t r = 0; r < circle.size(); r++)
239                     {
240                       x_point = (x*circle[r]).real();
241                       y_point = (y*circle[r]).real();
242                       vtkIdType anId[1];
243                       if (anAxis == 2)
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);
247                       else
248                         anId[0] = aClonePoints->InsertNextPoint(z_point, x_point, y_point);                   
249                       aCloneDS->InsertNextCell(VTK_VERTEX, 1, anId);
250                     }             
251                 }
252             }
253           else
254             {
255               continue;
256             }
257         }
258     }
259   anIter->Delete();
260   if(!created)
261     return 0;
262   return 1;
263 }
264
265 //------------------------------------------------------------------------------
266 int vtkEllipseBuilderFilter::RequestInformation(vtkInformation* request,
267                                                 vtkInformationVector **theInputVector,
268                                                 vtkInformationVector *theOutputVector)
269 {
270     // Retrieve an instance of vtkMultiBlockDataSet class from an information object.
271     vtkMultiBlockDataSet* anInputMDataSet = vtkMultiBlockDataSet::GetData(theInputVector[0], 0);
272
273     list<string> aList;
274     vtkDataObjectTreeIterator* anIter = anInputMDataSet->NewTreeIterator();
275     anIter->VisitOnlyLeavesOff();
276     for (anIter->InitTraversal(); !anIter->IsDoneWithTraversal(); anIter->GoToNextItem())
277     {
278         vtkDataObject* anInputNode = anInputMDataSet->GetDataSet(anIter);
279         if (anInputNode->IsA("vtkDataSet"))
280         {
281           list<string> aSubList = GetListOfFields(anInputNode);
282           add2List(aSubList, aList);
283         }
284     }
285     anIter->Delete();
286     
287     this->FieldList->Reset();
288     this->FieldList->SetNumberOfValues((vtkIdType)aList.size());
289     list<string>::const_iterator anIterName;
290     int i = 0;
291     for (anIterName = aList.begin(); anIterName != aList.end(); anIterName++)
292     {
293         this->FieldList->SetValue(i, *anIterName);
294         i++;
295     }
296     
297     return this->Superclass::RequestInformation(request, theInputVector, theOutputVector);
298 }
299
300
301 //------------------------------------------------------------------------------
302 vtkStringArray* vtkEllipseBuilderFilter::GetFieldList()
303 {
304     return this->FieldList;
305 }
306
307 //------------------------------------------------------------------------------
308 void vtkEllipseBuilderFilter::PrintSelf(ostream& os, vtkIndent indent)
309 {
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;
318 }
319