Beispiel #1
0
def add_textures(output, textures, elname):
    """Add textures to a pyvista data object"""
    if not pyvista.is_pyvista_obj(output):
        output = pyvista.wrap(output)

    for i, tex in enumerate(textures):
        # Now map the coordinates for the texture
        m = vtk.vtkTextureMapToPlane()
        m.SetInputDataObject(output)
        m.SetOrigin(tex.origin)
        m.SetPoint1(tex.origin + tex.axis_u)
        m.SetPoint2(tex.origin + tex.axis_v)
        m.Update()
        # Grab the texture coordinates
        tmp = m.GetOutputDataObject(0)
        tcoord = tmp.GetPointData().GetTCoords()
        name = tex.name
        if name is None or name == '':
            name = '{}-texture-{}'.format(elname, i)
        tcoord.SetName(name)
        # Add these coordinates to the PointData of the output
        # NOTE: Let pyvista handle setting the TCoords because of how VTK cleans
        #       up old TCoords
        output.GetPointData().AddArray(tcoord)
        # Add the vtkTexture to the output
        img = np.array(Image.open(tex.image))
        tex.image.seek(0)  # Reset the image bytes in case it is accessed again
        if img.shape[2] > 3:
            img = img[:, :, 0:3]
        vtexture = pyvista.numpy_to_texture(img)
        output.textures[name] = vtexture
        output._activate_texture(name)

    return output
Beispiel #2
0
def test_read_texture_from_numpy():
    """"Test adding a texture to a plot"""
    globe = examples.load_globe()
    texture = pyvista.numpy_to_texture(imageio.imread(examples.mapfile))
    plotter = pyvista.Plotter(off_screen=OFF_SCREEN)
    plotter.add_mesh(globe, texture=texture)
    plotter.show()
Beispiel #3
0
def test_read_texture_from_numpy():
    """"Test adding a texture to a plot"""
    globe = examples.load_globe()
    texture = pyvista.numpy_to_texture(imageio.imread(examples.mapfile))
    plotter = pyvista.Plotter()
    plotter.add_mesh(globe, texture=texture)
    plotter.show(before_close_callback=verify_cache_image)
Beispiel #4
0
    def get_many_noisy_photos(mesh, movement, resolution, cmap, plotter, camera, title=None, title_location="upper_edge",
                              background_photos=None, background_scale=1, title_color="black", cam_noise_lambda=None,
                              texture_params=(255/2, 155, (1000, 1000, 3))):
        """
        Take a photo of the mesh in a cerain position WITH GAUSSIAN TEXTURE
        all args in case for more then one mesh should be in list

       Args:
           mesh: the mesh to use
           movement: V side vector
           texture: the texture to use
           cmap: the colormap to use, used only if texture is not supplied
           plotter: the pyvista plotter, clear the mesh "get_photo" in the plotter
           camera: list of [camera position , focal point, view up] each (x,y,z) tuple
           resolution: the image resolution [w,h]
           background_photos: list of background photos to use in random
           texture_params: (mean, variance, shape) of the noisy texture


        Returns:
           An image shot from camera of the mesh
        """
        to_return = np.zeros(shape=(len(camera), resolution[1], resolution[0], 4))
        num_of_mesh = len(mesh)
        if background_photos:
            plotter.add_background_image(random.choice(background_photos), scale=background_scale)
        if cam_noise_lambda:
            cam_noise = np.zeros((len(camera), 3, 3))
            cam_noise[:,0] += np.random.normal(0, cam_noise_lambda[0], (len(camera), 3))
            cam_noise[:,1] += np.random.normal(0, cam_noise_lambda[1], (len(camera), 3))
            cam_noise[:,2] += np.random.normal(0, cam_noise_lambda[2], (len(camera), 3))
            camera = np.array(camera) + cam_noise

        if num_of_mesh == 1:
            mesh = [mesh]
        for i in range(num_of_mesh):
            tex = np.random.normal(texture_params[0], texture_params[1], texture_params[2]).astype(np.uint8)
            tex[np.where(tex > 255)] = 255
            tex[np.where(tex < 0)] = 0
            tex = pv.numpy_to_texture(tex)
            mesh[i].pv_mesh.texture_map_to_plane(inplace=True)
            plotter.add_mesh(mesh[i].pv_mesh, texture=tex, name='get_photo_mesh_' + str(i))
            plotter.update_coordinates(movement[i], mesh=mesh[i].pv_mesh)
        if title:
            plotter.add_text(title, position=title_location, font_size=10, color=title_color, name="title", shadow=True)
        plotter.set_background(color="white")
        plotter.show(auto_close=False, window_size=resolution)
        for idx, cam in enumerate(camera):
            plotter.set_position(cam[0])
            plotter.set_focus(cam[1])
            plotter.set_viewup(cam[2])
            depth = plotter.get_image_depth(fill_value=None)
            depth = np.abs(depth)
            screen = plotter.screenshot(window_size=resolution)
            screen = screen / 255
            to_return[idx] = np.append(screen, depth.reshape(resolution[1], resolution[0], 1), axis=-1)
        if background_photos:
            plotter.remove_background_image()
        return np.asarray(to_return, np.float32)
Beispiel #5
0
def read_texture(filename, attrs=None):
    """Load a ``vtkTexture`` from an image file."""
    filename = os.path.abspath(os.path.expanduser(filename))
    try:
        # initialize the reader using the extension to find it
        reader = get_reader(filename)
        image = standard_reader_routine(reader, filename, attrs=attrs)
        return pyvista.image_to_texture(image)
    except KeyError:
        # Otherwise, use the imageio reader
        pass
    return pyvista.numpy_to_texture(imageio.imread(filename))
Beispiel #6
0
    def draw_model(self, with_texture=False):
        if self.mode == RenderMode.image:
            self.mesh.points = self.model.vertices
            self.plotter.add_mesh(self.mesh, color=self.model_color)
            return self.plotter.image

        model_mesh = pv.PolyData(self.model.vertices, self.faces)
        if with_texture:
            model_mesh.t_coords = self.model.vertex_texture_coords
            texture = pv.numpy_to_texture(self.model.texture)
            model_mesh.textures[0] = texture
        return self._plot(model_mesh)
Beispiel #7
0
    def animate(self, movement, f=None, index_col=0, index_row=0, texture=None, cmap='jet',
                plotter=None, title='', font_size=10, font_color='black', gif_path=None, camera=None):
        """
       animate the mash using movement as movement metrix press "q" after adjusting the frame to start the animation

       Args:
           movement: tuple of  V side vector as elements, (hull_movement,tip_movement)
           f: map between (x,y,z) of vertex to scalar for the color map
           index_row: chosen subplot row
           index_col: chosen subplot column
           texture: the texture to use
           cmap: the colormap to use
           plotter: the pyvista plotter
           title: the title of the figure
           font_size: the font size of the title
           font_color: the color of the font for the title
           gif_path: gif path to create, None if no gif is needed
           camera: the [camera position , focal point, view up] each (x,y,z) tuple


        Returns:
           None
        """

        if not plotter:
            plotter = pv.Plotter()

        plotter.subplot(index_column=index_col, index_row=index_row)
        plotter.add_text(title, position="upper_edge", font_size=font_size, color=font_color)
        if camera is not None:  # it gives .any() crushes without..
            plotter.set_position(camera[0])
            plotter.set_focus(camera[1])
            plotter.set_viewup(camera[2])
        if not texture:
            plotter.add_mesh(self.pv_mesh, scalars=f, cmap=cmap, texture=texture)
        else:
            if isinstance(texture, np.ndarray):
                tex = pv.numpy_to_texture(texture)
            else:
                tex = pv.read_texture(texture)
            self.pv_mesh.texture_map_to_plane(inplace=True)
            plotter.add_mesh(self.pv_mesh, texture=tex)
        plotter.show(auto_close=False)
        if gif_path:
            plotter.open_gif(gif_path)
        for item in movement:
            plotter.update_coordinates(item, mesh=self.pv_mesh)
            if gif_path:
                plotter.write_frame()

        plotter.close()
