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 : VTKViewer_GeometryFilter.cxx
25 // Author : Michael ZORIN
29 #include "VTKViewer_GeometryFilter.h"
30 #include "VTKViewer_ConvexTool.h"
32 #include <vtkSmartPointer.h>
33 #include <vtkCellArray.h>
34 #include <vtkCellData.h>
35 #include <vtkGenericCell.h>
36 #include <vtkHexahedron.h>
37 #include <vtkMergePoints.h>
38 #include <vtkObjectFactory.h>
39 #include <vtkPointData.h>
40 #include <vtkPolyData.h>
41 #include <vtkPyramid.h>
42 #include <vtkStructuredGrid.h>
44 #include <vtkUnsignedCharArray.h>
45 #include <vtkUnstructuredGrid.h>
55 static int MYDEBUG = 0;
56 static int MYDEBUGWITHFILES = 0;
58 static int MYDEBUG = 0;
59 static int MYDEBUGWITHFILES = 0;
68 vtkCxxRevisionMacro(VTKViewer_GeometryFilter, "$Revision$");
69 vtkStandardNewMacro(VTKViewer_GeometryFilter);
71 VTKViewer_GeometryFilter::VTKViewer_GeometryFilter():
77 VTKViewer_GeometryFilter::~VTKViewer_GeometryFilter()
81 void VTKViewer_GeometryFilter::Execute()
83 vtkDataSet *input= this->GetInput();
84 vtkIdType numCells=input->GetNumberOfCells();
91 if (input->GetDataObjectType() == VTK_UNSTRUCTURED_GRID){
92 this->UnstructuredGridExecute();
95 vtkGeometryFilter::Execute();
99 void VTKViewer_GeometryFilter::SetStoreMapping(int theStoreMapping){
100 myStoreMapping = theStoreMapping;
105 vtkIdType VTKViewer_GeometryFilter::GetElemObjId(int theVtkID){
106 if(myVTK2ObjIds.empty() || theVtkID > myVTK2ObjIds.size()) return -1;
107 #if defined __GNUC_2__
108 return myVTK2ObjIds[theVtkID];
110 return myVTK2ObjIds.at(theVtkID);
115 void VTKViewer_GeometryFilter::UnstructuredGridExecute()
117 vtkUnstructuredGrid *input= (vtkUnstructuredGrid *)this->GetInput();
118 vtkCellArray *Connectivity = input->GetCells();
119 if (Connectivity == NULL) {return;}
125 vtkPoints *p = input->GetPoints();
126 vtkIdType numCells=input->GetNumberOfCells();
127 vtkPointData *pd = input->GetPointData();
128 vtkCellData *cd = input->GetCellData();
129 vtkPolyData *output = this->GetOutput();
130 vtkPointData *outputPD = output->GetPointData();
132 vtkCellData *outputCD = output->GetCellData();
133 //vtkCellArray *Verts, *Lines, *Polys, *Strips;
134 vtkIdList *cellIds, *faceIds;
137 int faceId, *faceVerts, numFacePts;
139 int PixelConvert[4], aNewPts[VTK_CELL_SIZE];
141 unsigned char updateLevel = (unsigned char)(output->GetUpdateGhostLevel());
142 unsigned char *cellGhostLevels = 0;
149 vtkDebugMacro(<<"Executing geometry filter for unstructured grid input");
151 vtkDataArray* temp = 0;
154 temp = cd->GetArray("vtkGhostLevels");
156 if ( (!temp) || (temp->GetDataType() != VTK_UNSIGNED_CHAR)
157 || (temp->GetNumberOfComponents() != 1))
159 vtkDebugMacro("No appropriate ghost levels field available.");
163 cellGhostLevels = ((vtkUnsignedCharArray*)temp)->GetPointer(0);
167 if ( Connectivity == NULL )
169 vtkDebugMacro(<<"Nothing to extract");
173 // Determine nature of what we have to do
174 cellIds = vtkIdList::New();
175 faceIds = vtkIdList::New();
176 if ( (!this->CellClipping) && (!this->PointClipping) &&
177 (!this->ExtentClipping) )
185 cellVis = new char[numCells];
188 // Just pass points through, never merge
189 output->SetPoints(input->GetPoints());
190 outputPD->PassData(pd);
192 outputCD->CopyAllocate(cd,numCells,numCells/2);
194 output->Allocate(numCells/4+1,numCells);
195 //Verts = vtkCellArray::New();
196 //Verts->Allocate(numCells/4+1,numCells);
197 //Lines = vtkCellArray::New();
198 //Lines->Allocate(numCells/4+1,numCells);
199 //Polys = vtkCellArray::New();
200 //Polys->Allocate(numCells/4+1,numCells);
201 //Strips = vtkCellArray::New();
202 //Strips->Allocate(numCells/4+1,numCells);
204 // Loop over the cells determining what's visible
207 for (cellId=0, Connectivity->InitTraversal();
208 Connectivity->GetNextCell(npts,pts);
212 if ( this->CellClipping && cellId < this->CellMinimum ||
213 cellId > this->CellMaximum )
219 for (i=0; i < npts; i++)
221 x = p->GetPoint(pts[i]);
222 if ( (this->PointClipping && (pts[i] < this->PointMinimum ||
223 pts[i] > this->PointMaximum) ) ||
224 (this->ExtentClipping &&
225 (x[0] < this->Extent[0] || x[0] > this->Extent[1] ||
226 x[1] < this->Extent[2] || x[1] > this->Extent[3] ||
227 x[2] < this->Extent[4] || x[2] > this->Extent[5] )) )
231 }//point/extent clipping
233 }//if point clipping needs checking
235 }//if not all visible
237 // Loop over all cells now that visibility is known
238 // (Have to compute visibility first for 3D cell boundarys)
239 int progressInterval = numCells/20 + 1;
241 myVTK2ObjIds.clear();
242 myVTK2ObjIds.reserve(numCells);
244 for (cellId=0, Connectivity->InitTraversal();
245 Connectivity->GetNextCell(npts,pts);
248 //Progress and abort method support
249 if ( !(cellId % progressInterval) )
251 vtkDebugMacro(<<"Process cell #" << cellId);
252 this->UpdateProgress ((float)cellId/numCells);
255 // Handle ghost cells here. Another option was used cellVis array.
256 if (cellGhostLevels && cellGhostLevels[cellId] > updateLevel)
257 { // Do not create surfaces in outer ghost cells.
261 if (allVisible || cellVis[cellId]) //now if visible extract geometry
263 //special code for nonlinear cells - rarely occurs, so right now it
265 vtkIdType aCellType = input->GetCellType(cellId);
272 case VTK_POLY_VERTEX:
273 newCellId = output->InsertNextCell(aCellType,npts,pts);
275 myVTK2ObjIds.push_back(cellId); //apo
277 outputCD->CopyData(cd,cellId,newCellId);
282 newCellId = output->InsertNextCell(VTK_LINE,npts,pts);
284 myVTK2ObjIds.push_back(cellId); //apo
286 outputCD->CopyData(cd,cellId,newCellId);
292 newCellId = output->InsertNextCell(aCellType,npts,pts);
294 myVTK2ObjIds.push_back(cellId); //apo
296 outputCD->CopyData(cd,cellId,newCellId);
299 case VTK_TRIANGLE_STRIP:
300 newCellId = output->InsertNextCell(aCellType,npts,pts);
302 myVTK2ObjIds.push_back(cellId); //apo
304 outputCD->CopyData(cd,cellId,newCellId);
308 newCellId = output->InsertNextCell(aCellType,npts,pts);
310 myVTK2ObjIds.push_back(cellId); //apo
312 outputCD->CopyData(cd,cellId,newCellId);
315 case VTK_CONVEX_POINT_SET:{
316 TCellArray tmpCellArray;
318 CONVEX_TOOL::GetPolygonalFaces(input,cellId,tmpCellArray); // "VTKViewer_ConvexTool.cxx"
319 } catch (const std::exception& theExc){
320 cout << __FILE__ << "[" << __LINE__ << "] " << "Exception:" << theExc.what() << endl;
322 cout << __FILE__ << "[" << __LINE__ << "] " << "Exception was occured"<< endl;
324 TCellArray::iterator aFaceIter = tmpCellArray.begin();
325 for (; aFaceIter!=tmpCellArray.end(); aFaceIter++){
326 TCell cell = aFaceIter->second;
327 numFacePts = cell.size();
329 aCellType = VTK_POLYGON;
330 else if(numFacePts == 3)
331 aCellType = VTK_TRIANGLE;
332 else if(numFacePts<3)
335 for ( i=0; i < numFacePts; i++)
337 aNewPts[i] = cell[i];
339 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
341 myVTK2ObjIds.push_back(cellId);
343 outputCD->CopyData(cd,cellId,newCellId);
348 for (faceId = 0; faceId < 4; faceId++)
351 faceVerts = vtkTetra::GetFaceArray(faceId);
352 faceIds->InsertNextId(pts[faceVerts[0]]);
353 faceIds->InsertNextId(pts[faceVerts[1]]);
354 faceIds->InsertNextId(pts[faceVerts[2]]);
356 aCellType = VTK_TRIANGLE;
357 input->GetCellNeighbors(cellId, faceIds, cellIds);
358 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
359 (!allVisible && !cellVis[cellIds->GetId(0)]) )
361 for ( i=0; i < numFacePts; i++)
363 aNewPts[i] = pts[faceVerts[i]];
365 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
367 myVTK2ObjIds.push_back(cellId); //apo
369 outputCD->CopyData(cd,cellId,newCellId);
375 for (faceId = 0; faceId < 6; faceId++)
378 faceVerts = vtkVoxel::GetFaceArray(faceId);
379 faceIds->InsertNextId(pts[faceVerts[0]]);
380 faceIds->InsertNextId(pts[faceVerts[1]]);
381 faceIds->InsertNextId(pts[faceVerts[2]]);
382 faceIds->InsertNextId(pts[faceVerts[3]]);
384 aCellType = VTK_QUAD;
385 input->GetCellNeighbors(cellId, faceIds, cellIds);
386 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
387 (!allVisible && !cellVis[cellIds->GetId(0)]) )
389 for ( i=0; i < numFacePts; i++)
391 aNewPts[i] = pts[faceVerts[PixelConvert[i]]];
393 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
395 myVTK2ObjIds.push_back(cellId); //apo
397 outputCD->CopyData(cd,cellId,newCellId);
402 case VTK_HEXAHEDRON: {
403 for (faceId = 0; faceId < 6; faceId++)
406 faceVerts = vtkHexahedron::GetFaceArray(faceId);
407 faceIds->InsertNextId(pts[faceVerts[0]]);
408 faceIds->InsertNextId(pts[faceVerts[1]]);
409 faceIds->InsertNextId(pts[faceVerts[2]]);
410 faceIds->InsertNextId(pts[faceVerts[3]]);
412 aCellType = VTK_QUAD;
413 input->GetCellNeighbors(cellId, faceIds, cellIds);
414 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
415 (!allVisible && !cellVis[cellIds->GetId(0)]) )
417 for ( i=0; i < numFacePts; i++)
419 aNewPts[i] = pts[faceVerts[i]];
421 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
423 myVTK2ObjIds.push_back(cellId); //apo
425 outputCD->CopyData(cd,cellId,newCellId);
431 for (faceId = 0; faceId < 5; faceId++)
434 faceVerts = vtkWedge::GetFaceArray(faceId);
435 faceIds->InsertNextId(pts[faceVerts[0]]);
436 faceIds->InsertNextId(pts[faceVerts[1]]);
437 faceIds->InsertNextId(pts[faceVerts[2]]);
439 aCellType = VTK_TRIANGLE;
440 if (faceVerts[3] >= 0)
442 faceIds->InsertNextId(pts[faceVerts[3]]);
444 aCellType = VTK_QUAD;
446 input->GetCellNeighbors(cellId, faceIds, cellIds);
447 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
448 (!allVisible && !cellVis[cellIds->GetId(0)]) )
450 for ( i=0; i < numFacePts; i++)
452 aNewPts[i] = pts[faceVerts[i]];
454 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
456 myVTK2ObjIds.push_back(cellId); //apo
458 outputCD->CopyData(cd,cellId,newCellId);
464 for (faceId = 0; faceId < 5; faceId++)
467 faceVerts = vtkPyramid::GetFaceArray(faceId);
468 faceIds->InsertNextId(pts[faceVerts[0]]);
469 faceIds->InsertNextId(pts[faceVerts[1]]);
470 faceIds->InsertNextId(pts[faceVerts[2]]);
472 aCellType = VTK_TRIANGLE;
473 if (faceVerts[3] >= 0)
475 faceIds->InsertNextId(pts[faceVerts[3]]);
477 aCellType = VTK_QUAD;
479 input->GetCellNeighbors(cellId, faceIds, cellIds);
480 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
481 (!allVisible && !cellVis[cellIds->GetId(0)]) )
483 for ( i=0; i < numFacePts; i++)
485 aNewPts[i] = pts[faceVerts[i]];
487 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
489 myVTK2ObjIds.push_back(cellId); //apo
491 outputCD->CopyData(cd,cellId,newCellId);
497 case VTK_QUADRATIC_EDGE:
498 case VTK_QUADRATIC_TRIANGLE:
499 case VTK_QUADRATIC_QUAD:
500 case VTK_QUADRATIC_TETRA:
501 case VTK_QUADRATIC_HEXAHEDRON:
503 break; //done with quadratic cells
509 if(MYDEBUG && myStoreMapping){
510 for(int i = 0, iEnd = myVTK2ObjIds.size(); i < iEnd; i++){
511 cout<<myVTK2ObjIds[i]<<", ";
516 // Update ourselves and release memory
518 //output->SetVerts(Verts);
520 //output->SetLines(Lines);
522 //output->SetPolys(Polys);
524 //output->SetStrips(Strips);
529 vtkDebugMacro(<<"Extracted " << input->GetNumberOfPoints() << " points,"
530 << output->GetNumberOfCells() << " cells.");
541 void VTKViewer_GeometryFilter::SetInside(int theShowInside){
542 if(myShowInside == theShowInside) return;
543 myShowInside = theShowInside;
546 int VTKViewer_GeometryFilter::GetInside(){