1 // Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 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, or (at your option) any later version.
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.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : VTKViewer_GeometryFilter.cxx
24 // Author : Michael ZORIN
27 #include "VTKViewer_GeometryFilter.h"
28 #include "VTKViewer_ConvexTool.h"
29 #include "VTKViewer_ArcBuilder.h"
31 #include <vtkCellArray.h>
32 #include <vtkCellData.h>
33 #include <vtkGenericCell.h>
34 #include <vtkHexagonalPrism.h>
35 #include <vtkHexahedron.h>
36 #include <vtkInformation.h>
37 #include <vtkInformationVector.h>
38 #include <vtkMergePoints.h>
39 #include <vtkObjectFactory.h>
40 #include <vtkPointData.h>
41 #include <vtkPolyData.h>
42 #include <vtkPolygon.h>
43 #include <vtkPyramid.h>
44 #include <vtkSmartPointer.h>
45 #include <vtkStaticCellLinks.h>
46 #include <vtkStructuredGrid.h>
48 #include <vtkUnsignedCharArray.h>
49 #include <vtkUnstructuredGrid.h>
50 #include <vtkVersion.h>
60 #include "utilities.h"
68 #define VTK_XVERSION (VTK_MAJOR_VERSION*10000+VTK_MINOR_VERSION*100+VTK_BUILD_VERSION)
71 //#define USE_ROBUST_TRIANGULATION
73 ///////////////////////////////////////////////////////////////////////////////////////////////
74 // VSR 26/10/2012: fix of regression (issue 21924) - increased memory consumption
75 // for displaying of 3d elements, introduced by fix for issue 20314.
77 // The macro SHOW_COINCIDING_3D_PAL20314, when defined, allows correct visualization of
78 // coincident 3d elements but causes substantial increasing of memory consumption, as all 3d
79 // elements are always shown, even if they are totally covered by surrounding faces.
80 // If this macro is not defined (commented), the behaviour is defined by another macro -
81 // SHOW_COINCIDING_3D_PAL21924, as follows:
82 // - If SHOW_COINCIDING_3D_PAL21924 is defined, an alternative solution for computing
83 // visibility of 3d elements is used; this solution allows to fix problem with visibility
84 // of coinciding 3d elements in most cases (though some cases might not work), while not
85 // causing significant increasing of memory consumption.
86 // - If SHOW_COINCIDING_3D_PAL21924 is not defined (commented), coinciding 3d elements are
87 // not shown at all (this corresponds to the state before issue 20314 fixing).
88 ///////////////////////////////////////////////////////////////////////////////////////////////
89 //#define SHOW_COINCIDING_3D_PAL20314
90 #ifndef SHOW_COINCIDING_3D_PAL20314
91 #define SHOW_COINCIDING_3D_PAL21924
93 ///////////////////////////////////////////////////////////////////////////////////////////////
95 vtkStandardNewMacro(VTKViewer_GeometryFilter)
97 VTKViewer_GeometryFilter
98 ::VTKViewer_GeometryFilter():
101 myIsWireframeMode(0),
102 myAppendCoincident3D(0),
108 VTKViewer_GeometryFilter
109 ::~VTKViewer_GeometryFilter()
113 * \brief Return true for only one volume including a given edge
114 * \param [in] id1 - 1st edge end
115 * \param [in] id2 - second edge end
116 * \param [in] cellId - volume ID
117 * \param [in] input - the grid
119 static inline bool toShowEdge( vtkIdType id1, vtkIdType id2, vtkIdType cellId, vtkUnstructuredGrid* input )
121 // return true if the given cell is the 1st among cells including the edge
122 vtkStaticCellLinks * links = static_cast<vtkStaticCellLinks *>(input->GetCellLinks());
125 links = static_cast<vtkStaticCellLinks *>(input->GetCellLinks());
128 std::swap( id1, id2 );
129 vtkIdType *cells = links->GetCells( id1 );
131 // among cells, look for a cell including the edge
132 vtkIdType npts, iCell = 0;
133 vtkIdType const *cellPts;
137 if ( cells[iCell] == cellId )
139 input->GetCellPoints( cells[iCell], npts, cellPts );
140 for ( vtkIdType i = 0; i < npts && !found; ++i )
141 found = ( cellPts[i] == id2 );
144 return ( cells[iCell] == cellId );
148 VTKViewer_GeometryFilter
150 vtkInformation *request,
151 vtkInformationVector **inputVector,
152 vtkInformationVector *outputVector)
154 // get the info objects
155 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
156 vtkInformation *outInfo = outputVector->GetInformationObject(0);
158 // get the input and ouptut
159 vtkDataSet *input = vtkDataSet::SafeDownCast(
160 inInfo->Get(vtkDataObject::DATA_OBJECT()));
161 vtkPolyData *output = vtkPolyData::SafeDownCast(
162 outInfo->Get(vtkDataObject::DATA_OBJECT()));
164 vtkIdType numCells=input->GetNumberOfCells();
171 if (input->GetDataObjectType() == VTK_UNSTRUCTURED_GRID){
172 return this->UnstructuredGridExecute(input, output, outInfo);
174 return Superclass::RequestData(request,inputVector,outputVector);
180 VTKViewer_GeometryFilter
181 ::UnstructuredGridExecute(vtkDataSet *dataSetInput,
183 vtkInformation */*outInfo*/)
185 vtkUnstructuredGrid *input= (vtkUnstructuredGrid *)dataSetInput;
186 vtkCellArray *Connectivity = input->GetCells();
188 if ( Connectivity == NULL )
190 vtkDebugMacro(<<"Nothing to extract");
198 vtkIdType const *pts = 0;
199 vtkPoints *p = input->GetPoints();
200 vtkIdType numCells=input->GetNumberOfCells();
201 vtkPointData *pd = input->GetPointData();
202 vtkCellData *cd = input->GetCellData();
203 vtkPointData *outputPD = output->GetPointData();
205 VTKViewer_OrderedTriangulator anOrderedTriangulator;
206 VTKViewer_DelaunayTriangulator aDelaunayTriangulator;
208 vtkCellData *outputCD = output->GetCellData();
209 vtkGenericCell *cell = vtkGenericCell::New();
211 vtkIdList *cellIds = vtkIdList::New();
212 vtkIdList *faceIds = vtkIdList::New();
213 vtkIdList *cellIdsTmp = vtkIdList::New();
214 vtkIdList *faceIdsTmp = vtkIdList::New();
215 std::set< vtkIdType > midPoints;
219 int faceId, numFacePts;
221 vtkIdType PixelConvert[4];
222 // Change the type from int to vtkIdType in order to avoid compilation errors while using VTK
223 // from ParaView-3.4.0 compiled on 64-bit Debian platform with VTK_USE_64BIT_IDS = ON
224 vtkIdType aNewPts[VTK_CELL_SIZE];
226 unsigned char updateLevel = (unsigned char)(GetUpdateGhostLevel());
227 unsigned char *cellGhostLevels = 0;
234 vtkDebugMacro(<<"Executing geometry filter for unstructured grid input");
236 vtkDataArray* temp = 0;
239 temp = cd->GetArray("vtkGhostLevels");
241 if ( (!temp) || (temp->GetDataType() != VTK_UNSIGNED_CHAR)
242 || (temp->GetNumberOfComponents() != 1))
244 vtkDebugMacro("No appropriate ghost levels field available.");
248 cellGhostLevels = ((vtkUnsignedCharArray*)temp)->GetPointer(0);
251 // Determine nature of what we have to do
252 if ( (!this->CellClipping) && (!this->PointClipping) &&
253 (!this->ExtentClipping) )
261 cellVis = new char[numCells];
264 bool buildArcs = false;
267 // check if there are quadratic 1D or 2D elements
268 bool hasQuad1D2D = false;
269 if ( vtkUnsignedCharArray* types = input->GetCellTypesArray() )
271 std::set<vtkIdType> quad1D2DTypes;
272 quad1D2DTypes.insert( VTK_QUADRATIC_EDGE );
273 quad1D2DTypes.insert( VTK_QUADRATIC_TRIANGLE );
274 quad1D2DTypes.insert( VTK_BIQUADRATIC_TRIANGLE );
275 quad1D2DTypes.insert( VTK_QUADRATIC_QUAD );
276 quad1D2DTypes.insert( VTK_BIQUADRATIC_QUAD );
277 quad1D2DTypes.insert( VTK_QUADRATIC_POLYGON );
279 for ( int i = 0; i < types->GetNumberOfTuples() && !hasQuad1D2D; ++i )
280 hasQuad1D2D = quad1D2DTypes.count( types->GetValue(i) );
282 buildArcs = hasQuad1D2D;
286 // Issue 0020115: [CEA 308] Quadratic elements visualization
287 // Fix of remark described in note 0005222 - SIGSEGV
288 vtkPoints* outputPoints = vtkPoints::New();
289 outputPoints->DeepCopy(input->GetPoints());
290 output->SetPoints(outputPoints);
291 outputPoints->Delete();
295 output->SetPoints(input->GetPoints());
298 outputPD->PassData(pd);
300 outputCD->CopyAllocate(cd,numCells,numCells/2);
302 output->Allocate(numCells/4+1,numCells);
304 // Loop over the cells determining what's visible
307 for (cellId=0, Connectivity->InitTraversal();
308 Connectivity->GetNextCell(npts,pts);
312 if ( ( this->CellClipping && cellId < this->CellMinimum ) ||
313 cellId > this->CellMaximum )
319 for (i=0; i < npts; i++)
321 x = p->GetPoint(pts[i]);
322 if ( ( ( ( this->PointClipping && (pts[i] < this->PointMinimum ) ) ||
323 pts[i] > this->PointMaximum) ) ||
324 ( this->ExtentClipping &&
325 ( x[0] < this->Extent[0] || x[0] > this->Extent[1] ||
326 x[1] < this->Extent[2] || x[1] > this->Extent[3] ||
327 x[2] < this->Extent[4] || x[2] > this->Extent[5] )) )
331 }//point/extent clipping
333 }//if point clipping needs checking
335 }//if not all visible
337 if ( input->GetCellLinks() )
340 // Loop over all cells now that visibility is known
341 // (Have to compute visibility first for 3D cell boundaries)
342 int progressInterval = numCells/20 + 1;
343 TMapOfVectorId aDimension2VTK2ObjIds;
344 if ( myStoreMapping )
345 aDimension2VTK2ObjIds.resize( 3 ); // max dimension is 2
347 for (cellId=0, Connectivity->InitTraversal();
348 Connectivity->GetNextCell(npts,pts);
351 //Progress and abort method support
352 if ( !(cellId % progressInterval) )
354 vtkDebugMacro(<<"Process cell #" << cellId);
355 this->UpdateProgress ((float)cellId/numCells);
358 // Handle ghost cells here. Another option was used cellVis array.
359 if (cellGhostLevels && cellGhostLevels[cellId] > updateLevel)
360 { // Do not create surfaces in outer ghost cells.
364 if (allVisible || cellVis[cellId]) //now if visible extract geometry
366 //special code for nonlinear cells - rarely occurs, so right now it
368 vtkIdType aCellType = input->GetCellType(cellId);
375 case VTK_POLY_VERTEX:
376 newCellId = output->InsertNextCell(aCellType,npts,pts);
378 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
380 outputCD->CopyData(cd,cellId,newCellId);
385 newCellId = output->InsertNextCell(aCellType,npts,pts);
387 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
388 outputCD->CopyData(cd,cellId,newCellId);
394 newCellId = output->InsertNextCell(aCellType,npts,pts);
396 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
397 outputCD->CopyData(cd,cellId,newCellId);
400 case VTK_TRIANGLE_STRIP:
401 newCellId = output->InsertNextCell(aCellType,npts,pts);
403 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
404 outputCD->CopyData(cd,cellId,newCellId);
408 newCellId = output->InsertNextCell(aCellType,npts,pts);
410 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
411 outputCD->CopyData(cd,cellId,newCellId);
414 case VTK_CONVEX_POINT_SET: {
415 bool anIsOk = anOrderedTriangulator.Execute(input,
420 GetAppendCoincident3D(),
426 aDimension2VTK2ObjIds,
429 aDelaunayTriangulator.Execute(input,
434 GetAppendCoincident3D(),
440 aDimension2VTK2ObjIds,
449 aCellType = VTK_LINE;
450 for ( int edgeID = 0; edgeID < 6; ++edgeID )
452 const vtkIdType *edgeVerts = vtkTetra::GetEdgeArray( edgeID );
453 if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
455 aNewPts[0] = pts[edgeVerts[0]];
456 aNewPts[1] = pts[edgeVerts[1]];
457 newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
459 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
460 outputCD->CopyData(cd,cellId,newCellId);
467 #ifdef SHOW_COINCIDING_3D_PAL21924
468 faceIdsTmp->SetNumberOfIds( npts );
469 for ( int ai = 0; ai < npts; ai++ )
470 faceIdsTmp->SetId( ai, pts[ai] );
471 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
473 aCellType = VTK_TRIANGLE;
475 for (faceId = 0; faceId < 4; faceId++)
478 const vtkIdType *faceVerts = vtkTetra::GetFaceArray(faceId);
479 faceIds->InsertNextId(pts[faceVerts[0]]);
480 faceIds->InsertNextId(pts[faceVerts[1]]);
481 faceIds->InsertNextId(pts[faceVerts[2]]);
482 input->GetCellNeighbors(cellId, faceIds, cellIds);
483 int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
484 #ifdef SHOW_COINCIDING_3D_PAL21924
485 bool process = nbNeighbors <= 0;
487 bool process = nbNeighbors <= 0 || GetAppendCoincident3D();
489 if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
491 for ( i=0; i < numFacePts; i++)
492 aNewPts[i] = pts[faceVerts[i]];
493 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
495 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
496 outputCD->CopyData(cd,cellId,newCellId);
506 aCellType = VTK_LINE;
507 for ( int edgeID = 0; edgeID < 12; ++edgeID )
509 const vtkIdType *edgeVerts = vtkVoxel::GetEdgeArray( edgeID );
510 if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
512 aNewPts[0] = pts[edgeVerts[0]];
513 aNewPts[1] = pts[edgeVerts[1]];
514 newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
516 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
517 outputCD->CopyData(cd,cellId,newCellId);
524 #ifdef SHOW_COINCIDING_3D_PAL21924
525 faceIdsTmp->SetNumberOfIds( npts );
526 for ( int ai = 0; ai < npts; ai++ )
527 faceIdsTmp->SetId( ai, pts[ai] );
528 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
530 for (faceId = 0; faceId < 6; faceId++)
533 const vtkIdType*faceVerts = vtkVoxel::GetFaceArray(faceId);
534 faceIds->InsertNextId(pts[faceVerts[0]]);
535 faceIds->InsertNextId(pts[faceVerts[1]]);
536 faceIds->InsertNextId(pts[faceVerts[2]]);
537 faceIds->InsertNextId(pts[faceVerts[3]]);
538 aCellType = VTK_QUAD;
540 input->GetCellNeighbors(cellId, faceIds, cellIds);
541 int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
542 #ifdef SHOW_COINCIDING_3D_PAL21924
543 bool process = nbNeighbors <= 0;
545 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
547 if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
549 for ( i=0; i < numFacePts; i++)
550 aNewPts[i] = pts[faceVerts[PixelConvert[i]]];
551 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
553 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
554 outputCD->CopyData(cd,cellId,newCellId);
564 aCellType = VTK_LINE;
565 for ( int edgeID = 0; edgeID < 12; ++edgeID )
567 const vtkIdType *edgeVerts = vtkHexahedron::GetEdgeArray( edgeID );
568 if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
570 aNewPts[0] = pts[edgeVerts[0]];
571 aNewPts[1] = pts[edgeVerts[1]];
572 newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
574 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
575 outputCD->CopyData(cd,cellId,newCellId);
582 #ifdef SHOW_COINCIDING_3D_PAL21924
583 faceIdsTmp->SetNumberOfIds( npts );
584 for ( int ai = 0; ai < npts; ai++ )
585 faceIdsTmp->SetId( ai, pts[ai] );
586 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
588 aCellType = VTK_QUAD;
590 for (faceId = 0; faceId < 6; faceId++)
593 const vtkIdType *faceVerts = vtkHexahedron::GetFaceArray(faceId);
594 faceIds->InsertNextId(pts[faceVerts[0]]);
595 faceIds->InsertNextId(pts[faceVerts[1]]);
596 faceIds->InsertNextId(pts[faceVerts[2]]);
597 faceIds->InsertNextId(pts[faceVerts[3]]);
598 input->GetCellNeighbors(cellId, faceIds, cellIds);
599 int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
600 #ifdef SHOW_COINCIDING_3D_PAL21924
601 bool process = nbNeighbors <= 0;
603 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
605 if ( process || (!allVisible && !cellVis[cellIds->GetId(0)]) )
607 for ( i=0; i < numFacePts; i++)
608 aNewPts[i] = pts[faceVerts[i]];
609 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
611 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
612 outputCD->CopyData(cd,cellId,newCellId);
622 aCellType = VTK_LINE;
623 for ( int edgeID = 0; edgeID < 9; ++edgeID )
625 const vtkIdType *edgeVerts = vtkWedge::GetEdgeArray( edgeID );
626 if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
628 aNewPts[0] = pts[edgeVerts[0]];
629 aNewPts[1] = pts[edgeVerts[1]];
630 newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
632 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
633 outputCD->CopyData(cd,cellId,newCellId);
640 #ifdef SHOW_COINCIDING_3D_PAL21924
641 faceIdsTmp->SetNumberOfIds( npts );
642 for ( int ai = 0; ai < npts; ai++ )
643 faceIdsTmp->SetId( ai, pts[ai] );
644 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
646 for (faceId = 0; faceId < 5; faceId++)
649 const vtkIdType *faceVerts = vtkWedge::GetFaceArray(faceId);
650 faceIds->InsertNextId(pts[faceVerts[0]]);
651 faceIds->InsertNextId(pts[faceVerts[1]]);
652 faceIds->InsertNextId(pts[faceVerts[2]]);
653 aCellType = VTK_TRIANGLE;
655 if (faceVerts[3] >= 0)
657 faceIds->InsertNextId(pts[faceVerts[3]]);
658 aCellType = VTK_QUAD;
661 input->GetCellNeighbors(cellId, faceIds, cellIds);
662 int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
663 #ifdef SHOW_COINCIDING_3D_PAL21924
664 bool process = nbNeighbors <= 0;
666 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
668 if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
670 for ( i=0; i < numFacePts; i++)
671 aNewPts[i] = pts[faceVerts[i]];
672 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
674 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
675 outputCD->CopyData(cd,cellId,newCellId);
681 case VTK_HEXAGONAL_PRISM:
685 aCellType = VTK_LINE;
686 for ( int edgeID = 0; edgeID < 18; ++edgeID )
688 const vtkIdType *edgeVerts = vtkHexagonalPrism::GetEdgeArray( edgeID );
689 if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
691 aNewPts[0] = pts[edgeVerts[0]];
692 aNewPts[1] = pts[edgeVerts[1]];
693 newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
695 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
696 outputCD->CopyData(cd,cellId,newCellId);
703 #ifdef SHOW_COINCIDING_3D_PAL21924
704 faceIdsTmp->SetNumberOfIds( npts );
705 for ( int ai = 0; ai < npts; ai++ )
706 faceIdsTmp->SetId( ai, pts[ai] );
707 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
709 for (faceId = 0; faceId < 8; faceId++)
711 const vtkIdType *faceVerts = vtkHexagonalPrism::GetFaceArray(faceId);
713 faceIds->InsertNextId(pts[faceVerts[0]]);
714 faceIds->InsertNextId(pts[faceVerts[1]]);
715 faceIds->InsertNextId(pts[faceVerts[2]]);
716 faceIds->InsertNextId(pts[faceVerts[3]]);
717 aCellType = VTK_QUAD;
719 if (faceVerts[5] >= 0)
721 faceIds->InsertNextId(pts[faceVerts[4]]);
722 faceIds->InsertNextId(pts[faceVerts[5]]);
723 aCellType = VTK_POLYGON;
726 input->GetCellNeighbors(cellId, faceIds, cellIds);
727 int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
728 #ifdef SHOW_COINCIDING_3D_PAL21924
729 bool process = nbNeighbors <= 0;
731 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
733 if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
735 for ( i=0; i < numFacePts; i++)
736 aNewPts[i] = pts[faceVerts[i]];
737 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
739 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
740 outputCD->CopyData(cd,cellId,newCellId);
750 aCellType = VTK_LINE;
751 for ( int edgeID = 0; edgeID < 8; ++edgeID )
753 const vtkIdType *edgeVerts = vtkPyramid::GetEdgeArray( edgeID );
754 if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
756 aNewPts[0] = pts[edgeVerts[0]];
757 aNewPts[1] = pts[edgeVerts[1]];
758 newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
760 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
761 outputCD->CopyData(cd,cellId,newCellId);
768 #ifdef SHOW_COINCIDING_3D_PAL21924
769 faceIdsTmp->SetNumberOfIds( npts );
770 for ( int ai = 0; ai < npts; ai++ )
771 faceIdsTmp->SetId( ai, pts[ai] );
772 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
774 for (faceId = 0; faceId < 5; faceId++)
777 const vtkIdType *faceVerts = vtkPyramid::GetFaceArray(faceId);
778 faceIds->InsertNextId(pts[faceVerts[0]]);
779 faceIds->InsertNextId(pts[faceVerts[1]]);
780 faceIds->InsertNextId(pts[faceVerts[2]]);
781 aCellType = VTK_TRIANGLE;
783 if (faceVerts[3] >= 0)
785 faceIds->InsertNextId(pts[faceVerts[3]]);
786 aCellType = VTK_QUAD;
789 input->GetCellNeighbors(cellId, faceIds, cellIds);
790 int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
791 #ifdef SHOW_COINCIDING_3D_PAL21924
792 bool process = nbNeighbors <= 0;
794 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
796 if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
798 for ( i=0; i < numFacePts; i++)
799 aNewPts[i] = pts[faceVerts[i]];
800 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
802 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
803 outputCD->CopyData(cd,cellId,newCellId);
810 #if VTK_XVERSION > 50700
813 vtkIdType nFaces = 0;
814 const vtkIdType* ptIds = 0;
816 input->GetFaceStream(cellId, nFaces, ptIds);
817 #ifdef SHOW_COINCIDING_3D_PAL21924
820 faceIdsTmp->Reset(); // use 2 facets
821 numFacePts = ptIds[idp];
822 for (i = 0; i < numFacePts; i++)
823 faceIdsTmp->InsertNextId(ptIds[idp + i]);
825 numFacePts = ptIds[idp];
826 for (i = 0; i < numFacePts; i++)
827 faceIdsTmp->InsertNextId(ptIds[idp + i]);
828 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
832 for (faceId = 0; faceId < nFaces; faceId++)
835 numFacePts = ptIds[idp];
837 for (i = 0; i < numFacePts; i++)
839 faceIds->InsertNextId(ptIds[idp + i]);
844 case 3: aCellType = VTK_TRIANGLE; break;
845 case 4: aCellType = VTK_QUAD; break;
846 default:aCellType = VTK_POLYGON;
848 input->GetCellNeighbors(cellId, faceIds, cellIds);
849 int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
850 if ( myShowInside && nbNeighbors > 0 && cellId < cellIds->GetId(0) )
851 continue; // don't add twice same internal face in wireframe mode
852 #ifdef SHOW_COINCIDING_3D_PAL21924
853 bool process = nbNeighbors <= 0;
855 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
857 if (process || myShowInside
858 || (!allVisible && !cellVis[cellIds->GetId(0)]))
860 for (i = 0; i < numFacePts; i++)
861 aNewPts[i] = ptIds[pt0 + i];
862 newCellId = output->InsertNextCell(aCellType, numFacePts, aNewPts);
864 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
865 outputCD->CopyData(cd, cellId, newCellId);
872 case VTK_QUADRATIC_EDGE:
873 case VTK_QUADRATIC_TRIANGLE:
874 case VTK_BIQUADRATIC_TRIANGLE:
875 case VTK_QUADRATIC_QUAD:
876 case VTK_BIQUADRATIC_QUAD:
877 case VTK_QUADRATIC_POLYGON:
878 case VTK_QUADRATIC_TETRA:
879 case VTK_QUADRATIC_HEXAHEDRON:
880 case VTK_TRIQUADRATIC_HEXAHEDRON:
881 case VTK_QUADRATIC_WEDGE:
882 case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
883 case VTK_QUADRATIC_PYRAMID:
885 if(!myIsWireframeMode)
887 input->GetCell(cellId,cell);
888 vtkIdList *lpts = vtkIdList::New();
889 vtkPoints *coords = vtkPoints::New();
890 vtkIdList *cellIds = vtkIdList::New();
893 if ( cell->GetCellDimension() == 1 ) {
894 vtkIdType arcResult = -1;
896 arcResult = Build1DArc(cellId, input, output, const_cast<vtkIdType *>(pts), myMaxArcAngle);
897 newCellId = arcResult;
900 if(!myIsBuildArc || arcResult == -1 ) {
901 aCellType = VTK_LINE;
903 cell->Triangulate(0,lpts,coords);
904 for (i=0; i < lpts->GetNumberOfIds(); i+=2) {
905 aNewPts[0] = lpts->GetId(i);
906 aNewPts[1] = lpts->GetId(i+1);
907 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
909 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
910 outputCD->CopyData(cd,cellId,newCellId);
915 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
916 outputCD->CopyData(cd,cellId,newCellId);
919 else if ( cell->GetCellDimension() == 2 ) {
921 aCellType = VTK_TRIANGLE;
923 cell->Triangulate(0,lpts,coords);
924 for (i=0; i < lpts->GetNumberOfIds(); i+=3) {
925 aNewPts[0] = lpts->GetId(i);
926 aNewPts[1] = lpts->GetId(i+1);
927 aNewPts[2] = lpts->GetId(i+2);
928 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
930 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
931 outputCD->CopyData(cd,cellId,newCellId);
935 BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds,true);
938 else //3D nonlinear cell
940 #ifdef SHOW_COINCIDING_3D_PAL21924
945 case VTK_QUADRATIC_TETRA: npts1 = 4; break;
946 case VTK_QUADRATIC_HEXAHEDRON: npts1 = 8; break;
947 case VTK_TRIQUADRATIC_HEXAHEDRON: npts1 = 8; break;
948 case VTK_QUADRATIC_WEDGE: npts1 = 6; break;
949 case VTK_BIQUADRATIC_QUADRATIC_WEDGE: npts1 = 6; break;
950 case VTK_QUADRATIC_PYRAMID: npts1 = 5; break;
952 faceIdsTmp->SetNumberOfIds( npts1 );
954 for (int ai=0; ai<npts1; ai++)
955 faceIdsTmp->SetId( ai, pts[ai] );
956 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
960 aCellType = VTK_TRIANGLE;
963 for (int j=0; j < cell->GetNumberOfFaces(); j++)
965 vtkCell *face = cell->GetFace(j);
966 if ( !myShowInside ) {
967 input->GetCellNeighbors(cellId, face->PointIds, cellIds);
968 nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
970 #ifdef SHOW_COINCIDING_3D_PAL21924
971 bool process = nbNeighbors <= 0;
973 bool process = nbNeighbors <= 0 || GetAppendCoincident3D();
975 if ( process || myShowInside ) {
976 face->Triangulate(0,lpts,coords);
977 for (i=0; i < lpts->GetNumberOfIds(); i+=3) {
978 aNewPts[0] = lpts->GetId(i);
979 aNewPts[1] = lpts->GetId(i+1);
980 aNewPts[2] = lpts->GetId(i+2);
981 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
983 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
984 outputCD->CopyData(cd,cellId,newCellId);
988 } //3d nonlinear cell
996 case VTK_QUADRATIC_EDGE:
998 vtkIdType arcResult = -1;
1000 arcResult = Build1DArc(cellId, input, output, const_cast<vtkIdType *>(pts), myMaxArcAngle);
1001 newCellId = arcResult;
1003 if(!myIsBuildArc || arcResult == -1) {
1004 aCellType = VTK_POLY_LINE;
1007 aNewPts[0] = pts[0];
1008 aNewPts[2] = pts[1];
1009 aNewPts[1] = pts[2];
1011 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1015 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1017 outputCD->CopyData(cd,cellId,newCellId);
1020 case VTK_QUADRATIC_TRIANGLE:
1021 case VTK_BIQUADRATIC_TRIANGLE:
1024 aCellType = VTK_POLYGON;
1027 aNewPts[0] = pts[0];
1028 aNewPts[1] = pts[3];
1029 aNewPts[2] = pts[1];
1030 aNewPts[3] = pts[4];
1031 aNewPts[4] = pts[2];
1032 aNewPts[5] = pts[5];
1034 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1036 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1038 outputCD->CopyData(cd,cellId,newCellId);
1041 BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds);
1044 case VTK_QUADRATIC_QUAD:
1045 case VTK_BIQUADRATIC_QUAD:
1048 aCellType = VTK_POLYGON;
1051 aNewPts[0] = pts[0];
1052 aNewPts[1] = pts[4];
1053 aNewPts[2] = pts[1];
1054 aNewPts[3] = pts[5];
1055 aNewPts[4] = pts[2];
1056 aNewPts[5] = pts[6];
1057 aNewPts[6] = pts[3];
1058 aNewPts[7] = pts[7];
1060 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1062 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1064 outputCD->CopyData(cd,cellId,newCellId);
1067 BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds);
1070 case VTK_QUADRATIC_POLYGON:
1074 aCellType = VTK_POLYGON;
1076 for ( i = 0; i < npts/2; ++i )
1078 aNewPts[i*2 ] = pts[i];
1079 aNewPts[i*2+1] = pts[i+npts/2];
1081 newCellId = output->InsertNextCell(aCellType,npts,aNewPts);
1083 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1085 outputCD->CopyData(cd,cellId,newCellId);
1088 BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds);
1091 case VTK_QUADRATIC_TETRA:
1092 case VTK_QUADRATIC_WEDGE:
1093 case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
1094 case VTK_TRIQUADRATIC_HEXAHEDRON:
1095 case VTK_QUADRATIC_HEXAHEDRON:
1096 case VTK_QUADRATIC_PYRAMID:
1098 aCellType = VTK_POLY_LINE;
1099 input->GetCell(cellId,cell);
1102 int nbEdges = cell->GetNumberOfEdges();
1103 for ( int edgeId = 0; edgeId < nbEdges; ++edgeId )
1105 vtkCell * edge = cell->GetEdge( edgeId );
1106 if ( toShowEdge( edge->GetPointId(0), edge->GetPointId(2), cellId, input ))
1108 aNewPts[0] = edge->GetPointId(0);
1109 aNewPts[1] = edge->GetPointId(2);
1110 aNewPts[2] = edge->GetPointId(1);
1111 newCellId = output->InsertNextCell( aCellType, 3, aNewPts );
1113 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1114 outputCD->CopyData(cd,cellId,newCellId);
1120 int nbCoincident = 0;
1121 #ifdef SHOW_COINCIDING_3D_PAL21924
1122 int nbPnt = npts - cell->GetNumberOfEdges();
1123 faceIdsTmp->SetNumberOfIds( nbPnt );
1124 for ( int ai = 0; ai < nbPnt; ai++ )
1125 faceIdsTmp->SetId( ai, pts[ai] );
1126 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
1127 nbCoincident = cellIdsTmp->GetNumberOfIds();
1130 int nbFaces = cell->GetNumberOfFaces();
1131 for ( faceId = 0; faceId < nbFaces; faceId++ )
1133 vtkCell * face = cell->GetFace( faceId );
1134 input->GetCellNeighbors( cellId, face->GetPointIds(), cellIds );
1135 int nbNeighbors = cellIds->GetNumberOfIds() - nbCoincident;
1136 if ( nbNeighbors <= 0 )
1138 int nbEdges = face->GetNumberOfPoints() / 2;
1139 for ( int edgeId = 0; edgeId < nbEdges; ++edgeId )
1141 vtkIdType p1 = ( edgeId ); // corner
1142 vtkIdType p2 = ( edgeId + nbEdges ); // medium
1143 vtkIdType p3 = ( edgeId + 1 ) % nbEdges; // next corner
1144 faceIdsTmp->SetNumberOfIds( 2 );
1145 faceIdsTmp->SetId( 0, face->GetPointId(p2) );
1146 faceIdsTmp->SetId( 1, face->GetPointId(p1) );
1147 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
1149 switch ( cellIdsTmp->GetNumberOfIds() ) {
1150 case 0: // the edge belong to this cell only
1151 // avoid adding it when treating another face
1152 process = midPoints.insert( face->GetPointId(p2) ).second; break;
1153 case 1: // the edge is shared by two cells
1154 process = ( cellIdsTmp->GetId(0) < cellId ); break;
1155 default: // the edge is shared by >2 cells
1156 process = ( cellIdsTmp->GetId(0) < cellId ); break;
1160 aNewPts[0] = face->GetPointId( p1 );
1161 aNewPts[1] = face->GetPointId( p2 );
1162 aNewPts[2] = face->GetPointId( p3 );
1163 newCellId = output->InsertNextCell( aCellType, 3, aNewPts );
1165 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1166 outputCD->CopyData(cd,cellId,newCellId);
1173 } // case of volumes in wireframe
1174 } // switch by quadratic type
1184 vtkDebugMacro(<<"Extracted " << input->GetNumberOfPoints() << " points,"
1185 << output->GetNumberOfCells() << " cells.");
1191 cellIdsTmp->Delete();
1192 faceIdsTmp->Delete();
1199 if ( input->GetCellLinks() )
1201 input->GetCellLinks()->Initialize(); // free memory
1204 // fill myVTK2ObjIds vector in ascending cell dimension order
1205 myVTK2ObjIds.clear();
1206 if( myStoreMapping && !aDimension2VTK2ObjIds.empty() )
1208 size_t nbCells = ( aDimension2VTK2ObjIds[0].size() +
1209 aDimension2VTK2ObjIds[1].size() +
1210 aDimension2VTK2ObjIds[2].size() );
1211 if ( myVTK2ObjIds.capacity() > nbCells )
1212 TVectorId().swap( myVTK2ObjIds );
1213 myVTK2ObjIds.reserve( nbCells );
1215 for( int aDimension = 0; aDimension <= 2; aDimension++ )
1216 if ( !aDimension2VTK2ObjIds[ aDimension ].empty() )
1218 myVTK2ObjIds.insert( myVTK2ObjIds.end(),
1219 aDimension2VTK2ObjIds[ aDimension ].begin(),
1220 aDimension2VTK2ObjIds[ aDimension ].end() );
1221 TVectorId().swap( aDimension2VTK2ObjIds[ aDimension ]);
1229 VTKViewer_GeometryFilter
1230 ::InsertId( const vtkIdType theCellId,
1231 const vtkIdType theCellType,
1232 TVectorId& /*theVTK2ObjIds*/,
1233 TMapOfVectorId& theDimension2VTK2ObjIds )
1235 //theVTK2ObjIds.push_back( theCellId );
1238 switch( theCellType )
1241 case VTK_POLY_VERTEX:
1249 case VTK_TRIANGLE_STRIP:
1257 TVectorId& aCellIds = theDimension2VTK2ObjIds[ aDimension ];
1258 aCellIds.push_back( theCellId );
1262 VTKViewer_GeometryFilter
1263 ::SetInside(int theShowInside)
1265 if(myShowInside == theShowInside)
1268 myShowInside = theShowInside;
1273 VTKViewer_GeometryFilter
1276 return myShowInside;
1281 VTKViewer_GeometryFilter
1282 ::SetWireframeMode(int theIsWireframeMode)
1284 if(myIsWireframeMode == theIsWireframeMode)
1287 myIsWireframeMode = theIsWireframeMode;
1292 VTKViewer_GeometryFilter
1293 ::GetWireframeMode()
1295 return myIsWireframeMode;
1300 VTKViewer_GeometryFilter
1301 ::SetStoreMapping(int theStoreMapping)
1303 if(myStoreMapping == theStoreMapping)
1306 myStoreMapping = theStoreMapping;
1311 VTKViewer_GeometryFilter
1314 return myStoreMapping;
1318 vtkIdType VTKViewer_GeometryFilter::GetElemObjId( int theVtkID )
1320 if( theVtkID < 0 || theVtkID >= (int)myVTK2ObjIds.size() )
1322 return myVTK2ObjIds[theVtkID];
1326 void VTKViewer_GeometryFilter::BuildArcedPolygon(vtkIdType cellId,
1327 vtkUnstructuredGrid* input,
1328 vtkPolyData *output,
1329 TMapOfVectorId& theDimension2VTK2ObjIds,
1332 vtkIdType aCellType = VTK_POLYGON;
1333 vtkIdType *aNewPoints = NULL;
1334 vtkIdType aNbPoints = 0;
1335 vtkIdType newCellId;
1337 //Input and output cell data
1338 vtkCellData *cd = input->GetCellData();
1339 vtkCellData *outputCD = output->GetCellData();
1341 //Input and output scalars on point data
1342 vtkDataArray* inputScalars = input->GetPointData()->GetScalars();
1343 vtkDataArray* outputScalars = output->GetPointData()->GetScalars();
1345 std::vector< vtkSmartPointer<vtkPoints> > aCollection;
1346 std::vector< std::vector<double> > aScalarCollection;
1348 vtkCell* aCell = input->GetCell(cellId);
1349 switch(aCell->GetCellType()) {
1350 case VTK_QUADRATIC_TRIANGLE:
1351 case VTK_BIQUADRATIC_TRIANGLE:
1353 //Get All points from input cell
1354 Pnt P0 = CreatePnt( aCell, inputScalars, 0 );
1355 Pnt P1 = CreatePnt( aCell, inputScalars, 1 );
1356 Pnt P2 = CreatePnt( aCell, inputScalars, 2 );
1357 Pnt P3 = CreatePnt( aCell, inputScalars, 3 );
1358 Pnt P4 = CreatePnt( aCell, inputScalars, 4 );
1359 Pnt P5 = CreatePnt( aCell, inputScalars, 5 );
1361 VTKViewer_ArcBuilder aBuilder1(P0,P3,P1,myMaxArcAngle); //Build arc using 0, 3 and 1 points
1363 cout << "Quadrangle arc 1 " << ( aBuilder1.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1366 VTKViewer_ArcBuilder aBuilder2(P1,P4,P2,myMaxArcAngle); //Build arc using 1, 4 and 2 points
1368 cout << "Quadrangle arc 2 " << ( aBuilder2.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1371 VTKViewer_ArcBuilder aBuilder3(P2,P5,P0,myMaxArcAngle); //Build arc using 2, 5 and 0 points
1373 cout << "Quadrangle arc 3 " << ( aBuilder3.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1376 aCollection.push_back(aBuilder1.GetPoints());
1377 aCollection.push_back(aBuilder2.GetPoints());
1378 aCollection.push_back(aBuilder3.GetPoints());
1380 aScalarCollection.push_back(aBuilder1.GetScalarValues());
1381 aScalarCollection.push_back(aBuilder2.GetScalarValues());
1382 aScalarCollection.push_back(aBuilder3.GetScalarValues());
1385 case VTK_QUADRATIC_QUAD:
1386 case VTK_BIQUADRATIC_QUAD:
1388 //Get All points from input cell
1389 Pnt P0 = CreatePnt( aCell, inputScalars, 0 );
1390 Pnt P1 = CreatePnt( aCell, inputScalars, 1 );
1391 Pnt P2 = CreatePnt( aCell, inputScalars, 2 );
1392 Pnt P3 = CreatePnt( aCell, inputScalars, 3 );
1393 Pnt P4 = CreatePnt( aCell, inputScalars, 4 );
1394 Pnt P5 = CreatePnt( aCell, inputScalars, 5 );
1395 Pnt P6 = CreatePnt( aCell, inputScalars, 6 );
1396 Pnt P7 = CreatePnt( aCell, inputScalars, 7 );
1398 VTKViewer_ArcBuilder aBuilder1(P0,P4,P1,myMaxArcAngle); //Build arc using 0, 4 and 1 points
1400 cout << "Quadrangle arc 1 " << ( aBuilder1.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1403 VTKViewer_ArcBuilder aBuilder2(P1,P5,P2,myMaxArcAngle); //Build arc using 1, 5 and 2 points
1405 cout << "Quadrangle arc 2 " << ( aBuilder2.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1408 VTKViewer_ArcBuilder aBuilder3(P2,P6,P3,myMaxArcAngle); //Build arc using 2, 6 and 3 points
1410 cout << "Quadrangle arc 3 " << ( aBuilder3.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1413 VTKViewer_ArcBuilder aBuilder4(P3,P7,P0,myMaxArcAngle); //Build arc using 3, 7 and 0 points
1415 cout << "Quadrangle arc 4 " << ( aBuilder4.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1418 aCollection.push_back(aBuilder1.GetPoints());
1419 aCollection.push_back(aBuilder2.GetPoints());
1420 aCollection.push_back(aBuilder3.GetPoints());
1421 aCollection.push_back(aBuilder4.GetPoints());
1423 aScalarCollection.push_back(aBuilder1.GetScalarValues());
1424 aScalarCollection.push_back(aBuilder2.GetScalarValues());
1425 aScalarCollection.push_back(aBuilder3.GetScalarValues());
1426 aScalarCollection.push_back(aBuilder4.GetScalarValues());
1429 case VTK_QUADRATIC_POLYGON:
1431 int nbP = aCell->GetNumberOfPoints();
1432 std::vector< Pnt > pVec( nbP + 2 );
1434 for ( int i = 0; i < nbP/2; ++i )
1436 pVec[i*2 + 0] = CreatePnt( aCell, inputScalars, i );
1437 pVec[i*2 + 1] = CreatePnt( aCell, inputScalars, i + nbP/2 );
1439 pVec[ nbP ] = pVec[ 0 ];
1440 pVec[ nbP+1 ] = pVec[ 1 ];
1442 for ( int i = 0; i < nbP; i += 2 )
1444 VTKViewer_ArcBuilder aBuilder( pVec[i], pVec[i+1], pVec[i+2], myMaxArcAngle );
1445 aCollection.push_back( aBuilder.GetPoints() );
1446 aScalarCollection.push_back( aBuilder.GetScalarValues() );
1450 default: //Unsupported cell type
1455 const vtkIdType numFacePts = 3;
1456 vtkIdList *pts = vtkIdList::New();
1457 vtkPoints *coords = vtkPoints::New();
1458 aCellType = VTK_TRIANGLE;
1459 vtkIdType aNewPts[numFacePts];
1460 vtkIdType aTriangleId;
1462 vtkPolygon *aPlg = vtkPolygon::New();
1463 std::map<int, double> aPntId2ScalarValue;
1464 aNbPoints = MergevtkPoints(aCollection, aScalarCollection, aPlg->GetPoints(), aPntId2ScalarValue, aNewPoints);
1465 aPlg->GetPointIds()->SetNumberOfIds(aNbPoints);
1467 for(vtkIdType i = 0; i < aNbPoints;i++) {
1468 aPlg->GetPointIds()->SetId(i, aNewPoints[i]);
1471 aPlg->Triangulate(0,pts,coords);
1473 for (vtkIdType i=0; i < pts->GetNumberOfIds(); i+=3) {
1474 aNewPts[0] = output->GetPoints()->InsertNextPoint(coords->GetPoint(i));
1475 aNewPts[1] = output->GetPoints()->InsertNextPoint(coords->GetPoint(i+1));
1476 aNewPts[2] = output->GetPoints()->InsertNextPoint(coords->GetPoint(i+2));
1479 outputScalars->InsertNextTuple1(aPntId2ScalarValue[pts->GetId(i)]);
1480 outputScalars->InsertNextTuple1(aPntId2ScalarValue[pts->GetId(i+1)]);
1481 outputScalars->InsertNextTuple1(aPntId2ScalarValue[pts->GetId(i+2)]);
1484 aTriangleId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1487 InsertId( cellId, aCellType, myVTK2ObjIds, theDimension2VTK2ObjIds );
1488 outputCD->CopyData(cd,cellId,aTriangleId);
1495 std::map<int, double> aPntId2ScalarValue;
1496 aNbPoints = MergevtkPoints(aCollection, aScalarCollection, output->GetPoints(), aPntId2ScalarValue, aNewPoints);
1498 for(vtkIdType i = 0; i < aNbPoints; i++)
1499 outputScalars->InsertNextTuple1(aPntId2ScalarValue[aNewPoints[i]]);
1500 newCellId = output->InsertNextCell(aCellType,aNbPoints,aNewPoints);
1501 outputCD->CopyData(cd,cellId,newCellId);
1504 InsertId( cellId, aCellType, myVTK2ObjIds, theDimension2VTK2ObjIds );
1508 delete [] aNewPoints;
1512 void VTKViewer_GeometryFilter::SetQuadraticArcMode(bool theFlag)
1514 if(myIsBuildArc != theFlag) {
1515 myIsBuildArc = theFlag;
1519 bool VTKViewer_GeometryFilter::GetQuadraticArcMode() const
1521 return myIsBuildArc;
1524 void VTKViewer_GeometryFilter::SetQuadraticArcAngle(double theMaxAngle)
1526 if(myMaxArcAngle != theMaxAngle) {
1527 myMaxArcAngle = theMaxAngle;
1532 double VTKViewer_GeometryFilter:: GetQuadraticArcAngle() const
1534 return myMaxArcAngle;
1537 int VTKViewer_GeometryFilter::GetAppendCoincident3D() const {
1538 // VSR 26/10/2012: see description of SHOW_COINCIDING_3D_PAL20314
1539 // in the top of this file
1540 #ifdef SHOW_COINCIDING_3D_PAL20314
1541 return myAppendCoincident3D;
1547 void VTKViewer_GeometryFilter::SetAppendCoincident3D(int theFlag) {
1548 if(myAppendCoincident3D != theFlag){
1549 myAppendCoincident3D = theFlag;