FBX Export: Tidy up after numpy patches #104471
@ -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,10 +1251,8 @@ 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:
|
||||||
@ -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)
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user