-
Notifications
You must be signed in to change notification settings - Fork 966
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for per-face texture coordinates in the PLY decoder. #1028
base: main
Are you sure you want to change the base?
Conversation
1aea0ab
to
6e4ea15
Compare
Draco doesn't really expect texture coordinates to be stored per-vertex. In fact all non-position attributes are usually stored per-corner (so each corner of a single vertex can have a different attribute value). Given that, we would prefer to have a solution that would decode the texture coordinates properly. The solution in this PR would probably lead to even more confusion and hard-to-track bugs down the line. |
Am I correct in thinking that would require a more substantial rewrite of the PlyDecoder to use point mapping rather than identity mapping, or is there a shortcut I'm missing? |
Not necessarily. The easiest way would be to use |
Thanks for your patience. I tried using Mesh::AddAttributeWithConnectivity(), but it doesn't work, either failing at I've pushed a commit here with my (non-working) code, in case you are able to spot something I'm missing. |
pushTexcoordPair(uv_list_offset, 0); | ||
for (int64_t ti = 0; ti < num_triangles; ++ti) { | ||
for (int64_t c = 1; c < 3; ++c) { | ||
pushTexcoordPair(uv_list_offset, ti + c); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this would add one value for each corner, not to mention the corner index seems to be wrong.
Basically you would have to add value for each corner where the corner index is (3 * triangle_index + c) where c={0, 1, 2}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, fixed. This moves through vertices in the same order as in DecodeFaceData
. When triangulating a polygon with more than 3 sides, the first vertex is repeated in each triangle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that the first vertex is repeated but even so, each triangle of the polygon will have a distinct corner attached to the "first" vertex. E.g. if you have a quad there will be two corners attached to it. In the current implementation only the corner from the first triangle is going to be processed which is wrong because it messes up the way how Draco maps corners to triangles + it leaves some corners with uninitialized values. Again, as an example for a quad, we would expect to have two triangles with corners: (0, 1, 2), (3, 4, 5) where they would be mapped to values (0, 1, 2), (0, 2, 3).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to make sure, are you looking at the change from the latest commit? eee2335
for (int64_t ti = 0; ti < num_triangles; ++ti) {
pushTexcoordPair(uv_list_offset, 0);
for (int64_t c = 1; c < 3; ++c) {
pushTexcoordPair(uv_list_offset, ti + c);
}
}
For a quad with corners (0, 1, 2, 3), this should push 6 pairs of UVs in the order (0, 1, 2, 0, 2, 3). Is that not correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about that. Not sure what I was looking at, you are right.
One other potential issue I can see is that, if I understand it correctly, the DecodeTexCoordData() is called before we decode any vertex data. I think this may cause some issues because AddAttributeWithConnectivity assumes that we have some valid points in the mesh already. Can you try to move this decoding after DecodeVertexData() to see if it helps?
src/draco/io/ply_decoder.cc
Outdated
} | ||
// I don't think it works to have this as the only point-mapped attribute | ||
// while the rest of the attributes are identity-mapped. | ||
out_mesh_->set_num_points(num_corners); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the number of points should be recomputed automatically when the function is called. I think this may actually cause some issues in the subsequent function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made this change, but it crashes because the is_point_used
vector is initialized with its size set to num_points(), which is 0 if we don't set the number here. That results in out-of-bounds access.
I've tried setting the number of points here to the number of corners, and the number of vertices. Nothing works; the program either crashes or fails non-deterministically at various points.
This PR adds support to the PlyDecoder for decoding texture coordinates from the
texcoord
property of theface
element.PLY files can support a single vertex with different texture coordinates per face. Since Draco expects texture coordinates to be stored per-vertex, this implementation chooses the last set of texture coordinates found for each vertex. For many users this should not be an issue. Where it is a problem, it's no worse than not having texture coordinate support at all.