summaryrefslogtreecommitdiff
path: root/camera.py
diff options
context:
space:
mode:
authorStan Seibert <stan@mtrr.org>2011-09-16 14:27:46 -0400
committerStan Seibert <stan@mtrr.org>2011-09-16 14:27:46 -0400
commit084dfd08b714faefaea77cb7dc04d2e93dc04b1d (patch)
tree5be8c1f1d30dc52d74c70c4964ec54f66294c265 /camera.py
parentcfecff941fc619eb7269128afc62d9c11ae78aff (diff)
downloadchroma-084dfd08b714faefaea77cb7dc04d2e93dc04b1d.tar.gz
chroma-084dfd08b714faefaea77cb7dc04d2e93dc04b1d.tar.bz2
chroma-084dfd08b714faefaea77cb7dc04d2e93dc04b1d.zip
File reorganization to move toward standard python package layout
Diffstat (limited to 'camera.py')
-rwxr-xr-xcamera.py749
1 files changed, 0 insertions, 749 deletions
diff --git a/camera.py b/camera.py
deleted file mode 100755
index 470a1b9..0000000
--- a/camera.py
+++ /dev/null
@@ -1,749 +0,0 @@
-#!/usr/bin/env python
-import numpy as np
-import itertools
-import threading
-import multiprocessing
-import os
-from subprocess import call
-import shutil
-import tempfile
-import inspect
-
-import pycuda.driver as cuda
-from pycuda import gpuarray as ga
-
-from chroma.color import map_to_color
-from chroma.geometry import Mesh, Solid, Geometry
-from chroma.transform import rotate, make_rotation_matrix
-from chroma.sample import uniform_sphere
-from chroma.optics import vacuum
-from chroma.project import from_film
-from chroma.fileio.root import RootReader
-from chroma import make
-from chroma import gpu
-
-import pygame
-from pygame.locals import *
-
-def build(obj):
- """Construct and build a geometry from `obj`."""
- if inspect.isfunction(obj):
- obj = obj()
-
- if isinstance(obj, Geometry):
- geometry = obj
- elif isinstance(obj, Solid):
- geometry = Geometry()
- geometry.add_solid(obj)
- elif isinstance(obj, Mesh):
- geometry = Geometry()
- geometry.add_solid(Solid(obj, vacuum, vacuum, color=0x99ffffff))
- else:
- raise TypeError('cannot build type %s' % type(obj))
-
- geometry.build()
-
- return geometry
-
-def bvh_mesh(geometry, layer):
- lower_bounds = geometry.lower_bounds[geometry.layers == layer]
- upper_bounds = geometry.upper_bounds[geometry.layers == layer]
-
- if len(lower_bounds) == 0 or len(upper_bounds) == 0:
- raise Exception('no nodes at layer %i' % layer)
-
- dx, dy, dz = upper_bounds[0] - lower_bounds[0]
- center = np.mean([upper_bounds[0],lower_bounds[0]], axis=0)
-
- mesh = make.box(dx, dy, dz, center)
-
- for center, dx, dy, dz in zip(np.mean([lower_bounds,upper_bounds],axis=0),
- *zip(*upper_bounds-lower_bounds))[1:]:
- mesh += make.box(dx,dy,dz,center)
-
- return mesh
-
-def encode_movie(dir):
- root, ext = 'movie', 'avi'
- for i in itertools.count():
- path = '.'.join([root + str(i).zfill(5), ext])
-
- if not os.path.exists(path):
- break
-
- call(['mencoder', 'mf://' + dir + '/*.png', '-mf', 'fps=10', '-o',
- path, '-ovc', 'xvid', '-xvidencopts', 'bitrate=3000'])
-
- shutil.rmtree(dir)
-
- print 'movie saved to %s.' % filename
-
-class Camera(multiprocessing.Process):
- "The camera class is used to render a Geometry object."
- def __init__(self, geometry, size=(800,600), device_id=None):
- multiprocessing.Process.__init__(self)
- self.geometry = geometry
- self.device_id = device_id
- self.size = size
-
- self.unique_bvh_layers = np.unique(self.geometry.layers)
- self.currentlayer = None
- self.bvh_layers = {}
-
- self.display3d = False
- self.green_magenta = False
- self.max_alpha_depth = 10
- self.alpha_depth = 10
-
- try:
- import spnav as spnav_module
- self.spnav_module = spnav_module
- self.spnav = True
- except:
- self.spnav = False
-
- def init_gpu(self):
- self.context = gpu.create_cuda_context(self.device_id)
-
- self.gpu_geometry = gpu.GPUGeometry(self.geometry)
- self.gpu_funcs = gpu.GPUFuncs(gpu.get_cu_module('mesh.h'))
- self.hybrid_funcs = gpu.GPUFuncs(gpu.get_cu_module('hybrid_render.cu'))
-
- self.gpu_geometries = [self.gpu_geometry]
-
- self.width, self.height = self.size
-
- self.npixels = self.width*self.height
-
- self.clock = pygame.time.Clock()
-
- self.doom_mode = False
- try:
- if self.width == 640: # SECRET DOOM MODE!
- print 'shotgun activated!'
- self.doom_hud = pygame.image.load('images/doomhud.png').convert_alpha()
- rect = self.doom_hud.get_rect()
- self.doom_rect = rect.move(0, self.height - rect.height)
- self.doom_mode = True
- except:
- pass
-
- lower_bound, upper_bound = self.geometry.mesh.get_bounds()
-
- self.mesh_diagonal_norm = np.linalg.norm(upper_bound-lower_bound)
-
- self.scale = self.mesh_diagonal_norm
-
- self.motion = 'coarse'
-
- self.nblocks = 64
-
- self.point = np.array([0, -self.mesh_diagonal_norm,
- (lower_bound[2]+upper_bound[2])/2])
-
- self.axis1 = np.array([0,0,1], float)
- self.axis2 = np.array([1,0,0], float)
-
- self.film_width = 0.035
-
- pos, dir = from_film(self.point, axis1=self.axis1, axis2=self.axis2,
- size=self.size, width=self.film_width)
-
- self.rays = gpu.GPURays(pos, dir, max_alpha_depth=self.max_alpha_depth)
-
- self.pixels_gpu = ga.empty(self.npixels, dtype=np.uint32)
-
- self.movie = False
- self.movie_index = 0
- self.movie_dir = None
- self.hybrid_render = False
-
- def disable3d(self):
- pos, dir = from_film(self.point, axis1=self.axis1, axis2=self.axis2,
- size=self.size, width=self.film_width)
-
- self.rays = gpu.GPURays(pos, dir, max_alpha_depth=self.max_alpha_depth)
-
- self.display3d = False
-
- def enable3d(self):
- self.point1 = self.point-(self.mesh_diagonal_norm/60)*self.axis2
- self.point2 = self.point+(self.mesh_diagonal_norm/60)*self.axis2
-
- self.viewing_angle = 0.0
-
- pos1, dir1 = from_film(self.point1, axis1=self.axis1, axis2=self.axis2,
- size=self.size, width=self.film_width)
- pos2, dir2 = from_film(self.point2, axis1=self.axis1, axis2=self.axis2,
- size=self.size, width=self.film_width)
-
- self.rays1 = gpu.GPURays(pos1, dir1,
- max_alpha_depth=self.max_alpha_depth)
- self.rays2 = gpu.GPURays(pos2, dir2,
- max_alpha_depth=self.max_alpha_depth)
-
- scope_size = (self.size[0]//4, self.size[0]//4)
-
- scope_pos, scope_dir = from_film(self.point, axis1=self.axis1,
- axis2=self.axis2, size=scope_size,
- width=self.film_width/4.0)
-
- self.scope_rays = gpu.GPURays(scope_pos, scope_dir)
-
- self.scope_pixels_gpu = ga.empty(self.scope_rays.pos.size, dtype=np.uint32)
-
- self.pixels1_gpu = ga.empty(self.width*self.height, dtype=np.uint32)
- self.pixels2_gpu = ga.empty(self.width*self.height, dtype=np.uint32)
-
- self.distances_gpu = ga.empty(self.scope_rays.pos.size,
- dtype=np.float32)
- self.display3d = True
-
- def initialize_render(self):
- self.rng_states_gpu = gpu.get_rng_states(self.npixels)
- self.xyz_lookup1_gpu = ga.zeros(len(self.geometry.mesh.triangles),
- dtype=ga.vec.float3)
- self.xyz_lookup2_gpu = ga.zeros(len(self.geometry.mesh.triangles),
- dtype=ga.vec.float3)
-
- if self.display3d:
- self.image1_gpu = ga.zeros(self.npixels, dtype=ga.vec.float3)
- self.image2_gpu = ga.zeros(self.npixels, dtype=ga.vec.float3)
- else:
- self.image_gpu = ga.zeros(self.npixels, dtype=ga.vec.float3)
-
- self.source_position = self.point
-
- self.nimages = 0
- self.nlookup_calls = 0
- self.max_steps = 10
-
- def clear_xyz_lookup(self):
- self.xyz_lookup1_gpu.fill(ga.vec.make_float3(0.0,0.0,0.0))
- self.xyz_lookup2_gpu.fill(ga.vec.make_float3(0.0,0.0,0.0))
-
- self.nlookup_calls = 0
-
- def update_xyz_lookup(self, source_position):
- for wavelength, rgb_tuple in \
- zip([685.0, 545.0, 445.0],[(1,0,0),(0,1,0),(0,0,1)]):
- for i in range(self.xyz_lookup1_gpu.size//(self.npixels)+1):
- self.hybrid_funcs.update_xyz_lookup(np.int32(self.npixels), np.int32(self.xyz_lookup1_gpu.size), np.int32(i*self.npixels), ga.vec.make_float3(*source_position), self.rng_states_gpu, np.float32(wavelength), ga.vec.make_float3(*rgb_tuple), self.xyz_lookup1_gpu, self.xyz_lookup2_gpu, np.int32(self.max_steps), self.gpu_geometry.gpudata, block=(self.nblocks,1,1), grid=(self.npixels//self.nblocks+1,1))
-
- self.nlookup_calls += 1
-
- def clear_image(self):
- if self.display3d:
- self.image1_gpu.fill(ga.vec.make_float3(0.0,0.0,0.0))
- self.image2_gpu.fill(ga.vec.make_float3(0.0,0.0,0.0))
- else:
- self.image_gpu.fill(ga.vec.make_float3(0.0,0.0,0.0))
-
- self.nimages = 0
-
- def update_image_from_rays(self, image, rays):
- for wavelength, rgb_tuple in \
- zip([685.0, 545.0, 445.0],[(1,0,0),(0,1,0),(0,0,1)]):
- self.hybrid_funcs.update_xyz_image(np.int32(rays.pos.size), self.rng_states_gpu, rays.pos, rays.dir, np.float32(wavelength), ga.vec.make_float3(*rgb_tuple), self.xyz_lookup1_gpu, self.xyz_lookup2_gpu, image, np.int32(self.nlookup_calls), np.int32(self.max_steps), self.gpu_geometry.gpudata, block=(self.nblocks,1,1), grid=(rays.pos.size//self.nblocks+1,1))
-
- def update_image(self):
- if self.display3d:
- self.update_image_from_rays(self.image1_gpu, self.rays1)
- self.update_image_from_rays(self.image2_gpu, self.rays2)
- else:
- self.update_image_from_rays(self.image_gpu, self.rays)
-
- self.nimages += 1
-
- def process_image(self):
- if self.display3d:
- self.hybrid_funcs.process_image(np.int32(self.pixels1_gpu.size), self.image1_gpu, self.pixels1_gpu, np.int32(self.nimages), block=(self.nblocks,1,1), grid=((self.pixels1_gpu.size)//self.nblocks+1,1))
- self.hybrid_funcs.process_image(np.int32(self.pixels2_gpu.size), self.image2_gpu, self.pixels2_gpu, np.int32(self.nimages), block=(self.nblocks,1,1), grid=((self.pixels2_gpu.size)//self.nblocks+1,1))
- else:
- self.hybrid_funcs.process_image(np.int32(self.pixels_gpu.size), self.image_gpu, self.pixels_gpu, np.int32(self.nimages), block=(self.nblocks,1,1), grid=((self.pixels_gpu.size)//self.nblocks+1,1))
-
- def screenshot(self, dir='', start=0):
- root, ext = 'screenshot', 'png'
-
- for i in itertools.count(start):
- path = os.path.join(dir, '.'.join([root + str(i).zfill(5), ext]))
-
- if not os.path.exists(path):
- break
-
- pygame.image.save(self.screen, path)
- print 'image saved to %s' % path
-
- def rotate(self, phi, n):
- if self.display3d:
- self.rays1.rotate(phi, n)
- self.rays2.rotate(phi, n)
- self.scope_rays.rotate(phi, n)
-
- self.point1 = rotate(self.point1, phi, n)
- self.point2 = rotate(self.point2, phi, n)
- else:
- self.rays.rotate(phi, n)
-
- self.point = rotate(self.point, phi, n)
- self.axis1 = rotate(self.axis1, phi, n)
- self.axis2 = rotate(self.axis2, phi, n)
-
- if self.hybrid_render:
- self.clear_image()
-
- self.update()
-
- def rotate_around_point(self, phi, n, point, redraw=True):
- self.axis1 = rotate(self.axis1, phi, n)
- self.axis2 = rotate(self.axis2, phi, n)
-
- if self.display3d:
- self.rays1.rotate_around_point(phi, n, point)
- self.rays2.rotate_around_point(phi, n, point)
- self.scope_rays.rotate_around_point(phi, n, point)
- else:
- self.rays.rotate_around_point(phi, n, point)
-
- if redraw:
- if self.hybrid_render:
- self.clear_image()
-
- self.update()
-
- def translate(self, v, redraw=True):
- self.point += v
-
- if self.display3d:
- self.rays1.translate(v)
- self.rays2.translate(v)
- self.scope_rays.translate(v)
-
- self.point1 += v
- self.point2 += v
- else:
- self.rays.translate(v)
-
- if redraw:
- if self.hybrid_render:
- self.clear_image()
-
- self.update()
-
- def update_pixels(self, gpu_geometry=None, keep_last_render=False):
- if gpu_geometry is None:
- gpu_geometry = self.gpu_geometry
-
- if self.hybrid_render:
- while self.nlookup_calls < 10:
- self.update_xyz_lookup(self.source_position)
- self.update_image()
- self.process_image()
- else:
- if self.display3d:
- self.rays1.render(gpu_geometry, self.pixels1_gpu,
- self.alpha_depth, keep_last_render)
- self.rays2.render(gpu_geometry, self.pixels2_gpu,
- self.alpha_depth, keep_last_render)
- else:
- self.rays.render(gpu_geometry, self.pixels_gpu,
- self.alpha_depth, keep_last_render)
-
- def update_viewing_angle(self):
- if self.display3d:
- distance_gpu = ga.empty(self.scope_rays.pos.size, dtype=np.float32)
- distance_gpu.fill(1e9)
-
- for i, gpu_geometry in enumerate(self.gpu_geometries):
- self.gpu_funcs.distance_to_mesh(np.int32(self.scope_rays.pos.size), self.scope_rays.pos, self.scope_rays.dir, gpu_geometry.gpudata, distance_gpu, block=(self.nblocks,1,1), grid=(self.scope_rays.pos.size//self.nblocks,1))
-
- if i == 0:
- distance = distance_gpu.get()
- else:
- distance = np.minimum(distance, distance_gpu.get())
-
- baseline = distance.min()
-
- if baseline < 1e9:
- d1 = self.point1 - self.point
- v1 = d1/np.linalg.norm(d1)
- v1 *= baseline/60 - np.linalg.norm(d1)
-
- self.rays1.translate(v1)
-
- self.point1 += v1
-
- d2 = self.point2 - self.point
- v2 = d2/np.linalg.norm(d2)
- v2 *= baseline/60 - np.linalg.norm(d2)
-
- self.rays2.translate(v2)
-
- self.point2 += v2
-
- direction = np.cross(self.axis1,self.axis2)
- direction /= np.linalg.norm(direction)
- direction1 = self.point + direction*baseline - self.point1
- direction1 /= np.linalg.norm(direction1)
-
- new_viewing_angle = np.arccos(direction1.dot(direction))
-
- phi = new_viewing_angle - self.viewing_angle
-
- self.rays1.rotate_around_point(phi, self.axis1, self.point1)
- self.rays2.rotate_around_point(-phi, self.axis1, self.point2)
-
- self.viewing_angle = new_viewing_angle
-
- def update(self):
- if self.display3d:
- self.update_viewing_angle()
-
- n = len(self.gpu_geometries)
- for i, gpu_geometry in enumerate(self.gpu_geometries):
- if i == 0:
- self.update_pixels(gpu_geometry)
- else:
- self.update_pixels(gpu_geometry, keep_last_render=True)
-
- if self.display3d:
- pixels1 = self.pixels1_gpu.get()
- pixels2 = self.pixels2_gpu.get()
-
- if self.green_magenta:
- pixels = (pixels1 & 0x00ff00) | (pixels2 & 0xff00ff)
- else:
- pixels = (pixels1 & 0xff0000) | (pixels2 & 0x00ffff)
-
- alpha = ((0xff & (pixels1 >> 24)) + (0xff & (pixels2 >> 24)))/2
-
- pixels |= (alpha << 24)
- else:
- pixels = self.pixels_gpu.get()
-
- pygame.surfarray.blit_array(self.screen, pixels.reshape(self.size))
- if self.doom_mode:
- self.screen.blit(self.doom_hud, self.doom_rect)
- self.window.fill(0)
- self.window.blit(self.screen, (0,0))
- pygame.display.flip()
-
- if self.movie:
- self.screenshot(self.movie_dir, self.movie_index)
- self.movie_index += 1
-
- def loadlayer(self, layer):
- if layer is None:
- self.gpu_geometries = [self.gpu_geometry]
- else:
- try:
- gpu_geometry = self.bvh_layers[layer]
- except KeyError:
- geometry = build(bvh_mesh(self.geometry, layer))
- gpu_geometry = gpu.GPUGeometry(geometry, print_usage=False)
- self.bvh_layers[layer] = gpu_geometry
-
- self.gpu_geometries = [self.gpu_geometry, gpu_geometry]
-
- self.update()
-
- def process_event(self, event):
- if event.type == MOUSEBUTTONDOWN:
- if event.button == 4:
- v = self.scale*np.cross(self.axis1,self.axis2)/10.0
- self.translate(v)
-
- elif event.button == 5:
- v = -self.scale*np.cross(self.axis1,self.axis2)/10.0
- self.translate(v)
-
- elif event.button == 1:
- mouse_position = pygame.mouse.get_rel()
- self.clicked = True
-
- elif event.type == MOUSEBUTTONUP:
- if event.button == 1:
- self.clicked = False
-
- elif event.type == MOUSEMOTION and self.clicked:
- movement = np.array(pygame.mouse.get_rel())
-
- if (movement == 0).all():
- return
-
- length = np.linalg.norm(movement)
-
- mouse_direction = movement[0]*self.axis2 - movement[1]*self.axis1
- mouse_direction /= np.linalg.norm(mouse_direction)
-
- if pygame.key.get_mods() & (KMOD_LSHIFT | KMOD_RSHIFT):
- v = -mouse_direction*self.scale*length/float(self.width)
- self.translate(v)
- else:
- phi = np.float32(2*np.pi*length/float(self.width))
- n = rotate(mouse_direction, np.pi/2,
- np.cross(self.axis1,self.axis2))
-
- if pygame.key.get_mods() & KMOD_LCTRL:
- self.rotate_around_point(phi, n, self.point)
- else:
- self.rotate(phi, n)
-
- elif event.type == KEYDOWN:
- if event.key == K_LALT or event.key == K_RALT:
- if self.motion == 'coarse':
- self.scale = self.mesh_diagonal_norm/20.0
- self.motion = 'fine'
- elif self.motion == 'fine':
- self.scale = self.mesh_diagonal_norm/400.0
- self.motion = 'superfine'
- elif self.motion == 'superfine':
- self.scale = self.mesh_diagonal_norm
- self.motion = 'coarse'
-
- elif event.key == K_F6:
- self.clear_xyz_lookup()
- self.clear_image()
- self.source_position = self.point
-
- elif event.key == K_F7:
- for i in range(100):
- self.update_xyz_lookup(self.point)
- self.source_position = self.point
-
- elif event.key == K_F11:
- pygame.display.toggle_fullscreen()
-
- elif event.key == K_ESCAPE:
- self.done = True
- return
-
- elif event.key == K_EQUALS:
- if self.alpha_depth < self.max_alpha_depth:
- self.alpha_depth += 1
- self.update()
-
- elif event.key == K_MINUS:
- if self.alpha_depth > 1:
- self.alpha_depth -= 1
- self.update()
-
- elif event.key == K_PAGEDOWN:
- if self.currentlayer is None:
- self.currentlayer = self.unique_bvh_layers[-1]
- else:
- if self.currentlayer > np.min(self.unique_bvh_layers):
- self.currentlayer -= 1
- else:
- self.currentlayer = None
-
- self.loadlayer(self.currentlayer)
-
- elif event.key == K_PAGEUP:
- if self.currentlayer is None:
- self.currentlayer = self.unique_bvh_layers[0]
- else:
- if self.currentlayer < np.max(self.unique_bvh_layers):
- self.currentlayer += 1
- else:
- self.currentlayer = None
-
- self.loadlayer(self.currentlayer)
-
- elif event.key == K_3:
- if self.display3d:
- self.disable3d()
- else:
- self.enable3d()
- self.update()
-
- elif event.key == K_g:
- self.green_magenta = not self.green_magenta
- self.update()
-
- elif event.key == K_F12:
- self.screenshot()
-
- elif event.key == K_F5:
- if not hasattr(self, 'rng_states_gpu'):
- self.initialize_render()
-
- self.hybrid_render = not self.hybrid_render
- self.clear_image()
- self.update()
-
- elif event.key == K_m:
- if self.movie:
- encode_movie(self.movie_dir)
- self.movie_dir = None
- self.movie = False
- else:
- self.movie_index = 0
- self.movie_dir = tempfile.mkdtemp()
- self.movie = True
-
- elif event.type == pygame.SYSWMEVENT and self.spnav:
- # Space Navigator controls
- spnav_event = self.spnav_module.spnav_x11_event(event.event)
- if spnav_event is None:
- return
-
- if spnav_event.ev_type == self.spnav_module.SPNAV_EVENT_MOTION:
- if pygame.key.get_mods() & (KMOD_LSHIFT | KMOD_RSHIFT):
- accelerate_factor = 2.0
- else:
- accelerate_factor = 1.0
-
- v1 = self.axis1
- v2 = self.axis2
- v3 = np.cross(self.axis1,self.axis2)
-
- x, y, z = spnav_event.translation
- rx, ry, rz = spnav_event.rotation
-
- v = v2*x + v1*y + v3*z
- v *= self.scale / 5000.0 * accelerate_factor
-
- self.translate(v, redraw=False)
-
- axis = -v2*rx - v1*ry - v3*rz
-
- if (axis != 0).any():
- axis = axis.astype(float)
- length = np.linalg.norm(axis)
- angle = length * 0.0001 * accelerate_factor
- axis /= length
- self.rotate_around_point(angle, axis, self.point,
- redraw=False)
-
- if self.hybrid_render:
- self.clear_image()
-
- self.update()
- pygame.event.clear(pygame.SYSWMEVENT)
-
- elif spnav_event.ev_type == self.spnav_module.SPNAV_EVENT_BUTTON:
- if spnav_event.bnum == 0 and spnav_event.press:
- if not hasattr(self, 'rng_states_gpu'):
- self.initialize_render()
-
- self.hybrid_render = not self.hybrid_render
- self.clear_image()
- self.update()
- pygame.event.clear(pygame.SYSWMEVENT)
-
- elif event.type == pygame.QUIT:
- self.done = True
- return
-
- def run(self):
- self.window = pygame.display.set_mode(self.size)
- self.screen = pygame.Surface(self.size, pygame.SRCALPHA)
- pygame.display.set_caption('')
-
- self.init_gpu()
-
- if self.spnav:
- try:
- wm_info = pygame.display.get_wm_info()
- self.spnav_module.spnav_x11_open(wm_info['display'],
- wm_info['window'])
- pygame.event.set_allowed(pygame.SYSWMEVENT)
- #print 'Space Navigator support enabled.'
- except:
- self.spnav = False
-
- self.update()
-
- self.done = False
- self.clicked = False
-
- while not self.done:
- self.clock.tick(20)
-
- if self.hybrid_render and not self.clicked and \
- not pygame.event.peek(KEYDOWN):
- self.update()
-
- # Grab only last SYSWMEVENT (SpaceNav!) to avoid lagged controls
- for event in pygame.event.get(pygame.SYSWMEVENT)[-1:] + \
- pygame.event.get():
- self.process_event(event)
-
- if self.movie:
- encode_movie(self.movie_dir)
-
- pygame.display.quit()
- if self.spnav:
- self.spnav_module.spnav_close()
-
- self.context.pop()
-
-class EventViewer(Camera):
- def __init__(self, geometry, filename, **kwargs):
- Camera.__init__(self, geometry, **kwargs)
- self.rr = RootReader(filename)
-
- def render_particle_track(self):
- x = 0.01
- h = x*np.sqrt(3)/2
- pyramid = make.linear_extrude([-x/2,0,x/2], [-h/2,h/2,-h/2], h,
- [0]*3, [0]*3)
- marker = Solid(pyramid, vacuum, vacuum)
-
- geometry = Geometry()
- for pos in self.ev.photons_beg.pos[::100]:
- geometry.add_solid(marker, displacement=pos, rotation=make_rotation_matrix(np.random.uniform(0,2*np.pi), uniform_sphere()))
-
- geometry.build(bits=11)
- gpu_geometry = gpu.GPUGeometry(geometry)
-
- self.gpu_geometries = [self.gpu_geometry, gpu_geometry]
-
- def color_hit_pmts(self):
- self.gpu_geometry.reset_colors()
-
- hit = self.ev.channels.hit
- t = self.ev.channels.t
- q = self.ev.channels.q
-
- # Important: Compute range only with HIT channels
- solid_colors = map_to_color(q, range=(q[hit].min(),q[hit].max()))
- self.gpu_geometry.color_solids(hit, solid_colors)
-
- def process_event(self, event):
- if event.type == KEYDOWN:
- if event.key == K_PAGEUP:
- try:
- self.ev = self.rr.next()
- except StopIteration:
- pass
- else:
- self.color_hit_pmts()
-
- if self.ev.photons_beg is not None:
- self.render_particle_track()
-
- self.update()
- return
-
- elif event.key == K_PAGEDOWN:
- try:
- self.ev = self.rr.prev()
- except StopIteration:
- pass
- else:
- self.color_hit_pmts()
-
- if self.ev.photons_beg is not None:
- self.render_particle_track()
-
- self.update()
- return
-
- Camera.process_event(self, event)
-
-def view(obj, size=(800,600), **camera_kwargs):
- geometry = build(obj)
- camera = Camera(geometry, size, **camera_kwargs)
- camera.start()