[Bf-extensions-cvs] [495eca4] fbx_io_development: WIP

Bastien Montagne noreply at git.blender.org
Sun Jul 6 19:16:00 CEST 2014


Commit: 495eca43eb9f50fce72a58c0735ffdf26e36dc9f
Author: Bastien Montagne
Date:   Fri Jul 4 12:55:46 2014 +0200
https://developer.blender.org/rBA495eca43eb9f50fce72a58c0735ffdf26e36dc9f

WIP

===================================================================

M	io_scene_fbx/import_fbx.py

===================================================================

diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py
index 193f5df..98cc395 100644
--- a/io_scene_fbx/import_fbx.py
+++ b/io_scene_fbx/import_fbx.py
@@ -1570,19 +1570,42 @@ def load(operator, context, filepath="",
     def _():
         nonlocal fbx_objects_ignore, fbx_objects_parent_ignore
         for a_uuid, a_item in fbx_table_nodes.items():
+            root_bone = False
             fbx_adata, bl_adata = a_item = fbx_table_nodes.get(a_uuid, (None, None))
-            if fbx_adata is None or fbx_adata.id != b'Model' or fbx_adata.props[2] != b'Null':
+            if fbx_adata is None or fbx_adata.id != b'Model':
                 continue
+            elif fbx_adata.props[2] != b'Null':
+                if fbx_adata.props[2] not in {b'LimbNode', b'Root'}:
+                    continue
+                # In some cases, armatures have no root 'Null' object, we have to consider all root bones
+                # as armatures in this case. :/
+                root_bone = True
+                for p_uuid, p_ctype in fbx_connection_map.get(a_uuid, ()):
+                    if p_ctype.props[0] != b'OO':
+                        continue
+                    fbx_pdata, bl_pdata = p_item = fbx_table_nodes.get(p_uuid, (None, None))
+                    if (fbx_pdata and fbx_pdata.id == b'Model' and fbx_pdata.props[2] in {b'LimbNode', b'Root'}):
+                        # Not a root bone...
+                        root_bone = False
+                if not root_bone:
+                    continue
 
             bones = {}
-            todo_uuids = {a_uuid}
+            todo_uuids = {} if root_bone else {a_uuid}
+            init_uuids = {a_uuid} if root_bone else {}
             done_uuids = set()
-            while todo_uuids:
-                p_uuid = todo_uuids.pop()
+            while todo_uuids or init_uuids:
+                if init_uuids:
+                    p_uuid = None
+                    uuids = [(uuid, None) for uuid in init_uuids]
+                    init_uuids = None
+                else:
+                    p_uuid = todo_uuids.pop()
+                    uuids = fbx_connection_map_reverse.get(p_uuid, ())
                 # bone -> cluster -> skin -> mesh.
                 # XXX Note: only LimbNode for now (there are also Limb's :/ ).
-                for b_uuid, b_ctype in fbx_connection_map_reverse.get(p_uuid, ()):
-                    if b_ctype.props[0] != b'OO':
+                for b_uuid, b_ctype in uuids:
+                    if b_ctype and b_ctype.props[0] != b'OO':
                         continue
                     fbx_bdata, bl_bdata = b_item = fbx_table_nodes.get(b_uuid, (None, None))
                     if (fbx_bdata is None or fbx_bdata.id != b'Model' or
@@ -1637,12 +1660,14 @@ def load(operator, context, filepath="",
                             # Skin deformers are only here to connect clusters to meshes, for us, nothing else to do.
                         clusters.append((fbx_cdata, meshes, objects))
                     # For now, we assume there is only one cluster & skin per bone (at least for a given armature)!
-                    assert(len(clusters) <= 1)
-                    bones[b_uuid] = (b_item, size, p_uuid if p_uuid != a_uuid else None, clusters)
+                    # XXX This is not true, some apps export several clusters (kind of LoD), we only use first one!
+                    # assert(len(clusters) <= 1)
+                    bones[b_uuid] = (b_item, size, p_uuid if (p_uuid != a_uuid or root_bone) else None, clusters)
                     fbx_objects_parent_ignore.add(b_uuid)
                     done_uuids.add(p_uuid)
                     todo_uuids.add(b_uuid)
             if bones:
+                # in case we have no Null parent, rootbone will be a_item too...
                 armatures.append((a_item, bones))
                 fbx_objects_ignore.add(a_uuid)
         fbx_objects_ignore |= fbx_objects_parent_ignore
@@ -1657,7 +1682,7 @@ def load(operator, context, filepath="",
                 # armatures and bones, handled separately.
                 continue
             fbx_obj, blen_data = fbx_item
-            if fbx_obj.id != b'Model' or fbx_obj.props[2] == b'LimbNode':
+            if fbx_obj.id != b'Model' or fbx_obj.props[2] in {b'Root', b'LimbNode'}:
                 continue
 
             # Create empty object or search for object data



More information about the Bf-extensions-cvs mailing list