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

Is there any way to get the Texture from a PngImageFile object? #145

Open
fishbotics opened this issue Mar 2, 2024 · 2 comments
Open

Is there any way to get the Texture from a PngImageFile object? #145

fishbotics opened this issue Mar 2, 2024 · 2 comments

Comments

@fishbotics
Copy link

fishbotics commented Mar 2, 2024

I'm trying to visualize a mesh that I loaded through Trimesh. It's easy to get the triangular mesh geometry (Meshcat just needs the vertices and faces) but I'm also trying to visualize the textures. For textured meshes, Trimesh uses an object called trimesh.visual.texture.TextureVisuals, which is instantiated with not the png file path but the PIL data as loaded from Pillow.

In Meshcat, the expectation is that I have the png file name, which was lost along the way when loading from Trimesh. Is there any other way to do this conversion?

I know this is kind of an esoteric question and seems sort of silly to be crossing back and forth between mesh libraries, but I find that it's helpful to be able to do mesh manipulation in Trimesh and then visualize complex things in Meshcat.

@fishbotics
Copy link
Author

After some more reading, it seems like the easiest thing to do might be to dump the trimesh object into a BytesIO stream and then load it as an ObjFile, but there is no current support for loading textures from obj files (see #27)

Another strategy I tried was to take the PIL texture object, dump it into a BytesIO buffer, gran the whole buffer, and then try to instantiate a meshcat.geometry.PngImage object directly, but this also didn't seem to work. Maybe the way I'm converting between objects wrong.

Basically I did the following:

im = mesh.visual.material.image
if im is not None:
    buffer = BytesIO()
    im.save(buffer, format="PNG")
    binary_image_data = buffer.getvalue()
    image = meshcat.geometry.PngImage(binary_image_data)
    material = meshcat.geometry.MeshPhongMaterial(
        map=meshcat.geometry.ImageTexture(image=image)
    )

But this doesn't seem to work with my PNG. In the original OBJ file, I think there are UV coordinates specified to map the texture to the file. Is there something I need to do to make that mapping work?

@kielnino
Copy link

Your approach looks right to me. Have you tried to save the png to an file and load it with

material = g.MeshLambertMaterial(map=g.ImageTexture(image=g.PngImage.from_file(path_to_texture_file)))

Another problem may be a missing MTL-File. I often see a combination of a .obj file containing the mesh, a .mtl file containing the mapping, and finally the texture itself.

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

2 participants