1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkDataSetAttributes.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 "vtkDataSetAttributes.h"
16
17 #include "vtkArrayDispatch.h"
18 #include "vtkArrayIteratorIncludes.h"
19 #include "vtkDataArrayRange.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkStructuredExtent.h"
22
23 #include <vector>
24
25 vtkStandardNewMacro(vtkDataSetAttributes);
26 vtkStandardExtendedNewMacro(vtkDataSetAttributes);
27 //------------------------------------------------------------------------------
28 const char vtkDataSetAttributes::AttributeNames[vtkDataSetAttributes::NUM_ATTRIBUTES][19] = {
29 "Scalars",
30 "Vectors",
31 "Normals",
32 "TCoords",
33 "Tensors",
34 "GlobalIds",
35 "PedigreeIds",
36 "EdgeFlag",
37 "Tangents",
38 "RationalWeights",
39 "HigherOrderDegrees",
40 };
41
42 const char vtkDataSetAttributes::LongAttributeNames[vtkDataSetAttributes::NUM_ATTRIBUTES][42] = {
43 "vtkDataSetAttributes::SCALARS",
44 "vtkDataSetAttributes::VECTORS",
45 "vtkDataSetAttributes::NORMALS",
46 "vtkDataSetAttributes::TCOORDS",
47 "vtkDataSetAttributes::TENSORS",
48 "vtkDataSetAttributes::GLOBALIDS",
49 "vtkDataSetAttributes::PEDIGREEIDS",
50 "vtkDataSetAttributes::EDGEFLAG",
51 "vtkDataSetAttributes::TANGENTS",
52 "vtkDataSetAttributes::RATIONALWEIGHTS",
53 "vtkDataSetAttributes::HIGHERORDERDEGREES",
54 };
55
56 //------------------------------------------------------------------------------
57 // Construct object with copying turned on for all data.
vtkDataSetAttributes()58 vtkDataSetAttributes::vtkDataSetAttributes()
59 {
60 int attributeType;
61 for (attributeType = 0; attributeType < NUM_ATTRIBUTES; attributeType++)
62 {
63 this->AttributeIndices[attributeType] = -1;
64 this->CopyAttributeFlags[COPYTUPLE][attributeType] = 1;
65 this->CopyAttributeFlags[INTERPOLATE][attributeType] = 1;
66 this->CopyAttributeFlags[PASSDATA][attributeType] = 1;
67 }
68
69 // Global IDs should not be interpolated because they are labels, not "numbers"
70 // Global IDs should not be copied either, unless doing so preserves meaning.
71 // Passing through is usually OK because it is 1:1.
72 this->CopyAttributeFlags[COPYTUPLE][GLOBALIDS] = 0;
73 this->CopyAttributeFlags[INTERPOLATE][GLOBALIDS] = 0;
74
75 // Pedigree IDs should not be interpolated because they are labels, not "numbers"
76 // Pedigree IDs may be copied since they do not require 1:1 mapping.
77 this->CopyAttributeFlags[INTERPOLATE][PEDIGREEIDS] = 0;
78
79 this->TargetIndices = nullptr;
80 }
81
82 //------------------------------------------------------------------------------
83 // Destructor for the vtkDataSetAttributes objects.
~vtkDataSetAttributes()84 vtkDataSetAttributes::~vtkDataSetAttributes()
85 {
86 this->Initialize();
87 delete[] this->TargetIndices;
88 this->TargetIndices = nullptr;
89 }
90
91 //------------------------------------------------------------------------------
92 // Turn on copying of all data.
CopyAllOn(int ctype)93 void vtkDataSetAttributes::CopyAllOn(int ctype)
94 {
95 this->vtkFieldData::CopyAllOn();
96 this->SetCopyScalars(1, ctype);
97 this->SetCopyVectors(1, ctype);
98 this->SetCopyNormals(1, ctype);
99 this->SetCopyTCoords(1, ctype);
100 this->SetCopyTensors(1, ctype);
101 this->SetCopyGlobalIds(1, ctype);
102 this->SetCopyPedigreeIds(1, ctype);
103 this->SetCopyTangents(1, ctype);
104 this->SetCopyRationalWeights(1, ctype);
105 this->SetCopyHigherOrderDegrees(1, ctype);
106 }
107
108 //------------------------------------------------------------------------------
109 // Turn off copying of all data.
CopyAllOff(int ctype)110 void vtkDataSetAttributes::CopyAllOff(int ctype)
111 {
112 this->vtkFieldData::CopyAllOff();
113 this->SetCopyScalars(0, ctype);
114 this->SetCopyVectors(0, ctype);
115 this->SetCopyNormals(0, ctype);
116 this->SetCopyTCoords(0, ctype);
117 this->SetCopyTensors(0, ctype);
118 this->SetCopyGlobalIds(0, ctype);
119 this->SetCopyPedigreeIds(0, ctype);
120 this->SetCopyTangents(0, ctype);
121 this->SetCopyRationalWeights(0, ctype);
122 this->SetCopyHigherOrderDegrees(0, ctype);
123 }
124
125 //------------------------------------------------------------------------------
126 // Deep copy of data (i.e., create new data arrays and
127 // copy from input data). Note that attribute data is
128 // not copied.
DeepCopy(vtkFieldData * fd)129 void vtkDataSetAttributes::DeepCopy(vtkFieldData* fd)
130 {
131 this->Initialize(); // free up memory
132
133 vtkDataSetAttributes* dsa = vtkDataSetAttributes::SafeDownCast(fd);
134 // If the source is a vtkDataSetAttributes
135 if (dsa)
136 {
137 int numArrays = fd->GetNumberOfArrays();
138 int attributeType, i;
139 vtkAbstractArray *data, *newData;
140
141 // Allocate space for numArrays
142 this->AllocateArrays(numArrays);
143 for (i = 0; i < numArrays; i++)
144 {
145 data = fd->GetAbstractArray(i);
146 newData = data->NewInstance(); // instantiate same type of object
147 newData->DeepCopy(data);
148 newData->SetName(data->GetName());
149 this->AddArray(newData);
150 newData->Delete();
151 }
152 // Copy the copy flags
153 for (attributeType = 0; attributeType < NUM_ATTRIBUTES; attributeType++)
154 {
155 // If an array is an attribute in the source, then mark it as a attribute
156 // in the clone as well.
157 this->AttributeIndices[attributeType] = dsa->AttributeIndices[attributeType];
158
159 this->CopyAttributeFlags[COPYTUPLE][attributeType] =
160 dsa->CopyAttributeFlags[COPYTUPLE][attributeType];
161 this->CopyAttributeFlags[INTERPOLATE][attributeType] =
162 dsa->CopyAttributeFlags[INTERPOLATE][attributeType];
163 this->CopyAttributeFlags[PASSDATA][attributeType] =
164 dsa->CopyAttributeFlags[PASSDATA][attributeType];
165 }
166 this->CopyFlags(dsa);
167 }
168 // If the source is field data, do a field data copy
169 else
170 {
171 this->vtkFieldData::DeepCopy(fd);
172 }
173 }
174
175 //------------------------------------------------------------------------------
176 // Shallow copy of data (i.e., use reference counting).
ShallowCopy(vtkFieldData * fd)177 void vtkDataSetAttributes::ShallowCopy(vtkFieldData* fd)
178 {
179 this->Initialize(); // free up memory
180
181 vtkDataSetAttributes* dsa = vtkDataSetAttributes::SafeDownCast(fd);
182 // If the source is a vtkDataSetAttributes
183 if (dsa)
184 {
185 int numArrays = fd->GetNumberOfArrays();
186 int attributeType, i;
187
188 // Allocate space for numArrays
189 this->AllocateArrays(numArrays);
190 this->NumberOfActiveArrays = 0;
191 for (i = 0; i < numArrays; i++)
192 {
193 this->NumberOfActiveArrays++;
194 this->SetArray(i, fd->GetAbstractArray(i));
195 }
196
197 // Copy the copy flags
198 for (attributeType = 0; attributeType < NUM_ATTRIBUTES; attributeType++)
199 {
200 // If an array is an attribute in the source, then mark it as a attribute
201 // in the clone as well.
202 this->AttributeIndices[attributeType] = dsa->AttributeIndices[attributeType];
203
204 this->CopyAttributeFlags[COPYTUPLE][attributeType] =
205 dsa->CopyAttributeFlags[COPYTUPLE][attributeType];
206 this->CopyAttributeFlags[INTERPOLATE][attributeType] =
207 dsa->CopyAttributeFlags[INTERPOLATE][attributeType];
208 this->CopyAttributeFlags[PASSDATA][attributeType] =
209 dsa->CopyAttributeFlags[PASSDATA][attributeType];
210 }
211 this->CopyFlags(dsa);
212 }
213 // If the source is field data, do a field data copy
214 else
215 {
216 this->vtkFieldData::ShallowCopy(fd);
217 }
218 }
219
220 //------------------------------------------------------------------------------
221 // Initialize all of the object's data to nullptr
InitializeFields()222 void vtkDataSetAttributes::InitializeFields()
223 {
224 this->vtkFieldData::InitializeFields();
225
226 int attributeType;
227 for (attributeType = 0; attributeType < NUM_ATTRIBUTES; attributeType++)
228 {
229 this->AttributeIndices[attributeType] = -1;
230 this->CopyAttributeFlags[COPYTUPLE][attributeType] = 1;
231 this->CopyAttributeFlags[INTERPOLATE][attributeType] = 1;
232 this->CopyAttributeFlags[PASSDATA][attributeType] = 1;
233 }
234 this->CopyAttributeFlags[COPYTUPLE][GLOBALIDS] = 0;
235 this->CopyAttributeFlags[INTERPOLATE][GLOBALIDS] = 0;
236
237 this->CopyAttributeFlags[INTERPOLATE][PEDIGREEIDS] = 0;
238 }
239
240 //------------------------------------------------------------------------------
241 // Initialize all of the object's data to nullptr
Initialize()242 void vtkDataSetAttributes::Initialize()
243 {
244 //
245 // We don't modify ourselves because the "ReleaseData" methods depend upon
246 // no modification when initialized.
247 //
248
249 // Call superclass' Initialize()
250 this->vtkFieldData::Initialize();
251 //
252 // Free up any memory
253 // And don't forget to reset the attribute copy flags.
254 int attributeType;
255 for (attributeType = 0; attributeType < NUM_ATTRIBUTES; attributeType++)
256 {
257 this->AttributeIndices[attributeType] = -1;
258 this->CopyAttributeFlags[COPYTUPLE][attributeType] = 1;
259 this->CopyAttributeFlags[INTERPOLATE][attributeType] = 1;
260 this->CopyAttributeFlags[PASSDATA][attributeType] = 1;
261 }
262 this->CopyAttributeFlags[COPYTUPLE][GLOBALIDS] = 0;
263 this->CopyAttributeFlags[INTERPOLATE][GLOBALIDS] = 0;
264
265 this->CopyAttributeFlags[INTERPOLATE][PEDIGREEIDS] = 0;
266 }
267
268 //------------------------------------------------------------------------------
269 // This method is used to determine which arrays
270 // will be copied to this object
ComputeRequiredArrays(vtkDataSetAttributes * pd,int ctype)271 vtkFieldData::BasicIterator vtkDataSetAttributes::ComputeRequiredArrays(
272 vtkDataSetAttributes* pd, int ctype)
273 {
274 if ((ctype < COPYTUPLE) || (ctype > PASSDATA))
275 {
276 vtkErrorMacro("Must call compute required with COPYTUPLE, INTERPOLATE or PASSDATA");
277 ctype = COPYTUPLE;
278 }
279
280 // We need to do some juggling to find the number of arrays
281 // which will be passed.
282
283 // First, find the number of arrays to be copied because they
284 // are in the list of _fields_ to be copied (and the actual data
285 // pointer is non-nullptr). Also, we keep those indices in a list.
286 int* copyFlags = new int[pd->GetNumberOfArrays()];
287 int index, i, numArrays = 0;
288 for (i = 0; i < pd->GetNumberOfArrays(); i++)
289 {
290 const char* arrayName = pd->GetArrayName(i);
291 // If there is no blocker for the given array
292 // and both CopyAllOff and CopyOn for that array are not true
293 if ((this->GetFlag(arrayName) != 0) &&
294 !(this->DoCopyAllOff && (this->GetFlag(arrayName) != 1)) && pd->GetAbstractArray(i))
295 {
296 // Cannot interpolate idtype arrays
297 if (ctype != INTERPOLATE || pd->GetAbstractArray(i)->GetDataType() != VTK_ID_TYPE)
298 {
299 copyFlags[numArrays] = i;
300 numArrays++;
301 }
302 }
303 }
304
305 // Next, we check the arrays to be copied because they are one of
306 // the _attributes_ to be copied (and the data array in non-nullptr).
307 // We make sure that we don't count anything twice.
308 int alreadyCopied;
309 int attributeType, j;
310 for (attributeType = 0; attributeType < NUM_ATTRIBUTES; attributeType++)
311 {
312 index = pd->AttributeIndices[attributeType];
313 int flag = this->GetFlag(pd->GetArrayName(index));
314 // If this attribute is to be copied
315 if (this->CopyAttributeFlags[ctype][attributeType] && flag)
316 {
317 // Find out if it is also in the list of fields to be copied
318 // Since attributes can only be vtkDataArray, we use GetArray() call.
319 if (pd->GetArray(index))
320 {
321 alreadyCopied = 0;
322 for (i = 0; i < numArrays; i++)
323 {
324 if (index == copyFlags[i])
325 {
326 alreadyCopied = 1;
327 }
328 }
329 // If not, increment the number of arrays to be copied.
330 if (!alreadyCopied)
331 {
332 // Cannot interpolate idtype arrays
333 if (ctype != INTERPOLATE || pd->GetArray(index)->GetDataType() != VTK_ID_TYPE)
334 {
335 copyFlags[numArrays] = index;
336 numArrays++;
337 }
338 }
339 }
340 }
341 // If it is not to be copied and it is in the list (from the
342 // previous pass), remove it
343 else
344 {
345 for (i = 0; i < numArrays; i++)
346 {
347 if (index == copyFlags[i])
348 {
349 for (j = i; j < numArrays - 1; j++)
350 {
351 copyFlags[j] = copyFlags[j + 1];
352 }
353 numArrays--;
354 i--;
355 }
356 }
357 }
358 }
359
360 vtkFieldData::BasicIterator it(copyFlags, numArrays);
361 delete[] copyFlags;
362 return it;
363 }
364
365 //------------------------------------------------------------------------------
366 // Pass entire arrays of input data through to output. Obey the "copy"
367 // flags.
PassData(vtkFieldData * fd)368 void vtkDataSetAttributes::PassData(vtkFieldData* fd)
369 {
370 if (!fd)
371 {
372 return;
373 }
374
375 vtkDataSetAttributes* dsa = vtkDataSetAttributes::SafeDownCast(fd);
376
377 if (dsa)
378 {
379 // Create an iterator to iterate over the fields which will
380 // be passed, i.e. fields which are either:
381 // 1> in the list of _fields_ to be copied or
382 // 2> in the list of _attributes_ to be copied.
383 // Note that nullptr data arrays are not copied
384
385 vtkFieldData::BasicIterator it = this->ComputeRequiredArrays(dsa, PASSDATA);
386
387 if (it.GetListSize() > this->NumberOfArrays)
388 {
389 this->AllocateArrays(it.GetListSize());
390 }
391 if (it.GetListSize() == 0)
392 {
393 return;
394 }
395
396 // Since we are replacing, remove old attributes
397 int attributeType; // will change//
398 for (attributeType = 0; attributeType < NUM_ATTRIBUTES; attributeType++)
399 {
400 if (this->CopyAttributeFlags[PASSDATA][attributeType])
401 {
402 this->RemoveArray(this->AttributeIndices[attributeType]);
403 this->AttributeIndices[attributeType] = -1;
404 }
405 }
406
407 int arrayIndex;
408 for (const auto& i : it)
409 {
410 arrayIndex = this->AddArray(dsa->GetAbstractArray(i));
411 // If necessary, make the array an attribute
412 if (((attributeType = dsa->IsArrayAnAttribute(i)) != -1) &&
413 this->CopyAttributeFlags[PASSDATA][attributeType])
414 {
415 this->SetActiveAttribute(arrayIndex, attributeType);
416 }
417 }
418 }
419 else
420 {
421 this->vtkFieldData::PassData(fd);
422 }
423 }
424
425 //------------------------------------------------------------------------------
426 namespace
427 {
428 struct CopyStructuredDataWorker
429 {
430 const int* OutExt;
431 const int* InExt;
432
CopyStructuredDataWorker__anon64e9ea3c0111::CopyStructuredDataWorker433 CopyStructuredDataWorker(const int* outExt, const int* inExt)
434 : OutExt(outExt)
435 , InExt(inExt)
436 {
437 }
438
439 template <typename Array1T, typename Array2T>
operator ()__anon64e9ea3c0111::CopyStructuredDataWorker440 void operator()(Array1T* dstArray, Array2T* srcArray)
441 {
442 // Give the compiler a hand -- allow optimizations that require both arrays
443 // to have the same stride.
444 VTK_ASSUME(srcArray->GetNumberOfComponents() == dstArray->GetNumberOfComponents());
445
446 // Create some tuple ranges to simplify optimized copying:
447 const auto srcTuples = vtk::DataArrayTupleRange(srcArray);
448 auto dstTuples = vtk::DataArrayTupleRange(dstArray);
449
450 if (vtkStructuredExtent::Smaller(this->OutExt, this->InExt))
451 {
452 // get outExt relative to the inExt to keep the logic simple. This assumes
453 // that outExt is a subset of the inExt.
454 const int relOutExt[6] = {
455 this->OutExt[0] - this->InExt[0],
456 this->OutExt[1] - this->InExt[0],
457 this->OutExt[2] - this->InExt[2],
458 this->OutExt[3] - this->InExt[2],
459 this->OutExt[4] - this->InExt[4],
460 this->OutExt[5] - this->InExt[4],
461 };
462
463 const int dims[3] = {
464 this->InExt[1] - this->InExt[0] + 1,
465 this->InExt[3] - this->InExt[2] + 1,
466 this->InExt[5] - this->InExt[4] + 1,
467 };
468
469 auto dstTupleIter = dstTuples.begin();
470 for (int outz = relOutExt[4]; outz <= relOutExt[5]; ++outz)
471 {
472 const vtkIdType zfactor = static_cast<vtkIdType>(outz) * dims[1];
473 for (int outy = relOutExt[2]; outy <= relOutExt[3]; ++outy)
474 {
475 const vtkIdType yfactor = (zfactor + outy) * dims[0];
476 for (int outx = relOutExt[0]; outx <= relOutExt[1]; ++outx)
477 {
478 const vtkIdType inTupleIdx = yfactor + outx;
479 *dstTupleIter++ = srcTuples[inTupleIdx];
480 }
481 }
482 }
483 }
484 else
485 {
486 int writeExt[6];
487 memcpy(writeExt, this->OutExt, 6 * sizeof(int));
488 vtkStructuredExtent::Clamp(writeExt, this->InExt);
489
490 const vtkIdType inDims[3] = { this->InExt[1] - this->InExt[0] + 1,
491 this->InExt[3] - this->InExt[2] + 1, this->InExt[5] - this->InExt[4] + 1 };
492 const vtkIdType outDims[3] = { this->OutExt[1] - this->OutExt[0] + 1,
493 this->OutExt[3] - this->OutExt[2] + 1, this->OutExt[5] - this->OutExt[4] + 1 };
494
495 for (int idz = writeExt[4]; idz <= writeExt[5]; ++idz)
496 {
497 const vtkIdType inTupleId1 = (idz - this->InExt[4]) * inDims[0] * inDims[1];
498 const vtkIdType outTupleId1 = (idz - this->OutExt[4]) * outDims[0] * outDims[1];
499 for (int idy = writeExt[2]; idy <= writeExt[3]; ++idy)
500 {
501 const vtkIdType inTupleId2 = inTupleId1 + (idy - this->InExt[2]) * inDims[0];
502 const vtkIdType outTupleId2 = outTupleId1 + (idy - this->OutExt[2]) * outDims[0];
503 for (int idx = writeExt[0]; idx <= writeExt[1]; ++idx)
504 {
505 const vtkIdType inTupleIdx = inTupleId2 + idx - this->InExt[0];
506 const vtkIdType outTupleIdx = outTupleId2 + idx - this->OutExt[0];
507
508 dstTuples[outTupleIdx] = srcTuples[inTupleIdx];
509 }
510 }
511 }
512 }
513
514 dstArray->DataChanged();
515 }
516 };
517
518 //------------------------------------------------------------------------------
519 // Handle vtkAbstractArrays that aren't vtkDataArrays.
520 template <class iterT>
vtkDataSetAttributesCopyValues(iterT * destIter,const int * outExt,vtkIdType outIncs[3],iterT * srcIter,const int * inExt,vtkIdType inIncs[3])521 void vtkDataSetAttributesCopyValues(iterT* destIter, const int* outExt, vtkIdType outIncs[3],
522 iterT* srcIter, const int* inExt, vtkIdType inIncs[3])
523 {
524 int data_type_size = srcIter->GetArray()->GetDataTypeSize();
525 vtkIdType rowLength = outIncs[1];
526 unsigned char* inPtr;
527 unsigned char* outPtr;
528 unsigned char* inZPtr;
529 unsigned char* outZPtr;
530
531 // Get the starting input pointer.
532 inZPtr = static_cast<unsigned char*>(srcIter->GetArray()->GetVoidPointer(0));
533 // Shift to the start of the subextent.
534 inZPtr += (outExt[0] - inExt[0]) * inIncs[0] * data_type_size +
535 (outExt[2] - inExt[2]) * inIncs[1] * data_type_size +
536 (outExt[4] - inExt[4]) * inIncs[2] * data_type_size;
537
538 // Get output pointer.
539 outZPtr = static_cast<unsigned char*>(destIter->GetArray()->GetVoidPointer(0));
540
541 // Loop over z axis.
542 for (int zIdx = outExt[4]; zIdx <= outExt[5]; ++zIdx)
543 {
544 inPtr = inZPtr;
545 outPtr = outZPtr;
546 for (int yIdx = outExt[2]; yIdx <= outExt[3]; ++yIdx)
547 {
548 memcpy(outPtr, inPtr, rowLength * data_type_size);
549 inPtr += inIncs[1] * data_type_size;
550 outPtr += outIncs[1] * data_type_size;
551 }
552 inZPtr += inIncs[2] * data_type_size;
553 outZPtr += outIncs[2] * data_type_size;
554 }
555 }
556
557 //------------------------------------------------------------------------------
558 // Specialize for vtkStringArray.
559 template <>
vtkDataSetAttributesCopyValues(vtkArrayIteratorTemplate<vtkStdString> * destIter,const int * outExt,vtkIdType outIncs[3],vtkArrayIteratorTemplate<vtkStdString> * srcIter,const int * inExt,vtkIdType inIncs[3])560 void vtkDataSetAttributesCopyValues(vtkArrayIteratorTemplate<vtkStdString>* destIter,
561 const int* outExt, vtkIdType outIncs[3], vtkArrayIteratorTemplate<vtkStdString>* srcIter,
562 const int* inExt, vtkIdType inIncs[3])
563 {
564 vtkIdType inZIndex = (outExt[0] - inExt[0]) * inIncs[0] + (outExt[2] - inExt[2]) * inIncs[1] +
565 (outExt[4] - inExt[4]) * inIncs[2];
566
567 vtkIdType outZIndex = 0;
568 vtkIdType rowLength = outIncs[1];
569
570 for (int zIdx = outExt[4]; zIdx <= outExt[5]; ++zIdx)
571 {
572 vtkIdType inIndex = inZIndex;
573 vtkIdType outIndex = outZIndex;
574 for (int yIdx = outExt[2]; yIdx <= outExt[3]; ++yIdx)
575 {
576 for (int xIdx = 0; xIdx < rowLength; ++xIdx)
577 {
578 destIter->GetValue(outIndex + xIdx) = srcIter->GetValue(inIndex + xIdx);
579 }
580 inIndex += inIncs[1];
581 outIndex += outIncs[1];
582 }
583 inZIndex += inIncs[2];
584 outZIndex += outIncs[2];
585 }
586 }
587
588 } // end anon namespace
589
590 //------------------------------------------------------------------------------
591 // This is used in the imaging pipeline for copying arrays.
592 // CopyAllocate needs to be called before this method.
CopyStructuredData(vtkDataSetAttributes * fromPd,const int * inExt,const int * outExt,bool setSize)593 void vtkDataSetAttributes::CopyStructuredData(
594 vtkDataSetAttributes* fromPd, const int* inExt, const int* outExt, bool setSize)
595 {
596 for (const auto& i : this->RequiredArrays)
597 {
598 vtkAbstractArray* inArray = fromPd->Data[i];
599 vtkAbstractArray* outArray = this->Data[this->TargetIndices[i]];
600 vtkIdType inIncs[3];
601 vtkIdType outIncs[3];
602 vtkIdType zIdx;
603
604 // Compute increments
605 inIncs[0] = inArray->GetNumberOfComponents();
606 inIncs[1] = inIncs[0] * (inExt[1] - inExt[0] + 1);
607 inIncs[2] = inIncs[1] * (inExt[3] - inExt[2] + 1);
608 outIncs[0] = inIncs[0];
609 outIncs[1] = outIncs[0] * (outExt[1] - outExt[0] + 1);
610 outIncs[2] = outIncs[1] * (outExt[3] - outExt[2] + 1);
611
612 // Make sure the input extents match the actual array lengths.
613 zIdx = inIncs[2] / inIncs[0] * (inExt[5] - inExt[4] + 1);
614 if (inArray->GetNumberOfTuples() != zIdx)
615 {
616 vtkErrorMacro("Input extent (" << inExt[0] << ", " << inExt[1] << ", " << inExt[2] << ", "
617 << inExt[3] << ", " << inExt[4] << ", " << inExt[5]
618 << ") does not match array length: " << zIdx);
619 // Skip copying this array.
620 continue;
621 }
622 // Make sure the output extents match the actual array lengths.
623 zIdx = outIncs[2] / outIncs[0] * (outExt[5] - outExt[4] + 1);
624 if (outArray->GetNumberOfTuples() != zIdx && setSize)
625 {
626 // The "CopyAllocate" method only sets the size, not the number of tuples.
627 outArray->SetNumberOfTuples(zIdx);
628 }
629
630 // We get very little performance improvement from this, but we'll leave the
631 // legacy code around until we've done through benchmarking.
632 vtkDataArray* inDA = vtkArrayDownCast<vtkDataArray>(inArray);
633 vtkDataArray* outDA = vtkArrayDownCast<vtkDataArray>(outArray);
634 if (!inDA || !outDA) // String array, etc
635 {
636 vtkArrayIterator* srcIter = inArray->NewIterator();
637 vtkArrayIterator* destIter = outArray->NewIterator();
638 switch (inArray->GetDataType())
639 {
640 vtkArrayIteratorTemplateMacro(vtkDataSetAttributesCopyValues(static_cast<VTK_TT*>(destIter),
641 outExt, outIncs, static_cast<VTK_TT*>(srcIter), inExt, inIncs));
642 }
643 srcIter->Delete();
644 destIter->Delete();
645 }
646 else
647 {
648 CopyStructuredDataWorker worker(outExt, inExt);
649 if (!vtkArrayDispatch::Dispatch2SameValueType::Execute(outDA, inDA, worker))
650 {
651 // Fallback to vtkDataArray API (e.g. vtkBitArray):
652 worker(outDA, inDA);
653 }
654 }
655 }
656 }
657
658 //------------------------------------------------------------------------------
SetupForCopy(vtkDataSetAttributes * pd)659 void vtkDataSetAttributes::SetupForCopy(vtkDataSetAttributes* pd)
660 {
661 this->InternalCopyAllocate(pd, COPYTUPLE, 0, 0, false, false);
662 }
663
664 //------------------------------------------------------------------------------
665 // Allocates point data for point-by-point (or cell-by-cell) copy operation.
666 // If sze=0, then use the input DataSetAttributes to create (i.e., find
667 // initial size of) new objects; otherwise use the sze variable.
InternalCopyAllocate(vtkDataSetAttributes * pd,int ctype,vtkIdType sze,vtkIdType ext,int shallowCopyArrays,bool createNewArrays)668 void vtkDataSetAttributes::InternalCopyAllocate(vtkDataSetAttributes* pd, int ctype, vtkIdType sze,
669 vtkIdType ext, int shallowCopyArrays, bool createNewArrays)
670 {
671 vtkAbstractArray* newAA;
672
673 // Create various point data depending upon input
674 //
675 if (!pd)
676 {
677 return;
678 }
679
680 if ((ctype < COPYTUPLE) || (ctype > PASSDATA))
681 {
682 return;
683 }
684
685 this->RequiredArrays = this->ComputeRequiredArrays(pd, ctype);
686 if (this->RequiredArrays.GetListSize() == 0)
687 {
688 return;
689 }
690 delete[] this->TargetIndices;
691 this->TargetIndices = new int[pd->GetNumberOfArrays()];
692 for (int i = 0; i < pd->GetNumberOfArrays(); i++)
693 {
694 this->TargetIndices[i] = -1;
695 }
696
697 vtkAbstractArray* aa = nullptr;
698 int attributeType;
699
700 // If we are not copying on self
701 if ((pd != this) && createNewArrays)
702 {
703 for (const auto& i : this->RequiredArrays)
704 {
705 // Create all required arrays
706 aa = pd->GetAbstractArray(i);
707 if (shallowCopyArrays)
708 {
709 newAA = aa;
710 }
711 else
712 {
713 newAA = aa->NewInstance();
714 newAA->SetNumberOfComponents(aa->GetNumberOfComponents());
715 newAA->CopyComponentNames(aa);
716 newAA->SetName(aa->GetName());
717 if (aa->HasInformation())
718 {
719 newAA->CopyInformation(aa->GetInformation(), /*deep=*/1);
720 }
721 if (sze > 0)
722 {
723 newAA->Allocate(sze * aa->GetNumberOfComponents(), ext);
724 }
725 else
726 {
727 newAA->Allocate(aa->GetNumberOfTuples());
728 }
729 vtkDataArray* newDA = vtkArrayDownCast<vtkDataArray>(newAA);
730 if (newDA)
731 {
732 vtkDataArray* da = vtkArrayDownCast<vtkDataArray>(aa);
733 newDA->SetLookupTable(da->GetLookupTable());
734 }
735 }
736 this->TargetIndices[i] = this->AddArray(newAA);
737 // If necessary, make the array an attribute
738 if (((attributeType = pd->IsArrayAnAttribute(i)) != -1) &&
739 this->CopyAttributeFlags[ctype][attributeType])
740 {
741 this->CopyAttributeFlags[ctype][attributeType] =
742 pd->CopyAttributeFlags[ctype][attributeType];
743 this->SetActiveAttribute(this->TargetIndices[i], attributeType);
744 }
745 if (!shallowCopyArrays)
746 {
747 newAA->Delete();
748 }
749 }
750 }
751 else if (pd == this)
752 {
753 // If copying on self, resize the arrays and initialize
754 // TargetIndices
755 for (const auto& i : this->RequiredArrays)
756 {
757 aa = pd->GetAbstractArray(i);
758 aa->Resize(sze);
759 this->TargetIndices[i] = i;
760 }
761 }
762 else
763 {
764 // All we are asked to do is create a mapping.
765 // Here we assume that arrays are the same and ordered
766 // the same way.
767 for (const auto& i : this->RequiredArrays)
768 {
769 this->TargetIndices[i] = i;
770 }
771 }
772 }
773
774 //------------------------------------------------------------------------------
RemoveArray(int index)775 void vtkDataSetAttributes::RemoveArray(int index)
776 {
777 if ((index < 0) || (index >= this->NumberOfActiveArrays))
778 {
779 return;
780 }
781 this->Superclass::RemoveArray(index);
782
783 // Adjust attribute types
784 int attributeType;
785 for (attributeType = 0; attributeType < NUM_ATTRIBUTES; attributeType++)
786 {
787 if (this->AttributeIndices[attributeType] == index)
788 {
789 this->AttributeIndices[attributeType] = -1;
790 }
791 else if (this->AttributeIndices[attributeType] > index)
792 {
793 this->AttributeIndices[attributeType]--;
794 }
795 }
796 }
797
798 //------------------------------------------------------------------------------
799 // Copy the attribute data from one id to another. Make sure CopyAllocate() has
800 // been invoked before using this method.
CopyData(vtkDataSetAttributes * fromPd,vtkIdType fromId,vtkIdType toId)801 void vtkDataSetAttributes::CopyData(vtkDataSetAttributes* fromPd, vtkIdType fromId, vtkIdType toId)
802 {
803 for (const auto& i : this->RequiredArrays)
804 {
805 this->CopyTuple(fromPd->Data[i], this->Data[this->TargetIndices[i]], fromId, toId);
806 }
807 }
808
809 //------------------------------------------------------------------------------
CopyData(vtkDataSetAttributes * fromPd,vtkIdList * fromIds,vtkIdList * toIds)810 void vtkDataSetAttributes::CopyData(
811 vtkDataSetAttributes* fromPd, vtkIdList* fromIds, vtkIdList* toIds)
812 {
813 for (const auto& i : this->RequiredArrays)
814 {
815 this->CopyTuples(fromPd->Data[i], this->Data[this->TargetIndices[i]], fromIds, toIds);
816 }
817 }
818
819 //------------------------------------------------------------------------------
CopyData(vtkDataSetAttributes * fromPd,vtkIdType dstStart,vtkIdType n,vtkIdType srcStart)820 void vtkDataSetAttributes::CopyData(
821 vtkDataSetAttributes* fromPd, vtkIdType dstStart, vtkIdType n, vtkIdType srcStart)
822 {
823 for (const auto& i : this->RequiredArrays)
824 {
825 this->CopyTuples(fromPd->Data[i], this->Data[this->TargetIndices[i]], dstStart, n, srcStart);
826 }
827 }
828
829 //------------------------------------------------------------------------------
CopyAllocate(vtkDataSetAttributes * pd,vtkIdType sze,vtkIdType ext,int shallowCopyArrays)830 void vtkDataSetAttributes::CopyAllocate(
831 vtkDataSetAttributes* pd, vtkIdType sze, vtkIdType ext, int shallowCopyArrays)
832 {
833 this->InternalCopyAllocate(pd, COPYTUPLE, sze, ext, shallowCopyArrays);
834 }
835
836 // Initialize point interpolation method.
InterpolateAllocate(vtkDataSetAttributes * pd,vtkIdType sze,vtkIdType ext,int shallowCopyArrays)837 void vtkDataSetAttributes::InterpolateAllocate(
838 vtkDataSetAttributes* pd, vtkIdType sze, vtkIdType ext, int shallowCopyArrays)
839 {
840 this->InternalCopyAllocate(pd, INTERPOLATE, sze, ext, shallowCopyArrays);
841 }
842
843 //------------------------------------------------------------------------------
844 // Interpolate data from points and interpolation weights. Make sure that the
845 // method InterpolateAllocate() has been invoked before using this method.
InterpolatePoint(vtkDataSetAttributes * fromPd,vtkIdType toId,vtkIdList * ptIds,double * weights)846 void vtkDataSetAttributes::InterpolatePoint(
847 vtkDataSetAttributes* fromPd, vtkIdType toId, vtkIdList* ptIds, double* weights)
848 {
849 for (const auto& i : this->RequiredArrays)
850 {
851 vtkAbstractArray* fromArray = fromPd->Data[i];
852 vtkAbstractArray* toArray = this->Data[this->TargetIndices[i]];
853
854 // check if the destination array needs nearest neighbor interpolation
855 int attributeIndex = this->IsArrayAnAttribute(this->TargetIndices[i]);
856 if (attributeIndex != -1 && this->CopyAttributeFlags[INTERPOLATE][attributeIndex] == 2)
857 {
858 vtkIdType numIds = ptIds->GetNumberOfIds();
859 vtkIdType maxId = ptIds->GetId(0);
860 vtkIdType maxWeight = 0.;
861 for (int j = 0; j < numIds; j++)
862 {
863 if (weights[j] > maxWeight)
864 {
865 maxWeight = weights[j];
866 maxId = ptIds->GetId(j);
867 }
868 }
869 toArray->InsertTuple(toId, maxId, fromArray);
870 }
871 else
872 {
873 toArray->InterpolateTuple(toId, ptIds, fromArray, weights);
874 }
875 } // for all arrays to interpolate
876 }
877
878 //------------------------------------------------------------------------------
879 // Interpolate data from the two points p1,p2 (forming an edge) and an
880 // interpolation factor, t, along the edge. The weight ranges from (0,1),
881 // with t=0 located at p1. Make sure that the method InterpolateAllocate()
882 // has been invoked before using this method.
InterpolateEdge(vtkDataSetAttributes * fromPd,vtkIdType toId,vtkIdType p1,vtkIdType p2,double t)883 void vtkDataSetAttributes::InterpolateEdge(
884 vtkDataSetAttributes* fromPd, vtkIdType toId, vtkIdType p1, vtkIdType p2, double t)
885 {
886 for (const auto& i : this->RequiredArrays)
887 {
888 vtkAbstractArray* fromArray = fromPd->Data[i];
889 vtkAbstractArray* toArray = this->Data[this->TargetIndices[i]];
890
891 // check if the destination array needs nearest neighbor interpolation
892 int attributeIndex = this->IsArrayAnAttribute(this->TargetIndices[i]);
893 if (attributeIndex != -1 && this->CopyAttributeFlags[INTERPOLATE][attributeIndex] == 2)
894 {
895 if (t < .5)
896 {
897 toArray->InsertTuple(toId, p1, fromArray);
898 }
899 else
900 {
901 toArray->InsertTuple(toId, p2, fromArray);
902 }
903 }
904 else
905 {
906 toArray->InterpolateTuple(toId, p1, fromArray, p2, fromArray, t);
907 }
908 }
909 }
910
911 //------------------------------------------------------------------------------
912 // Interpolate data from the two points p1,p2 (forming an edge) and an
913 // interpolation factor, t, along the edge. The weight ranges from (0,1),
914 // with t=0 located at p1. Make sure that the method InterpolateAllocate()
915 // has been invoked before using this method.
InterpolateTime(vtkDataSetAttributes * from1,vtkDataSetAttributes * from2,vtkIdType id,double t)916 void vtkDataSetAttributes::InterpolateTime(
917 vtkDataSetAttributes* from1, vtkDataSetAttributes* from2, vtkIdType id, double t)
918 {
919 for (int attributeType = 0; attributeType < NUM_ATTRIBUTES; attributeType++)
920 {
921 // If this attribute is to be copied
922 if (this->CopyAttributeFlags[INTERPOLATE][attributeType])
923 {
924 if (from1->GetAttribute(attributeType) && from2->GetAttribute(attributeType))
925 {
926 vtkAbstractArray* toArray = this->GetAttribute(attributeType);
927 // check if the destination array needs nearest neighbor interpolation
928 if (this->CopyAttributeFlags[INTERPOLATE][attributeType] == 2)
929 {
930 if (t < .5)
931 {
932 toArray->InsertTuple(id, id, from1->GetAttribute(attributeType));
933 }
934 else
935 {
936 toArray->InsertTuple(id, id, from2->GetAttribute(attributeType));
937 }
938 }
939 else
940 {
941 toArray->InterpolateTuple(
942 id, id, from1->GetAttribute(attributeType), id, from2->GetAttribute(attributeType), t);
943 }
944 }
945 }
946 }
947 }
948
949 //------------------------------------------------------------------------------
950 // Copy a tuple of data from one data array to another. This method (and
951 // following ones) assume that the fromData and toData objects are of the
952 // same type, and have the same number of components. This is true if you
953 // invoke CopyAllocate() or InterpolateAllocate().
CopyTuple(vtkAbstractArray * fromData,vtkAbstractArray * toData,vtkIdType fromId,vtkIdType toId)954 void vtkDataSetAttributes::CopyTuple(
955 vtkAbstractArray* fromData, vtkAbstractArray* toData, vtkIdType fromId, vtkIdType toId)
956 {
957 toData->InsertTuple(toId, fromId, fromData);
958 }
959
960 //------------------------------------------------------------------------------
CopyTuples(vtkAbstractArray * fromData,vtkAbstractArray * toData,vtkIdList * fromIds,vtkIdList * toIds)961 void vtkDataSetAttributes::CopyTuples(
962 vtkAbstractArray* fromData, vtkAbstractArray* toData, vtkIdList* fromIds, vtkIdList* toIds)
963 {
964 toData->InsertTuples(toIds, fromIds, fromData);
965 }
966
967 //------------------------------------------------------------------------------
CopyTuples(vtkAbstractArray * fromData,vtkAbstractArray * toData,vtkIdType dstStart,vtkIdType n,vtkIdType srcStart)968 void vtkDataSetAttributes::CopyTuples(vtkAbstractArray* fromData, vtkAbstractArray* toData,
969 vtkIdType dstStart, vtkIdType n, vtkIdType srcStart)
970 {
971 toData->InsertTuples(dstStart, n, srcStart, fromData);
972 }
973
974 //------------------------------------------------------------------------------
SetScalars(vtkDataArray * da)975 int vtkDataSetAttributes::SetScalars(vtkDataArray* da)
976 {
977 return this->SetAttribute(da, SCALARS);
978 }
979
980 //------------------------------------------------------------------------------
SetActiveScalars(const char * name)981 int vtkDataSetAttributes::SetActiveScalars(const char* name)
982 {
983 return this->SetActiveAttribute(name, SCALARS);
984 }
985
986 //------------------------------------------------------------------------------
SetActiveAttribute(const char * name,int attributeType)987 int vtkDataSetAttributes::SetActiveAttribute(const char* name, int attributeType)
988 {
989 int index;
990 this->GetAbstractArray(name, index);
991 return this->SetActiveAttribute(index, attributeType);
992 }
993
994 //------------------------------------------------------------------------------
GetScalars()995 vtkDataArray* vtkDataSetAttributes::GetScalars()
996 {
997 return this->GetAttribute(SCALARS);
998 }
999
1000 //------------------------------------------------------------------------------
SetVectors(vtkDataArray * da)1001 int vtkDataSetAttributes::SetVectors(vtkDataArray* da)
1002 {
1003 return this->SetAttribute(da, VECTORS);
1004 }
1005
1006 //------------------------------------------------------------------------------
SetActiveVectors(const char * name)1007 int vtkDataSetAttributes::SetActiveVectors(const char* name)
1008 {
1009 return this->SetActiveAttribute(name, VECTORS);
1010 }
1011
1012 //------------------------------------------------------------------------------
GetVectors()1013 vtkDataArray* vtkDataSetAttributes::GetVectors()
1014 {
1015 return this->GetAttribute(VECTORS);
1016 }
1017
1018 //------------------------------------------------------------------------------
SetNormals(vtkDataArray * da)1019 int vtkDataSetAttributes::SetNormals(vtkDataArray* da)
1020 {
1021 return this->SetAttribute(da, NORMALS);
1022 }
1023
1024 //------------------------------------------------------------------------------
SetActiveNormals(const char * name)1025 int vtkDataSetAttributes::SetActiveNormals(const char* name)
1026 {
1027 return this->SetActiveAttribute(name, NORMALS);
1028 }
1029
1030 //------------------------------------------------------------------------------
GetNormals()1031 vtkDataArray* vtkDataSetAttributes::GetNormals()
1032 {
1033 return this->GetAttribute(NORMALS);
1034 }
1035
1036 //------------------------------------------------------------------------------
SetTangents(vtkDataArray * da)1037 int vtkDataSetAttributes::SetTangents(vtkDataArray* da)
1038 {
1039 return this->SetAttribute(da, TANGENTS);
1040 }
1041
1042 //------------------------------------------------------------------------------
SetActiveTangents(const char * name)1043 int vtkDataSetAttributes::SetActiveTangents(const char* name)
1044 {
1045 return this->SetActiveAttribute(name, TANGENTS);
1046 }
1047
1048 //------------------------------------------------------------------------------
GetTangents()1049 vtkDataArray* vtkDataSetAttributes::GetTangents()
1050 {
1051 return this->GetAttribute(TANGENTS);
1052 }
1053
1054 //------------------------------------------------------------------------------
SetTCoords(vtkDataArray * da)1055 int vtkDataSetAttributes::SetTCoords(vtkDataArray* da)
1056 {
1057 return this->SetAttribute(da, TCOORDS);
1058 }
1059
1060 //------------------------------------------------------------------------------
SetActiveTCoords(const char * name)1061 int vtkDataSetAttributes::SetActiveTCoords(const char* name)
1062 {
1063 return this->SetActiveAttribute(name, TCOORDS);
1064 }
1065 //------------------------------------------------------------------------------
GetTCoords()1066 vtkDataArray* vtkDataSetAttributes::GetTCoords()
1067 {
1068 return this->GetAttribute(TCOORDS);
1069 }
1070
1071 //------------------------------------------------------------------------------
SetTensors(vtkDataArray * da)1072 int vtkDataSetAttributes::SetTensors(vtkDataArray* da)
1073 {
1074 return this->SetAttribute(da, TENSORS);
1075 }
1076
1077 //------------------------------------------------------------------------------
SetActiveTensors(const char * name)1078 int vtkDataSetAttributes::SetActiveTensors(const char* name)
1079 {
1080 return this->SetActiveAttribute(name, TENSORS);
1081 }
1082
1083 //------------------------------------------------------------------------------
GetTensors()1084 vtkDataArray* vtkDataSetAttributes::GetTensors()
1085 {
1086 return this->GetAttribute(TENSORS);
1087 }
1088
1089 //------------------------------------------------------------------------------
SetGlobalIds(vtkDataArray * da)1090 int vtkDataSetAttributes::SetGlobalIds(vtkDataArray* da)
1091 {
1092 return this->SetAttribute(da, GLOBALIDS);
1093 }
1094
1095 //------------------------------------------------------------------------------
SetActiveGlobalIds(const char * name)1096 int vtkDataSetAttributes::SetActiveGlobalIds(const char* name)
1097 {
1098 return this->SetActiveAttribute(name, GLOBALIDS);
1099 }
1100
1101 //------------------------------------------------------------------------------
GetGlobalIds()1102 vtkDataArray* vtkDataSetAttributes::GetGlobalIds()
1103 {
1104 return this->GetAttribute(GLOBALIDS);
1105 }
1106
1107 //------------------------------------------------------------------------------
SetPedigreeIds(vtkAbstractArray * aa)1108 int vtkDataSetAttributes::SetPedigreeIds(vtkAbstractArray* aa)
1109 {
1110 return this->SetAttribute(aa, PEDIGREEIDS);
1111 }
1112
1113 //------------------------------------------------------------------------------
SetActivePedigreeIds(const char * name)1114 int vtkDataSetAttributes::SetActivePedigreeIds(const char* name)
1115 {
1116 return this->SetActiveAttribute(name, PEDIGREEIDS);
1117 }
1118
1119 //------------------------------------------------------------------------------
GetPedigreeIds()1120 vtkAbstractArray* vtkDataSetAttributes::GetPedigreeIds()
1121 {
1122 return this->GetAbstractAttribute(PEDIGREEIDS);
1123 }
1124
1125 //------------------------------------------------------------------------------
SetRationalWeights(vtkDataArray * da)1126 int vtkDataSetAttributes::SetRationalWeights(vtkDataArray* da)
1127 {
1128 return this->SetAttribute(da, RATIONALWEIGHTS);
1129 }
1130
1131 //------------------------------------------------------------------------------
SetActiveRationalWeights(const char * name)1132 int vtkDataSetAttributes::SetActiveRationalWeights(const char* name)
1133 {
1134 return this->SetActiveAttribute(name, RATIONALWEIGHTS);
1135 }
1136
1137 //------------------------------------------------------------------------------
GetRationalWeights()1138 vtkDataArray* vtkDataSetAttributes::GetRationalWeights()
1139 {
1140 return this->GetAttribute(RATIONALWEIGHTS);
1141 }
1142
1143 //------------------------------------------------------------------------------
SetHigherOrderDegrees(vtkDataArray * da)1144 int vtkDataSetAttributes::SetHigherOrderDegrees(vtkDataArray* da)
1145 {
1146 return this->SetAttribute(da, HIGHERORDERDEGREES);
1147 }
1148
1149 //------------------------------------------------------------------------------
SetActiveHigherOrderDegrees(const char * name)1150 int vtkDataSetAttributes::SetActiveHigherOrderDegrees(const char* name)
1151 {
1152 return this->SetActiveAttribute(name, HIGHERORDERDEGREES);
1153 }
1154
1155 //------------------------------------------------------------------------------
GetHigherOrderDegrees()1156 vtkDataArray* vtkDataSetAttributes::GetHigherOrderDegrees()
1157 {
1158 return this->GetAttribute(HIGHERORDERDEGREES);
1159 }
1160
1161 //------------------------------------------------------------------------------
GetScalars(const char * name)1162 vtkDataArray* vtkDataSetAttributes::GetScalars(const char* name)
1163 {
1164 if (name == nullptr || name[0] == '\0')
1165 {
1166 return this->GetScalars();
1167 }
1168 return this->GetArray(name);
1169 }
1170
1171 //------------------------------------------------------------------------------
GetVectors(const char * name)1172 vtkDataArray* vtkDataSetAttributes::GetVectors(const char* name)
1173 {
1174 if (name == nullptr || name[0] == '\0')
1175 {
1176 return this->GetVectors();
1177 }
1178 return this->GetArray(name);
1179 }
1180
1181 //------------------------------------------------------------------------------
GetNormals(const char * name)1182 vtkDataArray* vtkDataSetAttributes::GetNormals(const char* name)
1183 {
1184 if (name == nullptr || name[0] == '\0')
1185 {
1186 return this->GetNormals();
1187 }
1188 return this->GetArray(name);
1189 }
1190
1191 //------------------------------------------------------------------------------
GetTangents(const char * name)1192 vtkDataArray* vtkDataSetAttributes::GetTangents(const char* name)
1193 {
1194 if (name == nullptr || name[0] == '\0')
1195 {
1196 return this->GetTangents();
1197 }
1198 return this->GetArray(name);
1199 }
1200
1201 //------------------------------------------------------------------------------
GetTCoords(const char * name)1202 vtkDataArray* vtkDataSetAttributes::GetTCoords(const char* name)
1203 {
1204 if (name == nullptr || name[0] == '\0')
1205 {
1206 return this->GetTCoords();
1207 }
1208 return this->GetArray(name);
1209 }
1210
1211 //------------------------------------------------------------------------------
GetTensors(const char * name)1212 vtkDataArray* vtkDataSetAttributes::GetTensors(const char* name)
1213 {
1214 if (name == nullptr || name[0] == '\0')
1215 {
1216 return this->GetTensors();
1217 }
1218 return this->GetArray(name);
1219 }
1220
1221 //------------------------------------------------------------------------------
GetGlobalIds(const char * name)1222 vtkDataArray* vtkDataSetAttributes::GetGlobalIds(const char* name)
1223 {
1224 if (name == nullptr || name[0] == '\0')
1225 {
1226 return this->GetGlobalIds();
1227 }
1228 return this->GetArray(name);
1229 }
1230
1231 //------------------------------------------------------------------------------
GetPedigreeIds(const char * name)1232 vtkAbstractArray* vtkDataSetAttributes::GetPedigreeIds(const char* name)
1233 {
1234 if (name == nullptr || name[0] == '\0')
1235 {
1236 return this->GetPedigreeIds();
1237 }
1238 return this->GetAbstractArray(name);
1239 }
1240
1241 //------------------------------------------------------------------------------
GetRationalWeights(const char * name)1242 vtkDataArray* vtkDataSetAttributes::GetRationalWeights(const char* name)
1243 {
1244 if (name == nullptr || name[0] == '\0')
1245 {
1246 return this->GetRationalWeights();
1247 }
1248 return this->GetArray(name);
1249 }
1250
1251 //------------------------------------------------------------------------------
GetHigherOrderDegrees(const char * name)1252 vtkDataArray* vtkDataSetAttributes::GetHigherOrderDegrees(const char* name)
1253 {
1254 if (name == nullptr || name[0] == '\0')
1255 {
1256 return this->GetHigherOrderDegrees();
1257 }
1258 return this->GetArray(name);
1259 }
1260
1261 //------------------------------------------------------------------------------
SetActiveAttribute(int index,int attributeType)1262 int vtkDataSetAttributes::SetActiveAttribute(int index, int attributeType)
1263 {
1264 if ((index >= 0) && (index < this->GetNumberOfArrays()))
1265 {
1266 if (attributeType != PEDIGREEIDS)
1267 {
1268 vtkDataArray* darray = vtkArrayDownCast<vtkDataArray>(this->Data[index]);
1269 if (!darray)
1270 {
1271 vtkWarningMacro("Can not set attribute "
1272 << vtkDataSetAttributes::AttributeNames[attributeType]
1273 << ". Only vtkDataArray subclasses can be set as active attributes.");
1274 return -1;
1275 }
1276 if (!vtkDataSetAttributes::CheckNumberOfComponents(darray, attributeType))
1277 {
1278 vtkWarningMacro("Can not set attribute "
1279 << vtkDataSetAttributes::AttributeNames[attributeType]
1280 << ". Incorrect number of components.");
1281 return -1;
1282 }
1283 }
1284
1285 this->AttributeIndices[attributeType] = index;
1286 this->Modified();
1287 return index;
1288 }
1289 else if (index == -1)
1290 {
1291 this->AttributeIndices[attributeType] = index;
1292 this->Modified();
1293 }
1294
1295 return -1;
1296 }
1297
1298 //------------------------------------------------------------------------------
1299 const int
1300 vtkDataSetAttributes ::NumberOfAttributeComponents[vtkDataSetAttributes::NUM_ATTRIBUTES] = { 0, 3,
1301 3, 3, 9, 1, 1, 1, 3, 1, 3 };
1302
1303 //------------------------------------------------------------------------------
1304 // Scalars set to NOLIMIT
1305 const int vtkDataSetAttributes ::AttributeLimits[vtkDataSetAttributes::NUM_ATTRIBUTES] = { NOLIMIT,
1306 EXACT, EXACT, MAX, EXACT, EXACT, EXACT, EXACT, EXACT, EXACT, EXACT };
1307
1308 //------------------------------------------------------------------------------
CheckNumberOfComponents(vtkAbstractArray * aa,int attributeType)1309 int vtkDataSetAttributes::CheckNumberOfComponents(vtkAbstractArray* aa, int attributeType)
1310 {
1311 int numComp = aa->GetNumberOfComponents();
1312
1313 if (vtkDataSetAttributes::AttributeLimits[attributeType] == MAX)
1314 {
1315 if (numComp > vtkDataSetAttributes::NumberOfAttributeComponents[attributeType])
1316 {
1317 return 0;
1318 }
1319 else
1320 {
1321 return 1;
1322 }
1323 }
1324 else if (vtkDataSetAttributes::AttributeLimits[attributeType] == EXACT)
1325 {
1326 if (numComp == vtkDataSetAttributes::NumberOfAttributeComponents[attributeType] ||
1327 (numComp == 6 && attributeType == TENSORS)) // TENSORS6 support
1328 {
1329 return 1;
1330 }
1331 else
1332 {
1333 return 0;
1334 }
1335 }
1336 else if (vtkDataSetAttributes::AttributeLimits[attributeType] == NOLIMIT)
1337 {
1338 return 1;
1339 }
1340 else
1341 {
1342 return 0;
1343 }
1344 }
1345
1346 //------------------------------------------------------------------------------
GetAttribute(int attributeType)1347 vtkDataArray* vtkDataSetAttributes::GetAttribute(int attributeType)
1348 {
1349 int index = this->AttributeIndices[attributeType];
1350 if (index == -1)
1351 {
1352 return nullptr;
1353 }
1354 else
1355 {
1356 return vtkArrayDownCast<vtkDataArray>(this->Data[index]);
1357 }
1358 }
1359
1360 //------------------------------------------------------------------------------
GetAbstractAttribute(int attributeType)1361 vtkAbstractArray* vtkDataSetAttributes::GetAbstractAttribute(int attributeType)
1362 {
1363 int index = this->AttributeIndices[attributeType];
1364 if (index == -1)
1365 {
1366 return nullptr;
1367 }
1368 else
1369 {
1370 return this->Data[index];
1371 }
1372 }
1373
1374 //------------------------------------------------------------------------------
1375 // This method lets the user add an array and make it the current
1376 // scalars, vectors etc... (this is determined by the attribute type
1377 // which is an enum defined vtkDataSetAttributes)
SetAttribute(vtkAbstractArray * aa,int attributeType)1378 int vtkDataSetAttributes::SetAttribute(vtkAbstractArray* aa, int attributeType)
1379 {
1380 if (aa && attributeType != PEDIGREEIDS && !vtkArrayDownCast<vtkDataArray>(aa))
1381 {
1382 vtkWarningMacro("Can not set attribute "
1383 << vtkDataSetAttributes::AttributeNames[attributeType]
1384 << ". This attribute must be a subclass of vtkDataArray.");
1385 return -1;
1386 }
1387 if (aa && !this->CheckNumberOfComponents(aa, attributeType))
1388 {
1389 vtkWarningMacro("Can not set attribute " << vtkDataSetAttributes::AttributeNames[attributeType]
1390 << ". Incorrect number of components.");
1391 return -1;
1392 }
1393
1394 int currentAttribute = this->AttributeIndices[attributeType];
1395
1396 // If there is an existing attribute, replace it
1397 if ((currentAttribute >= 0) && (currentAttribute < this->GetNumberOfArrays()))
1398 {
1399 if (this->GetAbstractArray(currentAttribute) == aa)
1400 {
1401 return currentAttribute;
1402 }
1403 this->RemoveArray(currentAttribute);
1404 }
1405
1406 if (aa)
1407 {
1408 // Add the array
1409 currentAttribute = this->AddArray(aa);
1410 this->AttributeIndices[attributeType] = currentAttribute;
1411 }
1412 else
1413 {
1414 this->AttributeIndices[attributeType] = -1; // attribute of this type doesn't exist
1415 }
1416 this->Modified();
1417 return this->AttributeIndices[attributeType];
1418 }
1419
1420 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)1421 void vtkDataSetAttributes::PrintSelf(ostream& os, vtkIndent indent)
1422 {
1423 this->Superclass::PrintSelf(os, indent);
1424
1425 // Print the copy flags
1426 int i;
1427 os << indent << "Copy Tuple Flags: ( ";
1428 for (i = 0; i < NUM_ATTRIBUTES; i++)
1429 {
1430 os << this->CopyAttributeFlags[COPYTUPLE][i] << " ";
1431 }
1432 os << ")" << endl;
1433 os << indent << "Interpolate Flags: ( ";
1434 for (i = 0; i < NUM_ATTRIBUTES; i++)
1435 {
1436 os << this->CopyAttributeFlags[INTERPOLATE][i] << " ";
1437 }
1438 os << ")" << endl;
1439 os << indent << "Pass Through Flags: ( ";
1440 for (i = 0; i < NUM_ATTRIBUTES; i++)
1441 {
1442 os << this->CopyAttributeFlags[PASSDATA][i] << " ";
1443 }
1444 os << ")" << endl;
1445
1446 // Now print the various attributes
1447 vtkAbstractArray* aa;
1448 int attributeType;
1449 for (attributeType = 0; attributeType < NUM_ATTRIBUTES; attributeType++)
1450 {
1451 os << indent << vtkDataSetAttributes::AttributeNames[attributeType] << ": ";
1452 if ((aa = this->GetAbstractAttribute(attributeType)))
1453 {
1454 os << endl;
1455 aa->PrintSelf(os, indent.GetNextIndent());
1456 }
1457 else
1458 {
1459 os << "(none)" << endl;
1460 }
1461 }
1462 }
1463
1464 //------------------------------------------------------------------------------
GetAttributeIndices(int * indexArray)1465 void vtkDataSetAttributes::GetAttributeIndices(int* indexArray)
1466 {
1467 int i;
1468 for (i = 0; i < NUM_ATTRIBUTES; i++)
1469 {
1470 indexArray[i] = this->AttributeIndices[i];
1471 }
1472 }
1473
1474 //------------------------------------------------------------------------------
IsArrayAnAttribute(int idx)1475 int vtkDataSetAttributes::IsArrayAnAttribute(int idx)
1476 {
1477 int i;
1478 for (i = 0; i < NUM_ATTRIBUTES; i++)
1479 {
1480 if (idx == this->AttributeIndices[i])
1481 {
1482 return i;
1483 }
1484 }
1485 return -1;
1486 }
1487
1488 //------------------------------------------------------------------------------
SetCopyAttribute(int index,int value,int ctype)1489 void vtkDataSetAttributes::SetCopyAttribute(int index, int value, int ctype)
1490 {
1491 if (index < 0 || ctype < 0 || index >= vtkDataSetAttributes::NUM_ATTRIBUTES ||
1492 ctype > vtkDataSetAttributes::ALLCOPY)
1493 {
1494 vtkErrorMacro("Cannot set copy attribute for attribute type "
1495 << index << " and copy operation " << ctype << ". These values are out of range.");
1496 return;
1497 }
1498
1499 if (ctype == vtkDataSetAttributes::ALLCOPY)
1500 {
1501 int t;
1502 for (t = COPYTUPLE; t < vtkDataSetAttributes::ALLCOPY; t++)
1503 {
1504 if (this->CopyAttributeFlags[t][index] != value)
1505 {
1506 this->CopyAttributeFlags[t][index] = value;
1507 this->Modified();
1508 }
1509 }
1510 }
1511 else
1512 {
1513 if (this->CopyAttributeFlags[ctype][index] != value)
1514 {
1515 this->CopyAttributeFlags[ctype][index] = value;
1516 this->Modified();
1517 }
1518 }
1519 }
1520
1521 //------------------------------------------------------------------------------
GetCopyAttribute(int index,int ctype)1522 int vtkDataSetAttributes::GetCopyAttribute(int index, int ctype)
1523 {
1524 if (index < 0 || ctype < 0 || index >= vtkDataSetAttributes::NUM_ATTRIBUTES ||
1525 ctype > vtkDataSetAttributes::ALLCOPY)
1526 {
1527 vtkWarningMacro("Cannot get copy attribute for attribute type "
1528 << index << " and copy operation " << ctype << ". These values are out of range.");
1529 return -1;
1530 }
1531 else if (ctype == vtkDataSetAttributes::ALLCOPY)
1532 {
1533 return (this->CopyAttributeFlags[COPYTUPLE][index] &&
1534 this->CopyAttributeFlags[INTERPOLATE][index] && this->CopyAttributeFlags[PASSDATA][index]);
1535 }
1536 else
1537 {
1538 return this->CopyAttributeFlags[ctype][index];
1539 }
1540 }
1541
1542 //------------------------------------------------------------------------------
SetCopyScalars(vtkTypeBool i,int ctype)1543 void vtkDataSetAttributes::SetCopyScalars(vtkTypeBool i, int ctype)
1544 {
1545 this->SetCopyAttribute(SCALARS, i, ctype);
1546 }
1547
1548 //------------------------------------------------------------------------------
GetCopyScalars(int ctype)1549 vtkTypeBool vtkDataSetAttributes::GetCopyScalars(int ctype)
1550 {
1551 return this->GetCopyAttribute(SCALARS, ctype);
1552 }
1553
1554 //------------------------------------------------------------------------------
SetCopyVectors(vtkTypeBool i,int ctype)1555 void vtkDataSetAttributes::SetCopyVectors(vtkTypeBool i, int ctype)
1556 {
1557 this->SetCopyAttribute(VECTORS, i, ctype);
1558 }
1559
1560 //------------------------------------------------------------------------------
GetCopyVectors(int ctype)1561 vtkTypeBool vtkDataSetAttributes::GetCopyVectors(int ctype)
1562 {
1563 return this->GetCopyAttribute(VECTORS, ctype);
1564 }
1565
1566 //------------------------------------------------------------------------------
SetCopyNormals(vtkTypeBool i,int ctype)1567 void vtkDataSetAttributes::SetCopyNormals(vtkTypeBool i, int ctype)
1568 {
1569 this->SetCopyAttribute(NORMALS, i, ctype);
1570 }
1571
1572 //------------------------------------------------------------------------------
GetCopyNormals(int ctype)1573 vtkTypeBool vtkDataSetAttributes::GetCopyNormals(int ctype)
1574 {
1575 return this->GetCopyAttribute(NORMALS, ctype);
1576 }
1577
1578 //------------------------------------------------------------------------------
SetCopyTangents(vtkTypeBool i,int ctype)1579 void vtkDataSetAttributes::SetCopyTangents(vtkTypeBool i, int ctype)
1580 {
1581 this->SetCopyAttribute(TANGENTS, i, ctype);
1582 }
1583
1584 //------------------------------------------------------------------------------
GetCopyTangents(int ctype)1585 vtkTypeBool vtkDataSetAttributes::GetCopyTangents(int ctype)
1586 {
1587 return this->GetCopyAttribute(TANGENTS, ctype);
1588 }
1589
1590 //------------------------------------------------------------------------------
SetCopyTCoords(vtkTypeBool i,int ctype)1591 void vtkDataSetAttributes::SetCopyTCoords(vtkTypeBool i, int ctype)
1592 {
1593 this->SetCopyAttribute(TCOORDS, i, ctype);
1594 }
1595
1596 //------------------------------------------------------------------------------
GetCopyTCoords(int ctype)1597 vtkTypeBool vtkDataSetAttributes::GetCopyTCoords(int ctype)
1598 {
1599 return this->GetCopyAttribute(TCOORDS, ctype);
1600 }
1601
1602 //------------------------------------------------------------------------------
SetCopyTensors(vtkTypeBool i,int ctype)1603 void vtkDataSetAttributes::SetCopyTensors(vtkTypeBool i, int ctype)
1604 {
1605 this->SetCopyAttribute(TENSORS, i, ctype);
1606 }
1607 //------------------------------------------------------------------------------
GetCopyTensors(int ctype)1608 vtkTypeBool vtkDataSetAttributes::GetCopyTensors(int ctype)
1609 {
1610 return this->GetCopyAttribute(TENSORS, ctype);
1611 }
1612
1613 //------------------------------------------------------------------------------
SetCopyGlobalIds(vtkTypeBool i,int ctype)1614 void vtkDataSetAttributes::SetCopyGlobalIds(vtkTypeBool i, int ctype)
1615 {
1616 this->SetCopyAttribute(GLOBALIDS, i, ctype);
1617 }
1618
1619 //------------------------------------------------------------------------------
GetCopyGlobalIds(int ctype)1620 vtkTypeBool vtkDataSetAttributes::GetCopyGlobalIds(int ctype)
1621 {
1622 return this->GetCopyAttribute(GLOBALIDS, ctype);
1623 }
1624
1625 //------------------------------------------------------------------------------
SetCopyPedigreeIds(vtkTypeBool i,int ctype)1626 void vtkDataSetAttributes::SetCopyPedigreeIds(vtkTypeBool i, int ctype)
1627 {
1628 this->SetCopyAttribute(PEDIGREEIDS, i, ctype);
1629 }
1630
1631 //------------------------------------------------------------------------------
GetCopyPedigreeIds(int ctype)1632 vtkTypeBool vtkDataSetAttributes::GetCopyPedigreeIds(int ctype)
1633 {
1634 return this->GetCopyAttribute(PEDIGREEIDS, ctype);
1635 }
1636
1637 //------------------------------------------------------------------------------
SetCopyRationalWeights(vtkTypeBool i,int ctype)1638 void vtkDataSetAttributes::SetCopyRationalWeights(vtkTypeBool i, int ctype)
1639 {
1640 this->SetCopyAttribute(RATIONALWEIGHTS, i, ctype);
1641 }
1642
1643 //------------------------------------------------------------------------------
GetCopyRationalWeights(int ctype)1644 vtkTypeBool vtkDataSetAttributes::GetCopyRationalWeights(int ctype)
1645 {
1646 return this->GetCopyAttribute(RATIONALWEIGHTS, ctype);
1647 }
1648
1649 //------------------------------------------------------------------------------
SetCopyHigherOrderDegrees(vtkTypeBool i,int ctype)1650 void vtkDataSetAttributes::SetCopyHigherOrderDegrees(vtkTypeBool i, int ctype)
1651 {
1652 this->SetCopyAttribute(HIGHERORDERDEGREES, i, ctype);
1653 }
1654
1655 //------------------------------------------------------------------------------
GetCopyHigherOrderDegrees(int ctype)1656 vtkTypeBool vtkDataSetAttributes::GetCopyHigherOrderDegrees(int ctype)
1657 {
1658 return this->GetCopyAttribute(HIGHERORDERDEGREES, ctype);
1659 }
1660
1661 //------------------------------------------------------------------------------
CopyAllocate(vtkDataSetAttributes::FieldList & list,vtkIdType sze,vtkIdType ext)1662 void vtkDataSetAttributes::CopyAllocate(
1663 vtkDataSetAttributes::FieldList& list, vtkIdType sze, vtkIdType ext)
1664 {
1665 list.CopyAllocate(this, COPYTUPLE, sze, ext);
1666 }
1667
1668 //------------------------------------------------------------------------------
InterpolateAllocate(vtkDataSetAttributes::FieldList & list,vtkIdType sze,vtkIdType ext)1669 void vtkDataSetAttributes::InterpolateAllocate(
1670 vtkDataSetAttributes::FieldList& list, vtkIdType sze, vtkIdType ext)
1671 {
1672 list.CopyAllocate(this, INTERPOLATE, sze, ext);
1673 }
1674
1675 //------------------------------------------------------------------------------
1676 // Description:
1677 // A special form of CopyData() to be used with FieldLists. Use it when you are
1678 // copying data from a set of vtkDataSetAttributes. Make sure that you have
1679 // called the special form of CopyAllocate that accepts FieldLists.
CopyData(vtkDataSetAttributes::FieldList & list,vtkDataSetAttributes * fromDSA,int idx,vtkIdType fromId,vtkIdType toId)1680 void vtkDataSetAttributes::CopyData(vtkDataSetAttributes::FieldList& list,
1681 vtkDataSetAttributes* fromDSA, int idx, vtkIdType fromId, vtkIdType toId)
1682 {
1683 list.CopyData(idx, fromDSA, fromId, this, toId);
1684 }
1685
1686 //------------------------------------------------------------------------------
1687 // Description:
1688 // A special form of CopyData() to be used with FieldLists. Use it when you are
1689 // copying data from a set of vtkDataSetAttributes. Make sure that you have
1690 // called the special form of CopyAllocate that accepts FieldLists.
CopyData(vtkDataSetAttributes::FieldList & list,vtkDataSetAttributes * fromDSA,int idx,vtkIdType dstStart,vtkIdType n,vtkIdType srcStart)1691 void vtkDataSetAttributes::CopyData(vtkDataSetAttributes::FieldList& list,
1692 vtkDataSetAttributes* fromDSA, int idx, vtkIdType dstStart, vtkIdType n, vtkIdType srcStart)
1693 {
1694 list.CopyData(idx, fromDSA, srcStart, n, this, dstStart);
1695 }
1696
1697 //------------------------------------------------------------------------------
1698 // Interpolate data from points and interpolation weights. Make sure that the
1699 // method InterpolateAllocate() has been invoked before using this method.
InterpolatePoint(vtkDataSetAttributes::FieldList & list,vtkDataSetAttributes * fromPd,int idx,vtkIdType toId,vtkIdList * ptIds,double * weights)1700 void vtkDataSetAttributes::InterpolatePoint(vtkDataSetAttributes::FieldList& list,
1701 vtkDataSetAttributes* fromPd, int idx, vtkIdType toId, vtkIdList* ptIds, double* weights)
1702 {
1703 list.InterpolatePoint(idx, fromPd, ptIds, weights, this, toId);
1704 }
1705
1706 //------------------------------------------------------------------------------
GetAttributeTypeAsString(int attributeType)1707 const char* vtkDataSetAttributes::GetAttributeTypeAsString(int attributeType)
1708 {
1709 if (attributeType < 0 || attributeType >= NUM_ATTRIBUTES)
1710 {
1711 vtkGenericWarningMacro("Bad attribute type: " << attributeType << ".");
1712 return nullptr;
1713 }
1714 return vtkDataSetAttributes::AttributeNames[attributeType];
1715 }
1716
1717 //------------------------------------------------------------------------------
GetLongAttributeTypeAsString(int attributeType)1718 const char* vtkDataSetAttributes::GetLongAttributeTypeAsString(int attributeType)
1719 {
1720 if (attributeType < 0 || attributeType >= NUM_ATTRIBUTES)
1721 {
1722 vtkGenericWarningMacro("Bad attribute type: " << attributeType << ".");
1723 return nullptr;
1724 }
1725 return vtkDataSetAttributes::LongAttributeNames[attributeType];
1726 }
1727