Fix: FBX fails to export materials on geometry nodes objects #104530
@ -1431,7 +1431,7 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
|
|||||||
me_fbxmaterials_idx = scene_data.mesh_material_indices.get(me)
|
me_fbxmaterials_idx = scene_data.mesh_material_indices.get(me)
|
||||||
if me_fbxmaterials_idx is not None:
|
if me_fbxmaterials_idx is not None:
|
||||||
# We cannot use me.materials here, as this array is filled with None in case materials are linked to object...
|
# We cannot use me.materials here, as this array is filled with None in case materials are linked to object...
|
||||||
me_blmaterials = [mat_slot.material for mat_slot in me_obj.material_slots]
|
me_blmaterials = me_obj.materials
|
||||||
if me_fbxmaterials_idx and me_blmaterials:
|
if me_fbxmaterials_idx and me_blmaterials:
|
||||||
lay_ma = elem_data_single_int32(geom, b"LayerElementMaterial", 0)
|
lay_ma = elem_data_single_int32(geom, b"LayerElementMaterial", 0)
|
||||||
elem_data_single_int32(lay_ma, b"Version", FBX_GEOMETRY_MATERIAL_VERSION)
|
elem_data_single_int32(lay_ma, b"Version", FBX_GEOMETRY_MATERIAL_VERSION)
|
||||||
@ -2598,6 +2598,14 @@ def fbx_data_from_scene(scene, depsgraph, settings):
|
|||||||
bmesh.ops.triangulate(bm, faces=bm.faces)
|
bmesh.ops.triangulate(bm, faces=bm.faces)
|
||||||
bm.to_mesh(tmp_me)
|
bm.to_mesh(tmp_me)
|
||||||
bm.free()
|
bm.free()
|
||||||
|
# Usually the materials of the evaluated object will be the same, but modifiers, such as Geometry Nodes,
|
||||||
|
# can change the materials.
|
||||||
|
orig_mats = tuple(slot.material for slot in ob.material_slots)
|
||||||
|
eval_mats = tuple(slot.material.original if slot.material else None
|
||||||
|
for slot in ob_to_convert.material_slots)
|
||||||
|
if orig_mats != eval_mats:
|
||||||
|
# Override the default behaviour of getting materials from ob_obj.bdata.material_slots.
|
||||||
|
ob_obj.override_materials = eval_mats
|
||||||
data_meshes[ob_obj] = (get_blenderID_key(tmp_me), tmp_me, True)
|
data_meshes[ob_obj] = (get_blenderID_key(tmp_me), tmp_me, True)
|
||||||
# Change armatures back.
|
# Change armatures back.
|
||||||
for armature, pose_position in backup_pose_positions:
|
for armature, pose_position in backup_pose_positions:
|
||||||
@ -2713,8 +2721,7 @@ def fbx_data_from_scene(scene, depsgraph, settings):
|
|||||||
data_materials = {}
|
data_materials = {}
|
||||||
for ob_obj in objects:
|
for ob_obj in objects:
|
||||||
# If obj is not a valid object for materials, wrapper will just return an empty tuple...
|
# If obj is not a valid object for materials, wrapper will just return an empty tuple...
|
||||||
for ma_s in ob_obj.material_slots:
|
for ma in ob_obj.materials:
|
||||||
ma = ma_s.material
|
|
||||||
if ma is None:
|
if ma is None:
|
||||||
continue # Empty slots!
|
continue # Empty slots!
|
||||||
# Note theoretically, FBX supports any kind of materials, even GLSL shaders etc.
|
# Note theoretically, FBX supports any kind of materials, even GLSL shaders etc.
|
||||||
|
@ -1174,7 +1174,7 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
|
|||||||
we need to use a key to identify each.
|
we need to use a key to identify each.
|
||||||
"""
|
"""
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
'name', 'key', 'bdata', 'parented_to_armature',
|
'name', 'key', 'bdata', 'parented_to_armature', 'override_materials',
|
||||||
'_tag', '_ref', '_dupli_matrix'
|
'_tag', '_ref', '_dupli_matrix'
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1229,6 +1229,7 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
|
|||||||
self.bdata = bdata
|
self.bdata = bdata
|
||||||
self._ref = armature
|
self._ref = armature
|
||||||
self.parented_to_armature = False
|
self.parented_to_armature = False
|
||||||
|
self.override_materials = None
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return isinstance(other, self.__class__) and self.key == other.key
|
return isinstance(other, self.__class__) and self.key == other.key
|
||||||
@ -1443,11 +1444,14 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
|
|||||||
return ()
|
return ()
|
||||||
bones = property(get_bones)
|
bones = property(get_bones)
|
||||||
|
|
||||||
def get_material_slots(self):
|
def get_materials(self):
|
||||||
|
override_materials = self.override_materials
|
||||||
|
if override_materials is not None:
|
||||||
|
return override_materials
|
||||||
if self._tag in {'OB', 'DP'}:
|
if self._tag in {'OB', 'DP'}:
|
||||||
return self.bdata.material_slots
|
return tuple(slot.material for slot in self.bdata.material_slots)
|
||||||
return ()
|
return ()
|
||||||
material_slots = property(get_material_slots)
|
materials = property(get_materials)
|
||||||
|
|
||||||
def is_deformed_by_armature(self, arm_obj):
|
def is_deformed_by_armature(self, arm_obj):
|
||||||
if not (self.is_object and self.type == 'MESH'):
|
if not (self.is_object and self.type == 'MESH'):
|
||||||
|
Loading…
Reference in New Issue
Block a user