Пример #1
0
 def sphere(self,
            center,
            color,
            scale,
            opacity=1.0,
            resolution=8,
            backface_culling=False,
            radius=None):
     factor = 1.0 if radius is not None else scale
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore", category=FutureWarning)
         sphere = vtk.vtkSphereSource()
         sphere.SetThetaResolution(resolution)
         sphere.SetPhiResolution(resolution)
         if radius is not None:
             sphere.SetRadius(radius)
         sphere.Update()
         geom = sphere.GetOutput()
         mesh = PolyData(np.array(center))
         glyph = mesh.glyph(orient=False,
                            scale=False,
                            factor=factor,
                            geom=geom)
         actor = _add_mesh(self.plotter,
                           mesh=glyph,
                           color=color,
                           opacity=opacity,
                           backface_culling=backface_culling,
                           smooth_shading=self.figure.smooth_shading)
         return actor, glyph
Пример #2
0
 def contour(self,
             surface,
             scalars,
             contours,
             line_width=1.0,
             opacity=1.0,
             vmin=None,
             vmax=None,
             colormap=None,
             normalized_colormap=False):
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore", category=FutureWarning)
         from pyvista import PolyData
         cmap = _get_colormap_from_array(colormap, normalized_colormap)
         vertices = np.array(surface['rr'])
         triangles = np.array(surface['tris'])
         n_triangles = len(triangles)
         triangles = np.c_[np.full(n_triangles, 3), triangles]
         pd = PolyData(vertices, triangles)
         pd.point_arrays['scalars'] = scalars
         self.plotter.add_mesh(pd.contour(isosurfaces=contours,
                                          rng=(vmin, vmax)),
                               show_scalar_bar=False,
                               line_width=line_width,
                               cmap=cmap,
                               opacity=opacity,
                               smooth_shading=self.figure.smooth_shading)
Пример #3
0
 def sphere(self, center, color, scale, opacity=1.0,
            resolution=8, backface_culling=False,
            radius=None):
     factor = 1.0 if radius is not None else scale
     center = np.array(center, dtype=float)
     if len(center) == 0:
         return None, None
     _check_option('center.ndim', center.ndim, (1, 2))
     _check_option('center.shape[-1]', center.shape[-1], (3,))
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore", category=FutureWarning)
         sphere = vtk.vtkSphereSource()
         sphere.SetThetaResolution(resolution)
         sphere.SetPhiResolution(resolution)
         if radius is not None:
             sphere.SetRadius(radius)
         sphere.Update()
         geom = sphere.GetOutput()
         mesh = PolyData(center)
         glyph = mesh.glyph(orient=False, scale=False,
                            factor=factor, geom=geom)
         actor = _add_mesh(
             self.plotter,
             mesh=glyph, color=color, opacity=opacity,
             backface_culling=backface_culling,
             smooth_shading=self.smooth_shading
         )
         return actor, glyph
Пример #4
0
 def surface(self,
             surface,
             color=None,
             opacity=1.0,
             vmin=None,
             vmax=None,
             colormap=None,
             normalized_colormap=False,
             scalars=None,
             backface_culling=False):
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore", category=FutureWarning)
         cmap = _get_colormap_from_array(colormap, normalized_colormap)
         vertices = np.array(surface['rr'])
         triangles = np.array(surface['tris'])
         n_triangles = len(triangles)
         triangles = np.c_[np.full(n_triangles, 3), triangles]
         mesh = PolyData(vertices, triangles)
         if scalars is not None:
             mesh.point_arrays['scalars'] = scalars
         self.plotter.add_mesh(mesh=mesh,
                               color=color,
                               rng=[vmin, vmax],
                               show_scalar_bar=False,
                               opacity=opacity,
                               cmap=cmap,
                               backface_culling=backface_culling,
                               smooth_shading=self.figure.smooth_shading)
