def triangle_strips_to_faces(strips):
    """
    Given a sequence of triangle strips, convert them to (n,3) faces.

    Processes all strips at once using np.concatenate and is significantly
    faster than loop- based methods.

    From the OpenGL programming guide describing a single triangle
    strip [v0, v1, v2, v3, v4]:

    Draws a series of triangles (three-sided polygons) using vertices
    v0, v1, v2, then v2, v1, v3  (note the order), then v2, v3, v4,
    and so on. The ordering is to ensure that the triangles are all
    drawn with the same orientation so that the strip can correctly form
    part of a surface.

    Parameters
    ------------
    strips: (n,) list of (m,) int vertex indices

    Returns
    ------------
    faces: (m,3) int, vertex indices representing triangles
    """

    # save the length of each list in the list of lists
    lengths = np.array([len(i) for i in strips])
    # looping through a list of lists is extremely slow
    # combine all the sequences into a blob we can manipulate
    blob = np.concatenate(strips)

    # preallocate and slice the blob into rough triangles
    tri = np.zeros((len(blob) - 2, 3), dtype=np.int)
    for i in range(3):
        tri[:len(blob) - 3, i] = blob[i:-3 + i]
    # the last triangle is left off from the slicing, add it back
    tri[-1] = blob[-3:]

    # remove the triangles which were implicit but not actually there
    # because we combined everything into one big array for speed
    length_index = np.cumsum(lengths)[:-1]
    keep = np.ones(len(tri), dtype=np.bool)
    keep[length_index - 2] = False
    keep[length_index - 1] = False
    tri = tri[keep]

    # flip every other triangle so they generate correct normals/winding
    length_index = np.append(0, np.cumsum(lengths - 2))
    flip = np.zeros(length_index[-1], dtype=np.bool)
    for i in range(len(length_index) - 1):
        flip[length_index[i] + 1:length_index[i + 1]][::2] = True
    tri[flip] = np.fliplr(tri[flip])

    return tri
def triangle_strips_to_faces ( strips ) : lengths = np . array ( [ len ( i ) for i in strips ] ) blob = np . concatenate ( strips ) tri = np . zeros ( ( len ( blob ) - 2 , 3 ) , dtype = np . int ) for i in range ( 3 ) : tri [ : len ( blob ) - 3 , i ] = blob [ i : - 3 + i ] tri [ - 1 ] = blob [ - 3 : ] length_index = np . cumsum ( lengths ) [ : - 1 ] keep = np . ones ( len ( tri ) , dtype = np . bool ) keep [ length_index - 2 ] = False keep [ length_index - 1 ] = False tri = tri [ keep ] length_index = np . append ( 0 , np . cumsum ( lengths - 2 ) ) flip = np . zeros ( length_index [ - 1 ] , dtype = np . bool ) for i in range ( len ( length_index ) - 1 ) : flip [ length_index [ i ] + 1 : length_index [ i + 1 ] ] [ : : 2 ] = True tri [ flip ] = np . fliplr ( tri [ flip ] ) return tri
Given a sequence of triangle strips, convert them to (n,3) faces.

    Processes all strips at once using np.concatenate and is significantly
    faster than loop- based methods.

    From the OpenGL programming guide describing a single triangle
    strip [v0, v1, v2, v3, v4]:

    Draws a series of triangles (three-sided polygons) using vertices
    v0, v1, v2, then v2, v1, v3  (note the order), then v2, v3, v4,
    and so on. The ordering is to ensure that the triangles are all
    drawn with the same orientation so that the strip can correctly form
    part of a surface.

    Parameters
    ------------
    strips: (n,) list of (m,) int vertex indices

    Returns
    ------------
    faces: (m,3) int, vertex indices representing triangles