Beispiel #8
0
def read_texture(filename, attrs=None):
    """Load a ``vtkTexture`` from an image file."""
    filename = os.path.abspath(os.path.expanduser(filename))
    try:
        # initialize the reader using the extension to find it
        reader = get_reader(filename)
        image = standard_reader_routine(reader, filename, attrs=attrs)
        if image.n_points < 2:
            raise RuntimeError("Problem reading the image with VTK.")
        return pyvista.image_to_texture(image)
    except (KeyError, RuntimeError):
        # Otherwise, use the imageio reader
        pass
    import imageio
    return pyvista.numpy_to_texture(imageio.imread(filename))
Beispiel #9
0
    def plot_faces(self, f=None, index_row=0, index_col=0, show=True, plotter=None, cmap='jet', title=None,
                   title_location="upper_edge", font_size=10, font_color='black', texture=None, camera=None):
        """
             plots the faces of the Mesh

             Args:
                  f: map between (x,y,z) of vertex to scalar for the color map
                  index_row: chosen subplot row
                  index_col: chosen subplot column
                  show: should the function call imshow()
                  plotter: the pyvista plotter
                  cmap: the color map to use
                  title: the title of the figure
                  title_location: title location
                  font_size: the font size of the title
                  font_color: the color of the font for the title
                  texture: the filename for the texture of the figure or np array
                  camera: the [camera position , focal point, view up] each (x,y,z) tuple

             Returns:
                 the pyvista plotter
        """
        if not plotter:
            plotter = pv.Plotter()
        plotter.subplot(index_column=index_col, index_row=index_row)
        if title:
            plotter.add_text(title, position=title_location, font_size=font_size, color=font_color)
        if camera is not None:
            plotter.set_position(camera[0])
            plotter.set_focus(camera[1])
            plotter.set_viewup(camera[2])
        if self.texture:
            plotter.add_mesh(self.pv_mesh, texture=self.texture)
        elif texture is None:
            plotter.add_mesh(self.pv_mesh, scalars=f, cmap=cmap, texture=texture, show_scalar_bar=False)
        else:
            if isinstance(texture, np.ndarray):
                tex = pv.numpy_to_texture(texture)
            else:
                tex = pv.read_texture(texture)
            self.pv_mesh.texture_map_to_plane(inplace=True)
            plotter.add_mesh(self.pv_mesh, texture=tex)
        if show:
            plotter.show()
        return plotter
Beispiel #10
0
    def plot_projection(self, normal=(1, 1, 1), index_row=0, index_col=0, show=True, texture=None, cmap="jet", f=None,
                        plotter=None, title='', font_size=10, font_color='black'):
        """
       plots the projection of the Mesh

       Args:
           normal: the normal of the projected image
           index_row: chosen subplot row
           index_col: chosen subplot column
           show: should the function call imshow()
           texture: the texture to use
           cmap: the color map to use
           f: the color for each vertex or face.
           plotter: the pyvista plotter
           title: the title of the figure
           font_size: the font size of the title
           font_color: the color of the font for the title

        Returns:
            the pyvista plotter
        """
        if not plotter:
            plotter = pv.Plotter()
        plotter.subplot(index_column=index_col, index_row=index_row)

        plotter.add_text(title, position="upper_edge", font_size=font_size, color=font_color)
        tex = None
        if texture:

            if isinstance(texture, np.ndarray):
                tex = pv.numpy_to_texture(texture)
            else:
                tex = pv.read_texture(texture)
            self.pv_mesh.texture_map_to_plane(inplace=True)
            # plotter.add_mesh(pv_mesh, texture=tex)

        og = self.pv_mesh.center
        projected = self.pv_mesh.project_points_to_plane(origin=og, normal=normal)
        projected.texture_map_to_plane()
        plotter.add_mesh(projected, texture=tex)
        if show:
            plotter.show()
        return plotter
