miniassimp

annotate include/miniassimp/BaseImporter.h @ 0:879c81d94345

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 28 Jan 2019 18:19:26 +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-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