Page MenuHome

Alembic: support reading per-vertex UV sets
ClosedPublic

Authored by Kévin Dietrich (kevindietrich) on Jun 11 2021, 6:59 PM.

Details

Summary

In Alembic, UVs can be defined with different scopes. The most common one
is "face varying" scope, which maps to Blender's polygon loops, where a value
is stored for each vertex of each polygon. This makes sense as a given vertex
might be on a UV seam and thus have multiple possible UV coordinates.

However, it is also possible to define UVs using a "vertex" scope, meaning that
we will have a single UV value for each vertex. This can happen when the mesh
is split according to the UV islands, in which case it makes sense to only store
one value per vertex, as vertices are guaranteed to only have a single possible
UV coordinate.

Currently, the Alembic importer only supports the former case, this patch
implements the latter case. The implementation is pretty straighforward,
we mainly have to properly check whether the size of the UVs indices given
by the sample matches the size of the attribute domain (loops vs. vertices).
UVs are then assigned to the loop UVs based on the index of the vertex pointed
to by the loop.

Here is a test file (.blend and .abc), the UV map is not imported in Blender 2.93:

Diff Detail

Repository
rB Blender
Branch
abc_vertex_uvs_D11584 (branched from master)
Build Status
Buildable 15164
Build 15164: arc lint + arc unit

Event Timeline

Kévin Dietrich (kevindietrich) requested review of this revision.Jun 11 2021, 6:59 PM
Kévin Dietrich (kevindietrich) created this revision.
Sybren A. Stüvel (sybren) requested changes to this revision.Jun 14 2021, 12:00 PM

The functionality is nice to have, but there are some potential improvements to the implementation.

source/blender/io/alembic/intern/abc_customdata.cc
336–364

There is a lot of duplication between the two conditional blocks, which should be resolved.

The duplication could make sense from a performance point of view, but in such a case it should be profiled and a decision made based on actual data. Without that, I would prefer clean code.

source/blender/io/alembic/intern/abc_reader_mesh.cc
196–197

This duplicates the same logic from read_uvs(). It's better to relay such decisions to a separate function, and use that in both cases. This function could then sit next to is_valid_uv_scope().

229–240

The only difference between these two blocks is uv_index = (*uvs_indices)[loop_index]; vs. uv_index = (*uvs_indices)[loop.v];. I'm sure this can be deduplicated.

source/blender/io/alembic/intern/abc_util.cc
233–235 ↗(On Diff #38220)

I think all parameters can be const

240–246 ↗(On Diff #38220)

This is tightly coupled to the read_uvs() and read_mpolys() functions. However, these are in different files, so this relation is not clear.

This revision now requires changes to proceed.Jun 14 2021, 12:00 PM
Kévin Dietrich (kevindietrich) marked 4 inline comments as done.

Deduplicated logic in loops.

I am not sure what you meant by the relation is not clear between
is_valid_uv_scope, read_uvs, and read_mcol. However, I revised
the function signature and moved is_valid_uv_scope in abc_customdata.h.

Added get_uv_scope to determine in which scope the UVs are depending on
whether the indices size matches that of the loops or the vertices.

I am not sure what you meant by the relation is not clear between is_valid_uv_scope, read_uvs, and read_mcol.

I mean that these functions are defined in different files, and there is no comment or code design that makes this relation explicit.

However, I revised the function signature and moved is_valid_uv_scope in abc_customdata.h.

That's already an improvement. I do wonder, however, whether we actually need both. Now that I see them side-by-side, they are very similar. Would it be possible to merge the two, so that get_uv_scope() becomes safer to use (because it also includes a check on the geometry scope declared in the Alembic file), and is_valid_uv_scope() can be reduced to get_uv_scope() != ABC_UV_SCOPE_NONE.

Remove is_valid_uv_scope() (merged logic with get_uv_scope()), and
pass a AbcUvScope around as proof that the scope was checked.

This revision is now accepted and ready to land.Jun 15 2021, 2:06 PM

Please remember to update the release notes straight after committing.

Please remember to update the release notes straight after committing.

Added a note, thanks for the reminder !