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

writePLY() exports vertex colors as float instead of uchar #425

Closed
aidanmorales opened this issue Jun 20, 2024 · 3 comments
Closed

writePLY() exports vertex colors as float instead of uchar #425

aidanmorales opened this issue Jun 20, 2024 · 3 comments

Comments

@aidanmorales
Copy link

  • rgl Version: 1.3.6
  • R Version: 4.4.0
  • Platform: Windows 10 Intel 64 (i7-8700k)

Hi. I am using your excellent rgl library in my package rTwig to efficiently export and visualize cylinder meshes of tree. I found an issue with the writePLY() function on both the latest CRAN and development versions.

The issue is that custom colors applied to vertices display correctly in the plotting window, but are not correctly applied when using writePLY(), and do not display properly when opening the file in third party applications. I believe the issue is that the header of the .ply file assigns the RGBA colors as float, instead of uchar.

If I manually edit the header of the exported .ply file:

property float red
property float green
property float blue
property float alpha

to

property uchar red
property uchar green
property uchar blue
property uchar alpha

the colors are now displayed properly in third party applications, such as CloudCompare, for example. Is it possible to modify writePLY() to export RGBA colors as unsigned char instead of floating point?

Here is a reproducible example:

# Import rgl 
library(rgl)

 # Function to generate n random colors
generate_random_colors<- function(n) {
  colors <- replicate(n, {
    r <- sprintf("%02X", sample(0:255, 1))
    g <- sprintf("%02X", sample(0:255, 1))
    b <- sprintf("%02X", sample(0:255, 1))
    paste0("#", r, g, b)
  })
  return(colors)
}

# Temp file 
filename <- tempfile(pattern = "mesh",  fileext = ".ply")

# Generate mesh
mesh <- icosahedron3d()

# Assign colors to vertices
colors <- generate_random_colors(length(mesh$vb))
mesh$material$color <- colors

# Plot mesh
open3d()
shade3d(mesh)

# Export mesh
writePLY(filename, withColors = TRUE, format = "ascii")

The issue was also documented in this stackoverflow thread a few years ago: https://stackoverflow.com/questions/39239298/

@dmurdoch
Copy link
Owner

I think an argument could be made that those other applications should support float, but uchar is indeed the recommended type. The trouble is that the current code puts together a big matrix of values and writes them all using the float format. Mixing some float and some uchar will make writing more complicated and probably slower. Still, I suspect the speed difference doesn't matter, so I'll look into it.

@dmurdoch
Copy link
Owner

@aidanmorales : Okay, I have made some changes, but I don't use PLY format much, so I don't know if they are correct. In particular, the colors aren't being displayed the way they look in R, but that might be the fault of the viewer (which is F3D 2.4.0). Could you build rgl from the writePLY branch and see if things work with your viewer? If not, can you take a look at the output file or source and suggest what needs changing?

@aidanmorales
Copy link
Author

@dmurdoch Thanks for looking into this! I tested your new patch in my package and everything works flawlessly. In terms of the speed difference, withColors = TRUE has a very slight performance hit, but it is still very fast and can export >100,000 vertices in a few seconds. I will mark this issue as closed, since this solved all of the issues I had with the function.

dmurdoch added a commit that referenced this issue Jun 28, 2024
fix writePLY to handle colors properly.  Fixes #425.
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