Пример #5
0
 def contour(self,
             surface,
             scalars,
             contours,
             width=1.0,
             opacity=1.0,
             vmin=None,
             vmax=None,
             colormap=None,
             normalized_colormap=False,
             kind='line',
             color=None):
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore", category=FutureWarning)
         if colormap is not None:
             colormap = _get_colormap_from_array(colormap,
                                                 normalized_colormap)
         vertices = np.array(surface['rr'])
         triangles = np.array(surface['tris'])
         n_triangles = len(triangles)
         triangles = np.c_[np.full(n_triangles, 3), triangles]
         mesh = PolyData(vertices, triangles)
         mesh.point_arrays['scalars'] = scalars
         contour = mesh.contour(isosurfaces=contours, rng=(vmin, vmax))
         line_width = width
         if kind == 'tube':
             contour = contour.tube(radius=width)
             line_width = 1.0
         self.plotter.add_mesh(mesh=contour,
                               show_scalar_bar=False,
                               line_width=line_width,
                               color=color,
                               cmap=colormap,
                               opacity=opacity,
                               smooth_shading=self.figure.smooth_shading)
Пример #6
0
 def surface(self, surface, color=None, opacity=1.0,
             vmin=None, vmax=None, colormap=None,
             normalized_colormap=False, scalars=None,
             backface_culling=False, polygon_offset=None):
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore", category=FutureWarning)
         normals = surface.get('nn', None)
         vertices = np.array(surface['rr'])
         triangles = np.array(surface['tris'])
         triangles = np.c_[np.full(len(triangles), 3), triangles]
         mesh = PolyData(vertices, triangles)
     colormap = _get_colormap_from_array(colormap, normalized_colormap)
     if scalars is not None:
         mesh.point_arrays['scalars'] = scalars
     return self.polydata(
         mesh=mesh,
         color=color,
         opacity=opacity,
         normals=normals,
         backface_culling=backface_culling,
         scalars=scalars,
         colormap=colormap,
         vmin=vmin,
         vmax=vmax,
         polygon_offset=polygon_offset,
     )
Пример #7
0
 def mono_centering(data):
     if VERBOSE: print(f"Centering: {data['meta_data']['name']}")
     mesh = data["poly_data"]
     remesh = PolyData(mesh.points.copy(), mesh.faces.copy())
     offset = mesh.center
     remesh.translate(np.zeros_like(offset) - offset)
     return remesh
Пример #8
0
    def __init__(
        self,
        mesh: pv.PolyData,
        meridian: float,
        offset: Optional[float] = None,
    ):
        """
        TODO

        Parameters
        ----------
        mesh
        meridian
        offset

        Notes
        -----
        .. versionadded :: 0.1.0

        """
        # logging convenience
        self._extra = dict(cls=self.__class__.__name__)

        if is_projected(mesh):
            emsg = "Cannot slice mesh that appears to be a planar projection."
            raise ValueError(emsg)

        self._info = mesh.active_scalars_info
        mesh[GV_CELL_IDS] = np.arange(mesh.n_cells)
        mesh[GV_POINT_IDS] = np.arange(mesh.n_points)
        mesh.set_active_scalars(
            self._info.name, preference=self._info.association.name.lower()
        )

        self.mesh = mesh
        # XXX: hack
        self.radius = calculate_radius(mesh, decimals=6)
        self.meridian = wrap(meridian)[0]
        self.offset = abs(CUT_OFFSET if offset is None else offset)
        logger.debug(
            "meridian=%s, offset=%s, radius=%s",
            self.meridian,
            self.offset,
            self.radius,
            extra=self._extra,
        )
        self.slices = {bias.name: self._intersection(bias.value) for bias in SliceBias}

        n_cells = self.slices[CUT_EXACT].n_cells
        self.west_ids = set(self.slices[CUT_WEST][GV_CELL_IDS]) if n_cells else set()
        self.east_ids = set(self.slices[CUT_EAST][GV_CELL_IDS]) if n_cells else set()
        self.split_ids = self.west_ids.intersection(self.east_ids)
        logger.debug(
            "west=%s, east=%s, split=%s",
            len(self.west_ids),
            len(self.east_ids),
            len(self.split_ids),
            extra=self._extra,
        )
Пример #9
0
 def center(self):
     if VERBOSE: print("Centering")
     tmp_mesh = []
     for mesh, full_mesh_stuff in zip(self.history[-1], self.full_data):
         remesh = PolyData(mesh.points.copy(), mesh.faces.copy())
         offset = mesh.center
         remesh.translate(np.zeros_like(offset) - offset)
         tmp_mesh.append(remesh)
     self.history.append(tmp_mesh)
