Revision: 48653
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48653
Author:   aramis_acg
Date:     2012-07-05 15:23:39 +0000 (Thu, 05 Jul 2012)
Log Message:
-----------
- fbx: merge https://github.com/acgessler/assimp-gsoc2012-fbx - fbx importer 
now reads materials, textures, models, node hierarchy and resolves fbx object 
links between these. Conversion code now handles multi-material meshes, also 
support multiple UV channels. Lots of bugfixes. See git commit log for a full 
changelist.

Modified Paths:
--------------
    branches/soc-2012-bratwurst/extern/assimp/CMakeLists.txt
    branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.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/FBXImportSettings.h
    branches/soc-2012-bratwurst/extern/assimp/code/FBXUtil.cpp

Added Paths:
-----------
    branches/soc-2012-bratwurst/extern/assimp/code/FBXDocumentUtil.h
    branches/soc-2012-bratwurst/extern/assimp/code/FBXMaterial.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/FBXProperties.cpp
    branches/soc-2012-bratwurst/extern/assimp/code/FBXProperties.h

Modified: branches/soc-2012-bratwurst/extern/assimp/CMakeLists.txt
===================================================================
--- branches/soc-2012-bratwurst/extern/assimp/CMakeLists.txt    2012-07-05 
15:09:16 UTC (rev 48652)
+++ branches/soc-2012-bratwurst/extern/assimp/CMakeLists.txt    2012-07-05 
15:23:39 UTC (rev 48653)
@@ -297,6 +297,12 @@
        code/FBXTokenizer.h
        code/FBXUtil.cpp
        code/FBXUtil.h
+       code/FBXDocumentUtil.h
+       code/FBXMaterial.cpp
+       code/FBXMeshGeometry.cpp
+       code/FBXModel.cpp
+       code/FBXProperties.cpp
+       code/FBXProperties.h
 )
 
 
@@ -523,6 +529,7 @@
 
 add_definitions(-DASSIMP_BUILD_NO_COLLADA_IMPORTER)
 add_definitions(-DASSIMP_BUILD_NO_BLEND_IMPORTER)
+add_definitions(-Icode/BoostWorkaround/)
 
 blender_add_lib(extern_assimp "${SRC}" "${INC}" "$(INC_SYS)")
 

Modified: branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp
===================================================================
--- branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp     
2012-07-05 15:09:16 UTC (rev 48652)
+++ branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp     
2012-07-05 15:23:39 UTC (rev 48653)
@@ -38,8 +38,8 @@
 ----------------------------------------------------------------------
 */
 
-/** @file  FBXDocument.cpp
- *  @brief Implementation of the FBX DOM classes
+/** @file  FBXConverter.cpp
+ *  @brief Implementation of the FBX DOM -> aiScene converter
  */
 #include "AssimpPCH.h"
 
@@ -49,11 +49,17 @@
 #include "FBXConverter.h"
 #include "FBXDocument.h"
 #include "FBXUtil.h"
