0030058: Visualization, Select3D_SensitivePrimitiveArray - the selection is not fast...
[occt.git] / src / IVtkTools / IVtkTools_SubPolyDataFilter.cxx
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>
18
19 // prevent disabling some MSVC warning messages by VTK headers 
20 #ifdef _MSC_VER
21 #pragma warning(push)
22 #endif
23 #include <vtkCellData.h>
24 #include <vtkIdList.h>
25 #include <vtkIdTypeArray.h>
26 #include <vtkInformation.h>
27 #include <vtkInformationVector.h>
28 #include <vtkObjectFactory.h>
29 #ifdef _MSC_VER
30 #pragma warning(pop)
31 #endif
32
33 vtkStandardNewMacro(IVtkTools_SubPolyDataFilter)
34
35 //================================================================
36 // Function : Constructor
37 // Purpose  : 
38 //================================================================
39 IVtkTools_SubPolyDataFilter::IVtkTools_SubPolyDataFilter()
40 {
41   myIdsArrayName = IVtkVTK_ShapeData::ARRNAME_SUBSHAPE_IDS();
42   myDoFiltering = true;
43 }
44
45 //================================================================
46 // Function : Destructor
47 // Purpose  : 
48 //================================================================
49 IVtkTools_SubPolyDataFilter::~IVtkTools_SubPolyDataFilter() { }
50
51 //================================================================
52 // Function : RequestData
53 // Purpose  : Filter cells according to the given set of ids.
54 //================================================================
55 int IVtkTools_SubPolyDataFilter::RequestData (vtkInformation *vtkNotUsed(theRequest),
56                                               vtkInformationVector **theInputVector,
57                                               vtkInformationVector *theOutputVector)
58 {
59   // get the input and output
60   vtkSmartPointer<vtkInformation> anInInfo = theInputVector[0]->GetInformationObject(0);
61   vtkSmartPointer<vtkInformation> anOutInfo = theOutputVector->GetInformationObject(0);
62
63   vtkSmartPointer<vtkPolyData> anInput = vtkPolyData::SafeDownCast(
64     anInInfo->Get (vtkDataObject::DATA_OBJECT()));
65
66   vtkSmartPointer<vtkPolyData> anOutput = vtkPolyData::SafeDownCast(
67     anOutInfo->Get (vtkDataObject::DATA_OBJECT()));
68
69   anInput->Modified();
70
71   if (myDoFiltering)
72   {
73     vtkSmartPointer<vtkCellData> aCellData = anInput->GetCellData();
74     vtkIdType aSize = 0;
75     vtkSmartPointer<vtkIdTypeArray> aDataArray =
76       vtkIdTypeArray::SafeDownCast (aCellData->GetArray (myIdsArrayName));
77
78     // List of cell ids to be passed
79     vtkSmartPointer<vtkIdList> anIdList = vtkSmartPointer<vtkIdList>::New();
80     anIdList->Allocate(myIdsSet.Extent());  // Allocate the list of ids
81
82     if (aDataArray.GetPointer() != NULL)
83     {
84       aSize = aDataArray->GetNumberOfTuples();
85       anIdList->Allocate (aSize);  // Allocate the list of ids
86     }
87
88     // Prepare the list of ids from the set of ids.
89     // Iterate on input cells.
90     if (!myIdsSet.IsEmpty())
91     {
92       for (vtkIdType anI = 0; anI < aSize; anI++)
93       {
94         if (myIdsSet.Contains (aDataArray->GetValue (anI)))
95         {
96           // Add a cell id to output if it's value is in the set.
97           anIdList->InsertNextId (anI);
98         }
99       }
100     }
101
102     // Copy cells with their points according to the prepared list of cell ids.
103     anOutput->GetCellData()->AllocateArrays(anInput->GetCellData()->GetNumberOfArrays());
104     anOutput->Allocate(anInput, anIdList->GetNumberOfIds());  // Allocate output cells
105     // Pass data arrays.
106     // Create new arrays for output data 
107     vtkSmartPointer<vtkCellData> anInData = anInput->GetCellData();
108     vtkSmartPointer<vtkCellData> anOutData = anOutput->GetCellData();
109     vtkSmartPointer<vtkDataArray> anInArr, anOutArr;
110
111     for (Standard_Integer anI = 0; anI < anInData->GetNumberOfArrays(); anI++)
112     {
113       anInArr = anInData->GetArray (anI);
114       anOutArr = vtkSmartPointer<vtkDataArray>::Take(
115         vtkDataArray::CreateDataArray(anInArr->GetDataType()));
116       anOutArr->SetName(anInArr->GetName());
117       anOutArr->Allocate(anIdList->GetNumberOfIds() * anInArr->GetNumberOfComponents());
118       anOutArr->SetNumberOfTuples (anIdList->GetNumberOfIds());
119       anOutArr->SetNumberOfComponents (anInArr->GetNumberOfComponents());
120       anOutData->AddArray(anOutArr);
121     }
122
123     // Copy cells with ids from our list.
124     anOutput->CopyCells (anInput, anIdList);
125
126     // Copy filtered arrays data
127     vtkIdType anOutId, anInId;
128
129     for (Standard_Integer anI = 0; anI < anInData->GetNumberOfArrays(); anI++)
130     {
131       anInArr = anInData->GetArray (anI);
132       anOutArr = anOutData->GetArray(anI);
133       for (anOutId = 0; anOutId < anIdList->GetNumberOfIds(); anOutId++)
134       {
135         anInId = anIdList->GetId (anOutId);
136         anOutArr->SetTuple (anOutId, anInId, anInArr);
137       }
138     }
139   }
140   else
141   {
142     anOutput->CopyStructure (anInput);  // Copy points and cells
143     anOutput->CopyAttributes (anInput); // Copy data arrays (sub-shapes ids)
144   }
145
146   return 1; // Return non-zero value if success and pipeline is not failed.
147 }
148
149 //================================================================
150 // Function : SetDoFiltering
151 // Purpose  : 
152 //================================================================
153 void IVtkTools_SubPolyDataFilter::SetDoFiltering (const bool theDoFiltering)
154 {
155   myDoFiltering = theDoFiltering;
156 }
157
158 //================================================================
159 // Function : PrintSelf
160 // Purpose  : 
161 //================================================================
162 void IVtkTools_SubPolyDataFilter::PrintSelf (std::ostream& theOs, vtkIndent theIndent)
163 {
164   this->Superclass::PrintSelf (theOs,theIndent);
165   theOs << theIndent << "SubPolyData: " << "\n"; 
166   theOs << theIndent << "   Number of cells to pass: " << myIdsSet.Extent() << "\n";
167   theOs << theIndent << "   Cells ids to pass: {" ;
168   // Print the content of the set of ids.
169   IVtk_IdTypeMap::Iterator anIter(myIdsSet);
170   while (anIter.More())
171   {
172       theOs << " " << anIter.Value();
173       anIter.Next();
174       if (anIter.More())
175       {
176           theOs << "; ";
177       }
178   }
179   theOs << "}" << "\n";
180 }
181
182 //================================================================
183 // Function : Clear
184 // Purpose  : Clear ids set to be passed through this filter.
185 //================================================================
186 void IVtkTools_SubPolyDataFilter::Clear()
187 {
188   myIdsSet.Clear();
189 }
190
191 //================================================================
192 // Function : SetData
193 // Purpose  : Set ids to be passed through this filter.
194 //================================================================
195 void IVtkTools_SubPolyDataFilter::SetData (const IVtk_IdTypeMap theSet)
196 {
197   myIdsSet = theSet;
198 }
199
200 //================================================================
201 // Function : AddData
202 // Purpose  : Add ids to be passed through this filter.
203 //================================================================
204 void IVtkTools_SubPolyDataFilter::AddData (const IVtk_IdTypeMap theSet)
205 {
206   IVtk_IdTypeMap::Iterator anIt (theSet);
207   for (; anIt.More(); anIt.Next())
208   {
209     if (!myIdsSet.Contains (anIt.Value()))
210     {
211       myIdsSet.Add (anIt.Value());
212     }
213   }
214 }
215
216 //================================================================
217 // Function : SetData
218 // Purpose  : Set ids to be passed through this filter.
219 //================================================================
220 void IVtkTools_SubPolyDataFilter::SetData (const IVtk_ShapeIdList theIdList)
221 {
222   myIdsSet.Clear();
223   AddData (theIdList);
224 }
225
226 //================================================================
227 // Function : AddData
228 // Purpose  : Add ids to be passed through this filter.
229 //================================================================
230 void IVtkTools_SubPolyDataFilter::AddData (const IVtk_ShapeIdList theIdList)
231 {
232   IVtk_ShapeIdList::Iterator anIt (theIdList);
233   for (; anIt.More(); anIt.Next())
234   {
235     if (!myIdsSet.Contains (anIt.Value()))
236     {
237       myIdsSet.Add (anIt.Value());
238     }
239   }
240 }
241
242 //! Set ids to be passed through this filter.
243 //================================================================
244 // Function : SetIdsArrayName
245 // Purpose  : 
246 //================================================================
247 void IVtkTools_SubPolyDataFilter::SetIdsArrayName (const char* theArrayName)
248 {
249   myIdsArrayName = theArrayName;
250 }