1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "SALOME_ExtractGeometry.h"
26 #include <vtkCellData.h>
27 #include <vtkFloatArray.h>
28 #include <vtkIdList.h>
29 #include <vtkImplicitFunction.h>
30 #include <vtkObjectFactory.h>
31 #include <vtkPointData.h>
32 #include <vtkUnstructuredGrid.h>
34 #include <vtkInformation.h>
35 #include <vtkInformationVector.h>
37 #include <vtkImplicitBoolean.h>
38 #include <vtkImplicitFunctionCollection.h>
47 //----------------------------------------------------------------------------
48 vtkStandardNewMacro(SALOME_ExtractGeometry);
51 //----------------------------------------------------------------------------
52 SALOME_ExtractGeometry
53 ::SALOME_ExtractGeometry():
54 myStoreMapping(false),
55 myIsDoneShallowCopy(false)
58 SALOME_ExtractGeometry
59 ::~SALOME_ExtractGeometry()
63 //----------------------------------------------------------------------------
65 SALOME_ExtractGeometry
66 ::GetImplicitBoolean()
68 return myImplicitBoolean.GetPointer();
73 SALOME_ExtractGeometry
74 ::SetImplicitFunction(vtkImplicitFunction* theImplicitFunction)
76 myImplicitBoolean = dynamic_cast<vtkImplicitBoolean*>(theImplicitFunction);
77 Superclass::SetImplicitFunction(theImplicitFunction);
81 //----------------------------------------------------------------------------
83 SALOME_ExtractGeometry
84 ::SetStoreMapping(bool theStoreMapping)
86 if(myStoreMapping != theStoreMapping){
87 myStoreMapping = theStoreMapping;
93 SALOME_ExtractGeometry
94 ::GetStoreMapping() const
96 return myStoreMapping;
100 //----------------------------------------------------------------------------
102 SALOME_ExtractGeometry
103 ::GetElemVTKId(vtkIdType theID)
105 if(!myStoreMapping || myIsDoneShallowCopy)
108 vtkIdType iEnd = myElemVTK2ObjIds.size();
109 for(vtkIdType i = 0; i < iEnd; i++)
110 if(myElemVTK2ObjIds[i] == theID)
117 SALOME_ExtractGeometry
118 ::GetNodeVTKId(vtkIdType theID)
120 if(!myStoreMapping || myIsDoneShallowCopy)
123 vtkIdType iEnd = myNodeVTK2ObjIds.size();
124 for(vtkIdType i = 0; i < iEnd; i++)
125 if(myNodeVTK2ObjIds[i] == theID)
132 //----------------------------------------------------------------------------
134 SALOME_ExtractGeometry
135 ::GetElemObjId(vtkIdType theVtkID)
137 if(!myStoreMapping || myIsDoneShallowCopy)
140 if(theVtkID < myElemVTK2ObjIds.size())
141 return myElemVTK2ObjIds[theVtkID];
148 SALOME_ExtractGeometry
149 ::GetNodeObjId(vtkIdType theVtkID)
151 if(!myStoreMapping || myIsDoneShallowCopy)
154 if(theVtkID < myNodeVTK2ObjIds.size())
155 return myNodeVTK2ObjIds[theVtkID];
161 //----------------------------------------------------------------------------
163 SALOME_ExtractGeometry
164 ::RequestData(vtkInformation *request,
165 vtkInformationVector **inputVector,
166 vtkInformationVector *outputVector)
168 // get the info objects
169 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
170 vtkInformation *outInfo = outputVector->GetInformationObject(0);
172 // get the input and ouptut
173 vtkDataSet *input = vtkDataSet::SafeDownCast(
174 inInfo->Get(vtkDataObject::DATA_OBJECT()));
175 vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
176 outInfo->Get(vtkDataObject::DATA_OBJECT()));
178 myElemVTK2ObjIds.clear();
179 myNodeVTK2ObjIds.clear();
181 myIsDoneShallowCopy = !this->ImplicitFunction;
183 if(!myIsDoneShallowCopy && myImplicitBoolean.GetPointer())
184 if(vtkImplicitFunctionCollection* aFunction = myImplicitBoolean->GetFunction())
185 myIsDoneShallowCopy = aFunction->GetNumberOfItems() == 0;
187 if(myIsDoneShallowCopy){
188 output->ShallowCopy(input);
192 return RequestData2(request,inputVector,outputVector);
196 //----------------------------------------------------------------------------
198 SALOME_ExtractGeometry
199 ::RequestData2(vtkInformation *vtkNotUsed(request),
200 vtkInformationVector **inputVector,
201 vtkInformationVector *outputVector)
203 // get the info objects
204 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
205 vtkInformation *outInfo = outputVector->GetInformationObject(0);
207 // get the input and ouptut
208 vtkDataSet *input = vtkDataSet::SafeDownCast(
209 inInfo->Get(vtkDataObject::DATA_OBJECT()));
210 vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
211 outInfo->Get(vtkDataObject::DATA_OBJECT()));
213 vtkIdType ptId, numPts, numCells, i, cellId, newCellId, newId, *pointMap;
217 vtkFloatingPointType *x;
218 vtkFloatingPointType multiplier;
220 vtkIdList *newCellPts;
221 vtkPointData *pd = input->GetPointData();
222 vtkCellData *cd = input->GetCellData();
223 vtkPointData *outputPD = output->GetPointData();
224 vtkCellData *outputCD = output->GetCellData();
226 numCells = input->GetNumberOfCells();
227 numPts = input->GetNumberOfPoints();
229 if ( ! this->ImplicitFunction )
231 vtkErrorMacro(<<"No implicit function specified");
235 newCellPts = vtkIdList::New();
236 newCellPts->Allocate(VTK_CELL_SIZE);
238 if ( this->ExtractInside )
247 // Loop over all points determining whether they are inside the
248 // implicit function. Copy the points and point data if they are.
250 pointMap = new vtkIdType[numPts]; // maps old point ids into new
251 for (i=0; i < numPts; i++)
256 output->Allocate(numCells/4); //allocate storage for geometry/topology
257 newPts = vtkPoints::New();
258 newPts->Allocate(numPts/4,numPts);
259 outputPD->CopyAllocate(pd);
260 outputCD->CopyAllocate(cd);
261 vtkFloatArray *newScalars = NULL;
264 myElemVTK2ObjIds.reserve(numCells);
265 myNodeVTK2ObjIds.reserve(numPts);
268 if ( ! this->ExtractBoundaryCells )
270 for ( ptId=0; ptId < numPts; ptId++ )
272 x = input->GetPoint(ptId);
273 if ( (this->ImplicitFunction->FunctionValue(x)*multiplier) < 0.0 )
275 newId = newPts->InsertNextPoint(x);
276 pointMap[ptId] = newId;
278 myNodeVTK2ObjIds.push_back(ptId);
279 outputPD->CopyData(pd,ptId,newId);
285 // To extract boundary cells, we have to create supplemental information
286 if ( this->ExtractBoundaryCells )
288 vtkFloatingPointType val;
289 newScalars = vtkFloatArray::New();
290 newScalars->SetNumberOfValues(numPts);
292 for (ptId=0; ptId < numPts; ptId++ )
294 x = input->GetPoint(ptId);
295 val = this->ImplicitFunction->FunctionValue(x) * multiplier;
296 newScalars->SetValue(ptId, val);
299 newId = newPts->InsertNextPoint(x);
300 pointMap[ptId] = newId;
302 myNodeVTK2ObjIds.push_back(ptId);
303 outputPD->CopyData(pd,ptId,newId);
309 // Now loop over all cells to see whether they are inside implicit
310 // function (or on boundary if ExtractBoundaryCells is on).
312 for (cellId=0; cellId < numCells; cellId++)
314 cell = input->GetCell(cellId);
315 cellPts = cell->GetPointIds();
316 numCellPts = cell->GetNumberOfPoints();
319 if ( ! this->ExtractBoundaryCells ) //requires less work
321 for ( npts=0, i=0; i < numCellPts; i++, npts++)
323 ptId = cellPts->GetId(i);
324 if ( pointMap[ptId] < 0 )
326 break; //this cell won't be inserted
330 newCellPts->InsertId(i,pointMap[ptId]);
333 } //if don't want to extract boundary cells
335 else //want boundary cells
337 for ( npts=0, i=0; i < numCellPts; i++ )
339 ptId = cellPts->GetId(i);
340 if ( newScalars->GetValue(ptId) <= 0.0 )
347 for ( i=0; i < numCellPts; i++ )
349 ptId = cellPts->GetId(i);
350 if ( pointMap[ptId] < 0 )
352 x = input->GetPoint(ptId);
353 newId = newPts->InsertNextPoint(x);
354 pointMap[ptId] = newId;
356 myNodeVTK2ObjIds.push_back(ptId);
357 outputPD->CopyData(pd,ptId,newId);
359 newCellPts->InsertId(i,pointMap[ptId]);
361 }//a boundary or interior cell
362 }//if mapping boundary cells
364 if ( npts >= numCellPts || (this->ExtractBoundaryCells && npts > 0) )
366 newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
368 myElemVTK2ObjIds.push_back(cellId);
369 outputCD->CopyData(cd,cellId,newCellId);
373 // Update ourselves and release memory
376 newCellPts->Delete();
377 output->SetPoints(newPts);
380 if ( this->ExtractBoundaryCells )
382 newScalars->Delete();