diff --git a/Filters/General/Testing/CMakeLists.txt b/Filters/General/Testing/CMakeLists.txt index 472dd2206221efa4d6d7fc8919755a19764dde7f..d2a50043f203da9ffe67a53aeaf00c6a7d8f3349 100644 --- a/Filters/General/Testing/CMakeLists.txt +++ b/Filters/General/Testing/CMakeLists.txt @@ -8,9 +8,11 @@ vtk_module_test_data( Data/2DScalar.vti Data/can.vtu Data/cow.vtp + Data/distTest.vtm Data/explicitStructuredGrid.vtu Data/fullhead15.png Data/hexa.vtk + Data/mb-of-mps.vtm Data/mine_with_dates.vtp Data/quadraticTetra01.vtu Data/rectGrid.vtr diff --git a/Filters/General/Testing/Cxx/TestAxisAlignedReflectionFilter.cxx b/Filters/General/Testing/Cxx/TestAxisAlignedReflectionFilter.cxx index fb39ef1403eb5e9992ef6cbfba81667b4dd1f2d5..bacda5b883e30820c3c3f620f21ad3924f45dfd0 100644 --- a/Filters/General/Testing/Cxx/TestAxisAlignedReflectionFilter.cxx +++ b/Filters/General/Testing/Cxx/TestAxisAlignedReflectionFilter.cxx @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: Copyright (c) Kitware Inc. // SPDX-License-Identifier: BSD-3-Clause +#include <vtkXMLMultiBlockDataReader.h> + #include "vtkAxisAlignedReflectionFilter.h" #include "vtkCellData.h" #include "vtkDataAssembly.h" @@ -281,7 +283,7 @@ int TestHyperTreeGrid(int argc, char* argv[]) return EXIT_SUCCESS; } -int TestCompositeData(int argc, char* argv[]) +int TestPartitionedDataSetCollection(int argc, char* argv[]) { ReadFileMacro("Data/sphereMirror.vtpc", vtkXMLPartitionedDataSetCollectionReader); @@ -302,25 +304,14 @@ int TestCompositeData(int argc, char* argv[]) AssertMacro(strcmp(assembly->GetNodeName(reflectionId), "Reflection") == 0, output->GetClassName(), "Incorrect assembly"); - int inputCompositeId = assembly->GetChild(inputId, 0); - int reflectionCompositeId = assembly->GetChild(reflectionId, 0); - AssertMacro(strcmp(assembly->GetNodeName(inputCompositeId), "Composite") == 0, - output->GetClassName(), "Incorrect assembly"); - AssertMacro(strcmp(assembly->GetNodeName(reflectionCompositeId), "Composite") == 0, - output->GetClassName(), "Incorrect assembly"); - - AssertMacro( - strcmp(assembly->GetNodeName(assembly->GetChild(inputCompositeId, 0)), "Input_Input") == 0, + AssertMacro(strcmp(assembly->GetNodeName(assembly->GetChild(inputId, 0)), "Input") == 0, output->GetClassName(), "Incorrect assembly"); - AssertMacro( - strcmp(assembly->GetNodeName(assembly->GetChild(inputCompositeId, 1)), "Input_Reflection") == 0, + AssertMacro(strcmp(assembly->GetNodeName(assembly->GetChild(inputId, 1)), "Reflection") == 0, output->GetClassName(), "Incorrect assembly"); - AssertMacro( - strcmp(assembly->GetNodeName(assembly->GetChild(reflectionCompositeId, 0)), "Input") == 0, + AssertMacro(strcmp(assembly->GetNodeName(assembly->GetChild(reflectionId, 0)), "Input") == 0, output->GetClassName(), "Incorrect assembly"); - AssertMacro( - strcmp(assembly->GetNodeName(assembly->GetChild(reflectionCompositeId, 1)), "Reflection") == 0, + AssertMacro(strcmp(assembly->GetNodeName(assembly->GetChild(reflectionId, 1)), "Reflection") == 0, output->GetClassName(), "Incorrect assembly"); AssertMacro(output->GetNumberOfPartitionedDataSets() == 4, output->GetClassName(), @@ -335,11 +326,81 @@ int TestCompositeData(int argc, char* argv[]) return EXIT_SUCCESS; } +int TestMultiBlockMultiPiece(int argc, char* argv[]) +{ + ReadFileMacro("Data/mb-of-mps.vtm", vtkXMLMultiBlockDataReader); + + vtkSmartPointer<vtkPartitionedDataSetCollection> output = + Reflect(reader->GetOutputPort(), true, true, vtkAxisAlignedReflectionFilter::X_MIN); + + vtkDataAssembly* assembly = output->GetDataAssembly(); + + int rootId = assembly->GetRootNode(); + + int inputId = assembly->GetChild(rootId, 0); + int reflectionId = assembly->GetChild(rootId, 1); + + AssertMacro(strcmp(assembly->GetNodeName(inputId), "Input") == 0, output->GetClassName(), + "Incorrect assembly"); + AssertMacro(strcmp(assembly->GetNodeName(reflectionId), "Reflection") == 0, + output->GetClassName(), "Incorrect assembly"); + + AssertMacro(strcmp(assembly->GetNodeName(assembly->GetChild(inputId, 0)), "Composite") == 0, + output->GetClassName(), "Incorrect assembly"); + AssertMacro(strcmp(assembly->GetNodeName(assembly->GetChild(inputId, 1)), "Composite") == 0, + output->GetClassName(), "Incorrect assembly"); + AssertMacro(strcmp(assembly->GetNodeName(assembly->GetChild(inputId, 2)), "Composite") == 0, + output->GetClassName(), "Incorrect assembly"); + AssertMacro(strcmp(assembly->GetNodeName(assembly->GetChild(reflectionId, 0)), "Composite") == 0, + output->GetClassName(), "Incorrect assembly"); + AssertMacro(strcmp(assembly->GetNodeName(assembly->GetChild(reflectionId, 1)), "Composite") == 0, + output->GetClassName(), "Incorrect assembly"); + AssertMacro(strcmp(assembly->GetNodeName(assembly->GetChild(reflectionId, 2)), "Composite") == 0, + output->GetClassName(), "Incorrect assembly"); + + return EXIT_SUCCESS; +} + +int TestMultiBlockOnlyDataSets(int argc, char* argv[]) +{ + ReadFileMacro("Data/distTest.vtm", vtkXMLMultiBlockDataReader); + + vtkSmartPointer<vtkPartitionedDataSetCollection> output = + Reflect(reader->GetOutputPort(), true, true, vtkAxisAlignedReflectionFilter::X_MIN); + + vtkDataAssembly* assembly = output->GetDataAssembly(); + + int rootId = assembly->GetRootNode(); + + int inputId = assembly->GetChild(rootId, 0); + int reflectionId = assembly->GetChild(rootId, 1); + + AssertMacro(strcmp(assembly->GetNodeName(inputId), "Input") == 0, output->GetClassName(), + "Incorrect assembly"); + AssertMacro(strcmp(assembly->GetNodeName(reflectionId), "Reflection") == 0, + output->GetClassName(), "Incorrect assembly"); + + for (int i = 0; i < 10; i++) + { + std::string inputCorrect = "Input_" + std::to_string(i); + AssertMacro( + strcmp(assembly->GetNodeName(assembly->GetChild(inputId, i)), inputCorrect.c_str()) == 0, + output->GetClassName(), "Incorrect assembly"); + std::string reflectionCorrect = "Reflection_" + std::to_string(i); + AssertMacro(strcmp(assembly->GetNodeName(assembly->GetChild(reflectionId, i)), + reflectionCorrect.c_str()) == 0, + output->GetClassName(), "Incorrect assembly"); + } + + return EXIT_SUCCESS; +} + // This function tests all the input types, and each input type will test a different plane mode. int TestAxisAlignedReflectionFilter(int argc, char* argv[]) { return TestUnstructuredGrid(argc, argv) || TestImageData(argc, argv) || TestRectilinearGrid(argc, argv) || TestExplicitStructuredGrid(argc, argv) || TestStructuredGrid(argc, argv) || TestPolyData(argc, argv) || TestHyperTreeGrid(argc, argv) || - TestCompositeData(argc, argv); + TestPartitionedDataSetCollection(argc, argv) || TestMultiBlockMultiPiece(argc, argv) || + TestMultiBlockOnlyDataSets(argc, argv); } diff --git a/Filters/General/vtkAxisAlignedReflectionFilter.cxx b/Filters/General/vtkAxisAlignedReflectionFilter.cxx index 3d9aaf6740e6552d992c9147018ad4e70dfb4c9d..08796b173a0796e3298142aac02facf43f404fd3 100644 --- a/Filters/General/vtkAxisAlignedReflectionFilter.cxx +++ b/Filters/General/vtkAxisAlignedReflectionFilter.cxx @@ -7,6 +7,7 @@ #include "vtkCompositeDataSet.h" #include "vtkDataArray.h" #include "vtkDataAssembly.h" +#include "vtkDataObjectTreeIterator.h" #include "vtkDataSet.h" #include "vtkDoubleArray.h" #include "vtkExplicitStructuredGrid.h" @@ -17,6 +18,7 @@ #include "vtkImageData.h" #include "vtkInformation.h" #include "vtkInformationVector.h" +#include "vtkMultiBlockDataSet.h" #include "vtkPartitionedDataSet.h" #include "vtkPartitionedDataSetCollection.h" #include "vtkPlane.h" @@ -63,8 +65,6 @@ bool vtkAxisAlignedReflectionFilter::ProcessComposite(vtkPartitionedDataSetColle vtkCompositeDataSet* inputCD, double bounds[6], int inputNodeId, int reflectionNodeId, vtkDataAssembly* outputHierarchy, int& partitionIndex, int& inputCount, int& reflectionCount) { - const std::string compositeNodeName = "Composite"; - vtkDataObjectTree* inputTree = vtkDataObjectTree::SafeDownCast(inputCD); if (!inputTree) { @@ -72,26 +72,46 @@ bool vtkAxisAlignedReflectionFilter::ProcessComposite(vtkPartitionedDataSetColle return false; } - if (this->CopyInput) - { - inputNodeId = outputHierarchy->AddNode(compositeNodeName.c_str(), inputNodeId); - } - reflectionNodeId = outputHierarchy->AddNode(compositeNodeName.c_str(), reflectionNodeId); + vtkMultiBlockDataSet* mb = vtkMultiBlockDataSet::SafeDownCast(inputCD); - vtkSmartPointer<vtkCompositeDataIterator> iter; - iter.TakeReference(inputCD->NewIterator()); - int childIdx = 0; + vtkSmartPointer<vtkDataObjectTreeIterator> iter; + iter.TakeReference(inputTree->NewTreeIterator()); + iter->SetVisitOnlyLeaves(false); + iter->SetTraverseSubTree(false); for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem()) { if (this->CheckAbort()) { break; } + vtkCompositeDataSet* cds = vtkCompositeDataSet::SafeDownCast(iter->GetCurrentDataObject()); if (cds) { - return ProcessComposite(outputPDSC, cds, bounds, inputNodeId, reflectionNodeId, - outputHierarchy, partitionIndex, inputCount, reflectionCount); + std::string compositeNodeName = "Composite"; + if (inputTree->HasMetaData(iter) && + inputTree->GetMetaData(iter)->Has(vtkCompositeDataSet::NAME())) + { + compositeNodeName = outputHierarchy->MakeValidNodeName( + inputTree->GetMetaData(iter)->Get(vtkCompositeDataSet::NAME())); + } + + int compositeInputNodeId = -1; + if (this->CopyInput) + { + compositeInputNodeId = outputHierarchy->AddNode(compositeNodeName.c_str(), inputNodeId); + } + int compositeReflectionNodeId = + outputHierarchy->AddNode(compositeNodeName.c_str(), reflectionNodeId); + + if (!ProcessComposite(outputPDSC, cds, bounds, compositeInputNodeId, + compositeReflectionNodeId, outputHierarchy, partitionIndex, inputCount, + reflectionCount)) + { + vtkErrorMacro("Failed to process composite dataset " << cds->GetClassName()); + return false; + } + continue; } vtkDataSet* ds = vtkDataSet::SafeDownCast(iter->GetCurrentDataObject()); @@ -110,19 +130,28 @@ bool vtkAxisAlignedReflectionFilter::ProcessComposite(vtkPartitionedDataSetColle vtkSmartPointer<vtkDataObject> inputCopy = dObj->NewInstance(); inputCopy->ShallowCopy(dObj); outputPDSC->SetPartitionedDataSet(partitionIndex, CreatePartitionedDataSet(inputCopy)); - const char* objName = inputTree->GetChildMetaData(childIdx)->Get(vtkCompositeDataSet::NAME()); std::string nodeName; - if (objName) + if (inputTree->HasMetaData(iter) && + inputTree->GetMetaData(iter)->Has(vtkCompositeDataSet::NAME())) { - nodeName = "Input_" + std::string(objName); + nodeName = "Input_" + + outputHierarchy->MakeValidNodeName( + inputTree->GetMetaData(iter)->Get(vtkCompositeDataSet::NAME())); } else { nodeName = "Input_" + std::to_string(inputCount++); } outputPDSC->GetMetaData(partitionIndex)->Set(vtkCompositeDataSet::NAME(), nodeName.c_str()); - int id = outputHierarchy->AddNode(nodeName.c_str(), inputNodeId); - outputHierarchy->AddDataSetIndex(id, partitionIndex); + if (mb) + { + int dsNodeId = outputHierarchy->AddNode(nodeName.c_str(), inputNodeId); + outputHierarchy->AddDataSetIndex(dsNodeId, partitionIndex); + } + else + { + outputHierarchy->AddDataSetIndex(inputNodeId, partitionIndex); + } inputCopy->Delete(); partitionIndex++; } @@ -135,21 +164,29 @@ bool vtkAxisAlignedReflectionFilter::ProcessComposite(vtkPartitionedDataSetColle } outputPDSC->SetPartitionedDataSet(partitionIndex, CreatePartitionedDataSet(outputObj)); - const char* objName = inputTree->GetChildMetaData(childIdx)->Get(vtkCompositeDataSet::NAME()); std::string nodeName; - if (objName) + if (inputTree->HasMetaData(iter) && + inputTree->GetMetaData(iter)->Has(vtkCompositeDataSet::NAME())) { - nodeName = objName; + nodeName = outputHierarchy->MakeValidNodeName( + inputTree->GetMetaData(iter)->Get(vtkCompositeDataSet::NAME())); } else { - nodeName = "Reflection" + std::to_string(reflectionCount++); + nodeName = "Reflection_" + std::to_string(reflectionCount++); } + outputPDSC->GetMetaData(partitionIndex)->Set(vtkCompositeDataSet::NAME(), nodeName.c_str()); - int id = outputHierarchy->AddNode(nodeName.c_str(), reflectionNodeId); - outputHierarchy->AddDataSetIndex(id, partitionIndex); + if (mb) + { + int dsNodeId = outputHierarchy->AddNode(nodeName.c_str(), reflectionNodeId); + outputHierarchy->AddDataSetIndex(dsNodeId, partitionIndex); + } + else + { + outputHierarchy->AddDataSetIndex(reflectionNodeId, partitionIndex); + } partitionIndex++; - childIdx++; outputObj->Delete(); } @@ -244,13 +281,14 @@ int vtkAxisAlignedReflectionFilter::RequestData(vtkInformation* vtkNotUsed(reque int partitionIndex = 0; // For naming purposes - int inputCount = 1; - int reflectionCount = 1; + int inputCount = 0; + int reflectionCount = 0; if (!ProcessComposite(outputPDSC, inputCD, bounds, inputNodeId, reflectionNodeId, outputHierarchy, partitionIndex, inputCount, reflectionCount)) { vtkErrorMacro("Failed to process composite dataset " << inputCD->GetClassName()); + return 0; } } else