You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

279 lines
7.3 KiB
C++

/*=========================================================================
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() {}
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