nuclear@14: //----------------------------------------------------------------------------- nuclear@14: // Product: OpenCTM nuclear@14: // File: openctmpp.h nuclear@14: // Description: C++ wrapper for the OpenCTM API. nuclear@14: //----------------------------------------------------------------------------- nuclear@14: // Copyright (c) 2009-2010 Marcus Geelnard nuclear@14: // nuclear@14: // This software is provided 'as-is', without any express or implied nuclear@14: // warranty. In no event will the authors be held liable for any damages nuclear@14: // arising from the use of this software. nuclear@14: // nuclear@14: // Permission is granted to anyone to use this software for any purpose, nuclear@14: // including commercial applications, and to alter it and redistribute it nuclear@14: // freely, subject to the following restrictions: nuclear@14: // nuclear@14: // 1. The origin of this software must not be misrepresented; you must not nuclear@14: // claim that you wrote the original software. If you use this software nuclear@14: // in a product, an acknowledgment in the product documentation would be nuclear@14: // appreciated but is not required. nuclear@14: // nuclear@14: // 2. Altered source versions must be plainly marked as such, and must not nuclear@14: // be misrepresented as being the original software. nuclear@14: // nuclear@14: // 3. This notice may not be removed or altered from any source nuclear@14: // distribution. nuclear@14: //----------------------------------------------------------------------------- nuclear@14: nuclear@14: // To disable C++ extensions, define OPENCTM_NO_CPP nuclear@14: #ifndef OPENCTM_NO_CPP nuclear@14: nuclear@14: #ifndef __OPENCTMPP_H_ nuclear@14: #define __OPENCTMPP_H_ nuclear@14: nuclear@14: // Just in case (if this file was included from outside openctm.h)... nuclear@14: #ifndef __OPENCTM_H_ nuclear@14: #include "openctm.h" nuclear@14: #endif nuclear@14: nuclear@14: #include nuclear@14: nuclear@14: /// OpenCTM exception. When an error occurs, a \c ctm_error exception is nuclear@14: /// thrown. Its what() function returns the name of the OpenCTM error code nuclear@14: /// (for instance "CTM_INVALID_OPERATION"). nuclear@14: class ctm_error: public std::exception nuclear@14: { nuclear@14: private: nuclear@14: CTMenum mErrorCode; nuclear@14: nuclear@14: public: nuclear@14: explicit ctm_error(CTMenum aError) nuclear@14: { nuclear@14: mErrorCode = aError; nuclear@14: } nuclear@14: nuclear@14: virtual const char* what() const throw() nuclear@14: { nuclear@14: return ctmErrorString(mErrorCode); nuclear@14: } nuclear@14: nuclear@14: CTMenum error_code() const throw() nuclear@14: { nuclear@14: return mErrorCode; nuclear@14: } nuclear@14: }; nuclear@14: nuclear@14: nuclear@14: /// OpenCTM importer class. This is a C++ wrapper class for an OpenCTM import nuclear@14: /// context. Usage example: nuclear@14: /// nuclear@14: /// @code nuclear@14: /// // Create a new OpenCTM importer object nuclear@14: /// CTMimporter ctm; nuclear@14: /// nuclear@14: /// // Load the OpenCTM file nuclear@14: /// ctm.Load("mymesh.ctm"); nuclear@14: /// nuclear@14: /// // Access the mesh data nuclear@14: /// vertCount = ctm.GetInteger(CTM_VERTEX_COUNT); nuclear@14: /// vertices = ctm.GetFloatArray(CTM_VERTICES); nuclear@14: /// triCount = ctm.GetInteger(CTM_TRIANGLE_COUNT); nuclear@14: /// indices = ctm.GetIntegerArray(CTM_INDICES); nuclear@14: /// nuclear@14: /// // Deal with the mesh (e.g. transcode it to our internal representation) nuclear@14: /// // ... nuclear@14: /// @endcode nuclear@14: nuclear@14: class CTMimporter { nuclear@14: private: nuclear@14: /// The OpenCTM context handle. nuclear@14: CTMcontext mContext; nuclear@14: nuclear@14: /// Check for OpenCTM errors, and throw an exception if an error has nuclear@14: /// occured. nuclear@14: void CheckError() nuclear@14: { nuclear@14: CTMenum err = ctmGetError(mContext); nuclear@14: if(err != CTM_NONE) nuclear@14: throw ctm_error(err); nuclear@14: } nuclear@14: nuclear@14: public: nuclear@14: /// Constructor nuclear@14: CTMimporter() nuclear@14: { nuclear@14: mContext = ctmNewContext(CTM_IMPORT); nuclear@14: } nuclear@14: nuclear@14: /// Destructor nuclear@14: ~CTMimporter() nuclear@14: { nuclear@14: ctmFreeContext(mContext); nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmGetInteger() nuclear@14: CTMuint GetInteger(CTMenum aProperty) nuclear@14: { nuclear@14: CTMuint res = ctmGetInteger(mContext, aProperty); nuclear@14: CheckError(); nuclear@14: return res; nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmGetFloat() nuclear@14: CTMfloat GetFloat(CTMenum aProperty) nuclear@14: { nuclear@14: CTMfloat res = ctmGetFloat(mContext, aProperty); nuclear@14: CheckError(); nuclear@14: return res; nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmGetIntegerArray() nuclear@14: const CTMuint * GetIntegerArray(CTMenum aProperty) nuclear@14: { nuclear@14: const CTMuint * res = ctmGetIntegerArray(mContext, aProperty); nuclear@14: CheckError(); nuclear@14: return res; nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmGetFloatArray() nuclear@14: const CTMfloat * GetFloatArray(CTMenum aProperty) nuclear@14: { nuclear@14: const CTMfloat * res = ctmGetFloatArray(mContext, aProperty); nuclear@14: CheckError(); nuclear@14: return res; nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmGetNamedUVMap() nuclear@14: CTMenum GetNamedUVMap(const char * aName) nuclear@14: { nuclear@14: CTMenum res = ctmGetNamedUVMap(mContext, aName); nuclear@14: CheckError(); nuclear@14: return res; nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmGetUVMapString() nuclear@14: const char * GetUVMapString(CTMenum aUVMap, CTMenum aProperty) nuclear@14: { nuclear@14: const char * res = ctmGetUVMapString(mContext, aUVMap, aProperty); nuclear@14: CheckError(); nuclear@14: return res; nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmGetUVMapFloat() nuclear@14: CTMfloat GetUVMapFloat(CTMenum aUVMap, CTMenum aProperty) nuclear@14: { nuclear@14: CTMfloat res = ctmGetUVMapFloat(mContext, aUVMap, aProperty); nuclear@14: CheckError(); nuclear@14: return res; nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmGetNamedAttribMap() nuclear@14: CTMenum GetNamedAttribMap(const char * aName) nuclear@14: { nuclear@14: CTMenum res = ctmGetNamedAttribMap(mContext, aName); nuclear@14: CheckError(); nuclear@14: return res; nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmGetAttribMapString() nuclear@14: const char * GetAttribMapString(CTMenum aAttribMap, CTMenum aProperty) nuclear@14: { nuclear@14: const char * res = ctmGetAttribMapString(mContext, aAttribMap, aProperty); nuclear@14: CheckError(); nuclear@14: return res; nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmGetAttribMapFloat() nuclear@14: CTMfloat GetAttribMapFloat(CTMenum aAttribMap, CTMenum aProperty) nuclear@14: { nuclear@14: CTMfloat res = ctmGetAttribMapFloat(mContext, aAttribMap, aProperty); nuclear@14: CheckError(); nuclear@14: return res; nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmGetString() nuclear@14: const char * GetString(CTMenum aProperty) nuclear@14: { nuclear@14: const char * res = ctmGetString(mContext, aProperty); nuclear@14: CheckError(); nuclear@14: return res; nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmLoad() nuclear@14: void Load(const char * aFileName) nuclear@14: { nuclear@14: ctmLoad(mContext, aFileName); nuclear@14: CheckError(); nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmLoadCustom() nuclear@14: void LoadCustom(CTMreadfn aReadFn, void * aUserData) nuclear@14: { nuclear@14: ctmLoadCustom(mContext, aReadFn, aUserData); nuclear@14: CheckError(); nuclear@14: } nuclear@14: nuclear@14: // You can not copy nor assign from one CTMimporter object to another, since nuclear@14: // the object contains hidden state. By declaring these dummy prototypes nuclear@14: // without an implementation, you will at least get linker errors if you try nuclear@14: // to copy or assign a CTMimporter object. nuclear@14: CTMimporter(const CTMimporter& v); nuclear@14: CTMimporter& operator=(const CTMimporter& v); nuclear@14: }; nuclear@14: nuclear@14: nuclear@14: /// OpenCTM exporter class. This is a C++ wrapper class for an OpenCTM export nuclear@14: /// context. Usage example: nuclear@14: /// @code nuclear@14: /// void MySaveFile(CTMuint aVertCount, CTMuint aTriCount, CTMfloat * aVertices, nuclear@14: /// CTMuint * aIndices, const char * aFileName) nuclear@14: /// { nuclear@14: /// // Create a new OpenCTM exporter object nuclear@14: /// CTMexporter ctm; nuclear@14: /// nuclear@14: /// // Define our mesh representation to OpenCTM (store references to it in nuclear@14: /// // the context) nuclear@14: /// ctm.DefineMesh(aVertices, aVertCount, aIndices, aTriCount, NULL); nuclear@14: /// nuclear@14: /// // Save the OpenCTM file nuclear@14: /// ctm.Save(aFileName); nuclear@14: /// } nuclear@14: /// @endcode nuclear@14: nuclear@14: class CTMexporter { nuclear@14: private: nuclear@14: /// The OpenCTM context handle. nuclear@14: CTMcontext mContext; nuclear@14: nuclear@14: /// Check for OpenCTM errors, and throw an exception if an error has nuclear@14: /// occured. nuclear@14: void CheckError() nuclear@14: { nuclear@14: CTMenum err = ctmGetError(mContext); nuclear@14: if(err != CTM_NONE) nuclear@14: throw ctm_error(err); nuclear@14: } nuclear@14: nuclear@14: public: nuclear@14: /// Constructor nuclear@14: CTMexporter() nuclear@14: { nuclear@14: mContext = ctmNewContext(CTM_EXPORT); nuclear@14: } nuclear@14: nuclear@14: /// Destructor nuclear@14: ~CTMexporter() nuclear@14: { nuclear@14: ctmFreeContext(mContext); nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmCompressionMethod() nuclear@14: void CompressionMethod(CTMenum aMethod) nuclear@14: { nuclear@14: ctmCompressionMethod(mContext, aMethod); nuclear@14: CheckError(); nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmCompressionLevel() nuclear@14: void CompressionLevel(CTMuint aLevel) nuclear@14: { nuclear@14: ctmCompressionLevel(mContext, aLevel); nuclear@14: CheckError(); nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmVertexPrecision() nuclear@14: void VertexPrecision(CTMfloat aPrecision) nuclear@14: { nuclear@14: ctmVertexPrecision(mContext, aPrecision); nuclear@14: CheckError(); nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmVertexPrecisionRel() nuclear@14: void VertexPrecisionRel(CTMfloat aRelPrecision) nuclear@14: { nuclear@14: ctmVertexPrecisionRel(mContext, aRelPrecision); nuclear@14: CheckError(); nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmNormalPrecision() nuclear@14: void NormalPrecision(CTMfloat aPrecision) nuclear@14: { nuclear@14: ctmNormalPrecision(mContext, aPrecision); nuclear@14: CheckError(); nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmUVCoordPrecision() nuclear@14: void UVCoordPrecision(CTMenum aUVMap, CTMfloat aPrecision) nuclear@14: { nuclear@14: ctmUVCoordPrecision(mContext, aUVMap, aPrecision); nuclear@14: CheckError(); nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmAttribPrecision() nuclear@14: void AttribPrecision(CTMenum aAttribMap, CTMfloat aPrecision) nuclear@14: { nuclear@14: ctmAttribPrecision(mContext, aAttribMap, aPrecision); nuclear@14: CheckError(); nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmFileComment() nuclear@14: void FileComment(const char * aFileComment) nuclear@14: { nuclear@14: ctmFileComment(mContext, aFileComment); nuclear@14: CheckError(); nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmDefineMesh() nuclear@14: void DefineMesh(const CTMfloat * aVertices, CTMuint aVertexCount, nuclear@14: const CTMuint * aIndices, CTMuint aTriangleCount, nuclear@14: const CTMfloat * aNormals) nuclear@14: { nuclear@14: ctmDefineMesh(mContext, aVertices, aVertexCount, aIndices, aTriangleCount, nuclear@14: aNormals); nuclear@14: CheckError(); nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmAddUVMap() nuclear@14: CTMenum AddUVMap(const CTMfloat * aUVCoords, const char * aName, nuclear@14: const char * aFileName) nuclear@14: { nuclear@14: CTMenum res = ctmAddUVMap(mContext, aUVCoords, aName, aFileName); nuclear@14: CheckError(); nuclear@14: return res; nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmAddAttribMap() nuclear@14: CTMenum AddAttribMap(const CTMfloat * aAttribValues, const char * aName) nuclear@14: { nuclear@14: CTMenum res = ctmAddAttribMap(mContext, aAttribValues, aName); nuclear@14: CheckError(); nuclear@14: return res; nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmSave() nuclear@14: void Save(const char * aFileName) nuclear@14: { nuclear@14: ctmSave(mContext, aFileName); nuclear@14: CheckError(); nuclear@14: } nuclear@14: nuclear@14: /// Wrapper for ctmSaveCustom() nuclear@14: void SaveCustom(CTMwritefn aWriteFn, void * aUserData) nuclear@14: { nuclear@14: ctmSaveCustom(mContext, aWriteFn, aUserData); nuclear@14: CheckError(); nuclear@14: } nuclear@14: nuclear@14: // You can not copy nor assign from one CTMexporter object to another, since nuclear@14: // the object contains hidden state. By declaring these dummy prototypes nuclear@14: // without an implementation, you will at least get linker errors if you try nuclear@14: // to copy or assign a CTMexporter object. nuclear@14: CTMexporter(const CTMexporter& v); nuclear@14: CTMexporter& operator=(const CTMexporter& v); nuclear@14: }; nuclear@14: nuclear@14: #endif // __OPENCTMPP_H_ nuclear@14: nuclear@14: #endif // OPENCTM_NO_CPP