Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to load obj models with group information #2898

Closed
Sunwinds opened this issue Jan 7, 2013 · 36 comments
Closed

How to load obj models with group information #2898

Sunwinds opened this issue Jan 7, 2013 · 36 comments
Labels

Comments

@Sunwinds
Copy link

Sunwinds commented Jan 7, 2013

Hi All, I am trying to use the ObjLoader.js to load OBJ pre-segmented models. Each segment is tagged as a group in the OBJ file.
But the current ObjLoader.js seems not so capable to read group information.
What I want is loading a mesh and coloring different segments with different colors.

@mrdoob
Copy link
Owner

mrdoob commented Jan 7, 2013

Can you share an example obj?

@Sunwinds
Copy link
Author

Sunwinds commented Jan 7, 2013

Sure, how to send you the file?

@mrdoob
Copy link
Owner

mrdoob commented Jan 7, 2013

Dropbox and share link?

@Sunwinds
Copy link
Author

Sunwinds commented Jan 7, 2013

@mrdoob
Copy link
Owner

mrdoob commented Jan 8, 2013

Thanks for the model.

I guess we should create objects instead of trying to put everything into a single geometry...

@mrdoob
Copy link
Owner

mrdoob commented Jan 9, 2013

After closer inspection. What's the difference between o and g?
OBJLoader handles o as different objects, but ignores g

@bhouston
Copy link
Contributor

bhouston commented Jan 9, 2013

I think there is a pretty complete specification of obj here:

http://en.wikipedia.org/wiki/Wavefront_.obj_file

In the "Referencing Materials" section here:

http://en.wikipedia.org/wiki/Wavefront_.obj_file#Referencing_materials

They describe "g" as being a reference to a polygon material group.

@bhouston
Copy link
Contributor

bhouston commented Jan 9, 2013

Basically I guess g (material groups) should be mapped to different materialIds within the same mesh?

@mrdoob
Copy link
Owner

mrdoob commented Jan 9, 2013

Oh, ugh... Uhm, I've mixed things up then... 437b0a9

@mrdoob
Copy link
Owner

mrdoob commented Jan 9, 2013

I'll give another go tomorrow, I'm currently annoyed with the file format :)

@mrdoob
Copy link
Owner

mrdoob commented Jan 10, 2013

I'm not sure how to translate obj to threejs.
This is what I'm thinking:

usemtl = material name/type to be *instantiated* in subsequent o and g
o = start new Mesh
g =  materialID

I'm not sure if that's the most accurate representation of what the data is supposed to be.

@Sunwinds
Copy link
Author

http://www.fileformat.info/format/wavefrontobj/egff.htm
I do not think g is for material ID

@mrdoob
Copy link
Owner

mrdoob commented Jan 11, 2013

Right. But we don't have the concept of polygon groups in three.js
As far as I understand, you want to change the color (thus material) of those groups, but you wouldn't want to change the position/rotation/scale of such groups. Right?

@Sunwinds
Copy link
Author

Yes, that's it

@bsenftner
Copy link

I've been looking at this issue for my own needs, and I believe that because three.js does not have polygon groups, it is cleaner to implement a separate tool which generates the group information as a JSON description. Then the geometry can be loaded as normal, with the groups information loaded separately.

FYI, MrDoob, the polygon groups can be used for identification of bone-skinning vertices, as well as various other logical uses such as identification of anchors for "mesh accessories" like eyeglasses, earrings and other items which are logically maintained in attachment to a base mesh rather than the traditional hierarchical method (parent -> child in the scene graph).

And by "logically maintained" I mean: some types of geometry, let's say a nose ring, is "added" to a character via user selection of that nose ring as a character accessory in some game. The character's face has bones or morph targets, which get blended to achieve whatever face expression. The "added" nose ring can't easily be added to the character's morph targets (may be used by multiple characters). An easy solution is use of a polygon group to identify locations where skinned meshes can have accessories attached. With a polygon group identifying the polygon(s) the nose ring attaches, a simple retrieval of polygon(s) vertex locations after bone and morph target deformations provides all that is necessary to maintain the geometric accessory in position and in its correct orientation.

@mrdoob
Copy link
Owner

mrdoob commented Jan 31, 2013

@bsenftner Yeah. I can see the polygon groups works that way. But it gets problematic whenever they're used for grouping a material type. Things get a little bit complicated there.

@bsenftner
Copy link

@mrdoob In practice, from both film and game productions over the years, the group information is used for both material and non-material purposes, but by convention a group used for materials is not expected to also be available for non-material uses.
The groups within an OBJ are all "by convention" within your production flow. The loader should just give the group info and let clients interpret as needed.

@hdesouky
Copy link

hdesouky commented Oct 2, 2013

Is there any news regarding this issue?

If not, what is the technique we can use to be able to apply material to part of the mesh?

@bhouston
Copy link
Contributor

bhouston commented Oct 2, 2013

http://Clara.io has ability to import OBJs and FBXs and export ThreeJS JSON scenes. Might be a solution for you.

