Source code for gcs.triangulation

from __future__ import annotations

from typing import TYPE_CHECKING
import numpy as np
import mapbox_earcut as earcut


if TYPE_CHECKING:
    import gcs


[docs]def triangulate(shape: gcs.GCS) -> np.ndarray: """Triangulates a GCS. Parameters ---------- shape : gcs.GCS The GCS. Returns ------- faces : (N, 3) np.ndarray The faces. Examples -------- >>> shape = gcs.GCS(...) >>> faces = gcs.triangulate(shape=shape) >>> shape = gcs.GCS(...) >>> faces = gcs.faces """ triangulate_faces = shape.parameters['triangulate_faces'] vertices = shape.vertices parameters = shape.parameters n_steps = parameters['n_steps'] n_vertices_per_step = vertices.shape[0] // n_steps n_faces = 2 * n_vertices_per_step * (n_steps - 1) faces = np.zeros((n_faces, 3), dtype=np.int32) for step in range(n_steps - 1): offset = step * n_vertices_per_step for vertex_index in range(n_vertices_per_step): # bottom right vertex index index_br = offset + vertex_index # bottom left vertex index index_bl = index_br - 1 if vertex_index == 0: index_bl += n_vertices_per_step # top right vertex index index_tr = index_br + n_vertices_per_step # top left vertex index index_tl = index_tr - 1 if vertex_index == 0: index_tl += n_vertices_per_step # lower triangle lower_triangle = np.array([index_br, index_tl, index_bl]) lower_triangle_index = offset + vertex_index faces[lower_triangle_index, :] = lower_triangle # upper triangle upper_triangle = np.array([index_br, index_tr, index_tl]) upper_triangle_index = lower_triangle_index + \ n_vertices_per_step * (n_steps - 1) faces[upper_triangle_index, :] = upper_triangle if triangulate_faces: base_vertices = vertices[:n_vertices_per_step:, :2] top_vertices = vertices[-n_vertices_per_step:, :2] # from mapbox_earcut: # An array of end-indices for each ring (1st ring is outer contour of the polygon). rings = np.array([n_vertices_per_step]) triangles_indices_base = earcut.triangulate_float32(base_vertices, rings) triangles_indices_top = earcut.triangulate_float32(top_vertices, rings) # offset top indices to correct indices triangles_indices_top = triangles_indices_top + (vertices.shape[0] - n_vertices_per_step) faces_base = triangles_indices_base.reshape(-1, 3) faces_top = triangles_indices_top.reshape(-1, 3) # Flip order of base vertices for outward facing normals faces_base = np.fliplr(m=faces_base) faces = np.vstack((faces, faces_base, faces_top)) return faces