1
votes

Je souhaite générer un maillage à partir d'un nuage de points en Python

J'ai un nuage de points provenant de différentes parties du corps humain, comme un œil et je veux faire un maillage. J'ai essayé d'utiliser Mayavi et Delaunay mais je n'obtiens pas un bon maillage. Les points du nuage sont en désordre total. J'ai mon nuage de points dans un fichier .npz

 entrez la description de l'image ici

Utilisation de Mayavi

 entrez la description de l'image ici

Ensuite, je veux enregistrer mon modèle dans un fichier obj ou stl, mais je veux d'abord générer le maillage. Que me recommandez-vous d'utiliser, ai-je besoin d'une bibliothèque spéciale?


0 commentaires

4 Réponses :


1
votes

Si vos points sont "en désordre total", et si vous voulez générer un maillage, alors vous avez besoin d'une interpolation du nuage de points aux points de grille du maillage en quelque sorte structurés.

Dans le cas à 2 dimensions, la triangulation de matplotlib peut être une aide: triangulation de matplotlib 2dim .

Dans le cas en 3 dimensions, il y a 2 options. En fonction des données, vous souhaiterez peut-être les interpoler sur une surface tridimensionnelle. Alors trisurf3d de matplotlib peut être une aide.

Si vous avez besoin d'une grille de volume en 3 dimensions, vous devez probablement rechercher une grille FEM (éléments finis), par exemple FEnics

Un exemple d'interpolation d'un champ tridimensionnel avec scipy pour le contouring peut être trouvé ici


7 commentaires

Merci, je vais vérifier ces liens, je ne connais pas grand chose à ce sujet, y a-t-il une documentation où je peux être guidé?


Je n'ai pas plus de documentations non plus (quel type d'interpolation / maillage vous intéresse?). Habituellement, j'essaie de télécharger un exemple exécutable complet et de modifier ensuite le code étape par étape.


Disposez-vous d'un ensemble de données disponible pour exécuter certains essais?


Je veux le faire en utilisant la tétraédrisation ou les splines mais je ne trouve aucun moyen de le faire à partir de mon nuage de points. Oui, bien sûr, j'ai un ensemble de données au format npz.


J'ai une autre question, puis-je utiliser geomdl pour générer le maillage en utilisant la fonction nurb?


Je ne l'ai jamais utilisé, donc je n'ai aucune expérience, mais suivre la documentation geomdl sonne bien. Il a des procédures pour les grilles de surface et pour les grilles de volume. (Que voulez-vous réaliser réellement?)


Je veux uniquement générer un maillage à partir de mon nuage de points, de la même manière que MeshLab le fait à partir d'un nuage de points.



0
votes

Avez-vous essayé cet exemple? https://docs.enthought.com/mayavi/mayavi/auto/example_surface_data_from_irregularo. html

La partie pertinente est ici

# 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)


1 commentaires

J'ai déjà essayé avec, la deuxième image est le résultat. Je pense qu'il n'y a pas de méthode aussi simple pour créer ce maillage. J'ai aussi d'autres parties du corps humain comme un crâne et un cerveau.



1
votes

 entrez la description de l'image ici Données

Utilisons les capitales de l'Europe. Nous les lisons depuis Excel avec Pandas:

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()

Grille par triangulation

Nous utilisons Scipy pour cela. Pour un exemple en 3 dimensions, voir ICI et ICI ou ici (CGAL a un wrapper Python)

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)

Graphiques

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


0 commentaires

2
votes

Vous pouvez utiliser pyvista pour effectuer l'interpolation 3D. Vous devez cependant jouer manuellement avec le paramètre alpha qui contrôle la distance sous laquelle deux points sont liés.

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

maillage après interpolation delaunay


0 commentaires