/*++

Copyright (C) 2024 3MF Consortium (Original Author)

All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This file has been generated by the Automatic Component Toolkit (ACT) version 1.8.1-develop.

Abstract: This is an autogenerated C++-Header file in order to allow an easy
 use of the 3MF Library

Interface version: 2.5.0

*/

#ifndef __LIB3MF_CPPHEADER_IMPLICIT_CPP
#define __LIB3MF_CPPHEADER_IMPLICIT_CPP

#include "lib3mf_types.hpp"
#include "lib3mf_abi.hpp"


#ifdef _WIN32
#include <windows.h>
#else // _WIN32
#include <dlfcn.h>
#endif // _WIN32
#include <array>
#include <string>
#include <memory>
#include <vector>
#include <exception>

namespace Lib3MF {

/*************************************************************************************************************************
 Forward Declaration of all classes
**************************************************************************************************************************/
class CWrapper;
class CBase;
class CWriter;
class CReader;
class CPackagePart;
class CResource;
class CResourceIterator;
class CSliceStackIterator;
class CObjectIterator;
class CMeshObjectIterator;
class CComponentsObjectIterator;
class CTexture2DIterator;
class CBaseMaterialGroupIterator;
class CColorGroupIterator;
class CTexture2DGroupIterator;
class CCompositeMaterialsIterator;
class CMultiPropertyGroupIterator;
class CImage3DIterator;
class CFunctionIterator;
class CLevelSetIterator;
class CMetaData;
class CMetaDataGroup;
class CTriangleSet;
class CObject;
class CMeshObject;
class CLevelSet;
class CBeamLattice;
class CFunctionReference;
class CVolumeDataColor;
class CMaterialMapping;
class CVolumeDataComposite;
class CVolumeDataProperty;
class CVolumeData;
class CComponent;
class CComponentsObject;
class CBeamSet;
class CBaseMaterialGroup;
class CColorGroup;
class CTexture2DGroup;
class CCompositeMaterials;
class CMultiPropertyGroup;
class CImage3D;
class CImageStack;
class CAttachment;
class CTexture2D;
class CImplicitPort;
class CIterator;
class CImplicitPortIterator;
class CImplicitNode;
class COneInputNode;
class CSinNode;
class CCosNode;
class CTanNode;
class CArcSinNode;
class CArcCosNode;
class CArcTanNode;
class CSinhNode;
class CCoshNode;
class CTanhNode;
class CRoundNode;
class CCeilNode;
class CFloorNode;
class CSignNode;
class CFractNode;
class CAbsNode;
class CExpNode;
class CLogNode;
class CLog2Node;
class CLog10Node;
class CLengthNode;
class CTransposeNode;
class CInverseNode;
class CSqrtNode;
class CResourceIdNode;
class CTwoInputNode;
class CAdditionNode;
class CSubtractionNode;
class CMultiplicationNode;
class CDivisionNode;
class CDotNode;
class CCrossNode;
class CArcTan2Node;
class CMatVecMultiplicationNode;
class CMinNode;
class CMaxNode;
class CFmodNode;
class CModNode;
class CPowNode;
class CSelectNode;
class CClampNode;
class CComposeVectorNode;
class CVectorFromScalarNode;
class CDecomposeVectorNode;
class CComposeMatrixNode;
class CMatrixFromRowsNode;
class CMatrixFromColumnsNode;
class CConstantNode;
class CConstVecNode;
class CConstMatNode;
class CMeshNode;
class CUnsignedMeshNode;
class CBeamLatticeNode;
class CFunctionGradientNode;
class CNormalizeDistanceNode;
class CFunctionCallNode;
class CNodeIterator;
class CFunction;
class CImplicitFunction;
class CFunctionFromImage3D;
class CBuildItem;
class CBuildItemIterator;
class CSlice;
class CSliceStack;
class CConsumer;
class CAccessRight;
class CContentEncryptionParams;
class CResourceData;
class CResourceDataGroup;
class CKeyStore;
class CModel;

/*************************************************************************************************************************
 Declaration of deprecated class types
**************************************************************************************************************************/
typedef CWrapper CLib3MFWrapper;
typedef CBase CLib3MFBase;
typedef CWriter CLib3MFWriter;
typedef CReader CLib3MFReader;
typedef CPackagePart CLib3MFPackagePart;
typedef CResource CLib3MFResource;
typedef CResourceIterator CLib3MFResourceIterator;
typedef CSliceStackIterator CLib3MFSliceStackIterator;
typedef CObjectIterator CLib3MFObjectIterator;
typedef CMeshObjectIterator CLib3MFMeshObjectIterator;
typedef CComponentsObjectIterator CLib3MFComponentsObjectIterator;
typedef CTexture2DIterator CLib3MFTexture2DIterator;
typedef CBaseMaterialGroupIterator CLib3MFBaseMaterialGroupIterator;
typedef CColorGroupIterator CLib3MFColorGroupIterator;
typedef CTexture2DGroupIterator CLib3MFTexture2DGroupIterator;
typedef CCompositeMaterialsIterator CLib3MFCompositeMaterialsIterator;
typedef CMultiPropertyGroupIterator CLib3MFMultiPropertyGroupIterator;
typedef CImage3DIterator CLib3MFImage3DIterator;
typedef CFunctionIterator CLib3MFFunctionIterator;
typedef CLevelSetIterator CLib3MFLevelSetIterator;
typedef CMetaData CLib3MFMetaData;
typedef CMetaDataGroup CLib3MFMetaDataGroup;
typedef CTriangleSet CLib3MFTriangleSet;
typedef CObject CLib3MFObject;
typedef CMeshObject CLib3MFMeshObject;
typedef CLevelSet CLib3MFLevelSet;
typedef CBeamLattice CLib3MFBeamLattice;
typedef CFunctionReference CLib3MFFunctionReference;
typedef CVolumeDataColor CLib3MFVolumeDataColor;
typedef CMaterialMapping CLib3MFMaterialMapping;
typedef CVolumeDataComposite CLib3MFVolumeDataComposite;
typedef CVolumeDataProperty CLib3MFVolumeDataProperty;
typedef CVolumeData CLib3MFVolumeData;
typedef CComponent CLib3MFComponent;
typedef CComponentsObject CLib3MFComponentsObject;
typedef CBeamSet CLib3MFBeamSet;
typedef CBaseMaterialGroup CLib3MFBaseMaterialGroup;
typedef CColorGroup CLib3MFColorGroup;
typedef CTexture2DGroup CLib3MFTexture2DGroup;
typedef CCompositeMaterials CLib3MFCompositeMaterials;
typedef CMultiPropertyGroup CLib3MFMultiPropertyGroup;
typedef CImage3D CLib3MFImage3D;
typedef CImageStack CLib3MFImageStack;
typedef CAttachment CLib3MFAttachment;
typedef CTexture2D CLib3MFTexture2D;
typedef CImplicitPort CLib3MFImplicitPort;
typedef CIterator CLib3MFIterator;
typedef CImplicitPortIterator CLib3MFImplicitPortIterator;
typedef CImplicitNode CLib3MFImplicitNode;
typedef COneInputNode CLib3MFOneInputNode;
typedef CSinNode CLib3MFSinNode;
typedef CCosNode CLib3MFCosNode;
typedef CTanNode CLib3MFTanNode;
typedef CArcSinNode CLib3MFArcSinNode;
typedef CArcCosNode CLib3MFArcCosNode;
typedef CArcTanNode CLib3MFArcTanNode;
typedef CSinhNode CLib3MFSinhNode;
typedef CCoshNode CLib3MFCoshNode;
typedef CTanhNode CLib3MFTanhNode;
typedef CRoundNode CLib3MFRoundNode;
typedef CCeilNode CLib3MFCeilNode;
typedef CFloorNode CLib3MFFloorNode;
typedef CSignNode CLib3MFSignNode;
typedef CFractNode CLib3MFFractNode;
typedef CAbsNode CLib3MFAbsNode;
typedef CExpNode CLib3MFExpNode;
typedef CLogNode CLib3MFLogNode;
typedef CLog2Node CLib3MFLog2Node;
typedef CLog10Node CLib3MFLog10Node;
typedef CLengthNode CLib3MFLengthNode;
typedef CTransposeNode CLib3MFTransposeNode;
typedef CInverseNode CLib3MFInverseNode;
typedef CSqrtNode CLib3MFSqrtNode;
typedef CResourceIdNode CLib3MFResourceIdNode;
typedef CTwoInputNode CLib3MFTwoInputNode;
typedef CAdditionNode CLib3MFAdditionNode;
typedef CSubtractionNode CLib3MFSubtractionNode;
typedef CMultiplicationNode CLib3MFMultiplicationNode;
typedef CDivisionNode CLib3MFDivisionNode;
typedef CDotNode CLib3MFDotNode;
typedef CCrossNode CLib3MFCrossNode;
typedef CArcTan2Node CLib3MFArcTan2Node;
typedef CMatVecMultiplicationNode CLib3MFMatVecMultiplicationNode;
typedef CMinNode CLib3MFMinNode;
typedef CMaxNode CLib3MFMaxNode;
typedef CFmodNode CLib3MFFmodNode;
typedef CModNode CLib3MFModNode;
typedef CPowNode CLib3MFPowNode;
typedef CSelectNode CLib3MFSelectNode;
typedef CClampNode CLib3MFClampNode;
typedef CComposeVectorNode CLib3MFComposeVectorNode;
typedef CVectorFromScalarNode CLib3MFVectorFromScalarNode;
typedef CDecomposeVectorNode CLib3MFDecomposeVectorNode;
typedef CComposeMatrixNode CLib3MFComposeMatrixNode;
typedef CMatrixFromRowsNode CLib3MFMatrixFromRowsNode;
typedef CMatrixFromColumnsNode CLib3MFMatrixFromColumnsNode;
typedef CConstantNode CLib3MFConstantNode;
typedef CConstVecNode CLib3MFConstVecNode;
typedef CConstMatNode CLib3MFConstMatNode;
typedef CMeshNode CLib3MFMeshNode;
typedef CUnsignedMeshNode CLib3MFUnsignedMeshNode;
typedef CBeamLatticeNode CLib3MFBeamLatticeNode;
typedef CFunctionGradientNode CLib3MFFunctionGradientNode;
typedef CNormalizeDistanceNode CLib3MFNormalizeDistanceNode;
typedef CFunctionCallNode CLib3MFFunctionCallNode;
typedef CNodeIterator CLib3MFNodeIterator;
typedef CFunction CLib3MFFunction;
typedef CImplicitFunction CLib3MFImplicitFunction;
typedef CFunctionFromImage3D CLib3MFFunctionFromImage3D;
typedef CBuildItem CLib3MFBuildItem;
typedef CBuildItemIterator CLib3MFBuildItemIterator;
typedef CSlice CLib3MFSlice;
typedef CSliceStack CLib3MFSliceStack;
typedef CConsumer CLib3MFConsumer;
typedef CAccessRight CLib3MFAccessRight;
typedef CContentEncryptionParams CLib3MFContentEncryptionParams;
typedef CResourceData CLib3MFResourceData;
typedef CResourceDataGroup CLib3MFResourceDataGroup;
typedef CKeyStore CLib3MFKeyStore;
typedef CModel CLib3MFModel;

/*************************************************************************************************************************
 Declaration of shared pointer types
**************************************************************************************************************************/
typedef std::shared_ptr<CWrapper> PWrapper;
typedef std::shared_ptr<CBase> PBase;
typedef std::shared_ptr<CWriter> PWriter;
typedef std::shared_ptr<CReader> PReader;
typedef std::shared_ptr<CPackagePart> PPackagePart;
typedef std::shared_ptr<CResource> PResource;
typedef std::shared_ptr<CResourceIterator> PResourceIterator;
typedef std::shared_ptr<CSliceStackIterator> PSliceStackIterator;
typedef std::shared_ptr<CObjectIterator> PObjectIterator;
typedef std::shared_ptr<CMeshObjectIterator> PMeshObjectIterator;
typedef std::shared_ptr<CComponentsObjectIterator> PComponentsObjectIterator;
typedef std::shared_ptr<CTexture2DIterator> PTexture2DIterator;
typedef std::shared_ptr<CBaseMaterialGroupIterator> PBaseMaterialGroupIterator;
typedef std::shared_ptr<CColorGroupIterator> PColorGroupIterator;
typedef std::shared_ptr<CTexture2DGroupIterator> PTexture2DGroupIterator;
typedef std::shared_ptr<CCompositeMaterialsIterator> PCompositeMaterialsIterator;
typedef std::shared_ptr<CMultiPropertyGroupIterator> PMultiPropertyGroupIterator;
typedef std::shared_ptr<CImage3DIterator> PImage3DIterator;
typedef std::shared_ptr<CFunctionIterator> PFunctionIterator;
typedef std::shared_ptr<CLevelSetIterator> PLevelSetIterator;
typedef std::shared_ptr<CMetaData> PMetaData;
typedef std::shared_ptr<CMetaDataGroup> PMetaDataGroup;
typedef std::shared_ptr<CTriangleSet> PTriangleSet;
typedef std::shared_ptr<CObject> PObject;
typedef std::shared_ptr<CMeshObject> PMeshObject;
typedef std::shared_ptr<CLevelSet> PLevelSet;
typedef std::shared_ptr<CBeamLattice> PBeamLattice;
typedef std::shared_ptr<CFunctionReference> PFunctionReference;
typedef std::shared_ptr<CVolumeDataColor> PVolumeDataColor;
typedef std::shared_ptr<CMaterialMapping> PMaterialMapping;
typedef std::shared_ptr<CVolumeDataComposite> PVolumeDataComposite;
typedef std::shared_ptr<CVolumeDataProperty> PVolumeDataProperty;
typedef std::shared_ptr<CVolumeData> PVolumeData;
typedef std::shared_ptr<CComponent> PComponent;
typedef std::shared_ptr<CComponentsObject> PComponentsObject;
typedef std::shared_ptr<CBeamSet> PBeamSet;
typedef std::shared_ptr<CBaseMaterialGroup> PBaseMaterialGroup;
typedef std::shared_ptr<CColorGroup> PColorGroup;
typedef std::shared_ptr<CTexture2DGroup> PTexture2DGroup;
typedef std::shared_ptr<CCompositeMaterials> PCompositeMaterials;
typedef std::shared_ptr<CMultiPropertyGroup> PMultiPropertyGroup;
typedef std::shared_ptr<CImage3D> PImage3D;
typedef std::shared_ptr<CImageStack> PImageStack;
typedef std::shared_ptr<CAttachment> PAttachment;
typedef std::shared_ptr<CTexture2D> PTexture2D;
typedef std::shared_ptr<CImplicitPort> PImplicitPort;
typedef std::shared_ptr<CIterator> PIterator;
typedef std::shared_ptr<CImplicitPortIterator> PImplicitPortIterator;
typedef std::shared_ptr<CImplicitNode> PImplicitNode;
typedef std::shared_ptr<COneInputNode> POneInputNode;
typedef std::shared_ptr<CSinNode> PSinNode;
typedef std::shared_ptr<CCosNode> PCosNode;
typedef std::shared_ptr<CTanNode> PTanNode;
typedef std::shared_ptr<CArcSinNode> PArcSinNode;
typedef std::shared_ptr<CArcCosNode> PArcCosNode;
typedef std::shared_ptr<CArcTanNode> PArcTanNode;
typedef std::shared_ptr<CSinhNode> PSinhNode;
typedef std::shared_ptr<CCoshNode> PCoshNode;
typedef std::shared_ptr<CTanhNode> PTanhNode;
typedef std::shared_ptr<CRoundNode> PRoundNode;
typedef std::shared_ptr<CCeilNode> PCeilNode;
typedef std::shared_ptr<CFloorNode> PFloorNode;
typedef std::shared_ptr<CSignNode> PSignNode;
typedef std::shared_ptr<CFractNode> PFractNode;
typedef std::shared_ptr<CAbsNode> PAbsNode;
typedef std::shared_ptr<CExpNode> PExpNode;
typedef std::shared_ptr<CLogNode> PLogNode;
typedef std::shared_ptr<CLog2Node> PLog2Node;
typedef std::shared_ptr<CLog10Node> PLog10Node;
typedef std::shared_ptr<CLengthNode> PLengthNode;
typedef std::shared_ptr<CTransposeNode> PTransposeNode;
typedef std::shared_ptr<CInverseNode> PInverseNode;
typedef std::shared_ptr<CSqrtNode> PSqrtNode;
typedef std::shared_ptr<CResourceIdNode> PResourceIdNode;
typedef std::shared_ptr<CTwoInputNode> PTwoInputNode;
typedef std::shared_ptr<CAdditionNode> PAdditionNode;
typedef std::shared_ptr<CSubtractionNode> PSubtractionNode;
typedef std::shared_ptr<CMultiplicationNode> PMultiplicationNode;
typedef std::shared_ptr<CDivisionNode> PDivisionNode;
typedef std::shared_ptr<CDotNode> PDotNode;
typedef std::shared_ptr<CCrossNode> PCrossNode;
typedef std::shared_ptr<CArcTan2Node> PArcTan2Node;
typedef std::shared_ptr<CMatVecMultiplicationNode> PMatVecMultiplicationNode;
typedef std::shared_ptr<CMinNode> PMinNode;
typedef std::shared_ptr<CMaxNode> PMaxNode;
typedef std::shared_ptr<CFmodNode> PFmodNode;
typedef std::shared_ptr<CModNode> PModNode;
typedef std::shared_ptr<CPowNode> PPowNode;
typedef std::shared_ptr<CSelectNode> PSelectNode;
typedef std::shared_ptr<CClampNode> PClampNode;
typedef std::shared_ptr<CComposeVectorNode> PComposeVectorNode;
typedef std::shared_ptr<CVectorFromScalarNode> PVectorFromScalarNode;
typedef std::shared_ptr<CDecomposeVectorNode> PDecomposeVectorNode;
typedef std::shared_ptr<CComposeMatrixNode> PComposeMatrixNode;
typedef std::shared_ptr<CMatrixFromRowsNode> PMatrixFromRowsNode;
typedef std::shared_ptr<CMatrixFromColumnsNode> PMatrixFromColumnsNode;
typedef std::shared_ptr<CConstantNode> PConstantNode;
typedef std::shared_ptr<CConstVecNode> PConstVecNode;
typedef std::shared_ptr<CConstMatNode> PConstMatNode;
typedef std::shared_ptr<CMeshNode> PMeshNode;
typedef std::shared_ptr<CUnsignedMeshNode> PUnsignedMeshNode;
typedef std::shared_ptr<CBeamLatticeNode> PBeamLatticeNode;
typedef std::shared_ptr<CFunctionGradientNode> PFunctionGradientNode;
typedef std::shared_ptr<CNormalizeDistanceNode> PNormalizeDistanceNode;
typedef std::shared_ptr<CFunctionCallNode> PFunctionCallNode;
typedef std::shared_ptr<CNodeIterator> PNodeIterator;
typedef std::shared_ptr<CFunction> PFunction;
typedef std::shared_ptr<CImplicitFunction> PImplicitFunction;
typedef std::shared_ptr<CFunctionFromImage3D> PFunctionFromImage3D;
typedef std::shared_ptr<CBuildItem> PBuildItem;
typedef std::shared_ptr<CBuildItemIterator> PBuildItemIterator;
typedef std::shared_ptr<CSlice> PSlice;
typedef std::shared_ptr<CSliceStack> PSliceStack;
typedef std::shared_ptr<CConsumer> PConsumer;
typedef std::shared_ptr<CAccessRight> PAccessRight;
typedef std::shared_ptr<CContentEncryptionParams> PContentEncryptionParams;
typedef std::shared_ptr<CResourceData> PResourceData;
typedef std::shared_ptr<CResourceDataGroup> PResourceDataGroup;
typedef std::shared_ptr<CKeyStore> PKeyStore;
typedef std::shared_ptr<CModel> PModel;

/*************************************************************************************************************************
 Declaration of deprecated shared pointer types
**************************************************************************************************************************/
typedef PWrapper PLib3MFWrapper;
typedef PBase PLib3MFBase;
typedef PWriter PLib3MFWriter;
typedef PReader PLib3MFReader;
typedef PPackagePart PLib3MFPackagePart;
typedef PResource PLib3MFResource;
typedef PResourceIterator PLib3MFResourceIterator;
typedef PSliceStackIterator PLib3MFSliceStackIterator;
typedef PObjectIterator PLib3MFObjectIterator;
typedef PMeshObjectIterator PLib3MFMeshObjectIterator;
typedef PComponentsObjectIterator PLib3MFComponentsObjectIterator;
typedef PTexture2DIterator PLib3MFTexture2DIterator;
typedef PBaseMaterialGroupIterator PLib3MFBaseMaterialGroupIterator;
typedef PColorGroupIterator PLib3MFColorGroupIterator;
typedef PTexture2DGroupIterator PLib3MFTexture2DGroupIterator;
typedef PCompositeMaterialsIterator PLib3MFCompositeMaterialsIterator;
typedef PMultiPropertyGroupIterator PLib3MFMultiPropertyGroupIterator;
typedef PImage3DIterator PLib3MFImage3DIterator;
typedef PFunctionIterator PLib3MFFunctionIterator;
typedef PLevelSetIterator PLib3MFLevelSetIterator;
typedef PMetaData PLib3MFMetaData;
typedef PMetaDataGroup PLib3MFMetaDataGroup;
typedef PTriangleSet PLib3MFTriangleSet;
typedef PObject PLib3MFObject;
typedef PMeshObject PLib3MFMeshObject;
typedef PLevelSet PLib3MFLevelSet;
typedef PBeamLattice PLib3MFBeamLattice;
typedef PFunctionReference PLib3MFFunctionReference;
typedef PVolumeDataColor PLib3MFVolumeDataColor;
typedef PMaterialMapping PLib3MFMaterialMapping;
typedef PVolumeDataComposite PLib3MFVolumeDataComposite;
typedef PVolumeDataProperty PLib3MFVolumeDataProperty;
typedef PVolumeData PLib3MFVolumeData;
typedef PComponent PLib3MFComponent;
typedef PComponentsObject PLib3MFComponentsObject;
typedef PBeamSet PLib3MFBeamSet;
typedef PBaseMaterialGroup PLib3MFBaseMaterialGroup;
typedef PColorGroup PLib3MFColorGroup;
typedef PTexture2DGroup PLib3MFTexture2DGroup;
typedef PCompositeMaterials PLib3MFCompositeMaterials;
typedef PMultiPropertyGroup PLib3MFMultiPropertyGroup;
typedef PImage3D PLib3MFImage3D;
typedef PImageStack PLib3MFImageStack;
typedef PAttachment PLib3MFAttachment;
typedef PTexture2D PLib3MFTexture2D;
typedef PImplicitPort PLib3MFImplicitPort;
typedef PIterator PLib3MFIterator;
typedef PImplicitPortIterator PLib3MFImplicitPortIterator;
typedef PImplicitNode PLib3MFImplicitNode;
typedef POneInputNode PLib3MFOneInputNode;
typedef PSinNode PLib3MFSinNode;
typedef PCosNode PLib3MFCosNode;
typedef PTanNode PLib3MFTanNode;
typedef PArcSinNode PLib3MFArcSinNode;
typedef PArcCosNode PLib3MFArcCosNode;
typedef PArcTanNode PLib3MFArcTanNode;
typedef PSinhNode PLib3MFSinhNode;
typedef PCoshNode PLib3MFCoshNode;
typedef PTanhNode PLib3MFTanhNode;
typedef PRoundNode PLib3MFRoundNode;
typedef PCeilNode PLib3MFCeilNode;
typedef PFloorNode PLib3MFFloorNode;
typedef PSignNode PLib3MFSignNode;
typedef PFractNode PLib3MFFractNode;
typedef PAbsNode PLib3MFAbsNode;
typedef PExpNode PLib3MFExpNode;
typedef PLogNode PLib3MFLogNode;
typedef PLog2Node PLib3MFLog2Node;
typedef PLog10Node PLib3MFLog10Node;
typedef PLengthNode PLib3MFLengthNode;
typedef PTransposeNode PLib3MFTransposeNode;
typedef PInverseNode PLib3MFInverseNode;
typedef PSqrtNode PLib3MFSqrtNode;
typedef PResourceIdNode PLib3MFResourceIdNode;
typedef PTwoInputNode PLib3MFTwoInputNode;
typedef PAdditionNode PLib3MFAdditionNode;
typedef PSubtractionNode PLib3MFSubtractionNode;
typedef PMultiplicationNode PLib3MFMultiplicationNode;
typedef PDivisionNode PLib3MFDivisionNode;
typedef PDotNode PLib3MFDotNode;
typedef PCrossNode PLib3MFCrossNode;
typedef PArcTan2Node PLib3MFArcTan2Node;
typedef PMatVecMultiplicationNode PLib3MFMatVecMultiplicationNode;
typedef PMinNode PLib3MFMinNode;
typedef PMaxNode PLib3MFMaxNode;
typedef PFmodNode PLib3MFFmodNode;
typedef PModNode PLib3MFModNode;
typedef PPowNode PLib3MFPowNode;
typedef PSelectNode PLib3MFSelectNode;
typedef PClampNode PLib3MFClampNode;
typedef PComposeVectorNode PLib3MFComposeVectorNode;
typedef PVectorFromScalarNode PLib3MFVectorFromScalarNode;
typedef PDecomposeVectorNode PLib3MFDecomposeVectorNode;
typedef PComposeMatrixNode PLib3MFComposeMatrixNode;
typedef PMatrixFromRowsNode PLib3MFMatrixFromRowsNode;
typedef PMatrixFromColumnsNode PLib3MFMatrixFromColumnsNode;
typedef PConstantNode PLib3MFConstantNode;
typedef PConstVecNode PLib3MFConstVecNode;
typedef PConstMatNode PLib3MFConstMatNode;
typedef PMeshNode PLib3MFMeshNode;
typedef PUnsignedMeshNode PLib3MFUnsignedMeshNode;
typedef PBeamLatticeNode PLib3MFBeamLatticeNode;
typedef PFunctionGradientNode PLib3MFFunctionGradientNode;
typedef PNormalizeDistanceNode PLib3MFNormalizeDistanceNode;
typedef PFunctionCallNode PLib3MFFunctionCallNode;
typedef PNodeIterator PLib3MFNodeIterator;
typedef PFunction PLib3MFFunction;
typedef PImplicitFunction PLib3MFImplicitFunction;
typedef PFunctionFromImage3D PLib3MFFunctionFromImage3D;
typedef PBuildItem PLib3MFBuildItem;
typedef PBuildItemIterator PLib3MFBuildItemIterator;
typedef PSlice PLib3MFSlice;
typedef PSliceStack PLib3MFSliceStack;
typedef PConsumer PLib3MFConsumer;
typedef PAccessRight PLib3MFAccessRight;
typedef PContentEncryptionParams PLib3MFContentEncryptionParams;
typedef PResourceData PLib3MFResourceData;
typedef PResourceDataGroup PLib3MFResourceDataGroup;
typedef PKeyStore PLib3MFKeyStore;
typedef PModel PLib3MFModel;


/*************************************************************************************************************************
 classParam Definition
**************************************************************************************************************************/

template<class T> class classParam {
private:
	std::shared_ptr<T> m_sharedPtr;
	const T* m_ptr;

public:
	classParam(const T* ptr)
		: m_ptr(ptr)
	{
	}

	classParam(std::shared_ptr <T> sharedPtr)
		: m_sharedPtr(sharedPtr), m_ptr(sharedPtr.get())
	{
	}

	Lib3MFHandle GetHandle()
	{
		if (m_ptr != nullptr)
			return m_ptr->handle();
		return (Lib3MFHandle)nullptr;
	}
};


/*************************************************************************************************************************
 Class ELib3MFException 
**************************************************************************************************************************/
class ELib3MFException : public std::exception {
protected:
	/**
	* Error code for the Exception.
	*/
	Lib3MFResult m_errorCode;
	/**
	* Error message for the Exception.
	*/
	std::string m_errorMessage;
	std::string m_originalErrorMessage;

public:
	/**
	* Exception Constructor.
	*/
	ELib3MFException(Lib3MFResult errorCode, const std::string & sErrorMessage)
		: m_errorCode(errorCode), m_originalErrorMessage(sErrorMessage)
	{
		m_errorMessage = buildErrorMessage();
	}

	/**
	* Returns error code
	*/
	Lib3MFResult getErrorCode() const noexcept
	{
		return m_errorCode;
	}

	/**
	* Returns error message
	*/
	const char* what() const noexcept
	{
		return m_errorMessage.c_str();
	}

	const char* getErrorMessage() const noexcept
	{
		return m_originalErrorMessage.c_str();
	}

	const char* getErrorName() const noexcept
	{
		switch(getErrorCode()) {
			case LIB3MF_SUCCESS: return "SUCCESS";
			case LIB3MF_ERROR_NOTIMPLEMENTED: return "NOTIMPLEMENTED";
			case LIB3MF_ERROR_INVALIDPARAM: return "INVALIDPARAM";
			case LIB3MF_ERROR_INVALIDCAST: return "INVALIDCAST";
			case LIB3MF_ERROR_BUFFERTOOSMALL: return "BUFFERTOOSMALL";
			case LIB3MF_ERROR_GENERICEXCEPTION: return "GENERICEXCEPTION";
			case LIB3MF_ERROR_COULDNOTLOADLIBRARY: return "COULDNOTLOADLIBRARY";
			case LIB3MF_ERROR_COULDNOTFINDLIBRARYEXPORT: return "COULDNOTFINDLIBRARYEXPORT";
			case LIB3MF_ERROR_INCOMPATIBLEBINARYVERSION: return "INCOMPATIBLEBINARYVERSION";
			case LIB3MF_ERROR_CALCULATIONABORTED: return "CALCULATIONABORTED";
			case LIB3MF_ERROR_SHOULDNOTBECALLED: return "SHOULDNOTBECALLED";
			case LIB3MF_ERROR_READERCLASSUNKNOWN: return "READERCLASSUNKNOWN";
			case LIB3MF_ERROR_WRITERCLASSUNKNOWN: return "WRITERCLASSUNKNOWN";
			case LIB3MF_ERROR_ITERATORINVALIDINDEX: return "ITERATORINVALIDINDEX";
			case LIB3MF_ERROR_INVALIDMODELRESOURCE: return "INVALIDMODELRESOURCE";
			case LIB3MF_ERROR_RESOURCENOTFOUND: return "RESOURCENOTFOUND";
			case LIB3MF_ERROR_INVALIDMODEL: return "INVALIDMODEL";
			case LIB3MF_ERROR_INVALIDOBJECT: return "INVALIDOBJECT";
			case LIB3MF_ERROR_INVALIDMESHOBJECT: return "INVALIDMESHOBJECT";
			case LIB3MF_ERROR_INVALIDCOMPONENTSOBJECT: return "INVALIDCOMPONENTSOBJECT";
			case LIB3MF_ERROR_INVALIDCOMPONENT: return "INVALIDCOMPONENT";
			case LIB3MF_ERROR_INVALIDBUILDITEM: return "INVALIDBUILDITEM";
			case LIB3MF_ERROR_INVALIDBASEMATERIALGROUP: return "INVALIDBASEMATERIALGROUP";
			case LIB3MF_ERROR_INVALIDSLICESTACKRESOURCE: return "INVALIDSLICESTACKRESOURCE";
			case LIB3MF_ERROR_INVALIDTEXTURERESOURCE: return "INVALIDTEXTURERESOURCE";
			case LIB3MF_ERROR_INVALIDCOLORGROUP: return "INVALIDCOLORGROUP";
			case LIB3MF_ERROR_INVALIDTEXTURE2DGROUP: return "INVALIDTEXTURE2DGROUP";
			case LIB3MF_ERROR_INVALIDCOMPOSITEMATERIALS: return "INVALIDCOMPOSITEMATERIALS";
			case LIB3MF_ERROR_INVALIDMULTIPROPERTYGROUP: return "INVALIDMULTIPROPERTYGROUP";
			case LIB3MF_ERROR_INVALIDRESOURCEINDEX: return "INVALIDRESOURCEINDEX";
			case LIB3MF_ERROR_ATTACHMENTNOTFOUND: return "ATTACHMENTNOTFOUND";
			case LIB3MF_ERROR_FORBIDDENCYCLICREFERENCE: return "FORBIDDENCYCLICREFERENCE";
			case LIB3MF_ERROR_INVALIDATTACHMENTSTREAM: return "INVALIDATTACHMENTSTREAM";
			case LIB3MF_ERROR_INVALIDPROPERTYCOUNT: return "INVALIDPROPERTYCOUNT";
			case LIB3MF_ERROR_UNKOWNPROGRESSIDENTIFIER: return "UNKOWNPROGRESSIDENTIFIER";
			case LIB3MF_ERROR_ELEMENTCOUNTEXCEEDSLIMIT: return "ELEMENTCOUNTEXCEEDSLIMIT";
			case LIB3MF_ERROR_INVALIDRESOURCE: return "INVALIDRESOURCE";
			case LIB3MF_ERROR_INVALIDLEVELSET: return "INVALIDLEVELSET";
			case LIB3MF_ERROR_COULDNOTFINDTRIANGLESET: return "COULDNOTFINDTRIANGLESET";
			case LIB3MF_ERROR_INVALIDTRIANGLESETINDEX: return "INVALIDTRIANGLESETINDEX";
			case LIB3MF_ERROR_BEAMLATTICE_INVALID_OBJECTTYPE: return "BEAMLATTICE_INVALID_OBJECTTYPE";
			case LIB3MF_ERROR_INVALIDKEYSTORE: return "INVALIDKEYSTORE";
			case LIB3MF_ERROR_INVALIDKEYSTORECONSUMER: return "INVALIDKEYSTORECONSUMER";
			case LIB3MF_ERROR_KEYSTORECONSUMERNOTFOUND: return "KEYSTORECONSUMERNOTFOUND";
			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";
	}

	const char* getErrorDescription() const noexcept
	{
		switch(getErrorCode()) {
			case LIB3MF_SUCCESS: return "success";
			case LIB3MF_ERROR_NOTIMPLEMENTED: return "functionality not implemented";
			case LIB3MF_ERROR_INVALIDPARAM: return "an invalid parameter was passed";
			case LIB3MF_ERROR_INVALIDCAST: return "a type cast failed";
			case LIB3MF_ERROR_BUFFERTOOSMALL: return "a provided buffer is too small";
			case LIB3MF_ERROR_GENERICEXCEPTION: return "a generic exception occurred";
			case LIB3MF_ERROR_COULDNOTLOADLIBRARY: return "the library could not be loaded";
			case LIB3MF_ERROR_COULDNOTFINDLIBRARYEXPORT: return "a required exported symbol could not be found in the library";
			case LIB3MF_ERROR_INCOMPATIBLEBINARYVERSION: return "the version of the binary interface does not match the bindings interface";
			case LIB3MF_ERROR_CALCULATIONABORTED: return "a calculation has been aborted";
			case LIB3MF_ERROR_SHOULDNOTBECALLED: return "functionality should not be called";
			case LIB3MF_ERROR_READERCLASSUNKNOWN: return "the queried reader class is unknown";
			case LIB3MF_ERROR_WRITERCLASSUNKNOWN: return "the queried writer class is unknown";
			case LIB3MF_ERROR_ITERATORINVALIDINDEX: return "the current index of an iterator is invalid";
			case LIB3MF_ERROR_INVALIDMODELRESOURCE: return "no Model Resource has been given";
			case LIB3MF_ERROR_RESOURCENOTFOUND: return "Resource not found";
			case LIB3MF_ERROR_INVALIDMODEL: return "A model is invalid";
			case LIB3MF_ERROR_INVALIDOBJECT: return "An object is invalid";
			case LIB3MF_ERROR_INVALIDMESHOBJECT: return "A mesh object is invalid";
			case LIB3MF_ERROR_INVALIDCOMPONENTSOBJECT: return "A components object is invalid";
			case LIB3MF_ERROR_INVALIDCOMPONENT: return "A component is invalid";
			case LIB3MF_ERROR_INVALIDBUILDITEM: return "A build item is invalid";
			case LIB3MF_ERROR_INVALIDBASEMATERIALGROUP: return "A basematerialgroup is invalid";
			case LIB3MF_ERROR_INVALIDSLICESTACKRESOURCE: return "A slicestack resource is invalid";
			case LIB3MF_ERROR_INVALIDTEXTURERESOURCE: return "A texture resource is invalid";
			case LIB3MF_ERROR_INVALIDCOLORGROUP: return "A color group resource is invalid";
			case LIB3MF_ERROR_INVALIDTEXTURE2DGROUP: return "A texture2d group resource is invalid";
			case LIB3MF_ERROR_INVALIDCOMPOSITEMATERIALS: return "A composite materials resource is invalid";
			case LIB3MF_ERROR_INVALIDMULTIPROPERTYGROUP: return "A MultiPropertyGroup resource is invalid";
			case LIB3MF_ERROR_INVALIDRESOURCEINDEX: return "A resource index is invalid";
			case LIB3MF_ERROR_ATTACHMENTNOTFOUND: return "Attachment not found";
			case LIB3MF_ERROR_FORBIDDENCYCLICREFERENCE: return "A component references one of its ancestors";
			case LIB3MF_ERROR_INVALIDATTACHMENTSTREAM: return "An attachment stream is invalid";
			case LIB3MF_ERROR_INVALIDPROPERTYCOUNT: return "Invalid property count.";
			case LIB3MF_ERROR_UNKOWNPROGRESSIDENTIFIER: return "A progress identifier is unknown";
			case LIB3MF_ERROR_ELEMENTCOUNTEXCEEDSLIMIT: return "An element buffer exceeds its spec limit";
			case LIB3MF_ERROR_INVALIDRESOURCE: return "A resource is invalid";
			case LIB3MF_ERROR_INVALIDLEVELSET: return "A level set is invalid";
			case LIB3MF_ERROR_COULDNOTFINDTRIANGLESET: return "Could not find triangle set";
			case LIB3MF_ERROR_INVALIDTRIANGLESETINDEX: return "Invalid triangle set index";
			case LIB3MF_ERROR_BEAMLATTICE_INVALID_OBJECTTYPE: return "This object type is not valid for beamlattices";
			case LIB3MF_ERROR_INVALIDKEYSTORE: return "The keystore object is invalid";
			case LIB3MF_ERROR_INVALIDKEYSTORECONSUMER: return "The consumer keystore object is invalid";
			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 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";
	}

private:

	std::string buildErrorMessage() const noexcept
	{
		std::string msg = m_originalErrorMessage;
		if (msg.empty()) {
			msg = getErrorDescription();
		}
		return std::string("Error: ") + getErrorName() + ": " + msg;
	}
};

/*************************************************************************************************************************
 Class CInputVector
**************************************************************************************************************************/
template <typename T>
class CInputVector {
private:
	
	const T* m_data;
	size_t m_size;
	
public:
	
	CInputVector(const std::vector<T>& vec)
		: m_data( vec.data() ), m_size( vec.size() )
	{
	}
	
	CInputVector(const T* in_data, size_t in_size)
		: m_data( in_data ), m_size(in_size )
	{
	}
	
	const T* data() const
	{
		return m_data;
	}
	
	size_t size() const
	{
		return m_size;
	}
	
};

// declare deprecated class name
template<typename T>
using CLib3MFInputVector = CInputVector<T>;

/*************************************************************************************************************************
 Class CWrapper 
**************************************************************************************************************************/
class CWrapper {
public:
	
	CWrapper()
	{
	}
	
	~CWrapper()
	{
	}
	static inline PWrapper loadLibrary()
	{
		return std::make_shared<CWrapper>();
	}
	
	inline void CheckError(CBase * pBaseClass, Lib3MFResult nResult);

	inline void GetLibraryVersion(Lib3MF_uint32 & nMajor, Lib3MF_uint32 & nMinor, Lib3MF_uint32 & nMicro);
	inline bool GetPrereleaseInformation(std::string & sPrereleaseInfo);
	inline bool GetBuildInformation(std::string & sBuildInformation);
	inline void GetSpecificationVersion(const std::string & sSpecificationURL, bool & bIsSupported, Lib3MF_uint32 & nMajor, Lib3MF_uint32 & nMinor, Lib3MF_uint32 & nMicro);
	inline PModel CreateModel();
	inline void Release(classParam<CBase> pInstance);
	inline void Acquire(classParam<CBase> pInstance);
	inline void SetJournal(const std::string & sJournalPath);
	inline bool GetLastError(classParam<CBase> pInstance, std::string & sLastErrorString);
	inline Lib3MF_pvoid GetSymbolLookupMethod();
	inline void RetrieveProgressMessage(const eProgressIdentifier eTheProgressIdentifier, std::string & sProgressMessage);
	inline sColor RGBAToColor(const Lib3MF_uint8 nRed, const Lib3MF_uint8 nGreen, const Lib3MF_uint8 nBlue, const Lib3MF_uint8 nAlpha);
	inline sColor FloatRGBAToColor(const Lib3MF_single fRed, const Lib3MF_single fGreen, const Lib3MF_single fBlue, const Lib3MF_single fAlpha);
	inline void ColorToRGBA(const sColor & TheColor, Lib3MF_uint8 & nRed, Lib3MF_uint8 & nGreen, Lib3MF_uint8 & nBlue, Lib3MF_uint8 & nAlpha);
	inline void ColorToFloatRGBA(const sColor & TheColor, Lib3MF_single & fRed, Lib3MF_single & fGreen, Lib3MF_single & fBlue, Lib3MF_single & fAlpha);
	inline sTransform GetIdentityTransform();
	inline sTransform GetUniformScaleTransform(const Lib3MF_single fFactor);
	inline sTransform GetScaleTransform(const Lib3MF_single fFactorX, const Lib3MF_single fFactorY, const Lib3MF_single fFactorZ);
	inline sTransform GetTranslationTransform(const Lib3MF_single fVectorX, const Lib3MF_single fVectorY, const Lib3MF_single fVectorZ);

	inline CBase* polymorphicFactory(Lib3MFHandle);

private:
	
	Lib3MFResult checkBinaryVersion()
	{
		Lib3MF_uint32 nMajor, nMinor, nMicro;
		GetLibraryVersion(nMajor, nMinor, nMicro);
		if ( (nMajor != LIB3MF_VERSION_MAJOR) || (nMinor < LIB3MF_VERSION_MINOR) ) {
			return LIB3MF_ERROR_INCOMPATIBLEBINARYVERSION;
		}
		return LIB3MF_SUCCESS;
	}

	friend class CBase;
	friend class CWriter;
	friend class CReader;
	friend class CPackagePart;
	friend class CResource;
	friend class CResourceIterator;
	friend class CSliceStackIterator;
	friend class CObjectIterator;
	friend class CMeshObjectIterator;
	friend class CComponentsObjectIterator;
	friend class CTexture2DIterator;
	friend class CBaseMaterialGroupIterator;
	friend class CColorGroupIterator;
	friend class CTexture2DGroupIterator;
	friend class CCompositeMaterialsIterator;
	friend class CMultiPropertyGroupIterator;
	friend class CImage3DIterator;
	friend class CFunctionIterator;
	friend class CLevelSetIterator;
	friend class CMetaData;
	friend class CMetaDataGroup;
	friend class CTriangleSet;
	friend class CObject;
	friend class CMeshObject;
	friend class CLevelSet;
	friend class CBeamLattice;
	friend class CFunctionReference;
	friend class CVolumeDataColor;
	friend class CMaterialMapping;
	friend class CVolumeDataComposite;
	friend class CVolumeDataProperty;
	friend class CVolumeData;
	friend class CComponent;
	friend class CComponentsObject;
	friend class CBeamSet;
	friend class CBaseMaterialGroup;
	friend class CColorGroup;
	friend class CTexture2DGroup;
	friend class CCompositeMaterials;
	friend class CMultiPropertyGroup;
	friend class CImage3D;
	friend class CImageStack;
	friend class CAttachment;
	friend class CTexture2D;
	friend class CImplicitPort;
	friend class CIterator;
	friend class CImplicitPortIterator;
	friend class CImplicitNode;
	friend class COneInputNode;
	friend class CSinNode;
	friend class CCosNode;
	friend class CTanNode;
	friend class CArcSinNode;
	friend class CArcCosNode;
	friend class CArcTanNode;
	friend class CSinhNode;
	friend class CCoshNode;
	friend class CTanhNode;
	friend class CRoundNode;
	friend class CCeilNode;
	friend class CFloorNode;
	friend class CSignNode;
	friend class CFractNode;
	friend class CAbsNode;
	friend class CExpNode;
	friend class CLogNode;
	friend class CLog2Node;
	friend class CLog10Node;
	friend class CLengthNode;
	friend class CTransposeNode;
	friend class CInverseNode;
	friend class CSqrtNode;
	friend class CResourceIdNode;
	friend class CTwoInputNode;
	friend class CAdditionNode;
	friend class CSubtractionNode;
	friend class CMultiplicationNode;
	friend class CDivisionNode;
	friend class CDotNode;
	friend class CCrossNode;
	friend class CArcTan2Node;
	friend class CMatVecMultiplicationNode;
	friend class CMinNode;
	friend class CMaxNode;
	friend class CFmodNode;
	friend class CModNode;
	friend class CPowNode;
	friend class CSelectNode;
	friend class CClampNode;
	friend class CComposeVectorNode;
	friend class CVectorFromScalarNode;
	friend class CDecomposeVectorNode;
	friend class CComposeMatrixNode;
	friend class CMatrixFromRowsNode;
	friend class CMatrixFromColumnsNode;
	friend class CConstantNode;
	friend class CConstVecNode;
	friend class CConstMatNode;
	friend class CMeshNode;
	friend class CUnsignedMeshNode;
	friend class CBeamLatticeNode;
	friend class CFunctionGradientNode;
	friend class CNormalizeDistanceNode;
	friend class CFunctionCallNode;
	friend class CNodeIterator;
	friend class CFunction;
	friend class CImplicitFunction;
	friend class CFunctionFromImage3D;
	friend class CBuildItem;
	friend class CBuildItemIterator;
	friend class CSlice;
	friend class CSliceStack;
	friend class CConsumer;
	friend class CAccessRight;
	friend class CContentEncryptionParams;
	friend class CResourceData;
	friend class CResourceDataGroup;
	friend class CKeyStore;
	friend class CModel;

};

	
/*************************************************************************************************************************
 Class CBase 
**************************************************************************************************************************/
class CBase {
public:
	
protected:
	/* Wrapper Object that created the class. */
	CWrapper * m_pWrapper;
	/* Handle to Instance in library*/
	Lib3MFHandle m_pHandle;

	/* Checks for an Error code and raises Exceptions */
	void CheckError(Lib3MFResult nResult)
	{
		if (m_pWrapper != nullptr)
			m_pWrapper->CheckError(this, nResult);
	}
public:
	/**
	* CBase::CBase - Constructor for Base class.
	*/
	CBase(CWrapper * pWrapper, Lib3MFHandle pHandle)
		: m_pWrapper(pWrapper), m_pHandle(pHandle)
	{
	}

	/**
	* CBase::~CBase - Destructor for Base class.
	*/
	virtual ~CBase()
	{
		if (m_pWrapper != nullptr)
			m_pWrapper->Release(this);
		m_pWrapper = nullptr;
	}

	/**
	* CBase::handle - Returns handle to instance.
	*/
	Lib3MFHandle handle() const
	{
		return m_pHandle;
	}

	/**
	* CBase::wrapper - Returns wrapper instance.
	*/
	CWrapper * wrapper() const
	{
		return m_pWrapper;
	}

	friend class CWrapper;
	inline Lib3MF_uint64 ClassTypeId();
	
protected:
};
	
/*************************************************************************************************************************
 Class CWriter 
**************************************************************************************************************************/
class CWriter : public CBase {
public:
	
	/**
	* CWriter::CWriter - Constructor for Writer class.
	*/
	CWriter(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline void WriteToFile(const std::string & sFilename);
	inline Lib3MF_uint64 GetStreamSize();
	inline void WriteToBuffer(std::vector<Lib3MF_uint8> & BufferBuffer);
	inline void WriteToCallback(const WriteCallback pTheWriteCallback, const SeekCallback pTheSeekCallback, const Lib3MF_pvoid pUserData);
	inline void SetProgressCallback(const ProgressCallback pProgressCallback, const Lib3MF_pvoid pUserData);
	inline Lib3MF_uint32 GetDecimalPrecision();
	inline void SetDecimalPrecision(const Lib3MF_uint32 nDecimalPrecision);
	inline void SetStrictModeActive(const bool bStrictModeActive);
	inline bool GetStrictModeActive();
	inline std::string GetWarning(const Lib3MF_uint32 nIndex, Lib3MF_uint32 & nErrorCode);
	inline Lib3MF_uint32 GetWarningCount();
	inline void AddKeyWrappingCallback(const std::string & sConsumerID, const KeyWrappingCallback pTheCallback, const Lib3MF_pvoid pUserData);
	inline void SetContentEncryptionCallback(const ContentEncryptionCallback pTheCallback, const Lib3MF_pvoid pUserData);
};
	
/*************************************************************************************************************************
 Class CReader 
**************************************************************************************************************************/
class CReader : public CBase {
public:
	
	/**
	* CReader::CReader - Constructor for Reader class.
	*/
	CReader(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline void ReadFromFile(const std::string & sFilename);
	inline void ReadFromBuffer(const CInputVector<Lib3MF_uint8> & BufferBuffer);
	inline void ReadFromCallback(const ReadCallback pTheReadCallback, const Lib3MF_uint64 nStreamSize, const SeekCallback pTheSeekCallback, const Lib3MF_pvoid pUserData);
	inline void SetProgressCallback(const ProgressCallback pProgressCallback, const Lib3MF_pvoid pUserData);
	inline void AddRelationToRead(const std::string & sRelationShipType);
	inline void RemoveRelationToRead(const std::string & sRelationShipType);
	inline void SetStrictModeActive(const bool bStrictModeActive);
	inline bool GetStrictModeActive();
	inline std::string GetWarning(const Lib3MF_uint32 nIndex, Lib3MF_uint32 & nErrorCode);
	inline Lib3MF_uint32 GetWarningCount();
	inline void AddKeyWrappingCallback(const std::string & sConsumerID, const KeyWrappingCallback pTheCallback, const Lib3MF_pvoid pUserData);
	inline void SetContentEncryptionCallback(const ContentEncryptionCallback pTheCallback, const Lib3MF_pvoid pUserData);
};
	
/*************************************************************************************************************************
 Class CPackagePart 
**************************************************************************************************************************/
class CPackagePart : public CBase {
public:
	
	/**
	* CPackagePart::CPackagePart - Constructor for PackagePart class.
	*/
	CPackagePart(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline std::string GetPath();
	inline void SetPath(const std::string & sPath);
};
	
/*************************************************************************************************************************
 Class CResource 
**************************************************************************************************************************/
class CResource : public CBase {
public:
	
	/**
	* CResource::CResource - Constructor for Resource class.
	*/
	CResource(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline Lib3MF_uint32 GetResourceID();
	inline Lib3MF_uint32 GetUniqueResourceID();
	inline PPackagePart PackagePart();
	inline void SetPackagePart(classParam<CPackagePart> pPackagePart);
	inline Lib3MF_uint32 GetModelResourceID();
};
	
/*************************************************************************************************************************
 Class CResourceIterator 
**************************************************************************************************************************/
class CResourceIterator : public CBase {
public:
	
	/**
	* CResourceIterator::CResourceIterator - Constructor for ResourceIterator class.
	*/
	CResourceIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline bool MoveNext();
	inline bool MovePrevious();
	inline PResource GetCurrent();
	inline PResourceIterator Clone();
	inline Lib3MF_uint64 Count();
};
	
/*************************************************************************************************************************
 Class CSliceStackIterator 
**************************************************************************************************************************/
class CSliceStackIterator : public CResourceIterator {
public:
	
	/**
	* CSliceStackIterator::CSliceStackIterator - Constructor for SliceStackIterator class.
	*/
	CSliceStackIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResourceIterator(pWrapper, pHandle)
	{
	}
	
	inline PSliceStack GetCurrentSliceStack();
};
	
/*************************************************************************************************************************
 Class CObjectIterator 
**************************************************************************************************************************/
class CObjectIterator : public CResourceIterator {
public:
	
	/**
	* CObjectIterator::CObjectIterator - Constructor for ObjectIterator class.
	*/
	CObjectIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResourceIterator(pWrapper, pHandle)
	{
	}
	
	inline PObject GetCurrentObject();
};
	
/*************************************************************************************************************************
 Class CMeshObjectIterator 
**************************************************************************************************************************/
class CMeshObjectIterator : public CResourceIterator {
public:
	
	/**
	* CMeshObjectIterator::CMeshObjectIterator - Constructor for MeshObjectIterator class.
	*/
	CMeshObjectIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResourceIterator(pWrapper, pHandle)
	{
	}
	
	inline PMeshObject GetCurrentMeshObject();
};
	
/*************************************************************************************************************************
 Class CComponentsObjectIterator 
**************************************************************************************************************************/
class CComponentsObjectIterator : public CResourceIterator {
public:
	
	/**
	* CComponentsObjectIterator::CComponentsObjectIterator - Constructor for ComponentsObjectIterator class.
	*/
	CComponentsObjectIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResourceIterator(pWrapper, pHandle)
	{
	}
	
	inline PComponentsObject GetCurrentComponentsObject();
};
	
/*************************************************************************************************************************
 Class CTexture2DIterator 
**************************************************************************************************************************/
class CTexture2DIterator : public CResourceIterator {
public:
	
	/**
	* CTexture2DIterator::CTexture2DIterator - Constructor for Texture2DIterator class.
	*/
	CTexture2DIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResourceIterator(pWrapper, pHandle)
	{
	}
	
	inline PTexture2D GetCurrentTexture2D();
};
	
/*************************************************************************************************************************
 Class CBaseMaterialGroupIterator 
**************************************************************************************************************************/
class CBaseMaterialGroupIterator : public CResourceIterator {
public:
	
	/**
	* CBaseMaterialGroupIterator::CBaseMaterialGroupIterator - Constructor for BaseMaterialGroupIterator class.
	*/
	CBaseMaterialGroupIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResourceIterator(pWrapper, pHandle)
	{
	}
	
	inline PBaseMaterialGroup GetCurrentBaseMaterialGroup();
};
	
/*************************************************************************************************************************
 Class CColorGroupIterator 
**************************************************************************************************************************/
class CColorGroupIterator : public CResourceIterator {
public:
	
	/**
	* CColorGroupIterator::CColorGroupIterator - Constructor for ColorGroupIterator class.
	*/
	CColorGroupIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResourceIterator(pWrapper, pHandle)
	{
	}
	
	inline PColorGroup GetCurrentColorGroup();
};
	
/*************************************************************************************************************************
 Class CTexture2DGroupIterator 
**************************************************************************************************************************/
class CTexture2DGroupIterator : public CResourceIterator {
public:
	
	/**
	* CTexture2DGroupIterator::CTexture2DGroupIterator - Constructor for Texture2DGroupIterator class.
	*/
	CTexture2DGroupIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResourceIterator(pWrapper, pHandle)
	{
	}
	
	inline PTexture2DGroup GetCurrentTexture2DGroup();
};
	
/*************************************************************************************************************************
 Class CCompositeMaterialsIterator 
**************************************************************************************************************************/
class CCompositeMaterialsIterator : public CResourceIterator {
public:
	
	/**
	* CCompositeMaterialsIterator::CCompositeMaterialsIterator - Constructor for CompositeMaterialsIterator class.
	*/
	CCompositeMaterialsIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResourceIterator(pWrapper, pHandle)
	{
	}
	
	inline PCompositeMaterials GetCurrentCompositeMaterials();
};
	
/*************************************************************************************************************************
 Class CMultiPropertyGroupIterator 
**************************************************************************************************************************/
class CMultiPropertyGroupIterator : public CResourceIterator {
public:
	
	/**
	* CMultiPropertyGroupIterator::CMultiPropertyGroupIterator - Constructor for MultiPropertyGroupIterator class.
	*/
	CMultiPropertyGroupIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResourceIterator(pWrapper, pHandle)
	{
	}
	
	inline PMultiPropertyGroup GetCurrentMultiPropertyGroup();
};
	
/*************************************************************************************************************************
 Class CImage3DIterator 
**************************************************************************************************************************/
class CImage3DIterator : public CResourceIterator {
public:
	
	/**
	* CImage3DIterator::CImage3DIterator - Constructor for Image3DIterator class.
	*/
	CImage3DIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResourceIterator(pWrapper, pHandle)
	{
	}
	
	inline PImage3D GetCurrentImage3D();
};
	
/*************************************************************************************************************************
 Class CFunctionIterator 
**************************************************************************************************************************/
class CFunctionIterator : public CResourceIterator {
public:
	
	/**
	* CFunctionIterator::CFunctionIterator - Constructor for FunctionIterator class.
	*/
	CFunctionIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResourceIterator(pWrapper, pHandle)
	{
	}
	
	inline PFunction GetCurrentFunction();
};
	
/*************************************************************************************************************************
 Class CLevelSetIterator 
**************************************************************************************************************************/
class CLevelSetIterator : public CResourceIterator {
public:
	
	/**
	* CLevelSetIterator::CLevelSetIterator - Constructor for LevelSetIterator class.
	*/
	CLevelSetIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResourceIterator(pWrapper, pHandle)
	{
	}
	
	inline PLevelSet GetCurrentLevelSet();
};
	
/*************************************************************************************************************************
 Class CMetaData 
**************************************************************************************************************************/
class CMetaData : public CBase {
public:
	
	/**
	* CMetaData::CMetaData - Constructor for MetaData class.
	*/
	CMetaData(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline std::string GetNameSpace();
	inline void SetNameSpace(const std::string & sNameSpace);
	inline std::string GetName();
	inline void SetName(const std::string & sName);
	inline std::string GetKey();
	inline bool GetMustPreserve();
	inline void SetMustPreserve(const bool bMustPreserve);
	inline std::string GetType();
	inline void SetType(const std::string & sType);
	inline std::string GetValue();
	inline void SetValue(const std::string & sValue);
};
	
/*************************************************************************************************************************
 Class CMetaDataGroup 
**************************************************************************************************************************/
class CMetaDataGroup : public CBase {
public:
	
	/**
	* CMetaDataGroup::CMetaDataGroup - Constructor for MetaDataGroup class.
	*/
	CMetaDataGroup(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline Lib3MF_uint32 GetMetaDataCount();
	inline PMetaData GetMetaData(const Lib3MF_uint32 nIndex);
	inline PMetaData GetMetaDataByKey(const std::string & sNameSpace, const std::string & sName);
	inline void RemoveMetaDataByIndex(const Lib3MF_uint32 nIndex);
	inline void RemoveMetaData(classParam<CMetaData> pTheMetaData);
	inline PMetaData AddMetaData(const std::string & sNameSpace, const std::string & sName, const std::string & sValue, const std::string & sType, const bool bMustPreserve);
};
	
/*************************************************************************************************************************
 Class CTriangleSet 
**************************************************************************************************************************/
class CTriangleSet : public CBase {
public:
	
	/**
	* CTriangleSet::CTriangleSet - Constructor for TriangleSet class.
	*/
	CTriangleSet(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline void SetName(const std::string & sName);
	inline std::string GetName();
	inline void SetIdentifier(const std::string & sIdentifier);
	inline std::string GetIdentifier();
	inline void AddTriangle(const Lib3MF_uint32 nTriangleIndex);
	inline void RemoveTriangle(const Lib3MF_uint32 nTriangleIndex);
	inline void Clear();
	inline void SetTriangleList(const CInputVector<Lib3MF_uint32> & TriangleIndicesBuffer);
	inline void GetTriangleList(std::vector<Lib3MF_uint32> & TriangleIndicesBuffer);
	inline void AddTriangleList(const CInputVector<Lib3MF_uint32> & TriangleIndicesBuffer);
	inline void Merge(classParam<CTriangleSet> pOtherTriangleSet, const bool bDeleteOther);
	inline void DeleteSet();
	inline PTriangleSet Duplicate(const std::string & sIdentifier);
};
	
/*************************************************************************************************************************
 Class CObject 
**************************************************************************************************************************/
class CObject : public CResource {
public:
	
	/**
	* CObject::CObject - Constructor for Object class.
	*/
	CObject(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResource(pWrapper, pHandle)
	{
	}
	
	inline eObjectType GetType();
	inline void SetType(const eObjectType eObjectType);
	inline std::string GetName();
	inline void SetName(const std::string & sName);
	inline std::string GetPartNumber();
	inline void SetPartNumber(const std::string & sPartNumber);
	inline bool IsMeshObject();
	inline bool IsComponentsObject();
	inline bool IsLevelSetObject();
	inline bool IsValid();
	inline void SetAttachmentAsThumbnail(classParam<CAttachment> pAttachment);
	inline PAttachment GetThumbnailAttachment();
	inline void ClearThumbnailAttachment();
	inline sBox GetOutbox();
	inline std::string GetUUID(bool & bHasUUID);
	inline void SetUUID(const std::string & sUUID);
	inline PMetaDataGroup GetMetaDataGroup();
	inline void SetSlicesMeshResolution(const eSlicesMeshResolution eMeshResolution);
	inline eSlicesMeshResolution GetSlicesMeshResolution();
	inline bool HasSlices(const bool bRecursive);
	inline void ClearSliceStack();
	inline PSliceStack GetSliceStack();
	inline void AssignSliceStack(classParam<CSliceStack> pSliceStackInstance);
};
	
/*************************************************************************************************************************
 Class CMeshObject 
**************************************************************************************************************************/
class CMeshObject : public CObject {
public:
	
	/**
	* CMeshObject::CMeshObject - Constructor for MeshObject class.
	*/
	CMeshObject(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CObject(pWrapper, pHandle)
	{
	}
	
	inline Lib3MF_uint32 GetVertexCount();
	inline Lib3MF_uint32 GetTriangleCount();
	inline sPosition GetVertex(const Lib3MF_uint32 nIndex);
	inline void SetVertex(const Lib3MF_uint32 nIndex, const sPosition & Coordinates);
	inline Lib3MF_uint32 AddVertex(const sPosition & Coordinates);
	inline void GetVertices(std::vector<sPosition> & VerticesBuffer);
	inline sTriangle GetTriangle(const Lib3MF_uint32 nIndex);
	inline void SetTriangle(const Lib3MF_uint32 nIndex, const sTriangle & Indices);
	inline Lib3MF_uint32 AddTriangle(const sTriangle & Indices);
	inline void GetTriangleIndices(std::vector<sTriangle> & IndicesBuffer);
	inline void SetObjectLevelProperty(const Lib3MF_uint32 nUniqueResourceID, const Lib3MF_uint32 nPropertyID);
	inline bool GetObjectLevelProperty(Lib3MF_uint32 & nUniqueResourceID, Lib3MF_uint32 & nPropertyID);
	inline void SetTriangleProperties(const Lib3MF_uint32 nIndex, const sTriangleProperties & Properties);
	inline void GetTriangleProperties(const Lib3MF_uint32 nIndex, sTriangleProperties & Property);
	inline void SetAllTriangleProperties(const CInputVector<sTriangleProperties> & PropertiesArrayBuffer);
	inline void GetAllTriangleProperties(std::vector<sTriangleProperties> & PropertiesArrayBuffer);
	inline void ClearAllProperties();
	inline void SetGeometry(const CInputVector<sPosition> & VerticesBuffer, const CInputVector<sTriangle> & IndicesBuffer);
	inline bool IsManifoldAndOriented();
	inline PBeamLattice BeamLattice();
	inline PVolumeData GetVolumeData();
	inline void SetVolumeData(classParam<CVolumeData> pTheVolumeData);
	inline PTriangleSet AddTriangleSet(const std::string & sIdentifier, const std::string & sName);
	inline bool HasTriangleSet(const std::string & sIdentifier);
	inline PTriangleSet FindTriangleSet(const std::string & sIdentifier);
	inline Lib3MF_uint32 GetTriangleSetCount();
	inline PTriangleSet GetTriangleSet(const Lib3MF_uint32 nIndex);
};
	
/*************************************************************************************************************************
 Class CLevelSet 
**************************************************************************************************************************/
class CLevelSet : public CObject {
public:
	
	/**
	* CLevelSet::CLevelSet - Constructor for LevelSet class.
	*/
	CLevelSet(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CObject(pWrapper, pHandle)
	{
	}
	
	inline PFunction GetFunction();
	inline void SetFunction(classParam<CFunction> pTheFunction);
	inline sTransform GetTransform();
	inline void SetTransform(const sTransform & Transform);
	inline std::string GetChannelName();
	inline void SetChannelName(const std::string & sChannelName);
	inline void SetMinFeatureSize(const Lib3MF_double dMinFeatureSize);
	inline Lib3MF_double GetMinFeatureSize();
	inline void SetFallBackValue(const Lib3MF_double dFallBackValue);
	inline Lib3MF_double GetFallBackValue();
	inline void SetMeshBBoxOnly(const bool bMeshBBoxOnly);
	inline bool GetMeshBBoxOnly();
	inline void SetMesh(classParam<CMeshObject> pTheMesh);
	inline PMeshObject GetMesh();
	inline PVolumeData GetVolumeData();
	inline void SetVolumeData(classParam<CVolumeData> pTheVolumeData);
};
	
/*************************************************************************************************************************
 Class CBeamLattice 
**************************************************************************************************************************/
class CBeamLattice : public CBase {
public:
	
	/**
	* CBeamLattice::CBeamLattice - Constructor for BeamLattice class.
	*/
	CBeamLattice(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline Lib3MF_double GetMinLength();
	inline void SetMinLength(const Lib3MF_double dMinLength);
	inline void GetClipping(eBeamLatticeClipMode & eClipMode, Lib3MF_uint32 & nUniqueResourceID);
	inline void SetClipping(const eBeamLatticeClipMode eClipMode, const Lib3MF_uint32 nUniqueResourceID);
	inline bool GetRepresentation(Lib3MF_uint32 & nUniqueResourceID);
	inline void SetRepresentation(const Lib3MF_uint32 nUniqueResourceID);
	inline void GetBallOptions(eBeamLatticeBallMode & eBallMode, Lib3MF_double & dBallRadius);
	inline void SetBallOptions(const eBeamLatticeBallMode eBallMode, const Lib3MF_double dBallRadius);
	inline Lib3MF_uint32 GetBeamCount();
	inline sBeam GetBeam(const Lib3MF_uint32 nIndex);
	inline Lib3MF_uint32 AddBeam(const sBeam & BeamInfo);
	inline void SetBeam(const Lib3MF_uint32 nIndex, const sBeam & BeamInfo);
	inline void SetBeams(const CInputVector<sBeam> & BeamInfoBuffer);
	inline void GetBeams(std::vector<sBeam> & BeamInfoBuffer);
	inline Lib3MF_uint32 GetBallCount();
	inline sBall GetBall(const Lib3MF_uint32 nIndex);
	inline Lib3MF_uint32 AddBall(const sBall & BallInfo);
	inline void SetBall(const Lib3MF_uint32 nIndex, const sBall & BallInfo);
	inline void SetBalls(const CInputVector<sBall> & BallInfoBuffer);
	inline void GetBalls(std::vector<sBall> & BallInfoBuffer);
	inline Lib3MF_uint32 GetBeamSetCount();
	inline PBeamSet AddBeamSet();
	inline PBeamSet GetBeamSet(const Lib3MF_uint32 nIndex);
};
	
/*************************************************************************************************************************
 Class CFunctionReference 
**************************************************************************************************************************/
class CFunctionReference : public CBase {
public:
	
	/**
	* CFunctionReference::CFunctionReference - Constructor for FunctionReference class.
	*/
	CFunctionReference(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline Lib3MF_uint32 GetFunctionResourceID();
	inline void SetFunctionResourceID(const Lib3MF_uint32 nUniqueResourceID);
	inline sTransform GetTransform();
	inline void SetTransform(const sTransform & Transform);
	inline std::string GetChannelName();
	inline void SetChannelName(const std::string & sChannelName);
	inline void SetMinFeatureSize(const Lib3MF_double dMinFeatureSize);
	inline Lib3MF_double GetMinFeatureSize();
	inline void SetFallBackValue(const Lib3MF_double dFallBackValue);
	inline Lib3MF_double GetFallBackValue();
};
	
/*************************************************************************************************************************
 Class CVolumeDataColor 
**************************************************************************************************************************/
class CVolumeDataColor : public CFunctionReference {
public:
	
	/**
	* CVolumeDataColor::CVolumeDataColor - Constructor for VolumeDataColor class.
	*/
	CVolumeDataColor(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CFunctionReference(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CMaterialMapping 
**************************************************************************************************************************/
class CMaterialMapping : public CFunctionReference {
public:
	
	/**
	* CMaterialMapping::CMaterialMapping - Constructor for MaterialMapping class.
	*/
	CMaterialMapping(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CFunctionReference(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CVolumeDataComposite 
**************************************************************************************************************************/
class CVolumeDataComposite : public CBase {
public:
	
	/**
	* CVolumeDataComposite::CVolumeDataComposite - Constructor for VolumeDataComposite class.
	*/
	CVolumeDataComposite(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline PBaseMaterialGroup GetBaseMaterialGroup();
	inline void SetBaseMaterialGroup(classParam<CBaseMaterialGroup> pBaseMaterialGroupInstance);
	inline Lib3MF_uint32 GetMaterialMappingCount();
	inline PMaterialMapping GetMaterialMapping(const Lib3MF_uint32 nIndex);
	inline PMaterialMapping AddMaterialMapping(const sTransform & Transform);
	inline void RemoveMaterialMapping(const Lib3MF_uint32 nIndex);
};
	
/*************************************************************************************************************************
 Class CVolumeDataProperty 
**************************************************************************************************************************/
class CVolumeDataProperty : public CFunctionReference {
public:
	
	/**
	* CVolumeDataProperty::CVolumeDataProperty - Constructor for VolumeDataProperty class.
	*/
	CVolumeDataProperty(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CFunctionReference(pWrapper, pHandle)
	{
	}
	
	inline std::string GetName();
	inline void SetIsRequired(const bool bIsRequired);
	inline bool IsRequired();
};
	
/*************************************************************************************************************************
 Class CVolumeData 
**************************************************************************************************************************/
class CVolumeData : public CResource {
public:
	
	/**
	* CVolumeData::CVolumeData - Constructor for VolumeData class.
	*/
	CVolumeData(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResource(pWrapper, pHandle)
	{
	}
	
	inline PVolumeDataComposite GetComposite();
	inline PVolumeDataComposite CreateNewComposite();
	inline void RemoveComposite();
	inline PVolumeDataColor GetColor();
	inline PVolumeDataColor CreateNewColor(classParam<CFunction> pTheFunction);
	inline void RemoveColor();
	inline Lib3MF_uint32 GetPropertyCount();
	inline PVolumeDataProperty GetProperty(const Lib3MF_uint32 nIndex);
	inline PVolumeDataProperty AddPropertyFromFunction(const std::string & sName, classParam<CFunction> pTheFunction);
	inline void RemoveProperty(const Lib3MF_uint32 nIndex);
};
	
/*************************************************************************************************************************
 Class CComponent 
**************************************************************************************************************************/
class CComponent : public CBase {
public:
	
	/**
	* CComponent::CComponent - Constructor for Component class.
	*/
	CComponent(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline PObject GetObjectResource();
	inline Lib3MF_uint32 GetObjectResourceID();
	inline std::string GetUUID(bool & bHasUUID);
	inline void SetUUID(const std::string & sUUID);
	inline bool HasTransform();
	inline sTransform GetTransform();
	inline void SetTransform(const sTransform & Transform);
};
	
/*************************************************************************************************************************
 Class CComponentsObject 
**************************************************************************************************************************/
class CComponentsObject : public CObject {
public:
	
	/**
	* CComponentsObject::CComponentsObject - Constructor for ComponentsObject class.
	*/
	CComponentsObject(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CObject(pWrapper, pHandle)
	{
	}
	
	inline PComponent AddComponent(classParam<CObject> pObjectResource, const sTransform & Transform);
	inline PComponent GetComponent(const Lib3MF_uint32 nIndex);
	inline Lib3MF_uint32 GetComponentCount();
};
	
/*************************************************************************************************************************
 Class CBeamSet 
**************************************************************************************************************************/
class CBeamSet : public CBase {
public:
	
	/**
	* CBeamSet::CBeamSet - Constructor for BeamSet class.
	*/
	CBeamSet(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline void SetName(const std::string & sName);
	inline std::string GetName();
	inline void SetIdentifier(const std::string & sIdentifier);
	inline std::string GetIdentifier();
	inline Lib3MF_uint32 GetReferenceCount();
	inline void SetReferences(const CInputVector<Lib3MF_uint32> & ReferencesBuffer);
	inline void GetReferences(std::vector<Lib3MF_uint32> & ReferencesBuffer);
	inline Lib3MF_uint32 GetBallReferenceCount();
	inline void SetBallReferences(const CInputVector<Lib3MF_uint32> & BallReferencesBuffer);
	inline void GetBallReferences(std::vector<Lib3MF_uint32> & BallReferencesBuffer);
};
	
/*************************************************************************************************************************
 Class CBaseMaterialGroup 
**************************************************************************************************************************/
class CBaseMaterialGroup : public CResource {
public:
	
	/**
	* CBaseMaterialGroup::CBaseMaterialGroup - Constructor for BaseMaterialGroup class.
	*/
	CBaseMaterialGroup(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResource(pWrapper, pHandle)
	{
	}
	
	inline Lib3MF_uint32 GetCount();
	inline void GetAllPropertyIDs(std::vector<Lib3MF_uint32> & PropertyIDsBuffer);
	inline Lib3MF_uint32 AddMaterial(const std::string & sName, const sColor & DisplayColor);
	inline void RemoveMaterial(const Lib3MF_uint32 nPropertyID);
	inline std::string GetName(const Lib3MF_uint32 nPropertyID);
	inline void SetName(const Lib3MF_uint32 nPropertyID, const std::string & sName);
	inline void SetDisplayColor(const Lib3MF_uint32 nPropertyID, const sColor & TheColor);
	inline sColor GetDisplayColor(const Lib3MF_uint32 nPropertyID);
};
	
/*************************************************************************************************************************
 Class CColorGroup 
**************************************************************************************************************************/
class CColorGroup : public CResource {
public:
	
	/**
	* CColorGroup::CColorGroup - Constructor for ColorGroup class.
	*/
	CColorGroup(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResource(pWrapper, pHandle)
	{
	}
	
	inline Lib3MF_uint32 GetCount();
	inline void GetAllPropertyIDs(std::vector<Lib3MF_uint32> & PropertyIDsBuffer);
	inline Lib3MF_uint32 AddColor(const sColor & TheColor);
	inline void RemoveColor(const Lib3MF_uint32 nPropertyID);
	inline void SetColor(const Lib3MF_uint32 nPropertyID, const sColor & TheColor);
	inline sColor GetColor(const Lib3MF_uint32 nPropertyID);
};
	
/*************************************************************************************************************************
 Class CTexture2DGroup 
**************************************************************************************************************************/
class CTexture2DGroup : public CResource {
public:
	
	/**
	* CTexture2DGroup::CTexture2DGroup - Constructor for Texture2DGroup class.
	*/
	CTexture2DGroup(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResource(pWrapper, pHandle)
	{
	}
	
	inline Lib3MF_uint32 GetCount();
	inline void GetAllPropertyIDs(std::vector<Lib3MF_uint32> & PropertyIDsBuffer);
	inline Lib3MF_uint32 AddTex2Coord(const sTex2Coord & UVCoordinate);
	inline sTex2Coord GetTex2Coord(const Lib3MF_uint32 nPropertyID);
	inline void RemoveTex2Coord(const Lib3MF_uint32 nPropertyID);
	inline PTexture2D GetTexture2D();
};
	
/*************************************************************************************************************************
 Class CCompositeMaterials 
**************************************************************************************************************************/
class CCompositeMaterials : public CResource {
public:
	
	/**
	* CCompositeMaterials::CCompositeMaterials - Constructor for CompositeMaterials class.
	*/
	CCompositeMaterials(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResource(pWrapper, pHandle)
	{
	}
	
	inline Lib3MF_uint32 GetCount();
	inline void GetAllPropertyIDs(std::vector<Lib3MF_uint32> & PropertyIDsBuffer);
	inline PBaseMaterialGroup GetBaseMaterialGroup();
	inline Lib3MF_uint32 AddComposite(const CInputVector<sCompositeConstituent> & CompositeBuffer);
	inline void RemoveComposite(const Lib3MF_uint32 nPropertyID);
	inline void GetComposite(const Lib3MF_uint32 nPropertyID, std::vector<sCompositeConstituent> & CompositeBuffer);
};
	
/*************************************************************************************************************************
 Class CMultiPropertyGroup 
**************************************************************************************************************************/
class CMultiPropertyGroup : public CResource {
public:
	
	/**
	* CMultiPropertyGroup::CMultiPropertyGroup - Constructor for MultiPropertyGroup class.
	*/
	CMultiPropertyGroup(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResource(pWrapper, pHandle)
	{
	}
	
	inline Lib3MF_uint32 GetCount();
	inline void GetAllPropertyIDs(std::vector<Lib3MF_uint32> & PropertyIDsBuffer);
	inline Lib3MF_uint32 AddMultiProperty(const CInputVector<Lib3MF_uint32> & PropertyIDsBuffer);
	inline void SetMultiProperty(const Lib3MF_uint32 nPropertyID, const CInputVector<Lib3MF_uint32> & PropertyIDsBuffer);
	inline void GetMultiProperty(const Lib3MF_uint32 nPropertyID, std::vector<Lib3MF_uint32> & PropertyIDsBuffer);
	inline void RemoveMultiProperty(const Lib3MF_uint32 nPropertyID);
	inline Lib3MF_uint32 GetLayerCount();
	inline Lib3MF_uint32 AddLayer(const sMultiPropertyLayer & TheLayer);
	inline sMultiPropertyLayer GetLayer(const Lib3MF_uint32 nLayerIndex);
	inline void RemoveLayer(const Lib3MF_uint32 nLayerIndex);
};
	
/*************************************************************************************************************************
 Class CImage3D 
**************************************************************************************************************************/
class CImage3D : public CResource {
public:
	
	/**
	* CImage3D::CImage3D - Constructor for Image3D class.
	*/
	CImage3D(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResource(pWrapper, pHandle)
	{
	}
	
	inline std::string GetName();
	inline void SetName(const std::string & sName);
	inline bool IsImageStack();
};
	
/*************************************************************************************************************************
 Class CImageStack 
**************************************************************************************************************************/
class CImageStack : public CImage3D {
public:
	
	/**
	* CImageStack::CImageStack - Constructor for ImageStack class.
	*/
	CImageStack(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImage3D(pWrapper, pHandle)
	{
	}
	
	inline Lib3MF_uint32 GetRowCount();
	inline void SetRowCount(const Lib3MF_uint32 nRowCount);
	inline Lib3MF_uint32 GetColumnCount();
	inline void SetColumnCount(const Lib3MF_uint32 nColumnCount);
	inline Lib3MF_uint32 GetSheetCount();
	inline PAttachment GetSheet(const Lib3MF_uint32 nIndex);
	inline void SetSheet(const Lib3MF_uint32 nIndex, classParam<CAttachment> pSheet);
	inline PAttachment CreateEmptySheet(const Lib3MF_uint32 nIndex, const std::string & sPath);
	inline PAttachment CreateSheetFromBuffer(const Lib3MF_uint32 nIndex, const std::string & sPath, const CInputVector<Lib3MF_uint8> & DataBuffer);
	inline PAttachment CreateSheetFromFile(const Lib3MF_uint32 nIndex, const std::string & sPath, const std::string & sFileName);
};
	
/*************************************************************************************************************************
 Class CAttachment 
**************************************************************************************************************************/
class CAttachment : public CBase {
public:
	
	/**
	* CAttachment::CAttachment - Constructor for Attachment class.
	*/
	CAttachment(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline std::string GetPath();
	inline void SetPath(const std::string & sPath);
	inline PPackagePart PackagePart();
	inline std::string GetRelationShipType();
	inline void SetRelationShipType(const std::string & sPath);
	inline void WriteToFile(const std::string & sFileName);
	inline void ReadFromFile(const std::string & sFileName);
	inline void ReadFromCallback(const ReadCallback pTheReadCallback, const Lib3MF_uint64 nStreamSize, const SeekCallback pTheSeekCallback, const Lib3MF_pvoid pUserData);
	inline Lib3MF_uint64 GetStreamSize();
	inline void WriteToBuffer(std::vector<Lib3MF_uint8> & BufferBuffer);
	inline void ReadFromBuffer(const CInputVector<Lib3MF_uint8> & BufferBuffer);
};
	
/*************************************************************************************************************************
 Class CTexture2D 
**************************************************************************************************************************/
class CTexture2D : public CResource {
public:
	
	/**
	* CTexture2D::CTexture2D - Constructor for Texture2D class.
	*/
	CTexture2D(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResource(pWrapper, pHandle)
	{
	}
	
	inline PAttachment GetAttachment();
	inline void SetAttachment(classParam<CAttachment> pAttachment);
	inline eTextureType GetContentType();
	inline void SetContentType(const eTextureType eContentType);
	inline void GetTileStyleUV(eTextureTileStyle & eTileStyleU, eTextureTileStyle & eTileStyleV);
	inline void SetTileStyleUV(const eTextureTileStyle eTileStyleU, const eTextureTileStyle eTileStyleV);
	inline eTextureFilter GetFilter();
	inline void SetFilter(const eTextureFilter eFilter);
};
	
/*************************************************************************************************************************
 Class CImplicitPort 
**************************************************************************************************************************/
class CImplicitPort : public CBase {
public:
	
	/**
	* CImplicitPort::CImplicitPort - Constructor for ImplicitPort class.
	*/
	CImplicitPort(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline std::string GetIdentifier();
	inline void SetIdentifier(const std::string & sIdentifier);
	inline std::string GetDisplayName();
	inline void SetDisplayName(const std::string & sDisplayName);
	inline void SetType(const eImplicitPortType eImplicitPortType);
	inline eImplicitPortType GetType();
	inline std::string GetReference();
	inline void SetReference(const std::string & sReference);
};
	
/*************************************************************************************************************************
 Class CIterator 
**************************************************************************************************************************/
class CIterator : public CBase {
public:
	
	/**
	* CIterator::CIterator - Constructor for Iterator class.
	*/
	CIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline bool MoveNext();
	inline bool MovePrevious();
	inline Lib3MF_uint64 Count();
};
	
/*************************************************************************************************************************
 Class CImplicitPortIterator 
**************************************************************************************************************************/
class CImplicitPortIterator : public CIterator {
public:
	
	/**
	* CImplicitPortIterator::CImplicitPortIterator - Constructor for ImplicitPortIterator class.
	*/
	CImplicitPortIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CIterator(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetCurrent();
};
	
/*************************************************************************************************************************
 Class CImplicitNode 
**************************************************************************************************************************/
class CImplicitNode : public CBase {
public:
	
	/**
	* CImplicitNode::CImplicitNode - Constructor for ImplicitNode class.
	*/
	CImplicitNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline std::string GetIdentifier();
	inline void SetIdentifier(const std::string & sIdentifier);
	inline std::string GetDisplayName();
	inline void SetDisplayName(const std::string & sDisplayName);
	inline std::string GetTag();
	inline void SetTag(const std::string & sTag);
	inline eImplicitNodeType GetNodeType();
	inline PImplicitPort AddInput(const std::string & sIdentifier, const std::string & sDisplayName);
	inline PImplicitPortIterator GetInputs();
	inline PImplicitPort AddOutput(const std::string & sIdentifier, const std::string & sDisplayName);
	inline PImplicitPortIterator GetOutputs();
	inline PImplicitPort FindInput(const std::string & sIdentifier);
	inline PImplicitPort FindOutput(const std::string & sIdentifier);
	inline bool AreTypesValid();
};
	
/*************************************************************************************************************************
 Class COneInputNode 
**************************************************************************************************************************/
class COneInputNode : public CImplicitNode {
public:
	
	/**
	* COneInputNode::COneInputNode - Constructor for OneInputNode class.
	*/
	COneInputNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputA();
	inline PImplicitPort GetOutputResult();
};
	
/*************************************************************************************************************************
 Class CSinNode 
**************************************************************************************************************************/
class CSinNode : public COneInputNode {
public:
	
	/**
	* CSinNode::CSinNode - Constructor for SinNode class.
	*/
	CSinNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CCosNode 
**************************************************************************************************************************/
class CCosNode : public COneInputNode {
public:
	
	/**
	* CCosNode::CCosNode - Constructor for CosNode class.
	*/
	CCosNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CTanNode 
**************************************************************************************************************************/
class CTanNode : public COneInputNode {
public:
	
	/**
	* CTanNode::CTanNode - Constructor for TanNode class.
	*/
	CTanNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CArcSinNode 
**************************************************************************************************************************/
class CArcSinNode : public COneInputNode {
public:
	
	/**
	* CArcSinNode::CArcSinNode - Constructor for ArcSinNode class.
	*/
	CArcSinNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CArcCosNode 
**************************************************************************************************************************/
class CArcCosNode : public COneInputNode {
public:
	
	/**
	* CArcCosNode::CArcCosNode - Constructor for ArcCosNode class.
	*/
	CArcCosNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CArcTanNode 
**************************************************************************************************************************/
class CArcTanNode : public COneInputNode {
public:
	
	/**
	* CArcTanNode::CArcTanNode - Constructor for ArcTanNode class.
	*/
	CArcTanNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CSinhNode 
**************************************************************************************************************************/
class CSinhNode : public COneInputNode {
public:
	
	/**
	* CSinhNode::CSinhNode - Constructor for SinhNode class.
	*/
	CSinhNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CCoshNode 
**************************************************************************************************************************/
class CCoshNode : public COneInputNode {
public:
	
	/**
	* CCoshNode::CCoshNode - Constructor for CoshNode class.
	*/
	CCoshNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CTanhNode 
**************************************************************************************************************************/
class CTanhNode : public COneInputNode {
public:
	
	/**
	* CTanhNode::CTanhNode - Constructor for TanhNode class.
	*/
	CTanhNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CRoundNode 
**************************************************************************************************************************/
class CRoundNode : public COneInputNode {
public:
	
	/**
	* CRoundNode::CRoundNode - Constructor for RoundNode class.
	*/
	CRoundNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CCeilNode 
**************************************************************************************************************************/
class CCeilNode : public COneInputNode {
public:
	
	/**
	* CCeilNode::CCeilNode - Constructor for CeilNode class.
	*/
	CCeilNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CFloorNode 
**************************************************************************************************************************/
class CFloorNode : public COneInputNode {
public:
	
	/**
	* CFloorNode::CFloorNode - Constructor for FloorNode class.
	*/
	CFloorNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CSignNode 
**************************************************************************************************************************/
class CSignNode : public COneInputNode {
public:
	
	/**
	* CSignNode::CSignNode - Constructor for SignNode class.
	*/
	CSignNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CFractNode 
**************************************************************************************************************************/
class CFractNode : public COneInputNode {
public:
	
	/**
	* CFractNode::CFractNode - Constructor for FractNode class.
	*/
	CFractNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CAbsNode 
**************************************************************************************************************************/
class CAbsNode : public COneInputNode {
public:
	
	/**
	* CAbsNode::CAbsNode - Constructor for AbsNode class.
	*/
	CAbsNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CExpNode 
**************************************************************************************************************************/
class CExpNode : public COneInputNode {
public:
	
	/**
	* CExpNode::CExpNode - Constructor for ExpNode class.
	*/
	CExpNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CLogNode 
**************************************************************************************************************************/
class CLogNode : public COneInputNode {
public:
	
	/**
	* CLogNode::CLogNode - Constructor for LogNode class.
	*/
	CLogNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CLog2Node 
**************************************************************************************************************************/
class CLog2Node : public COneInputNode {
public:
	
	/**
	* CLog2Node::CLog2Node - Constructor for Log2Node class.
	*/
	CLog2Node(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CLog10Node 
**************************************************************************************************************************/
class CLog10Node : public COneInputNode {
public:
	
	/**
	* CLog10Node::CLog10Node - Constructor for Log10Node class.
	*/
	CLog10Node(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CLengthNode 
**************************************************************************************************************************/
class CLengthNode : public COneInputNode {
public:
	
	/**
	* CLengthNode::CLengthNode - Constructor for LengthNode class.
	*/
	CLengthNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CTransposeNode 
**************************************************************************************************************************/
class CTransposeNode : public COneInputNode {
public:
	
	/**
	* CTransposeNode::CTransposeNode - Constructor for TransposeNode class.
	*/
	CTransposeNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CInverseNode 
**************************************************************************************************************************/
class CInverseNode : public COneInputNode {
public:
	
	/**
	* CInverseNode::CInverseNode - Constructor for InverseNode class.
	*/
	CInverseNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CSqrtNode 
**************************************************************************************************************************/
class CSqrtNode : public COneInputNode {
public:
	
	/**
	* CSqrtNode::CSqrtNode - Constructor for SqrtNode class.
	*/
	CSqrtNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CResourceIdNode 
**************************************************************************************************************************/
class CResourceIdNode : public CImplicitNode {
public:
	
	/**
	* CResourceIdNode::CResourceIdNode - Constructor for ResourceIdNode class.
	*/
	CResourceIdNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline void SetResource(classParam<CResource> pResource);
	inline PResource GetResource();
	inline PImplicitPort GetOutputValue();
};
	
/*************************************************************************************************************************
 Class CTwoInputNode 
**************************************************************************************************************************/
class CTwoInputNode : public COneInputNode {
public:
	
	/**
	* CTwoInputNode::CTwoInputNode - Constructor for TwoInputNode class.
	*/
	CTwoInputNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputB();
};
	
/*************************************************************************************************************************
 Class CAdditionNode 
**************************************************************************************************************************/
class CAdditionNode : public CTwoInputNode {
public:
	
	/**
	* CAdditionNode::CAdditionNode - Constructor for AdditionNode class.
	*/
	CAdditionNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CTwoInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CSubtractionNode 
**************************************************************************************************************************/
class CSubtractionNode : public CTwoInputNode {
public:
	
	/**
	* CSubtractionNode::CSubtractionNode - Constructor for SubtractionNode class.
	*/
	CSubtractionNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CTwoInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CMultiplicationNode 
**************************************************************************************************************************/
class CMultiplicationNode : public CTwoInputNode {
public:
	
	/**
	* CMultiplicationNode::CMultiplicationNode - Constructor for MultiplicationNode class.
	*/
	CMultiplicationNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CTwoInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CDivisionNode 
**************************************************************************************************************************/
class CDivisionNode : public CTwoInputNode {
public:
	
	/**
	* CDivisionNode::CDivisionNode - Constructor for DivisionNode class.
	*/
	CDivisionNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CTwoInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CDotNode 
**************************************************************************************************************************/
class CDotNode : public CTwoInputNode {
public:
	
	/**
	* CDotNode::CDotNode - Constructor for DotNode class.
	*/
	CDotNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CTwoInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CCrossNode 
**************************************************************************************************************************/
class CCrossNode : public CTwoInputNode {
public:
	
	/**
	* CCrossNode::CCrossNode - Constructor for CrossNode class.
	*/
	CCrossNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CTwoInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CArcTan2Node 
**************************************************************************************************************************/
class CArcTan2Node : public CTwoInputNode {
public:
	
	/**
	* CArcTan2Node::CArcTan2Node - Constructor for ArcTan2Node class.
	*/
	CArcTan2Node(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CTwoInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CMatVecMultiplicationNode 
**************************************************************************************************************************/
class CMatVecMultiplicationNode : public CTwoInputNode {
public:
	
	/**
	* CMatVecMultiplicationNode::CMatVecMultiplicationNode - Constructor for MatVecMultiplicationNode class.
	*/
	CMatVecMultiplicationNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CTwoInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CMinNode 
**************************************************************************************************************************/
class CMinNode : public CTwoInputNode {
public:
	
	/**
	* CMinNode::CMinNode - Constructor for MinNode class.
	*/
	CMinNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CTwoInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CMaxNode 
**************************************************************************************************************************/
class CMaxNode : public CTwoInputNode {
public:
	
	/**
	* CMaxNode::CMaxNode - Constructor for MaxNode class.
	*/
	CMaxNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CTwoInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CFmodNode 
**************************************************************************************************************************/
class CFmodNode : public CTwoInputNode {
public:
	
	/**
	* CFmodNode::CFmodNode - Constructor for FmodNode class.
	*/
	CFmodNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CTwoInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CModNode 
**************************************************************************************************************************/
class CModNode : public CTwoInputNode {
public:
	
	/**
	* CModNode::CModNode - Constructor for ModNode class.
	*/
	CModNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CTwoInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CPowNode 
**************************************************************************************************************************/
class CPowNode : public CTwoInputNode {
public:
	
	/**
	* CPowNode::CPowNode - Constructor for PowNode class.
	*/
	CPowNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CTwoInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CSelectNode 
**************************************************************************************************************************/
class CSelectNode : public COneInputNode {
public:
	
	/**
	* CSelectNode::CSelectNode - Constructor for SelectNode class.
	*/
	CSelectNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputB();
	inline PImplicitPort GetInputC();
	inline PImplicitPort GetInputD();
};
	
/*************************************************************************************************************************
 Class CClampNode 
**************************************************************************************************************************/
class CClampNode : public COneInputNode {
public:
	
	/**
	* CClampNode::CClampNode - Constructor for ClampNode class.
	*/
	CClampNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputMin();
	inline PImplicitPort GetInputMax();
};
	
/*************************************************************************************************************************
 Class CComposeVectorNode 
**************************************************************************************************************************/
class CComposeVectorNode : public CImplicitNode {
public:
	
	/**
	* CComposeVectorNode::CComposeVectorNode - Constructor for ComposeVectorNode class.
	*/
	CComposeVectorNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputX();
	inline PImplicitPort GetInputY();
	inline PImplicitPort GetInputZ();
	inline PImplicitPort GetOutputResult();
};
	
/*************************************************************************************************************************
 Class CVectorFromScalarNode 
**************************************************************************************************************************/
class CVectorFromScalarNode : public COneInputNode {
public:
	
	/**
	* CVectorFromScalarNode::CVectorFromScalarNode - Constructor for VectorFromScalarNode class.
	*/
	CVectorFromScalarNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: COneInputNode(pWrapper, pHandle)
	{
	}
	
};
	
/*************************************************************************************************************************
 Class CDecomposeVectorNode 
**************************************************************************************************************************/
class CDecomposeVectorNode : public CImplicitNode {
public:
	
	/**
	* CDecomposeVectorNode::CDecomposeVectorNode - Constructor for DecomposeVectorNode class.
	*/
	CDecomposeVectorNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputA();
	inline PImplicitPort GetOutputX();
	inline PImplicitPort GetOutputY();
	inline PImplicitPort GetOutputZ();
};
	
/*************************************************************************************************************************
 Class CComposeMatrixNode 
**************************************************************************************************************************/
class CComposeMatrixNode : public CImplicitNode {
public:
	
	/**
	* CComposeMatrixNode::CComposeMatrixNode - Constructor for ComposeMatrixNode class.
	*/
	CComposeMatrixNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputM00();
	inline PImplicitPort GetInputM01();
	inline PImplicitPort GetInputM02();
	inline PImplicitPort GetInputM03();
	inline PImplicitPort GetInputM10();
	inline PImplicitPort GetInputM11();
	inline PImplicitPort GetInputM12();
	inline PImplicitPort GetInputM13();
	inline PImplicitPort GetInputM20();
	inline PImplicitPort GetInputM21();
	inline PImplicitPort GetInputM22();
	inline PImplicitPort GetInputM23();
	inline PImplicitPort GetInputM30();
	inline PImplicitPort GetInputM31();
	inline PImplicitPort GetInputM32();
	inline PImplicitPort GetInputM33();
	inline PImplicitPort GetOutputResult();
};
	
/*************************************************************************************************************************
 Class CMatrixFromRowsNode 
**************************************************************************************************************************/
class CMatrixFromRowsNode : public CImplicitNode {
public:
	
	/**
	* CMatrixFromRowsNode::CMatrixFromRowsNode - Constructor for MatrixFromRowsNode class.
	*/
	CMatrixFromRowsNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputA();
	inline PImplicitPort GetInputB();
	inline PImplicitPort GetInputC();
	inline PImplicitPort GetInputD();
	inline PImplicitPort GetOutputResult();
};
	
/*************************************************************************************************************************
 Class CMatrixFromColumnsNode 
**************************************************************************************************************************/
class CMatrixFromColumnsNode : public CImplicitNode {
public:
	
	/**
	* CMatrixFromColumnsNode::CMatrixFromColumnsNode - Constructor for MatrixFromColumnsNode class.
	*/
	CMatrixFromColumnsNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputA();
	inline PImplicitPort GetInputB();
	inline PImplicitPort GetInputC();
	inline PImplicitPort GetInputD();
	inline PImplicitPort GetOutputResult();
};
	
/*************************************************************************************************************************
 Class CConstantNode 
**************************************************************************************************************************/
class CConstantNode : public CImplicitNode {
public:
	
	/**
	* CConstantNode::CConstantNode - Constructor for ConstantNode class.
	*/
	CConstantNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline void SetConstant(const Lib3MF_double dValue);
	inline Lib3MF_double GetConstant();
	inline PImplicitPort GetOutputValue();
};
	
/*************************************************************************************************************************
 Class CConstVecNode 
**************************************************************************************************************************/
class CConstVecNode : public CImplicitNode {
public:
	
	/**
	* CConstVecNode::CConstVecNode - Constructor for ConstVecNode class.
	*/
	CConstVecNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline void SetVector(const sVector & Value);
	inline sVector GetVector();
	inline PImplicitPort GetOutputVector();
};
	
/*************************************************************************************************************************
 Class CConstMatNode 
**************************************************************************************************************************/
class CConstMatNode : public CImplicitNode {
public:
	
	/**
	* CConstMatNode::CConstMatNode - Constructor for ConstMatNode class.
	*/
	CConstMatNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline void SetMatrix(const sMatrix4x4 & Value);
	inline sMatrix4x4 GetMatrix();
	inline PImplicitPort GetOutputMatrix();
};
	
/*************************************************************************************************************************
 Class CMeshNode 
**************************************************************************************************************************/
class CMeshNode : public CImplicitNode {
public:
	
	/**
	* CMeshNode::CMeshNode - Constructor for MeshNode class.
	*/
	CMeshNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputMesh();
	inline PImplicitPort GetInputPos();
	inline PImplicitPort GetOutputDistance();
};
	
/*************************************************************************************************************************
 Class CUnsignedMeshNode 
**************************************************************************************************************************/
class CUnsignedMeshNode : public CImplicitNode {
public:
	
	/**
	* CUnsignedMeshNode::CUnsignedMeshNode - Constructor for UnsignedMeshNode class.
	*/
	CUnsignedMeshNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputMesh();
	inline PImplicitPort GetInputPos();
	inline PImplicitPort GetOutputDistance();
};
	
/*************************************************************************************************************************
 Class CBeamLatticeNode 
**************************************************************************************************************************/
class CBeamLatticeNode : public CImplicitNode {
public:
	
	/**
	* CBeamLatticeNode::CBeamLatticeNode - Constructor for BeamLatticeNode class.
	*/
	CBeamLatticeNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputBeamLattice();
	inline PImplicitPort GetInputPos();
	inline PImplicitPort GetOutputDistance();
	inline void SetAccurateRange(const Lib3MF_double dAccurateRange);
	inline Lib3MF_double GetAccurateRange();
};
	
/*************************************************************************************************************************
 Class CFunctionGradientNode 
**************************************************************************************************************************/
class CFunctionGradientNode : public CImplicitNode {
public:
	
	/**
	* CFunctionGradientNode::CFunctionGradientNode - Constructor for FunctionGradientNode class.
	*/
	CFunctionGradientNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputFunctionID();
	inline PImplicitPort GetInputPos();
	inline PImplicitPort GetInputStep();
	inline void SetScalarOutputName(const std::string & sScalarOutputName);
	inline std::string GetScalarOutputName();
	inline void SetVectorInputName(const std::string & sVectorInputName);
	inline std::string GetVectorInputName();
	inline PImplicitPort GetOutputNormalizedGradient();
	inline PImplicitPort GetOutputGradient();
	inline PImplicitPort GetOutputMagnitude();
};
	
/*************************************************************************************************************************
 Class CNormalizeDistanceNode 
**************************************************************************************************************************/
class CNormalizeDistanceNode : public CImplicitNode {
public:
	
	/**
	* CNormalizeDistanceNode::CNormalizeDistanceNode - Constructor for NormalizeDistanceNode class.
	*/
	CNormalizeDistanceNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputFunctionID();
	inline PImplicitPort GetInputPos();
	inline PImplicitPort GetInputStep();
	inline void SetScalarOutputName(const std::string & sScalarOutputName);
	inline std::string GetScalarOutputName();
	inline void SetVectorInputName(const std::string & sVectorInputName);
	inline std::string GetVectorInputName();
	inline PImplicitPort GetOutputResult();
};
	
/*************************************************************************************************************************
 Class CFunctionCallNode 
**************************************************************************************************************************/
class CFunctionCallNode : public CImplicitNode {
public:
	
	/**
	* CFunctionCallNode::CFunctionCallNode - Constructor for FunctionCallNode class.
	*/
	CFunctionCallNode(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CImplicitNode(pWrapper, pHandle)
	{
	}
	
	inline PImplicitPort GetInputFunctionID();
};
	
/*************************************************************************************************************************
 Class CNodeIterator 
**************************************************************************************************************************/
class CNodeIterator : public CIterator {
public:
	
	/**
	* CNodeIterator::CNodeIterator - Constructor for NodeIterator class.
	*/
	CNodeIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CIterator(pWrapper, pHandle)
	{
	}
	
	inline PImplicitNode GetCurrent();
};
	
/*************************************************************************************************************************
 Class CFunction 
**************************************************************************************************************************/
class CFunction : public CResource {
public:
	
	/**
	* CFunction::CFunction - Constructor for Function class.
	*/
	CFunction(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResource(pWrapper, pHandle)
	{
	}
	
	inline std::string GetDisplayName();
	inline void SetDisplayName(const std::string & sDisplayName);
	inline PImplicitPort AddInput(const std::string & sIdentifier, const std::string & sDisplayName, const eImplicitPortType eType);
	inline PImplicitPortIterator GetInputs();
	inline void RemoveInput(classParam<CImplicitPort> pInput);
	inline PImplicitPort AddOutput(const std::string & sIdentifier, const std::string & sDisplayName, const eImplicitPortType eType);
	inline PImplicitPortIterator GetOutputs();
	inline void RemoveOutput(classParam<CImplicitPort> pOutput);
	inline PImplicitPort FindInput(const std::string & sIdentifier);
	inline PImplicitPort FindOutput(const std::string & sIdentifier);
};
	
/*************************************************************************************************************************
 Class CImplicitFunction 
**************************************************************************************************************************/
class CImplicitFunction : public CFunction {
public:
	
	/**
	* CImplicitFunction::CImplicitFunction - Constructor for ImplicitFunction class.
	*/
	CImplicitFunction(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CFunction(pWrapper, pHandle)
	{
	}
	
	inline std::string GetIdentifier();
	inline void SetIdentifier(const std::string & sIdentifier);
	inline PImplicitNode AddNode(const eImplicitNodeType eNodeType, const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PSinNode AddSinNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PCosNode AddCosNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PTanNode AddTanNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PArcSinNode AddArcSinNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PArcCosNode AddArcCosNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PArcTan2Node AddArcTan2Node(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PSinhNode AddSinhNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PCoshNode AddCoshNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PTanhNode AddTanhNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PRoundNode AddRoundNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PCeilNode AddCeilNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PFloorNode AddFloorNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PSignNode AddSignNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PFractNode AddFractNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PAbsNode AddAbsNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PExpNode AddExpNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PLogNode AddLogNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PLog2Node AddLog2Node(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PLog10Node AddLog10Node(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PLengthNode AddLengthNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PTransposeNode AddTransposeNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PInverseNode AddInverseNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PSqrtNode AddSqrtNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PResourceIdNode AddResourceIdNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PAdditionNode AddAdditionNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PSubtractionNode AddSubtractionNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PMultiplicationNode AddMultiplicationNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PDivisionNode AddDivisionNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PDotNode AddDotNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PCrossNode AddCrossNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PMatVecMultiplicationNode AddMatVecMultiplicationNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PMinNode AddMinNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PMaxNode AddMaxNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PFmodNode AddFmodNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PPowNode AddPowNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PSelectNode AddSelectNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PClampNode AddClampNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag);
	inline PComposeVectorNode AddComposeVectorNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PVectorFromScalarNode AddVectorFromScalarNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PDecomposeVectorNode AddDecomposeVectorNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PComposeMatrixNode AddComposeMatrixNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PMatrixFromRowsNode AddMatrixFromRowsNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PMatrixFromColumnsNode AddMatrixFromColumnsNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PConstantNode AddConstantNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PConstVecNode AddConstVecNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PConstMatNode AddConstMatNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PMeshNode AddMeshNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PUnsignedMeshNode AddUnsignedMeshNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PBeamLatticeNode AddBeamLatticeNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PFunctionGradientNode AddFunctionGradientNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PNormalizeDistanceNode AddNormalizeDistanceNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PFunctionCallNode AddFunctionCallNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag);
	inline PNodeIterator GetNodes();
	inline void RemoveNode(classParam<CImplicitNode> pNode);
	inline void AddLink(classParam<CImplicitPort> pSource, classParam<CImplicitPort> pTarget);
	inline void AddLinkByNames(const std::string & sSource, const std::string & sTarget);
	inline void Clear();
	inline void SortNodesTopologically();
};
	
/*************************************************************************************************************************
 Class CFunctionFromImage3D 
**************************************************************************************************************************/
class CFunctionFromImage3D : public CFunction {
public:
	
	/**
	* CFunctionFromImage3D::CFunctionFromImage3D - Constructor for FunctionFromImage3D class.
	*/
	CFunctionFromImage3D(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CFunction(pWrapper, pHandle)
	{
	}
	
	inline PImage3D GetImage3D();
	inline void SetImage3D(classParam<CImage3D> pImage3D);
	inline void SetFilter(const eTextureFilter eFilter);
	inline eTextureFilter GetFilter();
	inline void SetTileStyles(const eTextureTileStyle eTileStyleU, const eTextureTileStyle eTileStyleV, const eTextureTileStyle eTileStyleW);
	inline void GetTileStyles(eTextureTileStyle & eTileStyleU, eTextureTileStyle & eTileStyleV, eTextureTileStyle & eTileStyleW);
	inline Lib3MF_double GetOffset();
	inline void SetOffset(const Lib3MF_double dOffset);
	inline Lib3MF_double GetScale();
	inline void SetScale(const Lib3MF_double dScale);
};
	
/*************************************************************************************************************************
 Class CBuildItem 
**************************************************************************************************************************/
class CBuildItem : public CBase {
public:
	
	/**
	* CBuildItem::CBuildItem - Constructor for BuildItem class.
	*/
	CBuildItem(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline PObject GetObjectResource();
	inline std::string GetUUID(bool & bHasUUID);
	inline void SetUUID(const std::string & sUUID);
	inline Lib3MF_uint32 GetObjectResourceID();
	inline bool HasObjectTransform();
	inline sTransform GetObjectTransform();
	inline void SetObjectTransform(const sTransform & Transform);
	inline std::string GetPartNumber();
	inline void SetPartNumber(const std::string & sSetPartnumber);
	inline PMetaDataGroup GetMetaDataGroup();
	inline sBox GetOutbox();
};
	
/*************************************************************************************************************************
 Class CBuildItemIterator 
**************************************************************************************************************************/
class CBuildItemIterator : public CBase {
public:
	
	/**
	* CBuildItemIterator::CBuildItemIterator - Constructor for BuildItemIterator class.
	*/
	CBuildItemIterator(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline bool MoveNext();
	inline bool MovePrevious();
	inline PBuildItem GetCurrent();
	inline PBuildItemIterator Clone();
	inline Lib3MF_uint64 Count();
};
	
/*************************************************************************************************************************
 Class CSlice 
**************************************************************************************************************************/
class CSlice : public CBase {
public:
	
	/**
	* CSlice::CSlice - Constructor for Slice class.
	*/
	CSlice(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline void SetVertices(const CInputVector<sPosition2D> & VerticesBuffer);
	inline void GetVertices(std::vector<sPosition2D> & VerticesBuffer);
	inline Lib3MF_uint64 GetVertexCount();
	inline Lib3MF_uint64 AddPolygon(const CInputVector<Lib3MF_uint32> & IndicesBuffer);
	inline Lib3MF_uint64 GetPolygonCount();
	inline void SetPolygonIndices(const Lib3MF_uint64 nIndex, const CInputVector<Lib3MF_uint32> & IndicesBuffer);
	inline void GetPolygonIndices(const Lib3MF_uint64 nIndex, std::vector<Lib3MF_uint32> & IndicesBuffer);
	inline Lib3MF_uint64 GetPolygonIndexCount(const Lib3MF_uint64 nIndex);
	inline Lib3MF_double GetZTop();
};
	
/*************************************************************************************************************************
 Class CSliceStack 
**************************************************************************************************************************/
class CSliceStack : public CResource {
public:
	
	/**
	* CSliceStack::CSliceStack - Constructor for SliceStack class.
	*/
	CSliceStack(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CResource(pWrapper, pHandle)
	{
	}
	
	inline Lib3MF_double GetBottomZ();
	inline Lib3MF_uint64 GetSliceCount();
	inline PSlice GetSlice(const Lib3MF_uint64 nSliceIndex);
	inline PSlice AddSlice(const Lib3MF_double dZTop);
	inline Lib3MF_uint64 GetSliceRefCount();
	inline void AddSliceStackReference(classParam<CSliceStack> pTheSliceStack);
	inline PSliceStack GetSliceStackReference(const Lib3MF_uint64 nSliceRefIndex);
	inline void CollapseSliceReferences();
	inline void SetOwnPath(const std::string & sPath);
	inline std::string GetOwnPath();
};
	
/*************************************************************************************************************************
 Class CConsumer 
**************************************************************************************************************************/
class CConsumer : public CBase {
public:
	
	/**
	* CConsumer::CConsumer - Constructor for Consumer class.
	*/
	CConsumer(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline std::string GetConsumerID();
	inline std::string GetKeyID();
	inline std::string GetKeyValue();
};
	
/*************************************************************************************************************************
 Class CAccessRight 
**************************************************************************************************************************/
class CAccessRight : public CBase {
public:
	
	/**
	* CAccessRight::CAccessRight - Constructor for AccessRight class.
	*/
	CAccessRight(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline PConsumer GetConsumer();
	inline eWrappingAlgorithm GetWrappingAlgorithm();
	inline eMgfAlgorithm GetMgfAlgorithm();
	inline eDigestMethod GetDigestMethod();
};
	
/*************************************************************************************************************************
 Class CContentEncryptionParams 
**************************************************************************************************************************/
class CContentEncryptionParams : public CBase {
public:
	
	/**
	* CContentEncryptionParams::CContentEncryptionParams - Constructor for ContentEncryptionParams class.
	*/
	CContentEncryptionParams(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline eEncryptionAlgorithm GetEncryptionAlgorithm();
	inline void GetKey(std::vector<Lib3MF_uint8> & ByteDataBuffer);
	inline void GetInitializationVector(std::vector<Lib3MF_uint8> & ByteDataBuffer);
	inline void GetAuthenticationTag(std::vector<Lib3MF_uint8> & ByteDataBuffer);
	inline void SetAuthenticationTag(const CInputVector<Lib3MF_uint8> & ByteDataBuffer);
	inline void GetAdditionalAuthenticationData(std::vector<Lib3MF_uint8> & ByteDataBuffer);
	inline Lib3MF_uint64 GetDescriptor();
	inline std::string GetKeyUUID();
};
	
/*************************************************************************************************************************
 Class CResourceData 
**************************************************************************************************************************/
class CResourceData : public CBase {
public:
	
	/**
	* CResourceData::CResourceData - Constructor for ResourceData class.
	*/
	CResourceData(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline PPackagePart GetPath();
	inline eEncryptionAlgorithm GetEncryptionAlgorithm();
	inline eCompression GetCompression();
	inline void GetAdditionalAuthenticationData(std::vector<Lib3MF_uint8> & ByteDataBuffer);
};
	
/*************************************************************************************************************************
 Class CResourceDataGroup 
**************************************************************************************************************************/
class CResourceDataGroup : public CBase {
public:
	
	/**
	* CResourceDataGroup::CResourceDataGroup - Constructor for ResourceDataGroup class.
	*/
	CResourceDataGroup(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline std::string GetKeyUUID();
	inline PAccessRight AddAccessRight(classParam<CConsumer> pConsumer, const eWrappingAlgorithm eWrappingAlgorithm, const eMgfAlgorithm eMgfAlgorithm, const eDigestMethod eDigestMethod);
	inline PAccessRight FindAccessRightByConsumer(classParam<CConsumer> pConsumer);
	inline void RemoveAccessRight(classParam<CConsumer> pConsumer);
};
	
/*************************************************************************************************************************
 Class CKeyStore 
**************************************************************************************************************************/
class CKeyStore : public CBase {
public:
	
	/**
	* CKeyStore::CKeyStore - Constructor for KeyStore class.
	*/
	CKeyStore(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline PConsumer AddConsumer(const std::string & sConsumerID, const std::string & sKeyID, const std::string & sKeyValue);
	inline Lib3MF_uint64 GetConsumerCount();
	inline PConsumer GetConsumer(const Lib3MF_uint64 nConsumerIndex);
	inline void RemoveConsumer(classParam<CConsumer> pConsumer);
	inline PConsumer FindConsumer(const std::string & sConsumerID);
	inline Lib3MF_uint64 GetResourceDataGroupCount();
	inline PResourceDataGroup AddResourceDataGroup();
	inline PResourceDataGroup GetResourceDataGroup(const Lib3MF_uint64 nResourceDataIndex);
	inline void RemoveResourceDataGroup(classParam<CResourceDataGroup> pResourceDataGroup);
	inline PResourceDataGroup FindResourceDataGroup(classParam<CPackagePart> pPartPath);
	inline PResourceData AddResourceData(classParam<CResourceDataGroup> pResourceDataGroup, classParam<CPackagePart> pPartPath, const eEncryptionAlgorithm eAlgorithm, const eCompression eCompression, const CInputVector<Lib3MF_uint8> & AdditionalAuthenticationDataBuffer);
	inline void RemoveResourceData(classParam<CResourceData> pResourceData);
	inline PResourceData FindResourceData(classParam<CPackagePart> pResourcePath);
	inline Lib3MF_uint64 GetResourceDataCount();
	inline PResourceData GetResourceData(const Lib3MF_uint64 nResourceDataIndex);
	inline std::string GetUUID(bool & bHasUUID);
	inline void SetUUID(const std::string & sUUID);
};
	
/*************************************************************************************************************************
 Class CModel 
**************************************************************************************************************************/
class CModel : public CBase {
public:
	
	/**
	* CModel::CModel - Constructor for Model class.
	*/
	CModel(CWrapper* pWrapper, Lib3MFHandle pHandle)
		: CBase(pWrapper, pHandle)
	{
	}
	
	inline PPackagePart RootModelPart();
	inline PPackagePart FindOrCreatePackagePart(const std::string & sAbsolutePath);
	inline void SetUnit(const eModelUnit eUnit);
	inline eModelUnit GetUnit();
	inline std::string GetLanguage();
	inline void SetLanguage(const std::string & sLanguage);
	inline PWriter QueryWriter(const std::string & sWriterClass);
	inline PReader QueryReader(const std::string & sReaderClass);
	inline PResource GetResourceByID(const Lib3MF_uint32 nUniqueResourceID);
	inline PTexture2D GetTexture2DByID(const Lib3MF_uint32 nUniqueResourceID);
	inline ePropertyType GetPropertyTypeByID(const Lib3MF_uint32 nUniqueResourceID);
	inline PBaseMaterialGroup GetBaseMaterialGroupByID(const Lib3MF_uint32 nUniqueResourceID);
	inline PTexture2DGroup GetTexture2DGroupByID(const Lib3MF_uint32 nUniqueResourceID);
	inline PCompositeMaterials GetCompositeMaterialsByID(const Lib3MF_uint32 nUniqueResourceID);
	inline PMultiPropertyGroup GetMultiPropertyGroupByID(const Lib3MF_uint32 nUniqueResourceID);
	inline PMeshObject GetMeshObjectByID(const Lib3MF_uint32 nUniqueResourceID);
	inline PComponentsObject GetComponentsObjectByID(const Lib3MF_uint32 nUniqueResourceID);
	inline PColorGroup GetColorGroupByID(const Lib3MF_uint32 nUniqueResourceID);
	inline PSliceStack GetSliceStackByID(const Lib3MF_uint32 nUniqueResourceID);
	inline PLevelSet GetLevelSetByID(const Lib3MF_uint32 nUniqueResourceID);
	inline std::string GetBuildUUID(bool & bHasUUID);
	inline void SetBuildUUID(const std::string & sUUID);
	inline PBuildItemIterator GetBuildItems();
	inline sBox GetOutbox();
	inline PResourceIterator GetResources();
	inline PObjectIterator GetObjects();
	inline PMeshObjectIterator GetMeshObjects();
	inline PComponentsObjectIterator GetComponentsObjects();
	inline PTexture2DIterator GetTexture2Ds();
	inline PBaseMaterialGroupIterator GetBaseMaterialGroups();
	inline PColorGroupIterator GetColorGroups();
	inline PTexture2DGroupIterator GetTexture2DGroups();
	inline PCompositeMaterialsIterator GetCompositeMaterials();
	inline PMultiPropertyGroupIterator GetMultiPropertyGroups();
	inline PSliceStackIterator GetSliceStacks();
	inline PImage3DIterator GetImage3Ds();
	inline PModel MergeToModel();
	inline void MergeFromModel(classParam<CModel> pModelInstance);
	inline PMeshObject AddMeshObject();
	inline PComponentsObject AddComponentsObject();
	inline PSliceStack AddSliceStack(const Lib3MF_double dZBottom);
	inline PTexture2D AddTexture2DFromAttachment(classParam<CAttachment> pTextureAttachment);
	inline PBaseMaterialGroup AddBaseMaterialGroup();
	inline PColorGroup AddColorGroup();
	inline PTexture2DGroup AddTexture2DGroup(classParam<CTexture2D> pTexture2DInstance);
	inline PCompositeMaterials AddCompositeMaterials(classParam<CBaseMaterialGroup> pBaseMaterialGroupInstance);
	inline PMultiPropertyGroup AddMultiPropertyGroup();
	inline PImageStack AddImageStack(const Lib3MF_uint32 nColumnCount, const Lib3MF_uint32 nRowCount, const Lib3MF_uint32 nSheetCount);
	inline PImageStack GetImageStackByID(const Lib3MF_uint32 nUniqueResourceID);
	inline PBuildItem AddBuildItem(classParam<CObject> pObject, const sTransform & Transform);
	inline void RemoveBuildItem(classParam<CBuildItem> pBuildItemInstance);
	inline PMetaDataGroup GetMetaDataGroup();
	inline PAttachment AddAttachment(const std::string & sURI, const std::string & sRelationShipType);
	inline void RemoveAttachment(classParam<CAttachment> pAttachmentInstance);
	inline PAttachment GetAttachment(const Lib3MF_uint32 nIndex);
	inline PAttachment FindAttachment(const std::string & sURI);
	inline Lib3MF_uint32 GetAttachmentCount();
	inline bool HasPackageThumbnailAttachment();
	inline PAttachment CreatePackageThumbnailAttachment();
	inline PAttachment GetPackageThumbnailAttachment();
	inline void RemovePackageThumbnailAttachment();
	inline void AddCustomContentType(const std::string & sExtension, const std::string & sContentType);
	inline void RemoveCustomContentType(const std::string & sExtension);
	inline void SetRandomNumberCallback(const RandomNumberCallback pTheCallback, const Lib3MF_pvoid pUserData);
	inline PKeyStore GetKeyStore();
	inline PFunctionIterator GetFunctions();
	inline PImplicitFunction AddImplicitFunction();
	inline PFunctionFromImage3D AddFunctionFromImage3D(classParam<CImage3D> pImage3DInstance);
	inline PVolumeData AddVolumeData();
	inline PLevelSet AddLevelSet();
	inline PLevelSetIterator GetLevelSets();
	inline void RemoveResource(classParam<CResource> pResource);
};

/*************************************************************************************************************************
 RTTI: Polymorphic Factory implementation
**************************************************************************************************************************/

/**
* IMPORTANT: PolymorphicFactory method should not be used by application directly.
*            It's designed to be used on Lib3MFHandle object only once.
*            If it's used on any existing object as a form of dynamic cast then
*            CWrapper::AcquireInstance(CBase object) must be called after instantiating new object.
*            This is important to keep reference count matching between application and library sides.
*/
inline CBase* CWrapper::polymorphicFactory(Lib3MFHandle pHandle)
{
	Lib3MF_uint64 resultClassTypeId = 0;
	CheckError(nullptr, lib3mf_base_classtypeid(pHandle, &resultClassTypeId));
	switch(resultClassTypeId) {
		case 0x856632D0BAF1D8B7UL: return new CBase(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Base"
		case 0xE76F642F363FD7E9UL: return new CWriter(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Writer"
		case 0x2D86831DA59FBE72UL: return new CReader(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Reader"
		case 0x0E55A826D377483EUL: return new CPackagePart(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::PackagePart"
		case 0xDFE3889D1B269CBBUL: return new CResource(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Resource"
		case 0x460F3515E2621DBEUL: return new CResourceIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ResourceIterator"
		case 0x69684DB99FA813F6UL: return new CSliceStackIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::SliceStackIterator"
		case 0xDE92510BD2112288UL: return new CObjectIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ObjectIterator"
		case 0xF4196034E2B9FDE6UL: return new CMeshObjectIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MeshObjectIterator"
		case 0x564DE4217ED7614AUL: return new CComponentsObjectIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ComponentsObjectIterator"
		case 0x4BD32B4870FFC03BUL: return new CTexture2DIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Texture2DIterator"
		case 0x65E6EDD9362C79CBUL: return new CBaseMaterialGroupIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::BaseMaterialGroupIterator"
		case 0x10274A1757C729C0UL: return new CColorGroupIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ColorGroupIterator"
		case 0x30D55F4DB88FE0CAUL: return new CTexture2DGroupIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Texture2DGroupIterator"
		case 0xA99CC6C3F70FB6F9UL: return new CCompositeMaterialsIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::CompositeMaterialsIterator"
		case 0xC2BDF5D8CBBDB1F0UL: return new CMultiPropertyGroupIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MultiPropertyGroupIterator"
		case 0xC4B8EC00A82BF336UL: return new CImage3DIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Image3DIterator"
		case 0x40E9035363ACE65EUL: return new CFunctionIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::FunctionIterator"
		case 0xA0C005C035D5371DUL: return new CLevelSetIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::LevelSetIterator"
		case 0xD17716D063DE2C22UL: return new CMetaData(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MetaData"
		case 0x0C3B85369E9B25D3UL: return new CMetaDataGroup(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MetaDataGroup"
		case 0x5950BB3EE8A82090UL: return new CTriangleSet(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::TriangleSet"
		case 0x2DA2136F577A779CUL: return new CObject(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Object"
		case 0x3B3A6DC6EC610497UL: return new CMeshObject(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MeshObject"
		case 0xE8A7D9C192EFD0E2UL: return new CLevelSet(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::LevelSet"
		case 0x63B3B461B30B4BA5UL: return new CBeamLattice(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::BeamLattice"
		case 0x4DF17E76926221C2UL: return new CFunctionReference(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::FunctionReference"
		case 0xD85B5B6143E787E3UL: return new CVolumeDataColor(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::VolumeDataColor"
		case 0x241FE6B4817C3FE4UL: return new CMaterialMapping(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MaterialMapping"
		case 0x46F1DAC40581B304UL: return new CVolumeDataComposite(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::VolumeDataComposite"
		case 0xFC368AA44ACE42DAUL: return new CVolumeDataProperty(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::VolumeDataProperty"
		case 0x9200586FB91587A7UL: return new CVolumeData(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::VolumeData"
		case 0x4ECDB6A6F69F2BEBUL: return new CComponent(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Component"
		case 0x6522CF04EB283FEDUL: return new CComponentsObject(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ComponentsObject"
		case 0x30CCDBE90E00B55BUL: return new CBeamSet(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::BeamSet"
		case 0xB27D4656E16609FAUL: return new CBaseMaterialGroup(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::BaseMaterialGroup"
		case 0xD085FB2E49CDB5B1UL: return new CColorGroup(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ColorGroup"
		case 0xBC1208397E37055DUL: return new CTexture2DGroup(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Texture2DGroup"
		case 0xCE16224D688B86F2UL: return new CCompositeMaterials(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::CompositeMaterials"
		case 0xB989E02E43158FE6UL: return new CMultiPropertyGroup(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MultiPropertyGroup"
		case 0xBD938FF2D2663D61UL: return new CImage3D(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Image3D"
		case 0x13A2561F0CFB712AUL: return new CImageStack(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ImageStack"
		case 0x8CE7A1191A63A35DUL: return new CAttachment(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Attachment"
		case 0xE0441CF976B36319UL: return new CTexture2D(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Texture2D"
		case 0xD5C49B04AF1963CDUL: return new CImplicitPort(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ImplicitPort"
		case 0x52F06268CD098EFEUL: return new CIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Iterator"
		case 0xC62268F2D7C7012CUL: return new CImplicitPortIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ImplicitPortIterator"
		case 0xE72592A7725AB29BUL: return new CImplicitNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ImplicitNode"
		case 0xB19B9FDA94B0A5E7UL: return new COneInputNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::OneInputNode"
		case 0xD5AEA50A56306722UL: return new CSinNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::SinNode"
		case 0x59BC328F6FB5C5FFUL: return new CCosNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::CosNode"
		case 0x2614CC572AF350B7UL: return new CTanNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::TanNode"
		case 0xE554C8A7E72AAF4DUL: return new CArcSinNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ArcSinNode"
		case 0x943AF6AE0EFD2B8AUL: return new CArcCosNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ArcCosNode"
		case 0xE47D547615816BADUL: return new CArcTanNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ArcTanNode"
		case 0x3C7756A456F2D089UL: return new CSinhNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::SinhNode"
		case 0x4A993F91E1DE256DUL: return new CCoshNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::CoshNode"
		case 0xCF077B19B0B78E9DUL: return new CTanhNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::TanhNode"
		case 0xD9F5A53C657765AEUL: return new CRoundNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::RoundNode"
		case 0x627E211653E11D93UL: return new CCeilNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::CeilNode"
		case 0x392A0F4C041D249CUL: return new CFloorNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::FloorNode"
		case 0x8A45165E6C9646D7UL: return new CSignNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::SignNode"
		case 0x53E62FD67F4D9A65UL: return new CFractNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::FractNode"
		case 0x6B641C7060040BE3UL: return new CAbsNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::AbsNode"
		case 0x3390243A8E2410F3UL: return new CExpNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ExpNode"
		case 0x0070021D73AA89FDUL: return new CLogNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::LogNode"
		case 0xE8C0ABF7C5DC7068UL: return new CLog2Node(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Log2Node"
		case 0x87740AD53454E0DFUL: return new CLog10Node(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Log10Node"
		case 0xD85889E2739A74B1UL: return new CLengthNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::LengthNode"
		case 0xA808B7599C158CE6UL: return new CTransposeNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::TransposeNode"
		case 0xE8601F66A23A0540UL: return new CInverseNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::InverseNode"
		case 0x9F831944A3DE31DAUL: return new CSqrtNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::SqrtNode"
		case 0xCA86A77C71CD3FAEUL: return new CResourceIdNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ResourceIdNode"
		case 0x7DE3951BA4C1064CUL: return new CTwoInputNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::TwoInputNode"
		case 0x57A2236998DF5248UL: return new CAdditionNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::AdditionNode"
		case 0x6079B12FFF345D02UL: return new CSubtractionNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::SubtractionNode"
		case 0xA3C27CF54C2AA76CUL: return new CMultiplicationNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MultiplicationNode"
		case 0xB896B6413C08CF39UL: return new CDivisionNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::DivisionNode"
		case 0xFE60932A66375FADUL: return new CDotNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::DotNode"
		case 0x106182D38CA5CFE3UL: return new CCrossNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::CrossNode"
		case 0xB6153EF5DE7E5E11UL: return new CArcTan2Node(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ArcTan2Node"
		case 0x7570C43B9721D0C0UL: return new CMatVecMultiplicationNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MatVecMultiplicationNode"
		case 0x846AFDE9A091E997UL: return new CMinNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MinNode"
		case 0x073F910381BF250DUL: return new CMaxNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MaxNode"
		case 0x1EF703D298223F2AUL: return new CFmodNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::FmodNode"
		case 0xEA57335849379F22UL: return new CModNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ModNode"
		case 0x7700AA17CA1AC0F8UL: return new CPowNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::PowNode"
		case 0x1127ED71E05A9BD4UL: return new CSelectNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::SelectNode"
		case 0x77AF68C971B1485FUL: return new CClampNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ClampNode"
		case 0x49C24B8840C01F7EUL: return new CComposeVectorNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ComposeVectorNode"
		case 0x2E417B93351375E2UL: return new CVectorFromScalarNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::VectorFromScalarNode"
		case 0xCC4F8D561CCE35D4UL: return new CDecomposeVectorNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::DecomposeVectorNode"
		case 0x9EF9EB54A53AA40DUL: return new CComposeMatrixNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ComposeMatrixNode"
		case 0xD6DFD0A7EB64AC33UL: return new CMatrixFromRowsNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MatrixFromRowsNode"
		case 0x0DCBEAFCF83F3AACUL: return new CMatrixFromColumnsNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MatrixFromColumnsNode"
		case 0x3F8E5D082F966B1BUL: return new CConstantNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ConstantNode"
		case 0x9C9363B3F708D556UL: return new CConstVecNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ConstVecNode"
		case 0xF85C90EDCE6F90A4UL: return new CConstMatNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ConstMatNode"
		case 0x53601FD432E3DEF4UL: return new CMeshNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::MeshNode"
		case 0x29985A628251A9CDUL: return new CUnsignedMeshNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::UnsignedMeshNode"
		case 0x0F3A4EE98F7FEC0CUL: return new CBeamLatticeNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::BeamLatticeNode"
		case 0x0437E27AEF740121UL: return new CFunctionGradientNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::FunctionGradientNode"
		case 0x817D2E566E73AA8FUL: return new CNormalizeDistanceNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::NormalizeDistanceNode"
		case 0x0765C17C952F24E3UL: return new CFunctionCallNode(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::FunctionCallNode"
		case 0xFC006BC888CAB4D0UL: return new CNodeIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::NodeIterator"
		case 0x9EFB2757CA1A5231UL: return new CFunction(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Function"
		case 0x6CE54469EEA83BC1UL: return new CImplicitFunction(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ImplicitFunction"
		case 0x9BD7D3C2026B8CE8UL: return new CFunctionFromImage3D(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::FunctionFromImage3D"
		case 0x68FB2D5FFC4BA12AUL: return new CBuildItem(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::BuildItem"
		case 0xA7D21BD364910860UL: return new CBuildItemIterator(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::BuildItemIterator"
		case 0x2198BCF4D8DF9C40UL: return new CSlice(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Slice"
		case 0x6594B031B6096238UL: return new CSliceStack(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::SliceStack"
		case 0xD9E46D5E6D8118EEUL: return new CConsumer(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Consumer"
		case 0x385C42FC5609498AUL: return new CAccessRight(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::AccessRight"
		case 0x7FB36B91D4CE4671UL: return new CContentEncryptionParams(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ContentEncryptionParams"
		case 0x1A47A5E258E22EF9UL: return new CResourceData(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ResourceData"
		case 0xD59067227E428AA4UL: return new CResourceDataGroup(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::ResourceDataGroup"
		case 0x1CC9E0CC082253C6UL: return new CKeyStore(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::KeyStore"
		case 0x5A8164ECEDB03F09UL: return new CModel(this, pHandle); break; // First 64 bits of SHA1 of a string: "Lib3MF::Model"
	}
	return new CBase(this, pHandle);
}
	
	/**
	* CWrapper::GetLibraryVersion - retrieves the binary version of this library.
	* @param[out] nMajor - returns the major version of this library
	* @param[out] nMinor - returns the minor version of this library
	* @param[out] nMicro - returns the micro version of this library
	*/
	inline void CWrapper::GetLibraryVersion(Lib3MF_uint32 & nMajor, Lib3MF_uint32 & nMinor, Lib3MF_uint32 & nMicro)
	{
		CheckError(nullptr,lib3mf_getlibraryversion(&nMajor, &nMinor, &nMicro));
	}
	
	/**
	* CWrapper::GetPrereleaseInformation - retrieves prerelease information of this library.
	* @return Does the library provide prerelease version?
	* @param[out] sPrereleaseInfo - retrieves prerelease information of this library.
	*/
	inline bool CWrapper::GetPrereleaseInformation(std::string & sPrereleaseInfo)
	{
		bool resultHasPrereleaseInfo = 0;
		Lib3MF_uint32 bytesNeededPrereleaseInfo = 0;
		Lib3MF_uint32 bytesWrittenPrereleaseInfo = 0;
		CheckError(nullptr,lib3mf_getprereleaseinformation(&resultHasPrereleaseInfo, 0, &bytesNeededPrereleaseInfo, nullptr));
		std::vector<char> bufferPrereleaseInfo(bytesNeededPrereleaseInfo);
		CheckError(nullptr,lib3mf_getprereleaseinformation(&resultHasPrereleaseInfo, bytesNeededPrereleaseInfo, &bytesWrittenPrereleaseInfo, &bufferPrereleaseInfo[0]));
		sPrereleaseInfo = std::string(&bufferPrereleaseInfo[0]);
		
		return resultHasPrereleaseInfo;
	}
	
	/**
	* CWrapper::GetBuildInformation - retrieves build information of this library.
	* @return Does the library provide build version?
	* @param[out] sBuildInformation - retrieves build information of this library.
	*/
	inline bool CWrapper::GetBuildInformation(std::string & sBuildInformation)
	{
		bool resultHasBuildInfo = 0;
		Lib3MF_uint32 bytesNeededBuildInformation = 0;
		Lib3MF_uint32 bytesWrittenBuildInformation = 0;
		CheckError(nullptr,lib3mf_getbuildinformation(&resultHasBuildInfo, 0, &bytesNeededBuildInformation, nullptr));
		std::vector<char> bufferBuildInformation(bytesNeededBuildInformation);
		CheckError(nullptr,lib3mf_getbuildinformation(&resultHasBuildInfo, bytesNeededBuildInformation, &bytesWrittenBuildInformation, &bufferBuildInformation[0]));
		sBuildInformation = std::string(&bufferBuildInformation[0]);
		
		return resultHasBuildInfo;
	}
	
	/**
	* CWrapper::GetSpecificationVersion - retrieves whether a specification is supported, and if so, which version.
	* @param[in] sSpecificationURL - URL of extension to check
	* @param[out] bIsSupported - returns whether this specification is supported
	* @param[out] nMajor - returns the major version of the extension (if IsSupported)
	* @param[out] nMinor - returns the minor version of the extension (if IsSupported)
	* @param[out] nMicro - returns the micro version of the extension (if IsSupported)
	*/
	inline void CWrapper::GetSpecificationVersion(const std::string & sSpecificationURL, bool & bIsSupported, Lib3MF_uint32 & nMajor, Lib3MF_uint32 & nMinor, Lib3MF_uint32 & nMicro)
	{
		CheckError(nullptr,lib3mf_getspecificationversion(sSpecificationURL.c_str(), &bIsSupported, &nMajor, &nMinor, &nMicro));
	}
	
	/**
	* CWrapper::CreateModel - creates an empty model instance.
	* @return returns an empty model instance
	*/
	inline PModel CWrapper::CreateModel()
	{
		Lib3MFHandle hModel = (Lib3MFHandle)nullptr;
		CheckError(nullptr,lib3mf_createmodel(&hModel));
		
		if (!hModel) {
			CheckError(nullptr,LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CModel>(dynamic_cast<CModel*>(this->polymorphicFactory(hModel)));
	}
	
	/**
	* CWrapper::Release - releases shared ownership of an object instance
	* @param[in] pInstance - the object instance to release
	*/
	inline void CWrapper::Release(classParam<CBase> pInstance)
	{
		Lib3MFHandle hInstance = pInstance.GetHandle();
		CheckError(nullptr,lib3mf_release(hInstance));
	}
	
	/**
	* CWrapper::Acquire - acquires shared ownership of an object instance
	* @param[in] pInstance - the object instance to acquire
	*/
	inline void CWrapper::Acquire(classParam<CBase> pInstance)
	{
		Lib3MFHandle hInstance = pInstance.GetHandle();
		CheckError(nullptr,lib3mf_acquire(hInstance));
	}
	
	/**
	* CWrapper::SetJournal - Sets the journal file path
	* @param[in] sJournalPath - File name of the journal file
	*/
	inline void CWrapper::SetJournal(const std::string & sJournalPath)
	{
		CheckError(nullptr,lib3mf_setjournal(sJournalPath.c_str()));
	}
	
	/**
	* CWrapper::GetLastError - Retrieves the last error string of an instance
	* @param[in] pInstance - Object where the error occured.
	* @param[out] sLastErrorString - Last Error String
	* @return Returns if the instance has a last error.
	*/
	inline bool CWrapper::GetLastError(classParam<CBase> pInstance, std::string & sLastErrorString)
	{
		Lib3MFHandle hInstance = pInstance.GetHandle();
		Lib3MF_uint32 bytesNeededLastErrorString = 0;
		Lib3MF_uint32 bytesWrittenLastErrorString = 0;
		bool resultHasLastError = 0;
		CheckError(nullptr,lib3mf_getlasterror(hInstance, 0, &bytesNeededLastErrorString, nullptr, &resultHasLastError));
		std::vector<char> bufferLastErrorString(bytesNeededLastErrorString);
		CheckError(nullptr,lib3mf_getlasterror(hInstance, bytesNeededLastErrorString, &bytesWrittenLastErrorString, &bufferLastErrorString[0], &resultHasLastError));
		sLastErrorString = std::string(&bufferLastErrorString[0]);
		
		return resultHasLastError;
	}
	
	/**
	* CWrapper::GetSymbolLookupMethod - Returns the address of the SymbolLookupMethod
	* @return Address of the SymbolAddressMethod
	*/
	inline Lib3MF_pvoid CWrapper::GetSymbolLookupMethod()
	{
		Lib3MF_pvoid resultSymbolLookupMethod = 0;
		CheckError(nullptr,lib3mf_getsymbollookupmethod(&resultSymbolLookupMethod));
		
		return resultSymbolLookupMethod;
	}
	
	/**
	* CWrapper::RetrieveProgressMessage - Return an English text for a progress identifier.|Note: this is the only function you can call from your callback function.
	* @param[in] eTheProgressIdentifier - the progress identifier that is passed to the callback function
	* @param[out] sProgressMessage - English text for the progress identifier
	*/
	inline void CWrapper::RetrieveProgressMessage(const eProgressIdentifier eTheProgressIdentifier, std::string & sProgressMessage)
	{
		Lib3MF_uint32 bytesNeededProgressMessage = 0;
		Lib3MF_uint32 bytesWrittenProgressMessage = 0;
		CheckError(nullptr,lib3mf_retrieveprogressmessage(eTheProgressIdentifier, 0, &bytesNeededProgressMessage, nullptr));
		std::vector<char> bufferProgressMessage(bytesNeededProgressMessage);
		CheckError(nullptr,lib3mf_retrieveprogressmessage(eTheProgressIdentifier, bytesNeededProgressMessage, &bytesWrittenProgressMessage, &bufferProgressMessage[0]));
		sProgressMessage = std::string(&bufferProgressMessage[0]);
	}
	
	/**
	* CWrapper::RGBAToColor - Creates a Color from uint8 RGBA values
	* @param[in] nRed - Red value of color (0-255)
	* @param[in] nGreen - Green value of color (0-255)
	* @param[in] nBlue - Blue value of color (0-255)
	* @param[in] nAlpha - Alpha value of color (0-255)
	* @return Assembled color
	*/
	inline sColor CWrapper::RGBAToColor(const Lib3MF_uint8 nRed, const Lib3MF_uint8 nGreen, const Lib3MF_uint8 nBlue, const Lib3MF_uint8 nAlpha)
	{
		sColor resultTheColor;
		CheckError(nullptr,lib3mf_rgbatocolor(nRed, nGreen, nBlue, nAlpha, &resultTheColor));
		
		return resultTheColor;
	}
	
	/**
	* CWrapper::FloatRGBAToColor - Creates a Color from uint8 RGBA values
	* @param[in] fRed - Red value of color (0-1)
	* @param[in] fGreen - Green value of color (0-1)
	* @param[in] fBlue - Blue value of color (0-1)
	* @param[in] fAlpha - Alpha value of color (0-1)
	* @return Assembled color
	*/
	inline sColor CWrapper::FloatRGBAToColor(const Lib3MF_single fRed, const Lib3MF_single fGreen, const Lib3MF_single fBlue, const Lib3MF_single fAlpha)
	{
		sColor resultTheColor;
		CheckError(nullptr,lib3mf_floatrgbatocolor(fRed, fGreen, fBlue, fAlpha, &resultTheColor));
		
		return resultTheColor;
	}
	
	/**
	* CWrapper::ColorToRGBA - Calculates uint8-RGBA-values from a Color
	* @param[in] TheColor - Color to handle
	* @param[out] nRed - Red value of color (0-255)
	* @param[out] nGreen - Green value of color (0-255)
	* @param[out] nBlue - Blue value of color (0-255)
	* @param[out] nAlpha - Alpha value of color (0-255)
	*/
	inline void CWrapper::ColorToRGBA(const sColor & TheColor, Lib3MF_uint8 & nRed, Lib3MF_uint8 & nGreen, Lib3MF_uint8 & nBlue, Lib3MF_uint8 & nAlpha)
	{
		CheckError(nullptr,lib3mf_colortorgba(&TheColor, &nRed, &nGreen, &nBlue, &nAlpha));
	}
	
	/**
	* CWrapper::ColorToFloatRGBA - Calculates float-RGBA-values from a Color
	* @param[in] TheColor - Color to handle
	* @param[out] fRed - Red value of color (0-1)
	* @param[out] fGreen - Green value of color (0-1)
	* @param[out] fBlue - Blue value of color (0-1)
	* @param[out] fAlpha - Alpha value of color (0-1)
	*/
	inline void CWrapper::ColorToFloatRGBA(const sColor & TheColor, Lib3MF_single & fRed, Lib3MF_single & fGreen, Lib3MF_single & fBlue, Lib3MF_single & fAlpha)
	{
		CheckError(nullptr,lib3mf_colortofloatrgba(&TheColor, &fRed, &fGreen, &fBlue, &fAlpha));
	}
	
	/**
	* CWrapper::GetIdentityTransform - Creates an identity transform
	* @return Transformation matrix.
	*/
	inline sTransform CWrapper::GetIdentityTransform()
	{
		sTransform resultTransform;
		CheckError(nullptr,lib3mf_getidentitytransform(&resultTransform));
		
		return resultTransform;
	}
	
	/**
	* CWrapper::GetUniformScaleTransform - Creates a uniform scale transform
	* @param[in] fFactor - Factor in X, Y and Z
	* @return Transformation matrix.
	*/
	inline sTransform CWrapper::GetUniformScaleTransform(const Lib3MF_single fFactor)
	{
		sTransform resultTransform;
		CheckError(nullptr,lib3mf_getuniformscaletransform(fFactor, &resultTransform));
		
		return resultTransform;
	}
	
	/**
	* CWrapper::GetScaleTransform - Creates a scale transform
	* @param[in] fFactorX - Factor in X
	* @param[in] fFactorY - Factor in Y
	* @param[in] fFactorZ - Factor in Z
	* @return Transformation matrix.
	*/
	inline sTransform CWrapper::GetScaleTransform(const Lib3MF_single fFactorX, const Lib3MF_single fFactorY, const Lib3MF_single fFactorZ)
	{
		sTransform resultTransform;
		CheckError(nullptr,lib3mf_getscaletransform(fFactorX, fFactorY, fFactorZ, &resultTransform));
		
		return resultTransform;
	}
	
	/**
	* CWrapper::GetTranslationTransform - Creates an translation transform
	* @param[in] fVectorX - Translation in X
	* @param[in] fVectorY - Translation in Y
	* @param[in] fVectorZ - Translation in Z
	* @return Transformation matrix.
	*/
	inline sTransform CWrapper::GetTranslationTransform(const Lib3MF_single fVectorX, const Lib3MF_single fVectorY, const Lib3MF_single fVectorZ)
	{
		sTransform resultTransform;
		CheckError(nullptr,lib3mf_gettranslationtransform(fVectorX, fVectorY, fVectorZ, &resultTransform));
		
		return resultTransform;
	}

	inline void CWrapper::CheckError(CBase * pBaseClass, Lib3MFResult nResult)
	{
		if (nResult != 0) {
			std::string sErrorMessage;
			if (pBaseClass != nullptr) {
				GetLastError(pBaseClass, sErrorMessage);
			}
			throw ELib3MFException(nResult, sErrorMessage);
		}
	}
	

	
	/**
	 * Method definitions for class CBase
	 */
	
	/**
	* CBase::ClassTypeId - Get Class Type Id
	* @return Class type as a 64 bits integer
	*/
	Lib3MF_uint64 CBase::ClassTypeId()
	{
		Lib3MF_uint64 resultClassTypeId = 0;
		CheckError(lib3mf_base_classtypeid(m_pHandle, &resultClassTypeId));
		
		return resultClassTypeId;
	}
	
	/**
	 * Method definitions for class CWriter
	 */
	
	/**
	* CWriter::WriteToFile - Writes out the model as file. The file type is specified by the Model Writer class.
	* @param[in] sFilename - Filename to write into
	*/
	void CWriter::WriteToFile(const std::string & sFilename)
	{
		CheckError(lib3mf_writer_writetofile(m_pHandle, sFilename.c_str()));
	}
	
	/**
	* CWriter::GetStreamSize - Retrieves the size of the full 3MF file stream.
	* @return the stream size
	*/
	Lib3MF_uint64 CWriter::GetStreamSize()
	{
		Lib3MF_uint64 resultStreamSize = 0;
		CheckError(lib3mf_writer_getstreamsize(m_pHandle, &resultStreamSize));
		
		return resultStreamSize;
	}
	
	/**
	* CWriter::WriteToBuffer - Writes out the 3MF file into a memory buffer
	* @param[out] BufferBuffer - buffer to write into
	*/
	void CWriter::WriteToBuffer(std::vector<Lib3MF_uint8> & BufferBuffer)
	{
		Lib3MF_uint64 elementsNeededBuffer = 0;
		Lib3MF_uint64 elementsWrittenBuffer = 0;
		CheckError(lib3mf_writer_writetobuffer(m_pHandle, 0, &elementsNeededBuffer, nullptr));
		BufferBuffer.resize((size_t) elementsNeededBuffer);
		CheckError(lib3mf_writer_writetobuffer(m_pHandle, elementsNeededBuffer, &elementsWrittenBuffer, BufferBuffer.data()));
	}
	
	/**
	* CWriter::WriteToCallback - Writes out the model and passes the data to a provided callback function. The file type is specified by the Model Writer class.
	* @param[in] pTheWriteCallback - Callback to call for writing a data chunk
	* @param[in] pTheSeekCallback - Callback to call for seeking in the stream
	* @param[in] pUserData - Userdata that is passed to the callback function
	*/
	void CWriter::WriteToCallback(const WriteCallback pTheWriteCallback, const SeekCallback pTheSeekCallback, const Lib3MF_pvoid pUserData)
	{
		CheckError(lib3mf_writer_writetocallback(m_pHandle, pTheWriteCallback, pTheSeekCallback, pUserData));
	}
	
	/**
	* CWriter::SetProgressCallback - Set the progress callback for calls to this writer
	* @param[in] pProgressCallback - pointer to the callback function.
	* @param[in] pUserData - pointer to arbitrary user data that is passed without modification to the callback.
	*/
	void CWriter::SetProgressCallback(const ProgressCallback pProgressCallback, const Lib3MF_pvoid pUserData)
	{
		CheckError(lib3mf_writer_setprogresscallback(m_pHandle, pProgressCallback, pUserData));
	}
	
	/**
	* CWriter::GetDecimalPrecision - Returns the number of digits after the decimal point to be written in each vertex coordinate-value.
	* @return The number of digits to be written in each vertex coordinate-value after the decimal point.
	*/
	Lib3MF_uint32 CWriter::GetDecimalPrecision()
	{
		Lib3MF_uint32 resultDecimalPrecision = 0;
		CheckError(lib3mf_writer_getdecimalprecision(m_pHandle, &resultDecimalPrecision));
		
		return resultDecimalPrecision;
	}
	
	/**
	* CWriter::SetDecimalPrecision - Sets the number of digits after the decimal point to be written in each vertex coordinate-value.
	* @param[in] nDecimalPrecision - The number of digits to be written in each vertex coordinate-value after the decimal point.
	*/
	void CWriter::SetDecimalPrecision(const Lib3MF_uint32 nDecimalPrecision)
	{
		CheckError(lib3mf_writer_setdecimalprecision(m_pHandle, nDecimalPrecision));
	}
	
	/**
	* CWriter::SetStrictModeActive - Activates (deactivates) the strict mode of the reader.
	* @param[in] bStrictModeActive - flag whether strict mode is active or not.
	*/
	void CWriter::SetStrictModeActive(const bool bStrictModeActive)
	{
		CheckError(lib3mf_writer_setstrictmodeactive(m_pHandle, bStrictModeActive));
	}
	
	/**
	* CWriter::GetStrictModeActive - Queries whether the strict mode of the reader is active or not
	* @return returns flag whether strict mode is active or not.
	*/
	bool CWriter::GetStrictModeActive()
	{
		bool resultStrictModeActive = 0;
		CheckError(lib3mf_writer_getstrictmodeactive(m_pHandle, &resultStrictModeActive));
		
		return resultStrictModeActive;
	}
	
	/**
	* CWriter::GetWarning - Returns Warning and Error Information of the read process
	* @param[in] nIndex - Index of the Warning. Valid values are 0 to WarningCount - 1
	* @param[out] nErrorCode - filled with the error code of the warning
	* @return the message of the warning
	*/
	std::string CWriter::GetWarning(const Lib3MF_uint32 nIndex, Lib3MF_uint32 & nErrorCode)
	{
		Lib3MF_uint32 bytesNeededWarning = 0;
		Lib3MF_uint32 bytesWrittenWarning = 0;
		CheckError(lib3mf_writer_getwarning(m_pHandle, nIndex, &nErrorCode, 0, &bytesNeededWarning, nullptr));
		std::vector<char> bufferWarning(bytesNeededWarning);
		CheckError(lib3mf_writer_getwarning(m_pHandle, nIndex, &nErrorCode, bytesNeededWarning, &bytesWrittenWarning, &bufferWarning[0]));
		
		return std::string(&bufferWarning[0]);
	}
	
	/**
	* CWriter::GetWarningCount - Returns Warning and Error Count of the read process
	* @return filled with the count of the occurred warnings.
	*/
	Lib3MF_uint32 CWriter::GetWarningCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_writer_getwarningcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CWriter::AddKeyWrappingCallback - Registers a callback to deal with data key encryption/decryption from keystore
	* @param[in] sConsumerID - The ConsumerID to register for
	* @param[in] pTheCallback - The callback to be callede for wrapping and encryption key
	* @param[in] pUserData - Userdata that is passed to the callback function
	*/
	void CWriter::AddKeyWrappingCallback(const std::string & sConsumerID, const KeyWrappingCallback pTheCallback, const Lib3MF_pvoid pUserData)
	{
		CheckError(lib3mf_writer_addkeywrappingcallback(m_pHandle, sConsumerID.c_str(), pTheCallback, pUserData));
	}
	
	/**
	* CWriter::SetContentEncryptionCallback - Registers a callback to deal with encryption of content
	* @param[in] pTheCallback - The callback used to encrypt content
	* @param[in] pUserData - Userdata that is passed to the callback function
	*/
	void CWriter::SetContentEncryptionCallback(const ContentEncryptionCallback pTheCallback, const Lib3MF_pvoid pUserData)
	{
		CheckError(lib3mf_writer_setcontentencryptioncallback(m_pHandle, pTheCallback, pUserData));
	}
	
	/**
	 * Method definitions for class CReader
	 */
	
	/**
	* CReader::ReadFromFile - Reads a model from a file. The file type is specified by the Model Reader class
	* @param[in] sFilename - Filename to read from
	*/
	void CReader::ReadFromFile(const std::string & sFilename)
	{
		CheckError(lib3mf_reader_readfromfile(m_pHandle, sFilename.c_str()));
	}
	
	/**
	* CReader::ReadFromBuffer - Reads a model from a memory buffer.
	* @param[in] BufferBuffer - Buffer to read from
	*/
	void CReader::ReadFromBuffer(const CInputVector<Lib3MF_uint8> & BufferBuffer)
	{
		Lib3MF_uint64 nBufferSize = BufferBuffer.size();
		CheckError(lib3mf_reader_readfrombuffer(m_pHandle, nBufferSize, BufferBuffer.data()));
	}
	
	/**
	* CReader::ReadFromCallback - Reads a model and from the data provided by a callback function
	* @param[in] pTheReadCallback - Callback to call for reading a data chunk
	* @param[in] nStreamSize - number of bytes the callback returns
	* @param[in] pTheSeekCallback - Callback to call for seeking in the stream.
	* @param[in] pUserData - Userdata that is passed to the callback function
	*/
	void CReader::ReadFromCallback(const ReadCallback pTheReadCallback, const Lib3MF_uint64 nStreamSize, const SeekCallback pTheSeekCallback, const Lib3MF_pvoid pUserData)
	{
		CheckError(lib3mf_reader_readfromcallback(m_pHandle, pTheReadCallback, nStreamSize, pTheSeekCallback, pUserData));
	}
	
	/**
	* CReader::SetProgressCallback - Set the progress callback for calls to this writer
	* @param[in] pProgressCallback - pointer to the callback function.
	* @param[in] pUserData - pointer to arbitrary user data that is passed without modification to the callback.
	*/
	void CReader::SetProgressCallback(const ProgressCallback pProgressCallback, const Lib3MF_pvoid pUserData)
	{
		CheckError(lib3mf_reader_setprogresscallback(m_pHandle, pProgressCallback, pUserData));
	}
	
	/**
	* CReader::AddRelationToRead - Adds a relationship type which shall be read as attachment in memory while loading
	* @param[in] sRelationShipType - String of the relationship type
	*/
	void CReader::AddRelationToRead(const std::string & sRelationShipType)
	{
		CheckError(lib3mf_reader_addrelationtoread(m_pHandle, sRelationShipType.c_str()));
	}
	
	/**
	* CReader::RemoveRelationToRead - Removes a relationship type which shall be read as attachment in memory while loading
	* @param[in] sRelationShipType - String of the relationship type
	*/
	void CReader::RemoveRelationToRead(const std::string & sRelationShipType)
	{
		CheckError(lib3mf_reader_removerelationtoread(m_pHandle, sRelationShipType.c_str()));
	}
	
	/**
	* CReader::SetStrictModeActive - Activates (deactivates) the strict mode of the reader.
	* @param[in] bStrictModeActive - flag whether strict mode is active or not.
	*/
	void CReader::SetStrictModeActive(const bool bStrictModeActive)
	{
		CheckError(lib3mf_reader_setstrictmodeactive(m_pHandle, bStrictModeActive));
	}
	
	/**
	* CReader::GetStrictModeActive - Queries whether the strict mode of the reader is active or not
	* @return returns flag whether strict mode is active or not.
	*/
	bool CReader::GetStrictModeActive()
	{
		bool resultStrictModeActive = 0;
		CheckError(lib3mf_reader_getstrictmodeactive(m_pHandle, &resultStrictModeActive));
		
		return resultStrictModeActive;
	}
	
	/**
	* CReader::GetWarning - Returns Warning and Error Information of the read process
	* @param[in] nIndex - Index of the Warning. Valid values are 0 to WarningCount - 1
	* @param[out] nErrorCode - filled with the error code of the warning
	* @return the message of the warning
	*/
	std::string CReader::GetWarning(const Lib3MF_uint32 nIndex, Lib3MF_uint32 & nErrorCode)
	{
		Lib3MF_uint32 bytesNeededWarning = 0;
		Lib3MF_uint32 bytesWrittenWarning = 0;
		CheckError(lib3mf_reader_getwarning(m_pHandle, nIndex, &nErrorCode, 0, &bytesNeededWarning, nullptr));
		std::vector<char> bufferWarning(bytesNeededWarning);
		CheckError(lib3mf_reader_getwarning(m_pHandle, nIndex, &nErrorCode, bytesNeededWarning, &bytesWrittenWarning, &bufferWarning[0]));
		
		return std::string(&bufferWarning[0]);
	}
	
	/**
	* CReader::GetWarningCount - Returns Warning and Error Count of the read process
	* @return filled with the count of the occurred warnings.
	*/
	Lib3MF_uint32 CReader::GetWarningCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_reader_getwarningcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CReader::AddKeyWrappingCallback - Registers a callback to deal with key wrapping mechanism from keystore
	* @param[in] sConsumerID - The ConsumerID to register for
	* @param[in] pTheCallback - The callback used to decrypt data key
	* @param[in] pUserData - Userdata that is passed to the callback function
	*/
	void CReader::AddKeyWrappingCallback(const std::string & sConsumerID, const KeyWrappingCallback pTheCallback, const Lib3MF_pvoid pUserData)
	{
		CheckError(lib3mf_reader_addkeywrappingcallback(m_pHandle, sConsumerID.c_str(), pTheCallback, pUserData));
	}
	
	/**
	* CReader::SetContentEncryptionCallback - Registers a callback to deal with encryption of content
	* @param[in] pTheCallback - The callback used to encrypt content
	* @param[in] pUserData - Userdata that is passed to the callback function
	*/
	void CReader::SetContentEncryptionCallback(const ContentEncryptionCallback pTheCallback, const Lib3MF_pvoid pUserData)
	{
		CheckError(lib3mf_reader_setcontentencryptioncallback(m_pHandle, pTheCallback, pUserData));
	}
	
	/**
	 * Method definitions for class CPackagePart
	 */
	
	/**
	* CPackagePart::GetPath - Returns the absolute path of this PackagePart.
	* @return Returns the absolute path of this PackagePart
	*/
	std::string CPackagePart::GetPath()
	{
		Lib3MF_uint32 bytesNeededPath = 0;
		Lib3MF_uint32 bytesWrittenPath = 0;
		CheckError(lib3mf_packagepart_getpath(m_pHandle, 0, &bytesNeededPath, nullptr));
		std::vector<char> bufferPath(bytesNeededPath);
		CheckError(lib3mf_packagepart_getpath(m_pHandle, bytesNeededPath, &bytesWrittenPath, &bufferPath[0]));
		
		return std::string(&bufferPath[0]);
	}
	
	/**
	* CPackagePart::SetPath - Sets the absolute path of this PackagePart.
	* @param[in] sPath - Sets the absolute path of this PackagePart.
	*/
	void CPackagePart::SetPath(const std::string & sPath)
	{
		CheckError(lib3mf_packagepart_setpath(m_pHandle, sPath.c_str()));
	}
	
	/**
	 * Method definitions for class CResource
	 */
	
	/**
	* CResource::GetResourceID - Retrieves the unique id of this resource within a package. This function will be removed in a later release in favor of GetUniqueResourceID
	* @return Retrieves the unique id of this resource within a package.
	*/
	Lib3MF_uint32 CResource::GetResourceID()
	{
		Lib3MF_uint32 resultUniqueResourceID = 0;
		CheckError(lib3mf_resource_getresourceid(m_pHandle, &resultUniqueResourceID));
		
		return resultUniqueResourceID;
	}
	
	/**
	* CResource::GetUniqueResourceID - Retrieves the unique id of this resource within a package.
	* @return Retrieves the unique id of this resource within a package.
	*/
	Lib3MF_uint32 CResource::GetUniqueResourceID()
	{
		Lib3MF_uint32 resultUniqueResourceID = 0;
		CheckError(lib3mf_resource_getuniqueresourceid(m_pHandle, &resultUniqueResourceID));
		
		return resultUniqueResourceID;
	}
	
	/**
	* CResource::PackagePart - Returns the PackagePart within which this resource resides
	* @return the PackagePart within which this resource resides.
	*/
	PPackagePart CResource::PackagePart()
	{
		Lib3MFHandle hPackagePart = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_resource_packagepart(m_pHandle, &hPackagePart));
		
		if (!hPackagePart) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CPackagePart>(dynamic_cast<CPackagePart*>(m_pWrapper->polymorphicFactory(hPackagePart)));
	}
	
	/**
	* CResource::SetPackagePart - Sets the new PackagePart within which this resource resides
	* @param[in] pPackagePart - the new PackagePart within which this resource resides.
	*/
	void CResource::SetPackagePart(classParam<CPackagePart> pPackagePart)
	{
		Lib3MFHandle hPackagePart = pPackagePart.GetHandle();
		CheckError(lib3mf_resource_setpackagepart(m_pHandle, hPackagePart));
	}
	
	/**
	* CResource::GetModelResourceID - Retrieves the id of this resource within a model.
	* @return Retrieves the id of this resource within a model.
	*/
	Lib3MF_uint32 CResource::GetModelResourceID()
	{
		Lib3MF_uint32 resultModelResourceId = 0;
		CheckError(lib3mf_resource_getmodelresourceid(m_pHandle, &resultModelResourceId));
		
		return resultModelResourceId;
	}
	
	/**
	 * Method definitions for class CResourceIterator
	 */
	
	/**
	* CResourceIterator::MoveNext - Iterates to the next resource in the list.
	* @return Iterates to the next resource in the list.
	*/
	bool CResourceIterator::MoveNext()
	{
		bool resultHasNext = 0;
		CheckError(lib3mf_resourceiterator_movenext(m_pHandle, &resultHasNext));
		
		return resultHasNext;
	}
	
	/**
	* CResourceIterator::MovePrevious - Iterates to the previous resource in the list.
	* @return Iterates to the previous resource in the list.
	*/
	bool CResourceIterator::MovePrevious()
	{
		bool resultHasPrevious = 0;
		CheckError(lib3mf_resourceiterator_moveprevious(m_pHandle, &resultHasPrevious));
		
		return resultHasPrevious;
	}
	
	/**
	* CResourceIterator::GetCurrent - Returns the resource the iterator points at.
	* @return returns the resource instance.
	*/
	PResource CResourceIterator::GetCurrent()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_resourceiterator_getcurrent(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CResource>(dynamic_cast<CResource*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	* CResourceIterator::Clone - Creates a new resource iterator with the same resource list.
	* @return returns the cloned Iterator instance
	*/
	PResourceIterator CResourceIterator::Clone()
	{
		Lib3MFHandle hOutResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_resourceiterator_clone(m_pHandle, &hOutResourceIterator));
		
		if (!hOutResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CResourceIterator>(dynamic_cast<CResourceIterator*>(m_pWrapper->polymorphicFactory(hOutResourceIterator)));
	}
	
	/**
	* CResourceIterator::Count - Returns the number of resoucres the iterator captures.
	* @return returns the number of resoucres the iterator captures.
	*/
	Lib3MF_uint64 CResourceIterator::Count()
	{
		Lib3MF_uint64 resultCount = 0;
		CheckError(lib3mf_resourceiterator_count(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	 * Method definitions for class CSliceStackIterator
	 */
	
	/**
	* CSliceStackIterator::GetCurrentSliceStack - Returns the SliceStack the iterator points at.
	* @return returns the SliceStack instance.
	*/
	PSliceStack CSliceStackIterator::GetCurrentSliceStack()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_slicestackiterator_getcurrentslicestack(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSliceStack>(dynamic_cast<CSliceStack*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	 * Method definitions for class CObjectIterator
	 */
	
	/**
	* CObjectIterator::GetCurrentObject - Returns the Object the iterator points at.
	* @return returns the Object instance.
	*/
	PObject CObjectIterator::GetCurrentObject()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_objectiterator_getcurrentobject(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CObject>(dynamic_cast<CObject*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	 * Method definitions for class CMeshObjectIterator
	 */
	
	/**
	* CMeshObjectIterator::GetCurrentMeshObject - Returns the MeshObject the iterator points at.
	* @return returns the MeshObject instance.
	*/
	PMeshObject CMeshObjectIterator::GetCurrentMeshObject()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_meshobjectiterator_getcurrentmeshobject(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMeshObject>(dynamic_cast<CMeshObject*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	 * Method definitions for class CComponentsObjectIterator
	 */
	
	/**
	* CComponentsObjectIterator::GetCurrentComponentsObject - Returns the ComponentsObject the iterator points at.
	* @return returns the ComponentsObject instance.
	*/
	PComponentsObject CComponentsObjectIterator::GetCurrentComponentsObject()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_componentsobjectiterator_getcurrentcomponentsobject(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CComponentsObject>(dynamic_cast<CComponentsObject*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	 * Method definitions for class CTexture2DIterator
	 */
	
	/**
	* CTexture2DIterator::GetCurrentTexture2D - Returns the Texture2D the iterator points at.
	* @return returns the Texture2D instance.
	*/
	PTexture2D CTexture2DIterator::GetCurrentTexture2D()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_texture2diterator_getcurrenttexture2d(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTexture2D>(dynamic_cast<CTexture2D*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	 * Method definitions for class CBaseMaterialGroupIterator
	 */
	
	/**
	* CBaseMaterialGroupIterator::GetCurrentBaseMaterialGroup - Returns the MaterialGroup the iterator points at.
	* @return returns the BaseMaterialGroup instance.
	*/
	PBaseMaterialGroup CBaseMaterialGroupIterator::GetCurrentBaseMaterialGroup()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_basematerialgroupiterator_getcurrentbasematerialgroup(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBaseMaterialGroup>(dynamic_cast<CBaseMaterialGroup*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	 * Method definitions for class CColorGroupIterator
	 */
	
	/**
	* CColorGroupIterator::GetCurrentColorGroup - Returns the ColorGroup the iterator points at.
	* @return returns the ColorGroup instance.
	*/
	PColorGroup CColorGroupIterator::GetCurrentColorGroup()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_colorgroupiterator_getcurrentcolorgroup(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CColorGroup>(dynamic_cast<CColorGroup*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	 * Method definitions for class CTexture2DGroupIterator
	 */
	
	/**
	* CTexture2DGroupIterator::GetCurrentTexture2DGroup - Returns the Texture2DGroup the iterator points at.
	* @return returns the Texture2DGroup instance.
	*/
	PTexture2DGroup CTexture2DGroupIterator::GetCurrentTexture2DGroup()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_texture2dgroupiterator_getcurrenttexture2dgroup(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTexture2DGroup>(dynamic_cast<CTexture2DGroup*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	 * Method definitions for class CCompositeMaterialsIterator
	 */
	
	/**
	* CCompositeMaterialsIterator::GetCurrentCompositeMaterials - Returns the CompositeMaterials the iterator points at.
	* @return returns the CompositeMaterials instance.
	*/
	PCompositeMaterials CCompositeMaterialsIterator::GetCurrentCompositeMaterials()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_compositematerialsiterator_getcurrentcompositematerials(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CCompositeMaterials>(dynamic_cast<CCompositeMaterials*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	 * Method definitions for class CMultiPropertyGroupIterator
	 */
	
	/**
	* CMultiPropertyGroupIterator::GetCurrentMultiPropertyGroup - Returns the MultiPropertyGroup the iterator points at.
	* @return returns the MultiPropertyGroup instance.
	*/
	PMultiPropertyGroup CMultiPropertyGroupIterator::GetCurrentMultiPropertyGroup()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_multipropertygroupiterator_getcurrentmultipropertygroup(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMultiPropertyGroup>(dynamic_cast<CMultiPropertyGroup*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	 * Method definitions for class CImage3DIterator
	 */
	
	/**
	* CImage3DIterator::GetCurrentImage3D - Returns the Image3D the iterator points at.
	* @return returns the Image3D instance.
	*/
	PImage3D CImage3DIterator::GetCurrentImage3D()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_image3diterator_getcurrentimage3d(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImage3D>(dynamic_cast<CImage3D*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	 * Method definitions for class CFunctionIterator
	 */
	
	/**
	* CFunctionIterator::GetCurrentFunction - Returns the Function the iterator points at.
	* @return returns the Function instance.
	*/
	PFunction CFunctionIterator::GetCurrentFunction()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_functioniterator_getcurrentfunction(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CFunction>(dynamic_cast<CFunction*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	 * Method definitions for class CLevelSetIterator
	 */
	
	/**
	* CLevelSetIterator::GetCurrentLevelSet - Returns the LevelSet the iterator points at.
	* @return returns the MeshObject instance.
	*/
	PLevelSet CLevelSetIterator::GetCurrentLevelSet()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_levelsetiterator_getcurrentlevelset(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CLevelSet>(dynamic_cast<CLevelSet*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	 * Method definitions for class CMetaData
	 */
	
	/**
	* CMetaData::GetNameSpace - returns the namespace URL of the metadata
	* @return the namespace URL of the metadata
	*/
	std::string CMetaData::GetNameSpace()
	{
		Lib3MF_uint32 bytesNeededNameSpace = 0;
		Lib3MF_uint32 bytesWrittenNameSpace = 0;
		CheckError(lib3mf_metadata_getnamespace(m_pHandle, 0, &bytesNeededNameSpace, nullptr));
		std::vector<char> bufferNameSpace(bytesNeededNameSpace);
		CheckError(lib3mf_metadata_getnamespace(m_pHandle, bytesNeededNameSpace, &bytesWrittenNameSpace, &bufferNameSpace[0]));
		
		return std::string(&bufferNameSpace[0]);
	}
	
	/**
	* CMetaData::SetNameSpace - sets a new namespace URL of the metadata
	* @param[in] sNameSpace - the new namespace URL of the metadata
	*/
	void CMetaData::SetNameSpace(const std::string & sNameSpace)
	{
		CheckError(lib3mf_metadata_setnamespace(m_pHandle, sNameSpace.c_str()));
	}
	
	/**
	* CMetaData::GetName - returns the name of a metadata
	* @return the name of the metadata
	*/
	std::string CMetaData::GetName()
	{
		Lib3MF_uint32 bytesNeededName = 0;
		Lib3MF_uint32 bytesWrittenName = 0;
		CheckError(lib3mf_metadata_getname(m_pHandle, 0, &bytesNeededName, nullptr));
		std::vector<char> bufferName(bytesNeededName);
		CheckError(lib3mf_metadata_getname(m_pHandle, bytesNeededName, &bytesWrittenName, &bufferName[0]));
		
		return std::string(&bufferName[0]);
	}
	
	/**
	* CMetaData::SetName - sets a new name of a metadata
	* @param[in] sName - the new name of the metadata
	*/
	void CMetaData::SetName(const std::string & sName)
	{
		CheckError(lib3mf_metadata_setname(m_pHandle, sName.c_str()));
	}
	
	/**
	* CMetaData::GetKey - returns the (namespace+name) of a metadata
	* @return the key (namespace+name) of the metadata
	*/
	std::string CMetaData::GetKey()
	{
		Lib3MF_uint32 bytesNeededKey = 0;
		Lib3MF_uint32 bytesWrittenKey = 0;
		CheckError(lib3mf_metadata_getkey(m_pHandle, 0, &bytesNeededKey, nullptr));
		std::vector<char> bufferKey(bytesNeededKey);
		CheckError(lib3mf_metadata_getkey(m_pHandle, bytesNeededKey, &bytesWrittenKey, &bufferKey[0]));
		
		return std::string(&bufferKey[0]);
	}
	
	/**
	* CMetaData::GetMustPreserve - returns, whether a metadata must be preserved
	* @return returns, whether a metadata must be preserved
	*/
	bool CMetaData::GetMustPreserve()
	{
		bool resultMustPreserve = 0;
		CheckError(lib3mf_metadata_getmustpreserve(m_pHandle, &resultMustPreserve));
		
		return resultMustPreserve;
	}
	
	/**
	* CMetaData::SetMustPreserve - sets whether a metadata must be preserved
	* @param[in] bMustPreserve - a new value whether a metadata must be preserved
	*/
	void CMetaData::SetMustPreserve(const bool bMustPreserve)
	{
		CheckError(lib3mf_metadata_setmustpreserve(m_pHandle, bMustPreserve));
	}
	
	/**
	* CMetaData::GetType - returns the type of a metadata
	* @return the type of the metadata
	*/
	std::string CMetaData::GetType()
	{
		Lib3MF_uint32 bytesNeededType = 0;
		Lib3MF_uint32 bytesWrittenType = 0;
		CheckError(lib3mf_metadata_gettype(m_pHandle, 0, &bytesNeededType, nullptr));
		std::vector<char> bufferType(bytesNeededType);
		CheckError(lib3mf_metadata_gettype(m_pHandle, bytesNeededType, &bytesWrittenType, &bufferType[0]));
		
		return std::string(&bufferType[0]);
	}
	
	/**
	* CMetaData::SetType - sets a new type of a metadata. This must be a simple XML type
	* @param[in] sType - a new type of the metadata
	*/
	void CMetaData::SetType(const std::string & sType)
	{
		CheckError(lib3mf_metadata_settype(m_pHandle, sType.c_str()));
	}
	
	/**
	* CMetaData::GetValue - returns the value of the metadata
	* @return the value of the metadata
	*/
	std::string CMetaData::GetValue()
	{
		Lib3MF_uint32 bytesNeededValue = 0;
		Lib3MF_uint32 bytesWrittenValue = 0;
		CheckError(lib3mf_metadata_getvalue(m_pHandle, 0, &bytesNeededValue, nullptr));
		std::vector<char> bufferValue(bytesNeededValue);
		CheckError(lib3mf_metadata_getvalue(m_pHandle, bytesNeededValue, &bytesWrittenValue, &bufferValue[0]));
		
		return std::string(&bufferValue[0]);
	}
	
	/**
	* CMetaData::SetValue - sets a new value of the metadata
	* @param[in] sValue - a new value of the metadata
	*/
	void CMetaData::SetValue(const std::string & sValue)
	{
		CheckError(lib3mf_metadata_setvalue(m_pHandle, sValue.c_str()));
	}
	
	/**
	 * Method definitions for class CMetaDataGroup
	 */
	
	/**
	* CMetaDataGroup::GetMetaDataCount - returns the number of metadata in this metadatagroup
	* @return returns the number metadata
	*/
	Lib3MF_uint32 CMetaDataGroup::GetMetaDataCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_metadatagroup_getmetadatacount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CMetaDataGroup::GetMetaData - returns a metadata value within this metadatagroup
	* @param[in] nIndex - Index of the Metadata.
	* @return an instance of the metadata
	*/
	PMetaData CMetaDataGroup::GetMetaData(const Lib3MF_uint32 nIndex)
	{
		Lib3MFHandle hMetaData = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_metadatagroup_getmetadata(m_pHandle, nIndex, &hMetaData));
		
		if (!hMetaData) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMetaData>(dynamic_cast<CMetaData*>(m_pWrapper->polymorphicFactory(hMetaData)));
	}
	
	/**
	* CMetaDataGroup::GetMetaDataByKey - returns a metadata value within this metadatagroup
	* @param[in] sNameSpace - the namespace of the metadata
	* @param[in] sName - the name of the Metadata
	* @return an instance of the metadata
	*/
	PMetaData CMetaDataGroup::GetMetaDataByKey(const std::string & sNameSpace, const std::string & sName)
	{
		Lib3MFHandle hMetaData = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_metadatagroup_getmetadatabykey(m_pHandle, sNameSpace.c_str(), sName.c_str(), &hMetaData));
		
		if (!hMetaData) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMetaData>(dynamic_cast<CMetaData*>(m_pWrapper->polymorphicFactory(hMetaData)));
	}
	
	/**
	* CMetaDataGroup::RemoveMetaDataByIndex - removes metadata by index from the model.
	* @param[in] nIndex -  Index of the metadata to remove
	*/
	void CMetaDataGroup::RemoveMetaDataByIndex(const Lib3MF_uint32 nIndex)
	{
		CheckError(lib3mf_metadatagroup_removemetadatabyindex(m_pHandle, nIndex));
	}
	
	/**
	* CMetaDataGroup::RemoveMetaData - removes metadata from the model.
	* @param[in] pTheMetaData - The metadata to remove
	*/
	void CMetaDataGroup::RemoveMetaData(classParam<CMetaData> pTheMetaData)
	{
		Lib3MFHandle hTheMetaData = pTheMetaData.GetHandle();
		CheckError(lib3mf_metadatagroup_removemetadata(m_pHandle, hTheMetaData));
	}
	
	/**
	* CMetaDataGroup::AddMetaData - adds a new metadata to this metadatagroup
	* @param[in] sNameSpace - the namespace of the metadata
	* @param[in] sName - the name of the metadata
	* @param[in] sValue - the value of the metadata
	* @param[in] sType - the type of the metadata
	* @param[in] bMustPreserve - should the metadata be preserved
	* @return a new instance of the metadata
	*/
	PMetaData CMetaDataGroup::AddMetaData(const std::string & sNameSpace, const std::string & sName, const std::string & sValue, const std::string & sType, const bool bMustPreserve)
	{
		Lib3MFHandle hMetaData = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_metadatagroup_addmetadata(m_pHandle, sNameSpace.c_str(), sName.c_str(), sValue.c_str(), sType.c_str(), bMustPreserve, &hMetaData));
		
		if (!hMetaData) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMetaData>(dynamic_cast<CMetaData*>(m_pWrapper->polymorphicFactory(hMetaData)));
	}
	
	/**
	 * Method definitions for class CTriangleSet
	 */
	
	/**
	* CTriangleSet::SetName - sets the name of the triangle set
	* @param[in] sName - the new name
	*/
	void CTriangleSet::SetName(const std::string & sName)
	{
		CheckError(lib3mf_triangleset_setname(m_pHandle, sName.c_str()));
	}
	
	/**
	* CTriangleSet::GetName - returns the name of the triangle set
	* @return returns the name
	*/
	std::string CTriangleSet::GetName()
	{
		Lib3MF_uint32 bytesNeededName = 0;
		Lib3MF_uint32 bytesWrittenName = 0;
		CheckError(lib3mf_triangleset_getname(m_pHandle, 0, &bytesNeededName, nullptr));
		std::vector<char> bufferName(bytesNeededName);
		CheckError(lib3mf_triangleset_getname(m_pHandle, bytesNeededName, &bytesWrittenName, &bufferName[0]));
		
		return std::string(&bufferName[0]);
	}
	
	/**
	* CTriangleSet::SetIdentifier - sets the identifier of the triangle set.
	* @param[in] sIdentifier - the new identifier. MUST be unique within the mesh. MUST NOT be an empty string
	*/
	void CTriangleSet::SetIdentifier(const std::string & sIdentifier)
	{
		CheckError(lib3mf_triangleset_setidentifier(m_pHandle, sIdentifier.c_str()));
	}
	
	/**
	* CTriangleSet::GetIdentifier - returns the identifier of the triangle set
	* @return returns the identifier
	*/
	std::string CTriangleSet::GetIdentifier()
	{
		Lib3MF_uint32 bytesNeededIdentifier = 0;
		Lib3MF_uint32 bytesWrittenIdentifier = 0;
		CheckError(lib3mf_triangleset_getidentifier(m_pHandle, 0, &bytesNeededIdentifier, nullptr));
		std::vector<char> bufferIdentifier(bytesNeededIdentifier);
		CheckError(lib3mf_triangleset_getidentifier(m_pHandle, bytesNeededIdentifier, &bytesWrittenIdentifier, &bufferIdentifier[0]));
		
		return std::string(&bufferIdentifier[0]);
	}
	
	/**
	* CTriangleSet::AddTriangle - adds a triangle to the set. Does nothing if triangle is already in the set.
	* @param[in] nTriangleIndex - Triangle index to add. MUST be between 0 and TriangleCount - 1.
	*/
	void CTriangleSet::AddTriangle(const Lib3MF_uint32 nTriangleIndex)
	{
		CheckError(lib3mf_triangleset_addtriangle(m_pHandle, nTriangleIndex));
	}
	
	/**
	* CTriangleSet::RemoveTriangle - removes a triangle from the set
	* @param[in] nTriangleIndex - Triangle index to remove. MUST be between 0 and TriangleCount - 1.
	*/
	void CTriangleSet::RemoveTriangle(const Lib3MF_uint32 nTriangleIndex)
	{
		CheckError(lib3mf_triangleset_removetriangle(m_pHandle, nTriangleIndex));
	}
	
	/**
	* CTriangleSet::Clear - clears all triangles from the list
	*/
	void CTriangleSet::Clear()
	{
		CheckError(lib3mf_triangleset_clear(m_pHandle));
	}
	
	/**
	* CTriangleSet::SetTriangleList - Sets all triangles in the list, while clearing old values. Duplicates will be merged.
	* @param[in] TriangleIndicesBuffer - Triangle indices to add. Every element MUST be between 0 and TriangleCount - 1.
	*/
	void CTriangleSet::SetTriangleList(const CInputVector<Lib3MF_uint32> & TriangleIndicesBuffer)
	{
		Lib3MF_uint64 nTriangleIndicesSize = TriangleIndicesBuffer.size();
		CheckError(lib3mf_triangleset_settrianglelist(m_pHandle, nTriangleIndicesSize, TriangleIndicesBuffer.data()));
	}
	
	/**
	* CTriangleSet::GetTriangleList - Retrieves all the triangles in the TriangleSet
	* @param[out] TriangleIndicesBuffer - retrieves the indices of the triangles in this TriangleSet
	*/
	void CTriangleSet::GetTriangleList(std::vector<Lib3MF_uint32> & TriangleIndicesBuffer)
	{
		Lib3MF_uint64 elementsNeededTriangleIndices = 0;
		Lib3MF_uint64 elementsWrittenTriangleIndices = 0;
		CheckError(lib3mf_triangleset_gettrianglelist(m_pHandle, 0, &elementsNeededTriangleIndices, nullptr));
		TriangleIndicesBuffer.resize((size_t) elementsNeededTriangleIndices);
		CheckError(lib3mf_triangleset_gettrianglelist(m_pHandle, elementsNeededTriangleIndices, &elementsWrittenTriangleIndices, TriangleIndicesBuffer.data()));
	}
	
	/**
	* CTriangleSet::AddTriangleList - Adds multiple triangles in the list. Duplicates will be merged.
	* @param[in] TriangleIndicesBuffer - Triangle indices to add. Every element MUST be between 0 and TriangleCount - 1.
	*/
	void CTriangleSet::AddTriangleList(const CInputVector<Lib3MF_uint32> & TriangleIndicesBuffer)
	{
		Lib3MF_uint64 nTriangleIndicesSize = TriangleIndicesBuffer.size();
		CheckError(lib3mf_triangleset_addtrianglelist(m_pHandle, nTriangleIndicesSize, TriangleIndicesBuffer.data()));
	}
	
	/**
	* CTriangleSet::Merge - Merges another Triangle set.
	* @param[in] pOtherTriangleSet - Other triangle set to merge.
	* @param[in] bDeleteOther - Flag if other triangle set is getting removed.
	*/
	void CTriangleSet::Merge(classParam<CTriangleSet> pOtherTriangleSet, const bool bDeleteOther)
	{
		Lib3MFHandle hOtherTriangleSet = pOtherTriangleSet.GetHandle();
		CheckError(lib3mf_triangleset_merge(m_pHandle, hOtherTriangleSet, bDeleteOther));
	}
	
	/**
	* CTriangleSet::DeleteSet - Deletes the whole set from the mesh.
	*/
	void CTriangleSet::DeleteSet()
	{
		CheckError(lib3mf_triangleset_deleteset(m_pHandle));
	}
	
	/**
	* CTriangleSet::Duplicate - Duplicates the set in the mesh.
	* @param[in] sIdentifier - the new identifier. MUST be unique within the mesh. MUST NOT be an empty string
	* @return Copy of the triangle set.
	*/
	PTriangleSet CTriangleSet::Duplicate(const std::string & sIdentifier)
	{
		Lib3MFHandle hNewSet = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_triangleset_duplicate(m_pHandle, sIdentifier.c_str(), &hNewSet));
		
		if (!hNewSet) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTriangleSet>(dynamic_cast<CTriangleSet*>(m_pWrapper->polymorphicFactory(hNewSet)));
	}
	
	/**
	 * Method definitions for class CObject
	 */
	
	/**
	* CObject::GetType - Retrieves an object's type
	* @return returns object type enum.
	*/
	eObjectType CObject::GetType()
	{
		eObjectType resultObjectType = (eObjectType) 0;
		CheckError(lib3mf_object_gettype(m_pHandle, &resultObjectType));
		
		return resultObjectType;
	}
	
	/**
	* CObject::SetType - Sets an object's type
	* @param[in] eObjectType - object type enum.
	*/
	void CObject::SetType(const eObjectType eObjectType)
	{
		CheckError(lib3mf_object_settype(m_pHandle, eObjectType));
	}
	
	/**
	* CObject::GetName - Retrieves an object's name
	* @return returns object name.
	*/
	std::string CObject::GetName()
	{
		Lib3MF_uint32 bytesNeededName = 0;
		Lib3MF_uint32 bytesWrittenName = 0;
		CheckError(lib3mf_object_getname(m_pHandle, 0, &bytesNeededName, nullptr));
		std::vector<char> bufferName(bytesNeededName);
		CheckError(lib3mf_object_getname(m_pHandle, bytesNeededName, &bytesWrittenName, &bufferName[0]));
		
		return std::string(&bufferName[0]);
	}
	
	/**
	* CObject::SetName - Sets an object's name string
	* @param[in] sName - new object name.
	*/
	void CObject::SetName(const std::string & sName)
	{
		CheckError(lib3mf_object_setname(m_pHandle, sName.c_str()));
	}
	
	/**
	* CObject::GetPartNumber - Retrieves an object's part number
	* @return returns object part number.
	*/
	std::string CObject::GetPartNumber()
	{
		Lib3MF_uint32 bytesNeededPartNumber = 0;
		Lib3MF_uint32 bytesWrittenPartNumber = 0;
		CheckError(lib3mf_object_getpartnumber(m_pHandle, 0, &bytesNeededPartNumber, nullptr));
		std::vector<char> bufferPartNumber(bytesNeededPartNumber);
		CheckError(lib3mf_object_getpartnumber(m_pHandle, bytesNeededPartNumber, &bytesWrittenPartNumber, &bufferPartNumber[0]));
		
		return std::string(&bufferPartNumber[0]);
	}
	
	/**
	* CObject::SetPartNumber - Sets an objects partnumber string
	* @param[in] sPartNumber - new object part number.
	*/
	void CObject::SetPartNumber(const std::string & sPartNumber)
	{
		CheckError(lib3mf_object_setpartnumber(m_pHandle, sPartNumber.c_str()));
	}
	
	/**
	* CObject::IsMeshObject - Retrieves, if an object is a mesh object
	* @return returns, whether the object is a mesh object
	*/
	bool CObject::IsMeshObject()
	{
		bool resultIsMeshObject = 0;
		CheckError(lib3mf_object_ismeshobject(m_pHandle, &resultIsMeshObject));
		
		return resultIsMeshObject;
	}
	
	/**
	* CObject::IsComponentsObject - Retrieves, if an object is a components object
	* @return returns, whether the object is a components object
	*/
	bool CObject::IsComponentsObject()
	{
		bool resultIsComponentsObject = 0;
		CheckError(lib3mf_object_iscomponentsobject(m_pHandle, &resultIsComponentsObject));
		
		return resultIsComponentsObject;
	}
	
	/**
	* CObject::IsLevelSetObject - Retrieves, if an object is a level set object
	* @return returns, whether the object is a level set object
	*/
	bool CObject::IsLevelSetObject()
	{
		bool resultIsLevelSetObject = 0;
		CheckError(lib3mf_object_islevelsetobject(m_pHandle, &resultIsLevelSetObject));
		
		return resultIsLevelSetObject;
	}
	
	/**
	* CObject::IsValid - Retrieves, if the object is valid according to the core spec. For mesh objects, we distinguish between the type attribute of the object:In case of object type other, this always means false.In case of object type model or solidsupport, this means, if the mesh suffices all requirements of the core spec chapter 4.1.In case of object type support or surface, this always means true.A component objects is valid if and only if it contains at least one component and all child components are valid objects.
	* @return returns whether the object is a valid object description
	*/
	bool CObject::IsValid()
	{
		bool resultIsValid = 0;
		CheckError(lib3mf_object_isvalid(m_pHandle, &resultIsValid));
		
		return resultIsValid;
	}
	
	/**
	* CObject::SetAttachmentAsThumbnail - Use an existing attachment as thumbnail for this object
	* @param[in] pAttachment - Instance of a new or the existing thumbnailattachment object.
	*/
	void CObject::SetAttachmentAsThumbnail(classParam<CAttachment> pAttachment)
	{
		Lib3MFHandle hAttachment = pAttachment.GetHandle();
		CheckError(lib3mf_object_setattachmentasthumbnail(m_pHandle, hAttachment));
	}
	
	/**
	* CObject::GetThumbnailAttachment - Get the attachment containing the object thumbnail.
	* @return Instance of the thumbnailattachment object or NULL.
	*/
	PAttachment CObject::GetThumbnailAttachment()
	{
		Lib3MFHandle hAttachment = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_object_getthumbnailattachment(m_pHandle, &hAttachment));
		
		if (hAttachment) {
			return std::shared_ptr<CAttachment>(dynamic_cast<CAttachment*>(m_pWrapper->polymorphicFactory(hAttachment)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CObject::ClearThumbnailAttachment - Clears the attachment. The attachment instance is not removed from the package.
	*/
	void CObject::ClearThumbnailAttachment()
	{
		CheckError(lib3mf_object_clearthumbnailattachment(m_pHandle));
	}
	
	/**
	* CObject::GetOutbox - Returns the outbox of a build item
	* @return Outbox of this build item
	*/
	sBox CObject::GetOutbox()
	{
		sBox resultOutbox;
		CheckError(lib3mf_object_getoutbox(m_pHandle, &resultOutbox));
		
		return resultOutbox;
	}
	
	/**
	* CObject::GetUUID - Retrieves an object's uuid string (see production extension specification)
	* @param[out] bHasUUID - flag whether the build item has a UUID
	* @return returns object uuid.
	*/
	std::string CObject::GetUUID(bool & bHasUUID)
	{
		Lib3MF_uint32 bytesNeededUUID = 0;
		Lib3MF_uint32 bytesWrittenUUID = 0;
		CheckError(lib3mf_object_getuuid(m_pHandle, &bHasUUID, 0, &bytesNeededUUID, nullptr));
		std::vector<char> bufferUUID(bytesNeededUUID);
		CheckError(lib3mf_object_getuuid(m_pHandle, &bHasUUID, bytesNeededUUID, &bytesWrittenUUID, &bufferUUID[0]));
		
		return std::string(&bufferUUID[0]);
	}
	
	/**
	* CObject::SetUUID - Sets a build object's uuid string (see production extension specification)
	* @param[in] sUUID - new object uuid string.
	*/
	void CObject::SetUUID(const std::string & sUUID)
	{
		CheckError(lib3mf_object_setuuid(m_pHandle, sUUID.c_str()));
	}
	
	/**
	* CObject::GetMetaDataGroup - Returns the metadatagroup of this object
	* @return returns an Instance of the metadatagroup of this object
	*/
	PMetaDataGroup CObject::GetMetaDataGroup()
	{
		Lib3MFHandle hMetaDataGroup = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_object_getmetadatagroup(m_pHandle, &hMetaDataGroup));
		
		if (!hMetaDataGroup) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMetaDataGroup>(dynamic_cast<CMetaDataGroup*>(m_pWrapper->polymorphicFactory(hMetaDataGroup)));
	}
	
	/**
	* CObject::SetSlicesMeshResolution - set the meshresolution of the mesh object
	* @param[in] eMeshResolution - meshresolution of this object
	*/
	void CObject::SetSlicesMeshResolution(const eSlicesMeshResolution eMeshResolution)
	{
		CheckError(lib3mf_object_setslicesmeshresolution(m_pHandle, eMeshResolution));
	}
	
	/**
	* CObject::GetSlicesMeshResolution - get the meshresolution of the mesh object
	* @return meshresolution of this object
	*/
	eSlicesMeshResolution CObject::GetSlicesMeshResolution()
	{
		eSlicesMeshResolution resultMeshResolution = (eSlicesMeshResolution) 0;
		CheckError(lib3mf_object_getslicesmeshresolution(m_pHandle, &resultMeshResolution));
		
		return resultMeshResolution;
	}
	
	/**
	* CObject::HasSlices - returns whether the Object has a slice stack. If Recursive is true, also checks whether any references object has a slice stack
	* @param[in] bRecursive - check also all referenced objects?
	* @return does the object have a slice stack?
	*/
	bool CObject::HasSlices(const bool bRecursive)
	{
		bool resultHasSlices = 0;
		CheckError(lib3mf_object_hasslices(m_pHandle, bRecursive, &resultHasSlices));
		
		return resultHasSlices;
	}
	
	/**
	* CObject::ClearSliceStack - unlinks the attached slicestack from this object. If no slice stack is attached, do noting.
	*/
	void CObject::ClearSliceStack()
	{
		CheckError(lib3mf_object_clearslicestack(m_pHandle));
	}
	
	/**
	* CObject::GetSliceStack - get the Slicestack attached to the object
	* @return returns the slicestack instance
	*/
	PSliceStack CObject::GetSliceStack()
	{
		Lib3MFHandle hSliceStackInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_object_getslicestack(m_pHandle, &hSliceStackInstance));
		
		if (!hSliceStackInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSliceStack>(dynamic_cast<CSliceStack*>(m_pWrapper->polymorphicFactory(hSliceStackInstance)));
	}
	
	/**
	* CObject::AssignSliceStack - assigns a slicestack to the object
	* @param[in] pSliceStackInstance - the new slice stack of this Object
	*/
	void CObject::AssignSliceStack(classParam<CSliceStack> pSliceStackInstance)
	{
		Lib3MFHandle hSliceStackInstance = pSliceStackInstance.GetHandle();
		CheckError(lib3mf_object_assignslicestack(m_pHandle, hSliceStackInstance));
	}
	
	/**
	 * Method definitions for class CMeshObject
	 */
	
	/**
	* CMeshObject::GetVertexCount - Returns the vertex count of a mesh object.
	* @return filled with the vertex count.
	*/
	Lib3MF_uint32 CMeshObject::GetVertexCount()
	{
		Lib3MF_uint32 resultVertexCount = 0;
		CheckError(lib3mf_meshobject_getvertexcount(m_pHandle, &resultVertexCount));
		
		return resultVertexCount;
	}
	
	/**
	* CMeshObject::GetTriangleCount - Returns the triangle count of a mesh object.
	* @return filled with the triangle count.
	*/
	Lib3MF_uint32 CMeshObject::GetTriangleCount()
	{
		Lib3MF_uint32 resultVertexCount = 0;
		CheckError(lib3mf_meshobject_gettrianglecount(m_pHandle, &resultVertexCount));
		
		return resultVertexCount;
	}
	
	/**
	* CMeshObject::GetVertex - Returns the vertex count of a mesh object.
	* @param[in] nIndex - Index of the vertex (0 to vertexcount - 1)
	* @return filled with the vertex coordinates.
	*/
	sPosition CMeshObject::GetVertex(const Lib3MF_uint32 nIndex)
	{
		sPosition resultCoordinates;
		CheckError(lib3mf_meshobject_getvertex(m_pHandle, nIndex, &resultCoordinates));
		
		return resultCoordinates;
	}
	
	/**
	* CMeshObject::SetVertex - Sets the coordinates of a single vertex of a mesh object
	* @param[in] nIndex - Index of the vertex (0 to vertexcount - 1)
	* @param[in] Coordinates - contains the vertex coordinates.
	*/
	void CMeshObject::SetVertex(const Lib3MF_uint32 nIndex, const sPosition & Coordinates)
	{
		CheckError(lib3mf_meshobject_setvertex(m_pHandle, nIndex, &Coordinates));
	}
	
	/**
	* CMeshObject::AddVertex - Adds a single vertex to a mesh object
	* @param[in] Coordinates - contains the vertex coordinates.
	* @return Index of the new vertex
	*/
	Lib3MF_uint32 CMeshObject::AddVertex(const sPosition & Coordinates)
	{
		Lib3MF_uint32 resultNewIndex = 0;
		CheckError(lib3mf_meshobject_addvertex(m_pHandle, &Coordinates, &resultNewIndex));
		
		return resultNewIndex;
	}
	
	/**
	* CMeshObject::GetVertices - Obtains all vertex positions of a mesh object
	* @param[out] VerticesBuffer - contains the vertex coordinates.
	*/
	void CMeshObject::GetVertices(std::vector<sPosition> & VerticesBuffer)
	{
		Lib3MF_uint64 elementsNeededVertices = 0;
		Lib3MF_uint64 elementsWrittenVertices = 0;
		CheckError(lib3mf_meshobject_getvertices(m_pHandle, 0, &elementsNeededVertices, nullptr));
		VerticesBuffer.resize((size_t) elementsNeededVertices);
		CheckError(lib3mf_meshobject_getvertices(m_pHandle, elementsNeededVertices, &elementsWrittenVertices, VerticesBuffer.data()));
	}
	
	/**
	* CMeshObject::GetTriangle - Returns indices of a single triangle of a mesh object.
	* @param[in] nIndex - Index of the triangle (0 to trianglecount - 1)
	* @return filled with the triangle indices.
	*/
	sTriangle CMeshObject::GetTriangle(const Lib3MF_uint32 nIndex)
	{
		sTriangle resultIndices;
		CheckError(lib3mf_meshobject_gettriangle(m_pHandle, nIndex, &resultIndices));
		
		return resultIndices;
	}
	
	/**
	* CMeshObject::SetTriangle - Sets the indices of a single triangle of a mesh object.
	* @param[in] nIndex - Index of the triangle (0 to trianglecount - 1)
	* @param[in] Indices - contains the triangle indices.
	*/
	void CMeshObject::SetTriangle(const Lib3MF_uint32 nIndex, const sTriangle & Indices)
	{
		CheckError(lib3mf_meshobject_settriangle(m_pHandle, nIndex, &Indices));
	}
	
	/**
	* CMeshObject::AddTriangle - Adds a single triangle to a mesh object
	* @param[in] Indices - contains the triangle indices.
	* @return Index of the new triangle
	*/
	Lib3MF_uint32 CMeshObject::AddTriangle(const sTriangle & Indices)
	{
		Lib3MF_uint32 resultNewIndex = 0;
		CheckError(lib3mf_meshobject_addtriangle(m_pHandle, &Indices, &resultNewIndex));
		
		return resultNewIndex;
	}
	
	/**
	* CMeshObject::GetTriangleIndices - Get all triangles of a mesh object
	* @param[out] IndicesBuffer - contains the triangle indices.
	*/
	void CMeshObject::GetTriangleIndices(std::vector<sTriangle> & IndicesBuffer)
	{
		Lib3MF_uint64 elementsNeededIndices = 0;
		Lib3MF_uint64 elementsWrittenIndices = 0;
		CheckError(lib3mf_meshobject_gettriangleindices(m_pHandle, 0, &elementsNeededIndices, nullptr));
		IndicesBuffer.resize((size_t) elementsNeededIndices);
		CheckError(lib3mf_meshobject_gettriangleindices(m_pHandle, elementsNeededIndices, &elementsWrittenIndices, IndicesBuffer.data()));
	}
	
	/**
	* CMeshObject::SetObjectLevelProperty - Sets the property at the object-level of the mesh object.
	* @param[in] nUniqueResourceID - the object-level Property UniqueResourceID.
	* @param[in] nPropertyID - the object-level PropertyID.
	*/
	void CMeshObject::SetObjectLevelProperty(const Lib3MF_uint32 nUniqueResourceID, const Lib3MF_uint32 nPropertyID)
	{
		CheckError(lib3mf_meshobject_setobjectlevelproperty(m_pHandle, nUniqueResourceID, nPropertyID));
	}
	
	/**
	* CMeshObject::GetObjectLevelProperty - Gets the property at the object-level of the mesh object.
	* @param[out] nUniqueResourceID - the object-level Property UniqueResourceID.
	* @param[out] nPropertyID - the object-level PropertyID.
	* @return Has an object-level property been specified?
	*/
	bool CMeshObject::GetObjectLevelProperty(Lib3MF_uint32 & nUniqueResourceID, Lib3MF_uint32 & nPropertyID)
	{
		bool resultHasObjectLevelProperty = 0;
		CheckError(lib3mf_meshobject_getobjectlevelproperty(m_pHandle, &nUniqueResourceID, &nPropertyID, &resultHasObjectLevelProperty));
		
		return resultHasObjectLevelProperty;
	}
	
	/**
	* CMeshObject::SetTriangleProperties - Sets the properties of a single triangle of a mesh object.
	* @param[in] nIndex - Index of the triangle (0 to trianglecount - 1)
	* @param[in] Properties - contains the triangle properties.
	*/
	void CMeshObject::SetTriangleProperties(const Lib3MF_uint32 nIndex, const sTriangleProperties & Properties)
	{
		CheckError(lib3mf_meshobject_settriangleproperties(m_pHandle, nIndex, &Properties));
	}
	
	/**
	* CMeshObject::GetTriangleProperties - Gets the properties of a single triangle of a mesh object.
	* @param[in] nIndex - Index of the triangle (0 to trianglecount - 1)
	* @param[out] Property - returns the triangle properties.
	*/
	void CMeshObject::GetTriangleProperties(const Lib3MF_uint32 nIndex, sTriangleProperties & Property)
	{
		CheckError(lib3mf_meshobject_gettriangleproperties(m_pHandle, nIndex, &Property));
	}
	
	/**
	* CMeshObject::SetAllTriangleProperties - Sets the properties of all triangles of a mesh object. Sets the object level property to the first entry of the passed triangle properties, if not yet specified.
	* @param[in] PropertiesArrayBuffer - contains the triangle properties array. Must have trianglecount elements.
	*/
	void CMeshObject::SetAllTriangleProperties(const CInputVector<sTriangleProperties> & PropertiesArrayBuffer)
	{
		Lib3MF_uint64 nPropertiesArraySize = PropertiesArrayBuffer.size();
		CheckError(lib3mf_meshobject_setalltriangleproperties(m_pHandle, nPropertiesArraySize, PropertiesArrayBuffer.data()));
	}
	
	/**
	* CMeshObject::GetAllTriangleProperties - Gets the properties of all triangles of a mesh object.
	* @param[out] PropertiesArrayBuffer - returns the triangle properties array. Must have trianglecount elements.
	*/
	void CMeshObject::GetAllTriangleProperties(std::vector<sTriangleProperties> & PropertiesArrayBuffer)
	{
		Lib3MF_uint64 elementsNeededPropertiesArray = 0;
		Lib3MF_uint64 elementsWrittenPropertiesArray = 0;
		CheckError(lib3mf_meshobject_getalltriangleproperties(m_pHandle, 0, &elementsNeededPropertiesArray, nullptr));
		PropertiesArrayBuffer.resize((size_t) elementsNeededPropertiesArray);
		CheckError(lib3mf_meshobject_getalltriangleproperties(m_pHandle, elementsNeededPropertiesArray, &elementsWrittenPropertiesArray, PropertiesArrayBuffer.data()));
	}
	
	/**
	* CMeshObject::ClearAllProperties - Clears all properties of this mesh object (triangle and object-level).
	*/
	void CMeshObject::ClearAllProperties()
	{
		CheckError(lib3mf_meshobject_clearallproperties(m_pHandle));
	}
	
	/**
	* CMeshObject::SetGeometry - Set all triangles of a mesh object
	* @param[in] VerticesBuffer - contains the positions.
	* @param[in] IndicesBuffer - contains the triangle indices.
	*/
	void CMeshObject::SetGeometry(const CInputVector<sPosition> & VerticesBuffer, const CInputVector<sTriangle> & IndicesBuffer)
	{
		Lib3MF_uint64 nVerticesSize = VerticesBuffer.size();
		Lib3MF_uint64 nIndicesSize = IndicesBuffer.size();
		CheckError(lib3mf_meshobject_setgeometry(m_pHandle, nVerticesSize, VerticesBuffer.data(), nIndicesSize, IndicesBuffer.data()));
	}
	
	/**
	* CMeshObject::IsManifoldAndOriented - Retrieves, if an object describes a topologically oriented and manifold mesh, according to the core spec.
	* @return returns, if the object is oriented and manifold.
	*/
	bool CMeshObject::IsManifoldAndOriented()
	{
		bool resultIsManifoldAndOriented = 0;
		CheckError(lib3mf_meshobject_ismanifoldandoriented(m_pHandle, &resultIsManifoldAndOriented));
		
		return resultIsManifoldAndOriented;
	}
	
	/**
	* CMeshObject::BeamLattice - Retrieves the BeamLattice within this MeshObject.
	* @return the BeamLattice within this MeshObject
	*/
	PBeamLattice CMeshObject::BeamLattice()
	{
		Lib3MFHandle hTheBeamLattice = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_meshobject_beamlattice(m_pHandle, &hTheBeamLattice));
		
		if (!hTheBeamLattice) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBeamLattice>(dynamic_cast<CBeamLattice*>(m_pWrapper->polymorphicFactory(hTheBeamLattice)));
	}
	
	/**
	* CMeshObject::GetVolumeData - Retrieves the VolumeData of this MeshObject.
	* @return the VolumeData of this MeshObject
	*/
	PVolumeData CMeshObject::GetVolumeData()
	{
		Lib3MFHandle hTheVolumeData = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_meshobject_getvolumedata(m_pHandle, &hTheVolumeData));
		
		if (hTheVolumeData) {
			return std::shared_ptr<CVolumeData>(dynamic_cast<CVolumeData*>(m_pWrapper->polymorphicFactory(hTheVolumeData)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CMeshObject::SetVolumeData - Sets the VolumeData of this MeshObject.
	* @param[in] pTheVolumeData - the VolumeData of this MeshObject
	*/
	void CMeshObject::SetVolumeData(classParam<CVolumeData> pTheVolumeData)
	{
		Lib3MFHandle hTheVolumeData = pTheVolumeData.GetHandle();
		CheckError(lib3mf_meshobject_setvolumedata(m_pHandle, hTheVolumeData));
	}
	
	/**
	* CMeshObject::AddTriangleSet - Adds a new triangle set.
	* @param[in] sIdentifier - the new identifier. MUST be unique within the mesh. MUST NOT be an empty string
	* @param[in] sName - the human readable name. MUST NOT be an empty string
	* @return the new Triangle Set Instance.
	*/
	PTriangleSet CMeshObject::AddTriangleSet(const std::string & sIdentifier, const std::string & sName)
	{
		Lib3MFHandle hTheTriangleSet = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_meshobject_addtriangleset(m_pHandle, sIdentifier.c_str(), sName.c_str(), &hTheTriangleSet));
		
		if (!hTheTriangleSet) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTriangleSet>(dynamic_cast<CTriangleSet*>(m_pWrapper->polymorphicFactory(hTheTriangleSet)));
	}
	
	/**
	* CMeshObject::HasTriangleSet - Checks if a triangle set exists.
	* @param[in] sIdentifier - the identifier to be found.
	* @return flag if the triangles set exists.
	*/
	bool CMeshObject::HasTriangleSet(const std::string & sIdentifier)
	{
		bool resultTriangleSetExists = 0;
		CheckError(lib3mf_meshobject_hastriangleset(m_pHandle, sIdentifier.c_str(), &resultTriangleSetExists));
		
		return resultTriangleSetExists;
	}
	
	/**
	* CMeshObject::FindTriangleSet - Finds a new triangle set by identifier. Fails if not existing.
	* @param[in] sIdentifier - the identifier to be found.
	* @return the triangle Set Instance.
	*/
	PTriangleSet CMeshObject::FindTriangleSet(const std::string & sIdentifier)
	{
		Lib3MFHandle hTheTriangleSet = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_meshobject_findtriangleset(m_pHandle, sIdentifier.c_str(), &hTheTriangleSet));
		
		if (!hTheTriangleSet) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTriangleSet>(dynamic_cast<CTriangleSet*>(m_pWrapper->polymorphicFactory(hTheTriangleSet)));
	}
	
	/**
	* CMeshObject::GetTriangleSetCount - Returns number of triangle sets.
	* @return the number of triangle sets of this mesh.
	*/
	Lib3MF_uint32 CMeshObject::GetTriangleSetCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_meshobject_gettrianglesetcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CMeshObject::GetTriangleSet - Returns a specific triangle set by index.
	* @param[in] nIndex - the index of the triangle set.
	* @return the triangle Set Instance.
	*/
	PTriangleSet CMeshObject::GetTriangleSet(const Lib3MF_uint32 nIndex)
	{
		Lib3MFHandle hTheTriangleSet = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_meshobject_gettriangleset(m_pHandle, nIndex, &hTheTriangleSet));
		
		if (!hTheTriangleSet) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTriangleSet>(dynamic_cast<CTriangleSet*>(m_pWrapper->polymorphicFactory(hTheTriangleSet)));
	}
	
	/**
	 * Method definitions for class CLevelSet
	 */
	
	/**
	* CLevelSet::GetFunction - Returns the function that is used as boundary shape.
	* @return the function to use as boundary shape
	*/
	PFunction CLevelSet::GetFunction()
	{
		Lib3MFHandle hTheFunction = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_levelset_getfunction(m_pHandle, &hTheFunction));
		
		if (hTheFunction) {
			return std::shared_ptr<CFunction>(dynamic_cast<CFunction*>(m_pWrapper->polymorphicFactory(hTheFunction)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CLevelSet::SetFunction - Sets the function to use as boundary shape.
	* @param[in] pTheFunction - the function to use as boundary shape
	*/
	void CLevelSet::SetFunction(classParam<CFunction> pTheFunction)
	{
		Lib3MFHandle hTheFunction = pTheFunction.GetHandle();
		CheckError(lib3mf_levelset_setfunction(m_pHandle, hTheFunction));
	}
	
	/**
	* CLevelSet::GetTransform - Returns the transformation matrix into the coordinate system of the referenced Function.
	* @return the transformation matrix
	*/
	sTransform CLevelSet::GetTransform()
	{
		sTransform resultTransform;
		CheckError(lib3mf_levelset_gettransform(m_pHandle, &resultTransform));
		
		return resultTransform;
	}
	
	/**
	* CLevelSet::SetTransform - Sets the transformation matrix into the coordinate system of the referenced Function.
	* @param[in] Transform - new transformation matrix
	*/
	void CLevelSet::SetTransform(const sTransform & Transform)
	{
		CheckError(lib3mf_levelset_settransform(m_pHandle, &Transform));
	}
	
	/**
	* CLevelSet::GetChannelName - Returns the name of the function output channel to use.
	* @return the name of the function output channel
	*/
	std::string CLevelSet::GetChannelName()
	{
		Lib3MF_uint32 bytesNeededChannelName = 0;
		Lib3MF_uint32 bytesWrittenChannelName = 0;
		CheckError(lib3mf_levelset_getchannelname(m_pHandle, 0, &bytesNeededChannelName, nullptr));
		std::vector<char> bufferChannelName(bytesNeededChannelName);
		CheckError(lib3mf_levelset_getchannelname(m_pHandle, bytesNeededChannelName, &bytesWrittenChannelName, &bufferChannelName[0]));
		
		return std::string(&bufferChannelName[0]);
	}
	
	/**
	* CLevelSet::SetChannelName - Sets the name of the function output channel to use.
	* @param[in] sChannelName - new name of the function output channel
	*/
	void CLevelSet::SetChannelName(const std::string & sChannelName)
	{
		CheckError(lib3mf_levelset_setchannelname(m_pHandle, sChannelName.c_str()));
	}
	
	/**
	* CLevelSet::SetMinFeatureSize - Sets the minimal feature size as a hint for the function evaluator
	* @param[in] dMinFeatureSize - minimal feature size
	*/
	void CLevelSet::SetMinFeatureSize(const Lib3MF_double dMinFeatureSize)
	{
		CheckError(lib3mf_levelset_setminfeaturesize(m_pHandle, dMinFeatureSize));
	}
	
	/**
	* CLevelSet::GetMinFeatureSize - Returns the minimal feature size as a hint for the function evaluator
	* @return minimal feature size
	*/
	Lib3MF_double CLevelSet::GetMinFeatureSize()
	{
		Lib3MF_double resultMinFeatureSize = 0;
		CheckError(lib3mf_levelset_getminfeaturesize(m_pHandle, &resultMinFeatureSize));
		
		return resultMinFeatureSize;
	}
	
	/**
	* CLevelSet::SetFallBackValue - Sets the fallback value to use if the function evaluation fails (e.g. evaluates to NaN or Inf).
	* @param[in] dFallBackValue - fallback value
	*/
	void CLevelSet::SetFallBackValue(const Lib3MF_double dFallBackValue)
	{
		CheckError(lib3mf_levelset_setfallbackvalue(m_pHandle, dFallBackValue));
	}
	
	/**
	* CLevelSet::GetFallBackValue - Returns the fallback value to use if the function evaluation fails (e.g. evaluates to NaN or Inf).
	* @return fallback value
	*/
	Lib3MF_double CLevelSet::GetFallBackValue()
	{
		Lib3MF_double resultFallBackValue = 0;
		CheckError(lib3mf_levelset_getfallbackvalue(m_pHandle, &resultFallBackValue));
		
		return resultFallBackValue;
	}
	
	/**
	* CLevelSet::SetMeshBBoxOnly - If set only the bounding box of the mesh is intersected with the boundary
	* @param[in] bMeshBBoxOnly - If set only the bounding box of the mesh is intersected with the boundary
	*/
	void CLevelSet::SetMeshBBoxOnly(const bool bMeshBBoxOnly)
	{
		CheckError(lib3mf_levelset_setmeshbboxonly(m_pHandle, bMeshBBoxOnly));
	}
	
	/**
	* CLevelSet::GetMeshBBoxOnly - If set only the bounding box of the mesh is intersected with the boundary
	* @return If set only the bounding box of the mesh is intersected with the boundary
	*/
	bool CLevelSet::GetMeshBBoxOnly()
	{
		bool resultMeshBBoxOnly = 0;
		CheckError(lib3mf_levelset_getmeshbboxonly(m_pHandle, &resultMeshBBoxOnly));
		
		return resultMeshBBoxOnly;
	}
	
	/**
	* CLevelSet::SetMesh - Sets the mesh to use as evaluation domain
	* @param[in] pTheMesh - The mesh
	*/
	void CLevelSet::SetMesh(classParam<CMeshObject> pTheMesh)
	{
		Lib3MFHandle hTheMesh = pTheMesh.GetHandle();
		CheckError(lib3mf_levelset_setmesh(m_pHandle, hTheMesh));
	}
	
	/**
	* CLevelSet::GetMesh - Returns the mesh that is used as evaluation domain
	* @return The mesh
	*/
	PMeshObject CLevelSet::GetMesh()
	{
		Lib3MFHandle hTheMesh = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_levelset_getmesh(m_pHandle, &hTheMesh));
		
		if (hTheMesh) {
			return std::shared_ptr<CMeshObject>(dynamic_cast<CMeshObject*>(m_pWrapper->polymorphicFactory(hTheMesh)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CLevelSet::GetVolumeData - Retrieves the VolumeData this Object.
	* @return the VolumeData of this Object
	*/
	PVolumeData CLevelSet::GetVolumeData()
	{
		Lib3MFHandle hTheVolumeData = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_levelset_getvolumedata(m_pHandle, &hTheVolumeData));
		
		if (hTheVolumeData) {
			return std::shared_ptr<CVolumeData>(dynamic_cast<CVolumeData*>(m_pWrapper->polymorphicFactory(hTheVolumeData)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CLevelSet::SetVolumeData - Sets the VolumeData of this LevelSet.
	* @param[in] pTheVolumeData - the VolumeData of this MeshObject
	*/
	void CLevelSet::SetVolumeData(classParam<CVolumeData> pTheVolumeData)
	{
		Lib3MFHandle hTheVolumeData = pTheVolumeData.GetHandle();
		CheckError(lib3mf_levelset_setvolumedata(m_pHandle, hTheVolumeData));
	}
	
	/**
	 * Method definitions for class CBeamLattice
	 */
	
	/**
	* CBeamLattice::GetMinLength - Returns the minimal length of beams for the beamlattice.
	* @return minimal length of beams for the beamlattice
	*/
	Lib3MF_double CBeamLattice::GetMinLength()
	{
		Lib3MF_double resultMinLength = 0;
		CheckError(lib3mf_beamlattice_getminlength(m_pHandle, &resultMinLength));
		
		return resultMinLength;
	}
	
	/**
	* CBeamLattice::SetMinLength - Sets the minimal length of beams for the beamlattice.
	* @param[in] dMinLength - minimal length of beams for the beamlattice
	*/
	void CBeamLattice::SetMinLength(const Lib3MF_double dMinLength)
	{
		CheckError(lib3mf_beamlattice_setminlength(m_pHandle, dMinLength));
	}
	
	/**
	* CBeamLattice::GetClipping - Returns the clipping mode and the clipping-mesh for the beamlattice of this mesh.
	* @param[out] eClipMode - contains the clip mode of this mesh
	* @param[out] nUniqueResourceID - filled with the UniqueResourceID of the clipping mesh-object or an undefined value if pClipMode is MODELBEAMLATTICECLIPMODE_NONE
	*/
	void CBeamLattice::GetClipping(eBeamLatticeClipMode & eClipMode, Lib3MF_uint32 & nUniqueResourceID)
	{
		CheckError(lib3mf_beamlattice_getclipping(m_pHandle, &eClipMode, &nUniqueResourceID));
	}
	
	/**
	* CBeamLattice::SetClipping - Sets the clipping mode and the clipping-mesh for the beamlattice of this mesh.
	* @param[in] eClipMode - contains the clip mode of this mesh
	* @param[in] nUniqueResourceID - the UniqueResourceID of the clipping mesh-object. This mesh-object has to be defined before setting the Clipping.
	*/
	void CBeamLattice::SetClipping(const eBeamLatticeClipMode eClipMode, const Lib3MF_uint32 nUniqueResourceID)
	{
		CheckError(lib3mf_beamlattice_setclipping(m_pHandle, eClipMode, nUniqueResourceID));
	}
	
	/**
	* CBeamLattice::GetRepresentation - Returns the representation-mesh for the beamlattice of this mesh.
	* @return flag whether the beamlattice has a representation mesh.
	* @param[out] nUniqueResourceID - filled with the UniqueResourceID of the clipping mesh-object.
	*/
	bool CBeamLattice::GetRepresentation(Lib3MF_uint32 & nUniqueResourceID)
	{
		bool resultHasRepresentation = 0;
		CheckError(lib3mf_beamlattice_getrepresentation(m_pHandle, &resultHasRepresentation, &nUniqueResourceID));
		
		return resultHasRepresentation;
	}
	
	/**
	* CBeamLattice::SetRepresentation - Sets the representation-mesh for the beamlattice of this mesh.
	* @param[in] nUniqueResourceID - the UniqueResourceID of the representation mesh-object. This mesh-object has to be defined before setting the representation.
	*/
	void CBeamLattice::SetRepresentation(const Lib3MF_uint32 nUniqueResourceID)
	{
		CheckError(lib3mf_beamlattice_setrepresentation(m_pHandle, nUniqueResourceID));
	}
	
	/**
	* CBeamLattice::GetBallOptions - Returns the ball mode and the default ball radius for the beamlattice of this mesh.
	* @param[out] eBallMode - contains the ball mode of this mesh
	* @param[out] dBallRadius - default ball radius of balls for the beamlattice
	*/
	void CBeamLattice::GetBallOptions(eBeamLatticeBallMode & eBallMode, Lib3MF_double & dBallRadius)
	{
		CheckError(lib3mf_beamlattice_getballoptions(m_pHandle, &eBallMode, &dBallRadius));
	}
	
	/**
	* CBeamLattice::SetBallOptions - Sets the ball mode and thedefault ball radius for the beamlattice.
	* @param[in] eBallMode - contains the ball mode of this mesh
	* @param[in] dBallRadius - default ball radius of balls for the beamlattice
	*/
	void CBeamLattice::SetBallOptions(const eBeamLatticeBallMode eBallMode, const Lib3MF_double dBallRadius)
	{
		CheckError(lib3mf_beamlattice_setballoptions(m_pHandle, eBallMode, dBallRadius));
	}
	
	/**
	* CBeamLattice::GetBeamCount - Returns the beam count of a mesh object.
	* @return filled with the beam count.
	*/
	Lib3MF_uint32 CBeamLattice::GetBeamCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_beamlattice_getbeamcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CBeamLattice::GetBeam - Returns indices, radii and capmodes of a single beam of a mesh object.
	* @param[in] nIndex - Index of the beam (0 to beamcount - 1).
	* @return filled with the beam indices, radii and capmodes.
	*/
	sBeam CBeamLattice::GetBeam(const Lib3MF_uint32 nIndex)
	{
		sBeam resultBeamInfo;
		CheckError(lib3mf_beamlattice_getbeam(m_pHandle, nIndex, &resultBeamInfo));
		
		return resultBeamInfo;
	}
	
	/**
	* CBeamLattice::AddBeam - Adds a single beam to a mesh object.
	* @param[in] BeamInfo - contains the node indices, radii and capmodes.
	* @return filled with the new Index of the beam.
	*/
	Lib3MF_uint32 CBeamLattice::AddBeam(const sBeam & BeamInfo)
	{
		Lib3MF_uint32 resultIndex = 0;
		CheckError(lib3mf_beamlattice_addbeam(m_pHandle, &BeamInfo, &resultIndex));
		
		return resultIndex;
	}
	
	/**
	* CBeamLattice::SetBeam - Sets the indices, radii and capmodes of a single beam of a mesh object.
	* @param[in] nIndex - Index of the beam (0 to beamcount - 1).
	* @param[in] BeamInfo - filled with the beam indices, radii and capmodes.
	*/
	void CBeamLattice::SetBeam(const Lib3MF_uint32 nIndex, const sBeam & BeamInfo)
	{
		CheckError(lib3mf_beamlattice_setbeam(m_pHandle, nIndex, &BeamInfo));
	}
	
	/**
	* CBeamLattice::SetBeams - Sets all beam indices, radii and capmodes of a mesh object.
	* @param[in] BeamInfoBuffer - contains information of a number of  beams
	*/
	void CBeamLattice::SetBeams(const CInputVector<sBeam> & BeamInfoBuffer)
	{
		Lib3MF_uint64 nBeamInfoSize = BeamInfoBuffer.size();
		CheckError(lib3mf_beamlattice_setbeams(m_pHandle, nBeamInfoSize, BeamInfoBuffer.data()));
	}
	
	/**
	* CBeamLattice::GetBeams - obtains all beam indices, radii and capmodes of a mesh object.
	* @param[out] BeamInfoBuffer - contains information of all beams
	*/
	void CBeamLattice::GetBeams(std::vector<sBeam> & BeamInfoBuffer)
	{
		Lib3MF_uint64 elementsNeededBeamInfo = 0;
		Lib3MF_uint64 elementsWrittenBeamInfo = 0;
		CheckError(lib3mf_beamlattice_getbeams(m_pHandle, 0, &elementsNeededBeamInfo, nullptr));
		BeamInfoBuffer.resize((size_t) elementsNeededBeamInfo);
		CheckError(lib3mf_beamlattice_getbeams(m_pHandle, elementsNeededBeamInfo, &elementsWrittenBeamInfo, BeamInfoBuffer.data()));
	}
	
	/**
	* CBeamLattice::GetBallCount - Returns the ball count of a mesh object.
	* @return filled with the ball count.
	*/
	Lib3MF_uint32 CBeamLattice::GetBallCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_beamlattice_getballcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CBeamLattice::GetBall - Returns index and radius of a single ball of a mesh object.
	* @param[in] nIndex - Index of the ball (0 to ballcount - 1).
	* @return filled with the ball node index and radius.
	*/
	sBall CBeamLattice::GetBall(const Lib3MF_uint32 nIndex)
	{
		sBall resultBallInfo;
		CheckError(lib3mf_beamlattice_getball(m_pHandle, nIndex, &resultBallInfo));
		
		return resultBallInfo;
	}
	
	/**
	* CBeamLattice::AddBall - Adds a single ball to a mesh object.
	* @param[in] BallInfo - contains the node index and radius.
	* @return filled with the new Index of the ball.
	*/
	Lib3MF_uint32 CBeamLattice::AddBall(const sBall & BallInfo)
	{
		Lib3MF_uint32 resultIndex = 0;
		CheckError(lib3mf_beamlattice_addball(m_pHandle, &BallInfo, &resultIndex));
		
		return resultIndex;
	}
	
	/**
	* CBeamLattice::SetBall - Sets the index and radius of a single ball of a mesh object.
	* @param[in] nIndex - Index of the ball (0 to ballcount - 1).
	* @param[in] BallInfo - filled with the ball node index and radius.
	*/
	void CBeamLattice::SetBall(const Lib3MF_uint32 nIndex, const sBall & BallInfo)
	{
		CheckError(lib3mf_beamlattice_setball(m_pHandle, nIndex, &BallInfo));
	}
	
	/**
	* CBeamLattice::SetBalls - Sets all ball indices and radii of a mesh object.
	* @param[in] BallInfoBuffer - contains information of a number of  balls
	*/
	void CBeamLattice::SetBalls(const CInputVector<sBall> & BallInfoBuffer)
	{
		Lib3MF_uint64 nBallInfoSize = BallInfoBuffer.size();
		CheckError(lib3mf_beamlattice_setballs(m_pHandle, nBallInfoSize, BallInfoBuffer.data()));
	}
	
	/**
	* CBeamLattice::GetBalls - obtains all ball indices and radii of a mesh object.
	* @param[out] BallInfoBuffer - contains information of all balls
	*/
	void CBeamLattice::GetBalls(std::vector<sBall> & BallInfoBuffer)
	{
		Lib3MF_uint64 elementsNeededBallInfo = 0;
		Lib3MF_uint64 elementsWrittenBallInfo = 0;
		CheckError(lib3mf_beamlattice_getballs(m_pHandle, 0, &elementsNeededBallInfo, nullptr));
		BallInfoBuffer.resize((size_t) elementsNeededBallInfo);
		CheckError(lib3mf_beamlattice_getballs(m_pHandle, elementsNeededBallInfo, &elementsWrittenBallInfo, BallInfoBuffer.data()));
	}
	
	/**
	* CBeamLattice::GetBeamSetCount - Returns the number of beamsets of a mesh object.
	* @return filled with the beamset count.
	*/
	Lib3MF_uint32 CBeamLattice::GetBeamSetCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_beamlattice_getbeamsetcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CBeamLattice::AddBeamSet - Adds an empty beamset to a mesh object
	* @return the new beamset
	*/
	PBeamSet CBeamLattice::AddBeamSet()
	{
		Lib3MFHandle hBeamSet = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_beamlattice_addbeamset(m_pHandle, &hBeamSet));
		
		if (!hBeamSet) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBeamSet>(dynamic_cast<CBeamSet*>(m_pWrapper->polymorphicFactory(hBeamSet)));
	}
	
	/**
	* CBeamLattice::GetBeamSet - Returns a beamset of a mesh object
	* @param[in] nIndex - index of the requested beamset (0 ... beamsetcount-1).
	* @return the requested beamset
	*/
	PBeamSet CBeamLattice::GetBeamSet(const Lib3MF_uint32 nIndex)
	{
		Lib3MFHandle hBeamSet = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_beamlattice_getbeamset(m_pHandle, nIndex, &hBeamSet));
		
		if (!hBeamSet) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBeamSet>(dynamic_cast<CBeamSet*>(m_pWrapper->polymorphicFactory(hBeamSet)));
	}
	
	/**
	 * Method definitions for class CFunctionReference
	 */
	
	/**
	* CFunctionReference::GetFunctionResourceID - Returns the UniqueResourceID of the Function. Only functions with a 'pos'-input are allowed.
	* @return returns the UniqueResourceID.
	*/
	Lib3MF_uint32 CFunctionReference::GetFunctionResourceID()
	{
		Lib3MF_uint32 resultUniqueResourceID = 0;
		CheckError(lib3mf_functionreference_getfunctionresourceid(m_pHandle, &resultUniqueResourceID));
		
		return resultUniqueResourceID;
	}
	
	/**
	* CFunctionReference::SetFunctionResourceID - Sets the UniqueResourceID to refer to.
	* @param[in] nUniqueResourceID - UniqueResourceID of the function
	*/
	void CFunctionReference::SetFunctionResourceID(const Lib3MF_uint32 nUniqueResourceID)
	{
		CheckError(lib3mf_functionreference_setfunctionresourceid(m_pHandle, nUniqueResourceID));
	}
	
	/**
	* CFunctionReference::GetTransform - Returns the transformation matrix into the coordinate system of the referenced Function.
	* @return the transformation matrix
	*/
	sTransform CFunctionReference::GetTransform()
	{
		sTransform resultTransform;
		CheckError(lib3mf_functionreference_gettransform(m_pHandle, &resultTransform));
		
		return resultTransform;
	}
	
	/**
	* CFunctionReference::SetTransform - Sets the transformation matrix into the coordinate system of the referenced Function.
	* @param[in] Transform - new transformation matrix
	*/
	void CFunctionReference::SetTransform(const sTransform & Transform)
	{
		CheckError(lib3mf_functionreference_settransform(m_pHandle, &Transform));
	}
	
	/**
	* CFunctionReference::GetChannelName - Returns the name of the function output channel to use.
	* @return the name of the function output channel
	*/
	std::string CFunctionReference::GetChannelName()
	{
		Lib3MF_uint32 bytesNeededChannelName = 0;
		Lib3MF_uint32 bytesWrittenChannelName = 0;
		CheckError(lib3mf_functionreference_getchannelname(m_pHandle, 0, &bytesNeededChannelName, nullptr));
		std::vector<char> bufferChannelName(bytesNeededChannelName);
		CheckError(lib3mf_functionreference_getchannelname(m_pHandle, bytesNeededChannelName, &bytesWrittenChannelName, &bufferChannelName[0]));
		
		return std::string(&bufferChannelName[0]);
	}
	
	/**
	* CFunctionReference::SetChannelName - Sets the name of the function output channel to use.
	* @param[in] sChannelName - new name of the function output channel
	*/
	void CFunctionReference::SetChannelName(const std::string & sChannelName)
	{
		CheckError(lib3mf_functionreference_setchannelname(m_pHandle, sChannelName.c_str()));
	}
	
	/**
	* CFunctionReference::SetMinFeatureSize - Sets the minimal feature size as a hint for the function evaluator
	* @param[in] dMinFeatureSize - minimal feature size
	*/
	void CFunctionReference::SetMinFeatureSize(const Lib3MF_double dMinFeatureSize)
	{
		CheckError(lib3mf_functionreference_setminfeaturesize(m_pHandle, dMinFeatureSize));
	}
	
	/**
	* CFunctionReference::GetMinFeatureSize - Returns the minimal feature size as a hint for the function evaluator
	* @return minimal feature size
	*/
	Lib3MF_double CFunctionReference::GetMinFeatureSize()
	{
		Lib3MF_double resultMinFeatureSize = 0;
		CheckError(lib3mf_functionreference_getminfeaturesize(m_pHandle, &resultMinFeatureSize));
		
		return resultMinFeatureSize;
	}
	
	/**
	* CFunctionReference::SetFallBackValue - Sets the fallback value to use if the function evaluation fails (e.g. evaluates to NaN or Inf).
	* @param[in] dFallBackValue - fallback value
	*/
	void CFunctionReference::SetFallBackValue(const Lib3MF_double dFallBackValue)
	{
		CheckError(lib3mf_functionreference_setfallbackvalue(m_pHandle, dFallBackValue));
	}
	
	/**
	* CFunctionReference::GetFallBackValue - Returns the fallback value to use if the function evaluation fails (e.g. evaluates to NaN or Inf).
	* @return fallback value
	*/
	Lib3MF_double CFunctionReference::GetFallBackValue()
	{
		Lib3MF_double resultFallBackValue = 0;
		CheckError(lib3mf_functionreference_getfallbackvalue(m_pHandle, &resultFallBackValue));
		
		return resultFallBackValue;
	}
	
	/**
	 * Method definitions for class CVolumeDataColor
	 */
	
	/**
	 * Method definitions for class CMaterialMapping
	 */
	
	/**
	 * Method definitions for class CVolumeDataComposite
	 */
	
	/**
	* CVolumeDataComposite::GetBaseMaterialGroup - Returns the BaseMaterialGroup used within this volume data item
	* @return The BaseMaterialGroup instance of this VolumeDataComposite element
	*/
	PBaseMaterialGroup CVolumeDataComposite::GetBaseMaterialGroup()
	{
		Lib3MFHandle hBaseMaterialGroupInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_volumedatacomposite_getbasematerialgroup(m_pHandle, &hBaseMaterialGroupInstance));
		
		if (!hBaseMaterialGroupInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBaseMaterialGroup>(dynamic_cast<CBaseMaterialGroup*>(m_pWrapper->polymorphicFactory(hBaseMaterialGroupInstance)));
	}
	
	/**
	* CVolumeDataComposite::SetBaseMaterialGroup - Sets the BaseMaterialGroup to use within this volume data item.
	* @param[in] pBaseMaterialGroupInstance - The new BaseMaterialGroup instance of this VolumeDataComposite element
	*/
	void CVolumeDataComposite::SetBaseMaterialGroup(classParam<CBaseMaterialGroup> pBaseMaterialGroupInstance)
	{
		Lib3MFHandle hBaseMaterialGroupInstance = pBaseMaterialGroupInstance.GetHandle();
		CheckError(lib3mf_volumedatacomposite_setbasematerialgroup(m_pHandle, hBaseMaterialGroupInstance));
	}
	
	/**
	* CVolumeDataComposite::GetMaterialMappingCount - Returns the number of material mappings of this VolumeDataComposite element
	* @return the number of material mappings.
	*/
	Lib3MF_uint32 CVolumeDataComposite::GetMaterialMappingCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_volumedatacomposite_getmaterialmappingcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CVolumeDataComposite::GetMaterialMapping - Returns MaterialMapping with given index
	* @param[in] nIndex - Index of the MaterialMapping in question.
	* @return MaterialMapping used in this element
	*/
	PMaterialMapping CVolumeDataComposite::GetMaterialMapping(const Lib3MF_uint32 nIndex)
	{
		Lib3MFHandle hTheMaterialMapping = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_volumedatacomposite_getmaterialmapping(m_pHandle, nIndex, &hTheMaterialMapping));
		
		if (!hTheMaterialMapping) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMaterialMapping>(dynamic_cast<CMaterialMapping*>(m_pWrapper->polymorphicFactory(hTheMaterialMapping)));
	}
	
	/**
	* CVolumeDataComposite::AddMaterialMapping - Adds a MaterialMapping
	* @param[in] Transform - new transformation matrix
	* @return The new MaterialMapping
	*/
	PMaterialMapping CVolumeDataComposite::AddMaterialMapping(const sTransform & Transform)
	{
		Lib3MFHandle hTheMaterialMapping = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_volumedatacomposite_addmaterialmapping(m_pHandle, &Transform, &hTheMaterialMapping));
		
		if (!hTheMaterialMapping) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMaterialMapping>(dynamic_cast<CMaterialMapping*>(m_pWrapper->polymorphicFactory(hTheMaterialMapping)));
	}
	
	/**
	* CVolumeDataComposite::RemoveMaterialMapping - Removes the MaterialMapping with given index
	* @param[in] nIndex - The index of the MaterialMapping to be removed.
	*/
	void CVolumeDataComposite::RemoveMaterialMapping(const Lib3MF_uint32 nIndex)
	{
		CheckError(lib3mf_volumedatacomposite_removematerialmapping(m_pHandle, nIndex));
	}
	
	/**
	 * Method definitions for class CVolumeDataProperty
	 */
	
	/**
	* CVolumeDataProperty::GetName - Gets the qualified name of this property.
	* @return The qualified name of this property.
	*/
	std::string CVolumeDataProperty::GetName()
	{
		Lib3MF_uint32 bytesNeededPropertyName = 0;
		Lib3MF_uint32 bytesWrittenPropertyName = 0;
		CheckError(lib3mf_volumedataproperty_getname(m_pHandle, 0, &bytesNeededPropertyName, nullptr));
		std::vector<char> bufferPropertyName(bytesNeededPropertyName);
		CheckError(lib3mf_volumedataproperty_getname(m_pHandle, bytesNeededPropertyName, &bytesWrittenPropertyName, &bufferPropertyName[0]));
		
		return std::string(&bufferPropertyName[0]);
	}
	
	/**
	* CVolumeDataProperty::SetIsRequired - Sets whether this property is required to process this 3MF document instance.
	* @param[in] bIsRequired - New value for whether this property is required to process this 3MF document instance.
	*/
	void CVolumeDataProperty::SetIsRequired(const bool bIsRequired)
	{
		CheckError(lib3mf_volumedataproperty_setisrequired(m_pHandle, bIsRequired));
	}
	
	/**
	* CVolumeDataProperty::IsRequired - Returns whether this property is required to process this 3MF document instance.
	* @return Is this property required to process this 3MF document instance?
	*/
	bool CVolumeDataProperty::IsRequired()
	{
		bool resultIsRequired = 0;
		CheckError(lib3mf_volumedataproperty_isrequired(m_pHandle, &resultIsRequired));
		
		return resultIsRequired;
	}
	
	/**
	 * Method definitions for class CVolumeData
	 */
	
	/**
	* CVolumeData::GetComposite - Returns the VolumeDataComposite of this VolumeData instance
	* @return filled with the VolumeDataComposite of this VolumeData instance.
	*/
	PVolumeDataComposite CVolumeData::GetComposite()
	{
		Lib3MFHandle hTheCompositeData = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_volumedata_getcomposite(m_pHandle, &hTheCompositeData));
		
		if (hTheCompositeData) {
			return std::shared_ptr<CVolumeDataComposite>(dynamic_cast<CVolumeDataComposite*>(m_pWrapper->polymorphicFactory(hTheCompositeData)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CVolumeData::CreateNewComposite - Creates a new VolumeDataComposite for this VolumeData instance
	* @return The new VolumeDataComposite of this VolumeData instance.
	*/
	PVolumeDataComposite CVolumeData::CreateNewComposite()
	{
		Lib3MFHandle hTheCompositeData = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_volumedata_createnewcomposite(m_pHandle, &hTheCompositeData));
		
		if (!hTheCompositeData) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CVolumeDataComposite>(dynamic_cast<CVolumeDataComposite*>(m_pWrapper->polymorphicFactory(hTheCompositeData)));
	}
	
	/**
	* CVolumeData::RemoveComposite - Removes the VolumeDataComposite of this VolumeData instance
	*/
	void CVolumeData::RemoveComposite()
	{
		CheckError(lib3mf_volumedata_removecomposite(m_pHandle));
	}
	
	/**
	* CVolumeData::GetColor - Returns the VolumeDataColor of this VolumeData instance
	* @return filled with the VolumeDataColor of this VolumeData instance.
	*/
	PVolumeDataColor CVolumeData::GetColor()
	{
		Lib3MFHandle hTheColorData = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_volumedata_getcolor(m_pHandle, &hTheColorData));
		
		if (hTheColorData) {
			return std::shared_ptr<CVolumeDataColor>(dynamic_cast<CVolumeDataColor*>(m_pWrapper->polymorphicFactory(hTheColorData)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CVolumeData::CreateNewColor - Creates a new VolumeDataColor for this VolumeData instance
	* @param[in] pTheFunction - Function used in this element
	* @return The new VolumeDataColor of this VolumeData instance.
	*/
	PVolumeDataColor CVolumeData::CreateNewColor(classParam<CFunction> pTheFunction)
	{
		Lib3MFHandle hTheFunction = pTheFunction.GetHandle();
		Lib3MFHandle hTheColorData = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_volumedata_createnewcolor(m_pHandle, hTheFunction, &hTheColorData));
		
		if (!hTheColorData) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CVolumeDataColor>(dynamic_cast<CVolumeDataColor*>(m_pWrapper->polymorphicFactory(hTheColorData)));
	}
	
	/**
	* CVolumeData::RemoveColor - Removes the VolumeDataColor of this VolumeData instance
	*/
	void CVolumeData::RemoveColor()
	{
		CheckError(lib3mf_volumedata_removecolor(m_pHandle));
	}
	
	/**
	* CVolumeData::GetPropertyCount - Returns the number of VolumeDataProperty
	* @return the number of VolumeDataProperty-elements within this VolumeData
	*/
	Lib3MF_uint32 CVolumeData::GetPropertyCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_volumedata_getpropertycount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CVolumeData::GetProperty - Returns the VolumeDataProperty at a given Index
	* @param[in] nIndex - the index of the VolumeDataProperty to be returned.
	* @return the VolumeDataProperty at the given index.
	*/
	PVolumeDataProperty CVolumeData::GetProperty(const Lib3MF_uint32 nIndex)
	{
		Lib3MFHandle hTheVolumeDataProperty = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_volumedata_getproperty(m_pHandle, nIndex, &hTheVolumeDataProperty));
		
		if (!hTheVolumeDataProperty) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CVolumeDataProperty>(dynamic_cast<CVolumeDataProperty*>(m_pWrapper->polymorphicFactory(hTheVolumeDataProperty)));
	}
	
	/**
	* CVolumeData::AddPropertyFromFunction - Adds a new VolumeDataProperty from a Function
	* @param[in] sName - the qualified name (namespace+name) of the Property
	* @param[in] pTheFunction - Function used in this element
	* @return the newly created VolumeDataProperty.
	*/
	PVolumeDataProperty CVolumeData::AddPropertyFromFunction(const std::string & sName, classParam<CFunction> pTheFunction)
	{
		Lib3MFHandle hTheFunction = pTheFunction.GetHandle();
		Lib3MFHandle hTheVolumeDataProperty = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_volumedata_addpropertyfromfunction(m_pHandle, sName.c_str(), hTheFunction, &hTheVolumeDataProperty));
		
		if (!hTheVolumeDataProperty) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CVolumeDataProperty>(dynamic_cast<CVolumeDataProperty*>(m_pWrapper->polymorphicFactory(hTheVolumeDataProperty)));
	}
	
	/**
	* CVolumeData::RemoveProperty - Removes the VolumeDataProperty with a given index
	* @param[in] nIndex - the index of the VolumeDataProperty to be removed.
	*/
	void CVolumeData::RemoveProperty(const Lib3MF_uint32 nIndex)
	{
		CheckError(lib3mf_volumedata_removeproperty(m_pHandle, nIndex));
	}
	
	/**
	 * Method definitions for class CComponent
	 */
	
	/**
	* CComponent::GetObjectResource - Returns the Resource Instance of the component.
	* @return filled with the Resource Instance.
	*/
	PObject CComponent::GetObjectResource()
	{
		Lib3MFHandle hObjectResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_component_getobjectresource(m_pHandle, &hObjectResource));
		
		if (!hObjectResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CObject>(dynamic_cast<CObject*>(m_pWrapper->polymorphicFactory(hObjectResource)));
	}
	
	/**
	* CComponent::GetObjectResourceID - Returns the UniqueResourceID of the component.
	* @return returns the UniqueResourceID.
	*/
	Lib3MF_uint32 CComponent::GetObjectResourceID()
	{
		Lib3MF_uint32 resultUniqueResourceID = 0;
		CheckError(lib3mf_component_getobjectresourceid(m_pHandle, &resultUniqueResourceID));
		
		return resultUniqueResourceID;
	}
	
	/**
	* CComponent::GetUUID - returns, whether a component has a UUID and, if true, the component's UUID
	* @param[out] bHasUUID - flag whether the component has a UUID
	* @return the UUID as string of the form 'xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx'
	*/
	std::string CComponent::GetUUID(bool & bHasUUID)
	{
		Lib3MF_uint32 bytesNeededUUID = 0;
		Lib3MF_uint32 bytesWrittenUUID = 0;
		CheckError(lib3mf_component_getuuid(m_pHandle, &bHasUUID, 0, &bytesNeededUUID, nullptr));
		std::vector<char> bufferUUID(bytesNeededUUID);
		CheckError(lib3mf_component_getuuid(m_pHandle, &bHasUUID, bytesNeededUUID, &bytesWrittenUUID, &bufferUUID[0]));
		
		return std::string(&bufferUUID[0]);
	}
	
	/**
	* CComponent::SetUUID - sets the component's UUID
	* @param[in] sUUID - the UUID as string of the form 'xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx'
	*/
	void CComponent::SetUUID(const std::string & sUUID)
	{
		CheckError(lib3mf_component_setuuid(m_pHandle, sUUID.c_str()));
	}
	
	/**
	* CComponent::HasTransform - Returns, if the component has a different transformation than the identity matrix
	* @return if true is returned, the transformation is not equal than the identity
	*/
	bool CComponent::HasTransform()
	{
		bool resultHasTransform = 0;
		CheckError(lib3mf_component_hastransform(m_pHandle, &resultHasTransform));
		
		return resultHasTransform;
	}
	
	/**
	* CComponent::GetTransform - Returns the transformation matrix of the component.
	* @return filled with the component transformation matrix
	*/
	sTransform CComponent::GetTransform()
	{
		sTransform resultTransform;
		CheckError(lib3mf_component_gettransform(m_pHandle, &resultTransform));
		
		return resultTransform;
	}
	
	/**
	* CComponent::SetTransform - Sets the transformation matrix of the component.
	* @param[in] Transform - new transformation matrix
	*/
	void CComponent::SetTransform(const sTransform & Transform)
	{
		CheckError(lib3mf_component_settransform(m_pHandle, &Transform));
	}
	
	/**
	 * Method definitions for class CComponentsObject
	 */
	
	/**
	* CComponentsObject::AddComponent - Adds a new component to a components object.
	* @param[in] pObjectResource - object to add as component. Must not lead to circular references!
	* @param[in] Transform - optional transform matrix for the component.
	* @return new component instance
	*/
	PComponent CComponentsObject::AddComponent(classParam<CObject> pObjectResource, const sTransform & Transform)
	{
		Lib3MFHandle hObjectResource = pObjectResource.GetHandle();
		Lib3MFHandle hComponentInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_componentsobject_addcomponent(m_pHandle, hObjectResource, &Transform, &hComponentInstance));
		
		if (!hComponentInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CComponent>(dynamic_cast<CComponent*>(m_pWrapper->polymorphicFactory(hComponentInstance)));
	}
	
	/**
	* CComponentsObject::GetComponent - Retrieves a component from a component object.
	* @param[in] nIndex - index of the component to retrieve (0 to componentcount - 1)
	* @return component instance
	*/
	PComponent CComponentsObject::GetComponent(const Lib3MF_uint32 nIndex)
	{
		Lib3MFHandle hComponentInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_componentsobject_getcomponent(m_pHandle, nIndex, &hComponentInstance));
		
		if (!hComponentInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CComponent>(dynamic_cast<CComponent*>(m_pWrapper->polymorphicFactory(hComponentInstance)));
	}
	
	/**
	* CComponentsObject::GetComponentCount - Retrieves a component count of a component object.
	* @return returns the component count
	*/
	Lib3MF_uint32 CComponentsObject::GetComponentCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_componentsobject_getcomponentcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	 * Method definitions for class CBeamSet
	 */
	
	/**
	* CBeamSet::SetName - Sets a beamset's name string
	* @param[in] sName - new name of the beamset.
	*/
	void CBeamSet::SetName(const std::string & sName)
	{
		CheckError(lib3mf_beamset_setname(m_pHandle, sName.c_str()));
	}
	
	/**
	* CBeamSet::GetName - Retrieves a beamset's name string
	* @return returns the name of the beamset.
	*/
	std::string CBeamSet::GetName()
	{
		Lib3MF_uint32 bytesNeededName = 0;
		Lib3MF_uint32 bytesWrittenName = 0;
		CheckError(lib3mf_beamset_getname(m_pHandle, 0, &bytesNeededName, nullptr));
		std::vector<char> bufferName(bytesNeededName);
		CheckError(lib3mf_beamset_getname(m_pHandle, bytesNeededName, &bytesWrittenName, &bufferName[0]));
		
		return std::string(&bufferName[0]);
	}
	
	/**
	* CBeamSet::SetIdentifier - Sets a beamset's identifier string
	* @param[in] sIdentifier - new name of the beamset.
	*/
	void CBeamSet::SetIdentifier(const std::string & sIdentifier)
	{
		CheckError(lib3mf_beamset_setidentifier(m_pHandle, sIdentifier.c_str()));
	}
	
	/**
	* CBeamSet::GetIdentifier - Retrieves a beamset's identifier string
	* @return returns the identifier of the beamset.
	*/
	std::string CBeamSet::GetIdentifier()
	{
		Lib3MF_uint32 bytesNeededIdentifier = 0;
		Lib3MF_uint32 bytesWrittenIdentifier = 0;
		CheckError(lib3mf_beamset_getidentifier(m_pHandle, 0, &bytesNeededIdentifier, nullptr));
		std::vector<char> bufferIdentifier(bytesNeededIdentifier);
		CheckError(lib3mf_beamset_getidentifier(m_pHandle, bytesNeededIdentifier, &bytesWrittenIdentifier, &bufferIdentifier[0]));
		
		return std::string(&bufferIdentifier[0]);
	}
	
	/**
	* CBeamSet::GetReferenceCount - Retrieves the reference count of a beamset
	* @return returns the reference count
	*/
	Lib3MF_uint32 CBeamSet::GetReferenceCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_beamset_getreferencecount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CBeamSet::SetReferences - Sets the references of a beamset
	* @param[in] ReferencesBuffer - the new indices of all beams in this beamset
	*/
	void CBeamSet::SetReferences(const CInputVector<Lib3MF_uint32> & ReferencesBuffer)
	{
		Lib3MF_uint64 nReferencesSize = ReferencesBuffer.size();
		CheckError(lib3mf_beamset_setreferences(m_pHandle, nReferencesSize, ReferencesBuffer.data()));
	}
	
	/**
	* CBeamSet::GetReferences - Retrieves the references of a beamset
	* @param[out] ReferencesBuffer - retrieves the indices of all beams in this beamset
	*/
	void CBeamSet::GetReferences(std::vector<Lib3MF_uint32> & ReferencesBuffer)
	{
		Lib3MF_uint64 elementsNeededReferences = 0;
		Lib3MF_uint64 elementsWrittenReferences = 0;
		CheckError(lib3mf_beamset_getreferences(m_pHandle, 0, &elementsNeededReferences, nullptr));
		ReferencesBuffer.resize((size_t) elementsNeededReferences);
		CheckError(lib3mf_beamset_getreferences(m_pHandle, elementsNeededReferences, &elementsWrittenReferences, ReferencesBuffer.data()));
	}
	
	/**
	* CBeamSet::GetBallReferenceCount - Retrieves the ball reference count of a beamset
	* @return returns the ball reference count
	*/
	Lib3MF_uint32 CBeamSet::GetBallReferenceCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_beamset_getballreferencecount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CBeamSet::SetBallReferences - Sets the ball references of a beamset
	* @param[in] BallReferencesBuffer - the new indices of all balls in this beamset
	*/
	void CBeamSet::SetBallReferences(const CInputVector<Lib3MF_uint32> & BallReferencesBuffer)
	{
		Lib3MF_uint64 nBallReferencesSize = BallReferencesBuffer.size();
		CheckError(lib3mf_beamset_setballreferences(m_pHandle, nBallReferencesSize, BallReferencesBuffer.data()));
	}
	
	/**
	* CBeamSet::GetBallReferences - Retrieves the ball references of a beamset
	* @param[out] BallReferencesBuffer - retrieves the indices of all balls in this beamset
	*/
	void CBeamSet::GetBallReferences(std::vector<Lib3MF_uint32> & BallReferencesBuffer)
	{
		Lib3MF_uint64 elementsNeededBallReferences = 0;
		Lib3MF_uint64 elementsWrittenBallReferences = 0;
		CheckError(lib3mf_beamset_getballreferences(m_pHandle, 0, &elementsNeededBallReferences, nullptr));
		BallReferencesBuffer.resize((size_t) elementsNeededBallReferences);
		CheckError(lib3mf_beamset_getballreferences(m_pHandle, elementsNeededBallReferences, &elementsWrittenBallReferences, BallReferencesBuffer.data()));
	}
	
	/**
	 * Method definitions for class CBaseMaterialGroup
	 */
	
	/**
	* CBaseMaterialGroup::GetCount - Retrieves the count of base materials in the material group.
	* @return returns the count of base materials.
	*/
	Lib3MF_uint32 CBaseMaterialGroup::GetCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_basematerialgroup_getcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CBaseMaterialGroup::GetAllPropertyIDs - returns all the PropertyIDs of all materials in this group
	* @param[out] PropertyIDsBuffer - PropertyID of the material in the material group.
	*/
	void CBaseMaterialGroup::GetAllPropertyIDs(std::vector<Lib3MF_uint32> & PropertyIDsBuffer)
	{
		Lib3MF_uint64 elementsNeededPropertyIDs = 0;
		Lib3MF_uint64 elementsWrittenPropertyIDs = 0;
		CheckError(lib3mf_basematerialgroup_getallpropertyids(m_pHandle, 0, &elementsNeededPropertyIDs, nullptr));
		PropertyIDsBuffer.resize((size_t) elementsNeededPropertyIDs);
		CheckError(lib3mf_basematerialgroup_getallpropertyids(m_pHandle, elementsNeededPropertyIDs, &elementsWrittenPropertyIDs, PropertyIDsBuffer.data()));
	}
	
	/**
	* CBaseMaterialGroup::AddMaterial - Adds a new material to the material group
	* @param[in] sName - new name of the base material.
	* @param[in] DisplayColor - Display color of the material
	* @return returns new PropertyID of the new material in the material group.
	*/
	Lib3MF_uint32 CBaseMaterialGroup::AddMaterial(const std::string & sName, const sColor & DisplayColor)
	{
		Lib3MF_uint32 resultPropertyID = 0;
		CheckError(lib3mf_basematerialgroup_addmaterial(m_pHandle, sName.c_str(), &DisplayColor, &resultPropertyID));
		
		return resultPropertyID;
	}
	
	/**
	* CBaseMaterialGroup::RemoveMaterial - Removes a material from the material group.
	* @param[in] nPropertyID - PropertyID of the material in the material group.
	*/
	void CBaseMaterialGroup::RemoveMaterial(const Lib3MF_uint32 nPropertyID)
	{
		CheckError(lib3mf_basematerialgroup_removematerial(m_pHandle, nPropertyID));
	}
	
	/**
	* CBaseMaterialGroup::GetName - Returns the base material's name
	* @param[in] nPropertyID - PropertyID of the material in the material group.
	* @return returns the name of the base material.
	*/
	std::string CBaseMaterialGroup::GetName(const Lib3MF_uint32 nPropertyID)
	{
		Lib3MF_uint32 bytesNeededName = 0;
		Lib3MF_uint32 bytesWrittenName = 0;
		CheckError(lib3mf_basematerialgroup_getname(m_pHandle, nPropertyID, 0, &bytesNeededName, nullptr));
		std::vector<char> bufferName(bytesNeededName);
		CheckError(lib3mf_basematerialgroup_getname(m_pHandle, nPropertyID, bytesNeededName, &bytesWrittenName, &bufferName[0]));
		
		return std::string(&bufferName[0]);
	}
	
	/**
	* CBaseMaterialGroup::SetName - Sets a base material's name
	* @param[in] nPropertyID - PropertyID of the material in the material group.
	* @param[in] sName - new name of the base material.
	*/
	void CBaseMaterialGroup::SetName(const Lib3MF_uint32 nPropertyID, const std::string & sName)
	{
		CheckError(lib3mf_basematerialgroup_setname(m_pHandle, nPropertyID, sName.c_str()));
	}
	
	/**
	* CBaseMaterialGroup::SetDisplayColor - Sets a base material's display color.
	* @param[in] nPropertyID - PropertyID of the material in the material group.
	* @param[in] TheColor - The base material's display color
	*/
	void CBaseMaterialGroup::SetDisplayColor(const Lib3MF_uint32 nPropertyID, const sColor & TheColor)
	{
		CheckError(lib3mf_basematerialgroup_setdisplaycolor(m_pHandle, nPropertyID, &TheColor));
	}
	
	/**
	* CBaseMaterialGroup::GetDisplayColor - Returns a base material's display color.
	* @param[in] nPropertyID - PropertyID of the material in the material group.
	* @return The base material's display color
	*/
	sColor CBaseMaterialGroup::GetDisplayColor(const Lib3MF_uint32 nPropertyID)
	{
		sColor resultTheColor;
		CheckError(lib3mf_basematerialgroup_getdisplaycolor(m_pHandle, nPropertyID, &resultTheColor));
		
		return resultTheColor;
	}
	
	/**
	 * Method definitions for class CColorGroup
	 */
	
	/**
	* CColorGroup::GetCount - Retrieves the count of base materials in this Color Group.
	* @return returns the count of colors within this color group.
	*/
	Lib3MF_uint32 CColorGroup::GetCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_colorgroup_getcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CColorGroup::GetAllPropertyIDs - returns all the PropertyIDs of all colors within this group
	* @param[out] PropertyIDsBuffer - PropertyID of the color in the color group.
	*/
	void CColorGroup::GetAllPropertyIDs(std::vector<Lib3MF_uint32> & PropertyIDsBuffer)
	{
		Lib3MF_uint64 elementsNeededPropertyIDs = 0;
		Lib3MF_uint64 elementsWrittenPropertyIDs = 0;
		CheckError(lib3mf_colorgroup_getallpropertyids(m_pHandle, 0, &elementsNeededPropertyIDs, nullptr));
		PropertyIDsBuffer.resize((size_t) elementsNeededPropertyIDs);
		CheckError(lib3mf_colorgroup_getallpropertyids(m_pHandle, elementsNeededPropertyIDs, &elementsWrittenPropertyIDs, PropertyIDsBuffer.data()));
	}
	
	/**
	* CColorGroup::AddColor - Adds a new value.
	* @param[in] TheColor - The new color
	* @return PropertyID of the new color within this color group.
	*/
	Lib3MF_uint32 CColorGroup::AddColor(const sColor & TheColor)
	{
		Lib3MF_uint32 resultPropertyID = 0;
		CheckError(lib3mf_colorgroup_addcolor(m_pHandle, &TheColor, &resultPropertyID));
		
		return resultPropertyID;
	}
	
	/**
	* CColorGroup::RemoveColor - Removes a color from the color group.
	* @param[in] nPropertyID - PropertyID of the color to be removed from the color group.
	*/
	void CColorGroup::RemoveColor(const Lib3MF_uint32 nPropertyID)
	{
		CheckError(lib3mf_colorgroup_removecolor(m_pHandle, nPropertyID));
	}
	
	/**
	* CColorGroup::SetColor - Sets a color value.
	* @param[in] nPropertyID - PropertyID of a color within this color group.
	* @param[in] TheColor - The color
	*/
	void CColorGroup::SetColor(const Lib3MF_uint32 nPropertyID, const sColor & TheColor)
	{
		CheckError(lib3mf_colorgroup_setcolor(m_pHandle, nPropertyID, &TheColor));
	}
	
	/**
	* CColorGroup::GetColor - Sets a color value.
	* @param[in] nPropertyID - PropertyID of a color within this color group.
	* @return The color
	*/
	sColor CColorGroup::GetColor(const Lib3MF_uint32 nPropertyID)
	{
		sColor resultTheColor;
		CheckError(lib3mf_colorgroup_getcolor(m_pHandle, nPropertyID, &resultTheColor));
		
		return resultTheColor;
	}
	
	/**
	 * Method definitions for class CTexture2DGroup
	 */
	
	/**
	* CTexture2DGroup::GetCount - Retrieves the count of tex2coords in the Texture2DGroup.
	* @return returns the count of tex2coords.
	*/
	Lib3MF_uint32 CTexture2DGroup::GetCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_texture2dgroup_getcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CTexture2DGroup::GetAllPropertyIDs - returns all the PropertyIDs of all tex2coords in this Texture2DGroup
	* @param[out] PropertyIDsBuffer - PropertyID of the tex2coords in the Texture2DGroup.
	*/
	void CTexture2DGroup::GetAllPropertyIDs(std::vector<Lib3MF_uint32> & PropertyIDsBuffer)
	{
		Lib3MF_uint64 elementsNeededPropertyIDs = 0;
		Lib3MF_uint64 elementsWrittenPropertyIDs = 0;
		CheckError(lib3mf_texture2dgroup_getallpropertyids(m_pHandle, 0, &elementsNeededPropertyIDs, nullptr));
		PropertyIDsBuffer.resize((size_t) elementsNeededPropertyIDs);
		CheckError(lib3mf_texture2dgroup_getallpropertyids(m_pHandle, elementsNeededPropertyIDs, &elementsWrittenPropertyIDs, PropertyIDsBuffer.data()));
	}
	
	/**
	* CTexture2DGroup::AddTex2Coord - Adds a new tex2coord to the Texture2DGroup
	* @param[in] UVCoordinate - The u/v-coordinate within the texture, horizontally right/vertically up from the origin in the lower left of the texture.
	* @return returns new PropertyID of the new tex2coord in the Texture2DGroup.
	*/
	Lib3MF_uint32 CTexture2DGroup::AddTex2Coord(const sTex2Coord & UVCoordinate)
	{
		Lib3MF_uint32 resultPropertyID = 0;
		CheckError(lib3mf_texture2dgroup_addtex2coord(m_pHandle, &UVCoordinate, &resultPropertyID));
		
		return resultPropertyID;
	}
	
	/**
	* CTexture2DGroup::GetTex2Coord - Obtains a tex2coord to the Texture2DGroup
	* @param[in] nPropertyID - the PropertyID of the tex2coord in the Texture2DGroup.
	* @return The u/v-coordinate within the texture, horizontally right/vertically up from the origin in the lower left of the texture.
	*/
	sTex2Coord CTexture2DGroup::GetTex2Coord(const Lib3MF_uint32 nPropertyID)
	{
		sTex2Coord resultUVCoordinate;
		CheckError(lib3mf_texture2dgroup_gettex2coord(m_pHandle, nPropertyID, &resultUVCoordinate));
		
		return resultUVCoordinate;
	}
	
	/**
	* CTexture2DGroup::RemoveTex2Coord - Removes a tex2coords from the Texture2DGroup.
	* @param[in] nPropertyID - PropertyID of the tex2coords in the Texture2DGroup.
	*/
	void CTexture2DGroup::RemoveTex2Coord(const Lib3MF_uint32 nPropertyID)
	{
		CheckError(lib3mf_texture2dgroup_removetex2coord(m_pHandle, nPropertyID));
	}
	
	/**
	* CTexture2DGroup::GetTexture2D - Obtains the texture2D instance of this group.
	* @return the texture2D instance of this group.
	*/
	PTexture2D CTexture2DGroup::GetTexture2D()
	{
		Lib3MFHandle hTexture2DInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_texture2dgroup_gettexture2d(m_pHandle, &hTexture2DInstance));
		
		if (!hTexture2DInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTexture2D>(dynamic_cast<CTexture2D*>(m_pWrapper->polymorphicFactory(hTexture2DInstance)));
	}
	
	/**
	 * Method definitions for class CCompositeMaterials
	 */
	
	/**
	* CCompositeMaterials::GetCount - Retrieves the count of Composite-s in the CompositeMaterials.
	* @return returns the count of Composite-s
	*/
	Lib3MF_uint32 CCompositeMaterials::GetCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_compositematerials_getcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CCompositeMaterials::GetAllPropertyIDs - returns all the PropertyIDs of all Composite-Mixing Values in this CompositeMaterials
	* @param[out] PropertyIDsBuffer - PropertyID of the Composite-Mixing Values in the CompositeMaterials.
	*/
	void CCompositeMaterials::GetAllPropertyIDs(std::vector<Lib3MF_uint32> & PropertyIDsBuffer)
	{
		Lib3MF_uint64 elementsNeededPropertyIDs = 0;
		Lib3MF_uint64 elementsWrittenPropertyIDs = 0;
		CheckError(lib3mf_compositematerials_getallpropertyids(m_pHandle, 0, &elementsNeededPropertyIDs, nullptr));
		PropertyIDsBuffer.resize((size_t) elementsNeededPropertyIDs);
		CheckError(lib3mf_compositematerials_getallpropertyids(m_pHandle, elementsNeededPropertyIDs, &elementsWrittenPropertyIDs, PropertyIDsBuffer.data()));
	}
	
	/**
	* CCompositeMaterials::GetBaseMaterialGroup - Obtains the BaseMaterialGroup instance of this CompositeMaterials.
	* @return returns the BaseMaterialGroup instance of this CompositeMaterials
	*/
	PBaseMaterialGroup CCompositeMaterials::GetBaseMaterialGroup()
	{
		Lib3MFHandle hBaseMaterialGroupInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_compositematerials_getbasematerialgroup(m_pHandle, &hBaseMaterialGroupInstance));
		
		if (!hBaseMaterialGroupInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBaseMaterialGroup>(dynamic_cast<CBaseMaterialGroup*>(m_pWrapper->polymorphicFactory(hBaseMaterialGroupInstance)));
	}
	
	/**
	* CCompositeMaterials::AddComposite - Adds a new Composite-Mixing Values to the CompositeMaterials.
	* @param[in] CompositeBuffer - The Composite Constituents to be added as composite
	* @return returns new PropertyID of the new Composite in the CompositeMaterials.
	*/
	Lib3MF_uint32 CCompositeMaterials::AddComposite(const CInputVector<sCompositeConstituent> & CompositeBuffer)
	{
		Lib3MF_uint64 nCompositeSize = CompositeBuffer.size();
		Lib3MF_uint32 resultPropertyID = 0;
		CheckError(lib3mf_compositematerials_addcomposite(m_pHandle, nCompositeSize, CompositeBuffer.data(), &resultPropertyID));
		
		return resultPropertyID;
	}
	
	/**
	* CCompositeMaterials::RemoveComposite - Removes a Composite-Maxing Ratio from the CompositeMaterials.
	* @param[in] nPropertyID - PropertyID of the  Composite-Mixing Values in the CompositeMaterials to be removed.
	*/
	void CCompositeMaterials::RemoveComposite(const Lib3MF_uint32 nPropertyID)
	{
		CheckError(lib3mf_compositematerials_removecomposite(m_pHandle, nPropertyID));
	}
	
	/**
	* CCompositeMaterials::GetComposite - Obtains a Composite-Maxing Ratio of this CompositeMaterials.
	* @param[in] nPropertyID - the PropertyID of the Composite-Maxing Ratio in the CompositeMaterials.
	* @param[out] CompositeBuffer - The Composite-Mixing Values with the given PropertyID
	*/
	void CCompositeMaterials::GetComposite(const Lib3MF_uint32 nPropertyID, std::vector<sCompositeConstituent> & CompositeBuffer)
	{
		Lib3MF_uint64 elementsNeededComposite = 0;
		Lib3MF_uint64 elementsWrittenComposite = 0;
		CheckError(lib3mf_compositematerials_getcomposite(m_pHandle, nPropertyID, 0, &elementsNeededComposite, nullptr));
		CompositeBuffer.resize((size_t) elementsNeededComposite);
		CheckError(lib3mf_compositematerials_getcomposite(m_pHandle, nPropertyID, elementsNeededComposite, &elementsWrittenComposite, CompositeBuffer.data()));
	}
	
	/**
	 * Method definitions for class CMultiPropertyGroup
	 */
	
	/**
	* CMultiPropertyGroup::GetCount - Retrieves the count of MultiProperty-s in the MultiPropertyGroup.
	* @return returns the count of MultiProperty-s
	*/
	Lib3MF_uint32 CMultiPropertyGroup::GetCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_multipropertygroup_getcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CMultiPropertyGroup::GetAllPropertyIDs - returns all the PropertyIDs of all MultiProperty-s in this MultiPropertyGroup
	* @param[out] PropertyIDsBuffer - PropertyID of the MultiProperty-s in the MultiPropertyGroup.
	*/
	void CMultiPropertyGroup::GetAllPropertyIDs(std::vector<Lib3MF_uint32> & PropertyIDsBuffer)
	{
		Lib3MF_uint64 elementsNeededPropertyIDs = 0;
		Lib3MF_uint64 elementsWrittenPropertyIDs = 0;
		CheckError(lib3mf_multipropertygroup_getallpropertyids(m_pHandle, 0, &elementsNeededPropertyIDs, nullptr));
		PropertyIDsBuffer.resize((size_t) elementsNeededPropertyIDs);
		CheckError(lib3mf_multipropertygroup_getallpropertyids(m_pHandle, elementsNeededPropertyIDs, &elementsWrittenPropertyIDs, PropertyIDsBuffer.data()));
	}
	
	/**
	* CMultiPropertyGroup::AddMultiProperty - Adds a new MultiProperty to the MultiPropertyGroup.
	* @param[in] PropertyIDsBuffer - The PropertyIDs of the new MultiProperty.
	* @return returns the PropertyID of the new MultiProperty in the MultiPropertyGroup.
	*/
	Lib3MF_uint32 CMultiPropertyGroup::AddMultiProperty(const CInputVector<Lib3MF_uint32> & PropertyIDsBuffer)
	{
		Lib3MF_uint64 nPropertyIDsSize = PropertyIDsBuffer.size();
		Lib3MF_uint32 resultPropertyID = 0;
		CheckError(lib3mf_multipropertygroup_addmultiproperty(m_pHandle, nPropertyIDsSize, PropertyIDsBuffer.data(), &resultPropertyID));
		
		return resultPropertyID;
	}
	
	/**
	* CMultiPropertyGroup::SetMultiProperty - Sets the PropertyIDs of a MultiProperty.
	* @param[in] nPropertyID - the PropertyID of the MultiProperty to be changed.
	* @param[in] PropertyIDsBuffer - The new PropertyIDs of the MultiProperty
	*/
	void CMultiPropertyGroup::SetMultiProperty(const Lib3MF_uint32 nPropertyID, const CInputVector<Lib3MF_uint32> & PropertyIDsBuffer)
	{
		Lib3MF_uint64 nPropertyIDsSize = PropertyIDsBuffer.size();
		CheckError(lib3mf_multipropertygroup_setmultiproperty(m_pHandle, nPropertyID, nPropertyIDsSize, PropertyIDsBuffer.data()));
	}
	
	/**
	* CMultiPropertyGroup::GetMultiProperty - Obtains the PropertyIDs of a MultiProperty.
	* @param[in] nPropertyID - the PropertyID of the MultiProperty to be queried.
	* @param[out] PropertyIDsBuffer - The PropertyIDs of the MultiProperty
	*/
	void CMultiPropertyGroup::GetMultiProperty(const Lib3MF_uint32 nPropertyID, std::vector<Lib3MF_uint32> & PropertyIDsBuffer)
	{
		Lib3MF_uint64 elementsNeededPropertyIDs = 0;
		Lib3MF_uint64 elementsWrittenPropertyIDs = 0;
		CheckError(lib3mf_multipropertygroup_getmultiproperty(m_pHandle, nPropertyID, 0, &elementsNeededPropertyIDs, nullptr));
		PropertyIDsBuffer.resize((size_t) elementsNeededPropertyIDs);
		CheckError(lib3mf_multipropertygroup_getmultiproperty(m_pHandle, nPropertyID, elementsNeededPropertyIDs, &elementsWrittenPropertyIDs, PropertyIDsBuffer.data()));
	}
	
	/**
	* CMultiPropertyGroup::RemoveMultiProperty - Removes a MultiProperty from this MultiPropertyGroup.
	* @param[in] nPropertyID - the PropertyID of the MultiProperty to be removed.
	*/
	void CMultiPropertyGroup::RemoveMultiProperty(const Lib3MF_uint32 nPropertyID)
	{
		CheckError(lib3mf_multipropertygroup_removemultiproperty(m_pHandle, nPropertyID));
	}
	
	/**
	* CMultiPropertyGroup::GetLayerCount - Retrieves the number of layers of this MultiPropertyGroup.
	* @return returns the number of layers
	*/
	Lib3MF_uint32 CMultiPropertyGroup::GetLayerCount()
	{
		Lib3MF_uint32 resultCount = 0;
		CheckError(lib3mf_multipropertygroup_getlayercount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CMultiPropertyGroup::AddLayer - Adds a MultiPropertyLayer to this MultiPropertyGroup.
	* @param[in] TheLayer - The MultiPropertyLayer to add to this MultiPropertyGroup
	* @return returns the index of this MultiPropertyLayer
	*/
	Lib3MF_uint32 CMultiPropertyGroup::AddLayer(const sMultiPropertyLayer & TheLayer)
	{
		Lib3MF_uint32 resultLayerIndex = 0;
		CheckError(lib3mf_multipropertygroup_addlayer(m_pHandle, &TheLayer, &resultLayerIndex));
		
		return resultLayerIndex;
	}
	
	/**
	* CMultiPropertyGroup::GetLayer - Obtains a MultiPropertyLayer of this MultiPropertyGroup.
	* @param[in] nLayerIndex - The Index of the MultiPropertyLayer queried
	* @return The MultiPropertyLayer with index LayerIndex within MultiPropertyGroup
	*/
	sMultiPropertyLayer CMultiPropertyGroup::GetLayer(const Lib3MF_uint32 nLayerIndex)
	{
		sMultiPropertyLayer resultTheLayer;
		CheckError(lib3mf_multipropertygroup_getlayer(m_pHandle, nLayerIndex, &resultTheLayer));
		
		return resultTheLayer;
	}
	
	/**
	* CMultiPropertyGroup::RemoveLayer - Removes a MultiPropertyLayer from this MultiPropertyGroup.
	* @param[in] nLayerIndex - The Index of the MultiPropertyLayer to be removed
	*/
	void CMultiPropertyGroup::RemoveLayer(const Lib3MF_uint32 nLayerIndex)
	{
		CheckError(lib3mf_multipropertygroup_removelayer(m_pHandle, nLayerIndex));
	}
	
	/**
	 * Method definitions for class CImage3D
	 */
	
	/**
	* CImage3D::GetName - returns the name of this Image3D
	* @return the name of this Image3D
	*/
	std::string CImage3D::GetName()
	{
		Lib3MF_uint32 bytesNeededName = 0;
		Lib3MF_uint32 bytesWrittenName = 0;
		CheckError(lib3mf_image3d_getname(m_pHandle, 0, &bytesNeededName, nullptr));
		std::vector<char> bufferName(bytesNeededName);
		CheckError(lib3mf_image3d_getname(m_pHandle, bytesNeededName, &bytesWrittenName, &bufferName[0]));
		
		return std::string(&bufferName[0]);
	}
	
	/**
	* CImage3D::SetName - sets a new name of this Image3D
	* @param[in] sName - the new name of this Image3D
	*/
	void CImage3D::SetName(const std::string & sName)
	{
		CheckError(lib3mf_image3d_setname(m_pHandle, sName.c_str()));
	}
	
	/**
	* CImage3D::IsImageStack - Retrieves, if this Image3D is a ImageStack
	* @return returns, whether the Image3D is an ImageStack
	*/
	bool CImage3D::IsImageStack()
	{
		bool resultIsImageStack = 0;
		CheckError(lib3mf_image3d_isimagestack(m_pHandle, &resultIsImageStack));
		
		return resultIsImageStack;
	}
	
	/**
	 * Method definitions for class CImageStack
	 */
	
	/**
	* CImageStack::GetRowCount - Retrieves the number of rows in each image of this image3d
	* @return number of rows
	*/
	Lib3MF_uint32 CImageStack::GetRowCount()
	{
		Lib3MF_uint32 resultRowCount = 0;
		CheckError(lib3mf_imagestack_getrowcount(m_pHandle, &resultRowCount));
		
		return resultRowCount;
	}
	
	/**
	* CImageStack::SetRowCount - Sets the number of rows in each image of this image3d
	* @param[in] nRowCount - number of rows
	*/
	void CImageStack::SetRowCount(const Lib3MF_uint32 nRowCount)
	{
		CheckError(lib3mf_imagestack_setrowcount(m_pHandle, nRowCount));
	}
	
	/**
	* CImageStack::GetColumnCount - Retrieves the number of columns in each image of this image3d
	* @return number of columns
	*/
	Lib3MF_uint32 CImageStack::GetColumnCount()
	{
		Lib3MF_uint32 resultColumnCount = 0;
		CheckError(lib3mf_imagestack_getcolumncount(m_pHandle, &resultColumnCount));
		
		return resultColumnCount;
	}
	
	/**
	* CImageStack::SetColumnCount - Sets the number of columns in each image of this image3d
	* @param[in] nColumnCount - number of columns
	*/
	void CImageStack::SetColumnCount(const Lib3MF_uint32 nColumnCount)
	{
		CheckError(lib3mf_imagestack_setcolumncount(m_pHandle, nColumnCount));
	}
	
	/**
	* CImageStack::GetSheetCount - Retrieves the number of images in the stack.
	* @return number of images
	*/
	Lib3MF_uint32 CImageStack::GetSheetCount()
	{
		Lib3MF_uint32 resultSheetCount = 0;
		CheckError(lib3mf_imagestack_getsheetcount(m_pHandle, &resultSheetCount));
		
		return resultSheetCount;
	}
	
	/**
	* CImageStack::GetSheet - Retrieves a sheet of the stack. Raises an error if sheet is not set.
	* @param[in] nIndex - index of the image (0-based)
	* @return attachment containing the image
	*/
	PAttachment CImageStack::GetSheet(const Lib3MF_uint32 nIndex)
	{
		Lib3MFHandle hSheet = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_imagestack_getsheet(m_pHandle, nIndex, &hSheet));
		
		if (!hSheet) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CAttachment>(dynamic_cast<CAttachment*>(m_pWrapper->polymorphicFactory(hSheet)));
	}
	
	/**
	* CImageStack::SetSheet - Sets a sheet to an existing attachment.
	* @param[in] nIndex - index of the image (0-based)
	* @param[in] pSheet - attachment containing the image
	*/
	void CImageStack::SetSheet(const Lib3MF_uint32 nIndex, classParam<CAttachment> pSheet)
	{
		Lib3MFHandle hSheet = pSheet.GetHandle();
		CheckError(lib3mf_imagestack_setsheet(m_pHandle, nIndex, hSheet));
	}
	
	/**
	* CImageStack::CreateEmptySheet - Creates a new sheet attachment with empty data.
	* @param[in] nIndex - index of the image (0-based)
	* @param[in] sPath - path of part in the package
	* @return attachment containing the image
	*/
	PAttachment CImageStack::CreateEmptySheet(const Lib3MF_uint32 nIndex, const std::string & sPath)
	{
		Lib3MFHandle hSheet = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_imagestack_createemptysheet(m_pHandle, nIndex, sPath.c_str(), &hSheet));
		
		if (!hSheet) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CAttachment>(dynamic_cast<CAttachment*>(m_pWrapper->polymorphicFactory(hSheet)));
	}
	
	/**
	* CImageStack::CreateSheetFromBuffer - Creates a new sheet attachment from a memory buffer.
	* @param[in] nIndex - index of the image (0-based)
	* @param[in] sPath - path of part in the package
	* @param[in] DataBuffer - binary image data
	* @return attachment containing the image
	*/
	PAttachment CImageStack::CreateSheetFromBuffer(const Lib3MF_uint32 nIndex, const std::string & sPath, const CInputVector<Lib3MF_uint8> & DataBuffer)
	{
		Lib3MF_uint64 nDataSize = DataBuffer.size();
		Lib3MFHandle hSheet = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_imagestack_createsheetfrombuffer(m_pHandle, nIndex, sPath.c_str(), nDataSize, DataBuffer.data(), &hSheet));
		
		if (!hSheet) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CAttachment>(dynamic_cast<CAttachment*>(m_pWrapper->polymorphicFactory(hSheet)));
	}
	
	/**
	* CImageStack::CreateSheetFromFile - Creates a new sheet attachment from a file on disk.
	* @param[in] nIndex - index of the image (0-based)
	* @param[in] sPath - path of part in the package
	* @param[in] sFileName - file name to read from
	* @return attachment containing the image
	*/
	PAttachment CImageStack::CreateSheetFromFile(const Lib3MF_uint32 nIndex, const std::string & sPath, const std::string & sFileName)
	{
		Lib3MFHandle hSheet = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_imagestack_createsheetfromfile(m_pHandle, nIndex, sPath.c_str(), sFileName.c_str(), &hSheet));
		
		if (!hSheet) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CAttachment>(dynamic_cast<CAttachment*>(m_pWrapper->polymorphicFactory(hSheet)));
	}
	
	/**
	 * Method definitions for class CAttachment
	 */
	
	/**
	* CAttachment::GetPath - Retrieves an attachment's package path. This function will be removed in a later release.
	* @return returns the attachment's package path string
	*/
	std::string CAttachment::GetPath()
	{
		Lib3MF_uint32 bytesNeededPath = 0;
		Lib3MF_uint32 bytesWrittenPath = 0;
		CheckError(lib3mf_attachment_getpath(m_pHandle, 0, &bytesNeededPath, nullptr));
		std::vector<char> bufferPath(bytesNeededPath);
		CheckError(lib3mf_attachment_getpath(m_pHandle, bytesNeededPath, &bytesWrittenPath, &bufferPath[0]));
		
		return std::string(&bufferPath[0]);
	}
	
	/**
	* CAttachment::SetPath - Sets an attachment's package path. This function will be removed in a later release.
	* @param[in] sPath - new path of the attachment.
	*/
	void CAttachment::SetPath(const std::string & sPath)
	{
		CheckError(lib3mf_attachment_setpath(m_pHandle, sPath.c_str()));
	}
	
	/**
	* CAttachment::PackagePart - Returns the PackagePart that is this attachment.
	* @return The PackagePart of this attachment.
	*/
	PPackagePart CAttachment::PackagePart()
	{
		Lib3MFHandle hPackagePart = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_attachment_packagepart(m_pHandle, &hPackagePart));
		
		if (!hPackagePart) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CPackagePart>(dynamic_cast<CPackagePart*>(m_pWrapper->polymorphicFactory(hPackagePart)));
	}
	
	/**
	* CAttachment::GetRelationShipType - Retrieves an attachment's relationship type
	* @return returns the attachment's package relationship type string
	*/
	std::string CAttachment::GetRelationShipType()
	{
		Lib3MF_uint32 bytesNeededPath = 0;
		Lib3MF_uint32 bytesWrittenPath = 0;
		CheckError(lib3mf_attachment_getrelationshiptype(m_pHandle, 0, &bytesNeededPath, nullptr));
		std::vector<char> bufferPath(bytesNeededPath);
		CheckError(lib3mf_attachment_getrelationshiptype(m_pHandle, bytesNeededPath, &bytesWrittenPath, &bufferPath[0]));
		
		return std::string(&bufferPath[0]);
	}
	
	/**
	* CAttachment::SetRelationShipType - Sets an attachment's relationship type.
	* @param[in] sPath - new relationship type string.
	*/
	void CAttachment::SetRelationShipType(const std::string & sPath)
	{
		CheckError(lib3mf_attachment_setrelationshiptype(m_pHandle, sPath.c_str()));
	}
	
	/**
	* CAttachment::WriteToFile - Writes out the attachment as file.
	* @param[in] sFileName - file to write into.
	*/
	void CAttachment::WriteToFile(const std::string & sFileName)
	{
		CheckError(lib3mf_attachment_writetofile(m_pHandle, sFileName.c_str()));
	}
	
	/**
	* CAttachment::ReadFromFile - Reads an attachment from a file. The path of this file is only read when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer methods.
	* @param[in] sFileName - file to read from.
	*/
	void CAttachment::ReadFromFile(const std::string & sFileName)
	{
		CheckError(lib3mf_attachment_readfromfile(m_pHandle, sFileName.c_str()));
	}
	
	/**
	* CAttachment::ReadFromCallback - Reads an attachment from the data provided by a callback function. This callback function is only invoked when this attachment is being written as part of the 3MF package, or via the WriteToFile or WriteToBuffer methods.
	* @param[in] pTheReadCallback - Callback to call for reading a data chunk
	* @param[in] nStreamSize - number of bytes the callback returns
	* @param[in] pTheSeekCallback - Callback to call for seeking in the stream.
	* @param[in] pUserData - Userdata that is passed to the callback function
	*/
	void CAttachment::ReadFromCallback(const ReadCallback pTheReadCallback, const Lib3MF_uint64 nStreamSize, const SeekCallback pTheSeekCallback, const Lib3MF_pvoid pUserData)
	{
		CheckError(lib3mf_attachment_readfromcallback(m_pHandle, pTheReadCallback, nStreamSize, pTheSeekCallback, pUserData));
	}
	
	/**
	* CAttachment::GetStreamSize - Retrieves the size of the attachment stream
	* @return the stream size
	*/
	Lib3MF_uint64 CAttachment::GetStreamSize()
	{
		Lib3MF_uint64 resultStreamSize = 0;
		CheckError(lib3mf_attachment_getstreamsize(m_pHandle, &resultStreamSize));
		
		return resultStreamSize;
	}
	
	/**
	* CAttachment::WriteToBuffer - Writes out the attachment into a buffer
	* @param[out] BufferBuffer - Buffer to write into
	*/
	void CAttachment::WriteToBuffer(std::vector<Lib3MF_uint8> & BufferBuffer)
	{
		Lib3MF_uint64 elementsNeededBuffer = 0;
		Lib3MF_uint64 elementsWrittenBuffer = 0;
		CheckError(lib3mf_attachment_writetobuffer(m_pHandle, 0, &elementsNeededBuffer, nullptr));
		BufferBuffer.resize((size_t) elementsNeededBuffer);
		CheckError(lib3mf_attachment_writetobuffer(m_pHandle, elementsNeededBuffer, &elementsWrittenBuffer, BufferBuffer.data()));
	}
	
	/**
	* CAttachment::ReadFromBuffer - Reads an attachment from a memory buffer. This buffer is immediately read (in contrast to the ReadFromCallback and ReadFromFile-methods).
	* @param[in] BufferBuffer - Buffer to read from
	*/
	void CAttachment::ReadFromBuffer(const CInputVector<Lib3MF_uint8> & BufferBuffer)
	{
		Lib3MF_uint64 nBufferSize = BufferBuffer.size();
		CheckError(lib3mf_attachment_readfrombuffer(m_pHandle, nBufferSize, BufferBuffer.data()));
	}
	
	/**
	 * Method definitions for class CTexture2D
	 */
	
	/**
	* CTexture2D::GetAttachment - Retrieves the attachment located at the path of the texture.
	* @return attachment that holds the texture's image information.
	*/
	PAttachment CTexture2D::GetAttachment()
	{
		Lib3MFHandle hAttachment = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_texture2d_getattachment(m_pHandle, &hAttachment));
		
		if (!hAttachment) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CAttachment>(dynamic_cast<CAttachment*>(m_pWrapper->polymorphicFactory(hAttachment)));
	}
	
	/**
	* CTexture2D::SetAttachment - Sets the texture's package path to the path of the attachment.
	* @param[in] pAttachment - attachment that holds the texture's image information.
	*/
	void CTexture2D::SetAttachment(classParam<CAttachment> pAttachment)
	{
		Lib3MFHandle hAttachment = pAttachment.GetHandle();
		CheckError(lib3mf_texture2d_setattachment(m_pHandle, hAttachment));
	}
	
	/**
	* CTexture2D::GetContentType - Retrieves a texture's content type.
	* @return returns content type enum.
	*/
	eTextureType CTexture2D::GetContentType()
	{
		eTextureType resultContentType = (eTextureType) 0;
		CheckError(lib3mf_texture2d_getcontenttype(m_pHandle, &resultContentType));
		
		return resultContentType;
	}
	
	/**
	* CTexture2D::SetContentType - Retrieves a texture's content type.
	* @param[in] eContentType - new Content Type
	*/
	void CTexture2D::SetContentType(const eTextureType eContentType)
	{
		CheckError(lib3mf_texture2d_setcontenttype(m_pHandle, eContentType));
	}
	
	/**
	* CTexture2D::GetTileStyleUV - Retrieves a texture's tilestyle type.
	* @param[out] eTileStyleU - returns tilestyle type enum.
	* @param[out] eTileStyleV - returns tilestyle type enum.
	*/
	void CTexture2D::GetTileStyleUV(eTextureTileStyle & eTileStyleU, eTextureTileStyle & eTileStyleV)
	{
		CheckError(lib3mf_texture2d_gettilestyleuv(m_pHandle, &eTileStyleU, &eTileStyleV));
	}
	
	/**
	* CTexture2D::SetTileStyleUV - Sets a texture's tilestyle type.
	* @param[in] eTileStyleU - new tilestyle type enum.
	* @param[in] eTileStyleV - new tilestyle type enum.
	*/
	void CTexture2D::SetTileStyleUV(const eTextureTileStyle eTileStyleU, const eTextureTileStyle eTileStyleV)
	{
		CheckError(lib3mf_texture2d_settilestyleuv(m_pHandle, eTileStyleU, eTileStyleV));
	}
	
	/**
	* CTexture2D::GetFilter - Retrieves a texture's filter type.
	* @return returns filter type enum.
	*/
	eTextureFilter CTexture2D::GetFilter()
	{
		eTextureFilter resultFilter = (eTextureFilter) 0;
		CheckError(lib3mf_texture2d_getfilter(m_pHandle, &resultFilter));
		
		return resultFilter;
	}
	
	/**
	* CTexture2D::SetFilter - Sets a texture's filter type.
	* @param[in] eFilter - sets new filter type enum.
	*/
	void CTexture2D::SetFilter(const eTextureFilter eFilter)
	{
		CheckError(lib3mf_texture2d_setfilter(m_pHandle, eFilter));
	}
	
	/**
	 * Method definitions for class CImplicitPort
	 */
	
	/**
	* CImplicitPort::GetIdentifier - Retrieves the identifier of the port
	* @return the identifier
	*/
	std::string CImplicitPort::GetIdentifier()
	{
		Lib3MF_uint32 bytesNeededIdentifier = 0;
		Lib3MF_uint32 bytesWrittenIdentifier = 0;
		CheckError(lib3mf_implicitport_getidentifier(m_pHandle, 0, &bytesNeededIdentifier, nullptr));
		std::vector<char> bufferIdentifier(bytesNeededIdentifier);
		CheckError(lib3mf_implicitport_getidentifier(m_pHandle, bytesNeededIdentifier, &bytesWrittenIdentifier, &bufferIdentifier[0]));
		
		return std::string(&bufferIdentifier[0]);
	}
	
	/**
	* CImplicitPort::SetIdentifier - Sets the identifier of the port
	* @param[in] sIdentifier - the identifier
	*/
	void CImplicitPort::SetIdentifier(const std::string & sIdentifier)
	{
		CheckError(lib3mf_implicitport_setidentifier(m_pHandle, sIdentifier.c_str()));
	}
	
	/**
	* CImplicitPort::GetDisplayName - Retrieves the display name of the port
	* @return the display name
	*/
	std::string CImplicitPort::GetDisplayName()
	{
		Lib3MF_uint32 bytesNeededDisplayName = 0;
		Lib3MF_uint32 bytesWrittenDisplayName = 0;
		CheckError(lib3mf_implicitport_getdisplayname(m_pHandle, 0, &bytesNeededDisplayName, nullptr));
		std::vector<char> bufferDisplayName(bytesNeededDisplayName);
		CheckError(lib3mf_implicitport_getdisplayname(m_pHandle, bytesNeededDisplayName, &bytesWrittenDisplayName, &bufferDisplayName[0]));
		
		return std::string(&bufferDisplayName[0]);
	}
	
	/**
	* CImplicitPort::SetDisplayName - Sets the display name of the port
	* @param[in] sDisplayName - the display name
	*/
	void CImplicitPort::SetDisplayName(const std::string & sDisplayName)
	{
		CheckError(lib3mf_implicitport_setdisplayname(m_pHandle, sDisplayName.c_str()));
	}
	
	/**
	* CImplicitPort::SetType - Sets the type of the port
	* @param[in] eImplicitPortType - the type
	*/
	void CImplicitPort::SetType(const eImplicitPortType eImplicitPortType)
	{
		CheckError(lib3mf_implicitport_settype(m_pHandle, eImplicitPortType));
	}
	
	/**
	* CImplicitPort::GetType - Retrieves the type of the port
	* @return the type
	*/
	eImplicitPortType CImplicitPort::GetType()
	{
		eImplicitPortType resultImplicitPortType = (eImplicitPortType) 0;
		CheckError(lib3mf_implicitport_gettype(m_pHandle, &resultImplicitPortType));
		
		return resultImplicitPortType;
	}
	
	/**
	* CImplicitPort::GetReference - Retrieves the reference of the port, only used for input ports
	* @return the reference
	*/
	std::string CImplicitPort::GetReference()
	{
		Lib3MF_uint32 bytesNeededReference = 0;
		Lib3MF_uint32 bytesWrittenReference = 0;
		CheckError(lib3mf_implicitport_getreference(m_pHandle, 0, &bytesNeededReference, nullptr));
		std::vector<char> bufferReference(bytesNeededReference);
		CheckError(lib3mf_implicitport_getreference(m_pHandle, bytesNeededReference, &bytesWrittenReference, &bufferReference[0]));
		
		return std::string(&bufferReference[0]);
	}
	
	/**
	* CImplicitPort::SetReference - Sets the reference of the port, only used for input ports
	* @param[in] sReference - the reference
	*/
	void CImplicitPort::SetReference(const std::string & sReference)
	{
		CheckError(lib3mf_implicitport_setreference(m_pHandle, sReference.c_str()));
	}
	
	/**
	 * Method definitions for class CIterator
	 */
	
	/**
	* CIterator::MoveNext - Iterates to the next item in the list.
	* @return Iterates to the next item in the list.
	*/
	bool CIterator::MoveNext()
	{
		bool resultHasNext = 0;
		CheckError(lib3mf_iterator_movenext(m_pHandle, &resultHasNext));
		
		return resultHasNext;
	}
	
	/**
	* CIterator::MovePrevious - Iterates to the previous item in the list.
	* @return Iterates to the previous item in the list.
	*/
	bool CIterator::MovePrevious()
	{
		bool resultHasPrevious = 0;
		CheckError(lib3mf_iterator_moveprevious(m_pHandle, &resultHasPrevious));
		
		return resultHasPrevious;
	}
	
	/**
	* CIterator::Count - Returns the number of items the iterator captures.
	* @return returns the number of items the iterator captures.
	*/
	Lib3MF_uint64 CIterator::Count()
	{
		Lib3MF_uint64 resultCount = 0;
		CheckError(lib3mf_iterator_count(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	 * Method definitions for class CImplicitPortIterator
	 */
	
	/**
	* CImplicitPortIterator::GetCurrent - Returns the current element
	* @return The current element
	*/
	PImplicitPort CImplicitPortIterator::GetCurrent()
	{
		Lib3MFHandle hPort = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitportiterator_getcurrent(m_pHandle, &hPort));
		
		if (!hPort) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hPort)));
	}
	
	/**
	 * Method definitions for class CImplicitNode
	 */
	
	/**
	* CImplicitNode::GetIdentifier - Retrieves the identifier of the node
	* @return the identifier
	*/
	std::string CImplicitNode::GetIdentifier()
	{
		Lib3MF_uint32 bytesNeededIdentifier = 0;
		Lib3MF_uint32 bytesWrittenIdentifier = 0;
		CheckError(lib3mf_implicitnode_getidentifier(m_pHandle, 0, &bytesNeededIdentifier, nullptr));
		std::vector<char> bufferIdentifier(bytesNeededIdentifier);
		CheckError(lib3mf_implicitnode_getidentifier(m_pHandle, bytesNeededIdentifier, &bytesWrittenIdentifier, &bufferIdentifier[0]));
		
		return std::string(&bufferIdentifier[0]);
	}
	
	/**
	* CImplicitNode::SetIdentifier - Sets the identifier of the node
	* @param[in] sIdentifier - the identifier
	*/
	void CImplicitNode::SetIdentifier(const std::string & sIdentifier)
	{
		CheckError(lib3mf_implicitnode_setidentifier(m_pHandle, sIdentifier.c_str()));
	}
	
	/**
	* CImplicitNode::GetDisplayName - Retrieves the display name of the node
	* @return the display name
	*/
	std::string CImplicitNode::GetDisplayName()
	{
		Lib3MF_uint32 bytesNeededDisplayName = 0;
		Lib3MF_uint32 bytesWrittenDisplayName = 0;
		CheckError(lib3mf_implicitnode_getdisplayname(m_pHandle, 0, &bytesNeededDisplayName, nullptr));
		std::vector<char> bufferDisplayName(bytesNeededDisplayName);
		CheckError(lib3mf_implicitnode_getdisplayname(m_pHandle, bytesNeededDisplayName, &bytesWrittenDisplayName, &bufferDisplayName[0]));
		
		return std::string(&bufferDisplayName[0]);
	}
	
	/**
	* CImplicitNode::SetDisplayName - Sets the display name of the node
	* @param[in] sDisplayName - the display name
	*/
	void CImplicitNode::SetDisplayName(const std::string & sDisplayName)
	{
		CheckError(lib3mf_implicitnode_setdisplayname(m_pHandle, sDisplayName.c_str()));
	}
	
	/**
	* CImplicitNode::GetTag - Retrieves the tag of the node
	* @return the tag
	*/
	std::string CImplicitNode::GetTag()
	{
		Lib3MF_uint32 bytesNeededTag = 0;
		Lib3MF_uint32 bytesWrittenTag = 0;
		CheckError(lib3mf_implicitnode_gettag(m_pHandle, 0, &bytesNeededTag, nullptr));
		std::vector<char> bufferTag(bytesNeededTag);
		CheckError(lib3mf_implicitnode_gettag(m_pHandle, bytesNeededTag, &bytesWrittenTag, &bufferTag[0]));
		
		return std::string(&bufferTag[0]);
	}
	
	/**
	* CImplicitNode::SetTag - Sets the tag of the node
	* @param[in] sTag - the tag
	*/
	void CImplicitNode::SetTag(const std::string & sTag)
	{
		CheckError(lib3mf_implicitnode_settag(m_pHandle, sTag.c_str()));
	}
	
	/**
	* CImplicitNode::GetNodeType - Retrieves the type of the node
	* @return the type of the node
	*/
	eImplicitNodeType CImplicitNode::GetNodeType()
	{
		eImplicitNodeType resultType = (eImplicitNodeType) 0;
		CheckError(lib3mf_implicitnode_getnodetype(m_pHandle, &resultType));
		
		return resultType;
	}
	
	/**
	* CImplicitNode::AddInput - Add an input
	* @param[in] sIdentifier - the identifier of the input
	* @param[in] sDisplayName - the display name of the input
	* @return 
	*/
	PImplicitPort CImplicitNode::AddInput(const std::string & sIdentifier, const std::string & sDisplayName)
	{
		Lib3MFHandle hPort = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitnode_addinput(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), &hPort));
		
		if (!hPort) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hPort)));
	}
	
	/**
	* CImplicitNode::GetInputs - Retrieves the inputs
	* @return the iterator for the inputs
	*/
	PImplicitPortIterator CImplicitNode::GetInputs()
	{
		Lib3MFHandle hIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitnode_getinputs(m_pHandle, &hIterator));
		
		if (!hIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPortIterator>(dynamic_cast<CImplicitPortIterator*>(m_pWrapper->polymorphicFactory(hIterator)));
	}
	
	/**
	* CImplicitNode::AddOutput - Add an output
	* @param[in] sIdentifier - the identifier of the output
	* @param[in] sDisplayName - the display name of the output
	* @return 
	*/
	PImplicitPort CImplicitNode::AddOutput(const std::string & sIdentifier, const std::string & sDisplayName)
	{
		Lib3MFHandle hPort = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitnode_addoutput(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), &hPort));
		
		if (!hPort) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hPort)));
	}
	
	/**
	* CImplicitNode::GetOutputs - Retrieves the outputs
	* @return the iterator the outputs
	*/
	PImplicitPortIterator CImplicitNode::GetOutputs()
	{
		Lib3MFHandle hIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitnode_getoutputs(m_pHandle, &hIterator));
		
		if (!hIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPortIterator>(dynamic_cast<CImplicitPortIterator*>(m_pWrapper->polymorphicFactory(hIterator)));
	}
	
	/**
	* CImplicitNode::FindInput - Retrieves an input
	* @param[in] sIdentifier - the identifier of the input
	* @return the input port
	*/
	PImplicitPort CImplicitNode::FindInput(const std::string & sIdentifier)
	{
		Lib3MFHandle hInput = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitnode_findinput(m_pHandle, sIdentifier.c_str(), &hInput));
		
		if (hInput) {
			return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hInput)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CImplicitNode::FindOutput - Retrieves an output
	* @param[in] sIdentifier - the identifier of the output
	* @return the output port
	*/
	PImplicitPort CImplicitNode::FindOutput(const std::string & sIdentifier)
	{
		Lib3MFHandle hOutput = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitnode_findoutput(m_pHandle, sIdentifier.c_str(), &hOutput));
		
		if (hOutput) {
			return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hOutput)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CImplicitNode::AreTypesValid - Checks if the types of the input and output ports are valid for the node type
	* @return true, if the types are valid
	*/
	bool CImplicitNode::AreTypesValid()
	{
		bool resultValid = 0;
		CheckError(lib3mf_implicitnode_aretypesvalid(m_pHandle, &resultValid));
		
		return resultValid;
	}
	
	/**
	 * Method definitions for class COneInputNode
	 */
	
	/**
	* COneInputNode::GetInputA - Retrieves the input
	* @return the input
	*/
	PImplicitPort COneInputNode::GetInputA()
	{
		Lib3MFHandle hInput = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_oneinputnode_getinputa(m_pHandle, &hInput));
		
		if (!hInput) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hInput)));
	}
	
	/**
	* COneInputNode::GetOutputResult - Retrieves the output
	* @return the output
	*/
	PImplicitPort COneInputNode::GetOutputResult()
	{
		Lib3MFHandle hResult = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_oneinputnode_getoutputresult(m_pHandle, &hResult));
		
		if (!hResult) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hResult)));
	}
	
	/**
	 * Method definitions for class CSinNode
	 */
	
	/**
	 * Method definitions for class CCosNode
	 */
	
	/**
	 * Method definitions for class CTanNode
	 */
	
	/**
	 * Method definitions for class CArcSinNode
	 */
	
	/**
	 * Method definitions for class CArcCosNode
	 */
	
	/**
	 * Method definitions for class CArcTanNode
	 */
	
	/**
	 * Method definitions for class CSinhNode
	 */
	
	/**
	 * Method definitions for class CCoshNode
	 */
	
	/**
	 * Method definitions for class CTanhNode
	 */
	
	/**
	 * Method definitions for class CRoundNode
	 */
	
	/**
	 * Method definitions for class CCeilNode
	 */
	
	/**
	 * Method definitions for class CFloorNode
	 */
	
	/**
	 * Method definitions for class CSignNode
	 */
	
	/**
	 * Method definitions for class CFractNode
	 */
	
	/**
	 * Method definitions for class CAbsNode
	 */
	
	/**
	 * Method definitions for class CExpNode
	 */
	
	/**
	 * Method definitions for class CLogNode
	 */
	
	/**
	 * Method definitions for class CLog2Node
	 */
	
	/**
	 * Method definitions for class CLog10Node
	 */
	
	/**
	 * Method definitions for class CLengthNode
	 */
	
	/**
	 * Method definitions for class CTransposeNode
	 */
	
	/**
	 * Method definitions for class CInverseNode
	 */
	
	/**
	 * Method definitions for class CSqrtNode
	 */
	
	/**
	 * Method definitions for class CResourceIdNode
	 */
	
	/**
	* CResourceIdNode::SetResource - Sets the Resource that the resourceid attribute of the node will point to
	* @param[in] pResource - the resource
	*/
	void CResourceIdNode::SetResource(classParam<CResource> pResource)
	{
		Lib3MFHandle hResource = pResource.GetHandle();
		CheckError(lib3mf_resourceidnode_setresource(m_pHandle, hResource));
	}
	
	/**
	* CResourceIdNode::GetResource - Retrieves the resource of the node
	* @return the resource
	*/
	PResource CResourceIdNode::GetResource()
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_resourceidnode_getresource(m_pHandle, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CResource>(dynamic_cast<CResource*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	* CResourceIdNode::GetOutputValue - Retrieves the output
	* @return the output
	*/
	PImplicitPort CResourceIdNode::GetOutputValue()
	{
		Lib3MFHandle hValue = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_resourceidnode_getoutputvalue(m_pHandle, &hValue));
		
		if (!hValue) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hValue)));
	}
	
	/**
	 * Method definitions for class CTwoInputNode
	 */
	
	/**
	* CTwoInputNode::GetInputB - Retrieves the second input
	* @return the second input
	*/
	PImplicitPort CTwoInputNode::GetInputB()
	{
		Lib3MFHandle hB = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_twoinputnode_getinputb(m_pHandle, &hB));
		
		if (!hB) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hB)));
	}
	
	/**
	 * Method definitions for class CAdditionNode
	 */
	
	/**
	 * Method definitions for class CSubtractionNode
	 */
	
	/**
	 * Method definitions for class CMultiplicationNode
	 */
	
	/**
	 * Method definitions for class CDivisionNode
	 */
	
	/**
	 * Method definitions for class CDotNode
	 */
	
	/**
	 * Method definitions for class CCrossNode
	 */
	
	/**
	 * Method definitions for class CArcTan2Node
	 */
	
	/**
	 * Method definitions for class CMatVecMultiplicationNode
	 */
	
	/**
	 * Method definitions for class CMinNode
	 */
	
	/**
	 * Method definitions for class CMaxNode
	 */
	
	/**
	 * Method definitions for class CFmodNode
	 */
	
	/**
	 * Method definitions for class CModNode
	 */
	
	/**
	 * Method definitions for class CPowNode
	 */
	
	/**
	 * Method definitions for class CSelectNode
	 */
	
	/**
	* CSelectNode::GetInputB - Retrieves the second input
	* @return the second input
	*/
	PImplicitPort CSelectNode::GetInputB()
	{
		Lib3MFHandle hB = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_selectnode_getinputb(m_pHandle, &hB));
		
		if (!hB) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hB)));
	}
	
	/**
	* CSelectNode::GetInputC - Retrieves the third input
	* @return the third input
	*/
	PImplicitPort CSelectNode::GetInputC()
	{
		Lib3MFHandle hC = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_selectnode_getinputc(m_pHandle, &hC));
		
		if (!hC) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hC)));
	}
	
	/**
	* CSelectNode::GetInputD - Retrieves the fourth input
	* @return the fourth input
	*/
	PImplicitPort CSelectNode::GetInputD()
	{
		Lib3MFHandle hD = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_selectnode_getinputd(m_pHandle, &hD));
		
		if (!hD) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hD)));
	}
	
	/**
	 * Method definitions for class CClampNode
	 */
	
	/**
	* CClampNode::GetInputMin - Retrieves the input for the lower limit
	* @return the input for the lower limit
	*/
	PImplicitPort CClampNode::GetInputMin()
	{
		Lib3MFHandle hMin = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_clampnode_getinputmin(m_pHandle, &hMin));
		
		if (!hMin) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hMin)));
	}
	
	/**
	* CClampNode::GetInputMax - Retrieves the input for the upper limit
	* @return the input for the upper limit
	*/
	PImplicitPort CClampNode::GetInputMax()
	{
		Lib3MFHandle hMax = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_clampnode_getinputmax(m_pHandle, &hMax));
		
		if (!hMax) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hMax)));
	}
	
	/**
	 * Method definitions for class CComposeVectorNode
	 */
	
	/**
	* CComposeVectorNode::GetInputX - Retrieves the input for the x component
	* @return the input for the x component
	*/
	PImplicitPort CComposeVectorNode::GetInputX()
	{
		Lib3MFHandle hX = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composevectornode_getinputx(m_pHandle, &hX));
		
		if (!hX) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hX)));
	}
	
	/**
	* CComposeVectorNode::GetInputY - Retrieves the input for the y component
	* @return the input for the y component
	*/
	PImplicitPort CComposeVectorNode::GetInputY()
	{
		Lib3MFHandle hY = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composevectornode_getinputy(m_pHandle, &hY));
		
		if (!hY) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hY)));
	}
	
	/**
	* CComposeVectorNode::GetInputZ - Retrieves the input for the z component
	* @return the input for the z component
	*/
	PImplicitPort CComposeVectorNode::GetInputZ()
	{
		Lib3MFHandle hZ = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composevectornode_getinputz(m_pHandle, &hZ));
		
		if (!hZ) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hZ)));
	}
	
	/**
	* CComposeVectorNode::GetOutputResult - Retrieves the output
	* @return the output
	*/
	PImplicitPort CComposeVectorNode::GetOutputResult()
	{
		Lib3MFHandle hResult = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composevectornode_getoutputresult(m_pHandle, &hResult));
		
		if (!hResult) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hResult)));
	}
	
	/**
	 * Method definitions for class CVectorFromScalarNode
	 */
	
	/**
	 * Method definitions for class CDecomposeVectorNode
	 */
	
	/**
	* CDecomposeVectorNode::GetInputA - Retrieves the input
	* @return the input port for the vector to decompose
	*/
	PImplicitPort CDecomposeVectorNode::GetInputA()
	{
		Lib3MFHandle hA = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_decomposevectornode_getinputa(m_pHandle, &hA));
		
		if (!hA) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hA)));
	}
	
	/**
	* CDecomposeVectorNode::GetOutputX - Retrieves the output for the x component
	* @return the output for the x component
	*/
	PImplicitPort CDecomposeVectorNode::GetOutputX()
	{
		Lib3MFHandle hX = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_decomposevectornode_getoutputx(m_pHandle, &hX));
		
		if (!hX) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hX)));
	}
	
	/**
	* CDecomposeVectorNode::GetOutputY - Retrieves the output for the y component
	* @return the output for the y component
	*/
	PImplicitPort CDecomposeVectorNode::GetOutputY()
	{
		Lib3MFHandle hY = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_decomposevectornode_getoutputy(m_pHandle, &hY));
		
		if (!hY) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hY)));
	}
	
	/**
	* CDecomposeVectorNode::GetOutputZ - Retrieves the output for the z component
	* @return the output for the z component
	*/
	PImplicitPort CDecomposeVectorNode::GetOutputZ()
	{
		Lib3MFHandle hZ = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_decomposevectornode_getoutputz(m_pHandle, &hZ));
		
		if (!hZ) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hZ)));
	}
	
	/**
	 * Method definitions for class CComposeMatrixNode
	 */
	
	/**
	* CComposeMatrixNode::GetInputM00 - Retrieves the input for the element 0 0
	* @return the input for the m00 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM00()
	{
		Lib3MFHandle hM00 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm00(m_pHandle, &hM00));
		
		if (!hM00) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM00)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM01 - Retrieves the input for the element 0 1
	* @return the input for the m01 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM01()
	{
		Lib3MFHandle hM01 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm01(m_pHandle, &hM01));
		
		if (!hM01) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM01)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM02 - Retrieves the input for the element 0 2
	* @return the input for the m02 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM02()
	{
		Lib3MFHandle hM02 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm02(m_pHandle, &hM02));
		
		if (!hM02) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM02)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM03 - Retrieves the input for the element 0 3
	* @return the input for the m03 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM03()
	{
		Lib3MFHandle hM03 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm03(m_pHandle, &hM03));
		
		if (!hM03) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM03)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM10 - Retrieves the input for the element 1 0
	* @return the input for the m10 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM10()
	{
		Lib3MFHandle hM10 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm10(m_pHandle, &hM10));
		
		if (!hM10) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM10)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM11 - Retrieves the input for the element 1 1
	* @return the input for the m11 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM11()
	{
		Lib3MFHandle hM11 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm11(m_pHandle, &hM11));
		
		if (!hM11) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM11)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM12 - Retrieves the input for the element 1 2
	* @return the input for the m12 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM12()
	{
		Lib3MFHandle hM12 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm12(m_pHandle, &hM12));
		
		if (!hM12) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM12)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM13 - Retrieves the input for the element 1 3
	* @return the input for the m13 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM13()
	{
		Lib3MFHandle hM13 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm13(m_pHandle, &hM13));
		
		if (!hM13) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM13)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM20 - Retrieves the input for the element 2 0
	* @return the input for the m20 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM20()
	{
		Lib3MFHandle hM20 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm20(m_pHandle, &hM20));
		
		if (!hM20) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM20)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM21 - Retrieves the input for the element 2 1
	* @return 
	*/
	PImplicitPort CComposeMatrixNode::GetInputM21()
	{
		Lib3MFHandle hM21 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm21(m_pHandle, &hM21));
		
		if (!hM21) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM21)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM22 - Retrieves the input for the element 2 2
	* @return the input for the m22 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM22()
	{
		Lib3MFHandle hM22 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm22(m_pHandle, &hM22));
		
		if (!hM22) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM22)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM23 - Retrieves the input for the element 2 3
	* @return the input for the m23 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM23()
	{
		Lib3MFHandle hM23 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm23(m_pHandle, &hM23));
		
		if (!hM23) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM23)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM30 - Retrieves the input for the element 3 0
	* @return the input for the m30 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM30()
	{
		Lib3MFHandle hM30 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm30(m_pHandle, &hM30));
		
		if (!hM30) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM30)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM31 - Retrieves the input for the element 3 1
	* @return the input for the m31 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM31()
	{
		Lib3MFHandle hM31 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm31(m_pHandle, &hM31));
		
		if (!hM31) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM31)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM32 - Retrieves the input for the element 3 2
	* @return the input for the m32 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM32()
	{
		Lib3MFHandle hM32 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm32(m_pHandle, &hM32));
		
		if (!hM32) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM32)));
	}
	
	/**
	* CComposeMatrixNode::GetInputM33 - Retrieves the input for the element 3 3
	* @return the input for the m33 element
	*/
	PImplicitPort CComposeMatrixNode::GetInputM33()
	{
		Lib3MFHandle hM33 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getinputm33(m_pHandle, &hM33));
		
		if (!hM33) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hM33)));
	}
	
	/**
	* CComposeMatrixNode::GetOutputResult - Retrieves the output
	* @return the output
	*/
	PImplicitPort CComposeMatrixNode::GetOutputResult()
	{
		Lib3MFHandle hResult = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_composematrixnode_getoutputresult(m_pHandle, &hResult));
		
		if (!hResult) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hResult)));
	}
	
	/**
	 * Method definitions for class CMatrixFromRowsNode
	 */
	
	/**
	* CMatrixFromRowsNode::GetInputA - Retrieves the input for the first row
	* @return the input for the first row
	*/
	PImplicitPort CMatrixFromRowsNode::GetInputA()
	{
		Lib3MFHandle hRow0 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_matrixfromrowsnode_getinputa(m_pHandle, &hRow0));
		
		if (!hRow0) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hRow0)));
	}
	
	/**
	* CMatrixFromRowsNode::GetInputB - Retrieves the input for the second row
	* @return the input for the second row
	*/
	PImplicitPort CMatrixFromRowsNode::GetInputB()
	{
		Lib3MFHandle hRow1 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_matrixfromrowsnode_getinputb(m_pHandle, &hRow1));
		
		if (!hRow1) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hRow1)));
	}
	
	/**
	* CMatrixFromRowsNode::GetInputC - Retrieves the input for the third row
	* @return the input for the third row
	*/
	PImplicitPort CMatrixFromRowsNode::GetInputC()
	{
		Lib3MFHandle hRow2 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_matrixfromrowsnode_getinputc(m_pHandle, &hRow2));
		
		if (!hRow2) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hRow2)));
	}
	
	/**
	* CMatrixFromRowsNode::GetInputD - Retrieves the input for the fourth row
	* @return the input for the fourth row
	*/
	PImplicitPort CMatrixFromRowsNode::GetInputD()
	{
		Lib3MFHandle hRow3 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_matrixfromrowsnode_getinputd(m_pHandle, &hRow3));
		
		if (!hRow3) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hRow3)));
	}
	
	/**
	* CMatrixFromRowsNode::GetOutputResult - Retrieves the output
	* @return the output
	*/
	PImplicitPort CMatrixFromRowsNode::GetOutputResult()
	{
		Lib3MFHandle hResult = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_matrixfromrowsnode_getoutputresult(m_pHandle, &hResult));
		
		if (!hResult) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hResult)));
	}
	
	/**
	 * Method definitions for class CMatrixFromColumnsNode
	 */
	
	/**
	* CMatrixFromColumnsNode::GetInputA - Retrieves the input for the first column
	* @return the input for the first column
	*/
	PImplicitPort CMatrixFromColumnsNode::GetInputA()
	{
		Lib3MFHandle hColumn0 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_matrixfromcolumnsnode_getinputa(m_pHandle, &hColumn0));
		
		if (!hColumn0) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hColumn0)));
	}
	
	/**
	* CMatrixFromColumnsNode::GetInputB - Retrieves the input for the second column
	* @return the input for the second column
	*/
	PImplicitPort CMatrixFromColumnsNode::GetInputB()
	{
		Lib3MFHandle hColumn1 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_matrixfromcolumnsnode_getinputb(m_pHandle, &hColumn1));
		
		if (!hColumn1) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hColumn1)));
	}
	
	/**
	* CMatrixFromColumnsNode::GetInputC - Retrieves the input for the third column
	* @return the input for the third column
	*/
	PImplicitPort CMatrixFromColumnsNode::GetInputC()
	{
		Lib3MFHandle hColumn2 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_matrixfromcolumnsnode_getinputc(m_pHandle, &hColumn2));
		
		if (!hColumn2) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hColumn2)));
	}
	
	/**
	* CMatrixFromColumnsNode::GetInputD - Retrieves the input for the fourth column
	* @return the input for the fourth column
	*/
	PImplicitPort CMatrixFromColumnsNode::GetInputD()
	{
		Lib3MFHandle hColumn3 = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_matrixfromcolumnsnode_getinputd(m_pHandle, &hColumn3));
		
		if (!hColumn3) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hColumn3)));
	}
	
	/**
	* CMatrixFromColumnsNode::GetOutputResult - Retrieves the output
	* @return the output
	*/
	PImplicitPort CMatrixFromColumnsNode::GetOutputResult()
	{
		Lib3MFHandle hResult = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_matrixfromcolumnsnode_getoutputresult(m_pHandle, &hResult));
		
		if (!hResult) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hResult)));
	}
	
	/**
	 * Method definitions for class CConstantNode
	 */
	
	/**
	* CConstantNode::SetConstant - Sets the constant value of the node
	* @param[in] dValue - the value
	*/
	void CConstantNode::SetConstant(const Lib3MF_double dValue)
	{
		CheckError(lib3mf_constantnode_setconstant(m_pHandle, dValue));
	}
	
	/**
	* CConstantNode::GetConstant - Retrieves the constant value of the node
	* @return the value
	*/
	Lib3MF_double CConstantNode::GetConstant()
	{
		Lib3MF_double resultValue = 0;
		CheckError(lib3mf_constantnode_getconstant(m_pHandle, &resultValue));
		
		return resultValue;
	}
	
	/**
	* CConstantNode::GetOutputValue - Retrieves the output
	* @return the output
	*/
	PImplicitPort CConstantNode::GetOutputValue()
	{
		Lib3MFHandle hValue = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_constantnode_getoutputvalue(m_pHandle, &hValue));
		
		if (!hValue) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hValue)));
	}
	
	/**
	 * Method definitions for class CConstVecNode
	 */
	
	/**
	* CConstVecNode::SetVector - Sets the vector value of the node
	* @param[in] Value - the value
	*/
	void CConstVecNode::SetVector(const sVector & Value)
	{
		CheckError(lib3mf_constvecnode_setvector(m_pHandle, &Value));
	}
	
	/**
	* CConstVecNode::GetVector - Retrieves the vector value of the node
	* @return the value
	*/
	sVector CConstVecNode::GetVector()
	{
		sVector resultValue;
		CheckError(lib3mf_constvecnode_getvector(m_pHandle, &resultValue));
		
		return resultValue;
	}
	
	/**
	* CConstVecNode::GetOutputVector - Retrieves the output
	* @return the output
	*/
	PImplicitPort CConstVecNode::GetOutputVector()
	{
		Lib3MFHandle hVector = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_constvecnode_getoutputvector(m_pHandle, &hVector));
		
		if (!hVector) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hVector)));
	}
	
	/**
	 * Method definitions for class CConstMatNode
	 */
	
	/**
	* CConstMatNode::SetMatrix - Sets the matrix value of the node
	* @param[in] Value - the value
	*/
	void CConstMatNode::SetMatrix(const sMatrix4x4 & Value)
	{
		CheckError(lib3mf_constmatnode_setmatrix(m_pHandle, &Value));
	}
	
	/**
	* CConstMatNode::GetMatrix - Retrieves the matrix value of the node
	* @return the matrix
	*/
	sMatrix4x4 CConstMatNode::GetMatrix()
	{
		sMatrix4x4 resultValue;
		CheckError(lib3mf_constmatnode_getmatrix(m_pHandle, &resultValue));
		
		return resultValue;
	}
	
	/**
	* CConstMatNode::GetOutputMatrix - Retrieves the output
	* @return the output
	*/
	PImplicitPort CConstMatNode::GetOutputMatrix()
	{
		Lib3MFHandle hMatrix = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_constmatnode_getoutputmatrix(m_pHandle, &hMatrix));
		
		if (!hMatrix) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hMatrix)));
	}
	
	/**
	 * Method definitions for class CMeshNode
	 */
	
	/**
	* CMeshNode::GetInputMesh - Retrieves the input for the model resource id of the mesh
	* @return the input port for the model resource id of the mesh
	*/
	PImplicitPort CMeshNode::GetInputMesh()
	{
		Lib3MFHandle hMesh = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_meshnode_getinputmesh(m_pHandle, &hMesh));
		
		if (!hMesh) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hMesh)));
	}
	
	/**
	* CMeshNode::GetInputPos - Retrieves the input for the position
	* @return the input port for the position
	*/
	PImplicitPort CMeshNode::GetInputPos()
	{
		Lib3MFHandle hPos = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_meshnode_getinputpos(m_pHandle, &hPos));
		
		if (!hPos) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hPos)));
	}
	
	/**
	* CMeshNode::GetOutputDistance - Retrieves the output
	* @return the output port for the signed distance to the mesh
	*/
	PImplicitPort CMeshNode::GetOutputDistance()
	{
		Lib3MFHandle hDistance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_meshnode_getoutputdistance(m_pHandle, &hDistance));
		
		if (!hDistance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hDistance)));
	}
	
	/**
	 * Method definitions for class CUnsignedMeshNode
	 */
	
	/**
	* CUnsignedMeshNode::GetInputMesh - Retrieves the input for the model resource id of the mesh
	* @return the input port for the model resource id of the mesh
	*/
	PImplicitPort CUnsignedMeshNode::GetInputMesh()
	{
		Lib3MFHandle hMesh = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_unsignedmeshnode_getinputmesh(m_pHandle, &hMesh));
		
		if (!hMesh) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hMesh)));
	}
	
	/**
	* CUnsignedMeshNode::GetInputPos - Retrieves the input for the position
	* @return the input port for the position
	*/
	PImplicitPort CUnsignedMeshNode::GetInputPos()
	{
		Lib3MFHandle hPos = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_unsignedmeshnode_getinputpos(m_pHandle, &hPos));
		
		if (!hPos) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hPos)));
	}
	
	/**
	* CUnsignedMeshNode::GetOutputDistance - Retrieves the output
	* @return the output port for the unsigned distance to the mesh
	*/
	PImplicitPort CUnsignedMeshNode::GetOutputDistance()
	{
		Lib3MFHandle hDistance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_unsignedmeshnode_getoutputdistance(m_pHandle, &hDistance));
		
		if (!hDistance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hDistance)));
	}
	
	/**
	 * Method definitions for class CBeamLatticeNode
	 */
	
	/**
	* CBeamLatticeNode::GetInputBeamLattice - Retrieves the input for the model resource id of the beam lattice
	* @return the input port for the model resource id of the beam lattice (mesh with beamlattice extension)
	*/
	PImplicitPort CBeamLatticeNode::GetInputBeamLattice()
	{
		Lib3MFHandle hBeamLattice = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_beamlatticenode_getinputbeamlattice(m_pHandle, &hBeamLattice));
		
		if (!hBeamLattice) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hBeamLattice)));
	}
	
	/**
	* CBeamLatticeNode::GetInputPos - Retrieves the input for the position
	* @return the input port for the position
	*/
	PImplicitPort CBeamLatticeNode::GetInputPos()
	{
		Lib3MFHandle hPos = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_beamlatticenode_getinputpos(m_pHandle, &hPos));
		
		if (!hPos) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hPos)));
	}
	
	/**
	* CBeamLatticeNode::GetOutputDistance - Retrieves the output
	* @return the output port for the signed distance to the beam lattice
	*/
	PImplicitPort CBeamLatticeNode::GetOutputDistance()
	{
		Lib3MFHandle hDistance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_beamlatticenode_getoutputdistance(m_pHandle, &hDistance));
		
		if (!hDistance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hDistance)));
	}
	
	/**
	* CBeamLatticeNode::SetAccurateRange - Sets the accurate range for distance computation
	* @param[in] dAccurateRange - the accurate range in model units
	*/
	void CBeamLatticeNode::SetAccurateRange(const Lib3MF_double dAccurateRange)
	{
		CheckError(lib3mf_beamlatticenode_setaccuraterange(m_pHandle, dAccurateRange));
	}
	
	/**
	* CBeamLatticeNode::GetAccurateRange - Retrieves the accurate range for distance computation
	* @return the accurate range in model units
	*/
	Lib3MF_double CBeamLatticeNode::GetAccurateRange()
	{
		Lib3MF_double resultAccurateRange = 0;
		CheckError(lib3mf_beamlatticenode_getaccuraterange(m_pHandle, &resultAccurateRange));
		
		return resultAccurateRange;
	}
	
	/**
	 * Method definitions for class CFunctionGradientNode
	 */
	
	/**
	* CFunctionGradientNode::GetInputFunctionID - Retrieves the input for the function id
	* @return the input port for the function
	*/
	PImplicitPort CFunctionGradientNode::GetInputFunctionID()
	{
		Lib3MFHandle hFunction = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_functiongradientnode_getinputfunctionid(m_pHandle, &hFunction));
		
		if (!hFunction) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hFunction)));
	}
	
	/**
	* CFunctionGradientNode::GetInputPos - Retrieves the input for the position
	* @return the input port for the position
	*/
	PImplicitPort CFunctionGradientNode::GetInputPos()
	{
		Lib3MFHandle hPos = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_functiongradientnode_getinputpos(m_pHandle, &hPos));
		
		if (!hPos) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hPos)));
	}
	
	/**
	* CFunctionGradientNode::GetInputStep - Retrieves the input for the finite difference step
	* @return the input port for the finite difference step
	*/
	PImplicitPort CFunctionGradientNode::GetInputStep()
	{
		Lib3MFHandle hStep = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_functiongradientnode_getinputstep(m_pHandle, &hStep));
		
		if (!hStep) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hStep)));
	}
	
	/**
	* CFunctionGradientNode::SetScalarOutputName - Sets the name of the referenced scalar output
	* @param[in] sScalarOutputName - the name of the scalar output of the referenced function
	*/
	void CFunctionGradientNode::SetScalarOutputName(const std::string & sScalarOutputName)
	{
		CheckError(lib3mf_functiongradientnode_setscalaroutputname(m_pHandle, sScalarOutputName.c_str()));
	}
	
	/**
	* CFunctionGradientNode::GetScalarOutputName - Retrieves the name of the referenced scalar output
	* @return the name of the scalar output of the referenced function
	*/
	std::string CFunctionGradientNode::GetScalarOutputName()
	{
		Lib3MF_uint32 bytesNeededScalarOutputName = 0;
		Lib3MF_uint32 bytesWrittenScalarOutputName = 0;
		CheckError(lib3mf_functiongradientnode_getscalaroutputname(m_pHandle, 0, &bytesNeededScalarOutputName, nullptr));
		std::vector<char> bufferScalarOutputName(bytesNeededScalarOutputName);
		CheckError(lib3mf_functiongradientnode_getscalaroutputname(m_pHandle, bytesNeededScalarOutputName, &bytesWrittenScalarOutputName, &bufferScalarOutputName[0]));
		
		return std::string(&bufferScalarOutputName[0]);
	}
	
	/**
	* CFunctionGradientNode::SetVectorInputName - Sets the name of the referenced vector input
	* @param[in] sVectorInputName - the name of the vector input (float3) of the referenced function
	*/
	void CFunctionGradientNode::SetVectorInputName(const std::string & sVectorInputName)
	{
		CheckError(lib3mf_functiongradientnode_setvectorinputname(m_pHandle, sVectorInputName.c_str()));
	}
	
	/**
	* CFunctionGradientNode::GetVectorInputName - Retrieves the name of the referenced vector input
	* @return the name of the vector input (float3) of the referenced function
	*/
	std::string CFunctionGradientNode::GetVectorInputName()
	{
		Lib3MF_uint32 bytesNeededVectorInputName = 0;
		Lib3MF_uint32 bytesWrittenVectorInputName = 0;
		CheckError(lib3mf_functiongradientnode_getvectorinputname(m_pHandle, 0, &bytesNeededVectorInputName, nullptr));
		std::vector<char> bufferVectorInputName(bytesNeededVectorInputName);
		CheckError(lib3mf_functiongradientnode_getvectorinputname(m_pHandle, bytesNeededVectorInputName, &bytesWrittenVectorInputName, &bufferVectorInputName[0]));
		
		return std::string(&bufferVectorInputName[0]);
	}
	
	/**
	* CFunctionGradientNode::GetOutputNormalizedGradient - Retrieves the normalized gradient output
	* @return the output port for the normalized gradient
	*/
	PImplicitPort CFunctionGradientNode::GetOutputNormalizedGradient()
	{
		Lib3MFHandle hNormalizedGradient = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_functiongradientnode_getoutputnormalizedgradient(m_pHandle, &hNormalizedGradient));
		
		if (!hNormalizedGradient) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hNormalizedGradient)));
	}
	
	/**
	* CFunctionGradientNode::GetOutputGradient - Retrieves the raw gradient output
	* @return the output port for the raw gradient
	*/
	PImplicitPort CFunctionGradientNode::GetOutputGradient()
	{
		Lib3MFHandle hGradient = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_functiongradientnode_getoutputgradient(m_pHandle, &hGradient));
		
		if (!hGradient) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hGradient)));
	}
	
	/**
	* CFunctionGradientNode::GetOutputMagnitude - Retrieves the gradient magnitude output
	* @return the output port for the gradient magnitude
	*/
	PImplicitPort CFunctionGradientNode::GetOutputMagnitude()
	{
		Lib3MFHandle hMagnitude = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_functiongradientnode_getoutputmagnitude(m_pHandle, &hMagnitude));
		
		if (!hMagnitude) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hMagnitude)));
	}
	
	/**
	 * Method definitions for class CNormalizeDistanceNode
	 */
	
	/**
	* CNormalizeDistanceNode::GetInputFunctionID - Retrieves the input for the function id
	* @return the input port for the function
	*/
	PImplicitPort CNormalizeDistanceNode::GetInputFunctionID()
	{
		Lib3MFHandle hFunction = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_normalizedistancenode_getinputfunctionid(m_pHandle, &hFunction));
		
		if (!hFunction) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hFunction)));
	}
	
	/**
	* CNormalizeDistanceNode::GetInputPos - Retrieves the input for the position
	* @return the input port for the position (vector)
	*/
	PImplicitPort CNormalizeDistanceNode::GetInputPos()
	{
		Lib3MFHandle hPos = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_normalizedistancenode_getinputpos(m_pHandle, &hPos));
		
		if (!hPos) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hPos)));
	}
	
	/**
	* CNormalizeDistanceNode::GetInputStep - Retrieves the input for the finite difference step
	* @return the input port for the finite difference step
	*/
	PImplicitPort CNormalizeDistanceNode::GetInputStep()
	{
		Lib3MFHandle hStep = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_normalizedistancenode_getinputstep(m_pHandle, &hStep));
		
		if (!hStep) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hStep)));
	}
	
	/**
	* CNormalizeDistanceNode::SetScalarOutputName - Sets the name of the referenced scalar output
	* @param[in] sScalarOutputName - the name of the scalar output of the referenced function
	*/
	void CNormalizeDistanceNode::SetScalarOutputName(const std::string & sScalarOutputName)
	{
		CheckError(lib3mf_normalizedistancenode_setscalaroutputname(m_pHandle, sScalarOutputName.c_str()));
	}
	
	/**
	* CNormalizeDistanceNode::GetScalarOutputName - Retrieves the name of the referenced scalar output
	* @return the name of the scalar output of the referenced function
	*/
	std::string CNormalizeDistanceNode::GetScalarOutputName()
	{
		Lib3MF_uint32 bytesNeededScalarOutputName = 0;
		Lib3MF_uint32 bytesWrittenScalarOutputName = 0;
		CheckError(lib3mf_normalizedistancenode_getscalaroutputname(m_pHandle, 0, &bytesNeededScalarOutputName, nullptr));
		std::vector<char> bufferScalarOutputName(bytesNeededScalarOutputName);
		CheckError(lib3mf_normalizedistancenode_getscalaroutputname(m_pHandle, bytesNeededScalarOutputName, &bytesWrittenScalarOutputName, &bufferScalarOutputName[0]));
		
		return std::string(&bufferScalarOutputName[0]);
	}
	
	/**
	* CNormalizeDistanceNode::SetVectorInputName - Sets the name of the referenced vector input
	* @param[in] sVectorInputName - the name of the vector input (float3) of the referenced function
	*/
	void CNormalizeDistanceNode::SetVectorInputName(const std::string & sVectorInputName)
	{
		CheckError(lib3mf_normalizedistancenode_setvectorinputname(m_pHandle, sVectorInputName.c_str()));
	}
	
	/**
	* CNormalizeDistanceNode::GetVectorInputName - Retrieves the name of the referenced vector input
	* @return the name of the vector input (float3) of the referenced function
	*/
	std::string CNormalizeDistanceNode::GetVectorInputName()
	{
		Lib3MF_uint32 bytesNeededVectorInputName = 0;
		Lib3MF_uint32 bytesWrittenVectorInputName = 0;
		CheckError(lib3mf_normalizedistancenode_getvectorinputname(m_pHandle, 0, &bytesNeededVectorInputName, nullptr));
		std::vector<char> bufferVectorInputName(bytesNeededVectorInputName);
		CheckError(lib3mf_normalizedistancenode_getvectorinputname(m_pHandle, bytesNeededVectorInputName, &bytesWrittenVectorInputName, &bufferVectorInputName[0]));
		
		return std::string(&bufferVectorInputName[0]);
	}
	
	/**
	* CNormalizeDistanceNode::GetOutputResult - Retrieves the normalized result output
	* @return the output port for the normalized distance
	*/
	PImplicitPort CNormalizeDistanceNode::GetOutputResult()
	{
		Lib3MFHandle hResult = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_normalizedistancenode_getoutputresult(m_pHandle, &hResult));
		
		if (!hResult) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hResult)));
	}
	
	/**
	 * Method definitions for class CFunctionCallNode
	 */
	
	/**
	* CFunctionCallNode::GetInputFunctionID - Retrieves the input for the function id
	* @return the input port for the function
	*/
	PImplicitPort CFunctionCallNode::GetInputFunctionID()
	{
		Lib3MFHandle hFunction = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_functioncallnode_getinputfunctionid(m_pHandle, &hFunction));
		
		if (!hFunction) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hFunction)));
	}
	
	/**
	 * Method definitions for class CNodeIterator
	 */
	
	/**
	* CNodeIterator::GetCurrent - Returns the current element
	* @return The current element
	*/
	PImplicitNode CNodeIterator::GetCurrent()
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_nodeiterator_getcurrent(m_pHandle, &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitNode>(dynamic_cast<CImplicitNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	 * Method definitions for class CFunction
	 */
	
	/**
	* CFunction::GetDisplayName - Retrieves the display name of the function
	* @return the display name
	*/
	std::string CFunction::GetDisplayName()
	{
		Lib3MF_uint32 bytesNeededDisplayName = 0;
		Lib3MF_uint32 bytesWrittenDisplayName = 0;
		CheckError(lib3mf_function_getdisplayname(m_pHandle, 0, &bytesNeededDisplayName, nullptr));
		std::vector<char> bufferDisplayName(bytesNeededDisplayName);
		CheckError(lib3mf_function_getdisplayname(m_pHandle, bytesNeededDisplayName, &bytesWrittenDisplayName, &bufferDisplayName[0]));
		
		return std::string(&bufferDisplayName[0]);
	}
	
	/**
	* CFunction::SetDisplayName - Sets the display name of the function
	* @param[in] sDisplayName - the display name
	*/
	void CFunction::SetDisplayName(const std::string & sDisplayName)
	{
		CheckError(lib3mf_function_setdisplayname(m_pHandle, sDisplayName.c_str()));
	}
	
	/**
	* CFunction::AddInput - Add an input
	* @param[in] sIdentifier - the identifier of the input
	* @param[in] sDisplayName - the display name of the input
	* @param[in] eType - the type of the input
	* @return The added input port
	*/
	PImplicitPort CFunction::AddInput(const std::string & sIdentifier, const std::string & sDisplayName, const eImplicitPortType eType)
	{
		Lib3MFHandle hPort = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_function_addinput(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), eType, &hPort));
		
		if (!hPort) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hPort)));
	}
	
	/**
	* CFunction::GetInputs - Retrieves the inputs
	* @return iterator for the list of inputs
	*/
	PImplicitPortIterator CFunction::GetInputs()
	{
		Lib3MFHandle hIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_function_getinputs(m_pHandle, &hIterator));
		
		if (!hIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPortIterator>(dynamic_cast<CImplicitPortIterator*>(m_pWrapper->polymorphicFactory(hIterator)));
	}
	
	/**
	* CFunction::RemoveInput - Removes an input
	* @param[in] pInput - The input to be removed
	*/
	void CFunction::RemoveInput(classParam<CImplicitPort> pInput)
	{
		Lib3MFHandle hInput = pInput.GetHandle();
		CheckError(lib3mf_function_removeinput(m_pHandle, hInput));
	}
	
	/**
	* CFunction::AddOutput - Add an output
	* @param[in] sIdentifier - the identifier of the output
	* @param[in] sDisplayName - the display name of the output
	* @param[in] eType - the type of the input
	* @return The added input port
	*/
	PImplicitPort CFunction::AddOutput(const std::string & sIdentifier, const std::string & sDisplayName, const eImplicitPortType eType)
	{
		Lib3MFHandle hPort = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_function_addoutput(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), eType, &hPort));
		
		if (!hPort) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hPort)));
	}
	
	/**
	* CFunction::GetOutputs - Retrieves the outputs
	* @return iterator for the outputs
	*/
	PImplicitPortIterator CFunction::GetOutputs()
	{
		Lib3MFHandle hIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_function_getoutputs(m_pHandle, &hIterator));
		
		if (!hIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPortIterator>(dynamic_cast<CImplicitPortIterator*>(m_pWrapper->polymorphicFactory(hIterator)));
	}
	
	/**
	* CFunction::RemoveOutput - Removes an output
	* @param[in] pOutput - The output to be removed
	*/
	void CFunction::RemoveOutput(classParam<CImplicitPort> pOutput)
	{
		Lib3MFHandle hOutput = pOutput.GetHandle();
		CheckError(lib3mf_function_removeoutput(m_pHandle, hOutput));
	}
	
	/**
	* CFunction::FindInput - Retrieves an input
	* @param[in] sIdentifier - the identifier of the input
	* @return the input port
	*/
	PImplicitPort CFunction::FindInput(const std::string & sIdentifier)
	{
		Lib3MFHandle hInput = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_function_findinput(m_pHandle, sIdentifier.c_str(), &hInput));
		
		if (!hInput) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hInput)));
	}
	
	/**
	* CFunction::FindOutput - Retrieves an output
	* @param[in] sIdentifier - the identifier of the output
	* @return the output port
	*/
	PImplicitPort CFunction::FindOutput(const std::string & sIdentifier)
	{
		Lib3MFHandle hOutput = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_function_findoutput(m_pHandle, sIdentifier.c_str(), &hOutput));
		
		if (!hOutput) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitPort>(dynamic_cast<CImplicitPort*>(m_pWrapper->polymorphicFactory(hOutput)));
	}
	
	/**
	 * Method definitions for class CImplicitFunction
	 */
	
	/**
	* CImplicitFunction::GetIdentifier - Retrieves the identifier of the function
	* @return the identifier
	*/
	std::string CImplicitFunction::GetIdentifier()
	{
		Lib3MF_uint32 bytesNeededIdentifier = 0;
		Lib3MF_uint32 bytesWrittenIdentifier = 0;
		CheckError(lib3mf_implicitfunction_getidentifier(m_pHandle, 0, &bytesNeededIdentifier, nullptr));
		std::vector<char> bufferIdentifier(bytesNeededIdentifier);
		CheckError(lib3mf_implicitfunction_getidentifier(m_pHandle, bytesNeededIdentifier, &bytesWrittenIdentifier, &bufferIdentifier[0]));
		
		return std::string(&bufferIdentifier[0]);
	}
	
	/**
	* CImplicitFunction::SetIdentifier - Sets the identifier of the function
	* @param[in] sIdentifier - the identifier
	*/
	void CImplicitFunction::SetIdentifier(const std::string & sIdentifier)
	{
		CheckError(lib3mf_implicitfunction_setidentifier(m_pHandle, sIdentifier.c_str()));
	}
	
	/**
	* CImplicitFunction::AddNode - Add a node
	* @param[in] eNodeType - the type of the node
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PImplicitNode CImplicitFunction::AddNode(const eImplicitNodeType eNodeType, const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addnode(m_pHandle, eNodeType, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitNode>(dynamic_cast<CImplicitNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddSinNode - Add a SinNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PSinNode CImplicitFunction::AddSinNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addsinnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSinNode>(dynamic_cast<CSinNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddCosNode - Add a CosNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PCosNode CImplicitFunction::AddCosNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addcosnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CCosNode>(dynamic_cast<CCosNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddTanNode - Add a TanNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PTanNode CImplicitFunction::AddTanNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addtannode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTanNode>(dynamic_cast<CTanNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddArcSinNode - Add a ArcSinNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PArcSinNode CImplicitFunction::AddArcSinNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addarcsinnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CArcSinNode>(dynamic_cast<CArcSinNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddArcCosNode - Add a ArcCosNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PArcCosNode CImplicitFunction::AddArcCosNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addarccosnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CArcCosNode>(dynamic_cast<CArcCosNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddArcTan2Node - Add a ArcTan2Node
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PArcTan2Node CImplicitFunction::AddArcTan2Node(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addarctan2node(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CArcTan2Node>(dynamic_cast<CArcTan2Node*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddSinhNode - Add a SinhNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PSinhNode CImplicitFunction::AddSinhNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addsinhnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSinhNode>(dynamic_cast<CSinhNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddCoshNode - Add a CoshNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PCoshNode CImplicitFunction::AddCoshNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addcoshnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CCoshNode>(dynamic_cast<CCoshNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddTanhNode - Add a TanhNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PTanhNode CImplicitFunction::AddTanhNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addtanhnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTanhNode>(dynamic_cast<CTanhNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddRoundNode - Add a RoundNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PRoundNode CImplicitFunction::AddRoundNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addroundnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CRoundNode>(dynamic_cast<CRoundNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddCeilNode - Add a CeilNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PCeilNode CImplicitFunction::AddCeilNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addceilnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CCeilNode>(dynamic_cast<CCeilNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddFloorNode - Add a FloorNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PFloorNode CImplicitFunction::AddFloorNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addfloornode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CFloorNode>(dynamic_cast<CFloorNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddSignNode - Add a SignNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PSignNode CImplicitFunction::AddSignNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addsignnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSignNode>(dynamic_cast<CSignNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddFractNode - Add a FractNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PFractNode CImplicitFunction::AddFractNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addfractnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CFractNode>(dynamic_cast<CFractNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddAbsNode - Add a AbsNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PAbsNode CImplicitFunction::AddAbsNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addabsnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CAbsNode>(dynamic_cast<CAbsNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddExpNode - Add a ExpNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PExpNode CImplicitFunction::AddExpNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addexpnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CExpNode>(dynamic_cast<CExpNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddLogNode - Add a LogNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PLogNode CImplicitFunction::AddLogNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addlognode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CLogNode>(dynamic_cast<CLogNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddLog2Node - Add a Log2Node
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PLog2Node CImplicitFunction::AddLog2Node(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addlog2node(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CLog2Node>(dynamic_cast<CLog2Node*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddLog10Node - Add a Log10Node
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PLog10Node CImplicitFunction::AddLog10Node(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addlog10node(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CLog10Node>(dynamic_cast<CLog10Node*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddLengthNode - Add a LengthNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PLengthNode CImplicitFunction::AddLengthNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addlengthnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CLengthNode>(dynamic_cast<CLengthNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddTransposeNode - Add a TransposeNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PTransposeNode CImplicitFunction::AddTransposeNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addtransposenode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTransposeNode>(dynamic_cast<CTransposeNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddInverseNode - Add a InverseNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PInverseNode CImplicitFunction::AddInverseNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addinversenode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CInverseNode>(dynamic_cast<CInverseNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddSqrtNode - Add a SqrtNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PSqrtNode CImplicitFunction::AddSqrtNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addsqrtnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSqrtNode>(dynamic_cast<CSqrtNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddResourceIdNode - Add a ResourceIdNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PResourceIdNode CImplicitFunction::AddResourceIdNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addresourceidnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CResourceIdNode>(dynamic_cast<CResourceIdNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddAdditionNode - Add an AdditionNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PAdditionNode CImplicitFunction::AddAdditionNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addadditionnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CAdditionNode>(dynamic_cast<CAdditionNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddSubtractionNode - Add a SubtractionNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PSubtractionNode CImplicitFunction::AddSubtractionNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addsubtractionnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSubtractionNode>(dynamic_cast<CSubtractionNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddMultiplicationNode - Add a MultiplicationNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PMultiplicationNode CImplicitFunction::AddMultiplicationNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addmultiplicationnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMultiplicationNode>(dynamic_cast<CMultiplicationNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddDivisionNode - Add a DivisionNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PDivisionNode CImplicitFunction::AddDivisionNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_adddivisionnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CDivisionNode>(dynamic_cast<CDivisionNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddDotNode - Add a DotNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PDotNode CImplicitFunction::AddDotNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_adddotnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CDotNode>(dynamic_cast<CDotNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddCrossNode - Add a CrossNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PCrossNode CImplicitFunction::AddCrossNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addcrossnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CCrossNode>(dynamic_cast<CCrossNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddMatVecMultiplicationNode - Add a MatVecMultiplicationNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PMatVecMultiplicationNode CImplicitFunction::AddMatVecMultiplicationNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addmatvecmultiplicationnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMatVecMultiplicationNode>(dynamic_cast<CMatVecMultiplicationNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddMinNode - Add a MinNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PMinNode CImplicitFunction::AddMinNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addminnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMinNode>(dynamic_cast<CMinNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddMaxNode - Add a MaxNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PMaxNode CImplicitFunction::AddMaxNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addmaxnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMaxNode>(dynamic_cast<CMaxNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddFmodNode - Add a FmodNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PFmodNode CImplicitFunction::AddFmodNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addfmodnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CFmodNode>(dynamic_cast<CFmodNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddPowNode - Add a PowNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PPowNode CImplicitFunction::AddPowNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addpownode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CPowNode>(dynamic_cast<CPowNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddSelectNode - Add a SelectNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PSelectNode CImplicitFunction::AddSelectNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addselectnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSelectNode>(dynamic_cast<CSelectNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddClampNode - Add a ClampNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] eConfiguration - the configuration of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PClampNode CImplicitFunction::AddClampNode(const std::string & sIdentifier, const eImplicitNodeConfiguration eConfiguration, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addclampnode(m_pHandle, sIdentifier.c_str(), eConfiguration, sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CClampNode>(dynamic_cast<CClampNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddComposeVectorNode - Add a ComposeVectorNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PComposeVectorNode CImplicitFunction::AddComposeVectorNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addcomposevectornode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CComposeVectorNode>(dynamic_cast<CComposeVectorNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddVectorFromScalarNode - Add a VectorFromScalar
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PVectorFromScalarNode CImplicitFunction::AddVectorFromScalarNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addvectorfromscalarnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CVectorFromScalarNode>(dynamic_cast<CVectorFromScalarNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddDecomposeVectorNode - Add a DecomposeVectorNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PDecomposeVectorNode CImplicitFunction::AddDecomposeVectorNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_adddecomposevectornode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CDecomposeVectorNode>(dynamic_cast<CDecomposeVectorNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddComposeMatrixNode - Add a ComposeMatrixNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PComposeMatrixNode CImplicitFunction::AddComposeMatrixNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addcomposematrixnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CComposeMatrixNode>(dynamic_cast<CComposeMatrixNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddMatrixFromRowsNode - Add a MatrixFromRowsNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PMatrixFromRowsNode CImplicitFunction::AddMatrixFromRowsNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addmatrixfromrowsnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMatrixFromRowsNode>(dynamic_cast<CMatrixFromRowsNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddMatrixFromColumnsNode - Add a MatrixFromColumnsNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PMatrixFromColumnsNode CImplicitFunction::AddMatrixFromColumnsNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addmatrixfromcolumnsnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMatrixFromColumnsNode>(dynamic_cast<CMatrixFromColumnsNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddConstantNode - Add a ConstantNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PConstantNode CImplicitFunction::AddConstantNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addconstantnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CConstantNode>(dynamic_cast<CConstantNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddConstVecNode - Add a ConstVecNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PConstVecNode CImplicitFunction::AddConstVecNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addconstvecnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CConstVecNode>(dynamic_cast<CConstVecNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddConstMatNode - Add a ConstMatNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PConstMatNode CImplicitFunction::AddConstMatNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addconstmatnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CConstMatNode>(dynamic_cast<CConstMatNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddMeshNode - Add a MeshNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PMeshNode CImplicitFunction::AddMeshNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addmeshnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMeshNode>(dynamic_cast<CMeshNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddUnsignedMeshNode - Add a UnsignedMeshNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PUnsignedMeshNode CImplicitFunction::AddUnsignedMeshNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addunsignedmeshnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CUnsignedMeshNode>(dynamic_cast<CUnsignedMeshNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddBeamLatticeNode - Add a BeamLatticeNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PBeamLatticeNode CImplicitFunction::AddBeamLatticeNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addbeamlatticenode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBeamLatticeNode>(dynamic_cast<CBeamLatticeNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddFunctionGradientNode - Add a FunctionGradientNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PFunctionGradientNode CImplicitFunction::AddFunctionGradientNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addfunctiongradientnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CFunctionGradientNode>(dynamic_cast<CFunctionGradientNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddNormalizeDistanceNode - Add a NormalizeDistanceNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PNormalizeDistanceNode CImplicitFunction::AddNormalizeDistanceNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addnormalizedistancenode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CNormalizeDistanceNode>(dynamic_cast<CNormalizeDistanceNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::AddFunctionCallNode - Add a FunctionCallNode
	* @param[in] sIdentifier - the identifier of the node
	* @param[in] sDisplayName - the display name of the node
	* @param[in] sTag - the tag of the node
	* @return the added node
	*/
	PFunctionCallNode CImplicitFunction::AddFunctionCallNode(const std::string & sIdentifier, const std::string & sDisplayName, const std::string & sTag)
	{
		Lib3MFHandle hNode = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_addfunctioncallnode(m_pHandle, sIdentifier.c_str(), sDisplayName.c_str(), sTag.c_str(), &hNode));
		
		if (!hNode) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CFunctionCallNode>(dynamic_cast<CFunctionCallNode*>(m_pWrapper->polymorphicFactory(hNode)));
	}
	
	/**
	* CImplicitFunction::GetNodes - Retrieves the nodes
	* @return iterator for the list of nodes
	*/
	PNodeIterator CImplicitFunction::GetNodes()
	{
		Lib3MFHandle hIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_implicitfunction_getnodes(m_pHandle, &hIterator));
		
		if (!hIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CNodeIterator>(dynamic_cast<CNodeIterator*>(m_pWrapper->polymorphicFactory(hIterator)));
	}
	
	/**
	* CImplicitFunction::RemoveNode - Removes a node
	* @param[in] pNode - The node to be removed
	*/
	void CImplicitFunction::RemoveNode(classParam<CImplicitNode> pNode)
	{
		Lib3MFHandle hNode = pNode.GetHandle();
		CheckError(lib3mf_implicitfunction_removenode(m_pHandle, hNode));
	}
	
	/**
	* CImplicitFunction::AddLink - Add a link
	* @param[in] pSource - the source port
	* @param[in] pTarget - the target port
	*/
	void CImplicitFunction::AddLink(classParam<CImplicitPort> pSource, classParam<CImplicitPort> pTarget)
	{
		Lib3MFHandle hSource = pSource.GetHandle();
		Lib3MFHandle hTarget = pTarget.GetHandle();
		CheckError(lib3mf_implicitfunction_addlink(m_pHandle, hSource, hTarget));
	}
	
	/**
	* CImplicitFunction::AddLinkByNames - Add a link
	* @param[in] sSource - name of the source port in the format nodename.portname
	* @param[in] sTarget - name of the target port in the format nodename.portname
	*/
	void CImplicitFunction::AddLinkByNames(const std::string & sSource, const std::string & sTarget)
	{
		CheckError(lib3mf_implicitfunction_addlinkbynames(m_pHandle, sSource.c_str(), sTarget.c_str()));
	}
	
	/**
	* CImplicitFunction::Clear - Clears the function
	*/
	void CImplicitFunction::Clear()
	{
		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
	 */
	
	/**
	* CFunctionFromImage3D::GetImage3D - Returns the selected 3D image.
	* @return image instance
	*/
	PImage3D CFunctionFromImage3D::GetImage3D()
	{
		Lib3MFHandle hImage3D = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_functionfromimage3d_getimage3d(m_pHandle, &hImage3D));
		
		if (!hImage3D) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImage3D>(dynamic_cast<CImage3D*>(m_pWrapper->polymorphicFactory(hImage3D)));
	}
	
	/**
	* CFunctionFromImage3D::SetImage3D - Sets the 3D image of the selector.
	* @param[in] pImage3D - image instance
	*/
	void CFunctionFromImage3D::SetImage3D(classParam<CImage3D> pImage3D)
	{
		Lib3MFHandle hImage3D = pImage3D.GetHandle();
		CheckError(lib3mf_functionfromimage3d_setimage3d(m_pHandle, hImage3D));
	}
	
	/**
	* CFunctionFromImage3D::SetFilter - Sets the texture filter of the selector.
	* @param[in] eFilter - texture filter
	*/
	void CFunctionFromImage3D::SetFilter(const eTextureFilter eFilter)
	{
		CheckError(lib3mf_functionfromimage3d_setfilter(m_pHandle, eFilter));
	}
	
	/**
	* CFunctionFromImage3D::GetFilter - Returns the texture filter of the selector.
	* @return texture filter
	*/
	eTextureFilter CFunctionFromImage3D::GetFilter()
	{
		eTextureFilter resultFilter = (eTextureFilter) 0;
		CheckError(lib3mf_functionfromimage3d_getfilter(m_pHandle, &resultFilter));
		
		return resultFilter;
	}
	
	/**
	* CFunctionFromImage3D::SetTileStyles - Sets the tile styles of the selector.
	* @param[in] eTileStyleU - tile style in U
	* @param[in] eTileStyleV - tile style in V
	* @param[in] eTileStyleW - tile style in W
	*/
	void CFunctionFromImage3D::SetTileStyles(const eTextureTileStyle eTileStyleU, const eTextureTileStyle eTileStyleV, const eTextureTileStyle eTileStyleW)
	{
		CheckError(lib3mf_functionfromimage3d_settilestyles(m_pHandle, eTileStyleU, eTileStyleV, eTileStyleW));
	}
	
	/**
	* CFunctionFromImage3D::GetTileStyles - Retrieves the tile styles of the selector.
	* @param[out] eTileStyleU - tile style in U
	* @param[out] eTileStyleV - tile style in V
	* @param[out] eTileStyleW - tile style in W
	*/
	void CFunctionFromImage3D::GetTileStyles(eTextureTileStyle & eTileStyleU, eTextureTileStyle & eTileStyleV, eTextureTileStyle & eTileStyleW)
	{
		CheckError(lib3mf_functionfromimage3d_gettilestyles(m_pHandle, &eTileStyleU, &eTileStyleV, &eTileStyleW));
	}
	
	/**
	* CFunctionFromImage3D::GetOffset - returns the offset value for the pixel values in the Image3D
	* @return the offset value for the pixel values in the Image3D
	*/
	Lib3MF_double CFunctionFromImage3D::GetOffset()
	{
		Lib3MF_double resultOffset = 0;
		CheckError(lib3mf_functionfromimage3d_getoffset(m_pHandle, &resultOffset));
		
		return resultOffset;
	}
	
	/**
	* CFunctionFromImage3D::SetOffset - Sets the offset value for the pixel values in the Image3D
	* @param[in] dOffset - the offset value for the pixel values in the Image3D
	*/
	void CFunctionFromImage3D::SetOffset(const Lib3MF_double dOffset)
	{
		CheckError(lib3mf_functionfromimage3d_setoffset(m_pHandle, dOffset));
	}
	
	/**
	* CFunctionFromImage3D::GetScale - returns the scale value for the pixel values in the Image3D
	* @return the scale value for the pixel values in the Image3D
	*/
	Lib3MF_double CFunctionFromImage3D::GetScale()
	{
		Lib3MF_double resultScale = 0;
		CheckError(lib3mf_functionfromimage3d_getscale(m_pHandle, &resultScale));
		
		return resultScale;
	}
	
	/**
	* CFunctionFromImage3D::SetScale - Sets the scale value for the pixel values in the Image3D
	* @param[in] dScale - the scale value for the pixel values in the Image3D
	*/
	void CFunctionFromImage3D::SetScale(const Lib3MF_double dScale)
	{
		CheckError(lib3mf_functionfromimage3d_setscale(m_pHandle, dScale));
	}
	
	/**
	 * Method definitions for class CBuildItem
	 */
	
	/**
	* CBuildItem::GetObjectResource - Retrieves the object resource associated to a build item
	* @return returns the associated resource instance
	*/
	PObject CBuildItem::GetObjectResource()
	{
		Lib3MFHandle hObjectResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_builditem_getobjectresource(m_pHandle, &hObjectResource));
		
		if (!hObjectResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CObject>(dynamic_cast<CObject*>(m_pWrapper->polymorphicFactory(hObjectResource)));
	}
	
	/**
	* CBuildItem::GetUUID - returns, whether a build item has a UUID and, if true, the build item's UUID
	* @param[out] bHasUUID - flag whether the build item has a UUID
	* @return the UUID as string of the form 'xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx'
	*/
	std::string CBuildItem::GetUUID(bool & bHasUUID)
	{
		Lib3MF_uint32 bytesNeededUUID = 0;
		Lib3MF_uint32 bytesWrittenUUID = 0;
		CheckError(lib3mf_builditem_getuuid(m_pHandle, &bHasUUID, 0, &bytesNeededUUID, nullptr));
		std::vector<char> bufferUUID(bytesNeededUUID);
		CheckError(lib3mf_builditem_getuuid(m_pHandle, &bHasUUID, bytesNeededUUID, &bytesWrittenUUID, &bufferUUID[0]));
		
		return std::string(&bufferUUID[0]);
	}
	
	/**
	* CBuildItem::SetUUID - sets the build item's UUID
	* @param[in] sUUID - the UUID as string of the form 'xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx'
	*/
	void CBuildItem::SetUUID(const std::string & sUUID)
	{
		CheckError(lib3mf_builditem_setuuid(m_pHandle, sUUID.c_str()));
	}
	
	/**
	* CBuildItem::GetObjectResourceID - Retrieves the object UniqueResourceID associated to a build item
	* @return returns the UniqueResourceID of the object
	*/
	Lib3MF_uint32 CBuildItem::GetObjectResourceID()
	{
		Lib3MF_uint32 resultUniqueResourceID = 0;
		CheckError(lib3mf_builditem_getobjectresourceid(m_pHandle, &resultUniqueResourceID));
		
		return resultUniqueResourceID;
	}
	
	/**
	* CBuildItem::HasObjectTransform - Checks, if a build item has a non-identity transformation matrix
	* @return returns true, if the transformation matrix is not the identity
	*/
	bool CBuildItem::HasObjectTransform()
	{
		bool resultHasTransform = 0;
		CheckError(lib3mf_builditem_hasobjecttransform(m_pHandle, &resultHasTransform));
		
		return resultHasTransform;
	}
	
	/**
	* CBuildItem::GetObjectTransform - Retrieves a build item's transformation matrix.
	* @return returns the transformation matrix
	*/
	sTransform CBuildItem::GetObjectTransform()
	{
		sTransform resultTransform;
		CheckError(lib3mf_builditem_getobjecttransform(m_pHandle, &resultTransform));
		
		return resultTransform;
	}
	
	/**
	* CBuildItem::SetObjectTransform - Sets a build item's transformation matrix.
	* @param[in] Transform - new transformation matrix
	*/
	void CBuildItem::SetObjectTransform(const sTransform & Transform)
	{
		CheckError(lib3mf_builditem_setobjecttransform(m_pHandle, &Transform));
	}
	
	/**
	* CBuildItem::GetPartNumber - Retrieves a build item's part number string
	* @return Returns a build item's part number string
	*/
	std::string CBuildItem::GetPartNumber()
	{
		Lib3MF_uint32 bytesNeededPartNumber = 0;
		Lib3MF_uint32 bytesWrittenPartNumber = 0;
		CheckError(lib3mf_builditem_getpartnumber(m_pHandle, 0, &bytesNeededPartNumber, nullptr));
		std::vector<char> bufferPartNumber(bytesNeededPartNumber);
		CheckError(lib3mf_builditem_getpartnumber(m_pHandle, bytesNeededPartNumber, &bytesWrittenPartNumber, &bufferPartNumber[0]));
		
		return std::string(&bufferPartNumber[0]);
	}
	
	/**
	* CBuildItem::SetPartNumber - Sets a build item's part number string
	* @param[in] sSetPartnumber - new part number string for referencing parts from the outside world
	*/
	void CBuildItem::SetPartNumber(const std::string & sSetPartnumber)
	{
		CheckError(lib3mf_builditem_setpartnumber(m_pHandle, sSetPartnumber.c_str()));
	}
	
	/**
	* CBuildItem::GetMetaDataGroup - Returns the metadatagroup of this build item
	* @return returns an Instance of the metadatagroup of this build item
	*/
	PMetaDataGroup CBuildItem::GetMetaDataGroup()
	{
		Lib3MFHandle hMetaDataGroup = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_builditem_getmetadatagroup(m_pHandle, &hMetaDataGroup));
		
		if (!hMetaDataGroup) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMetaDataGroup>(dynamic_cast<CMetaDataGroup*>(m_pWrapper->polymorphicFactory(hMetaDataGroup)));
	}
	
	/**
	* CBuildItem::GetOutbox - Returns the outbox of a build item
	* @return Outbox of this build item
	*/
	sBox CBuildItem::GetOutbox()
	{
		sBox resultOutbox;
		CheckError(lib3mf_builditem_getoutbox(m_pHandle, &resultOutbox));
		
		return resultOutbox;
	}
	
	/**
	 * Method definitions for class CBuildItemIterator
	 */
	
	/**
	* CBuildItemIterator::MoveNext - Iterates to the next build item in the list.
	* @return Iterates to the next build item in the list.
	*/
	bool CBuildItemIterator::MoveNext()
	{
		bool resultHasNext = 0;
		CheckError(lib3mf_builditemiterator_movenext(m_pHandle, &resultHasNext));
		
		return resultHasNext;
	}
	
	/**
	* CBuildItemIterator::MovePrevious - Iterates to the previous build item in the list.
	* @return Iterates to the previous build item in the list.
	*/
	bool CBuildItemIterator::MovePrevious()
	{
		bool resultHasPrevious = 0;
		CheckError(lib3mf_builditemiterator_moveprevious(m_pHandle, &resultHasPrevious));
		
		return resultHasPrevious;
	}
	
	/**
	* CBuildItemIterator::GetCurrent - Returns the build item the iterator points at.
	* @return returns the build item instance.
	*/
	PBuildItem CBuildItemIterator::GetCurrent()
	{
		Lib3MFHandle hBuildItem = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_builditemiterator_getcurrent(m_pHandle, &hBuildItem));
		
		if (!hBuildItem) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBuildItem>(dynamic_cast<CBuildItem*>(m_pWrapper->polymorphicFactory(hBuildItem)));
	}
	
	/**
	* CBuildItemIterator::Clone - Creates a new build item iterator with the same build item list.
	* @return returns the cloned Iterator instance
	*/
	PBuildItemIterator CBuildItemIterator::Clone()
	{
		Lib3MFHandle hOutBuildItemIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_builditemiterator_clone(m_pHandle, &hOutBuildItemIterator));
		
		if (!hOutBuildItemIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBuildItemIterator>(dynamic_cast<CBuildItemIterator*>(m_pWrapper->polymorphicFactory(hOutBuildItemIterator)));
	}
	
	/**
	* CBuildItemIterator::Count - Returns the number of build items the iterator captures.
	* @return returns the number of build items the iterator captures.
	*/
	Lib3MF_uint64 CBuildItemIterator::Count()
	{
		Lib3MF_uint64 resultCount = 0;
		CheckError(lib3mf_builditemiterator_count(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	 * Method definitions for class CSlice
	 */
	
	/**
	* CSlice::SetVertices - Set all vertices of a slice. All polygons will be cleared.
	* @param[in] VerticesBuffer - contains the positions.
	*/
	void CSlice::SetVertices(const CInputVector<sPosition2D> & VerticesBuffer)
	{
		Lib3MF_uint64 nVerticesSize = VerticesBuffer.size();
		CheckError(lib3mf_slice_setvertices(m_pHandle, nVerticesSize, VerticesBuffer.data()));
	}
	
	/**
	* CSlice::GetVertices - Get all vertices of a slice
	* @param[out] VerticesBuffer - contains the positions.
	*/
	void CSlice::GetVertices(std::vector<sPosition2D> & VerticesBuffer)
	{
		Lib3MF_uint64 elementsNeededVertices = 0;
		Lib3MF_uint64 elementsWrittenVertices = 0;
		CheckError(lib3mf_slice_getvertices(m_pHandle, 0, &elementsNeededVertices, nullptr));
		VerticesBuffer.resize((size_t) elementsNeededVertices);
		CheckError(lib3mf_slice_getvertices(m_pHandle, elementsNeededVertices, &elementsWrittenVertices, VerticesBuffer.data()));
	}
	
	/**
	* CSlice::GetVertexCount - Get the number of vertices in a slice
	* @return the number of vertices in the slice
	*/
	Lib3MF_uint64 CSlice::GetVertexCount()
	{
		Lib3MF_uint64 resultCount = 0;
		CheckError(lib3mf_slice_getvertexcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CSlice::AddPolygon - Add a new polygon to this slice
	* @param[in] IndicesBuffer - the new indices of the new polygon
	* @return the index of the new polygon
	*/
	Lib3MF_uint64 CSlice::AddPolygon(const CInputVector<Lib3MF_uint32> & IndicesBuffer)
	{
		Lib3MF_uint64 nIndicesSize = IndicesBuffer.size();
		Lib3MF_uint64 resultIndex = 0;
		CheckError(lib3mf_slice_addpolygon(m_pHandle, nIndicesSize, IndicesBuffer.data(), &resultIndex));
		
		return resultIndex;
	}
	
	/**
	* CSlice::GetPolygonCount - Get the number of polygons in the slice
	* @return the number of polygons in the slice
	*/
	Lib3MF_uint64 CSlice::GetPolygonCount()
	{
		Lib3MF_uint64 resultCount = 0;
		CheckError(lib3mf_slice_getpolygoncount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CSlice::SetPolygonIndices - Set all indices of a polygon
	* @param[in] nIndex - the index of the polygon to manipulate
	* @param[in] IndicesBuffer - the new indices of the index-th polygon
	*/
	void CSlice::SetPolygonIndices(const Lib3MF_uint64 nIndex, const CInputVector<Lib3MF_uint32> & IndicesBuffer)
	{
		Lib3MF_uint64 nIndicesSize = IndicesBuffer.size();
		CheckError(lib3mf_slice_setpolygonindices(m_pHandle, nIndex, nIndicesSize, IndicesBuffer.data()));
	}
	
	/**
	* CSlice::GetPolygonIndices - Get all vertices of a slice
	* @param[in] nIndex - the index of the polygon to manipulate
	* @param[out] IndicesBuffer - the indices of the index-th polygon 
	*/
	void CSlice::GetPolygonIndices(const Lib3MF_uint64 nIndex, std::vector<Lib3MF_uint32> & IndicesBuffer)
	{
		Lib3MF_uint64 elementsNeededIndices = 0;
		Lib3MF_uint64 elementsWrittenIndices = 0;
		CheckError(lib3mf_slice_getpolygonindices(m_pHandle, nIndex, 0, &elementsNeededIndices, nullptr));
		IndicesBuffer.resize((size_t) elementsNeededIndices);
		CheckError(lib3mf_slice_getpolygonindices(m_pHandle, nIndex, elementsNeededIndices, &elementsWrittenIndices, IndicesBuffer.data()));
	}
	
	/**
	* CSlice::GetPolygonIndexCount - Get the number of vertices in a slice
	* @param[in] nIndex - the index of the polygon to manipulate
	* @return the number of indices of the index-th polygon
	*/
	Lib3MF_uint64 CSlice::GetPolygonIndexCount(const Lib3MF_uint64 nIndex)
	{
		Lib3MF_uint64 resultCount = 0;
		CheckError(lib3mf_slice_getpolygonindexcount(m_pHandle, nIndex, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CSlice::GetZTop - Get the upper Z-Coordinate of this slice.
	* @return the upper Z-Coordinate of this slice
	*/
	Lib3MF_double CSlice::GetZTop()
	{
		Lib3MF_double resultZTop = 0;
		CheckError(lib3mf_slice_getztop(m_pHandle, &resultZTop));
		
		return resultZTop;
	}
	
	/**
	 * Method definitions for class CSliceStack
	 */
	
	/**
	* CSliceStack::GetBottomZ - Get the lower Z-Coordinate of the slice stack.
	* @return the lower Z-Coordinate the slice stack
	*/
	Lib3MF_double CSliceStack::GetBottomZ()
	{
		Lib3MF_double resultZBottom = 0;
		CheckError(lib3mf_slicestack_getbottomz(m_pHandle, &resultZBottom));
		
		return resultZBottom;
	}
	
	/**
	* CSliceStack::GetSliceCount - Returns the number of slices
	* @return the number of slices
	*/
	Lib3MF_uint64 CSliceStack::GetSliceCount()
	{
		Lib3MF_uint64 resultCount = 0;
		CheckError(lib3mf_slicestack_getslicecount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CSliceStack::GetSlice - Query a slice from the slice stack
	* @param[in] nSliceIndex - the index of the slice
	* @return the Slice instance
	*/
	PSlice CSliceStack::GetSlice(const Lib3MF_uint64 nSliceIndex)
	{
		Lib3MFHandle hTheSlice = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_slicestack_getslice(m_pHandle, nSliceIndex, &hTheSlice));
		
		if (!hTheSlice) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSlice>(dynamic_cast<CSlice*>(m_pWrapper->polymorphicFactory(hTheSlice)));
	}
	
	/**
	* CSliceStack::AddSlice - Returns the number of slices
	* @param[in] dZTop - upper Z coordinate of the slice
	* @return a new Slice instance
	*/
	PSlice CSliceStack::AddSlice(const Lib3MF_double dZTop)
	{
		Lib3MFHandle hTheSlice = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_slicestack_addslice(m_pHandle, dZTop, &hTheSlice));
		
		if (!hTheSlice) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSlice>(dynamic_cast<CSlice*>(m_pWrapper->polymorphicFactory(hTheSlice)));
	}
	
	/**
	* CSliceStack::GetSliceRefCount - Returns the number of slice refs
	* @return the number of slicereferences
	*/
	Lib3MF_uint64 CSliceStack::GetSliceRefCount()
	{
		Lib3MF_uint64 resultCount = 0;
		CheckError(lib3mf_slicestack_getslicerefcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CSliceStack::AddSliceStackReference - Adds another existing slicestack as sliceref in this slicestack
	* @param[in] pTheSliceStack - the slicestack to use as sliceref
	*/
	void CSliceStack::AddSliceStackReference(classParam<CSliceStack> pTheSliceStack)
	{
		Lib3MFHandle hTheSliceStack = pTheSliceStack.GetHandle();
		CheckError(lib3mf_slicestack_addslicestackreference(m_pHandle, hTheSliceStack));
	}
	
	/**
	* CSliceStack::GetSliceStackReference - Adds another existing slicestack as sliceref in this slicestack
	* @param[in] nSliceRefIndex - the index of the slice ref
	* @return the slicestack that is used as sliceref
	*/
	PSliceStack CSliceStack::GetSliceStackReference(const Lib3MF_uint64 nSliceRefIndex)
	{
		Lib3MFHandle hTheSliceStack = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_slicestack_getslicestackreference(m_pHandle, nSliceRefIndex, &hTheSliceStack));
		
		if (!hTheSliceStack) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSliceStack>(dynamic_cast<CSliceStack*>(m_pWrapper->polymorphicFactory(hTheSliceStack)));
	}
	
	/**
	* CSliceStack::CollapseSliceReferences - Removes the indirection of slices via slice-refs, i.e. creates the slices of all slice refs of this SliceStack as actual slices of this SliceStack. All previously existing slices or slicerefs will be removed.
	*/
	void CSliceStack::CollapseSliceReferences()
	{
		CheckError(lib3mf_slicestack_collapseslicereferences(m_pHandle));
	}
	
	/**
	* CSliceStack::SetOwnPath - Sets the package path where this Slice should be stored. Input an empty string to reset the path
	* @param[in] sPath - the package path where this Slice should be stored
	*/
	void CSliceStack::SetOwnPath(const std::string & sPath)
	{
		CheckError(lib3mf_slicestack_setownpath(m_pHandle, sPath.c_str()));
	}
	
	/**
	* CSliceStack::GetOwnPath - Obtains the package path where this Slice should be stored. Returns an empty string if the slicestack is stored within the root model.
	* @return the package path where this Slice will be stored
	*/
	std::string CSliceStack::GetOwnPath()
	{
		Lib3MF_uint32 bytesNeededPath = 0;
		Lib3MF_uint32 bytesWrittenPath = 0;
		CheckError(lib3mf_slicestack_getownpath(m_pHandle, 0, &bytesNeededPath, nullptr));
		std::vector<char> bufferPath(bytesNeededPath);
		CheckError(lib3mf_slicestack_getownpath(m_pHandle, bytesNeededPath, &bytesWrittenPath, &bufferPath[0]));
		
		return std::string(&bufferPath[0]);
	}
	
	/**
	 * Method definitions for class CConsumer
	 */
	
	/**
	* CConsumer::GetConsumerID - Gets the consumerid
	* @return A unique identifier for the consumers
	*/
	std::string CConsumer::GetConsumerID()
	{
		Lib3MF_uint32 bytesNeededConsumerID = 0;
		Lib3MF_uint32 bytesWrittenConsumerID = 0;
		CheckError(lib3mf_consumer_getconsumerid(m_pHandle, 0, &bytesNeededConsumerID, nullptr));
		std::vector<char> bufferConsumerID(bytesNeededConsumerID);
		CheckError(lib3mf_consumer_getconsumerid(m_pHandle, bytesNeededConsumerID, &bytesWrittenConsumerID, &bufferConsumerID[0]));
		
		return std::string(&bufferConsumerID[0]);
	}
	
	/**
	* CConsumer::GetKeyID - Getts the keyid
	* @return The identifier for the key of this consumer
	*/
	std::string CConsumer::GetKeyID()
	{
		Lib3MF_uint32 bytesNeededKeyID = 0;
		Lib3MF_uint32 bytesWrittenKeyID = 0;
		CheckError(lib3mf_consumer_getkeyid(m_pHandle, 0, &bytesNeededKeyID, nullptr));
		std::vector<char> bufferKeyID(bytesNeededKeyID);
		CheckError(lib3mf_consumer_getkeyid(m_pHandle, bytesNeededKeyID, &bytesWrittenKeyID, &bufferKeyID[0]));
		
		return std::string(&bufferKeyID[0]);
	}
	
	/**
	* CConsumer::GetKeyValue - Gets the keyvalue associated with this consumer
	* @return The public key, when available, of this consumer
	*/
	std::string CConsumer::GetKeyValue()
	{
		Lib3MF_uint32 bytesNeededKeyValue = 0;
		Lib3MF_uint32 bytesWrittenKeyValue = 0;
		CheckError(lib3mf_consumer_getkeyvalue(m_pHandle, 0, &bytesNeededKeyValue, nullptr));
		std::vector<char> bufferKeyValue(bytesNeededKeyValue);
		CheckError(lib3mf_consumer_getkeyvalue(m_pHandle, bytesNeededKeyValue, &bytesWrittenKeyValue, &bufferKeyValue[0]));
		
		return std::string(&bufferKeyValue[0]);
	}
	
	/**
	 * Method definitions for class CAccessRight
	 */
	
	/**
	* CAccessRight::GetConsumer - Gets the consumer associated with this access right
	* @return The consumer instance
	*/
	PConsumer CAccessRight::GetConsumer()
	{
		Lib3MFHandle hConsumer = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_accessright_getconsumer(m_pHandle, &hConsumer));
		
		if (!hConsumer) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CConsumer>(dynamic_cast<CConsumer*>(m_pWrapper->polymorphicFactory(hConsumer)));
	}
	
	/**
	* CAccessRight::GetWrappingAlgorithm - Gets the associated encryption algorithm
	* @return The algorithm used for the key in this accessright
	*/
	eWrappingAlgorithm CAccessRight::GetWrappingAlgorithm()
	{
		eWrappingAlgorithm resultAlgorithm = (eWrappingAlgorithm) 0;
		CheckError(lib3mf_accessright_getwrappingalgorithm(m_pHandle, &resultAlgorithm));
		
		return resultAlgorithm;
	}
	
	/**
	* CAccessRight::GetMgfAlgorithm - Gets the associated mask generation function algorithm
	* @return The MFG1 algorithm
	*/
	eMgfAlgorithm CAccessRight::GetMgfAlgorithm()
	{
		eMgfAlgorithm resultAlgorithm = (eMgfAlgorithm) 0;
		CheckError(lib3mf_accessright_getmgfalgorithm(m_pHandle, &resultAlgorithm));
		
		return resultAlgorithm;
	}
	
	/**
	* CAccessRight::GetDigestMethod - Gets the digest method assoicated
	* @return The digest method for this accessright
	*/
	eDigestMethod CAccessRight::GetDigestMethod()
	{
		eDigestMethod resultAlgorithm = (eDigestMethod) 0;
		CheckError(lib3mf_accessright_getdigestmethod(m_pHandle, &resultAlgorithm));
		
		return resultAlgorithm;
	}
	
	/**
	 * Method definitions for class CContentEncryptionParams
	 */
	
	/**
	* CContentEncryptionParams::GetEncryptionAlgorithm - Returns the encryption method to be used in this encryption process
	* @return 
	*/
	eEncryptionAlgorithm CContentEncryptionParams::GetEncryptionAlgorithm()
	{
		eEncryptionAlgorithm resultAlgorithm = (eEncryptionAlgorithm) 0;
		CheckError(lib3mf_contentencryptionparams_getencryptionalgorithm(m_pHandle, &resultAlgorithm));
		
		return resultAlgorithm;
	}
	
	/**
	* CContentEncryptionParams::GetKey - Gets the key for the resource associated
	* @param[out] ByteDataBuffer - Pointer to a buffer where to place the key.
	*/
	void CContentEncryptionParams::GetKey(std::vector<Lib3MF_uint8> & ByteDataBuffer)
	{
		Lib3MF_uint64 elementsNeededByteData = 0;
		Lib3MF_uint64 elementsWrittenByteData = 0;
		CheckError(lib3mf_contentencryptionparams_getkey(m_pHandle, 0, &elementsNeededByteData, nullptr));
		ByteDataBuffer.resize((size_t) elementsNeededByteData);
		CheckError(lib3mf_contentencryptionparams_getkey(m_pHandle, elementsNeededByteData, &elementsWrittenByteData, ByteDataBuffer.data()));
	}
	
	/**
	* CContentEncryptionParams::GetInitializationVector - Gets the IV data
	* @param[out] ByteDataBuffer - Pointer to a buffer where to place the data.
	*/
	void CContentEncryptionParams::GetInitializationVector(std::vector<Lib3MF_uint8> & ByteDataBuffer)
	{
		Lib3MF_uint64 elementsNeededByteData = 0;
		Lib3MF_uint64 elementsWrittenByteData = 0;
		CheckError(lib3mf_contentencryptionparams_getinitializationvector(m_pHandle, 0, &elementsNeededByteData, nullptr));
		ByteDataBuffer.resize((size_t) elementsNeededByteData);
		CheckError(lib3mf_contentencryptionparams_getinitializationvector(m_pHandle, elementsNeededByteData, &elementsWrittenByteData, ByteDataBuffer.data()));
	}
	
	/**
	* CContentEncryptionParams::GetAuthenticationTag - A handler descriptor that uniquely identifies the context of the resource. Each resource will be assigned a different value
	* @param[out] ByteDataBuffer - Pointer to a buffer where to place the data.
	*/
	void CContentEncryptionParams::GetAuthenticationTag(std::vector<Lib3MF_uint8> & ByteDataBuffer)
	{
		Lib3MF_uint64 elementsNeededByteData = 0;
		Lib3MF_uint64 elementsWrittenByteData = 0;
		CheckError(lib3mf_contentencryptionparams_getauthenticationtag(m_pHandle, 0, &elementsNeededByteData, nullptr));
		ByteDataBuffer.resize((size_t) elementsNeededByteData);
		CheckError(lib3mf_contentencryptionparams_getauthenticationtag(m_pHandle, elementsNeededByteData, &elementsWrittenByteData, ByteDataBuffer.data()));
	}
	
	/**
	* CContentEncryptionParams::SetAuthenticationTag - Sets the authentication tag
	* @param[in] ByteDataBuffer - The authentication tag size
	*/
	void CContentEncryptionParams::SetAuthenticationTag(const CInputVector<Lib3MF_uint8> & ByteDataBuffer)
	{
		Lib3MF_uint64 nByteDataSize = ByteDataBuffer.size();
		CheckError(lib3mf_contentencryptionparams_setauthenticationtag(m_pHandle, nByteDataSize, ByteDataBuffer.data()));
	}
	
	/**
	* CContentEncryptionParams::GetAdditionalAuthenticationData - A handler descriptor that uniquely identifies the context of the resource. Each resource will be assigned a different value
	* @param[out] ByteDataBuffer - Buffer where the data will be placed
	*/
	void CContentEncryptionParams::GetAdditionalAuthenticationData(std::vector<Lib3MF_uint8> & ByteDataBuffer)
	{
		Lib3MF_uint64 elementsNeededByteData = 0;
		Lib3MF_uint64 elementsWrittenByteData = 0;
		CheckError(lib3mf_contentencryptionparams_getadditionalauthenticationdata(m_pHandle, 0, &elementsNeededByteData, nullptr));
		ByteDataBuffer.resize((size_t) elementsNeededByteData);
		CheckError(lib3mf_contentencryptionparams_getadditionalauthenticationdata(m_pHandle, elementsNeededByteData, &elementsWrittenByteData, ByteDataBuffer.data()));
	}
	
	/**
	* CContentEncryptionParams::GetDescriptor - A handler descriptor that uniquely identifies the context of the resource. Each resource will be assigned a different value
	* @return 
	*/
	Lib3MF_uint64 CContentEncryptionParams::GetDescriptor()
	{
		Lib3MF_uint64 resultDescriptor = 0;
		CheckError(lib3mf_contentencryptionparams_getdescriptor(m_pHandle, &resultDescriptor));
		
		return resultDescriptor;
	}
	
	/**
	* CContentEncryptionParams::GetKeyUUID - Gets the resourcedatagroup keyuuid
	* @return The resourcedatagroup keyuuid that may be use to reference an external key
	*/
	std::string CContentEncryptionParams::GetKeyUUID()
	{
		Lib3MF_uint32 bytesNeededUUID = 0;
		Lib3MF_uint32 bytesWrittenUUID = 0;
		CheckError(lib3mf_contentencryptionparams_getkeyuuid(m_pHandle, 0, &bytesNeededUUID, nullptr));
		std::vector<char> bufferUUID(bytesNeededUUID);
		CheckError(lib3mf_contentencryptionparams_getkeyuuid(m_pHandle, bytesNeededUUID, &bytesWrittenUUID, &bufferUUID[0]));
		
		return std::string(&bufferUUID[0]);
	}
	
	/**
	 * Method definitions for class CResourceData
	 */
	
	/**
	* CResourceData::GetPath - Gets the encrypted part path
	* @return The part path
	*/
	PPackagePart CResourceData::GetPath()
	{
		Lib3MFHandle hPath = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_resourcedata_getpath(m_pHandle, &hPath));
		
		if (!hPath) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CPackagePart>(dynamic_cast<CPackagePart*>(m_pWrapper->polymorphicFactory(hPath)));
	}
	
	/**
	* CResourceData::GetEncryptionAlgorithm - Gets the encryption algorithm used to encrypt this ResourceData
	* @return The encryption algorithm
	*/
	eEncryptionAlgorithm CResourceData::GetEncryptionAlgorithm()
	{
		eEncryptionAlgorithm resultEncryptionAlgorithm = (eEncryptionAlgorithm) 0;
		CheckError(lib3mf_resourcedata_getencryptionalgorithm(m_pHandle, &resultEncryptionAlgorithm));
		
		return resultEncryptionAlgorithm;
	}
	
	/**
	* CResourceData::GetCompression - Tells whether this ResourceData is compressed or not
	* @return The compression method
	*/
	eCompression CResourceData::GetCompression()
	{
		eCompression resultCompression = (eCompression) 0;
		CheckError(lib3mf_resourcedata_getcompression(m_pHandle, &resultCompression));
		
		return resultCompression;
	}
	
	/**
	* CResourceData::GetAdditionalAuthenticationData - Tells whether this ResourceData is compressed or not
	* @param[out] ByteDataBuffer - The compression method
	*/
	void CResourceData::GetAdditionalAuthenticationData(std::vector<Lib3MF_uint8> & ByteDataBuffer)
	{
		Lib3MF_uint64 elementsNeededByteData = 0;
		Lib3MF_uint64 elementsWrittenByteData = 0;
		CheckError(lib3mf_resourcedata_getadditionalauthenticationdata(m_pHandle, 0, &elementsNeededByteData, nullptr));
		ByteDataBuffer.resize((size_t) elementsNeededByteData);
		CheckError(lib3mf_resourcedata_getadditionalauthenticationdata(m_pHandle, elementsNeededByteData, &elementsWrittenByteData, ByteDataBuffer.data()));
	}
	
	/**
	 * Method definitions for class CResourceDataGroup
	 */
	
	/**
	* CResourceDataGroup::GetKeyUUID - Sets the resourcedatagroup keyuuid
	* @return The new resourcedatagroup keyuuid.
	*/
	std::string CResourceDataGroup::GetKeyUUID()
	{
		Lib3MF_uint32 bytesNeededUUID = 0;
		Lib3MF_uint32 bytesWrittenUUID = 0;
		CheckError(lib3mf_resourcedatagroup_getkeyuuid(m_pHandle, 0, &bytesNeededUUID, nullptr));
		std::vector<char> bufferUUID(bytesNeededUUID);
		CheckError(lib3mf_resourcedatagroup_getkeyuuid(m_pHandle, bytesNeededUUID, &bytesWrittenUUID, &bufferUUID[0]));
		
		return std::string(&bufferUUID[0]);
	}
	
	/**
	* CResourceDataGroup::AddAccessRight - Add accessright to resourcedatagroup element
	* @param[in] pConsumer - The Consumer reference
	* @param[in] eWrappingAlgorithm - The key wrapping algorithm to be used
	* @param[in] eMgfAlgorithm - The mask generation function to be used
	* @param[in] eDigestMethod - The digest mechanism to be used
	* @return The acess right instance
	*/
	PAccessRight CResourceDataGroup::AddAccessRight(classParam<CConsumer> pConsumer, const eWrappingAlgorithm eWrappingAlgorithm, const eMgfAlgorithm eMgfAlgorithm, const eDigestMethod eDigestMethod)
	{
		Lib3MFHandle hConsumer = pConsumer.GetHandle();
		Lib3MFHandle hTheAccessRight = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_resourcedatagroup_addaccessright(m_pHandle, hConsumer, eWrappingAlgorithm, eMgfAlgorithm, eDigestMethod, &hTheAccessRight));
		
		if (!hTheAccessRight) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CAccessRight>(dynamic_cast<CAccessRight*>(m_pWrapper->polymorphicFactory(hTheAccessRight)));
	}
	
	/**
	* CResourceDataGroup::FindAccessRightByConsumer - Finds the AccessRight associated with a Consumer
	* @param[in] pConsumer - The Consumer instance
	* @return The AcessRight instance
	*/
	PAccessRight CResourceDataGroup::FindAccessRightByConsumer(classParam<CConsumer> pConsumer)
	{
		Lib3MFHandle hConsumer = pConsumer.GetHandle();
		Lib3MFHandle hTheAccessRight = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_resourcedatagroup_findaccessrightbyconsumer(m_pHandle, hConsumer, &hTheAccessRight));
		
		if (hTheAccessRight) {
			return std::shared_ptr<CAccessRight>(dynamic_cast<CAccessRight*>(m_pWrapper->polymorphicFactory(hTheAccessRight)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CResourceDataGroup::RemoveAccessRight - Removes access from a Consumer on this resource data group
	* @param[in] pConsumer - The Consumer instance
	*/
	void CResourceDataGroup::RemoveAccessRight(classParam<CConsumer> pConsumer)
	{
		Lib3MFHandle hConsumer = pConsumer.GetHandle();
		CheckError(lib3mf_resourcedatagroup_removeaccessright(m_pHandle, hConsumer));
	}
	
	/**
	 * Method definitions for class CKeyStore
	 */
	
	/**
	* CKeyStore::AddConsumer - Adds a consumer to the keystore
	* @param[in] sConsumerID - A unique identifier for the consumer
	* @param[in] sKeyID - The id of the key of the consumer
	* @param[in] sKeyValue - The public key for this consumer in PEM format
	* @return The consumer instance
	*/
	PConsumer CKeyStore::AddConsumer(const std::string & sConsumerID, const std::string & sKeyID, const std::string & sKeyValue)
	{
		Lib3MFHandle hConsumer = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_keystore_addconsumer(m_pHandle, sConsumerID.c_str(), sKeyID.c_str(), sKeyValue.c_str(), &hConsumer));
		
		if (!hConsumer) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CConsumer>(dynamic_cast<CConsumer*>(m_pWrapper->polymorphicFactory(hConsumer)));
	}
	
	/**
	* CKeyStore::GetConsumerCount - Gets the number of consumers in the keystore
	* @return The consumer count
	*/
	Lib3MF_uint64 CKeyStore::GetConsumerCount()
	{
		Lib3MF_uint64 resultCount = 0;
		CheckError(lib3mf_keystore_getconsumercount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CKeyStore::GetConsumer - Get a consumer from the keystore
	* @param[in] nConsumerIndex - The index of the consumer
	* @return The consumer instance
	*/
	PConsumer CKeyStore::GetConsumer(const Lib3MF_uint64 nConsumerIndex)
	{
		Lib3MFHandle hConsumer = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_keystore_getconsumer(m_pHandle, nConsumerIndex, &hConsumer));
		
		if (!hConsumer) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CConsumer>(dynamic_cast<CConsumer*>(m_pWrapper->polymorphicFactory(hConsumer)));
	}
	
	/**
	* CKeyStore::RemoveConsumer - Removes a consumer from the keystore
	* @param[in] pConsumer - The consumer instance to remove
	*/
	void CKeyStore::RemoveConsumer(classParam<CConsumer> pConsumer)
	{
		Lib3MFHandle hConsumer = pConsumer.GetHandle();
		CheckError(lib3mf_keystore_removeconsumer(m_pHandle, hConsumer));
	}
	
	/**
	* CKeyStore::FindConsumer - Finds a consumer by ID
	* @param[in] sConsumerID - The ID of the consumer
	* @return The consumer instance
	*/
	PConsumer CKeyStore::FindConsumer(const std::string & sConsumerID)
	{
		Lib3MFHandle hConsumer = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_keystore_findconsumer(m_pHandle, sConsumerID.c_str(), &hConsumer));
		
		if (hConsumer) {
			return std::shared_ptr<CConsumer>(dynamic_cast<CConsumer*>(m_pWrapper->polymorphicFactory(hConsumer)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CKeyStore::GetResourceDataGroupCount - Gets the number of resource data group in the keysore
	* @return The number of resource data available
	*/
	Lib3MF_uint64 CKeyStore::GetResourceDataGroupCount()
	{
		Lib3MF_uint64 resultCount = 0;
		CheckError(lib3mf_keystore_getresourcedatagroupcount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CKeyStore::AddResourceDataGroup - Adds a resource data group into the keystore.
	* @return The resource data group instance
	*/
	PResourceDataGroup CKeyStore::AddResourceDataGroup()
	{
		Lib3MFHandle hResourceDataGroup = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_keystore_addresourcedatagroup(m_pHandle, &hResourceDataGroup));
		
		if (!hResourceDataGroup) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CResourceDataGroup>(dynamic_cast<CResourceDataGroup*>(m_pWrapper->polymorphicFactory(hResourceDataGroup)));
	}
	
	/**
	* CKeyStore::GetResourceDataGroup - Gets a resource data group
	* @param[in] nResourceDataIndex - The index of the resource data
	* @return The resource data group instance
	*/
	PResourceDataGroup CKeyStore::GetResourceDataGroup(const Lib3MF_uint64 nResourceDataIndex)
	{
		Lib3MFHandle hResourceDataGroup = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_keystore_getresourcedatagroup(m_pHandle, nResourceDataIndex, &hResourceDataGroup));
		
		if (!hResourceDataGroup) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CResourceDataGroup>(dynamic_cast<CResourceDataGroup*>(m_pWrapper->polymorphicFactory(hResourceDataGroup)));
	}
	
	/**
	* CKeyStore::RemoveResourceDataGroup - Removes a resource data group
	* @param[in] pResourceDataGroup - The resource data group instance
	*/
	void CKeyStore::RemoveResourceDataGroup(classParam<CResourceDataGroup> pResourceDataGroup)
	{
		Lib3MFHandle hResourceDataGroup = pResourceDataGroup.GetHandle();
		CheckError(lib3mf_keystore_removeresourcedatagroup(m_pHandle, hResourceDataGroup));
	}
	
	/**
	* CKeyStore::FindResourceDataGroup - Finds a resource data group that contains a particular resourcedata
	* @param[in] pPartPath - The target path for the resourcedata hold by the resource data group
	* @return The data resource instance
	*/
	PResourceDataGroup CKeyStore::FindResourceDataGroup(classParam<CPackagePart> pPartPath)
	{
		Lib3MFHandle hPartPath = pPartPath.GetHandle();
		Lib3MFHandle hResourceDataGroup = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_keystore_findresourcedatagroup(m_pHandle, hPartPath, &hResourceDataGroup));
		
		if (hResourceDataGroup) {
			return std::shared_ptr<CResourceDataGroup>(dynamic_cast<CResourceDataGroup*>(m_pWrapper->polymorphicFactory(hResourceDataGroup)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CKeyStore::AddResourceData - Add resourcedata to resourcedatagroup element
	* @param[in] pResourceDataGroup - The resource data group where to add this resource data
	* @param[in] pPartPath - The path of the part to be encrypted
	* @param[in] eAlgorithm - The encryption algorithm to be used to encrypt this resource
	* @param[in] eCompression - Whether compression should be used prior to encryption
	* @param[in] AdditionalAuthenticationDataBuffer - Additional data to be encrypted along the contents for better security
	* @return The data resource instance
	*/
	PResourceData CKeyStore::AddResourceData(classParam<CResourceDataGroup> pResourceDataGroup, classParam<CPackagePart> pPartPath, const eEncryptionAlgorithm eAlgorithm, const eCompression eCompression, const CInputVector<Lib3MF_uint8> & AdditionalAuthenticationDataBuffer)
	{
		Lib3MFHandle hResourceDataGroup = pResourceDataGroup.GetHandle();
		Lib3MFHandle hPartPath = pPartPath.GetHandle();
		Lib3MF_uint64 nAdditionalAuthenticationDataSize = AdditionalAuthenticationDataBuffer.size();
		Lib3MFHandle hResourceData = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_keystore_addresourcedata(m_pHandle, hResourceDataGroup, hPartPath, eAlgorithm, eCompression, nAdditionalAuthenticationDataSize, AdditionalAuthenticationDataBuffer.data(), &hResourceData));
		
		if (!hResourceData) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CResourceData>(dynamic_cast<CResourceData*>(m_pWrapper->polymorphicFactory(hResourceData)));
	}
	
	/**
	* CKeyStore::RemoveResourceData - Removes a resource data
	* @param[in] pResourceData - The resource data to be removed
	*/
	void CKeyStore::RemoveResourceData(classParam<CResourceData> pResourceData)
	{
		Lib3MFHandle hResourceData = pResourceData.GetHandle();
		CheckError(lib3mf_keystore_removeresourcedata(m_pHandle, hResourceData));
	}
	
	/**
	* CKeyStore::FindResourceData - Finds a resource data on this resource group
	* @param[in] pResourcePath - The target path for the resourcedata
	* @return The resource data instance
	*/
	PResourceData CKeyStore::FindResourceData(classParam<CPackagePart> pResourcePath)
	{
		Lib3MFHandle hResourcePath = pResourcePath.GetHandle();
		Lib3MFHandle hResourceData = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_keystore_findresourcedata(m_pHandle, hResourcePath, &hResourceData));
		
		if (hResourceData) {
			return std::shared_ptr<CResourceData>(dynamic_cast<CResourceData*>(m_pWrapper->polymorphicFactory(hResourceData)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CKeyStore::GetResourceDataCount - Gets the number of resource data in the keysore
	* @return The number of resource data available
	*/
	Lib3MF_uint64 CKeyStore::GetResourceDataCount()
	{
		Lib3MF_uint64 resultCount = 0;
		CheckError(lib3mf_keystore_getresourcedatacount(m_pHandle, &resultCount));
		
		return resultCount;
	}
	
	/**
	* CKeyStore::GetResourceData - Gets a resource data
	* @param[in] nResourceDataIndex - The index of the resource data
	* @return The data resource instance
	*/
	PResourceData CKeyStore::GetResourceData(const Lib3MF_uint64 nResourceDataIndex)
	{
		Lib3MFHandle hResourceData = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_keystore_getresourcedata(m_pHandle, nResourceDataIndex, &hResourceData));
		
		if (!hResourceData) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CResourceData>(dynamic_cast<CResourceData*>(m_pWrapper->polymorphicFactory(hResourceData)));
	}
	
	/**
	* CKeyStore::GetUUID - Gets the keystore UUID
	* @param[out] bHasUUID - flag whether the keystore has a UUID
	* @return returns the keystore uuid.
	*/
	std::string CKeyStore::GetUUID(bool & bHasUUID)
	{
		Lib3MF_uint32 bytesNeededUUID = 0;
		Lib3MF_uint32 bytesWrittenUUID = 0;
		CheckError(lib3mf_keystore_getuuid(m_pHandle, &bHasUUID, 0, &bytesNeededUUID, nullptr));
		std::vector<char> bufferUUID(bytesNeededUUID);
		CheckError(lib3mf_keystore_getuuid(m_pHandle, &bHasUUID, bytesNeededUUID, &bytesWrittenUUID, &bufferUUID[0]));
		
		return std::string(&bufferUUID[0]);
	}
	
	/**
	* CKeyStore::SetUUID - Sets the keystore UUID
	* @param[in] sUUID - The new keystore uuid.
	*/
	void CKeyStore::SetUUID(const std::string & sUUID)
	{
		CheckError(lib3mf_keystore_setuuid(m_pHandle, sUUID.c_str()));
	}
	
	/**
	 * Method definitions for class CModel
	 */
	
	/**
	* CModel::RootModelPart - Returns the PackagePart within the OPC package that holds the root model.
	* @return the PackagePart within the OPC package that holds the model-file
	*/
	PPackagePart CModel::RootModelPart()
	{
		Lib3MFHandle hRootModelPart = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_rootmodelpart(m_pHandle, &hRootModelPart));
		
		if (!hRootModelPart) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CPackagePart>(dynamic_cast<CPackagePart*>(m_pWrapper->polymorphicFactory(hRootModelPart)));
	}
	
	/**
	* CModel::FindOrCreatePackagePart - Returns a new PackagePart for use within the OPC package.
	* @param[in] sAbsolutePath - the absolute Path (physical location) within the OPC package
	* @return the new PackagePart within the OPC package
	*/
	PPackagePart CModel::FindOrCreatePackagePart(const std::string & sAbsolutePath)
	{
		Lib3MFHandle hModelPart = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_findorcreatepackagepart(m_pHandle, sAbsolutePath.c_str(), &hModelPart));
		
		if (!hModelPart) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CPackagePart>(dynamic_cast<CPackagePart*>(m_pWrapper->polymorphicFactory(hModelPart)));
	}
	
	/**
	* CModel::SetUnit - sets the units of a model.
	* @param[in] eUnit - Unit enum value for the model unit
	*/
	void CModel::SetUnit(const eModelUnit eUnit)
	{
		CheckError(lib3mf_model_setunit(m_pHandle, eUnit));
	}
	
	/**
	* CModel::GetUnit - returns the units of a model.
	* @return Unit enum value for the model unit
	*/
	eModelUnit CModel::GetUnit()
	{
		eModelUnit resultUnit = (eModelUnit) 0;
		CheckError(lib3mf_model_getunit(m_pHandle, &resultUnit));
		
		return resultUnit;
	}
	
	/**
	* CModel::GetLanguage - retrieves the language of a model
	* @return language identifier
	*/
	std::string CModel::GetLanguage()
	{
		Lib3MF_uint32 bytesNeededLanguage = 0;
		Lib3MF_uint32 bytesWrittenLanguage = 0;
		CheckError(lib3mf_model_getlanguage(m_pHandle, 0, &bytesNeededLanguage, nullptr));
		std::vector<char> bufferLanguage(bytesNeededLanguage);
		CheckError(lib3mf_model_getlanguage(m_pHandle, bytesNeededLanguage, &bytesWrittenLanguage, &bufferLanguage[0]));
		
		return std::string(&bufferLanguage[0]);
	}
	
	/**
	* CModel::SetLanguage - sets the language of a model
	* @param[in] sLanguage - language identifier
	*/
	void CModel::SetLanguage(const std::string & sLanguage)
	{
		CheckError(lib3mf_model_setlanguage(m_pHandle, sLanguage.c_str()));
	}
	
	/**
	* CModel::QueryWriter - creates a model writer instance for a specific file type
	* @param[in] sWriterClass -  string identifier for the file type
	* @return  string identifier for the file type
	*/
	PWriter CModel::QueryWriter(const std::string & sWriterClass)
	{
		Lib3MFHandle hWriterInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_querywriter(m_pHandle, sWriterClass.c_str(), &hWriterInstance));
		
		if (!hWriterInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CWriter>(dynamic_cast<CWriter*>(m_pWrapper->polymorphicFactory(hWriterInstance)));
	}
	
	/**
	* CModel::QueryReader - creates a model reader instance for a specific file type
	* @param[in] sReaderClass -  string identifier for the file type
	* @return  string identifier for the file type
	*/
	PReader CModel::QueryReader(const std::string & sReaderClass)
	{
		Lib3MFHandle hReaderInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_queryreader(m_pHandle, sReaderClass.c_str(), &hReaderInstance));
		
		if (!hReaderInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CReader>(dynamic_cast<CReader*>(m_pWrapper->polymorphicFactory(hReaderInstance)));
	}
	
	/**
	* CModel::GetResourceByID - finds a model resource by its UniqueResourceID
	* @param[in] nUniqueResourceID - UniqueResourceID
	* @return returns the resource instance
	*/
	PResource CModel::GetResourceByID(const Lib3MF_uint32 nUniqueResourceID)
	{
		Lib3MFHandle hResource = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getresourcebyid(m_pHandle, nUniqueResourceID, &hResource));
		
		if (!hResource) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CResource>(dynamic_cast<CResource*>(m_pWrapper->polymorphicFactory(hResource)));
	}
	
	/**
	* CModel::GetTexture2DByID - finds a model texture by its UniqueResourceID
	* @param[in] nUniqueResourceID - UniqueResourceID
	* @return returns the texture2d instance
	*/
	PTexture2D CModel::GetTexture2DByID(const Lib3MF_uint32 nUniqueResourceID)
	{
		Lib3MFHandle hTextureInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_gettexture2dbyid(m_pHandle, nUniqueResourceID, &hTextureInstance));
		
		if (!hTextureInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTexture2D>(dynamic_cast<CTexture2D*>(m_pWrapper->polymorphicFactory(hTextureInstance)));
	}
	
	/**
	* CModel::GetPropertyTypeByID - returns a Property's type
	* @param[in] nUniqueResourceID - Resource ID of the Property to Query
	* @return returns a Property's type
	*/
	ePropertyType CModel::GetPropertyTypeByID(const Lib3MF_uint32 nUniqueResourceID)
	{
		ePropertyType resultThePropertyType = (ePropertyType) 0;
		CheckError(lib3mf_model_getpropertytypebyid(m_pHandle, nUniqueResourceID, &resultThePropertyType));
		
		return resultThePropertyType;
	}
	
	/**
	* CModel::GetBaseMaterialGroupByID - finds a model base material group by its UniqueResourceID
	* @param[in] nUniqueResourceID - UniqueResourceID
	* @return returns the BaseMaterialGroup instance
	*/
	PBaseMaterialGroup CModel::GetBaseMaterialGroupByID(const Lib3MF_uint32 nUniqueResourceID)
	{
		Lib3MFHandle hBaseMaterialGroupInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getbasematerialgroupbyid(m_pHandle, nUniqueResourceID, &hBaseMaterialGroupInstance));
		
		if (!hBaseMaterialGroupInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBaseMaterialGroup>(dynamic_cast<CBaseMaterialGroup*>(m_pWrapper->polymorphicFactory(hBaseMaterialGroupInstance)));
	}
	
	/**
	* CModel::GetTexture2DGroupByID - finds a model texture2d group by its UniqueResourceID
	* @param[in] nUniqueResourceID - UniqueResourceID
	* @return returns the Texture2DGroup instance
	*/
	PTexture2DGroup CModel::GetTexture2DGroupByID(const Lib3MF_uint32 nUniqueResourceID)
	{
		Lib3MFHandle hTexture2DGroupInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_gettexture2dgroupbyid(m_pHandle, nUniqueResourceID, &hTexture2DGroupInstance));
		
		if (!hTexture2DGroupInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTexture2DGroup>(dynamic_cast<CTexture2DGroup*>(m_pWrapper->polymorphicFactory(hTexture2DGroupInstance)));
	}
	
	/**
	* CModel::GetCompositeMaterialsByID - finds a model CompositeMaterials by its UniqueResourceID
	* @param[in] nUniqueResourceID - UniqueResourceID
	* @return returns the CompositeMaterials instance
	*/
	PCompositeMaterials CModel::GetCompositeMaterialsByID(const Lib3MF_uint32 nUniqueResourceID)
	{
		Lib3MFHandle hCompositeMaterialsInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getcompositematerialsbyid(m_pHandle, nUniqueResourceID, &hCompositeMaterialsInstance));
		
		if (!hCompositeMaterialsInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CCompositeMaterials>(dynamic_cast<CCompositeMaterials*>(m_pWrapper->polymorphicFactory(hCompositeMaterialsInstance)));
	}
	
	/**
	* CModel::GetMultiPropertyGroupByID - finds a model MultiPropertyGroup by its UniqueResourceID
	* @param[in] nUniqueResourceID - UniqueResourceID
	* @return returns the MultiPropertyGroup instance
	*/
	PMultiPropertyGroup CModel::GetMultiPropertyGroupByID(const Lib3MF_uint32 nUniqueResourceID)
	{
		Lib3MFHandle hMultiPropertyGroupInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getmultipropertygroupbyid(m_pHandle, nUniqueResourceID, &hMultiPropertyGroupInstance));
		
		if (!hMultiPropertyGroupInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMultiPropertyGroup>(dynamic_cast<CMultiPropertyGroup*>(m_pWrapper->polymorphicFactory(hMultiPropertyGroupInstance)));
	}
	
	/**
	* CModel::GetMeshObjectByID - finds a mesh object by its UniqueResourceID
	* @param[in] nUniqueResourceID - UniqueResourceID
	* @return returns the mesh object instance
	*/
	PMeshObject CModel::GetMeshObjectByID(const Lib3MF_uint32 nUniqueResourceID)
	{
		Lib3MFHandle hMeshObjectInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getmeshobjectbyid(m_pHandle, nUniqueResourceID, &hMeshObjectInstance));
		
		if (!hMeshObjectInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMeshObject>(dynamic_cast<CMeshObject*>(m_pWrapper->polymorphicFactory(hMeshObjectInstance)));
	}
	
	/**
	* CModel::GetComponentsObjectByID - finds a components object by its UniqueResourceID
	* @param[in] nUniqueResourceID - UniqueResourceID
	* @return returns the components object instance
	*/
	PComponentsObject CModel::GetComponentsObjectByID(const Lib3MF_uint32 nUniqueResourceID)
	{
		Lib3MFHandle hComponentsObjectInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getcomponentsobjectbyid(m_pHandle, nUniqueResourceID, &hComponentsObjectInstance));
		
		if (!hComponentsObjectInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CComponentsObject>(dynamic_cast<CComponentsObject*>(m_pWrapper->polymorphicFactory(hComponentsObjectInstance)));
	}
	
	/**
	* CModel::GetColorGroupByID - finds a model color group by its UniqueResourceID
	* @param[in] nUniqueResourceID - UniqueResourceID
	* @return returns the ColorGroup instance
	*/
	PColorGroup CModel::GetColorGroupByID(const Lib3MF_uint32 nUniqueResourceID)
	{
		Lib3MFHandle hColorGroupInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getcolorgroupbyid(m_pHandle, nUniqueResourceID, &hColorGroupInstance));
		
		if (!hColorGroupInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CColorGroup>(dynamic_cast<CColorGroup*>(m_pWrapper->polymorphicFactory(hColorGroupInstance)));
	}
	
	/**
	* CModel::GetSliceStackByID - finds a model slicestack by its UniqueResourceID
	* @param[in] nUniqueResourceID - UniqueResourceID
	* @return returns the slicestack instance
	*/
	PSliceStack CModel::GetSliceStackByID(const Lib3MF_uint32 nUniqueResourceID)
	{
		Lib3MFHandle hSliceStacInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getslicestackbyid(m_pHandle, nUniqueResourceID, &hSliceStacInstance));
		
		if (!hSliceStacInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSliceStack>(dynamic_cast<CSliceStack*>(m_pWrapper->polymorphicFactory(hSliceStacInstance)));
	}
	
	/**
	* CModel::GetLevelSetByID - finds a level set object by its UniqueResourceID
	* @param[in] nUniqueResourceID - UniqueResourceID
	* @return returns the level set object instance
	*/
	PLevelSet CModel::GetLevelSetByID(const Lib3MF_uint32 nUniqueResourceID)
	{
		Lib3MFHandle hLevelSetObjectInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getlevelsetbyid(m_pHandle, nUniqueResourceID, &hLevelSetObjectInstance));
		
		if (!hLevelSetObjectInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CLevelSet>(dynamic_cast<CLevelSet*>(m_pWrapper->polymorphicFactory(hLevelSetObjectInstance)));
	}
	
	/**
	* CModel::GetBuildUUID - returns, whether a build has a UUID and, if true, the build's UUID
	* @param[out] bHasUUID - flag whether the build has a UUID
	* @return the UUID as string of the form 'xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx'
	*/
	std::string CModel::GetBuildUUID(bool & bHasUUID)
	{
		Lib3MF_uint32 bytesNeededUUID = 0;
		Lib3MF_uint32 bytesWrittenUUID = 0;
		CheckError(lib3mf_model_getbuilduuid(m_pHandle, &bHasUUID, 0, &bytesNeededUUID, nullptr));
		std::vector<char> bufferUUID(bytesNeededUUID);
		CheckError(lib3mf_model_getbuilduuid(m_pHandle, &bHasUUID, bytesNeededUUID, &bytesWrittenUUID, &bufferUUID[0]));
		
		return std::string(&bufferUUID[0]);
	}
	
	/**
	* CModel::SetBuildUUID - sets the build's UUID
	* @param[in] sUUID - the UUID as string of the form 'xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx'
	*/
	void CModel::SetBuildUUID(const std::string & sUUID)
	{
		CheckError(lib3mf_model_setbuilduuid(m_pHandle, sUUID.c_str()));
	}
	
	/**
	* CModel::GetBuildItems - creates a build item iterator instance with all build items.
	* @return returns the iterator instance.
	*/
	PBuildItemIterator CModel::GetBuildItems()
	{
		Lib3MFHandle hBuildItemIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getbuilditems(m_pHandle, &hBuildItemIterator));
		
		if (!hBuildItemIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBuildItemIterator>(dynamic_cast<CBuildItemIterator*>(m_pWrapper->polymorphicFactory(hBuildItemIterator)));
	}
	
	/**
	* CModel::GetOutbox - Returns the outbox of a Model
	* @return Outbox of this Model
	*/
	sBox CModel::GetOutbox()
	{
		sBox resultOutbox;
		CheckError(lib3mf_model_getoutbox(m_pHandle, &resultOutbox));
		
		return resultOutbox;
	}
	
	/**
	* CModel::GetResources - creates a resource iterator instance with all resources.
	* @return returns the iterator instance.
	*/
	PResourceIterator CModel::GetResources()
	{
		Lib3MFHandle hResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getresources(m_pHandle, &hResourceIterator));
		
		if (!hResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CResourceIterator>(dynamic_cast<CResourceIterator*>(m_pWrapper->polymorphicFactory(hResourceIterator)));
	}
	
	/**
	* CModel::GetObjects - creates a resource iterator instance with all object resources.
	* @return returns the iterator instance.
	*/
	PObjectIterator CModel::GetObjects()
	{
		Lib3MFHandle hResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getobjects(m_pHandle, &hResourceIterator));
		
		if (!hResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CObjectIterator>(dynamic_cast<CObjectIterator*>(m_pWrapper->polymorphicFactory(hResourceIterator)));
	}
	
	/**
	* CModel::GetMeshObjects - creates a resource iterator instance with all mesh object resources.
	* @return returns the iterator instance.
	*/
	PMeshObjectIterator CModel::GetMeshObjects()
	{
		Lib3MFHandle hResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getmeshobjects(m_pHandle, &hResourceIterator));
		
		if (!hResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMeshObjectIterator>(dynamic_cast<CMeshObjectIterator*>(m_pWrapper->polymorphicFactory(hResourceIterator)));
	}
	
	/**
	* CModel::GetComponentsObjects - creates a resource iterator instance with all components object resources.
	* @return returns the iterator instance.
	*/
	PComponentsObjectIterator CModel::GetComponentsObjects()
	{
		Lib3MFHandle hResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getcomponentsobjects(m_pHandle, &hResourceIterator));
		
		if (!hResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CComponentsObjectIterator>(dynamic_cast<CComponentsObjectIterator*>(m_pWrapper->polymorphicFactory(hResourceIterator)));
	}
	
	/**
	* CModel::GetTexture2Ds - creates a Texture2DIterator instance with all texture2d resources.
	* @return returns the iterator instance.
	*/
	PTexture2DIterator CModel::GetTexture2Ds()
	{
		Lib3MFHandle hResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_gettexture2ds(m_pHandle, &hResourceIterator));
		
		if (!hResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTexture2DIterator>(dynamic_cast<CTexture2DIterator*>(m_pWrapper->polymorphicFactory(hResourceIterator)));
	}
	
	/**
	* CModel::GetBaseMaterialGroups - creates a BaseMaterialGroupIterator instance with all base material resources.
	* @return returns the iterator instance.
	*/
	PBaseMaterialGroupIterator CModel::GetBaseMaterialGroups()
	{
		Lib3MFHandle hResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getbasematerialgroups(m_pHandle, &hResourceIterator));
		
		if (!hResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBaseMaterialGroupIterator>(dynamic_cast<CBaseMaterialGroupIterator*>(m_pWrapper->polymorphicFactory(hResourceIterator)));
	}
	
	/**
	* CModel::GetColorGroups - creates a ColorGroupIterator instance with all ColorGroup resources.
	* @return returns the iterator instance.
	*/
	PColorGroupIterator CModel::GetColorGroups()
	{
		Lib3MFHandle hResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getcolorgroups(m_pHandle, &hResourceIterator));
		
		if (!hResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CColorGroupIterator>(dynamic_cast<CColorGroupIterator*>(m_pWrapper->polymorphicFactory(hResourceIterator)));
	}
	
	/**
	* CModel::GetTexture2DGroups - creates a Texture2DGroupIterator instance with all base material resources.
	* @return returns the iterator instance.
	*/
	PTexture2DGroupIterator CModel::GetTexture2DGroups()
	{
		Lib3MFHandle hResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_gettexture2dgroups(m_pHandle, &hResourceIterator));
		
		if (!hResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTexture2DGroupIterator>(dynamic_cast<CTexture2DGroupIterator*>(m_pWrapper->polymorphicFactory(hResourceIterator)));
	}
	
	/**
	* CModel::GetCompositeMaterials - creates a CompositeMaterialsIterator instance with all CompositeMaterials resources.
	* @return returns the iterator instance.
	*/
	PCompositeMaterialsIterator CModel::GetCompositeMaterials()
	{
		Lib3MFHandle hResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getcompositematerials(m_pHandle, &hResourceIterator));
		
		if (!hResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CCompositeMaterialsIterator>(dynamic_cast<CCompositeMaterialsIterator*>(m_pWrapper->polymorphicFactory(hResourceIterator)));
	}
	
	/**
	* CModel::GetMultiPropertyGroups - creates a MultiPropertyGroupsIterator instance with all MultiPropertyGroup resources.
	* @return returns the iterator instance.
	*/
	PMultiPropertyGroupIterator CModel::GetMultiPropertyGroups()
	{
		Lib3MFHandle hResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getmultipropertygroups(m_pHandle, &hResourceIterator));
		
		if (!hResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMultiPropertyGroupIterator>(dynamic_cast<CMultiPropertyGroupIterator*>(m_pWrapper->polymorphicFactory(hResourceIterator)));
	}
	
	/**
	* CModel::GetSliceStacks - creates a resource iterator instance with all slice stack resources.
	* @return returns the iterator instance.
	*/
	PSliceStackIterator CModel::GetSliceStacks()
	{
		Lib3MFHandle hResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getslicestacks(m_pHandle, &hResourceIterator));
		
		if (!hResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSliceStackIterator>(dynamic_cast<CSliceStackIterator*>(m_pWrapper->polymorphicFactory(hResourceIterator)));
	}
	
	/**
	* CModel::GetImage3Ds - creates a resource iterator instance with all image3d resources.
	* @return returns the iterator instance.
	*/
	PImage3DIterator CModel::GetImage3Ds()
	{
		Lib3MFHandle hResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getimage3ds(m_pHandle, &hResourceIterator));
		
		if (!hResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImage3DIterator>(dynamic_cast<CImage3DIterator*>(m_pWrapper->polymorphicFactory(hResourceIterator)));
	}
	
	/**
	* CModel::MergeToModel - Merges all components and objects which are referenced by a build item into a mesh. The memory is duplicated and a new model is created.
	* @return returns the merged model instance
	*/
	PModel CModel::MergeToModel()
	{
		Lib3MFHandle hMergedModelInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_mergetomodel(m_pHandle, &hMergedModelInstance));
		
		if (!hMergedModelInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CModel>(dynamic_cast<CModel*>(m_pWrapper->polymorphicFactory(hMergedModelInstance)));
	}
	
	/**
	* CModel::MergeFromModel - Merges the given model into this model.
	* @param[in] pModelInstance - model to be merged
	*/
	void CModel::MergeFromModel(classParam<CModel> pModelInstance)
	{
		Lib3MFHandle hModelInstance = pModelInstance.GetHandle();
		CheckError(lib3mf_model_mergefrommodel(m_pHandle, hModelInstance));
	}
	
	/**
	* CModel::AddMeshObject - adds an empty mesh object to the model.
	* @return  returns the mesh object instance
	*/
	PMeshObject CModel::AddMeshObject()
	{
		Lib3MFHandle hMeshObjectInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addmeshobject(m_pHandle, &hMeshObjectInstance));
		
		if (!hMeshObjectInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMeshObject>(dynamic_cast<CMeshObject*>(m_pWrapper->polymorphicFactory(hMeshObjectInstance)));
	}
	
	/**
	* CModel::AddComponentsObject - adds an empty component object to the model.
	* @return  returns the components object instance
	*/
	PComponentsObject CModel::AddComponentsObject()
	{
		Lib3MFHandle hComponentsObjectInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addcomponentsobject(m_pHandle, &hComponentsObjectInstance));
		
		if (!hComponentsObjectInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CComponentsObject>(dynamic_cast<CComponentsObject*>(m_pWrapper->polymorphicFactory(hComponentsObjectInstance)));
	}
	
	/**
	* CModel::AddSliceStack - creates a new model slicestack by its id
	* @param[in] dZBottom - Bottom Z value of the slicestack
	* @return returns the new slicestack instance
	*/
	PSliceStack CModel::AddSliceStack(const Lib3MF_double dZBottom)
	{
		Lib3MFHandle hSliceStackInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addslicestack(m_pHandle, dZBottom, &hSliceStackInstance));
		
		if (!hSliceStackInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CSliceStack>(dynamic_cast<CSliceStack*>(m_pWrapper->polymorphicFactory(hSliceStackInstance)));
	}
	
	/**
	* CModel::AddTexture2DFromAttachment - adds a texture2d resource to the model. Its path is given by that of an existing attachment.
	* @param[in] pTextureAttachment - attachment containing the image data.
	* @return returns the new texture instance.
	*/
	PTexture2D CModel::AddTexture2DFromAttachment(classParam<CAttachment> pTextureAttachment)
	{
		Lib3MFHandle hTextureAttachment = pTextureAttachment.GetHandle();
		Lib3MFHandle hTexture2DInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addtexture2dfromattachment(m_pHandle, hTextureAttachment, &hTexture2DInstance));
		
		if (!hTexture2DInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTexture2D>(dynamic_cast<CTexture2D*>(m_pWrapper->polymorphicFactory(hTexture2DInstance)));
	}
	
	/**
	* CModel::AddBaseMaterialGroup - adds an empty BaseMaterialGroup resource to the model.
	* @return returns the new base material instance.
	*/
	PBaseMaterialGroup CModel::AddBaseMaterialGroup()
	{
		Lib3MFHandle hBaseMaterialGroupInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addbasematerialgroup(m_pHandle, &hBaseMaterialGroupInstance));
		
		if (!hBaseMaterialGroupInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBaseMaterialGroup>(dynamic_cast<CBaseMaterialGroup*>(m_pWrapper->polymorphicFactory(hBaseMaterialGroupInstance)));
	}
	
	/**
	* CModel::AddColorGroup - adds an empty ColorGroup resource to the model.
	* @return returns the new ColorGroup instance.
	*/
	PColorGroup CModel::AddColorGroup()
	{
		Lib3MFHandle hColorGroupInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addcolorgroup(m_pHandle, &hColorGroupInstance));
		
		if (!hColorGroupInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CColorGroup>(dynamic_cast<CColorGroup*>(m_pWrapper->polymorphicFactory(hColorGroupInstance)));
	}
	
	/**
	* CModel::AddTexture2DGroup - adds an empty Texture2DGroup resource to the model.
	* @param[in] pTexture2DInstance - The texture2D instance of the created Texture2DGroup.
	* @return returns the new Texture2DGroup instance.
	*/
	PTexture2DGroup CModel::AddTexture2DGroup(classParam<CTexture2D> pTexture2DInstance)
	{
		Lib3MFHandle hTexture2DInstance = pTexture2DInstance.GetHandle();
		Lib3MFHandle hTexture2DGroupInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addtexture2dgroup(m_pHandle, hTexture2DInstance, &hTexture2DGroupInstance));
		
		if (!hTexture2DGroupInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CTexture2DGroup>(dynamic_cast<CTexture2DGroup*>(m_pWrapper->polymorphicFactory(hTexture2DGroupInstance)));
	}
	
	/**
	* CModel::AddCompositeMaterials - adds an empty CompositeMaterials resource to the model.
	* @param[in] pBaseMaterialGroupInstance - The BaseMaterialGroup instance of the created CompositeMaterials.
	* @return returns the new CompositeMaterials instance.
	*/
	PCompositeMaterials CModel::AddCompositeMaterials(classParam<CBaseMaterialGroup> pBaseMaterialGroupInstance)
	{
		Lib3MFHandle hBaseMaterialGroupInstance = pBaseMaterialGroupInstance.GetHandle();
		Lib3MFHandle hCompositeMaterialsInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addcompositematerials(m_pHandle, hBaseMaterialGroupInstance, &hCompositeMaterialsInstance));
		
		if (!hCompositeMaterialsInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CCompositeMaterials>(dynamic_cast<CCompositeMaterials*>(m_pWrapper->polymorphicFactory(hCompositeMaterialsInstance)));
	}
	
	/**
	* CModel::AddMultiPropertyGroup - adds an empty MultiPropertyGroup resource to the model.
	* @return returns the new MultiPropertyGroup instance.
	*/
	PMultiPropertyGroup CModel::AddMultiPropertyGroup()
	{
		Lib3MFHandle hMultiPropertyGroupInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addmultipropertygroup(m_pHandle, &hMultiPropertyGroupInstance));
		
		if (!hMultiPropertyGroupInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMultiPropertyGroup>(dynamic_cast<CMultiPropertyGroup*>(m_pWrapper->polymorphicFactory(hMultiPropertyGroupInstance)));
	}
	
	/**
	* CModel::AddImageStack - creates a new 3D Image Resource
	* @param[in] nColumnCount - the number of columns in each sheet.
	* @param[in] nRowCount - the number of rows in each sheet.
	* @param[in] nSheetCount - the number of sheets in the image stack.
	* @return returns the new ImageStack instance
	*/
	PImageStack CModel::AddImageStack(const Lib3MF_uint32 nColumnCount, const Lib3MF_uint32 nRowCount, const Lib3MF_uint32 nSheetCount)
	{
		Lib3MFHandle hInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addimagestack(m_pHandle, nColumnCount, nRowCount, nSheetCount, &hInstance));
		
		if (!hInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImageStack>(dynamic_cast<CImageStack*>(m_pWrapper->polymorphicFactory(hInstance)));
	}
	
	/**
	* CModel::GetImageStackByID - finds an ImageStack object by its UniqueResourceID
	* @param[in] nUniqueResourceID - UniqueResourceID
	* @return returns the image stack instance
	*/
	PImageStack CModel::GetImageStackByID(const Lib3MF_uint32 nUniqueResourceID)
	{
		Lib3MFHandle hImageStackInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getimagestackbyid(m_pHandle, nUniqueResourceID, &hImageStackInstance));
		
		if (!hImageStackInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImageStack>(dynamic_cast<CImageStack*>(m_pWrapper->polymorphicFactory(hImageStackInstance)));
	}
	
	/**
	* CModel::AddBuildItem - adds a build item to the model.
	* @param[in] pObject - Object instance.
	* @param[in] Transform - Transformation matrix.
	* @return returns the build item instance.
	*/
	PBuildItem CModel::AddBuildItem(classParam<CObject> pObject, const sTransform & Transform)
	{
		Lib3MFHandle hObject = pObject.GetHandle();
		Lib3MFHandle hBuildItemInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addbuilditem(m_pHandle, hObject, &Transform, &hBuildItemInstance));
		
		if (!hBuildItemInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CBuildItem>(dynamic_cast<CBuildItem*>(m_pWrapper->polymorphicFactory(hBuildItemInstance)));
	}
	
	/**
	* CModel::RemoveBuildItem - removes a build item from the model
	* @param[in] pBuildItemInstance - Build item to remove.
	*/
	void CModel::RemoveBuildItem(classParam<CBuildItem> pBuildItemInstance)
	{
		Lib3MFHandle hBuildItemInstance = pBuildItemInstance.GetHandle();
		CheckError(lib3mf_model_removebuilditem(m_pHandle, hBuildItemInstance));
	}
	
	/**
	* CModel::GetMetaDataGroup - Returns the metadata of the model as MetaDataGroup
	* @return returns an Instance of the metadatagroup of the model
	*/
	PMetaDataGroup CModel::GetMetaDataGroup()
	{
		Lib3MFHandle hTheMetaDataGroup = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getmetadatagroup(m_pHandle, &hTheMetaDataGroup));
		
		if (!hTheMetaDataGroup) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CMetaDataGroup>(dynamic_cast<CMetaDataGroup*>(m_pWrapper->polymorphicFactory(hTheMetaDataGroup)));
	}
	
	/**
	* CModel::AddAttachment - adds an attachment stream to the model. The OPC part will be related to the model stream with a certain relationship type.
	* @param[in] sURI - Path of the attachment
	* @param[in] sRelationShipType - Relationship type of the attachment
	* @return Instance of the attachment object
	*/
	PAttachment CModel::AddAttachment(const std::string & sURI, const std::string & sRelationShipType)
	{
		Lib3MFHandle hAttachmentInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addattachment(m_pHandle, sURI.c_str(), sRelationShipType.c_str(), &hAttachmentInstance));
		
		if (!hAttachmentInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CAttachment>(dynamic_cast<CAttachment*>(m_pWrapper->polymorphicFactory(hAttachmentInstance)));
	}
	
	/**
	* CModel::RemoveAttachment - Removes attachment from the model.
	* @param[in] pAttachmentInstance - Attachment instance to remove
	*/
	void CModel::RemoveAttachment(classParam<CAttachment> pAttachmentInstance)
	{
		Lib3MFHandle hAttachmentInstance = pAttachmentInstance.GetHandle();
		CheckError(lib3mf_model_removeattachment(m_pHandle, hAttachmentInstance));
	}
	
	/**
	* CModel::GetAttachment - retrieves an attachment stream object from the model..
	* @param[in] nIndex - Index of the attachment stream
	* @return Instance of the attachment object
	*/
	PAttachment CModel::GetAttachment(const Lib3MF_uint32 nIndex)
	{
		Lib3MFHandle hAttachmentInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getattachment(m_pHandle, nIndex, &hAttachmentInstance));
		
		if (!hAttachmentInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CAttachment>(dynamic_cast<CAttachment*>(m_pWrapper->polymorphicFactory(hAttachmentInstance)));
	}
	
	/**
	* CModel::FindAttachment - retrieves an attachment stream object from the model.
	* @param[in] sURI - Path URI in the package
	* @return Instance of the attachment object
	*/
	PAttachment CModel::FindAttachment(const std::string & sURI)
	{
		Lib3MFHandle hAttachmentInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_findattachment(m_pHandle, sURI.c_str(), &hAttachmentInstance));
		
		if (!hAttachmentInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CAttachment>(dynamic_cast<CAttachment*>(m_pWrapper->polymorphicFactory(hAttachmentInstance)));
	}
	
	/**
	* CModel::GetAttachmentCount - retrieves the number of attachments of the model.
	* @return Returns the number of attachments.
	*/
	Lib3MF_uint32 CModel::GetAttachmentCount()
	{
		Lib3MF_uint32 resultAttachmentCount = 0;
		CheckError(lib3mf_model_getattachmentcount(m_pHandle, &resultAttachmentCount));
		
		return resultAttachmentCount;
	}
	
	/**
	* CModel::HasPackageThumbnailAttachment - Retrieve whether the OPC package contains a package thumbnail.
	* @return returns whether the OPC package contains a package thumbnail
	*/
	bool CModel::HasPackageThumbnailAttachment()
	{
		bool resultHasThumbnail = 0;
		CheckError(lib3mf_model_haspackagethumbnailattachment(m_pHandle, &resultHasThumbnail));
		
		return resultHasThumbnail;
	}
	
	/**
	* CModel::CreatePackageThumbnailAttachment - Create a new or the existing package thumbnail for the OPC package.
	* @return Instance of a new or the existing thumbnailattachment object.
	*/
	PAttachment CModel::CreatePackageThumbnailAttachment()
	{
		Lib3MFHandle hAttachment = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_createpackagethumbnailattachment(m_pHandle, &hAttachment));
		
		if (!hAttachment) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CAttachment>(dynamic_cast<CAttachment*>(m_pWrapper->polymorphicFactory(hAttachment)));
	}
	
	/**
	* CModel::GetPackageThumbnailAttachment - Get the attachment to the OPC package containing the package thumbnail.
	* @return Instance of the thumbnailattachment object or NULL.
	*/
	PAttachment CModel::GetPackageThumbnailAttachment()
	{
		Lib3MFHandle hAttachment = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getpackagethumbnailattachment(m_pHandle, &hAttachment));
		
		if (hAttachment) {
			return std::shared_ptr<CAttachment>(dynamic_cast<CAttachment*>(m_pWrapper->polymorphicFactory(hAttachment)));
		} else {
			return nullptr;
		}
	}
	
	/**
	* CModel::RemovePackageThumbnailAttachment - Remove the attachment to the OPC package containing the package thumbnail.
	*/
	void CModel::RemovePackageThumbnailAttachment()
	{
		CheckError(lib3mf_model_removepackagethumbnailattachment(m_pHandle));
	}
	
	/**
	* CModel::AddCustomContentType - Adds a new Content Type to the model.
	* @param[in] sExtension - File Extension
	* @param[in] sContentType - Content Type Identifier
	*/
	void CModel::AddCustomContentType(const std::string & sExtension, const std::string & sContentType)
	{
		CheckError(lib3mf_model_addcustomcontenttype(m_pHandle, sExtension.c_str(), sContentType.c_str()));
	}
	
	/**
	* CModel::RemoveCustomContentType - Removes a custom Content Type from the model (UTF8 version).
	* @param[in] sExtension - File Extension
	*/
	void CModel::RemoveCustomContentType(const std::string & sExtension)
	{
		CheckError(lib3mf_model_removecustomcontenttype(m_pHandle, sExtension.c_str()));
	}
	
	/**
	* CModel::SetRandomNumberCallback - Sets the random number generator callback for use in the library
	* @param[in] pTheCallback - The callback used to generate random numbers
	* @param[in] pUserData - Userdata to be passed to the callback function
	*/
	void CModel::SetRandomNumberCallback(const RandomNumberCallback pTheCallback, const Lib3MF_pvoid pUserData)
	{
		CheckError(lib3mf_model_setrandomnumbercallback(m_pHandle, pTheCallback, pUserData));
	}
	
	/**
	* CModel::GetKeyStore - Gets the keystore associated with this model
	* @return The package keystore
	*/
	PKeyStore CModel::GetKeyStore()
	{
		Lib3MFHandle hKeyStore = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getkeystore(m_pHandle, &hKeyStore));
		
		if (!hKeyStore) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CKeyStore>(dynamic_cast<CKeyStore*>(m_pWrapper->polymorphicFactory(hKeyStore)));
	}
	
	/**
	* CModel::GetFunctions - creates a resource iterator for all functions
	* @return returns the resource iterator
	*/
	PFunctionIterator CModel::GetFunctions()
	{
		Lib3MFHandle hTheResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getfunctions(m_pHandle, &hTheResourceIterator));
		
		if (!hTheResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CFunctionIterator>(dynamic_cast<CFunctionIterator*>(m_pWrapper->polymorphicFactory(hTheResourceIterator)));
	}
	
	/**
	* CModel::AddImplicitFunction - adds a function described by nodes to the model
	* @return returns the function instance
	*/
	PImplicitFunction CModel::AddImplicitFunction()
	{
		Lib3MFHandle hFunctionInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addimplicitfunction(m_pHandle, &hFunctionInstance));
		
		if (!hFunctionInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CImplicitFunction>(dynamic_cast<CImplicitFunction*>(m_pWrapper->polymorphicFactory(hFunctionInstance)));
	}
	
	/**
	* CModel::AddFunctionFromImage3D - adds a function defined by an image3d to the model
	* @param[in] pImage3DInstance - the Image3D-instance used for this function
	* @return returns the function instance
	*/
	PFunctionFromImage3D CModel::AddFunctionFromImage3D(classParam<CImage3D> pImage3DInstance)
	{
		Lib3MFHandle hImage3DInstance = pImage3DInstance.GetHandle();
		Lib3MFHandle hFunctionInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addfunctionfromimage3d(m_pHandle, hImage3DInstance, &hFunctionInstance));
		
		if (!hFunctionInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CFunctionFromImage3D>(dynamic_cast<CFunctionFromImage3D*>(m_pWrapper->polymorphicFactory(hFunctionInstance)));
	}
	
	/**
	* CModel::AddVolumeData - adds a volume data resource to the model.
	* @return returns the new volume data instance.
	*/
	PVolumeData CModel::AddVolumeData()
	{
		Lib3MFHandle hVolumeDataInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addvolumedata(m_pHandle, &hVolumeDataInstance));
		
		if (!hVolumeDataInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CVolumeData>(dynamic_cast<CVolumeData*>(m_pWrapper->polymorphicFactory(hVolumeDataInstance)));
	}
	
	/**
	* CModel::AddLevelSet - adds an empty boundary shape object to the model.
	* @return  returns the mesh object instance
	*/
	PLevelSet CModel::AddLevelSet()
	{
		Lib3MFHandle hLevelSetInstance = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_addlevelset(m_pHandle, &hLevelSetInstance));
		
		if (!hLevelSetInstance) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CLevelSet>(dynamic_cast<CLevelSet*>(m_pWrapper->polymorphicFactory(hLevelSetInstance)));
	}
	
	/**
	* CModel::GetLevelSets - creates a resource iterator instance with all boundary shape resources.
	* @return returns the iterator instance.
	*/
	PLevelSetIterator CModel::GetLevelSets()
	{
		Lib3MFHandle hResourceIterator = (Lib3MFHandle)nullptr;
		CheckError(lib3mf_model_getlevelsets(m_pHandle, &hResourceIterator));
		
		if (!hResourceIterator) {
			CheckError(LIB3MF_ERROR_INVALIDPARAM);
		}
		return std::shared_ptr<CLevelSetIterator>(dynamic_cast<CLevelSetIterator*>(m_pWrapper->polymorphicFactory(hResourceIterator)));
	}
	
	/**
	* CModel::RemoveResource - Removes a resource from the model
	* @param[in] pResource - The resource to remove
	*/
	void CModel::RemoveResource(classParam<CResource> pResource)
	{
		Lib3MFHandle hResource = pResource.GetHandle();
		CheckError(lib3mf_model_removeresource(m_pHandle, hResource));
	}

} // namespace Lib3MF

#endif // __LIB3MF_CPPHEADER_IMPLICIT_CPP