@hdesouky
Copy link

hdesouky commented Oct 5, 2013

I tried the THREEJS JSON Export for Blender 2.68 but plugin is not working. Blender can't import the plugin!

For Clara.io, do I need to register?

@2pha
Copy link
Contributor

2pha commented Jun 27, 2014

I am also having a problem with the OBJLoader. On a project using r55 I could load an OBJ and it would create an Object3D with the children property populated with the separate objects in the .OBJ file. I would separate by object (instead of groups) to set different materials. But today when starting a project with r67, The OBJLoader no longer seems to separate the objects. I am exporting the from 3ds max with the export selected option. I select multiple objects to export but it seems to use 'g' in the resulting .obj to separate the objects.

@doambroa
Copy link

doambroa commented Oct 5, 2015

The problem persists, I am having issues to colour different parts of my OBJ (I am using OBJMTLLoader) because it seems that there are created lots of groups, and when I try to colour something concrete, lots of things are colored. As 2pha says, 3DSMax creates unusual "g" in the OBJ file for unique objects, any fix today? Can be different parts of an OBJ colored with Three.js?

@mrdoob
Copy link
Owner

mrdoob commented Oct 5, 2015

Since r72, we support that internally now. However OBJMTLLoader is deprecated and we need to implement g parsing in OBJLoader.

@2pha
Copy link
Contributor

2pha commented Jan 10, 2016

I seem to be having this problem again but have realised that it is because the 3dsMax exporter is not including the line with the object name (line prefixed with o). I'm not sure if this is because I am using the exporter wrong or it is how the 3ds max exporter works. Stack question here.
Adding the object names in lines beginning with o results in the expected behaviour

@jonnenauha
Copy link
Contributor

@mrdoob I think this can also be closed. g parsing has been implemented some time ago (dunno which release). Pretty much the same issue as #6682 and seems also touches on the multiple materials inside a group issue discussed in #8203

@katsuya0719
Copy link

I want to use g attribute after loading obj data through OBJLoader. But looking at console screen,I cannot find any attribute corresponding to g attribute of obj file. Could you tell me in which attribute I can find g attribute? ( I could find o attribute in sc>children>0:ya>name as shown in the below image)
image
Thank you for your help!

@mrdoob
Copy link
Owner

mrdoob commented Nov 28, 2016

mesh.geometry.groups?

@katsuya0719
Copy link

@mrdoob Thank you for your reply. I could not find the mesh.geometry.groups. Are there any example which is reading obj file and be able to check mesh.geometry.groups in console?

@mrdoob
Copy link
Owner

mrdoob commented Nov 29, 2016

Can you share your file?

@katsuya0719
Copy link

katsuya0719 commented Nov 29, 2016

@mrdoob Please find the file from following url https://gist.github.com/katsuya0719/abb3b15270e6e9f509e113d1c3ccf41b

Thank you for your help!

@mrdoob
Copy link
Owner

mrdoob commented Nov 29, 2016

Weird, that model has both g and o for every part... 😐

/ping @jonnenauha

@WestLangley
Copy link
Collaborator

Weird, that model has both g and o for every part..

Actually, it appears to me to have 124 o and 29 g.

@katsuya0719 What are you expecting? 124 meshes that each use one of 29 material instances?

@katsuya0719
Copy link

@mrdoob @WestLangley Thank you for investigating. This obj file is exported from Rhinoceros. Assuming from that file, 124 o is the total number of mesh. 29 g is the total number of layer.
What I am expecting is that I can differentiate imported mesh by group name. Is that possible?
Thank you!

@jonnenauha
Copy link
Contributor

jonnenauha commented Nov 30, 2016

g and o are treated the same in the loader. I believe it should ignore the g ones as they don't have any geometry in them. We don't parent os into gs that appear before them. That kind of hierarchy is not preserved. They will be all flat children of the returner container THREE.Group.

That file does not use any materials. So you won't get geometry.groups (only done if you use multiple materials while declaring faces). Should produce a mesh (well a THREE.Group) with 125 THREE.Mesh children. Each having a BufferGeometry and a default material.

Does the parser error out of the file or what is the issue?

@jonnenauha
Copy link
Contributor

jonnenauha commented Nov 30, 2016

To answer the latest question of @katsuya0719: We don't do any child groupings with g, as said the returned hierarchy is flat. You should have each o name in the .name property.

It might not be very convenient, but you'll have to differentiate by the 125 unique names with some kind of helper func.

I believe adding child grouping could be done quite easily, but now people are assuming flat hierarchy, this would change the behavior quite a bit. If we change it to recognize g as a start of child grouping of any subsequent os. One this we could do without breaking things is to mark the g name into something like objmodel.children[i].objGroup (I believe .group might conflict with standard three stuff). At least this way you could make a utility to find with group name, not tens of o names.

@katsuya0719
Copy link

@jonnenauha Thank you for your clear explanation! I could understand the direction I should go. I am not sure whether I can make it, but will try! Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants