Back to home page

EIC code displayed by LXR

 
 

    


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