FBX Export: Tidy up after numpy patches #104471

Merged
Bastien Montagne merged 1 commits from Mysteryem/blender-addons:fbx_numpy_tidyup_pr into main 2023-03-13 12:27:38 +01:00
2 changed files with 13 additions and 25 deletions
Showing only changes of commit 6eb52267e4 - Show all commits

View File

@ -3,14 +3,13 @@
# Script copyright (C) Campbell Barton, Bastien Montagne # Script copyright (C) Campbell Barton, Bastien Montagne
import array
import datetime import datetime
import math import math
import numpy as np import numpy as np
import os import os
import time import time
from itertools import zip_longest, chain from itertools import zip_longest
from functools import cache from functools import cache
if "bpy" in locals(): if "bpy" in locals():
@ -51,7 +50,7 @@ from .fbx_utils import (
matrix4_to_array, similar_values, shape_difference_exclude_similar, astype_view_signedness, fast_first_axis_unique, matrix4_to_array, similar_values, shape_difference_exclude_similar, astype_view_signedness, fast_first_axis_unique,
fast_first_axis_flat, fast_first_axis_flat,
# Mesh transform helpers. # Mesh transform helpers.
vcos_transformed_gen, vcos_transformed, nors_transformed, vcos_transformed, nors_transformed,
# UUID from key. # UUID from key.
get_fbx_uuid_from_key, get_fbx_uuid_from_key,
# Key generators. # Key generators.
@ -999,7 +998,8 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
# We have to ^-1 last index of each loop. # We have to ^-1 last index of each loop.
# Ensure t_pvi is the correct number of bits before inverting. # Ensure t_pvi is the correct number of bits before inverting.
t_pvi = astype_view_signedness(t_lvi, pvi_fbx_dtype) # t_lvi may be used again later, so always create a copy to avoid modifying it in the next step.
t_pvi = t_lvi.astype(pvi_fbx_dtype)
# The index of the end of each loop is one before the index of the start of the next loop. # The index of the end of each loop is one before the index of the start of the next loop.
t_pvi[t_ls[1:] - 1] ^= -1 t_pvi[t_ls[1:] - 1] ^= -1
# The index of the end of the last loop will be the very last index. # The index of the end of the last loop will be the very last index.
@ -1015,7 +1015,6 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
t_eli = astype_view_signedness(t_eli, eli_fbx_dtype) t_eli = astype_view_signedness(t_eli, eli_fbx_dtype)
elem_data_single_int32_array(geom, b"PolygonVertexIndex", t_pvi) elem_data_single_int32_array(geom, b"PolygonVertexIndex", t_pvi)
elem_data_single_int32_array(geom, b"Edges", t_eli) elem_data_single_int32_array(geom, b"Edges", t_eli)
del t_lvi
del t_pvi del t_pvi
del t_eli del t_eli
del t_ev del t_ev
@ -1168,7 +1167,7 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
elem_data_single_float64_array(lay_nor, b"Normals", t_ln) elem_data_single_float64_array(lay_nor, b"Normals", t_ln)
# Normal weights, no idea what it is. # Normal weights, no idea what it is.
# t_lnw = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(t_ln) # t_lnw = np.zeros(len(t_ln), dtype=np.float64)
# elem_data_single_float64_array(lay_nor, b"NormalsW", t_lnw) # elem_data_single_float64_array(lay_nor, b"NormalsW", t_lnw)
elem_data_single_int32_array(lay_nor, b"NormalsIndex", t_lnidx) elem_data_single_int32_array(lay_nor, b"NormalsIndex", t_lnidx)
@ -1183,7 +1182,7 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
elem_data_single_string(lay_nor, b"ReferenceInformationType", b"Direct") elem_data_single_string(lay_nor, b"ReferenceInformationType", b"Direct")
elem_data_single_float64_array(lay_nor, b"Normals", t_ln) elem_data_single_float64_array(lay_nor, b"Normals", t_ln)
# Normal weights, no idea what it is. # Normal weights, no idea what it is.
# t_ln = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(me.loops) # t_ln = np.zeros(len(me.loops), dtype=np.float64)
# elem_data_single_float64_array(lay_nor, b"NormalsW", t_ln) # elem_data_single_float64_array(lay_nor, b"NormalsW", t_ln)
del t_ln del t_ln
@ -1205,7 +1204,7 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
del t_lt del t_lt
num_loops = len(me.loops) num_loops = len(me.loops)
t_ln = np.empty(num_loops * 3, dtype=ln_bl_dtype) t_ln = np.empty(num_loops * 3, dtype=ln_bl_dtype)
# t_lnw = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(me.loops) # t_lnw = np.zeros(len(me.loops), dtype=np.float64)
uv_names = [uvlayer.name for uvlayer in me.uv_layers] uv_names = [uvlayer.name for uvlayer in me.uv_layers]
# Annoying, `me.calc_tangent` errors in case there is no geometry... # Annoying, `me.calc_tangent` errors in case there is no geometry...
if num_loops > 0: if num_loops > 0:
@ -1252,15 +1251,13 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
color_prop_name = "color_srgb" if colors_type == 'SRGB' else "color" color_prop_name = "color_srgb" if colors_type == 'SRGB' else "color"
# ByteColorAttribute color also gets returned by the API as single precision float # ByteColorAttribute color also gets returned by the API as single precision float
bl_lc_dtype = np.single bl_lc_dtype = np.single
bl_lvi_dtype = np.uintc
fbx_lc_dtype = np.float64 fbx_lc_dtype = np.float64
fbx_lcidx_dtype = np.int32 fbx_lcidx_dtype = np.int32
t_lvi = None
color_attributes = me.color_attributes color_attributes = me.color_attributes
if scene_data.settings.prioritize_active_color: if scene_data.settings.prioritize_active_color:
active_color = me.color_attributes.active_color active_color = me.color_attributes.active_color
color_attributes = sorted(color_attributes, key=lambda x: x == active_color, reverse=True) color_attributes = sorted(color_attributes, key=lambda x: x == active_color, reverse=True)
for colindex, collayer in enumerate(color_attributes): for colindex, collayer in enumerate(color_attributes):
is_point = collayer.domain == "POINT" is_point = collayer.domain == "POINT"
@ -1282,10 +1279,8 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
# with a "ByVertex" mapping type, but some software does not # with a "ByVertex" mapping type, but some software does not
# properly understand that. So expand to full "ByPolygonVertex" # properly understand that. So expand to full "ByPolygonVertex"
# index map. # index map.
if t_lvi is None: # Ignore loops added for loose edges.
t_lvi = np.empty(len(me.loops), dtype=bl_lvi_dtype) col_indices = col_indices[t_lvi[:len(me.loops)]]
me.loops.foreach_get("vertex_index", t_lvi)
col_indices = col_indices[t_lvi]
t_lc = t_lc.astype(fbx_lc_dtype, copy=False) t_lc = t_lc.astype(fbx_lc_dtype, copy=False)
col_indices = astype_view_signedness(col_indices, fbx_lcidx_dtype) col_indices = astype_view_signedness(col_indices, fbx_lcidx_dtype)
@ -1295,7 +1290,6 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
del t_lc del t_lc
del col_indices del col_indices
del t_lvi
# Write UV layers. # Write UV layers.
# Note: LayerElementTexture is deprecated since FBX 2011 - luckily! # Note: LayerElementTexture is deprecated since FBX 2011 - luckily!
@ -1304,7 +1298,6 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
if uvnumber: if uvnumber:
luv_bl_dtype = np.single luv_bl_dtype = np.single
luv_fbx_dtype = np.float64 luv_fbx_dtype = np.float64
lv_idx_bl_dtype = np.uintc
lv_idx_fbx_dtype = np.int32 lv_idx_fbx_dtype = np.int32
t_luv = np.empty(len(me.loops) * 2, dtype=luv_bl_dtype) t_luv = np.empty(len(me.loops) * 2, dtype=luv_bl_dtype)
@ -1315,8 +1308,8 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
# Looks like this mapping is also expected to convey UV islands (arg..... :((((( ). # 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. # So we need to generate unique triplets (uv, vertex_idx) here, not only just based on UV values.
t_lvidx = np.empty(len(me.loops), dtype=lv_idx_bl_dtype) # Ignore loops added for loose edges.
me.loops.foreach_get("vertex_index", t_lvidx) t_lvidx = t_lvi[:len(me.loops)]
# If we were to create a combined array of (uv, vertex_idx) elements, we could find unique triplets by sorting # If we were to create a combined array of (uv, vertex_idx) elements, we could find unique triplets by sorting
# that array by first sorting by the vertex_idx column and then sorting by the uv column using a stable sorting # that array by first sorting by the vertex_idx column and then sorting by the uv column using a stable sorting
@ -1407,6 +1400,7 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
del t_lvidx del t_lvidx
del t_luv del t_luv
del t_luv_fast_pair_view del t_luv_fast_pair_view
del t_lvi
# Face's materials. # Face's materials.
me_fbxmaterials_idx = scene_data.mesh_material_indices.get(me) me_fbxmaterials_idx = scene_data.mesh_material_indices.get(me)

View File

@ -295,12 +295,6 @@ def shape_difference_exclude_similar(sv_cos, ref_cos, e=1e-6):
return difference_cos, not_similar_verts_idx return difference_cos, not_similar_verts_idx
def vcos_transformed_gen(raw_cos, m=None):
# Note: we could most likely get much better performances with numpy, but will leave this as TODO for now.
gen = zip(*(iter(raw_cos),) * 3)
return gen if m is None else (m @ Vector(v) for v in gen)
def _mat4_vec3_array_multiply(mat4, vec3_array, dtype=None, return_4d=False): def _mat4_vec3_array_multiply(mat4, vec3_array, dtype=None, return_4d=False):
"""Multiply a 4d matrix by each 3d vector in an array and return as an array of either 3d or 4d vectors. """Multiply a 4d matrix by each 3d vector in an array and return as an array of either 3d or 4d vectors.