def triangulation(e, i):
    vertices = []
    holes = []
    segments = []
    index_point = 0
    #-- Slope computation points
    a = [[], [], []]
    b = [[], [], []]
    for ip in range(len(e)-1):
        vertices.append(e[ip])
        if a == [[], [], []] and index_point == 0:
            a = [e[ip][0], e[ip][1], e[ip][2]]
        if index_point > 0 and (e[ip] != e[ip-1]):
            if b == [[], [], []]:
                b = [e[ip][0], e[ip][1], e[ip][2]]
        if ip == len(e) - 2:
            segments.append([index_point, 0])
        else:
            segments.append([index_point, index_point+1])
        index_point += 1
    for hole in i:
        first_point_in_hole = index_point
        for p in range(len(hole)-1):
            if p == len(hole)-2:
                segments.append([index_point, first_point_in_hole])
            else:
                segments.append([index_point, index_point+1])
            index_point += 1
            vertices.append(hole[p])
        #-- A more robust way to get the point inside the hole, should work for non-convex interior polygons
        holes.append(point_inside(hole[:-1]))
        #-- Alternative, use centroid
        # holes.append(centroid(hole[:-1]))

    #-- Project to 2D since the triangulation cannot be done in 3D with the library that is used
    npolypoints = len(vertices)
    nholes = len(holes)
    #-- Check if the polygon is vertical, i.e. a projection cannot be made.
    #-- First copy the list so the originals are not modified
    temppolypoints = copy.deepcopy(vertices)
    newpolypoints = copy.deepcopy(vertices)
    tempholes = copy.deepcopy(holes)
    newholes = copy.deepcopy(holes)
    #-- Compute the normal of the polygon for detecting vertical polygons and
    #-- for the correct orientation of the new triangulated faces
    #-- If the polygon is vertical
    normal = unit_normal(temppolypoints[0], temppolypoints[1], temppolypoints[2])
    if math.fabs(normal[2]) < 10e-2:
        vertical = True
    else:
        vertical = False
    #-- We want to project the vertical polygon to the XZ plane
    #-- If a polygon is parallel with the YZ plane that will not be possible
    YZ = True
    for i in range(1, npolypoints):
        if temppolypoints[i][0] != temppolypoints[0][0]:
            YZ = False
            continue
    #-- Project the plane in the special case
    if YZ:
        for i in range(0, npolypoints):
            newpolypoints[i][0] = temppolypoints[i][1]
            newpolypoints[i][1] = temppolypoints[i][2]
        for i in range(0, nholes):
            newholes[i][0] = tempholes[i][1]
            newholes[i][1] = tempholes[i][2]
    #-- Project the plane
    elif vertical:
        for i in range(0, npolypoints):
            newpolypoints[i][1] = temppolypoints[i][2]
        for i in range(0, nholes):
            newholes[i][1] = tempholes[i][2]
    else:
        pass #-- No changes here

    #-- Drop the last point (identical to first)
    for p in newpolypoints:
        p.pop(-1)

    #-- If there are no holes
    if len(newholes) == 0:
        newholes = None
    else:
        for h in newholes:
            h.pop(-1)

    #-- Plane information (assumes planarity)
    a = e[0]
    b = e[1]
    c = e[2]
    #-- Construct the plane
    pl = plane(a, b, c)
 
    #-- Prepare the polygon to be triangulated
    poly = {'vertices' : np.array(newpolypoints), 'segments' : np.array(segments), 'holes' : np.array(newholes)}
    # print poly
    #-- Triangulate
    t = triangle.triangulate(poly, "pQjz")
    #-- Get the triangles and their vertices
    tris = t['triangles']
    vert = t['vertices'].tolist()
    #-- Store the vertices of each triangle in a list
    tri_points = []
    for tri in tris:
        tri_points_tmp = []
        for v in tri.tolist():
            vert_adj = [[], [], []]
            if YZ:
                vert_adj[0] = temppolypoints[0][0]
                vert_adj[1] = vert[v][0]
                vert_adj[2] = vert[v][1]
            elif vertical:
                vert_adj[0] = vert[v][0]            
                vert_adj[2] = vert[v][1]
                vert_adj[1] = get_y(pl, vert_adj[0], vert_adj[2])
            else:
                vert_adj[0] = vert[v][0]
                vert_adj[1] = vert[v][1]
                vert_adj[2] = get_height(pl, vert_adj[0], vert_adj[1])
            tri_points_tmp.append(vert_adj)
            try:
                tri_normal = unit_normal(tri_points_tmp[0], tri_points_tmp[1], tri_points_tmp[2])
            except:
                continue
            if compare_normals(normal, tri_normal):
                tri_points.append(tri_points_tmp)
            else:
                tri_points_tmp = reverse_vertices(tri_points_tmp)
                tri_points.append(tri_points_tmp)
    return tri_points
Triangulate the polygon with the exterior and interior list of points. Works only for convex polygons.
dataset/ETHPy150Open tudelft3d/CityGML2OBJs/polygon3dmodule.py/triangulation