/*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkPolyData.h,v $ 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. =========================================================================*/ // .NAME vtkPolyData - concrete dataset represents vertices, lines, polygons, and triangle strips // .SECTION Description // 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. // // .SECTION Caveats // 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). // // 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. #ifndef __vtkPolyData_h #define __vtkPolyData_h #include "vtkPointSet.h" #include "vtkCellTypes.h" // Needed for inline methods #include "vtkCellLinks.h" // Needed for inline methods class vtkVertex; class vtkPolyVertex; class vtkLine; class vtkPolyLine; class vtkTriangle; class vtkQuad; class vtkPolygon; class vtkTriangleStrip; class vtkEmptyCell; class VTK_FILTERING_EXPORT vtkPolyData : public vtkPointSet { public: static vtkPolyData *New(); vtkTypeRevisionMacro(vtkPolyData,vtkPointSet); void PrintSelf(ostream& os, vtkIndent indent); // Description: // Return what type of dataset this is. int GetDataObjectType() {return VTK_POLY_DATA;} // Description: // Copy the geometric and topological structure of an input poly data object. void CopyStructure(vtkDataSet *ds); // Description: // Standard vtkDataSet interface. vtkIdType GetNumberOfCells(); vtkCell *GetCell(vtkIdType cellId); void GetCell(vtkIdType cellId, vtkGenericCell *cell); int GetCellType(vtkIdType cellId); void GetCellBounds(vtkIdType cellId, double bounds[6]); void GetCellNeighbors(vtkIdType cellId, vtkIdList *ptIds, vtkIdList *cellIds); // Description: // 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. void CopyCells(vtkPolyData *pd, vtkIdList *idList, vtkPointLocator *locator = NULL); // Description: // Copy a cells point ids into list provided. (Less efficient.) void GetCellPoints(vtkIdType cellId, vtkIdList *ptIds); // Description: // Efficient method to obtain cells using a particular point. Make sure that // routine BuildLinks() has been called. void GetPointCells(vtkIdType ptId, vtkIdList *cellIds); // Description: // Compute the (X, Y, Z) bounds of the data. void ComputeBounds(); // Description: // 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(); // Description: // Return the maximum cell size in this poly data. int GetMaxCellSize(); // Description: // Set the cell array defining vertices. void SetVerts (vtkCellArray* v); // Description: // Get the cell array defining vertices. If there are no vertices, an // empty array will be returned (convenience to simplify traversal). vtkCellArray *GetVerts(); // Description: // Set the cell array defining lines. void SetLines (vtkCellArray* l); // Description: // Get the cell array defining lines. If there are no lines, an // empty array will be returned (convenience to simplify traversal). vtkCellArray *GetLines(); // Description: // Set the cell array defining polygons. void SetPolys (vtkCellArray* p); // Description: // Get the cell array defining polygons. If there are no polygons, an // empty array will be returned (convenience to simplify traversal). vtkCellArray *GetPolys(); // Description: // Set the cell array defining triangle strips. void SetStrips (vtkCellArray* s); // Description: // 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(); // Description: // Return the number of primitives of a particular type held.. vtkIdType GetNumberOfVerts(); vtkIdType GetNumberOfLines(); vtkIdType GetNumberOfPolys(); vtkIdType GetNumberOfStrips(); // Description: // 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.) void Allocate(vtkIdType numCells=1000, int extSize=1000); // Description: // 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 extSize=1000); // Description: // 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. int InsertNextCell(int type, int npts, vtkIdType *pts); // Description: // 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. int InsertNextCell(int type, vtkIdList *pts); // Description: // Begin inserting data all over again. Memory is not freed but otherwise // objects are returned to their initial state. void Reset(); // Description: // Create data structure that allows random access of cells. void BuildCells(); // Description: // 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); // Description: // 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(); // Description: // Release the upward links from point to cells that use each point. void DeleteLinks(); // Description: // Special (efficient) operations on poly data. Use carefully. void GetPointCells(vtkIdType ptId, unsigned short& ncells, vtkIdType* &cells); // Description: // 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); // Description: // Return a pointer to a list of point ids defining cell. (More efficient.) // Assumes that cells have been built (with BuildCells()). void GetCellPoints(vtkIdType cellId, vtkIdType& npts, vtkIdType* &pts); // Description: // Given three vertices, determine whether it's a triangle. Make sure // BuildLinks() has been called first. int IsTriangle(int v1, int v2, int v3); // Description: // 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); // Description: // 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); // Description: // 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. void ReplaceCell(vtkIdType cellId, int npts, vtkIdType *pts); // Description: // Replace a point in the cell connectivity list with a different point. void ReplaceCellPoint(vtkIdType cellId, vtkIdType oldPtId, vtkIdType newPtId); // Description: // Reverse the order of point ids defining the cell. void ReverseCell(vtkIdType cellId); // Description: // Mark a point/cell as deleted from this vtkPolyData. void DeletePoint(vtkIdType ptId); void DeleteCell(vtkIdType cellId); // Description: // 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. int InsertNextLinkedPoint(int numLinks); int InsertNextLinkedPoint(double x[3], int numLinks); // Description: // 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.) int InsertNextLinkedCell(int type, int npts, vtkIdType *pts); // Description: // 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. void ReplaceLinkedCell(vtkIdType cellId, int npts, vtkIdType *pts); // Description: // 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.) void RemoveCellReference(vtkIdType cellId); // Description: // 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.) void AddCellReference(vtkIdType cellId); // Description: // 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. void RemoveReferenceToCell(vtkIdType ptId, vtkIdType cellId); // Description: // 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. void AddReferenceToCell(vtkIdType ptId, vtkIdType cellId); // Description: // Resize the list of cells using a particular point. (This operator assumes // that BuildLinks() has been called.) void ResizeCellList(vtkIdType ptId, int size); // Description: // Restore object to initial state. Release memory back to system. virtual void Initialize(); // Description: // For streaming. User/next filter specifies which piece they want updated. // The source of this poly data has to return exactly this piece. void GetUpdateExtent(int &piece, int &numPieces, int &ghostLevel); // Description: // We need this here to avoid hiding superclass method virtual int* GetUpdateExtent(); virtual void GetUpdateExtent(int& x0, int& x1, int& y0, int& y1, int& z0, int& z1); virtual void GetUpdateExtent(int extent[6]); // Description: // Get the piece and the number of pieces. Similar to extent in 3D. virtual int GetPiece(); virtual int GetNumberOfPieces(); // Description: // Get the ghost level. virtual int GetGhostLevel(); // Description: // Return the actual size of the data in kilobytes. 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(); // Description: // Shallow and Deep copy. void ShallowCopy(vtkDataObject *src); void DeepCopy(vtkDataObject *src); // Description: // This method will remove any cell that has a ghost level array value // greater or equal to level. It does not remove unused points (yet). void RemoveGhostCells(int level); //BTX // Description: // Retrieve an instance of this class from an information object. static vtkPolyData* GetData(vtkInformation* info); static vtkPolyData* GetData(vtkInformationVector* v, int i=0); //ETX protected: vtkPolyData(); ~vtkPolyData(); // constant cell objects returned by GetCell called. vtkVertex *Vertex; vtkPolyVertex *PolyVertex; vtkLine *Line; vtkPolyLine *PolyLine; vtkTriangle *Triangle; vtkQuad *Quad; vtkPolygon *Polygon; vtkTriangleStrip *TriangleStrip; vtkEmptyCell *EmptyCell; // points inherited // point data (i.e., scalars, vectors, normals, tcoords) inherited vtkCellArray *Verts; vtkCellArray *Lines; vtkCellArray *Polys; vtkCellArray *Strips; // dummy static member below used as a trick to simplify traversal static vtkCellArray *Dummy; // supporting structures for more complex topological operations // built only when necessary vtkCellTypes *Cells; vtkCellLinks *Links; // This method is called during an update. // If the CropFilter is set, the user reqquested a piece which the // source cannot generate, then it will break up the // data set in order to satisfy the request. virtual void Crop(); private: // Hide these from the user and the compiler. // Description: // For legacy compatibility. Do not use. void GetCellNeighbors(vtkIdType cellId, vtkIdList& ptIds, vtkIdList& cellIds) {this->GetCellNeighbors(cellId, &ptIds, &cellIds);} private: vtkPolyData(const vtkPolyData&); // Not implemented. void operator=(const vtkPolyData&); // Not implemented. }; inline void vtkPolyData::GetPointCells(vtkIdType ptId, unsigned short& ncells, vtkIdType* &cells) { ncells = this->Links->GetNcells(ptId); cells = this->Links->GetCells(ptId); } inline int vtkPolyData::IsTriangle(int v1, int v2, int v3) { unsigned short int n1; int i, j, tVerts[3]; vtkIdType *cells, *tVerts2, 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; jGetCellPoints(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 *pts, npts; 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->DeleteCell(cellId); } inline void vtkPolyData::RemoveCellReference(vtkIdType cellId) { vtkIdType *pts, npts; this->GetCellPoints(cellId, npts, pts); for (vtkIdType i=0; iLinks->RemoveCellReference(cellId, pts[i]); } } inline void vtkPolyData::AddCellReference(vtkIdType cellId) { vtkIdType *pts, npts; this->GetCellPoints(cellId, npts, pts); for (vtkIdType i=0; iLinks->AddCellReference(cellId, pts[i]); } } inline void vtkPolyData::ResizeCellList(vtkIdType ptId, int size) { this->Links->ResizeCellList(ptId,size); } inline void vtkPolyData::ReplaceCellPoint(vtkIdType cellId, vtkIdType oldPtId, vtkIdType newPtId) { int i; vtkIdType *verts, nverts; this->GetCellPoints(cellId,nverts,verts); for ( i=0; i < nverts; i++ ) { if ( verts[i] == oldPtId ) { verts[i] = newPtId; // this is very nasty! direct write! return; } } } #endif