tobj: Do not duplicate vertices/mirror structure of original OBJ

tobj blows up the number of vertices when an imported model has per-vertex-per-face normals. There may be other cases (I e.g. would assume the same happens with per-vertex-per-face UVs/vertex colors).

In offline renderers like 3Delight, Arnold or RenderMan, duplicated vertices make the geometry discontinuous and a mesh will crack wide open at face boundaries when displacement shaders are attached to.

A mesh tagged as a render-time subdivision surface won’t even render correct if the vertices are not shared between faces in the index.

o Tetrahedron
v  1  1  1
v  1 -1 -1
v -1  1 -1
v -1 -1  1
vn  0.577  0.577 -0.577
vn -0.577  0.577  0.577
vn  0.577 -0.577  0.577
vn  0.577  0.577 -0.577
vn  0.577 -0.577  0.577
vn -0.577 -0.577 -0.577
vn  0.577  0.577 -0.577
vn -0.577  0.577  0.577
vn -0.577 -0.577 -0.577
vn -0.577  0.577  0.577
vn  0.577 -0.577  0.577
vn -0.577 -0.577 -0.577
s 1
f 1//3 4//11 2//5
s 2
f 2//4 3//7 1//1
s 3
f 2//6 4//12 3//9
s 4
f 3//8 4//10 1//2

For this example, I expect the resulting Mesh’s positions to have 12 f32 entries (aka 4 vertices). The normals should have 36 entries (aka 12 normals).

However, to not require a separate index for the normals, the normals (or texture coordinates/vertex colors) need to be reordered, if they are per-vertex-per-face. I.e. their index should just be monotonically increasing.

In the case above, the index in the file needs to be re-ordered, on import so that it would it look like this:

s 1
f 1//1 4//2 2//3
s 2
f 2//4 3//5 1//6
s 3
f 2//7 4//8 3//9
s 4
f 3//10 4//11 1//12

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 17 (17 by maintainers)

Commits related to this issue

Most upvoted comments

Oh, that was quick. So I am already working on this. I should hopefully have a naive implementation in an hour or so. What I did was:

pub struct Mesh {
    pub positions: Vec<f32>,
    pub normals: Vec<f32>,
    pub texcoords: Vec<f32>,
    
    pub indices: Vec<u32>,
    pub normal_indices: Option<Vec<u32>>,
    pub texcoord_indices: Option<Vec<u32>>,

    pub num_face_indices: Vec<u32>,
    
    pub material_id: Option<usize>,
}

Once I have this working I get back to you and eventually look into reordering (although I do not need this, at the beginning).