From eb2a18f2a0ecfc95e5a29744b8eb28e9585ee122 Mon Sep 17 00:00:00 2001 From: Thomas Barlow Date: Tue, 20 Jun 2023 17:59:28 +0100 Subject: [PATCH] Fix #104707: FBX edge creases fail to be imported/exported The MeshEdge.crease API has been removed in 4.0, replaced with the "crease_edge" attribute and the Python defined Mesh.edge_creases/edge_creases_ensure()/edge_creases_remove(). This patch replaces use of the old MeshEdge.crease API with accessing the "crease_edge" attribute with the Python defined property and function. The intention of this patch is not to perform any functional changes compared to when the older MeshEdge.crease API was used, so while it may be possible to skip exporting creases when there aren't any, this has been left as a "todo" comment for now. --- io_scene_fbx/export_fbx_bin.py | 28 +++++++++++++++++----------- io_scene_fbx/import_fbx.py | 4 ++-- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py index 66cd9e691..2509dee84 100644 --- a/io_scene_fbx/export_fbx_bin.py +++ b/io_scene_fbx/export_fbx_bin.py @@ -1109,19 +1109,25 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes): ec_fbx_dtype = np.float64 if t_pvi_edge_indices.size: ec_bl_dtype = np.single - t_ec_raw = np.empty(len(me.edges), dtype=ec_bl_dtype) - me.edges.foreach_get('crease', t_ec_raw) + edge_creases = me.edge_creases + if edge_creases: + t_ec_raw = np.empty(len(me.edges), dtype=ec_bl_dtype) + edge_creases.data.foreach_get("value", t_ec_raw) - # Convert to t_pvi edge-keys. - t_ec_ek_raw = t_ec_raw[t_pvi_edge_indices] + # Convert to t_pvi edge-keys. + t_ec_ek_raw = t_ec_raw[t_pvi_edge_indices] - # Blender squares those values before sending them to OpenSubdiv, when other software don't, - # so we need to compensate that to get similar results through FBX... - # Use the precision of the fbx dtype for the calculation since it's usually higher precision. - t_ec_ek_raw = t_ec_ek_raw.astype(ec_fbx_dtype, copy=False) - t_ec = np.square(t_ec_ek_raw, out=t_ec_ek_raw) - del t_ec_ek_raw - del t_ec_raw + # Blender squares those values before sending them to OpenSubdiv, when other software don't, + # so we need to compensate that to get similar results through FBX... + # Use the precision of the fbx dtype for the calculation since it's usually higher precision. + t_ec_ek_raw = t_ec_ek_raw.astype(ec_fbx_dtype, copy=False) + t_ec = np.square(t_ec_ek_raw, out=t_ec_ek_raw) + del t_ec_ek_raw + del t_ec_raw + else: + # todo: Blender edge creases are optional now, we may be able to avoid writing the array to FBX when + # there are no edge creases. + t_ec = np.zeros(t_pvi_edge_indices.shape, dtype=ec_fbx_dtype) else: t_ec = np.empty(0, dtype=ec_fbx_dtype) diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py index a14559cbf..8ea898b1b 100644 --- a/io_scene_fbx/import_fbx.py +++ b/io_scene_fbx/import_fbx.py @@ -1360,9 +1360,9 @@ def blen_read_geom_layer_edge_crease(fbx_obj, mesh): print("warning skipping edge crease data, no valid edges...") return False - blen_data = mesh.edges + blen_data = mesh.edge_creases_ensure().data return blen_read_geom_array_mapped_edge( - mesh, blen_data, "crease", np.single, + mesh, blen_data, "value", np.single, fbx_layer_data, None, fbx_layer_mapping, fbx_layer_ref, 1, 1, layer_id, -- 2.30.2