Fix #120590: FBX import gives sharp edges for non-normalized normals
A few files included in reports contained normals that were not normalized. In order to contain consistent normals around smooth corner fans, sharp edges are added when neighboring corner normals aren't close enough. Non-unit-vector normals also triggered this check. Blender used to do this implicitly when the derived `MeshLoop.normal` value was set. That API has been changed already, and it's clearer if the addon provides normalized normals, so this PR adds a normalization step to the FBX importer. Pull Request: https://projects.blender.org/blender/blender/pulls/124261
This commit is contained in:
@@ -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)))
|
||||
|
||||
Reference in New Issue
Block a user