重新划分3D三角形表面以获得更好的网格质量

时间:2018-06-12 17:43:47

标签: python mesh scikit-image triangulation marching-cubes

我正在使用行进立方体从卷中提取2D表面。在这种情况下是Gyroid。

import numpy as np
from numpy import sin, cos, pi
from skimage import measure
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def gyroid(x, y, z, t):
    return cos(x)*sin(y) + cos(y)*sin(z) + cos(z)*sin(x) - t

lattice_param = 1.0
strut_param = 0.0
resolution = 31j

x, y, z = pi*np.mgrid[-1:1:resolution, -1:1:resolution, -1:1:resolution] * lattice_param
vol = gyroid(x, y, z, strut_param)

verts, faces = measure.marching_cubes(vol, 0, spacing=(0.1, 0.1, 0.1)) # , normals, values

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(verts[:, 0], verts[:, 1], faces, verts[:, 2], cmap='ocean', lw=1)

enter image description here

这一切都很好,但网格quailty在很多地方令人震惊。我不能在网格上运行任何有限元分析,因为许多元素/面都接近零区域或高度扭曲。

enter image description here

有没有一种方法可以重新划分给定顶点和&确保特定的元素面/方面指标(如宽高比)或强制行进立方体做这样的事情?

只要网格是一个公平的近似值,我就不会为移动顶点而烦恼。

4 个答案:

答案 0 :(得分:0)

奇怪的三角形来自奇怪的数据,而不是来自用于三角测量的方法。

我可以说Delaunay三角剖分实现了最佳的三角形区域/三角形 - 周长比(最佳理论比例是等边三角形)。但是你不能使用if作为你的网格,因为Delaunay三角剖分输出一个凸网格。

你前面的任务很紧张。一些想法:

  • 在网格化之前删除cuasi-duplicateped点。这将避免许多接近零区域的三角形。
  • 检测细三角形。将它们细分为更常规的'三角形。
  • 您可以创建一个密集的常规网格。可以找到每个z遍历网格,直到找到包含网格中点的x,y坐标的三角形,然后插入z。如果你有一些额外的信息,比如neigbours或hierachy,搜索可以比检查每个三角形更快。对网格进行三角测量非常简单。

答案 1 :(得分:0)

一种选择可能是重新筛选'使用表面网格包输出行进立方体。从本质上讲,这意味着行进立方体三角剖分将作为重新三角化的初始表面定义。

有许多技术可以用来做到这一点。一些可能有用的选项(所有C++ / C实现):

  • JIGSAW受限正面 - delaunay 算法^^,通常会构建非常高质量的表面Delaunay三角剖分。对于所示的对象类型,我希望它能够很好地工作。在包含的演示中(在MATLAB中提供),几个示例解决了行进立方体输出的重新网格化问题。
  • CGAL受限 delaunay-refinement 方法,也可以构建表面Delaunay三角剖分,但使用稍微不同的算法JIGSAW还包括CVT - 类型网格优化方案。
  • MMG:一系列重新网格划分/优化策略(据我所知),可用于通过迭代应用局部修改来转换(并因此改进)初始网格。

^^我是JIGSAW的作者,所以,基本上是无耻的推广。

答案 2 :(得分:0)

使用也可以使用pygalmesh进行表面重新定型。 (这是CGAL的易于使用的界面。)

import pygalmesh

# create verts, faces

meshio.write_points_cells("in.vtu", verts, [("triangle", faces)])

mesh = pygalmesh.remesh_surface(
    "in.vtu",
    edge_size=0.025,
    facet_angle=25,
    facet_size=0.1,
    facet_distance=0.001,
    verbose=False,
)
# mesh.points, mesh.cells

答案 3 :(得分:0)

我建议使用带有平滑效果的3d自适应重新网格化。地理编程库(http://alice.loria.fr/software/geogram/doc/html/index.html)提供了一个不错的实现。请参阅:https://twitter.com/brunolevy01/status/1132343120690122752?lang=en