vrshoot

view libs/assimp/BaseImporter.h @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line source
1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
5 Copyright (c) 2006-2012, assimp team
6 All rights reserved.
8 Redistribution and use of this software in source and binary forms,
9 with or without modification, are permitted provided that the
10 following conditions are met:
12 * Redistributions of source code must retain the above
13 copyright notice, this list of conditions and the
14 following disclaimer.
16 * Redistributions in binary form must reproduce the above
17 copyright notice, this list of conditions and the
18 following disclaimer in the documentation and/or other
19 materials provided with the distribution.
21 * Neither the name of the assimp team, nor the names of its
22 contributors may be used to endorse or promote products
23 derived from this software without specific prior
24 written permission of the assimp team.
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 ----------------------------------------------------------------------
39 */
41 /** @file Definition of the base class for all importer worker classes. */
42 #ifndef INCLUDED_AI_BASEIMPORTER_H
43 #define INCLUDED_AI_BASEIMPORTER_H
45 #include "Exceptional.h"
47 #include <string>
48 #include <map>
49 #include <vector>
50 #include "assimp/types.h"
52 struct aiScene;
54 namespace Assimp {
56 class IOSystem;
57 class Importer;
58 class BaseImporter;
59 class BaseProcess;
60 class SharedPostProcessInfo;
61 class IOStream;
63 // utility to do char4 to uint32 in a portable manner
64 #define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
65 (string[1] << 16) + (string[2] << 8) + string[3]))
67 // ---------------------------------------------------------------------------
68 template <typename T>
69 struct ScopeGuard
70 {
71 ScopeGuard(T* obj) : obj(obj), mdismiss() {}
72 ~ScopeGuard () throw() {
73 if (!mdismiss) {
74 delete obj;
75 }
76 obj = NULL;
77 }
79 T* dismiss() {
80 mdismiss=true;
81 return obj;
82 }
84 operator T*() {
85 return obj;
86 }
88 T* operator -> () {
89 return obj;
90 }
92 private:
93 T* obj;
94 bool mdismiss;
95 };
99 // ---------------------------------------------------------------------------
100 /** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface
101 * for all importer worker classes.
102 *
103 * The interface defines two functions: CanRead() is used to check if the
104 * importer can handle the format of the given file. If an implementation of
105 * this function returns true, the importer then calls ReadFile() which
106 * imports the given file. ReadFile is not overridable, it just calls
107 * InternReadFile() and catches any ImportErrorException that might occur.
108 */
109 class BaseImporter
110 {
111 friend class Importer;
113 public:
115 /** Constructor to be privately used by #Importer */
116 BaseImporter();
118 /** Destructor, private as well */
119 virtual ~BaseImporter();
121 public:
122 // -------------------------------------------------------------------
123 /** Returns whether the class can handle the format of the given file.
124 *
125 * The implementation should be as quick as possible. A check for
126 * the file extension is enough. If no suitable loader is found with
127 * this strategy, CanRead() is called again, the 'checkSig' parameter
128 * set to true this time. Now the implementation is expected to
129 * perform a full check of the file structure, possibly searching the
130 * first bytes of the file for magic identifiers or keywords.
131 *
132 * @param pFile Path and file name of the file to be examined.
133 * @param pIOHandler The IO handler to use for accessing any file.
134 * @param checkSig Set to true if this method is called a second time.
135 * This time, the implementation may take more time to examine the
136 * contents of the file to be loaded for magic bytes, keywords, etc
137 * to be able to load files with unknown/not existent file extensions.
138 * @return true if the class can read this file, false if not.
139 */
140 virtual bool CanRead(
141 const std::string& pFile,
142 IOSystem* pIOHandler,
143 bool checkSig
144 ) const = 0;
146 // -------------------------------------------------------------------
147 /** Imports the given file and returns the imported data.
148 * If the import succeeds, ownership of the data is transferred to
149 * the caller. If the import fails, NULL is returned. The function
150 * takes care that any partially constructed data is destroyed
151 * beforehand.
152 *
153 * @param pImp #Importer object hosting this loader.
154 * @param pFile Path of the file to be imported.
155 * @param pIOHandler IO-Handler used to open this and possible other files.
156 * @return The imported data or NULL if failed. If it failed a
157 * human-readable error description can be retrieved by calling
158 * GetErrorText()
159 *
160 * @note This function is not intended to be overridden. Implement
161 * InternReadFile() to do the import. If an exception is thrown somewhere
162 * in InternReadFile(), this function will catch it and transform it into
163 * a suitable response to the caller.
164 */
165 aiScene* ReadFile(
166 const Importer* pImp,
167 const std::string& pFile,
168 IOSystem* pIOHandler
169 );
171 // -------------------------------------------------------------------
172 /** Returns the error description of the last error that occured.
173 * @return A description of the last error that occured. An empty
174 * string if there was no error.
175 */
176 const std::string& GetErrorText() const {
177 return mErrorText;
178 }
180 // -------------------------------------------------------------------
181 /** Called prior to ReadFile().
182 * The function is a request to the importer to update its configuration
183 * basing on the Importer's configuration property list.
184 * @param pImp Importer instance
185 */
186 virtual void SetupProperties(
187 const Importer* pImp
188 );
191 // -------------------------------------------------------------------
192 /** Called by #Importer::GetImporterInfo to get a description of
193 * some loader features. Importers must provide this information. */
194 virtual const aiImporterDesc* GetInfo() const = 0;
198 // -------------------------------------------------------------------
199 /** Called by #Importer::GetExtensionList for each loaded importer.
200 * Take the extension list contained in the structure returned by
201 * #GetInfo and insert all file extensions into the given set.
202 * @param extension set to collect file extensions in*/
203 void GetExtensionList(std::set<std::string>& extensions);
205 protected:
207 // -------------------------------------------------------------------
208 /** Imports the given file into the given scene structure. The
209 * function is expected to throw an ImportErrorException if there is
210 * an error. If it terminates normally, the data in aiScene is
211 * expected to be correct. Override this function to implement the
212 * actual importing.
213 * <br>
214 * The output scene must meet the following requirements:<br>
215 * <ul>
216 * <li>At least a root node must be there, even if its only purpose
217 * is to reference one mesh.</li>
218 * <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives
219 * in the mesh are determined automatically in this case.</li>
220 * <li>the vertex data is stored in a pseudo-indexed "verbose" format.
221 * In fact this means that every vertex that is referenced by
222 * a face is unique. Or the other way round: a vertex index may
223 * not occur twice in a single aiMesh.</li>
224 * <li>aiAnimation::mDuration may be -1. Assimp determines the length
225 * of the animation automatically in this case as the length of
226 * the longest animation channel.</li>
227 * <li>aiMesh::mBitangents may be NULL if tangents and normals are
228 * given. In this case bitangents are computed as the cross product
229 * between normal and tangent.</li>
230 * <li>There needn't be a material. If none is there a default material
231 * is generated. However, it is recommended practice for loaders
232 * to generate a default material for yourself that matches the
233 * default material setting for the file format better than Assimp's
234 * generic default material. Note that default materials *should*
235 * be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded
236 * or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy)
237 * texture. </li>
238 * </ul>
239 * If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul>
240 * <li> at least one mesh must be there</li>
241 * <li> there may be no meshes with 0 vertices or faces</li>
242 * </ul>
243 * This won't be checked (except by the validation step): Assimp will
244 * crash if one of the conditions is not met!
245 *
246 * @param pFile Path of the file to be imported.
247 * @param pScene The scene object to hold the imported data.
248 * NULL is not a valid parameter.
249 * @param pIOHandler The IO handler to use for any file access.
250 * NULL is not a valid parameter. */
251 virtual void InternReadFile(
252 const std::string& pFile,
253 aiScene* pScene,
254 IOSystem* pIOHandler
255 ) = 0;
257 public: // static utilities
259 // -------------------------------------------------------------------
260 /** A utility for CanRead().
261 *
262 * The function searches the header of a file for a specific token
263 * and returns true if this token is found. This works for text
264 * files only. There is a rudimentary handling of UNICODE files.
265 * The comparison is case independent.
266 *
267 * @param pIOSystem IO System to work with
268 * @param file File name of the file
269 * @param tokens List of tokens to search for
270 * @param numTokens Size of the token array
271 * @param searchBytes Number of bytes to be searched for the tokens.
272 */
273 static bool SearchFileHeaderForToken(
274 IOSystem* pIOSystem,
275 const std::string& file,
276 const char** tokens,
277 unsigned int numTokens,
278 unsigned int searchBytes = 200,
279 bool tokensSol = false);
281 // -------------------------------------------------------------------
282 /** @brief Check whether a file has a specific file extension
283 * @param pFile Input file
284 * @param ext0 Extension to check for. Lowercase characters only, no dot!
285 * @param ext1 Optional second extension
286 * @param ext2 Optional third extension
287 * @note Case-insensitive
288 */
289 static bool SimpleExtensionCheck (
290 const std::string& pFile,
291 const char* ext0,
292 const char* ext1 = NULL,
293 const char* ext2 = NULL);
295 // -------------------------------------------------------------------
296 /** @brief Extract file extension from a string
297 * @param pFile Input file
298 * @return Extension without trailing dot, all lowercase
299 */
300 static std::string GetExtension (
301 const std::string& pFile);
303 // -------------------------------------------------------------------
304 /** @brief Check whether a file starts with one or more magic tokens
305 * @param pFile Input file
306 * @param pIOHandler IO system to be used
307 * @param magic n magic tokens
308 * @params num Size of magic
309 * @param offset Offset from file start where tokens are located
310 * @param Size of one token, in bytes. Maximally 16 bytes.
311 * @return true if one of the given tokens was found
312 *
313 * @note For convinence, the check is also performed for the
314 * byte-swapped variant of all tokens (big endian). Only for
315 * tokens of size 2,4.
316 */
317 static bool CheckMagicToken(
318 IOSystem* pIOHandler,
319 const std::string& pFile,
320 const void* magic,
321 unsigned int num,
322 unsigned int offset = 0,
323 unsigned int size = 4);
325 // -------------------------------------------------------------------
326 /** An utility for all text file loaders. It converts a file to our
327 * UTF8 character set. Errors are reported, but ignored.
328 *
329 * @param data File buffer to be converted to UTF8 data. The buffer
330 * is resized as appropriate. */
331 static void ConvertToUTF8(
332 std::vector<char>& data);
334 // -------------------------------------------------------------------
335 /** Utility for text file loaders which copies the contents of the
336 * file into a memory buffer and converts it to our UTF8
337 * representation.
338 * @param stream Stream to read from.
339 * @param data Output buffer to be resized and filled with the
340 * converted text file data. The buffer is terminated with
341 * a binary 0. */
342 static void TextFileToBuffer(
343 IOStream* stream,
344 std::vector<char>& data);
346 protected:
348 /** Error description in case there was one. */
349 std::string mErrorText;
351 /** Currently set progress handler */
352 ProgressHandler* progress;
353 };
357 } // end of namespace Assimp
359 #endif // AI_BASEIMPORTER_H_INC