0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / IVtkTools / IVtkTools_SubPolyDataFilter.cxx
CommitLineData
913a4c4a 1// Created on: 2011-10-27
2// Created by: Roman KOZLOV
3// Copyright (c) 2011-2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
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.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <IVtkTools_SubPolyDataFilter.hxx>
17#include <IVtkVTK_ShapeData.hxx>
a9660929 18
19// prevent disabling some MSVC warning messages by VTK headers
20#ifdef _MSC_VER
21#pragma warning(push)
22#endif
a2f76b15 23#include <vtkCellData.h>
d0b8f010 24#include <vtkFloatArray.h>
25#include <vtkGenericCell.h>
a2f76b15 26#include <vtkIdList.h>
27#include <vtkIdTypeArray.h>
913a4c4a 28#include <vtkInformation.h>
29#include <vtkInformationVector.h>
30#include <vtkObjectFactory.h>
d0b8f010 31#include <vtkPointData.h>
a9660929 32#ifdef _MSC_VER
33#pragma warning(pop)
34#endif
913a4c4a 35
d0b8f010 36namespace
37{
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,
41 vtkPolyData* theSrc,
42 vtkIdList* theIdList)
43 {
44 //theDst->CopyCells (theSrc, theIdList);
45
46 const vtkIdType aNbPts = theSrc->GetNumberOfPoints();
47 vtkDataArray* anOldNormals = theSrc->GetPointData()->GetNormals();
48
49 if (theDst->GetPoints() == NULL)
50 {
51 theDst->SetPoints (vtkSmartPointer<vtkPoints>::New());
52 }
53
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)
62 {
63 aNewNormals = vtkSmartPointer<vtkFloatArray>::New();
64 aNewNormals->SetName ("Normals");
65 aNewNormals->SetNumberOfComponents (3);
66 theDst->GetPointData()->SetNormals (aNewNormals);
67 }
68
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)
72 {
73 aPntMap->SetId (i, -1);
74 }
75
76 // Filter the cells
77 for (vtkIdType aCellIter = 0; aCellIter < theIdList->GetNumberOfIds(); ++aCellIter)
78 {
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)
83 {
84 const vtkIdType aPtId = aCellPts->GetId (i);
85 vtkIdType aNewId = aPntMap->GetId (aPtId);
86 if (aNewId < 0)
87 {
88 theSrc->GetPoint (aPtId, anXYZ.ChangeData());
89
90 aNewId = aNewPoints->InsertNextPoint (anXYZ.GetData());
91 aPntMap->SetId (aPtId, aNewId);
92 aNewPntData->CopyData (theSrc->GetPointData(), aPtId, aNewId);
93
94 if (anOldNormals != NULL)
95 {
96 anOldNormals->GetTuple (aPtId, anXYZ.ChangeData());
97 aNewNormals->InsertNextTuple (anXYZ.GetData());
98 }
99 }
100 aNewCellPts->InsertId (i, aNewId);
101 }
102
103 const vtkIdType aNewCellId = theDst->InsertNextCell (aCell->GetCellType(), aNewCellPts);
104 aNewCellData->CopyData (theSrc->GetCellData(), theIdList->GetId (aCellIter), aNewCellId);
105 aNewCellPts->Reset();
106 }
107 }
108}
109
68858c7d 110vtkStandardNewMacro(IVtkTools_SubPolyDataFilter)
913a4c4a 111
112//================================================================
113// Function : Constructor
d0b8f010 114// Purpose :
913a4c4a 115//================================================================
116IVtkTools_SubPolyDataFilter::IVtkTools_SubPolyDataFilter()
d0b8f010 117: myIdsArrayName (IVtkVTK_ShapeData::ARRNAME_SUBSHAPE_IDS()),
118 myDoFiltering (true),
119 myToCopyNormals (true)
913a4c4a 120{
d0b8f010 121 //
913a4c4a 122}
123
124//================================================================
125// Function : Destructor
d0b8f010 126// Purpose :
913a4c4a 127//================================================================
128IVtkTools_SubPolyDataFilter::~IVtkTools_SubPolyDataFilter() { }
129
130//================================================================
131// Function : RequestData
132// Purpose : Filter cells according to the given set of ids.
133//================================================================
134int IVtkTools_SubPolyDataFilter::RequestData (vtkInformation *vtkNotUsed(theRequest),
135 vtkInformationVector **theInputVector,
136 vtkInformationVector *theOutputVector)
137{
138 // get the input and output
a2f76b15 139 vtkSmartPointer<vtkInformation> anInInfo = theInputVector[0]->GetInformationObject(0);
140 vtkSmartPointer<vtkInformation> anOutInfo = theOutputVector->GetInformationObject(0);
913a4c4a 141
a2f76b15 142 vtkSmartPointer<vtkPolyData> anInput = vtkPolyData::SafeDownCast(
913a4c4a 143 anInInfo->Get (vtkDataObject::DATA_OBJECT()));
144
a2f76b15 145 vtkSmartPointer<vtkPolyData> anOutput = vtkPolyData::SafeDownCast(
913a4c4a 146 anOutInfo->Get (vtkDataObject::DATA_OBJECT()));
147
913a4c4a 148 anInput->Modified();
149
150 if (myDoFiltering)
151 {
d0b8f010 152 vtkSmartPointer<vtkCellData> anInputCellData = anInput->GetCellData();
153 vtkSmartPointer<vtkCellData> anOutputCellData = anOutput->GetCellData();
154 vtkSmartPointer<vtkIdTypeArray> aDataArray = vtkIdTypeArray::SafeDownCast (anInputCellData->GetArray (myIdsArrayName));
a2f76b15 155
156 // List of cell ids to be passed
157 vtkSmartPointer<vtkIdList> anIdList = vtkSmartPointer<vtkIdList>::New();
d0b8f010 158 anIdList->Allocate (myIdsSet.Extent()); // Allocate the list of ids
913a4c4a 159
d0b8f010 160 const vtkIdType aSize = aDataArray.GetPointer() != NULL ? aDataArray->GetNumberOfTuples() : 0;
161 if (aSize != 0)
913a4c4a 162 {
913a4c4a 163 anIdList->Allocate (aSize); // Allocate the list of ids
164 }
165
166 // Prepare the list of ids from the set of ids.
167 // Iterate on input cells.
2c276f91 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;
172#endif
913a4c4a 173 if (!myIdsSet.IsEmpty())
174 {
175 for (vtkIdType anI = 0; anI < aSize; anI++)
176 {
177 if (myIdsSet.Contains (aDataArray->GetValue (anI)))
178 {
179 // Add a cell id to output if it's value is in the set.
180 anIdList->InsertNextId (anI);
2c276f91 181#if (VTK_MAJOR_VERSION >= 9)
182 switch (anInput->GetCellType(anI))
183 {
184 case VTK_VERTEX:
185 aNbVerts++;
186 aNbVertPts++;
187 break;
188 case VTK_POLY_VERTEX:
189 aNbVerts++;
190 aNbVertPts += anInput->GetCell(anI)->GetNumberOfPoints();
191 break;
192 case VTK_LINE:
193 aNbLines++;
194 aNbLinePts += 2;
195 break;
196 case VTK_POLY_LINE:
197 aNbLines++;
198 aNbLinePts += anInput->GetCell(anI)->GetNumberOfPoints();
199 break;
200 case VTK_TRIANGLE:
201 aNbPolys++;
202 aNbPolyPts += 3;
203 break;
204 case VTK_QUAD:
205 aNbPolys++;
206 aNbPolyPts += 4;
207 break;
208 case VTK_POLYGON:
209 aNbPolys++;
210 aNbPolyPts += anInput->GetCell(anI)->GetNumberOfPoints();
211 break;
212 case VTK_TRIANGLE_STRIP:
213 aNbStrips++;
214 aNbStripPts += anInput->GetCell(anI)->GetNumberOfPoints();
215 break;
216 }
217#endif
913a4c4a 218 }
219 }
220 }
221
222 // Copy cells with their points according to the prepared list of cell ids.
d0b8f010 223 anOutputCellData->AllocateArrays (anInputCellData->GetNumberOfArrays());
2c276f91 224 // Allocate output cells
225#if (VTK_MAJOR_VERSION >= 9)
226 anOutput->AllocateExact (aNbVerts, aNbVertPts, aNbLines, aNbLinePts, aNbPolys, aNbPolyPts, aNbStrips, aNbStripPts);
227#else
228 anOutput->Allocate (anInput, anIdList->GetNumberOfIds());
229#endif
d0b8f010 230
913a4c4a 231 // Pass data arrays.
232 // Create new arrays for output data
d0b8f010 233 for (Standard_Integer anI = 0; anI < anInputCellData->GetNumberOfArrays(); anI++)
913a4c4a 234 {
d0b8f010 235 vtkSmartPointer<vtkDataArray> anInArr = anInputCellData->GetArray (anI);
236 vtkSmartPointer<vtkDataArray> anOutArr = vtkSmartPointer<vtkDataArray>::Take (vtkDataArray::CreateDataArray(anInArr->GetDataType()));
237
238 anOutArr->SetName (anInArr->GetName());
239 anOutArr->Allocate (anIdList->GetNumberOfIds() * anInArr->GetNumberOfComponents());
913a4c4a 240 anOutArr->SetNumberOfTuples (anIdList->GetNumberOfIds());
241 anOutArr->SetNumberOfComponents (anInArr->GetNumberOfComponents());
d0b8f010 242 anOutputCellData->AddArray (anOutArr);
913a4c4a 243 }
244
245 // Copy cells with ids from our list.
d0b8f010 246 if (myToCopyNormals)
247 {
248 copyCells (anOutput, anInput, anIdList);
249 }
250 else
251 {
252 anOutput->CopyCells (anInput, anIdList);
253 }
913a4c4a 254
255 // Copy filtered arrays data
d0b8f010 256 for (Standard_Integer anI = 0; anI < anInputCellData->GetNumberOfArrays(); anI++)
913a4c4a 257 {
d0b8f010 258 vtkSmartPointer<vtkDataArray> anInArr = anInputCellData ->GetArray (anI);
259 vtkSmartPointer<vtkDataArray> anOutArr = anOutputCellData->GetArray (anI);
260 for (vtkIdType anOutId = 0; anOutId < anIdList->GetNumberOfIds(); anOutId++)
913a4c4a 261 {
d0b8f010 262 const vtkIdType anInId = anIdList->GetId (anOutId);
913a4c4a 263 anOutArr->SetTuple (anOutId, anInId, anInArr);
264 }
265 }
913a4c4a 266 }
267 else
268 {
269 anOutput->CopyStructure (anInput); // Copy points and cells
270 anOutput->CopyAttributes (anInput); // Copy data arrays (sub-shapes ids)
271 }
272
273 return 1; // Return non-zero value if success and pipeline is not failed.
274}
275
276//================================================================
277// Function : SetDoFiltering
d0b8f010 278// Purpose :
913a4c4a 279//================================================================
280void IVtkTools_SubPolyDataFilter::SetDoFiltering (const bool theDoFiltering)
281{
282 myDoFiltering = theDoFiltering;
283}
284
285//================================================================
286// Function : PrintSelf
287// Purpose :
288//================================================================
289void IVtkTools_SubPolyDataFilter::PrintSelf (std::ostream& theOs, vtkIndent theIndent)
290{
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())
298 {
d0b8f010 299 theOs << " " << anIter.Value();
300 anIter.Next();
301 if (anIter.More())
302 {
303 theOs << "; ";
304 }
913a4c4a 305 }
306 theOs << "}" << "\n";
307}
308
309//================================================================
310// Function : Clear
311// Purpose : Clear ids set to be passed through this filter.
312//================================================================
313void IVtkTools_SubPolyDataFilter::Clear()
314{
315 myIdsSet.Clear();
316}
317
318//================================================================
319// Function : SetData
320// Purpose : Set ids to be passed through this filter.
321//================================================================
322void IVtkTools_SubPolyDataFilter::SetData (const IVtk_IdTypeMap theSet)
323{
324 myIdsSet = theSet;
325}
326
327//================================================================
328// Function : AddData
329// Purpose : Add ids to be passed through this filter.
330//================================================================
331void IVtkTools_SubPolyDataFilter::AddData (const IVtk_IdTypeMap theSet)
332{
d0b8f010 333 for (IVtk_IdTypeMap::Iterator anIt (theSet); anIt.More(); anIt.Next())
913a4c4a 334 {
335 if (!myIdsSet.Contains (anIt.Value()))
336 {
337 myIdsSet.Add (anIt.Value());
338 }
339 }
340}
341
342//================================================================
343// Function : SetData
344// Purpose : Set ids to be passed through this filter.
345//================================================================
346void IVtkTools_SubPolyDataFilter::SetData (const IVtk_ShapeIdList theIdList)
347{
348 myIdsSet.Clear();
349 AddData (theIdList);
350}
351
352//================================================================
353// Function : AddData
354// Purpose : Add ids to be passed through this filter.
355//================================================================
356void IVtkTools_SubPolyDataFilter::AddData (const IVtk_ShapeIdList theIdList)
357{
d0b8f010 358 for (IVtk_ShapeIdList::Iterator anIt (theIdList); anIt.More(); anIt.Next())
913a4c4a 359 {
360 if (!myIdsSet.Contains (anIt.Value()))
361 {
362 myIdsSet.Add (anIt.Value());
363 }
364 }
365}
366
913a4c4a 367//================================================================
368// Function : SetIdsArrayName
d0b8f010 369// Purpose :
913a4c4a 370//================================================================
371void IVtkTools_SubPolyDataFilter::SetIdsArrayName (const char* theArrayName)
372{
373 myIdsArrayName = theArrayName;
374}