rev |
line source |
nuclear@14
|
1 //-----------------------------------------------------------------------------
|
nuclear@14
|
2 // Product: OpenCTM
|
nuclear@14
|
3 // File: openctmpp.h
|
nuclear@14
|
4 // Description: C++ wrapper for the OpenCTM API.
|
nuclear@14
|
5 //-----------------------------------------------------------------------------
|
nuclear@14
|
6 // Copyright (c) 2009-2010 Marcus Geelnard
|
nuclear@14
|
7 //
|
nuclear@14
|
8 // This software is provided 'as-is', without any express or implied
|
nuclear@14
|
9 // warranty. In no event will the authors be held liable for any damages
|
nuclear@14
|
10 // arising from the use of this software.
|
nuclear@14
|
11 //
|
nuclear@14
|
12 // Permission is granted to anyone to use this software for any purpose,
|
nuclear@14
|
13 // including commercial applications, and to alter it and redistribute it
|
nuclear@14
|
14 // freely, subject to the following restrictions:
|
nuclear@14
|
15 //
|
nuclear@14
|
16 // 1. The origin of this software must not be misrepresented; you must not
|
nuclear@14
|
17 // claim that you wrote the original software. If you use this software
|
nuclear@14
|
18 // in a product, an acknowledgment in the product documentation would be
|
nuclear@14
|
19 // appreciated but is not required.
|
nuclear@14
|
20 //
|
nuclear@14
|
21 // 2. Altered source versions must be plainly marked as such, and must not
|
nuclear@14
|
22 // be misrepresented as being the original software.
|
nuclear@14
|
23 //
|
nuclear@14
|
24 // 3. This notice may not be removed or altered from any source
|
nuclear@14
|
25 // distribution.
|
nuclear@14
|
26 //-----------------------------------------------------------------------------
|
nuclear@14
|
27
|
nuclear@14
|
28 // To disable C++ extensions, define OPENCTM_NO_CPP
|
nuclear@14
|
29 #ifndef OPENCTM_NO_CPP
|
nuclear@14
|
30
|
nuclear@14
|
31 #ifndef __OPENCTMPP_H_
|
nuclear@14
|
32 #define __OPENCTMPP_H_
|
nuclear@14
|
33
|
nuclear@14
|
34 // Just in case (if this file was included from outside openctm.h)...
|
nuclear@14
|
35 #ifndef __OPENCTM_H_
|
nuclear@14
|
36 #include "openctm.h"
|
nuclear@14
|
37 #endif
|
nuclear@14
|
38
|
nuclear@14
|
39 #include <exception>
|
nuclear@14
|
40
|
nuclear@14
|
41 /// OpenCTM exception. When an error occurs, a \c ctm_error exception is
|
nuclear@14
|
42 /// thrown. Its what() function returns the name of the OpenCTM error code
|
nuclear@14
|
43 /// (for instance "CTM_INVALID_OPERATION").
|
nuclear@14
|
44 class ctm_error: public std::exception
|
nuclear@14
|
45 {
|
nuclear@14
|
46 private:
|
nuclear@14
|
47 CTMenum mErrorCode;
|
nuclear@14
|
48
|
nuclear@14
|
49 public:
|
nuclear@14
|
50 explicit ctm_error(CTMenum aError)
|
nuclear@14
|
51 {
|
nuclear@14
|
52 mErrorCode = aError;
|
nuclear@14
|
53 }
|
nuclear@14
|
54
|
nuclear@14
|
55 virtual const char* what() const throw()
|
nuclear@14
|
56 {
|
nuclear@14
|
57 return ctmErrorString(mErrorCode);
|
nuclear@14
|
58 }
|
nuclear@14
|
59
|
nuclear@14
|
60 CTMenum error_code() const throw()
|
nuclear@14
|
61 {
|
nuclear@14
|
62 return mErrorCode;
|
nuclear@14
|
63 }
|
nuclear@14
|
64 };
|
nuclear@14
|
65
|
nuclear@14
|
66
|
nuclear@14
|
67 /// OpenCTM importer class. This is a C++ wrapper class for an OpenCTM import
|
nuclear@14
|
68 /// context. Usage example:
|
nuclear@14
|
69 ///
|
nuclear@14
|
70 /// @code
|
nuclear@14
|
71 /// // Create a new OpenCTM importer object
|
nuclear@14
|
72 /// CTMimporter ctm;
|
nuclear@14
|
73 ///
|
nuclear@14
|
74 /// // Load the OpenCTM file
|
nuclear@14
|
75 /// ctm.Load("mymesh.ctm");
|
nuclear@14
|
76 ///
|
nuclear@14
|
77 /// // Access the mesh data
|
nuclear@14
|
78 /// vertCount = ctm.GetInteger(CTM_VERTEX_COUNT);
|
nuclear@14
|
79 /// vertices = ctm.GetFloatArray(CTM_VERTICES);
|
nuclear@14
|
80 /// triCount = ctm.GetInteger(CTM_TRIANGLE_COUNT);
|
nuclear@14
|
81 /// indices = ctm.GetIntegerArray(CTM_INDICES);
|
nuclear@14
|
82 ///
|
nuclear@14
|
83 /// // Deal with the mesh (e.g. transcode it to our internal representation)
|
nuclear@14
|
84 /// // ...
|
nuclear@14
|
85 /// @endcode
|
nuclear@14
|
86
|
nuclear@14
|
87 class CTMimporter {
|
nuclear@14
|
88 private:
|
nuclear@14
|
89 /// The OpenCTM context handle.
|
nuclear@14
|
90 CTMcontext mContext;
|
nuclear@14
|
91
|
nuclear@14
|
92 /// Check for OpenCTM errors, and throw an exception if an error has
|
nuclear@14
|
93 /// occured.
|
nuclear@14
|
94 void CheckError()
|
nuclear@14
|
95 {
|
nuclear@14
|
96 CTMenum err = ctmGetError(mContext);
|
nuclear@14
|
97 if(err != CTM_NONE)
|
nuclear@14
|
98 throw ctm_error(err);
|
nuclear@14
|
99 }
|
nuclear@14
|
100
|
nuclear@14
|
101 public:
|
nuclear@14
|
102 /// Constructor
|
nuclear@14
|
103 CTMimporter()
|
nuclear@14
|
104 {
|
nuclear@14
|
105 mContext = ctmNewContext(CTM_IMPORT);
|
nuclear@14
|
106 }
|
nuclear@14
|
107
|
nuclear@14
|
108 /// Destructor
|
nuclear@14
|
109 ~CTMimporter()
|
nuclear@14
|
110 {
|
nuclear@14
|
111 ctmFreeContext(mContext);
|
nuclear@14
|
112 }
|
nuclear@14
|
113
|
nuclear@14
|
114 /// Wrapper for ctmGetInteger()
|
nuclear@14
|
115 CTMuint GetInteger(CTMenum aProperty)
|
nuclear@14
|
116 {
|
nuclear@14
|
117 CTMuint res = ctmGetInteger(mContext, aProperty);
|
nuclear@14
|
118 CheckError();
|
nuclear@14
|
119 return res;
|
nuclear@14
|
120 }
|
nuclear@14
|
121
|
nuclear@14
|
122 /// Wrapper for ctmGetFloat()
|
nuclear@14
|
123 CTMfloat GetFloat(CTMenum aProperty)
|
nuclear@14
|
124 {
|
nuclear@14
|
125 CTMfloat res = ctmGetFloat(mContext, aProperty);
|
nuclear@14
|
126 CheckError();
|
nuclear@14
|
127 return res;
|
nuclear@14
|
128 }
|
nuclear@14
|
129
|
nuclear@14
|
130 /// Wrapper for ctmGetIntegerArray()
|
nuclear@14
|
131 const CTMuint * GetIntegerArray(CTMenum aProperty)
|
nuclear@14
|
132 {
|
nuclear@14
|
133 const CTMuint * res = ctmGetIntegerArray(mContext, aProperty);
|
nuclear@14
|
134 CheckError();
|
nuclear@14
|
135 return res;
|
nuclear@14
|
136 }
|
nuclear@14
|
137
|
nuclear@14
|
138 /// Wrapper for ctmGetFloatArray()
|
nuclear@14
|
139 const CTMfloat * GetFloatArray(CTMenum aProperty)
|
nuclear@14
|
140 {
|
nuclear@14
|
141 const CTMfloat * res = ctmGetFloatArray(mContext, aProperty);
|
nuclear@14
|
142 CheckError();
|
nuclear@14
|
143 return res;
|
nuclear@14
|
144 }
|
nuclear@14
|
145
|
nuclear@14
|
146 /// Wrapper for ctmGetNamedUVMap()
|
nuclear@14
|
147 CTMenum GetNamedUVMap(const char * aName)
|
nuclear@14
|
148 {
|
nuclear@14
|
149 CTMenum res = ctmGetNamedUVMap(mContext, aName);
|
nuclear@14
|
150 CheckError();
|
nuclear@14
|
151 return res;
|
nuclear@14
|
152 }
|
nuclear@14
|
153
|
nuclear@14
|
154 /// Wrapper for ctmGetUVMapString()
|
nuclear@14
|
155 const char * GetUVMapString(CTMenum aUVMap, CTMenum aProperty)
|
nuclear@14
|
156 {
|
nuclear@14
|
157 const char * res = ctmGetUVMapString(mContext, aUVMap, aProperty);
|
nuclear@14
|
158 CheckError();
|
nuclear@14
|
159 return res;
|
nuclear@14
|
160 }
|
nuclear@14
|
161
|
nuclear@14
|
162 /// Wrapper for ctmGetUVMapFloat()
|
nuclear@14
|
163 CTMfloat GetUVMapFloat(CTMenum aUVMap, CTMenum aProperty)
|
nuclear@14
|
164 {
|
nuclear@14
|
165 CTMfloat res = ctmGetUVMapFloat(mContext, aUVMap, aProperty);
|
nuclear@14
|
166 CheckError();
|
nuclear@14
|
167 return res;
|
nuclear@14
|
168 }
|
nuclear@14
|
169
|
nuclear@14
|
170 /// Wrapper for ctmGetNamedAttribMap()
|
nuclear@14
|
171 CTMenum GetNamedAttribMap(const char * aName)
|
nuclear@14
|
172 {
|
nuclear@14
|
173 CTMenum res = ctmGetNamedAttribMap(mContext, aName);
|
nuclear@14
|
174 CheckError();
|
nuclear@14
|
175 return res;
|
nuclear@14
|
176 }
|
nuclear@14
|
177
|
nuclear@14
|
178 /// Wrapper for ctmGetAttribMapString()
|
nuclear@14
|
179 const char * GetAttribMapString(CTMenum aAttribMap, CTMenum aProperty)
|
nuclear@14
|
180 {
|
nuclear@14
|
181 const char * res = ctmGetAttribMapString(mContext, aAttribMap, aProperty);
|
nuclear@14
|
182 CheckError();
|
nuclear@14
|
183 return res;
|
nuclear@14
|
184 }
|
nuclear@14
|
185
|
nuclear@14
|
186 /// Wrapper for ctmGetAttribMapFloat()
|
nuclear@14
|
187 CTMfloat GetAttribMapFloat(CTMenum aAttribMap, CTMenum aProperty)
|
nuclear@14
|
188 {
|
nuclear@14
|
189 CTMfloat res = ctmGetAttribMapFloat(mContext, aAttribMap, aProperty);
|
nuclear@14
|
190 CheckError();
|
nuclear@14
|
191 return res;
|
nuclear@14
|
192 }
|
nuclear@14
|
193
|
nuclear@14
|
194 /// Wrapper for ctmGetString()
|
nuclear@14
|
195 const char * GetString(CTMenum aProperty)
|
nuclear@14
|
196 {
|
nuclear@14
|
197 const char * res = ctmGetString(mContext, aProperty);
|
nuclear@14
|
198 CheckError();
|
nuclear@14
|
199 return res;
|
nuclear@14
|
200 }
|
nuclear@14
|
201
|
nuclear@14
|
202 /// Wrapper for ctmLoad()
|
nuclear@14
|
203 void Load(const char * aFileName)
|
nuclear@14
|
204 {
|
nuclear@14
|
205 ctmLoad(mContext, aFileName);
|
nuclear@14
|
206 CheckError();
|
nuclear@14
|
207 }
|
nuclear@14
|
208
|
nuclear@14
|
209 /// Wrapper for ctmLoadCustom()
|
nuclear@14
|
210 void LoadCustom(CTMreadfn aReadFn, void * aUserData)
|
nuclear@14
|
211 {
|
nuclear@14
|
212 ctmLoadCustom(mContext, aReadFn, aUserData);
|
nuclear@14
|
213 CheckError();
|
nuclear@14
|
214 }
|
nuclear@14
|
215
|
nuclear@14
|
216 // You can not copy nor assign from one CTMimporter object to another, since
|
nuclear@14
|
217 // the object contains hidden state. By declaring these dummy prototypes
|
nuclear@14
|
218 // without an implementation, you will at least get linker errors if you try
|
nuclear@14
|
219 // to copy or assign a CTMimporter object.
|
nuclear@14
|
220 CTMimporter(const CTMimporter& v);
|
nuclear@14
|
221 CTMimporter& operator=(const CTMimporter& v);
|
nuclear@14
|
222 };
|
nuclear@14
|
223
|
nuclear@14
|
224
|
nuclear@14
|
225 /// OpenCTM exporter class. This is a C++ wrapper class for an OpenCTM export
|
nuclear@14
|
226 /// context. Usage example:
|
nuclear@14
|
227 /// @code
|
nuclear@14
|
228 /// void MySaveFile(CTMuint aVertCount, CTMuint aTriCount, CTMfloat * aVertices,
|
nuclear@14
|
229 /// CTMuint * aIndices, const char * aFileName)
|
nuclear@14
|
230 /// {
|
nuclear@14
|
231 /// // Create a new OpenCTM exporter object
|
nuclear@14
|
232 /// CTMexporter ctm;
|
nuclear@14
|
233 ///
|
nuclear@14
|
234 /// // Define our mesh representation to OpenCTM (store references to it in
|
nuclear@14
|
235 /// // the context)
|
nuclear@14
|
236 /// ctm.DefineMesh(aVertices, aVertCount, aIndices, aTriCount, NULL);
|
nuclear@14
|
237 ///
|
nuclear@14
|
238 /// // Save the OpenCTM file
|
nuclear@14
|
239 /// ctm.Save(aFileName);
|
nuclear@14
|
240 /// }
|
nuclear@14
|
241 /// @endcode
|
nuclear@14
|
242
|
nuclear@14
|
243 class CTMexporter {
|
nuclear@14
|
244 private:
|
nuclear@14
|
245 /// The OpenCTM context handle.
|
nuclear@14
|
246 CTMcontext mContext;
|
nuclear@14
|
247
|
nuclear@14
|
248 /// Check for OpenCTM errors, and throw an exception if an error has
|
nuclear@14
|
249 /// occured.
|
nuclear@14
|
250 void CheckError()
|
nuclear@14
|
251 {
|
nuclear@14
|
252 CTMenum err = ctmGetError(mContext);
|
nuclear@14
|
253 if(err != CTM_NONE)
|
nuclear@14
|
254 throw ctm_error(err);
|
nuclear@14
|
255 }
|
nuclear@14
|
256
|
nuclear@14
|
257 public:
|
nuclear@14
|
258 /// Constructor
|
nuclear@14
|
259 CTMexporter()
|
nuclear@14
|
260 {
|
nuclear@14
|
261 mContext = ctmNewContext(CTM_EXPORT);
|
nuclear@14
|
262 }
|
nuclear@14
|
263
|
nuclear@14
|
264 /// Destructor
|
nuclear@14
|
265 ~CTMexporter()
|
nuclear@14
|
266 {
|
nuclear@14
|
267 ctmFreeContext(mContext);
|
nuclear@14
|
268 }
|
nuclear@14
|
269
|
nuclear@14
|
270 /// Wrapper for ctmCompressionMethod()
|
nuclear@14
|
271 void CompressionMethod(CTMenum aMethod)
|
nuclear@14
|
272 {
|
nuclear@14
|
273 ctmCompressionMethod(mContext, aMethod);
|
nuclear@14
|
274 CheckError();
|
nuclear@14
|
275 }
|
nuclear@14
|
276
|
nuclear@14
|
277 /// Wrapper for ctmCompressionLevel()
|
nuclear@14
|
278 void CompressionLevel(CTMuint aLevel)
|
nuclear@14
|
279 {
|
nuclear@14
|
280 ctmCompressionLevel(mContext, aLevel);
|
nuclear@14
|
281 CheckError();
|
nuclear@14
|
282 }
|
nuclear@14
|
283
|
nuclear@14
|
284 /// Wrapper for ctmVertexPrecision()
|
nuclear@14
|
285 void VertexPrecision(CTMfloat aPrecision)
|
nuclear@14
|
286 {
|
nuclear@14
|
287 ctmVertexPrecision(mContext, aPrecision);
|
nuclear@14
|
288 CheckError();
|
nuclear@14
|
289 }
|
nuclear@14
|
290
|
nuclear@14
|
291 /// Wrapper for ctmVertexPrecisionRel()
|
nuclear@14
|
292 void VertexPrecisionRel(CTMfloat aRelPrecision)
|
nuclear@14
|
293 {
|
nuclear@14
|
294 ctmVertexPrecisionRel(mContext, aRelPrecision);
|
nuclear@14
|
295 CheckError();
|
nuclear@14
|
296 }
|
nuclear@14
|
297
|
nuclear@14
|
298 /// Wrapper for ctmNormalPrecision()
|
nuclear@14
|
299 void NormalPrecision(CTMfloat aPrecision)
|
nuclear@14
|
300 {
|
nuclear@14
|
301 ctmNormalPrecision(mContext, aPrecision);
|
nuclear@14
|
302 CheckError();
|
nuclear@14
|
303 }
|
nuclear@14
|
304
|
nuclear@14
|
305 /// Wrapper for ctmUVCoordPrecision()
|
nuclear@14
|
306 void UVCoordPrecision(CTMenum aUVMap, CTMfloat aPrecision)
|
nuclear@14
|
307 {
|
nuclear@14
|
308 ctmUVCoordPrecision(mContext, aUVMap, aPrecision);
|
nuclear@14
|
309 CheckError();
|
nuclear@14
|
310 }
|
nuclear@14
|
311
|
nuclear@14
|
312 /// Wrapper for ctmAttribPrecision()
|
nuclear@14
|
313 void AttribPrecision(CTMenum aAttribMap, CTMfloat aPrecision)
|
nuclear@14
|
314 {
|
nuclear@14
|
315 ctmAttribPrecision(mContext, aAttribMap, aPrecision);
|
nuclear@14
|
316 CheckError();
|
nuclear@14
|
317 }
|
nuclear@14
|
318
|
nuclear@14
|
319 /// Wrapper for ctmFileComment()
|
nuclear@14
|
320 void FileComment(const char * aFileComment)
|
nuclear@14
|
321 {
|
nuclear@14
|
322 ctmFileComment(mContext, aFileComment);
|
nuclear@14
|
323 CheckError();
|
nuclear@14
|
324 }
|
nuclear@14
|
325
|
nuclear@14
|
326 /// Wrapper for ctmDefineMesh()
|
nuclear@14
|
327 void DefineMesh(const CTMfloat * aVertices, CTMuint aVertexCount,
|
nuclear@14
|
328 const CTMuint * aIndices, CTMuint aTriangleCount,
|
nuclear@14
|
329 const CTMfloat * aNormals)
|
nuclear@14
|
330 {
|
nuclear@14
|
331 ctmDefineMesh(mContext, aVertices, aVertexCount, aIndices, aTriangleCount,
|
nuclear@14
|
332 aNormals);
|
nuclear@14
|
333 CheckError();
|
nuclear@14
|
334 }
|
nuclear@14
|
335
|
nuclear@14
|
336 /// Wrapper for ctmAddUVMap()
|
nuclear@14
|
337 CTMenum AddUVMap(const CTMfloat * aUVCoords, const char * aName,
|
nuclear@14
|
338 const char * aFileName)
|
nuclear@14
|
339 {
|
nuclear@14
|
340 CTMenum res = ctmAddUVMap(mContext, aUVCoords, aName, aFileName);
|
nuclear@14
|
341 CheckError();
|
nuclear@14
|
342 return res;
|
nuclear@14
|
343 }
|
nuclear@14
|
344
|
nuclear@14
|
345 /// Wrapper for ctmAddAttribMap()
|
nuclear@14
|
346 CTMenum AddAttribMap(const CTMfloat * aAttribValues, const char * aName)
|
nuclear@14
|
347 {
|
nuclear@14
|
348 CTMenum res = ctmAddAttribMap(mContext, aAttribValues, aName);
|
nuclear@14
|
349 CheckError();
|
nuclear@14
|
350 return res;
|
nuclear@14
|
351 }
|
nuclear@14
|
352
|
nuclear@14
|
353 /// Wrapper for ctmSave()
|
nuclear@14
|
354 void Save(const char * aFileName)
|
nuclear@14
|
355 {
|
nuclear@14
|
356 ctmSave(mContext, aFileName);
|
nuclear@14
|
357 CheckError();
|
nuclear@14
|
358 }
|
nuclear@14
|
359
|
nuclear@14
|
360 /// Wrapper for ctmSaveCustom()
|
nuclear@14
|
361 void SaveCustom(CTMwritefn aWriteFn, void * aUserData)
|
nuclear@14
|
362 {
|
nuclear@14
|
363 ctmSaveCustom(mContext, aWriteFn, aUserData);
|
nuclear@14
|
364 CheckError();
|
nuclear@14
|
365 }
|
nuclear@14
|
366
|
nuclear@14
|
367 // You can not copy nor assign from one CTMexporter object to another, since
|
nuclear@14
|
368 // the object contains hidden state. By declaring these dummy prototypes
|
nuclear@14
|
369 // without an implementation, you will at least get linker errors if you try
|
nuclear@14
|
370 // to copy or assign a CTMexporter object.
|
nuclear@14
|
371 CTMexporter(const CTMexporter& v);
|
nuclear@14
|
372 CTMexporter& operator=(const CTMexporter& v);
|
nuclear@14
|
373 };
|
nuclear@14
|
374
|
nuclear@14
|
375 #endif // __OPENCTMPP_H_
|
nuclear@14
|
376
|
nuclear@14
|
377 #endif // OPENCTM_NO_CPP
|