Revision: 47982
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=47982
Author:   aramis_acg
Date:     2012-06-16 00:47:10 +0000 (Sat, 16 Jun 2012)
Log Message:
-----------
- bf_assimp: sort assimp nodes into two bins: one kind is added to blender's 
scene hierarchy (including OB_EMPTY nodes when needed), the other only appears 
as part of armatures. This is needed because assimp does not distinguish 
between scene nodes and bones - the distinction is not needed in its data 
structures, so it was never made. 

Modified Paths:
--------------
    branches/soc-2012-bratwurst/source/blender/assimp/SceneImporter.cpp
    branches/soc-2012-bratwurst/source/blender/assimp/SceneImporter.h

Modified: branches/soc-2012-bratwurst/source/blender/assimp/SceneImporter.cpp
===================================================================
--- branches/soc-2012-bratwurst/source/blender/assimp/SceneImporter.cpp 
2012-06-15 23:54:51 UTC (rev 47981)
+++ branches/soc-2012-bratwurst/source/blender/assimp/SceneImporter.cpp 
2012-06-16 00:47:10 UTC (rev 47982)
@@ -127,11 +127,24 @@
                return false;
        }
 
+       // generate the subgraph of all mesh-carrier nodes
+       populate_mesh_node_graph(scene->mRootNode);
+
        handle_coordinate_space();
        handle_scale();
 
        convert_materials();
 
+       // check if there are bones present because this changes
+       // the way how the assimp node hierarchy is imported.
+       has_bones = false;
+       for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
+               if (scene->mMeshes[i]->mNumBones > 0)   {
+                       has_bones = true;
+                       break;
+               }
+       }
+
        const aiNode* nd = scene->mRootNode;
        convert_node(nd,NULL);
 
@@ -165,17 +178,6 @@
 
 void SceneImporter::convert_animations() 
 {
-       // check if there *is* anything to convert. There is no need to create 
an armature unless
-       // there is not a single bone.
-
-       bool has_bones = false;
-       for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
-               if (scene->mMeshes[i]->mNumBones > 0)   {
-                       has_bones = true;
-                       break;
-               }
-       }
-
        if (!has_bones) {
                return;
        }
@@ -234,6 +236,45 @@
 }
 
 
+bool SceneImporter::has_mesh_descendants(const aiNode* in_node) const
+{
+       return nodes_with_mesh_descendants.find(in_node) != 
nodes_with_mesh_descendants.end();
+}
+
+
+void SceneImporter::populate_mesh_node_graph(const aiNode* node)
+{
+       if (!node->mNumChildren)
+       {
+               // this is a leaf node, so traverse it upwards until we find a 
node
+               // that carries a mesh. Starting with this node, insert all 
+               // upwards nodes into the list of mesh nodes. 
+               bool flag = false;
+               do      {
+                       if (node->mNumMeshes > 0)       {
+                               flag = true;
+                       }
+
+                       if (nodes_with_mesh_descendants.find(node) != 
nodes_with_mesh_descendants.end()) {
+                               break;
+                       }
+
+                       if (flag)       {
+                               nodes_with_mesh_descendants.insert(node);
+                       }
+
+                       node = node->mParent;
+               }
+               while(node != NULL);
+       }
+       else {
+               for (unsigned int i = 0; i < node->mNumChildren; ++i)   {
+                       populate_mesh_node_graph(node->mChildren[i]);
+               }
+       }
+}
+
+
 void SceneImporter::convert_node(const aiNode* in_node, Object* out_parent) 
const
 {
        assert(in_node != NULL);
@@ -290,7 +331,7 @@
                }
        }
 
-       if (meshes + cameras + lights  == 0) {
+       if (meshes + cameras + lights  == 0 &&  (!has_bones || 
has_mesh_descendants(in_node))) {
                Object* const obj = util_add_object(out_scene, OB_EMPTY, NULL);
                objects_done.push_back(obj);
        }
@@ -306,10 +347,12 @@
                }
        }
 
-       // assign children
-       // XXX: objects_done.length > 1 is essentially unhandled .. i.e. 
results will be wrong
-       for (unsigned int i = 0, c = in_node->mNumChildren; i < c; ++i) {
-               convert_node(in_node->mChildren[i],objects_done.front());
+       // assign children - unless all descendants don't carry meshes (i.e. 
should become bones in the armature).
+       if (!objects_done.empty()) {
+               // XXX: objects_done.length > 1 is essentially unhandled .. 
i.e. results will be wrong
+               for (unsigned int i = 0, c = in_node->mNumChildren; i < c; ++i) 
{
+                       
convert_node(in_node->mChildren[i],objects_done.front());
+               }
        }
 }
 

Modified: branches/soc-2012-bratwurst/source/blender/assimp/SceneImporter.h
===================================================================
--- branches/soc-2012-bratwurst/source/blender/assimp/SceneImporter.h   
2012-06-15 23:54:51 UTC (rev 47981)
+++ branches/soc-2012-bratwurst/source/blender/assimp/SceneImporter.h   
2012-06-16 00:47:10 UTC (rev 47982)
@@ -28,6 +28,7 @@
 #define INCLUDED_SCENE_IMPORTER_H
 
 #include  "bassimp_shared.h"
+#include <set>
 
 namespace bassimp {
 
@@ -47,6 +48,12 @@
        std::vector<MaterialImporter*> materials;
        mutable std::vector<bool> materials_used;
 
+       bool has_bones;
+
+       // subgraph of the node graph containing all nodes that
+       // carry meshes, directly or indirectly.
+       std::set<const aiNode*> nodes_with_mesh_descendants;
+
 private:
 
        unsigned int get_assimp_flags() const;
@@ -62,8 +69,8 @@
 
        void handle_scale();
        void handle_coordinate_space();
+       void populate_mesh_node_graph(const aiNode* node);
 
-
 public:
 
        SceneImporter(const char* path, bContext *C);
@@ -81,6 +88,8 @@
        const MaterialImporter& get_material(unsigned int idx) const;
        unsigned int resolve_matid(unsigned int src) const;
 
+       // check if a node has any descendant nodes which carry meshes.
+       bool has_mesh_descendants(const aiNode* in_node) const;
 };
 
 }

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to