vrshoot

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