Commit 4bd8735d authored by Will Schroeder's avatar Will Schroeder
Browse files

Tested and working

Fully implemented classes, expanded testing.
parent ceb86646
...@@ -157,7 +157,6 @@ set(Module_SRCS ...@@ -157,7 +157,6 @@ set(Module_SRCS
vtkSmoothErrorMetric.cxx vtkSmoothErrorMetric.cxx
vtkSphere.cxx vtkSphere.cxx
vtkSpline.cxx vtkSpline.cxx
vtkStaticCellLinks.txx
vtkStaticCellLinks.cxx vtkStaticCellLinks.cxx
vtkStaticCellLinksTemplate.txx vtkStaticCellLinksTemplate.txx
vtkStaticPointLocator.cxx vtkStaticPointLocator.cxx
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
PURPOSE. See the above copyright notice for more information. PURPOSE. See the above copyright notice for more information.
=========================================================================*/ =========================================================================*/
#include "vtkStaticCellLinks.h"
#include "vtkStaticCellLinksTemplate.h" #include "vtkStaticCellLinksTemplate.h"
#include "vtkSmartPointer.h" #include "vtkSmartPointer.h"
#include "vtkImageData.h" #include "vtkImageData.h"
...@@ -28,12 +29,63 @@ int TestStaticCellLinks( int, char *[] ) ...@@ -28,12 +29,63 @@ int TestStaticCellLinks( int, char *[] )
{ {
int dataDim = 3; int dataDim = 3;
// First create an instructured grid // First create a volume which will be converted to an unstructured grid
vtkSmartPointer<vtkImageData> volume = vtkSmartPointer<vtkImageData> volume =
vtkSmartPointer<vtkImageData>::New(); vtkSmartPointer<vtkImageData>::New();
volume->SetDimensions(dataDim,dataDim,dataDim); volume->SetDimensions(dataDim,dataDim,dataDim);
volume->AllocateScalars(VTK_INT,1); volume->AllocateScalars(VTK_INT,1);
//----------------------------------------------------------------------------
// Build links on volume
vtkSmartPointer<vtkStaticCellLinks> imlinks =
vtkSmartPointer<vtkStaticCellLinks>::New();
imlinks->BuildLinks(volume);
vtkIdType ncells = imlinks->GetNumberOfCells(0);
const vtkIdType *imcells = imlinks->GetCells(0);
cout << "Volume:\n";
cout << " Lower Left corner (numCells, cells): " << ncells << " (";
for (int i=0; i<ncells; ++i)
{
cout << imcells[i];
if ( i < (ncells-1) ) cout << "," ;
}
cout << ")\n";
if ( ncells != 1 || imcells[0] != 0 )
{
return EXIT_FAILURE;
}
ncells = imlinks->GetNumberOfCells(13);
imcells = imlinks->GetCells(13);
cout << " Center (ncells, cells): " << ncells << " (";
for (int i=0; i<ncells; ++i)
{
cout << imcells[i];
if ( i < (ncells-1) ) cout << "," ;
}
cout << ")\n";
if ( ncells != 8 )
{
return EXIT_FAILURE;
}
ncells = imlinks->GetNumberOfCells(26);
imcells = imlinks->GetCells(26);
cout << " Upper Right corner (ncells, cells): " << ncells << " (";
for (int i=0; i<ncells; ++i)
{
cout << imcells[i];
if ( i < (ncells-1) ) cout << "," ;
}
cout << ")\n";
if ( ncells != 1 || imcells[0] != 7 )
{
return EXIT_FAILURE;
}
//----------------------------------------------------------------------------
// Unstructured grid
vtkSmartPointer<vtkSphere> sphere = vtkSmartPointer<vtkSphere> sphere =
vtkSmartPointer<vtkSphere>::New(); vtkSmartPointer<vtkSphere>::New();
sphere->SetCenter(0,0,0); sphere->SetCenter(0,0,0);
...@@ -46,7 +98,7 @@ int TestStaticCellLinks( int, char *[] ) ...@@ -46,7 +98,7 @@ int TestStaticCellLinks( int, char *[] )
extract->SetImplicitFunction(sphere); extract->SetImplicitFunction(sphere);
extract->Update(); extract->Update();
// Grab the output // Grab the output, build links on unstructured grid
vtkSmartPointer<vtkUnstructuredGrid> ugrid = vtkSmartPointer<vtkUnstructuredGrid> ugrid =
vtkSmartPointer<vtkUnstructuredGrid>::New(); vtkSmartPointer<vtkUnstructuredGrid>::New();
ugrid = extract->GetOutput(); ugrid = extract->GetOutput();
...@@ -56,7 +108,7 @@ int TestStaticCellLinks( int, char *[] ) ...@@ -56,7 +108,7 @@ int TestStaticCellLinks( int, char *[] )
int numCells = slinks.GetNumberOfCells(0); int numCells = slinks.GetNumberOfCells(0);
const int *cells = slinks.GetCells(0); const int *cells = slinks.GetCells(0);
cout << "Unstructured Grid:\n"; cout << "\nUnstructured Grid:\n";
cout << " Lower Left corner (numCells, cells): " << numCells << " ("; cout << " Lower Left corner (numCells, cells): " << numCells << " (";
for (int i=0; i<numCells; ++i) for (int i=0; i<numCells; ++i)
{ {
...@@ -97,7 +149,8 @@ int TestStaticCellLinks( int, char *[] ) ...@@ -97,7 +149,8 @@ int TestStaticCellLinks( int, char *[] )
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// Okay now create a polydata //----------------------------------------------------------------------------
// Polydata
vtkSmartPointer<vtkSphereSource> ss = vtkSmartPointer<vtkSphereSource> ss =
vtkSmartPointer<vtkSphereSource>::New(); vtkSmartPointer<vtkSphereSource>::New();
ss->SetThetaResolution(12); ss->SetThetaResolution(12);
......
...@@ -32,10 +32,10 @@ ...@@ -32,10 +32,10 @@
#include "vtkCommonDataModelModule.h" // For export macro #include "vtkCommonDataModelModule.h" // For export macro
#include "vtkObject.h" #include "vtkObject.h"
class vtkPolyData; class vtkDataSet;
class vtkUnstructuredGrid;
class vtkCellArray; class vtkCellArray;
class VTKCOMMONDATAMODEL_EXPORT vtkAbstractCellLinks : public vtkObject class VTKCOMMONDATAMODEL_EXPORT vtkAbstractCellLinks : public vtkObject
{ {
public: public:
......
...@@ -25,12 +25,14 @@ vtkStandardNewMacro(vtkStaticCellLinks); ...@@ -25,12 +25,14 @@ vtkStandardNewMacro(vtkStaticCellLinks);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
vtkStaticCellLinks::vtkStaticCellLinks() vtkStaticCellLinks::vtkStaticCellLinks()
{ {
this->Impl = new vtkStaticCellLinksTemplate<vtkIdType>;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
vtkStaticCellLinks::~vtkStaticCellLinks() vtkStaticCellLinks::~vtkStaticCellLinks()
{ {
delete this->Impl;
} }
...@@ -38,12 +40,7 @@ vtkStaticCellLinks::~vtkStaticCellLinks() ...@@ -38,12 +40,7 @@ vtkStaticCellLinks::~vtkStaticCellLinks()
// Build the link list array. // Build the link list array.
void vtkStaticCellLinks::BuildLinks(vtkDataSet *data) void vtkStaticCellLinks::BuildLinks(vtkDataSet *data)
{ {
} this->Impl->BuildLinks(data);
//----------------------------------------------------------------------------
// Build the link list array.
void vtkStaticCellLinks::BuildLinks(vtkDataSet *data, vtkCellArray *Connectivity)
{
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
......
...@@ -65,24 +65,25 @@ public: ...@@ -65,24 +65,25 @@ public:
// Description: // Description:
// Get the number of cells using the point specified by ptId. // Get the number of cells using the point specified by ptId.
vtkIdType GetNumberOfCells(vtkIdType ptId) vtkIdType GetNumberOfCells(vtkIdType ptId)
{ return 0;} {return this->Impl->GetNumberOfCells(ptId);}
// Description: // Description:
// Get the number of cells using the point specified by ptId. This is an // Get the number of cells using the point specified by ptId. This is an
// alias for GetNumberOfCells(); consistent with the vtkCellLinks API. // alias for GetNumberOfCells(); consistent with the vtkCellLinks API.
unsigned short GetNcells(vtkIdType ptId) unsigned short GetNcells(vtkIdType ptId)
{ return static_cast<unsigned short>(this->GetNumberOfCells()); } { return static_cast<unsigned short>(this->GetNumberOfCells(ptId)); }
// Description: // Description:
// Return a list of cell ids using the specified point. // Return a list of cell ids using the specified point.
vtkIdType *GetCells(vtkIdType ptId) const vtkIdType *GetCells(vtkIdType ptId)
{return NULL;} {return this->Impl->GetCells(ptId);}
protected: protected:
vtkStaticCellLinks(); vtkStaticCellLinks();
~vtkStaticCellLinks(); ~vtkStaticCellLinks();
vtkStaticCellLinksTemplate<vtkIdType> *Impl;
private: private:
vtkStaticCellLinks(const vtkStaticCellLinks&); // Not implemented. vtkStaticCellLinks(const vtkStaticCellLinks&); // Not implemented.
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkStaticCellLinks.cxx
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.
=========================================================================*/
#include "vtkStaticCellLinks.h"
#ifndef vtkStaticCellLinks_txx
#define vtkStaticCellLinks_txx
#include "vtkCellArray.h"
#include "vtkIdTypeArray.h"
#include "vtkPolyData.h"
#include "vtkUnstructuredGrid.h"
//----------------------------------------------------------------------------
// Build the link list array for unstructured grids
template <typename TIds> void vtkStaticCellLinks<TIds>::
BuildLinks(vtkUnstructuredGrid *ugrid)
{
// Basic information about the grid
this->NumCells = ugrid->GetNumberOfCells();
this->NumPts = ugrid->GetNumberOfPoints();
// We're going to get into the guts of the class
vtkCellArray *cellArray = ugrid->GetCells();
const vtkIdType *cells = cellArray->GetPointer();
// I love this trick: the size of the Links array is equal to
// the size of the cell array, minus the number of cells.
this->LinksSize =
cellArray->GetNumberOfConnectivityEntries() - this->NumCells;
// Extra one allocated to simplify later pointer manipulation
this->Links = new TIds[this->LinksSize+1];
this->Links[this->LinksSize] = this->NumPts;
this->Offsets = new TIds[this->NumPts+1];
std::fill_n(this->Offsets, this->NumPts, 0);
// Now create the links.
vtkIdType npts, cellId, ptId;
const vtkIdType *cell=cells;
int i;
// Count number of point uses
for ( cellId=0; cellId < this->NumCells; ++cellId )
{
npts = *cell++;
for (i=0; i<npts; ++i)
{
this->Offsets[*cell++]++;
}
}
// Perform prefix sum
for ( ptId=0; ptId < this->NumPts; ++ptId )
{
npts = this->Offsets[ptId+1];
this->Offsets[ptId+1] = this->Offsets[ptId] + npts;
}
// Now build the links. The summation from the prefix sum indicates where
// the cells are to be inserted. Each time a cell is inserted, the offset
// is decremented. In the end, the offset array is also constructed as it
// points to the beginning of each cell run.
for ( cell=cells, cellId=0; cellId < this->NumCells; ++cellId )
{
npts = *cell++;
for (i=0; i<npts; ++i)
{
this->Offsets[*cell]--;
this->Links[this->Offsets[*cell++]] = cellId;
}
}
this->Offsets[this->NumPts] = this->LinksSize;
}
//----------------------------------------------------------------------------
// Build the link list array for poly data. This is more complex because there
// are potentially fout different cell arrays to contend with.
template <typename TIds> void vtkStaticCellLinks<TIds>::
BuildLinks(vtkPolyData *pd)
{
// Basic information about the grid
this->NumCells = pd->GetNumberOfCells();
this->NumPts = pd->GetNumberOfPoints();
vtkCellArray *cellArrays[4];
vtkIdType numCells[4];
vtkIdType sizes[4];
int i, j;
cellArrays[0] = pd->GetVerts();
cellArrays[1] = pd->GetLines();
cellArrays[2] = pd->GetPolys();
cellArrays[3] = pd->GetStrips();
for (i=0; i<4; ++i)
{
if ( cellArrays[i] != NULL )
{
numCells[i] = cellArrays[i]->GetNumberOfCells();
sizes[i] = cellArrays[i]->GetNumberOfConnectivityEntries() - numCells[i];
}
else
{
numCells[i] = 0;
sizes[i] = 0;
}
}//for the four polydata arrays
// Allocate
this->LinksSize = sizes[0] + sizes[1] + sizes[2] + sizes[3];
this->Links = new TIds[this->LinksSize+1];
this->Links[this->LinksSize] = this->NumPts;
this->Offsets = new TIds[this->NumPts+1];
this->Offsets[this->NumPts] = this->LinksSize;
std::fill_n(this->Offsets, this->NumPts, 0);
// Now create the links.
vtkIdType npts, cellId, CellId, ptId;
const vtkIdType *cell;
// Visit the four arrays
for ( CellId=0, j=0; j < 4; ++j )
{
// Count number of point uses
cell = cellArrays[j]->GetPointer();
for ( cellId=0; cellId < numCells[j]; ++cellId )
{
npts = *cell++;
for (i=0; i<npts; ++i)
{
this->Offsets[CellId+(*cell++)]++;
}
}
CellId += numCells[j];
} //for each of the four polydata cell arrays
// Perform prefix sum
for ( ptId=0; ptId < this->NumPts; ++ptId )
{
npts = this->Offsets[ptId+1];
this->Offsets[ptId+1] = this->Offsets[ptId] + npts;
}
// Now build the links. The summation from the prefix sum indicates where
// the cells are to be inserted. Each time a cell is inserted, the offset
// is decremented. In the end, the offset array is also constructed as it
// points to the beginning of each cell run.
for ( CellId=0, j=0; j < 4; ++j )
{
cell = cellArrays[j]->GetPointer();
for ( cellId=0; cellId < numCells[j]; ++cellId )
{
npts = *cell++;
for (i=0; i<npts; ++i)
{
this->Offsets[*cell]--;
this->Links[this->Offsets[*cell++]] = CellId+cellId;
}
}
CellId += numCells[j];
}//for each of the four polydata arrays
this->Offsets[this->NumPts] = this->LinksSize;
}
#endif
...@@ -50,7 +50,7 @@ class vtkCellArray; ...@@ -50,7 +50,7 @@ class vtkCellArray;
template <typename TIds> template <typename TIds>
class vtkStaticCellLinksTemplate : vtkAbstractCellLinks class vtkStaticCellLinksTemplate : public vtkAbstractCellLinks
{ {
public: public:
// Description: // Description:
......
...@@ -39,46 +39,57 @@ BuildLinks(vtkDataSet *ds) ...@@ -39,46 +39,57 @@ BuildLinks(vtkDataSet *ds)
return this->BuildLinks(static_cast<vtkUnstructuredGrid*>(ds)); return this->BuildLinks(static_cast<vtkUnstructuredGrid*>(ds));
} }
// Any other type of dataset. Generally this is not called as there are // Any other type of dataset. Generally this is not called as datasets have
// more efficient ways of getting similar information. // their own, more efficient ways of getting similar information.
this->NumCells = ds->GetNumberOfCells(); this->NumCells = ds->GetNumberOfCells();
this->NumPts = ds->GetNumberOfPoints(); this->NumPts = ds->GetNumberOfPoints();
vtkIdType numberOfPoints, ptId; vtkIdType npts, ptId;
vtkGenericCell *cell=vtkGenericCell::New();
vtkIdType cellId, j; vtkIdType cellId, j;
vtkIdList *cellPts = vtkIdList::New();
// traverse data to determine number of uses of each point // Traverse data to determine number of uses of each point. Also count the
for (cellId=0; cellId < numCells; cellId++) // number of links to allocate.
this->Offsets = new TIds[this->NumPts+1];
std::fill_n(this->Offsets, this->NumPts, 0);
for (this->LinksSize=0, cellId=0; cellId < this->NumCells; cellId++)
{ {
data->GetCell(cellId,cell); ds->GetCellPoints(cellId,cellPts);
numberOfPoints = cell->GetNumberOfPoints(); npts = cellPts->GetNumberOfIds();
for (j=0; j < numberOfPoints; j++) for (j=0; j < npts; j++)
{ {
this->IncrementLinkCount(cell->PointIds->GetId(j)); this->Offsets[cellPts->GetId(j)]++;
this->LinksSize++;
} }
} }
// now allocate storage for the links // Allocate space for links. Perform prefix sum.
this->AllocateLinks(numPts); this->Links = new TIds[this->LinksSize+1];
this->MaxId = numPts - 1; this->Links[this->LinksSize] = this->NumPts;
for ( ptId=0; ptId < this->NumPts; ++ptId )
{
npts = this->Offsets[ptId+1];
this->Offsets[ptId+1] = this->Offsets[ptId] + npts;
}
for (cellId=0; cellId < numCells; cellId++) // Now build the links. The summation from the prefix sum indicates where
// the cells are to be inserted. Each time a cell is inserted, the offset
// is decremented. In the end, the offset array is also constructed as it
// points to the beginning of each cell run.
for ( cellId=0; cellId < this->NumCells; ++cellId )
{ {
data->GetCell(cellId,cell); ds->GetCellPoints(cellId,cellPts);
numberOfPoints = cell->GetNumberOfPoints(); npts = cellPts->GetNumberOfIds();
for (j=0; j < numberOfPoints; j++) for (j=0; j<npts; ++j)
{ {
ptId = cell->PointIds->GetId(j); ptId = cellPts->GetId(j);
this->InsertCellReference(ptId, (linkLoc[ptId])++, cellId); this->Offsets[ptId]--;
this->Links[this->Offsets[ptId]] = cellId;
} }
} }
cell->Delete(); this->Offsets[this->NumPts] = this->LinksSize;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment