Skip to content

Instantly share code, notes, and snippets.

@pmav99
Last active August 2, 2022 07:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pmav99/5ded91f18ef096b080b2ed45598c7d1c to your computer and use it in GitHub Desktop.
Save pmav99/5ded91f18ef096b080b2ed45598c7d1c to your computer and use it in GitHub Desktop.
Split quads using numpy

image

image

import numpy as np

face_nodes = np.array([
    [1, 2, 6, np.nan],
    [1, 6, 5, np.nan],
    [2, 3, 7, 6],
    [3, 4, 7, np.nan],
    [4, 8, 7, np.nan],
    [5, 6, 9, np.nan],
    [6, 10, 9, np.nan],
    [6, 7, 11, 10],
    [7, 8, 12, np.nan],
    [7, 12, 11, np.nan],
])

def split_quads(face_nodes: np.array) -> np.array:
    # We assume that the nans only exist in the last column
    # Therefore the first 3 columns are the existing triangles
    existing_triangles = face_nodes[:, :3]

    # Identify the quads. They are the rows with nan in the last column
    # The nonzero() function is a speed optimization. With this, we only keep 
    # the index  values we care about, instead of the whole boolean array
    quad_indexes = np.nonzero(~np.isnan(face_nodes).any(axis=1))
    quads = face_nodes[quad_indexes]

    # Extract the first and the last two columns of the quads
    quads_first_column = quads[:, 0]
    quads_last_two_columns = quads[:, -2:]

    # Create the new triangles by concatenating the extracted columns
    new_triangles = np.c_[quads_first_column, quads_last_two_columns]

    # append new triangles to the existing ones
    new_face_nodes = np.r_[existing_triangles, new_triangles]
    return new_face_nodes
    
def split_quads_concise(face_nodes: np.array) -> np.array:
    quad_indexes = np.nonzero(~np.isnan(face_nodes).any(axis=1))
    quads = face_nodes[quad_indexes]
    return np.r_[
        face_nodes[:, :3],  # existing triangles
        np.c_[              # new triangles
            quads[:, 0],        # first column
            quads[:, -2:],      # last two columns
        ],
    ]

split = split_quads(face_nodes)
split

results in

array([[ 1.,  2.,  6.],
       [ 1.,  6.,  5.],
       [ 2.,  3.,  7.],
       [ 3.,  4.,  7.],
       [ 4.,  8.,  7.],
       [ 5.,  6.,  9.],
       [ 6., 10.,  9.],
       [ 6.,  7., 11.],
       [ 7.,  8., 12.],
       [ 7., 12., 11.],
       [ 2.,  7.,  6.],
       [ 6., 11., 10.]])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment