From 95633e7f1b1bb40f058cbb6d7ed0d7afd1512a24 Mon Sep 17 00:00:00 2001
From: Bastien Montagne <montagne29@wanadoo.fr>
Date: Mon, 9 Feb 2015 20:54:57 +0100
Subject: [PATCH] Fix T43582: FBX IO: Handling of 'smooth edges' was rather
 flacky on both export and import.

On export, we also want to tage as sharp edges from flat faces, and edges shared by more than two faces.

On import, we want to tag all faces as smooth and enable autosmooth, when we only have smooth edge data...
---
 io_scene_fbx/export_fbx_bin.py | 16 +++++++++++++++-
 io_scene_fbx/import_fbx.py     |  8 ++++++--
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py
index 26af47dbf..8686bbc09 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -879,6 +879,7 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
     if t_ls and t_pvi:
         t_ls = set(t_ls)
         todo_edges = [None] * len(me.edges) * 2
+        # Sigh, cannot access edge.key through foreach_get... :/
         me.edges.foreach_get("vertices", todo_edges)
         todo_edges = set((v1, v2) if v1 < v2 else (v2, v1) for v1, v2 in zip(*(iter(todo_edges),) * 2))
 
@@ -925,11 +926,24 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
             _map = b"ByPolygon"
         else:  # EDGE
             # Write Edge Smoothing.
+            # Note edge is sharp also if it's used by more than two faces, or one of its faces is flat.
             t_ps = array.array(data_types.ARRAY_INT32, (0,)) * edges_nbr
+            sharp_edges = set()
+            temp_sharp_edges = {}
+            for p in me.polygons:
+                if not p.use_smooth:
+                    sharp_edges.update(p.edge_keys)
+                    continue
+                for k in p.edge_keys:
+                    if temp_sharp_edges.setdefault(k, 0) > 1:
+                        sharp_edges.add(k)
+                    else:
+                        temp_sharp_edges[k] += 1
+            del temp_sharp_edges
             for e in me.edges:
                 if e.key not in edges_map:
                     continue  # Only loose edges, in theory!
-                t_ps[edges_map[e.key]] = not e.use_edge_sharp
+                t_ps[edges_map[e.key]] = not (e.use_edge_sharp or (e.key in sharp_edges))
             _map = b"ByEdge"
         lay_smooth = elem_data_single_int32(geom, b"LayerElementSmoothing", 0)
         elem_data_single_int32(lay_smooth, b"Version", FBX_GEOMETRY_SMOOTHING_VERSION)
diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py
index dc2e69b36..ccc5caef3 100644
--- a/io_scene_fbx/import_fbx.py
+++ b/io_scene_fbx/import_fbx.py
@@ -987,17 +987,21 @@ def blen_read_geom_layer_smooth(fbx_obj, mesh):
     if fbx_layer_mapping == b'ByEdge':
         # some models have bad edge data, we cant use this info...
         if not mesh.edges:
+            print("warning skipping sharp edges data, no valid edges...")
             return False
 
         blen_data = mesh.edges
-        ok_smooth = blen_read_geom_array_mapped_edge(
+        blen_read_geom_array_mapped_edge(
             mesh, blen_data, "use_edge_sharp",
             fbx_layer_data, None,
             fbx_layer_mapping, fbx_layer_ref,
             1, 1, layer_id,
             xform=lambda s: not s,
             )
-        return ok_smooth
+        # We only set sharp edges here, not face smoothing itself...
+        mesh.use_auto_smooth = True
+        mesh.show_edge_sharp = True
+        return False
     elif fbx_layer_mapping == b'ByPolygon':
         blen_data = mesh.polygons
         return blen_read_geom_array_mapped_polygon(
-- 
GitLab