Fix: USD: Support color attributes on all relevant domains

Color primvars/attributes were historically treated as a special case
for both import and export. This was mostly done to align with how
painting and viewport display works in Blender. Export would generally
ignore color attributes except when they were found on a Mesh's Point or
FaceCorner domains. And import went out of its way to map incoming color
primvars to the FaceCorner domain in more situations than necessary.

To facilitate better roundtripping in Blender<=>USD workflows, and to
reduce code duplication, this PR teaches the common attribute utilities
how to handle color types. The color attributes will now work on all
relevant Mesh and Curve domains.

There were tests in place for this already but they were set to verify
the inverse state, i.e. the technically broken state, until this could
be fixed.

There remains one special case: "displayColor" primvars and attributes.
The "displayColor" is a special primvar in USD and is the de-facto way
to set a simple viewport color in that ecosystem. It must also be a
color3f type. In order to not regress import, if a "displayColor"
primvar is found on the Face domain we will map it to FaceCorner instead
so it can be displayed in the viewport; which has been the case for the
past several releases. We can drop this special-case if/when Blender can
display Face colors through the Viewport Shading "Attribute" color type.
Additionally, Blender will export this, and only this, color attribute
as a color3f.

Note: As was the case prior to this PR, the following 2 discrepancies
still prevent "perfect" round-trips:
- USD does not have an equivalent to Blender's byte colors; they are
  treated as float during IO
- Blender does not have an equivalent to USD's color3 types; they are
  treated as color4 during IO

Pull Request: https://projects.blender.org/blender/blender/pulls/127784
This commit is contained in:
Jesse Yurkovich
2024-09-24 19:05:55 +02:00
committed by Jesse Yurkovich
parent a6d5652043
commit 2cdbe7b5f3
11 changed files with 161 additions and 265 deletions

View File

@@ -270,8 +270,8 @@ class USDExportTest(AbstractUSDTest):
self.check_primvar(prim, "f_int8", "VtArray<unsigned char>", "uniform", 1)
self.check_primvar(prim, "f_int32", "VtArray<int>", "uniform", 1)
self.check_primvar(prim, "f_float", "VtArray<float>", "uniform", 1)
self.check_primvar_missing(prim, "f_color")
self.check_primvar_missing(prim, "f_byte_color")
self.check_primvar(prim, "f_color", "VtArray<GfVec4f>", "uniform", 1)
self.check_primvar(prim, "f_byte_color", "VtArray<GfVec4f>", "uniform", 1)
self.check_primvar(prim, "f_vec2", "VtArray<GfVec2f>", "uniform", 1)
self.check_primvar(prim, "f_vec3", "VtArray<GfVec3f>", "uniform", 1)
self.check_primvar(prim, "f_quat", "VtArray<GfQuatf>", "uniform", 1)
@@ -294,8 +294,8 @@ class USDExportTest(AbstractUSDTest):
self.check_primvar(prim, "p_int8", "VtArray<unsigned char>", "vertex", 24)
self.check_primvar(prim, "p_int32", "VtArray<int>", "vertex", 24)
self.check_primvar(prim, "p_float", "VtArray<float>", "vertex", 24)
self.check_primvar_missing(prim, "p_color")
self.check_primvar_missing(prim, "p_byte_color")
self.check_primvar(prim, "p_color", "VtArray<GfVec4f>", "vertex", 24)
self.check_primvar(prim, "p_byte_color", "VtArray<GfVec4f>", "vertex", 24)
self.check_primvar(prim, "p_vec2", "VtArray<GfVec2f>", "vertex", 24)
self.check_primvar(prim, "p_vec3", "VtArray<GfVec3f>", "vertex", 24)
self.check_primvar(prim, "p_quat", "VtArray<GfQuatf>", "vertex", 24)
@@ -305,8 +305,8 @@ class USDExportTest(AbstractUSDTest):
self.check_primvar(prim, "sp_int8", "VtArray<unsigned char>", "uniform", 2)
self.check_primvar(prim, "sp_int32", "VtArray<int>", "uniform", 2)
self.check_primvar(prim, "sp_float", "VtArray<float>", "uniform", 2)
self.check_primvar_missing(prim, "sp_color")
self.check_primvar_missing(prim, "sp_byte_color")
self.check_primvar(prim, "sp_color", "VtArray<GfVec4f>", "uniform", 2)
self.check_primvar(prim, "sp_byte_color", "VtArray<GfVec4f>", "uniform", 2)
self.check_primvar(prim, "sp_vec2", "VtArray<GfVec2f>", "uniform", 2)
self.check_primvar(prim, "sp_vec3", "VtArray<GfVec3f>", "uniform", 2)
self.check_primvar(prim, "sp_quat", "VtArray<GfQuatf>", "uniform", 2)
@@ -318,8 +318,8 @@ class USDExportTest(AbstractUSDTest):
self.check_primvar(prim, "p_int8", "VtArray<unsigned char>", "varying", 10)
self.check_primvar(prim, "p_int32", "VtArray<int>", "varying", 10)
self.check_primvar(prim, "p_float", "VtArray<float>", "varying", 10)
self.check_primvar_missing(prim, "p_color")
self.check_primvar_missing(prim, "p_byte_color")
self.check_primvar(prim, "p_color", "VtArray<GfVec4f>", "varying", 10)
self.check_primvar(prim, "p_byte_color", "VtArray<GfVec4f>", "varying", 10)
self.check_primvar(prim, "p_vec2", "VtArray<GfVec2f>", "varying", 10)
self.check_primvar(prim, "p_vec3", "VtArray<GfVec3f>", "varying", 10)
self.check_primvar(prim, "p_quat", "VtArray<GfQuatf>", "varying", 10)
@@ -329,8 +329,8 @@ class USDExportTest(AbstractUSDTest):
self.check_primvar(prim, "sp_int8", "VtArray<unsigned char>", "uniform", 3)
self.check_primvar(prim, "sp_int32", "VtArray<int>", "uniform", 3)
self.check_primvar(prim, "sp_float", "VtArray<float>", "uniform", 3)
self.check_primvar_missing(prim, "sp_color")
self.check_primvar_missing(prim, "sp_byte_color")
self.check_primvar(prim, "sp_color", "VtArray<GfVec4f>", "uniform", 3)
self.check_primvar(prim, "sp_byte_color", "VtArray<GfVec4f>", "uniform", 3)
self.check_primvar(prim, "sp_vec2", "VtArray<GfVec2f>", "uniform", 3)
self.check_primvar(prim, "sp_vec3", "VtArray<GfVec3f>", "uniform", 3)
self.check_primvar(prim, "sp_quat", "VtArray<GfQuatf>", "uniform", 3)

