From 6020218b0b6d728eb8eee84005c7ca6b72191ae6 Mon Sep 17 00:00:00 2001 From: Jan Orend <56254096+3dJan@users.noreply.github.com> Date: Wed, 21 Aug 2024 15:08:27 +0200 Subject: [PATCH] CModelReaderNode100_Mesh parses volumeid with namestace prefix --- .../Reader/v100/NMR_ModelReaderNode100_Mesh.h | 6 +++-- ...elReaderNode_Volumetric2201_VolumeData.cpp | 4 +++- .../v100/NMR_ModelReaderNode100_Mesh.cpp | 23 +++++++++++++++++-- .../v100/NMR_ModelReaderNode100_Resources.cpp | 5 ++++ Tests/CPP_Bindings/Source/Volumetric.cpp | 21 ++++++++++------- 5 files changed, 46 insertions(+), 13 deletions(-) diff --git a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.h b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.h index a3d2a88ad..2bbb24dfd 100644 --- a/Include/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.h +++ b/Include/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.h @@ -61,8 +61,10 @@ namespace NMR { nfBool m_bHasVolumeDataID = false; ModelResourceID m_nVolumeDataID = 0; protected: - virtual void OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue); - virtual void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader); + void OnNSAttribute(_In_z_ const nfChar *pAttributeName, + _In_z_ const nfChar *pAttributeValue, + _In_z_ const nfChar *pNameSpace) override; + void OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader) override; public: CModelReaderNode100_Mesh() = delete; CModelReaderNode100_Mesh(_In_ CModel * pModel, PModelMeshObject pMesh, _In_ PModelWarnings pWarnings, _In_ PProgressMonitor pProgressMonitor, _In_ PPackageResourceID m_pObjectLevelPropertyID, _In_ ModelResourceIndex nDefaultPropertyIndex); diff --git a/Source/Model/Reader/Volumetric2201/NMR_ModelReaderNode_Volumetric2201_VolumeData.cpp b/Source/Model/Reader/Volumetric2201/NMR_ModelReaderNode_Volumetric2201_VolumeData.cpp index 0fd99e23b..9b40c58e7 100644 --- a/Source/Model/Reader/Volumetric2201/NMR_ModelReaderNode_Volumetric2201_VolumeData.cpp +++ b/Source/Model/Reader/Volumetric2201/NMR_ModelReaderNode_Volumetric2201_VolumeData.cpp @@ -67,10 +67,12 @@ namespace NMR // Parse attribute parseAttributes(pXMLReader); + // parseContent needs m_pVolumeData to be initialized, and m_nID to be set by parseAttributes + m_pVolumeData = std::make_shared(m_nID, m_pModel); // Parse Content parseContent(pXMLReader); - m_pVolumeData = std::make_shared(m_nID, m_pModel); + m_pModel->addResource(m_pVolumeData); } void CModelReaderNode_Volumetric2201_VolumeData::OnAttribute( diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.cpp index 15fc834ec..35bad5fd0 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Mesh.cpp @@ -109,13 +109,32 @@ namespace NMR { nRepresentationMeshID = m_nRepresentationMeshID; } - void CModelReaderNode100_Mesh::OnAttribute(_In_z_ const nfChar * pAttributeName, _In_z_ const nfChar * pAttributeValue) + void CModelReaderNode100_Mesh::OnNSAttribute( + _In_z_ const nfChar *pAttributeName, + _In_z_ const nfChar *pAttributeValue, + _In_z_ const nfChar *pNameSpace) { __NMRASSERT(pAttributeName); __NMRASSERT(pAttributeValue); + __NMRASSERT(pNameSpace); + + if(strcmp(pNameSpace, XML_3MF_NAMESPACE_VOLUMETRICSPEC) == 0) + { + if(strcmp(pAttributeName, XML_3MF_ATTRIBUTE_MESH_VOLUMEDATA) == + 0) + { + if(m_bHasVolumeDataID) + { + throw CNMRException( + NMR_ERROR_DUPLICATE_BOUNDARY_SHAPE_VOLUME_ID); + } + m_bHasVolumeDataID = true; + m_nVolumeDataID = fnStringToUint32(pAttributeValue); + } + } } - void CModelReaderNode100_Mesh::OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader) + void CModelReaderNode100_Mesh::OnNSChildElement(_In_z_ const nfChar * pChildName, _In_z_ const nfChar * pNameSpace, _In_ CXmlReader * pXMLReader) { __NMRASSERT(pChildName); __NMRASSERT(pXMLReader); diff --git a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Resources.cpp b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Resources.cpp index 6b48bda17..edb0e3f3c 100644 --- a/Source/Model/Reader/v100/NMR_ModelReaderNode100_Resources.cpp +++ b/Source/Model/Reader/v100/NMR_ModelReaderNode100_Resources.cpp @@ -162,6 +162,11 @@ namespace NMR { PModelReaderNode pXMLNode = std::make_shared( m_pModel, m_pWarnings); pXMLNode->parseXML(pXMLReader); + } if (strcmp(pChildName, XML_3MF_ELEMENT_VOLUMEDATA) == 0) + { + PModelReaderNode pXMLNode = std::make_shared( + m_pModel, m_pWarnings); + pXMLNode->parseXML(pXMLReader); } else m_pWarnings->addException(CNMRException(NMR_ERROR_NAMESPACE_INVALID_ELEMENT), mrwInvalidOptionalValue); diff --git a/Tests/CPP_Bindings/Source/Volumetric.cpp b/Tests/CPP_Bindings/Source/Volumetric.cpp index bb7a322f7..c7e1a54bd 100644 --- a/Tests/CPP_Bindings/Source/Volumetric.cpp +++ b/Tests/CPP_Bindings/Source/Volumetric.cpp @@ -854,7 +854,6 @@ namespace Lib3MF auto volumeData = model->AddVolumeData(); auto theColor = volumeData->CreateNewColor(implicitFunction.get()); - auto volumeDataId = volumeData->GetUniqueResourceID(); theMesh->SetVolumeData(volumeData); // Set transformation @@ -877,8 +876,14 @@ namespace Lib3MF // Assert - EXPECT_NE(volumeDataId, 0); - auto volumeDataFromFile = ioModel->GetResourceByID(volumeDataId); + // get the first mesh of ioModel + auto meshesFromWrittenFile = ioModel->GetMeshObjects(); + meshesFromWrittenFile->MoveNext(); + auto meshFromWrittenFile = + meshesFromWrittenFile->GetCurrentMeshObject(); + + // Check if volumeData is a volume data + auto volumeDataFromFile = meshFromWrittenFile->GetVolumeData(); ASSERT_TRUE(volumeDataFromFile); // Check if volumeDataFromFile is a volume data @@ -905,11 +910,11 @@ namespace Lib3MF /** * @brief Test case to create and load a function from an image3d and add a - * boundary to it. + * levelset to it. * @details This test case creates a new image stack and adds a function - * from the image3d to the model. It then adds a boundary to the volume data + * from the image3d to the model. It then adds a levelset to the volume data * and writes the model to a file. The test then reads the file, compares - * the function and boundary with the original and asserts that they are the + * the function and levelset with the original and asserts that they are the * same. */ TEST_F(Volumetric, CreateAndLoad_FunctionFromImage3dAddBoundary_SameContent) @@ -947,12 +952,12 @@ namespace Lib3MF // Write to file writer3MF = model->QueryWriter("3mf"); - writer3MF->WriteToFile(Volumetric::OutFolder + "Boundary.3mf"); + writer3MF->WriteToFile(Volumetric::OutFolder + "levlelset.3mf"); // Read and compare PModel ioModel = wrapper->CreateModel(); PReader ioReader = ioModel->QueryReader("3mf"); - ioReader->ReadFromFile(Volumetric::OutFolder + "Boundary.3mf"); + ioReader->ReadFromFile(Volumetric::OutFolder + "levlelset.3mf"); // Check the function auto functionIterator = ioModel->GetFunctions();