pytorch3d
pytorch3d copied to clipboard
Support other face / vertex attributes in save_{obj,ply} function
🚀 Feature
Support other texture representations (at least the TexturesVertex
one) in save_obj
function
https://github.com/facebookresearch/pytorch3d/blob/1872e0249c8c2c4eef7088996284a16cab52ca25/pytorch3d/io/obj_io.py#L652
Motivation
Saving a mesh without loosing the texture information, e.g. as done in fit_textured_mesh.ipynb
Pitch
For the TexturesVertex case it should be simple, the beginning of the _save
function can for example be replaced by:
def _save(
f,
verts,
faces,
decimal_places: Optional[int] = None,
*,
verts_rgb: Optional[torch.Tensor] = None,
verts_uvs: Optional[torch.Tensor] = None,
faces_uvs: Optional[torch.Tensor] = None,
save_texture: bool = False,
) -> None:
if len(faces) and (faces.dim() != 2 or faces.size(1) != 3):
message = "'faces' should either be empty or of shape (num_faces, 3)."
raise ValueError(message)
if not (len(verts) or len(faces)):
warnings.warn("Empty 'verts' and 'faces' arguments provided")
return
if verts_rgb is not None and (verts_rgb.dim() != 2 or verts_rgb.size(1) != 3):
message = "'verts_rgb' should either be empty or of shape (num_verts, 3)."
raise ValueError(message)
verts, faces = verts.cpu(), faces.cpu()
lines = ""
if len(verts):
if decimal_places is None:
float_str = "%f"
else:
float_str = "%" + ".%df" % decimal_places
V, D = verts.shape
for i in range(V):
vert = [float_str % verts[i, j] for j in range(D)]
if verts_rgb is not None:
vert += [float_str % verts_rgb[i, j] for j in range(3)]
lines += "v %s\n" % " ".join(vert)
modulo some verifications that verts_rgb
has values in [0, 1]
Thanks for the suggestion. I believe the OBJ format does not support per-vertex colors though.
If you need to save such information, try using instead the PLY format: while the exposed save_ply()
does not support saving colors, the internal _save_ply()
should. Feel free to submit a PR to close this gap.
my bad I thought it was rather standard to append rgb colors to the vertex position as it is fully supported by MeshLab (see for example this discussion
I will keep using my local function then and see what can be done in the PLY format
Oh I see, I guess this non-standard extension could potentially be added to save_obj()
then.
great that would be cool, thanks for the detailed answers :)