dmurdoch/rgl

writePLY() exports vertex colors as float instead of uchar

Closed this issue · 3 comments

  • 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/

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.

@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?

@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.