Пример #10
0
def Sphere(radius=0.5, center=(0, 0, 0), direction=(0, 0, 1), theta_resolution=30,
           phi_resolution=30, start_theta=0, end_theta=360, start_phi=0, end_phi=180):
    """
    Create a vtk Sphere

    Parameters
    ----------
    radius : float, optional
        Sphere radius

    center : np.ndarray or list, optional
        Center in [x, y, z]

    direction : list or np.ndarray
        Direction the top of the sphere points to in [x, y, z]

    theta_resolution: int , optional
        Set the number of points in the longitude direction (ranging from
        start_theta to end theta).

    phi_resolution : int, optional
        Set the number of points in the latitude direction (ranging from
        start_phi to end_phi).

    start_theta : float, optional
        Starting longitude angle.

    end_theta : float, optional
        Ending longitude angle.

    start_phi : float, optional
        Starting latitude angle.

    end_phi : float, optional
        Ending latitude angle.

    Returns
    -------
    sphere : pyvista.PolyData
        Sphere mesh.
    """
    sphere = vtk.vtkSphereSource()
    sphere.SetRadius(radius)
    sphere.SetThetaResolution(theta_resolution)
    sphere.SetPhiResolution(phi_resolution)
    sphere.SetStartTheta(start_theta)
    sphere.SetEndTheta(end_theta)
    sphere.SetStartPhi(start_phi)
    sphere.SetEndPhi(end_phi)
    sphere.Update()
    surf = PolyData(sphere.GetOutput())
    surf.rotate_y(-90)
    translate(surf, center, direction)
    return surf
Пример #11
0
def add_texture_coords(
    mesh: pv.PolyData,
    meridian: Optional[float] = None,
    antimeridian: Optional[bool] = False,
) -> pv.PolyData:
    """
    TODO

    Parameters
    ----------
    mesh
    meridian
    antimeridian
    inplace

    Returns
    -------

    Notes
    -----
    .. versionadded:: 0.1.0

    """
    if meridian is None:
        meridian = DEFAULT_MERIDIAN

    if antimeridian:
        meridian += 180

    meridian = wrap(meridian)[0]

    if GV_REMESH_POINT_IDS not in mesh.point_data:
        mesh = cut_along_meridian(mesh, meridian=meridian)
    else:
        mesh = mesh.copy(deep=True)

    # convert from cartesian xyz to spherical lat/lons
    ll = to_xy0(mesh, closed_interval=True)
    lons, lats = ll[:, 0], ll[:, 1]
    # convert to normalised UV space
    u = (lons + 180) / 360
    v = (lats + 90) / 180
    t = np.vstack([u, v]).T
    mesh.active_t_coords = t
    logger.debug(
        "u.min()=%s, u.max()=%s, v.min()=%s, v.max()=%s",
        u.min(),
        u.max(),
        v.min(),
        v.max(),
    )

    return mesh
Пример #12
0
def Cylinder(center=(0., 0., 0.),
             direction=(1., 0., 0.),
             radius=0.5,
             height=1.0,
             resolution=100,
             **kwargs):
    """
    Create the surface of a cylinder.

    Parameters
    ----------
    center : list or np.ndarray
        Location of the centroid in [x, y, z]

    direction : list or np.ndarray
        Direction cylinder points to  in [x, y, z]

    radius : float
        Radius of the cylinder.

    height : float
        Height of the cylinder.

    resolution : int
        Number of points on the circular face of the cylinder.

    capping : bool, optional
        Cap cylinder ends with polygons.  Default True

    Returns
    -------
    cylinder : pyvista.PolyData
        Cylinder surface.

    Examples
    --------
    >>> import pyvista
    >>> import numpy as np
    >>> cylinder = pyvista.Cylinder(np.array([1, 2, 3]), np.array([1, 1, 1]), 1, 1)
    >>> cylinder.plot() # doctest:+SKIP

    """
    capping = kwargs.get('capping', kwargs.get('cap_ends', True))
    cylinderSource = vtk.vtkCylinderSource()
    cylinderSource.SetRadius(radius)
    cylinderSource.SetHeight(height)
    cylinderSource.SetCapping(capping)
    cylinderSource.SetResolution(resolution)
    cylinderSource.Update()
    surf = PolyData(cylinderSource.GetOutput())
    surf.rotate_z(-90)
    translate(surf, center, direction)
    return surf
Пример #13
0
    def clip_horizon_with_faults(
            self,
            horizon: pv.PolyData,
            faults: Iterable[pv.PolyData],
            value: float = None
    ) -> List[pv.PolyData]:
        """Clip given horizon surface with given list of fault surfaces. The
        given value represents the distance to clip away from the fault 
        surfaces.
        
        Args:
            horizon (pv.PolyData): The horizon surface to be clipped.
            faults (Iterable[pv.PolyData]): Fault(s) surface(s) to clip with.
            value (float, optional): Set the clipping value of the implicit 
                function (clipping distance from faults). Defaults to 50.
        
        Returns:
            List[pv.PolyData]: Individual clipped horizon surfaces.
        """
        if hasattr(faults, "next"):
            if type(faults[0]) == str:
                faults = [self.get_surface(f) for f in faults]

        horizons = []
        if not value:
            value = np.mean(self.model.grid.regular_grid.get_dx_dy_dz()[:2])

        # TODO: this somehow doesn't work properly with Gullfaks model
        horizons.append(
            horizon.clip_surface(faults[0], value=-value)
        )

        horizons.append(
            horizon.clip_surface(faults[-1], invert=False, value=-value)
        )

        if len(faults) == 1:
            print("Returning after 1")
            return horizons

        for f1, f2 in zip(faults[:-1], faults[1:]):
            horizons.append(
                horizon.clip_surface(
                    f1, invert=False, value=value
                ).clip_surface(
                    f2, value=-value
                )
            )

        return horizons
Пример #14
0
def process_spider_box_unit_cell(
    spider: pv.PolyData = get_unit_cell_spider(),
    box: pv.PolyData = get_unit_cell_box(),
    scale: float = 1.0,
    rotation: List[Tuple[str, float]] = None,
    translation: List[Union[int, float]] = None,
) -> Tuple[pv.PolyData, pv.PolyData]:
    """Process the spider-box unit cell through operations including scaling,
    rotations, and translations.

    Args:
        spider (pv.PolyData, optional): Polydata containing the spider unit.
            Defaults to get_unit_cell_spider().
        box (pv.PolyData, optional): Polydata containing the box unit. Defaults
            to get_unit_cell_box().
        scale (float, optional): scaling factor. Defaults to 1.0.
        rotation (List[Tuple[str, float]], optional): list of steps for
            rotation, in the form of list of tuples, and the tuple containing
            the direction (``"x"``, ``"y"``, or ``"z"``) in the first element,
            and the degrees in the second direction. Example:
            ``[("x", 90), ("z", 180)]``. Under the hood, the
            `rotate_x <https://docs.pyvista.org/core/common.html#pyvista.Common.rotate_x>`_,
            `rotate_y <https://docs.pyvista.org/core/common.html#pyvista.Common.rotate_y>`_, and
            `rotate_z <https://docs.pyvista.org/core/common.html#pyvista.Common.rotate_z>`_
            methods in ``pv.PolyData`` are called. Defaults to None.
        translation (List[Union[int, float]], optional): Length of 3 list or
            array to translate the polydata. Under the hood, the
            `translate <https://docs.pyvista.org/core/common.html#pyvista.Common.translate>`_
            method in ``pv.PolyData`` is called. Defaults to None.

    Returns:
        Tuple[pv.PolyData, pv.PolyData]: A tuple of ``pv.Polydata`` containing the spider and box.
    """
    spider.points *= scale
    box.points *= scale

    if isinstance(rotation, list):
        for step in rotation:
            if step[0] == "x":
                spider.rotate_x(step[1])
            if step[0] == "y":
                spider.rotate_y(step[1])
            if step[0] == "z":
                spider.rotate_z(step[1])

    if isinstance(translation, list):
        spider.translate(translation)
        box.translate(translation)

    return (spider, box)
