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.

881 lines
30 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkPolyData.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 vtkPolyData
* @brief concrete dataset represents vertices, lines, polygons, and triangle strips
*
* vtkPolyData is a data object that is a concrete implementation of
* vtkDataSet. vtkPolyData represents a geometric structure consisting of
* vertices, lines, polygons, and/or triangle strips. Point and cell
* attribute values (e.g., scalars, vectors, etc.) also are represented.
*
* The actual cell types (vtkCellType.h) supported by vtkPolyData are:
* vtkVertex, vtkPolyVertex, vtkLine, vtkPolyLine, vtkTriangle, vtkQuad,
* vtkPolygon, and vtkTriangleStrip.
*
* One important feature of vtkPolyData objects is that special traversal and
* data manipulation methods are available to process data. These methods are
* generally more efficient than vtkDataSet methods and should be used
* whenever possible. For example, traversing the cells in a dataset we would
* use GetCell(). To traverse cells with vtkPolyData we would retrieve the
* cell array object representing polygons (for example using GetPolys()) and
* then use vtkCellArray's InitTraversal() and GetNextCell() methods.
*
* @warning
* Because vtkPolyData is implemented with four separate instances of
* vtkCellArray to represent 0D vertices, 1D lines, 2D polygons, and 2D
* triangle strips, it is possible to create vtkPolyData instances that
* consist of a mixture of cell types. Because of the design of the class,
* there are certain limitations on how mixed cell types are inserted into
* the vtkPolyData, and in turn the order in which they are processed and
* rendered. To preserve the consistency of cell ids, and to insure that
* cells with cell data are rendered properly, users must insert mixed cells
* in the order of vertices (vtkVertex and vtkPolyVertex), lines (vtkLine and
* vtkPolyLine), polygons (vtkTriangle, vtkQuad, vtkPolygon), and triangle
* strips (vtkTriangleStrip).
*
* @warning
* Some filters when processing vtkPolyData with mixed cell types may process
* the cells in differing ways. Some will convert one type into another
* (e.g., vtkTriangleStrip into vtkTriangles) or expect a certain type
* (vtkDecimatePro expects triangles or triangle strips; vtkTubeFilter
* expects lines). Read the documentation for each filter carefully to
* understand how each part of vtkPolyData is processed.
*
* @warning
* Some of the methods specified here function properly only when the dataset
* has been specified as "Editable". They are documented as such.
*/
#ifndef vtkPolyData_h
#define vtkPolyData_h
#include "vtkCommonDataModelModule.h" // For export macro
#include "vtkPointSet.h"
#include "vtkCellArray.h" // Needed for inline methods
#include "vtkCellLinks.h" // Needed for inline methods
#include "vtkPolyDataInternals.h" // Needed for inline methods
class vtkVertex;
class vtkPolyVertex;
class vtkLine;
class vtkPolyLine;
class vtkTriangle;
class vtkQuad;
class vtkPolygon;
class vtkTriangleStrip;
class vtkEmptyCell;
struct vtkPolyDataDummyContainter;
class vtkIncrementalPointLocator;
class VTKCOMMONDATAMODEL_EXPORT vtkPolyData : public vtkPointSet
{
public:
static vtkPolyData* New();
vtkTypeMacro(vtkPolyData, vtkPointSet);
void PrintSelf(ostream& os, vtkIndent indent) override;
/**
* Return what type of dataset this is.
*/
int GetDataObjectType() override { return VTK_POLY_DATA; }
/**
* Copy the geometric and topological structure of an input poly data object.
*/
void CopyStructure(vtkDataSet* ds) override;
//@{
/**
* Standard vtkDataSet interface.
*/
vtkIdType GetNumberOfCells() override;
using vtkDataSet::GetCell;
vtkCell* GetCell(vtkIdType cellId) override;
void GetCell(vtkIdType cellId, vtkGenericCell* cell) override;
int GetCellType(vtkIdType cellId) override;
void GetCellBounds(vtkIdType cellId, double bounds[6]) override;
void GetCellNeighbors(vtkIdType cellId, vtkIdList* ptIds, vtkIdList* cellIds) override;
//@}
/**
* Copy cells listed in idList from pd, including points, point data,
* and cell data. This method assumes that point and cell data have
* been allocated. If you pass in a point locator, then the points
* won't be duplicated in the output. This requires the use of an
* incremental point locator.
*/
void CopyCells(vtkPolyData* pd, vtkIdList* idList, vtkIncrementalPointLocator* locator = nullptr);
/**
* Copy a cells point ids into list provided. (Less efficient.)
*/
void GetCellPoints(vtkIdType cellId, vtkIdList* ptIds) override;
/**
* Efficient method to obtain cells using a particular point. Make sure that
* routine BuildLinks() has been called.
*/
void GetPointCells(vtkIdType ptId, vtkIdList* cellIds) override;
/**
* Compute the (X, Y, Z) bounds of the data. Note that the method only considers
* points that are used by cells (unless there are no cells, in which case all
* points are considered). This is done for usability and historical reasons.
*/
void ComputeBounds() override;
/**
* Recover extra allocated memory when creating data whose initial size
* is unknown. Examples include using the InsertNextCell() method, or
* when using the CellArray::EstimateSize() method to create vertices,
* lines, polygons, or triangle strips.
*/
void Squeeze() override;
/**
* Return the maximum cell size in this poly data.
*/
int GetMaxCellSize() override;
/**
* Set the cell array defining vertices.
*/
void SetVerts(vtkCellArray* v);
/**
* Get the cell array defining vertices. If there are no vertices, an
* empty array will be returned (convenience to simplify traversal).
*/
vtkCellArray* GetVerts();
/**
* Set the cell array defining lines.
*/
void SetLines(vtkCellArray* l);
/**
* Get the cell array defining lines. If there are no lines, an
* empty array will be returned (convenience to simplify traversal).
*/
vtkCellArray* GetLines();
/**
* Set the cell array defining polygons.
*/
void SetPolys(vtkCellArray* p);
/**
* Get the cell array defining polygons. If there are no polygons, an
* empty array will be returned (convenience to simplify traversal).
*/
vtkCellArray* GetPolys();
/**
* Set the cell array defining triangle strips.
*/
void SetStrips(vtkCellArray* s);
/**
* Get the cell array defining triangle strips. If there are no
* triangle strips, an empty array will be returned (convenience to
* simplify traversal).
*/
vtkCellArray* GetStrips();
//@{
/**
* Return the number of primitives of a particular type held.
*/
vtkIdType GetNumberOfVerts() { return (this->Verts ? this->Verts->GetNumberOfCells() : 0); }
vtkIdType GetNumberOfLines() { return (this->Lines ? this->Lines->GetNumberOfCells() : 0); }
vtkIdType GetNumberOfPolys() { return (this->Polys ? this->Polys->GetNumberOfCells() : 0); }
vtkIdType GetNumberOfStrips() { return (this->Strips ? this->Strips->GetNumberOfCells() : 0); }
//@}
/**
* Preallocate memory for the internal cell arrays. Each of the internal
* cell arrays (verts, lines, polys, and strips) will be resized to hold
* @a numCells cells of size @a maxCellSize.
*
* Existing data is not preserved and the number of cells is set to zero.
*
* @return True if allocation succeeds.
*/
bool AllocateEstimate(vtkIdType numCells, vtkIdType maxCellSize);
/**
* Preallocate memory for the internal cell arrays. Each of the internal
* cell arrays (verts, lines, polys, and strips) will be resized to hold
* the indicated number of cells of the specified cell size.
*
* Existing data is not preserved and the number of cells is set to zero.
*
* @return True if allocation succeeds.
*/
bool AllocateEstimate(vtkIdType numVerts, vtkIdType maxVertSize, vtkIdType numLines,
vtkIdType maxLineSize, vtkIdType numPolys, vtkIdType maxPolySize, vtkIdType numStrips,
vtkIdType maxStripSize);
/**
* Preallocate memory for the internal cell arrays. Each of the internal
* cell arrays (verts, lines, polys, and strips) will be resized to hold
* @a numCells cells and @a connectivitySize pointIds.
*
* Existing data is not preserved and the number of cells is set to zero.
*
* @return True if allocation succeeds.
*/
bool AllocateExact(vtkIdType numCells, vtkIdType connectivitySize);
/**
* Preallocate memory for the internal cell arrays. Each of the internal
* cell arrays (verts, lines, polys, and strips) will be resized to hold
* the indicated number of cells and the specified number of point ids
* (ConnSize).
*
* Existing data is not preserved and the number of cells is set to zero.
*
* @return True if allocation succeeds.
*/
bool AllocateExact(vtkIdType numVerts, vtkIdType vertConnSize, vtkIdType numLines,
vtkIdType lineConnSize, vtkIdType numPolys, vtkIdType polyConnSize, vtkIdType numStrips,
vtkIdType stripConnSize);
/**
* Preallocate memory for the internal cell arrays such that they are the
* same size as those in @a pd.
*
* Existing data is not preserved and the number of cells is set to zero.
*
* @return True if allocation succeeds.
*/
bool AllocateCopy(vtkPolyData* pd);
/**
* Preallocate memory for the internal cell arrays such that they are
* proportional to those in @a pd by a factor of @a ratio (for instance,
* @a ratio = 2 allocates twice as many cells).
*
* Existing data is not preserved and the number of cells is set to zero.
*
* @return True if allocation succeeds.
*/
bool AllocateProportional(vtkPolyData* pd, double ratio);
/**
* Method allocates initial storage for vertex, line, polygon, and
* triangle strip arrays. Use this method before the method
* PolyData::InsertNextCell(). (Or, provide vertex, line, polygon, and
* triangle strip cell arrays). @a extSize is no longer used.
*/
void Allocate(vtkIdType numCells = 1000, int vtkNotUsed(extSize) = 1000)
{
this->AllocateExact(numCells, numCells);
}
/**
* Similar to the method above, this method allocates initial storage for
* vertex, line, polygon, and triangle strip arrays. It does this more
* intelligently, examining the supplied inPolyData to determine whether to
* allocate the verts, lines, polys, and strips arrays. (These arrays are
* allocated only if there is data in the corresponding arrays in the
* inPolyData.) Caution: if the inPolyData has no verts, and after
* allocating with this method an PolyData::InsertNextCell() is invoked
* where a vertex is inserted, bad things will happen.
*/
void Allocate(vtkPolyData* inPolyData, vtkIdType numCells = 1000, int vtkNotUsed(extSize) = 1000)
{
this->AllocateProportional(
inPolyData, static_cast<double>(numCells) / inPolyData->GetNumberOfCells());
}
/**
* Insert a cell of type VTK_VERTEX, VTK_POLY_VERTEX, VTK_LINE, VTK_POLY_LINE,
* VTK_TRIANGLE, VTK_QUAD, VTK_POLYGON, or VTK_TRIANGLE_STRIP. Make sure that
* the PolyData::Allocate() function has been called first or that vertex,
* line, polygon, and triangle strip arrays have been supplied.
* Note: will also insert VTK_PIXEL, but converts it to VTK_QUAD.
*/
vtkIdType InsertNextCell(int type, int npts, const vtkIdType pts[]) VTK_SIZEHINT(pts, npts);
/**
* Insert a cell of type VTK_VERTEX, VTK_POLY_VERTEX, VTK_LINE, VTK_POLY_LINE,
* VTK_TRIANGLE, VTK_QUAD, VTK_POLYGON, or VTK_TRIANGLE_STRIP. Make sure that
* the PolyData::Allocate() function has been called first or that vertex,
* line, polygon, and triangle strip arrays have been supplied.
* Note: will also insert VTK_PIXEL, but converts it to VTK_QUAD.
*/
vtkIdType InsertNextCell(int type, vtkIdList* pts);
/**
* Begin inserting data all over again. Memory is not freed but otherwise
* objects are returned to their initial state.
*/
void Reset();
/**
* Create data structure that allows random access of cells. BuildCells is
* expensive but necessary to make use of the faster non-virtual implementations
* of GetCell/GetCellPoints. One may check if cells need to be built via
* NeedToBuilds before invoking. Cells always need to be built/re-built after
* low level direct modifications to verts, lines, polys or strips cell arrays.
*/
void BuildCells();
/**
* Check if BuildCells is needed.
*/
bool NeedToBuildCells() { return this->Cells == nullptr; }
/**
* Create upward links from points to cells that use each point. Enables
* topologically complex queries. Normally the links array is allocated
* based on the number of points in the vtkPolyData. The optional
* initialSize parameter can be used to allocate a larger size initially.
*/
void BuildLinks(int initialSize = 0);
/**
* Release data structure that allows random access of the cells. This must
* be done before a 2nd call to BuildLinks(). DeleteCells implicitly deletes
* the links as well since they are no longer valid.
*/
void DeleteCells();
/**
* Release the upward links from point to cells that use each point.
*/
void DeleteLinks();
//@{
/**
* Special (efficient) operations on poly data. Use carefully (i.e., make
* sure that BuildLinks() has been called).
*/
void GetPointCells(vtkIdType ptId, vtkIdType& ncells, vtkIdType*& cells)
VTK_SIZEHINT(cells, ncells);
#ifndef VTK_LEGACY_REMOVE
VTK_LEGACY(void GetPointCells(vtkIdType ptId, unsigned short& ncells, vtkIdType*& cells))
VTK_SIZEHINT(cells, ncells);
#endif
//@}
/**
* Get the neighbors at an edge. More efficient than the general
* GetCellNeighbors(). Assumes links have been built (with BuildLinks()),
* and looks specifically for edge neighbors.
*/
void GetCellEdgeNeighbors(vtkIdType cellId, vtkIdType p1, vtkIdType p2, vtkIdList* cellIds);
/**
* Get a list of point ids that define a cell. The cell type is
* returned. Requires the the cells have been built with BuildCells.
*
* @warning Subsequent calls to this method may invalidate previous call
* results.
*
* The @a pts pointer must not be modified.
*/
unsigned char GetCellPoints(vtkIdType cellId, vtkIdType& npts, vtkIdType const*& pts)
VTK_SIZEHINT(pts, npts);
/**
* Given three vertices, determine whether it's a triangle. Make sure
* BuildLinks() has been called first.
*/
int IsTriangle(int v1, int v2, int v3);
/**
* Determine whether two points form an edge. If they do, return non-zero.
* By definition PolyVertex and PolyLine have no edges since 1-dimensional
* edges are only found on cells 2D and higher.
* Edges are defined as 1-D boundary entities to cells.
* Make sure BuildLinks() has been called first.
*/
int IsEdge(vtkIdType p1, vtkIdType p2);
/**
* Determine whether a point is used by a particular cell. If it is, return
* non-zero. Make sure BuildCells() has been called first.
*/
int IsPointUsedByCell(vtkIdType ptId, vtkIdType cellId);
/**
* Replace the points defining cell "cellId" with a new set of points. This
* operator is (typically) used when links from points to cells have not been
* built (i.e., BuildLinks() has not been executed). Use the operator
* ReplaceLinkedCell() to replace a cell when cell structure has been built. Use this
* method only when the dataset is set as Editable.
* @{
*/
void ReplaceCell(vtkIdType cellId, vtkIdList* ids);
void ReplaceCell(vtkIdType cellId, int npts, const vtkIdType pts[]) VTK_SIZEHINT(pts, npts);
/**@}*/
/**
* Replace a point in the cell connectivity list with a different point. Use this
* method only when the dataset is set as Editable.
*/
void ReplaceCellPoint(vtkIdType cellId, vtkIdType oldPtId, vtkIdType newPtId);
/**
* Reverse the order of point ids defining the cell. Use this
* method only when the dataset is set as Editable.
*/
void ReverseCell(vtkIdType cellId);
//@{
/**
* Mark a point/cell as deleted from this vtkPolyData. Use this
* method only when the dataset is set as Editable.
*/
void DeletePoint(vtkIdType ptId);
void DeleteCell(vtkIdType cellId);
//@}
/**
* The cells marked by calls to DeleteCell are stored in the Cell Array
* VTK_EMPTY_CELL, but they still exist in the cell arrays. Calling
* RemoveDeletedCells will traverse the cell arrays and remove/compact the
* cell arrays as well as any cell data thus truly removing the cells from
* the polydata object. Use this method only when the dataset is set as
* Editable.
*/
void RemoveDeletedCells();
//@{
/**
* Add a point to the cell data structure (after cell pointers have been
* built). This method adds the point and then allocates memory for the
* links to the cells. (To use this method, make sure points are available
* and BuildLinks() has been invoked.) Of the two methods below, one inserts
* a point coordinate and the other just makes room for cell links. Use this
* method only when the dataset is set as Editable.
*/
vtkIdType InsertNextLinkedPoint(int numLinks);
vtkIdType InsertNextLinkedPoint(double x[3], int numLinks);
//@}
/**
* Add a new cell to the cell data structure (after cell pointers have been
* built). This method adds the cell and then updates the links from the
* points to the cells. (Memory is allocated as necessary.) Use this method
* only when the dataset is set as Editable.
*/
vtkIdType InsertNextLinkedCell(int type, int npts, const vtkIdType pts[]) VTK_SIZEHINT(pts, npts);
/**
* Replace one cell with another in cell structure. This operator updates
* the connectivity list and the point's link list. It does not delete
* references to the old cell in the point's link list. Use the operator
* RemoveCellReference() to delete all references from points to (old)
* cell. You may also want to consider using the operator ResizeCellList()
* if the link list is changing size. Use this method only when the dataset
* is set as Editable.
*/
void ReplaceLinkedCell(vtkIdType cellId, int npts, const vtkIdType pts[]) VTK_SIZEHINT(pts, npts);
/**
* Remove all references to cell in cell structure. This means the links
* from the cell's points to the cell are deleted. Memory is not
* reclaimed. Use the method ResizeCellList() to resize the link list from
* a point to its using cells. (This operator assumes BuildLinks() has been
* called.) Use this method only when the dataset is set as Editable.
*/
void RemoveCellReference(vtkIdType cellId);
/**
* Add references to cell in cell structure. This means the links from
* the cell's points to the cell are modified. Memory is not extended. Use the
* method ResizeCellList() to resize the link list from a point to its using
* cells. (This operator assumes BuildLinks() has been called.) Use this
* method only when the dataset is set as Editable.
*/
void AddCellReference(vtkIdType cellId);
/**
* Remove a reference to a cell in a particular point's link list. You may
* also consider using RemoveCellReference() to remove the references from
* all the cell's points to the cell. This operator does not reallocate
* memory; use the operator ResizeCellList() to do this if necessary. Use
* this method only when the dataset is set as Editable.
*/
void RemoveReferenceToCell(vtkIdType ptId, vtkIdType cellId);
/**
* Add a reference to a cell in a particular point's link list. (You may also
* consider using AddCellReference() to add the references from all the
* cell's points to the cell.) This operator does not realloc memory; use the
* operator ResizeCellList() to do this if necessary. Use this
* method only when the dataset is set as Editable.
*/
void AddReferenceToCell(vtkIdType ptId, vtkIdType cellId);
/**
* Resize the list of cells using a particular point. (This operator
* assumes that BuildLinks() has been called.) Use this method only when
* the dataset is set as Editable.
*/
void ResizeCellList(vtkIdType ptId, int size);
/**
* Restore object to initial state. Release memory back to system.
*/
void Initialize() override;
//@{
/**
* Get the piece and the number of pieces. Similar to extent in 3D.
*/
virtual int GetPiece();
virtual int GetNumberOfPieces();
//@}
/**
* Get the ghost level.
*/
virtual int GetGhostLevel();
/**
* Return the actual size of the data in kibibytes (1024 bytes). This number
* is valid only after the pipeline has updated. The memory size
* returned is guaranteed to be greater than or equal to the
* memory required to represent the data (e.g., extra space in
* arrays, etc. are not included in the return value). THIS METHOD
* IS THREAD SAFE.
*/
unsigned long GetActualMemorySize() override;
//@{
/**
* Shallow and Deep copy.
*/
void ShallowCopy(vtkDataObject* src) override;
void DeepCopy(vtkDataObject* src) override;
//@}
/**
* This method will remove any cell that is marked as ghost
* (has the vtkDataSetAttributes::DUPLICATECELL bit set).
* It does not remove unused points.
*/
void RemoveGhostCells();
//@{
/**
* Retrieve an instance of this class from an information object.
*/
static vtkPolyData* GetData(vtkInformation* info);
static vtkPolyData* GetData(vtkInformationVector* v, int i = 0);
//@}
/**
* Scalar field critical point classification (for manifold 2D meshes).
* Reference: J. Milnor "Morse Theory", Princeton University Press, 1963.
* Given a pointId and an attribute representing a scalar field, this member
* returns the index of the critical point:
* vtkPolyData::MINIMUM (index 0): local minimum;
* vtkPolyData::SADDLE (index 1): local saddle;
* vtkPolyData::MAXIMUM (index 2): local maximum.
* Other returned values are:
* vtkPolyData::REGULAR_POINT: regular point (the gradient does not vanish);
* vtkPolyData::ERR_NON_MANIFOLD_STAR: the star of the considered vertex is
* not manifold (could not evaluate the index)
* vtkPolyData::ERR_INCORRECT_FIELD: the number of entries in the scalar field
* array is different form the number of vertices in the mesh.
* vtkPolyData::ERR_NO_SUCH_FIELD: the specified scalar field does not exist.
*/
enum
{
ERR_NO_SUCH_FIELD = -4,
ERR_INCORRECT_FIELD = -3,
ERR_NON_MANIFOLD_STAR = -2,
REGULAR_POINT = -1,
MINIMUM = 0,
SADDLE = 1,
MAXIMUM = 2
};
int GetScalarFieldCriticalIndex(vtkIdType pointId, vtkDataArray* scalarField);
int GetScalarFieldCriticalIndex(vtkIdType pointId, int fieldId);
int GetScalarFieldCriticalIndex(vtkIdType pointId, const char* fieldName);
/**
* Return the mesh (geometry/topology) modification time.
* This time is different from the usual MTime which also takes into
* account the modification of data arrays. This function can be used to
* track the changes on the mesh separately from the data arrays
* (eg. static mesh over time with transient data).
*/
virtual vtkMTimeType GetMeshMTime();
/**
* Get MTime which also considers its cell array MTime.
*/
vtkMTimeType GetMTime() override;
/**
* Get a pointer to the cell, ie [npts pid1 .. pidn]. The cell type is
* returned. Requires the the cells have been built with BuildCells.
* The @a pts pointer must not be modified.
*
* @warning Internal cell storage has changed, and cell size is no longer
* stored with the cell point ids. The `pts` array returned here no longer
* exists in memory.
*/
unsigned char GetCell(vtkIdType cellId, const vtkIdType*& pts);
protected:
vtkPolyData();
~vtkPolyData() override;
using TaggedCellId = vtkPolyData_detail::TaggedCellId;
using CellMap = vtkPolyData_detail::CellMap;
vtkCellArray* GetCellArrayInternal(TaggedCellId tag);
// constant cell objects returned by GetCell called.
vtkSmartPointer<vtkVertex> Vertex;
vtkSmartPointer<vtkPolyVertex> PolyVertex;
vtkSmartPointer<vtkLine> Line;
vtkSmartPointer<vtkPolyLine> PolyLine;
vtkSmartPointer<vtkTriangle> Triangle;
vtkSmartPointer<vtkQuad> Quad;
vtkSmartPointer<vtkPolygon> Polygon;
vtkSmartPointer<vtkTriangleStrip> TriangleStrip;
vtkSmartPointer<vtkEmptyCell> EmptyCell;
// points inherited
// point data (i.e., scalars, vectors, normals, tcoords) inherited
vtkSmartPointer<vtkCellArray> Verts;
vtkSmartPointer<vtkCellArray> Lines;
vtkSmartPointer<vtkCellArray> Polys;
vtkSmartPointer<vtkCellArray> Strips;
// supporting structures for more complex topological operations
// built only when necessary
vtkSmartPointer<CellMap> Cells;
vtkSmartPointer<vtkCellLinks> Links;
vtkNew<vtkIdList> LegacyBuffer;
// dummy static member below used as a trick to simplify traversal
static vtkPolyDataDummyContainter DummyContainer;
private:
// Hide these from the user and the compiler.
/**
* For legacy compatibility. Do not use.
*/
void GetCellNeighbors(vtkIdType cellId, vtkIdList& ptIds, vtkIdList& cellIds)
{
this->GetCellNeighbors(cellId, &ptIds, &cellIds);
}
void Cleanup();
private:
vtkPolyData(const vtkPolyData&) = delete;
void operator=(const vtkPolyData&) = delete;
};
//------------------------------------------------------------------------------
inline void vtkPolyData::GetPointCells(vtkIdType ptId, vtkIdType& ncells, vtkIdType*& cells)
{
ncells = this->Links->GetNcells(ptId);
cells = this->Links->GetCells(ptId);
}
#ifndef VTK_LEGACY_REMOVE
inline void vtkPolyData::GetPointCells(vtkIdType ptId, unsigned short& ncells, vtkIdType*& cells)
{
VTK_LEGACY_BODY(vtkPolyData::GetPointCells, "VTK 9.0");
ncells = static_cast<unsigned short>(this->Links->GetNcells(ptId));
cells = this->Links->GetCells(ptId);
}
#endif
//------------------------------------------------------------------------------
inline vtkIdType vtkPolyData::GetNumberOfCells()
{
return (this->GetNumberOfVerts() + this->GetNumberOfLines() + this->GetNumberOfPolys() +
this->GetNumberOfStrips());
}
//------------------------------------------------------------------------------
inline int vtkPolyData::GetCellType(vtkIdType cellId)
{
if (!this->Cells)
{
this->BuildCells();
}
return static_cast<int>(this->Cells->GetTag(cellId).GetCellType());
}
//------------------------------------------------------------------------------
inline int vtkPolyData::IsTriangle(int v1, int v2, int v3)
{
vtkIdType n1;
int i, j, tVerts[3];
vtkIdType* cells;
const vtkIdType* tVerts2;
vtkIdType n2;
tVerts[0] = v1;
tVerts[1] = v2;
tVerts[2] = v3;
for (i = 0; i < 3; i++)
{
this->GetPointCells(tVerts[i], n1, cells);
for (j = 0; j < n1; j++)
{
this->GetCellPoints(cells[j], n2, tVerts2);
if ((tVerts[0] == tVerts2[0] || tVerts[0] == tVerts2[1] || tVerts[0] == tVerts2[2]) &&
(tVerts[1] == tVerts2[0] || tVerts[1] == tVerts2[1] || tVerts[1] == tVerts2[2]) &&
(tVerts[2] == tVerts2[0] || tVerts[2] == tVerts2[1] || tVerts[2] == tVerts2[2]))
{
return 1;
}
}
}
return 0;
}
//------------------------------------------------------------------------------
inline int vtkPolyData::IsPointUsedByCell(vtkIdType ptId, vtkIdType cellId)
{
vtkIdType npts;
const vtkIdType* pts;
this->GetCellPoints(cellId, npts, pts);
for (vtkIdType i = 0; i < npts; i++)
{
if (pts[i] == ptId)
{
return 1;
}
}
return 0;
}
//------------------------------------------------------------------------------
inline void vtkPolyData::DeletePoint(vtkIdType ptId)
{
this->Links->DeletePoint(ptId);
}
//------------------------------------------------------------------------------
inline void vtkPolyData::DeleteCell(vtkIdType cellId)
{
this->Cells->GetTag(cellId).MarkDeleted();
}
//------------------------------------------------------------------------------
inline void vtkPolyData::RemoveCellReference(vtkIdType cellId)
{
const vtkIdType* pts;
vtkIdType npts;
this->GetCellPoints(cellId, npts, pts);
for (vtkIdType i = 0; i < npts; i++)
{
this->Links->RemoveCellReference(cellId, pts[i]);
}
}
//------------------------------------------------------------------------------
inline void vtkPolyData::AddCellReference(vtkIdType cellId)
{
const vtkIdType* pts;
vtkIdType npts;
this->GetCellPoints(cellId, npts, pts);
for (vtkIdType i = 0; i < npts; i++)
{
this->Links->AddCellReference(cellId, pts[i]);
}
}
//------------------------------------------------------------------------------
inline void vtkPolyData::ResizeCellList(vtkIdType ptId, int size)
{
this->Links->ResizeCellList(ptId, size);
}
//------------------------------------------------------------------------------
inline vtkCellArray* vtkPolyData::GetCellArrayInternal(vtkPolyData::TaggedCellId tag)
{
switch (tag.GetTarget())
{
case vtkPolyData_detail::Target::Verts:
return this->Verts;
case vtkPolyData_detail::Target::Lines:
return this->Lines;
case vtkPolyData_detail::Target::Polys:
return this->Polys;
case vtkPolyData_detail::Target::Strips:
return this->Strips;
}
return nullptr; // unreachable
}
//------------------------------------------------------------------------------
inline void vtkPolyData::ReplaceCellPoint(vtkIdType cellId, vtkIdType oldPtId, vtkIdType newPtId)
{
vtkNew<vtkIdList> ids;
this->GetCellPoints(cellId, ids);
for (vtkIdType i = 0; i < ids->GetNumberOfIds(); i++)
{
if (ids->GetId(i) == oldPtId)
{
ids->SetId(i, newPtId);
break;
}
}
this->ReplaceCell(cellId, static_cast<int>(ids->GetNumberOfIds()), ids->GetPointer(0));
}
//------------------------------------------------------------------------------
inline unsigned char vtkPolyData::GetCellPoints(
vtkIdType cellId, vtkIdType& npts, vtkIdType const*& pts)
{
if (!this->Cells)
{
this->BuildCells();
}
const TaggedCellId tag = this->Cells->GetTag(cellId);
if (tag.IsDeleted())
{
npts = 0;
pts = nullptr;
return VTK_EMPTY_CELL;
}
vtkCellArray* cells = this->GetCellArrayInternal(tag);
cells->GetCellAtId(tag.GetCellId(), npts, pts);
return tag.GetCellType();
}
#endif