如何在Python中偏移/加厚/实体化3D网格?

q9yhzks0  于 2022-10-30  发布在  Python
关注(0)|答案(2)|浏览(1988)

我正在寻找一种通过Python脚本将TIN(不规则三角网)网格(例如地形)偏移一致距离的方法。过去我调用了Blender's Solidify modifier via the API,它工作得很好,但我想找到一种不需要依赖Blender的替代方法。
目前,我正在对每个三角形进行迭代,制作每个顶点的副本,并将这些顶点沿着它们的父三角形的表面法线移动一段设定的距离。当同一个顶点出现在多个三角形中时,我计算每个法线的偏移量并使用平均值。然后,我再次将顶点连接在一起,制作一个偏移网格。
这似乎适用于小偏移,但网格中的尖锐特征可能会创建自相交。
是否有特定的算法或库提供更好的方法?
到目前为止,除了Blender,我发现:

但是我还没有找到很多关于Python的东西,比如Open3DTrimesh

mdfafbf1

mdfafbf11#

我认为最简单的解决方法是沿着平均法线移动顶点,而不是沿着每条法线的平均值移动顶点。))

手动操作

我的意思是,当你得到尖锐的几何形状时,相邻法线的平均长度不再是1,所以最后你并没有把顶点偏移到你想要的距离。我认为你应该计算相邻的法线之和,然后归一化这些矢量来得到每个顶点的法线。如果你有三个以上的三角形连接到每个顶点(这是一般情况)你还需要通过三角形的连接角对相邻法线进行加权求和...

或使用python模块

你也可以pymadcad有一个函数,做正是我所说的:

from madcad import *

surface = Mesh([points, ...], [triangles, ...])
my_thick_mesh = thicken(surface, distance)

关于此问题有3个函数:

*inflateoffsets给出所需的偏移向量
*inflate偏移网格曲面
*加厚创建封套

  • 原始表面
  • 偏移表面
  • 所述侧面
lb3vh1jj

lb3vh1jj2#

网格的光栅化是一种最有效的等距方法,即先用带符号的距离填充体素,然后用所需的等距构造等值面,但这种方法有一定的局限性:要用signed距离填充体素,输入网格必须是闭合的。无论如何,你可以制作导致外壳偏移的无符号体素(对于非闭合曲面)。
该方法的一般优点是可以处理自相交网格。
在开源MeshLib库中有一个使用openvdb的C++实现,该库包含python模块。因此,您可以使用以下代码:

from meshlib import mrmeshpy

# load closed mesh

expClosedMesh = mrmeshpy.loadMesh("closedMesh.stl")
assert (expClosedMesh.has_value())

# load non-closed mesh

expNonClosedMesh = mrmeshpy.loadMesh("nonClosedMesh.stl")
assert (expNonClosedMesh.has_value())

# setup offset parameters

params = mrmeshpy.OffsetParameters()
params.voxelSize = 0.04
params.type = mrmeshpy.OffsetParametersType.Offset # requires closed mesh

# create positive offset mesh

expPosOffset = mrmeshpy.offsetMesh(expClosedMesh.value(),0.2,params)
assert (expPosOffset.has_value())

# create negative offset mesh

expNegOffset = mrmeshpy.offsetMesh(expClosedMesh.value(),-0.1,params)
assert (expNegOffset.has_value())

# change offset mode to `Shell`

params.type = mrmeshpy.OffsetParametersType.Shell # does not require closed mesh

# create shell mesh

expShell = mrmeshpy.offsetMesh(expNonClosedMesh.value(),0.1,params)
assert (expShell.has_value())

# save results

assert (mrmeshpy.saveMesh(expPosOffset.value(),"posOffset.stl").has_value())
assert (mrmeshpy.saveMesh(expNegOffset.value(),"negOffset.stl").has_value())
assert (mrmeshpy.saveMesh(expShell.value(),"shell.stl").has_value())

闭合网格.stl

位置偏移量.stl

负偏移量.stl

非闭合网格.stl

外壳.stl


指令集

相关问题