Пример #15
0
def test_multi_block_clean(rectilinear, uniform, ant):
    # now test a clean of the null values
    multi = MultiBlock()
    multi[1, 'rect'] = rectilinear
    multi[2, 'empty'] = PolyData()
    multi[3, 'mempty'] = MultiBlock()
    multi[5, 'uni'] = uniform
    # perform the clean to remove all Null elements
    multi.clean()
    assert multi.n_blocks == 2
    assert multi.GetNumberOfBlocks() == 2
    assert isinstance(multi[0], RectilinearGrid)
    assert isinstance(multi[1], UniformGrid)
    assert multi.get_block_name(0) == 'rect'
    assert multi.get_block_name(1) == 'uni'
    # Test a nested data struct
    foo = MultiBlock()
    foo[3] = ant
    assert foo.n_blocks == 4
    multi = MultiBlock()
    multi[1, 'rect'] = rectilinear
    multi[5, 'multi'] = foo
    # perform the clean to remove all Null elements
    assert multi.n_blocks == 6
    multi.clean()
    assert multi.n_blocks == 2
    assert multi.GetNumberOfBlocks() == 2
    assert isinstance(multi[0], RectilinearGrid)
    assert isinstance(multi[1], MultiBlock)
    assert multi.get_block_name(0) == 'rect'
    assert multi.get_block_name(1) == 'multi'
    assert foo.n_blocks == 1
Пример #16
0
 def sphere(self, center, color, scale, opacity=1.0,
            resolution=8, backface_culling=False):
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore", category=FutureWarning)
         from pyvista import PolyData
         sphere = vtk.vtkSphereSource()
         sphere.SetThetaResolution(resolution)
         sphere.SetPhiResolution(resolution)
         sphere.Update()
         geom = sphere.GetOutput()
         pd = PolyData(center)
         self.plotter.add_mesh(pd.glyph(orient=False, scale=False,
                                        factor=scale, geom=geom),
                               color=color, opacity=opacity,
                               backface_culling=backface_culling,
                               smooth_shading=self.figure.smooth_shading)
Пример #17
0
def resize(mesh: pv.PolyData, radius: Optional[float] = None) -> pv.PolyData:
    """
    Change the radius of the provided mesh.

    Parameters
    ----------
    mesh : PolyData
        The mesh to be resized to the provided ``radius``.
    radius : float, default=1.0
        The target radius of the ``mesh``.

    Returns
    -------
    PolyData
        The resized mesh.

    Notes
    -----
    .. versionadded:: 0.1.0

    """
    if is_projected(mesh):
        emsg = "Cannot resize mesh that appears to be a planar projection."
        raise ValueError(emsg)

    if radius is None:
        radius = 1.0

    if radius and not np.isclose(calculate_radius(mesh), radius):
        lonlat = to_xy0(mesh)
        xyz = to_xyz(lonlat[:, 0], lonlat[:, 1], radius=radius)
        mesh.points = xyz

    return mesh
Пример #18
0
    def mesh(self, x, y, z, triangles, color, opacity=1.0, shading=False,
             backface_culling=False, scalars=None, colormap=None,
             vmin=None, vmax=None, **kwargs):
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", category=FutureWarning)
            from pyvista import PolyData
            smooth_shading = self.figure.smooth_shading
            vertices = np.c_[x, y, z]
            n_vertices = len(vertices)
            triangles = np.c_[np.full(len(triangles), 3), triangles]
            pd = PolyData(vertices, triangles)
            rgba = False
            if color is not None and len(color) == n_vertices:
                if color.shape[1] == 3:
                    scalars = np.c_[color, np.ones(n_vertices)]
                else:
                    scalars = color
                scalars = (scalars * 255).astype('ubyte')
                color = None
                # Disabling normal computation for smooth shading
                # is a temporary workaround of:
                # https://github.com/pyvista/pyvista-support/issues/15
                smooth_shading = False
                rgba = True
            if isinstance(colormap, np.ndarray):
                if colormap.dtype == np.uint8:
                    colormap = colormap.astype(np.float) / 255.
                from matplotlib.colors import ListedColormap
                colormap = ListedColormap(colormap)

            self.plotter.add_mesh(mesh=pd, color=color, scalars=scalars,
                                  rgba=rgba, opacity=opacity, cmap=colormap,
                                  backface_culling=backface_culling,
                                  rng=[vmin, vmax], show_scalar_bar=False,
                                  smooth_shading=smooth_shading)
