<commit_before>from typing import Dict, Optional, Tuple

import pygmsh

from gdsfactory.pdk import get_layer_stack
from gdsfactory.tech import LayerStack
from gdsfactory.types import ComponentOrReference, Layer


def surface_loop_from_vertices(model, xmin, xmax, ymin, ymax, zmin, zmax, resolution):
    """Returns surface loop of prism from bounding box.

    Args:
        xmin: minimal x-value for bounding box
        xmax: maximal x-value for bounding box
        ymin: minimal y-value for bounding box
        ymax: maximal y-value for bounding box
        zmin: minimal z-value for bounding box
        zmax: maximal z-value for bounding box

    """
    channel_surfaces = []
    for coords in [
        [
            [xmin, ymin, zmin],
            [xmin, ymin, zmax],
            [xmin, ymax, zmax],
            [xmin, ymax, zmin],
        ],
        [
            [xmax, ymin, zmin],
            [xmax, ymin, zmax],
            [xmax, ymax, zmax],
            [xmax, ymax, zmin],
        ],
        [
            [xmax, ymin, zmin],
            [xmax, ymin, zmax],
            [xmin, ymin, zmax],
            [xmin, ymin, zmin],
        ],
        [
            [xmax, ymax, zmin],
            [xmax, ymax, zmax],
            [xmin, ymax, zmax],
            [xmin, ymax, zmin],
        ],
        [
            [xmin, ymin, zmin],
            [xmin, ymax, zmin],
            [xmax, ymax, zmin],
            [xmax, ymin, zmin],
        ],
        [
            [xmin, ymin, zmax],
            [xmin, ymax, zmax],
            [xmax, ymax, zmax],
            [xmax, ymin, zmax],
        ],
    ]:
        points = [model.add_point(coord, mesh_size=resolution) for coord in coords]
        channel_lines = [
            model.add_line(points[i], points[i + 1]) for i in range(-1, len(points) - 1)
        ]
        channel_loop = model.add_curve_loop(channel_lines)
        channel_surfaces.append(model.add_plane_surface(channel_loop))
    surface_loop = model.add_surface_loop(channel_surfaces)
    return channel_surfaces, surface_loop


def mesh3D(
    component: ComponentOrReference,
    base_resolution: float = 0.2,
    refine_resolution: Optional[Dict[Layer, float]] = None,
    padding: Tuple[float, float, float, float, float, float] = (
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
    ),
    layer_stack: Optional[LayerStack] = None,
    exclude_layers: Optional[Tuple[Layer, ...]] = None,
):
    """Returns gmsh 3D geometry of component.

    Similar to component.to_3d(), but returns a gmsh mesh with:
    - layer-dependent mesh resolution
    - different physical blocks for different objects
    - sub-object labels for introduction in physical solvers (e.g. edges)

    Args:
        component: Component or ComponentReference.
        base_resolution: background mesh resolution (um).
        refine_resolution: feature mesh resolution (um); layer dependent via a dict (default to base_resolution).
        padding: amount (west, east, south, north, down, up) to enlarge simulation region beyond features (um).

    """
    layer_stack = layer_stack or get_layer_stack()
    layer_to_thickness = layer_stack.get_layer_to_thickness()
    layer_to_zmin = layer_stack.get_layer_to_zmin()
    exclude_layers = exclude_layers or ()

    geometry = pygmsh.occ.geometry.Geometry()

    model = geometry.__enter__()

    zmin_cell = 0  # np.inf
    zmax_cell = 1.22  # -np.inf

    bbox = component.bbox
    xmin_cell = bbox[0][0] - padding[0]
    ymin_cell = bbox[0][1] - padding[2]
    xmax_cell = bbox[1][0] + padding[1]
    ymax_cell = bbox[1][1] + padding[3]

    # Create element resolution dict
    refine_dict = {
        layer: refine_resolution[layer]
        if layer in refine_resolution.keys()
        else base_resolution
        for layer in component.get_layers()
    }

    # Features
    # blocks = []
    for layer, polygons in component.get_polygons(by_spec=True).items():
        if (
            layer not in exclude_layers
            and layer in layer_to_thickness
            and layer in layer_to_zmin
        ):
            height = layer_to_thickness[layer]
            zmin_layer = layer_to_zmin[layer]
            zmax_layer = zmin_layer + height

            if zmin_layer < zmin_cell:<commit_msg>fix pre-commit<commit_after>from typing import Dict, Optional, Tuple

import pygmsh

