------------------------------------------------------------------------------ This is used in the imaging pipeline for copying arrays. CopyAllocate needs to be called before this method.
| 569 | // This is used in the imaging pipeline for copying arrays. |
| 570 | // CopyAllocate needs to be called before this method. |
| 571 | void vtkDataSetAttributes::CopyStructuredData( |
| 572 | vtkDataSetAttributes* fromPd, const int* inExt, const int* outExt, bool setSize) |
| 573 | { |
| 574 | for (const auto& i : this->RequiredArrays) |
| 575 | { |
| 576 | vtkAbstractArray* inArray = fromPd->Data[i]; |
| 577 | vtkAbstractArray* outArray = this->Data[this->TargetIndices[i]]; |
| 578 | |
| 579 | // Compute increments |
| 580 | vtkIdType inIncs[3]; |
| 581 | inIncs[0] = inArray->GetNumberOfComponents(); |
| 582 | inIncs[1] = inIncs[0] * (inExt[1] - inExt[0] + 1); |
| 583 | inIncs[2] = inIncs[1] * (inExt[3] - inExt[2] + 1); |
| 584 | |
| 585 | vtkIdType outIncs[3]; |
| 586 | outIncs[0] = inIncs[0]; |
| 587 | outIncs[1] = outIncs[0] * (outExt[1] - outExt[0] + 1); |
| 588 | outIncs[2] = outIncs[1] * (outExt[3] - outExt[2] + 1); |
| 589 | |
| 590 | // Make sure the input extents match the actual array lengths. |
| 591 | vtkIdType zIdx = inIncs[2] / inIncs[0] * (inExt[5] - inExt[4] + 1); |
| 592 | if (inArray->GetNumberOfTuples() != zIdx) |
| 593 | { |
| 594 | vtkErrorMacro("Input extent (" << inExt[0] << ", " << inExt[1] << ", " << inExt[2] << ", " |
| 595 | << inExt[3] << ", " << inExt[4] << ", " << inExt[5] |
| 596 | << ") does not match array length: " << zIdx); |
| 597 | // Skip copying this array. |
| 598 | continue; |
| 599 | } |
| 600 | // Make sure the output extents match the actual array lengths. |
| 601 | zIdx = outIncs[2] / outIncs[0] * (outExt[5] - outExt[4] + 1); |
| 602 | if (outArray->GetNumberOfTuples() != zIdx && setSize) |
| 603 | { |
| 604 | // The "CopyAllocate" method only sets the size, not the number of tuples. |
| 605 | outArray->SetNumberOfTuples(zIdx); |
| 606 | if (outArray->GetName() && !strcmp(outArray->GetName(), this->GhostArrayName())) |
| 607 | { |
| 608 | if (auto ghosts = vtkArrayDownCast<vtkUnsignedCharArray>(outArray)) |
| 609 | { |
| 610 | // Down the road, the output ghosts (call it outGhost) are set as follows: |
| 611 | // outGhost &= inGhost. The reason spans from the ambiguity of the ghostness of an element |
| 612 | // when merging multiple datasets. If one of the sources has its bit inactive but other |
| 613 | // sources have it active, the bit needs turned off. |
| 614 | // We initialize outGhost to 1111 1111 so that we can merge the state of ghosts from |
| 615 | // multiple sources using the formula above. |
| 616 | ghosts->FillValue(0xff); |
| 617 | } |
| 618 | } |
| 619 | } |
| 620 | |
| 621 | // We get very little performance improvement from this, but we'll leave the |
| 622 | // legacy code around until we've done through benchmarking. |
| 623 | vtkDataArray* inDA = vtkArrayDownCast<vtkDataArray>(inArray); |
| 624 | vtkDataArray* outDA = vtkArrayDownCast<vtkDataArray>(outArray); |
| 625 | if (!inDA || !outDA) // String array, etc |
| 626 | { |
| 627 | vtkArrayIterator* srcIter = inArray->NewIterator(); |
| 628 | vtkArrayIterator* destIter = outArray->NewIterator(); |