How to save custom vertex properties with openmesh in Python?

1.4k views Asked by At

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.

2

There are 2 answers

1
jsb On BEST ANSWER

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)
0
SoonJong Jung Jung Troubler On

When you store data, you should set set_persistent function true like below. (sorry for using c++, I don't know about python)

OpenMesh::VPropHandleT<float> vprop_float;
mesh.add_property(vprop_float,  "vprop_float");
mesh.property(vprop_float).set_persistent(true);
OpenMesh::IO::write_mesh(mesh, "tmesh.om");

and then, you have to request this custom property in your mesh before loading it with the obj reader. Order is important.

TriMesh readmesh;
OpenMesh::VPropHandleT<float> vprop_float;
readmesh.add_property(vprop_float, "vprop_float");
OpenMesh::IO::read_mesh(readmesh, "tmesh.om");'

I refered below. https://www.openmesh.org/media/Documentations/OpenMesh-4.0-Documentation/a00062.html https://www.openmesh.org/media/Documentations/OpenMesh-4.0-Documentation/a00060.html