[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [49795] branches/soc-2012-bratwurst/extern /assimp: - bf_assimp: merge https://github.com/acgessler/ assimp-gsoc2012-fbx - support for binary fbx files, arbitrary rotation orders, more supported camera and light options, improved error reporting, lots of bugfixes.

Alexander Gessler alexander.gessler at gmx.net
Sat Aug 11 05:22:22 CEST 2012


Revision: 49795
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=49795
Author:   aramis_acg
Date:     2012-08-11 03:22:18 +0000 (Sat, 11 Aug 2012)
Log Message:
-----------
- bf_assimp: merge https://github.com/acgessler/assimp-gsoc2012-fbx - support for binary fbx files, arbitrary rotation orders, more supported camera and light options, improved error reporting, lots of bugfixes.

Modified Paths:
--------------
    branches/soc-2012-bratwurst/extern/assimp/CMakeLists.txt
    branches/soc-2012-bratwurst/extern/assimp/code/FBXAnimation.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXDeformer.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXDocument.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXDocument.h
    branches/soc-2012-bratwurst/extern/assimp/code/FBXDocumentUtil.h
    branches/soc-2012-bratwurst/extern/assimp/code/FBXImporter.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXMeshGeometry.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXModel.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXNodeAttribute.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXParser.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXParser.h
    branches/soc-2012-bratwurst/extern/assimp/code/FBXProperties.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXTokenizer.h
    branches/soc-2012-bratwurst/extern/assimp/code/FBXUtil.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXUtil.h

Added Paths:
-----------
    branches/soc-2012-bratwurst/extern/assimp/code/FBXBinaryTokenizer.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXDocumentUtil.cpp

Modified: branches/soc-2012-bratwurst/extern/assimp/CMakeLists.txt
===================================================================
--- branches/soc-2012-bratwurst/extern/assimp/CMakeLists.txt	2012-08-11 01:17:16 UTC (rev 49794)
+++ branches/soc-2012-bratwurst/extern/assimp/CMakeLists.txt	2012-08-11 03:22:18 UTC (rev 49795)
@@ -306,6 +306,8 @@
 	code/FBXNodeAttribute.cpp
 	code/FBXDeformer.cpp
 	code/FBXAnimation.cpp
+	code/FBXBinaryTokenizer.cpp
+	code/FBXDocumentUtil.cpp
 )
 
 

Modified: branches/soc-2012-bratwurst/extern/assimp/code/FBXAnimation.cpp
===================================================================
--- branches/soc-2012-bratwurst/extern/assimp/code/FBXAnimation.cpp	2012-08-11 01:17:16 UTC (rev 49794)
+++ branches/soc-2012-bratwurst/extern/assimp/code/FBXAnimation.cpp	2012-08-11 03:22:18 UTC (rev 49795)
@@ -66,8 +66,8 @@
 	const Element& KeyTime = GetRequiredElement(sc,"KeyTime");
 	const Element& KeyValueFloat = GetRequiredElement(sc,"KeyValueFloat");
 
-	ReadVectorDataArray(keys, KeyTime);
-	ReadVectorDataArray(values, KeyValueFloat);
+	ParseVectorDataArray(keys, KeyTime);
+	ParseVectorDataArray(values, KeyValueFloat);
 
 	if(keys.size() != values.size()) {
 		DOMError("the number of key times does not match the number of keyframe values",&KeyTime);
@@ -80,12 +80,12 @@
 
 	const Element* KeyAttrDataFloat = sc["KeyAttrDataFloat"];
 	if(KeyAttrDataFloat) {
-		ReadVectorDataArray(attributes, *KeyAttrDataFloat);
+		ParseVectorDataArray(attributes, *KeyAttrDataFloat);
 	}
 
 	const Element* KeyAttrFlags = sc["KeyAttrFlags"];
 	if(KeyAttrFlags) {
-		ReadVectorDataArray(flags, *KeyAttrFlags);
+		ParseVectorDataArray(flags, *KeyAttrFlags);
 	}
 }
 

