C++ example:
#include <assimp.hpp> // C++ importer interface #include <aiScene.h> // Output data structure #include <aiPostProcess.h> // Post processing flags bool DoTheImportThing( const std::string& pFile) { // Create an instance of the Importer class Assimp::Importer importer; // And have it read the given file with some example postprocessing // Usually - if speed is not the most important aspect for you - you'll // propably to request more postprocessing than we do in this example. const aiScene* scene = importer.ReadFile( pFile, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_SortByPType); // If the import failed, report it if( !scene) { DoTheErrorLogging( importer.GetErrorString()); return false; } // Now we can access the file's contents. DoTheSceneProcessing( scene); // We're done. Everything will be cleaned up by the importer destructor return true; }
What exactly is read from the files and how you interpret it is described at the Data Structures page. The post processing steps that the ASSIMP library can apply to the imported data are listed at aiPostProcessSteps. See the pp Post proccessing page for more details.
Note that the aiScene data structure returned is declared 'const'. Yes, you can get rid of these 5 letters with a simple cast. Yes, you may do that. No, it's not recommended (and it's suicide in DLL builds if you try to use new or delete on any of the arrays in the scene).
C example:
#include <assimp.h> // Plain-C interface #include <aiScene.h> // Output data structure #include <aiPostProcess.h> // Post processing flags bool DoTheImportThing( const char* pFile) { // Start the import on the given file with some example postprocessing // Usually - if speed is not the most important aspect for you - you'll t // probably to request more postprocessing than we do in this example. const aiScene* scene = aiImportFile( pFile, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_SortByPType); // If the import failed, report it if( !scene) { DoTheErrorLogging( aiGetErrorString()); return false; } // Now we can access the file's contents DoTheSceneProcessing( scene); // We're done. Release all resources associated with this import aiReleaseImport( scene); return true; }
#include <IOStream.h> #include <IOSystem.h> // My own implementation of IOStream class MyIOStream : public ASSIMP::IOStream { friend class MyIOSystem; protected: // Constructor protected for private usage by MyIOSystem MyIOStream(void); public: ~MyIOStream(void); size_t Read( void* pvBuffer, size_t pSize, size_t pCount) { ... } size_t Write( const void* pvBuffer, size_t pSize, size_t pCount) { ... } aiReturn Seek( size_t pOffset, aiOrigin pOrigin) { ... } size_t Tell() const { ... } size_t FileSize() const { ... } void Flush () { ... } }; // Fisher Price - My First Filesystem class MyIOSystem : public ASSIMP::IOSystem { MyIOSystem() { ... } ~MyIOSystem() { ... } // Check whether a specific file exists bool Exists( const std::string& pFile) const { .. } // Get the path delimiter character we'd like to see char GetOsSeparator() const { return '/'; } // ... and finally a method to open a custom stream IOStream* Open( const std::string& pFile, const std::string& pMode) { return new MyIOStream( ... ); } void Close( IOStream* pFile) { delete pFile; } };
Now that your IO system is implemented, supply an instance of it to the Importer object by calling Assimp::Importer::SetIOHandler().
void DoTheImportThing( const std::string& pFile) { Assimp::Importer importer; // put my custom IO handling in place importer.SetIOHandler( new MyIOSystem()); // the import process will now use this implementation to access any file importer.ReadFile( pFile, SomeFlag | SomeOtherFlag); }
See the Single-threaded build section to learn how to build a lightweight variant of ASSIMP which is not thread-safe and does not utilize multiple threads for loading.
using namespace Assimp; // Create a logger instance DefaultLogger::create("",Logger::VERBOSE); // Now I am ready for logging my stuff DefaultLogger::get()->info("this is my info-call"); // Kill it after the work is done DefaultLogger::kill();
At first you have to create the default-logger-instance (create). Now you are ready to rock and can log a little bit around. After that you should kill it to release the singleton instance.
If you want to integrate the ASSIMP-log into your own GUI it my be helpful to have a mechanism writing the logs into your own log windows. The logger interface provides this by implementing an interface called LogStream. You can attach and detach this log stream to the default-logger instance or any implementation derived from Logger. Just derivate your own logger from the abstract base class LogStream and overwrite the write-method:
// Example stream class myStream : public LogStream { public: // Constructor myStream() { // empty } // Destructor ~myStream() { // empty } // Write womethink using your own functionality void write(const char* message) { ::printf("%s\n", message); } }; // Select the kinds of messages you want to receive on this log stream const unsigned int severity = Logger::DEBUGGING|Logger::INFO|Logger::ERR|Logger::WARN; // Attaching it to the default logger Assimp::DefaultLogger::get()->attachStream( new myStream(), severity );
The severity level controls the kind of message which will be written into the attached stream. If you just want to log errors and warnings set the warn and error severity flag for those severities. It is also possible to remove a self defined logstream from an error severity by detaching it with the severity flag set:
unsigned int severity = 0; severity |= Logger::DEBUGGING; // Detach debug messages from you self defined stream Assimp::DefaultLogger::get()->attachStream( new myStream(), severity );
If you want to implement your own logger just derive from the abstract base class Logger and overwrite the methods debug, info, warn and error.
If you want to see the debug-messages in a debug-configured build, the Logger-interface provides a logging-severity. You can set it calling the following method:
Assimp::DefaultLogger::get()->setLogSeverity( LogSeverity log_severity );
The normal logging severity supports just the basic stuff like, info, warnings and errors. In the verbose level very fine-grained debug messages will be logged, too. Note that this kind kind of logging might decrease import performance.