+#include "FBXProperties.h"
+#include "FBXImporter.h"
 
 namespace Assimp {
 namespace FBX {
-namespace {
 
+       using namespace Util;
+
+       // XXX vc9's debugger won't step into anonymous namespaces
+//namespace {
+
 /** Dummy class to encapsulate the conversion process */
 class Converter
 {
@@ -64,19 +70,25 @@
                : out(out) 
                , doc(doc)
        {
-               //ConvertRootNode();
+               ConvertRootNode();
 
-               // hack to process all meshes
-               BOOST_FOREACH(const ObjectMap::value_type& v,doc.Objects()) {
+               if(doc.Settings().readAllMaterials) {
+                       // unfortunately this means we have to evaluate all 
objects
+                       BOOST_FOREACH(const ObjectMap::value_type& 
v,doc.Objects()) {
 
-                       const Object* ob = v.second->Get();
-                       if(!ob) {
-                               continue;
+                               const Object* ob = v.second->Get();
+                               if(!ob) {
+                                       continue;
+                               }
+
+                               const Material* mat = dynamic_cast<const 
Material*>(ob);
+                               if(mat) {
+
+                                       if (materials_converted.find(mat) == 
materials_converted.end()) {
+                                               ConvertMaterial(*mat);
+                                       }
+                               }
                        }
-                       const MeshGeometry* geo = dynamic_cast<const 
MeshGeometry*>(ob);
-                       if(geo) {
-                               ConvertMesh(*geo);
-                       }
                }
 
                // dummy root node
@@ -94,6 +106,7 @@
        ~Converter()
        {
                
std::for_each(meshes.begin(),meshes.end(),Util::delete_fun<aiMesh>());
+               
std::for_each(materials.begin(),materials.end(),Util::delete_fun<aiMaterial>());
        }
 
 
@@ -103,30 +116,148 @@
        // find scene root and trigger recursive scene conversion
        void ConvertRootNode() 
        {
+               out->mRootNode = new aiNode();
+               out->mRootNode->mName.Set("Model::RootNode");
 
+               // root has ID 0
+               ConvertNodes(0L, *out->mRootNode);
        }
 
 
        // 
------------------------------------------------------------------------------------------------
-       // MeshGeometry -> aiMesh
-       void ConvertMesh(const MeshGeometry& mesh)
+       // collect and assign child nodes
+       void ConvertNodes(uint64_t id, aiNode& parent)
        {
+               const std::vector<const Connection*>& conns = 
doc.GetConnectionsByDestinationSequenced(id);
+
+               std::vector<aiNode*> nodes;
+               nodes.reserve(conns.size());
+
+               BOOST_FOREACH(const Connection* con, conns) {
+
+                       // ignore object-property links
+                       if(con->PropertyName().length()) {
+                               continue;
+                       }
+
+                       const Object* const object = con->SourceObject();
+                       if(!object) {
+                               FBXImporter::LogWarn("failed to convert source 
object for node link");
+                               continue;
+                       }
+
+                       const Model* const model = dynamic_cast<const 
Model*>(object);
+
+               
+                       if(model) {
+                               aiNode* nd = new aiNode();
+                               nd->mName.Set(model->Name());
+                               nd->mParent = &parent;
+
+                               // XXX handle transformation
+
+                               ConvertModel(*model, *nd);
+                               ConvertNodes(model->ID(), *nd);
+                       }
+               }
+
+               if(nodes.size()) {
+                       parent.mChildren = new aiNode*[nodes.size()]();
+                       parent.mNumChildren = static_cast<unsigned 
int>(nodes.size());
+
+                       
std::swap_ranges(nodes.begin(),nodes.end(),parent.mChildren);
+               }
+       }
+
+
+       // 
------------------------------------------------------------------------------------------------
+       void ConvertModel(const Model& model, aiNode& nd)
+       {
+               const std::vector<const Geometry*>& geos = model.GetGeometry();
+
+               std::vector<unsigned int> meshes;
+               meshes.reserve(geos.size());
+
+               BOOST_FOREACH(const Geometry* geo, geos) {
+
+                       const MeshGeometry* const mesh = dynamic_cast<const 
MeshGeometry*>(geo);
+                       if(mesh) {
+                               std::vector<unsigned int>& indices = 
ConvertMesh(*mesh, model);
+
+                               // mesh indices are shifted by 1 and 0 entries 
are failed conversions -
+                               // XXX maybe log how many conversions went 
wrong?
+                               std::remove(indices.begin(),indices.end(),0);
+                               
std::transform(indices.begin(),indices.end(),std::back_inserter(meshes), 
std::bind2nd(std::minus<unsigned int>(),1) );
+                       }
+                       else {
+                               FBXImporter::LogWarn("ignoring unrecognized 
geometry: " + geo->Name());
+                       }
+               }
+
+               if(meshes.size()) {
+                       nd.mMeshes = new unsigned int[meshes.size()]();
+                       nd.mNumMeshes = static_cast<unsigned 
int>(meshes.size());
+
+                       
std::swap_ranges(meshes.begin(),meshes.end(),nd.mMeshes);
+               }
+       }
+
+
+       // 
------------------------------------------------------------------------------------------------
+       // MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion 
failed
+       std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh, const 
Model& model)
+       {
+               std::vector<unsigned int> temp; 
+
+               MeshMap::const_iterator it = meshes_converted.find(&mesh);
+               if (it != meshes_converted.end()) {
+                       temp.push_back((*it).second + 1);
+                       return temp;
+               }
+
                const std::vector<aiVector3D>& vertices = mesh.GetVertices();
                const std::vector<unsigned int>& faces = 
mesh.GetFaceIndexCounts();
                if(vertices.empty() || faces.empty()) {
-                       return;
+                       FBXImporter::LogWarn("ignoring empty geometry: " + 
mesh.Name());
+                       return temp;
                }
 
                aiMesh* out_mesh = new aiMesh();
                meshes.push_back(out_mesh);
 
+               meshes_converted[&mesh] = static_cast<unsigned 
int>(meshes.size()-1);
+
+               // one material per mesh maps easily to aiMesh. Multiple 
material 
+               // meshes need to be split.
+               const std::vector<unsigned int>& mindices = 
mesh.GetMaterialIndices();
+               if (!mindices.empty()) {
+                       const unsigned int base = mindices[0];
+                       BOOST_FOREACH(unsigned int index, mindices) {
+                               if(index != base) {
+                                       return 
ConvertMeshMultiMaterial(out_mesh, mesh, model);
+                               }
+                       }
+               }
+
+               // faster codepath, just copy the data
+               temp.push_back(ConvertMeshSingleMaterial(out_mesh, mesh, 
model));
+               return temp;
+       }
+
+
+       // 
------------------------------------------------------------------------------------------------
+       unsigned int ConvertMeshSingleMaterial(aiMesh* out_mesh, const 
MeshGeometry& mesh, const Model& model)  
+       {
+               const std::vector<aiVector3D>& vertices = mesh.GetVertices();
+               const std::vector<unsigned int>& faces = 
mesh.GetFaceIndexCounts();
+
                // copy vertices
-               out_mesh->mNumVertices = static_cast<size_t>(vertices.size());
+               out_mesh->mNumVertices = static_cast<unsigned 
int>(vertices.size());
                out_mesh->mVertices = new aiVector3D[vertices.size()];
                std::copy(vertices.begin(),vertices.end(),out_mesh->mVertices);
 
                // generate dummy faces
-               out_mesh->mNumFaces = static_cast<size_t>(faces.size());
+               out_mesh->mNumFaces = static_cast<unsigned int>(faces.size());
                aiFace* fac = out_mesh->mFaces = new aiFace[faces.size()]();
 
                unsigned int cursor = 0;
@@ -136,18 +267,18 @@
                        f.mIndices = new unsigned int[pcount];
                        switch(pcount) 
                        {
-                               case 1:
-                                       out_mesh->mPrimitiveTypes |= 
aiPrimitiveType_POINT;
-                                       break;
-                               case 2:
-                                       out_mesh->mPrimitiveTypes |= 
aiPrimitiveType_LINE;
-                                       break;
-                               case 3:
-                                       out_mesh->mPrimitiveTypes |= 
aiPrimitiveType_TRIANGLE;
-                                       break;
-                               default:
-                                       out_mesh->mPrimitiveTypes |= 
aiPrimitiveType_POLYGON;
-                                       break;
+                       case 1:
+                               out_mesh->mPrimitiveTypes |= 
aiPrimitiveType_POINT;
+                               break;
+                       case 2:
+                               out_mesh->mPrimitiveTypes |= 
aiPrimitiveType_LINE;
+                               break;
+                       case 3:
+                               out_mesh->mPrimitiveTypes |= 
aiPrimitiveType_TRIANGLE;
+                               break;
+                       default:
+                               out_mesh->mPrimitiveTypes |= 
aiPrimitiveType_POLYGON;
+                               break;
                        }
                        for (unsigned int i = 0; i < pcount; ++i) {
                                f.mIndices[i] = cursor++;
@@ -155,7 +286,7 @@
                }
 
                // copy normals
-               const std::vector<aiVector3D>& normals = mesh.GetVertices();
+               const std::vector<aiVector3D>& normals = mesh.GetNormals();
                if(normals.size()) {
                        ai_assert(normals.size() == vertices.size());
 
@@ -221,10 +352,457 @@
                        out_mesh->mColors[i] = new aiColor4D[vertices.size()];
                        
std::copy(colors.begin(),colors.end(),out_mesh->mColors[i]);
                }
+
+               const std::vector<unsigned int>& mindices = 
mesh.GetMaterialIndices();
+               if(mindices.empty()) {
+                       FBXImporter::LogError("no material assigned to mesh, 
setting default material");
+                       out_mesh->mMaterialIndex = GetDefaultMaterial();
+               }
+               else {
+                       ConvertMaterialForMesh(out_mesh,model,mesh,mindices[0]);
+               }
+
+               return static_cast<unsigned int>(meshes.size());
        }
 
 
        // 
------------------------------------------------------------------------------------------------
+       std::vector<unsigned int> ConvertMeshMultiMaterial(aiMesh* out_mesh, 
const MeshGeometry& mesh, const Model& model)      
+       {
+               const std::vector<unsigned int>& mindices = 
mesh.GetMaterialIndices();
+               ai_assert(mindices.size());
+       
+               std::set<unsigned int> had;
+               std::vector<unsigned int> indices;
+
+               BOOST_FOREACH(unsigned int index, mindices) {
+                       if(had.find(index) != had.end()) {
+
+                               
indices.push_back(ConvertMeshMultiMaterial(out_mesh, mesh, model, index));
+                               had.insert(index);
+                       }
+               }
+
+               return indices;
+       }
+
+
+       // 
------------------------------------------------------------------------------------------------
+       unsigned int ConvertMeshMultiMaterial(aiMesh* out_mesh, const 
MeshGeometry& mesh, const Model& model, unsigned int index)       
+       {
+               const std::vector<unsigned int>& mindices = 
mesh.GetMaterialIndices();
+               ai_assert(mindices.size());
+
+               const std::vector<aiVector3D>& vertices = mesh.GetVertices();

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to