""" import imageio import numpy as np from wgpu.gui.auto import WgpuCanvas, run import pygfx as gfx canvas = WgpuCanvas() renderer = gfx.renderers.WgpuRenderer(canvas) scene = gfx.Scene() voldata = imageio.volread("imageio:stent.npz").astype(np.float32) tex = gfx.Texture(voldata, dim=3) vol = gfx.Volume(gfx.Geometry(grid=tex), gfx.VolumeRayMaterial(clim=(0, 2000))) slice = gfx.Volume( gfx.Geometry(grid=tex), gfx.VolumeSliceMaterial(clim=(0, 2000), plane=(0, 0, 1, 0)) ) scene.add(vol, slice) for ob in (slice, vol): ob.position.set(*(-0.5 * i for i in voldata.shape[::-1])) camera = gfx.PerspectiveCamera(70, 16 / 9) camera.position.z = 500 controls = gfx.OrbitControls(camera.position.clone(), up=gfx.linalg.Vector3(0, 0, 1)) controls.rotate(-0.5, -0.5)
""" Example showing multiple rotating cubes. This also tests the depth buffer. """ import imageio from wgpu.gui.auto import WgpuCanvas, run import pygfx as gfx canvas = WgpuCanvas() renderer = gfx.renderers.WgpuRenderer(canvas) scene = gfx.Scene() im = imageio.imread("imageio:chelsea.png") tex = gfx.Texture(im, dim=2).get_view(filter="linear") material = gfx.MeshBasicMaterial(map=tex) geometry = gfx.box_geometry(100, 100, 100) cubes = [gfx.Mesh(geometry, material) for i in range(8)] for i, cube in enumerate(cubes): cube.position.set(350 - i * 100, 0, 0) scene.add(cube) background = gfx.Background(None, gfx.BackgroundMaterial((0, 1, 0, 1), (0, 1, 1, 1))) scene.add(background) camera = gfx.PerspectiveCamera(70, 16 / 9) camera.position.z = 500 def animate():
Binding("r_sampler", "sampler/filtering", wobject.texture.get_view()), 1: Binding("r_tex", "texture/auto", wobject.texture.get_view()), }, }, ] # %% The application # The canvas for eventual display canvas = WgpuCanvas(size=(640, 480)) # The texture to render the scene into texture = gfx.Texture(dim=2, size=(640, 480, 1), format="rgba8unorm") # The regular scene renderer1 = gfx.renderers.WgpuRenderer(texture) scene = gfx.Scene() im = imageio.imread("imageio:astronaut.png").astype(np.float32) / 255 tex = gfx.Texture(im, dim=2).get_view(filter="linear", address_mode="repeat") geometry = gfx.box_geometry(200, 200, 200) material = gfx.MeshBasicMaterial(map=tex) cube = gfx.Mesh(geometry, material) scene.add(cube) camera = gfx.PerspectiveCamera(70, 16 / 9)
on. Upon clicking, the vertex closest to the pick location is moved. """ # todo: if we have per-vertex coloring, we can paint on the mesh instead :D import numpy as np import imageio from wgpu.gui.auto import WgpuCanvas, run import pygfx as gfx canvas = WgpuCanvas() renderer = gfx.renderers.WgpuRenderer(canvas) scene = gfx.Scene() im = imageio.imread("imageio:astronaut.png").astype(np.float32) / 255 tex = gfx.Texture(im, dim=2).get_view(filter="linear", address_mode="repeat") geometry = gfx.box_geometry(200, 200, 200) material = gfx.MeshBasicMaterial(map=tex) cube = gfx.Mesh(geometry, material) cube.position.x += 150 scene.add(cube) torus = gfx.Mesh(gfx.torus_knot_geometry(100, 20, 128, 32), gfx.MeshPhongMaterial()) torus.position.x -= 150 scene.add(torus) camera = gfx.PerspectiveCamera(70, 16 / 9) camera.position.z = 400
# Read the image # The order of the images is already correct for GPU cubemap texture sampling im = imageio.imread("imageio:meadow_cube.jpg") # Turn it into a 3D image (a 4d nd array) width = height = im.shape[1] im.shape = -1, width, height, 3 canvas = WgpuCanvas() renderer = gfx.renderers.WgpuRenderer(canvas) scene = gfx.Scene() # Create cubemap texture tex_size = width, height, 6 tex = gfx.Texture(im, dim=2, size=tex_size) view = tex.get_view(view_dim="cube", layer_range=range(6)) # And the background image with the cube texture background = gfx.Background(None, gfx.BackgroundImageMaterial(map=view)) scene.add(background) # Let's add some cubes to make the scene less boring cubes = [] for pos in (-600, 0, -600), (-600, 0, +600), (+600, 0, -600), (+600, 0, +600): clr = (0.5, 0.6, 0.0, 1.0) cube = gfx.Mesh(gfx.box_geometry(200, 200, 200), gfx.MeshPhongMaterial(color=clr)) cube.position.from_array(pos) cubes.append(cube) scene.add(cube)
geometry = get_geometry() camera = gfx.OrthographicCamera(16, 3) # === 1D colormap # # For the 1D texcoords we use the second dimension of the default # texcoords, which runs from the top to the bottom of the cylinder. The # 1D colormap runs from yellow to cyan. texcoords1 = geometry.texcoords.data[:, 1].copy() cmap1 = np.array([(1, 1, 0), (0, 1, 1)], np.float32) tex1 = gfx.Texture(cmap1, dim=1).get_view(filter="linear") create_object(texcoords1, tex1, -6) # === 2D colormap # # For the 2D texcoords we use the default texcoords. For the 2D colormap # we use an image texture. texcoords2 = geometry.texcoords.data.copy() cmap2 = imageio.imread("imageio:chelsea.png").astype(np.float32) / 255 tex2 = gfx.Texture(cmap2, dim=2).get_view(address_mode="repeat") create_object(texcoords2, tex2, -2)
""" import imageio from wgpu.gui.auto import WgpuCanvas, run import pygfx as gfx canvas = WgpuCanvas() renderer = gfx.renderers.WgpuRenderer(canvas) scene = gfx.Scene() # %% add image im = imageio.imread("imageio:astronaut.png") image = gfx.Image( gfx.Geometry(grid=gfx.Texture(im, dim=2)), gfx.ImageBasicMaterial(clim=(0, 255)), ) scene.add(image) # %% add points xx = [182, 180, 161, 153, 191, 237, 293, 300, 272, 267, 254] yy = [145, 131, 112, 59, 29, 14, 48, 91, 136, 137, 172] points = gfx.Points( gfx.Geometry(positions=[(x, y, 0) for x, y in zip(xx, yy)]), gfx.PointsMaterial(color=(0, 1, 1, 1), size=10), ) points.position.z = 1 # move points in front of the image scene.add(points)
canvas = WgpuCanvas() renderer = gfx.renderers.WgpuRenderer(canvas) scene = gfx.Scene() im = np.array( [ [0, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 2], ], np.float32, ) image = gfx.Image( gfx.Geometry(grid=gfx.Texture(im, dim=2).get_view(filter="nearest")), gfx.ImageBasicMaterial(clim=(0, 2)), ) scene.add(image) points = gfx.Points( gfx.Geometry(positions=[[0, 0, 1], [3, 3, 1]]), gfx.PointsMaterial(color=(0, 1, 0, 1), size=20), ) scene.add(points) camera = gfx.OrthographicCamera(10, 10) if __name__ == "__main__": print(__doc__) canvas.request_draw(lambda: renderer.render(scene, camera))
""" import imageio from wgpu.gui.auto import WgpuCanvas, run import pygfx as gfx canvas = WgpuCanvas() renderer = gfx.renderers.WgpuRenderer(canvas) scene = gfx.Scene() vol = imageio.volread("imageio:stent.npz") nslices = vol.shape[0] index = nslices // 2 tex_size = tuple(reversed(vol.shape)) tex = gfx.Texture(vol, dim=2, size=tex_size) view = tex.get_view(filter="linear", view_dim="2d", layer_range=range(index, index + 1)) geometry = gfx.plane_geometry(200, 200, 12, 12) material = gfx.MeshBasicMaterial(map=view, clim=(0, 2000)) plane = gfx.Mesh(geometry, material) scene.add(plane) camera = gfx.OrthographicCamera(200, 200) @canvas.add_event_handler("wheel") def handle_event(event): global index
from wgpu.gui.auto import WgpuCanvas, run import pygfx as gfx canvas = WgpuCanvas() renderer = gfx.renderers.WgpuRenderer(canvas) scene = gfx.Scene() axes = gfx.AxesHelper(length=250) scene.add(axes) background = gfx.Background(None, gfx.BackgroundMaterial((0, 1, 0, 1), (0, 1, 1, 1))) scene.add(background) im = imageio.imread("imageio:astronaut.png") tex = gfx.Texture(im, dim=2) geometry = gfx.plane_geometry(512, 512) material = gfx.MeshBasicMaterial(map=tex.get_view(filter="linear")) plane = gfx.Mesh(geometry, material) scene.add(plane) camera = gfx.OrthographicCamera(512, 512) camera.position.set(0, 0, 500) controls = gfx.PanZoomControls(camera.position.clone()) controls.add_default_event_handlers(canvas, camera) def animate(): controls.update_camera(camera) renderer.render(scene, camera)
geometry.texcoords = gfx.Buffer(geometry.texcoords.data[:, 0]) camera = gfx.OrthographicCamera(16, 3) def create_object(tex, xpos): material = gfx.MeshPhongMaterial(map=tex, clim=(-0.05, 1)) obj = gfx.Mesh(geometry, material) obj.position.x = xpos scene.add(obj) # === 1-channel colormap: grayscale cmap1 = np.array([(1,), (0,), (0,), (1,)], np.float32) tex1 = gfx.Texture(cmap1, dim=1).get_view(filter="linear") create_object(tex1, -6) # ==== 2-channel colormap: grayscale + alpha cmap2 = np.array([(1, 1), (0, 1), (0, 0), (1, 0)], np.float32) tex1 = gfx.Texture(cmap2, dim=1).get_view(filter="linear") create_object(tex1, -2) # === 3-channel colormap: RGB cmap3 = np.array([(1, 1, 0), (0, 1, 0), (0, 1, 0), (1, 1, 0)], np.float32) tex1 = gfx.Texture(cmap3, dim=1).get_view(filter="linear") create_object(tex1, +2) # === 4-channel colormap: RGBA
from wgpu.gui.auto import WgpuCanvas, run import pygfx as gfx from skimage.measure import marching_cubes canvas = WgpuCanvas() renderer = gfx.renderers.WgpuRenderer(canvas) scene = gfx.Scene() background = gfx.Background(None, gfx.BackgroundMaterial((0, 1, 0, 1), (0, 1, 1, 1))) scene.add(background) scene.add(gfx.AxesHelper(length=50)) vol = imageio.volread("imageio:stent.npz") tex = gfx.Texture(vol, dim=3) surface = marching_cubes(vol[0:], 200) geo = gfx.Geometry(positions=np.fliplr(surface[0]), indices=surface[1], normals=surface[2]) mesh = gfx.Mesh( geo, gfx.MeshSliceMaterial(plane=(0, 0, -1, vol.shape[0] / 2), color=(1, 1, 0, 1))) scene.add(mesh) planes = [] for dim in [0, 1, 2]: # xyz abcd = [0, 0, 0, 0] abcd[dim] = -1
import pygfx as gfx canvas = WgpuCanvas() renderer = gfx.renderers.WgpuRenderer(canvas) # Prepare a very small data volume. The data is integer and not uint8, # so its not interpolated (a wgpu restriction). In this case this is intended. voldata = np.ones((3, 3, 3), np.int16) * 200 voldata[1:-1, :, :] = 600 voldata[:, 1:-1, :] = 600 voldata[:, :, 1:-1] = 600 voldata[1, 1, 1] = 800 # Create a texture, (wrapped in a geometry) for it geo = gfx.Geometry(grid=gfx.Texture(voldata, dim=3)) # Prepare two 3x3x3 boxes to indicate the proper position box1 = gfx.Mesh( gfx.box_geometry(3.1, 3.1, 3.1), gfx.MeshBasicMaterial(color=(1, 0, 0, 1), wireframe=True, wireframe_thickness=2), ) box2 = gfx.Mesh( gfx.box_geometry(3.1, 3.1, 3.1), gfx.MeshBasicMaterial(color=(0, 1, 0, 1), wireframe=True, wireframe_thickness=2), ) # In scene1 we show a raycasted volume scene1 = gfx.Scene() vol = gfx.Volume(geo, gfx.VolumeRayMaterial(clim=(0, 2000))) vol.position.set(-1, -1, -1)