View File

@@ -818,8 +818,8 @@ class USDImportTest(AbstractUSDTest):
self.check_attribute(mesh, "f_int8", 'FACE', 'INT8', 1)
self.check_attribute(mesh, "f_int32", 'FACE', 'INT', 1)
self.check_attribute(mesh, "f_float", 'FACE', 'FLOAT', 1)
self.check_attribute_missing(mesh, "f_byte_color") # Not supported?
self.check_attribute_missing(mesh, "f_color") # Not supported?
self.check_attribute(mesh, "f_byte_color", 'FACE', 'FLOAT_COLOR', 1)
self.check_attribute(mesh, "f_color", 'FACE', 'FLOAT_COLOR', 1)
self.check_attribute(mesh, "f_vec2", 'FACE', 'FLOAT2', 1)
self.check_attribute(mesh, "f_vec3", 'FACE', 'FLOAT_VECTOR', 1)
self.check_attribute_missing(mesh, "f_quat")
@@ -845,8 +845,8 @@ class USDImportTest(AbstractUSDTest):
self.check_attribute(curves, "p_int8", 'POINT', 'INT8', 24)
self.check_attribute(curves, "p_int32", 'POINT', 'INT', 24)
self.check_attribute(curves, "p_float", 'POINT', 'FLOAT', 24)
self.check_attribute_missing(curves, "p_byte_color")
self.check_attribute_missing(curves, "p_color")
self.check_attribute(curves, "p_byte_color", 'POINT', 'FLOAT_COLOR', 24)
self.check_attribute(curves, "p_color", 'POINT', 'FLOAT_COLOR', 24)
self.check_attribute(curves, "p_vec2", 'POINT', 'FLOAT2', 24)
self.check_attribute(curves, "p_vec3", 'POINT', 'FLOAT_VECTOR', 24)
self.check_attribute(curves, "p_quat", 'POINT', 'QUATERNION', 24)
@@ -856,8 +856,8 @@ class USDImportTest(AbstractUSDTest):
self.check_attribute(curves, "sp_int8", 'CURVE', 'INT8', 2)
self.check_attribute(curves, "sp_int32", 'CURVE', 'INT', 2)
self.check_attribute(curves, "sp_float", 'CURVE', 'FLOAT', 2)
self.check_attribute_missing(curves, "sp_byte_color")
self.check_attribute_missing(curves, "sp_color")
self.check_attribute(curves, "sp_byte_color", 'CURVE', 'FLOAT_COLOR', 2)
self.check_attribute(curves, "sp_color", 'CURVE', 'FLOAT_COLOR', 2)
self.check_attribute(curves, "sp_vec2", 'CURVE', 'FLOAT2', 2)
self.check_attribute(curves, "sp_vec3", 'CURVE', 'FLOAT_VECTOR', 2)
self.check_attribute(curves, "sp_quat", 'CURVE', 'QUATERNION', 2)
@@ -871,8 +871,8 @@ class USDImportTest(AbstractUSDTest):
self.check_attribute(curves, "p_int8", 'POINT', 'INT8', 10)
self.check_attribute(curves, "p_int32", 'POINT', 'INT', 10)
self.check_attribute(curves, "p_float", 'POINT', 'FLOAT', 10)
self.check_attribute_missing(curves, "p_byte_color")
self.check_attribute_missing(curves, "p_color")
self.check_attribute(curves, "p_byte_color", 'POINT', 'FLOAT_COLOR', 10)
self.check_attribute(curves, "p_color", 'POINT', 'FLOAT_COLOR', 10)
self.check_attribute(curves, "p_vec2", 'POINT', 'FLOAT2', 10)
self.check_attribute(curves, "p_vec3", 'POINT', 'FLOAT_VECTOR', 10)
self.check_attribute(curves, "p_quat", 'POINT', 'QUATERNION', 10)
@@ -882,8 +882,8 @@ class USDImportTest(AbstractUSDTest):
self.check_attribute(curves, "sp_int8", 'CURVE', 'INT8', 3)
self.check_attribute(curves, "sp_int32", 'CURVE', 'INT', 3)
self.check_attribute(curves, "sp_float", 'CURVE', 'FLOAT', 3)
self.check_attribute_missing(curves, "sp_byte_color")
self.check_attribute_missing(curves, "sp_color")
self.check_attribute(curves, "sp_byte_color", 'CURVE', 'FLOAT_COLOR', 3)
self.check_attribute(curves, "sp_color", 'CURVE', 'FLOAT_COLOR', 3)
self.check_attribute(curves, "sp_vec2", 'CURVE', 'FLOAT2', 3)
self.check_attribute(curves, "sp_vec3", 'CURVE', 'FLOAT_VECTOR', 3)
self.check_attribute(curves, "sp_quat", 'CURVE', 'QUATERNION', 3)