Пример #19
0
 def mesh(self, x, y, z, triangles, color, opacity=1.0, shading=False,
          backface_culling=False, scalars=None, colormap=None,
          vmin=None, vmax=None, interpolate_before_map=True,
          representation='surface', line_width=1., normals=None,
          polygon_offset=None, **kwargs):
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore", category=FutureWarning)
         vertices = np.c_[x, y, z]
         triangles = np.c_[np.full(len(triangles), 3), triangles]
         mesh = PolyData(vertices, triangles)
     return self.polydata(
         mesh=mesh,
         color=color,
         opacity=opacity,
         normals=normals,
         backface_culling=backface_culling,
         scalars=scalars,
         colormap=colormap,
         vmin=vmin,
         vmax=vmax,
         interpolate_before_map=interpolate_before_map,
         representation=representation,
         line_width=line_width,
         polygon_offset=polygon_offset,
         **kwargs,
     )
Пример #20
0
def Plane(center=(0, 0, 0),
          direction=(0, 0, 1),
          i_size=1,
          j_size=1,
          i_resolution=10,
          j_resolution=10):
    """
    Create a plane

    Parameters
    ----------
    center : list or np.ndarray
        Location of the centroid in [x, y, z]

    direction : list or np.ndarray
        Direction cylinder points to  in [x, y, z]

    i_size : float
        Size of the plane in the i direction.

    j_size : float
        Size of the plane in the i direction.

    i_resolution : int
        Number of points on the plane in the i direction.

    j_resolution : int
        Number of points on the plane in the j direction.

    Returns
    -------
    plane : pyvista.PolyData
        Plane mesh

    """
    planeSource = vtk.vtkPlaneSource()
    planeSource.SetXResolution(i_resolution)
    planeSource.SetYResolution(j_resolution)
    planeSource.Update()

    surf = PolyData(planeSource.GetOutput())

    surf.points[:, 0] *= i_size
    surf.points[:, 1] *= j_size
    surf.rotate_y(-90)
    translate(surf, center, direction)
    return surf
Пример #21
0
 def mono_flipping(data):
     if VERBOSE: print(f"Flipping: {data['meta_data']['name']}")
     mesh = data["poly_data"]
     face_centers = mesh.cell_centers().points
     overall_signs = np.sum(np.sign(face_centers) * np.square(face_centers), axis=0)
     flipped_points = np.sign(overall_signs) * mesh.points
     remesh = PolyData(flipped_points, mesh.faces.copy())
     return remesh
Пример #22
0
def _compute_curvature(surface: pv.PolyData) -> Curvature:
    """Private helper function to retrieve curvature based on Polydata computed curvature values for each vertex
    Args:
        surface: the mesh created by the faces and vertices by running marching cubes

    Returns:
        A cached Curvature object for each vertex
    """
    mean_curvature = np.array(surface.curvature("Mean"))
    gaussian_curvature = np.array(surface.curvature("Gaussian"))
    p_min = np.array(surface.curvature("Minimum"))
    p_max = np.array(surface.curvature("Maximum"))

    _curvature = Curvature(gaussian_curvature=gaussian_curvature,
                           mean_curvature=mean_curvature,
                           principal_curvature_min=p_min,
                           principal_curvature_max=p_max)
    return _curvature
Пример #23
0
 def mono_scaling(data):
     if VERBOSE: print(f"\nScaling: {data['meta_data']['name']}")
     mesh = data["poly_data"]
     max_range = np.max(mesh.points, axis=0)
     min_range = np.min(mesh.points, axis=0)
     lengths_range = max_range - min_range
     longest_range = np.max(lengths_range)
     scaled_points = (mesh.points - min_range) / longest_range
     remesh = PolyData(scaled_points, mesh.faces.copy())
     return remesh
Пример #24
0
 def mono_alignment(data):
     if VERBOSE: print(f"Aligning: {data['meta_data']['name']}")
     mesh = data["poly_data"]
     A_cov = np.cov(mesh.points.T)
     eigenvalues, eigenvectors = np.linalg.eig(A_cov)
     biggest_idx = np.argsort(-eigenvalues)
     biggest_vec = eigenvectors[:, biggest_idx]
     new_points = np.dot(mesh.points, biggest_vec)
     remesh = PolyData(new_points, mesh.faces.copy())
     return remesh
