/*========================================================================= Program: Visualization Toolkit Module: vtkGenericEdgeTable.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** * @class vtkGenericEdgeTable * @brief keep track of edges (defined by pair of integer id's) * * vtkGenericEdgeTable is used to indicate the existence of and hold * information about edges. Similar to vtkEdgeTable, this class is * more sophisticated in that it uses reference counting to keep track * of when information about an edge should be deleted. * * vtkGenericEdgeTable is a helper class used in the adaptor framework. It * is used during the tessellation process to hold information about the * error metric on each edge. This avoids recomputing the error metric each * time the same edge is visited. */ #ifndef vtkGenericEdgeTable_h #define vtkGenericEdgeTable_h #include "vtkCommonDataModelModule.h" // For export macro #include "vtkObject.h" class vtkEdgeTableEdge; class vtkEdgeTablePoints; class VTKCOMMONDATAMODEL_EXPORT vtkGenericEdgeTable : public vtkObject { public: /** * Instantiate an empty edge table. */ static vtkGenericEdgeTable* New(); ///@{ /** * Standard VTK type and print macros. */ vtkTypeMacro(vtkGenericEdgeTable, vtkObject); void PrintSelf(ostream& os, vtkIndent indent) override; ///@} /** * Split the edge with the indicated point id. */ void InsertEdge(vtkIdType e1, vtkIdType e2, vtkIdType cellId, int ref, vtkIdType& ptId); /** * Insert an edge but do not split it. */ void InsertEdge(vtkIdType e1, vtkIdType e2, vtkIdType cellId, int ref = 1); /** * Method to remove an edge from the table. The method returns the * current reference count. */ int RemoveEdge(vtkIdType e1, vtkIdType e2); /** * Method to determine whether an edge is in the table (0 or 1), or not (-1). * It returns whether the edge was split (1) or not (0), * and the point id exists. */ int CheckEdge(vtkIdType e1, vtkIdType e2, vtkIdType& ptId); /** * Method that increments the referencecount and returns it. */ int IncrementEdgeReferenceCount(vtkIdType e1, vtkIdType e2, vtkIdType cellId); /** * Return the edge reference count. */ int CheckEdgeReferenceCount(vtkIdType e1, vtkIdType e2); /** * To specify the starting point id. It will initialize LastPointId * This is very sensitive the start point should be cautiously chosen */ void Initialize(vtkIdType start); /** * Return the total number of components for the point-centered attributes. * \post positive_result: result>0 */ int GetNumberOfComponents(); /** * Set the total number of components for the point-centered attributes. * \pre positive_count: count>0 */ void SetNumberOfComponents(int count); /** * Check if a point is already in the point table. */ int CheckPoint(vtkIdType ptId); /** * Check for the existence of a point and return its coordinate value. * \pre scalar_size: sizeof(scalar)==this->GetNumberOfComponents() */ int CheckPoint(vtkIdType ptId, double point[3], double* scalar); ///@{ /** * Insert point associated with an edge. */ void InsertPoint(vtkIdType ptId, double point[3]); // \pre: sizeof(s)==GetNumberOfComponents() void InsertPointAndScalar(vtkIdType ptId, double pt[3], double* s); ///@} /** * Remove a point from the point table. */ void RemovePoint(vtkIdType ptId); /** * Increment the reference count for the indicated point. */ void IncrementPointReferenceCount(vtkIdType ptId); ///@{ /** * For debugging purposes. It is particularly useful to dump the table * and check that nothing is left after a complete iteration. LoadFactor * should ideally be very low to be able to have a constant time access */ void DumpTable(); void LoadFactor(); ///@} class PointEntry { public: vtkIdType PointId; double Coord[3]; double* Scalar; // point data: all point-centered attributes at this point int numberOfComponents; int Reference; // signed char /** * Constructor with a scalar field of `size' doubles. * \pre positive_number_of_components: size>0 */ PointEntry(int size); ~PointEntry() { delete[] this->Scalar; } PointEntry(const PointEntry& other) { this->PointId = other.PointId; memcpy(this->Coord, other.Coord, sizeof(double) * 3); int c = other.numberOfComponents; this->numberOfComponents = c; this->Scalar = new double[c]; memcpy(this->Scalar, other.Scalar, sizeof(double) * c); this->Reference = other.Reference; } PointEntry& operator=(const PointEntry& other) { if (this != &other) { this->PointId = other.PointId; memcpy(this->Coord, other.Coord, sizeof(double) * 3); int c = other.numberOfComponents; if (this->numberOfComponents != c) { delete[] this->Scalar; this->Scalar = new double[c]; this->numberOfComponents = c; } memcpy(this->Scalar, other.Scalar, sizeof(double) * c); this->Reference = other.Reference; } return *this; } }; class EdgeEntry { public: vtkIdType E1; vtkIdType E2; int Reference; // signed char int ToSplit; // signed char vtkIdType PtId; vtkIdType CellId; // CellId the edge refer to at a step in tessellation EdgeEntry() { this->Reference = 0; this->CellId = -1; } ~EdgeEntry() = default; EdgeEntry(const EdgeEntry& copy) { this->E1 = copy.E1; this->E2 = copy.E2; this->Reference = copy.Reference; this->ToSplit = copy.ToSplit; this->PtId = copy.PtId; this->CellId = copy.CellId; } EdgeEntry& operator=(const EdgeEntry& entry) { if (this == &entry) { return *this; } this->E1 = entry.E1; this->E2 = entry.E2; this->Reference = entry.Reference; this->ToSplit = entry.ToSplit; this->PtId = entry.PtId; this->CellId = entry.CellId; return *this; } }; protected: vtkGenericEdgeTable(); ~vtkGenericEdgeTable() override; /** * Split the edge with the indicated point id. */ void InsertEdge( vtkIdType e1, vtkIdType e2, vtkIdType cellId, int ref, int toSplit, vtkIdType& ptId); // Hash table that contiain entry based on edges: vtkEdgeTableEdge* EdgeTable; // At end of process we should be able to retrieve points coord based on pointid vtkEdgeTablePoints* HashPoints; // Main hash functions // For edge table: vtkIdType HashFunction(vtkIdType e1, vtkIdType e2); // For point table: vtkIdType HashFunction(vtkIdType ptId); // Keep track of the last point id we inserted, increment it each time: vtkIdType LastPointId; vtkIdType NumberOfComponents; private: vtkGenericEdgeTable(const vtkGenericEdgeTable&) = delete; void operator=(const vtkGenericEdgeTable&) = delete; }; #endif