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