[Bf-extensions-cvs] [c9cde56] master: Fix T41316: FBX exporter in Blender cause artifacts to appear on meshes with Shape Keys.

Bastien Montagne noreply at git.blender.org
Fri Aug 8 20:12:07 CEST 2014


Commit: c9cde56179ce50605822eac25b4979c911feffe6
Author: Bastien Montagne
Date:   Fri Aug 8 20:09:16 2014 +0200
Branches: master
https://developer.blender.org/rBAc9cde56179ce50605822eac25b4979c911feffe6

Fix T41316: FBX exporter in Blender cause artifacts to appear on meshes with Shape Keys.

For some reason, Unity (and FBX SDK in general?) does not support well mixing
normals and smooth data, at least when using shapekeys.

Odd, odd, you said odd? That's odd...

Anyway, we do not really need both of those data at the same time, so for now
either write smooth or normals data, not both!

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

M	io_scene_fbx/__init__.py
M	io_scene_fbx/export_fbx_bin.py

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

diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py
index 38843b5..69c2a5f 100644
--- a/io_scene_fbx/__init__.py
+++ b/io_scene_fbx/__init__.py
@@ -246,13 +246,13 @@ class ExportFBX(bpy.types.Operator, ExportHelper):
             )
     mesh_smooth_type = EnumProperty(
             name="Smoothing",
-            items=(('OFF', "Off", "Don't write smoothing"),
+            items=(('OFF', "Off", "Don't write smoothing, export normals instead"),
                    ('FACE', "Face", "Write face smoothing"),
                    ('EDGE', "Edge", "Write edge smoothing"),
                    ),
             description=("Export smoothing information "
-                         "(not mandatory if your target importer understand split normals)"),
-            default='FACE',
+                         "(prefer 'Off' option if your target importer understand split normals)"),
+            default='OFF',
             )
     use_mesh_edges = BoolProperty(
             name="Loose Edges",
@@ -380,7 +380,9 @@ class ExportFBX(bpy.types.Operator, ExportHelper):
         layout.prop(self, "use_mesh_modifiers")
         layout.prop(self, "mesh_smooth_type")
         layout.prop(self, "use_mesh_edges")
-        layout.prop(self, "use_tspace")
+        sub = layout.row()
+        sub.enabled = self.mesh_smooth_type in {'OFF'}
+        sub.prop(self, "use_tspace")
         layout.prop(self, "use_armature_deform_only")
         if is_74bin:
             layout.prop(self, "use_custom_props")
diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py
index 7904e1d..17deee2 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -808,6 +808,7 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
 
     # No gscale/gmat here, all data are supposed to be in object space.
     smooth_type = scene_data.settings.mesh_smooth_type
+    write_normals = smooth_type in {'OFF'}
 
     do_bake_space_transform = me_obj.use_bake_space_transform(scene_data)
 
@@ -944,93 +945,94 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
     del edges_map
 
     # Loop normals.
-    # NOTE: this is not supported by importer currently.
-    # XXX Official docs says normals should use IndexToDirect,
-    #     but this does not seem well supported by apps currently...
-    me.calc_normals_split()
-
-    def _nortuples_gen(raw_nors, m):
-        # Great, now normals are also expected 4D!
-        # XXX Back to 3D normals for now!
-        # gen = zip(*(iter(raw_nors),) * 3 + (_infinite_gen(1.0),))
-        gen = zip(*(iter(raw_nors),) * 3)
-        return gen if m is None else (m * Vector(v) for v in gen)
-
-    t_ln = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(me.loops) * 3
-    me.loops.foreach_get("normal", t_ln)
-    t_ln = _nortuples_gen(t_ln, geom_mat_no)
-    if 0:
-        t_ln = tuple(t_ln)  # No choice... :/
-
-        lay_nor = elem_data_single_int32(geom, b"LayerElementNormal", 0)
-        elem_data_single_int32(lay_nor, b"Version", FBX_GEOMETRY_NORMAL_VERSION)
-        elem_data_single_string(lay_nor, b"Name", b"")
-        elem_data_single_string(lay_nor, b"MappingInformationType", b"ByPolygonVertex")
-        elem_data_single_string(lay_nor, b"ReferenceInformationType", b"IndexToDirect")
-
-        ln2idx = tuple(set(t_ln))
-        elem_data_single_float64_array(lay_nor, b"Normals", chain(*ln2idx))
-        # Normal weights, no idea what it is.
-        # t_lnw = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(ln2idx)
-        # elem_data_single_float64_array(lay_nor, b"NormalsW", t_lnw)
-
-        ln2idx = {nor: idx for idx, nor in enumerate(ln2idx)}
-        elem_data_single_int32_array(lay_nor, b"NormalsIndex", (ln2idx[n] for n in t_ln))
-
-        del ln2idx
-        # del t_lnw
-    else:
-        lay_nor = elem_data_single_int32(geom, b"LayerElementNormal", 0)
-        elem_data_single_int32(lay_nor, b"Version", FBX_GEOMETRY_NORMAL_VERSION)
-        elem_data_single_string(lay_nor, b"Name", b"")
-        elem_data_single_string(lay_nor, b"MappingInformationType", b"ByPolygonVertex")
-        elem_data_single_string(lay_nor, b"ReferenceInformationType", b"Direct")
-        elem_data_single_float64_array(lay_nor, b"Normals", chain(*t_ln))
-        # Normal weights, no idea what it is.
-        # t_ln = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(me.loops)
-        # elem_data_single_float64_array(lay_nor, b"NormalsW", t_ln)
-    del t_ln
-
-    # tspace
-    tspacenumber = 0
-    if scene_data.settings.use_tspace:
-        tspacenumber = len(me.uv_layers)
-        if tspacenumber:
-            t_ln = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(me.loops) * 3
-            # t_lnw = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(me.loops)
-            for idx, uvlayer in enumerate(me.uv_layers):
-                name = uvlayer.name
-                me.calc_tangents(name)
-                # Loop bitangents (aka binormals).
-                # NOTE: this is not supported by importer currently.
-                me.loops.foreach_get("bitangent", t_ln)
-                lay_nor = elem_data_single_int32(geom, b"LayerElementBinormal", idx)
-                elem_data_single_int32(lay_nor, b"Version", FBX_GEOMETRY_BINORMAL_VERSION)
-                elem_data_single_string_unicode(lay_nor, b"Name", name)
-                elem_data_single_string(lay_nor, b"MappingInformationType", b"ByPolygonVertex")
-                elem_data_single_string(lay_nor, b"ReferenceInformationType", b"Direct")
-                elem_data_single_float64_array(lay_nor, b"Binormals", chain(*_nortuples_gen(t_ln, geom_mat_no)))
-                # Binormal weights, no idea what it is.
-                # elem_data_single_float64_array(lay_nor, b"BinormalsW", t_lnw)
-
-                # Loop tangents.
-                # NOTE: this is not supported by importer currently.
-                me.loops.foreach_get("tangent", t_ln)
-                lay_nor = elem_data_single_int32(geom, b"LayerElementTangent", idx)
-                elem_data_single_int32(lay_nor, b"Version", FBX_GEOMETRY_TANGENT_VERSION)
-                elem_data_single_string_unicode(lay_nor, b"Name", name)
-                elem_data_single_string(lay_nor, b"MappingInformationType", b"ByPolygonVertex")
-                elem_data_single_string(lay_nor, b"ReferenceInformationType", b"Direct")
-                elem_data_single_float64_array(lay_nor, b"Tangents", chain(*_nortuples_gen(t_ln, geom_mat_no)))
-                # Tangent weights, no idea what it is.
-                # elem_data_single_float64_array(lay_nor, b"TangentsW", t_lnw)
-
-            del t_ln
+    if (write_normals):
+        # NOTE: this is not supported by importer currently.
+        # XXX Official docs says normals should use IndexToDirect,
+        #     but this does not seem well supported by apps currently...
+        me.calc_normals_split()
+
+        def _nortuples_gen(raw_nors, m):
+            # Great, now normals are also expected 4D!
+            # XXX Back to 3D normals for now!
+            # gen = zip(*(iter(raw_nors),) * 3 + (_infinite_gen(1.0),))
+            gen = zip(*(iter(raw_nors),) * 3)
+            return gen if m is None else (m * Vector(v) for v in gen)
+
+        t_ln = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(me.loops) * 3
+        me.loops.foreach_get("normal", t_ln)
+        t_ln = _nortuples_gen(t_ln, geom_mat_no)
+        if 0:
+            t_ln = tuple(t_ln)  # No choice... :/
+
+            lay_nor = elem_data_single_int32(geom, b"LayerElementNormal", 0)
+            elem_data_single_int32(lay_nor, b"Version", FBX_GEOMETRY_NORMAL_VERSION)
+            elem_data_single_string(lay_nor, b"Name", b"")
+            elem_data_single_string(lay_nor, b"MappingInformationType", b"ByPolygonVertex")
+            elem_data_single_string(lay_nor, b"ReferenceInformationType", b"IndexToDirect")
+
+            ln2idx = tuple(set(t_ln))
+            elem_data_single_float64_array(lay_nor, b"Normals", chain(*ln2idx))
+            # Normal weights, no idea what it is.
+            # t_lnw = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(ln2idx)
+            # elem_data_single_float64_array(lay_nor, b"NormalsW", t_lnw)
+
+            ln2idx = {nor: idx for idx, nor in enumerate(ln2idx)}
+            elem_data_single_int32_array(lay_nor, b"NormalsIndex", (ln2idx[n] for n in t_ln))
+
+            del ln2idx
             # del t_lnw
-            me.free_tangents()
-
-    me.free_normals_split()
-    del _nortuples_gen
+        else:
+            lay_nor = elem_data_single_int32(geom, b"LayerElementNormal", 0)
+            elem_data_single_int32(lay_nor, b"Version", FBX_GEOMETRY_NORMAL_VERSION)
+            elem_data_single_string(lay_nor, b"Name", b"")
+            elem_data_single_string(lay_nor, b"MappingInformationType", b"ByPolygonVertex")
+            elem_data_single_string(lay_nor, b"ReferenceInformationType", b"Direct")
+            elem_data_single_float64_array(lay_nor, b"Normals", chain(*t_ln))
+            # Normal weights, no idea what it is.
+            # t_ln = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(me.loops)
+            # elem_data_single_float64_array(lay_nor, b"NormalsW", t_ln)
+        del t_ln
+
+        # tspace
+        tspacenumber = 0
+        if scene_data.settings.use_tspace:
+            tspacenumber = len(me.uv_layers)
+            if tspacenumber:
+                t_ln = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(me.loops) * 3
+                # t_lnw = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(me.loops)
+                for idx, uvlayer in enumerate(me.uv_layers):
+                    name = uvlayer.name
+                    me.calc_tangents(name)
+                    # Loop bitangents (aka binormals).
+                    # NOTE: this is not supported by importer currently.
+                    me.loops.foreach_get("bitangent", t_ln)
+                    lay_nor = elem_data_single_int32(geom, b"LayerElementBinormal", idx)
+                    elem_data_single_int32(lay_nor, b"Version", FBX_GEOMETRY_BINORMAL_VERSION)
+                    elem_data_single_string_unicode(lay_nor, b"

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list