Beispiel #11
0
def DEM_to_vtk_withtexture(input_dem, input_sat=None, im_output='satellite.png', vtk_output='output.vtk', height_scale=1):
        
    # Import the DEM file as a 3D mesh   
    data = xr.open_rasterio(input_dem)
    values = np.asarray(data)
    nans = values == data.nodatavals
    if np.any(nans):
        values[nans] = np.nan
    # Make a mesh
    xx, yy = np.meshgrid(data['x'], data['y'])
    zz = values.reshape(xx.shape) # will make z-comp the values in the file
    mesh = pv.StructuredGrid(xx, yy, height_scale*zz)
    mesh['Elevation'] = values.ravel(order='F')
    mesh = mesh.warp_by_scalar()
    
    # If there is a satellite image file then add texture coordinates to the mesh and save the image in the correct format  
    if input_sat != None:       
        ds = xr.open_rasterio(input_sat)
        
        # Fetch the texture as an image: moves the first axis to the end, e.g. (10,15,4) -> (4,10,15)
        image = np.moveaxis(ds.values, 0, -1)
        
        # Create the ground control points (GCPs) for texture mapping ***super important
        o = ds.x.min(), ds.y.min(), 0.0 # Bottom Left
        u = ds.x.max(), ds.y.min(), 0.0 # Bottom Right
        v = ds.x.min(), ds.y.max(), 0.0 # Top left
        # Note: Z-coordinate doesn't matter
        
        # Use the GCPs to map the tex coords
        mesh.texture_map_to_plane(o, u, v, inplace=True)
        mesh.textures["aerial"] = pv.numpy_to_texture(image)
        
        # save the texture as a png to use as texture in Paraview
        from PIL import Image
        im = Image.fromarray(image)
        im.save(im_output)
    
    mesh.save(vtk_output) # save as a vtk file
        
    return mesh
Beispiel #12
0
    def __init__(self, parent, image, scale=1, view_port=None):
        """Initialize BackgroundRenderer with an image."""
        # read the image first as we don't need to create a render if
        # the image path is invalid
        image_data = pyvista.numpy_to_texture(image).to_image()

        super().__init__(parent, border=False)
        self.SetLayer(0)
        self.InteractiveOff()
        self.SetBackground(self.parent.renderer.GetBackground())
        self._scale = scale
        self._modified_observer = None
        self._prior_window_size = None
        if view_port is not None:
            self.SetViewport(view_port)

        # create image actor
        image_actor = vtk.vtkImageActor()
        image_actor.SetInputData(image_data)
        self.add_actor(image_actor, name='background')
        self.camera.ParallelProjectionOn()
        self.resize()
Beispiel #13
0
def animate_few_meshes(mesh, movement, f=None, subplot=(0, 0), texture=None, cmap='jet',
                       plotter=None, title='', font_size=10, font_color='black', gif_path=None, camera=None,
                       depth=False):
    """
   animate few mashes using f as movment metrix. press "q" after adjusting the frame to start the animation

   Args:
       mesh: list of the meshes to plot
       movement:  list of iterable with Vn side vector as elements for the num of vercies of the n-th mesh
       f: list of function that map between id of vertex to scalar for the color map
       subplot: list of subplots to use, each is a tuple in the form of: (row,col)
       texture: list of the textures to use
       cmap: list of the colormap to use
       plotter: the pyvista plotter
       title: the title of the figure
       font_size: the font size of the title
       font_color: the color of the font for the title
       gif_path: gif path to create, None if no gif is needed
       camera: list of the [camera position , focal point, view up] each (x,y,z) tuple


    Returns:
       None
    """
    num_of_plots = len(mesh)
    if num_of_plots == 1:
        return mesh.animate(movement=movement, f=f, index_col=subplot[1], index_row=subplot[0], texture=texture,
                            cmap=cmap, plotter=plotter, title=title, font_color=font_color, font_size=font_size,
                            gif_path=gif_path, camera=camera)

    if not plotter:
        plotter = pv.Plotter()
    pv_mesh = []
    # adding mushes with textures

    for idx in range(num_of_plots):
        plotter.subplot(subplot[idx][0], subplot[idx][1])
        if depth:
            plotter.enable_depth_peeling(0)
        plotter.add_text(title[idx], position="upper_edge", font_size=font_size[idx], color=font_color[idx])
        if camera[idx] is not None:
            plotter.set_position(camera[idx][0])
            plotter.set_focus(camera[idx][1])
            plotter.set_viewup(camera[idx][2])
        pv_mesh.append(mesh[idx].pv_mesh)
        if not texture[idx]:
            plotter.add_mesh(pv_mesh[idx], scalars=f[idx], cmap=cmap[idx], texture=texture[idx])
        else:
            if isinstance(texture[idx], np.ndarray):
                tex = pv.numpy_to_texture(texture[idx])
            else:
                tex = pv.read_texture(texture[idx])
            pv_mesh[idx].texture_map_to_plane(inplace=True)
            plotter.add_mesh(pv_mesh[idx], texture=tex)
    # starting the animation
    plotter.show(auto_close=False)
    if gif_path:
        plotter.open_gif(gif_path)
    for frame, item in enumerate(movement[0]):
        for plt_id in range(num_of_plots):
            plotter.update_coordinates(movement[plt_id][frame], mesh=pv_mesh[plt_id])
        if gif_path:
            plotter.write_frame()

    plotter.close()
