Salome HOME
cc08f7bad5cde73056b702718d49a6daf9d11e55
[modules/gui.git] / src / VTKViewer / VTKViewer_AppendFilter.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SALOME OBJECT : kernel of SALOME component
24 //  File   : VTKViewer_GeometryFilter.cxx
25 //  Author : 
26
27 #include "VTKViewer_AppendFilter.h"
28
29 #include <vtkCell.h>
30 #include <vtkCellData.h>
31 #include <vtkDataSetAttributes.h>
32 #include <vtkDataSetCollection.h>
33 #include <vtkObjectFactory.h>
34 #include <vtkPointData.h>
35 #include <vtkUnstructuredGrid.h>
36 #include <vtkInformation.h>
37 #include <vtkInformationVector.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 ::SetSharedPointsDataSet(vtkPointSet* thePointsDataSet)
82 {
83   if(GetSharedPointsDataSet() == thePointsDataSet)
84     return;
85
86   mySharedPointsDataSet = thePointsDataSet;
87
88   Modified();
89 }
90
91 vtkPointSet*
92 VTKViewer_AppendFilter
93 ::GetSharedPointsDataSet()
94 {
95   return mySharedPointsDataSet.GetPointer();
96 }
97
98 int
99 VTKViewer_AppendFilter
100 ::RequestData(
101               vtkInformation *request,
102               vtkInformationVector **inputVector,
103               vtkInformationVector *outputVector)
104 {
105   int aRet = 0;
106   if(GetSharedPointsDataSet())
107     aRet = MakeOutput(request,inputVector,outputVector);
108   else
109     aRet = Superclass::RequestData(request,inputVector,outputVector);
110
111   if(myDoMappingFlag)
112     DoMapping();
113   
114   return aRet;
115 }
116
117
118 void 
119 VTKViewer_AppendFilter
120 ::DoMapping()
121 {
122   myNodeRanges.clear();
123   myCellRanges.clear();
124
125   vtkIdType aPntStartId = 0;
126   vtkIdType aCellStartId = 0;
127
128   for(vtkIdType aDataSetId = 0; aDataSetId < this->GetNumberOfInputPorts(); ++aDataSetId){
129     vtkDataSet* aDataSet = (vtkDataSet *)(this->GetInput(aDataSetId));
130     // Do mapping of the nodes
131     if(!GetSharedPointsDataSet()){
132       vtkIdType aNbPnts = aDataSet->GetNumberOfPoints();
133       myNodeRanges.push_back(aPntStartId + aNbPnts);
134       aPntStartId += aNbPnts;
135     }
136     // Do mapping of the cells
137     vtkIdType aNbCells = aDataSet->GetNumberOfCells();
138     myCellRanges.push_back(aCellStartId + aNbCells);
139     aCellStartId += aNbCells;
140   }
141 }
142
143 namespace
144 {
145   inline
146   vtkIdType
147   GetOutputID(vtkIdType theInputID,
148               vtkIdType theInputDataSetID,
149               const VTKViewer_AppendFilter::TVectorIds& theRanges)
150   {
151     theInputID = theInputDataSetID = -1;
152
153     vtkIdType aNbInputs = theRanges.size();
154     if(theInputDataSetID < 0 || theInputDataSetID >= aNbInputs)
155       return -1;
156     
157     vtkIdType aStartId = theRanges[theInputDataSetID];
158     return aStartId + theInputID;
159   }
160 }
161
162 vtkIdType
163 VTKViewer_AppendFilter
164 ::GetPointOutputID(vtkIdType theInputID,
165                    vtkIdType theInputDataSetID)
166 {
167   if(GetSharedPointsDataSet())
168     return theInputID;
169
170   return GetOutputID(theInputID,theInputDataSetID,myNodeRanges);
171 }
172
173
174 vtkIdType 
175 VTKViewer_AppendFilter
176 ::GetCellOutputID(vtkIdType theInputID,
177                    vtkIdType theInputDataSetID)
178 {
179   if(GetSharedPointsDataSet())
180     return theInputID;
181
182   return GetOutputID(theInputID,theInputDataSetID,myCellRanges);
183 }
184
185
186 namespace
187 {
188   void
189   GetInputID(vtkIdType theOutputID,
190              vtkIdType& theInputID,
191              vtkIdType& theStartID,
192              vtkIdType& theInputDataSetID,
193              const VTKViewer_AppendFilter::TVectorIds& theRanges)
194   {
195     theInputID = theStartID = theInputDataSetID = -1;
196
197     if(theRanges.empty())
198       return;
199
200     const vtkIdType& aRangeEnd = theRanges.back();
201     if(theOutputID < 0 ||  theOutputID >= aRangeEnd)
202       return;
203
204     vtkIdType aStartId = 0;
205     vtkIdType aNbInputs = theRanges.size();
206     for(vtkIdType aDataSetId = 0; aDataSetId < aNbInputs; ++aDataSetId){
207       vtkIdType aRange = theRanges[aDataSetId];
208       if(aRange > theOutputID){
209         theInputID = theOutputID - aStartId;
210         theInputDataSetID = aDataSetId;
211         theStartID = aStartId;
212         break;
213       }
214       aStartId = aRange;
215     }
216   }
217 }
218
219 void 
220 VTKViewer_AppendFilter
221 ::GetPointInputID(vtkIdType theOutputID,
222                   vtkIdType& theInputID,
223                   vtkIdType& theStartID,
224                   vtkIdType& theInputDataSetID)
225 {
226   if(GetSharedPointsDataSet()) {
227     theStartID = theInputDataSetID = 0;
228     theInputID = theOutputID;
229     return;
230   }
231
232   ::GetInputID(theOutputID,
233                theInputID,
234                theStartID,
235                theInputDataSetID,
236                myNodeRanges);
237 }
238
239
240 void
241 VTKViewer_AppendFilter
242 ::GetCellInputID(vtkIdType theOutputID,
243                  vtkIdType& theInputID,
244                  vtkIdType& theStartID,
245                  vtkIdType& theInputDataSetID)
246 {
247   ::GetInputID(theOutputID,
248                theInputID,
249                theStartID,
250                theInputDataSetID,
251                myCellRanges);
252 }
253
254
255 int
256 VTKViewer_AppendFilter
257 ::MakeOutput(
258   vtkInformation *vtkNotUsed(request),
259   vtkInformationVector **inputVector,
260   vtkInformationVector *outputVector)
261 {
262   int idx;
263   vtkIdType numPts, numCells, cellId;
264   // vtkCellData *cd;
265   vtkIdList *ptIds;
266   vtkDataSet *ds;
267   int numInputs = this->GetNumberOfInputConnections(0);
268   
269   // get the output info object
270   vtkInformation *outInfo = outputVector->GetInformationObject(0);
271
272   // get the ouptut
273   vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
274     outInfo->Get(vtkDataObject::DATA_OBJECT()));
275   //
276   numPts = mySharedPointsDataSet->GetNumberOfPoints();
277   if (numPts < 1) {
278     return 0;
279   }
280   //
281   numCells = 0;
282   vtkInformation *inInfo = 0;
283   for (idx = 0; idx < numInputs;++idx) {
284     inInfo = inputVector[0]->GetInformationObject(idx);
285     ds = 0;
286     if (inInfo)
287       {
288       ds = vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
289       }
290     if (ds != NULL)  {
291       if ( ds->GetNumberOfPoints() <= 0 && ds->GetNumberOfCells() <= 0 )  {
292         continue; //no input, just skip
293       }
294       numCells += ds->GetNumberOfCells();
295     }//if non-empty dataset
296   }//for all inputs
297   if (numCells < 1) {
298     return 0;
299   }
300   //
301   // Now can allocate memory
302   output->Allocate(numCells); 
303   ptIds = vtkIdList::New(); 
304   ptIds->Allocate(VTK_CELL_SIZE);
305   //
306   // Append each input dataset together
307   //
308   // 1.points
309   output->SetPoints(GetSharedPointsDataSet()->GetPoints());
310   output->GetPointData()->PassData(GetSharedPointsDataSet()->GetPointData());
311   // 2.cells
312   for (idx = 0; idx < numInputs; ++idx) {
313     inInfo = inputVector[0]->GetInformationObject(idx);
314     ds = 0;
315     if (inInfo)
316       {
317       ds = vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
318       }
319     if (ds != NULL) {
320       
321       numCells = ds->GetNumberOfCells(); 
322       // cd = ds->GetCellData();
323       // copy cell and cell data
324       for (cellId=0; cellId<numCells; cellId++)  {
325         ds->GetCellPoints(cellId, ptIds);
326         output->InsertNextCell(ds->GetCellType(cellId), ptIds);
327       }
328     }
329   }
330   //
331   ptIds->Delete();
332   return 1;
333 }
334
335 int VTKViewer_AppendFilter::FillInputPortInformation(int, vtkInformation *info)
336 {
337   info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
338   info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
339   return 1;
340 }