Joel_Developer
Joel_Developer

Reputation: 103

I want to generate a mesh from a point cloud in Python

I have a point cloud from different parts of the human body, like an eye and I want to do a mesh. I tried to use Mayavi and Delaunay but I don't get a good mesh. The points of the cloud are in total disorder. I have my point cloud in .npz file

enter image description here

Using Mayavi

enter image description here

Then I want to save my model in an obj or stl file, but first I want to generate the mesh. What do you recommend me to use, do I need a special library?

Upvotes: 8

Views: 37396

Answers (4)

Hicham Janati
Hicham Janati

Reputation: 196

You can use pyvista to do the 3D interpolation. You need however to manually play with the alpha parameter that controls the distance under which two points are linked.

import numpy as np
import pyvista as pv

# points is a 3D numpy array (n_points, 3) coordinates of a sphere
cloud = pv.PolyData(points)
cloud.plot()

volume = cloud.delaunay_3d(alpha=2.)
shell = volume.extract_geometry()
shell.plot()

cloud viz

mesh after delaunay interpolation

Upvotes: 17

pyano
pyano

Reputation: 1978

enter image description here Data

Let's use the capitals of Europe. We read them in from Excel with Pandas:

import pandas as pd
dg0 = pd.read_excel('psc_StaedteEuropa_coord.xlsx')  # ,header=None
dg0.head()

    City    Inhabit     xK          yK
0   Andorra 24574.0     42.506939   1.521247
1   Athen   664046.0    37.984149   23.727984
2   Belgrad 1373651.0   44.817813   20.456897
3   Berlin  3538652.0   52.517037   13.388860
4   Bern    122658.0    46.948271   7.451451

Grid by triangulation

We use Scipy for that. For a 3-dim example see HERE and HERE or here (CGAL has a Python wrapper)

import numpy as np
from scipy.spatial import Delaunay
yk, xk, city = np.array(dg0['xK']), np.array(dg0['yK']), np.array(dg0['City'])
X1 = np.vstack((xk,yk)).T
tri = Delaunay(X1)

Graphics

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
#--- grafics -------
figX = 25; figY = 18
fig1 = plt.figure(figsize=(figX, figY), facecolor='white')

myProjection = ccrs.PlateCarree()
ax = plt.axes(projection=myProjection)
ax.stock_img()
ax.set_extent([-25, 40, 35, 65], crs=myProjection)

plt.triplot(X1[:,0], X1[:,1], tri.simplices.copy(), color='r', linestyle='-',lw=2)
plt.plot(X1[:,0], X1[:,1], 's', color='w')

plt.scatter(xk,yk,s=1000,c='w')
for i, txt in enumerate(city):
    ax.annotate(txt, (X1[i,0], X1[i,1]), color='k', fontweight='bold')

plt.savefig('Europe_A.png')
plt.show()

Upvotes: 2

pyano
pyano

Reputation: 1978

If your points are "are in total disorder", and if you want to generate a mesh, then you need some interpolation from the cloud of points to the somehow structured grid points of the mesh..

In the 2-dimensional case matplotlib's triangulation can be a help: matplotlib's triangulation 2dim.

In the 3-dimensional case there are 2 options. Depending on the data, you might want to interpolate them to a 3-dimensional surface. Then matplotlib's trisurf3d can be a help.

If you need a 3-dimensional volume grid then you have probably to look for a FEM (finite element) grid, e.g. FEnics

An example of interpolating a 3-dimensional field with scipy for contouring can be found here

Upvotes: 4

PerroNoob
PerroNoob

Reputation: 895

Have you tried this example? https://docs.enthought.com/mayavi/mayavi/auto/example_surface_from_irregular_data.html

The relevant part is here

# Visualize the points
pts = mlab.points3d(x, y, z, z, scale_mode='none', scale_factor=0.2)

# Create and visualize the mesh
mesh = mlab.pipeline.delaunay2d(pts)
surf = mlab.pipeline.surface(mesh)

Upvotes: 1

Related Questions