Delaunay点云的三角剖分

时间:2016-09-28 07:47:31

标签: python-2.7 numpy delaunay

我想使用Delaunay算法对3D点云进行三角测量。为了测试我的代码,我从STL文件中提取点云,然后尝试重新删除它。这是我的代码:

import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Delaunay

#--------------def funtion extract point cloud-------------------
def point_cloud(inp):
    node = []
    for line in inp:
        temp1 = line.strip()
        x = temp1.split()
        if x[0] == "vertex": 
            del x[0]
            node.append(x)
    node = set(map(tuple,node))
    return node
#--------------------end function---------------------------------

with open("D:\\cilinder.stl","r") as fo:
    pc = point_cloud(fo)

u = []
v = []
w = []

for l in pc:
    u.append(float(l[0]))
    v.append(float(l[1]))
    w.append(float(l[2])) 

ua = np.array(u)
va = np.array(v)

#tri = mtri.Triangulation(u, v)
tri = Delaunay(np.array([u,v]).T)

points = []
vertex = []

for i in range(ua.shape[0]):
    points.append([ua[i],va[i],w[i]])

for vert in tri.simplices:
#for vert in tri.triangles:
    vertex.append(vert)      

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')
ax.plot_trisurf(ua, va, w, triangles=tri.simplices, cmap=plt.cm.Spectral)
#ax.plot_trisurf(ua, va, w, triangles=tri.triangles, cmap=plt.cm.Spectral)
plt.show()

运行此代码后,我得到以下结果:

结果:

enter image description here enter image description here

该算法不会对点云的外表面进行三角测量。我无法弄清楚为什么会得到这个结果。有什么建议吗?

编辑:我刚才发现函数point_cloud提供了重复的点,因为它们直接从STL文件中提取。

2 个答案:

答案 0 :(得分:1)

在显示网格物体时获取网格物体的原因是你没有(也不能)向scipy的Delaunay网格物体提供拓扑信息。你给它一个点云,它连接所有的点,就是它。

网格生成是一个复杂的主题,不幸的是,我不知道任何软件,给定点云和拓扑信息,为您提供网格。

但是,有多种方法可以从头开始生成网格,只需给出对象的几何形状。对于你想到的气缸,一种方法是自己做;看看meshzoo

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np


def create_mesh(width=5.0, n=30, radius=1.0):
    # Number of nodes along the width of the strip (>= 2)
    # Choose it such that we have approximately square boxes.
    nw = int(round(width * n/(2*np.pi*radius)))

    # Generate suitable ranges for parametrization
    u_range = np.linspace(0.0, 2*np.pi, num=n, endpoint=False)
    v_range = np.linspace(-0.5*width, 0.5*width, num=nw)

    # Create the vertices.
    nodes = []
    for u in u_range:
    x = radius * np.cos(u)
    y = radius * np.sin(u)
    for v in v_range:
        nodes.append(np.array([x, y, v]))

    # create the elements (cells)
    elems = []
    for i in range(n - 1):
    for j in range(nw - 1):
        elems.append([i*nw + j, (i + 1)*nw + j + 1, i * nw + j + 1])
        elems.append([i*nw + j, (i + 1)*nw + j,     (i + 1)*nw + j + 1])
    # close the geometry
    for j in range(nw - 1):
    elems.append([(n - 1)*nw + j, j + 1, (n - 1)*nw + j + 1])
    elems.append([(n - 1)*nw + j, j, j + 1])

    return np.array(nodes), np.array(elems)


if __name__ == '__main__':
    import meshio
    points, cells = create_mesh()
    meshio.write('tube.vtu', points, {'triangle': cells})

enter image description here

从中做出锯齿也应该很容易。

其他网格生成器:

答案 1 :(得分:1)

您可以尝试使用四面体进行delaunay三角测量。然后手动删除孔。 IMO是一个四面体体网格。特别是Bowyer-Watson算法很简单。