summaryrefslogtreecommitdiff
path: root/camera.py
diff options
context:
space:
mode:
Diffstat (limited to 'camera.py')
-rwxr-xr-xcamera.py99
1 files changed, 98 insertions, 1 deletions
diff --git a/camera.py b/camera.py
index 98ea1fc..7d23be5 100755
--- a/camera.py
+++ b/camera.py
@@ -5,11 +5,14 @@ from threading import Thread, Lock
import os
import sys
from chroma.color import map_wavelength, map_to_color
+from chroma.geometry import Mesh, Solid, Geometry
+import chroma.make as make
import matplotlib.pyplot as plt
from chroma.gpu import GPU, CUDAFuncs
from chroma.tools import timeit
from chroma.transform import rotate
+from chroma.optics import vacuum, lambertian_surface
import pygame
from pygame.locals import *
@@ -22,6 +25,65 @@ from subprocess import call
import shutil
import tempfile
+def buildable(identifier):
+ """
+ Create a decorator which tags a function as buildable and assigns the
+ identifying string `identifier`.
+
+ Example:
+ >>> @buildable('my_sphere')
+ >>> def build_my_sphere():
+ >>> g = Geometry()
+ >>> g.add_solid(Solid(sphere(), vacuum, water))
+ >>> return g
+ """
+ def tag_as_buildable(func):
+ func.buildable = True
+ func.identifier = identifier
+ return func
+ return tag_as_buildable
+
+def build(obj, bits):
+ """Construct and build a geometry from `obj`."""
+ if inspect.isfunction(obj):
+ try:
+ if obj.buildable:
+ obj = obj()
+ except AttributeError:
+ raise Exception('function %s is not buildable.' % obj.__name__)
+
+ 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, surface=lambertian_surface, color=0x99ffffff))
+ else:
+ raise Exception('cannot build type %s' % type(obj))
+
+ geometry.build(bits)
+
+ 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 count():
@@ -59,6 +121,10 @@ class Camera(Thread):
self.device_id = device_id
self.size = size
+ self.unique_bvh_layers = np.unique(self.geometry.layers)
+ self.currentlayer = None
+ self.bvh_layers = {self.currentlayer : self.geometry}
+
try:
import spnav as spnav_module
self.spnav_module = spnav_module
@@ -231,6 +297,16 @@ class Camera(Thread):
self.screenshot(self.movie_dir, self.movie_index)
self.movie_index += 1
+ def loadlayer(self, layer):
+ try:
+ layergeometry = self.bvh_layers[layer]
+ except KeyError:
+ layergeometry = build(bvh_mesh(self.geometry, layer),8)
+ self.bvh_layers[layer] = layergeometry
+
+ self.gpu.load_geometry(layergeometry)
+ self.update()
+
def process_event(self, event):
if event.type == MOUSEBUTTONDOWN:
if event.button == 4:
@@ -310,6 +386,28 @@ class Camera(Thread):
self.done = True
return
+ 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_F12:
self.screenshot()
@@ -487,7 +585,6 @@ if __name__ == '__main__':
import chroma.detectors
import chroma.scenes
from chroma.stl import mesh_from_stl
- from chroma.view import build
parser = optparse.OptionParser('%prog filename.stl')
parser.add_option('-b', '--bits', type='int', dest='bits',