Jump to content

How is vertex data stored from OBJ file?


ozRocker
 Share

Recommended Posts

I'm referring to the list of vertices coming from this:

mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);

I used to think it would list the vertices referred to by the definition of the faces and that it was unique, so no vertices would appear more than once.

for example, if you had this in the OBJ file:

f 5/5/5 9/9/9 8/8/8
f 7/7/7 6/6/6 8/8/8
f 5/5/5 8/8/8 6/6/6
f 5/5/5 4/4/4 9/9/9

it would list 5th vertex, 9th vertex, 8th vertex, 7th vertex, 6th vertex, 5th vertex, then 4th vertex.  Once a vertex is listed it will not appear again so repeated vertex indices are ignored.

However, that does not seem to be the case here:

f 90/90/90 91/91/90 92/92/90
f 62/62/62 77/77/77 61/61/61
f 77/77/77 79/79/79 61/61/61
f 61/61/61 79/79/79 60/60/60
f 93/93/91 94/94/92 95/95/93
f 96/96/94 97/97/95 95/95/93
f 90/98/96 98/99/97 99/100/98

The vertex at index 90 will appear from 90/90/90 then its repeated when we hit 90/80/96.  So I'm thinking maybe its not just unique position index (90) but a combination of position and texture index (90/90/90 and 90/98/96).  However, this is not the only case.  There are other instances where vertex is repeated.  I'm wondering if anyone knows exactly how they are listed and under which cases a vertex is repeated in the "getVerticesData" result.

Link to comment
Share on other sites

I am a little reluctant to give the following an answer since given all you have achieved with BJS I presume you know this already. However my assumptions are so often wrong I will give it anyway and take the risk of `teaching my granny to suck eggs`

These pages show the underlying structure for vertex storage with vertexData and show why vertices might be repeated

http://doc.babylonjs.com/how_to/custom#positions-and-indices

http://doc.babylonjs.com/resources/normals

Of OBJ files I know nothing but once imported into BJS they must follow its data structure.

 

Link to comment
Share on other sites

12 minutes ago, JohnK said:

I am a little reluctant to give the following an answer since given all you have achieved with BJS I presume you know this already. However my assumptions are so often wrong I will give it anyway and take the risk of `teaching my granny to suck eggs`

These pages show the underlying structure for vertex storage with vertexData and show why vertices might be repeated

http://doc.babylonjs.com/how_to/custom#positions-and-indices

http://doc.babylonjs.com/resources/normals

Of OBJ files I know nothing.

 

Thanks for that.  I hadn't actually seen those pages before, but I had a read and unfortunately it doesn't help with my confusion.

Basically I'm trying to find out what makes a vertex index appear multiple times in the position data.

Link to comment
Share on other sites

Now I am not clear. Position data only contains positions in the form x, y, z and does not contain indices. You get indices from  mesh.getIndices(), which gives you triples i, j, k where vertices i, j, k form a triangular facet.

Link to comment
Share on other sites

50 minutes ago, JohnK said:

Now I am not clear. Position data only contains positions in the form x, y, z and does not contain indices. You get indices from  mesh.getIndices(), which gives you triples i, j, k where vertices i, j, k form a triangular facet.

Yeh, I refer to the indices 'cos that's how the vertices are listed.

If faces are set out like this:

f 5/5/5 9/9/9 8/8/8
f 7/7/7 6/6/6 8/8/8

then the position data will contain the vertex at index 5, then index 9, then index 8, index 7, index 6.  However, the last one will be ignored 'cos its already in the position data.  So the vertices are stored according to the way the indices are listed in the face definitions.

Link to comment
Share on other sites

6 hours ago, Sebavan said:

There are several ways to store info in obj file: https://github.com/BabylonJS/Babylon.js/blob/master/loaders/src/OBJ/babylon.objFileLoader.ts#L432

Basically, you are in mode 3 meaning positions/uv/normal: https://github.com/BabylonJS/Babylon.js/blob/master/loaders/src/OBJ/babylon.objFileLoader.ts#L523

Hope that helps? 

 

 

That does help. Thank you!

I can see this line:

//Check if this tuple already exists in the list of tuples

so it looks like the uniqueness comes from a combination of all 3 values.  

Link to comment
Share on other sites

This is what's confusing me.  I'm getting multiple entries when I swear the tuples should be unique.  I can see it in the code:

                var _index;
                if (OBJFileLoader.OPTIMIZE_WITH_UV) {
                    _index = isInArrayUV(tuplePosNorm, [
                        indicePositionFromObj,
                        indiceNormalFromObj,
                        indiceUvsFromObj
                    ]);
                }
                else {
                    _index = isInArray(tuplePosNorm, [
                        indicePositionFromObj,
                        indiceNormalFromObj
                    ]);
                }
                //If it not exists
                if (_index == -1) {

but when I output to console I can see repeated entries.  I'm trying to edit the position data so if I can at least figure out what conditions make the entries repeat, then I can pull it off

babylon_obj_problem.jpg

Link to comment
Share on other sites

I see what's going on.

This function here:

            var isInArrayUV = (arr: Array<{ normals: Array<number>; idx: Array<number>; uv: Array<number> }>, obj: Array<number>) => {
                if (!arr[obj[0]]) arr[obj[0]] = { normals: [], idx: [], uv: [] };
                var idx = arr[obj[0]].normals.indexOf(obj[1]);

                if (idx != 1 && (obj[2] == arr[obj[0]].uv[idx])) {  // <-- this comparison
                    return arr[obj[0]].idx[idx];
                }
                return -1;
            };

A position can be associated with multiple UV points.  In my OBJ I have some pos/UV pairs: 98/99 and 98/440.

When checking is 98/440 exists it will check arr[obj[0]].uv[idx] to see if there is a mapping between 98 and 440.  The problem is, uv[idx] (idx always being zero) will only return the first UV associated with the position.

So every time the parser encounters 98/440 it will incorrectly check it against 98/99, think its unique then add the 98/440 entry every time.  This is why I'm getting duplicate entries.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...