1/*
2Open Asset Import Library (assimp)
3----------------------------------------------------------------------
4
5Copyright (c) 2006-2017, assimp team
6
7All rights reserved.
8
9Redistribution and use of this software in source and binary forms,
10with or without modification, are permitted provided that the
11following conditions are met:
12
13* Redistributions of source code must retain the above
14 copyright notice, this list of conditions and the
15 following disclaimer.
16r
17* Redistributions in binary form must reproduce the above
18 copyright notice, this list of conditions and the
19 following disclaimer in the documentation and/or other
20 materials provided with the distribution.
21
22* Neither the name of the assimp team, nor the names of its
23 contributors may be used to endorse or promote products
24 derived from this software without specific prior
25 written permission of the assimp team.
26
27THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39----------------------------------------------------------------------
40*/
41
42/** @file FBXImporter.cpp
43 * @brief Implementation of the FBX importer.
44 */
45
46#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
47
48#include "FBXImporter.h"
49
50#include "FBXTokenizer.h"
51#include "FBXParser.h"
52#include "FBXUtil.h"
53#include "FBXDocument.h"
54#include "FBXConverter.h"
55
56#include "StreamReader.h"
57#include "MemoryIOWrapper.h"
58#include <assimp/Importer.hpp>
59#include <assimp/importerdesc.h>
60
61namespace Assimp {
62 template<> const char* LogFunctions<FBXImporter>::Prefix()
63 {
64 static auto prefix = "FBX: ";
65 return prefix;
66 }
67}
68
69using namespace Assimp;
70using namespace Assimp::Formatter;
71using namespace Assimp::FBX;
72
73namespace {
74static const aiImporterDesc desc = {
75 "Autodesk FBX Importer",
76 "",
77 "",
78 "",
79 aiImporterFlags_SupportTextFlavour,
80 0,
81 0,
82 0,
83 0,
84 "fbx"
85};
86}
87
88// ------------------------------------------------------------------------------------------------
89// Constructor to be privately used by #Importer
90FBXImporter::FBXImporter()
91{
92}
93
94// ------------------------------------------------------------------------------------------------
95// Destructor, private as well
96FBXImporter::~FBXImporter()
97{
98}
99
100// ------------------------------------------------------------------------------------------------
101// Returns whether the class can handle the format of the given file.
102bool FBXImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
103{
104 const std::string& extension = GetExtension(pFile);
105 if (extension == std::string( desc.mFileExtensions ) ) {
106 return true;
107 }
108
109 else if ((!extension.length() || checkSig) && pIOHandler) {
110 // at least ASCII-FBX files usually have a 'FBX' somewhere in their head
111 const char* tokens[] = {"fbx"};
112 return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
113 }
114 return false;
115}
116
117// ------------------------------------------------------------------------------------------------
118// List all extensions handled by this loader
119const aiImporterDesc* FBXImporter::GetInfo () const
120{
121 return &desc;
122}
123
124// ------------------------------------------------------------------------------------------------
125// Setup configuration properties for the loader
126void FBXImporter::SetupProperties(const Importer* pImp)
127{
128 settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
129 settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
130 settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
131 settings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true);
132 settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
133 settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
134 settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);
135 settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
136 settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
137 settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
138 settings.searchEmbeddedTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES, false);
139}
140
141// ------------------------------------------------------------------------------------------------
142// Imports the given file into the given scene structure.
143void FBXImporter::InternReadFile( const std::string& pFile,
144 aiScene* pScene, IOSystem* pIOHandler)
145{
146 std::unique_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb"));
147 if (!stream) {
148 ThrowException("Could not open file for reading");
149 }
150
151 // read entire file into memory - no streaming for this, fbx
152 // files can grow large, but the assimp output data structure
153 // then becomes very large, too. Assimp doesn't support
154 // streaming for its output data structures so the net win with
155 // streaming input data would be very low.
156 std::vector<char> contents;
157 contents.resize(stream->FileSize()+1);
158 stream->Read( &*contents.begin(), 1, contents.size()-1 );
159 contents[ contents.size() - 1 ] = 0;
160 const char* const begin = &*contents.begin();
161
162 // broadphase tokenizing pass in which we identify the core
163 // syntax elements of FBX (brackets, commas, key:value mappings)
164 TokenList tokens;
165 try {
166
167 bool is_binary = false;
168 if (!strncmp(begin,"Kaydara FBX Binary",18)) {
169 is_binary = true;
170 TokenizeBinary(tokens,begin,static_cast<unsigned int>(contents.size()));
171 }
172 else {
173 Tokenize(tokens,begin);
174 }
175
176 // use this information to construct a very rudimentary
177 // parse-tree representing the FBX scope structure
178 Parser parser(tokens, is_binary);
179
180 // take the raw parse-tree and convert it to a FBX DOM
181 Document doc(parser,settings);
182
183 // convert the FBX DOM to aiScene
184 ConvertToAssimpScene(pScene,doc);
185
186 std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
187 }
188 catch(std::exception&) {
189 std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
190 throw;
191 }
192}
193
194#endif // !ASSIMP_BUILD_NO_FBX_IMPORTER
195