1 // Copyright (C) 2007-2022 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 ///////////////////////////////////////////////////////////////////////////////////////////////
97 vtkStandardNewMacro(VTKViewer_GeometryFilter)
99 VTKViewer_GeometryFilter
100 ::VTKViewer_GeometryFilter():
103 myIsWireframeMode(0),
104 myAppendCoincident3D(0),
108 static int forceDelegateToVtk = -1;
109 if ( forceDelegateToVtk < 0 )
111 QString env = Qtx::getenv( "SALOME_ACTOR_DO_NOT_DELEGATE_TO_VTK" );
112 forceDelegateToVtk = (int)(env != "1");
114 delegateToVtk = forceDelegateToVtk > 0;
118 VTKViewer_GeometryFilter
119 ::~VTKViewer_GeometryFilter()
123 * \brief Return true for only one volume including a given edge
124 * \param [in] id1 - 1st edge end
125 * \param [in] id2 - second edge end
126 * \param [in] cellId - volume ID
127 * \param [in] input - the grid
129 static inline bool toShowEdge( vtkIdType id1, vtkIdType id2, vtkIdType cellId, vtkUnstructuredGrid* input )
131 // return true if the given cell is the 1st among cells including the edge
132 vtkStaticCellLinks * links = static_cast<vtkStaticCellLinks *>(input->GetCellLinks());
135 links = static_cast<vtkStaticCellLinks *>(input->GetCellLinks());
138 std::swap( id1, id2 );
139 vtkIdType *cells = links->GetCells( id1 );
141 // among cells, look for a cell including the edge
142 vtkIdType npts, iCell = 0;
143 vtkIdType const *cellPts;
147 if ( cells[iCell] == cellId )
149 input->GetCellPoints( cells[iCell], npts, cellPts );
150 for ( vtkIdType i = 0; i < npts && !found; ++i )
151 found = ( cellPts[i] == id2 );
154 return ( cells[iCell] == cellId );
157 //------------------------------------------------------------------------------
158 // Excluded faces are defined here.
159 struct vtkExcludedFaces
161 vtkStaticCellLinksTemplate<vtkIdType>* Links;
166 ~vtkExcludedFaces() { delete this->Links; }
169 // fill myVTK2ObjIds to get the correspondence between vtk ids (displayed edges and faces
170 // computed in vtkGeometryFilter::UnstructuredGridExecute) and original cell ids (mesh cells)
171 void VTKViewer_GeometryFilter
172 ::FillVTK2ObjIds(vtkPolyData *output) {
174 vtkDataArray* vtkOriginalCellIds = output->GetCellData()->GetArray("vtkOriginalCellIds");
176 if (vtkOriginalCellIds == nullptr)
177 throw std::runtime_error("vtkOriginalCellIds is null. Something is wrong.");
179 const vtkIdType numTuples = vtkOriginalCellIds->GetNumberOfTuples();
180 myVTK2ObjIds.resize(numTuples);
182 // copy ids of vtkOriginalCellIds into myVTK2ObjIds
183 vtkIdTypeArray *vtkOriginalCellIdsInt(vtkIdTypeArray::SafeDownCast(vtkOriginalCellIds));
184 vtkIdType* origIds(vtkOriginalCellIdsInt->GetPointer(0));
185 myVTK2ObjIds.assign(origIds, origIds+numTuples);
189 VTKViewer_GeometryFilter
191 vtkInformation *request,
192 vtkInformationVector **inputVector,
193 vtkInformationVector *outputVector)
196 // get the info objects
197 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
198 vtkInformation *outInfo = outputVector->GetInformationObject(0);
200 // get the input and ouptut
201 vtkDataSet *input = vtkDataSet::SafeDownCast(
202 inInfo->Get(vtkDataObject::DATA_OBJECT()));
203 vtkPolyData *output = vtkPolyData::SafeDownCast(
204 outInfo->Get(vtkDataObject::DATA_OBJECT()));
206 vtkIdType numCells=input->GetNumberOfCells();
207 vtkIdType numPts = input->GetNumberOfPoints();
209 if (numPts == 0 || numCells == 0)
214 #if VTK_VERSION_NUMBER >= VTK_VERSION_CHECK(9,0,0)
218 // get the info objects excluded faces
219 vtkInformation* excInfo = inputVector[1]->GetInformationObject(0);
221 vtkExcludedFaces exc; // Will delete exc->Links when goes out of scope
222 vtkPolyData* excFaces = nullptr;
225 excFaces = vtkPolyData::SafeDownCast(excInfo->Get(vtkDataObject::DATA_OBJECT()));
226 vtkCellArray* excPolys = excFaces->GetPolys();
227 if (excPolys->GetNumberOfCells() > 0)
229 exc.Links = new vtkStaticCellLinksTemplate<vtkIdType>;
230 exc.Links->ThreadedBuildLinks(numPts, excPolys->GetNumberOfCells(), excPolys);
234 switch (input->GetDataObjectType())
237 return this->vtkGeometryFilter::PolyDataExecute(input, output, excFaces);
238 case VTK_UNSTRUCTURED_GRID:
240 vtkUnstructuredGrid* inputUnstructured = static_cast<vtkUnstructuredGrid*>(input);
242 // The "info", is passed to provide information about the unstructured grid. This
243 // is done to avoid repeated evaluations of "info" in the vtkGeometryFilter and
244 // the vtkDataSetSurfaceFilter (which vtkGeometryFilter might delagate to in case
245 // of nonlinear data).
246 vtkGeometryFilterHelper* info = vtkGeometryFilterHelper::CharacterizeUnstructuredGrid(inputUnstructured);
248 bool NotFitForDelegation = false;
249 if ( vtkUnsignedCharArray* types = inputUnstructured->GetCellTypesArray() )
251 std::set<vtkIdType> ElementsNotFitToDelegate;
253 // All quadratic, biquadratic, and triquadratic elements not fit for delegation
254 // as SMESH has special display with curves mode for meshes containing these
255 // elements hence such meshes are not handled by "vtkGeometryFilter" instead
256 // the native VTKViewer_GeometryFilter::UnstructuredGridExecute is used.
257 ElementsNotFitToDelegate.insert( VTK_QUADRATIC_EDGE );
258 ElementsNotFitToDelegate.insert( VTK_QUADRATIC_TRIANGLE );
259 ElementsNotFitToDelegate.insert( VTK_BIQUADRATIC_TRIANGLE );
260 ElementsNotFitToDelegate.insert( VTK_QUADRATIC_QUAD );
261 ElementsNotFitToDelegate.insert( VTK_BIQUADRATIC_QUAD );
262 ElementsNotFitToDelegate.insert( VTK_QUADRATIC_POLYGON );
263 ElementsNotFitToDelegate.insert( VTK_QUADRATIC_TETRA );
264 ElementsNotFitToDelegate.insert( VTK_QUADRATIC_HEXAHEDRON );
265 ElementsNotFitToDelegate.insert( VTK_TRIQUADRATIC_HEXAHEDRON );
266 ElementsNotFitToDelegate.insert( VTK_QUADRATIC_WEDGE );
267 ElementsNotFitToDelegate.insert( VTK_BIQUADRATIC_QUADRATIC_WEDGE );
268 ElementsNotFitToDelegate.insert( VTK_QUADRATIC_PYRAMID );
270 for ( int i = 0; i < types->GetNumberOfTuples() && !NotFitForDelegation; ++i )
271 NotFitForDelegation = ElementsNotFitToDelegate.count( types->GetValue(i) );
273 if ( NotFitForDelegation )
274 return this->UnstructuredGridExecute(input, output, outInfo);
278 if ( myStoreMapping ) {
279 // pass through cell ids to get original cell ids
280 this->PassThroughCellIds = true;
281 ret = this->vtkGeometryFilter::UnstructuredGridExecute(input, output, info, excFaces);
282 FillVTK2ObjIds(output);
285 // no need to get original cell ids
286 this->PassThroughCellIds = false;
287 ret = this->vtkGeometryFilter::UnstructuredGridExecute(input, output, info, excFaces);
294 return this->vtkGeometryFilter::DataSetExecute(input, output, excFaces);
296 else // !delegateToVtk
299 if (input->GetDataObjectType() == VTK_UNSTRUCTURED_GRID){
300 return this->UnstructuredGridExecute(input, output, outInfo);
303 return Superclass::RequestData(request,inputVector,outputVector);
309 VTKViewer_GeometryFilter
310 ::UnstructuredGridExecute(vtkDataSet *dataSetInput,
312 vtkInformation */*outInfo*/)
314 vtkUnstructuredGrid *input= (vtkUnstructuredGrid *)dataSetInput;
315 vtkCellArray *Connectivity = input->GetCells();
317 if ( Connectivity == NULL )
319 vtkDebugMacro(<<"Nothing to extract");
327 vtkIdType const *pts = 0;
328 vtkPoints *p = input->GetPoints();
329 vtkIdType numCells=input->GetNumberOfCells();
330 vtkPointData *pd = input->GetPointData();
331 vtkCellData *cd = input->GetCellData();
332 vtkPointData *outputPD = output->GetPointData();
334 VTKViewer_OrderedTriangulator anOrderedTriangulator;
335 VTKViewer_DelaunayTriangulator aDelaunayTriangulator;
337 vtkCellData *outputCD = output->GetCellData();
338 vtkGenericCell *cell = vtkGenericCell::New();
340 vtkIdList *cellIds = vtkIdList::New();
341 vtkIdList *faceIds = vtkIdList::New();
342 vtkIdList *cellIdsTmp = vtkIdList::New();
343 vtkIdList *faceIdsTmp = vtkIdList::New();
344 std::set< vtkIdType > midPoints;
348 int faceId, numFacePts;
350 vtkIdType PixelConvert[4];
351 // Change the type from int to vtkIdType in order to avoid compilation errors while using VTK
352 // from ParaView-3.4.0 compiled on 64-bit Debian platform with VTK_USE_64BIT_IDS = ON
353 vtkIdType aNewPts[VTK_CELL_SIZE];
355 unsigned char updateLevel = (unsigned char)(GetUpdateGhostLevel());
356 unsigned char *cellGhostLevels = 0;
363 vtkDebugMacro(<<"Executing geometry filter for unstructured grid input");
365 vtkDataArray* temp = 0;
368 temp = cd->GetArray("vtkGhostLevels");
370 if ( (!temp) || (temp->GetDataType() != VTK_UNSIGNED_CHAR)
371 || (temp->GetNumberOfComponents() != 1))
373 vtkDebugMacro("No appropriate ghost levels field available.");
377 cellGhostLevels = ((vtkUnsignedCharArray*)temp)->GetPointer(0);
380 // Determine nature of what we have to do
381 if ( (!this->CellClipping) && (!this->PointClipping) &&
382 (!this->ExtentClipping) )
390 cellVis = new char[numCells];
393 bool buildArcs = false;
396 // check if there are quadratic 1D or 2D elements
397 bool hasQuad1D2D = false;
398 if ( vtkUnsignedCharArray* types = input->GetCellTypesArray() )
400 std::set<vtkIdType> quad1D2DTypes;
401 quad1D2DTypes.insert( VTK_QUADRATIC_EDGE );
402 quad1D2DTypes.insert( VTK_QUADRATIC_TRIANGLE );
403 quad1D2DTypes.insert( VTK_BIQUADRATIC_TRIANGLE );
404 quad1D2DTypes.insert( VTK_QUADRATIC_QUAD );
405 quad1D2DTypes.insert( VTK_BIQUADRATIC_QUAD );
406 quad1D2DTypes.insert( VTK_QUADRATIC_POLYGON );
408 for ( auto i = 0; i < types->GetNumberOfTuples() && !hasQuad1D2D; ++i )
409 hasQuad1D2D = quad1D2DTypes.count( types->GetValue(i) );
411 buildArcs = hasQuad1D2D;
415 // Issue 0020115: [CEA 308] Quadratic elements visualization
416 // Fix of remark described in note 0005222 - SIGSEGV
417 vtkPoints* outputPoints = vtkPoints::New();
418 outputPoints->DeepCopy(input->GetPoints());
419 output->SetPoints(outputPoints);
420 outputPoints->Delete();
424 output->SetPoints(input->GetPoints());
427 outputPD->PassData(pd);
429 outputCD->CopyAllocate(cd,numCells,numCells/2);
431 output->Allocate(numCells/4+1,numCells);
433 // Loop over the cells determining what's visible
436 for (cellId=0, Connectivity->InitTraversal();
437 Connectivity->GetNextCell(npts,pts);
441 if ( ( this->CellClipping && cellId < this->CellMinimum ) ||
442 cellId > this->CellMaximum )
448 for (i=0; i < npts; i++)
450 x = p->GetPoint(pts[i]);
451 if ( ( ( ( this->PointClipping && (pts[i] < this->PointMinimum ) ) ||
452 pts[i] > this->PointMaximum) ) ||
453 ( this->ExtentClipping &&
454 ( x[0] < this->Extent[0] || x[0] > this->Extent[1] ||
455 x[1] < this->Extent[2] || x[1] > this->Extent[3] ||
456 x[2] < this->Extent[4] || x[2] > this->Extent[5] )) )
460 }//point/extent clipping
462 }//if point clipping needs checking
464 }//if not all visible
466 if ( input->GetCellLinks() )
469 // Loop over all cells now that visibility is known
470 // (Have to compute visibility first for 3D cell boundaries)
471 vtkIdType progressInterval = numCells/20 + 1;
472 TMapOfVectorId aDimension2VTK2ObjIds;
473 if ( myStoreMapping )
474 aDimension2VTK2ObjIds.resize( 3 ); // max dimension is 2
476 for (cellId=0, Connectivity->InitTraversal();
477 Connectivity->GetNextCell(npts,pts);
480 //Progress and abort method support
481 if ( !(cellId % progressInterval) )
483 vtkDebugMacro(<<"Process cell #" << cellId);
484 this->UpdateProgress ((float)cellId/numCells);
487 // Handle ghost cells here. Another option was used cellVis array.
488 if (cellGhostLevels && cellGhostLevels[cellId] > updateLevel)
489 { // Do not create surfaces in outer ghost cells.
493 if (allVisible || cellVis[cellId]) //now if visible extract geometry
495 //special code for nonlinear cells - rarely occurs, so right now it
497 vtkIdType aCellType = input->GetCellType(cellId);
504 case VTK_POLY_VERTEX:
505 newCellId = output->InsertNextCell(aCellType,npts,pts);
507 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
509 outputCD->CopyData(cd,cellId,newCellId);
514 newCellId = output->InsertNextCell(aCellType,npts,pts);
516 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
517 outputCD->CopyData(cd,cellId,newCellId);
523 newCellId = output->InsertNextCell(aCellType,npts,pts);
525 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
526 outputCD->CopyData(cd,cellId,newCellId);
529 case VTK_TRIANGLE_STRIP:
530 newCellId = output->InsertNextCell(aCellType,npts,pts);
532 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
533 outputCD->CopyData(cd,cellId,newCellId);
537 newCellId = output->InsertNextCell(aCellType,npts,pts);
539 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
540 outputCD->CopyData(cd,cellId,newCellId);
543 case VTK_CONVEX_POINT_SET: {
544 bool anIsOk = anOrderedTriangulator.Execute(input,
549 GetAppendCoincident3D(),
555 aDimension2VTK2ObjIds,
558 aDelaunayTriangulator.Execute(input,
563 GetAppendCoincident3D(),
569 aDimension2VTK2ObjIds,
578 aCellType = VTK_LINE;
579 for ( int edgeID = 0; edgeID < 6; ++edgeID )
581 const vtkIdType *edgeVerts = vtkTetra::GetEdgeArray( edgeID );
582 if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
584 aNewPts[0] = pts[edgeVerts[0]];
585 aNewPts[1] = pts[edgeVerts[1]];
586 newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
588 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
589 outputCD->CopyData(cd,cellId,newCellId);
596 #ifdef SHOW_COINCIDING_3D_PAL21924
597 faceIdsTmp->SetNumberOfIds( npts );
598 for ( auto ai = 0; ai < npts; ai++ )
599 faceIdsTmp->SetId( ai, pts[ai] );
600 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
602 aCellType = VTK_TRIANGLE;
604 for (faceId = 0; faceId < 4; faceId++)
607 const vtkIdType *faceVerts = vtkTetra::GetFaceArray(faceId);
608 faceIds->InsertNextId(pts[faceVerts[0]]);
609 faceIds->InsertNextId(pts[faceVerts[1]]);
610 faceIds->InsertNextId(pts[faceVerts[2]]);
611 input->GetCellNeighbors(cellId, faceIds, cellIds);
612 vtkIdType nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
613 #ifdef SHOW_COINCIDING_3D_PAL21924
614 bool process = nbNeighbors <= 0;
616 bool process = nbNeighbors <= 0 || GetAppendCoincident3D();
618 if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
620 for ( i=0; i < numFacePts; i++)
621 aNewPts[i] = pts[faceVerts[i]];
622 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
624 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
625 outputCD->CopyData(cd,cellId,newCellId);
635 aCellType = VTK_LINE;
636 for ( int edgeID = 0; edgeID < 12; ++edgeID )
638 const vtkIdType *edgeVerts = vtkVoxel::GetEdgeArray( edgeID );
639 if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
641 aNewPts[0] = pts[edgeVerts[0]];
642 aNewPts[1] = pts[edgeVerts[1]];
643 newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
645 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
646 outputCD->CopyData(cd,cellId,newCellId);
653 #ifdef SHOW_COINCIDING_3D_PAL21924
654 faceIdsTmp->SetNumberOfIds( npts );
655 for ( auto ai = 0; ai < npts; ai++ )
656 faceIdsTmp->SetId( ai, pts[ai] );
657 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
659 for (faceId = 0; faceId < 6; faceId++)
662 const vtkIdType*faceVerts = vtkVoxel::GetFaceArray(faceId);
663 faceIds->InsertNextId(pts[faceVerts[0]]);
664 faceIds->InsertNextId(pts[faceVerts[1]]);
665 faceIds->InsertNextId(pts[faceVerts[2]]);
666 faceIds->InsertNextId(pts[faceVerts[3]]);
667 aCellType = VTK_QUAD;
669 input->GetCellNeighbors(cellId, faceIds, cellIds);
670 vtkIdType nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
671 #ifdef SHOW_COINCIDING_3D_PAL21924
672 bool process = nbNeighbors <= 0;
674 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
676 if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
678 for ( i=0; i < numFacePts; i++)
679 aNewPts[i] = pts[faceVerts[PixelConvert[i]]];
680 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
682 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
683 outputCD->CopyData(cd,cellId,newCellId);
693 aCellType = VTK_LINE;
694 for ( int edgeID = 0; edgeID < 12; ++edgeID )
696 const vtkIdType *edgeVerts = vtkHexahedron::GetEdgeArray( edgeID );
697 if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
699 aNewPts[0] = pts[edgeVerts[0]];
700 aNewPts[1] = pts[edgeVerts[1]];
701 newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
703 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
704 outputCD->CopyData(cd,cellId,newCellId);
711 #ifdef SHOW_COINCIDING_3D_PAL21924
712 faceIdsTmp->SetNumberOfIds( npts );
713 for ( auto ai = 0; ai < npts; ai++ )
714 faceIdsTmp->SetId( ai, pts[ai] );
715 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
717 aCellType = VTK_QUAD;
719 for (faceId = 0; faceId < 6; faceId++)
722 const vtkIdType *faceVerts = vtkHexahedron::GetFaceArray(faceId);
723 faceIds->InsertNextId(pts[faceVerts[0]]);
724 faceIds->InsertNextId(pts[faceVerts[1]]);
725 faceIds->InsertNextId(pts[faceVerts[2]]);
726 faceIds->InsertNextId(pts[faceVerts[3]]);
727 input->GetCellNeighbors(cellId, faceIds, cellIds);
728 vtkIdType nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
729 #ifdef SHOW_COINCIDING_3D_PAL21924
730 bool process = nbNeighbors <= 0;
732 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
734 if ( process || (!allVisible && !cellVis[cellIds->GetId(0)]) )
736 for ( i=0; i < numFacePts; i++)
737 aNewPts[i] = pts[faceVerts[i]];
738 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
740 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
741 outputCD->CopyData(cd,cellId,newCellId);
751 aCellType = VTK_LINE;
752 for ( int edgeID = 0; edgeID < 9; ++edgeID )
754 const vtkIdType *edgeVerts = vtkWedge::GetEdgeArray( edgeID );
755 if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
757 aNewPts[0] = pts[edgeVerts[0]];
758 aNewPts[1] = pts[edgeVerts[1]];
759 newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
761 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
762 outputCD->CopyData(cd,cellId,newCellId);
769 #ifdef SHOW_COINCIDING_3D_PAL21924
770 faceIdsTmp->SetNumberOfIds( npts );
771 for ( int ai = 0; ai < npts; ai++ )
772 faceIdsTmp->SetId( ai, pts[ai] );
773 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
775 for (faceId = 0; faceId < 5; faceId++)
778 const vtkIdType *faceVerts = vtkWedge::GetFaceArray(faceId);
779 faceIds->InsertNextId(pts[faceVerts[0]]);
780 faceIds->InsertNextId(pts[faceVerts[1]]);
781 faceIds->InsertNextId(pts[faceVerts[2]]);
782 aCellType = VTK_TRIANGLE;
784 if (faceVerts[3] >= 0)
786 faceIds->InsertNextId(pts[faceVerts[3]]);
787 aCellType = VTK_QUAD;
790 input->GetCellNeighbors(cellId, faceIds, cellIds);
791 vtkIdType nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
792 #ifdef SHOW_COINCIDING_3D_PAL21924
793 bool process = nbNeighbors <= 0;
795 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
797 if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
799 for ( i=0; i < numFacePts; i++)
800 aNewPts[i] = pts[faceVerts[i]];
801 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
803 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
804 outputCD->CopyData(cd,cellId,newCellId);
810 case VTK_HEXAGONAL_PRISM:
814 aCellType = VTK_LINE;
815 for ( int edgeID = 0; edgeID < 18; ++edgeID )
817 const vtkIdType *edgeVerts = vtkHexagonalPrism::GetEdgeArray( edgeID );
818 if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
820 aNewPts[0] = pts[edgeVerts[0]];
821 aNewPts[1] = pts[edgeVerts[1]];
822 newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
824 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
825 outputCD->CopyData(cd,cellId,newCellId);
832 #ifdef SHOW_COINCIDING_3D_PAL21924
833 faceIdsTmp->SetNumberOfIds( npts );
834 for ( auto ai = 0; ai < npts; ai++ )
835 faceIdsTmp->SetId( ai, pts[ai] );
836 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
838 for (faceId = 0; faceId < 8; faceId++)
840 const vtkIdType *faceVerts = vtkHexagonalPrism::GetFaceArray(faceId);
842 faceIds->InsertNextId(pts[faceVerts[0]]);
843 faceIds->InsertNextId(pts[faceVerts[1]]);
844 faceIds->InsertNextId(pts[faceVerts[2]]);
845 faceIds->InsertNextId(pts[faceVerts[3]]);
846 aCellType = VTK_QUAD;
848 if (faceVerts[5] >= 0)
850 faceIds->InsertNextId(pts[faceVerts[4]]);
851 faceIds->InsertNextId(pts[faceVerts[5]]);
852 aCellType = VTK_POLYGON;
855 input->GetCellNeighbors(cellId, faceIds, cellIds);
856 vtkIdType nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
857 #ifdef SHOW_COINCIDING_3D_PAL21924
858 bool process = nbNeighbors <= 0;
860 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
862 if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
864 for ( i=0; i < numFacePts; i++)
865 aNewPts[i] = pts[faceVerts[i]];
866 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
868 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
869 outputCD->CopyData(cd,cellId,newCellId);
879 aCellType = VTK_LINE;
880 for ( auto edgeID = 0; edgeID < 8; ++edgeID )
882 const vtkIdType *edgeVerts = vtkPyramid::GetEdgeArray( edgeID );
883 if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
885 aNewPts[0] = pts[edgeVerts[0]];
886 aNewPts[1] = pts[edgeVerts[1]];
887 newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
889 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
890 outputCD->CopyData(cd,cellId,newCellId);
897 #ifdef SHOW_COINCIDING_3D_PAL21924
898 faceIdsTmp->SetNumberOfIds( npts );
899 for ( auto ai = 0; ai < npts; ai++ )
900 faceIdsTmp->SetId( ai, pts[ai] );
901 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
903 for (faceId = 0; faceId < 5; faceId++)
906 const vtkIdType *faceVerts = vtkPyramid::GetFaceArray(faceId);
907 faceIds->InsertNextId(pts[faceVerts[0]]);
908 faceIds->InsertNextId(pts[faceVerts[1]]);
909 faceIds->InsertNextId(pts[faceVerts[2]]);
910 aCellType = VTK_TRIANGLE;
912 if (faceVerts[3] >= 0)
914 faceIds->InsertNextId(pts[faceVerts[3]]);
915 aCellType = VTK_QUAD;
918 input->GetCellNeighbors(cellId, faceIds, cellIds);
919 vtkIdType nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
920 #ifdef SHOW_COINCIDING_3D_PAL21924
921 bool process = nbNeighbors <= 0;
923 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
925 if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
927 for ( i=0; i < numFacePts; i++)
928 aNewPts[i] = pts[faceVerts[i]];
929 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
931 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
932 outputCD->CopyData(cd,cellId,newCellId);
939 #if VTK_XVERSION > 50700
942 vtkIdType nFaces = 0;
943 const vtkIdType* ptIds = 0;
945 input->GetFaceStream(cellId, nFaces, ptIds);
946 #ifdef SHOW_COINCIDING_3D_PAL21924
949 faceIdsTmp->Reset(); // use 2 facets
950 numFacePts = ptIds[idp];
951 for (i = 0; i < numFacePts; i++)
952 faceIdsTmp->InsertNextId(ptIds[idp + i]);
954 numFacePts = ptIds[idp];
955 for (i = 0; i < numFacePts; i++)
956 faceIdsTmp->InsertNextId(ptIds[idp + i]);
957 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
961 for (faceId = 0; faceId < nFaces; faceId++)
964 numFacePts = ptIds[idp];
965 vtkIdType pt0 = ++idp;
966 for (i = 0; i < numFacePts; i++)
968 faceIds->InsertNextId(ptIds[idp + i]);
973 case 3: aCellType = VTK_TRIANGLE; break;
974 case 4: aCellType = VTK_QUAD; break;
975 default:aCellType = VTK_POLYGON;
977 input->GetCellNeighbors(cellId, faceIds, cellIds);
978 vtkIdType nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
979 if ( myShowInside && nbNeighbors > 0 && cellId < cellIds->GetId(0) )
980 continue; // don't add twice same internal face in wireframe mode
981 #ifdef SHOW_COINCIDING_3D_PAL21924
982 bool process = nbNeighbors <= 0;
984 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
986 if (process || myShowInside
987 || (!allVisible && !cellVis[cellIds->GetId(0)]))
989 for (i = 0; i < numFacePts; i++)
990 aNewPts[i] = ptIds[pt0 + i];
991 newCellId = output->InsertNextCell(aCellType, numFacePts, aNewPts);
993 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
994 outputCD->CopyData(cd, cellId, newCellId);
1001 case VTK_QUADRATIC_EDGE:
1002 case VTK_QUADRATIC_TRIANGLE:
1003 case VTK_BIQUADRATIC_TRIANGLE:
1004 case VTK_QUADRATIC_QUAD:
1005 case VTK_BIQUADRATIC_QUAD:
1006 case VTK_QUADRATIC_POLYGON:
1007 case VTK_QUADRATIC_TETRA:
1008 case VTK_QUADRATIC_HEXAHEDRON:
1009 case VTK_TRIQUADRATIC_HEXAHEDRON:
1010 case VTK_QUADRATIC_WEDGE:
1011 case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
1012 case VTK_QUADRATIC_PYRAMID:
1014 if(!myIsWireframeMode)
1016 input->GetCell(cellId,cell);
1017 vtkIdList *lpts = vtkIdList::New();
1018 vtkPoints *coords = vtkPoints::New();
1019 vtkIdList *cellIds = vtkIdList::New();
1020 vtkIdType newCellId;
1022 if ( cell->GetCellDimension() == 1 ) {
1023 vtkIdType arcResult = -1;
1025 arcResult = Build1DArc(cellId, input, output, const_cast<vtkIdType *>(pts), myMaxArcAngle);
1026 newCellId = arcResult;
1029 if(!myIsBuildArc || arcResult == -1 ) {
1030 aCellType = VTK_LINE;
1032 cell->Triangulate(0,lpts,coords);
1033 for (i=0; i < lpts->GetNumberOfIds(); i+=2) {
1034 aNewPts[0] = lpts->GetId(i);
1035 aNewPts[1] = lpts->GetId(i+1);
1036 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1038 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1039 outputCD->CopyData(cd,cellId,newCellId);
1044 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1045 outputCD->CopyData(cd,cellId,newCellId);
1048 else if ( cell->GetCellDimension() == 2 ) {
1050 aCellType = VTK_TRIANGLE;
1052 cell->Triangulate(0,lpts,coords);
1053 for (i=0; i < lpts->GetNumberOfIds(); i+=3) {
1054 aNewPts[0] = lpts->GetId(i);
1055 aNewPts[1] = lpts->GetId(i+1);
1056 aNewPts[2] = lpts->GetId(i+2);
1057 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1059 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1060 outputCD->CopyData(cd,cellId,newCellId);
1064 BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds,true);
1067 else //3D nonlinear cell
1069 #ifdef SHOW_COINCIDING_3D_PAL21924
1070 if ( !myShowInside )
1072 vtkIdType npts1 = 0;
1073 switch (aCellType ){
1074 case VTK_QUADRATIC_TETRA: npts1 = 4; break;
1075 case VTK_QUADRATIC_HEXAHEDRON: npts1 = 8; break;
1076 case VTK_TRIQUADRATIC_HEXAHEDRON: npts1 = 8; break;
1077 case VTK_QUADRATIC_WEDGE: npts1 = 6; break;
1078 case VTK_BIQUADRATIC_QUADRATIC_WEDGE: npts1 = 6; break;
1079 case VTK_QUADRATIC_PYRAMID: npts1 = 5; break;
1081 faceIdsTmp->SetNumberOfIds( npts1 );
1083 for (auto ai=0; ai<npts1; ai++)
1084 faceIdsTmp->SetId( ai, pts[ai] );
1085 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
1089 aCellType = VTK_TRIANGLE;
1091 vtkIdType nbNeighbors = 0;
1092 for (auto j=0; j < cell->GetNumberOfFaces(); j++)
1094 vtkCell *face = cell->GetFace(j);
1095 if ( !myShowInside ) {
1096 input->GetCellNeighbors(cellId, face->PointIds, cellIds);
1097 nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
1099 #ifdef SHOW_COINCIDING_3D_PAL21924
1100 bool process = nbNeighbors <= 0;
1102 bool process = nbNeighbors <= 0 || GetAppendCoincident3D();
1104 if ( process || myShowInside ) {
1105 face->Triangulate(0,lpts,coords);
1106 for (i=0; i < lpts->GetNumberOfIds(); i+=3) {
1107 aNewPts[0] = lpts->GetId(i);
1108 aNewPts[1] = lpts->GetId(i+1);
1109 aNewPts[2] = lpts->GetId(i+2);
1110 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1112 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1113 outputCD->CopyData(cd,cellId,newCellId);
1117 } //3d nonlinear cell
1125 case VTK_QUADRATIC_EDGE:
1127 vtkIdType arcResult = -1;
1129 arcResult = Build1DArc(cellId, input, output, const_cast<vtkIdType *>(pts), myMaxArcAngle);
1130 newCellId = arcResult;
1132 if(!myIsBuildArc || arcResult == -1) {
1133 aCellType = VTK_POLY_LINE;
1136 aNewPts[0] = pts[0];
1137 aNewPts[2] = pts[1];
1138 aNewPts[1] = pts[2];
1140 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1144 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1146 outputCD->CopyData(cd,cellId,newCellId);
1149 case VTK_QUADRATIC_TRIANGLE:
1150 case VTK_BIQUADRATIC_TRIANGLE:
1153 aCellType = VTK_POLYGON;
1156 aNewPts[0] = pts[0];
1157 aNewPts[1] = pts[3];
1158 aNewPts[2] = pts[1];
1159 aNewPts[3] = pts[4];
1160 aNewPts[4] = pts[2];
1161 aNewPts[5] = pts[5];
1163 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1165 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1167 outputCD->CopyData(cd,cellId,newCellId);
1170 BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds);
1173 case VTK_QUADRATIC_QUAD:
1174 case VTK_BIQUADRATIC_QUAD:
1177 aCellType = VTK_POLYGON;
1180 aNewPts[0] = pts[0];
1181 aNewPts[1] = pts[4];
1182 aNewPts[2] = pts[1];
1183 aNewPts[3] = pts[5];
1184 aNewPts[4] = pts[2];
1185 aNewPts[5] = pts[6];
1186 aNewPts[6] = pts[3];
1187 aNewPts[7] = pts[7];
1189 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1191 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1193 outputCD->CopyData(cd,cellId,newCellId);
1196 BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds);
1199 case VTK_QUADRATIC_POLYGON:
1203 aCellType = VTK_POLYGON;
1205 for ( i = 0; i < npts/2; ++i )
1207 aNewPts[i*2 ] = pts[i];
1208 aNewPts[i*2+1] = pts[i+npts/2];
1210 newCellId = output->InsertNextCell(aCellType,npts,aNewPts);
1212 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1214 outputCD->CopyData(cd,cellId,newCellId);
1217 BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds);
1220 case VTK_QUADRATIC_TETRA:
1221 case VTK_QUADRATIC_WEDGE:
1222 case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
1223 case VTK_TRIQUADRATIC_HEXAHEDRON:
1224 case VTK_QUADRATIC_HEXAHEDRON:
1225 case VTK_QUADRATIC_PYRAMID:
1227 aCellType = VTK_POLY_LINE;
1228 input->GetCell(cellId,cell);
1231 int nbEdges = cell->GetNumberOfEdges();
1232 for ( int edgeId = 0; edgeId < nbEdges; ++edgeId )
1234 vtkCell * edge = cell->GetEdge( edgeId );
1235 if ( toShowEdge( edge->GetPointId(0), edge->GetPointId(2), cellId, input ))
1237 aNewPts[0] = edge->GetPointId(0);
1238 aNewPts[1] = edge->GetPointId(2);
1239 aNewPts[2] = edge->GetPointId(1);
1240 newCellId = output->InsertNextCell( aCellType, 3, aNewPts );
1242 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1243 outputCD->CopyData(cd,cellId,newCellId);
1249 vtkIdType nbCoincident = 0;
1250 #ifdef SHOW_COINCIDING_3D_PAL21924
1251 vtkIdType nbPnt = npts - cell->GetNumberOfEdges();
1252 faceIdsTmp->SetNumberOfIds( nbPnt );
1253 for ( auto ai = 0; ai < nbPnt; ai++ )
1254 faceIdsTmp->SetId( ai, pts[ai] );
1255 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
1256 nbCoincident = cellIdsTmp->GetNumberOfIds();
1259 int nbFaces = cell->GetNumberOfFaces();
1260 for ( faceId = 0; faceId < nbFaces; faceId++ )
1262 vtkCell * face = cell->GetFace( faceId );
1263 input->GetCellNeighbors( cellId, face->GetPointIds(), cellIds );
1264 vtkIdType nbNeighbors = cellIds->GetNumberOfIds() - nbCoincident;
1265 if ( nbNeighbors <= 0 )
1267 vtkIdType nbEdges = face->GetNumberOfPoints() / 2;
1268 for ( auto edgeId = 0; edgeId < nbEdges; ++edgeId )
1270 vtkIdType p1 = ( edgeId ); // corner
1271 vtkIdType p2 = ( edgeId + nbEdges ); // medium
1272 vtkIdType p3 = ( edgeId + 1 ) % nbEdges; // next corner
1273 faceIdsTmp->SetNumberOfIds( 2 );
1274 faceIdsTmp->SetId( 0, face->GetPointId(p2) );
1275 faceIdsTmp->SetId( 1, face->GetPointId(p1) );
1276 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
1278 switch ( cellIdsTmp->GetNumberOfIds() ) {
1279 case 0: // the edge belong to this cell only
1280 // avoid adding it when treating another face
1281 process = midPoints.insert( face->GetPointId(p2) ).second; break;
1282 case 1: // the edge is shared by two cells
1283 process = ( cellIdsTmp->GetId(0) < cellId ); break;
1284 default: // the edge is shared by >2 cells
1285 process = ( cellIdsTmp->GetId(0) < cellId ); break;
1289 aNewPts[0] = face->GetPointId( p1 );
1290 aNewPts[1] = face->GetPointId( p2 );
1291 aNewPts[2] = face->GetPointId( p3 );
1292 newCellId = output->InsertNextCell( aCellType, 3, aNewPts );
1294 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1295 outputCD->CopyData(cd,cellId,newCellId);
1302 } // case of volumes in wireframe
1303 } // switch by quadratic type
1313 vtkDebugMacro(<<"Extracted " << input->GetNumberOfPoints() << " points,"
1314 << output->GetNumberOfCells() << " cells.");
1320 cellIdsTmp->Delete();
1321 faceIdsTmp->Delete();
1328 if ( input->GetCellLinks() )
1330 input->GetCellLinks()->Initialize(); // free memory
1333 // fill myVTK2ObjIds vector in ascending cell dimension order
1334 myVTK2ObjIds.clear();
1335 if( myStoreMapping && !aDimension2VTK2ObjIds.empty() )
1337 size_t nbCells = ( aDimension2VTK2ObjIds[0].size() +
1338 aDimension2VTK2ObjIds[1].size() +
1339 aDimension2VTK2ObjIds[2].size() );
1340 if ( myVTK2ObjIds.capacity() > nbCells )
1341 TVectorId().swap( myVTK2ObjIds );
1342 myVTK2ObjIds.reserve( nbCells );
1344 for( int aDimension = 0; aDimension <= 2; aDimension++ )
1345 if ( !aDimension2VTK2ObjIds[ aDimension ].empty() )
1347 myVTK2ObjIds.insert( myVTK2ObjIds.end(),
1348 aDimension2VTK2ObjIds[ aDimension ].begin(),
1349 aDimension2VTK2ObjIds[ aDimension ].end() );
1350 TVectorId().swap( aDimension2VTK2ObjIds[ aDimension ]);
1358 VTKViewer_GeometryFilter
1359 ::InsertId( const vtkIdType theCellId,
1360 const vtkIdType theCellType,
1361 TVectorId& /*theVTK2ObjIds*/,
1362 TMapOfVectorId& theDimension2VTK2ObjIds )
1364 //theVTK2ObjIds.push_back( theCellId );
1367 switch( theCellType )
1370 case VTK_POLY_VERTEX:
1378 case VTK_TRIANGLE_STRIP:
1386 TVectorId& aCellIds = theDimension2VTK2ObjIds[ aDimension ];
1387 aCellIds.push_back( theCellId );
1391 VTKViewer_GeometryFilter
1392 ::SetInside(int theShowInside)
1394 if(myShowInside == theShowInside)
1397 myShowInside = theShowInside;
1402 VTKViewer_GeometryFilter
1405 return myShowInside;
1410 VTKViewer_GeometryFilter
1411 ::SetWireframeMode(int theIsWireframeMode)
1413 if(myIsWireframeMode == theIsWireframeMode)
1416 myIsWireframeMode = theIsWireframeMode;
1421 VTKViewer_GeometryFilter
1422 ::GetWireframeMode()
1424 return myIsWireframeMode;
1429 VTKViewer_GeometryFilter
1430 ::SetStoreMapping(int theStoreMapping)
1432 if(myStoreMapping == theStoreMapping)
1435 myStoreMapping = theStoreMapping;
1440 VTKViewer_GeometryFilter
1443 return myStoreMapping;
1447 vtkIdType VTKViewer_GeometryFilter::GetElemObjId( vtkIdType theVtkID )
1449 if( theVtkID < 0 || theVtkID >= (vtkIdType)myVTK2ObjIds.size() )
1451 return myVTK2ObjIds[theVtkID];
1455 void VTKViewer_GeometryFilter::BuildArcedPolygon(vtkIdType cellId,
1456 vtkUnstructuredGrid* input,
1457 vtkPolyData *output,
1458 TMapOfVectorId& theDimension2VTK2ObjIds,
1461 vtkIdType aCellType = VTK_POLYGON;
1462 vtkIdType *aNewPoints = NULL;
1463 vtkIdType aNbPoints = 0;
1464 vtkIdType newCellId;
1466 //Input and output cell data
1467 vtkCellData *cd = input->GetCellData();
1468 vtkCellData *outputCD = output->GetCellData();
1470 //Input and output scalars on point data
1471 vtkDataArray* inputScalars = input->GetPointData()->GetScalars();
1472 vtkDataArray* outputScalars = output->GetPointData()->GetScalars();
1474 std::vector< vtkSmartPointer<vtkPoints> > aCollection;
1475 std::vector< std::vector<double> > aScalarCollection;
1477 vtkCell* aCell = input->GetCell(cellId);
1478 switch(aCell->GetCellType()) {
1479 case VTK_QUADRATIC_TRIANGLE:
1480 case VTK_BIQUADRATIC_TRIANGLE:
1482 //Get All points from input cell
1483 Pnt P0 = CreatePnt( aCell, inputScalars, 0 );
1484 Pnt P1 = CreatePnt( aCell, inputScalars, 1 );
1485 Pnt P2 = CreatePnt( aCell, inputScalars, 2 );
1486 Pnt P3 = CreatePnt( aCell, inputScalars, 3 );
1487 Pnt P4 = CreatePnt( aCell, inputScalars, 4 );
1488 Pnt P5 = CreatePnt( aCell, inputScalars, 5 );
1490 VTKViewer_ArcBuilder aBuilder1(P0,P3,P1,myMaxArcAngle); //Build arc using 0, 3 and 1 points
1492 cout << "Quadrangle arc 1 " << ( aBuilder1.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1495 VTKViewer_ArcBuilder aBuilder2(P1,P4,P2,myMaxArcAngle); //Build arc using 1, 4 and 2 points
1497 cout << "Quadrangle arc 2 " << ( aBuilder2.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1500 VTKViewer_ArcBuilder aBuilder3(P2,P5,P0,myMaxArcAngle); //Build arc using 2, 5 and 0 points
1502 cout << "Quadrangle arc 3 " << ( aBuilder3.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1505 aCollection.push_back(aBuilder1.GetPoints());
1506 aCollection.push_back(aBuilder2.GetPoints());
1507 aCollection.push_back(aBuilder3.GetPoints());
1509 aScalarCollection.push_back(aBuilder1.GetScalarValues());
1510 aScalarCollection.push_back(aBuilder2.GetScalarValues());
1511 aScalarCollection.push_back(aBuilder3.GetScalarValues());
1514 case VTK_QUADRATIC_QUAD:
1515 case VTK_BIQUADRATIC_QUAD:
1517 //Get All points from input cell
1518 Pnt P0 = CreatePnt( aCell, inputScalars, 0 );
1519 Pnt P1 = CreatePnt( aCell, inputScalars, 1 );
1520 Pnt P2 = CreatePnt( aCell, inputScalars, 2 );
1521 Pnt P3 = CreatePnt( aCell, inputScalars, 3 );
1522 Pnt P4 = CreatePnt( aCell, inputScalars, 4 );
1523 Pnt P5 = CreatePnt( aCell, inputScalars, 5 );
1524 Pnt P6 = CreatePnt( aCell, inputScalars, 6 );
1525 Pnt P7 = CreatePnt( aCell, inputScalars, 7 );
1527 VTKViewer_ArcBuilder aBuilder1(P0,P4,P1,myMaxArcAngle); //Build arc using 0, 4 and 1 points
1529 cout << "Quadrangle arc 1 " << ( aBuilder1.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1532 VTKViewer_ArcBuilder aBuilder2(P1,P5,P2,myMaxArcAngle); //Build arc using 1, 5 and 2 points
1534 cout << "Quadrangle arc 2 " << ( aBuilder2.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1537 VTKViewer_ArcBuilder aBuilder3(P2,P6,P3,myMaxArcAngle); //Build arc using 2, 6 and 3 points
1539 cout << "Quadrangle arc 3 " << ( aBuilder3.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1542 VTKViewer_ArcBuilder aBuilder4(P3,P7,P0,myMaxArcAngle); //Build arc using 3, 7 and 0 points
1544 cout << "Quadrangle arc 4 " << ( aBuilder4.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1547 aCollection.push_back(aBuilder1.GetPoints());
1548 aCollection.push_back(aBuilder2.GetPoints());
1549 aCollection.push_back(aBuilder3.GetPoints());
1550 aCollection.push_back(aBuilder4.GetPoints());
1552 aScalarCollection.push_back(aBuilder1.GetScalarValues());
1553 aScalarCollection.push_back(aBuilder2.GetScalarValues());
1554 aScalarCollection.push_back(aBuilder3.GetScalarValues());
1555 aScalarCollection.push_back(aBuilder4.GetScalarValues());
1558 case VTK_QUADRATIC_POLYGON:
1560 vtkIdType nbP = aCell->GetNumberOfPoints();
1561 std::vector< Pnt > pVec( nbP + 2 );
1563 for ( auto i = 0; i < nbP/2; ++i )
1565 pVec[i*2 + 0] = CreatePnt( aCell, inputScalars, i );
1566 pVec[i*2 + 1] = CreatePnt( aCell, inputScalars, i + nbP/2 );
1568 pVec[ nbP ] = pVec[ 0 ];
1569 pVec[ nbP+1 ] = pVec[ 1 ];
1571 for ( auto i = 0; i < nbP; i += 2 )
1573 VTKViewer_ArcBuilder aBuilder( pVec[i], pVec[i+1], pVec[i+2], myMaxArcAngle );
1574 aCollection.push_back( aBuilder.GetPoints() );
1575 aScalarCollection.push_back( aBuilder.GetScalarValues() );
1579 default: //Unsupported cell type
1584 const vtkIdType numFacePts = 3;
1585 vtkIdList *pts = vtkIdList::New();
1586 vtkPoints *coords = vtkPoints::New();
1587 aCellType = VTK_TRIANGLE;
1588 vtkIdType aNewPts[numFacePts];
1589 vtkIdType aTriangleId;
1591 vtkPolygon *aPlg = vtkPolygon::New();
1592 std::map<vtkIdType, double> aPntId2ScalarValue;
1593 aNbPoints = MergevtkPoints(aCollection, aScalarCollection, aPlg->GetPoints(), aPntId2ScalarValue, aNewPoints);
1594 aPlg->GetPointIds()->SetNumberOfIds(aNbPoints);
1596 for(vtkIdType i = 0; i < aNbPoints;i++) {
1597 aPlg->GetPointIds()->SetId(i, aNewPoints[i]);
1600 aPlg->Triangulate(0,pts,coords);
1602 for (vtkIdType i=0; i < pts->GetNumberOfIds(); i+=3) {
1603 aNewPts[0] = output->GetPoints()->InsertNextPoint(coords->GetPoint(i));
1604 aNewPts[1] = output->GetPoints()->InsertNextPoint(coords->GetPoint(i+1));
1605 aNewPts[2] = output->GetPoints()->InsertNextPoint(coords->GetPoint(i+2));
1608 outputScalars->InsertNextTuple1(aPntId2ScalarValue[pts->GetId(i)]);
1609 outputScalars->InsertNextTuple1(aPntId2ScalarValue[pts->GetId(i+1)]);
1610 outputScalars->InsertNextTuple1(aPntId2ScalarValue[pts->GetId(i+2)]);
1613 aTriangleId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1616 InsertId( cellId, aCellType, myVTK2ObjIds, theDimension2VTK2ObjIds );
1617 outputCD->CopyData(cd,cellId,aTriangleId);
1624 std::map<vtkIdType, double> aPntId2ScalarValue;
1625 aNbPoints = MergevtkPoints(aCollection, aScalarCollection, output->GetPoints(), aPntId2ScalarValue, aNewPoints);
1627 for(vtkIdType i = 0; i < aNbPoints; i++)
1628 outputScalars->InsertNextTuple1(aPntId2ScalarValue[aNewPoints[i]]);
1629 newCellId = output->InsertNextCell(aCellType,aNbPoints,aNewPoints);
1630 outputCD->CopyData(cd,cellId,newCellId);
1633 InsertId( cellId, aCellType, myVTK2ObjIds, theDimension2VTK2ObjIds );
1637 delete [] aNewPoints;
1641 void VTKViewer_GeometryFilter::SetQuadraticArcMode(bool theFlag)
1643 if(myIsBuildArc != theFlag) {
1644 myIsBuildArc = theFlag;
1648 bool VTKViewer_GeometryFilter::GetQuadraticArcMode() const
1650 return myIsBuildArc;
1653 void VTKViewer_GeometryFilter::SetQuadraticArcAngle(double theMaxAngle)
1655 if(myMaxArcAngle != theMaxAngle) {
1656 myMaxArcAngle = theMaxAngle;
1661 double VTKViewer_GeometryFilter:: GetQuadraticArcAngle() const
1663 return myMaxArcAngle;
1666 int VTKViewer_GeometryFilter::GetAppendCoincident3D() const {
1667 // VSR 26/10/2012: see description of SHOW_COINCIDING_3D_PAL20314
1668 // in the top of this file
1669 #ifdef SHOW_COINCIDING_3D_PAL20314
1670 return myAppendCoincident3D;
1676 void VTKViewer_GeometryFilter::SetAppendCoincident3D(int theFlag) {
1677 if(myAppendCoincident3D != theFlag){
1678 myAppendCoincident3D = theFlag;