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