from gdsfactory.pdk import get_layer_stack
from gdsfactory.tech import LayerStack
from gdsfactory.types import ComponentOrReference, Layer


def surface_loop_from_vertices(model, xmin, xmax, ymin, ymax, zmin, zmax, resolution):
    """Returns surface loop of prism from bounding box.

    Args:
        xmin: minimal x-value for bounding box
        xmax: maximal x-value for bounding box
        ymin: minimal y-value for bounding box
        ymax: maximal y-value for bounding box
        zmin: minimal z-value for bounding box
        zmax: maximal z-value for bounding box

    """
    channel_surfaces = []
    for coords in [
        [
            [xmin, ymin, zmin],
            [xmin, ymin, zmax],
            [xmin, ymax, zmax],
            [xmin, ymax, zmin],
        ],
        [
            [xmax, ymin, zmin],
            [xmax, ymin, zmax],
            [xmax, ymax, zmax],
            [xmax, ymax, zmin],
        ],
        [
            [xmax, ymin, zmin],
            [xmax, ymin, zmax],
            [xmin, ymin, zmax],
            [xmin, ymin, zmin],
        ],
        [
            [xmax, ymax, zmin],
            [xmax, ymax, zmax],
            [xmin, ymax, zmax],
            [xmin, ymax, zmin],
        ],
        [
            [xmin, ymin, zmin],
            [xmin, ymax, zmin],
            [xmax, ymax, zmin],
            [xmax, ymin, zmin],
        ],
        [
            [xmin, ymin, zmax],
            [xmin, ymax, zmax],
            [xmax, ymax, zmax],
            [xmax, ymin, zmax],
        ],
    ]:
        points = [model.add_point(coord, mesh_size=resolution) for coord in coords]
        channel_lines = [
            model.add_line(points[i], points[i + 1]) for i in range(-1, len(points) - 1)
        ]
        channel_loop = model.add_curve_loop(channel_lines)
        channel_surfaces.append(model.add_plane_surface(channel_loop))
    surface_loop = model.add_surface_loop(channel_surfaces)
    return channel_surfaces, surface_loop


def mesh3D(
    component: ComponentOrReference,
    base_resolution: float = 0.2,
    refine_resolution: Optional[Dict[Layer, float]] = None,
    padding: Tuple[float, float, float, float, float, float] = (
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
    ),
    layer_stack: Optional[LayerStack] = None,
    exclude_layers: Optional[Tuple[Layer, ...]] = None,
):
    """Returns gmsh 3D geometry of component.

    Similar to component.to_3d(), but returns a gmsh mesh with:
    - layer-dependent mesh resolution
    - different physical blocks for different objects
    - sub-object labels for introduction in physical solvers (e.g. edges)

    Args:
        component: Component or ComponentReference.
        base_resolution: background mesh resolution (um).
        refine_resolution: feature mesh resolution (um); layer dependent via a dict (default to base_resolution).
        padding: amount (west, east, south, north, down, up) to enlarge simulation region beyond features (um).

    """
    layer_stack = layer_stack or get_layer_stack()
    layer_to_thickness = layer_stack.get_layer_to_thickness()
    layer_to_zmin = layer_stack.get_layer_to_zmin()
    exclude_layers = exclude_layers or ()

    geometry = pygmsh.occ.geometry.Geometry()

    model = geometry.__enter__()

    zmin_cell = 0  # np.inf
    zmax_cell = 1.22  # -np.inf

    bbox = component.bbox
    xmin_cell = bbox[0][0] - padding[0]
    ymin_cell = bbox[0][1] - padding[2]
    xmax_cell = bbox[1][0] + padding[1]
    ymax_cell = bbox[1][1] + padding[3]

    # Create element resolution dict
    # refine_dict = {
    #     layer: refine_resolution[layer]
    #     if layer in refine_resolution.keys()
    #     else base_resolution
    #     for layer in component.get_layers()
    # }

    # Features
    # blocks = []
    for layer, polygons in component.get_polygons(by_spec=True).items():
        if (
            layer not in exclude_layers
            and layer in layer_to_thickness
            and layer in layer_to_zmin
        ):
            height = layer_to_thickness[layer]
            zmin_layer = layer_to_zmin[layer]
            zmax_layer = zmin_layer + height

            if zmin_layer < zmin_cell:
{'fraction_non_alphanumeric': 0.1020646214860609, 'fraction_numerical': 0.008398460282281582, 'mean_word_length': 2.1212231525300327, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2640685', 'n_tokens_mistral': 2804, 'n_tokens_neox': 2702, 'n_words': 718}