Jelajahi Sumber

Merge pull request #1091 from assimp/issue_1089

FBX: woraround for issue 1089.
Kim Kulling 8 tahun lalu
induk
melakukan
573c8b1cb1

+ 3 - 3
CMakeLists.txt

@@ -168,14 +168,14 @@ IF((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT CMAKE_COMPILER_
      SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
   ENDIF()
   # hide all not-exported symbols
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -std=c++0x" )
+  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -Wall -std=c++0x" )
 ELSEIF(MSVC)
   # enable multi-core compilation with MSVC
   add_compile_options(/MP)
 ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -pedantic -std=c++11" )
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -Wall -Wno-long-long -pedantic -std=c++11" )
 ELSEIF( CMAKE_COMPILER_IS_MINGW )
-	SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -pedantic -std=c++11" )
+  SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -pedantic -std=c++11" )
 ENDIF()
 
 if (ASSIMP_COVERALLS)

+ 9 - 9
code/FBXBinaryTokenizer.cpp

@@ -146,18 +146,20 @@ void TokenizeError(const std::string& message, const char* begin, const char* cu
 // ------------------------------------------------------------------------------------------------
 uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
 {
-    if(Offset(cursor, end) < 4) {
+    const size_t k_to_read = sizeof( uint32_t );
+    if(Offset(cursor, end) < k_to_read ) {
         TokenizeError("cannot ReadWord, out of bounds",input, cursor);
     }
 
     uint32_t word = *reinterpret_cast<const uint32_t*>(cursor);
     AI_SWAP4(word);
 
-    cursor += 4;
+    cursor += k_to_read;
 
     return word;
 }
 
+// ------------------------------------------------------------------------------------------------
 uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end)
 {
     const size_t k_to_read = sizeof(uint64_t);
@@ -177,7 +179,7 @@ uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end)
 // ------------------------------------------------------------------------------------------------
 uint8_t ReadByte(const char* input, const char*& cursor, const char* end)
 {
-    if(Offset(cursor, end) < 1) {
+    if(Offset(cursor, end) < sizeof( uint8_t ) ) {
         TokenizeError("cannot ReadByte, out of bounds",input, cursor);
     }
 
@@ -220,8 +222,6 @@ unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const ch
     return length;
 }
 
-
-
 // ------------------------------------------------------------------------------------------------
 void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end)
 {
@@ -345,7 +345,7 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
 bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end, uint32_t const flags)
 {
     // the first word contains the offset at which this block ends
-    const uint64_t end_offset = check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
+    const uint64_t end_offset = /*check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : */ReadWord(input, cursor, end);
 
     // we may get 0 if reading reached the end of the file -
     // fbx files have a mysterious extra footer which I don't know
@@ -363,10 +363,10 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
     }
 
     // the second data word contains the number of properties in the scope
-    const uint64_t prop_count = check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
+    const uint64_t prop_count = /*check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : */ReadWord(input, cursor, end);
 
     // the third data word contains the length of the property list
-    const uint64_t prop_length = check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
+    const uint64_t prop_length = /*check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) :*/ ReadWord(input, cursor, end);
 
     // now comes the name of the scope/key
     const char* sbeg, *send;
@@ -393,7 +393,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
     // at the end of each nested block, there is a NUL record to indicate
     // that the sub-scope exists (i.e. to distinguish between P: and P : {})
     // this NUL record is 13 bytes long on 32 bit version and 25 bytes long on 64 bit.
-    const size_t sentinel_block_length = check_flag(flags, e_flag_field_size_64_bit) ? (sizeof(uint64_t) * 3 + 1) : (sizeof(uint32_t) * 3 + 1);
+    const size_t sentinel_block_length = /*check_flag(flags, e_flag_field_size_64_bit) ? (sizeof(uint64_t) * 3 + 1) : */(sizeof(uint32_t) * 3 + 1);
 
     if (Offset(input, cursor) < end_offset) {
         if (end_offset - Offset(input, cursor) < sentinel_block_length) {

+ 1 - 14
code/FBXConverter.cpp

@@ -71,7 +71,7 @@ using namespace Util;
 
 #define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
 
-    // XXX vc9's debugger won't step into anonymous namespaces
+// XXX vc9's debugger won't step into anonymous namespaces
 //namespace {
 
 /** Dummy class to encapsulate the conversion process */
@@ -114,11 +114,9 @@ private:
     // collect and assign child nodes
     void ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4() );
 
-
     // ------------------------------------------------------------------------------------------------
     void ConvertLights( const Model& model );
 
-
     // ------------------------------------------------------------------------------------------------
     void ConvertCameras( const Model& model );
 
@@ -189,7 +187,6 @@ private:
     static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */
         static_cast<unsigned int>(-1);
 
-
     // ------------------------------------------------------------------------------------------------
     /**
      *  - if materialIndex == NO_MATERIAL_SEPARATION, materials are not taken into
@@ -341,8 +338,6 @@ private:
     typedef std::tuple<std::shared_ptr<KeyTimeList>, std::shared_ptr<KeyValueList>, unsigned int > KeyFrameList;
     typedef std::vector<KeyFrameList> KeyFrameListList;
 
-
-
     // ------------------------------------------------------------------------------------------------
     KeyFrameListList GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop );
 
@@ -899,7 +894,6 @@ void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotat
     }
 }
 
-
 bool Converter::NeedsComplexTransformationChain( const Model& model )
 {
     const PropertyTable& props = model.Props();
@@ -923,7 +917,6 @@ bool Converter::NeedsComplexTransformationChain( const Model& model )
     return false;
 }
 
-
 std::string Converter::NameTransformationChainNode( const std::string& name, TransformationComp comp )
 {
     return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp );
@@ -1067,7 +1060,6 @@ void Converter::GenerateTransformationNodeChain( const Model& model,
     }
 }
 
-
 void Converter::SetupNodeMetadata( const Model& model, aiNode& nd )
 {
     const PropertyTable& props = model.Props();
@@ -1132,7 +1124,6 @@ void Converter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4&
     }
 }
 
-
 std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, const Model& model,
     const aiMatrix4x4& node_global_transform )
 {
@@ -1168,7 +1159,6 @@ std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, cons
     return temp;
 }
 
-
 aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh )
 {
     aiMesh* const out_mesh = new aiMesh();
@@ -1188,7 +1178,6 @@ aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh )
     return out_mesh;
 }
 
-
 unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model,
     const aiMatrix4x4& node_global_transform )
 {
@@ -1511,7 +1500,6 @@ unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, cons
     return static_cast<unsigned int>( meshes.size() - 1 );
 }
 
-
 void Converter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo,
     const aiMatrix4x4& node_global_transform ,
     unsigned int materialIndex,
@@ -1658,7 +1646,6 @@ void Converter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*mode
     }
 }
 
-
 void Converter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo,
     MatIndexArray::value_type materialIndex )
 {

+ 1 - 3
code/FBXDeformer.cpp

@@ -54,7 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp {
 namespace FBX {
 
-    using namespace Util;
+using namespace Util;
 
 // ------------------------------------------------------------------------------------------------
 Deformer::Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name)
@@ -159,8 +159,6 @@ Skin::~Skin()
 
 }
 
-
-
 }
 }
 

+ 3 - 7
code/FBXDocument.cpp

@@ -252,17 +252,15 @@ FileGlobalSettings::FileGlobalSettings(const Document& doc, std::shared_ptr<cons
 : props(props)
 , doc(doc)
 {
-
+    // empty
 }
 
-
 // ------------------------------------------------------------------------------------------------
 FileGlobalSettings::~FileGlobalSettings()
 {
-
+    // empty
 }
 
-
 // ------------------------------------------------------------------------------------------------
 Document::Document(const Parser& parser, const ImportSettings& settings)
 : settings(settings)
@@ -285,7 +283,6 @@ Document::Document(const Parser& parser, const ImportSettings& settings)
     ReadConnections();
 }
 
-
 // ------------------------------------------------------------------------------------------------
 Document::~Document()
 {
@@ -315,7 +312,7 @@ void Document::ReadHeader()
     const Scope& shead = *ehead->Compound();
     fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0));
 
-    // While we maye have some success with newer files, we don't support
+    // While we may have some success with newer files, we don't support
     // the older 6.n fbx format
     if(fbxVersion < LowerSupportedVersion ) {
         DOMError("unsupported, old format version, supported are only FBX 2011, FBX 2012 and FBX 2013");
@@ -331,7 +328,6 @@ void Document::ReadHeader()
         }
     }
 
-
     const Element* const ecreator = shead["Creator"];
     if(ecreator) {
         creator = ParseTokenAsString(GetRequiredToken(*ecreator,0));

+ 4 - 6
code/FBXImporter.cpp

@@ -44,9 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
 
-#include <exception>
-#include <iterator>
-
 #include "FBXImporter.h"
 
 #include "FBXTokenizer.h"
@@ -59,6 +56,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "MemoryIOWrapper.h"
 #include <assimp/Importer.hpp>
 
+#include <exception>
+#include <iterator>
+
 namespace Assimp {
     template<> const std::string LogFunctions<FBXImporter>::log_prefix = "FBX: ";
 }
@@ -99,7 +99,7 @@ FBXImporter::~FBXImporter()
 bool FBXImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
 {
     const std::string& extension = GetExtension(pFile);
-    if (extension == "fbx") {
+    if (extension == std::string( desc.mFileExtensions ) ) {
         return true;
     }
 
@@ -118,7 +118,6 @@ const aiImporterDesc* FBXImporter::GetInfo () const
     return &desc;
 }
 
-
 // ------------------------------------------------------------------------------------------------
 // Setup configuration properties for the loader
 void FBXImporter::SetupProperties(const Importer* pImp)
@@ -135,7 +134,6 @@ void FBXImporter::SetupProperties(const Importer* pImp)
     settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
 }
 
-
 // ------------------------------------------------------------------------------------------------
 // Imports the given file into the given scene structure.
 void FBXImporter::InternReadFile( const std::string& pFile,

+ 0 - 5
code/FBXTokenizer.h

@@ -84,13 +84,10 @@ enum TokenType
  *  Offers iterator protocol. Tokens are immutable. */
 class Token
 {
-
 private:
-
     static const unsigned int BINARY_MARKER = static_cast<unsigned int>(-1);
 
 public:
-
     /** construct a textual token */
     Token(const char* sbegin, const char* send, TokenType type, unsigned int line, unsigned int column);
 
@@ -100,13 +97,11 @@ public:
     ~Token();
 
 public:
-
     std::string StringContents() const {
         return std::string(begin(),end());
     }
 
 public:
-
     bool IsBinary() const {
         return column == BINARY_MARKER;
     }

+ 1 - 0
test/CMakeLists.txt

@@ -68,6 +68,7 @@ SET( TEST_SRCS
   unit/utColladaExportLight.cpp
   unit/utDefaultIOStream.cpp
   unit/utFastAtof.cpp
+  unit/utFBXImporterExporter.cpp
   unit/utFindDegenerates.cpp
   unit/utFindInvalidData.cpp
   unit/utFixInfacingNormals.cpp

TEMPAT SAMPAH
test/models/FBX/spider.fbx


+ 61 - 0
test/unit/utFBXImporterExporter.cpp

@@ -0,0 +1,61 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2016, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+#include "UnitTestPCH.h"
+#include "SceneDiffer.h"
+#include "AbstractImportExportBase.h"
+
+#include <assimp/Importer.hpp>
+
+using namespace Assimp;
+
+class utFBXImporterExporter : public AbstractImportExportBase {
+public:
+    virtual bool importerTest() {
+        Assimp::Importer importer;
+        const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/FBX/spider.fbx", 0 );
+        return nullptr != scene;
+    }
+};
+
+TEST_F( utFBXImporterExporter, importXFromFileTest ) {
+    EXPECT_TRUE( importerTest() );
+}