Reading wavefront OBJ and defining textures #1040
Replies: 5 comments 3 replies
-
Save as coloured_cube.obj file
|
Beta Was this translation helpful? Give feedback.
-
Save as coloured_cube.mtl file:
|
Beta Was this translation helpful? Give feedback.
-
Cleaning duplicated vertices in CC[1] above produces quite a funky cube, but, unfortunately, useless :) |
Beta Was this translation helpful? Give feedback.
-
Hi Sergei - sorry for the late reply. from vedo import *
# this might help to visualize the texture correctly
# settings.interpolate_scalars_before_mapping = False
C0 = Mesh("coloured_cube.obj").lw(1)
C0.add_ids()
# C0.clean().flat()
print(C0.nvertices)
print(C0.cells)
print(C0.pointdata["PointID"])
print(C0.pointdata["Material"])
C0.texture("coloured_cube.jpg", tcoords="Material")
show(C0, axes=1) In the dev version of vedo there is also a recently added function: from vedo import *
from vedo.file_io import load_obj
C0 = load_obj("coloured_cube.obj")[1]
print(C0)
# C0.clean().flat()
show(C0, axes=1) which reads the mtl file and also sets the lighting. Also check Line 1472 in cb44ad7 |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Hello, vedo users and Marco!
I have some questions on how import obj-file (especially textured) to a vedo.Mesh. I will illustrate the questions on a cube with coloured faces defined in 3 files:
coloured_cube.obj # defined in the comment - .obj cannot be attached
coloured_cube.mtl - materials definition # defined in the comment - .mtl cannot be attached
cube_face_colours.jpg - the texture
To recall, .obj is a text-file. The lines starting with "v" describe the coordinates of the vertices (8 for the cube), lines starting with "vt" define the uv-coordinates of the vertices mapped onto the jpg-texture as the proportions of its width and height (corner points on the picture above), "vn" - normals, "f" lines are faces in the format vid/tid/nid, where vid is the index of the vertex in the face, tid - the index of the uv-coordinate this vertex maps to, nid - the index of the normal. Thus the first face is [1,5,7,3] (so cell [0,4,6,2] - the numeration starts with 1 in obj-file), etc.
It is possible to load the mesh, ignoring the texture, with
And here comes the first surprise: it contains 24 vertices instead of 8! Examining
print(C0.cells)
each face generated its own vertex so in the end each vertex was replicated thrice.
Collapsing these with clean makes 8 vertices (as expected) but their indices are changed as seen from the cells:
That makes texturing with uv-coordinates in the obj-file impossible.
So the first question:
It is important because I want to import a mesh from 3D software, move some vertices, possibly, re-texture and load it back. But if the vertices get duplicated, I need to detect and move all duplicates. Moreover, 3D soft gets confused when the vertex order has changed.
I have found a nice script wavefront.py that parses obj-file and extracts vertex and faces information (not groups or curves, etc., but for me this is not needed). I renamed
load_obj
there toload_wavefront_obj
so that it does not collide with vedo's functionload_obj
, see below. ThenI am copying the outcome (compare with what obj-file contains: subtract 1 from indices there):
so now I can define the cube preserving the order of vertices and faces:
C = Mesh([verts, cells_v])
The first cell [0,4,6,2] has texture indices [0,1,2,3] meaning that it is mapped to the rectangle with pixel coordinates
1024 * (uvs[0], uvs[1], uvs[2], uvs[3] )
since cube_face_colours.jpg has size 1024x1024 pixels. Question:cells_vt
anduvs
at hand?I suspect I need to use
C.texture
but I do not understand how to use its parameters:C.texture(tname="cube_face_colours.jpg", tcoords=uvs)
produces the following error message:
[vedo.visual] ERROR: nr of texture coords must match nr of points
This is a strange requirement, because the number of vertices (v-lines in obj-file) need not (and usually does not) equal the number of texture vertices (vt-lines). Indeed, the top left corner of the yellow square and the bottom left corner of the cyan square on the jpg are the images of the same vertex.
I see that there is a function
load_obj
which is not so well documented nor there are examples.CC is a list of two meshes. CC[0] has no vertices, no idea what is it. CC[1] is the cube, it still has duplicated vertices, but magically it acquired the texture:
show(CC[1]).close()
CC[1]
?Thanks for your much appreciated help!
Beta Was this translation helpful? Give feedback.
All reactions