Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

594 lines
13 KiB

2 years ago
/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkEdgeTable.cxx,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.
=========================================================================*/
#include "vtkEdgeTable.h"
#include "vtkPoints.h"
#include "vtkIdList.h"
#include "vtkVoidArray.h"
#include "vtkObjectFactory.h"
vtkCxxRevisionMacro(vtkEdgeTable, "$Revision: 1.39 $");
vtkStandardNewMacro(vtkEdgeTable);
// Instantiate object based on maximum point id.
vtkEdgeTable::vtkEdgeTable()
{
this->Table = NULL;
this->Attributes = NULL;
this->PointerAttributes = NULL;
this->Points = NULL;
this->TableMaxId = -1;
this->TableSize = 0;
this->Position[0] = 0;
this->Position[1] = -1;
this->NumberOfEdges = 0;
}
// Free memory and return to instantiated state.
void vtkEdgeTable::Initialize()
{
vtkIdType i;
if ( this->Table )
{
for (i=0; i < this->TableSize; i++)
{
if ( this->Table[i] )
{
this->Table[i]->Delete();
}
}
delete [] this->Table;
this->Table = NULL;
this->TableMaxId = -1;
if ( this->StoreAttributes == 1 )
{
for (i=0; i < this->TableSize; i++)
{
if ( this->Attributes[i] )
{
this->Attributes[i]->Delete();
}
}
delete [] this->Attributes;
this->Attributes = NULL;
}
else if ( this->StoreAttributes == 2 )
{
for (i=0; i < this->TableSize; i++)
{
if ( this->PointerAttributes[i] )
{
this->PointerAttributes[i]->Delete();
}
}
delete [] this->PointerAttributes;
this->PointerAttributes = NULL;
}
}//if table defined
if ( this->Points )
{
this->Points->Delete();
this->Points = NULL;
}
this->TableSize = 0;
this->NumberOfEdges = 0;
}
// Free memory and return to instantiated state.
void vtkEdgeTable::Reset()
{
vtkIdType i;
if ( this->Table )
{
for (i=0; i < this->TableSize; i++)
{
if ( this->Table[i] )
{
this->Table[i]->Reset();
}
}
if ( this->StoreAttributes == 1 && this->Attributes )
{
for (i=0; i < this->TableSize; i++)
{
if ( this->Attributes[i] )
{
this->Attributes[i]->Reset();
}
}
}
else if ( this->StoreAttributes == 2 && this->PointerAttributes )
{
for (i=0; i < this->TableSize; i++)
{
if ( this->PointerAttributes[i] )
{
this->PointerAttributes[i]->Reset();
}
}
}
}//if table defined
this->TableMaxId = -1;
if ( this->Points )
{
this->Points->Reset();
}
this->NumberOfEdges = 0;
}
vtkEdgeTable::~vtkEdgeTable()
{
this->Initialize();
}
int vtkEdgeTable::InitEdgeInsertion(vtkIdType numPoints, int storeAttributes)
{
vtkIdType i;
numPoints = (numPoints < 1 ? 1 : numPoints);
// Discard old memory if not enough has been previously allocated
this->StoreAttributes = storeAttributes;
this->TableMaxId = -1;
if ( numPoints > this->TableSize )
{
this->Initialize();
this->Table = new vtkIdList *[numPoints];
for (i=0; i < numPoints; i++)
{
this->Table[i] = NULL;
}
if (this->StoreAttributes == 1)
{
this->Attributes = new vtkIdList *[numPoints];
for (i=0; i < numPoints; i++)
{
this->Attributes[i] = NULL;
}
}
else if (this->StoreAttributes == 2)
{
this->PointerAttributes = new vtkVoidArray *[numPoints];
for (i=0; i < numPoints; i++)
{
this->PointerAttributes[i] = NULL;
}
}
this->TableSize = numPoints;
}
// Otherwise, reuse the old memory
else
{
this->Reset();
}
this->Position[0] = 0;
this->Position[1] = -1;
this->NumberOfEdges = 0;
return 1;
}
// Return non-negative if edge (p1,p2) is an edge; otherwise -1.
vtkIdType vtkEdgeTable::IsEdge(vtkIdType p1, vtkIdType p2)
{
vtkIdType index, search;
if ( p1 < p2 )
{
index = p1;
search = p2;
}
else
{
index = p2;
search = p1;
}
if ( this->Table[index] == NULL )
{
return (-1);
}
else
{
vtkIdType loc;
if ( (loc=this->Table[index]->IsId(search)) == (-1) )
{
return (-1);
}
else
{
if ( this->StoreAttributes == 1 )
{
return this->Attributes[index]->GetId(loc);
}
else
{
return 1;
}
}
}
}
// Return non-negative if edge (p1,p2) is an edge; otherwise -1.
void vtkEdgeTable::IsEdge(vtkIdType p1, vtkIdType p2, void* &ptr)
{
vtkIdType index, search;
if ( p1 < p2 )
{
index = p1;
search = p2;
}
else
{
index = p2;
search = p1;
}
if ( this->Table[index] == NULL )
{
ptr = NULL;
}
else
{
vtkIdType loc;
if ( (loc=this->Table[index]->IsId(search)) == (-1) )
{
ptr = NULL;
}
else
{
if ( this->StoreAttributes == 2 )
{
ptr = this->PointerAttributes[index]->GetVoidPointer(loc);
}
else
{
ptr = NULL;
}
}
}
}
// Insert the edge (p1,p2) into the table. It is the user's responsibility to
// check if the edge has already been inserted.
vtkIdType vtkEdgeTable::InsertEdge(vtkIdType p1, vtkIdType p2)
{
vtkIdType index, search;
if ( p1 < p2 )
{
index = p1;
search = p2;
}
else
{
index = p2;
search = p1;
}
if ( index >= this->TableSize )
{
this->Resize(index+1);
}
if ( index > this->TableMaxId )
{
this->TableMaxId = index;
}
if ( this->Table[index] == NULL )
{
this->Table[index] = vtkIdList::New();
this->Table[index]->Allocate(6,12);
if ( this->StoreAttributes == 1 )
{
if ( this->Attributes[index] )
{
this->Attributes[index]->Delete();
}
this->Attributes[index] = vtkIdList::New();
this->Attributes[index]->Allocate(6,12);
}
}
this->Table[index]->InsertNextId(search);
if ( this->StoreAttributes == 1 )
{
this->Attributes[index]->InsertNextId(this->NumberOfEdges);
}
this->NumberOfEdges++;
return (this->NumberOfEdges - 1);
}
void vtkEdgeTable::InsertEdge(vtkIdType p1, vtkIdType p2,
vtkIdType attributeId)
{
vtkIdType index, search;
if ( p1 < p2 )
{
index = p1;
search = p2;
}
else
{
index = p2;
search = p1;
}
if ( index >= this->TableSize )
{
this->Resize(index+1);
}
if ( index > this->TableMaxId )
{
this->TableMaxId = index;
}
if ( this->Table[index] == NULL )
{
this->Table[index] = vtkIdList::New();
this->Table[index]->Allocate(6,12);
if ( this->StoreAttributes == 1 )
{
this->Attributes[index] = vtkIdList::New();
this->Attributes[index]->Allocate(6,12);
}
}
this->NumberOfEdges++;
this->Table[index]->InsertNextId(search);
if ( this->StoreAttributes )
{
this->Attributes[index]->InsertNextId(attributeId);
}
}
void vtkEdgeTable::InsertEdge(vtkIdType p1, vtkIdType p2, void* ptr)
{
vtkIdType index, search;
if ( p1 < p2 )
{
index = p1;
search = p2;
}
else
{
index = p2;
search = p1;
}
if ( index >= this->TableSize )
{
this->Resize(index+1);
}
if ( index > this->TableMaxId )
{
this->TableMaxId = index;
}
if ( this->Table[index] == NULL )
{
this->Table[index] = vtkIdList::New();
this->Table[index]->Allocate(6,12);
if ( this->StoreAttributes == 2 )
{
this->PointerAttributes[index] = vtkVoidArray::New();
this->PointerAttributes[index]->Allocate(6,12);
}
}
this->NumberOfEdges++;
this->Table[index]->InsertNextId(search);
if ( this->StoreAttributes == 2 )
{
this->PointerAttributes[index]->InsertNextVoidPointer(ptr);
}
}
// Intialize traversal of edges in table.
void vtkEdgeTable::InitTraversal()
{
this->Position[0] = 0;
this->Position[1] = -1;
}
// Traverse list of edges in table. Return the edge as (p1,p2), where p1 and
// p2 are point id's. Method return value is <0 if the list is exhausted;
// otherwise a valid id >=0. The value of p1 is guaranteed to be <= p2. The
// return value is an id that can be used for accessing attributes.
vtkIdType vtkEdgeTable::GetNextEdge(vtkIdType &p1, vtkIdType &p2)
{
for ( ; this->Position[0] <= this->TableMaxId;
this->Position[0]++, this->Position[1]=(-1) )
{
if ( this->Table[this->Position[0]] != NULL &&
++this->Position[1] < this->Table[this->Position[0]]->GetNumberOfIds() )
{
p1 = this->Position[0];
p2 = this->Table[this->Position[0]]->GetId(this->Position[1]);
if ( this->StoreAttributes == 1 )
{
return this->Attributes[this->Position[0]]->GetId(this->Position[1]);
}
else
{
return (-1);
}
}
}
return (-1);
}
// Traverse list of edges in table. Return the edge as (p1,p2), where p1 and
// p2 are point id's. The value of p1 is guaranteed to be <= p2. The
// return value is either 1 for success or 0 if the list is exhausted.
int vtkEdgeTable::GetNextEdge(vtkIdType &p1, vtkIdType &p2, void* &ptr)
{
for ( ; this->Position[0] <= this->TableMaxId;
this->Position[0]++, this->Position[1]=(-1) )
{
if ( this->Table[this->Position[0]] != NULL &&
++this->Position[1] < this->Table[this->Position[0]]->GetNumberOfIds() )
{
p1 = this->Position[0];
p2 = this->Table[this->Position[0]]->GetId(this->Position[1]);
if ( this->StoreAttributes == 2 )
{
this->IsEdge(p1, p2, ptr);
}
else
{
ptr = NULL;
}
return 1;
}
}
return 0;
}
vtkIdList **vtkEdgeTable::Resize(vtkIdType sz)
{
vtkIdList **newTableArray;
vtkIdList **newAttributeArray;
vtkVoidArray **newPointerAttributeArray;
vtkIdType newSize, i;
vtkIdType extend=this->TableSize/2 + 1;
if (sz >= this->TableSize)
{
newSize = this->TableSize +
extend*(((sz-this->TableSize)/extend)+1);
}
else
{
newSize = sz;
}
sz = (sz < this->TableSize ? sz : this->TableSize);
newTableArray = new vtkIdList *[newSize];
memcpy(newTableArray, this->Table, sz * sizeof(vtkIdList *));
for (i=sz; i < newSize; i++)
{
newTableArray[i] = NULL;
}
this->TableSize = newSize;
delete [] this->Table;
this->Table = newTableArray;
if ( this->StoreAttributes == 1 )
{
newAttributeArray = new vtkIdList *[newSize];
memcpy(newAttributeArray, this->Attributes, sz * sizeof(vtkIdList *));
for (i=sz; i < newSize; i++)
{
newAttributeArray[i] = NULL;
}
if ( this->Attributes )
{
delete [] this->Attributes;
}
this->Attributes = newAttributeArray;
}
else if ( this->StoreAttributes == 2 )
{
newPointerAttributeArray = new vtkVoidArray *[newSize];
memcpy(newPointerAttributeArray, this->Attributes, sz * sizeof(vtkVoidArray *));
for (i=sz; i < newSize; i++)
{
newPointerAttributeArray[i] = NULL;
}
if ( this->PointerAttributes )
{
delete [] this->PointerAttributes;
}
this->PointerAttributes = newPointerAttributeArray;
}
return this->Table;
}
int vtkEdgeTable::InitPointInsertion(vtkPoints *newPts, vtkIdType estSize)
{
// Initialize
if ( this->Table )
{
this->Initialize();
}
if ( newPts == NULL )
{
vtkErrorMacro(<<"Must define points for point insertion");
return 0;
}
if (this->Points != NULL)
{
this->Points->Delete();
}
// Set up the edge insertion
this->InitEdgeInsertion(estSize,1);
this->Points = newPts;
this->Points->Register(this);
return 1;
}
int vtkEdgeTable::InsertUniquePoint(vtkIdType p1, vtkIdType p2, double x[3],
vtkIdType &ptId)
{
int loc = this->IsEdge(p1,p2);
if ( loc != -1 )
{
ptId = loc;
return 0;
}
else
{
ptId = this->InsertEdge(p1,p2);
this->Points->InsertPoint(ptId,x);
return 1;
}
}
void vtkEdgeTable::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "NumberOfEdges: " << this->GetNumberOfEdges() << "\n";
}