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 access faces? #87

Closed
luizavolpi opened this issue Feb 14, 2019 · 14 comments
Closed

How to access faces? #87

luizavolpi opened this issue Feb 14, 2019 · 14 comments

Comments

@luizavolpi
Copy link

Hello,
How can I access objects' faces?

When I open the file using
object = pywavefront.Wavefront("object.obj", create_materials = True, collect_faces=True)

I can access the vertices simply by using object.vertices, but when it comes to the faces it is under either 2 folders, meshes or mesh_list, but the folders 0 and None are not accessible:
image

Thank you

@greenmoss
Copy link
Collaborator

Hello, thanks for trying out pywavefront!

Can you point me to the code and data you used generate this view?

Is this a Python object viewer you are using? Is it free, e.g. can you point me to where you downloaded it?

@einarf
Copy link
Member

einarf commented Feb 15, 2019

Seems they are in mesh.faces:
https://github.com/greenmoss/PyWavefront/blob/8311d3f464cff694f201709e2429b71448b2c65a/pywavefront/obj.py#L275-L276

As far as I remember face lists are located in the mesh while vertices (positions) are located in materials. I'm guessing an index lookup using the face data should at least be simple if the obj file has one object and one material. Faces are also always triangulated as this has always been default in this project so far.

This is probably not ideal but grouping vertices together per material made it much easier to load and display almost any obj file. There are so many weird corner cases with the obj format. Probably something that needs improvement in the future. Proper info per mesh is a good start.

@luizavolpi
Copy link
Author

Hello, thanks for trying out pywavefront!

Can you point me to the code and data you used generate this view?

Is this a Python object viewer you are using? Is it free, e.g. can you point me to where you downloaded it?

Hi, thank you for the response!
This is a print screen from PyCharm Community Edition 2018.3.4's variable view. The sample file I used was downloaded for free just for testing, but I also tried with a few objects I generated using 3DS Max. It was the Male Base Mesh from (https://free3d.com/3d-models/man)

The code I used was just
import pywavefront
object = pywavefront.Wavefront(r'C:(...)ManMesh.obj',create_materials=True,collect_faces=True)

Thank you!

@luizavolpi
Copy link
Author

Seems they are in mesh.faces:
PyWavefront/pywavefront/obj.py

Lines 275 to 276 in 8311d3f

if self.collect_faces:
self.mesh.faces += list(collected_faces)
As far as I remember face lists are located in the mesh while vertices (positions) are located in materials. I'm guessing an index lookup using the face data should at least be simple if the obj file has one object and one material. Faces are also always triangulated as this has always been default in this project so far.

This is probably not ideal but grouping vertices together per material made it much easier to load and display almost any obj file. There are so many weird corner cases with the obj format. Probably something that needs improvement in the future. Proper info per mesh is a good start.

Thank you for your response!
I can see the fac lists inside meshes in the variables view, but I'm not able to read it. For the vertices, they are not inside materials (at least in the structure I have), and I can read them without any problems. I'm not sure what you mean by "if the obj file has one object and one material", but I had to create a material (create_materials = True) since the file I uploaded had only info on the mesh and not on the material. Could this be the issue? Thank you!

@einarf
Copy link
Member

einarf commented Feb 16, 2019

Quick test program:

test.obj

o Simple
v 1.0 2.0 3.0
v 3.0 5.0 6.0
v 7.0 8.0 9.0
vt 0.0 1.0
vt 1.0  0.0
vt 0.0 0.0
vn 0.0 0.0 1.0
f 2/3/1 1/2/1 3/1/1

test.py

import pywavefront

scene = pywavefront.Wavefront(
    "test.obj",
    create_materials=True,
    collect_faces=True,
)

print("Faces:", scene.mesh_list[0].faces)
print("Vertices:", scene.vertices)
print("Format:", scene.mesh_list[0].materials[0].vertex_format)
print("Vertices:", scene.mesh_list[0].materials[0].vertices)

Output:

Faces: [[1, 0, 2]]
Vertices: [(1.0, 2.0, 3.0), (3.0, 5.0, 6.0), (7.0, 8.0, 9.0)]
Format: T2F_N3F_V3F
           <  UV  >  <  Normal   >  < Position  >
Vertices: [0.0, 0.0, 0.0, 0.0, 1.0, 3.0, 5.0, 6.0, # Vertex 1 T2F_N3F_V3F
           1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 3.0, # Vertex 2 T2F_N3F_V3F
           0.0, 1.0, 0.0, 0.0, 1.0, 7.0, 8.0, 9.0] # Vertex 3 T2F_N3F_V3F

The first vertex list is the raw vertices from the obj file. The second vertex list represents the interleaved vertex data with the format specified in the material. Faces will always be triangulized (no quads)

@luizavolpi
Copy link
Author

Thank you!!! I can access it with the command you provided scene.mesh_list[0].faces, I was not familiar with it before.

@einarf
Copy link
Member

einarf commented Feb 21, 2019

No problem. I opened #88 related to this. It's not always entirely clear how to access the parsed data at this moment.

@victoriapoghosyan
Copy link

@einarf getting vertices with scene.vertices gives me array of shape (43436, 3) ,and I've checked on my .obj vertices are 43436 but when I get them with scene.mesh_list[0].materials[0].vertices and reshape it (n,8) (8 for 2 texture + 3 normal + 3 position ) it resulted vertices with shape (257490, 3)
Whats the problem?

@einarf
Copy link
Member

einarf commented Feb 27, 2019

The vertices in the material itself is currently repeated based on the face list. It's interleaved data (with the specified vertex_format) you could just dump into a VBO in OpenGL and render the complete object.

The vertices in the root is just the vertices in the order they appear in the obj file.

A lot of these things certainly needs to change in 2.0.

@victoriapoghosyan
Copy link

So there is no way to get UV vectors in order they appear in obj file ? Similar to mesh.vertices

@einarf
Copy link
Member

einarf commented Feb 27, 2019

I think you can obtain them from the parser at the moment. scene.parser.*

https://github.com/pywavefront/PyWavefront/blob/master/pywavefront/obj.py#L76-L78

Otherwise the are already interleaved in the material.vertices (see material.vertex_format for location in array)

@victoriapoghosyan
Copy link

Again thank you

@einarf
Copy link
Member

einarf commented Feb 27, 2019

No problem! Hoping to sort this out in 2.0 very soon with excellent documentation as well.

@mikesuttie
Copy link

I can't seem to read faces.

I thought it might be my .objs or code, but after trying this example smile obj with scene.mesh_list[0].faces, the array is always empty, has_faces is always false.

Any thoughts?

Many thanks

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

No branches or pull requests

5 participants