def get_multipolygon(self, zmin: Optional[float]=None, zmax: Optional[float]=None) -> MultiPolygon:
    'Calculate multipolygon covering mesh elements (hull)\n\n        Parameters\n        ----------\n        zmin : float or None\n            Minimum elevation to consider for multipolygon extraction\n        zmax : float or None\n            Maximum elevation to consider for multipolygon extraction\n\n        Returns\n        -------\n        MultiPolygon\n            Calculated multipolygon shape\n        '
    values = self.msh_t.value
    mask = np.ones(values.shape)
    if (zmin is not None):
        mask = np.logical_and(mask, (values > zmin))
    if (zmax is not None):
        mask = np.logical_and(mask, (values < zmax))
    verts_in = np.argwhere(mask).ravel()
    clipped_mesh = utils.clip_mesh_by_vertex(self.msh_t, verts_in, can_use_other_verts=True)
    boundary_edges = utils.get_boundary_edges(clipped_mesh)
    coords = clipped_mesh.vert2['coord']
    coo_to_idx = {tuple(coo): idx for (idx, coo) in enumerate(coords)}
    poly_gen = polygonize(coords[boundary_edges])
    polys = list(poly_gen)
    polys = sorted(polys, key=(lambda p: p.area), reverse=True)
    rings = [p.exterior for p in polys]
    n_parents = np.zeros((len(rings),))
    represent = np.array([r.coords[0] for r in rings])
    for (e, ring) in enumerate(rings[:(- 1)]):
        path = Path(ring.coords, closed=True)
        n_parents = (n_parents + np.pad(np.array([path.contains_point(pt) for pt in represent[(e + 1):]]), ((e + 1), 0), 'constant', constant_values=0))
    polys = [p for (e, p) in enumerate(polys) if (not (n_parents[e] % 2))]
    return MultiPolygon(polys)
Calculate multipolygon covering mesh elements (hull)

Parameters
----------
zmin : float or None
    Minimum elevation to consider for multipolygon extraction
zmax : float or None
    Maximum elevation to consider for multipolygon extraction

Returns
-------
MultiPolygon
    Calculated multipolygon shape
def get_multipolygon(self, zmin: Optional[float]=None, zmax: Optional[float]=None) -> MultiPolygon:
    'Calculate multipolygon covering mesh elements (hull)\n\n        Parameters\n        ----------\n        zmin : float or None\n            Minimum elevation to consider for multipolygon extraction\n        zmax : float or None\n            Maximum elevation to consider for multipolygon extraction\n\n        Returns\n        -------\n        MultiPolygon\n            Calculated multipolygon shape\n        '
    values = self.msh_t.value
    mask = np.ones(values.shape)
    if (zmin is not None):
        mask = np.logical_and(mask, (values > zmin))
    if (zmax is not None):
        mask = np.logical_and(mask, (values < zmax))
    verts_in = np.argwhere(mask).ravel()
    clipped_mesh = utils.clip_mesh_by_vertex(self.msh_t, verts_in, can_use_other_verts=True)
    boundary_edges = utils.get_boundary_edges(clipped_mesh)
    coords = clipped_mesh.vert2['coord']
    coo_to_idx = {tuple(coo): idx for (idx, coo) in enumerate(coords)}
    poly_gen = polygonize(coords[boundary_edges])
    polys = list(poly_gen)
    polys = sorted(polys, key=(lambda p: p.area), reverse=True)
    rings = [p.exterior for p in polys]
    n_parents = np.zeros((len(rings),))
    represent = np.array([r.coords[0] for r in rings])
    for (e, ring) in enumerate(rings[:(- 1)]):
        path = Path(ring.coords, closed=True)
        n_parents = (n_parents + np.pad(np.array([path.contains_point(pt) for pt in represent[(e + 1):]]), ((e + 1), 0), 'constant', constant_values=0))
    polys = [p for (e, p) in enumerate(polys) if (not (n_parents[e] % 2))]
    return MultiPolygon(polys)