/*========================================================================= Program: Visualization Toolkit Module: vtkCell.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 vtkCell * @brief abstract class to specify cell behavior * * vtkCell is an abstract class that specifies the interfaces for data cells. * Data cells are simple topological elements like points, lines, polygons, * and tetrahedra of which visualization datasets are composed. In some * cases visualization datasets may explicitly represent cells (e.g., * vtkPolyData, vtkUnstructuredGrid), and in some cases, the datasets are * implicitly composed of cells (e.g., vtkStructuredPoints). * * @warning * The \#define VTK_CELL_SIZE is a parameter used to construct cells and provide * a general guideline for controlling object execution. This parameter is * not a hard boundary: you can create cells with more points. * * @sa * vtkHexahedron vtkLine vtkPixel vtkPolyLine vtkPolyVertex * vtkPolygon vtkQuad vtkTetra vtkTriangle * vtkTriangleStrip vtkVertex vtkVoxel vtkWedge vtkPyramid */ #ifndef vtkCell_h #define vtkCell_h #define VTK_CELL_SIZE 512 #define VTK_TOL 1.e-05 // Tolerance for geometric calculation #include "vtkCommonDataModelModule.h" // For export macro #include "vtkObject.h" #include "vtkCellType.h" // Needed to define cell types #include "vtkIdList.h" // Needed for inline methods class vtkCellArray; class vtkCellData; class vtkDataArray; class vtkPointData; class vtkIncrementalPointLocator; class vtkPoints; class VTKCOMMONDATAMODEL_EXPORT vtkCell : public vtkObject { public: vtkTypeMacro(vtkCell, vtkObject); void PrintSelf(ostream& os, vtkIndent indent) override; /** * Initialize cell from outside with point ids and point * coordinates specified. */ void Initialize(int npts, const vtkIdType* pts, vtkPoints* p); /** * Initialize the cell with point coordinates specified. Note that this * simplified version of Initialize() assumes that the point ids are simply * the indices into the supplied points array. Make sure that the ordering * of the points is consistent with the definition of the cell. */ void Initialize(int npts, vtkPoints* p); /** * Copy this cell by reference counting the internal data structures. * This is safe if you want a "read-only" copy. If you modify the cell * you might wish to use DeepCopy(). */ virtual void ShallowCopy(vtkCell* c); /** * Copy this cell by completely copying internal data structures. This is * slower but safer than ShallowCopy(). */ virtual void DeepCopy(vtkCell* c); /** * Return the type of cell. */ virtual int GetCellType() = 0; /** * Return the topological dimensional of the cell (0,1,2, or 3). */ virtual int GetCellDimension() = 0; /** * Non-linear cells require special treatment beyond the usual cell type * and connectivity list information. Most cells in VTK are implicit * cells. */ virtual int IsLinear() { return 1; } /** * Some cells require initialization prior to access. For example, they * may have to triangulate themselves or set up internal data structures. */ virtual int RequiresInitialization() { return 0; } virtual void Initialize() {} /** * Explicit cells require additional representational information * beyond the usual cell type and connectivity list information. * Most cells in VTK are implicit cells. */ virtual int IsExplicitCell() { return 0; } /** * Determine whether the cell requires explicit face representation, and * methods for setting and getting the faces (see vtkPolyhedron for example * usage of these methods). */ virtual int RequiresExplicitFaceRepresentation() { return 0; } virtual void SetFaces(vtkIdType* vtkNotUsed(faces)) {} virtual vtkIdType* GetFaces() { return nullptr; } /** * Get the point coordinates for the cell. */ vtkPoints* GetPoints() { return this->Points; } /** * Return the number of points in the cell. */ vtkIdType GetNumberOfPoints() { return this->PointIds->GetNumberOfIds(); } /** * Return the number of edges in the cell. */ virtual int GetNumberOfEdges() = 0; /** * Return the number of faces in the cell. */ virtual int GetNumberOfFaces() = 0; /** * Return the list of point ids defining the cell. */ vtkIdList* GetPointIds() { return this->PointIds; } /** * For cell point i, return the actual point id. */ vtkIdType GetPointId(int ptId) VTK_EXPECTS(0 <= ptId && ptId < GetPointIds()->GetNumberOfIds()) { return this->PointIds->GetId(ptId); } /** * Return the edge cell from the edgeId of the cell. */ virtual vtkCell* GetEdge(int edgeId) = 0; /** * Return the face cell from the faceId of the cell. */ virtual vtkCell* GetFace(int faceId) = 0; /** * Given parametric coordinates of a point, return the closest cell * boundary, and whether the point is inside or outside of the cell. The * cell boundary is defined by a list of points (pts) that specify a face * (3D cell), edge (2D cell), or vertex (1D cell). If the return value of * the method is != 0, then the point is inside the cell. */ virtual int CellBoundary(int subId, const double pcoords[3], vtkIdList* pts) = 0; /** * Given a point x[3] return inside(=1), outside(=0) cell, or (-1) * computational problem encountered; evaluate * parametric coordinates, sub-cell id (!=0 only if cell is composite), * distance squared of point x[3] to cell (in particular, the sub-cell * indicated), closest point on cell to x[3] (unless closestPoint is null, * in which case, the closest point and dist2 are not found), and * interpolation weights in cell. (The number of weights is equal to the * number of points defining the cell). Note: on rare occasions a -1 is * returned from the method. This means that numerical error has occurred * and all data returned from this method should be ignored. Also, * inside/outside is determine parametrically. That is, a point is inside * if it satisfies parametric limits. This can cause problems for cells of * topological dimension 2 or less, since a point in 3D can project onto * the cell within parametric limits but be "far" from the cell. Thus the * value dist2 may be checked to determine true in/out. */ virtual int EvaluatePosition(const double x[3], double closestPoint[3], int& subId, double pcoords[3], double& dist2, double weights[]) = 0; /** * Determine global coordinate (x[3]) from subId and parametric coordinates. * Also returns interpolation weights. (The number of weights is equal to * the number of points in the cell.) */ virtual void EvaluateLocation( int& subId, const double pcoords[3], double x[3], double* weights) = 0; /** * Generate contouring primitives. The scalar list cellScalars are * scalar values at each cell point. The point locator is essentially a * points list that merges points as they are inserted (i.e., prevents * duplicates). Contouring primitives can be vertices, lines, or * polygons. It is possible to interpolate point data along the edge * by providing input and output point data - if outPd is nullptr, then * no interpolation is performed. Also, if the output cell data is * non-nullptr, the cell data from the contoured cell is passed to the * generated contouring primitives. (Note: the CopyAllocate() method * must be invoked on both the output cell and point data. The * cellId refers to the cell from which the cell data is copied.) */ virtual void Contour(double value, vtkDataArray* cellScalars, vtkIncrementalPointLocator* locator, vtkCellArray* verts, vtkCellArray* lines, vtkCellArray* polys, vtkPointData* inPd, vtkPointData* outPd, vtkCellData* inCd, vtkIdType cellId, vtkCellData* outCd) = 0; /** * Cut (or clip) the cell based on the input cellScalars and the * specified value. The output of the clip operation will be one or * more cells of the same topological dimension as the original cell. * The flag insideOut controls what part of the cell is considered inside - * normally cell points whose scalar value is greater than "value" are * considered inside. If insideOut is on, this is reversed. Also, if the * output cell data is non-nullptr, the cell data from the clipped cell is * passed to the generated contouring primitives. (Note: the CopyAllocate() * method must be invoked on both the output cell and point data. The * cellId refers to the cell from which the cell data is copied.) */ virtual void Clip(double value, vtkDataArray* cellScalars, vtkIncrementalPointLocator* locator, vtkCellArray* connectivity, vtkPointData* inPd, vtkPointData* outPd, vtkCellData* inCd, vtkIdType cellId, vtkCellData* outCd, int insideOut) = 0; /** * Intersect with a ray. Return parametric coordinates (both line and cell) * and global intersection coordinates, given ray definition p1[3], p2[3] and tolerance tol. * The method returns non-zero value if intersection occurs. A parametric distance t * between 0 and 1 along the ray representing the intersection point, the point coordinates * x[3] in data coordinates and also pcoords[3] in parametric coordinates. subId is the index * within the cell if a composed cell like a triangle strip. */ virtual int IntersectWithLine(const double p1[3], const double p2[3], double tol, double& t, double x[3], double pcoords[3], int& subId) = 0; /** * Generate simplices of proper dimension. If cell is 3D, tetrahedron are * generated; if 2D triangles; if 1D lines; if 0D points. The form of the * output is a sequence of points, each n+1 points (where n is topological * cell dimension) defining a simplex. The index is a parameter that controls * which triangulation to use (if more than one is possible). If numerical * degeneracy encountered, 0 is returned, otherwise 1 is returned. * This method does not insert new points: all the points that define the * simplices are the points that define the cell. */ virtual int Triangulate(int index, vtkIdList* ptIds, vtkPoints* pts) = 0; /** * Compute derivatives given cell subId and parametric coordinates. The * values array is a series of data value(s) at the cell points. There is a * one-to-one correspondence between cell point and data value(s). Dim is * the number of data values per cell point. Derivs are derivatives in the * x-y-z coordinate directions for each data value. Thus, if computing * derivatives for a scalar function in a hexahedron, dim=1, 8 values are * supplied, and 3 deriv values are returned (i.e., derivatives in x-y-z * directions). On the other hand, if computing derivatives of velocity * (vx,vy,vz) dim=3, 24 values are supplied ((vx,vy,vz)1, (vx,vy,vz)2, * ....()8), and 9 deriv values are returned * ((d(vx)/dx),(d(vx)/dy),(d(vx)/dz), (d(vy)/dx),(d(vy)/dy), (d(vy)/dz), * (d(vz)/dx),(d(vz)/dy),(d(vz)/dz)). */ virtual void Derivatives( int subId, const double pcoords[3], const double* values, int dim, double* derivs) = 0; /** * Compute cell bounding box (xmin,xmax,ymin,ymax,zmin,zmax). Copy result * into user provided array. */ void GetBounds(double bounds[6]); /** * Compute cell bounding box (xmin,xmax,ymin,ymax,zmin,zmax). Return pointer * to array of six double values. */ double* GetBounds() VTK_SIZEHINT(6); /** * Compute Length squared of cell (i.e., bounding box diagonal squared). */ double GetLength2(); /** * Return center of the cell in parametric coordinates. Note that the * parametric center is not always located at (0.5,0.5,0.5). The return * value is the subId that the center is in (if a composite cell). If you * want the center in x-y-z space, invoke the EvaluateLocation() method. */ virtual int GetParametricCenter(double pcoords[3]); /** * Return the distance of the parametric coordinate provided to the * cell. If inside the cell, a distance of zero is returned. This is * used during picking to get the correct cell picked. (The tolerance * will occasionally allow cells to be picked who are not really * intersected "inside" the cell.) */ virtual double GetParametricDistance(const double pcoords[3]); /** * Return whether this cell type has a fixed topology or whether the * topology varies depending on the data (e.g., vtkConvexPointSet). * This compares to composite cells that are typically composed of * primary cells (e.g., a triangle strip composite cell is made up of * triangle primary cells). */ virtual int IsPrimaryCell() { return 1; } /** * Return a contiguous array of parametric coordinates of the points * defining this cell. In other words, (px,py,pz, px,py,pz, etc..) The * coordinates are ordered consistent with the definition of the point * ordering for the cell. This method returns a non-nullptr pointer when * the cell is a primary type (i.e., IsPrimaryCell() is true). Note that * 3D parametric coordinates are returned no matter what the topological * dimension of the cell. */ virtual double* GetParametricCoords() VTK_SIZEHINT(3 * GetNumberOfPoints()); /** * Compute the interpolation functions/derivatives * (aka shape functions/derivatives) * No-ops at this level. Typically overridden in subclasses. */ virtual void InterpolateFunctions(const double vtkNotUsed(pcoords)[3], double* vtkNotUsed(weight)) { } virtual void InterpolateDerivs(const double vtkNotUsed(pcoords)[3], double* vtkNotUsed(derivs)) {} // left public for quick computational access vtkPoints* Points; vtkIdList* PointIds; protected: vtkCell(); ~vtkCell() override; double Bounds[6]; private: vtkCell(const vtkCell&) = delete; void operator=(const vtkCell&) = delete; }; #endif