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.]])