{"action":"opened","issue":{"url":"https://api.github.com/repos/mrdoob/three.js/issues/8383","repository_url":"https://api.github.com/repos/mrdoob/three.js","labels_url":"https://api.github.com/repos/mrdoob/three.js/issues/8383/labels{/name}","comments_url":"https://api.github.com/repos/mrdoob/three.js/issues/8383/comments","events_url":"https://api.github.com/repos/mrdoob/three.js/issues/8383/events","html_url":"https://github.com/mrdoob/three.js/issues/8383","id":141481467,"number":8383,"title":"OBJLoader does not distinguish between `o` and `g` tags.","user":{"login":"andreykaipov","id":9457739,"avatar_url":"https://avatars.githubusercontent.com/u/9457739?v=3","gravatar_id":"","url":"https://api.github.com/users/andreykaipov","html_url":"https://github.com/andreykaipov","followers_url":"https://api.github.com/users/andreykaipov/followers","following_url":"https://api.github.com/users/andreykaipov/following{/other_user}","gists_url":"https://api.github.com/users/andreykaipov/gists{/gist_id}","starred_url":"https://api.github.com/users/andreykaipov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andreykaipov/subscriptions","organizations_url":"https://api.github.com/users/andreykaipov/orgs","repos_url":"https://api.github.com/users/andreykaipov/repos","events_url":"https://api.github.com/users/andreykaipov/events{/privacy}","received_events_url":"https://api.github.com/users/andreykaipov/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2016-03-17T04:58:58Z","updated_at":"2016-03-17T04:58:58Z","closed_at":null,"body":"**OBJLoader does not distinguish between `o` and `g` tags.**\r\n\r\nThis causes OBJLoader to create superfluous meshes whose geometries are empty, which can be seen in the OBJLoader example [here](http://threejs.org/examples/webgl_loader_obj).\r\n\r\nOpen up the dev-tools console and copy-paste in the following snippet.\r\n\r\n```\r\nvar object;\r\nscene.traverse( function( child ) {\r\n    if ( child instanceof THREE.Group ) object = child;\r\n});\r\n\r\nobject.traverse( function( child ) {\r\n    if ( child instanceof THREE.Mesh ) {\r\n        var geometry = new THREE.Geometry().fromBufferGeometry(child.geometry);\r\n        console.log(\"Mesh name: \" + child.name);\r\n        console.log(\"Mesh's geometry has \" + geometry.vertices.length + \" vertices.\");\r\n        console.log(\"Mesh's geometry has \" + geometry.faces.length + \" faces.\");\r\n        console.log(\"\");\r\n    }\r\n});\r\n```\r\n\r\nThese empty meshes are due to treating `o` and `g` as the same tag, seen from this line [here](https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader.js#L303).\r\n\r\nSpecifically, the offending meshes are those created by the OBJLoader whenever it parses an `o` tag. Looking inside the `.obj` file, we find that an `o` tag is always followed by a series of vertices, and before its scope can reach any faces, a `g` tag is encountered!\r\n\r\nI believe part of the problem is that the [`.obj` file specification](http://www.martinreddy.net/gfx/3d/OBJ.spec) is very scarce when it comes to grouping, but here are the two sections for both `o` and `g` tags.\r\n\r\n> g group_name1 group_name2 . . .\r\n> \r\n>     Polygonal and free-form geometry statement.\r\n> \r\n>     Specifies the group name for the elements that follow it. You can\r\n>     have multiple group names. If there are multiple groups on one\r\n>     line, the data that follows belong to all groups. Group information\r\n>     is optional.\r\n> \r\n>     group_name is the name for the group. Letters, numbers, and\r\n>     combinations of letters and numbers are accepted for group names.\r\n>     The default group name is default.\r\n> \r\n> o object_name\r\n> \r\n>     Polygonal and free-form geometry statement.\r\n> \r\n>     Optional statement; it is not processed by any Wavefront programs.\r\n>     It specifies a user-defined object name for the elements defined\r\n>     after this statement.\r\n> \r\n>     object_name is the user-defined object name. There is no default.\r\n\r\nThe sentence I find interesting is that `o` tags are \"not processed by any Wavefront programs\". Interestingly enough, this sentence is not present for the groups! So, since the `o` tag is not processed by any Wavefront programs, perhaps Three.js shouldn't process it either?\r\n\r\nThe name is rather strange too. If the `o` tag is for object names, one would think there can be at most one in an **object** file, but it seems like Blender exports always have several `o` tags.\r\n\r\n---\r\n\r\n##### Three.js version\r\n\r\n- [x] Dev\r\n- [x] r75"}}