簡體   English   中英

在 PyVista 中擠出一個凹的復雜多邊形

[英]Extrude a concave, complex polygon in PyVista

我希望采用凹形和復雜(包含孔)多邊形並將其“垂直”擠壓成多面體,純粹是為了可視化。 我從一個勻稱的Polygon開始,如下所示:

poly = Polygon(
    [(0,0), (10,0), (10,10), (5,8), (0,10), (1,7), (0,5), (1,3)], 
    holes=[
        [(2,2),(4,2),(4,4),(2,4)],
        [(6,6), (7,6), (6.5,6.5), (7,7), (6,7), (6.2,6.5)]])

我在 matplotlib 中正確地將 plot(將外部坐標重新定向為順時針,並將孔坐標重新定向為逆時針)為:

在此處輸入圖像描述

然后,我試圖使用PyVista將這個多邊形渲染到頁面外(沿着z )。 有一些障礙; PyVista 不直接支持其PolyData類型的凹凸輸入。 所以我們首先創建一個簡單(無孔)凸多邊形的擠壓:

def extrude_simple_polygon(xy, z0, z1):

    # force counter-clockwise ordering, so PyVista interprets polygon correctly
    xy = _reorient_coords(xy, clockwise=False)

    # remove duplication of first & last vertex
    xyz0 = [(x,y,z0) for x,y in xy]
    if (xyz0[0] == xyz0[-1]):
        xyz0.pop()

    # use delaunay, as per https://github.com/pyvista/pyvista/discussions/2398
    base_vert = [len(xyz0)] + list(range(len(xyz0)))
    base_data = pyvista.PolyData(xyz0, base_vert)
    base_mesh = base_data.delaunay_2d(edge_source=base_data)
    vol_mesh  = base_mesh.extrude((0, 0, z1-z0), capping=True)

    # force triangulation, so PyVista allows boolean_difference
    return vol_mesh.triangulate()

當依次擠壓外部多邊形及其每個內部多邊形時,請觀察此方法:

extrude_simple_polygon(list(poly.exterior.coords), 0, 5).plot()

在此處輸入圖像描述

extrude_simple_polygon(list(poly.interiors[0].coords), 0, 5).plot()
extrude_simple_polygon(list(poly.interiors[1].coords), 0, 5).plot()

在此處輸入圖像描述 在此處輸入圖像描述

我推斷要創建原始復雜多邊形的擠壓,我可以計算boolean_difference 唉,結果

outer_vol = extrude_simple_polygon(list(poly.exterior.coords), 0, 5)
for hole in poly.interiors:
    hole_vol = extrude_simple_polygon(list(hole.coords), 0, 5)
    outer_vol = outer_vol.boolean_difference(hole_vol)

outer_vol.plot()

是錯誤的:

在此處輸入圖像描述

該文檔建議通過plot_normals檢查法線,揭示所有擠壓體積都有向內指向(或者,意外的)法線:

在此處輸入圖像描述 在此處輸入圖像描述 在此處輸入圖像描述

extrude文檔沒有提及擠出表面法線或原始 object(在本例中為多邊形)方向。

我們可以原諒我們期望我們的多邊形必須是clockwise ,所以我們在extrude_simple_polygon的第一行設置clockwise=True並重試。 唉, PolyData現在誤解了我們的基本多邊形; 調用base_mesh.plot()顯示(應該看起來像我們原來的藍色外多邊形):

在此處輸入圖像描述

帶擠壓

在此處輸入圖像描述

  • PyVista 是否總是期望逆時針多邊形?
  • 為什么拉伸會創建具有向內指向的表面法線的體積?
  • 如何修正擠出的表面法線?
  • 否則,我怎樣才能讓 PyVista 正確地可視化應該是一個令人難以置信的簡單擠壓凸復雜多邊形?

你非常接近。 您需要做的是對delaunay_2d()進行一次調用,將所有三個多邊形(即封閉的一個和兩個孔)作為邊源(循環源?)。 每個多邊形都有面(而不是線)也很重要; 這就是可以加強孔洞的多孔性的原因。

這是您輸入的完整示例(我手動翻轉了孔的方向;您似乎有一個_reorient_coords()助手,您應該改用):

import pyvista as pv

# coordinates of enclosing polygon
poly_points = [
    (0, 0), (10, 0), (10, 10), (5, 8), (0, 10), (1, 7), (0, 5), (1, 3),
]
# hole point order hard-coded here; use your _reorient_coords() function
holes = [
    [(2, 2), (4, 2), (4, 4), (2, 4)][::-1],
    [(6, 6), (7, 6), (6.5, 6.5), (7, 7), (6, 7), (6.2, 6.5)][::-1],
]

z0, z1 = 0.0, 5.0

def points_2d_to_poly(points, z):
    """Convert a sequence of 2d coordinates to a polydata with a polygon."""
    faces = [len(points) + 1, *range(len(points)), 0]
    poly = pv.PolyData([p + (z,) for p in points], faces=faces)
    return poly

# bounding polygon
polygon = points_2d_to_poly(poly_points, z0)

# add all holes
for hole_points in holes:
    polygon += points_2d_to_poly(hole_points, z0)

# triangulate poly with all three subpolygons supplying edges
# (relative face orientation is critical here)
polygon_with_holes = polygon.delaunay_2d(edge_source=polygon)

# extrude
holey_solid = polygon_with_holes.extrude((0, 0, z1 - z0), capping=True)
holey_solid.plot()

預期擠壓“體積”的透視圖截圖

這是多邊形預擠壓的頂視圖:

plotter = pv.Plotter()
plotter.add_mesh(polygon_with_holes, show_edges=True, color='cyan')
plotter.view_xy()
plotter.show()

多邊形的頂視圖顯示預期的孔,以及其他地方的三角測量邊緣

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM