From 55c37a1f87179c60ef0c2480d0f56ffaa6b77c12 Mon Sep 17 00:00:00 2001 From: "Orend, Dr Jan (ORJ)" <56254096+3dJan@users.noreply.github.com> Date: Thu, 2 Nov 2023 14:03:24 +0100 Subject: [PATCH] [Volumetric] Improving error messages --- Autogenerated/Bindings/C/lib3mf_types.h | 12 +- .../Bindings/CDynamic/lib3mf_types.h | 12 +- .../Bindings/Cpp/lib3mf_implicit.hpp | 10 +- Autogenerated/Bindings/Cpp/lib3mf_types.hpp | 12 +- .../Bindings/CppDynamic/lib3mf_dynamic.hpp | 10 +- .../Bindings/CppDynamic/lib3mf_types.hpp | 12 +- Autogenerated/Bindings/Go/lib3mf.go | 14 +- Autogenerated/Bindings/Go/lib3mf_types.h | 12 +- Autogenerated/Bindings/NodeJS/lib3mf_types.h | 12 +- Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas | 10 +- Autogenerated/Bindings/Python/Lib3MF.py | 4 + Autogenerated/Source/lib3mf_types.hpp | 12 +- AutomaticComponentToolkit/lib3mf.xml | 7 +- .../Model/Classes/NMR_ImplicitNodeTypes.cpp | 179 +++++++++--------- .../Classes/NMR_ModelImplicitFunction.cpp | 106 +++++++++-- Tests/CPP_Bindings/Source/Volumetric.cpp | 73 ++++++- 16 files changed, 364 insertions(+), 133 deletions(-) diff --git a/Autogenerated/Bindings/C/lib3mf_types.h b/Autogenerated/Bindings/C/lib3mf_types.h index 998f09f99..a43ce9619 100644 --- a/Autogenerated/Bindings/C/lib3mf_types.h +++ b/Autogenerated/Bindings/C/lib3mf_types.h @@ -136,7 +136,11 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND 3002 /** A consumer has not been found */ #define LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND 3003 /** A resource data has not been found */ #define LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED 3004 /** A Key or Conentent encryption callback has not been registered */ -#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key siue is invalid */ +#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key size is invalid */ +#define LIB3MF_ERROR_INCOMPATIBLEPORTTYPES 4000 /** Link could not be added, the port types are incompatible */ +#define LIB3MF_ERROR_GRAPHISCYCLIC 4001 /** The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted. */ +#define LIB3MF_ERROR_INPUTNOTSET 4002 /** The input of a node is not set. */ +#define LIB3MF_ERROR_INVALIDNODECONFIGURATION 4003 /** The selected node configuration is not supported */ /************************************************************************************************************************* Error strings for Lib3MF @@ -187,7 +191,11 @@ inline const char * LIB3MF_GETERRORSTRING (Lib3MFResult nErrorCode) { case LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND: return "A consumer has not been found"; case LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND: return "A resource data has not been found"; case LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED: return "A Key or Conentent encryption callback has not been registered"; - case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key siue is invalid"; + case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key size is invalid"; + case LIB3MF_ERROR_INCOMPATIBLEPORTTYPES: return "Link could not be added, the port types are incompatible"; + case LIB3MF_ERROR_GRAPHISCYCLIC: return "The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted."; + case LIB3MF_ERROR_INPUTNOTSET: return "The input of a node is not set."; + case LIB3MF_ERROR_INVALIDNODECONFIGURATION: return "The selected node configuration is not supported"; default: return "unknown error"; } } diff --git a/Autogenerated/Bindings/CDynamic/lib3mf_types.h b/Autogenerated/Bindings/CDynamic/lib3mf_types.h index 998f09f99..a43ce9619 100644 --- a/Autogenerated/Bindings/CDynamic/lib3mf_types.h +++ b/Autogenerated/Bindings/CDynamic/lib3mf_types.h @@ -136,7 +136,11 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND 3002 /** A consumer has not been found */ #define LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND 3003 /** A resource data has not been found */ #define LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED 3004 /** A Key or Conentent encryption callback has not been registered */ -#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key siue is invalid */ +#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key size is invalid */ +#define LIB3MF_ERROR_INCOMPATIBLEPORTTYPES 4000 /** Link could not be added, the port types are incompatible */ +#define LIB3MF_ERROR_GRAPHISCYCLIC 4001 /** The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted. */ +#define LIB3MF_ERROR_INPUTNOTSET 4002 /** The input of a node is not set. */ +#define LIB3MF_ERROR_INVALIDNODECONFIGURATION 4003 /** The selected node configuration is not supported */ /************************************************************************************************************************* Error strings for Lib3MF @@ -187,7 +191,11 @@ inline const char * LIB3MF_GETERRORSTRING (Lib3MFResult nErrorCode) { case LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND: return "A consumer has not been found"; case LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND: return "A resource data has not been found"; case LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED: return "A Key or Conentent encryption callback has not been registered"; - case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key siue is invalid"; + case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key size is invalid"; + case LIB3MF_ERROR_INCOMPATIBLEPORTTYPES: return "Link could not be added, the port types are incompatible"; + case LIB3MF_ERROR_GRAPHISCYCLIC: return "The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted."; + case LIB3MF_ERROR_INPUTNOTSET: return "The input of a node is not set."; + case LIB3MF_ERROR_INVALIDNODECONFIGURATION: return "The selected node configuration is not supported"; default: return "unknown error"; } } diff --git a/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp b/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp index 8bd6b7b8a..10b6224aa 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_implicit.hpp @@ -638,6 +638,10 @@ class ELib3MFException : public std::exception { case LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND: return "KEYSTORERESOURCEDATANOTFOUND"; case LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED: return "SECURECONTEXTNOTREGISTERED"; case LIB3MF_ERROR_INVALIDKEYSIZE: return "INVALIDKEYSIZE"; + case LIB3MF_ERROR_INCOMPATIBLEPORTTYPES: return "INCOMPATIBLEPORTTYPES"; + case LIB3MF_ERROR_GRAPHISCYCLIC: return "GRAPHISCYCLIC"; + case LIB3MF_ERROR_INPUTNOTSET: return "INPUTNOTSET"; + case LIB3MF_ERROR_INVALIDNODECONFIGURATION: return "INVALIDNODECONFIGURATION"; } return "UNKNOWN"; } @@ -688,7 +692,11 @@ class ELib3MFException : public std::exception { case LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND: return "A consumer has not been found"; case LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND: return "A resource data has not been found"; case LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED: return "A Key or Conentent encryption callback has not been registered"; - case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key siue is invalid"; + case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key size is invalid"; + case LIB3MF_ERROR_INCOMPATIBLEPORTTYPES: return "Link could not be added, the port types are incompatible"; + case LIB3MF_ERROR_GRAPHISCYCLIC: return "The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted."; + case LIB3MF_ERROR_INPUTNOTSET: return "The input of a node is not set."; + case LIB3MF_ERROR_INVALIDNODECONFIGURATION: return "The selected node configuration is not supported"; } return "unknown error"; } diff --git a/Autogenerated/Bindings/Cpp/lib3mf_types.hpp b/Autogenerated/Bindings/Cpp/lib3mf_types.hpp index a80775966..1b0d9bd95 100644 --- a/Autogenerated/Bindings/Cpp/lib3mf_types.hpp +++ b/Autogenerated/Bindings/Cpp/lib3mf_types.hpp @@ -135,7 +135,11 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND 3002 /** A consumer has not been found */ #define LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND 3003 /** A resource data has not been found */ #define LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED 3004 /** A Key or Conentent encryption callback has not been registered */ -#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key siue is invalid */ +#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key size is invalid */ +#define LIB3MF_ERROR_INCOMPATIBLEPORTTYPES 4000 /** Link could not be added, the port types are incompatible */ +#define LIB3MF_ERROR_GRAPHISCYCLIC 4001 /** The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted. */ +#define LIB3MF_ERROR_INPUTNOTSET 4002 /** The input of a node is not set. */ +#define LIB3MF_ERROR_INVALIDNODECONFIGURATION 4003 /** The selected node configuration is not supported */ /************************************************************************************************************************* Error strings for Lib3MF @@ -186,7 +190,11 @@ inline const char * LIB3MF_GETERRORSTRING (Lib3MFResult nErrorCode) { case LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND: return "A consumer has not been found"; case LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND: return "A resource data has not been found"; case LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED: return "A Key or Conentent encryption callback has not been registered"; - case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key siue is invalid"; + case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key size is invalid"; + case LIB3MF_ERROR_INCOMPATIBLEPORTTYPES: return "Link could not be added, the port types are incompatible"; + case LIB3MF_ERROR_GRAPHISCYCLIC: return "The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted."; + case LIB3MF_ERROR_INPUTNOTSET: return "The input of a node is not set."; + case LIB3MF_ERROR_INVALIDNODECONFIGURATION: return "The selected node configuration is not supported"; default: return "unknown error"; } } diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp index a4ff80dc3..c0cf38234 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_dynamic.hpp @@ -638,6 +638,10 @@ class ELib3MFException : public std::exception { case LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND: return "KEYSTORERESOURCEDATANOTFOUND"; case LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED: return "SECURECONTEXTNOTREGISTERED"; case LIB3MF_ERROR_INVALIDKEYSIZE: return "INVALIDKEYSIZE"; + case LIB3MF_ERROR_INCOMPATIBLEPORTTYPES: return "INCOMPATIBLEPORTTYPES"; + case LIB3MF_ERROR_GRAPHISCYCLIC: return "GRAPHISCYCLIC"; + case LIB3MF_ERROR_INPUTNOTSET: return "INPUTNOTSET"; + case LIB3MF_ERROR_INVALIDNODECONFIGURATION: return "INVALIDNODECONFIGURATION"; } return "UNKNOWN"; } @@ -688,7 +692,11 @@ class ELib3MFException : public std::exception { case LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND: return "A consumer has not been found"; case LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND: return "A resource data has not been found"; case LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED: return "A Key or Conentent encryption callback has not been registered"; - case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key siue is invalid"; + case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key size is invalid"; + case LIB3MF_ERROR_INCOMPATIBLEPORTTYPES: return "Link could not be added, the port types are incompatible"; + case LIB3MF_ERROR_GRAPHISCYCLIC: return "The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted."; + case LIB3MF_ERROR_INPUTNOTSET: return "The input of a node is not set."; + case LIB3MF_ERROR_INVALIDNODECONFIGURATION: return "The selected node configuration is not supported"; } return "unknown error"; } diff --git a/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp b/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp index a80775966..1b0d9bd95 100644 --- a/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp +++ b/Autogenerated/Bindings/CppDynamic/lib3mf_types.hpp @@ -135,7 +135,11 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND 3002 /** A consumer has not been found */ #define LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND 3003 /** A resource data has not been found */ #define LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED 3004 /** A Key or Conentent encryption callback has not been registered */ -#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key siue is invalid */ +#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key size is invalid */ +#define LIB3MF_ERROR_INCOMPATIBLEPORTTYPES 4000 /** Link could not be added, the port types are incompatible */ +#define LIB3MF_ERROR_GRAPHISCYCLIC 4001 /** The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted. */ +#define LIB3MF_ERROR_INPUTNOTSET 4002 /** The input of a node is not set. */ +#define LIB3MF_ERROR_INVALIDNODECONFIGURATION 4003 /** The selected node configuration is not supported */ /************************************************************************************************************************* Error strings for Lib3MF @@ -186,7 +190,11 @@ inline const char * LIB3MF_GETERRORSTRING (Lib3MFResult nErrorCode) { case LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND: return "A consumer has not been found"; case LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND: return "A resource data has not been found"; case LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED: return "A Key or Conentent encryption callback has not been registered"; - case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key siue is invalid"; + case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key size is invalid"; + case LIB3MF_ERROR_INCOMPATIBLEPORTTYPES: return "Link could not be added, the port types are incompatible"; + case LIB3MF_ERROR_GRAPHISCYCLIC: return "The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted."; + case LIB3MF_ERROR_INPUTNOTSET: return "The input of a node is not set."; + case LIB3MF_ERROR_INVALIDNODECONFIGURATION: return "The selected node configuration is not supported"; default: return "unknown error"; } } diff --git a/Autogenerated/Bindings/Go/lib3mf.go b/Autogenerated/Bindings/Go/lib3mf.go index 728fa8b87..d4b182415 100644 --- a/Autogenerated/Bindings/Go/lib3mf.go +++ b/Autogenerated/Bindings/Go/lib3mf.go @@ -5663,6 +5663,10 @@ const LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND = 3002; const LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND = 3003; const LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED = 3004; const LIB3MF_ERROR_INVALIDKEYSIZE = 3005; +const LIB3MF_ERROR_INCOMPATIBLEPORTTYPES = 4000; +const LIB3MF_ERROR_GRAPHISCYCLIC = 4001; +const LIB3MF_ERROR_INPUTNOTSET = 4002; +const LIB3MF_ERROR_INVALIDNODECONFIGURATION = 4003; // WrappedError is an error that wraps a Lib3MF error. type WrappedError struct { @@ -5761,7 +5765,15 @@ func errorMessage(errorcode uint32) string { case LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED: return "A Key or Conentent encryption callback has not been registered"; case LIB3MF_ERROR_INVALIDKEYSIZE: - return "The key siue is invalid"; + return "The key size is invalid"; + case LIB3MF_ERROR_INCOMPATIBLEPORTTYPES: + return "Link could not be added, the port types are incompatible"; + case LIB3MF_ERROR_GRAPHISCYCLIC: + return "The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted."; + case LIB3MF_ERROR_INPUTNOTSET: + return "The input of a node is not set."; + case LIB3MF_ERROR_INVALIDNODECONFIGURATION: + return "The selected node configuration is not supported"; default: return "unknown"; } diff --git a/Autogenerated/Bindings/Go/lib3mf_types.h b/Autogenerated/Bindings/Go/lib3mf_types.h index 998f09f99..a43ce9619 100644 --- a/Autogenerated/Bindings/Go/lib3mf_types.h +++ b/Autogenerated/Bindings/Go/lib3mf_types.h @@ -136,7 +136,11 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND 3002 /** A consumer has not been found */ #define LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND 3003 /** A resource data has not been found */ #define LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED 3004 /** A Key or Conentent encryption callback has not been registered */ -#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key siue is invalid */ +#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key size is invalid */ +#define LIB3MF_ERROR_INCOMPATIBLEPORTTYPES 4000 /** Link could not be added, the port types are incompatible */ +#define LIB3MF_ERROR_GRAPHISCYCLIC 4001 /** The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted. */ +#define LIB3MF_ERROR_INPUTNOTSET 4002 /** The input of a node is not set. */ +#define LIB3MF_ERROR_INVALIDNODECONFIGURATION 4003 /** The selected node configuration is not supported */ /************************************************************************************************************************* Error strings for Lib3MF @@ -187,7 +191,11 @@ inline const char * LIB3MF_GETERRORSTRING (Lib3MFResult nErrorCode) { case LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND: return "A consumer has not been found"; case LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND: return "A resource data has not been found"; case LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED: return "A Key or Conentent encryption callback has not been registered"; - case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key siue is invalid"; + case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key size is invalid"; + case LIB3MF_ERROR_INCOMPATIBLEPORTTYPES: return "Link could not be added, the port types are incompatible"; + case LIB3MF_ERROR_GRAPHISCYCLIC: return "The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted."; + case LIB3MF_ERROR_INPUTNOTSET: return "The input of a node is not set."; + case LIB3MF_ERROR_INVALIDNODECONFIGURATION: return "The selected node configuration is not supported"; default: return "unknown error"; } } diff --git a/Autogenerated/Bindings/NodeJS/lib3mf_types.h b/Autogenerated/Bindings/NodeJS/lib3mf_types.h index 998f09f99..a43ce9619 100644 --- a/Autogenerated/Bindings/NodeJS/lib3mf_types.h +++ b/Autogenerated/Bindings/NodeJS/lib3mf_types.h @@ -136,7 +136,11 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND 3002 /** A consumer has not been found */ #define LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND 3003 /** A resource data has not been found */ #define LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED 3004 /** A Key or Conentent encryption callback has not been registered */ -#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key siue is invalid */ +#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key size is invalid */ +#define LIB3MF_ERROR_INCOMPATIBLEPORTTYPES 4000 /** Link could not be added, the port types are incompatible */ +#define LIB3MF_ERROR_GRAPHISCYCLIC 4001 /** The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted. */ +#define LIB3MF_ERROR_INPUTNOTSET 4002 /** The input of a node is not set. */ +#define LIB3MF_ERROR_INVALIDNODECONFIGURATION 4003 /** The selected node configuration is not supported */ /************************************************************************************************************************* Error strings for Lib3MF @@ -187,7 +191,11 @@ inline const char * LIB3MF_GETERRORSTRING (Lib3MFResult nErrorCode) { case LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND: return "A consumer has not been found"; case LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND: return "A resource data has not been found"; case LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED: return "A Key or Conentent encryption callback has not been registered"; - case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key siue is invalid"; + case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key size is invalid"; + case LIB3MF_ERROR_INCOMPATIBLEPORTTYPES: return "Link could not be added, the port types are incompatible"; + case LIB3MF_ERROR_GRAPHISCYCLIC: return "The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted."; + case LIB3MF_ERROR_INPUTNOTSET: return "The input of a node is not set."; + case LIB3MF_ERROR_INVALIDNODECONFIGURATION: return "The selected node configuration is not supported"; default: return "unknown error"; } } diff --git a/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas b/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas index c6e91e431..d3444c2be 100644 --- a/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas +++ b/Autogenerated/Bindings/Pascal/Unit_Lib3MF.pas @@ -120,6 +120,10 @@ interface LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND = 3003; LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED = 3004; LIB3MF_ERROR_INVALIDKEYSIZE = 3005; + LIB3MF_ERROR_INCOMPATIBLEPORTTYPES = 4000; + LIB3MF_ERROR_GRAPHISCYCLIC = 4001; + LIB3MF_ERROR_INPUTNOTSET = 4002; + LIB3MF_ERROR_INVALIDNODECONFIGURATION = 4003; (************************************************************************************************************************* Declaration of enums @@ -11289,7 +11293,11 @@ implementation LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND: ADescription := 'A consumer has not been found'; LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND: ADescription := 'A resource data has not been found'; LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED: ADescription := 'A Key or Conentent encryption callback has not been registered'; - LIB3MF_ERROR_INVALIDKEYSIZE: ADescription := 'The key siue is invalid'; + LIB3MF_ERROR_INVALIDKEYSIZE: ADescription := 'The key size is invalid'; + LIB3MF_ERROR_INCOMPATIBLEPORTTYPES: ADescription := 'Link could not be added, the port types are incompatible'; + LIB3MF_ERROR_GRAPHISCYCLIC: ADescription := 'The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted.'; + LIB3MF_ERROR_INPUTNOTSET: ADescription := 'The input of a node is not set.'; + LIB3MF_ERROR_INVALIDNODECONFIGURATION: ADescription := 'The selected node configuration is not supported'; else ADescription := 'unknown'; end; diff --git a/Autogenerated/Bindings/Python/Lib3MF.py b/Autogenerated/Bindings/Python/Lib3MF.py index ceadb1384..64352c731 100644 --- a/Autogenerated/Bindings/Python/Lib3MF.py +++ b/Autogenerated/Bindings/Python/Lib3MF.py @@ -107,6 +107,10 @@ class ErrorCodes(enum.IntEnum): KEYSTORERESOURCEDATANOTFOUND = 3003 SECURECONTEXTNOTREGISTERED = 3004 INVALIDKEYSIZE = 3005 + INCOMPATIBLEPORTTYPES = 4000 + GRAPHISCYCLIC = 4001 + INPUTNOTSET = 4002 + INVALIDNODECONFIGURATION = 4003 '''Definition of Function Table ''' diff --git a/Autogenerated/Source/lib3mf_types.hpp b/Autogenerated/Source/lib3mf_types.hpp index a80775966..1b0d9bd95 100644 --- a/Autogenerated/Source/lib3mf_types.hpp +++ b/Autogenerated/Source/lib3mf_types.hpp @@ -135,7 +135,11 @@ typedef void * Lib3MF_pvoid; #define LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND 3002 /** A consumer has not been found */ #define LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND 3003 /** A resource data has not been found */ #define LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED 3004 /** A Key or Conentent encryption callback has not been registered */ -#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key siue is invalid */ +#define LIB3MF_ERROR_INVALIDKEYSIZE 3005 /** The key size is invalid */ +#define LIB3MF_ERROR_INCOMPATIBLEPORTTYPES 4000 /** Link could not be added, the port types are incompatible */ +#define LIB3MF_ERROR_GRAPHISCYCLIC 4001 /** The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted. */ +#define LIB3MF_ERROR_INPUTNOTSET 4002 /** The input of a node is not set. */ +#define LIB3MF_ERROR_INVALIDNODECONFIGURATION 4003 /** The selected node configuration is not supported */ /************************************************************************************************************************* Error strings for Lib3MF @@ -186,7 +190,11 @@ inline const char * LIB3MF_GETERRORSTRING (Lib3MFResult nErrorCode) { case LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND: return "A consumer has not been found"; case LIB3MF_ERROR_KEYSTORERESOURCEDATANOTFOUND: return "A resource data has not been found"; case LIB3MF_ERROR_SECURECONTEXTNOTREGISTERED: return "A Key or Conentent encryption callback has not been registered"; - case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key siue is invalid"; + case LIB3MF_ERROR_INVALIDKEYSIZE: return "The key size is invalid"; + case LIB3MF_ERROR_INCOMPATIBLEPORTTYPES: return "Link could not be added, the port types are incompatible"; + case LIB3MF_ERROR_GRAPHISCYCLIC: return "The functin graph is cyclic. Only dircected graphs are valid and can be topological sorted."; + case LIB3MF_ERROR_INPUTNOTSET: return "The input of a node is not set."; + case LIB3MF_ERROR_INVALIDNODECONFIGURATION: return "The selected node configuration is not supported"; default: return "unknown error"; } } diff --git a/AutomaticComponentToolkit/lib3mf.xml b/AutomaticComponentToolkit/lib3mf.xml index 7aa4015f0..dfcac4eb9 100644 --- a/AutomaticComponentToolkit/lib3mf.xml +++ b/AutomaticComponentToolkit/lib3mf.xml @@ -109,8 +109,13 @@ description="A resource data has not been found" /> - + + + + + diff --git a/Source/Model/Classes/NMR_ImplicitNodeTypes.cpp b/Source/Model/Classes/NMR_ImplicitNodeTypes.cpp index a13037004..910f650cd 100644 --- a/Source/Model/Classes/NMR_ImplicitNodeTypes.cpp +++ b/Source/Model/Classes/NMR_ImplicitNodeTypes.cpp @@ -28,10 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Model/Classes/NMR_ImplicitNodeTypes.h" -#include - #include "Common/NMR_Exception.h" #include "Model/Classes/NMR_ModelImplicitNode.h" +#include "lib3mf_interfaceexception.hpp" namespace NMR { @@ -73,7 +72,6 @@ namespace NMR In{{"A", eImplicitPortType::Matrix}, {"B", eImplicitPortType::Matrix}}, Out{{"result", eImplicitPortType::Matrix}}}}; - static AllowedInputOutputs const oneParameterFunctionSameDimensions{ InputOutputRule{ @@ -97,23 +95,19 @@ namespace NMR {eImplicitNodeType::Constant, {"constant", {InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, - In{}, Out{{"value", eImplicitPortType::Scalar}}}}}}, + Lib3MF::eImplicitNodeConfiguration::Default, In{}, + Out{{"value", eImplicitPortType::Scalar}}}}}}, {eImplicitNodeType::Multiplication, - { - "multiplication", twoParameterSameDimensions - }}, + {"multiplication", twoParameterSameDimensions}}, {eImplicitNodeType::Division, - { - "division", twoParameterSameDimensions - }}, + {"division", twoParameterSameDimensions}}, {eImplicitNodeType::ConstVec, { "constvec", { InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, - In{}, Out{{"vector", eImplicitPortType::Vector}}}, + Lib3MF::eImplicitNodeConfiguration::Default, In{}, + Out{{"vector", eImplicitPortType::Vector}}}, }, }}, {eImplicitNodeType::ConstMat, @@ -121,8 +115,8 @@ namespace NMR "constmat", { InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, - In{}, Out{{"matrix", eImplicitPortType::Matrix}}}, + Lib3MF::eImplicitNodeConfiguration::Default, In{}, + Out{{"matrix", eImplicitPortType::Matrix}}}, }, }}, {eImplicitNodeType::ComposeVector, @@ -130,11 +124,11 @@ namespace NMR "composevector", { InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, - In{{"x", eImplicitPortType::Scalar}, - {"y", eImplicitPortType::Scalar}, - {"z", eImplicitPortType::Scalar}}, - Out{{"result", eImplicitPortType::Vector}}}, + Lib3MF::eImplicitNodeConfiguration::Default, + In{{"x", eImplicitPortType::Scalar}, + {"y", eImplicitPortType::Scalar}, + {"z", eImplicitPortType::Scalar}}, + Out{{"result", eImplicitPortType::Vector}}}, }, }}, {eImplicitNodeType::DecomposeVector, @@ -142,11 +136,11 @@ namespace NMR "decomposevector", { InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, - In{{"A", eImplicitPortType::Vector}}, - Out{{"x", eImplicitPortType::Scalar}, - {"y", eImplicitPortType::Scalar}, - {"z", eImplicitPortType::Scalar}}}, + Lib3MF::eImplicitNodeConfiguration::Default, + In{{"A", eImplicitPortType::Vector}}, + Out{{"x", eImplicitPortType::Scalar}, + {"y", eImplicitPortType::Scalar}, + {"z", eImplicitPortType::Scalar}}}, }, }}, {eImplicitNodeType::ComposeMatrix, @@ -193,45 +187,45 @@ namespace NMR {eImplicitNodeType::Dot, {"dot", { - InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, - In{{"A", eImplicitPortType::Vector}, - {"B", eImplicitPortType::Vector}}, - Out{{"result", eImplicitPortType::Scalar}}}, + InputOutputRule{ + Lib3MF::eImplicitNodeConfiguration::Default, + In{{"A", eImplicitPortType::Vector}, + {"B", eImplicitPortType::Vector}}, + Out{{"result", eImplicitPortType::Scalar}}}, }}}, {eImplicitNodeType::Cross, {"cross", { InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, - In{{"A", eImplicitPortType::Vector}, - {"B", eImplicitPortType::Vector}}, - Out{{"result", eImplicitPortType::Vector}}}, + Lib3MF::eImplicitNodeConfiguration::Default, + In{{"A", eImplicitPortType::Vector}, + {"B", eImplicitPortType::Vector}}, + Out{{"result", eImplicitPortType::Vector}}}, }}}, {eImplicitNodeType::MatVecMultiplication, {"matvecmultiplication", { InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, - In{{"A", eImplicitPortType::Matrix}, - {"B", eImplicitPortType::Vector}}, - Out{{"result", eImplicitPortType::Vector}}}, + Lib3MF::eImplicitNodeConfiguration::Default, + In{{"A", eImplicitPortType::Matrix}, + {"B", eImplicitPortType::Vector}}, + Out{{"result", eImplicitPortType::Vector}}}, }}}, {eImplicitNodeType::Transpose, {"transpose", { InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, - In{{"A", eImplicitPortType::Matrix}}, - Out{{"result", eImplicitPortType::Matrix}}}, + Lib3MF::eImplicitNodeConfiguration::Default, + In{{"A", eImplicitPortType::Matrix}}, + Out{{"result", eImplicitPortType::Matrix}}}, }}}, {eImplicitNodeType::Inverse, {"inverse", { InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, - In{{"A", eImplicitPortType::Matrix}}, - Out{{"result", eImplicitPortType::Matrix}}}, + Lib3MF::eImplicitNodeConfiguration::Default, + In{{"A", eImplicitPortType::Matrix}}, + Out{{"result", eImplicitPortType::Matrix}}}, }}}, {eImplicitNodeType::Sinus, {"sin", oneParameterFunctionSameDimensions}}, @@ -247,16 +241,12 @@ namespace NMR {"atan", oneParameterFunctionSameDimensions}}, {eImplicitNodeType::ArcTan2, {"atan2", twoParameterSameDimensions}}, - {eImplicitNodeType::Min, - {"min", twoParameterSameDimensions}}, - {eImplicitNodeType::Max, - {"max", twoParameterSameDimensions}}, + {eImplicitNodeType::Min, {"min", twoParameterSameDimensions}}, + {eImplicitNodeType::Max, {"max", twoParameterSameDimensions}}, {eImplicitNodeType::Abs, {"abs", oneParameterFunctionSameDimensions}}, - {eImplicitNodeType::Fmod, - {"fmod", twoParameterSameDimensions}}, - {eImplicitNodeType::Pow, - {"pow", twoParameterSameDimensions}}, + {eImplicitNodeType::Fmod, {"fmod", twoParameterSameDimensions}}, + {eImplicitNodeType::Pow, {"pow", twoParameterSameDimensions}}, {eImplicitNodeType::Sqrt, {"sqrt", oneParameterFunctionSameDimensions}}, {eImplicitNodeType::Exp, @@ -287,21 +277,21 @@ namespace NMR {"select", // result = A < B ? C : D { InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::ScalarToScalar, + Lib3MF::eImplicitNodeConfiguration::ScalarToScalar, In{{"A", eImplicitPortType::Scalar}, {"B", eImplicitPortType::Scalar}, {"C", eImplicitPortType::Scalar}, {"D", eImplicitPortType::Scalar}}, Out{{"result", eImplicitPortType::Scalar}}}, InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::VectorToVector, + Lib3MF::eImplicitNodeConfiguration::VectorToVector, In{{"A", eImplicitPortType::Vector}, {"B", eImplicitPortType::Vector}, {"C", eImplicitPortType::Vector}, {"D", eImplicitPortType::Vector}}, Out{{"result", eImplicitPortType::Vector}}}, InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::MatrixToMatrix, + Lib3MF::eImplicitNodeConfiguration::MatrixToMatrix, In{{"A", eImplicitPortType::Matrix}, {"B", eImplicitPortType::Matrix}, {"C", eImplicitPortType::Matrix}, @@ -309,23 +299,23 @@ namespace NMR Out{{"result", eImplicitPortType::Matrix}}}, }}}, - {eImplicitNodeType::Clamp, // result = min(max(A, min), max) + {eImplicitNodeType::Clamp, // result = min(max(A, min), max) {"clamp", { InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::ScalarToScalar, + Lib3MF::eImplicitNodeConfiguration::ScalarToScalar, In{{"A", eImplicitPortType::Scalar}, {"min", eImplicitPortType::Scalar}, {"max", eImplicitPortType::Scalar}}, Out{{"result", eImplicitPortType::Scalar}}}, InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::VectorToVector, + Lib3MF::eImplicitNodeConfiguration::VectorToVector, In{{"A", eImplicitPortType::Vector}, {"min", eImplicitPortType::Vector}, {"max", eImplicitPortType::Vector}}, Out{{"result", eImplicitPortType::Vector}}}, InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::MatrixToMatrix, + Lib3MF::eImplicitNodeConfiguration::MatrixToMatrix, In{{"A", eImplicitPortType::Matrix}, {"min", eImplicitPortType::Matrix}, {"max", eImplicitPortType::Matrix}}, @@ -335,7 +325,7 @@ namespace NMR {"length", { InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, + Lib3MF::eImplicitNodeConfiguration::Default, In{{"A", eImplicitPortType::Vector}}, Out{{"result", eImplicitPortType::Scalar}}}, }}}, @@ -343,14 +333,14 @@ namespace NMR {"resource", { InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, - In{}, Out{{"value", eImplicitPortType::ResourceID}}}, + Lib3MF::eImplicitNodeConfiguration::Default, In{}, + Out{{"value", eImplicitPortType::ResourceID}}}, }}}, {eImplicitNodeType::Mesh, {"mesh", { InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, + Lib3MF::eImplicitNodeConfiguration::Default, In{{"pos", eImplicitPortType::Vector}, {"mesh", eImplicitPortType::ResourceID}}, Out{{"distance", eImplicitPortType::Scalar}}}, @@ -358,9 +348,11 @@ namespace NMR {eImplicitNodeType::FunctionCall, {"functioncall", {InputOutputRule{ - Lib3MF::eImplicitNodeConfiguration::Default, + Lib3MF::eImplicitNodeConfiguration::Default, In{{"functionID", - eImplicitPortType::ResourceID}}, // not predefined besides the functionID + eImplicitPortType::ResourceID}}, // not predefined + // besides the + // functionID Out{} // not predefined }}}}}; } @@ -371,9 +363,10 @@ namespace NMR auto it = m_nodeTypes.find(type); if(it == m_nodeTypes.end()) { - std::cerr << "Unknown node type: " << static_cast(type) - << std::endl; - throw CNMRException(NMR_ERROR_UNKNOWN_NODETYPE_IMPLICITMODEL); + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INVALIDNODECONFIGURATION, + "Unknown node type " + + std::to_string(static_cast(type))); } return it->second; } @@ -389,10 +382,10 @@ namespace NMR if(nodeType.getAllowedInputOutputs().empty()) { - std::cerr << "InputOutput map for node type: " - << static_cast(node.getNodeType()) << " is empty" - << std::endl; - throw CNMRException(NMR_ERROR_UNKNOWN_NODETYPE_IMPLICITMODEL); + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INVALIDNODECONFIGURATION, + "No known configuration for node type " + + std::to_string(static_cast(node.getNodeType()))); } applyInputOutputRuleToNode( node, nodeType.getAllowedInputOutputs().front()); @@ -402,7 +395,7 @@ namespace NMR NMR::CModelImplicitNode& node, Lib3MF::eImplicitNodeConfiguration const configuration) const { - if (configuration == Lib3MF::eImplicitNodeConfiguration::Default) + if(configuration == Lib3MF::eImplicitNodeConfiguration::Default) { addExpectedPortsToNode(node); return; @@ -411,34 +404,37 @@ namespace NMR auto const& nodeType = getNodeType(node.getNodeType()); if(nodeType.getAllowedInputOutputs().empty()) { - std::cerr << "InputOutput map for node type: " - << static_cast(node.getNodeType()) << " is empty" - << std::endl; - throw CNMRException(NMR_ERROR_UNKNOWN_NODETYPE_IMPLICITMODEL); + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INVALIDNODECONFIGURATION, + "No known configuration for node type " + + std::to_string(static_cast(node.getNodeType()))); } - if ((nodeType.getAllowedInputOutputs().size() == 1u) && configuration != Lib3MF::eImplicitNodeConfiguration::Default) + if((nodeType.getAllowedInputOutputs().size() == 1u) && + configuration != Lib3MF::eImplicitNodeConfiguration::Default) { - std::cerr << "Node type: " - << static_cast(node.getNodeType()) << " only supports the default configuration" - << std::endl; - throw CNMRException(NMR_ERROR_UNKNOWN_NODETYPE_IMPLICITMODEL); + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INVALIDNODECONFIGURATION, + "Node type: " + + std::to_string(static_cast(node.getNodeType())) + + " only supports the default configuration"); } - for (auto const& rule : nodeType.getAllowedInputOutputs()) + for(auto const& rule : nodeType.getAllowedInputOutputs()) { - if (rule.configuration == configuration) + if(rule.configuration == configuration) { applyInputOutputRuleToNode(node, rule); return; } } - std::cerr << "No rule for configuration: " - << static_cast(configuration) << " for node type: " - << static_cast(node.getNodeType()) << std::endl; - - throw CNMRException(NMR_ERROR_UNKNOWN_NODETYPE_IMPLICITMODEL); + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INVALIDNODECONFIGURATION, + "Node type: " + + std::to_string(static_cast(node.getNodeType())) + + " does not support configuration: " + + std::to_string(static_cast(configuration))); } void NodeTypes::applyInputOutputRuleToNode( @@ -470,8 +466,9 @@ namespace NMR return false; } - bool NodeTypes::arePortsValidForRule(NMR::CModelImplicitNode const& node, - InputOutputRule const& rule) const + bool NodeTypes::arePortsValidForRule( + NMR::CModelImplicitNode const& node, + InputOutputRule const& rule) const { for(auto const& input : rule.inputs) { diff --git a/Source/Model/Classes/NMR_ModelImplicitFunction.cpp b/Source/Model/Classes/NMR_ModelImplicitFunction.cpp index 8f1cd9e57..3064b836a 100644 --- a/Source/Model/Classes/NMR_ModelImplicitFunction.cpp +++ b/Source/Model/Classes/NMR_ModelImplicitFunction.cpp @@ -29,9 +29,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Model/Classes/NMR_ModelImplicitFunction.h" #include "Common/NMR_Exception.h" +#include "lib3mf_interfaceexception.hpp" +#include "lib3mf_types.hpp" #include "Model/Classes/NMR_ImplicitNodeTypes.h" -#include "Model/Classes/NMR_ModelImplicitPort.h" #include "Model/Classes/NMR_ModelImplicitFunction.h" +#include "Model/Classes/NMR_ModelImplicitPort.h" #include #include @@ -111,14 +113,17 @@ namespace NMR auto const sourceNode = findNode(sourceNodeName); if(sourceNode == nullptr) { - throw CNMRException( - NMR_ERROR_IMPLICIT_FUNCTION_INVALID_SOURCE_NODE); + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INVALIDPARAM, + "Source node " + sourceNodeName + " does not exist."); } auto const sourcePortName = extractPortName(sSourceNodeIdentifier); if(sourcePortName.empty()) { - throw CNMRException( - NMR_ERROR_IMPLICIT_FUNCTION_INVALID_SOURCE_PORT); + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INVALIDPARAM, + "Source port " + sourcePortName + " of node " + + sourceNodeName + " does not exist."); } sourcePort = sourceNode->findOutput(sourcePortName); } @@ -140,14 +145,17 @@ namespace NMR auto const targetNode = findNode(targetNodeName); if(targetNode == nullptr) { - throw CNMRException( - NMR_ERROR_IMPLICIT_FUNCTION_INVALID_TARGET_NODE); + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INVALIDPARAM, + "Target node " + targetNodeName + " does not exist."); } if(targetPortName.empty()) { - throw CNMRException( - NMR_ERROR_IMPLICIT_FUNCTION_INVALID_TARGET_PORT); + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INVALIDPARAM, + "Target port " + targetPortName + " of node " + + targetNodeName + " does not exist."); } targetPort = targetNode->findInput(targetPortName); @@ -155,13 +163,37 @@ namespace NMR if(!targetPort) { - throw CNMRException( - NMR_ERROR_IMPLICIT_FUNCTION_INVALID_TARGET_PORT); + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INVALIDPARAM, + "Target port " + targetPortName + " of node " + + targetNodeName + " does not exist."); } if(sourcePort->getType() != targetPort->getType()) { - throw CNMRException(NMR_ERROR_IMPLICIT_FUNCTION_INVALID_PORT_TYPE); + std::string sourceNodeIdentifier = "function inputs"; + std::string targetNodeIdentifier = "function outputs"; + + if(sourcePort->getParent()) + { + sourceNodeIdentifier = sourcePort->getParent()->getIdentifier(); + } + + if(targetPort->getParent()) + { + targetNodeIdentifier = targetPort->getParent()->getIdentifier(); + } + + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INCOMPATIBLEPORTTYPES, + "Output " + sourcePort->getIdentifier() + " of node " + + sourceNodeIdentifier + " has type " + + std::to_string(static_cast(sourcePort->getType())) + + " while target input " + targetPort->getIdentifier() + + " of node " + targetNodeIdentifier + " has type " + + std::to_string(static_cast(targetPort->getType())) + + "."); + } targetPort->setReference(sSourceNodeIdentifier); @@ -175,13 +207,41 @@ namespace NMR void CModelImplicitFunction::addLink(CModelImplicitPort const & pSourcePort, CModelImplicitPort & pTargetPort) { - if (pSourcePort.getParent() == nullptr) // That is the case for a function input + if(pSourcePort.getType() != pTargetPort.getType()) + { + std::string sourceNodeIdentifier = "function inputs"; + std::string targetNodeIdentifier = "function outputs"; + + if(pSourcePort.getParent()) + { + sourceNodeIdentifier = pSourcePort.getParent()->getIdentifier(); + } + + if(pTargetPort.getParent()) + { + targetNodeIdentifier = pTargetPort.getParent()->getIdentifier(); + } + + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INCOMPATIBLEPORTTYPES, + "Output " + pSourcePort.getIdentifier() + " of node " + + sourceNodeIdentifier + " has type " + + std::to_string(static_cast(pSourcePort.getType())) + + " while target input " + pTargetPort.getIdentifier() + + " of node " + targetNodeIdentifier + " has type " + + std::to_string(static_cast(pTargetPort.getType())) + + "."); + } + if(pSourcePort.getParent() == + nullptr) // That is the case for a function input { pTargetPort.setReference(pSourcePort.getIdentifier()); + return; } - pTargetPort.setReference(makeReferenceIdentifier(pSourcePort.getParent()->getIdentifier(), - pSourcePort.getIdentifier())); + pTargetPort.setReference( + makeReferenceIdentifier(pSourcePort.getParent()->getIdentifier(), + pSourcePort.getIdentifier())); } implicit::NodeTypes const& CModelImplicitFunction::getNodeTypes() const @@ -267,11 +327,23 @@ namespace NMR for (auto const& port : *node->getInputs()) { auto const& referenceName = port->getReference(); + if (referenceName.empty()) + { + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INPUTNOTSET, + "Input " + port->getIdentifier() + " of node " + + node->getIdentifier() + " is not set."); + } auto const& sourceNodeName = extractNodeName(referenceName); CModelImplicitNode* sourceNode = findNode(sourceNodeName); if (sourceNode == nullptr) { - throw CNMRException(NMR_ERROR_IMPLICIT_FUNCTION_INVALID_SOURCE_NODE); + throw ELib3MFInterfaceException( + LIB3MF_ERROR_INVALIDPARAM, + "Input " + port->getIdentifier() + " of node " + + node->getIdentifier() + + " references a non-existing node " + + sourceNodeName + "."); } auto const& sourceId = sourceNode->getGraphID(); graph[sourceId].push_back(id); @@ -310,7 +382,7 @@ namespace NMR // Check if there is a cycle in the graph if (sortedNodes.size() != m_nodes->size()) { - throw CNMRException(NMR_ERROR_IMPLICIT_FUNCTION_CYCLIC_GRAPH); + throw ELib3MFInterfaceException(LIB3MF_ERROR_GRAPHISCYCLIC, "The graph of the implicit function " + getIdentifier() + " is cyclic."); } // Update the node order diff --git a/Tests/CPP_Bindings/Source/Volumetric.cpp b/Tests/CPP_Bindings/Source/Volumetric.cpp index ba82285bc..70ce979f1 100644 --- a/Tests/CPP_Bindings/Source/Volumetric.cpp +++ b/Tests/CPP_Bindings/Source/Volumetric.cpp @@ -315,7 +315,7 @@ namespace Lib3MF auto output = newFunction->AddOutput("shape", "signed distance to the surface", - Lib3MF::eImplicitPortType::Vector); + Lib3MF::eImplicitPortType::Scalar); newFunction->AddLink(subNode->GetOutputResult().get(), output.get()); @@ -1011,14 +1011,75 @@ namespace Lib3MF writer3MF->WriteToFile(Volumetric::OutFolder + "TwoFunctions.3mf"); } - TEST_F(Volumetric, SortNodesTopologically_SimpleFunction_SortedNodes) + TEST_F(Volumetric, AddLink_InvalidTypes_ThrowsException) { - // auto const function = helper::createGyroidFunction(*model); + auto const function = model->AddImplicitFunction(); + + auto const constVector = function->AddConstVecNode( + "constVector", "constVector", "group_constVector"); - // function->SortNodesTopologically(); + auto const scalarAdd = function->AddAdditionNode( + "scalarAdd", Lib3MF::eImplicitNodeConfiguration::ScalarToScalar, + "scalarAdd", "group_scalarAdd"); - // auto const nodes = function->GetNodes(); + auto const inputA = scalarAdd->GetInputA(); + auto const vectorOutput = constVector->GetOutputVector(); + EXPECT_THROW(function->AddLink(inputA, vectorOutput), + ELib3MFException); + } - // ToDo: Check the order of the nodes + /** + * @brief Test case for sorting nodes topologically. The function creates a cyclic graph with three nodes and sets up circular + * dependencies between them. The test expects the function to throw an exception when trying to sort the nodes topologically. + * + * Graph structure: + * + * +--------+ + * | | + * v | + * +-------+ | + * | add1 | | + * +-------+ | + * ^ | + * | | + * +-----------+ | + * | constVec1 | | + * +-----------+ | + * | | + * v | + * +-------+ | + * | add2 | | + * +-------+ | + * ^ | + * | | + * +--------+ + * + */ + TEST_F(Volumetric, SortNodesTopologically_CyclicGraph_Throws) + { + auto const function = model->AddImplicitFunction(); + + function->AddInput("pos", "position", Lib3MF::eImplicitPortType::Vector); + // Add nodes with circular dependencies + auto const constVec1 = function->AddConstVecNode("constVec1", "constVec1", "group1"); + auto const add1 = function->AddAdditionNode("add1", Lib3MF::eImplicitNodeConfiguration::VectorToVector, "add1", "group1"); + auto const add2 = function->AddAdditionNode("add2", Lib3MF::eImplicitNodeConfiguration::VectorToVector, "add2", "group1"); + + // Set up circular dependencies + auto const vectorOutput = constVec1->GetOutputVector(); + auto const inputAdd1A = add1->GetInputA(); + auto const inputAdd1B = add1->GetInputB(); + + auto const inputAdd2A = add2->GetInputA(); + auto const inputAdd2B = add2->GetInputB(); + + auto const outputAdd1 = add1->GetOutputResult(); + auto const outputAdd2 = add2->GetOutputResult(); + function->AddLink(vectorOutput, inputAdd1A); + function->AddLink(outputAdd2, inputAdd1B); + function->AddLink(outputAdd1, inputAdd1A); + function->AddLink(vectorOutput, inputAdd2A); + function->AddLink(outputAdd1, inputAdd2B); + EXPECT_THROW(function->SortNodesTopologically(), ELib3MFException); } } // namespace Lib3MF