Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAras Pranckevicius <aras@nesnausk.org>2022-09-14 23:00:01 +0300
committerAras Pranckevicius <aras@nesnausk.org>2022-09-14 23:00:01 +0300
commit692f4691abc6a21f9d30f94a99882f2c46330903 (patch)
treee123e09c05a6938dfc44de0ade3aeb6616b1f46a
parentad6d68161076025a51b145a3d6dbe03eefaf6cf9 (diff)
FBX: support new color attributes, and sRGB/Linear/None colors option (T98721)
FBX exporter code was only supporting "Face Corner - Byte Color" attribute type, using the deprecated Mesh.vertex_colors API. Update the to use the new attributes API, and to handle all the attribute combinations. An option to pick between sRGB (default, matches current behavior), Linear (requested in T82847) or None (don't export/import any color attributes) has been added to the exporter and the importer. Reviewed By: Bastien Montagne Differential Revision: https://developer.blender.org/D15942
-rw-r--r--io_scene_fbx/__init__.py24
-rw-r--r--io_scene_fbx/export_fbx_bin.py29
-rw-r--r--io_scene_fbx/fbx_utils.py4
-rw-r--r--io_scene_fbx/import_fbx.py19
4 files changed, 58 insertions, 18 deletions
diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py
index feea8436..185e8336 100644
--- a/io_scene_fbx/__init__.py
+++ b/io_scene_fbx/__init__.py
@@ -3,8 +3,8 @@
bl_info = {
"name": "FBX format",
"author": "Campbell Barton, Bastien Montagne, Jens Restemeier",
- "version": (4, 36, 3),
- "blender": (3, 2, 0),
+ "version": (4, 37, 0),
+ "blender": (3, 4, 0),
"location": "File > Import-Export",
"description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions",
"warning": "",
@@ -89,6 +89,15 @@ class ImportFBX(bpy.types.Operator, ImportHelper):
description="Import custom normals, if available (otherwise Blender will recompute them)",
default=True,
)
+ colors_type: EnumProperty(
+ name="Vertex Colors",
+ items=(('NONE', "None", "Do not import color attributes"),
+ ('SRGB', "sRGB", "Expect file colors in sRGB color space"),
+ ('LINEAR', "Linear", "Expect file colors in linear color space"),
+ ),
+ description="Import vertex color attributes",
+ default='SRGB',
+ )
use_image_search: BoolProperty(
name="Image Search",
@@ -230,6 +239,7 @@ class FBX_PT_import_include(bpy.types.Panel):
sub.enabled = operator.use_custom_props
sub.prop(operator, "use_custom_props_enum_as_string")
layout.prop(operator, "use_image_search")
+ layout.prop(operator, "colors_type")
class FBX_PT_import_transform(bpy.types.Panel):
@@ -463,6 +473,15 @@ class ExportFBX(bpy.types.Operator, ExportHelper):
"(prefer 'Normals Only' option if your target importer understand split normals)",
default='OFF',
)
+ colors_type: EnumProperty(
+ name="Vertex Colors",
+ items=(('NONE', "None", "Do not export color attributes"),
+ ('SRGB', "sRGB", "Export colors in sRGB color space"),
+ ('LINEAR', "Linear", "Export colors in linear color space"),
+ ),
+ description="Export vertex color attributes",
+ default='SRGB',
+ )
use_subsurf: BoolProperty(
name="Export Subdivision Surface",
description="Export the last Catmull-Rom subdivision modifier as FBX subdivision "
@@ -767,6 +786,7 @@ class FBX_PT_export_geometry(bpy.types.Panel):
sub = layout.row()
#~ sub.enabled = operator.mesh_smooth_type in {'OFF'}
sub.prop(operator, "use_tspace")
+ layout.prop(operator, "colors_type")
class FBX_PT_export_armature(bpy.types.Panel):
diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py
index f560b19c..a4a96bf5 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -1111,14 +1111,20 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
me.free_normals_split()
# Write VertexColor Layers.
- vcolnumber = len(me.vertex_colors)
+ colors_type = scene_data.settings.colors_type
+ vcolnumber = 0 if colors_type == 'NONE' else len(me.color_attributes)
if vcolnumber:
def _coltuples_gen(raw_cols):
return zip(*(iter(raw_cols),) * 4)
- t_lc = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * len(me.loops) * 4
- for colindex, collayer in enumerate(me.vertex_colors):
- collayer.data.foreach_get("color", t_lc)
+ color_prop_name = "color_srgb" if colors_type == 'SRGB' else "color"
+
+ for colindex, collayer in enumerate(me.color_attributes):
+ is_point = collayer.domain == "POINT"
+ vcollen = len(me.vertices if is_point else me.loops)
+ t_lc = array.array(data_types.ARRAY_FLOAT64, (0.0,)) * vcollen * 4
+ collayer.data.foreach_get(color_prop_name, t_lc)
+
lay_vcol = elem_data_single_int32(geom, b"LayerElementColor", colindex)
elem_data_single_int32(lay_vcol, b"Version", FBX_GEOMETRY_VCOLOR_VERSION)
elem_data_single_string_unicode(lay_vcol, b"Name", collayer.name)
@@ -1129,9 +1135,16 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
elem_data_single_float64_array(lay_vcol, b"Colors", chain(*col2idx)) # Flatten again...
col2idx = {col: idx for idx, col in enumerate(col2idx)}
- elem_data_single_int32_array(lay_vcol, b"ColorIndex", (col2idx[c] for c in _coltuples_gen(t_lc)))
+ col_indices = list(col2idx[c] for c in _coltuples_gen(t_lc))
+ if is_point:
+ # for "point" domain colors, we could directly emit them
+ # with a "ByVertex" mapping type, but some software does not
+ # properly understand that. So expand to full "ByPolygonVertex"
+ # index map.
+ col_indices = list((col_indices[c.vertex_index] for c in me.loops))
+ elem_data_single_int32_array(lay_vcol, b"ColorIndex", col_indices)
del col2idx
- del t_lc
+ del t_lc
del _coltuples_gen
# Write UV layers.
@@ -3021,6 +3034,7 @@ def save_single(operator, scene, depsgraph, filepath="",
use_custom_props=False,
bake_space_transform=False,
armature_nodetype='NULL',
+ colors_type='SRGB',
**kwargs
):
@@ -3088,7 +3102,7 @@ def save_single(operator, scene, depsgraph, filepath="",
add_leaf_bones, bone_correction_matrix, bone_correction_matrix_inv,
bake_anim, bake_anim_use_all_bones, bake_anim_use_nla_strips, bake_anim_use_all_actions,
bake_anim_step, bake_anim_simplify_factor, bake_anim_force_startend_keying,
- False, media_settings, use_custom_props,
+ False, media_settings, use_custom_props, colors_type,
)
import bpy_extras.io_utils
@@ -3155,6 +3169,7 @@ def defaults_unity3d():
"use_mesh_modifiers_render": True,
"use_mesh_edges": False,
"mesh_smooth_type": 'FACE',
+ "colors_type": 'SRGB',
"use_subsurf": False,
"use_tspace": False, # XXX Why? Unity is expected to support tspace import...
"use_triangles": False,
diff --git a/io_scene_fbx/fbx_utils.py b/io_scene_fbx/fbx_utils.py
index 41c63ef8..e52cd9eb 100644
--- a/io_scene_fbx/fbx_utils.py
+++ b/io_scene_fbx/fbx_utils.py
@@ -1220,7 +1220,7 @@ FBXExportSettings = namedtuple("FBXExportSettings", (
"bone_correction_matrix", "bone_correction_matrix_inv",
"bake_anim", "bake_anim_use_all_bones", "bake_anim_use_nla_strips", "bake_anim_use_all_actions",
"bake_anim_step", "bake_anim_simplify_factor", "bake_anim_force_startend_keying",
- "use_metadata", "media_settings", "use_custom_props",
+ "use_metadata", "media_settings", "use_custom_props", "colors_type",
))
# Helper container gathering some data we need multiple times:
@@ -1249,5 +1249,5 @@ FBXImportSettings = namedtuple("FBXImportSettings", (
"use_custom_props", "use_custom_props_enum_as_string",
"nodal_material_wrap_map", "image_cache",
"ignore_leaf_bones", "force_connect_children", "automatic_bone_orientation", "bone_correction_matrix",
- "use_prepost_rot",
+ "use_prepost_rot", "colors_type",
))
diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py
index 72d666c1..00376f38 100644
--- a/io_scene_fbx/import_fbx.py
+++ b/io_scene_fbx/import_fbx.py
@@ -1061,7 +1061,12 @@ def blen_read_geom_layer_uv(fbx_obj, mesh):
)
-def blen_read_geom_layer_color(fbx_obj, mesh):
+def blen_read_geom_layer_color(fbx_obj, mesh, colors_type):
+ if colors_type == 'NONE':
+ return
+ use_srgb = colors_type == 'SRGB'
+ layer_type = 'BYTE_COLOR' if use_srgb else 'FLOAT_COLOR'
+ color_prop_name = "color_srgb" if use_srgb else "color"
# almost same as UV's
for layer_id in (b'LayerElementColor',):
for fbx_layer in elem_find_iter(fbx_obj, layer_id):
@@ -1074,8 +1079,7 @@ def blen_read_geom_layer_color(fbx_obj, mesh):
fbx_layer_data = elem_prop_first(elem_find_first(fbx_layer, b'Colors'))
fbx_layer_index = elem_prop_first(elem_find_first(fbx_layer, b'ColorIndex'))
- # Always init our new layers with full white opaque color.
- color_lay = mesh.vertex_colors.new(name=fbx_layer_name, do_init=False)
+ color_lay = mesh.color_attributes.new(name=fbx_layer_name, type=layer_type, domain='CORNER')
if color_lay is None:
print("Failed to add {%r %r} vertex color layer to %r (probably too many of them?)"
@@ -1090,7 +1094,7 @@ def blen_read_geom_layer_color(fbx_obj, mesh):
continue
blen_read_geom_array_mapped_polyloop(
- mesh, blen_data, "color",
+ mesh, blen_data, color_prop_name,
fbx_layer_data, fbx_layer_index,
fbx_layer_mapping, fbx_layer_ref,
4, 4, layer_id,
@@ -1289,7 +1293,7 @@ def blen_read_geom(fbx_tmpl, fbx_obj, settings):
blen_read_geom_layer_material(fbx_obj, mesh)
blen_read_geom_layer_uv(fbx_obj, mesh)
- blen_read_geom_layer_color(fbx_obj, mesh)
+ blen_read_geom_layer_color(fbx_obj, mesh, settings.colors_type)
if fbx_edges:
# edges in fact index the polygons (NOT the vertices)
@@ -2365,7 +2369,8 @@ def load(operator, context, filepath="",
automatic_bone_orientation=False,
primary_bone_axis='Y',
secondary_bone_axis='X',
- use_prepost_rot=True):
+ use_prepost_rot=True,
+ colors_type='SRGB'):
global fbx_elem_nil
fbx_elem_nil = FBXElem('', (), (), ())
@@ -2504,7 +2509,7 @@ def load(operator, context, filepath="",
use_custom_props, use_custom_props_enum_as_string,
nodal_material_wrap_map, image_cache,
ignore_leaf_bones, force_connect_children, automatic_bone_orientation, bone_correction_matrix,
- use_prepost_rot,
+ use_prepost_rot, colors_type,
)
# #### And now, the "real" data.