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;
57 static int MYDEBUG = 0;
66 vtkCxxRevisionMacro(VTKViewer_GeometryFilter, "$Revision$");
67 vtkStandardNewMacro(VTKViewer_GeometryFilter);
69 VTKViewer_GeometryFilter::VTKViewer_GeometryFilter():
75 VTKViewer_GeometryFilter::~VTKViewer_GeometryFilter()
79 void VTKViewer_GeometryFilter::Execute()
81 vtkDataSet *input= this->GetInput();
82 vtkIdType numCells=input->GetNumberOfCells();
89 if (input->GetDataObjectType() == VTK_UNSTRUCTURED_GRID){
90 this->UnstructuredGridExecute();
93 vtkGeometryFilter::Execute();
97 void VTKViewer_GeometryFilter::SetStoreMapping(int theStoreMapping){
98 myStoreMapping = theStoreMapping;
103 vtkIdType VTKViewer_GeometryFilter::GetElemObjId(int theVtkID){
104 if(myVTK2ObjIds.empty() || theVtkID > myVTK2ObjIds.size()) return -1;
105 #if defined __GNUC_2__
106 return myVTK2ObjIds[theVtkID];
108 return myVTK2ObjIds.at(theVtkID);
113 void VTKViewer_GeometryFilter::UnstructuredGridExecute()
115 vtkUnstructuredGrid *input= (vtkUnstructuredGrid *)this->GetInput();
116 vtkCellArray *Connectivity = input->GetCells();
117 if (Connectivity == NULL) {return;}
123 vtkPoints *p = input->GetPoints();
124 vtkIdType numCells=input->GetNumberOfCells();
125 vtkPointData *pd = input->GetPointData();
126 vtkCellData *cd = input->GetCellData();
127 vtkPolyData *output = this->GetOutput();
128 vtkPointData *outputPD = output->GetPointData();
130 vtkCellData *outputCD = output->GetCellData();
131 //vtkCellArray *Verts, *Lines, *Polys, *Strips;
132 vtkIdList *cellIds, *faceIds;
135 int faceId, *faceVerts, numFacePts;
137 int PixelConvert[4], aNewPts[VTK_CELL_SIZE];
139 unsigned char updateLevel = (unsigned char)(output->GetUpdateGhostLevel());
140 unsigned char *cellGhostLevels = 0;
147 vtkDebugMacro(<<"Executing geometry filter for unstructured grid input");
149 vtkDataArray* temp = 0;
152 temp = cd->GetArray("vtkGhostLevels");
154 if ( (!temp) || (temp->GetDataType() != VTK_UNSIGNED_CHAR)
155 || (temp->GetNumberOfComponents() != 1))
157 vtkDebugMacro("No appropriate ghost levels field available.");
161 cellGhostLevels = ((vtkUnsignedCharArray*)temp)->GetPointer(0);
165 if ( Connectivity == NULL )
167 vtkDebugMacro(<<"Nothing to extract");
171 // Determine nature of what we have to do
172 cellIds = vtkIdList::New();
173 faceIds = vtkIdList::New();
174 if ( (!this->CellClipping) && (!this->PointClipping) &&
175 (!this->ExtentClipping) )
183 cellVis = new char[numCells];
186 // Just pass points through, never merge
187 output->SetPoints(input->GetPoints());
188 outputPD->PassData(pd);
190 outputCD->CopyAllocate(cd,numCells,numCells/2);
192 output->Allocate(numCells/4+1,numCells);
193 //Verts = vtkCellArray::New();
194 //Verts->Allocate(numCells/4+1,numCells);
195 //Lines = vtkCellArray::New();
196 //Lines->Allocate(numCells/4+1,numCells);
197 //Polys = vtkCellArray::New();
198 //Polys->Allocate(numCells/4+1,numCells);
199 //Strips = vtkCellArray::New();
200 //Strips->Allocate(numCells/4+1,numCells);
202 // Loop over the cells determining what's visible
205 for (cellId=0, Connectivity->InitTraversal();
206 Connectivity->GetNextCell(npts,pts);
210 if ( this->CellClipping && cellId < this->CellMinimum ||
211 cellId > this->CellMaximum )
217 for (i=0; i < npts; i++)
219 x = p->GetPoint(pts[i]);
220 if ( (this->PointClipping && (pts[i] < this->PointMinimum ||
221 pts[i] > this->PointMaximum) ) ||
222 (this->ExtentClipping &&
223 (x[0] < this->Extent[0] || x[0] > this->Extent[1] ||
224 x[1] < this->Extent[2] || x[1] > this->Extent[3] ||
225 x[2] < this->Extent[4] || x[2] > this->Extent[5] )) )
229 }//point/extent clipping
231 }//if point clipping needs checking
233 }//if not all visible
235 // Loop over all cells now that visibility is known
236 // (Have to compute visibility first for 3D cell boundarys)
237 int progressInterval = numCells/20 + 1;
239 myVTK2ObjIds.clear();
240 myVTK2ObjIds.reserve(numCells);
242 for (cellId=0, Connectivity->InitTraversal();
243 Connectivity->GetNextCell(npts,pts);
246 //Progress and abort method support
247 if ( !(cellId % progressInterval) )
249 vtkDebugMacro(<<"Process cell #" << cellId);
250 this->UpdateProgress ((float)cellId/numCells);
253 // Handle ghost cells here. Another option was used cellVis array.
254 if (cellGhostLevels && cellGhostLevels[cellId] > updateLevel)
255 { // Do not create surfaces in outer ghost cells.
259 if (allVisible || cellVis[cellId]) //now if visible extract geometry
261 //special code for nonlinear cells - rarely occurs, so right now it
263 vtkIdType aCellType = input->GetCellType(cellId);
270 case VTK_POLY_VERTEX:
271 newCellId = output->InsertNextCell(aCellType,npts,pts);
273 myVTK2ObjIds.push_back(cellId); //apo
275 outputCD->CopyData(cd,cellId,newCellId);
280 newCellId = output->InsertNextCell(aCellType,npts,pts);
282 myVTK2ObjIds.push_back(cellId); //apo
284 outputCD->CopyData(cd,cellId,newCellId);
290 newCellId = output->InsertNextCell(aCellType,npts,pts);
292 myVTK2ObjIds.push_back(cellId); //apo
294 outputCD->CopyData(cd,cellId,newCellId);
297 case VTK_TRIANGLE_STRIP:
298 newCellId = output->InsertNextCell(aCellType,npts,pts);
300 myVTK2ObjIds.push_back(cellId); //apo
302 outputCD->CopyData(cd,cellId,newCellId);
306 newCellId = output->InsertNextCell(aCellType,npts,pts);
308 myVTK2ObjIds.push_back(cellId); //apo
310 outputCD->CopyData(cd,cellId,newCellId);
313 case VTK_CONVEX_POINT_SET:{
314 TCellArray tmpCellArray;
316 CONVEX_TOOL::GetPolygonalFaces(input,cellId,tmpCellArray); // "VTKViewer_ConvexTool.cxx"
317 } catch (const std::exception& theExc){
318 cout << __FILE__ << "[" << __LINE__ << "] " << "Exception:" << theExc.what() << endl;
320 cout << __FILE__ << "[" << __LINE__ << "] " << "Exception was occured"<< endl;
322 TCellArray::iterator aFaceIter = tmpCellArray.begin();
323 for (; aFaceIter!=tmpCellArray.end(); aFaceIter++){
324 TCell cell = aFaceIter->second;
325 numFacePts = cell.size();
327 aCellType = VTK_POLYGON;
328 else if(numFacePts == 3)
329 aCellType = VTK_TRIANGLE;
330 else if(numFacePts<3)
333 for ( i=0; i < numFacePts; i++)
335 aNewPts[i] = cell[i];
337 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
339 myVTK2ObjIds.push_back(cellId);
341 outputCD->CopyData(cd,cellId,newCellId);
346 for (faceId = 0; faceId < 4; faceId++)
349 faceVerts = vtkTetra::GetFaceArray(faceId);
350 faceIds->InsertNextId(pts[faceVerts[0]]);
351 faceIds->InsertNextId(pts[faceVerts[1]]);
352 faceIds->InsertNextId(pts[faceVerts[2]]);
354 aCellType = VTK_TRIANGLE;
355 input->GetCellNeighbors(cellId, faceIds, cellIds);
356 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
357 (!allVisible && !cellVis[cellIds->GetId(0)]) )
359 for ( i=0; i < numFacePts; i++)
361 aNewPts[i] = pts[faceVerts[i]];
363 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
365 myVTK2ObjIds.push_back(cellId); //apo
367 outputCD->CopyData(cd,cellId,newCellId);
373 for (faceId = 0; faceId < 6; faceId++)
376 faceVerts = vtkVoxel::GetFaceArray(faceId);
377 faceIds->InsertNextId(pts[faceVerts[0]]);
378 faceIds->InsertNextId(pts[faceVerts[1]]);
379 faceIds->InsertNextId(pts[faceVerts[2]]);
380 faceIds->InsertNextId(pts[faceVerts[3]]);
382 aCellType = VTK_QUAD;
383 input->GetCellNeighbors(cellId, faceIds, cellIds);
384 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
385 (!allVisible && !cellVis[cellIds->GetId(0)]) )
387 for ( i=0; i < numFacePts; i++)
389 aNewPts[i] = pts[faceVerts[PixelConvert[i]]];
391 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
393 myVTK2ObjIds.push_back(cellId); //apo
395 outputCD->CopyData(cd,cellId,newCellId);
400 case VTK_HEXAHEDRON: {
401 for (faceId = 0; faceId < 6; faceId++)
404 faceVerts = vtkHexahedron::GetFaceArray(faceId);
405 faceIds->InsertNextId(pts[faceVerts[0]]);
406 faceIds->InsertNextId(pts[faceVerts[1]]);
407 faceIds->InsertNextId(pts[faceVerts[2]]);
408 faceIds->InsertNextId(pts[faceVerts[3]]);
410 aCellType = VTK_QUAD;
411 input->GetCellNeighbors(cellId, faceIds, cellIds);
412 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
413 (!allVisible && !cellVis[cellIds->GetId(0)]) )
415 for ( i=0; i < numFacePts; i++)
417 aNewPts[i] = pts[faceVerts[i]];
419 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
421 myVTK2ObjIds.push_back(cellId); //apo
423 outputCD->CopyData(cd,cellId,newCellId);
429 for (faceId = 0; faceId < 5; faceId++)
432 faceVerts = vtkWedge::GetFaceArray(faceId);
433 faceIds->InsertNextId(pts[faceVerts[0]]);
434 faceIds->InsertNextId(pts[faceVerts[1]]);
435 faceIds->InsertNextId(pts[faceVerts[2]]);
437 aCellType = VTK_TRIANGLE;
438 if (faceVerts[3] >= 0)
440 faceIds->InsertNextId(pts[faceVerts[3]]);
442 aCellType = VTK_QUAD;
444 input->GetCellNeighbors(cellId, faceIds, cellIds);
445 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
446 (!allVisible && !cellVis[cellIds->GetId(0)]) )
448 for ( i=0; i < numFacePts; i++)
450 aNewPts[i] = pts[faceVerts[i]];
452 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
454 myVTK2ObjIds.push_back(cellId); //apo
456 outputCD->CopyData(cd,cellId,newCellId);
462 for (faceId = 0; faceId < 5; faceId++)
465 faceVerts = vtkPyramid::GetFaceArray(faceId);
466 faceIds->InsertNextId(pts[faceVerts[0]]);
467 faceIds->InsertNextId(pts[faceVerts[1]]);
468 faceIds->InsertNextId(pts[faceVerts[2]]);
470 aCellType = VTK_TRIANGLE;
471 if (faceVerts[3] >= 0)
473 faceIds->InsertNextId(pts[faceVerts[3]]);
475 aCellType = VTK_QUAD;
477 input->GetCellNeighbors(cellId, faceIds, cellIds);
478 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside == 1 ||
479 (!allVisible && !cellVis[cellIds->GetId(0)]) )
481 for ( i=0; i < numFacePts; i++)
483 aNewPts[i] = pts[faceVerts[i]];
485 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
487 myVTK2ObjIds.push_back(cellId); //apo
489 outputCD->CopyData(cd,cellId,newCellId);
495 case VTK_QUADRATIC_EDGE: {
496 newCellId = output->InsertNextCell(VTK_POLY_LINE,npts,pts);
498 myVTK2ObjIds.push_back(cellId);
500 outputCD->CopyData(cd,cellId,newCellId);
504 case VTK_QUADRATIC_TRIANGLE: {
506 aCellType = VTK_POLYGON;
515 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
517 myVTK2ObjIds.push_back(cellId);
519 outputCD->CopyData(cd,cellId,newCellId);
522 case VTK_QUADRATIC_QUAD: {
524 aCellType = VTK_POLYGON;
535 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
537 myVTK2ObjIds.push_back(cellId);
539 outputCD->CopyData(cd,cellId,newCellId);
542 case VTK_QUADRATIC_TETRA: {
544 aCellType = VTK_POLYGON;
555 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
557 myVTK2ObjIds.push_back(cellId);
559 outputCD->CopyData(cd,cellId,newCellId);
562 case VTK_QUADRATIC_HEXAHEDRON: {
564 aCellType = VTK_POLYGON;
566 //---------------------------------------------------------------
570 aNewPts[3] = pts[17];
572 aNewPts[5] = pts[12];
574 aNewPts[7] = pts[16];
576 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
578 myVTK2ObjIds.push_back(cellId);
580 outputCD->CopyData(cd,cellId,newCellId);
582 //---------------------------------------------------------------
586 aNewPts[3] = pts[18];
588 aNewPts[5] = pts[13];
590 aNewPts[7] = pts[17];
592 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
594 myVTK2ObjIds.push_back(cellId);
596 outputCD->CopyData(cd,cellId,newCellId);
598 //---------------------------------------------------------------
600 aNewPts[1] = pts[10];
602 aNewPts[3] = pts[19];
604 aNewPts[5] = pts[14];
606 aNewPts[7] = pts[18];
608 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
610 myVTK2ObjIds.push_back(cellId);
612 outputCD->CopyData(cd,cellId,newCellId);
614 //---------------------------------------------------------------
616 aNewPts[1] = pts[11];
618 aNewPts[3] = pts[16];
620 aNewPts[5] = pts[15];
622 aNewPts[7] = pts[19];
624 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
626 myVTK2ObjIds.push_back(cellId);
628 outputCD->CopyData(cd,cellId,newCellId);
630 //---------------------------------------------------------------
636 aNewPts[5] = pts[10];
638 aNewPts[7] = pts[11];
640 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
642 myVTK2ObjIds.push_back(cellId);
644 outputCD->CopyData(cd,cellId,newCellId);
646 //---------------------------------------------------------------
648 aNewPts[1] = pts[12];
650 aNewPts[3] = pts[13];
652 aNewPts[5] = pts[14];
654 aNewPts[7] = pts[15];
656 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
658 myVTK2ObjIds.push_back(cellId);
660 outputCD->CopyData(cd,cellId,newCellId);
668 if(MYDEBUG && myStoreMapping){
669 for(int i = 0, iEnd = myVTK2ObjIds.size(); i < iEnd; i++){
670 cout<<myVTK2ObjIds[i]<<", ";
675 // Update ourselves and release memory
677 //output->SetVerts(Verts);
679 //output->SetLines(Lines);
681 //output->SetPolys(Polys);
683 //output->SetStrips(Strips);
688 vtkDebugMacro(<<"Extracted " << input->GetNumberOfPoints() << " points,"
689 << output->GetNumberOfCells() << " cells.");
700 void VTKViewer_GeometryFilter::SetInside(int theShowInside){
701 if(myShowInside == theShowInside) return;
702 myShowInside = theShowInside;
705 int VTKViewer_GeometryFilter::GetInside(){