Salome HOME
Join modifications from branch OCC_development_for_3_2_0a2
[modules/gui.git] / src / VTKViewer / VTKViewer_AppendFilter.cxx
1 //  SALOME OBJECT : kernel of SALOME component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : VTKViewer_GeometryFilter.cxx
25 //  Author : 
26 //  Module : SALOME
27 //  $Header$
28
29 #include "VTKViewer_AppendFilter.h"
30
31 #include <vtkCell.h>
32 #include <vtkCellData.h>
33 #include <vtkDataSetAttributes.h>
34 #include <vtkDataSetCollection.h>
35 #include <vtkObjectFactory.h>
36 #include <vtkPointData.h>
37 #include <vtkUnstructuredGrid.h>
38
39 #include <vtkPoints.h>
40
41 #if defined __GNUC__
42   #if __GNUC__ == 2
43     #define __GNUC_2__
44   #endif
45 #endif
46
47 vtkCxxRevisionMacro(VTKViewer_AppendFilter, "$Revision$");
48 vtkStandardNewMacro(VTKViewer_AppendFilter);
49
50 VTKViewer_AppendFilter
51 ::VTKViewer_AppendFilter() 
52 {
53   myDoMappingFlag = false;
54 }
55
56 VTKViewer_AppendFilter
57 ::~VTKViewer_AppendFilter()
58 {}
59
60 void
61 VTKViewer_AppendFilter
62 ::SetDoMappingFlag(const bool theFlag)
63 {
64   if(myDoMappingFlag == theFlag)
65     return;
66
67   myDoMappingFlag = theFlag;
68
69   this->Modified();
70 }
71
72 bool 
73 VTKViewer_AppendFilter
74 ::DoMappingFlag() const
75 {
76   return myDoMappingFlag;
77 }
78
79 void
80 VTKViewer_AppendFilter
81 ::SetPoints(vtkPoints* thePoints)
82 {
83   if(GetPoints() == thePoints)
84     return;
85
86   myPoints = thePoints;
87
88   this->Modified();
89 }
90
91 vtkPoints*
92 VTKViewer_AppendFilter
93 ::GetPoints()
94 {
95   return myPoints.GetPointer();
96 }
97
98 void
99 VTKViewer_AppendFilter
100 ::Execute()
101 {
102   if(myPoints.GetPointer())
103     MakeOutput();
104   else
105     Superclass::Execute();
106
107   if(myDoMappingFlag)
108     DoMapping();
109 }
110
111
112 //==================================================================
113 // function: DoMapping
114 // purpose :
115 //==================================================================
116 void 
117 VTKViewer_AppendFilter
118 ::DoMapping()
119 {
120   myNodeRanges.clear();
121   myCellRanges.clear();
122
123   vtkIdType aPntStartId = 0;
124   vtkIdType aCellStartId = 0;
125
126   for(vtkIdType aDataSetId = 0; aDataSetId < this->NumberOfInputs; ++aDataSetId){
127     vtkDataSet* aDataSet = (vtkDataSet *)(this->Inputs[aDataSetId]);
128     // Do mapping of the nodes
129     if(!myPoints.GetPointer()){
130       vtkIdType aNbPnts = aDataSet->GetNumberOfPoints();
131       myNodeRanges.push_back(aPntStartId + aNbPnts);
132       aPntStartId += aNbPnts;
133     }
134     // Do mapping of the cells
135     vtkIdType aNbCells = aDataSet->GetNumberOfCells();
136     myCellRanges.push_back(aCellStartId + aNbCells);
137     aCellStartId += aNbCells;
138   }
139 }
140
141 //---------------------------------------------------------------
142 namespace
143 {
144   inline
145   vtkIdType
146   GetOutputID(vtkIdType theInputID,
147               vtkIdType theInputDataSetID,
148               const VTKViewer_AppendFilter::TVectorIds& theRanges)
149   {
150     theInputID = theInputDataSetID = -1;
151
152     vtkIdType aNbInputs = theRanges.size();
153     if(theInputDataSetID < 0 || theInputDataSetID >= aNbInputs)
154       return -1;
155     
156     vtkIdType aStartId = theRanges[theInputDataSetID];
157     return aStartId + theInputID;
158   }
159 }
160
161 vtkIdType
162 VTKViewer_AppendFilter
163 ::GetPointOutputID(vtkIdType theInputID,
164                    vtkIdType theInputDataSetID)
165 {
166   if(myPoints.GetPointer())
167     return theInputID;
168
169   return GetOutputID(theInputID,theInputDataSetID,myNodeRanges);
170 }
171
172
173 //---------------------------------------------------------------
174 vtkIdType 
175 VTKViewer_AppendFilter
176 ::GetCellOutputID(vtkIdType theInputID,
177                    vtkIdType theInputDataSetID)
178 {
179   if(myPoints.GetPointer())
180     return theInputID;
181
182   return GetOutputID(theInputID,theInputDataSetID,myCellRanges);
183 }
184
185
186 //---------------------------------------------------------------
187 namespace
188 {
189   void
190   GetInputID(vtkIdType theOutputID,
191              vtkIdType& theInputID,
192              vtkIdType& theStartID,
193              vtkIdType& theInputDataSetID,
194              const VTKViewer_AppendFilter::TVectorIds& theRanges)
195   {
196     theInputID = theStartID = theInputDataSetID = -1;
197
198     if(theRanges.empty())
199       return;
200
201     const vtkIdType& aRangeEnd = theRanges.back();
202     if(theOutputID < 0 ||  theOutputID >= aRangeEnd)
203       return;
204
205     vtkIdType aStartId = 0;
206     vtkIdType aNbInputs = theRanges.size();
207     for(vtkIdType aDataSetId = 0; aDataSetId < aNbInputs; ++aDataSetId){
208       vtkIdType aRange = theRanges[aDataSetId];
209       if(aRange > theOutputID){
210         theInputID = theOutputID - aStartId;
211         theInputDataSetID = aDataSetId;
212         theStartID = aStartId;
213         break;
214       }
215       aStartId = aRange;
216     }
217   }
218 }
219
220 void 
221 VTKViewer_AppendFilter
222 ::GetPointInputID(vtkIdType theOutputID,
223                   vtkIdType& theInputID,
224                   vtkIdType& theStartID,
225                   vtkIdType& theInputDataSetID)
226 {
227   if(myPoints.GetPointer()) {
228     theStartID = theInputDataSetID = 0;
229     theInputID = theOutputID;
230     return;
231   }
232
233   ::GetInputID(theOutputID,
234                theInputID,
235                theStartID,
236                theInputDataSetID,
237                myNodeRanges);
238 }
239
240
241 //---------------------------------------------------------------
242 void
243 VTKViewer_AppendFilter
244 ::GetCellInputID(vtkIdType theOutputID,
245                  vtkIdType& theInputID,
246                  vtkIdType& theStartID,
247                  vtkIdType& theInputDataSetID)
248 {
249   ::GetInputID(theOutputID,
250                theInputID,
251                theStartID,
252                theInputDataSetID,
253                myCellRanges);
254 }
255
256
257 //---------------------------------------------------------------
258 void 
259 VTKViewer_AppendFilter
260 ::MakeOutput()
261 {
262   int idx;
263   vtkIdType numPts, numCells, newCellId, cellId;
264   vtkCellData *cd;
265   vtkIdList *ptIds;
266   vtkDataSet *ds;
267   vtkUnstructuredGrid *output = this->GetOutput();
268   //
269   numPts = myPoints->GetNumberOfPoints();
270   if (numPts < 1) {
271     return;
272   }
273   //
274   numCells = 0;
275   for (idx = 0; idx < this->NumberOfInputs; ++idx) {
276     ds = (vtkDataSet *)(this->Inputs[idx]);
277     if (ds != NULL)  {
278       if ( ds->GetNumberOfPoints() <= 0 && ds->GetNumberOfCells() <= 0 )  {
279         continue; //no input, just skip
280       }
281       numCells += ds->GetNumberOfCells();
282     }//if non-empty dataset
283   }//for all inputs
284   if (numCells < 1) {
285     return;
286   }
287   //
288   // Now can allocate memory
289   output->Allocate(numCells); 
290   ptIds = vtkIdList::New(); 
291   ptIds->Allocate(VTK_CELL_SIZE);
292   //
293   // Append each input dataset together
294   //
295   // 1.points
296   output->SetPoints(myPoints.GetPointer());
297   // 2.cells
298   for (idx = 0; idx < this->NumberOfInputs; ++idx) {
299     ds = (vtkDataSet *)(this->Inputs[idx]);
300     if (ds != NULL) {
301       numCells = ds->GetNumberOfCells(); 
302       cd = ds->GetCellData();
303       // copy cell and cell data
304       for (cellId=0; cellId<numCells; cellId++)  {
305         ds->GetCellPoints(cellId, ptIds);
306         newCellId = output->InsertNextCell(ds->GetCellType(cellId), ptIds);
307       }
308     }
309   }
310   //
311   ptIds->Delete();
312 }
313