1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkUnstructuredGrid.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 
16 // Hide VTK_DEPRECATED_IN_9_0_0() warnings for this class.
17 #define VTK_DEPRECATION_LEVEL 0
18 
19 #include "vtkUnstructuredGrid.h"
20 
21 #include "vtkArrayDispatch.h"
22 #include "vtkBezierCurve.h"
23 #include "vtkBezierHexahedron.h"
24 #include "vtkBezierQuadrilateral.h"
25 #include "vtkBezierTetra.h"
26 #include "vtkBezierTriangle.h"
27 #include "vtkBezierWedge.h"
28 #include "vtkBiQuadraticQuad.h"
29 #include "vtkBiQuadraticQuadraticHexahedron.h"
30 #include "vtkBiQuadraticQuadraticWedge.h"
31 #include "vtkBiQuadraticTriangle.h"
32 #include "vtkCellArray.h"
33 #include "vtkCellArrayIterator.h"
34 #include "vtkCellData.h"
35 #include "vtkCellLinks.h"
36 #include "vtkCellTypes.h"
37 #include "vtkConvexPointSet.h"
38 #include "vtkCubicLine.h"
39 #include "vtkDataArrayRange.h"
40 #include "vtkDoubleArray.h"
41 #include "vtkEmptyCell.h"
42 #include "vtkGenericCell.h"
43 #include "vtkHexagonalPrism.h"
44 #include "vtkHexahedron.h"
45 #include "vtkInformation.h"
46 #include "vtkInformationVector.h"
47 #include "vtkLagrangeCurve.h"
48 #include "vtkLagrangeHexahedron.h"
49 #include "vtkLagrangeQuadrilateral.h"
50 #include "vtkLagrangeTetra.h"
51 #include "vtkLagrangeTriangle.h"
52 #include "vtkLagrangeWedge.h"
53 #include "vtkLine.h"
54 #include "vtkNew.h"
55 #include "vtkObjectFactory.h"
56 #include "vtkPentagonalPrism.h"
57 #include "vtkPixel.h"
58 #include "vtkPointData.h"
59 #include "vtkPolyLine.h"
60 #include "vtkPolyVertex.h"
61 #include "vtkPolygon.h"
62 #include "vtkPolyhedron.h"
63 #include "vtkPyramid.h"
64 #include "vtkQuad.h"
65 #include "vtkQuadraticEdge.h"
66 #include "vtkQuadraticHexahedron.h"
67 #include "vtkQuadraticLinearQuad.h"
68 #include "vtkQuadraticLinearWedge.h"
69 #include "vtkQuadraticPolygon.h"
70 #include "vtkQuadraticPyramid.h"
71 #include "vtkQuadraticQuad.h"
72 #include "vtkQuadraticTetra.h"
73 #include "vtkQuadraticTriangle.h"
74 #include "vtkQuadraticWedge.h"
75 #include "vtkSMPTools.h"
76 #include "vtkStaticCellLinks.h"
77 #include "vtkTetra.h"
78 #include "vtkTriQuadraticHexahedron.h"
79 #include "vtkTriQuadraticPyramid.h"
80 #include "vtkTriangle.h"
81 #include "vtkTriangleStrip.h"
82 #include "vtkUnsignedCharArray.h"
83 #include "vtkUnstructuredGridCellIterator.h"
84 #include "vtkVertex.h"
85 #include "vtkVoxel.h"
86 #include "vtkWedge.h"
87 
88 #include <algorithm>
89 #include <set>
90 
91 vtkStandardNewMacro(vtkUnstructuredGrid);
92 vtkStandardExtendedNewMacro(vtkUnstructuredGrid);
93 
94 //------------------------------------------------------------------------------
GetCellLocationsArray()95 vtkIdTypeArray* vtkUnstructuredGrid::GetCellLocationsArray()
96 {
97   if (!this->CellLocations)
98   {
99     this->CellLocations = vtkSmartPointer<vtkIdTypeArray>::New();
100   }
101   this->CellLocations->DeepCopy(this->Connectivity->GetOffsetsArray());
102   this->CellLocations->SetNumberOfValues(this->GetNumberOfCells());
103 
104   return this->CellLocations;
105 }
106 
107 //------------------------------------------------------------------------------
SetCells(vtkUnsignedCharArray * cellTypes,vtkIdTypeArray *,vtkCellArray * cells)108 void vtkUnstructuredGrid::SetCells(
109   vtkUnsignedCharArray* cellTypes, vtkIdTypeArray*, vtkCellArray* cells)
110 {
111   this->SetCells(cellTypes, cells);
112 }
113 
114 //------------------------------------------------------------------------------
SetCells(vtkUnsignedCharArray * cellTypes,vtkIdTypeArray *,vtkCellArray * cells,vtkIdTypeArray * faceLocations,vtkIdTypeArray * faces)115 void vtkUnstructuredGrid::SetCells(vtkUnsignedCharArray* cellTypes, vtkIdTypeArray*,
116   vtkCellArray* cells, vtkIdTypeArray* faceLocations, vtkIdTypeArray* faces)
117 {
118   this->SetCells(cellTypes, cells, faceLocations, faces);
119 }
120 
121 //------------------------------------------------------------------------------
vtkUnstructuredGrid()122 vtkUnstructuredGrid::vtkUnstructuredGrid()
123 {
124   this->Vertex = nullptr;
125   this->PolyVertex = nullptr;
126   this->BezierCurve = nullptr;
127   this->BezierQuadrilateral = nullptr;
128   this->BezierHexahedron = nullptr;
129   this->BezierTriangle = nullptr;
130   this->BezierTetra = nullptr;
131   this->BezierWedge = nullptr;
132   this->LagrangeCurve = nullptr;
133   this->LagrangeQuadrilateral = nullptr;
134   this->LagrangeHexahedron = nullptr;
135   this->LagrangeTriangle = nullptr;
136   this->LagrangeTetra = nullptr;
137   this->LagrangeWedge = nullptr;
138   this->Line = nullptr;
139   this->PolyLine = nullptr;
140   this->Triangle = nullptr;
141   this->TriangleStrip = nullptr;
142   this->Pixel = nullptr;
143   this->Quad = nullptr;
144   this->Polygon = nullptr;
145   this->Tetra = nullptr;
146   this->Voxel = nullptr;
147   this->Hexahedron = nullptr;
148   this->Wedge = nullptr;
149   this->Pyramid = nullptr;
150   this->PentagonalPrism = nullptr;
151   this->HexagonalPrism = nullptr;
152   this->QuadraticEdge = nullptr;
153   this->QuadraticTriangle = nullptr;
154   this->QuadraticQuad = nullptr;
155   this->QuadraticPolygon = nullptr;
156   this->QuadraticTetra = nullptr;
157   this->QuadraticHexahedron = nullptr;
158   this->QuadraticWedge = nullptr;
159   this->QuadraticPyramid = nullptr;
160   this->QuadraticLinearQuad = nullptr;
161   this->BiQuadraticQuad = nullptr;
162   this->TriQuadraticHexahedron = nullptr;
163   this->TriQuadraticPyramid = nullptr;
164   this->QuadraticLinearWedge = nullptr;
165   this->BiQuadraticQuadraticWedge = nullptr;
166   this->BiQuadraticQuadraticHexahedron = nullptr;
167   this->BiQuadraticTriangle = nullptr;
168   this->CubicLine = nullptr;
169 
170   this->ConvexPointSet = nullptr;
171   this->Polyhedron = nullptr;
172   this->EmptyCell = nullptr;
173 
174   this->Information->Set(vtkDataObject::DATA_EXTENT_TYPE(), VTK_PIECES_EXTENT);
175   this->Information->Set(vtkDataObject::DATA_PIECE_NUMBER(), -1);
176   this->Information->Set(vtkDataObject::DATA_NUMBER_OF_PIECES(), 1);
177   this->Information->Set(vtkDataObject::DATA_NUMBER_OF_GHOST_LEVELS(), 0);
178 
179   this->DistinctCellTypesUpdateMTime = 0;
180 
181   this->AllocateExact(1024, 1024);
182 }
183 
184 //------------------------------------------------------------------------------
~vtkUnstructuredGrid()185 vtkUnstructuredGrid::~vtkUnstructuredGrid()
186 {
187   if (this->Vertex)
188   {
189     this->Vertex->Delete();
190   }
191   if (this->PolyVertex)
192   {
193     this->PolyVertex->Delete();
194   }
195   if (this->BezierCurve)
196   {
197     this->BezierCurve->Delete();
198   }
199   if (this->BezierQuadrilateral)
200   {
201     this->BezierQuadrilateral->Delete();
202   }
203   if (this->BezierHexahedron)
204   {
205     this->BezierHexahedron->Delete();
206   }
207   if (this->BezierTriangle)
208   {
209     this->BezierTriangle->Delete();
210   }
211   if (this->BezierTetra)
212   {
213     this->BezierTetra->Delete();
214   }
215   if (this->BezierWedge)
216   {
217     this->BezierWedge->Delete();
218   }
219   if (this->LagrangeCurve)
220   {
221     this->LagrangeCurve->Delete();
222   }
223   if (this->LagrangeQuadrilateral)
224   {
225     this->LagrangeQuadrilateral->Delete();
226   }
227   if (this->LagrangeHexahedron)
228   {
229     this->LagrangeHexahedron->Delete();
230   }
231   if (this->LagrangeTriangle)
232   {
233     this->LagrangeTriangle->Delete();
234   }
235   if (this->LagrangeTetra)
236   {
237     this->LagrangeTetra->Delete();
238   }
239   if (this->LagrangeWedge)
240   {
241     this->LagrangeWedge->Delete();
242   }
243   if (this->Line)
244   {
245     this->Line->Delete();
246   }
247   if (this->PolyLine)
248   {
249     this->PolyLine->Delete();
250   }
251   if (this->Triangle)
252   {
253     this->Triangle->Delete();
254   }
255   if (this->TriangleStrip)
256   {
257     this->TriangleStrip->Delete();
258   }
259   if (this->Pixel)
260   {
261     this->Pixel->Delete();
262   }
263   if (this->Quad)
264   {
265     this->Quad->Delete();
266   }
267   if (this->Polygon)
268   {
269     this->Polygon->Delete();
270   }
271   if (this->Tetra)
272   {
273     this->Tetra->Delete();
274   }
275   if (this->Voxel)
276   {
277     this->Voxel->Delete();
278   }
279   if (this->Hexahedron)
280   {
281     this->Hexahedron->Delete();
282   }
283   if (this->Wedge)
284   {
285     this->Wedge->Delete();
286   }
287   if (this->Pyramid)
288   {
289     this->Pyramid->Delete();
290   }
291   if (this->PentagonalPrism)
292   {
293     this->PentagonalPrism->Delete();
294   }
295   if (this->HexagonalPrism)
296   {
297     this->HexagonalPrism->Delete();
298   }
299   if (this->QuadraticEdge)
300   {
301     this->QuadraticEdge->Delete();
302   }
303   if (this->QuadraticTriangle)
304   {
305     this->QuadraticTriangle->Delete();
306   }
307   if (this->QuadraticQuad)
308   {
309     this->QuadraticQuad->Delete();
310   }
311   if (this->QuadraticPolygon)
312   {
313     this->QuadraticPolygon->Delete();
314   }
315   if (this->QuadraticTetra)
316   {
317     this->QuadraticTetra->Delete();
318   }
319   if (this->QuadraticHexahedron)
320   {
321     this->QuadraticHexahedron->Delete();
322   }
323   if (this->QuadraticWedge)
324   {
325     this->QuadraticWedge->Delete();
326   }
327   if (this->QuadraticPyramid)
328   {
329     this->QuadraticPyramid->Delete();
330   }
331   if (this->QuadraticLinearQuad)
332   {
333     this->QuadraticLinearQuad->Delete();
334   }
335   if (this->BiQuadraticQuad)
336   {
337     this->BiQuadraticQuad->Delete();
338   }
339   if (this->TriQuadraticHexahedron)
340   {
341     this->TriQuadraticHexahedron->Delete();
342   }
343   if (this->TriQuadraticPyramid)
344   {
345     this->TriQuadraticPyramid->Delete();
346   }
347   if (this->QuadraticLinearWedge)
348   {
349     this->QuadraticLinearWedge->Delete();
350   }
351   if (this->BiQuadraticQuadraticWedge)
352   {
353     this->BiQuadraticQuadraticWedge->Delete();
354   }
355   if (this->BiQuadraticQuadraticHexahedron)
356   {
357     this->BiQuadraticQuadraticHexahedron->Delete();
358   }
359   if (this->BiQuadraticTriangle)
360   {
361     this->BiQuadraticTriangle->Delete();
362   }
363   if (this->CubicLine)
364   {
365     this->CubicLine->Delete();
366   }
367 
368   if (this->ConvexPointSet)
369   {
370     this->ConvexPointSet->Delete();
371   }
372   if (this->Polyhedron)
373   {
374     this->Polyhedron->Delete();
375   }
376   if (this->EmptyCell)
377   {
378     this->EmptyCell->Delete();
379   }
380 }
381 
382 //------------------------------------------------------------------------------
GetPiece()383 int vtkUnstructuredGrid::GetPiece()
384 {
385   return this->Information->Get(vtkDataObject::DATA_PIECE_NUMBER());
386 }
387 
388 //------------------------------------------------------------------------------
GetNumberOfPieces()389 int vtkUnstructuredGrid::GetNumberOfPieces()
390 {
391   return this->Information->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());
392 }
393 
394 //------------------------------------------------------------------------------
GetGhostLevel()395 int vtkUnstructuredGrid::GetGhostLevel()
396 {
397   return this->Information->Get(vtkDataObject::DATA_NUMBER_OF_GHOST_LEVELS());
398 }
399 
400 //------------------------------------------------------------------------------
401 // Copy the geometric and topological structure of an input unstructured grid.
CopyStructure(vtkDataSet * ds)402 void vtkUnstructuredGrid::CopyStructure(vtkDataSet* ds)
403 {
404   // If ds is a vtkUnstructuredGrid, do a shallow copy of the cell data.
405   if (vtkUnstructuredGrid* ug = vtkUnstructuredGrid::SafeDownCast(ds))
406   {
407     this->Connectivity = ug->Connectivity;
408     this->Links = ug->Links;
409     this->Types = ug->Types;
410     this->DistinctCellTypes = nullptr;
411     this->DistinctCellTypesUpdateMTime = 0;
412     this->Faces = ug->Faces;
413     this->FaceLocations = ug->FaceLocations;
414   }
415 
416   this->Superclass::CopyStructure(ds);
417 }
418 
419 //------------------------------------------------------------------------------
Cleanup()420 void vtkUnstructuredGrid::Cleanup()
421 {
422   this->Connectivity = nullptr;
423   this->Links = nullptr;
424   this->Types = nullptr;
425   this->DistinctCellTypes = nullptr;
426   this->DistinctCellTypesUpdateMTime = 0;
427   this->Faces = nullptr;
428   this->FaceLocations = nullptr;
429 }
430 
431 //------------------------------------------------------------------------------
Initialize()432 void vtkUnstructuredGrid::Initialize()
433 {
434   vtkPointSet::Initialize();
435 
436   this->Cleanup();
437 
438   if (this->Information)
439   {
440     this->Information->Set(vtkDataObject::DATA_PIECE_NUMBER(), -1);
441     this->Information->Set(vtkDataObject::DATA_NUMBER_OF_PIECES(), 0);
442     this->Information->Set(vtkDataObject::DATA_NUMBER_OF_GHOST_LEVELS(), 0);
443   }
444 }
445 
446 //------------------------------------------------------------------------------
GetCellType(vtkIdType cellId)447 int vtkUnstructuredGrid::GetCellType(vtkIdType cellId)
448 {
449   vtkDebugMacro(<< "Returning cell type " << static_cast<int>(this->Types->GetValue(cellId)));
450   return static_cast<int>(this->Types->GetValue(cellId));
451 }
452 
453 //------------------------------------------------------------------------------
GetCell(vtkIdType cellId)454 vtkCell* vtkUnstructuredGrid::GetCell(vtkIdType cellId)
455 {
456   vtkIdType numPts;
457   const vtkIdType* pts;
458   this->Connectivity->GetCellAtId(cellId, numPts, pts);
459 
460   vtkCell* cell = nullptr;
461   switch (this->Types->GetValue(cellId))
462   {
463     case VTK_VERTEX:
464       if (!this->Vertex)
465       {
466         this->Vertex = vtkVertex::New();
467       }
468       cell = this->Vertex;
469       break;
470 
471     case VTK_POLY_VERTEX:
472       if (!this->PolyVertex)
473       {
474         this->PolyVertex = vtkPolyVertex::New();
475       }
476       cell = this->PolyVertex;
477       break;
478 
479     case VTK_LINE:
480       if (!this->Line)
481       {
482         this->Line = vtkLine::New();
483       }
484       cell = this->Line;
485       break;
486 
487     case VTK_LAGRANGE_CURVE:
488       if (!this->LagrangeCurve)
489       {
490         this->LagrangeCurve = vtkLagrangeCurve::New();
491       }
492       cell = this->LagrangeCurve;
493       break;
494 
495     case VTK_LAGRANGE_QUADRILATERAL:
496     {
497       if (!this->LagrangeQuadrilateral)
498       {
499         this->LagrangeQuadrilateral = vtkLagrangeQuadrilateral::New();
500       }
501       vtkDataArray* v = GetCellData()->GetHigherOrderDegrees();
502       if (v)
503       {
504         double degs[3];
505         v->GetTuple(cellId, degs);
506         this->LagrangeQuadrilateral->SetOrder(degs[0], degs[1]);
507       }
508       else
509       {
510         this->LagrangeQuadrilateral->SetUniformOrderFromNumPoints(numPts);
511       }
512       cell = this->LagrangeQuadrilateral;
513       break;
514     }
515 
516     case VTK_LAGRANGE_HEXAHEDRON:
517     {
518       if (!this->LagrangeHexahedron)
519       {
520         this->LagrangeHexahedron = vtkLagrangeHexahedron::New();
521       }
522       vtkDataArray* v = GetCellData()->GetHigherOrderDegrees();
523       if (v)
524       {
525         double degs[3];
526         v->GetTuple(cellId, degs);
527         this->LagrangeHexahedron->SetOrder(degs[0], degs[1], degs[2]);
528       }
529       else
530       {
531         this->LagrangeHexahedron->SetUniformOrderFromNumPoints(numPts);
532       }
533       cell = this->LagrangeHexahedron;
534       break;
535     }
536 
537     case VTK_LAGRANGE_TRIANGLE:
538       if (!this->LagrangeTriangle)
539       {
540         this->LagrangeTriangle = vtkLagrangeTriangle::New();
541       }
542       cell = this->LagrangeTriangle;
543       break;
544 
545     case VTK_LAGRANGE_TETRAHEDRON:
546       if (!this->LagrangeTetra)
547       {
548         this->LagrangeTetra = vtkLagrangeTetra::New();
549       }
550       cell = this->LagrangeTetra;
551       break;
552 
553     case VTK_LAGRANGE_WEDGE:
554     {
555       if (!this->LagrangeWedge)
556       {
557         this->LagrangeWedge = vtkLagrangeWedge::New();
558       }
559       vtkDataArray* v = GetCellData()->GetHigherOrderDegrees();
560       if (v)
561       {
562         double degs[3];
563         v->GetTuple(cellId, degs);
564         this->LagrangeWedge->SetOrder(degs[0], degs[1], degs[2], numPts);
565       }
566       else
567       {
568         this->LagrangeWedge->SetUniformOrderFromNumPoints(numPts);
569       }
570       cell = this->LagrangeWedge;
571       break;
572     }
573 
574     case VTK_BEZIER_CURVE:
575     {
576       if (!this->BezierCurve)
577       {
578         this->BezierCurve = vtkBezierCurve::New();
579       }
580       vtkDataArray* wts = GetPointData()->GetRationalWeights();
581       if (wts)
582       {
583         this->BezierCurve->GetRationalWeights()->SetNumberOfTuples(numPts);
584         for (int i = 0; i < numPts; i++)
585         {
586           this->BezierCurve->GetRationalWeights()->SetValue(i, wts->GetTuple1(pts[i]));
587         }
588       }
589       else
590         this->BezierCurve->GetRationalWeights()->Reset();
591       cell = this->BezierCurve;
592       break;
593     }
594 
595     case VTK_BEZIER_QUADRILATERAL:
596     {
597       if (!this->BezierQuadrilateral)
598       {
599         this->BezierQuadrilateral = vtkBezierQuadrilateral::New();
600       }
601       vtkDataArray* v = GetCellData()->GetHigherOrderDegrees();
602       if (v)
603       {
604         double degs[3];
605         v->GetTuple(cellId, degs);
606         this->BezierQuadrilateral->SetOrder(degs[0], degs[1]);
607       }
608       else
609       {
610         this->BezierQuadrilateral->SetUniformOrderFromNumPoints(numPts);
611       }
612       vtkDataArray* wts = GetPointData()->GetRationalWeights();
613       if (wts)
614       {
615         this->BezierQuadrilateral->GetRationalWeights()->SetNumberOfTuples(numPts);
616         for (int i = 0; i < numPts; i++)
617         {
618           this->BezierQuadrilateral->GetRationalWeights()->SetValue(i, wts->GetTuple1(pts[i]));
619         }
620       }
621       else
622         this->BezierQuadrilateral->GetRationalWeights()->Reset();
623       cell = this->BezierQuadrilateral;
624       break;
625     }
626 
627     case VTK_BEZIER_HEXAHEDRON:
628     {
629       if (!this->BezierHexahedron)
630       {
631         this->BezierHexahedron = vtkBezierHexahedron::New();
632       }
633       vtkDataArray* v = GetCellData()->GetHigherOrderDegrees();
634       if (v)
635       {
636         double degs[3];
637         v->GetTuple(cellId, degs);
638         this->BezierHexahedron->SetOrder(degs[0], degs[1], degs[2]);
639       }
640       else
641       {
642         this->BezierHexahedron->SetUniformOrderFromNumPoints(numPts);
643       }
644       vtkDataArray* wts = GetPointData()->GetRationalWeights();
645       if (wts)
646       {
647         this->BezierHexahedron->GetRationalWeights()->SetNumberOfTuples(numPts);
648         for (int i = 0; i < numPts; i++)
649         {
650           this->BezierHexahedron->GetRationalWeights()->SetValue(i, wts->GetTuple1(pts[i]));
651         }
652       }
653       else
654         this->BezierHexahedron->GetRationalWeights()->Reset();
655       cell = this->BezierHexahedron;
656       break;
657     }
658 
659     case VTK_BEZIER_TRIANGLE:
660     {
661       if (!this->BezierTriangle)
662       {
663         this->BezierTriangle = vtkBezierTriangle::New();
664       }
665       vtkDataArray* wts = GetPointData()->GetRationalWeights();
666       if (wts)
667       {
668         this->BezierTriangle->GetRationalWeights()->SetNumberOfTuples(numPts);
669         for (int i = 0; i < numPts; i++)
670         {
671           this->BezierTriangle->GetRationalWeights()->SetValue(i, wts->GetTuple1(pts[i]));
672         }
673       }
674       else
675         this->BezierTriangle->GetRationalWeights()->Reset();
676       cell = this->BezierTriangle;
677       break;
678     }
679 
680     case VTK_BEZIER_TETRAHEDRON:
681     {
682       if (!this->BezierTetra)
683       {
684         this->BezierTetra = vtkBezierTetra::New();
685       }
686       vtkDataArray* wts = GetPointData()->GetRationalWeights();
687       if (wts)
688       {
689         this->BezierTetra->GetRationalWeights()->SetNumberOfTuples(numPts);
690         for (int i = 0; i < numPts; i++)
691         {
692           this->BezierTetra->GetRationalWeights()->SetValue(i, wts->GetTuple1(pts[i]));
693         }
694       }
695       else
696         this->BezierTetra->GetRationalWeights()->Reset();
697       cell = this->BezierTetra;
698       break;
699     }
700 
701     case VTK_BEZIER_WEDGE:
702     {
703       if (!this->BezierWedge)
704       {
705         this->BezierWedge = vtkBezierWedge::New();
706       }
707       vtkDataArray* v = GetCellData()->GetHigherOrderDegrees();
708       if (v)
709       {
710         double degs[3];
711         v->GetTuple(cellId, degs);
712         this->BezierWedge->SetOrder(degs[0], degs[1], degs[2], numPts);
713       }
714       else
715       {
716         this->BezierWedge->SetUniformOrderFromNumPoints(numPts);
717       }
718       vtkDataArray* wts = GetPointData()->GetRationalWeights();
719       if (wts)
720       {
721         this->BezierWedge->GetRationalWeights()->SetNumberOfTuples(numPts);
722         for (int i = 0; i < numPts; i++)
723         {
724           this->BezierWedge->GetRationalWeights()->SetValue(i, wts->GetTuple1(pts[i]));
725         }
726       }
727       else
728         this->BezierWedge->GetRationalWeights()->Reset();
729       cell = this->BezierWedge;
730       break;
731     }
732 
733     case VTK_POLY_LINE:
734       if (!this->PolyLine)
735       {
736         this->PolyLine = vtkPolyLine::New();
737       }
738       cell = this->PolyLine;
739       break;
740 
741     case VTK_TRIANGLE:
742       if (!this->Triangle)
743       {
744         this->Triangle = vtkTriangle::New();
745       }
746       cell = this->Triangle;
747       break;
748 
749     case VTK_TRIANGLE_STRIP:
750       if (!this->TriangleStrip)
751       {
752         this->TriangleStrip = vtkTriangleStrip::New();
753       }
754       cell = this->TriangleStrip;
755       break;
756 
757     case VTK_PIXEL:
758       if (!this->Pixel)
759       {
760         this->Pixel = vtkPixel::New();
761       }
762       cell = this->Pixel;
763       break;
764 
765     case VTK_QUAD:
766       if (!this->Quad)
767       {
768         this->Quad = vtkQuad::New();
769       }
770       cell = this->Quad;
771       break;
772 
773     case VTK_POLYGON:
774       if (!this->Polygon)
775       {
776         this->Polygon = vtkPolygon::New();
777       }
778       cell = this->Polygon;
779       break;
780 
781     case VTK_TETRA:
782       if (!this->Tetra)
783       {
784         this->Tetra = vtkTetra::New();
785       }
786       cell = this->Tetra;
787       break;
788 
789     case VTK_VOXEL:
790       if (!this->Voxel)
791       {
792         this->Voxel = vtkVoxel::New();
793       }
794       cell = this->Voxel;
795       break;
796 
797     case VTK_HEXAHEDRON:
798       if (!this->Hexahedron)
799       {
800         this->Hexahedron = vtkHexahedron::New();
801       }
802       cell = this->Hexahedron;
803       break;
804 
805     case VTK_WEDGE:
806       if (!this->Wedge)
807       {
808         this->Wedge = vtkWedge::New();
809       }
810       cell = this->Wedge;
811       break;
812 
813     case VTK_PYRAMID:
814       if (!this->Pyramid)
815       {
816         this->Pyramid = vtkPyramid::New();
817       }
818       cell = this->Pyramid;
819       break;
820 
821     case VTK_PENTAGONAL_PRISM:
822       if (!this->PentagonalPrism)
823       {
824         this->PentagonalPrism = vtkPentagonalPrism::New();
825       }
826       cell = this->PentagonalPrism;
827       break;
828 
829     case VTK_HEXAGONAL_PRISM:
830       if (!this->HexagonalPrism)
831       {
832         this->HexagonalPrism = vtkHexagonalPrism::New();
833       }
834       cell = this->HexagonalPrism;
835       break;
836 
837     case VTK_QUADRATIC_EDGE:
838       if (!this->QuadraticEdge)
839       {
840         this->QuadraticEdge = vtkQuadraticEdge::New();
841       }
842       cell = this->QuadraticEdge;
843       break;
844 
845     case VTK_QUADRATIC_TRIANGLE:
846       if (!this->QuadraticTriangle)
847       {
848         this->QuadraticTriangle = vtkQuadraticTriangle::New();
849       }
850       cell = this->QuadraticTriangle;
851       break;
852 
853     case VTK_QUADRATIC_QUAD:
854       if (!this->QuadraticQuad)
855       {
856         this->QuadraticQuad = vtkQuadraticQuad::New();
857       }
858       cell = this->QuadraticQuad;
859       break;
860 
861     case VTK_QUADRATIC_POLYGON:
862       if (!this->QuadraticPolygon)
863       {
864         this->QuadraticPolygon = vtkQuadraticPolygon::New();
865       }
866       cell = this->QuadraticPolygon;
867       break;
868 
869     case VTK_QUADRATIC_TETRA:
870       if (!this->QuadraticTetra)
871       {
872         this->QuadraticTetra = vtkQuadraticTetra::New();
873       }
874       cell = this->QuadraticTetra;
875       break;
876 
877     case VTK_QUADRATIC_HEXAHEDRON:
878       if (!this->QuadraticHexahedron)
879       {
880         this->QuadraticHexahedron = vtkQuadraticHexahedron::New();
881       }
882       cell = this->QuadraticHexahedron;
883       break;
884 
885     case VTK_QUADRATIC_WEDGE:
886       if (!this->QuadraticWedge)
887       {
888         this->QuadraticWedge = vtkQuadraticWedge::New();
889       }
890       cell = this->QuadraticWedge;
891       break;
892 
893     case VTK_QUADRATIC_PYRAMID:
894       if (!this->QuadraticPyramid)
895       {
896         this->QuadraticPyramid = vtkQuadraticPyramid::New();
897       }
898       cell = this->QuadraticPyramid;
899       break;
900 
901     case VTK_QUADRATIC_LINEAR_QUAD:
902       if (!this->QuadraticLinearQuad)
903       {
904         this->QuadraticLinearQuad = vtkQuadraticLinearQuad::New();
905       }
906       cell = this->QuadraticLinearQuad;
907       break;
908 
909     case VTK_BIQUADRATIC_QUAD:
910       if (!this->BiQuadraticQuad)
911       {
912         this->BiQuadraticQuad = vtkBiQuadraticQuad::New();
913       }
914       cell = this->BiQuadraticQuad;
915       break;
916 
917     case VTK_TRIQUADRATIC_HEXAHEDRON:
918       if (!this->TriQuadraticHexahedron)
919       {
920         this->TriQuadraticHexahedron = vtkTriQuadraticHexahedron::New();
921       }
922       cell = this->TriQuadraticHexahedron;
923       break;
924 
925     case VTK_TRIQUADRATIC_PYRAMID:
926       if (!this->TriQuadraticPyramid)
927       {
928         this->TriQuadraticPyramid = vtkTriQuadraticPyramid::New();
929       }
930       cell = this->TriQuadraticPyramid;
931       break;
932 
933     case VTK_QUADRATIC_LINEAR_WEDGE:
934       if (!this->QuadraticLinearWedge)
935       {
936         this->QuadraticLinearWedge = vtkQuadraticLinearWedge::New();
937       }
938       cell = this->QuadraticLinearWedge;
939       break;
940 
941     case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
942       if (!this->BiQuadraticQuadraticWedge)
943       {
944         this->BiQuadraticQuadraticWedge = vtkBiQuadraticQuadraticWedge::New();
945       }
946       cell = this->BiQuadraticQuadraticWedge;
947       break;
948 
949     case VTK_BIQUADRATIC_QUADRATIC_HEXAHEDRON:
950       if (!this->BiQuadraticQuadraticHexahedron)
951       {
952         this->BiQuadraticQuadraticHexahedron = vtkBiQuadraticQuadraticHexahedron::New();
953       }
954       cell = this->BiQuadraticQuadraticHexahedron;
955       break;
956 
957     case VTK_BIQUADRATIC_TRIANGLE:
958       if (!this->BiQuadraticTriangle)
959       {
960         this->BiQuadraticTriangle = vtkBiQuadraticTriangle::New();
961       }
962       cell = this->BiQuadraticTriangle;
963       break;
964 
965     case VTK_CUBIC_LINE:
966       if (!this->CubicLine)
967       {
968         this->CubicLine = vtkCubicLine::New();
969       }
970       cell = this->CubicLine;
971       break;
972 
973     case VTK_CONVEX_POINT_SET:
974       if (!this->ConvexPointSet)
975       {
976         this->ConvexPointSet = vtkConvexPointSet::New();
977       }
978       cell = this->ConvexPointSet;
979       break;
980 
981     case VTK_POLYHEDRON:
982       if (!this->Polyhedron)
983       {
984         this->Polyhedron = vtkPolyhedron::New();
985       }
986       this->Polyhedron->SetFaces(this->GetFaces(cellId));
987       cell = this->Polyhedron;
988       break;
989 
990     case VTK_EMPTY_CELL:
991       if (!this->EmptyCell)
992       {
993         this->EmptyCell = vtkEmptyCell::New();
994       }
995       cell = this->EmptyCell;
996       break;
997   }
998 
999   if (!cell)
1000   {
1001     return nullptr;
1002   }
1003 
1004   // Copy the points over to the cell.
1005   cell->PointIds->SetNumberOfIds(numPts);
1006   cell->Points->SetNumberOfPoints(numPts);
1007   for (vtkIdType i = 0; i < numPts; i++)
1008   {
1009     cell->PointIds->SetId(i, pts[i]);
1010     cell->Points->SetPoint(i, this->Points->GetPoint(pts[i]));
1011   }
1012 
1013   // Some cells require special initialization to build data structures
1014   // and such.
1015   if (cell->RequiresInitialization())
1016   {
1017     cell->Initialize();
1018   }
1019 
1020   return cell;
1021 }
1022 
1023 //------------------------------------------------------------------------------
GetCell(vtkIdType cellId,vtkGenericCell * cell)1024 void vtkUnstructuredGrid::GetCell(vtkIdType cellId, vtkGenericCell* cell)
1025 {
1026 
1027   int cellType = static_cast<int>(this->Types->GetValue(cellId));
1028   cell->SetCellType(cellType);
1029 
1030   this->Connectivity->GetCellAtId(cellId, cell->PointIds);
1031   this->Points->GetPoints(cell->PointIds, cell->Points);
1032 
1033   // Explicit face representation
1034   if (cell->RequiresExplicitFaceRepresentation())
1035   {
1036     cell->SetFaces(this->GetFaces(cellId));
1037   }
1038 
1039   // Some cells require special initialization to build data structures
1040   // and such.
1041   if (cell->RequiresInitialization())
1042   {
1043     cell->Initialize();
1044   }
1045   this->SetCellOrderAndRationalWeights(cellId, cell);
1046 }
1047 
1048 //------------------------------------------------------------------------------
1049 // Support GetCellBounds()
1050 namespace
1051 { // anonymous
1052 struct ComputeCellBoundsWorker
1053 {
1054   struct Visitor
1055   {
1056     // vtkCellArray::Visit entry point:
1057     template <typename CellStateT, typename PointArrayT>
operator ()__anon5f8c9a0d0111::ComputeCellBoundsWorker::Visitor1058     void operator()(
1059       CellStateT& state, PointArrayT* ptArray, vtkIdType cellId, double bounds[6]) const
1060     {
1061       using IdType = typename CellStateT::ValueType;
1062 
1063       const auto ptIds = state.GetCellRange(cellId);
1064       if (ptIds.size() == 0)
1065       {
1066         vtkMath::UninitializeBounds(bounds);
1067         return;
1068       }
1069 
1070       const auto points = vtk::DataArrayTupleRange<3>(ptArray);
1071 
1072       // Initialize bounds to first point:
1073       {
1074         const auto pt = points[ptIds[0]];
1075 
1076         // Explicitly reusing a local will improve performance when virtual
1077         // calls are involved in the iterator read:
1078         const double x = static_cast<double>(pt[0]);
1079         const double y = static_cast<double>(pt[1]);
1080         const double z = static_cast<double>(pt[2]);
1081 
1082         bounds[0] = x;
1083         bounds[1] = x;
1084         bounds[2] = y;
1085         bounds[3] = y;
1086         bounds[4] = z;
1087         bounds[5] = z;
1088       }
1089 
1090       // Reduce bounds with the rest of the ids:
1091       for (const IdType ptId : ptIds.GetSubRange(1))
1092       {
1093         const auto pt = points[ptId];
1094 
1095         // Explicitly reusing a local will improve performance when virtual
1096         // calls are involved in the iterator read:
1097         const double x = static_cast<double>(pt[0]);
1098         const double y = static_cast<double>(pt[1]);
1099         const double z = static_cast<double>(pt[2]);
1100 
1101         bounds[0] = std::min(bounds[0], x);
1102         bounds[1] = std::max(bounds[1], x);
1103         bounds[2] = std::min(bounds[2], y);
1104         bounds[3] = std::max(bounds[3], y);
1105         bounds[4] = std::min(bounds[4], z);
1106         bounds[5] = std::max(bounds[5], z);
1107       }
1108     }
1109   };
1110 
1111   // vtkArrayDispatch entry point:
1112   template <typename PointArrayT>
operator ()__anon5f8c9a0d0111::ComputeCellBoundsWorker1113   void operator()(
1114     PointArrayT* ptArray, vtkCellArray* conn, vtkIdType cellId, double bounds[6]) const
1115   {
1116     conn->Visit(Visitor{}, ptArray, cellId, bounds);
1117   }
1118 };
1119 
1120 } // anonymous
1121 
1122 //------------------------------------------------------------------------------
1123 // Faster implementation of GetCellBounds().  Bounds are calculated without
1124 // constructing a cell.
GetCellBounds(vtkIdType cellId,double bounds[6])1125 void vtkUnstructuredGrid::GetCellBounds(vtkIdType cellId, double bounds[6])
1126 {
1127   // Fast path for float/double:
1128   using vtkArrayDispatch::Reals;
1129   using Dispatcher = vtkArrayDispatch::DispatchByValueType<Reals>;
1130   ComputeCellBoundsWorker worker;
1131 
1132   vtkDataArray* ptArray = this->Points->GetData();
1133   if (!Dispatcher::Execute(ptArray, worker, this->Connectivity, cellId, bounds))
1134   { // fallback for weird types:
1135     worker(ptArray, this->Connectivity, cellId, bounds);
1136   }
1137 }
1138 
1139 //------------------------------------------------------------------------------
1140 // Return the number of points from the cell defined by the maximum number of
1141 // points/
GetMaxCellSize()1142 int vtkUnstructuredGrid::GetMaxCellSize()
1143 {
1144   if (this->Connectivity)
1145   { // The internal implementation is threaded.
1146     return this->Connectivity->GetMaxCellSize();
1147   }
1148   else
1149   {
1150     return 0;
1151   }
1152 }
1153 
1154 //------------------------------------------------------------------------------
GetNumberOfCells()1155 vtkIdType vtkUnstructuredGrid::GetNumberOfCells()
1156 {
1157   vtkDebugMacro(<< "NUMBER OF CELLS = "
1158                 << (this->Connectivity ? this->Connectivity->GetNumberOfCells() : 0));
1159   return (this->Connectivity ? this->Connectivity->GetNumberOfCells() : 0);
1160 }
1161 
1162 //------------------------------------------------------------------------------
1163 // Insert/create cell in object by type and list of point ids defining
1164 // cell topology. Using a special input format, this function also support
1165 // polyhedron cells.
InternalInsertNextCell(int type,vtkIdList * ptIds)1166 vtkIdType vtkUnstructuredGrid::InternalInsertNextCell(int type, vtkIdList* ptIds)
1167 {
1168   if (type == VTK_POLYHEDRON)
1169   {
1170     // For polyhedron cell, input ptIds is of format:
1171     // (numCellFaces, numFace0Pts, id1, id2, id3, numFace1Pts,id1, id2, id3, ...)
1172     vtkIdType* dataPtr = ptIds->GetPointer(0);
1173     return this->InsertNextCell(type, dataPtr[0], dataPtr + 1);
1174   }
1175 
1176   this->Connectivity->InsertNextCell(ptIds);
1177 
1178   // If faces have been created, we need to pad them (we are not creating
1179   // a polyhedral cell in this method)
1180   if (this->FaceLocations)
1181   {
1182     this->FaceLocations->InsertNextValue(-1);
1183   }
1184 
1185   // insert cell type
1186   return this->Types->InsertNextValue(static_cast<unsigned char>(type));
1187 }
1188 
1189 //------------------------------------------------------------------------------
1190 // Insert/create cell in object by type and list of point ids defining
1191 // cell topology. Using a special input format, this function also support
1192 // polyhedron cells.
InternalInsertNextCell(int type,vtkIdType npts,const vtkIdType ptIds[])1193 vtkIdType vtkUnstructuredGrid::InternalInsertNextCell(
1194   int type, vtkIdType npts, const vtkIdType ptIds[])
1195 {
1196   if (type != VTK_POLYHEDRON)
1197   {
1198     // insert connectivity
1199     this->Connectivity->InsertNextCell(npts, ptIds);
1200 
1201     // If faces have been created, we need to pad them (we are not creating
1202     // a polyhedral cell in this method)
1203     if (this->FaceLocations)
1204     {
1205       this->FaceLocations->InsertNextValue(-1);
1206     }
1207   }
1208   else
1209   {
1210     // For polyhedron, npts is actually number of faces, ptIds is of format:
1211     // (numFace0Pts, id1, id2, id3, numFace1Pts,id1, id2, id3, ...)
1212     vtkIdType realnpts;
1213 
1214     // We defer allocation for the faces because they are not commonly used and
1215     // we only want to allocate when necessary.
1216     if (!this->Faces)
1217     {
1218       this->Faces = vtkSmartPointer<vtkIdTypeArray>::New();
1219       this->Faces->Allocate(this->Types->GetSize());
1220       this->FaceLocations = vtkSmartPointer<vtkIdTypeArray>::New();
1221       this->FaceLocations->Allocate(this->Types->GetSize());
1222       // FaceLocations must be padded until the current position
1223       for (vtkIdType i = 0; i <= this->Types->GetMaxId(); i++)
1224       {
1225         this->FaceLocations->InsertNextValue(-1);
1226       }
1227     }
1228 
1229     // insert face location
1230     this->FaceLocations->InsertNextValue(this->Faces->GetMaxId() + 1);
1231 
1232     // insert cell connectivity and faces stream
1233     vtkUnstructuredGrid::DecomposeAPolyhedronCell(
1234       npts, ptIds, realnpts, this->Connectivity, this->Faces);
1235   }
1236 
1237   return this->Types->InsertNextValue(static_cast<unsigned char>(type));
1238 }
1239 
1240 //------------------------------------------------------------------------------
1241 // Insert/create cell in object by type and list of point and face ids
1242 // defining cell topology. This method is meant for face-explicit cells (e.g.
1243 // polyhedron).
InternalInsertNextCell(int type,vtkIdType npts,const vtkIdType pts[],vtkIdType nfaces,const vtkIdType faces[])1244 vtkIdType vtkUnstructuredGrid::InternalInsertNextCell(
1245   int type, vtkIdType npts, const vtkIdType pts[], vtkIdType nfaces, const vtkIdType faces[])
1246 {
1247   if (type != VTK_POLYHEDRON)
1248   {
1249     return this->InsertNextCell(type, npts, pts);
1250   }
1251   // Insert connectivity (points that make up polyhedron)
1252   this->Connectivity->InsertNextCell(npts, pts);
1253 
1254   // Now insert faces; allocate storage if necessary.
1255   // We defer allocation for the faces because they are not commonly used and
1256   // we only want to allocate when necessary.
1257   if (!this->Faces)
1258   {
1259     this->Faces = vtkSmartPointer<vtkIdTypeArray>::New();
1260     this->Faces->Allocate(this->Types->GetSize());
1261     this->FaceLocations = vtkSmartPointer<vtkIdTypeArray>::New();
1262     this->FaceLocations->Allocate(this->Types->GetSize());
1263     // FaceLocations must be padded until the current position
1264     for (vtkIdType i = 0; i <= this->Types->GetMaxId(); i++)
1265     {
1266       this->FaceLocations->InsertNextValue(-1);
1267     }
1268   }
1269 
1270   // Okay the faces go in
1271   this->FaceLocations->InsertNextValue(this->Faces->GetMaxId() + 1);
1272   this->Faces->InsertNextValue(nfaces);
1273 
1274   for (int faceNum = 0; faceNum < nfaces; ++faceNum)
1275   {
1276     npts = faces[0];
1277     this->Faces->InsertNextValue(npts);
1278     for (vtkIdType i = 1; i <= npts; ++i)
1279     {
1280       this->Faces->InsertNextValue(faces[i]);
1281     }
1282     faces += npts + 1;
1283   } // for all faces
1284 
1285   return this->Types->InsertNextValue(static_cast<unsigned char>(type));
1286 }
1287 
1288 //------------------------------------------------------------------------------
InitializeFacesRepresentation(vtkIdType numPrevCells)1289 int vtkUnstructuredGrid::InitializeFacesRepresentation(vtkIdType numPrevCells)
1290 {
1291   if (this->Faces || this->FaceLocations)
1292   {
1293     vtkErrorMacro("Face information already exist for this unstuructured grid. "
1294                   "InitializeFacesRepresentation returned without execution.");
1295     return 0;
1296   }
1297 
1298   this->Faces = vtkSmartPointer<vtkIdTypeArray>::New();
1299   this->Faces->Allocate(this->Types->GetSize());
1300 
1301   this->FaceLocations = vtkSmartPointer<vtkIdTypeArray>::New();
1302   this->FaceLocations->Allocate(this->Types->GetSize());
1303   // FaceLocations must be padded until the current position
1304   for (vtkIdType i = 0; i < numPrevCells; i++)
1305   {
1306     this->FaceLocations->InsertNextValue(-1);
1307   }
1308 
1309   return 1;
1310 }
1311 
1312 //------------------------------------------------------------------------------
GetMeshMTime()1313 vtkMTimeType vtkUnstructuredGrid::GetMeshMTime()
1314 {
1315   return vtkMath::Max(this->Points ? this->Points->GetMTime() : 0,
1316     this->Connectivity ? this->Connectivity->GetMTime() : 0);
1317 }
1318 
1319 //------------------------------------------------------------------------------
1320 // Return faces for a polyhedral cell (or face-explicit cell).
GetFaces(vtkIdType cellId)1321 vtkIdType* vtkUnstructuredGrid::GetFaces(vtkIdType cellId)
1322 {
1323   // Get the locations of the face
1324   vtkIdType loc;
1325   if (!this->Faces || cellId < 0 || cellId > this->FaceLocations->GetMaxId() ||
1326     (loc = this->FaceLocations->GetValue(cellId)) == -1)
1327   {
1328     return nullptr;
1329   }
1330 
1331   return this->Faces->GetPointer(loc);
1332 }
1333 
1334 //------------------------------------------------------------------------------
GetFaces()1335 vtkIdTypeArray* vtkUnstructuredGrid::GetFaces()
1336 {
1337   return this->Faces;
1338 }
1339 
1340 //------------------------------------------------------------------------------
GetFaceLocations()1341 vtkIdTypeArray* vtkUnstructuredGrid::GetFaceLocations()
1342 {
1343   return this->FaceLocations;
1344 }
1345 
1346 //------------------------------------------------------------------------------
SetCells(int type,vtkCellArray * cells)1347 void vtkUnstructuredGrid::SetCells(int type, vtkCellArray* cells)
1348 {
1349   vtkNew<vtkUnsignedCharArray> types;
1350   types->SetNumberOfComponents(1);
1351   types->SetNumberOfValues(cells->GetNumberOfCells());
1352   types->FillValue(static_cast<unsigned char>(type));
1353 
1354   this->SetCells(types, cells);
1355 }
1356 
1357 //------------------------------------------------------------------------------
SetCells(int * types,vtkCellArray * cells)1358 void vtkUnstructuredGrid::SetCells(int* types, vtkCellArray* cells)
1359 {
1360   const vtkIdType ncells = cells->GetNumberOfCells();
1361 
1362   // Convert the types into a vtkUnsignedCharArray:
1363   vtkNew<vtkUnsignedCharArray> cellTypes;
1364   cellTypes->SetNumberOfTuples(ncells);
1365   auto typeRange = vtk::DataArrayValueRange<1>(cellTypes);
1366   std::transform(types, types + ncells, typeRange.begin(),
1367     [](int t) -> unsigned char { return static_cast<unsigned char>(t); });
1368 
1369   this->SetCells(cellTypes, cells);
1370 }
1371 
1372 //------------------------------------------------------------------------------
SetCells(vtkUnsignedCharArray * cellTypes,vtkCellArray * cells)1373 void vtkUnstructuredGrid::SetCells(vtkUnsignedCharArray* cellTypes, vtkCellArray* cells)
1374 {
1375   // check if cells contain any polyhedron cell
1376   const vtkIdType ncells = cells->GetNumberOfCells();
1377   const auto typeRange = vtk::DataArrayValueRange<1>(cellTypes);
1378   const bool containPolyhedron =
1379     std::find(typeRange.cbegin(), typeRange.cend(), VTK_POLYHEDRON) != typeRange.cend();
1380 
1381   if (!containPolyhedron)
1382   {
1383     this->SetCells(cellTypes, cells, nullptr, nullptr);
1384     return;
1385   }
1386 
1387   // If a polyhedron cell exists, its input cellArray is of special format.
1388   // [nCell0Faces, nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...]
1389   // We need to convert it into new cell connectivities of standard format,
1390   // update cellLocations as well as create faces and facelocations.
1391   vtkNew<vtkCellArray> newCells;
1392   newCells->AllocateExact(ncells, cells->GetNumberOfConnectivityIds());
1393 
1394   vtkNew<vtkIdTypeArray> faces;
1395   faces->Allocate(ncells + cells->GetNumberOfConnectivityIds());
1396 
1397   vtkNew<vtkIdTypeArray> faceLocations;
1398   faceLocations->Allocate(ncells);
1399 
1400   auto cellIter = vtkSmartPointer<vtkCellArrayIterator>::Take(cells->NewIterator());
1401 
1402   for (cellIter->GoToFirstCell(); !cellIter->IsDoneWithTraversal(); cellIter->GoToNextCell())
1403   {
1404     vtkIdType npts;
1405     const vtkIdType* pts;
1406     cellIter->GetCurrentCell(npts, pts);
1407     const vtkIdType cellId = cellIter->GetCurrentCellId();
1408 
1409     if (cellTypes->GetValue(cellId) != VTK_POLYHEDRON)
1410     {
1411       newCells->InsertNextCell(npts, pts);
1412       faceLocations->InsertNextValue(-1);
1413     }
1414     else
1415     {
1416       vtkIdType realnpts;
1417       vtkIdType nfaces;
1418       faceLocations->InsertNextValue(faces->GetMaxId() + 1);
1419       vtkUnstructuredGrid::DecomposeAPolyhedronCell(pts, realnpts, nfaces, newCells, faces);
1420     }
1421   }
1422 
1423   this->SetCells(cellTypes, newCells, faceLocations, faces);
1424 }
1425 
1426 //------------------------------------------------------------------------------
SetCells(vtkUnsignedCharArray * cellTypes,vtkCellArray * cells,vtkIdTypeArray * faceLocations,vtkIdTypeArray * faces)1427 void vtkUnstructuredGrid::SetCells(vtkUnsignedCharArray* cellTypes, vtkCellArray* cells,
1428   vtkIdTypeArray* faceLocations, vtkIdTypeArray* faces)
1429 {
1430   this->Connectivity = cells;
1431   this->Types = cellTypes;
1432   this->DistinctCellTypes = nullptr;
1433   this->DistinctCellTypesUpdateMTime = 0;
1434   this->Faces = faces;
1435   this->FaceLocations = faceLocations;
1436 }
1437 
1438 //------------------------------------------------------------------------------
BuildLinks()1439 void vtkUnstructuredGrid::BuildLinks()
1440 {
1441   // Create appropriate locator. Currently it's either a vtkCellLocator (when
1442   // the dataset is editable) or vtkStaticCellLocator (when the dataset is
1443   // not editable).
1444   vtkIdType numPts = this->GetNumberOfPoints();
1445   if (!this->Editable)
1446   {
1447     this->Links = vtkSmartPointer<vtkStaticCellLinks>::New();
1448   }
1449   else
1450   {
1451     vtkNew<vtkCellLinks> links;
1452     links->Allocate(numPts);
1453     this->Links = links;
1454   }
1455 
1456   this->Links->BuildLinks(this);
1457 }
1458 
1459 //------------------------------------------------------------------------------
GetCellLinks()1460 vtkAbstractCellLinks* vtkUnstructuredGrid::GetCellLinks()
1461 {
1462   return this->Links;
1463 }
1464 
1465 //------------------------------------------------------------------------------
GetPointCells(vtkIdType ptId,vtkIdType & ncells,vtkIdType * & cells)1466 void vtkUnstructuredGrid::GetPointCells(vtkIdType ptId, vtkIdType& ncells, vtkIdType*& cells)
1467 {
1468   if (!this->Editable)
1469   {
1470     vtkStaticCellLinks* links = static_cast<vtkStaticCellLinks*>(this->Links.Get());
1471 
1472     ncells = links->GetNcells(ptId);
1473     cells = links->GetCells(ptId);
1474   }
1475   else
1476   {
1477     vtkCellLinks* links = static_cast<vtkCellLinks*>(this->Links.Get());
1478 
1479     ncells = links->GetNcells(ptId);
1480     cells = links->GetCells(ptId);
1481   }
1482 }
1483 
1484 //------------------------------------------------------------------------------
GetPointCells(vtkIdType ptId,unsigned short & ncells,vtkIdType * & cells)1485 void vtkUnstructuredGrid::GetPointCells(vtkIdType ptId, unsigned short& ncells, vtkIdType*& cells)
1486 {
1487   VTK_LEGACY_BODY(vtkUnstructuredGrid::GetPointCells, "VTK 9.0");
1488   vtkIdType nc;
1489   this->GetPointCells(ptId, nc, cells);
1490   ncells = static_cast<unsigned short>(nc);
1491 }
1492 
1493 //------------------------------------------------------------------------------
GetCellPoints(vtkIdType cellId,vtkIdList * ptIds)1494 void vtkUnstructuredGrid::GetCellPoints(vtkIdType cellId, vtkIdList* ptIds)
1495 {
1496   this->Connectivity->GetCellAtId(cellId, ptIds);
1497 }
1498 
1499 namespace
1500 {
1501 class DistinctCellTypesWorker
1502 {
1503 public:
DistinctCellTypesWorker(vtkUnstructuredGrid * grid)1504   DistinctCellTypesWorker(vtkUnstructuredGrid* grid)
1505     : Grid(grid)
1506   {
1507   }
1508 
1509   vtkUnstructuredGrid* Grid;
1510   std::set<unsigned char> DistinctCellTypes;
1511 
1512   // Thread-local storage
1513   vtkSMPThreadLocal<std::set<unsigned char>> LocalDistinctCellTypes;
1514 
Initialize()1515   void Initialize() {}
1516 
operator ()(vtkIdType begin,vtkIdType end)1517   void operator()(vtkIdType begin, vtkIdType end)
1518   {
1519     if (!this->Grid)
1520     {
1521       return;
1522     }
1523 
1524     for (vtkIdType idx = begin; idx < end; ++idx)
1525     {
1526       unsigned char cellType = static_cast<unsigned char>(this->Grid->GetCellType(idx));
1527       this->LocalDistinctCellTypes.Local().insert(cellType);
1528     }
1529   }
1530 
Reduce()1531   void Reduce()
1532   {
1533     this->DistinctCellTypes.clear();
1534     for (vtkSMPThreadLocal<std::set<unsigned char>>::iterator iter =
1535            this->LocalDistinctCellTypes.begin();
1536          iter != this->LocalDistinctCellTypes.end(); ++iter)
1537     {
1538       this->DistinctCellTypes.insert(iter->begin(), iter->end());
1539     }
1540   }
1541 };
1542 }
1543 
1544 //------------------------------------------------------------------------------
GetCellTypes(vtkCellTypes * types)1545 void vtkUnstructuredGrid::GetCellTypes(vtkCellTypes* types)
1546 {
1547   if (this->Types == nullptr)
1548   {
1549     // No cell types
1550     return;
1551   }
1552 
1553   if (this->DistinctCellTypes == nullptr ||
1554     this->Types->GetMTime() > this->DistinctCellTypesUpdateMTime)
1555   {
1556     // Update the list of cell types
1557     DistinctCellTypesWorker cellTypesWorker(this);
1558     vtkSMPTools::For(0, this->GetNumberOfCells(), cellTypesWorker);
1559 
1560     if (this->DistinctCellTypes)
1561     {
1562       this->DistinctCellTypes->Reset();
1563     }
1564     else
1565     {
1566       this->DistinctCellTypes = vtkSmartPointer<vtkCellTypes>::New();
1567       this->DistinctCellTypes->Register(this);
1568       this->DistinctCellTypes->Delete();
1569     }
1570     this->DistinctCellTypes->Allocate(static_cast<int>(cellTypesWorker.DistinctCellTypes.size()));
1571 
1572     for (auto cellType : cellTypesWorker.DistinctCellTypes)
1573     {
1574       this->DistinctCellTypes->InsertNextType(cellType);
1575     }
1576 
1577     this->DistinctCellTypesUpdateMTime = this->Types->GetMTime();
1578   }
1579 
1580   types->DeepCopy(this->DistinctCellTypes);
1581 }
1582 
1583 //------------------------------------------------------------------------------
GetCellTypesArray()1584 vtkUnsignedCharArray* vtkUnstructuredGrid::GetCellTypesArray()
1585 {
1586   return this->Types;
1587 }
1588 
1589 //------------------------------------------------------------------------------
GetFaceStream(vtkIdType cellId,vtkIdList * ptIds)1590 void vtkUnstructuredGrid::GetFaceStream(vtkIdType cellId, vtkIdList* ptIds)
1591 {
1592   if (this->GetCellType(cellId) != VTK_POLYHEDRON)
1593   {
1594     this->GetCellPoints(cellId, ptIds);
1595     return;
1596   }
1597 
1598   ptIds->Reset();
1599 
1600   if (!this->Faces || !this->FaceLocations)
1601   {
1602     return;
1603   }
1604 
1605   vtkIdType loc = this->FaceLocations->GetValue(cellId);
1606   vtkIdType* facePtr = this->Faces->GetPointer(loc);
1607 
1608   vtkIdType nfaces = *facePtr++;
1609   ptIds->InsertNextId(nfaces);
1610   for (vtkIdType i = 0; i < nfaces; i++)
1611   {
1612     vtkIdType npts = *facePtr++;
1613     ptIds->InsertNextId(npts);
1614     for (vtkIdType j = 0; j < npts; j++)
1615     {
1616       ptIds->InsertNextId(*facePtr++);
1617     }
1618   }
1619 }
1620 
1621 //------------------------------------------------------------------------------
GetFaceStream(vtkIdType cellId,vtkIdType & nfaces,vtkIdType const * & ptIds)1622 void vtkUnstructuredGrid::GetFaceStream(
1623   vtkIdType cellId, vtkIdType& nfaces, vtkIdType const*& ptIds)
1624 {
1625   if (this->GetCellType(cellId) != VTK_POLYHEDRON)
1626   {
1627     this->GetCellPoints(cellId, nfaces, ptIds);
1628     return;
1629   }
1630 
1631   if (!this->Faces || !this->FaceLocations)
1632   {
1633     return;
1634   }
1635 
1636   vtkIdType loc = this->FaceLocations->GetValue(cellId);
1637   const vtkIdType* facePtr = this->Faces->GetPointer(loc);
1638 
1639   nfaces = *facePtr;
1640   ptIds = facePtr + 1;
1641 }
1642 
1643 //------------------------------------------------------------------------------
GetPointCells(vtkIdType ptId,vtkIdList * cellIds)1644 void vtkUnstructuredGrid::GetPointCells(vtkIdType ptId, vtkIdList* cellIds)
1645 {
1646   if (!this->Links)
1647   {
1648     this->BuildLinks();
1649   }
1650   cellIds->Reset();
1651 
1652   vtkIdType numCells, *cells;
1653   if (!this->Editable)
1654   {
1655     vtkStaticCellLinks* links = static_cast<vtkStaticCellLinks*>(this->Links.Get());
1656     numCells = links->GetNcells(ptId);
1657     cells = links->GetCells(ptId);
1658   }
1659   else
1660   {
1661     vtkCellLinks* links = static_cast<vtkCellLinks*>(this->Links.Get());
1662     numCells = links->GetNcells(ptId);
1663     cells = links->GetCells(ptId);
1664   }
1665 
1666   cellIds->SetNumberOfIds(numCells);
1667   for (auto i = 0; i < numCells; i++)
1668   {
1669     cellIds->SetId(i, cells[i]);
1670   }
1671 }
1672 
1673 //------------------------------------------------------------------------------
NewCellIterator()1674 vtkCellIterator* vtkUnstructuredGrid::NewCellIterator()
1675 {
1676   vtkUnstructuredGridCellIterator* iter(vtkUnstructuredGridCellIterator::New());
1677   iter->SetUnstructuredGrid(this);
1678   return iter;
1679 }
1680 
1681 //------------------------------------------------------------------------------
Reset()1682 void vtkUnstructuredGrid::Reset()
1683 {
1684   if (this->Connectivity)
1685   {
1686     this->Connectivity->Reset();
1687   }
1688   if (this->Links)
1689   {
1690     this->Links->Reset();
1691   }
1692   if (this->Types)
1693   {
1694     this->Types->Reset();
1695   }
1696   if (this->DistinctCellTypes)
1697   {
1698     this->DistinctCellTypes->Reset();
1699   }
1700   if (this->Faces)
1701   {
1702     this->Faces->Reset();
1703   }
1704   if (this->FaceLocations)
1705   {
1706     this->FaceLocations->Reset();
1707   }
1708 }
1709 
1710 //------------------------------------------------------------------------------
Squeeze()1711 void vtkUnstructuredGrid::Squeeze()
1712 {
1713   if (this->Connectivity)
1714   {
1715     this->Connectivity->Squeeze();
1716   }
1717   if (this->Links)
1718   {
1719     this->Links->Squeeze();
1720   }
1721   if (this->Types)
1722   {
1723     this->Types->Squeeze();
1724   }
1725   if (this->Faces)
1726   {
1727     this->Faces->Squeeze();
1728   }
1729   if (this->FaceLocations)
1730   {
1731     this->FaceLocations->Squeeze();
1732   }
1733 
1734   vtkPointSet::Squeeze();
1735 }
1736 
1737 //------------------------------------------------------------------------------
1738 // Remove a reference to a cell in a particular point's link list. You may
1739 // also consider using RemoveCellReference() to remove the references from
1740 // all the cell's points to the cell. This operator does not reallocate
1741 // memory; use the operator ResizeCellList() to do this if necessary. Note that
1742 // dataset should be set to "Editable".
RemoveReferenceToCell(vtkIdType ptId,vtkIdType cellId)1743 void vtkUnstructuredGrid::RemoveReferenceToCell(vtkIdType ptId, vtkIdType cellId)
1744 {
1745   static_cast<vtkCellLinks*>(this->Links.Get())->RemoveCellReference(cellId, ptId);
1746 }
1747 
1748 //------------------------------------------------------------------------------
1749 // Add a reference to a cell in a particular point's link list. (You may also
1750 // consider using AddCellReference() to add the references from all the
1751 // cell's points to the cell.) This operator does not realloc memory; use the
1752 // operator ResizeCellList() to do this if necessary. Note that dataset
1753 // should be set to "Editable".
AddReferenceToCell(vtkIdType ptId,vtkIdType cellId)1754 void vtkUnstructuredGrid::AddReferenceToCell(vtkIdType ptId, vtkIdType cellId)
1755 {
1756   static_cast<vtkCellLinks*>(this->Links.Get())->AddCellReference(cellId, ptId);
1757 }
1758 
1759 //------------------------------------------------------------------------------
1760 // Resize the list of cells using a particular point. (This operator assumes
1761 // that BuildLinks() has been called.) Note that dataset should be set to
1762 // "Editable".
ResizeCellList(vtkIdType ptId,int size)1763 void vtkUnstructuredGrid::ResizeCellList(vtkIdType ptId, int size)
1764 {
1765   static_cast<vtkCellLinks*>(this->Links.Get())->ResizeCellList(ptId, size);
1766 }
1767 
1768 //------------------------------------------------------------------------------
1769 // Replace the points defining cell "cellId" with a new set of points. This
1770 // operator is (typically) used when links from points to cells have not been
1771 // built (i.e., BuildLinks() has not been executed). Use the operator
1772 // ReplaceLinkedCell() to replace a cell when cell structure has been built.
InternalReplaceCell(vtkIdType cellId,int npts,const vtkIdType pts[])1773 void vtkUnstructuredGrid::InternalReplaceCell(vtkIdType cellId, int npts, const vtkIdType pts[])
1774 {
1775   this->Connectivity->ReplaceCellAtId(cellId, npts, pts);
1776 }
1777 
1778 //------------------------------------------------------------------------------
1779 // Add a new cell to the cell data structure (after cell links have been
1780 // built). This method adds the cell and then updates the links from the points
1781 // to the cells. (Memory is allocated as necessary.) Note that the dataset must
1782 // be in "Editable" mode.
InsertNextLinkedCell(int type,int npts,const vtkIdType pts[])1783 vtkIdType vtkUnstructuredGrid::InsertNextLinkedCell(int type, int npts, const vtkIdType pts[])
1784 {
1785   vtkIdType i, id;
1786 
1787   id = this->InsertNextCell(type, npts, pts);
1788 
1789   vtkCellLinks* clinks = static_cast<vtkCellLinks*>(this->Links.Get());
1790   for (i = 0; i < npts; i++)
1791   {
1792     clinks->ResizeCellList(pts[i], 1);
1793     clinks->AddCellReference(id, pts[i]);
1794   }
1795 
1796   return id;
1797 }
1798 
1799 //------------------------------------------------------------------------------
GetActualMemorySize()1800 unsigned long vtkUnstructuredGrid::GetActualMemorySize()
1801 {
1802   unsigned long size = this->vtkPointSet::GetActualMemorySize();
1803   if (this->Connectivity)
1804   {
1805     size += this->Connectivity->GetActualMemorySize();
1806   }
1807 
1808   if (this->Links)
1809   {
1810     size += this->Links->GetActualMemorySize();
1811   }
1812 
1813   if (this->Types)
1814   {
1815     size += this->Types->GetActualMemorySize();
1816   }
1817 
1818   if (this->Faces)
1819   {
1820     size += this->Faces->GetActualMemorySize();
1821   }
1822 
1823   if (this->FaceLocations)
1824   {
1825     size += this->FaceLocations->GetActualMemorySize();
1826   }
1827 
1828   return size;
1829 }
1830 
1831 //------------------------------------------------------------------------------
ShallowCopy(vtkDataObject * dataObject)1832 void vtkUnstructuredGrid::ShallowCopy(vtkDataObject* dataObject)
1833 {
1834   if (vtkUnstructuredGrid* grid = vtkUnstructuredGrid::SafeDownCast(dataObject))
1835   {
1836     // I do not know if this is correct but.
1837     // ^ I really hope this comment lives for another 20 years.
1838 
1839     this->Connectivity = grid->Connectivity;
1840     this->Links = grid->Links;
1841     this->Types = grid->Types;
1842     this->DistinctCellTypes = nullptr;
1843     this->DistinctCellTypesUpdateMTime = 0;
1844     this->Faces = grid->Faces;
1845     this->FaceLocations = grid->FaceLocations;
1846   }
1847   else if (vtkUnstructuredGridBase* ugb = vtkUnstructuredGridBase::SafeDownCast(dataObject))
1848   {
1849     // The source object has vtkUnstructuredGrid topology, but a different
1850     // cell implementation. Deep copy the cells, and shallow copy the rest:
1851     vtkSmartPointer<vtkCellIterator> cellIter =
1852       vtkSmartPointer<vtkCellIterator>::Take(ugb->NewCellIterator());
1853     for (cellIter->InitTraversal(); !cellIter->IsDoneWithTraversal(); cellIter->GoToNextCell())
1854     {
1855       this->InsertNextCell(cellIter->GetCellType(), cellIter->GetNumberOfPoints(),
1856         cellIter->GetPointIds()->GetPointer(0), cellIter->GetNumberOfFaces(),
1857         cellIter->GetFaces()->GetPointer(1));
1858     }
1859   }
1860 
1861   this->Superclass::ShallowCopy(dataObject);
1862 }
1863 
1864 //------------------------------------------------------------------------------
DeepCopy(vtkDataObject * dataObject)1865 void vtkUnstructuredGrid::DeepCopy(vtkDataObject* dataObject)
1866 {
1867   auto mkhold = vtkMemkindRAII(this->GetIsInMemkind());
1868   vtkUnstructuredGrid* grid = vtkUnstructuredGrid::SafeDownCast(dataObject);
1869 
1870   if (grid != nullptr)
1871   {
1872     if (grid->Connectivity)
1873     {
1874       this->Connectivity = vtkSmartPointer<vtkCellArray>::New();
1875       this->Connectivity->DeepCopy(grid->Connectivity);
1876     }
1877     else
1878     {
1879       this->Connectivity = nullptr;
1880     }
1881 
1882     if (grid->Types)
1883     {
1884       this->Types = vtkSmartPointer<vtkUnsignedCharArray>::New();
1885       this->Types->DeepCopy(grid->Types);
1886     }
1887     else
1888     {
1889       this->Types = nullptr;
1890     }
1891 
1892     if (grid->DistinctCellTypes)
1893     {
1894       this->DistinctCellTypes = vtkSmartPointer<vtkCellTypes>::New();
1895       this->DistinctCellTypes->DeepCopy(grid->DistinctCellTypes);
1896     }
1897     else
1898     {
1899       this->DistinctCellTypes = nullptr;
1900     }
1901 
1902     if (grid->Faces)
1903     {
1904       this->Faces = vtkSmartPointer<vtkIdTypeArray>::New();
1905       this->Faces->DeepCopy(grid->Faces);
1906     }
1907     else
1908     {
1909       this->Faces = nullptr;
1910     }
1911 
1912     if (grid->FaceLocations)
1913     {
1914       this->FaceLocations = vtkSmartPointer<vtkIdTypeArray>::New();
1915       this->FaceLocations->DeepCopy(grid->FaceLocations);
1916     }
1917     else
1918     {
1919       this->FaceLocations = nullptr;
1920     }
1921 
1922     // Skip the unstructured grid base implementation, as it uses a less
1923     // efficient method of copying cell data.
1924     // NOLINTNEXTLINE(bugprone-parent-virtual-call)
1925     this->vtkUnstructuredGridBase::Superclass::DeepCopy(grid);
1926   }
1927   else
1928   {
1929     // Use the vtkUnstructuredGridBase deep copy implementation.
1930     this->Superclass::DeepCopy(dataObject);
1931   }
1932 
1933   // Finally Build Links if we need to
1934   if (grid && grid->Links)
1935   {
1936     this->BuildLinks();
1937   }
1938 }
1939 
1940 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)1941 void vtkUnstructuredGrid::PrintSelf(ostream& os, vtkIndent indent)
1942 {
1943   this->Superclass::PrintSelf(os, indent);
1944 
1945   os << indent << "Number Of Pieces: " << this->GetNumberOfPieces() << endl;
1946   os << indent << "Piece: " << this->GetPiece() << endl;
1947   os << indent << "Ghost Level: " << this->GetGhostLevel() << endl;
1948 }
1949 
1950 //------------------------------------------------------------------------------
AllocateExact(vtkIdType numCells,vtkIdType connectivitySize)1951 bool vtkUnstructuredGrid::AllocateExact(vtkIdType numCells, vtkIdType connectivitySize)
1952 {
1953   if (numCells < 1)
1954   {
1955     numCells = 1024;
1956   }
1957   if (connectivitySize < 1)
1958   {
1959     connectivitySize = 1024;
1960   }
1961 
1962   this->DistinctCellTypesUpdateMTime = 0;
1963   this->DistinctCellTypes = vtkSmartPointer<vtkCellTypes>::New();
1964   this->Types = vtkSmartPointer<vtkUnsignedCharArray>::New();
1965   this->Connectivity = vtkSmartPointer<vtkCellArray>::New();
1966 
1967   bool result = this->Connectivity->AllocateExact(numCells, connectivitySize);
1968   if (result)
1969   {
1970     result = this->Types->Allocate(numCells) != 0;
1971   }
1972   if (result)
1973   {
1974     result = this->DistinctCellTypes->Allocate(VTK_NUMBER_OF_CELL_TYPES) != 0;
1975   }
1976 
1977   return result;
1978 }
1979 
1980 //----------------------------------------------------------------------------
1981 // Supporting implementation functions for IsCellBoundary() and
1982 // GetCellNeighbors().  Basically these methods are an intersection of N sets
1983 // (e.g., each set is a list of cells using each point, the cell links). To
1984 // perform this intersection, the cell links associated with each point are
1985 // combined and then sorted. This will produce contiguous runs, the length
1986 // of which indicates how many times n a cell is represented in the N sets.
1987 // If n == N, then the cell is present in each of the cell links, and if
1988 // the cell != cellId, then this boundary defined by pts[] is an interior
1989 // face.
1990 namespace
1991 { // anonymous
1992 
1993 // Determine whether the points provided define a boundary entity (i.e., used
1994 // by only one cell), or whether the points define an interior entity (used
1995 // by more than one cell).
1996 template <class TLinks>
IsCellBoundaryImp(TLinks * links,vtkIdType cellId,vtkIdType npts,const vtkIdType * pts)1997 inline bool IsCellBoundaryImp(TLinks* links, vtkIdType cellId, vtkIdType npts, const vtkIdType* pts)
1998 {
1999   std::vector<vtkIdType> cellSet;
2000   cellSet.reserve(256); // avoid reallocs if possible
2001 
2002   // Combine all of the cell lists, and then sort them.
2003   for (auto i = 0; i < npts; ++i)
2004   {
2005     vtkIdType numCells = links->GetNcells(pts[i]);
2006     const vtkIdType* cells = links->GetCells(pts[i]);
2007     cellSet.insert(cellSet.end(), cells, cells + numCells);
2008   }
2009   std::sort(cellSet.begin(), cellSet.end());
2010 
2011   // Sorting will have grouped the cells into contiguous runs. Determine the
2012   // length of the runs - if equal to npts, then a cell is present in all
2013   // sets, and if this cell is not the user-provided cellId, then there is a
2014   // cell common to all sets, hence this is not a boundary cell.
2015   auto itr = cellSet.begin();
2016   while (itr != cellSet.end())
2017   {
2018     auto start = itr;
2019     vtkIdType currentCell = *itr;
2020     while (itr != cellSet.end() && *itr == currentCell)
2021       ++itr; // advance across this contiguous run
2022 
2023     // What is the size of the contiguous run? If equal to
2024     // the number of sets, then this is an interior boundary.
2025     if (((itr - start) >= npts) && (currentCell != cellId))
2026     {
2027       return false;
2028     }
2029   } // while over the cell set
2030 
2031   return true;
2032 }
2033 
2034 // Identify the neighbors to the specified cell, where the neighbors
2035 // use all the points in the points list (pts).
2036 template <class TLinks>
GetCellNeighborsImp(TLinks * links,vtkIdType cellId,vtkIdType npts,const vtkIdType * pts,vtkIdList * cellIds)2037 inline void GetCellNeighborsImp(
2038   TLinks* links, vtkIdType cellId, vtkIdType npts, const vtkIdType* pts, vtkIdList* cellIds)
2039 {
2040   std::vector<vtkIdType> cellSet;
2041   cellSet.reserve(256); // avoid reallocs if possible
2042 
2043   // Combine all of the cell lists, and then sort them.
2044   for (auto i = 0; i < npts; ++i)
2045   {
2046     vtkIdType numCells = links->GetNcells(pts[i]);
2047     const vtkIdType* cells = links->GetCells(pts[i]);
2048     cellSet.insert(cellSet.end(), cells, cells + numCells);
2049   }
2050   std::sort(cellSet.begin(), cellSet.end());
2051 
2052   // Sorting will have grouped the cells into contiguous runs. Determine the
2053   // length of the runs - if equal to npts, then a cell is present in all
2054   // sets, and if this cell is not the user-provided cellId, then this is a
2055   // cell common to all sets, hence it is a neighboring cell.
2056   auto itr = cellSet.begin();
2057   while (itr != cellSet.end())
2058   {
2059     auto start = itr;
2060     vtkIdType currentCell = *itr;
2061     while (itr != cellSet.end() && *itr == currentCell)
2062       ++itr; // advance across this contiguous run
2063 
2064     // What is the size of the contiguous run? If equal to
2065     // the number of sets, then this is a neighboring cell.
2066     if (((itr - start) >= npts) && (currentCell != cellId))
2067     {
2068       cellIds->InsertNextId(currentCell);
2069     }
2070   } // while over the cell set
2071 }
2072 
2073 } // end anonymous namespace
2074 
2075 //----------------------------------------------------------------------------
IsCellBoundary(vtkIdType cellId,vtkIdType npts,const vtkIdType * pts)2076 bool vtkUnstructuredGrid::IsCellBoundary(vtkIdType cellId, vtkIdType npts, const vtkIdType* pts)
2077 {
2078   // Ensure that a valid neighborhood request is made.
2079   if (npts <= 0)
2080   {
2081     return false;
2082   }
2083 
2084   // Ensure that cell links are available.
2085   if (!this->Links)
2086   {
2087     this->BuildLinks();
2088   }
2089 
2090   // Get the links (cells that use each point) depending on the editable
2091   // state of this object.
2092   if (!this->Editable)
2093   {
2094     vtkStaticCellLinks* links = static_cast<vtkStaticCellLinks*>(this->Links.Get());
2095     return IsCellBoundaryImp<vtkStaticCellLinks>(links, cellId, npts, pts);
2096   }
2097   else
2098   {
2099     vtkCellLinks* links = static_cast<vtkCellLinks*>(this->Links.Get());
2100     return IsCellBoundaryImp<vtkCellLinks>(links, cellId, npts, pts);
2101   }
2102 }
2103 
2104 //----------------------------------------------------------------------------
2105 // Return the cells that use all of the ptIds provided. This is a set
2106 // (intersection) operation - it can have significant performance impacts on
2107 // certain filters like vtkGeometryFilter.
GetCellNeighbors(vtkIdType cellId,vtkIdType npts,const vtkIdType * pts,vtkIdList * cellIds)2108 void vtkUnstructuredGrid::GetCellNeighbors(
2109   vtkIdType cellId, vtkIdType npts, const vtkIdType* pts, vtkIdList* cellIds)
2110 {
2111   // Empty the list
2112   cellIds->Reset();
2113 
2114   // Ensure that a proper neighborhood request is made.
2115   if (npts <= 0)
2116   {
2117     return;
2118   }
2119 
2120   // Ensure that links are built.
2121   if (!this->Links)
2122   {
2123     this->BuildLinks();
2124   }
2125 
2126   // Get the cell links based on the current state.
2127   if (!this->Editable)
2128   {
2129     vtkStaticCellLinks* links = static_cast<vtkStaticCellLinks*>(this->Links.Get());
2130     return GetCellNeighborsImp<vtkStaticCellLinks>(links, cellId, npts, pts, cellIds);
2131   }
2132   else
2133   {
2134     vtkCellLinks* links = static_cast<vtkCellLinks*>(this->Links.Get());
2135     return GetCellNeighborsImp<vtkCellLinks>(links, cellId, npts, pts, cellIds);
2136   }
2137 }
2138 
2139 //------------------------------------------------------------------------------
IsHomogeneous()2140 int vtkUnstructuredGrid::IsHomogeneous()
2141 {
2142   unsigned char type;
2143   if (this->Types && this->Types->GetMaxId() >= 0)
2144   {
2145     type = Types->GetValue(0);
2146     vtkIdType numCells = this->GetNumberOfCells();
2147     for (vtkIdType cellId = 0; cellId < numCells; ++cellId)
2148     {
2149       if (this->Types->GetValue(cellId) != type)
2150       {
2151         return 0;
2152       }
2153     }
2154     return 1;
2155   }
2156   return 0;
2157 }
2158 
2159 //------------------------------------------------------------------------------
2160 // Fill container with indices of cells which match given type.
GetIdsOfCellsOfType(int type,vtkIdTypeArray * array)2161 void vtkUnstructuredGrid::GetIdsOfCellsOfType(int type, vtkIdTypeArray* array)
2162 {
2163   for (int cellId = 0; cellId < this->GetNumberOfCells(); cellId++)
2164   {
2165     if (static_cast<int>(Types->GetValue(cellId)) == type)
2166     {
2167       array->InsertNextValue(cellId);
2168     }
2169   }
2170 }
2171 
2172 //------------------------------------------------------------------------------
RemoveGhostCells()2173 void vtkUnstructuredGrid::RemoveGhostCells()
2174 {
2175   vtkUnstructuredGrid* newGrid = vtkUnstructuredGrid::New();
2176   vtkUnsignedCharArray* temp;
2177   unsigned char* cellGhosts;
2178 
2179   vtkIdType cellId, newCellId;
2180   vtkIdList *cellPts, *pointMap;
2181   vtkIdList* newCellPts;
2182   vtkCell* cell;
2183   vtkPoints* newPoints;
2184   vtkIdType i, ptId, newId, numPts;
2185   vtkIdType numCellPts;
2186   double* x;
2187   vtkPointData* pd = this->GetPointData();
2188   vtkPointData* outPD = newGrid->GetPointData();
2189   vtkCellData* cd = this->GetCellData();
2190   vtkCellData* outCD = newGrid->GetCellData();
2191 
2192   // Get a pointer to the cell ghost array.
2193   temp = this->GetCellGhostArray();
2194   if (temp == nullptr)
2195   {
2196     vtkDebugMacro("Could not find cell ghost array.");
2197     newGrid->Delete();
2198     return;
2199   }
2200   if ((temp->GetNumberOfComponents() != 1) ||
2201     (temp->GetNumberOfTuples() < this->GetNumberOfCells()))
2202   {
2203     vtkErrorMacro("Poorly formed ghost array.");
2204     newGrid->Delete();
2205     return;
2206   }
2207   cellGhosts = temp->GetPointer(0);
2208 
2209   // Now threshold based on the cell ghost array.
2210 
2211   // ensure that all attributes are copied over, including global ids.
2212   outPD->CopyAllOn(vtkDataSetAttributes::COPYTUPLE);
2213   outCD->CopyAllOn(vtkDataSetAttributes::COPYTUPLE);
2214 
2215   outPD->CopyAllocate(pd);
2216   outCD->CopyAllocate(cd);
2217 
2218   numPts = this->GetNumberOfPoints();
2219   newGrid->Allocate(this->GetNumberOfCells());
2220   newPoints = vtkPoints::New();
2221   newPoints->SetDataType(this->GetPoints()->GetDataType());
2222   newPoints->Allocate(numPts);
2223 
2224   pointMap = vtkIdList::New(); // maps old point ids into new
2225   pointMap->SetNumberOfIds(numPts);
2226   pointMap->Fill(-1);
2227 
2228   newCellPts = vtkIdList::New();
2229 
2230   // Check that the scalars of each cell satisfy the threshold criterion
2231   for (cellId = 0; cellId < this->GetNumberOfCells(); cellId++)
2232   {
2233     cell = this->GetCell(cellId);
2234     cellPts = cell->GetPointIds();
2235     numCellPts = cell->GetNumberOfPoints();
2236 
2237     if ((cellGhosts[cellId] &
2238           (vtkDataSetAttributes::DUPLICATECELL | vtkDataSetAttributes::HIDDENCELL)) ==
2239       0) // Keep the cell.
2240     {
2241       for (i = 0; i < numCellPts; i++)
2242       {
2243         ptId = cellPts->GetId(i);
2244         if ((newId = pointMap->GetId(ptId)) < 0)
2245         {
2246           x = this->GetPoint(ptId);
2247           newId = newPoints->InsertNextPoint(x);
2248           pointMap->SetId(ptId, newId);
2249           outPD->CopyData(pd, ptId, newId);
2250         }
2251         newCellPts->InsertId(i, newId);
2252       }
2253       newCellId = newGrid->InsertNextCell(cell->GetCellType(), newCellPts);
2254       outCD->CopyData(cd, cellId, newCellId);
2255       newCellPts->Reset();
2256     } // satisfied thresholding
2257   }   // for all cells
2258 
2259   // now clean up / update ourselves
2260   pointMap->Delete();
2261   newCellPts->Delete();
2262 
2263   newGrid->SetPoints(newPoints);
2264   newPoints->Delete();
2265 
2266   this->CopyStructure(newGrid);
2267   this->GetPointData()->ShallowCopy(newGrid->GetPointData());
2268   this->GetCellData()->ShallowCopy(newGrid->GetCellData());
2269   newGrid->Delete();
2270   newGrid = nullptr;
2271 
2272   this->Squeeze();
2273 }
2274 
2275 //------------------------------------------------------------------------------
DecomposeAPolyhedronCell(vtkCellArray * polyhedronCell,vtkIdType & numCellPts,vtkIdType & nCellfaces,vtkCellArray * cellArray,vtkIdTypeArray * faces)2276 void vtkUnstructuredGrid::DecomposeAPolyhedronCell(vtkCellArray* polyhedronCell,
2277   vtkIdType& numCellPts, vtkIdType& nCellfaces, vtkCellArray* cellArray, vtkIdTypeArray* faces)
2278 {
2279   const vtkIdType* cellStream = nullptr;
2280   vtkIdType cellLength = 0;
2281 
2282   polyhedronCell->InitTraversal();
2283   polyhedronCell->GetNextCell(cellLength, cellStream);
2284 
2285   vtkUnstructuredGrid::DecomposeAPolyhedronCell(
2286     cellStream, numCellPts, nCellfaces, cellArray, faces);
2287 }
2288 
2289 //------------------------------------------------------------------------------
DecomposeAPolyhedronCell(const vtkIdType * cellStream,vtkIdType & numCellPts,vtkIdType & nCellFaces,vtkCellArray * cellArray,vtkIdTypeArray * faces)2290 void vtkUnstructuredGrid::DecomposeAPolyhedronCell(const vtkIdType* cellStream,
2291   vtkIdType& numCellPts, vtkIdType& nCellFaces, vtkCellArray* cellArray, vtkIdTypeArray* faces)
2292 {
2293   nCellFaces = cellStream[0];
2294   if (nCellFaces <= 0)
2295   {
2296     return;
2297   }
2298 
2299   vtkUnstructuredGrid::DecomposeAPolyhedronCell(
2300     nCellFaces, cellStream + 1, numCellPts, cellArray, faces);
2301 }
2302 
2303 //------------------------------------------------------------------------------
DecomposeAPolyhedronCell(vtkIdType nCellFaces,const vtkIdType cellStream[],vtkIdType & numCellPts,vtkCellArray * cellArray,vtkIdTypeArray * faces)2304 void vtkUnstructuredGrid::DecomposeAPolyhedronCell(vtkIdType nCellFaces,
2305   const vtkIdType cellStream[], vtkIdType& numCellPts, vtkCellArray* cellArray,
2306   vtkIdTypeArray* faces)
2307 {
2308   std::set<vtkIdType> cellPointSet;
2309   std::set<vtkIdType>::iterator it;
2310 
2311   // insert number of faces into the face array
2312   faces->InsertNextValue(nCellFaces);
2313 
2314   // for each face
2315   for (vtkIdType fid = 0; fid < nCellFaces; fid++)
2316   {
2317     // extract all points on the same face, store them into a set
2318     vtkIdType npts = *cellStream++;
2319     faces->InsertNextValue(npts);
2320     for (vtkIdType i = 0; i < npts; i++)
2321     {
2322       vtkIdType pid = *cellStream++;
2323       faces->InsertNextValue(pid);
2324       cellPointSet.insert(pid);
2325     }
2326   }
2327 
2328   // standard cell connectivity array that stores the number of points plus
2329   // a list of point ids.
2330   cellArray->InsertNextCell(static_cast<int>(cellPointSet.size()));
2331   for (it = cellPointSet.begin(); it != cellPointSet.end(); ++it)
2332   {
2333     cellArray->InsertCellPoint(*it);
2334   }
2335 
2336   // the real number of points in the polyhedron cell.
2337   numCellPts = static_cast<vtkIdType>(cellPointSet.size());
2338 }
2339 
2340 //------------------------------------------------------------------------------
ConvertFaceStreamPointIds(vtkIdList * faceStream,vtkIdType * idMap)2341 void vtkUnstructuredGrid::ConvertFaceStreamPointIds(vtkIdList* faceStream, vtkIdType* idMap)
2342 {
2343   vtkIdType* idPtr = faceStream->GetPointer(0);
2344   vtkIdType nfaces = *idPtr++;
2345   for (vtkIdType i = 0; i < nfaces; i++)
2346   {
2347     vtkIdType npts = *idPtr++;
2348     for (vtkIdType j = 0; j < npts; j++)
2349     {
2350       *idPtr = idMap[*idPtr];
2351       idPtr++;
2352     }
2353   }
2354 }
2355 
2356 //------------------------------------------------------------------------------
ConvertFaceStreamPointIds(vtkIdType nfaces,vtkIdType * faceStream,vtkIdType * idMap)2357 void vtkUnstructuredGrid::ConvertFaceStreamPointIds(
2358   vtkIdType nfaces, vtkIdType* faceStream, vtkIdType* idMap)
2359 {
2360   vtkIdType* idPtr = faceStream;
2361   for (vtkIdType i = 0; i < nfaces; i++)
2362   {
2363     vtkIdType npts = *idPtr++;
2364     for (vtkIdType j = 0; j < npts; j++)
2365     {
2366       *idPtr = idMap[*idPtr];
2367       idPtr++;
2368     }
2369   }
2370 }
2371 
2372 //------------------------------------------------------------------------------
GetData(vtkInformation * info)2373 vtkUnstructuredGrid* vtkUnstructuredGrid::GetData(vtkInformation* info)
2374 {
2375   return info ? vtkUnstructuredGrid::SafeDownCast(info->Get(DATA_OBJECT())) : nullptr;
2376 }
2377 
2378 //------------------------------------------------------------------------------
GetData(vtkInformationVector * v,int i)2379 vtkUnstructuredGrid* vtkUnstructuredGrid::GetData(vtkInformationVector* v, int i)
2380 {
2381   return vtkUnstructuredGrid::GetData(v->GetInformationObject(i));
2382 }
2383