Пример #25
0
 def mesh(self,
          x,
          y,
          z,
          triangles,
          color,
          opacity=1.0,
          shading=False,
          backface_culling=False,
          scalars=None,
          colormap=None,
          vmin=None,
          vmax=None,
          interpolate_before_map=True,
          representation='surface',
          line_width=1.,
          normals=None,
          **kwargs):
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore", category=FutureWarning)
         vertices = np.c_[x, y, z]
         triangles = np.c_[np.full(len(triangles), 3), triangles]
         mesh = PolyData(vertices, triangles)
         if normals is not None:
             mesh.point_arrays["Normals"] = normals
             mesh.GetPointData().SetActiveNormals("Normals")
     return self._mesh(
         mesh,
         color,
         opacity,
         backface_culling,
         scalars,
         colormap,
         vmin,
         vmax,
         interpolate_before_map,
         representation,
         line_width,
         **kwargs,
     )
Пример #26
0
def plot_mesh_pyvista(
    plotter: pv.Plotter,
    polydata: pv.PolyData,
    # vertices: np.ndarray,
    # triangles: np.ndarray,
    rotations: List[Tuple[int, int, int]] = [(0, 0, 0)],
    vertexcolors: List[int] = [],
    vertexscalar: str = '',
    cmap: str = 'YlGnBu',
    title: str = '',
    scalar_bar_idx: int = 0,
    **mesh_kwargs,
):
    shape = plotter.shape
    if len(shape) == 1:
        assert shape[0] > 0
        assert shape[0] == len(rotations)
        subp_idx = [(x, ) for x in range(shape[0])]
    else:
        assert shape[0] > 0 and shape[1] > 0
        assert shape[0] * shape[1] == len(rotations)
        subp_idx = product(range(shape[0]), range(shape[1]))

    if vertexscalar and vertexcolors is not None:
        polydata[vertexscalar] = vertexcolors

    cmap = plt.cm.get_cmap(cmap)

    mesh_kwargs = {
        'cmap': cmap,
        'flip_scalars': True,
        'show_scalar_bar': False,
        **mesh_kwargs,
    }
    if vertexscalar and vertexcolors is not None:
        mesh_kwargs['scalars'] = vertexscalar

    for i, (subp, rots) in enumerate(zip(subp_idx, rotations)):
        x, y, z = rots
        plotter.subplot(*subp)
        poly_copy = polydata.copy()
        poly_copy.rotate_x(x)
        poly_copy.rotate_y(y)
        poly_copy.rotate_z(z)
        plotter.add_mesh(
            poly_copy,
            **mesh_kwargs,
        )
        if i == 0:
            plotter.add_title(title, font_size=5)
        if i == scalar_bar_idx:
            plotter.add_scalar_bar(label_font_size=10, position_x=0.85)
Пример #27
0
    def get_pyvista_mesh(self, vertices: np.ndarray, triangles: np.ndarray):
        """Creates a PyVista mesh from the data.
        """
        try:
            from pyvista import PolyData

            triangles = np.hstack(
                np.append(np.full((triangles.shape[0], 1), 3),
                          triangles,
                          axis=1))
            return PolyData(vertices, triangles)
        except ImportError:
            raise ImportError(
                "The 'get_pyvista_mesh' method requires the PyVista python-package to"
                " be installed. Consider installing it via 'pip install pyvista'."
            )
Пример #28
0
def Arrow(start=(0., 0., 0.),
          direction=(1., 0., 0.),
          tip_length=0.25,
          tip_radius=0.1,
          shaft_radius=0.05,
          shaft_resolution=20):
    """
    Create a vtk Arrow

    Parameters
    ----------
    start : np.ndarray
        Start location in [x, y, z]

    direction : list or np.ndarray
        Direction the arrow points to in [x, y, z]

    tip_length : float, optional
        Length of the tip.

    tip_radius : float, optional
        Radius of the tip.

    shaft_radius : float, optional
        Radius of the shaft.

    shaft_resolution : int, optional
        Number of faces around the shaft

    Returns
    -------
    arrow : pyvista.PolyData
        Arrow surface.
    """
    # Create arrow object
    arrow = vtk.vtkArrowSource()
    arrow.SetTipLength(tip_length)
    arrow.SetTipRadius(tip_radius)
    arrow.SetShaftRadius(shaft_radius)
    arrow.SetShaftResolution(shaft_resolution)
    arrow.Update()
    surf = PolyData(arrow.GetOutput())
    translate(surf, start, direction)
    return surf
