From a2e1c4f1d1a236bbce714cb3ca52b3493c13aea7 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 12 Jan 2019 12:56:48 +0100 Subject: Fix T57308: (hopefully) FBX export UV islands broken. Looks like we need to not merge UVs from different islands into same set of coordinates in the 'compressed' mapped storage of FBX data, seems to be the way for that piece of crap of a wanabe format to convey islands concept... Gets the code even more cryptic, yay! --- io_scene_fbx/__init__.py | 2 +- io_scene_fbx/export_fbx_bin.py | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'io_scene_fbx') diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py index d415305d..86749770 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": (4, 13, 1), + "version": (4, 14, 0), "blender": (2, 80, 0), "location": "File > Import-Export", "description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions", diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py index 6f6005cb..77ee0e6f 100644 --- a/io_scene_fbx/export_fbx_bin.py +++ b/io_scene_fbx/export_fbx_bin.py @@ -1100,10 +1100,14 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes): # Textures are now only related to materials, in FBX! uvnumber = len(me.uv_layers) if uvnumber: - def _uvtuples_gen(raw_uvs): - return zip(*(iter(raw_uvs),) * 2) + # Looks like this mapping is also expected to convey UV islands (arg..... :((((( ). + # So we need to generate unique triplets (uv, vertex_idx) here, not only just based on UV values. + def _uvtuples_gen(raw_uvs, raw_lvidxs): + return zip(zip(*(iter(raw_uvs),) * 2), raw_lvidxs) t_luv = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(me.loops) * 2 + t_lvidx = array.array(data_types.ARRAY_INT32, (0,)) * len(me.loops) + me.loops.foreach_get("vertex_index", t_lvidx) for uvindex, uvlayer in enumerate(me.uv_layers): uvlayer.data.foreach_get("uv", t_luv) lay_uv = elem_data_single_int32(geom, b"LayerElementUV", uvindex) @@ -1112,13 +1116,15 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes): elem_data_single_string(lay_uv, b"MappingInformationType", b"ByPolygonVertex") elem_data_single_string(lay_uv, b"ReferenceInformationType", b"IndexToDirect") - uv2idx = tuple(set(_uvtuples_gen(t_luv))) - elem_data_single_float64_array(lay_uv, b"UV", chain(*uv2idx)) # Flatten again... + uv_ids = tuple(set(_uvtuples_gen(t_luv, t_lvidx))) + elem_data_single_float64_array(lay_uv, b"UV", chain(*(uv for uv, vidx in uv_ids))) # Flatten again... - uv2idx = {uv: idx for idx, uv in enumerate(uv2idx)} - elem_data_single_int32_array(lay_uv, b"UVIndex", (uv2idx[uv] for uv in _uvtuples_gen(t_luv))) + uv2idx = {uv_id: idx for idx, uv_id in enumerate(uv_ids)} + elem_data_single_int32_array(lay_uv, b"UVIndex", (uv2idx[uv_id] for uv_id in _uvtuples_gen(t_luv, t_lvidx))) del uv2idx + del uv_ids del t_luv + del t_lvidx del _uvtuples_gen # Face's materials. -- cgit v1.2.3