1 // Created on: 2011-10-27
2 // Created by: Roman KOZLOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <IVtkTools_SubPolyDataFilter.hxx>
17 #include <IVtkVTK_ShapeData.hxx>
19 // prevent disabling some MSVC warning messages by VTK headers
23 #include <vtkCellData.h>
24 #include <vtkFloatArray.h>
25 #include <vtkGenericCell.h>
26 #include <vtkIdList.h>
27 #include <vtkIdTypeArray.h>
28 #include <vtkInformation.h>
29 #include <vtkInformationVector.h>
30 #include <vtkObjectFactory.h>
31 #include <vtkPointData.h>
38 //! Modified version of vtkPolyData::CopyCells() that includes copying of normals.
39 //! How to ask vtkPolyData::CopyCells() to do that automatically?
40 static void copyCells (vtkPolyData* theDst,
44 //theDst->CopyCells (theSrc, theIdList);
46 const vtkIdType aNbPts = theSrc->GetNumberOfPoints();
47 vtkDataArray* anOldNormals = theSrc->GetPointData()->GetNormals();
49 if (theDst->GetPoints() == NULL)
51 theDst->SetPoints (vtkSmartPointer<vtkPoints>::New());
54 vtkSmartPointer<vtkIdList> aNewCellPts = vtkSmartPointer<vtkIdList>::New();
55 vtkSmartPointer<vtkGenericCell> aCell = vtkSmartPointer<vtkGenericCell>::New();
56 NCollection_Vec3<double> anXYZ;
57 vtkPointData* aNewPntData = theDst->GetPointData();
58 vtkCellData* aNewCellData = theDst->GetCellData();
59 vtkPoints* aNewPoints = theDst->GetPoints();
60 vtkSmartPointer<vtkFloatArray> aNewNormals;
61 if (anOldNormals != NULL)
63 aNewNormals = vtkSmartPointer<vtkFloatArray>::New();
64 aNewNormals->SetName ("Normals");
65 aNewNormals->SetNumberOfComponents (3);
66 theDst->GetPointData()->SetNormals (aNewNormals);
69 vtkSmartPointer<vtkIdList> aPntMap = vtkSmartPointer<vtkIdList>::New(); // maps old pt ids into new
70 aPntMap->SetNumberOfIds (aNbPts);
71 for (vtkIdType i = 0; i < aNbPts; ++i)
73 aPntMap->SetId (i, -1);
77 for (vtkIdType aCellIter = 0; aCellIter < theIdList->GetNumberOfIds(); ++aCellIter)
79 theSrc->GetCell (theIdList->GetId (aCellIter), aCell);
80 vtkIdList* aCellPts = aCell->GetPointIds();
81 const vtkIdType aNbCellPts = aCell->GetNumberOfPoints();
82 for (vtkIdType i = 0; i < aNbCellPts; ++i)
84 const vtkIdType aPtId = aCellPts->GetId (i);
85 vtkIdType aNewId = aPntMap->GetId (aPtId);
88 theSrc->GetPoint (aPtId, anXYZ.ChangeData());
90 aNewId = aNewPoints->InsertNextPoint (anXYZ.GetData());
91 aPntMap->SetId (aPtId, aNewId);
92 aNewPntData->CopyData (theSrc->GetPointData(), aPtId, aNewId);
94 if (anOldNormals != NULL)
96 anOldNormals->GetTuple (aPtId, anXYZ.ChangeData());
97 aNewNormals->InsertNextTuple (anXYZ.GetData());
100 aNewCellPts->InsertId (i, aNewId);
103 const vtkIdType aNewCellId = theDst->InsertNextCell (aCell->GetCellType(), aNewCellPts);
104 aNewCellData->CopyData (theSrc->GetCellData(), theIdList->GetId (aCellIter), aNewCellId);
105 aNewCellPts->Reset();
110 vtkStandardNewMacro(IVtkTools_SubPolyDataFilter)
112 //================================================================
113 // Function : Constructor
115 //================================================================
116 IVtkTools_SubPolyDataFilter::IVtkTools_SubPolyDataFilter()
117 : myIdsArrayName (IVtkVTK_ShapeData::ARRNAME_SUBSHAPE_IDS()),
118 myDoFiltering (true),
119 myToCopyNormals (true)
124 //================================================================
125 // Function : Destructor
127 //================================================================
128 IVtkTools_SubPolyDataFilter::~IVtkTools_SubPolyDataFilter() { }
130 //================================================================
131 // Function : RequestData
132 // Purpose : Filter cells according to the given set of ids.
133 //================================================================
134 int IVtkTools_SubPolyDataFilter::RequestData (vtkInformation *vtkNotUsed(theRequest),
135 vtkInformationVector **theInputVector,
136 vtkInformationVector *theOutputVector)
138 // get the input and output
139 vtkSmartPointer<vtkInformation> anInInfo = theInputVector[0]->GetInformationObject(0);
140 vtkSmartPointer<vtkInformation> anOutInfo = theOutputVector->GetInformationObject(0);
142 vtkSmartPointer<vtkPolyData> anInput = vtkPolyData::SafeDownCast(
143 anInInfo->Get (vtkDataObject::DATA_OBJECT()));
145 vtkSmartPointer<vtkPolyData> anOutput = vtkPolyData::SafeDownCast(
146 anOutInfo->Get (vtkDataObject::DATA_OBJECT()));
152 vtkSmartPointer<vtkCellData> anInputCellData = anInput->GetCellData();
153 vtkSmartPointer<vtkCellData> anOutputCellData = anOutput->GetCellData();
154 vtkSmartPointer<vtkIdTypeArray> aDataArray = vtkIdTypeArray::SafeDownCast (anInputCellData->GetArray (myIdsArrayName));
156 // List of cell ids to be passed
157 vtkSmartPointer<vtkIdList> anIdList = vtkSmartPointer<vtkIdList>::New();
158 anIdList->Allocate (myIdsSet.Extent()); // Allocate the list of ids
160 const vtkIdType aSize = aDataArray.GetPointer() != NULL ? aDataArray->GetNumberOfTuples() : 0;
163 anIdList->Allocate (aSize); // Allocate the list of ids
166 // Prepare the list of ids from the set of ids.
167 // Iterate on input cells.
168 #if (VTK_MAJOR_VERSION >= 9)
169 // Count number of different cells.
170 int aNbVerts = 0, aNbLines = 0, aNbPolys = 0, aNbStrips = 0;
171 int aNbVertPts = 0, aNbLinePts = 0, aNbPolyPts = 0, aNbStripPts = 0;
173 if (!myIdsSet.IsEmpty())
175 for (vtkIdType anI = 0; anI < aSize; anI++)
177 if (myIdsSet.Contains (aDataArray->GetValue (anI)))
179 // Add a cell id to output if it's value is in the set.
180 anIdList->InsertNextId (anI);
181 #if (VTK_MAJOR_VERSION >= 9)
182 switch (anInput->GetCellType(anI))
188 case VTK_POLY_VERTEX:
190 aNbVertPts += anInput->GetCell(anI)->GetNumberOfPoints();
198 aNbLinePts += anInput->GetCell(anI)->GetNumberOfPoints();
210 aNbPolyPts += anInput->GetCell(anI)->GetNumberOfPoints();
212 case VTK_TRIANGLE_STRIP:
214 aNbStripPts += anInput->GetCell(anI)->GetNumberOfPoints();
222 // Copy cells with their points according to the prepared list of cell ids.
223 anOutputCellData->AllocateArrays (anInputCellData->GetNumberOfArrays());
224 // Allocate output cells
225 #if (VTK_MAJOR_VERSION >= 9)
226 anOutput->AllocateExact (aNbVerts, aNbVertPts, aNbLines, aNbLinePts, aNbPolys, aNbPolyPts, aNbStrips, aNbStripPts);
228 anOutput->Allocate (anInput, anIdList->GetNumberOfIds());
232 // Create new arrays for output data
233 for (Standard_Integer anI = 0; anI < anInputCellData->GetNumberOfArrays(); anI++)
235 vtkSmartPointer<vtkDataArray> anInArr = anInputCellData->GetArray (anI);
236 vtkSmartPointer<vtkDataArray> anOutArr = vtkSmartPointer<vtkDataArray>::Take (vtkDataArray::CreateDataArray(anInArr->GetDataType()));
238 anOutArr->SetName (anInArr->GetName());
239 anOutArr->Allocate (anIdList->GetNumberOfIds() * anInArr->GetNumberOfComponents());
240 anOutArr->SetNumberOfTuples (anIdList->GetNumberOfIds());
241 anOutArr->SetNumberOfComponents (anInArr->GetNumberOfComponents());
242 anOutputCellData->AddArray (anOutArr);
245 // Copy cells with ids from our list.
248 copyCells (anOutput, anInput, anIdList);
252 anOutput->CopyCells (anInput, anIdList);
255 // Copy filtered arrays data
256 for (Standard_Integer anI = 0; anI < anInputCellData->GetNumberOfArrays(); anI++)
258 vtkSmartPointer<vtkDataArray> anInArr = anInputCellData ->GetArray (anI);
259 vtkSmartPointer<vtkDataArray> anOutArr = anOutputCellData->GetArray (anI);
260 for (vtkIdType anOutId = 0; anOutId < anIdList->GetNumberOfIds(); anOutId++)
262 const vtkIdType anInId = anIdList->GetId (anOutId);
263 anOutArr->SetTuple (anOutId, anInId, anInArr);
269 anOutput->CopyStructure (anInput); // Copy points and cells
270 anOutput->CopyAttributes (anInput); // Copy data arrays (sub-shapes ids)
273 return 1; // Return non-zero value if success and pipeline is not failed.
276 //================================================================
277 // Function : SetDoFiltering
279 //================================================================
280 void IVtkTools_SubPolyDataFilter::SetDoFiltering (const bool theDoFiltering)
282 myDoFiltering = theDoFiltering;
285 //================================================================
286 // Function : PrintSelf
288 //================================================================
289 void IVtkTools_SubPolyDataFilter::PrintSelf (std::ostream& theOs, vtkIndent theIndent)
291 this->Superclass::PrintSelf (theOs,theIndent);
292 theOs << theIndent << "SubPolyData: " << "\n";
293 theOs << theIndent << " Number of cells to pass: " << myIdsSet.Extent() << "\n";
294 theOs << theIndent << " Cells ids to pass: {" ;
295 // Print the content of the set of ids.
296 IVtk_IdTypeMap::Iterator anIter(myIdsSet);
297 while (anIter.More())
299 theOs << " " << anIter.Value();
306 theOs << "}" << "\n";
309 //================================================================
311 // Purpose : Clear ids set to be passed through this filter.
312 //================================================================
313 void IVtkTools_SubPolyDataFilter::Clear()
318 //================================================================
319 // Function : SetData
320 // Purpose : Set ids to be passed through this filter.
321 //================================================================
322 void IVtkTools_SubPolyDataFilter::SetData (const IVtk_IdTypeMap theSet)
327 //================================================================
328 // Function : AddData
329 // Purpose : Add ids to be passed through this filter.
330 //================================================================
331 void IVtkTools_SubPolyDataFilter::AddData (const IVtk_IdTypeMap theSet)
333 for (IVtk_IdTypeMap::Iterator anIt (theSet); anIt.More(); anIt.Next())
335 if (!myIdsSet.Contains (anIt.Value()))
337 myIdsSet.Add (anIt.Value());
342 //================================================================
343 // Function : SetData
344 // Purpose : Set ids to be passed through this filter.
345 //================================================================
346 void IVtkTools_SubPolyDataFilter::SetData (const IVtk_ShapeIdList theIdList)
352 //================================================================
353 // Function : AddData
354 // Purpose : Add ids to be passed through this filter.
355 //================================================================
356 void IVtkTools_SubPolyDataFilter::AddData (const IVtk_ShapeIdList theIdList)
358 for (IVtk_ShapeIdList::Iterator anIt (theIdList); anIt.More(); anIt.Next())
360 if (!myIdsSet.Contains (anIt.Value()))
362 myIdsSet.Add (anIt.Value());
367 //================================================================
368 // Function : SetIdsArrayName
370 //================================================================
371 void IVtkTools_SubPolyDataFilter::SetIdsArrayName (const char* theArrayName)
373 myIdsArrayName = theArrayName;