Twinklebear / tobj

Tiny OBJ Loader in Rust
MIT License
233 stars 47 forks source link

FaceColorOutOfBounds error when loading OBJs with mix of colored vertices/textured vertices #54

Open Kmschr opened 1 year ago

Kmschr commented 1 year ago

Import/export of OBJ is built in to Blender 3.3 onwards https://docs.blender.org/manual/en/latest/files/import_export/obj.html

When exporting a model with a mix of textured meshes and attribute color meshes, the resulting .obj will start with all colored vertices and end with textured vertices. It appears that when tobj encounters any vertex colors at all, it assumes every vertex will have an associated color and goes out of bounds when reaching the textured vertice section.

The .obj which fails to load looks something like this:

# Blender 3.4.1
# www.blender.org
mtllib example.mtl
o Mesh_0
v 1.280000 2.480000 -1.280000 0.4745 0.5686 0.1804
v 0.000000 2.320000 -1.280000 0.4863 0.5804 0.1804
v 1.280000 2.400000 0.000000 0.4863 0.5804 0.1804
vn -0.5517 0.8172 -0.1670
s 0
usemtl untextured
f 1//1 2//1 3//1
o Mesh_1
v 1.280000 4.800000 -5.440000
v 1.280000 4.800000 -5.120000
v 1.280000 2.400000 -5.440000
vn 0.1402 0.9057 0.4000
vt 0.000000 0.000000
vt 0.000000 0.250000
vt 1.000000 1.000000
s 0
usemtl texture_1
f 4/1/2 5/2/2 6/3/2

FYI @soluri

Twinklebear commented 1 year ago

Thanks for reporting this issue @Kmschr !

Maybe one option would be to check if the vertex being referenced had vertex colors, then if a mesh references a vertex w/ vertex colors all of its other vertices would be required to have vertex colors.

What becomes tricky though (and why tobj requires all or nothing for vertex colors) is that the vertex indices can get mixed up, with the wrong color referenced for a position. For example if the vertices in your file where specified in the opposite order as below, tobj would try to read color data out of bounds. So it would also need to track a map of vertex index -> color index to handle this case. I guess the perf impact of that would only be paid for files with vertex colors, but maybe it's best to split up the OBJ file to separate the meshes with and without vertex colors?

# Blender 3.4.1
# www.blender.org
mtllib example.mtl

o Mesh_1
v 1.280000 4.800000 -5.440000
v 1.280000 4.800000 -5.120000
v 1.280000 2.400000 -5.440000
vn 0.1402 0.9057 0.4000
vt 0.000000 0.000000
vt 0.000000 0.250000
vt 1.000000 1.000000
s 0
usemtl texture_1
f 1/1/2 2/2/2 3/3/2

o Mesh_0
v 1.280000 2.480000 -1.280000 0.4745 0.5686 0.1804
v 0.000000 2.320000 -1.280000 0.4863 0.5804 0.1804
v 1.280000 2.400000 0.000000 0.4863 0.5804 0.1804
vn -0.5517 0.8172 -0.1670
s 0
usemtl untextured
f 4//2 5//2 6//2
Kmschr commented 1 year ago

I see what you're saying, and I was incorrect in assuming that Blender will always export all of the colored vertices before the textured vertices. I've now seen a couple of examples where that isnt the case.

If it doesn't make sense to support this use case in a tiny library I will work on something small to split my files when I need to load them with tobj.

virtualritz commented 1 year ago

It would be great to have example OBJs for both cases (colored vertices before/after textured vertices) and add them to this issue for reference.