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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
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 <vtkImplicitBoolean.h>
33 #include <vtkImplicitFunctionCollection.h>
38 vtkStandardNewMacro(SALOME_ExtractGeometry);
41 SALOME_ExtractGeometry::SALOME_ExtractGeometry()
45 SALOME_ExtractGeometry::~SALOME_ExtractGeometry(){}
48 vtkIdType SALOME_ExtractGeometry::GetElemObjId(int theID){
49 if(myElemVTK2ObjIds.empty() || theID > myElemVTK2ObjIds.size())
51 return myElemVTK2ObjIds[theID];
55 vtkIdType SALOME_ExtractGeometry::GetNodeObjId(int theID){
56 if(myNodeVTK2ObjIds.empty() || theID > myNodeVTK2ObjIds.size())
58 return myNodeVTK2ObjIds[theID];
62 void SALOME_ExtractGeometry::SetImplicitBoolean(vtkImplicitBoolean* theImplicitBoolean)
64 myImplicitBoolean = theImplicitBoolean;
65 SetImplicitFunction(theImplicitBoolean);
69 void SALOME_ExtractGeometry::SetStoreMapping(bool theStoreMapping)
71 myStoreMapping = theStoreMapping;
76 void SALOME_ExtractGeometry::Execute()
78 if(myImplicitBoolean.GetPointer()){
79 if(vtkImplicitFunctionCollection* aFunction = myImplicitBoolean->GetFunction()){
80 if(aFunction->GetNumberOfItems() == 0){
81 vtkDebugMacro(<< "Extracting geometry - ShallowCopy");
82 GetOutput()->ShallowCopy(GetInput());
90 void SALOME_ExtractGeometry::Execute2()
92 vtkIdType ptId, numPts, numCells, i, cellId, newCellId, newId, *pointMap;
99 vtkIdList *newCellPts;
100 vtkDataSet *input = this->GetInput();
101 vtkPointData *pd = input->GetPointData();
102 vtkCellData *cd = input->GetCellData();
103 vtkUnstructuredGrid *output = this->GetOutput();
104 vtkPointData *outputPD = output->GetPointData();
105 vtkCellData *outputCD = output->GetCellData();
107 numCells = input->GetNumberOfCells();
108 numPts = input->GetNumberOfPoints();
110 vtkDebugMacro(<< "Extracting geometry");
112 if ( ! this->ImplicitFunction )
114 vtkErrorMacro(<<"No implicit function specified");
118 newCellPts = vtkIdList::New();
119 newCellPts->Allocate(VTK_CELL_SIZE);
121 if ( this->ExtractInside )
130 // Loop over all points determining whether they are inside the
131 // implicit function. Copy the points and point data if they are.
133 pointMap = new vtkIdType[numPts]; // maps old point ids into new
134 for (i=0; i < numPts; i++)
139 output->Allocate(numCells/4); //allocate storage for geometry/topology
140 newPts = vtkPoints::New();
141 newPts->Allocate(numPts/4,numPts);
142 outputPD->CopyAllocate(pd);
143 outputCD->CopyAllocate(cd);
144 vtkFloatArray *newScalars = NULL;
147 myElemVTK2ObjIds.clear();
148 myElemVTK2ObjIds.reserve(numCells);
149 myNodeVTK2ObjIds.clear();
150 myNodeVTK2ObjIds.reserve(numPts);
153 if ( ! this->ExtractBoundaryCells )
155 for ( ptId=0; ptId < numPts; ptId++ )
157 x = input->GetPoint(ptId);
158 if ( (this->ImplicitFunction->FunctionValue(x)*multiplier) < 0.0 )
160 newId = newPts->InsertNextPoint(x);
161 pointMap[ptId] = newId;
162 myNodeVTK2ObjIds.push_back(ptId);
163 outputPD->CopyData(pd,ptId,newId);
169 // To extract boundary cells, we have to create supplemental information
170 if ( this->ExtractBoundaryCells )
173 newScalars = vtkFloatArray::New();
174 newScalars->SetNumberOfValues(numPts);
176 for (ptId=0; ptId < numPts; ptId++ )
178 x = input->GetPoint(ptId);
179 val = this->ImplicitFunction->FunctionValue(x) * multiplier;
180 newScalars->SetValue(ptId, val);
183 newId = newPts->InsertNextPoint(x);
184 pointMap[ptId] = newId;
185 myNodeVTK2ObjIds.push_back(ptId);
186 outputPD->CopyData(pd,ptId,newId);
192 // Now loop over all cells to see whether they are inside implicit
193 // function (or on boundary if ExtractBoundaryCells is on).
195 for (cellId=0; cellId < numCells; cellId++)
197 cell = input->GetCell(cellId);
198 cellPts = cell->GetPointIds();
199 numCellPts = cell->GetNumberOfPoints();
202 if ( ! this->ExtractBoundaryCells ) //requires less work
204 for ( npts=0, i=0; i < numCellPts; i++, npts++)
206 ptId = cellPts->GetId(i);
207 if ( pointMap[ptId] < 0 )
209 break; //this cell won't be inserted
213 newCellPts->InsertId(i,pointMap[ptId]);
216 } //if don't want to extract boundary cells
218 else //want boundary cells
220 for ( npts=0, i=0; i < numCellPts; i++ )
222 ptId = cellPts->GetId(i);
223 if ( newScalars->GetValue(ptId) <= 0.0 )
230 for ( i=0; i < numCellPts; i++ )
232 ptId = cellPts->GetId(i);
233 if ( pointMap[ptId] < 0 )
235 x = input->GetPoint(ptId);
236 newId = newPts->InsertNextPoint(x);
237 pointMap[ptId] = newId;
238 myNodeVTK2ObjIds.push_back(ptId);
239 outputPD->CopyData(pd,ptId,newId);
241 newCellPts->InsertId(i,pointMap[ptId]);
243 }//a boundary or interior cell
244 }//if mapping boundary cells
246 if ( npts >= numCellPts || (this->ExtractBoundaryCells && npts > 0) )
248 newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
249 myElemVTK2ObjIds.push_back(cellId);
250 outputCD->CopyData(cd,cellId,newCellId);
254 // Update ourselves and release memory
257 newCellPts->Delete();
258 output->SetPoints(newPts);
261 if ( this->ExtractBoundaryCells )
263 newScalars->Delete();