[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