1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkIdList.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 "vtkIdList.h"
16 #include "vtkSMPTools.h" //for parallel sort
17 #include "vtkObjectFactory.h"
18
19 vtkStandardNewMacro(vtkIdList);
20
21 //----------------------------------------------------------------------------
vtkIdList()22 vtkIdList::vtkIdList()
23 {
24 this->NumberOfIds = 0;
25 this->Size = 0;
26 this->Ids = nullptr;
27 }
28
29 //----------------------------------------------------------------------------
~vtkIdList()30 vtkIdList::~vtkIdList()
31 {
32 delete [] this->Ids;
33 }
34
35 //----------------------------------------------------------------------------
Initialize()36 void vtkIdList::Initialize()
37 {
38 delete [] this->Ids;
39 this->Ids = nullptr;
40 this->NumberOfIds = 0;
41 this->Size = 0;
42 }
43
44 //----------------------------------------------------------------------------
Allocate(const vtkIdType sz,const int vtkNotUsed (strategy))45 int vtkIdList::Allocate(const vtkIdType sz, const int vtkNotUsed(strategy))
46 {
47 if ( sz > this->Size)
48 {
49 this->Initialize();
50 this->Size = ( sz > 0 ? sz : 1);
51 if ( (this->Ids = new vtkIdType[this->Size]) == nullptr )
52 {
53 return 0;
54 }
55 }
56 this->NumberOfIds = 0;
57 return 1;
58 }
59
60 //----------------------------------------------------------------------------
SetNumberOfIds(const vtkIdType number)61 void vtkIdList::SetNumberOfIds(const vtkIdType number)
62 {
63 this->Allocate(number,0);
64 this->NumberOfIds = number;
65 }
66
67 //----------------------------------------------------------------------------
InsertUniqueId(const vtkIdType vtkid)68 vtkIdType vtkIdList::InsertUniqueId(const vtkIdType vtkid)
69 {
70 for (vtkIdType i=0; i < this->NumberOfIds; i++)
71 {
72 if ( vtkid == this->Ids[i] )
73 {
74 return i;
75 }
76 }
77
78 return this->InsertNextId(vtkid);
79 }
80
81 //----------------------------------------------------------------------------
WritePointer(const vtkIdType i,const vtkIdType number)82 vtkIdType *vtkIdList::WritePointer(const vtkIdType i, const vtkIdType number)
83 {
84 vtkIdType newSize=i+number;
85 if ( newSize > this->Size )
86 {
87 this->Resize(newSize);
88 }
89 if ( newSize > this->NumberOfIds )
90 {
91 this->NumberOfIds = newSize;
92 }
93 return this->Ids + i;
94 }
95
96 //----------------------------------------------------------------------------
SetArray(vtkIdType * array,vtkIdType size)97 void vtkIdList::SetArray(vtkIdType *array, vtkIdType size)
98 {
99 delete [] this->Ids;
100 this->Ids = array;
101 this->NumberOfIds = size;
102 this->Size = size;
103 }
104
105 //----------------------------------------------------------------------------
DeleteId(vtkIdType vtkid)106 void vtkIdList::DeleteId(vtkIdType vtkid)
107 {
108 vtkIdType i=0;
109
110 // while loop is necessary to delete all occurrences of vtkid
111 while ( i < this->NumberOfIds )
112 {
113 for ( ; i < this->NumberOfIds; i++)
114 {
115 if ( this->Ids[i] == vtkid )
116 {
117 break;
118 }
119 }
120
121 // if found; replace current id with last
122 if ( i < this->NumberOfIds )
123 {
124 this->SetId(i,this->Ids[this->NumberOfIds-1]);
125 this->NumberOfIds--;
126 }
127 }
128 }
129
130 //----------------------------------------------------------------------------
DeepCopy(vtkIdList * ids)131 void vtkIdList::DeepCopy(vtkIdList *ids)
132 {
133 this->SetNumberOfIds(ids->NumberOfIds);
134 if (ids->NumberOfIds > 0)
135 {
136 std::copy(ids->Ids, ids->Ids + ids->NumberOfIds, this->Ids);
137 }
138 this->Squeeze();
139 }
140
141 //----------------------------------------------------------------------------
Resize(const vtkIdType sz)142 vtkIdType *vtkIdList::Resize(const vtkIdType sz)
143 {
144 vtkIdType *newIds;
145 vtkIdType newSize;
146
147 if ( sz > this->Size )
148 {
149 newSize = this->Size + sz;
150 }
151 else if (sz == this->Size)
152 {
153 return this->Ids;
154 }
155 else
156 {
157 newSize = sz;
158 }
159
160 if (newSize <= 0)
161 {
162 this->Initialize();
163 return nullptr;
164 }
165
166 if ( (newIds = new vtkIdType[newSize]) == nullptr )
167 {
168 vtkErrorMacro(<< "Cannot allocate memory\n");
169 return nullptr;
170 }
171
172 if (this->NumberOfIds > newSize)
173 {
174 this->NumberOfIds = newSize;
175 }
176
177 if (this->Ids)
178 {
179 memcpy(newIds, this->Ids,
180 static_cast<size_t>(sz < this->Size ? sz : this->Size) * sizeof(vtkIdType));
181 delete [] this->Ids;
182 }
183
184 this->Size = newSize;
185 this->Ids = newIds;
186 return this->Ids;
187 }
188
189 //----------------------------------------------------------------------------
190 #define VTK_TMP_ARRAY_SIZE 500
191 // Intersect this list with another vtkIdList. Updates current list according
192 // to result of intersection operation.
IntersectWith(vtkIdList * otherIds)193 void vtkIdList::IntersectWith(vtkIdList* otherIds)
194 {
195 // Fast method due to Dr. Andreas Mueller of ISE Integrated Systems
196 // Engineering (CH).
197 vtkIdType thisNumIds = this->GetNumberOfIds();
198
199 if (thisNumIds <= VTK_TMP_ARRAY_SIZE)
200 {//Use fast method if we can fit in temporary storage
201 vtkIdType thisIds[VTK_TMP_ARRAY_SIZE];
202 vtkIdType i, vtkid;
203
204 for (i=0; i < thisNumIds; i++)
205 {
206 thisIds[i] = this->GetId(i);
207 }
208 for (this->Reset(), i=0; i < thisNumIds; i++)
209 {
210 vtkid = thisIds[i];
211 if ( otherIds->IsId(vtkid) != (-1) )
212 {
213 this->InsertNextId(vtkid);
214 }
215 }
216 }
217 else
218 {//use slower method for extreme cases
219 vtkIdType *thisIds = new vtkIdType [thisNumIds];
220 vtkIdType i, vtkid;
221
222 for (i=0; i < thisNumIds; i++)
223 {
224 *(thisIds + i) = this->GetId(i);
225 }
226 for (this->Reset(), i=0; i < thisNumIds; i++)
227 {
228 vtkid = *(thisIds + i);
229 if ( otherIds->IsId(vtkid) != (-1) )
230 {
231 this->InsertNextId(vtkid);
232 }
233 }
234 delete [] thisIds;
235 }
236 }
237 #undef VTK_TMP_ARRAY_SIZE
238
239 //----------------------------------------------------------------------------
Sort()240 void vtkIdList::Sort()
241 {
242 if ( this->Ids == nullptr || this->NumberOfIds < 2 )
243 {
244 return;
245 }
246 vtkSMPTools::Sort(this->Ids, this->Ids+this->NumberOfIds);
247 }
248
249 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)250 void vtkIdList::PrintSelf(ostream& os, vtkIndent indent)
251 {
252 this->Superclass::PrintSelf(os,indent);
253
254 os << indent << "Number of Ids: " << this->NumberOfIds << "\n";
255 }
256