daavoo / pyntcloud

pyntcloud is a Python library for working with 3D point clouds.
http://pyntcloud.readthedocs.io
MIT License
1.39k stars 221 forks source link

could you help out converting it to .obj, please? #293

Closed AndreV84 closed 3 years ago

AndreV84 commented 3 years ago

https://storage.googleapis.com/nvidia-dev/113620.ply At my end I either get the points lost or the color lost with conversion `[GCC 8.4.0] on linux Type "help", "copyright", "credits" or "license" for more information.

from pyntcloud import PyntCloud diamond = PyntCloud.from_file("cloud.ply") convex_hull_id = diamond.add_structure("convex_hull") convex_hull = diamond.structures[convex_hull_id] diamond.to_file("diamond_hull.obj", also_save=["mesh"])`

AndreV84 commented 3 years ago

https://github.com/IntelRealSense/librealsense/issues/7800#issuecomment-729831606

daavoo commented 3 years ago

Hola @AndreV84 , I'm afraid that pyntcloud does not currently support reading/writing to/from .obj files with per-vertex color information.

As far as I remember when adding the .obj code, vertex coloring is not considered part of the format "standard" and it is only supported by a few applications (i.e. Meshlab).

Looking at how it appears to be implemented in Meshlab (https://gamedev.stackexchange.com/a/66270) it might be feasible to add support to vertex coloring for the .obj format in pyntcloud with minor modifications, will change the label to Feature Request. Contributions are allways wellcome.

daavoo commented 3 years ago

Hola again @AndreV84 I was feeling hacky so I think that you could use the following:


def write_obj(filename, points=None, mesh=None, save_vertex_colors=False):
    """
    Parameters
    ----------
    filename:   str
        The created file will be named with this
    points:     pd.DataFrame
    mesh:       pd.DataFrame
    save_vertex_colors: bool, optional
        Defaul False.
        If True, include per-vertex color info following:
        https://gamedev.stackexchange.com/a/66270

    Returns
    -------
    boolean
        True if no problems

    """
    if not filename.endswith('obj'):
        filename += '.obj'

    if points is not None:
        points = points.copy()
        columns_to_save = ["x", "y", "z"]
        if save_vertex_colors:
            columns_to_save.extend(["red", "green", "blue"])
            points["red"] /= 255.
            points["blue"] /= 255.
            points["green"] /= 255.
        points = points[columns_to_save]
        points.insert(loc=0, column="obj_v", value="v")
        points.to_csv(
            filename,
            sep=" ",
            index=False,
            header=False,
            mode='a',
            encoding='ascii')

    if mesh is not None:
        mesh = mesh.copy()
        mesh = mesh[["v1", "v2", "v3"]]
        mesh += 1  # index starts with 1 in obj file
        mesh.insert(loc=0, column="obj_f", value="f")
        mesh.to_csv(
            filename,
            sep=" ",
            index=False,
            header=False,
            mode='a',
            encoding='ascii')

    return True

cloud = PyntCloud.from_file("examples/data/ankylosaurus_mesh.ply")
write_obj("output.obj", points=cloud.points, mesh=cloud.mesh, save_vertex_colors=True)
AndreV84 commented 3 years ago

Thank you very much! It seems I was able to export ply to obj with meshlab. I can visualize the obj in meshlab. Not sure if it wil get drawn in other visualizers though.

Could you elaborate on how to visualize from terminal with the python tool? I never got any window to pop up

daavoo commented 3 years ago

Thank you very much! It seems I was able to export ply to obj with meshlab. I can visualize the obj in meshlab. Not sure if it wil get drawn in other visualizers though.

Could you elaborate on how to visualize from terminal with the python tool? I never got any window to pop up

If you want to visualize directly from the terminal, you need to first install matplotlib (pip install matplotlib). And then:

from pyntcloud import PyntCloud
cloud = PyntCloud.from_file("examples/data/ankylosaurus_mesh.ply")
cloud.plot(backend="matplotlib")
AndreV84 commented 3 years ago

Thank you very much!