[Bf-extensions-cvs] [8b2a241b] master: Attempt to fix FBX scaling issues in a different way.

Bastien Montagne noreply at git.blender.org
Fri Jun 16 15:58:46 CEST 2017


Commit: 8b2a241baca09c9ae5dc1580614c047aabb55d31
Author: Bastien Montagne
Date:   Fri Jun 16 15:58:06 2017 +0200
Branches: master
https://developer.blender.org/rBA8b2a241baca09c9ae5dc1580614c047aabb55d31

Attempt to fix FBX scaling issues in a different way.

Now we offer choices to apply everything in transform, store everyting
in FBX scale, or mix both solutions (taking custom export scale and unit
scale into account here).

This change a bit default behavior, and hopefully will allow to find at
least one options working correctly with a given 'other tool' importer.

This may address T51704 and T50159.

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

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

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

diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py
index 3b6ca352..039e7952 100644
--- a/io_scene_fbx/__init__.py
+++ b/io_scene_fbx/__init__.py
@@ -21,7 +21,7 @@
 bl_info = {
     "name": "FBX format",
     "author": "Campbell Barton, Bastien Montagne, Jens Restemeier",
-    "version": (3, 7, 10),
+    "version": (3, 7, 11),
     "blender": (2, 77, 0),
     "location": "File > Import-Export",
     "description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions",
@@ -281,11 +281,26 @@ class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
     # 7.4 only
     apply_unit_scale = BoolProperty(
             name="Apply Unit",
-            description="Scale all data according to current Blender size, to match default FBX unit "
-                        "(centimeter, some importers do not handle UnitScaleFactor properly)",
+            description="Take into account current Blender units settings (if unset, raw Blender Units values are used as-is)",
             default=True,
             )
     # 7.4 only
+    apply_scale_options = EnumProperty(
+            items=(('FBX_SCALE_NONE', "All Local",
+                    "Apply custom scaling and units scaling to each object transformation, FBX scale remains at 1.0"),
+                   ('FBX_SCALE_UNITS', "FBX Units Scale",
+                    "Apply custom scaling to each object transformation, and units scaling to FBX scale"),
+                   ('FBX_SCALE_CUSTOM', "FBX Custom Scale",
+                    "Apply custom scaling to FBX scale, and units scaling to each object transformation"),
+                   ('FBX_SCALE_ALL', "FBX All",
+                    "Apply custom scaling and units scaling to FBX scale"),
+                   ),
+            name="Apply Scalings",
+            description="How to apply custom and units scalings in generated FBX file "
+                        "(Blender uses FBX scale to detect units on import, "
+                        "but many other applications do not handle the same way)",
+            )
+    # 7.4 only
     bake_space_transform = BoolProperty(
             name="!EXPERIMENTAL! Apply Transform",
             description="Bake space transform into object data, avoids getting unwanted rotations to objects when "
@@ -499,10 +514,14 @@ class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
             layout.prop(self, "ui_tab", expand=True)
             if self.ui_tab == 'MAIN':
                 layout.prop(self, "use_selection")
-                row = layout.row(align=True)
+
+                col = layout.column(align=True)
+                row = col.row(align=True)
                 row.prop(self, "global_scale")
                 sub = row.row(align=True)
                 sub.prop(self, "apply_unit_scale", text="", icon='NDOF_TRANS')
+                col.prop(self, "apply_scale_options")
+
                 layout.prop(self, "axis_forward")
                 layout.prop(self, "axis_up")
 
@@ -585,13 +604,11 @@ class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
         if not self.filepath:
             raise Exception("filepath not set")
 
-        global_matrix = (Matrix.Scale(self.global_scale, 4) *
-                         axis_conversion(to_forward=self.axis_forward,
+        global_matrix = (axis_conversion(to_forward=self.axis_forward,
                                          to_up=self.axis_up,
                                          ).to_4x4())
 
-        keywords = self.as_keywords(ignore=("global_scale",
-                                            "check_existing",
+        keywords = self.as_keywords(ignore=("check_existing",
                                             "filter_glob",
                                             "ui_tab",
                                             ))
diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py
index 70d149bf..9797b117 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -2673,15 +2673,16 @@ def fbx_header_elements(root, scene_data, time=None):
 
     props = elem_properties(global_settings)
     up_axis, front_axis, coord_axis = RIGHT_HAND_AXES[scene_data.settings.to_axes]
-    # DO NOT take into account global scale here! That setting is applied to object transformations during export
-    # (in other words, this is pure blender-exporter feature, and has nothing to do with FBX data).
-    if scene_data.settings.apply_unit_scale:
-        # Unit scaling is applied to objects' scale, so our unit is effectively FBX one (centimeter).
-        scale_factor_org = 1.0
-        scale_factor = 1.0 / units_blender_to_fbx_factor(scene)
-    else:
-        scale_factor_org = units_blender_to_fbx_factor(scene)
-        scale_factor = scale_factor_org
+    #~ # DO NOT take into account global scale here! That setting is applied to object transformations during export
+    #~ # (in other words, this is pure blender-exporter feature, and has nothing to do with FBX data).
+    #~ if scene_data.settings.apply_unit_scale:
+        #~ # Unit scaling is applied to objects' scale, so our unit is effectively FBX one (centimeter).
+        #~ scale_factor_org = 1.0
+        #~ scale_factor = 1.0 / units_blender_to_fbx_factor(scene)
+    #~ else:
+        #~ scale_factor_org = units_blender_to_fbx_factor(scene)
+        #~ scale_factor = scale_factor_org
+    scale_factor = scale_factor_org = scene_data.settings.unit_scale
     elem_props_set(props, "p_integer", b"UpAxis", up_axis[0])
     elem_props_set(props, "p_integer", b"UpAxisSign", up_axis[1])
     elem_props_set(props, "p_integer", b"FrontAxis", front_axis[0])
@@ -2867,6 +2868,8 @@ def fbx_takes_elements(root, scene_data):
 def save_single(operator, scene, filepath="",
                 global_matrix=Matrix(),
                 apply_unit_scale=False,
+                global_scale=1.0,
+                apply_scale_options='FBX_SCALE_NONE',
                 axis_up="Z",
                 axis_forward="Y",
                 context_objects=None,
@@ -2905,8 +2908,19 @@ def save_single(operator, scene, filepath="",
     if 'OTHER' in object_types:
         object_types |= BLENDER_OTHER_OBJECT_TYPES
 
-    if apply_unit_scale:
-        global_matrix = global_matrix * Matrix.Scale(units_blender_to_fbx_factor(scene), 4)
+    # Default Blender unit is equivalent to meter, while FBX one is centimeter...
+    unit_scale = units_blender_to_fbx_factor(scene) if apply_unit_scale else 100.0
+    if apply_scale_options == 'FBX_SCALE_NONE':
+        global_matrix = Matrix.Scale(unit_scale * global_scale, 4) * global_matrix
+        unit_scale = 1.0
+    elif apply_scale_options == 'FBX_SCALE_UNITS':
+        global_matrix = Matrix.Scale(global_scale, 4) * global_matrix
+    elif apply_scale_options == 'FBX_SCALE_CUSTOM':
+        global_matrix = Matrix.Scale(unit_scale, 4) * global_matrix
+        unit_scale = global_scale
+    else: # if apply_scale_options == 'FBX_SCALE_ALL':
+        unit_scale = global_scale * unit_scale
+
     global_scale = global_matrix.median_scale
     global_matrix_inv = global_matrix.inverted()
     # For transforming mesh normals.
@@ -2941,7 +2955,7 @@ def save_single(operator, scene, filepath="",
     )
 
     settings = FBXExportSettings(
-        operator.report, (axis_up, axis_forward), global_matrix, global_scale, apply_unit_scale,
+        operator.report, (axis_up, axis_forward), global_matrix, global_scale, apply_unit_scale, unit_scale,
         bake_space_transform, global_matrix_inv, global_matrix_inv_transposed,
         context_objects, object_types, use_mesh_modifiers, use_mesh_modifiers_render,
         mesh_smooth_type, use_mesh_edges, use_tspace,
diff --git a/io_scene_fbx/fbx_utils.py b/io_scene_fbx/fbx_utils.py
index d79023ee..16a8256f 100644
--- a/io_scene_fbx/fbx_utils.py
+++ b/io_scene_fbx/fbx_utils.py
@@ -1191,7 +1191,7 @@ FBXExportSettingsMedia = namedtuple("FBXExportSettingsMedia", (
 
 # Helper container gathering all exporter settings.
 FBXExportSettings = namedtuple("FBXExportSettings", (
-    "report", "to_axes", "global_matrix", "global_scale", "apply_unit_scale",
+    "report", "to_axes", "global_matrix", "global_scale", "apply_unit_scale", "unit_scale",
     "bake_space_transform", "global_matrix_inv", "global_matrix_inv_transposed",
     "context_objects", "object_types", "use_mesh_modifiers", "use_mesh_modifiers_render",
     "mesh_smooth_type", "use_mesh_edges", "use_tspace",



More information about the Bf-extensions-cvs mailing list