Added: branches/soc-2012-bratwurst/extern/assimp/code/FBXBinaryTokenizer.cpp
===================================================================
--- branches/soc-2012-bratwurst/extern/assimp/code/FBXBinaryTokenizer.cpp	                        (rev 0)
+++ branches/soc-2012-bratwurst/extern/assimp/code/FBXBinaryTokenizer.cpp	2012-08-11 03:22:18 UTC (rev 49795)
@@ -0,0 +1,385 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2012, 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.
+
+----------------------------------------------------------------------
+*/
+/** @file  FBXBinaryTokenizer.cpp
+ *  @brief Implementation of a fake lexer for binary fbx files -
+ *    we emit tokens so the parser needs almost no special handling
+ *    for binary files.
+ */
+#include "AssimpPCH.h"
+
+#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
+
+#include "FBXTokenizer.h"
+#include "FBXUtil.h"
+
+namespace Assimp {
+namespace FBX {
+
+
+// ------------------------------------------------------------------------------------------------
+Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset)
+	: sbegin(sbegin)
+	, send(send)
+	, type(type)
+	, line(offset)
+	, column(BINARY_MARKER)
+#ifdef DEBUG
+	, contents(sbegin, static_cast<size_t>(send-sbegin))
+#endif
+{
+	ai_assert(sbegin);
+	ai_assert(send);
+
+	// binary tokens may have zero length because they are sometimes dummies
+	// inserted by TokenizeBinary()
+	ai_assert(send >= sbegin);
+}
+
+
+namespace {
+
+// ------------------------------------------------------------------------------------------------
+// signal tokenization error, this is always unrecoverable. Throws DeadlyImportError.
+void TokenizeError(const std::string& message, unsigned int offset)
+{
+	throw DeadlyImportError(Util::AddOffset("FBX-Tokenize",message,offset));
+}
+
+
+// ------------------------------------------------------------------------------------------------
+uint32_t Offset(const char* begin, const char* cursor)
+{
+	ai_assert(begin <= cursor);
+	return static_cast<unsigned int>(cursor - begin);
+}
+
+
+// ------------------------------------------------------------------------------------------------
+void TokenizeError(const std::string& message, const char* begin, const char* cursor)
+{
+	TokenizeError(message, Offset(begin, cursor));
+}
+
+
+// ------------------------------------------------------------------------------------------------
+uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
+{
+	if(Offset(cursor, end) < 4) {
+		TokenizeError("cannot ReadWord, out of bounds",input, cursor);
+	} 
+
+	uint32_t word = *reinterpret_cast<const uint32_t*>(cursor);
+	AI_SWAP4(word);
+
+	cursor += 4;
+
+	return word;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+uint8_t ReadByte(const char* input, const char*& cursor, const char* end)
+{
+	if(Offset(cursor, end) < 1) {
+		TokenizeError("cannot ReadByte, out of bounds",input, cursor);
+	} 
+
+	uint8_t word = *reinterpret_cast<const uint8_t*>(cursor);
+	++cursor;
+
+	return word;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end, 
+	bool long_length = false,
+	bool allow_null = false)
+{
+	const uint32_t len_len = long_length ? 4 : 1;
+	if(Offset(cursor, end) < len_len) {
+		TokenizeError("cannot ReadString, out of bounds reading length",input, cursor);
+	} 
+
+	const uint32_t length = long_length ? ReadWord(input, cursor, end) : ReadByte(input, cursor, end);
+
+	if (Offset(cursor, end) < length) {
+		TokenizeError("cannot ReadString, length is out of bounds",input, cursor);
+	}
+
+	sbegin_out = cursor;
+	cursor += length;
+
+	send_out = cursor;
+
+	if(!allow_null) {
+		for (unsigned int i = 0; i < length; ++i) {
+			if(sbegin_out[i] == '\0') {
+				TokenizeError("failed ReadString, unexpected NUL character in string",input, cursor);
+			}
+		}
+	}
+
+	return length;
+}
+
+
+
+// ------------------------------------------------------------------------------------------------
+void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end)
+{
+	if(Offset(cursor, end) < 1) {
+		TokenizeError("cannot ReadData, out of bounds reading length",input, cursor);
+	} 
+
+	const char type = *cursor;
+	sbegin_out = cursor++;
+
+	switch(type)
+	{
+		// 1 bit bool flag (yes/no)
+	case 'C':
+		cursor += 1;
+		break;
+
+		// 32 bit int
+	case 'I':
+		// <- fall thru
+
+		// float
+	case 'F':
+		cursor += 4;
+		break;
+
+		// double
+	case 'D':
+		cursor += 8;
+		break;
+
+		// 64 bit int
+	case 'L':
+		cursor += 8;
+		break;
+
+		// note: do not write cursor += ReadWord(...cursor) as this would be UB
+
+		// raw binary data
+	case 'R':	{
+		const uint32_t length = ReadWord(input, cursor, end);
+		cursor += length;
+		break;
+	}
+
+		// array of *
+	case 'f':
+	case 'd':
+	case 'l':
+	case 'i':	{
+	
+		const uint32_t length = ReadWord(input, cursor, end);
+		const uint32_t encoding = ReadWord(input, cursor, end);
+
+		const uint32_t comp_len = ReadWord(input, cursor, end);
+
+		// compute length based on type and check against the stored value
+		if(encoding == 0) {
+			uint32_t stride;
+			switch(type)
+			{
+			case 'f':
+			case 'i':
+				stride = 4;
+				break;
+
+			case 'd':
+			case 'l':
+				stride = 8;
+				break;
+
+			default:
+				ai_assert(false);
+			};
+			if(length * stride != comp_len) {
+				TokenizeError("cannot ReadData, calculated data stride differs from what the file claims",input, cursor);
+			}
+		}
+		// zip/deflate algorithm (encoding==1)? take given length. anything else? die
+		else if (encoding != 1) {			
+			TokenizeError("cannot ReadData, unknown encoding",input, cursor);
+		}
+		cursor += comp_len;
+		break;
+	}
+
+		// string
+	case 'S': {
+		const char* sb, *se;
+		// 0 characters can legally happen in such strings
+		ReadString(sb, se, input, cursor, end, true, true);
+		break;
+	}
+	default:
+		TokenizeError("cannot ReadData, unexpected type code: " + std::string(&type, 1),input, cursor);
+	}
+
+	if(cursor > end) {
+		TokenizeError("cannot ReadData, the remaining size is too small for the data type: " + std::string(&type, 1),input, cursor);
+	} 
+
+	// the type code is contained in the returned range
+	send_out = cursor;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end)
+{
+	// the first word contains the offset at which this block ends
+	const uint32_t end_offset = 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 
+	// how to extract any information from, but at least it always 
+	// starts with a 0.
+	if(!end_offset) {
+		return false;
+	}
+
+	if(end_offset > Offset(input, end)) {
+		TokenizeError("block offset is out of range",input, cursor);
+	}
+	else if(end_offset < Offset(input, cursor)) {
+		TokenizeError("block offset is negative out of range",input, cursor);
+	}
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list