Beispiel #14
0
# :func:`pyvista.numpy_to_texture`.

# create an image using numpy,
xx, yy = np.meshgrid(np.linspace(-200, 200, 20), np.linspace(-200, 200, 20))
A, b = 500, 100
zz = A * np.exp(-0.5 * ((xx / b) ** 2.0 + (yy / b) ** 2.0))

# Creating a custom RGB image
cmap = get_cmap("nipy_spectral")
norm = lambda x: (x - np.nanmin(x)) / (np.nanmax(x) - np.nanmin(x))
hue = norm(zz.ravel())
colors = (cmap(hue)[:, 0:3] * 255.0).astype(np.uint8)
image = colors.reshape((xx.shape[0], xx.shape[1], 3), order="F")

# Convert 3D numpy array to texture
tex = pv.numpy_to_texture(image)

# Render it!
curvsurf.plot(texture=tex)

###############################################################################
# Textures with Transparency
# ++++++++++++++++++++++++++
#
# Textures can also specify per-pixel opacity values. The image must
# contain a 4th channel specifying the opacity value from 0 [transparent] to
# 255 [fully visible]. To enable this feature just pass the opacity array as the
# 4th channel of the image as a 3 dimensional matrix with shape [nrows, ncols, 4]
# :func:`pyvista.numpy_to_texture`.
#
# Here we can download an image that has an alpha channel:
Beispiel #15
0
# Open the GeoTIFF
url = "https://dl.dropbox.com/s/pqgme8qsl95u9un/Sio020320_transparent_mosaic_group1.tif?dl=0"
path, _ = examples.downloads._retrieve_file(
    url, "Sio020320_transparent_mosaic_group1.tif.csv")
ds = xr.open_rasterio(path)

# Fetch the texture as an image
image = np.moveaxis(ds.values, 0, -1)

# Create the ground control points for texture mapping
o = ds.x.min(), ds.y.min(), 0.0  # Bottom Left
u = ds.x.max(), ds.y.min(), 0.0  # Bottom Right
v = ds.x.min(), ds.y.max(), 0.0  # Lop left
# Note: Z-coordinate doesn't matter

###############################################################################
# Use the GCPs to map the tex coords
mapped_surf = surf.texture_map_to_plane(o, u, v)

# Associate the texture with the mapped mesh
mapped_surf.textures["aerial"] = pv.numpy_to_texture(image)

###############################################################################
# Plot it up in 3D and enjoy!
cpos = [
    (469735.37431312964, 1321523.2987377762, 5242.9129552423465),
    (469928.4268006842, 1321916.1316302174, 5171.6505267522025),
    (0.08372003361058433, 0.13788753708579846, 0.986903228836878),
]
mapped_surf.plot(texture="aerial", cpos=cpos)