How do I create a custom constrained delaunay diagram in pyvista with a hole boundary inside the mesh?

409 Views Asked by At

I am working on a manual implementation of Ruppert's algorithm for my final project. The algorithm requires a constrained delaunay diagram as an input, which PyVista can produce by using the delaunay_2d() function. However, I am finding some inconsistency between how they managed to produce a mesh with hollowed out shapes inside, while I am unable to make my own custom inputs that achieve the same results.

For some context, here is the documentation on delaunay_2d() in PyVista: https://docs.pyvista.org/api/core/_autosummary/pyvista.PolyData.delaunay_2d.html

The code and image of the final example of this page, modified slightly for my own purposes (I turned the circles into squares), is shown below:

import pyvista as pv

squar = pv.Polygon(n_sides=4, radius=8, fill=False)
squar = squar.rotate_z(45, inplace=False)
hole1 = pv.Polygon(center=(2,3,0), n_sides=4, radius=1)
hole2 = pv.Polygon(center=(-2,-3,-0), n_sides=4, radius=0.5)
comb = hole1 + hole2 + squar
comb.plot(cpos='xy',show_edges=True)
tess = comb.delaunay_2d(edge_source=comb)
tess.plot(cpos='xy', show_edges=True)

The plot of comb, before the triangulation

The resulting constrained delaunay diagram

I tried to implement my own custom edge constraints as follows:

points1 = [[1,0,0],[1,1,0],[0,1,0],[0,0,0]]
points2 = [[0.25,0.5,0],[0.25,0.25,0],[0.5,0.25,0],[0.5,0.5,0]]

faces2 = [4, 0, 1, 2, 3]

lines1 = [5, 0, 1, 2, 3, 0]
lines2 = [5, 0, 1, 2, 3, 0]

rect1 = pv.PolyData(points1, lines=lines1)
rect2 = pv.PolyData(points2, faces2, lines=lines2)

PSLG = rect2 + rect1
PSLG.plot(cpos='xy', show_edges=True)

tess = PSLG.delaunay_2d(edge_source=PSLG)
tess.plot(cpos='xy', show_edges=True)

The plot of the PSLG constraints

The resulting constrained delaunay diagram

For some reason, my input does not recognize the inside square as a hole and it only uses the outer edges for the delaunay diagram. I am unsure why this is the case as from my understanding, I should have followed how the API example performed the operation to the letter. Please let me know if you have any insight to this matter.

1

There are 1 best solutions below

0
On

Gary Lucas pointed out how other APIs use the order of the polygon to indicate "enclosing" or "excluding." For PyVista, apparently that order is determined by the input given to the face.

In this case, reversing the face input to [4, 0, 3, 2, 1] is sufficient.

The result after reversing the point order of the face I wish to exclude