diff --git a/Include/Model/Classes/NMR_ModelImplicitNode.h b/Include/Model/Classes/NMR_ModelImplicitNode.h index b96522955..ca010c614 100644 --- a/Include/Model/Classes/NMR_ModelImplicitNode.h +++ b/Include/Model/Classes/NMR_ModelImplicitNode.h @@ -119,6 +119,7 @@ namespace NMR void setGraphID(GraphID id); GraphID getGraphID() const; CModelImplicitFunction * getParent() const; + void setParent(CModelImplicitFunction * parent); }; using PModelImplicitNode = std::shared_ptr; diff --git a/Source/Model/Classes/NMR_Model.cpp b/Source/Model/Classes/NMR_Model.cpp index 7db60fb15..2417d968d 100644 --- a/Source/Model/Classes/NMR_Model.cpp +++ b/Source/Model/Classes/NMR_Model.cpp @@ -1109,6 +1109,11 @@ namespace NMR { pNewImplicitFunction->setPackageResourceID(newPkgId); pNewImplicitFunction->setModel(this); + for (auto &node : *pNewImplicitFunction->getNodes()) + { + node->setParent(pNewImplicitFunction.get()); + } + addResource(pNewImplicitFunction); oldToNewMapping[pOldImplicitFunction->getPackageResourceID()->getUniqueID()] = pNewImplicitFunction->getPackageResourceID()->getUniqueID(); } @@ -1145,8 +1150,23 @@ namespace NMR { { throw CNMRException(NMR_ERROR_RESOURCENOTFOUND); } + node->setModelResourceID(newId->getModelResourceID()); - } + + // check if the resource is available + auto res = findResource(currentPath(), newId->getModelResourceID()); + if (!res) + { + throw CNMRException(NMR_ERROR_RESOURCENOTFOUND); + } + + auto resource = node->getResource(); + if (!resource) + { + throw CNMRException(NMR_ERROR_RESOURCENOTFOUND); + + } + } } } diff --git a/Source/Model/Classes/NMR_ModelImplicitNode.cpp b/Source/Model/Classes/NMR_ModelImplicitNode.cpp index 27ef56f6f..1735a79e0 100644 --- a/Source/Model/Classes/NMR_ModelImplicitNode.cpp +++ b/Source/Model/Classes/NMR_ModelImplicitNode.cpp @@ -252,4 +252,8 @@ namespace NMR return m_parent; } + void CModelImplicitNode::setParent(CModelImplicitFunction* parent) + { + m_parent = parent; + } } // namespace NMR diff --git a/Tests/CPP_Bindings/Source/Volumetric.cpp b/Tests/CPP_Bindings/Source/Volumetric.cpp index 5e69dab1a..169cb8815 100644 --- a/Tests/CPP_Bindings/Source/Volumetric.cpp +++ b/Tests/CPP_Bindings/Source/Volumetric.cpp @@ -1280,10 +1280,6 @@ namespace Lib3MF reader->SetStrictModeActive(true); reader->ReadFromFile(InFolder + "RadialRadiator.3mf"); - // save the source model to a file with a different name - auto writer = sourceModel->QueryWriter("3mf"); - writer->WriteToFile(Volumetric::OutFolder + "RadialRadiatorCopy.3mf"); - auto sourceModelFunctionCount = sourceModel->GetFunctions()->Count(); auto const targetModel = wrapper->CreateModel(); @@ -1299,4 +1295,58 @@ namespace Lib3MF EXPECT_EQ(targetFunctionsIter->Count(), sourceModelFunctionCount + previousTargetFunctionCount); } + TEST_F(Volumetric, + Volumetric_Merge_FunctionsFromLoadedModelIntoLoadedTargetModelWithoutFunctions_VaildResourceReferences) + { + // load the source model + auto const sourceModel = wrapper->CreateModel(); + auto reader = sourceModel->QueryReader("3mf"); + reader->SetStrictModeActive(true); + reader->ReadFromFile(InFolder + "template.3mf"); + + auto sourceModelFunctionCount = sourceModel->GetFunctions()->Count(); + auto const targetModel = wrapper->CreateModel(); + auto targetReader = targetModel->QueryReader("3mf"); + targetReader->SetStrictModeActive(true); + + targetReader->ReadFromFile(InFolder + "Cube.3mf"); + auto previousTargetFunctionCount = targetModel->GetFunctions()->Count(); + + EXPECT_NO_THROW(targetModel->MergeFromModel(sourceModel.get())); + + auto targetFunctionsIter = targetModel->GetFunctions(); + EXPECT_EQ(targetFunctionsIter->Count(), sourceModelFunctionCount + previousTargetFunctionCount); + + while (targetFunctionsIter->MoveNext()) + { + auto function = targetFunctionsIter->GetCurrentFunction(); + ASSERT_TRUE(function); + auto implicitFunction = std::dynamic_pointer_cast(function); + if (implicitFunction) + { + std::cout << "Implicit function: " << implicitFunction->GetDisplayName() << " Resource ID: " << implicitFunction->GetModelResourceID() << std::endl; + + auto res = targetModel->GetResourceByID(implicitFunction->GetUniqueResourceID()); + ASSERT_TRUE(res); + + auto nodeIterator = implicitFunction->GetNodes(); + while (nodeIterator->MoveNext()) + { + auto node = nodeIterator->GetCurrent(); + ASSERT_TRUE(node); + + + if (node->GetNodeType() == Lib3MF::eImplicitNodeType::ConstResourceID) + { + auto resourceIdNode = std::dynamic_pointer_cast(node); + std::cout << "Resource ID node: " << resourceIdNode->GetDisplayName() << " identifier: " << resourceIdNode->GetIdentifier() << std::endl; + ASSERT_TRUE(resourceIdNode); + auto resource = resourceIdNode->GetResource(); + ASSERT_TRUE(resource); + } + } + } + } + } + } // namespace Lib3MF diff --git a/Tests/TestFiles/Volumetric/template.3mf b/Tests/TestFiles/Volumetric/template.3mf index 169265784..b1858e56b 100644 Binary files a/Tests/TestFiles/Volumetric/template.3mf and b/Tests/TestFiles/Volumetric/template.3mf differ