[vtkusers] vtkPointLocator, Insertion and Moving Points
Mike Jackson
imikejackson at gmail.com
Wed Jun 4 18:37:13 EDT 2008
Ended up subclassing from vtkMergePoints to add a "MovePoint" method.
which was the heart of the problem.
//----------------------------------------------------------------------
------
vtkIdType vtkMergePoints2::MovePoint(const double oldPos[3], const
double newPos[3])
{
int i, ijk0, ijk1, ijk2;
vtkIdType idx;
vtkIdList *bucket;
vtkIdType ptId, id;
id = -1;
//
// Locate bucket that point is in.
//
ijk0 = static_cast<int>(
static_cast<double> ((oldPos[0] - this->Bounds[0]) /
(this->Bounds[1] - this->Bounds[0]))
* (this->Divisions[0] - 1));
ijk1 = static_cast<int>(
static_cast<double> ((oldPos[1] - this->Bounds[2]) /
(this->Bounds[3] - this->Bounds[2]))
* (this->Divisions[1] - 1));
ijk2 = static_cast<int>(
static_cast<double> ((oldPos[2] - this->Bounds[4]) /
(this->Bounds[5] - this->Bounds[4]))
* (this->Divisions[2] - 1));
idx = ijk0 + ijk1*this->Divisions[0] +
ijk2*this->Divisions[0]*this->Divisions[1];
bucket = this->HashTable[idx];
//
// Check the list of points in that bucket.
//
int nbOfIds = bucket->GetNumberOfIds ();
// For efficiency reasons, we break the data abstraction for points
// and ids (we are assuming vtkPoints stores a vtkIdList
// is storing ints).
vtkDataArray *dataArray = this->Points->GetData();
vtkIdType *idArray = bucket->GetPointer(0);
if (dataArray->GetDataType() == VTK_FLOAT)
{
float f[3];
f[0] = static_cast<float>(oldPos[0]);
f[1] = static_cast<float>(oldPos[1]);
f[2] = static_cast<float>(oldPos[2]);
vtkFloatArray *floatArray = static_cast<vtkFloatArray *>
(dataArray);
float *pt;
for (i=0; i < nbOfIds; i++)
{
ptId = idArray[i];
pt = floatArray->GetPointer(0) + 3*ptId;
if ( f[0] == pt[0] && f[1] == pt[1] && f[2] == pt[2] )
{
// point is already in the list, return 0 and set the id
parameter
id = ptId;
}
}
}
else
{
// Using the double interface
double *pt;
for (i=0; i < nbOfIds; i++)
{
ptId = idArray[i];
pt = dataArray->GetTuple(ptId);
if ( oldPos[0] == pt[0] && oldPos[1] == pt[1] && oldPos[2] ==
pt[2] )
{
// point is already in the list, return 0 and set the id
parameter
id = ptId;
}
}
}
if (id > -1)
{
bucket->DeleteId(id);
ijk0 = static_cast<int>(
static_cast<double> ((newPos[0] - this->Bounds[0]) /
(this->Bounds[1] - this->Bounds[0]))
* (this->Divisions[0] - 1));
ijk1 = static_cast<int>(
static_cast<double> ((newPos[1] - this->Bounds[2]) /
(this->Bounds[3] - this->Bounds[2]))
* (this->Divisions[1] - 1));
ijk2 = static_cast<int>(
static_cast<double> ((newPos[2] - this->Bounds[4]) /
(this->Bounds[5] - this->Bounds[4]))
* (this->Divisions[2] - 1));
idx = ijk0 + ijk1*this->Divisions[0] +
ijk2*this->Divisions[0]*this->Divisions[1];
// create a bucket point list and insert the point
bucket = vtkIdList::New();
bucket->Allocate(this->NumberOfPointsPerBucket/2,
this->NumberOfPointsPerBucket/3);
this->HashTable[idx] = bucket;
// point has to be added
bucket->InsertNextId(id);
this->Points->SetPoint(id, newPos);
}
return id;
}
--
Mike Jackson Senior Research Engineer
Innovative Management & Technology Services
On Jun 4, 2008, at 4:27 PM, Karthik Krishnan wrote:
> On Wed, Jun 4, 2008 at 7:24 PM, Mike Jackson
> <imikejackson at gmail.com> wrote:
>
>> while point0 is set to the _exact_ same values will actually
>> insert a whole
>> NEW point with a new PointID. Digging through the source I see
>> some uses of
>> Hashtables and such (which I will pretend to understand). After
>> debugging
>> this most of the afternoon I am coming to the conclusion (probably
>> and
>> obvious conclusion) that I need to "rehash" the vtkPointLocator
>> instance. I
>> looked through the docs but I don't really see anything that might
>> do that?
>> What would be the preferred way to solve this issue? Or am I
>> completely off
>> on how to do what I am doing?
>
> BuildLocator() does that for you.
>
> --
> karthik
More information about the vtkusers
mailing list