Page MenuHome

Fix for T53745 wrong writing of Alembic vertex colors
ClosedPublic

Authored by Wybren van Keulen (wybren) on Sep 18 2018, 3:18 PM.

Details

Summary

Blender writes vertex colors to Alembic, but no other software can read them. This bug has been reported and discussed at https://developer.blender.org/T53745

Blender stores a color for each vertex in an edge loop in each face - that's one long list of colors, more than just one color for every vertex. A vertex shared by two faces can have two separate colors. When analyzing Blender's code for write_mcol, I come to the conclusion that it has a buffer the length of the amount of vertices. It loops over every face, then loops over the vertex loop inside that face. It then saves a color to buffer[vertex index]. If a vertex is shared by four faces, then the color of this vertex will be written once and then overwritten three times. My conclusion is that the way Blender currently writes vertex colors to Alembic drops the ability to have different colors for each face sharing a single vertex. I think colors should be written just like UV's and normals, in vertex loops.

Apart from a list of colors, Alembic also seems to expect a second list (for every vertex in an edge loop in a face) pointing to colors in the first list. This allows you to have a very limited palette (short list) of colors, say black and white. Then the second list will be a long list of zero's and ones, palette indices pointing either to black or to white.

This is basically the same way GIF images work. They have an array (palette) of colors, and an array indices to color each pixel. There is an obvious reason to use this indexing, it can save a lot of data especially for vertex colors. Take for instance a vertex that is shared by four faces. In Blender, this single vertex has four color values attached to it via the face loops. This may be handy if you want to color each face differently, but in most cases vertex colors are used as "vertex" colors and all four colors will be the same. So that's probably the reasoning behind it.

On to a solution then. First, write the color of each corner vertex in each face's vertex loop. The simplest way to continue would be to simply ignore the possible optimisation benefits of reusing colors. That would mean the second list with indices to colors in the color list can simply be [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ... ] , going on for the same length as the colors array. That's the theory, and guess what, it worked on the first try!

So, recap: This patch changes two things in the way that Blender writes vertex colors to Alembic. First off, it adds the color of each vertex in each face's edge loop. This first list acts as the palette. Second, it adds a list of indices pointing to these colors.

I tested this patch with Houdini. To view the vertex colors in Houdini, import the Alembic as Houdini Geometry. You can see the attributes in the Geometry Spreadsheet under Vertices (be sure to disable the pin in the top right). Add a Color Visualizer to see the colors in the viewport. Change the Class attribute from Point to Vertex and then punch in the name of the attribute.

I will add an exported Alembic for testing purposes to https://developer.blender.org/T53745 .

Diff Detail

Repository
rB Blender

Event Timeline

Thanks dude! I hope I have time to test & commit this soon :)

Confirmed the vertex can be read correctly by Blender and two other softwares, and Alembic regression tests are passing.

No reason not to commit this immediately I think. I'll add a small optimization to avoid repeat memory allocations.

This revision is now accepted and ready to land.Sep 19 2018, 8:15 PM
This revision was automatically updated to reflect the committed changes.