Пример #29
0
    def mesh(self,
             x,
             y,
             z,
             triangles,
             color,
             opacity=1.0,
             shading=False,
             backface_culling=False,
             **kwargs):
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", category=FutureWarning)
            from pyvista import PolyData
            smooth_shading = self.figure.smooth_shading
            vertices = np.c_[x, y, z]
            n_vertices = len(vertices)
            triangles = np.c_[np.full(len(triangles), 3), triangles]
            pd = PolyData(vertices, triangles)
            if len(color) == n_vertices:
                if color.shape[1] == 3:
                    scalars = np.c_[color, np.ones(n_vertices)]
                else:
                    scalars = color
                scalars = (scalars * 255).astype('ubyte')
                color = None
                # Disabling normal computation for smooth shading
                # is a temporary workaround of:
                # https://github.com/pyvista/pyvista-support/issues/15
                smooth_shading = False
                rgba = True
            else:
                scalars = None
                rgba = False

            self.plotter.add_mesh(mesh=pd,
                                  color=color,
                                  scalars=scalars,
                                  rgba=rgba,
                                  opacity=opacity,
                                  backface_culling=backface_culling,
                                  smooth_shading=smooth_shading)
Пример #30
0
def cut_along_meridian(
    mesh: pv.PolyData,
    meridian: Optional[float] = None,
    antimeridian: Optional[bool] = False,
) -> pv.PolyData:
    """
    TODO

    Parameters
    ----------
    mesh
    meridian
    antimeridian

    Returns
    -------

    Notes
    -----
    .. versionadded:: 0.1.0

    """
    if not isinstance(mesh, pv.PolyData):
        emsg = f"Require a 'pyvista.PolyData' mesh, got '{mesh.__class__.__name__}'."
        raise TypeError(emsg)

    if meridian is None:
        meridian = DEFAULT_MERIDIAN

    if antimeridian:
        meridian += 180

    meridian = wrap(meridian)[0]
    logger.debug(
        "meridian=%s, antimeridian=%s",
        meridian,
        antimeridian,
    )

    slicer = MeridianSlice(mesh, meridian)
    mesh_whole = slicer.extract(split_cells=False)
    mesh_split = slicer.extract(split_cells=True)
    info = mesh.active_scalars_info
    result: pv.PolyData = mesh.copy(deep=True)

    meshes = []
    remeshed_ids = np.array([])

    if mesh_whole.n_cells:
        ll = to_xy0(mesh_whole)
        meridian_mask = np.isclose(ll[:, 0], meridian)
        join_points = np.empty(mesh_whole.n_points, dtype=int)
        join_points.fill(REMESH_JOIN)
        mesh_whole[GV_REMESH_POINT_IDS] = join_points
        mesh_whole[GV_REMESH_POINT_IDS][meridian_mask] = REMESH_SEAM
        meshes.append(mesh_whole)
        remeshed_ids = mesh_whole[GV_CELL_IDS]
        result[GV_REMESH_POINT_IDS] = result[GV_POINT_IDS].copy()

    if mesh_split.n_cells:
        remeshed, remeshed_west, remeshed_east = remesh(mesh_split, meridian)
        meshes.extend([remeshed_west, remeshed_east])
        remeshed_ids = np.unique(np.hstack([remeshed_ids, remeshed[GV_CELL_IDS]]))
        if GV_REMESH_POINT_IDS not in result.point_data:
            result.point_data[GV_REMESH_POINT_IDS] = result[GV_POINT_IDS].copy()

    if meshes:
        result.remove_cells(remeshed_ids, inplace=True)
        result.set_active_scalars(info.name, preference=info.association.name.lower())
        result = combine(result, *meshes)

    return result