marcomusy / vedo

A python module for scientific analysis of 3D data based on VTK and Numpy
https://vedo.embl.es
MIT License
2.03k stars 265 forks source link

Saving a vd mesh to a file. #1050

Closed ManuGraiph closed 7 months ago

ManuGraiph commented 7 months ago

Hi!

This is a very general question... if i have a vedo mesh object, how can i save it into a file or what's the most recommended way to- (and then how to load it again)?

Thanks in advance!

PS: As i always say Marco, this is the best python library ever.

marcomusy commented 7 months ago

@ManuGraiph thanks!

To write to disk a mesh simply do:

mymesh.write("filename.vtk")

# then load it back with
mymesh = Mesh("filename.vtk")

the extension will automatically specify the format.

There are so many different formats: STL, PLY, VTK, OBJ ..... It all depends on your work environment and if you need to share files with other people and/or use other applications. Format VTK for example allows to save data associated to vertices and faces which is a super convenient feature, but it's not always recognised by other applications. Format STL or PLY are very widely used formats, but don't allow for that. Keep in mind that you can always convert format from CLI, eg:

vedo --convert mymesh.vtk --to ply
ManuGraiph commented 7 months ago

Thanks a lot!

I just have some meshes that i'm regularly processing with some stuff and then i need to just store them for later use, so i was wondering how to do it better. Nothing fancy, just to save it as a file.

marcomusy commented 7 months ago

If it's just for you go for VTK. Keep in mind that you can also save to files entire 3D scenes with export("myscene.npz"). (or press E in window)

ManuGraiph commented 7 months ago

Ohh, nice to know too!! Not on the scope of this problem, but it's also useful!

EDIT: About that.. how can i read a dxf mesh object into a vedo mesh? I'm currently erading it with ezdxf and getting the points/faces from there and generating a vedo mesh with them.

ManuGraiph commented 7 months ago

About the writing/reading meshes, i'm getting the following error:

File "/home/ghost/micromamba/envs/dev/lib/python3.12/site-packages/vispy/geometry/meshdata.py", line 260, in get_bounds bounds = [(v[:, ax].min(), v[:, ax].max()) for ax in range(v.shape[1])]

AttributeError: 'str' object has no attribute 'shape'

When trying to read a mesh i previously saved with the mesh.write() method described above.

marcomusy commented 7 months ago

dxf mesh

not directly supported in vedo, so Mesh([vertices, faces] is the only way.

AttributeError: 'str' object has no attribute 'shape'

what format are you using ? this seems related to vispy though...

ManuGraiph commented 7 months ago

I literally saved a mesh (made as vedo.Mesh([verts,faces]), with both arrays) as a vtk file with mesh.write() and then try to load it with vedo.Mesh(file) and get that error.

marcomusy commented 7 months ago

Can you reproduce this?


import vedo

verts = [(50,50,50), (70,40,50), (50,40,80), (80,70,50)]
cells = [(0,1,2), (2,1,3), (1,0,3)] 

mesh = vedo.Mesh([verts, cells])
mesh.write("mymesh.vtk")

mesh2 = vedo.Mesh("mymesh.vtk")
print(mesh2)

output:

vedo.mesh.Mesh at (0x7fe63497c670)                                     
name          : Mesh
file name     : mymesh.vtk
elements      : vertices=4 polygons=3 lines=0
position      : (0, 0, 0)
scaling       : (1.00000, 1.00000, 1.00000)
size          : average=21.0954, diagonal=51.9615
center of mass: (62.5000, 50.0000, 57.5000)
bounds        : x=(50.0, 80.0), y=(40.0, 70.0), z=(50.0, 80.0)

In your terminal type

vedo

to dump your current setup.

ManuGraiph commented 7 months ago

Yep, all good, that one works. Could it maybe be that i need to make an explicit cast to int/float the vert points?

Output:

vedo version      : 2023.5.0  (https://vedo.embl.es)             
vtk version       : 9.2.6
numpy version     : 1.26.4
python version    : 3.12.1 | packaged by conda-forge | (main, Dec 23 2023, 08:03:24) [GCC 12.3.0]
python interpreter: /home/ghost/micromamba/envs/dev/bin/python
installation point: /home/ghost/micromamba/envs/dev/lib/python3.12/site-packages/vedo
system            : Linux 6.7.4-arch1-1 posix x86_64
ManuGraiph commented 7 months ago

I'm guessing there is some issue with either the verts or faces format/type.

This is the real case:

>>> mesh.vertices
array([[3.2694200e+05, 8.1075310e+06, 3.6156333e+03],
       [3.2694106e+05, 8.1075290e+06, 3.6170845e+03],
       [3.2694200e+05, 8.1075265e+06, 3.6182031e+03],
       ...,
       [3.2748200e+05, 8.1071260e+06, 3.7487109e+03],
       [3.2748200e+05, 8.1071310e+06, 3.7478096e+03],
       [3.2748200e+05, 8.1071310e+06, 3.7478096e+03]], dtype=float32)
>>> mesh.cells[0:10]
[[0, 1, 2], [1, 2, 3], [4, 5, 6], [5, 6, 7], [8, 9, 10], [9, 10, 11], [12, 13, 14], [13, 14, 15], [16, 17, 18], [17, 18, 19]]
>>> mesh.write("test.vtk")
<vedo.mesh.Mesh object at 0x732e064eb380>
>>> mesh = Mesh("test.vtk")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/ghost/micromamba/envs/dev/lib/python3.12/site-packages/vispy/scene/visuals.py", line 134, in __init__
    subclass.__init__(self, *args, **kwargs)
  File "/home/ghost/micromamba/envs/dev/lib/python3.12/site-packages/vispy/visuals/mesh.py", line 126, in __init__
    MeshVisual.set_data(
  File "/home/ghost/micromamba/envs/dev/lib/python3.12/site-packages/vispy/visuals/mesh.py", line 184, in set_data
    self._bounds = self._meshdata.get_bounds()
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ghost/micromamba/envs/dev/lib/python3.12/site-packages/vispy/geometry/meshdata.py", line 260, in get_bounds
    bounds = [(v[:, ax].min(), v[:, ax].max()) for ax in range(v.shape[1])]
                                                               ^^^^^^^
AttributeError: 'str' object has no attribute 'shape'
marcomusy commented 7 months ago

well you can try to do the cast... but it shouldn't matter.. I dont get how the message can be related to vispy..

I think you are messing up the Mesh from vispy with the Mesh from vedo.

ManuGraiph commented 7 months ago

Ohh, you are right, i'm importing Mesh from vispy too, didn't notice that!

Just doing vedo.Mesh(filename) instead, worked, sorry!

Thanks a lot!!

ManuGraiph commented 7 months ago

If it's just for you go for VTK. Keep in mind that you can also save to files entire 3D scenes with export("myscene.npz"). (or press E in window)

About this... how can i export them? The export command is not recognized in vispy.scene and E doesn't do anything in my canvas window.

marcomusy commented 7 months ago

This has nothing to do with vispy! In a vedo window you press Shift-E and you get a snapshot to the scene.

ManuGraiph commented 7 months ago

Ahh, ok ok, i thought it was some way to save the scene into a file and then loading it without having to render it all again. Thanks!