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
vtkSmoothErrorMetric.cxx
vtkSphere.cxx
vtkSpline.cxx
vtkStaticCellLinks.txx
vtkStaticCellLinks.cxx
vtkStaticCellLinksTemplate.txx
vtkStaticPointLocator.cxx
......
......@@ -12,6 +12,7 @@
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkStaticCellLinks.h"
#include "vtkStaticCellLinksTemplate.h"
#include "vtkSmartPointer.h"
#include "vtkImageData.h"
......@@ -28,12 +29,63 @@ int TestStaticCellLinks( int, char *[] )
{
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>::New();
volume->SetDimensions(dataDim,dataDim,dataDim);
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>::New();
sphere->SetCenter(0,0,0);
......@@ -46,7 +98,7 @@ int TestStaticCellLinks( int, char *[] )
extract->SetImplicitFunction(sphere);
extract->Update();
// Grab the output
// Grab the output, build links on unstructured grid
vtkSmartPointer<vtkUnstructuredGrid> ugrid =
vtkSmartPointer<vtkUnstructuredGrid>::New();
ugrid = extract->GetOutput();
......@@ -56,7 +108,7 @@ int TestStaticCellLinks( int, char *[] )
int numCells = slinks.GetNumberOfCells(0);
const int *cells = slinks.GetCells(0);
cout << "Unstructured Grid:\n";
cout << "\nUnstructured Grid:\n";
cout << " Lower Left corner (numCells, cells): " << numCells << " (";
for (int i=0; i<numCells; ++i)
{
......@@ -97,7 +149,8 @@ int TestStaticCellLinks( int, char *[] )
return EXIT_FAILURE;
}
// Okay now create a polydata
//----------------------------------------------------------------------------
// Polydata
vtkSmartPointer<vtkSphereSource> ss =
vtkSmartPointer<vtkSphereSource>::New();
ss->SetThetaResolution(12);
......
......@@ -32,10 +32,10 @@
#include "vtkCommonDataModelModule.h" // For export macro
#include "vtkObject.h"
class vtkPolyData;
class vtkUnstructuredGrid;
class vtkDataSet;
class vtkCellArray;
class VTKCOMMONDATAMODEL_EXPORT vtkAbstractCellLinks : public vtkObject
{
public:
......
......@@ -25,12 +25,14 @@ vtkStandardNewMacro(vtkStaticCellLinks);
//----------------------------------------------------------------------------
vtkStaticCellLinks::vtkStaticCellLinks()
{
this->Impl = new vtkStaticCellLinksTemplate<vtkIdType>;
}
//----------------------------------------------------------------------------
vtkStaticCellLinks::~vtkStaticCellLinks()
{
delete this->Impl;
}
......@@ -38,12 +40,7 @@ vtkStaticCellLinks::~vtkStaticCellLinks()
// Build the link list array.
void vtkStaticCellLinks::BuildLinks(vtkDataSet *data)
{
}
//----------------------------------------------------------------------------
// Build the link list array.
void vtkStaticCellLinks::BuildLinks(vtkDataSet *data, vtkCellArray *Connectivity)
{
this->Impl->BuildLinks(data);
}
//----------------------------------------------------------------------------
......
......@@ -65,24 +65,25 @@ public:
// Description:
// Get the number of cells using the point specified by ptId.
vtkIdType GetNumberOfCells(vtkIdType ptId)
{ return 0;}
{return this->Impl->GetNumberOfCells(ptId);}
// Description:
// Get the number of cells using the point specified by ptId. This is an
// alias for GetNumberOfCells(); consistent with the vtkCellLinks API.
unsigned short GetNcells(vtkIdType ptId)
{ return static_cast<unsigned short>(this->GetNumberOfCells()); }
{ return static_cast<unsigned short>(this->GetNumberOfCells(ptId)); }
// Description:
// Return a list of cell ids using the specified point.
vtkIdType *GetCells(vtkIdType ptId)
{return NULL;}
const vtkIdType *GetCells(vtkIdType ptId)
{return this->Impl->GetCells(ptId);}
protected:
vtkStaticCellLinks();
~vtkStaticCellLinks();
vtkStaticCellLinksTemplate<vtkIdType> *Impl;
private:
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;
template <typename TIds>
class vtkStaticCellLinksTemplate : vtkAbstractCellLinks
class vtkStaticCellLinksTemplate : public vtkAbstractCellLinks
{
public:
// Description:
......
......@@ -39,46 +39,57 @@ BuildLinks(vtkDataSet *ds)
return this->BuildLinks(static_cast<vtkUnstructuredGrid*>(ds));
}
// Any other type of dataset. Generally this is not called as there are
// more efficient ways of getting similar information.
// Any other type of dataset. Generally this is not called as datasets have
// their own, more efficient ways of getting similar information.
this->NumCells = ds->GetNumberOfCells();
this->NumPts = ds->GetNumberOfPoints();
vtkIdType numberOfPoints, ptId;
vtkGenericCell *cell=vtkGenericCell::New();
vtkIdType npts, ptId;
vtkIdType cellId, j;
vtkIdList *cellPts = vtkIdList::New();
// traverse data to determine number of uses of each point
for (cellId=0; cellId < numCells; cellId++)
// Traverse data to determine number of uses of each point. Also count the
// 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);
numberOfPoints = cell->GetNumberOfPoints();
for (j=0; j < numberOfPoints; j++)
ds->GetCellPoints(cellId,cellPts);
npts = cellPts->GetNumberOfIds();
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
this->AllocateLinks(numPts);
this->MaxId = numPts - 1;
// Allocate space for links. Perform prefix sum.
this->Links = new TIds[this->LinksSize+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);
numberOfPoints = cell->GetNumberOfPoints();
for (j=0; j < numberOfPoints; j++)
ds->GetCellPoints(cellId,cellPts);
npts = cellPts->GetNumberOfIds();
for (j=0; j<npts; ++j)
{
ptId = cell->PointIds->GetId(j);
this->InsertCellReference(ptId, (linkLoc[ptId])++, cellId);
ptId = cellPts->GetId(j);
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