Salome HOME
Update copyright information
[modules/visu.git] / src / CONVERTOR / VISU_CommonCellsFilter.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
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.
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 // File      : VISU_CommonCellsFilter.cxx
21 // Created   : Wed Apr  4 08:45:07 2007
22 // Author    : Eugeny NIKOLAEV (enk)
23 //
24 #include "VISU_CommonCellsFilter.hxx"
25 #include "VISU_ConvertorDef.hxx"
26
27 // VTK product headers
28 #include <vtkUnstructuredGrid.h>
29 #include <vtkSetGet.h>
30 #include <vtkObjectFactory.h>
31 #include <vtkDataSet.h>
32 #include <vtkCellTypes.h>
33 #include <vtkPointData.h>
34 #include <vtkCellData.h>
35 #include <vtkIdList.h>
36 #include <vtkFloatArray.h>
37 #include <vtkCell.h>
38
39 // STL
40 #include <algorithm>
41 #include <vector>
42 #include <map>
43 #include <set>
44
45 #ifdef _DEBUG_
46 static int MYDEBUG = 0;
47 #else
48 static int MYDEBUG = 0;
49 #endif
50
51 // TTimerLog
52 #include "VISU_ConvertorUtils.hxx"
53
54 namespace
55 {
56   typedef std::pair<int,int> TPair;// pair first - object id, second - entity
57   //
58   typedef std::vector<int>  TSortedArrayOne;
59   typedef std::set<TPair>   TSortedArrayPair;
60   typedef std::set<int>     TIdSet;
61   typedef std::map<int,int> TId2IdMap;
62
63   inline
64   void
65   GetSortedArrayAsPair(vtkIntArray *theArray, 
66                        TSortedArrayPair& theSortedArray)
67   {
68     TSortedArrayPair aSortedArray;
69     int nbComp = theArray->GetNumberOfComponents();
70     if(nbComp == 2){
71       int aMaxId = theArray->GetNumberOfTuples()*theArray->GetNumberOfComponents();
72       int* aPointer = theArray->GetPointer(0);
73       int* anEndPointer = theArray->GetPointer(aMaxId + 1);
74       for(;aPointer<anEndPointer;){
75         TPair aPair;
76         aPair.first = *aPointer;
77         aPointer++;
78         aPair.second = *aPointer;
79         aPointer++;
80         aSortedArray.insert(aPair);
81       }
82     } else if (nbComp == 1) {
83       int aMaxId = theArray->GetNumberOfTuples();
84       int* aPointer = theArray->GetPointer(0);
85       int* anEndPointer = theArray->GetPointer(aMaxId + 1);
86       for(;aPointer<anEndPointer;){
87         TPair aPair;
88         aPair.first = *aPointer;
89         aPointer++;
90         aPair.second = (int)VISU::NODE_ENTITY;
91         aSortedArray.insert(aPair);
92       }
93       
94     }
95     theSortedArray.swap(aSortedArray);
96   }
97
98   inline
99   void
100   GetSortedArrayOne(vtkIntArray *theArray, 
101                     TSortedArrayOne& theSortedArray)
102   {
103     int aMaxId = theArray->GetMaxId();
104     int* aPointer = theArray->GetPointer(0);
105     int* anEndPointer = theArray->GetPointer(aMaxId + 1);
106     TSortedArrayOne aSortedArray(aPointer, anEndPointer);
107     std::sort(aSortedArray.begin(), aSortedArray.end());
108     theSortedArray.swap(aSortedArray);
109   }
110
111   inline
112   void
113   GetIdsForCopy(vtkUnstructuredGrid *inputUGrid, 
114                 vtkIntArray* inputPointIds,
115                 TSortedArrayOne& outputSortedArray)
116   {
117     if(inputUGrid){
118       TSortedArrayOne aSortedPointIds;
119       TSortedArrayOne aOutputCellIds;
120       TIdSet aMapForSearch;
121       int nbTuples = inputPointIds->GetNumberOfTuples();
122       int nbComp = inputPointIds->GetNumberOfComponents();
123       int * aPtr = inputPointIds->GetPointer(0);
124       int * aPtrEnd = inputPointIds->GetPointer(nbTuples*nbComp+1);
125       if(nbComp == 1)
126         while(aPtr<aPtrEnd){
127           aMapForSearch.insert(*aPtr);
128           aPtr++;
129         }
130       else if (nbComp == 2)
131         while(aPtr<aPtrEnd){
132           aMapForSearch.insert(*aPtr);
133           aPtr++;aPtr++;
134         }
135       int nbInputCells = inputUGrid->GetNumberOfCells();
136
137       for(int idCell=0;idCell<nbInputCells;idCell++){
138         vtkCell*   aCell = inputUGrid->GetCell(idCell);
139         vtkIdList* ptIds = aCell->GetPointIds();
140         int nbPointsInCell = ptIds->GetNumberOfIds();
141         bool aGoodCell = true;
142         for(int i=0;i<nbPointsInCell;i++){
143           int aSearchingId = ptIds->GetId(i);
144           TIdSet::iterator aResult = aMapForSearch.find(aSearchingId);
145           if(aResult == aMapForSearch.end()){
146             aGoodCell = false;
147             break;
148           }
149         }
150         if(aGoodCell)
151           aOutputCellIds.push_back(idCell);
152         else
153           continue;
154         
155       }
156
157       outputSortedArray.swap(aOutputCellIds);
158     }
159   }
160
161   inline
162   void
163   CopyElementsToOutput(vtkUnstructuredGrid* theInputUG,
164                        int& theNbElements,
165                        TSortedArrayOne& theElementIdsForCopy,
166                        TId2IdMap& theOldId2NewIdPointsMap,
167                        vtkUnstructuredGrid* theOutputUG)
168   {
169     vtkIntArray* theOuputIDSArray = vtkIntArray::New();
170     theOuputIDSArray->SetName("VISU_CELLS_MAPPER");
171     theOuputIDSArray->SetNumberOfComponents(2);
172     theOuputIDSArray->SetNumberOfTuples(theNbElements);
173     int* aOuputIDSPtr = theOuputIDSArray->GetPointer(0);
174     
175     vtkIntArray* aInputCellsMapper =
176       dynamic_cast<vtkIntArray*>(theInputUG->GetCellData()->GetArray("VISU_CELLS_MAPPER"));
177     int* aInputCellsMapperPointer = aInputCellsMapper->GetPointer(0);
178     for(int aCellIndex=0;aCellIndex<theNbElements;aCellIndex++){
179       int aCellId = theElementIdsForCopy[aCellIndex];
180       vtkIdList* aOldPointIds = theInputUG->GetCell(aCellId)->GetPointIds();
181       vtkIdList* aNewPointIds = vtkIdList::New();
182       int nbPointIds = aOldPointIds->GetNumberOfIds();
183       aNewPointIds->SetNumberOfIds(nbPointIds);
184       for(int j=0;j<nbPointIds;j++){
185         int aOldId = aOldPointIds->GetId(j);
186         int aNewId = theOldId2NewIdPointsMap[aOldId];
187         aNewPointIds->SetId(j,aNewId);
188       }
189       const int aOldCellId = theElementIdsForCopy[aCellIndex];
190       theOutputUG->InsertNextCell(theInputUG->GetCellType(aOldCellId),
191                                   aNewPointIds);
192
193       *aOuputIDSPtr = aInputCellsMapperPointer[2*aOldCellId];
194       aOuputIDSPtr++;
195       *aOuputIDSPtr = aInputCellsMapperPointer[2*aOldCellId+1];
196       aOuputIDSPtr++;
197       
198       aNewPointIds->Delete();
199     }
200
201     theOutputUG->GetCellData()->AddArray(theOuputIDSArray);
202     
203     theOuputIDSArray->Delete();
204   }
205 }
206
207 vtkStandardNewMacro(VISU_CommonCellsFilter);
208
209 VISU_CommonCellsFilter
210 ::VISU_CommonCellsFilter()
211 {}
212
213 VISU_CommonCellsFilter
214 ::~VISU_CommonCellsFilter()
215 {}
216
217 void
218 VISU_CommonCellsFilter
219 ::SetProfileUG(vtkUnstructuredGrid *input)
220 {
221   this->SetInput(input);
222 }
223
224 vtkUnstructuredGrid*
225 VISU_CommonCellsFilter
226 ::GetProfileUG()
227 {
228   return dynamic_cast<vtkUnstructuredGrid*>(this->GetInput());
229 }
230
231 void
232 VISU_CommonCellsFilter
233 ::SetCellsUG(vtkUnstructuredGrid *input)
234 {
235   this->vtkProcessObject::SetNthInput(1, input);
236 }
237
238 vtkUnstructuredGrid*
239 VISU_CommonCellsFilter
240 ::GetCellsUG()
241 {
242   if (this->NumberOfInputs < 2)
243   {
244     return NULL;
245   }
246   return dynamic_cast<vtkUnstructuredGrid*>(this->Inputs[1]);
247 }
248
249 void
250 VISU_CommonCellsFilter
251 ::Execute()
252 {
253   VISU::TTimerLog aTimerLog(MYDEBUG,"VISU_CommonCellsFilter::Execute");
254   vtkUnstructuredGrid* anInputProfileUG = this->GetProfileUG();
255   vtkUnstructuredGrid* anInputCellsUG   = this->GetCellsUG();
256
257   vtkUnstructuredGrid* anOutput         = this->GetOutput();
258   
259   if(anInputCellsUG == NULL){
260     anOutput->ShallowCopy(anInputProfileUG);
261   }
262   else{
263     // check if anInputProfileUG already have cells types not equal VTK_VERTEX
264     vtkCellTypes* aCellTypes = vtkCellTypes::New();
265
266     anInputProfileUG->GetCellTypes(aCellTypes);
267     if(aCellTypes){
268       if (aCellTypes->GetNumberOfTypes()!=1 )
269         anOutput->ShallowCopy(anInputProfileUG);
270       else{
271         if(aCellTypes->GetCellType(0) != VTK_VERTEX)
272           anOutput->DeepCopy(anInputProfileUG);
273         else{
274
275           vtkCellData* aInputCellData = anInputProfileUG->GetCellData();
276
277           //
278           // Calculate output points
279           //
280           vtkIdList* aPointIdsForCopy = vtkIdList::New();
281           vtkPoints* aOutputPointSet = vtkPoints::New();
282           TId2IdMap  aOldId2NewIdPointsMap;
283           
284           aOutputPointSet->Reset();
285           
286           vtkIntArray* aPointIDS =
287             dynamic_cast<vtkIntArray*>(aInputCellData->GetArray("VISU_CELLS_MAPPER"));
288           if(aPointIDS){
289             int* aPtr = aPointIDS->GetPointer(0);
290             aPointIdsForCopy->SetNumberOfIds(aPointIDS->GetNumberOfTuples());
291             for(int i=0;i<aPointIDS->GetNumberOfTuples();i++){
292               aPointIdsForCopy->SetId(i,*aPtr);
293               aPtr++;aPtr++;
294             }
295             aOutputPointSet->SetNumberOfPoints(aPointIdsForCopy->GetNumberOfIds());
296             // aOutputPointSet copy points from anInputProfileUG to aOutputPointSet, which
297             // in aPointIdsForCopy ids list
298             anInputProfileUG->GetPoints()->GetPoints(aPointIdsForCopy,aOutputPointSet);
299             for(int i=0;i<aPointIdsForCopy->GetNumberOfIds();i++)
300               aOldId2NewIdPointsMap[aPointIdsForCopy->GetId(i)] = i;
301             anOutput->SetPoints(aOutputPointSet);
302           }
303           aOutputPointSet->Delete();
304           // applay scalar,vector,normal,tensor ... values
305           anOutput->GetPointData()->CopyFieldOff("VISU_CELLS_MAPPER");
306           anOutput->GetPointData()->CopyFieldOff("VISU_POINTS_MAPPER");
307           anOutput->GetPointData()->PassData(aInputCellData);
308           //anOutput->GetPointData()->GetArray("VISU_CELLS_MAPPER")->SetName("VISU_POINTS_MAPPER");
309
310           // apply VISU_POINTS_MAPPER
311           int anEntity = int(VISU::NODE_ENTITY);
312           vtkIntArray*  aNewPointsIdsArray = vtkIntArray::New();
313           aNewPointsIdsArray->SetName("VISU_POINTS_MAPPER");
314           aNewPointsIdsArray->SetNumberOfComponents(2);
315           aNewPointsIdsArray->SetNumberOfTuples(aPointIdsForCopy->GetNumberOfIds());
316           int *aPtr = aNewPointsIdsArray->GetPointer(0);
317           for(int i = 0; i < aPointIdsForCopy->GetNumberOfIds(); i++){
318             *aPtr++ = aPointIdsForCopy->GetId(i);
319             *aPtr++ = anEntity;
320           }
321           anOutput->GetPointData()->AddArray(aNewPointsIdsArray);
322
323           
324             
325           aNewPointsIdsArray->Delete();
326           
327           
328           // Calculate output cells
329           int nbCells=0;
330
331           TSortedArrayOne aCellIdsForCopy;
332           
333           GetIdsForCopy(anInputCellsUG,aPointIDS,aCellIdsForCopy);
334           nbCells = aCellIdsForCopy.size();
335
336           // copy cells to output
337           int aAllocMem = nbCells;
338           anOutput->Allocate(aAllocMem);
339
340           if(nbCells>0 && anInputCellsUG)
341             CopyElementsToOutput(anInputCellsUG,
342                                  nbCells,
343                                  aCellIdsForCopy,
344                                  aOldId2NewIdPointsMap,
345                                  anOutput);
346           
347           
348           aPointIdsForCopy->Delete();
349         }
350       }
351       
352     }
353     else
354       anOutput->ShallowCopy(anInputProfileUG);
355   }
356 }