VTK  9.7.1
vtkPolyhedronContour.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
27 #ifndef vtkPolyhedronContour_h
28 #define vtkPolyhedronContour_h
29 
30 #include "vtkCommonDataModelModule.h" // For export macro
31 #include "vtkType.h" // For vtkIdType
32 
33 #include "vtkSmartPointer.h" // For vtkSmartPointer
34 #include "vtkStaticEdgeLocatorTemplate.h" // For vtkStaticEdgeLocatorTemplate
35 
36 #include <array> // For array
37 #include <cstdint> // For int64_t
38 #include <unordered_map> // For unordered_map
39 #include <unordered_set> // For unordered_set
40 #include <vector> // For vector
41 
42 VTK_ABI_NAMESPACE_BEGIN
43 
44 class vtkCellArray;
45 class vtkCellData;
46 class vtkDataArray;
47 class vtkIdList;
49 class vtkPointData;
50 class vtkPolygon;
51 class vtkPolyhedron;
52 
56 class VTKCOMMONDATAMODEL_EXPORT vtkPolyhedronContour
57 {
58 public:
59  vtkPolyhedronContour() = default;
60  ~vtkPolyhedronContour() = default;
61 
62  enum class CellClassification
63  {
64  AllInside,
65  AllOutside,
66  Intersected
67  };
68 
80  CellClassification Execute(vtkPolyhedron* cell, vtkDataArray* scalars, double isoValue,
81  vtkIncrementalPointLocator* locator, vtkPointData* inPd, vtkPointData* outPd);
82 
86  int GetNumberOfIsoPolygons() const { return static_cast<int>(this->Result.IsoPolygons.size()); }
87 
91  int GetIsoPolygonSize(int polyIdx) const
92  {
93  return static_cast<int>(this->Result.IsoPolygons[polyIdx].size());
94  }
95 
99  vtkIdType GetIsoPolygonVertex(int polyIdx, int vertIdx) const
100  {
101  return this->Result.IsoVertices[this->Result.IsoPolygons[polyIdx][vertIdx]].OutputPointId;
102  }
103 
107  void OutputContours(vtkCellArray* polys, vtkCellData* inCd, vtkIdType cellId, vtkCellData* outCd);
108 
116  void OutputClip(vtkPolyhedron* cell, vtkCellArray* connectivity,
117  vtkIncrementalPointLocator* locator, vtkPointData* inPd, vtkPointData* outPd, vtkCellData* inCd,
118  vtkIdType cellId, vtkCellData* outCd, int insideOut, vtkCellArray* outFaces = nullptr,
119  vtkCellArray* outFaceLocs = nullptr);
120 
121  //
122  // Bulk API for integration with threaded filters (vtkContour3DLinearGrid,
123  // vtkTableBasedClipDataSet). Operates on raw point coordinates and face
124  // streams without instantiating vtkPolyhedron objects.
125  //
126  // - Contour: single-call ContourCell helper below.
127  // - Clip: two-pass CountClip / EmitClip, where CountClip produces the edge
128  // intersection list fed into a shared vtkStaticEdgeLocatorTemplate before
129  // EmitClip writes final geometry with deduplicated iso-vertex IDs.
130  //============================================================================
131 
150  static void ContourCell(vtkIdType numPointIds, const vtkIdType* pointIds,
151  vtkCellArray* polyhedronFaces, vtkDataArray* points, vtkDataArray* scalars, double isoValue,
152  bool generateTriangles, std::vector<vtkIdType>& polygonsSize,
153  std::vector<EdgeTuple<vtkIdType, double>>& intersectedEdges);
154 
171  static void CountClip(vtkIdType numPointIds, const vtkIdType* pointIds,
172  vtkCellArray* polyhedronFaces, vtkDataArray* scalars, double isoValue, bool insideOut,
173  vtkIdType& numOutputCells, vtkIdType& numOutputCellConnectivity, vtkIdType& numOutputFaces,
174  vtkIdType& numOutputFacesConnectivity,
175  std::vector<EdgeTuple<vtkIdType, double>>& intersectedEdges);
176 
197  static void EmitClip(vtkIdType numPointIds, const vtkIdType* pointIds,
198  vtkCellArray* polyhedronFaces, vtkDataArray* scalars, double isoValue, bool insideOut,
199  vtkDataArray* pointMap, vtkIdType numberOfKeptPoints,
200  const vtkStaticEdgeLocatorTemplate<vtkIdType, double>& edgeLocator, vtkCellArray* outputCells,
201  vtkCellArray* outputFaces);
202 
203 private:
204  //============================================================================
205  // Data Structures
206  //============================================================================
207 
212  struct IsoVertex
213  {
214  vtkIdType OutsideVertex;
215  vtkIdType InsideVertex;
216  int KeyFace;
217  int OtherFace;
218  double Weight;
219  std::array<double, 3> Position;
220  vtkIdType OutputPointId;
221  };
222 
223  struct TraceResult
224  {
226  std::vector<int> VertexTags;
227 
229  std::vector<IsoVertex> IsoVertices;
230 
232  std::vector<std::vector<int>> FaceIsoVertices;
233 
236  std::vector<std::vector<int>> IsoVertexPositionInFace;
237 
240  std::vector<std::vector<int>> IsoPolygons;
241 
243  std::unordered_map<int64_t, int> EdgeToIsoVert;
244 
245  // Assign vertices
246  std::vector<bool> Assigned;
247 
248  void Clear(vtkIdType nFaces)
249  {
250  this->VertexTags.clear();
251  this->IsoVertices.clear();
252  this->FaceIsoVertices.resize(nFaces);
253  for (vtkIdType i = 0; i < nFaces; ++i)
254  {
255  this->FaceIsoVertices[i].clear();
256  }
257  this->IsoVertexPositionInFace.resize(nFaces);
258  for (vtkIdType i = 0; i < nFaces; ++i)
259  {
260  this->IsoVertexPositionInFace[i].clear();
261  }
262  this->IsoPolygons.clear();
263  this->EdgeToIsoVert.clear();
264  this->Assigned.clear();
265  }
266  };
267 
268  TraceResult Result;
269 
270  //============================================================================
271  // Shared algorithm core (static — used by both the instance path and the
272  // bulk static API).
273  //============================================================================
274 
286  static void ClassifyVertices(TraceResult& result, const std::vector<double>& localScalars,
287  double isoValue, int& numInside, int& numOutside);
288 
296  static void FindIsoVertices(TraceResult& result, vtkIdType nFaces,
297  const vtkIdType* localFaceStream, const std::vector<double>& localScalars, double isoValue);
298 
304  static void TraceIsoPolygons(TraceResult& result);
305 
323  static void RunLopezTraceInto(TraceResult& result, vtkIdType nFaces,
324  const vtkIdType* localFaceStream, const std::vector<double>& localScalars, double isoValue);
325 
326  //============================================================================
327  // Instance-only helpers
328  //============================================================================
329 
335  void InterpolatePositionsAndInsertPoints(vtkPolyhedron* cell, vtkIncrementalPointLocator* locator,
336  vtkPointData* inPd, vtkPointData* outPd);
337 
338  //============================================================================
339  // Internal Data structured for ContourCell/CountClip/EmitClip
340  //============================================================================
341 
342  // Per-cell scratch for the bulk Contour/clip API. Held in a
343  // thread_local so allocations amortize across cells processed by the
344  // same worker thread. Capacities grow to the largest cell seen and are
345  // retained thereafter.
346  struct PolyhedronWorkspace
347  {
348  std::vector<double> LocalScalars;
349  std::vector<vtkIdType> LocalFaceStream; // face-stream remap: global ID -> local 0..N-1
350  std::unordered_map<vtkIdType, int> GlobalToLocal;
351  TraceResult Trace; // RunLopezTrace output reused
352  std::unordered_set<int64_t> LiveIsoEdgeKeys; // CountClip: edges with non-degenerate iso-verts
353  std::vector<vtkIdType> PieceSizes; // CountClip face-walker scratch
354  std::vector<vtkIdType> LocalToOutputId; // EmitClip: local vertex -> output point ID
355  std::vector<vtkIdType> IsoToOutputId; // EmitClip: iso-vertex index -> output point ID
356  std::unordered_map<int64_t, vtkIdType> EdgeToOutputId; // EmitClip face-walker lookup
357  std::vector<vtkIdType> CellPts; // EmitClip cell-connectivity scratch
358  std::vector<std::vector<vtkIdType>> Pieces; // EmitClip face-walker output pieces
359  std::vector<vtkIdType> CurrentPiece; // EmitClip face-walker active piece
360  std::vector<vtkIdType> CapFace; // EmitClip cap-face scratch
361  // ContourCell GT=ON ear-clip scratch (allocation-free per polygon).
362  std::vector<std::array<double, 3>> EarCoords; // iso-vertex coords, loop order
363  std::vector<int> EarPrev; // ear-clip linked-list prev
364  std::vector<int> EarNext; // ear-clip linked-list next
365  std::vector<int> EarRing; // ear-clip compacted ring
366  std::vector<double> EarHeapMeasure; // quality ear-clip heap keys
367  std::vector<int> EarHeapVertex; // quality ear-clip heap vertex ids
368  std::vector<int> EarHeapSlot; // quality ear-clip vertex id -> heap slot
369  };
370 };
371 
372 VTK_ABI_NAMESPACE_END
373 #endif // vtkPolyhedronContour_h
Templated on types of ids defining an edge, and any data associated with the edge.
represent and manipulate point attribute data
Definition: vtkPointData.h:30
Isosurface extraction using López polygon tracing algorithm.
int GetNumberOfIsoPolygons() const
Get the number of resulting iso-polygons.
represent and manipulate cell attribute data
Definition: vtkCellData.h:31
vtkIdType GetIsoPolygonVertex(int polyIdx, int vertIdx) const
Get iso-polygon vertex (output point ID)
Abstract class in support of both point location and point insertion.
int vtkIdType
Definition: vtkType.h:363
int GetIsoPolygonSize(int polyIdx) const
Get iso-polygon vertex count.
list of point or cell ids
Definition: vtkIdList.h:25
abstract superclass for arrays of numeric data
Definition: vtkDataArray.h:44
const std::string pointIds
a cell that represents an n-sided polygon
Definition: vtkPolygon.h:39
Definition of an edge tuple.
object to represent cell connectivity
Definition: vtkCellArray.h:177
A 3D cell defined by a set of polygonal faces.