diff --git a/Include/Model/Classes/NMR_Model.h b/Include/Model/Classes/NMR_Model.h index a0713bbf..a2553de2 100644 --- a/Include/Model/Classes/NMR_Model.h +++ b/Include/Model/Classes/NMR_Model.h @@ -118,6 +118,7 @@ namespace NMR { // Model Build Items std::vector m_BuildItems; + std::map m_BuildItemMap; // build's UUID. Empty if none defined PUUID m_buildUUID; @@ -212,6 +213,7 @@ namespace NMR { // Build Handling void addBuildItem(_In_ PModelBuildItem pBuildItem); + PModelBuildItem findBuildItemByUUID(_In_ const std::string & sUUID, bool bMustExist); nfUint32 getBuildItemCount(); PModelBuildItem getBuildItem(_In_ nfUint32 nIdx); // Removes a build item identified by its handle diff --git a/Source/API/lib3mf_toolpathlayerreader.cpp b/Source/API/lib3mf_toolpathlayerreader.cpp index dd0695a1..9441caef 100644 --- a/Source/API/lib3mf_toolpathlayerreader.cpp +++ b/Source/API/lib3mf_toolpathlayerreader.cpp @@ -30,9 +30,11 @@ Abstract: This is a stub class definition of CToolpathLayerReader #include "lib3mf_toolpathlayerreader.hpp" #include "lib3mf_toolpathprofile.hpp" +#include "lib3mf_builditem.hpp" #include "lib3mf_interfaceexception.hpp" #include "lib3mf_customdomtree.hpp" + using namespace Lib3MF::Impl; /************************************************************************************************************************* @@ -111,7 +113,19 @@ bool CToolpathLayerReader::SegmentHasUniformProfile(const Lib3MF_uint32 nIndex) IBuildItem* CToolpathLayerReader::GetSegmentPart(const Lib3MF_uint32 nIndex) { - throw ELib3MFInterfaceException(LIB3MF_ERROR_NOTIMPLEMENTED); + NMR::eModelToolpathSegmentType eNMRType; + uint32_t nProfileID; + uint32_t nPartID; + uint32_t nPointCount; + m_pReadData->getSegmentInfo(nIndex, eNMRType, nProfileID, nPartID, nPointCount); + std::string sUUID = m_pReadData->mapIDtoUUID(nPartID); + + auto pModel = m_pModelToolpath->getModel(); + auto pBuildItemInstance = pModel->findBuildItemByUUID(sUUID, true); + + return new CBuildItem(pBuildItemInstance); + + } std::string CToolpathLayerReader::GetSegmentPartUUID(const Lib3MF_uint32 nIndex) diff --git a/Source/Model/Classes/NMR_Model.cpp b/Source/Model/Classes/NMR_Model.cpp index a0a14160..28f2648d 100644 --- a/Source/Model/Classes/NMR_Model.cpp +++ b/Source/Model/Classes/NMR_Model.cpp @@ -329,8 +329,22 @@ namespace NMR { if (m_BuildItems.size() >= XML_3MF_MAXBUILDITEMCOUNT) throw CNMRException(NMR_ERROR_INVALIDBUILDITEMCOUNT); m_BuildItems.push_back(pBuildItem); + m_BuildItemMap.insert(std::make_pair(pBuildItem->uuid()->toString(), pBuildItem)); } + PModelBuildItem CModel::findBuildItemByUUID(_In_ const std::string& sUUID, bool bMustExist) + { + auto iIter = m_BuildItemMap.find(sUUID); + if (iIter != m_BuildItemMap.end()) + return iIter->second; + + if (bMustExist) + throw CNMRException(NMR_ERROR_BUILDITEMNOTFOUND); + + return nullptr; + } + + nfUint32 CModel::getBuildItemCount() { return (nfUint32)m_BuildItems.size(); @@ -345,9 +359,11 @@ namespace NMR { void CModel::removeBuildItem(_In_ nfUint32 nHandle, _In_ nfBool bThrowExceptionIfNotFound) { + auto iIterator = m_BuildItems.begin(); while (iIterator != m_BuildItems.end()) { if ((*iIterator)->getHandle() == nHandle) { + m_BuildItemMap.erase((*iIterator)->uuid ()->toString ()); m_BuildItems.erase(iIterator); return; } diff --git a/Source/Model/Classes/NMR_ModelToolpathLayerReadData.cpp b/Source/Model/Classes/NMR_ModelToolpathLayerReadData.cpp index 2f58f1c2..ccf59a75 100644 --- a/Source/Model/Classes/NMR_ModelToolpathLayerReadData.cpp +++ b/Source/Model/Classes/NMR_ModelToolpathLayerReadData.cpp @@ -328,7 +328,65 @@ namespace NMR { TOOLPATHREADSEGMENT* pSegment = m_Segments.getData(nSegmentIndex); __NMRASSERT(pSegment != nullptr); - //pSegment-> + switch (pSegment->m_eType) { + case eModelToolpathSegmentType::HatchSegment: { + + uint32_t nProfileID = pSegment->m_nProfileID; + + uint32_t nHatchCount = pSegment->m_nPointCount / 2; + for (uint32_t nHatchIndex = 0; nHatchIndex < nHatchCount; nHatchIndex++) { + + // The profile overrides for hatches are stored on point 1! + auto& point1 = getSegmentPoint(nSegmentIndex, nHatchIndex * 2 + 0); + if (point1.m_nProfileOverride != 0) { + if (point1.m_nProfileOverride != nProfileID) + return false; + } + + } + + return true; + } + + case eModelToolpathSegmentType::LoopSegment: + { + uint32_t nProfileID = pSegment->m_nProfileID; + + uint32_t nPointCount = pSegment->m_nPointCount; + for (uint32_t nPointIndex = 0; nPointIndex < nPointCount; nPointIndex++) { + auto& point = getSegmentPoint(nSegmentIndex, nPointIndex); + if (point.m_nProfileOverride != 0) { + if (point.m_nProfileOverride != nProfileID) + return false; + } + + } + + return true; + } + + case eModelToolpathSegmentType::PolylineSegment: + { + uint32_t nProfileID = pSegment->m_nProfileID; + + uint32_t nPointCount = pSegment->m_nPointCount; + // On a polyline, the profile ID of the last point is not applicable... + for (uint32_t nPointIndex = 0; nPointIndex < nPointCount - 1; nPointIndex++) { + auto& point = getSegmentPoint(nSegmentIndex, nPointIndex); + if (point.m_nProfileOverride != 0) { + if (point.m_nProfileOverride != nProfileID) + return false; + } + + } + + return true; + } + + default: + return false; + } + return false; }