dmurdoch / rgl

rgl is a 3D visualization system based on OpenGL. It provides a medium to high level interface for use in R, currently modelled on classic R graphics, with extensions to allow for interaction.
https://dmurdoch.github.io/rgl/
GNU General Public License v2.0
85 stars 20 forks source link

bug writeOBJ? #371

Closed stla closed 1 year ago

stla commented 1 year ago

Hello,

I have a mesh with 2500 vertices and 4900 faces:

> mesh
 mesh3d object with 2500 vertices, 4900 triangles.
> open3d(windowRect = 50 + c(0, 0, 512, 512), zoom = 0.9)
wgl 
  1 
> shade3d(mesh, color = "turquoise")
> writeOBJ("mesh_stla.obj", withNormals = FALSE)

When I write it in an OBJ file, there are 14700 vertices (=4900*3). And every face has form i i+1 i+2. Is it normal?

dmurdoch commented 1 year ago

Yes, that's expected. Your mesh has 4900 triangles, and each triangle has 3 vertices. writeOBJ sees those triangles, it doesn't see your mesh. (Your mesh isn't an argument to writeOBJ. It gets its data from the display.) It also doesn't try to remove redundant triangles.

There's code in writeOBJ to write out a mesh (which it uses for writing spheres), but it's not currently accessible from the user interface.

This could be improved in a couple of ways. writeOBJ could accept a mesh as an argument, and write it out. Alternatively, it could try to remove repeated vertices. You need to be careful doing that, because in OpenGL vertices have associated colour, normals, and texture coordinates; it's not enough to check that the x, y, z coordinates are equal to determine that they are duplicates.

If you are interested in making either of those changes, please go ahead and submit a PR. I don't think I will do either one, since the output displays properly, even if it is larger than it needs to be.

tylermorganwall commented 1 year ago

@stla If you're just interested in writing/manipulating meshes that preserve the topology/indexing in the original mesh, check out the rayvertex package:

https://www.rayvertex.com https://github.com/tylermorganwall/rayvertex

You can convert a mesh3d object to a ray_mesh class via the mesh3d_mesh() function:

https://www.rayvertex.com/reference/mesh3d_mesh.html

and write it to OBJ with the write_scene_to_obj() function:

https://www.rayvertex.com/reference/write_scene_to_obj.html

stla commented 1 year ago

@tylermorganwall Thanks for the info. One can also use Rvcg or cgalMeshes to read/write mesh files.