ozRocker Posted June 20, 2018 Share Posted June 20, 2018 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. Quote Link to comment Share on other sites More sharing options...
JohnK Posted June 20, 2018 Share Posted June 20, 2018 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. Quote Link to comment Share on other sites More sharing options...
ozRocker Posted June 20, 2018 Author Share Posted June 20, 2018 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. Quote Link to comment Share on other sites More sharing options...
JohnK Posted June 20, 2018 Share Posted June 20, 2018 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. Quote Link to comment Share on other sites More sharing options...
ozRocker Posted June 20, 2018 Author Share Posted June 20, 2018 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. Quote Link to comment Share on other sites More sharing options...
Sebavan Posted June 20, 2018 Share Posted June 20, 2018 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? Quote Link to comment Share on other sites More sharing options...
babbleon Posted June 20, 2018 Share Posted June 20, 2018 Just a guess, but does this obj file have any sharp edges? Blender: edge split, Max: ?smoothing groups (not used Max since 2002) Quote Link to comment Share on other sites More sharing options...
ozRocker Posted June 20, 2018 Author Share Posted June 20, 2018 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. Quote Link to comment Share on other sites More sharing options...
ozRocker Posted June 21, 2018 Author Share Posted June 21, 2018 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 Quote Link to comment Share on other sites More sharing options...
ozRocker Posted June 21, 2018 Author Share Posted June 21, 2018 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. Quote Link to comment Share on other sites More sharing options...
ozRocker Posted June 28, 2018 Author Share Posted June 28, 2018 So would this be considered a bug? Quote Link to comment Share on other sites More sharing options...
Guest Posted June 28, 2018 Share Posted June 28, 2018 Definitely! Can you suggest a fix? (or a PR :)) Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.