1 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #include "SALOME_ExtractGeometry.h"
24 #include <vtkCellData.h>
25 #include <vtkFloatArray.h>
26 #include <vtkIdList.h>
27 #include <vtkImplicitFunction.h>
28 #include <vtkObjectFactory.h>
29 #include <vtkPointData.h>
30 #include <vtkUnstructuredGrid.h>
32 #include <vtkInformation.h>
33 #include <vtkInformationVector.h>
35 #include <vtkImplicitBoolean.h>
36 #include <vtkImplicitFunctionCollection.h>
45 //----------------------------------------------------------------------------
46 vtkStandardNewMacro(SALOME_ExtractGeometry);
49 //----------------------------------------------------------------------------
50 SALOME_ExtractGeometry
51 ::SALOME_ExtractGeometry():
52 myStoreMapping(false),
53 myIsDoneShallowCopy(false)
56 SALOME_ExtractGeometry
57 ::~SALOME_ExtractGeometry()
61 //----------------------------------------------------------------------------
63 SALOME_ExtractGeometry
64 ::GetImplicitBoolean()
66 return myImplicitBoolean.GetPointer();
71 SALOME_ExtractGeometry
72 ::SetImplicitFunction(vtkImplicitFunction* theImplicitFunction)
74 myImplicitBoolean = dynamic_cast<vtkImplicitBoolean*>(theImplicitFunction);
75 Superclass::SetImplicitFunction(theImplicitFunction);
79 //----------------------------------------------------------------------------
81 SALOME_ExtractGeometry
82 ::SetStoreMapping(bool theStoreMapping)
84 if(myStoreMapping != theStoreMapping){
85 myStoreMapping = theStoreMapping;
91 SALOME_ExtractGeometry
92 ::GetStoreMapping() const
94 return myStoreMapping;
98 //----------------------------------------------------------------------------
100 SALOME_ExtractGeometry
101 ::GetElemVTKId(vtkIdType theID)
103 if(!myStoreMapping || myIsDoneShallowCopy)
106 vtkIdType iEnd = myElemVTK2ObjIds.size();
107 for(vtkIdType i = 0; i < iEnd; i++)
108 if(myElemVTK2ObjIds[i] == theID)
115 SALOME_ExtractGeometry
116 ::GetNodeVTKId(vtkIdType theID)
118 if(!myStoreMapping || myIsDoneShallowCopy)
121 vtkIdType iEnd = myNodeVTK2ObjIds.size();
122 for(vtkIdType i = 0; i < iEnd; i++)
123 if(myNodeVTK2ObjIds[i] == theID)
130 //----------------------------------------------------------------------------
132 SALOME_ExtractGeometry
133 ::GetElemObjId(int theVtkID)
135 if(!myStoreMapping || myIsDoneShallowCopy)
138 if(theVtkID < myElemVTK2ObjIds.size())
139 return myElemVTK2ObjIds[theVtkID];
146 SALOME_ExtractGeometry
147 ::GetNodeObjId(int theVtkID)
149 if(!myStoreMapping || myIsDoneShallowCopy)
152 if(theVtkID < myNodeVTK2ObjIds.size())
153 return myNodeVTK2ObjIds[theVtkID];
159 //----------------------------------------------------------------------------
161 SALOME_ExtractGeometry
162 ::RequestData(vtkInformation *request,
163 vtkInformationVector **inputVector,
164 vtkInformationVector *outputVector)
166 // get the info objects
167 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
168 vtkInformation *outInfo = outputVector->GetInformationObject(0);
170 // get the input and ouptut
171 vtkDataSet *input = vtkDataSet::SafeDownCast(
172 inInfo->Get(vtkDataObject::DATA_OBJECT()));
173 vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
174 outInfo->Get(vtkDataObject::DATA_OBJECT()));
176 myElemVTK2ObjIds.clear();
177 myNodeVTK2ObjIds.clear();
179 myIsDoneShallowCopy = !this->ImplicitFunction;
181 if(!myIsDoneShallowCopy && myImplicitBoolean.GetPointer())
182 if(vtkImplicitFunctionCollection* aFunction = myImplicitBoolean->GetFunction())
183 myIsDoneShallowCopy = aFunction->GetNumberOfItems() == 0;
185 if(myIsDoneShallowCopy){
186 output->ShallowCopy(input);
190 return RequestData2(request,inputVector,outputVector);
194 //----------------------------------------------------------------------------
196 SALOME_ExtractGeometry
197 ::RequestData2(vtkInformation *vtkNotUsed(request),
198 vtkInformationVector **inputVector,
199 vtkInformationVector *outputVector)
201 // get the info objects
202 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
203 vtkInformation *outInfo = outputVector->GetInformationObject(0);
205 // get the input and ouptut
206 vtkDataSet *input = vtkDataSet::SafeDownCast(
207 inInfo->Get(vtkDataObject::DATA_OBJECT()));
208 vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
209 outInfo->Get(vtkDataObject::DATA_OBJECT()));
211 vtkIdType ptId, numPts, numCells, i, cellId, newCellId, newId, *pointMap;
215 vtkFloatingPointType *x;
216 vtkFloatingPointType multiplier;
218 vtkIdList *newCellPts;
219 vtkPointData *pd = input->GetPointData();
220 vtkCellData *cd = input->GetCellData();
221 vtkPointData *outputPD = output->GetPointData();
222 vtkCellData *outputCD = output->GetCellData();
224 numCells = input->GetNumberOfCells();
225 numPts = input->GetNumberOfPoints();
227 if ( ! this->ImplicitFunction )
229 vtkErrorMacro(<<"No implicit function specified");
233 newCellPts = vtkIdList::New();
234 newCellPts->Allocate(VTK_CELL_SIZE);
236 if ( this->ExtractInside )
245 // Loop over all points determining whether they are inside the
246 // implicit function. Copy the points and point data if they are.
248 pointMap = new vtkIdType[numPts]; // maps old point ids into new
249 for (i=0; i < numPts; i++)
254 output->Allocate(numCells/4); //allocate storage for geometry/topology
255 newPts = vtkPoints::New();
256 newPts->Allocate(numPts/4,numPts);
257 outputPD->CopyAllocate(pd);
258 outputCD->CopyAllocate(cd);
259 vtkFloatArray *newScalars = NULL;
262 myElemVTK2ObjIds.reserve(numCells);
263 myNodeVTK2ObjIds.reserve(numPts);
266 if ( ! this->ExtractBoundaryCells )
268 for ( ptId=0; ptId < numPts; ptId++ )
270 x = input->GetPoint(ptId);
271 if ( (this->ImplicitFunction->FunctionValue(x)*multiplier) < 0.0 )
273 newId = newPts->InsertNextPoint(x);
274 pointMap[ptId] = newId;
276 myNodeVTK2ObjIds.push_back(ptId);
277 outputPD->CopyData(pd,ptId,newId);
283 // To extract boundary cells, we have to create supplemental information
284 if ( this->ExtractBoundaryCells )
286 vtkFloatingPointType val;
287 newScalars = vtkFloatArray::New();
288 newScalars->SetNumberOfValues(numPts);
290 for (ptId=0; ptId < numPts; ptId++ )
292 x = input->GetPoint(ptId);
293 val = this->ImplicitFunction->FunctionValue(x) * multiplier;
294 newScalars->SetValue(ptId, val);
297 newId = newPts->InsertNextPoint(x);
298 pointMap[ptId] = newId;
300 myNodeVTK2ObjIds.push_back(ptId);
301 outputPD->CopyData(pd,ptId,newId);
307 // Now loop over all cells to see whether they are inside implicit
308 // function (or on boundary if ExtractBoundaryCells is on).
310 for (cellId=0; cellId < numCells; cellId++)
312 cell = input->GetCell(cellId);
313 cellPts = cell->GetPointIds();
314 numCellPts = cell->GetNumberOfPoints();
317 if ( ! this->ExtractBoundaryCells ) //requires less work
319 for ( npts=0, i=0; i < numCellPts; i++, npts++)
321 ptId = cellPts->GetId(i);
322 if ( pointMap[ptId] < 0 )
324 break; //this cell won't be inserted
328 newCellPts->InsertId(i,pointMap[ptId]);
331 } //if don't want to extract boundary cells
333 else //want boundary cells
335 for ( npts=0, i=0; i < numCellPts; i++ )
337 ptId = cellPts->GetId(i);
338 if ( newScalars->GetValue(ptId) <= 0.0 )
345 for ( i=0; i < numCellPts; i++ )
347 ptId = cellPts->GetId(i);
348 if ( pointMap[ptId] < 0 )
350 x = input->GetPoint(ptId);
351 newId = newPts->InsertNextPoint(x);
352 pointMap[ptId] = newId;
354 myNodeVTK2ObjIds.push_back(ptId);
355 outputPD->CopyData(pd,ptId,newId);
357 newCellPts->InsertId(i,pointMap[ptId]);
359 }//a boundary or interior cell
360 }//if mapping boundary cells
362 if ( npts >= numCellPts || (this->ExtractBoundaryCells && npts > 0) )
364 newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
366 myElemVTK2ObjIds.push_back(cellId);
367 outputCD->CopyData(cd,cellId,newCellId);
371 // Update ourselves and release memory
374 newCellPts->Delete();
375 output->SetPoints(newPts);
378 if ( this->ExtractBoundaryCells )
380 newScalars->Delete();