![]() |
|
|||
File indexing completed on 2025-02-21 09:30:07
0001 /* 0002 Open Asset Import Library (assimp) 0003 ---------------------------------------------------------------------- 0004 0005 Copyright (c) 2006-2024, assimp team 0006 0007 All rights reserved. 0008 0009 Redistribution and use of this software in source and binary forms, 0010 with or without modification, are permitted provided that the 0011 following conditions are met: 0012 0013 * Redistributions of source code must retain the above 0014 copyright notice, this list of conditions and the 0015 following disclaimer. 0016 0017 * Redistributions in binary form must reproduce the above 0018 copyright notice, this list of conditions and the 0019 following disclaimer in the documentation and/or other 0020 materials provided with the distribution. 0021 0022 * Neither the name of the assimp team, nor the names of its 0023 contributors may be used to endorse or promote products 0024 derived from this software without specific prior 0025 written permission of the assimp team. 0026 0027 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 0028 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 0029 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 0030 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 0031 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 0032 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 0033 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0034 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0035 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0036 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0037 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0038 0039 ---------------------------------------------------------------------- 0040 */ 0041 0042 /// @file Definition of the base class for all importer worker classes. 0043 0044 #pragma once 0045 #ifndef INCLUDED_AI_BASEIMPORTER_H 0046 #define INCLUDED_AI_BASEIMPORTER_H 0047 0048 #ifdef __GNUC__ 0049 #pragma GCC system_header 0050 #endif 0051 0052 #include "Exceptional.h" 0053 0054 #include <assimp/types.h> 0055 #include <assimp/ProgressHandler.hpp> 0056 #include <exception> 0057 #include <set> 0058 #include <vector> 0059 #include <memory> 0060 0061 struct aiScene; 0062 struct aiImporterDesc; 0063 0064 namespace Assimp { 0065 0066 // Forward declarations 0067 class Importer; 0068 class IOSystem; 0069 class BaseProcess; 0070 class SharedPostProcessInfo; 0071 class IOStream; 0072 0073 // utility to do char4 to uint32 in a portable manner 0074 #define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \ 0075 (string[1] << 16) + (string[2] << 8) + string[3])) 0076 0077 using UByteBuffer = std::vector<uint8_t>; 0078 using ByteBuffer = std::vector<int8_t>; 0079 0080 // --------------------------------------------------------------------------- 0081 /** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface 0082 * for all importer worker classes. 0083 * 0084 * The interface defines two functions: CanRead() is used to check if the 0085 * importer can handle the format of the given file. If an implementation of 0086 * this function returns true, the importer then calls ReadFile() which 0087 * imports the given file. ReadFile is not overridable, it just calls 0088 * InternReadFile() and catches any ImportErrorException that might occur. 0089 */ 0090 class ASSIMP_API BaseImporter { 0091 friend class Importer; 0092 0093 public: 0094 /** Constructor to be privately used by #Importer */ 0095 BaseImporter() AI_NO_EXCEPT; 0096 0097 /** Destructor, private as well */ 0098 virtual ~BaseImporter() = default; 0099 0100 // ------------------------------------------------------------------- 0101 /** Returns whether the class can handle the format of the given file. 0102 * 0103 * The implementation is expected to perform a full check of the file 0104 * structure, possibly searching the first bytes of the file for magic 0105 * identifiers or keywords. 0106 * 0107 * @param pFile Path and file name of the file to be examined. 0108 * @param pIOHandler The IO handler to use for accessing any file. 0109 * @param checkSig Legacy; do not use. 0110 * @return true if the class can read this file, false if not or if 0111 * unsure. 0112 */ 0113 virtual bool CanRead( 0114 const std::string &pFile, 0115 IOSystem *pIOHandler, 0116 bool checkSig) const = 0; 0117 0118 // ------------------------------------------------------------------- 0119 /** Imports the given file and returns the imported data. 0120 * If the import succeeds, ownership of the data is transferred to 0121 * the caller. If the import fails, nullptr is returned. The function 0122 * takes care that any partially constructed data is destroyed 0123 * beforehand. 0124 * 0125 * @param pImp #Importer object hosting this loader. 0126 * @param pFile Path of the file to be imported. 0127 * @param pIOHandler IO-Handler used to open this and possible other files. 0128 * @return The imported data or nullptr if failed. If it failed a 0129 * human-readable error description can be retrieved by calling 0130 * GetErrorText() 0131 * 0132 * @note This function is not intended to be overridden. Implement 0133 * InternReadFile() to do the import. If an exception is thrown somewhere 0134 * in InternReadFile(), this function will catch it and transform it into 0135 * a suitable response to the caller. 0136 */ 0137 aiScene *ReadFile( 0138 Importer *pImp, 0139 const std::string &pFile, 0140 IOSystem *pIOHandler); 0141 0142 // ------------------------------------------------------------------- 0143 /** Returns the error description of the last error that occurred. 0144 * If the error is due to a std::exception, this will return the message. 0145 * Exceptions can also be accessed with GetException(). 0146 * @return A description of the last error that occurred. An empty 0147 * string if there was no error. 0148 */ 0149 const std::string &GetErrorText() const { 0150 return m_ErrorText; 0151 } 0152 0153 // ------------------------------------------------------------------- 0154 /** Returns the exception of the last exception that occurred. 0155 * Note: Exceptions are not the only source of error details, so GetErrorText 0156 * should be consulted too. 0157 * @return The last exception that occurred. 0158 */ 0159 const std::exception_ptr& GetException() const { 0160 return m_Exception; 0161 } 0162 0163 // ------------------------------------------------------------------- 0164 /** Called prior to ReadFile(). 0165 * The function is a request to the importer to update its configuration 0166 * basing on the Importer's configuration property list. 0167 * @param pImp Importer instance 0168 */ 0169 virtual void SetupProperties( 0170 const Importer *pImp); 0171 0172 // ------------------------------------------------------------------- 0173 /** Called by #Importer::GetImporterInfo to get a description of 0174 * some loader features. Importers must provide this information. */ 0175 virtual const aiImporterDesc *GetInfo() const = 0; 0176 0177 /** 0178 * Will be called only by scale process when scaling is requested. 0179 */ 0180 void SetFileScale(double scale) { 0181 fileScale = scale; 0182 } 0183 0184 // ------------------------------------------------------------------- 0185 /** Called by #Importer::GetExtensionList for each loaded importer. 0186 * Take the extension list contained in the structure returned by 0187 * #GetInfo and insert all file extensions into the given set. 0188 * @param extension set to collect file extensions in*/ 0189 void GetExtensionList(std::set<std::string> &extensions); 0190 0191 protected: 0192 double importerScale = 1.0; 0193 double fileScale = 1.0; 0194 0195 // ------------------------------------------------------------------- 0196 /** Imports the given file into the given scene structure. The 0197 * function is expected to throw an ImportErrorException if there is 0198 * an error. If it terminates normally, the data in aiScene is 0199 * expected to be correct. Override this function to implement the 0200 * actual importing. 0201 * <br> 0202 * The output scene must meet the following requirements:<br> 0203 * <ul> 0204 * <li>At least a root node must be there, even if its only purpose 0205 * is to reference one mesh.</li> 0206 * <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives 0207 * in the mesh are determined automatically in this case.</li> 0208 * <li>the vertex data is stored in a pseudo-indexed "verbose" format. 0209 * In fact this means that every vertex that is referenced by 0210 * a face is unique. Or the other way round: a vertex index may 0211 * not occur twice in a single aiMesh.</li> 0212 * <li>aiAnimation::mDuration may be -1. Assimp determines the length 0213 * of the animation automatically in this case as the length of 0214 * the longest animation channel.</li> 0215 * <li>aiMesh::mBitangents may be nullptr if tangents and normals are 0216 * given. In this case bitangents are computed as the cross product 0217 * between normal and tangent.</li> 0218 * <li>There needn't be a material. If none is there a default material 0219 * is generated. However, it is recommended practice for loaders 0220 * to generate a default material for yourself that matches the 0221 * default material setting for the file format better than Assimp's 0222 * generic default material. Note that default materials *should* 0223 * be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded 0224 * or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy) 0225 * texture. </li> 0226 * </ul> 0227 * If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul> 0228 * <li> at least one mesh must be there</li> 0229 * <li> there may be no meshes with 0 vertices or faces</li> 0230 * </ul> 0231 * This won't be checked (except by the validation step): Assimp will 0232 * crash if one of the conditions is not met! 0233 * 0234 * @param pFile Path of the file to be imported. 0235 * @param pScene The scene object to hold the imported data. 0236 * nullptr is not a valid parameter. 0237 * @param pIOHandler The IO handler to use for any file access. 0238 * nullptr is not a valid parameter. */ 0239 virtual void InternReadFile( 0240 const std::string &pFile, 0241 aiScene *pScene, 0242 IOSystem *pIOHandler) = 0; 0243 0244 public: // static utilities 0245 // ------------------------------------------------------------------- 0246 /** A utility for CanRead(). 0247 * 0248 * The function searches the header of a file for a specific token 0249 * and returns true if this token is found. This works for text 0250 * files only. There is a rudimentary handling of UNICODE files. 0251 * The comparison is case independent. 0252 * 0253 * @param pIOSystem IO System to work with 0254 * @param file File name of the file 0255 * @param tokens List of tokens to search for 0256 * @param numTokens Size of the token array 0257 * @param searchBytes Number of bytes to be searched for the tokens. 0258 */ 0259 static bool SearchFileHeaderForToken( 0260 IOSystem *pIOSystem, 0261 const std::string &file, 0262 const char **tokens, 0263 std::size_t numTokens, 0264 unsigned int searchBytes = 200, 0265 bool tokensSol = false, 0266 bool noGraphBeforeTokens = false); 0267 0268 // ------------------------------------------------------------------- 0269 /** @brief Check whether a file has a specific file extension 0270 * @param pFile Input file 0271 * @param ext0 Extension to check for. Lowercase characters only, no dot! 0272 * @param ext1 Optional second extension 0273 * @param ext2 Optional third extension 0274 * @note Case-insensitive 0275 */ 0276 static bool SimpleExtensionCheck( 0277 const std::string &pFile, 0278 const char *ext0, 0279 const char *ext1 = nullptr, 0280 const char *ext2 = nullptr, 0281 const char *ext3 = nullptr); 0282 0283 // ------------------------------------------------------------------- 0284 /** @brief Check whether a file has one of the passed file extensions 0285 * @param pFile Input file 0286 * @param extensions Extensions to check for. Lowercase characters only, no dot! 0287 * @note Case-insensitive 0288 */ 0289 static bool HasExtension( 0290 const std::string &pFile, 0291 const std::set<std::string> &extensions); 0292 0293 // ------------------------------------------------------------------- 0294 /** @brief Extract file extension from a string 0295 * @param pFile Input file 0296 * @return Extension without trailing dot, all lowercase 0297 */ 0298 static std::string GetExtension( 0299 const std::string &pFile); 0300 0301 // ------------------------------------------------------------------- 0302 /** @brief Check whether a file starts with one or more magic tokens 0303 * @param pFile Input file 0304 * @param pIOHandler IO system to be used 0305 * @param magic n magic tokens 0306 * @params num Size of magic 0307 * @param offset Offset from file start where tokens are located 0308 * @param Size of one token, in bytes. Maximally 16 bytes. 0309 * @return true if one of the given tokens was found 0310 * 0311 * @note For convenience, the check is also performed for the 0312 * byte-swapped variant of all tokens (big endian). Only for 0313 * tokens of size 2,4. 0314 */ 0315 static bool CheckMagicToken( 0316 IOSystem *pIOHandler, 0317 const std::string &pFile, 0318 const void *magic, 0319 std::size_t num, 0320 unsigned int offset = 0, 0321 unsigned int size = 4); 0322 0323 // ------------------------------------------------------------------- 0324 /** An utility for all text file loaders. It converts a file to our 0325 * UTF8 character set. Errors are reported, but ignored. 0326 * 0327 * @param data File buffer to be converted to UTF8 data. The buffer 0328 * is resized as appropriate. */ 0329 static void ConvertToUTF8( 0330 std::vector<char> &data); 0331 0332 // ------------------------------------------------------------------- 0333 /** An utility for all text file loaders. It converts a file from our 0334 * UTF8 character set back to ISO-8859-1. Errors are reported, but ignored. 0335 * 0336 * @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer 0337 * is resized as appropriate. */ 0338 static void ConvertUTF8toISO8859_1( 0339 std::string &data); 0340 0341 // ------------------------------------------------------------------- 0342 /// @brief Enum to define, if empty files are ok or not. 0343 enum TextFileMode { 0344 ALLOW_EMPTY, 0345 FORBID_EMPTY 0346 }; 0347 0348 // ------------------------------------------------------------------- 0349 /** Utility for text file loaders which copies the contents of the 0350 * file into a memory buffer and converts it to our UTF8 0351 * representation. 0352 * @param stream Stream to read from. 0353 * @param data Output buffer to be resized and filled with the 0354 * converted text file data. The buffer is terminated with 0355 * a binary 0. 0356 * @param mode Whether it is OK to load empty text files. */ 0357 static void TextFileToBuffer( 0358 IOStream *stream, 0359 std::vector<char> &data, 0360 TextFileMode mode = FORBID_EMPTY); 0361 0362 // ------------------------------------------------------------------- 0363 /** Utility function to move a std::vector into a aiScene array 0364 * @param vec The vector to be moved 0365 * @param out The output pointer to the allocated array. 0366 * @param numOut The output count of elements copied. */ 0367 template <typename T> 0368 AI_FORCE_INLINE static void CopyVector( 0369 std::vector<T> &vec, 0370 T *&out, 0371 unsigned int &outLength) { 0372 outLength = unsigned(vec.size()); 0373 if (outLength) { 0374 out = new T[outLength]; 0375 std::swap_ranges(vec.begin(), vec.end(), out); 0376 } 0377 } 0378 0379 // ------------------------------------------------------------------- 0380 /** Utility function to move a std::vector of unique_ptrs into a aiScene array 0381 * @param vec The vector of unique_ptrs to be moved 0382 * @param out The output pointer to the allocated array. 0383 * @param numOut The output count of elements copied. */ 0384 template <typename T> 0385 AI_FORCE_INLINE static void CopyVector( 0386 std::vector<std::unique_ptr<T> > &vec, 0387 T **&out, 0388 unsigned int &outLength) { 0389 outLength = unsigned(vec.size()); 0390 if (outLength) { 0391 out = new T*[outLength]; 0392 T** outPtr = out; 0393 std::for_each(vec.begin(), vec.end(), [&outPtr](std::unique_ptr<T>& uPtr){*outPtr = uPtr.release(); ++outPtr; }); 0394 } 0395 } 0396 0397 private: 0398 /* Pushes state into importer for the importer scale */ 0399 void UpdateImporterScale(Importer *pImp); 0400 0401 protected: 0402 /// Error description in case there was one. 0403 std::string m_ErrorText; 0404 /// The exception, in case there was one. 0405 std::exception_ptr m_Exception; 0406 /// Currently set progress handler. 0407 ProgressHandler *m_progress; 0408 }; 0409 0410 } // end of namespace Assimp 0411 0412 #endif // AI_BASEIMPORTER_H_INC
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |