From ac92c811e14646af508335a7ee915436474d14ec Mon Sep 17 00:00:00 2001 From: "Orend, Dr Jan (ORJ)" <56254096+3dJan@users.noreply.github.com> Date: Mon, 18 Sep 2023 10:03:05 +0200 Subject: [PATCH] [ImplicitFunction] Introducing SortNodesTopologically --- Autogenerated/Bindings/C/lib3mf.h | 8 ++ .../Bindings/CDynamic/lib3mf_dynamic.cc | 10 +++ .../Bindings/CDynamic/lib3mf_dynamic.h | 9 +++ Autogenerated/Bindings/CSharp/Lib3MF.cs | 9 +++ Autogenerated/Bindings/Cpp/lib3mf_abi.hpp | 8 ++ .../Bindings/Cpp/lib3mf_implicit.hpp | 9 +++ .../Bindings/CppDynamic/lib3mf_dynamic.h | 9 +++ .../Bindings/CppDynamic/lib3mf_dynamic.hpp | 23 ++++++ Autogenerated/Bindings/Go/lib3mf.go | 18 +++++ Autogenerated/Bindings/Go/lib3mf_dynamic.cc | 10 +++ Autogenerated/Bindings/Go/lib3mf_dynamic.h | 9 +++ .../Bindings/NodeJS/lib3mf_dynamic.cc | 10 +++ .../Bindings/NodeJS/lib3mf_dynamic.h | 9 +++ .../Bindings/NodeJS/lib3mf_nodewrapper.cc | 21 +++++ .../Bindings/NodeJS/lib3mf_nodewrapper.h | 1 + Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas | 20 +++++ Autogenerated/Bindings/Python/Lib3MF.py | 14 ++++ Autogenerated/Source/lib3mf_abi.hpp | 8 ++ Autogenerated/Source/lib3mf_interfaces.hpp | 5 ++ .../Source/lib3mf_interfacewrapper.cpp | 33 ++++++++ AutomaticComponentToolkit/lib3mf.xml | 3 + Include/API/lib3mf_implicitfunction.hpp | 6 ++ Include/Common/NMR_ErrorConst.h | 3 + .../Model/Classes/NMR_ModelImplicitFunction.h | 74 +++++++++++------ Include/Model/Classes/NMR_ModelImplicitNode.h | 10 +++ Source/API/lib3mf_implicitfunction.cpp | 5 ++ Source/Common/NMR_Exception.cpp | 4 +- .../Classes/NMR_ModelImplicitFunction.cpp | 80 ++++++++++++++++++- .../Model/Classes/NMR_ModelImplicitNode.cpp | 9 +++ Tests/CPP_Bindings/Source/Volumetric.cpp | 15 ++++ 30 files changed, 424 insertions(+), 28 deletions(-) diff --git a/Autogenerated/Bindings/C/lib3mf.h b/Autogenerated/Bindings/C/lib3mf.h index 5281da46d..fde22492f 100644 --- a/Autogenerated/Bindings/C/lib3mf.h +++ b/Autogenerated/Bindings/C/lib3mf.h @@ -3230,6 +3230,14 @@ LIB3MF_DECLSPEC Lib3MFResult lib3mf_implicitfunction_addlinkbynames(Lib3MF_Impli */ LIB3MF_DECLSPEC Lib3MFResult lib3mf_implicitfunction_clear(Lib3MF_ImplicitFunction pImplicitFunction); +/** +* Sorts the nodes topologically +* +* @param[in] pImplicitFunction - ImplicitFunction instance. +* @return error code or 0 (success) +*/ +LIB3MF_DECLSPEC Lib3MFResult lib3mf_implicitfunction_sortnodestopologically(Lib3MF_ImplicitFunction pImplicitFunction); + /************************************************************************************************************************* Class definition for FunctionFromImage3D **************************************************************************************************************************/ diff --git a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.cc b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.cc index e9845eaca..7185c4e2b 100644 --- a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.cc +++ b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.cc @@ -356,6 +356,7 @@ Lib3MFResult InitLib3MFWrapperTable(sLib3MFDynamicWrapperTable * pWrapperTable) pWrapperTable->m_ImplicitFunction_AddLink = NULL; pWrapperTable->m_ImplicitFunction_AddLinkByNames = NULL; pWrapperTable->m_ImplicitFunction_Clear = NULL; + pWrapperTable->m_ImplicitFunction_SortNodesTopologically = NULL; pWrapperTable->m_FunctionFromImage3D_GetImage3D = NULL; pWrapperTable->m_FunctionFromImage3D_SetImage3D = NULL; pWrapperTable->m_FunctionFromImage3D_SetFilter = NULL; @@ -3353,6 +3354,15 @@ Lib3MFResult LoadLib3MFWrapperTable(sLib3MFDynamicWrapperTable * pWrapperTable, if (pWrapperTable->m_ImplicitFunction_Clear == NULL) return LIB3MF_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 + pWrapperTable->m_ImplicitFunction_SortNodesTopologically = (PLib3MFImplicitFunction_SortNodesTopologicallyPtr) GetProcAddress(hLibrary, "lib3mf_implicitfunction_sortnodestopologically"); + #else // _WIN32 + pWrapperTable->m_ImplicitFunction_SortNodesTopologically = (PLib3MFImplicitFunction_SortNodesTopologicallyPtr) dlsym(hLibrary, "lib3mf_implicitfunction_sortnodestopologically"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_ImplicitFunction_SortNodesTopologically == NULL) + return LIB3MF_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 pWrapperTable->m_FunctionFromImage3D_GetImage3D = (PLib3MFFunctionFromImage3D_GetImage3DPtr) GetProcAddress(hLibrary, "lib3mf_functionfromimage3d_getimage3d"); #else // _WIN32 diff --git a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h index 8f150d46c..3f5701b86 100644 --- a/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/CDynamic/lib3mf_dynamic.h @@ -3217,6 +3217,14 @@ typedef Lib3MFResult (*PLib3MFImplicitFunction_AddLinkByNamesPtr) (Lib3MF_Implic */ typedef Lib3MFResult (*PLib3MFImplicitFunction_ClearPtr) (Lib3MF_ImplicitFunction pImplicitFunction); +/** +* Sorts the nodes topologically +* +* @param[in] pImplicitFunction - ImplicitFunction instance. +* @return error code or 0 (success) +*/ +typedef Lib3MFResult (*PLib3MFImplicitFunction_SortNodesTopologicallyPtr) (Lib3MF_ImplicitFunction pImplicitFunction); + /************************************************************************************************************************* Class definition for FunctionFromImage3D **************************************************************************************************************************/ @@ -5248,6 +5256,7 @@ typedef struct { PLib3MFImplicitFunction_AddLinkPtr m_ImplicitFunction_AddLink; PLib3MFImplicitFunction_AddLinkByNamesPtr m_ImplicitFunction_AddLinkByNames; PLib3MFImplicitFunction_ClearPtr m_ImplicitFunction_Clear; + PLib3MFImplicitFunction_SortNodesTopologicallyPtr m_ImplicitFunction_SortNodesTopologically; PLib3MFFunctionFromImage3D_GetImage3DPtr m_FunctionFromImage3D_GetImage3D; PLib3MFFunctionFromImage3D_SetImage3DPtr m_FunctionFromImage3D_SetImage3D; PLib3MFFunctionFromImage3D_SetFilterPtr m_FunctionFromImage3D_SetFilter; diff --git a/Autogenerated/Bindings/CSharp/Lib3MF.cs b/Autogenerated/Bindings/CSharp/Lib3MF.cs index 84f0bfb6c..cef325382 100644 --- a/Autogenerated/Bindings/CSharp/Lib3MF.cs +++ b/Autogenerated/Bindings/CSharp/Lib3MF.cs @@ -1349,6 +1349,9 @@ public class Lib3MFWrapper [DllImport("lib3mf.dll", EntryPoint = "lib3mf_implicitfunction_clear", CallingConvention=CallingConvention.Cdecl)] public unsafe extern static Int32 ImplicitFunction_Clear (IntPtr Handle); + [DllImport("lib3mf.dll", EntryPoint = "lib3mf_implicitfunction_sortnodestopologically", CallingConvention=CallingConvention.Cdecl)] + public unsafe extern static Int32 ImplicitFunction_SortNodesTopologically (IntPtr Handle); + [DllImport("lib3mf.dll", EntryPoint = "lib3mf_functionfromimage3d_getimage3d", CallingConvention=CallingConvention.Cdecl)] public unsafe extern static Int32 FunctionFromImage3D_GetImage3D (IntPtr Handle, out IntPtr AImage3D); @@ -5417,6 +5420,12 @@ public void Clear () CheckError(Internal.Lib3MFWrapper.ImplicitFunction_Clear (Handle)); } + public void SortNodesTopologically () + { + + CheckError(Internal.Lib3MFWrapper.ImplicitFunction_SortNodesTopologically (Handle)); + } + } public class CFunctionFromImage3D : CFunction diff --git a/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp b/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp index 8634b4438..5084100dc 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_abi.hpp @@ -3230,6 +3230,14 @@ LIB3MF_DECLSPEC Lib3MFResult lib3mf_implicitfunction_addlinkbynames(Lib3MF_Impli */ LIB3MF_DECLSPEC Lib3MFResult lib3mf_implicitfunction_clear(Lib3MF_ImplicitFunction pImplicitFunction); +/** +* Sorts the nodes topologically +* +* @param[in] pImplicitFunction - ImplicitFunction instance. +* @return error code or 0 (success) +*/ +LIB3MF_DECLSPEC Lib3MFResult lib3mf_implicitfunction_sortnodestopologically(Lib3MF_ImplicitFunction pImplicitFunction); + /************************************************************************************************************************* Class definition for FunctionFromImage3D **************************************************************************************************************************/ diff --git a/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp b/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp index 97f18cb79..3e0b29fad 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp @@ -1792,6 +1792,7 @@ class CImplicitFunction : public CFunction { inline void AddLink(classParam pSource, classParam pTarget); inline void AddLinkByNames(const std::string & sSource, const std::string & sTarget); inline void Clear(); + inline void SortNodesTopologically(); }; /************************************************************************************************************************* @@ -6466,6 +6467,14 @@ inline CBase* CWrapper::polymorphicFactory(Lib3MFHandle pHandle) CheckError(lib3mf_implicitfunction_clear(m_pHandle)); } + /** + * CImplicitFunction::SortNodesTopologically - Sorts the nodes topologically + */ + void CImplicitFunction::SortNodesTopologically() + { + CheckError(lib3mf_implicitfunction_sortnodestopologically(m_pHandle)); + } + /** * Method definitions for class CFunctionFromImage3D */ diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h index cce24bdac..b97e5d4b9 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.h @@ -3217,6 +3217,14 @@ typedef Lib3MFResult (*PLib3MFImplicitFunction_AddLinkByNamesPtr) (Lib3MF_Implic */ typedef Lib3MFResult (*PLib3MFImplicitFunction_ClearPtr) (Lib3MF_ImplicitFunction pImplicitFunction); +/** +* Sorts the nodes topologically +* +* @param[in] pImplicitFunction - ImplicitFunction instance. +* @return error code or 0 (success) +*/ +typedef Lib3MFResult (*PLib3MFImplicitFunction_SortNodesTopologicallyPtr) (Lib3MF_ImplicitFunction pImplicitFunction); + /************************************************************************************************************************* Class definition for FunctionFromImage3D **************************************************************************************************************************/ @@ -5248,6 +5256,7 @@ typedef struct { PLib3MFImplicitFunction_AddLinkPtr m_ImplicitFunction_AddLink; PLib3MFImplicitFunction_AddLinkByNamesPtr m_ImplicitFunction_AddLinkByNames; PLib3MFImplicitFunction_ClearPtr m_ImplicitFunction_Clear; + PLib3MFImplicitFunction_SortNodesTopologicallyPtr m_ImplicitFunction_SortNodesTopologically; PLib3MFFunctionFromImage3D_GetImage3DPtr m_FunctionFromImage3D_GetImage3D; PLib3MFFunctionFromImage3D_SetImage3DPtr m_FunctionFromImage3D_SetImage3D; PLib3MFFunctionFromImage3D_SetFilterPtr m_FunctionFromImage3D_SetFilter; diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp index aa2cf3ae3..95b02ec02 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp @@ -1816,6 +1816,7 @@ class CImplicitFunction : public CFunction { inline void AddLink(classParam pSource, classParam pTarget); inline void AddLinkByNames(const std::string & sSource, const std::string & sTarget); inline void Clear(); + inline void SortNodesTopologically(); }; /************************************************************************************************************************* @@ -2833,6 +2834,7 @@ inline CBase* CWrapper::polymorphicFactory(Lib3MFHandle pHandle) pWrapperTable->m_ImplicitFunction_AddLink = nullptr; pWrapperTable->m_ImplicitFunction_AddLinkByNames = nullptr; pWrapperTable->m_ImplicitFunction_Clear = nullptr; + pWrapperTable->m_ImplicitFunction_SortNodesTopologically = nullptr; pWrapperTable->m_FunctionFromImage3D_GetImage3D = nullptr; pWrapperTable->m_FunctionFromImage3D_SetImage3D = nullptr; pWrapperTable->m_FunctionFromImage3D_SetFilter = nullptr; @@ -5826,6 +5828,15 @@ inline CBase* CWrapper::polymorphicFactory(Lib3MFHandle pHandle) if (pWrapperTable->m_ImplicitFunction_Clear == nullptr) return LIB3MF_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 + pWrapperTable->m_ImplicitFunction_SortNodesTopologically = (PLib3MFImplicitFunction_SortNodesTopologicallyPtr) GetProcAddress(hLibrary, "lib3mf_implicitfunction_sortnodestopologically"); + #else // _WIN32 + pWrapperTable->m_ImplicitFunction_SortNodesTopologically = (PLib3MFImplicitFunction_SortNodesTopologicallyPtr) dlsym(hLibrary, "lib3mf_implicitfunction_sortnodestopologically"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_ImplicitFunction_SortNodesTopologically == nullptr) + return LIB3MF_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 pWrapperTable->m_FunctionFromImage3D_GetImage3D = (PLib3MFFunctionFromImage3D_GetImage3DPtr) GetProcAddress(hLibrary, "lib3mf_functionfromimage3d_getimage3d"); #else // _WIN32 @@ -8613,6 +8624,10 @@ inline CBase* CWrapper::polymorphicFactory(Lib3MFHandle pHandle) if ( (eLookupError != 0) || (pWrapperTable->m_ImplicitFunction_Clear == nullptr) ) return LIB3MF_ERROR_COULDNOTFINDLIBRARYEXPORT; + eLookupError = (*pLookup)("lib3mf_implicitfunction_sortnodestopologically", (void**)&(pWrapperTable->m_ImplicitFunction_SortNodesTopologically)); + if ( (eLookupError != 0) || (pWrapperTable->m_ImplicitFunction_SortNodesTopologically == nullptr) ) + return LIB3MF_ERROR_COULDNOTFINDLIBRARYEXPORT; + eLookupError = (*pLookup)("lib3mf_functionfromimage3d_getimage3d", (void**)&(pWrapperTable->m_FunctionFromImage3D_GetImage3D)); if ( (eLookupError != 0) || (pWrapperTable->m_FunctionFromImage3D_GetImage3D == nullptr) ) return LIB3MF_ERROR_COULDNOTFINDLIBRARYEXPORT; @@ -13272,6 +13287,14 @@ inline CBase* CWrapper::polymorphicFactory(Lib3MFHandle pHandle) CheckError(m_pWrapper->m_WrapperTable.m_ImplicitFunction_Clear(m_pHandle)); } + /** + * CImplicitFunction::SortNodesTopologically - Sorts the nodes topologically + */ + void CImplicitFunction::SortNodesTopologically() + { + CheckError(m_pWrapper->m_WrapperTable.m_ImplicitFunction_SortNodesTopologically(m_pHandle)); + } + /** * Method definitions for class CFunctionFromImage3D */ diff --git a/Autogenerated/Bindings/Go/lib3mf.go b/Autogenerated/Bindings/Go/lib3mf.go index 00112578e..f7a4c46fe 100644 --- a/Autogenerated/Bindings/Go/lib3mf.go +++ b/Autogenerated/Bindings/Go/lib3mf.go @@ -2844,6 +2844,15 @@ Lib3MFResult CCall_lib3mf_implicitfunction_clear(Lib3MFHandle libraryHandle, Lib } +Lib3MFResult CCall_lib3mf_implicitfunction_sortnodestopologically(Lib3MFHandle libraryHandle, Lib3MF_ImplicitFunction pImplicitFunction) +{ + if (libraryHandle == 0) + return LIB3MF_ERROR_INVALIDCAST; + sLib3MFDynamicWrapperTable * wrapperTable = (sLib3MFDynamicWrapperTable *) libraryHandle; + return wrapperTable->m_ImplicitFunction_SortNodesTopologically (pImplicitFunction); +} + + Lib3MFResult CCall_lib3mf_functionfromimage3d_getimage3d(Lib3MFHandle libraryHandle, Lib3MF_FunctionFromImage3D pFunctionFromImage3D, Lib3MF_Image3D * pImage3D) { if (libraryHandle == 0) @@ -8832,6 +8841,15 @@ func (inst ImplicitFunction) Clear() error { return nil } +// SortNodesTopologically sorts the nodes topologically. +func (inst ImplicitFunction) SortNodesTopologically() error { + ret := C.CCall_lib3mf_implicitfunction_sortnodestopologically(inst.wrapperRef.LibraryHandle, inst.Ref) + if ret != 0 { + return makeError(uint32(ret)) + } + return nil +} + // FunctionFromImage3D represents a Lib3MF class. type FunctionFromImage3D struct { diff --git a/Autogenerated/Bindings/Go/lib3mf_dynamic.cc b/Autogenerated/Bindings/Go/lib3mf_dynamic.cc index e9845eaca..7185c4e2b 100644 --- a/Autogenerated/Bindings/Go/lib3mf_dynamic.cc +++ b/Autogenerated/Bindings/Go/lib3mf_dynamic.cc @@ -356,6 +356,7 @@ Lib3MFResult InitLib3MFWrapperTable(sLib3MFDynamicWrapperTable * pWrapperTable) pWrapperTable->m_ImplicitFunction_AddLink = NULL; pWrapperTable->m_ImplicitFunction_AddLinkByNames = NULL; pWrapperTable->m_ImplicitFunction_Clear = NULL; + pWrapperTable->m_ImplicitFunction_SortNodesTopologically = NULL; pWrapperTable->m_FunctionFromImage3D_GetImage3D = NULL; pWrapperTable->m_FunctionFromImage3D_SetImage3D = NULL; pWrapperTable->m_FunctionFromImage3D_SetFilter = NULL; @@ -3353,6 +3354,15 @@ Lib3MFResult LoadLib3MFWrapperTable(sLib3MFDynamicWrapperTable * pWrapperTable, if (pWrapperTable->m_ImplicitFunction_Clear == NULL) return LIB3MF_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 + pWrapperTable->m_ImplicitFunction_SortNodesTopologically = (PLib3MFImplicitFunction_SortNodesTopologicallyPtr) GetProcAddress(hLibrary, "lib3mf_implicitfunction_sortnodestopologically"); + #else // _WIN32 + pWrapperTable->m_ImplicitFunction_SortNodesTopologically = (PLib3MFImplicitFunction_SortNodesTopologicallyPtr) dlsym(hLibrary, "lib3mf_implicitfunction_sortnodestopologically"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_ImplicitFunction_SortNodesTopologically == NULL) + return LIB3MF_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 pWrapperTable->m_FunctionFromImage3D_GetImage3D = (PLib3MFFunctionFromImage3D_GetImage3DPtr) GetProcAddress(hLibrary, "lib3mf_functionfromimage3d_getimage3d"); #else // _WIN32 diff --git a/Autogenerated/Bindings/Go/lib3mf_dynamic.h b/Autogenerated/Bindings/Go/lib3mf_dynamic.h index 8f150d46c..3f5701b86 100644 --- a/Autogenerated/Bindings/Go/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/Go/lib3mf_dynamic.h @@ -3217,6 +3217,14 @@ typedef Lib3MFResult (*PLib3MFImplicitFunction_AddLinkByNamesPtr) (Lib3MF_Implic */ typedef Lib3MFResult (*PLib3MFImplicitFunction_ClearPtr) (Lib3MF_ImplicitFunction pImplicitFunction); +/** +* Sorts the nodes topologically +* +* @param[in] pImplicitFunction - ImplicitFunction instance. +* @return error code or 0 (success) +*/ +typedef Lib3MFResult (*PLib3MFImplicitFunction_SortNodesTopologicallyPtr) (Lib3MF_ImplicitFunction pImplicitFunction); + /************************************************************************************************************************* Class definition for FunctionFromImage3D **************************************************************************************************************************/ @@ -5248,6 +5256,7 @@ typedef struct { PLib3MFImplicitFunction_AddLinkPtr m_ImplicitFunction_AddLink; PLib3MFImplicitFunction_AddLinkByNamesPtr m_ImplicitFunction_AddLinkByNames; PLib3MFImplicitFunction_ClearPtr m_ImplicitFunction_Clear; + PLib3MFImplicitFunction_SortNodesTopologicallyPtr m_ImplicitFunction_SortNodesTopologically; PLib3MFFunctionFromImage3D_GetImage3DPtr m_FunctionFromImage3D_GetImage3D; PLib3MFFunctionFromImage3D_SetImage3DPtr m_FunctionFromImage3D_SetImage3D; PLib3MFFunctionFromImage3D_SetFilterPtr m_FunctionFromImage3D_SetFilter; diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.cc b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.cc index e9845eaca..7185c4e2b 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.cc +++ b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.cc @@ -356,6 +356,7 @@ Lib3MFResult InitLib3MFWrapperTable(sLib3MFDynamicWrapperTable * pWrapperTable) pWrapperTable->m_ImplicitFunction_AddLink = NULL; pWrapperTable->m_ImplicitFunction_AddLinkByNames = NULL; pWrapperTable->m_ImplicitFunction_Clear = NULL; + pWrapperTable->m_ImplicitFunction_SortNodesTopologically = NULL; pWrapperTable->m_FunctionFromImage3D_GetImage3D = NULL; pWrapperTable->m_FunctionFromImage3D_SetImage3D = NULL; pWrapperTable->m_FunctionFromImage3D_SetFilter = NULL; @@ -3353,6 +3354,15 @@ Lib3MFResult LoadLib3MFWrapperTable(sLib3MFDynamicWrapperTable * pWrapperTable, if (pWrapperTable->m_ImplicitFunction_Clear == NULL) return LIB3MF_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 + pWrapperTable->m_ImplicitFunction_SortNodesTopologically = (PLib3MFImplicitFunction_SortNodesTopologicallyPtr) GetProcAddress(hLibrary, "lib3mf_implicitfunction_sortnodestopologically"); + #else // _WIN32 + pWrapperTable->m_ImplicitFunction_SortNodesTopologically = (PLib3MFImplicitFunction_SortNodesTopologicallyPtr) dlsym(hLibrary, "lib3mf_implicitfunction_sortnodestopologically"); + dlerror(); + #endif // _WIN32 + if (pWrapperTable->m_ImplicitFunction_SortNodesTopologically == NULL) + return LIB3MF_ERROR_COULDNOTFINDLIBRARYEXPORT; + #ifdef _WIN32 pWrapperTable->m_FunctionFromImage3D_GetImage3D = (PLib3MFFunctionFromImage3D_GetImage3DPtr) GetProcAddress(hLibrary, "lib3mf_functionfromimage3d_getimage3d"); #else // _WIN32 diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h index 8f150d46c..3f5701b86 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h +++ b/Autogenerated/Bindings/NodeJS/lib3mf_dynamic.h @@ -3217,6 +3217,14 @@ typedef Lib3MFResult (*PLib3MFImplicitFunction_AddLinkByNamesPtr) (Lib3MF_Implic */ typedef Lib3MFResult (*PLib3MFImplicitFunction_ClearPtr) (Lib3MF_ImplicitFunction pImplicitFunction); +/** +* Sorts the nodes topologically +* +* @param[in] pImplicitFunction - ImplicitFunction instance. +* @return error code or 0 (success) +*/ +typedef Lib3MFResult (*PLib3MFImplicitFunction_SortNodesTopologicallyPtr) (Lib3MF_ImplicitFunction pImplicitFunction); + /************************************************************************************************************************* Class definition for FunctionFromImage3D **************************************************************************************************************************/ @@ -5248,6 +5256,7 @@ typedef struct { PLib3MFImplicitFunction_AddLinkPtr m_ImplicitFunction_AddLink; PLib3MFImplicitFunction_AddLinkByNamesPtr m_ImplicitFunction_AddLinkByNames; PLib3MFImplicitFunction_ClearPtr m_ImplicitFunction_Clear; + PLib3MFImplicitFunction_SortNodesTopologicallyPtr m_ImplicitFunction_SortNodesTopologically; PLib3MFFunctionFromImage3D_GetImage3DPtr m_FunctionFromImage3D_GetImage3D; PLib3MFFunctionFromImage3D_SetImage3DPtr m_FunctionFromImage3D_SetImage3D; PLib3MFFunctionFromImage3D_SetFilterPtr m_FunctionFromImage3D_SetFilter; diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.cc b/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.cc index 8598f40d4..5cb8fb1ec 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.cc +++ b/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.cc @@ -11719,6 +11719,7 @@ void CLib3MFImplicitFunction::Init() NODE_SET_PROTOTYPE_METHOD(tpl, "AddLink", AddLink); NODE_SET_PROTOTYPE_METHOD(tpl, "AddLinkByNames", AddLinkByNames); NODE_SET_PROTOTYPE_METHOD(tpl, "Clear", Clear); + NODE_SET_PROTOTYPE_METHOD(tpl, "SortNodesTopologically", SortNodesTopologically); constructor.Reset(isolate, tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked()); } @@ -11982,6 +11983,26 @@ void CLib3MFImplicitFunction::Clear(const FunctionCallbackInfo& args) } } + +void CLib3MFImplicitFunction::SortNodesTopologically(const FunctionCallbackInfo& args) +{ + Isolate* isolate = args.GetIsolate(); + HandleScope scope(isolate); + try { + sLib3MFDynamicWrapperTable * wrapperTable = CLib3MFBaseClass::getDynamicWrapperTable(args.Holder()); + if (wrapperTable == nullptr) + throw std::runtime_error("Could not get wrapper table for Lib3MF method SortNodesTopologically."); + if (wrapperTable->m_ImplicitFunction_SortNodesTopologically == nullptr) + throw std::runtime_error("Could not call Lib3MF method ImplicitFunction::SortNodesTopologically."); + Lib3MFHandle instanceHandle = CLib3MFBaseClass::getHandle(args.Holder()); + Lib3MFResult errorCode = wrapperTable->m_ImplicitFunction_SortNodesTopologically(instanceHandle); + CheckError(isolate, wrapperTable, instanceHandle, errorCode); + + } catch (std::exception & E) { + RaiseError(isolate, E.what()); + } +} + /************************************************************************************************************************* Class CLib3MFFunctionFromImage3D Implementation **************************************************************************************************************************/ diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.h b/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.h index 09ee274a5..b06ee140d 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.h +++ b/Autogenerated/Bindings/NodeJS/lib3mf_nodewrapper.h @@ -1200,6 +1200,7 @@ class CLib3MFImplicitFunction : public CLib3MFBaseClass { static void AddLink(const v8::FunctionCallbackInfo& args); static void AddLinkByNames(const v8::FunctionCallbackInfo& args); static void Clear(const v8::FunctionCallbackInfo& args); + static void SortNodesTopologically(const v8::FunctionCallbackInfo& args); public: CLib3MFImplicitFunction(); diff --git a/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas b/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas index c441598de..bf271e631 100644 --- a/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas +++ b/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas @@ -3746,6 +3746,14 @@ TLib3MFModel = class; *) TLib3MFImplicitFunction_ClearFunc = function(pImplicitFunction: TLib3MFHandle): TLib3MFResult; cdecl; + (** + * Sorts the nodes topologically + * + * @param[in] pImplicitFunction - ImplicitFunction instance. + * @return error code or 0 (success) + *) + TLib3MFImplicitFunction_SortNodesTopologicallyFunc = function(pImplicitFunction: TLib3MFHandle): TLib3MFResult; cdecl; + (************************************************************************************************************************* Function type definitions for FunctionFromImage3D @@ -6345,6 +6353,7 @@ TLib3MFImplicitFunction = class(TLib3MFFunction) procedure AddLink(const ASource: TLib3MFImplicitPort; const ATarget: TLib3MFImplicitPort); procedure AddLinkByNames(const ASource: String; const ATarget: String); procedure Clear(); + procedure SortNodesTopologically(); end; @@ -6946,6 +6955,7 @@ TLib3MFWrapper = class(TObject) FLib3MFImplicitFunction_AddLinkFunc: TLib3MFImplicitFunction_AddLinkFunc; FLib3MFImplicitFunction_AddLinkByNamesFunc: TLib3MFImplicitFunction_AddLinkByNamesFunc; FLib3MFImplicitFunction_ClearFunc: TLib3MFImplicitFunction_ClearFunc; + FLib3MFImplicitFunction_SortNodesTopologicallyFunc: TLib3MFImplicitFunction_SortNodesTopologicallyFunc; FLib3MFFunctionFromImage3D_GetImage3DFunc: TLib3MFFunctionFromImage3D_GetImage3DFunc; FLib3MFFunctionFromImage3D_SetImage3DFunc: TLib3MFFunctionFromImage3D_SetImage3DFunc; FLib3MFFunctionFromImage3D_SetFilterFunc: TLib3MFFunctionFromImage3D_SetFilterFunc; @@ -7435,6 +7445,7 @@ TLib3MFWrapper = class(TObject) property Lib3MFImplicitFunction_AddLinkFunc: TLib3MFImplicitFunction_AddLinkFunc read FLib3MFImplicitFunction_AddLinkFunc; property Lib3MFImplicitFunction_AddLinkByNamesFunc: TLib3MFImplicitFunction_AddLinkByNamesFunc read FLib3MFImplicitFunction_AddLinkByNamesFunc; property Lib3MFImplicitFunction_ClearFunc: TLib3MFImplicitFunction_ClearFunc read FLib3MFImplicitFunction_ClearFunc; + property Lib3MFImplicitFunction_SortNodesTopologicallyFunc: TLib3MFImplicitFunction_SortNodesTopologicallyFunc read FLib3MFImplicitFunction_SortNodesTopologicallyFunc; property Lib3MFFunctionFromImage3D_GetImage3DFunc: TLib3MFFunctionFromImage3D_GetImage3DFunc read FLib3MFFunctionFromImage3D_GetImage3DFunc; property Lib3MFFunctionFromImage3D_SetImage3DFunc: TLib3MFFunctionFromImage3D_SetImage3DFunc read FLib3MFFunctionFromImage3D_SetImage3DFunc; property Lib3MFFunctionFromImage3D_SetFilterFunc: TLib3MFFunctionFromImage3D_SetFilterFunc read FLib3MFFunctionFromImage3D_SetFilterFunc; @@ -12164,6 +12175,11 @@ implementation FWrapper.CheckError(Self, FWrapper.Lib3MFImplicitFunction_ClearFunc(FHandle)); end; + procedure TLib3MFImplicitFunction.SortNodesTopologically(); + begin + FWrapper.CheckError(Self, FWrapper.Lib3MFImplicitFunction_SortNodesTopologicallyFunc(FHandle)); + end; + (************************************************************************************************************************* Class implementation for FunctionFromImage3D **************************************************************************************************************************) @@ -14232,6 +14248,7 @@ implementation FLib3MFImplicitFunction_AddLinkFunc := LoadFunction('lib3mf_implicitfunction_addlink'); FLib3MFImplicitFunction_AddLinkByNamesFunc := LoadFunction('lib3mf_implicitfunction_addlinkbynames'); FLib3MFImplicitFunction_ClearFunc := LoadFunction('lib3mf_implicitfunction_clear'); + FLib3MFImplicitFunction_SortNodesTopologicallyFunc := LoadFunction('lib3mf_implicitfunction_sortnodestopologically'); FLib3MFFunctionFromImage3D_GetImage3DFunc := LoadFunction('lib3mf_functionfromimage3d_getimage3d'); FLib3MFFunctionFromImage3D_SetImage3DFunc := LoadFunction('lib3mf_functionfromimage3d_setimage3d'); FLib3MFFunctionFromImage3D_SetFilterFunc := LoadFunction('lib3mf_functionfromimage3d_setfilter'); @@ -15336,6 +15353,9 @@ implementation if AResult <> LIB3MF_SUCCESS then raise ELib3MFException.CreateCustomMessage(LIB3MF_ERROR_COULDNOTLOADLIBRARY, ''); AResult := ALookupMethod(PAnsiChar('lib3mf_implicitfunction_clear'), @FLib3MFImplicitFunction_ClearFunc); + if AResult <> LIB3MF_SUCCESS then + raise ELib3MFException.CreateCustomMessage(LIB3MF_ERROR_COULDNOTLOADLIBRARY, ''); + AResult := ALookupMethod(PAnsiChar('lib3mf_implicitfunction_sortnodestopologically'), @FLib3MFImplicitFunction_SortNodesTopologicallyFunc); if AResult <> LIB3MF_SUCCESS then raise ELib3MFException.CreateCustomMessage(LIB3MF_ERROR_COULDNOTLOADLIBRARY, ''); AResult := ALookupMethod(PAnsiChar('lib3mf_functionfromimage3d_getimage3d'), @FLib3MFFunctionFromImage3D_GetImage3DFunc); diff --git a/Autogenerated/Bindings/Python/Lib3MF.py b/Autogenerated/Bindings/Python/Lib3MF.py index 2def5198e..571d5af0b 100644 --- a/Autogenerated/Bindings/Python/Lib3MF.py +++ b/Autogenerated/Bindings/Python/Lib3MF.py @@ -438,6 +438,7 @@ class FunctionTable: lib3mf_implicitfunction_addlink = None lib3mf_implicitfunction_addlinkbynames = None lib3mf_implicitfunction_clear = None + lib3mf_implicitfunction_sortnodestopologically = None lib3mf_functionfromimage3d_getimage3d = None lib3mf_functionfromimage3d_setimage3d = None lib3mf_functionfromimage3d_setfilter = None @@ -2952,6 +2953,12 @@ def _loadFunctionTableFromMethod(self, symbolLookupMethodAddress): methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p) self.lib.lib3mf_implicitfunction_clear = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("lib3mf_implicitfunction_sortnodestopologically")), methodAddress) + if err != 0: + raise ELib3MFException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) + methodType = ctypes.CFUNCTYPE(ctypes.c_int32, ctypes.c_void_p) + self.lib.lib3mf_implicitfunction_sortnodestopologically = methodType(int(methodAddress.value)) + err = symbolLookupMethod(ctypes.c_char_p(str.encode("lib3mf_functionfromimage3d_getimage3d")), methodAddress) if err != 0: raise ELib3MFException(ErrorCodes.COULDNOTLOADLIBRARY, str(err)) @@ -4850,6 +4857,9 @@ def _loadFunctionTable(self): self.lib.lib3mf_implicitfunction_clear.restype = ctypes.c_int32 self.lib.lib3mf_implicitfunction_clear.argtypes = [ctypes.c_void_p] + self.lib.lib3mf_implicitfunction_sortnodestopologically.restype = ctypes.c_int32 + self.lib.lib3mf_implicitfunction_sortnodestopologically.argtypes = [ctypes.c_void_p] + self.lib.lib3mf_functionfromimage3d_getimage3d.restype = ctypes.c_int32 self.lib.lib3mf_functionfromimage3d_getimage3d.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)] @@ -8348,6 +8358,10 @@ def Clear(self): self._wrapper.checkError(self, self._wrapper.lib.lib3mf_implicitfunction_clear(self._handle)) + def SortNodesTopologically(self): + self._wrapper.checkError(self, self._wrapper.lib.lib3mf_implicitfunction_sortnodestopologically(self._handle)) + + ''' Class Implementation for FunctionFromImage3D diff --git a/Autogenerated/Source/lib3mf_abi.hpp b/Autogenerated/Source/lib3mf_abi.hpp index 8634b4438..5084100dc 100644 --- a/Autogenerated/Source/lib3mf_abi.hpp +++ b/Autogenerated/Source/lib3mf_abi.hpp @@ -3230,6 +3230,14 @@ LIB3MF_DECLSPEC Lib3MFResult lib3mf_implicitfunction_addlinkbynames(Lib3MF_Impli */ LIB3MF_DECLSPEC Lib3MFResult lib3mf_implicitfunction_clear(Lib3MF_ImplicitFunction pImplicitFunction); +/** +* Sorts the nodes topologically +* +* @param[in] pImplicitFunction - ImplicitFunction instance. +* @return error code or 0 (success) +*/ +LIB3MF_DECLSPEC Lib3MFResult lib3mf_implicitfunction_sortnodestopologically(Lib3MF_ImplicitFunction pImplicitFunction); + /************************************************************************************************************************* Class definition for FunctionFromImage3D **************************************************************************************************************************/ diff --git a/Autogenerated/Source/lib3mf_interfaces.hpp b/Autogenerated/Source/lib3mf_interfaces.hpp index 64bef426b..1ae6a4e43 100644 --- a/Autogenerated/Source/lib3mf_interfaces.hpp +++ b/Autogenerated/Source/lib3mf_interfaces.hpp @@ -3268,6 +3268,11 @@ class IImplicitFunction : public virtual IFunction { */ virtual void Clear() = 0; + /** + * IImplicitFunction::SortNodesTopologically - Sorts the nodes topologically + */ + virtual void SortNodesTopologically() = 0; + }; typedef IBaseSharedPtr PIImplicitFunction; diff --git a/Autogenerated/Source/lib3mf_interfacewrapper.cpp b/Autogenerated/Source/lib3mf_interfacewrapper.cpp index 2d5074836..aee8999bf 100644 --- a/Autogenerated/Source/lib3mf_interfacewrapper.cpp +++ b/Autogenerated/Source/lib3mf_interfacewrapper.cpp @@ -11620,6 +11620,37 @@ Lib3MFResult lib3mf_implicitfunction_clear(Lib3MF_ImplicitFunction pImplicitFunc } } +Lib3MFResult lib3mf_implicitfunction_sortnodestopologically(Lib3MF_ImplicitFunction pImplicitFunction) +{ + IBase* pIBaseClass = (IBase *)pImplicitFunction; + + PLib3MFInterfaceJournalEntry pJournalEntry; + try { + if (m_GlobalJournal.get() != nullptr) { + pJournalEntry = m_GlobalJournal->beginClassMethod(pImplicitFunction, "ImplicitFunction", "SortNodesTopologically"); + } + IImplicitFunction* pIImplicitFunction = dynamic_cast(pIBaseClass); + if (!pIImplicitFunction) + throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDCAST); + + pIImplicitFunction->SortNodesTopologically(); + + if (pJournalEntry.get() != nullptr) { + pJournalEntry->writeSuccess(); + } + return LIB3MF_SUCCESS; + } + catch (ELib3MFInterfaceException & Exception) { + return handleLib3MFException(pIBaseClass, Exception, pJournalEntry.get()); + } + catch (std::exception & StdException) { + return handleStdException(pIBaseClass, StdException, pJournalEntry.get()); + } + catch (...) { + return handleUnhandledException(pIBaseClass, pJournalEntry.get()); + } +} + /************************************************************************************************************************* Class implementation for FunctionFromImage3D @@ -18014,6 +18045,8 @@ Lib3MFResult Lib3MF::Impl::Lib3MF_GetProcAddress (const char * pProcName, void * *ppProcAddress = (void*) &lib3mf_implicitfunction_addlinkbynames; if (sProcName == "lib3mf_implicitfunction_clear") *ppProcAddress = (void*) &lib3mf_implicitfunction_clear; + if (sProcName == "lib3mf_implicitfunction_sortnodestopologically") + *ppProcAddress = (void*) &lib3mf_implicitfunction_sortnodestopologically; if (sProcName == "lib3mf_functionfromimage3d_getimage3d") *ppProcAddress = (void*) &lib3mf_functionfromimage3d_getimage3d; if (sProcName == "lib3mf_functionfromimage3d_setimage3d") diff --git a/AutomaticComponentToolkit/lib3mf.xml b/AutomaticComponentToolkit/lib3mf.xml index 282c0f946..a509d6aaf 100644 --- a/AutomaticComponentToolkit/lib3mf.xml +++ b/AutomaticComponentToolkit/lib3mf.xml @@ -2134,6 +2134,9 @@ + + + diff --git a/Include/API/lib3mf_implicitfunction.hpp b/Include/API/lib3mf_implicitfunction.hpp index 87cb13592..58d50b7e1 100644 --- a/Include/API/lib3mf_implicitfunction.hpp +++ b/Include/API/lib3mf_implicitfunction.hpp @@ -132,6 +132,12 @@ namespace Lib3MF * IImplicitFunction::Clear - Clears the function */ void Clear() override; + + /** + * IImplicitFunction::SortNodesTopologically - Sorts the nodes + * topologically + */ + void SortNodesTopologically() override; }; } // namespace Impl diff --git a/Include/Common/NMR_ErrorConst.h b/Include/Common/NMR_ErrorConst.h index 327013823..3bfc3447c 100644 --- a/Include/Common/NMR_ErrorConst.h +++ b/Include/Common/NMR_ErrorConst.h @@ -1425,6 +1425,9 @@ Model error codes (0x8XXX) // Duplicate attribute minfeature size in volumedata element #define NMR_ERROR_DUPLICATE_VOLUMEDATA_MINFEATURESIZE 0x8840 +// Function graph is not a directed acyclic graph +#define NMR_ERROR_IMPLICIT_FUNCTION_CYCLIC_GRAPH 0x8841 + /*------------------------------------------------------------------- XML Parser Error Constants (0x9XXX) -------------------------------------------------------------------*/ diff --git a/Include/Model/Classes/NMR_ModelImplicitFunction.h b/Include/Model/Classes/NMR_ModelImplicitFunction.h index 10a1f8bb2..1b81d0946 100644 --- a/Include/Model/Classes/NMR_ModelImplicitFunction.h +++ b/Include/Model/Classes/NMR_ModelImplicitFunction.h @@ -28,7 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #pragma once -#include "Model/Classes/NMR_ModelFunction.h" #include #include @@ -36,6 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include "Model/Classes/NMR_ModelFunction.h" + namespace NMR { using ImplicitNodes = std::vector; @@ -47,62 +48,83 @@ namespace NMR } // Extract node name (before the first dot) from a node identifier - std::string extractNodeName(const ImplicitIdentifier & sIdentifier); + std::string extractNodeName(const ImplicitIdentifier& sIdentifier); // Extract port name (after the first dot) from a node identifier - std::string extractPortName(const ImplicitIdentifier & sIdentifier); + std::string extractPortName(const ImplicitIdentifier& sIdentifier); // Concatenate node name and port name to a reference identifier - ImplicitIdentifier makeReferenceIdentifier(const ImplicitIdentifier & sNodeIdentifier, - const ImplicitIdentifier & sPortIdentifier); + ImplicitIdentifier makeReferenceIdentifier( + const ImplicitIdentifier& sNodeIdentifier, + const ImplicitIdentifier& sPortIdentifier); class CModelImplicitFunction : public CModelFunction { - private: + private: ImplicitIdentifier m_identifier; PImplicitNodes m_nodes; static const implicit::NodeTypes m_nodeTypes; - CModelImplicitNode * findNode(const ImplicitIdentifier & sIdentifier) const; - - public: - CModelImplicitFunction(_In_ const ModelResourceID sID, _In_ CModel * pModel); + CModelImplicitNode* findNode( + const ImplicitIdentifier& sIdentifier) const; + public: + CModelImplicitFunction(_In_ const ModelResourceID sID, + _In_ CModel* pModel); // Copy constructor CModelImplicitFunction(const CModelImplicitFunction& other) = default; // Copy assignment operator - CModelImplicitFunction& operator=(const CModelImplicitFunction& other) = default; + CModelImplicitFunction& operator=(const CModelImplicitFunction& other) = + default; - ImplicitIdentifier const & getIdentifier() const; - void setIdentifier(ImplicitIdentifier const & identifier); + ImplicitIdentifier const& getIdentifier() const; + void setIdentifier(ImplicitIdentifier const& identifier); PModelImplicitNode addNode(const Lib3MF::eImplicitNodeType eNodeType, - const std::string & sIdentifier, - const std::string & sDisplayName, - const std::string & sTag); + const std::string& sIdentifier, + const std::string& sDisplayName, + const std::string& sTag); PModelImplicitNode addNode(const Lib3MF::eImplicitNodeType eNodeType); PImplicitNodes getNodes() const; - void addLink(const ImplicitIdentifier & sSourceNodeIdentifier, - const ImplicitIdentifier & sTargetNodeIdentifier); + void addLink(const ImplicitIdentifier& sSourceNodeIdentifier, + const ImplicitIdentifier& sTargetNodeIdentifier); - void addLink(CModelImplicitPort const & pSourcePort, CModelImplicitPort & pTargetPort); + void addLink(CModelImplicitPort const& pSourcePort, + CModelImplicitPort& pTargetPort); - implicit::NodeTypes const & getNodeTypes() const; + implicit::NodeTypes const& getNodeTypes() const; - void removeNode(const ImplicitIdentifier & sIdentifier); + void removeNode(const ImplicitIdentifier& sIdentifier); void clear() override; - /// @brief Replaces a resource ID with another one (e.g. after a merge) - /// @param sOldID - /// @param sNewID - void replaceResourceID(const ModelResourceID sOldID, const ModelResourceID sNewID); + /** + * @brief Replaces a resource ID with a new one. + * + * This function replaces all occurrences of the old resource ID with + * the new one. + * + * @param sOldID The old resource ID to replace. + * @param sNewID The new resource ID to use. + */ + void replaceResourceID(const ModelResourceID sOldID, + const ModelResourceID sNewID); + + /** + * @brief Topologically sorts the implicit function tree. + * + * This function performs a topological sort on the implicit function + * tree, ensuring that parent nodes are always evaluated before their + * children. + * + */ + void sortNodesTopologically() const; }; using PModelImplicitFunction = std::shared_ptr; -} +} // namespace NMR diff --git a/Include/Model/Classes/NMR_ModelImplicitNode.h b/Include/Model/Classes/NMR_ModelImplicitNode.h index 17329a555..3ad728ca6 100644 --- a/Include/Model/Classes/NMR_ModelImplicitNode.h +++ b/Include/Model/Classes/NMR_ModelImplicitNode.h @@ -43,6 +43,8 @@ namespace NMR { class CModelImplicitFunction; + using GraphID = unsigned int; + using TopologicalOrderIndex = unsigned int; class CModelImplicitNode { private: @@ -63,6 +65,11 @@ namespace NMR ModelResourceID m_modelResourceID; CModelImplicitFunction * m_parent = nullptr; + + // ID of the node in the graph, used for the topological sort + GraphID m_graphId = 0; + TopologicalOrderIndex m_topologicalOrderIndex = 0; + public: CModelImplicitNode(Lib3MF::eImplicitNodeType type, ImplicitIdentifier const & identifier, @@ -108,6 +115,9 @@ namespace NMR PModelResource getResource() const; bool arePortsValid() const; + + void setGraphID(GraphID id); + GraphID getGraphID() const; }; using PModelImplicitNode = std::shared_ptr; diff --git a/Source/API/lib3mf_implicitfunction.cpp b/Source/API/lib3mf_implicitfunction.cpp index 18725fcf4..4299352d5 100644 --- a/Source/API/lib3mf_implicitfunction.cpp +++ b/Source/API/lib3mf_implicitfunction.cpp @@ -100,3 +100,8 @@ void CImplicitFunction::Clear() { function()->clear(); } + +void CImplicitFunction::SortNodesTopologically() +{ + function()->sortNodesTopologically(); +} diff --git a/Source/Common/NMR_Exception.cpp b/Source/Common/NMR_Exception.cpp index 6043c8287..9b8e7df1e 100644 --- a/Source/Common/NMR_Exception.cpp +++ b/Source/Common/NMR_Exception.cpp @@ -500,7 +500,9 @@ namespace NMR { case NMR_ERROR_IMPLICIT_FUNCTION_INVALID_TARGET_PORT : return "Invalid target port in implicit function"; case NMR_ERROR_IMPLICIT_FUNCTION_INVALID_PORT_TYPE : return "Invalid port type in implicit function"; case NMR_ERROR_IMPLICIT_PORT_DOES_NOT_EXIST : return "The port does not exist"; - + case NMR_ERROR_DUPLICATE_VOLUMEDATA_MESHBBOXONLY : return "Duplicate VolumeData MeshBBoxOnly"; + case NMR_ERROR_DUPLICATE_VOLUMEDATA_MINFEATURESIZE : return "Duplicate VolumeData MinFeatureSize"; + case NMR_ERROR_IMPLICIT_FUNCTION_CYCLIC_GRAPH : return "Cyclic graph in implicit function"; // XML Parser Error Constants(0x9XXX) case NMR_ERROR_XMLPARSER_INVALIDATTRIBVALUE: return "Invalid XML attribute value"; diff --git a/Source/Model/Classes/NMR_ModelImplicitFunction.cpp b/Source/Model/Classes/NMR_ModelImplicitFunction.cpp index 80dc29302..8f71a00a9 100644 --- a/Source/Model/Classes/NMR_ModelImplicitFunction.cpp +++ b/Source/Model/Classes/NMR_ModelImplicitFunction.cpp @@ -33,6 +33,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Model/Classes/NMR_ModelImplicitPort.h" #include "Model/Classes/NMR_ModelImplicitFunction.h" +#include +#include + namespace NMR { const implicit::NodeTypes CModelImplicitFunction::m_nodeTypes; @@ -50,7 +53,8 @@ namespace NMR return nullptr; } - CModelImplicitFunction::CModelImplicitFunction(const ModelResourceID sID, CModel * pModel) + CModelImplicitFunction::CModelImplicitFunction(const ModelResourceID sID, + CModel* pModel) : CModelFunction(sID, pModel) { m_nodes = std::make_shared(); @@ -237,4 +241,78 @@ namespace NMR { return sNodeIdentifier + "." + sPortIdentifier; } + + void CModelImplicitFunction::sortNodesTopologically() const + { + // Assign an id to each node + for (size_t i = 0; i < m_nodes->size(); ++i) + { + (*m_nodes)[i]->setGraphID(i); + } + + std::unordered_map> graph; + std::unordered_map indegree; + + // Build the graph and calculate the indegree of each node + for (auto const& node : *m_nodes) + { + auto const& id = node->getGraphID(); + indegree[id] = 0; + for (auto const& port : *node->getInputs()) + { + auto const& referenceName = port->getReference(); + auto const& sourceNodeName = extractNodeName(referenceName); + CModelImplicitNode* sourceNode = findNode(sourceNodeName); + if (sourceNode == nullptr) + { + throw CNMRException(NMR_ERROR_IMPLICIT_FUNCTION_INVALID_SOURCE_NODE); + } + auto const& sourceId = sourceNode->getGraphID(); + graph[sourceId].push_back(id); + ++indegree[id]; + } + } + + // Perform the topological sort + std::queue q; + for (auto const& entry : indegree) + { + auto const& id = entry.first; + auto const& degree = entry.second; + if (degree == 0) + { + q.push(id); + } + } + + std::vector sortedNodes; + while (!q.empty()) + { + auto const& id = q.front(); + q.pop(); + sortedNodes.push_back(id); + for (auto const& neighbor : graph[id]) + { + --indegree[neighbor]; + if (indegree[neighbor] == 0) + { + q.push(neighbor); + } + } + } + + // Check if there is a cycle in the graph + if (sortedNodes.size() != m_nodes->size()) + { + throw CNMRException(NMR_ERROR_IMPLICIT_FUNCTION_CYCLIC_GRAPH); + } + + // Update the node order + std::vector newNodes(m_nodes->size()); + for (size_t i = 0; i < m_nodes->size(); ++i) + { + newNodes[i] = (*m_nodes)[sortedNodes[i]]; + } + m_nodes->swap(newNodes); + } } diff --git a/Source/Model/Classes/NMR_ModelImplicitNode.cpp b/Source/Model/Classes/NMR_ModelImplicitNode.cpp index 9b250019d..1d4443260 100644 --- a/Source/Model/Classes/NMR_ModelImplicitNode.cpp +++ b/Source/Model/Classes/NMR_ModelImplicitNode.cpp @@ -238,5 +238,14 @@ namespace NMR { return m_parent->getNodeTypes().arePortsValidForNode(*this); } + + void CModelImplicitNode::setGraphID(GraphID id) + { + m_graphId = id; + } + GraphID CModelImplicitNode::getGraphID() const + { + return m_graphId; + } } // namespace NMR diff --git a/Tests/CPP_Bindings/Source/Volumetric.cpp b/Tests/CPP_Bindings/Source/Volumetric.cpp index c26a96034..478c84f07 100644 --- a/Tests/CPP_Bindings/Source/Volumetric.cpp +++ b/Tests/CPP_Bindings/Source/Volumetric.cpp @@ -1040,6 +1040,21 @@ namespace Lib3MF auto const mergedFunction = targetFunctionsIter->GetCurrentFunction(); ASSERT_TRUE(mergedFunction); EXPECT_EQ(mergedFunction->GetModelResourceID(), 2u); + + //Save the target model to a file + writer3MF = targetModel->QueryWriter("3mf"); + writer3MF->WriteToFile(Volumetric::OutFolder + "TwoFunctions.3mf"); } + TEST_F(Volumetric, SortNodesTopologically_SimpleFunction_SortedNodes) + { + auto const function = helper::createGyroidFunction(*model); + + function->SortNodesTopologically(); + + auto const nodes = function->GetNodes(); + + // ToDo: Check the order of the nodes + + } } // namespace Lib3MF