1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkMergePoints.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkMergePoints.h"
16 
17 #include "vtkDataArray.h"
18 #include "vtkIdList.h"
19 #include "vtkObjectFactory.h"
20 #include "vtkPoints.h"
21 #include "vtkFloatArray.h"
22 
23 vtkStandardNewMacro(vtkMergePoints);
24 
25 //----------------------------------------------------------------------------
26 // Determine whether point given by x[3] has been inserted into points list.
27 // Return id of previously inserted point if this is true, otherwise return
28 // -1.
IsInsertedPoint(const double x[3])29 vtkIdType vtkMergePoints::IsInsertedPoint(const double x[3])
30 {
31   //
32   //  Locate bucket that point is in.
33   //
34   vtkIdType idx = this->GetBucketIndex(x);
35 
36   vtkIdList* bucket = this->HashTable[idx];
37 
38   if ( ! bucket )
39   {
40     return -1;
41   }
42   else // see whether we've got duplicate point
43   {
44     //
45     // Check the list of points in that bucket.
46     //
47     vtkIdType ptId;
48     vtkIdType nbOfIds = bucket->GetNumberOfIds ();
49 
50     // For efficiency reasons, we break the data abstraction for points
51     // and ids (we are assuming and vtkIdList
52     // is storing ints).
53     vtkDataArray *dataArray = this->Points->GetData();
54     vtkIdType *idArray = bucket->GetPointer(0);
55     if (dataArray->GetDataType() == VTK_FLOAT)
56     {
57       float f[3];
58       f[0] = static_cast<float>(x[0]);
59       f[1] = static_cast<float>(x[1]);
60       f[2] = static_cast<float>(x[2]);
61       vtkFloatArray *floatArray = static_cast<vtkFloatArray *>(dataArray);
62       float *pt;
63       for (vtkIdType i=0; i < nbOfIds; i++)
64       {
65         ptId = idArray[i];
66         pt = floatArray->GetPointer(0) + 3*ptId;
67         if ( f[0] == pt[0] && f[1] == pt[1] && f[2] == pt[2] )
68         {
69           return ptId;
70         }
71       }
72     }
73     else
74     {
75       // Using the double interface
76       double *pt;
77       for (vtkIdType i=0; i < nbOfIds; i++)
78       {
79         ptId = idArray[i];
80         pt = dataArray->GetTuple(ptId);
81         if ( x[0] == pt[0] && x[1] == pt[1] && x[2] == pt[2] )
82         {
83           return ptId;
84         }
85       }
86     }
87   }
88 
89   return -1;
90 }
91 
92 
93 //----------------------------------------------------------------------------
InsertUniquePoint(const double x[3],vtkIdType & id)94 int vtkMergePoints::InsertUniquePoint(const double x[3], vtkIdType &id)
95 {
96   //
97   //  Locate bucket that point is in.
98   //
99   vtkIdType idx = this->GetBucketIndex(x);
100   vtkIdList* bucket = this->HashTable[idx];
101 
102   if (bucket) // see whether we've got duplicate point
103   {
104     //
105     // Check the list of points in that bucket.
106     //
107     vtkIdType ptId;
108     vtkIdType nbOfIds = bucket->GetNumberOfIds ();
109 
110     // For efficiency reasons, we break the data abstraction for points
111     // and ids (we are assuming vtkPoints stores a vtkIdList
112     // is storing ints).
113     vtkDataArray *dataArray = this->Points->GetData();
114     vtkIdType *idArray = bucket->GetPointer(0);
115 
116     if (dataArray->GetDataType() == VTK_FLOAT)
117     {
118       float f[3];
119       f[0] = static_cast<float>(x[0]);
120       f[1] = static_cast<float>(x[1]);
121       f[2] = static_cast<float>(x[2]);
122       float *floatArray = static_cast<vtkFloatArray *>(dataArray)->GetPointer(0);
123       float *pt;
124       for (vtkIdType i=0; i < nbOfIds; ++i)
125       {
126         ptId = idArray[i];
127         pt = floatArray + 3*ptId;
128         if ( f[0] == pt[0] && f[1] == pt[1] && f[2] == pt[2] )
129         {
130           // point is already in the list, return 0 and set the id parameter
131           id = ptId;
132           return 0;
133         }
134       }
135     }
136     else
137     {
138       // Using the double interface
139       double *pt;
140       for (vtkIdType i=0; i < nbOfIds; ++i)
141       {
142         ptId = idArray[i];
143         pt = dataArray->GetTuple(ptId);
144         if ( x[0] == pt[0] && x[1] == pt[1] && x[2] == pt[2] )
145         {
146           // point is already in the list, return 0 and set the id parameter
147           id = ptId;
148           return 0;
149         }
150       }
151     }
152   }
153   else
154   {
155     // create a bucket point list and insert the point
156     bucket = vtkIdList::New();
157     bucket->Allocate(this->NumberOfPointsPerBucket/2,
158                      this->NumberOfPointsPerBucket/3);
159     this->HashTable[idx] = bucket;
160   }
161 
162   // point has to be added
163   bucket->InsertNextId(this->InsertionPointId);
164   this->Points->InsertPoint(this->InsertionPointId,x);
165   id = this->InsertionPointId++;
166 
167   return 1;
168 }
169 
170 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)171 void vtkMergePoints::PrintSelf(ostream& os, vtkIndent indent)
172 {
173   this->Superclass::PrintSelf(os,indent);
174 }
175