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