Salome HOME
4e1c400e8109795664dda73184d9b89ada02351e
[modules/gui.git] / src / VTKViewer / VTKViewer_AppendFilter.cxx
1 // Copyright (C) 2007-2023  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, or (at your option) any later version.
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 vtkStandardNewMacro(VTKViewer_AppendFilter)
48
49 VTKViewer_AppendFilter
50 ::VTKViewer_AppendFilter() 
51 {
52   myDoMappingFlag = false;
53 }
54
55 VTKViewer_AppendFilter
56 ::~VTKViewer_AppendFilter()
57 {}
58
59 void
60 VTKViewer_AppendFilter
61 ::SetDoMappingFlag(const bool theFlag)
62 {
63   if(myDoMappingFlag == theFlag)
64     return;
65
66   myDoMappingFlag = theFlag;
67
68   this->Modified();
69 }
70
71 bool 
72 VTKViewer_AppendFilter
73 ::DoMappingFlag() const
74 {
75   return myDoMappingFlag;
76 }
77
78 void
79 VTKViewer_AppendFilter
80 ::SetSharedPointsDataSet(vtkPointSet* thePointsDataSet)
81 {
82   if(GetSharedPointsDataSet() == thePointsDataSet)
83     return;
84
85   mySharedPointsDataSet = thePointsDataSet;
86
87   Modified();
88 }
89
90 vtkPointSet*
91 VTKViewer_AppendFilter
92 ::GetSharedPointsDataSet()
93 {
94   return mySharedPointsDataSet.GetPointer();
95 }
96
97 int
98 VTKViewer_AppendFilter
99 ::RequestData(
100               vtkInformation *request,
101               vtkInformationVector **inputVector,
102               vtkInformationVector *outputVector)
103 {
104   int aRet = 0;
105   if(GetSharedPointsDataSet())
106     aRet = MakeOutput(request,inputVector,outputVector);
107   else
108     aRet = Superclass::RequestData(request,inputVector,outputVector);
109
110   if(myDoMappingFlag)
111     DoMapping();
112   
113   return aRet;
114 }
115
116
117 void 
118 VTKViewer_AppendFilter
119 ::DoMapping()
120 {
121   myNodeRanges.clear();
122   myCellRanges.clear();
123
124   vtkIdType aPntStartId = 0;
125   vtkIdType aCellStartId = 0;
126
127   for(vtkIdType aDataSetId = 0; aDataSetId < this->GetNumberOfInputPorts(); ++aDataSetId){
128     vtkDataSet* aDataSet = (vtkDataSet *)(this->GetInput(aDataSetId));
129     // Do mapping of the nodes
130     if(!GetSharedPointsDataSet()){
131       vtkIdType aNbPnts = aDataSet->GetNumberOfPoints();
132       myNodeRanges.push_back(aPntStartId + aNbPnts);
133       aPntStartId += aNbPnts;
134     }
135     // Do mapping of the cells
136     vtkIdType aNbCells = aDataSet->GetNumberOfCells();
137     myCellRanges.push_back(aCellStartId + aNbCells);
138     aCellStartId += aNbCells;
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 = (vtkIdType)theRanges.size(); //!< TODO: conversion from size_t to vtkIdType
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(GetSharedPointsDataSet())
167     return theInputID;
168
169   return GetOutputID(theInputID,theInputDataSetID,myNodeRanges);
170 }
171
172
173 vtkIdType 
174 VTKViewer_AppendFilter
175 ::GetCellOutputID(vtkIdType theInputID,
176                    vtkIdType theInputDataSetID)
177 {
178   if(GetSharedPointsDataSet())
179     return theInputID;
180
181   return GetOutputID(theInputID,theInputDataSetID,myCellRanges);
182 }
183
184
185 namespace
186 {
187   void
188   GetInputID(vtkIdType theOutputID,
189              vtkIdType& theInputID,
190              vtkIdType& theStartID,
191              vtkIdType& theInputDataSetID,
192              const VTKViewer_AppendFilter::TVectorIds& theRanges)
193   {
194     theInputID = theStartID = theInputDataSetID = -1;
195
196     if(theRanges.empty())
197       return;
198
199     const vtkIdType& aRangeEnd = theRanges.back();
200     if(theOutputID < 0 ||  theOutputID >= aRangeEnd)
201       return;
202
203     vtkIdType aStartId = 0;
204     vtkIdType aNbInputs = (vtkIdType)theRanges.size(); //!< TODO: conversion from size_t to vtkIdType
205     for(vtkIdType aDataSetId = 0; aDataSetId < aNbInputs; ++aDataSetId){
206       vtkIdType aRange = theRanges[aDataSetId];
207       if(aRange > theOutputID){
208         theInputID = theOutputID - aStartId;
209         theInputDataSetID = aDataSetId;
210         theStartID = aStartId;
211         break;
212       }
213       aStartId = aRange;
214     }
215   }
216 }
217
218 void 
219 VTKViewer_AppendFilter
220 ::GetPointInputID(vtkIdType theOutputID,
221                   vtkIdType& theInputID,
222                   vtkIdType& theStartID,
223                   vtkIdType& theInputDataSetID)
224 {
225   if(GetSharedPointsDataSet()) {
226     theStartID = theInputDataSetID = 0;
227     theInputID = theOutputID;
228     return;
229   }
230
231   ::GetInputID(theOutputID,
232                theInputID,
233                theStartID,
234                theInputDataSetID,
235                myNodeRanges);
236 }
237
238
239 void
240 VTKViewer_AppendFilter
241 ::GetCellInputID(vtkIdType theOutputID,
242                  vtkIdType& theInputID,
243                  vtkIdType& theStartID,
244                  vtkIdType& theInputDataSetID)
245 {
246   ::GetInputID(theOutputID,
247                theInputID,
248                theStartID,
249                theInputDataSetID,
250                myCellRanges);
251 }
252
253
254 int
255 VTKViewer_AppendFilter
256 ::MakeOutput(
257   vtkInformation *vtkNotUsed(request),
258   vtkInformationVector **inputVector,
259   vtkInformationVector *outputVector)
260 {
261   int idx;
262   vtkIdType numPts, numCells, cellId;
263   // vtkCellData *cd;
264   vtkIdList *ptIds;
265   vtkDataSet *ds;
266   int numInputs = this->GetNumberOfInputConnections(0);
267   
268   // get the output info object
269   vtkInformation *outInfo = outputVector->GetInformationObject(0);
270
271   // get the ouptut
272   vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
273     outInfo->Get(vtkDataObject::DATA_OBJECT()));
274   //
275   numPts = mySharedPointsDataSet->GetNumberOfPoints();
276   if (numPts < 1) {
277     return 0;
278   }
279   //
280   numCells = 0;
281   vtkInformation *inInfo = 0;
282   for (idx = 0; idx < numInputs;++idx) {
283     inInfo = inputVector[0]->GetInformationObject(idx);
284     ds = 0;
285     if (inInfo)
286       {
287       ds = vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
288       }
289     if (ds != NULL)  {
290       if ( ds->GetNumberOfPoints() <= 0 && ds->GetNumberOfCells() <= 0 )  {
291         continue; //no input, just skip
292       }
293       numCells += ds->GetNumberOfCells();
294     }//if non-empty dataset
295   }//for all inputs
296   if (numCells < 1) {
297     return 0;
298   }
299   //
300   // Now can allocate memory
301   output->Allocate(numCells); 
302   ptIds = vtkIdList::New(); 
303   ptIds->Allocate(VTK_CELL_SIZE);
304   //
305   // Append each input dataset together
306   //
307   // 1.points
308   output->SetPoints(GetSharedPointsDataSet()->GetPoints());
309   output->GetPointData()->PassData(GetSharedPointsDataSet()->GetPointData());
310   // 2.cells
311   for (idx = 0; idx < numInputs; ++idx) {
312     inInfo = inputVector[0]->GetInformationObject(idx);
313     ds = 0;
314     if (inInfo)
315       {
316       ds = vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
317       }
318     if (ds != NULL) {
319       
320       numCells = ds->GetNumberOfCells(); 
321       // cd = ds->GetCellData();
322       // copy cell and cell data
323       for (cellId=0; cellId<numCells; cellId++)  {
324         ds->GetCellPoints(cellId, ptIds);
325         output->InsertNextCell(ds->GetCellType(cellId), ptIds);
326       }
327     }
328   }
329   //
330   ptIds->Delete();
331   return 1;
332 }
333
334 int VTKViewer_AppendFilter::FillInputPortInformation(int, vtkInformation *info)
335 {
336   info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
337   info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
338   return 1;
339 }