diff --git a/scripts/addons_core/io_scene_fbx/import_fbx.py b/scripts/addons_core/io_scene_fbx/import_fbx.py index 13daf585cba..0c95352605e 100644 --- a/scripts/addons_core/io_scene_fbx/import_fbx.py +++ b/scripts/addons_core/io_scene_fbx/import_fbx.py @@ -1784,6 +1784,11 @@ def blen_read_geom_layer_normal(fbx_obj, mesh, xform=None): return False +def normalize_vecs(vectors): + norms = np.linalg.norm(vectors, axis=1, keepdims=True) + np.divide(vectors, norms, out=vectors, where=norms != 0) + + def blen_read_geom(fbx_tmpl, fbx_obj, settings): # Vertices are in object space, but we are post-multiplying all transforms with the inverse of the # global matrix, so we need to apply the global matrix to the vertices to get the correct result. @@ -1914,6 +1919,10 @@ def blen_read_geom(fbx_tmpl, fbx_obj, settings): clnors = np.empty(len(mesh.loops) * 3, dtype=bl_nors_dtype) mesh.attributes["temp_custom_normals"].data.foreach_get("vector", clnors) + clnors = clnors.reshape(len(mesh.loops), 3) + normalize_vecs(clnors) + clnors = clnors.reshape(len(mesh.loops) * 3) + # Iterating clnors into a nested tuple first is faster than passing clnors.reshape(-1, 3) directly into # normals_split_custom_set. We use clnors.data since it is a memoryview, which is faster to iterate than clnors. mesh.normals_split_custom_set(tuple(zip(*(iter(clnors.data),) * 3)))