1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // SALOME OBJECT : kernel of SALOME component
21 // File : VISU_GeometryFilter.cxx
26 #include "VISU_AppendFilterUtilities.hxx"
27 #include "VISU_ConvertorUtils.hxx"
30 #include <vtkCellData.h>
31 #include <vtkPointData.h>
33 #include <vtkDataSetCollection.h>
34 #include <vtkObjectFactory.h>
36 #include <vtkUnstructuredGrid.h>
37 #include <vtkPolyData.h>
39 #include <vtkInformationVector.h>
40 #include <vtkInformation.h>
41 #include <vtkExecutive.h>
43 #include <vtkPoints.h>
44 #include <vtkIntArray.h>
52 //---------------------------------------------------------------
53 typedef vtkIdType TCellId;
54 typedef vtkIdType TInputId;
55 typedef std::pair<TInputId, TCellId> TInputCellId;
57 typedef std::pair<vtkIdType, vtkIdType> TObjectId;
58 typedef std::map<TObjectId, TInputCellId> TObject2InputIdMap;
61 //---------------------------------------------------------------
63 DoMergingInputs(vtkCellData *theCellData,
65 TObject2InputIdMap& theResult)
67 if(vtkDataArray *aDataArray = theCellData->GetArray("VISU_CELLS_MAPPER")){
68 if(vtkIntArray *anIntArray = dynamic_cast<vtkIntArray*>(aDataArray)){
69 int *aPointer = anIntArray->GetPointer(0);
70 int aNbCells = anIntArray->GetNumberOfTuples();
71 for(vtkIdType aCellId = 0; aCellId < aNbCells; aCellId++){
72 int aObjId = *aPointer++;
73 int anEntity = *aPointer++;
74 TObjectId anObjectId(aObjId, anEntity);
75 TObject2InputIdMap::iterator anIter = theResult.find(anObjectId);
76 if(anIter != theResult.end())
78 TInputCellId anInputCellId(theInputId, aCellId);
79 theResult.insert(anIter, TObject2InputIdMap::value_type(anObjectId, anInputCellId));
86 //---------------------------------------------------------------
89 vtkDataSetAttributes::FieldList myFieldList;
90 bool myIsFirstCellData;
92 TFillFieldList(vtkIdType theNbInputs):
93 myFieldList(theNbInputs),
94 myIsFirstCellData(true)
98 operator()(TInputId theInputId, vtkDataSet* theDataSet)
100 vtkCellData *aCellData = theDataSet->GetCellData();
101 if(myIsFirstCellData){
102 myFieldList.InitializeFieldList(aCellData);
103 myIsFirstCellData = false;
105 myFieldList.IntersectFieldList(aCellData);
111 GetNbCells() const = 0;
115 //---------------------------------------------------------------
116 struct TCellCounter: TFillFieldList
120 TCellCounter(vtkIdType theNbInputs):
121 TFillFieldList(theNbInputs),
126 operator()(TInputId theInputId, vtkDataSet* theDataSet)
128 TFillFieldList::operator()(theInputId, theDataSet);
129 myNbCells += theDataSet->GetNumberOfCells();
141 //---------------------------------------------------------------
142 struct TCellIdMerger: TFillFieldList
144 TObject2InputIdMap myObject2InputIdMap;
146 TCellIdMerger(vtkIdType theNbInputs):
147 TFillFieldList(theNbInputs)
151 operator()(TInputId theInputId, vtkDataSet* theDataSet)
153 TFillFieldList::operator()(theInputId, theDataSet);
154 vtkCellData *aCellData = theDataSet->GetCellData();
155 DoMergingInputs(aCellData, theInputId, myObject2InputIdMap);
162 return myObject2InputIdMap.size();
167 //---------------------------------------------------------------
168 template<class TFunctor>
170 ForEachInput(vtkInformationVector **theInputVector,
171 vtkIdType theNumberOfInputConnections,
172 TFunctor& theFunctor)
174 for(vtkIdType anInputId = 0; anInputId < theNumberOfInputConnections; anInputId++)
175 if(vtkDataSet *aDataSet = VISU::GetInput(theInputVector, anInputId))
176 if(aDataSet->GetNumberOfPoints() > 0 && aDataSet->GetNumberOfCells() > 0)
177 theFunctor(anInputId, aDataSet);
181 //---------------------------------------------------------------
182 template<class TDataSet>
184 RequestData(vtkInformationVector **theInputVector,
185 vtkIdType theNumberOfInputConnections,
186 vtkInformationVector *theOutputVector,
187 vtkPointSet* theSharedPointSet,
188 bool theIsMergingInputs,
189 bool theIsMappingInputs)
191 if ( theNumberOfInputConnections == 1 ) {
192 // get the input and ouptut
193 vtkDataSet *anInput = VISU::GetInput( theInputVector, 0 );
194 vtkDataSet* anOutput = VISU::GetOutput( theOutputVector );
196 if ( anInput->GetDataObjectType() != anOutput->GetDataObjectType() )
199 // This has to be here because it initialized all field datas.
200 anOutput->CopyStructure( anInput );
202 // Pass all. (data object's field data is passed by the
203 // superclass after this method)
204 anOutput->GetPointData()->PassData( anInput->GetPointData() );
205 anOutput->GetCellData()->PassData( anInput->GetCellData() );
210 if ( theSharedPointSet ) {
211 vtkPoints* aPoints = theSharedPointSet->GetPoints();
212 if(aPoints->GetNumberOfPoints() < 1)
215 TDataSet* anOutput = TDataSet::SafeDownCast(VISU::GetOutput(theOutputVector));
216 vtkIdType anNbInputs = theNumberOfInputConnections;
217 if ( theIsMergingInputs ) {
218 TCellIdMerger aFunctor(anNbInputs);
219 ForEachInput<TCellIdMerger>(theInputVector, anNbInputs, aFunctor);
221 vtkDataSetAttributes::FieldList& aFieldList = aFunctor.myFieldList;
222 TObject2InputIdMap& anObject2InputIdMap = aFunctor.myObject2InputIdMap;
223 vtkIdType aNbCells = aFunctor.GetNbCells();
227 // Now can allocate memory
228 anOutput->Allocate(aNbCells);
229 vtkCellData *anOutputCellData = anOutput->GetCellData();
230 anOutputCellData->CopyAllocate(aFieldList, aNbCells);
232 // Append each input dataset together
234 anOutput->SetPoints(theSharedPointSet->GetPoints());
235 anOutput->GetPointData()->PassData(theSharedPointSet->GetPointData());
238 vtkIdList *anIdList = vtkIdList::New();
239 anIdList->Allocate(VTK_CELL_SIZE);
240 TObject2InputIdMap::const_iterator anIter = anObject2InputIdMap.begin();
241 TObject2InputIdMap::const_iterator anEndIter = anObject2InputIdMap.end();
242 for(; anIter != anEndIter; anIter++){
243 //TObjectId anObjectId = anIter->first;
244 const TInputCellId& anInputCellId = anIter->second;
245 TInputId anInputId = anInputCellId.first;
246 if(vtkDataSet *aDataSet = VISU::GetInput(theInputVector, anInputId)){
247 TCellId aCellId = anInputCellId.second;
248 aDataSet->GetCellPoints(aCellId, anIdList);
250 vtkIdType aCellType = aDataSet->GetCellType(aCellId);
251 vtkIdType aNewCellId = anOutput->InsertNextCell(aCellType, anIdList);
253 vtkCellData *aCellData = aDataSet->GetCellData();
254 anOutputCellData->CopyData(aFieldList, aCellData, anInputId, aCellId, aNewCellId);
259 if(theIsMappingInputs){
260 vtkIntArray *aDataArray = vtkIntArray::New();
261 aDataArray->SetName("VISU_INPUTS_MAPPER");
262 aDataArray->SetNumberOfComponents(2);
263 aDataArray->SetNumberOfTuples(aNbCells);
265 vtkIdType aTupleId = 0;
266 TObject2InputIdMap::const_iterator anIter = anObject2InputIdMap.begin();
267 TObject2InputIdMap::const_iterator anEndIter = anObject2InputIdMap.end();
268 for(vtkIdType aCellId = 0; anIter != anEndIter; anIter++, aCellId++){
269 const TInputCellId& anInputCellId = anIter->second;
270 TInputId anInputId = anInputCellId.first;
271 /*TCellId*/ aCellId = anInputCellId.second;
272 aDataArray->SetValue(aTupleId++, anInputId);
273 aDataArray->SetValue(aTupleId++, aCellId);
276 anOutputCellData->AddArray(aDataArray);
277 aDataArray->Delete();
282 TCellCounter aFunctor(anNbInputs);
283 ForEachInput<TCellCounter>(theInputVector, anNbInputs, aFunctor);
285 vtkDataSetAttributes::FieldList& aFieldList = aFunctor.myFieldList;
286 vtkIdType aNbCells = aFunctor.GetNbCells();
290 // Now can allocate memory
291 anOutput->Allocate(aNbCells);
292 vtkCellData *anOutputCellData = anOutput->GetCellData();
293 anOutputCellData->CopyAllocate(aFieldList, aNbCells);
295 // Append each input dataset together
297 anOutput->SetPoints(theSharedPointSet->GetPoints());
298 anOutput->GetPointData()->PassData(theSharedPointSet->GetPointData());
301 vtkIdList *anIdList = vtkIdList::New();
302 anIdList->Allocate(VTK_CELL_SIZE);
303 for(vtkIdType anInputId = 0; anInputId < anNbInputs; anInputId++){
304 if(vtkDataSet *aDataSet = VISU::GetInput(theInputVector, anInputId)){
305 vtkIdType aNbCells = aDataSet->GetNumberOfCells();
306 vtkCellData *aCellData = aDataSet->GetCellData();
307 // copy cell and cell data
308 for(vtkIdType aCellId = 0; aCellId < aNbCells; aCellId++){
309 aDataSet->GetCellPoints(aCellId, anIdList);
311 vtkIdType aCellType = aDataSet->GetCellType(aCellId);
312 vtkIdType aNewCellId = anOutput->InsertNextCell(aCellType, anIdList);
314 anOutputCellData->CopyData(aFieldList, aCellData, anInputId, aCellId, aNewCellId);
320 if(theIsMappingInputs){
321 vtkIntArray *aDataArray = vtkIntArray::New();
322 aDataArray->SetName("VISU_INPUTS_MAPPER");
323 aDataArray->SetNumberOfComponents(2);
324 aDataArray->SetNumberOfTuples(aNbCells);
326 vtkIdType aTupleId = 0;
327 for(vtkIdType anInputId = 0; anInputId < anNbInputs; anInputId++){
328 if(vtkDataSet *aDataSet = VISU::GetInput(theInputVector, anInputId)){
329 vtkIdType aNbCells = aDataSet->GetNumberOfCells();
330 for(vtkIdType aCellId = 0; aCellId < aNbCells; aCellId++){
331 aDataArray->SetValue(aTupleId++, aCellId);
332 aDataArray->SetValue(aTupleId++, anInputId);
337 anOutputCellData->AddArray(aDataArray);
338 aDataArray->Delete();
348 //---------------------------------------------------------------
354 //---------------------------------------------------------------
356 ::TAppendFilterHelper(vtkObject* theParent):
357 myIsMergingInputs(false),
358 myIsMappingInputs(false),
363 //---------------------------------------------------------------
366 ::SetSharedPointSet(vtkPointSet* thePointSet)
368 if(GetSharedPointSet() == thePointSet)
371 mySharedPointSet = thePointSet;
377 //---------------------------------------------------------------
380 ::GetSharedPointSet()
382 return mySharedPointSet.GetPointer();
386 //---------------------------------------------------------------
389 ::SetMappingInputs(bool theIsMappingInputs)
391 if(myIsMappingInputs == theIsMappingInputs)
394 myIsMappingInputs = theIsMappingInputs;
399 //---------------------------------------------------------------
404 return myIsMappingInputs;
408 //---------------------------------------------------------------
411 ::SetMergingInputs(bool theIsMergingInputs)
413 if(myIsMergingInputs == theIsMergingInputs)
416 myIsMergingInputs = theIsMergingInputs;
421 //---------------------------------------------------------------
426 return myIsMergingInputs;
430 //---------------------------------------------------------------
432 UnstructuredGridRequestData(vtkInformationVector **theInputVector,
433 vtkIdType theNumberOfInputConnections,
434 vtkInformationVector *theOutputVector,
435 vtkPointSet* theSharedPointSet,
436 bool theIsMergingInputs,
437 bool theIsMappingInputs)
439 return RequestData<vtkUnstructuredGrid>(theInputVector,
440 theNumberOfInputConnections,
448 //---------------------------------------------------------------
450 PolyDataRequestData(vtkInformationVector **theInputVector,
451 vtkIdType theNumberOfInputConnections,
452 vtkInformationVector *theOutputVector,
453 vtkPointSet* theSharedPointSet,
454 bool theIsMergingInputs,
455 bool theIsMappingInputs)
457 return RequestData<vtkPolyData>(theInputVector,
458 theNumberOfInputConnections,
466 //---------------------------------------------------------------