Commit 7e026bd3 authored by Will Schroeder's avatar Will Schroeder
Browse files

ENH: Added additional topological operators.

parent 25b0cedd
/*=========================================================================
Program: Visualization Library
Module: CellArr.hh
Language: C++
Date: $Date$
Version: $Revision$
Description:
---------------------------------------------------------------------------
This file is part of the Visualization Library. No part of this file
or its contents may be copied, reproduced or altered in any way
without the express written consent of the authors.
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994
=========================================================================*/
//
// Define cell array
//
......@@ -16,6 +33,7 @@ public:
vlCellArray (const int sz, const int ext=1000):NumberOfCells(0),Location(0),Ia(sz,ext){};
vlCellArray(const vlCellArray& ca);
~vlCellArray() {};
char *GetClassName() {return "vlCellArray";};
int GetNumberOfCells() {return this->NumberOfCells;};
......
......@@ -35,29 +35,50 @@ public:
char *GetClassName() {return "vlDataSet";};
void PrintSelf(ostream& os, vlIndent indent);
// Instantiate appropriate mapper object for this dataset
virtual vlMapper *MakeMapper() = 0;
// restore data to initial state (i.e., release memory, etc.)
virtual void Initialize();
// absorb update methods which propagate through network
virtual void Update() {};
// Create concrete instance of this dataset
virtual vlDataSet *MakeObject() = 0;
virtual int GetNumberOfCells() = 0;
// Determine number of points and cells composing dataset
virtual int GetNumberOfPoints() = 0;
virtual int GetNumberOfCells() = 0;
// Get point or cell of id 0<=cellId<NumberOfPoints/Cells
virtual float *GetPoint(int ptId) = 0;
virtual vlCell *GetCell(int cellId) = 0;
virtual vlMapper *MakeMapper() = 0;
virtual void Initialize();
virtual void Update() {};
// topological inquiries to get neighbors and cells that use a point
virtual void GetPointCells(int ptId, vlIdList *cellIds) = 0;
virtual void GetCellNeighbors(int cellId, vlIdList *ptIds,
vlIdList *cellIds);
// Locate cell based on global coordinate and tolerance.
// Returns cellId >= 0 if inside, < 0 otherwise.
virtual int FindCell(float x[3], float dist2) = 0;
// some data sets are composite objects and need to check each part for MTime
unsigned long int GetMTime();
// compute geometric bounds, center, longest side
virtual void ComputeBounds();
float *GetBounds();
float *GetCenter();
float GetLength();
// return pointer to this dataset's point data
vlPointData *GetPointData() {return &this->PointData;};
protected:
vlPointData PointData; // Scalars, vectors, etc. associated w/ each point
vlTimeStamp ComputeTime; // Time at which bounds, center, etc. computed
float Bounds[6];
vlMapper *Mapper;
float Bounds[6]; // (xmin,xmax, ymin,ymax, zmin,zmax) geometric bounds
vlMapper *Mapper; // object used to map data to graphics
};
#endif
......
......@@ -16,8 +16,8 @@ public:
void SetId(const int i, const int id) {this->Ia[i]=id;};
void InsertId(const int i, const int id) {this->Ia.InsertValue(i,id);};
int InsertNextId(const int id) {return this->Ia.InsertNextValue(id);};
void operator+=(vlIdList& ids) {this->Ia += ids.Ia;};
void operator+=(const int i) {this->Ia += i;};
// void operator+=(vlIdList& ids) {this->Ia += ids.Ia;};
// void operator+=(const int i) {this->Ia += i;};
int getChunk(const int sz) { // get chunk of memory
int pos = this->Ia.GetMaxId()+1;
this->Ia.InsertValue(pos+sz-1,0);
......@@ -25,6 +25,13 @@ public:
}
void Reset() {this->Ia.Reset();};
// special set operations
void DeleteId(int Id);
void IntersectWith(vlIdList *otherIds);
int IsId(int id)
{for(int i=0; i<this->GetNumberOfIds(); i++) if(id == this->GetId(i)) return 1;
return 0;}
protected:
vlIntArray Ia;
};
......
......@@ -20,6 +20,7 @@ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994
#define __vlLinkList_h
#include "Object.hh"
class vlDataSet;
struct vlLink {
unsigned short ncells;
......@@ -29,16 +30,18 @@ struct vlLink {
class vlLinkList : public vlObject {
public:
vlLinkList():Array(0),Size(0),MaxId(-1),Extend(1000) {};
vlLinkList(const int sz, const int ext=1000);
vlLinkList(int sz, int ext=1000);
~vlLinkList();
char *GetClassName() {return "vlLinkList";};
vlLink &GetLink(const int id) {return this->Array[id];};
unsigned short GetNcells(const int id) {return this->Array[id].ncells;};
int *GetCells(const int id) {return this->Array[id].cells;};
void IncrementLinkCount(const int id) {this->Array[id].ncells++;};
vlLink &GetLink(int id) {return this->Array[id];};
unsigned short GetNcells(int id) {return this->Array[id].ncells;};
int *GetCells(int id) {return this->Array[id].cells;};
void IncrementLinkCount(int id) {this->Array[id].ncells++;};
void AllocateLinks();
void InsertCellReference(const int id, const int pos, const int cellId)
void InsertCellReference(int id, unsigned short pos, int cellId)
{this->Array[id].cells[pos] = cellId;};
void BuildLinks(vlDataSet *data);
void Squeeze();
void Reset();
......@@ -47,7 +50,7 @@ private:
int Size; // allocated size of data
int MaxId; // maximum index inserted thus far
int Extend; // grow array by this point
vlLink *Resize(const int sz); // function to resize data
vlLink *Resize(int sz); // function to resize data
};
#endif
......@@ -20,13 +20,13 @@ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994
#ifndef __vlPolyData_h
#define __vlPolyData_h
#include "DataSet.hh"
#include "PointSet.hh"
#include "FPoints.hh"
#include "CellArr.hh"
#include "CellList.hh"
#include "LinkList.hh"
class vlPolyData : public vlDataSet
class vlPolyData : public vlPointSet
{
public:
vlPolyData();
......@@ -37,18 +37,11 @@ public:
// dataset interface
vlDataSet *MakeObject();
int GetNumberOfPoints();
int GetNumberOfCells();
float *GetPoint(int ptId) {return this->Points->GetPoint(ptId);};
vlCell *GetCell(int cellId);
vlMapper *MakeMapper();
void Initialize();
void ComputeBounds();
// PolyData specific stuff follows
vlSetObjectMacro(Points,vlPoints);
vlGetObjectMacro(Points,vlPoints);
void GetPointCells(int ptId, vlIdList *cellIds);
// Can't use macros to set/get following cell arrays. This is due to tricks
// required to support traversal methods.
......@@ -101,8 +94,8 @@ public:
vlGetMacro(TriangleMesh,int);
protected:
// points inherited
// point data (i.e., scalars, vectors, normals, tcoords) inherited
vlPoints *Points;
vlCellArray *Verts;
vlCellArray *Lines;
vlCellArray *Polys;
......
......@@ -45,6 +45,7 @@ public:
int GetNumberOfCells();
int GetNumberOfPoints();
void Initialize();
void GetPointCells(int ptId, vlIdList *cellIds);
void SetDimensions(int i, int j, int k);
void SetDimensions(int dim[3]);
......
......@@ -37,6 +37,7 @@ public:
vlCell *GetCell(int cellId);
vlMapper *MakeMapper() {return (vlMapper *)0;};
void Initialize();
int FindCell(float x[3], float dist2);
vlSetVector3Macro(AspectRatio,float);
vlGetVectorMacro(AspectRatio,float);
......
......@@ -115,3 +115,21 @@ void vlDataSet::PrintSelf(ostream& os, vlIndent indent)
os << indent << "Compute Time: " <<this->ComputeTime.GetMTime() << "\n";
}
}
void vlDataSet::GetCellNeighbors(int cellId, vlIdList *ptIds,
vlIdList *cellIds)
{
int i;
static vlIdList otherCells(MAX_CELL_SIZE);
// load list with candidate cells, remove current cell
this->GetPointCells(ptIds->GetId(0),cellIds);
cellIds->DeleteId(cellId);
// now perform multiple intersections on list
for ( i=1; i < ptIds->GetNumberOfIds(); i++)
{
this->GetPointCells(ptIds->GetId(i), &otherCells);
cellIds->IntersectWith(&otherCells);
}
}
......@@ -14,13 +14,18 @@ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994
=========================================================================*/
#include "LinkList.hh"
#include "DataSet.hh"
vlLinkList::vlLinkList(const int sz, const int ext)
vlLinkList::vlLinkList(int sz, int ext)
{
static vlLink linkInit = {0,0};
this->Size = sz;
this->Array = new vlLink[sz];
this->Extend = ext;
this->MaxId = -1;
for (int i=0; i < sz; i++) this->Array[i] = linkInit;
}
vlLinkList::~vlLinkList()
......@@ -51,7 +56,7 @@ void vlLinkList::Reset()
//
// Private function does "reallocate"
//
vlLink *vlLinkList::Resize(const int sz)
vlLink *vlLinkList::Resize(int sz)
{
int i;
vlLink *newArray;
......@@ -76,3 +81,42 @@ vlLink *vlLinkList::Resize(const int sz)
return this->Array;
}
void vlLinkList::BuildLinks(vlDataSet *data)
{
int numPts = data->GetNumberOfPoints();
int numCells = data->GetNumberOfCells();
int i, j, ptId, cellId;
vlCell *cell;
unsigned short *linkLoc;
// traverse data to determine number of uses of each point
for (cellId=0; cellId < numCells; cellId++)
{
cell = data->GetCell(cellId);
for (j=0; j < cell->GetNumberOfPoints(); j++)
{
this->IncrementLinkCount(cell->PointIds.GetId(j));
}
}
// now allocate storage for the links
this->AllocateLinks();
// fill out lists with references to cells
linkLoc = new unsigned short[numPts];
for (i=0; i < numPts; i++) linkLoc[i] = 0;
for (cellId=0; cellId < numCells; cellId++)
{
cell = data->GetCell(cellId);
for (j=0; j < cell->GetNumberOfPoints(); j++)
{
ptId = cell->PointIds.GetId(j);
this->InsertCellReference(ptId, (linkLoc[ptId])++, cellId);
}
}
delete [] linkLoc;
}
......@@ -288,11 +288,6 @@ int vlPolyData::GetNumberOfCells()
GetNumberOfPolys() + GetNumberOfStrips();
}
int vlPolyData::GetNumberOfPoints()
{
return (this->Points ? this->Points->GetNumberOfPoints() : 0);
}
int vlPolyData::GetNumberOfVerts()
{
return (this->Verts ? this->Verts->GetNumberOfCells() : 0);
......@@ -325,25 +320,13 @@ vlMapper *vlPolyData::MakeMapper()
}
return this->Mapper;
}
void vlPolyData::ComputeBounds()
{
int i;
float *bounds;
if ( this->Points )
{
bounds = this->Points->GetBounds();
for (i=0; i<6; i++) this->Bounds[i] = bounds[i];
this->ComputeTime.Modified();
}
}
void vlPolyData::PrintSelf(ostream& os, vlIndent indent)
{
if (this->ShouldIPrint(vlPolyData::GetClassName()))
{
vlDataSet::PrintSelf(os,indent);
os << indent << "Number Of Points: " << this->GetNumberOfPoints() << "\n";
os << indent << "Number Of Vertices: " << this->GetNumberOfVerts() << "\n";
os << indent << "Number Of Lines: " << this->GetNumberOfLines() << "\n";
os << indent << "Number Of Polygons: " << this->GetNumberOfPolys() << "\n";
......@@ -545,4 +528,25 @@ void vlPolyData::BuildCells()
void vlPolyData::BuildLinks()
{
if ( ! this->Cells ) this->BuildCells();
this->Links = new vlLinkList(this->GetNumberOfPoints());
this->Links->BuildLinks(this);
}
void vlPolyData::GetPointCells(int ptId, vlIdList *cellIds)
{
int *cells;
int numCells;
int i;
if ( ! this->Links ) this->BuildLinks();
cellIds->Reset();
numCells = this->Links->GetNcells(ptId);
cells = this->Links->GetCells(ptId);
for (i=0; i < numCells; i++)
{
cellIds->InsertId(i,cells[i]);
}
}
......@@ -175,3 +175,50 @@ void vlStructuredDataSet::Initialize()
this->PointVisibility = 0;
}
}
void vlStructuredDataSet::GetPointCells(int ptId, vlIdList *cellIds)
{
int ptDim[3], cellDim[3];
int ptLoc[3], cellLoc[3];
int i, j, cellId, add;
static int offset[8][3] = {-1,0,0, -1,-1,0, -1,-1,-1, -1,0,-1,
0,0,0, 0,-1,0, 0,-1,-1, 0,0,-1};
for (i=0; i<3; i++)
{
ptDim[i] = this->Dimensions[i];
cellDim[i] = ptDim[i] - 1;
}
//
// Get the location of the point
//
ptLoc[0] = ptId % ptDim[0];
ptLoc[1] = ptId % (ptDim[0]*ptDim[1]) / ptDim[0];
ptLoc[2] = ptId / (ptDim[0]*ptDim[1]);
//
// From the point lcoation, compute the cell locations. There are at
// most eight possible.
//
cellIds->Reset();
for (j=0; j<8; j++)
{
for (add=1, i=0; i<3; i++)
{
cellLoc[i] = ptLoc[i] + offset[j][i];
if ( cellLoc[i] < 0 || cellLoc[i] >= cellDim[i] )
{
add = 0;
break;
}
}
if ( add )
{
cellId = cellLoc[0] + cellLoc[1]*cellDim[0] +
cellLoc[2]*cellDim[0]*cellDim[1];
cellIds->InsertNextId(cellId);
}
}
return;
}
......@@ -227,3 +227,30 @@ void vlStructuredPoints::Initialize()
this->SetAspectRatio(1,1,1);
this->SetOrigin(0,0,0);
}
int vlStructuredPoints::FindCell(float x[3], float tol2)
{
int i, loc[3];
float d;
//
// Compute the ijk location
//
for (i=0; i<3; i++)
{
d = x[i] - this->Origin[i];
if ( d < 0.0 || d > ((this->Dimensions[i]-1)*this->AspectRatio[i]) )
{
return -1;
}
else
{
loc[i] = d / this->AspectRatio[i];
}
}
//
// From this location get the cell number
//
return loc[2] * (this->Dimensions[0]-1)*(this->Dimensions[1]-1) +
loc[1] * (this->Dimensions[0]-1) + loc[0];
}
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