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>
61 //#define USE_ROBUST_TRIANGULATION
63 vtkCxxRevisionMacro(VTKViewer_GeometryFilter, "$Revision$");
64 vtkStandardNewMacro(VTKViewer_GeometryFilter);
66 VTKViewer_GeometryFilter
67 ::VTKViewer_GeometryFilter():
74 VTKViewer_GeometryFilter
75 ::~VTKViewer_GeometryFilter()
80 VTKViewer_GeometryFilter
83 vtkDataSet *input= this->GetInput();
84 vtkIdType numCells=input->GetNumberOfCells();
91 if (input->GetDataObjectType() == VTK_UNSTRUCTURED_GRID){
92 this->UnstructuredGridExecute();
95 vtkGeometryFilter::Execute();
100 VTKViewer_GeometryFilter
101 ::UnstructuredGridExecute()
103 vtkUnstructuredGrid *input= (vtkUnstructuredGrid *)this->GetInput();
104 vtkCellArray *Connectivity = input->GetCells();
106 if ( Connectivity == NULL )
108 vtkDebugMacro(<<"Nothing to extract");
117 vtkPoints *p = input->GetPoints();
118 vtkIdType numCells=input->GetNumberOfCells();
119 vtkPointData *pd = input->GetPointData();
120 vtkCellData *cd = input->GetCellData();
121 vtkPolyData *output = this->GetOutput();
122 vtkPointData *outputPD = output->GetPointData();
124 VTKViewer_OrderedTriangulator anOrderedTriangulator;
125 VTKViewer_DelaunayTriangulator aDelaunayTriangulator;
127 vtkCellData *outputCD = output->GetCellData();
128 vtkGenericCell *cell = vtkGenericCell::New();
130 vtkIdList *cellIds = vtkIdList::New();
131 vtkIdList *faceIds = vtkIdList::New();
135 int faceId, *faceVerts, numFacePts;
136 vtkFloatingPointType *x;
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);
164 // Determine nature of what we have to do
165 if ( (!this->CellClipping) && (!this->PointClipping) &&
166 (!this->ExtentClipping) )
174 cellVis = new char[numCells];
177 // Just pass points through, never merge
178 output->SetPoints(input->GetPoints());
179 outputPD->PassData(pd);
181 outputCD->CopyAllocate(cd,numCells,numCells/2);
183 output->Allocate(numCells/4+1,numCells);
185 // Loop over the cells determining what's visible
188 for (cellId=0, Connectivity->InitTraversal();
189 Connectivity->GetNextCell(npts,pts);
193 if ( this->CellClipping && cellId < this->CellMinimum ||
194 cellId > this->CellMaximum )
200 for (i=0; i < npts; i++)
202 x = p->GetPoint(pts[i]);
203 if ( (this->PointClipping && (pts[i] < this->PointMinimum ||
204 pts[i] > this->PointMaximum) ) ||
205 (this->ExtentClipping &&
206 (x[0] < this->Extent[0] || x[0] > this->Extent[1] ||
207 x[1] < this->Extent[2] || x[1] > this->Extent[3] ||
208 x[2] < this->Extent[4] || x[2] > this->Extent[5] )) )
212 }//point/extent clipping
214 }//if point clipping needs checking
216 }//if not all visible
218 // Loop over all cells now that visibility is known
219 // (Have to compute visibility first for 3D cell boundarys)
220 int progressInterval = numCells/20 + 1;
222 myVTK2ObjIds.clear();
223 myVTK2ObjIds.reserve(numCells);
225 for (cellId=0, Connectivity->InitTraversal();
226 Connectivity->GetNextCell(npts,pts);
229 //Progress and abort method support
230 if ( !(cellId % progressInterval) )
232 vtkDebugMacro(<<"Process cell #" << cellId);
233 this->UpdateProgress ((float)cellId/numCells);
236 // Handle ghost cells here. Another option was used cellVis array.
237 if (cellGhostLevels && cellGhostLevels[cellId] > updateLevel)
238 { // Do not create surfaces in outer ghost cells.
242 if (allVisible || cellVis[cellId]) //now if visible extract geometry
244 //special code for nonlinear cells - rarely occurs, so right now it
246 vtkIdType aCellType = input->GetCellType(cellId);
253 case VTK_POLY_VERTEX:
254 newCellId = output->InsertNextCell(aCellType,npts,pts);
256 myVTK2ObjIds.push_back(cellId); //apo
258 outputCD->CopyData(cd,cellId,newCellId);
263 newCellId = output->InsertNextCell(aCellType,npts,pts);
265 myVTK2ObjIds.push_back(cellId);
266 outputCD->CopyData(cd,cellId,newCellId);
272 newCellId = output->InsertNextCell(aCellType,npts,pts);
274 myVTK2ObjIds.push_back(cellId);
275 outputCD->CopyData(cd,cellId,newCellId);
278 case VTK_TRIANGLE_STRIP:
279 newCellId = output->InsertNextCell(aCellType,npts,pts);
281 myVTK2ObjIds.push_back(cellId);
282 outputCD->CopyData(cd,cellId,newCellId);
286 newCellId = output->InsertNextCell(aCellType,npts,pts);
288 myVTK2ObjIds.push_back(cellId);
289 outputCD->CopyData(cd,cellId,newCellId);
292 case VTK_CONVEX_POINT_SET: {
293 bool anIsOk = anOrderedTriangulator.Execute(input,
305 aDelaunayTriangulator.Execute(input,
320 for (faceId = 0; faceId < 4; faceId++)
323 faceVerts = vtkTetra::GetFaceArray(faceId);
324 faceIds->InsertNextId(pts[faceVerts[0]]);
325 faceIds->InsertNextId(pts[faceVerts[1]]);
326 faceIds->InsertNextId(pts[faceVerts[2]]);
327 aCellType = VTK_TRIANGLE;
329 input->GetCellNeighbors(cellId, faceIds, cellIds);
330 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside ||
331 (!allVisible && !cellVis[cellIds->GetId(0)]) )
333 for ( i=0; i < numFacePts; i++)
334 aNewPts[i] = pts[faceVerts[i]];
335 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
337 myVTK2ObjIds.push_back(cellId);
338 outputCD->CopyData(cd,cellId,newCellId);
344 for (faceId = 0; faceId < 6; faceId++)
347 faceVerts = vtkVoxel::GetFaceArray(faceId);
348 faceIds->InsertNextId(pts[faceVerts[0]]);
349 faceIds->InsertNextId(pts[faceVerts[1]]);
350 faceIds->InsertNextId(pts[faceVerts[2]]);
351 faceIds->InsertNextId(pts[faceVerts[3]]);
352 aCellType = VTK_QUAD;
354 input->GetCellNeighbors(cellId, faceIds, cellIds);
355 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside ||
356 (!allVisible && !cellVis[cellIds->GetId(0)]) )
358 for ( i=0; i < numFacePts; i++)
359 aNewPts[i] = pts[faceVerts[PixelConvert[i]]];
360 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
362 myVTK2ObjIds.push_back(cellId);
363 outputCD->CopyData(cd,cellId,newCellId);
368 case VTK_HEXAHEDRON: {
369 for (faceId = 0; faceId < 6; faceId++)
372 faceVerts = vtkHexahedron::GetFaceArray(faceId);
373 faceIds->InsertNextId(pts[faceVerts[0]]);
374 faceIds->InsertNextId(pts[faceVerts[1]]);
375 faceIds->InsertNextId(pts[faceVerts[2]]);
376 faceIds->InsertNextId(pts[faceVerts[3]]);
377 aCellType = VTK_QUAD;
379 input->GetCellNeighbors(cellId, faceIds, cellIds);
380 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside ||
381 (!allVisible && !cellVis[cellIds->GetId(0)]) )
383 for ( i=0; i < numFacePts; i++)
384 aNewPts[i] = pts[faceVerts[i]];
385 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
387 myVTK2ObjIds.push_back(cellId);
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]]);
401 aCellType = VTK_TRIANGLE;
403 if (faceVerts[3] >= 0)
405 faceIds->InsertNextId(pts[faceVerts[3]]);
406 aCellType = VTK_QUAD;
409 input->GetCellNeighbors(cellId, faceIds, cellIds);
410 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside ||
411 (!allVisible && !cellVis[cellIds->GetId(0)]) )
413 for ( i=0; i < numFacePts; i++)
414 aNewPts[i] = pts[faceVerts[i]];
415 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
417 myVTK2ObjIds.push_back(cellId);
418 outputCD->CopyData(cd,cellId,newCellId);
424 for (faceId = 0; faceId < 5; faceId++)
427 faceVerts = vtkPyramid::GetFaceArray(faceId);
428 faceIds->InsertNextId(pts[faceVerts[0]]);
429 faceIds->InsertNextId(pts[faceVerts[1]]);
430 faceIds->InsertNextId(pts[faceVerts[2]]);
431 aCellType = VTK_TRIANGLE;
433 if (faceVerts[3] >= 0)
435 faceIds->InsertNextId(pts[faceVerts[3]]);
436 aCellType = VTK_QUAD;
439 input->GetCellNeighbors(cellId, faceIds, cellIds);
440 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside ||
441 (!allVisible && !cellVis[cellIds->GetId(0)]) )
443 for ( i=0; i < numFacePts; i++)
444 aNewPts[i] = pts[faceVerts[i]];
445 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
447 myVTK2ObjIds.push_back(cellId);
448 outputCD->CopyData(cd,cellId,newCellId);
454 case VTK_QUADRATIC_EDGE:
455 case VTK_QUADRATIC_TRIANGLE:
456 case VTK_QUADRATIC_QUAD:
457 case VTK_QUADRATIC_TETRA:
458 case VTK_QUADRATIC_HEXAHEDRON:
459 if(!myIsWireframeMode){
460 input->GetCell(cellId,cell);
461 vtkIdList *pts = vtkIdList::New();
462 vtkPoints *coords = vtkPoints::New();
463 vtkIdList *cellIds = vtkIdList::New();
466 if ( cell->GetCellDimension() == 1 ) {
467 aCellType = VTK_LINE;
469 cell->Triangulate(0,pts,coords);
470 for (i=0; i < pts->GetNumberOfIds(); i+=2) {
471 aNewPts[0] = pts->GetId(i);
472 aNewPts[1] = pts->GetId(i+1);
473 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
475 myVTK2ObjIds.push_back(cellId);
476 outputCD->CopyData(cd,cellId,newCellId);
479 else if ( cell->GetCellDimension() == 2 ) {
480 aCellType = VTK_TRIANGLE;
482 cell->Triangulate(0,pts,coords);
483 for (i=0; i < pts->GetNumberOfIds(); i+=3) {
484 aNewPts[0] = pts->GetId(i);
485 aNewPts[1] = pts->GetId(i+1);
486 aNewPts[2] = pts->GetId(i+2);
487 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
489 myVTK2ObjIds.push_back(cellId);
490 outputCD->CopyData(cd,cellId,newCellId);
493 else //3D nonlinear cell
495 aCellType = VTK_TRIANGLE;
497 for (int j=0; j < cell->GetNumberOfFaces(); j++){
498 vtkCell *face = cell->GetFace(j);
499 input->GetCellNeighbors(cellId, face->PointIds, cellIds);
500 if ( cellIds->GetNumberOfIds() <= 0 || myShowInside ) {
501 face->Triangulate(0,pts,coords);
502 for (i=0; i < pts->GetNumberOfIds(); i+=3) {
503 aNewPts[0] = pts->GetId(i);
504 aNewPts[1] = pts->GetId(i+1);
505 aNewPts[2] = pts->GetId(i+2);
506 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
508 myVTK2ObjIds.push_back(cellId);
509 outputCD->CopyData(cd,cellId,newCellId);
520 case VTK_QUADRATIC_EDGE: {
521 aCellType = VTK_POLY_LINE;
528 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
530 myVTK2ObjIds.push_back(cellId);
532 outputCD->CopyData(cd,cellId,newCellId);
535 case VTK_QUADRATIC_TRIANGLE: {
536 aCellType = VTK_POLYGON;
546 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
548 myVTK2ObjIds.push_back(cellId);
550 outputCD->CopyData(cd,cellId,newCellId);
553 case VTK_QUADRATIC_QUAD: {
554 aCellType = VTK_POLYGON;
566 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
568 myVTK2ObjIds.push_back(cellId);
570 outputCD->CopyData(cd,cellId,newCellId);
573 case VTK_QUADRATIC_TETRA: {
574 aCellType = VTK_POLYGON;
577 //---------------------------------------------------------------
585 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
587 myVTK2ObjIds.push_back(cellId);
589 outputCD->CopyData(cd,cellId,newCellId);
591 //---------------------------------------------------------------
599 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
601 myVTK2ObjIds.push_back(cellId);
603 outputCD->CopyData(cd,cellId,newCellId);
605 //---------------------------------------------------------------
613 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
615 myVTK2ObjIds.push_back(cellId);
617 outputCD->CopyData(cd,cellId,newCellId);
619 //---------------------------------------------------------------
627 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
629 myVTK2ObjIds.push_back(cellId);
631 outputCD->CopyData(cd,cellId,newCellId);
635 case VTK_QUADRATIC_HEXAHEDRON: {
636 aCellType = VTK_POLYGON;
639 //---------------------------------------------------------------
643 aNewPts[3] = pts[17];
645 aNewPts[5] = pts[12];
647 aNewPts[7] = pts[16];
649 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
651 myVTK2ObjIds.push_back(cellId);
653 outputCD->CopyData(cd,cellId,newCellId);
655 //---------------------------------------------------------------
659 aNewPts[3] = pts[18];
661 aNewPts[5] = pts[13];
663 aNewPts[7] = pts[17];
665 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
667 myVTK2ObjIds.push_back(cellId);
669 outputCD->CopyData(cd,cellId,newCellId);
671 //---------------------------------------------------------------
673 aNewPts[1] = pts[10];
675 aNewPts[3] = pts[19];
677 aNewPts[5] = pts[14];
679 aNewPts[7] = pts[18];
681 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
683 myVTK2ObjIds.push_back(cellId);
685 outputCD->CopyData(cd,cellId,newCellId);
687 //---------------------------------------------------------------
689 aNewPts[1] = pts[11];
691 aNewPts[3] = pts[16];
693 aNewPts[5] = pts[15];
695 aNewPts[7] = pts[19];
697 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
699 myVTK2ObjIds.push_back(cellId);
701 outputCD->CopyData(cd,cellId,newCellId);
703 //---------------------------------------------------------------
709 aNewPts[5] = pts[10];
711 aNewPts[7] = pts[11];
713 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
715 myVTK2ObjIds.push_back(cellId);
717 outputCD->CopyData(cd,cellId,newCellId);
719 //---------------------------------------------------------------
721 aNewPts[1] = pts[12];
723 aNewPts[3] = pts[13];
725 aNewPts[5] = pts[14];
727 aNewPts[7] = pts[15];
729 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
731 myVTK2ObjIds.push_back(cellId);
733 outputCD->CopyData(cd,cellId,newCellId);
744 vtkDebugMacro(<<"Extracted " << input->GetNumberOfPoints() << " points,"
745 << output->GetNumberOfCells() << " cells.");
760 VTKViewer_GeometryFilter
761 ::SetInside(int theShowInside)
763 if(myShowInside == theShowInside)
766 myShowInside = theShowInside;
771 VTKViewer_GeometryFilter
779 VTKViewer_GeometryFilter
780 ::SetWireframeMode(int theIsWireframeMode)
782 if(myIsWireframeMode == theIsWireframeMode)
785 myIsWireframeMode = theIsWireframeMode;
790 VTKViewer_GeometryFilter
793 return myIsWireframeMode;
798 VTKViewer_GeometryFilter
799 ::SetStoreMapping(int theStoreMapping)
801 if(myStoreMapping == theStoreMapping)
804 myStoreMapping = theStoreMapping;
809 VTKViewer_GeometryFilter
812 return myStoreMapping;
816 vtkIdType VTKViewer_GeometryFilter::GetElemObjId(int theVtkID){
817 if(myVTK2ObjIds.empty() || theVtkID > myVTK2ObjIds.size()) return -1;
818 #if defined __GNUC_2__
819 return myVTK2ObjIds[theVtkID];
821 return myVTK2ObjIds.at(theVtkID);