------------------------------------------------------------------------------
| 485 | |
| 486 | //------------------------------------------------------------------------------ |
| 487 | void vtkDataSetAttributesFieldList::UnionFieldList(vtkDataSetAttributes* dsa) |
| 488 | { |
| 489 | auto& internals = *this->Internals; |
| 490 | if (internals.NumberOfInputs == 0) |
| 491 | { |
| 492 | // called without calling InitializeFieldList, just call it. |
| 493 | this->InitializeFieldList(dsa); |
| 494 | internals.Mode = vtkInternals::UNION; |
| 495 | return; |
| 496 | } |
| 497 | |
| 498 | if (internals.Mode == vtkInternals::INTERSECTION) |
| 499 | { |
| 500 | vtkGenericWarningMacro("Mixing of `IntersectFieldList` and `UnionFieldList` " |
| 501 | "calls is not supported!"); |
| 502 | return; |
| 503 | } |
| 504 | internals.Mode = vtkInternals::UNION; |
| 505 | internals.NumberOfTuples += dsa->GetNumberOfTuples(); |
| 506 | |
| 507 | auto curfields = detail::GetFields(dsa); |
| 508 | auto& accfields = internals.Fields; |
| 509 | |
| 510 | std::set<const detail::FieldInfo*> updated_finfos; |
| 511 | |
| 512 | // iterate over curfields to find matching fields in those accumulated so far |
| 513 | // and merge them if found. |
| 514 | for (auto& curpair : curfields) |
| 515 | { |
| 516 | const std::string& fname = curpair.first; |
| 517 | detail::FieldInfo& finfo = curpair.second; |
| 518 | |
| 519 | // for the incoming array, find an unused best-match, |
| 520 | decltype(accfields.begin()) acciter, accend; |
| 521 | std::tie(acciter, accend) = accfields.equal_range(fname); |
| 522 | for (; acciter != accend; ++acciter) |
| 523 | { |
| 524 | if (acciter->second.IsSimilar(finfo) && updated_finfos.count(&acciter->second) == 0) |
| 525 | { |
| 526 | // found a match, combine them. |
| 527 | acciter->second = acciter->second + finfo; |
| 528 | updated_finfos.insert(&acciter->second); |
| 529 | finfo = detail::FieldInfo(); |
| 530 | break; |
| 531 | } |
| 532 | } |
| 533 | } |
| 534 | |
| 535 | // for all FieldInfo instances in accumulated fields |
| 536 | // not in updated_finfos, pad them with a extra location |
| 537 | // for the current input with `-1`. That is indicate that the field is missing |
| 538 | // in the current input. |
| 539 | for (auto& accpair : accfields) |
| 540 | { |
| 541 | if (updated_finfos.find(&accpair.second) == updated_finfos.end()) |
| 542 | { |
| 543 | accpair.second.ExtendForUnion(); |
| 544 | } |