1 // SALOME OBJECT : kernel of SALOME component
3 // Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SALOME_GeometryFilter.cxx
25 // Author : Michael ZORIN
29 #include "SALOME_GeometryFilter.h"
31 #include <vtkCellArray.h>
32 #include <vtkCellData.h>
33 #include <vtkGenericCell.h>
34 #include <vtkHexahedron.h>
35 #include <vtkMergePoints.h>
36 #include <vtkObjectFactory.h>
37 #include <vtkPointData.h>
38 #include <vtkPolyData.h>
39 #include <vtkPyramid.h>
40 #include <vtkStructuredGrid.h>
42 #include <vtkUnsignedCharArray.h>
43 #include <vtkUnstructuredGrid.h>
49 static int MYDEBUG = 0;
50 static int MYDEBUGWITHFILES = 0;
52 static int MYDEBUG = 0;
53 static int MYDEBUGWITHFILES = 0;
62 vtkCxxRevisionMacro(SALOME_GeometryFilter, "$Revision$");
63 vtkStandardNewMacro(SALOME_GeometryFilter);
66 SALOME_GeometryFilter::SALOME_GeometryFilter():
72 SALOME_GeometryFilter::~SALOME_GeometryFilter()
76 void SALOME_GeometryFilter::Execute()
78 vtkDataSet *input= this->GetInput();
79 vtkIdType numCells=input->GetNumberOfCells();
86 if (input->GetDataObjectType() == VTK_UNSTRUCTURED_GRID){
87 this->UnstructuredGridExecute();
90 vtkGeometryFilter::Execute();
94 void SALOME_GeometryFilter::SetStoreMapping(int theStoreMapping){
95 myStoreMapping = theStoreMapping;
100 vtkIdType SALOME_GeometryFilter::GetElemObjId(int theVtkID){
101 if(myVTK2ObjIds.empty() || theVtkID > myVTK2ObjIds.size()) return -1;
102 #if defined __GNUC_2__
103 return myVTK2ObjIds[theVtkID];
105 return myVTK2ObjIds.at(theVtkID);
110 void SALOME_GeometryFilter::UnstructuredGridExecute()
112 vtkUnstructuredGrid *input= (vtkUnstructuredGrid *)this->GetInput();
113 vtkCellArray *Connectivity = input->GetCells();
114 if (Connectivity == NULL) {return;}
120 vtkPoints *p = input->GetPoints();
121 vtkIdType numCells=input->GetNumberOfCells();
122 vtkPointData *pd = input->GetPointData();
123 vtkCellData *cd = input->GetCellData();
124 vtkPolyData *output = this->GetOutput();
125 vtkPointData *outputPD = output->GetPointData();
127 vtkCellData *outputCD = output->GetCellData();
128 vtkCellArray *Verts, *Lines, *Polys, *Strips;
129 vtkIdList *cellIds, *faceIds;
132 int faceId, *faceVerts, numFacePts;
134 int PixelConvert[4], aNewPts[VTK_CELL_SIZE];
136 unsigned char updateLevel = (unsigned char)(output->GetUpdateGhostLevel());
137 unsigned char *cellGhostLevels = 0;
144 vtkDebugMacro(<<"Executing geometry filter for unstructured grid input");
146 vtkDataArray* temp = 0;
149 temp = cd->GetArray("vtkGhostLevels");
151 if ( (!temp) || (temp->GetDataType() != VTK_UNSIGNED_CHAR)
152 || (temp->GetNumberOfComponents() != 1))
154 vtkDebugMacro("No appropriate ghost levels field available.");
158 cellGhostLevels = ((vtkUnsignedCharArray*)temp)->GetPointer(0);
162 if ( Connectivity == NULL )
164 vtkDebugMacro(<<"Nothing to extract");
168 // Determine nature of what we have to do
169 cellIds = vtkIdList::New();
170 faceIds = vtkIdList::New();
171 if ( (!this->CellClipping) && (!this->PointClipping) &&
172 (!this->ExtentClipping) )
180 cellVis = new char[numCells];
183 // Just pass points through, never merge
184 output->SetPoints(input->GetPoints());
185 outputPD->PassData(pd);
187 outputCD->CopyAllocate(cd,numCells,numCells/2);
189 output->Allocate(numCells/4+1,numCells);
190 //Verts = vtkCellArray::New();
191 //Verts->Allocate(numCells/4+1,numCells);
192 //Lines = vtkCellArray::New();
193 //Lines->Allocate(numCells/4+1,numCells);
194 //Polys = vtkCellArray::New();
195 //Polys->Allocate(numCells/4+1,numCells);
196 //Strips = vtkCellArray::New();
197 //Strips->Allocate(numCells/4+1,numCells);
199 // Loop over the cells determining what's visible
202 for (cellId=0, Connectivity->InitTraversal();
203 Connectivity->GetNextCell(npts,pts);
207 if ( this->CellClipping && cellId < this->CellMinimum ||
208 cellId > this->CellMaximum )
214 for (i=0; i < npts; i++)
216 x = p->GetPoint(pts[i]);
217 if ( (this->PointClipping && (pts[i] < this->PointMinimum ||
218 pts[i] > this->PointMaximum) ) ||
219 (this->ExtentClipping &&
220 (x[0] < this->Extent[0] || x[0] > this->Extent[1] ||
221 x[1] < this->Extent[2] || x[1] > this->Extent[3] ||
222 x[2] < this->Extent[4] || x[2] > this->Extent[5] )) )
226 }//point/extent clipping
228 }//if point clipping needs checking
230 }//if not all visible
232 // Loop over all cells now that visibility is known
233 // (Have to compute visibility first for 3D cell boundarys)
234 int progressInterval = numCells/20 + 1;
236 myVTK2ObjIds.clear();
237 myVTK2ObjIds.reserve(numCells);
239 for (cellId=0, Connectivity->InitTraversal();
240 Connectivity->GetNextCell(npts,pts);
243 //Progress and abort method support
244 if ( !(cellId % progressInterval) )
246 vtkDebugMacro(<<"Process cell #" << cellId);
247 this->UpdateProgress ((float)cellId/numCells);
250 // Handle ghost cells here. Another option was used cellVis array.
251 if (cellGhostLevels && cellGhostLevels[cellId] > updateLevel)
252 { // Do not create surfaces in outer ghost cells.
256 if (allVisible || cellVis[cellId]) //now if visible extract geometry
258 //special code for nonlinear cells - rarely occurs, so right now it
260 vtkIdType aCellType = input->GetCellType(cellId);
267 case VTK_POLY_VERTEX:
268 newCellId = output->InsertNextCell(aCellType,npts,pts);
270 myVTK2ObjIds.push_back(cellId); //apo
272 outputCD->CopyData(cd,cellId,newCellId);
277 newCellId = output->InsertNextCell(VTK_LINE,npts,pts);
279 myVTK2ObjIds.push_back(cellId); //apo
281 outputCD->CopyData(cd,cellId,newCellId);
287 newCellId = output->InsertNextCell(aCellType,npts,pts);
289 myVTK2ObjIds.push_back(cellId); //apo
291 outputCD->CopyData(cd,cellId,newCellId);
294 case VTK_TRIANGLE_STRIP:
295 newCellId = output->InsertNextCell(aCellType,npts,pts);
297 myVTK2ObjIds.push_back(cellId); //apo
299 outputCD->CopyData(cd,cellId,newCellId);
303 newCellId = output->InsertNextCell(aCellType,npts,pts);
305 myVTK2ObjIds.push_back(cellId); //apo
307 outputCD->CopyData(cd,cellId,newCellId);
311 for (faceId = 0; faceId < 4; faceId++)
314 faceVerts = vtkTetra::GetFaceArray(faceId);
315 faceIds->InsertNextId(pts[faceVerts[0]]);
316 faceIds->InsertNextId(pts[faceVerts[1]]);
317 faceIds->InsertNextId(pts[faceVerts[2]]);
319 aCellType = VTK_TRIANGLE;
320 input->GetCellNeighbors(cellId, faceIds, cellIds);
321 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
322 (!allVisible && !cellVis[cellIds->GetId(0)]) )
324 for ( i=0; i < numFacePts; i++)
326 aNewPts[i] = pts[faceVerts[i]];
328 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
330 myVTK2ObjIds.push_back(cellId); //apo
332 outputCD->CopyData(cd,cellId,newCellId);
338 for (faceId = 0; faceId < 6; faceId++)
341 faceVerts = vtkVoxel::GetFaceArray(faceId);
342 faceIds->InsertNextId(pts[faceVerts[0]]);
343 faceIds->InsertNextId(pts[faceVerts[1]]);
344 faceIds->InsertNextId(pts[faceVerts[2]]);
345 faceIds->InsertNextId(pts[faceVerts[3]]);
347 aCellType = VTK_QUAD;
348 input->GetCellNeighbors(cellId, faceIds, cellIds);
349 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
350 (!allVisible && !cellVis[cellIds->GetId(0)]) )
352 for ( i=0; i < numFacePts; i++)
354 aNewPts[i] = pts[faceVerts[PixelConvert[i]]];
356 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
358 myVTK2ObjIds.push_back(cellId); //apo
360 outputCD->CopyData(cd,cellId,newCellId);
365 case VTK_HEXAHEDRON: {
366 for (faceId = 0; faceId < 6; faceId++)
369 faceVerts = vtkHexahedron::GetFaceArray(faceId);
370 faceIds->InsertNextId(pts[faceVerts[0]]);
371 faceIds->InsertNextId(pts[faceVerts[1]]);
372 faceIds->InsertNextId(pts[faceVerts[2]]);
373 faceIds->InsertNextId(pts[faceVerts[3]]);
375 aCellType = VTK_QUAD;
376 input->GetCellNeighbors(cellId, faceIds, cellIds);
377 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
378 (!allVisible && !cellVis[cellIds->GetId(0)]) )
380 for ( i=0; i < numFacePts; i++)
382 aNewPts[i] = pts[faceVerts[i]];
384 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
386 myVTK2ObjIds.push_back(cellId); //apo
388 outputCD->CopyData(cd,cellId,newCellId);
394 for (faceId = 0; faceId < 5; faceId++)
397 faceVerts = vtkWedge::GetFaceArray(faceId);
398 faceIds->InsertNextId(pts[faceVerts[0]]);
399 faceIds->InsertNextId(pts[faceVerts[1]]);
400 faceIds->InsertNextId(pts[faceVerts[2]]);
402 aCellType = VTK_TRIANGLE;
403 if (faceVerts[3] >= 0)
405 faceIds->InsertNextId(pts[faceVerts[3]]);
407 aCellType = VTK_QUAD;
409 input->GetCellNeighbors(cellId, faceIds, cellIds);
410 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
411 (!allVisible && !cellVis[cellIds->GetId(0)]) )
413 for ( i=0; i < numFacePts; i++)
415 aNewPts[i] = pts[faceVerts[i]];
417 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
419 myVTK2ObjIds.push_back(cellId); //apo
421 outputCD->CopyData(cd,cellId,newCellId);
427 for (faceId = 0; faceId < 5; faceId++)
430 faceVerts = vtkPyramid::GetFaceArray(faceId);
431 faceIds->InsertNextId(pts[faceVerts[0]]);
432 faceIds->InsertNextId(pts[faceVerts[1]]);
433 faceIds->InsertNextId(pts[faceVerts[2]]);
435 aCellType = VTK_TRIANGLE;
436 if (faceVerts[3] >= 0)
438 faceIds->InsertNextId(pts[faceVerts[3]]);
440 aCellType = VTK_QUAD;
442 input->GetCellNeighbors(cellId, faceIds, cellIds);
443 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
444 (!allVisible && !cellVis[cellIds->GetId(0)]) )
446 for ( i=0; i < numFacePts; i++)
448 aNewPts[i] = pts[faceVerts[i]];
450 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
452 myVTK2ObjIds.push_back(cellId); //apo
454 outputCD->CopyData(cd,cellId,newCellId);
460 case VTK_QUADRATIC_EDGE:
461 case VTK_QUADRATIC_TRIANGLE:
462 case VTK_QUADRATIC_QUAD:
463 case VTK_QUADRATIC_TETRA:
464 case VTK_QUADRATIC_HEXAHEDRON:
466 break; //done with quadratic cells
472 if(MYDEBUG && myStoreMapping){
473 for(int i = 0, iEnd = myVTK2ObjIds.size(); i < iEnd; i++){
474 cout<<myVTK2ObjIds[i]<<", ";
479 // Update ourselves and release memory
481 //output->SetVerts(Verts);
483 //output->SetLines(Lines);
485 //output->SetPolys(Polys);
487 //output->SetStrips(Strips);
492 vtkDebugMacro(<<"Extracted " << input->GetNumberOfPoints() << " points,"
493 << output->GetNumberOfCells() << " cells.");
504 void SALOME_GeometryFilter::SetInside(int theShowInside){
505 if(myShowInside == theShowInside) return;
506 myShowInside = theShowInside;
509 int SALOME_GeometryFilter::GetInside(){