pythonpython-3.xioopenmeshcustomproperty

How to save custom vertex properties with openmesh in Python?


I am working with openmesh installed in Python 3.6 via pip. I need to add custom properties to vertices of a mesh in order to store some data at each vertex. My code goes as follows :

import openmesh as OM
import numpy as np
mesh = OM.TriMesh()

#Some vertices
vh0 = mesh.add_vertex(np.array([0,0,0]));
vh1 = mesh.add_vertex(np.array([1,0,0]));
vh2 = mesh.add_vertex(np.array([1,1,0]));
vh3 = mesh.add_vertex(np.array([0,1,0]));

#Some data
data = np.arange(mesh.n_vertices)

#Add custom property
for vh in mesh.vertices():
    mesh.set_vertex_property('prop1', vh, data[vh.idx()])

#Check properties have been added correctly
print(mesh.vertex_property('prop1'))

OM.write_mesh('mesh.om',mesh)

print returns [0, 1, 2, 3]. So far, so good. But when I read again the mesh, the custom property has disappeared :

mesh1 = OM.TriMesh()

mesh1 = OM.read_trimesh('mesh.om')

print(mesh1.vertex_property('prop1'))

returns [None, None, None, None]

I have two guesses :
1 - The property was not saved in the first place
2 - The reader does not know there is a custom property when it reads the file mesh.om

Does anybody know how to save and read properly a mesh with custom vertex properties with openmesh in Python? Or is it even possible (has anybody done it before?)?
Is it that there is something wrong with my code?

Thanks for your help,

Charles.


Solution

  • The OM writer currently does not support custom properties. If you are working with numeric properties, it is probably easiest to convert the data to a NumPy array and save it separately.

    Say your mesh and properties are set up like this:

    import openmesh as om
    import numpy as np
    
    # create example mesh
    mesh1 = om.TriMesh()
    v00 = mesh1.add_vertex([0,0,0])
    v01 = mesh1.add_vertex([0,1,0])
    v10 = mesh1.add_vertex([1,0,0])
    v11 = mesh1.add_vertex([1,1,0])
    mesh1.add_face(v00, v01, v11)
    mesh1.add_face(v00, v11, v01)
    
    # set property data
    mesh1.set_vertex_property('color', v00, [1,0,0])
    mesh1.set_vertex_property('color', v01, [0,1,0])
    mesh1.set_vertex_property('color', v10, [0,0,1])
    mesh1.set_vertex_property('color', v11, [1,1,1])
    

    You can extract the property data as a numpy array using one of the *_property_array methods and save it alongside the mesh using NumPy's save function.

    om.write_mesh('mesh.om', mesh1)
    color_array1 = mesh1.vertex_property_array('color')
    np.save('color.npy', color_array1)
    

    Loading is similar:

    mesh2 = om.read_trimesh('mesh.om')
    color_array2 = np.load('color.npy')
    mesh2.set_vertex_property_array('color', color_array2)
    
    # verify property data is equal
    for vh1, vh2 in zip(mesh1.vertices(), mesh2.vertices()):
        color1 = mesh1.vertex_property('color', vh1)
        color2 = mesh2.vertex_property('color', vh2)
        assert np.allclose(color1, color2)