4

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?

Joel_Developer
  • 63
  • 1
  • 2
  • 10

4 Answers4

8

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

Calos
  • 1,783
  • 19
  • 28
Hicham Janati
  • 106
  • 1
  • 2
2

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()
pyano
  • 1,885
  • 10
  • 28
1

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

pyano
  • 1,885
  • 10
  • 28
  • I want to do it using tetrahedralization or splines but I can not find any way to do it from my point cloud. Yes, of course I have a data set in npz format. – Joel_Developer Mar 08 '19 at 01:42
  • I have another question, Can I use geomdl to generate the mesh using nurb function? – Joel_Developer Mar 08 '19 at 01:43
  • I have never used it, so I have no experiences, but following the docs geomdl sounds good. It has procedures for surface grids and for volume grids. (What do you want to achieve actually ?) – pyano Mar 08 '19 at 08:16
  • I only want to generate a mesh from my point cloud, in the same way that MeshLab does from a cloud of any points. – Joel_Developer Mar 11 '19 at 05:44
0

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)
PerroNoob
  • 843
  • 2
  • 16
  • 36
  • I've already tried with it, the second image is the result. I think there is not such a simple method to make this mesh. I also have other parts of the human body like a skull and a brain. – Joel_Developer Feb 27 '19 at 23:25