summaryrefslogtreecommitdiff
path: root/view.py
diff options
context:
space:
mode:
Diffstat (limited to 'view.py')
-rwxr-xr-xview.py194
1 files changed, 162 insertions, 32 deletions
diff --git a/view.py b/view.py
index 2abb76d..0a92dbd 100755
--- a/view.py
+++ b/view.py
@@ -2,6 +2,7 @@
import os
import sys
import numpy as np
+import pickle
import pygame
from pygame.locals import *
@@ -10,6 +11,7 @@ import src
from camera import *
from geometry import *
from transform import *
+#from bvh_view import *
import time
@@ -17,16 +19,7 @@ from pycuda import autoinit
from pycuda.compiler import SourceModule
from pycuda import gpuarray
-def view(viewable, name='', bits=8):
- """
- Render `viewable` in a pygame window.
-
- Movement:
- - zoom: scroll the mouse wheel
- - rotate: click and drag the mouse
- - move: shift+click and drag the mouse
- """
-
+def to_geometry(viewable, bits):
if isinstance(viewable, Geometry):
geometry = viewable
geometry.build(bits)
@@ -39,7 +32,81 @@ def view(viewable, name='', bits=8):
geometry.add_solid(Solid(viewable))
geometry.build(bits)
else:
- sys.exit("can't display %s" % args[0])
+ raise Exception("can't convert %s to a geometry" % viewable)
+
+ return geometry
+
+def box(lower_bound, upper_bound):
+ dx, dy, dz = upper_bound - lower_bound
+
+ vertices = np.array([lower_bound,
+ lower_bound + (dx,0,0),
+ lower_bound + (dx,dy,0),
+ lower_bound + (0,dy,0),
+ lower_bound + (0,0,dz),
+ lower_bound + (dx,0,dz),
+ lower_bound + (dx,dy,dz),
+ lower_bound + (0,dy,dz)])
+
+ triangles = np.empty((12,3), dtype=np.int32)
+ # bottom
+ triangles[0] = (1,3,2)
+ triangles[1] = (1,4,3)
+ # top
+ triangles[2] = (5,7,6)
+ triangles[3] = (5,8,7)
+ # left
+ triangles[4] = (5,1,2)
+ triangles[5] = (5,2,6)
+ # right
+ triangles[6] = (3,4,8)
+ triangles[7] = (3,8,7)
+ # front
+ triangles[8] = (2,3,7)
+ triangles[9] = (2,7,6)
+ # back
+ triangles[10] = (1,5,8)
+ triangles[11] = (1,8,4)
+
+ triangles -= 1
+
+ return Mesh(vertices, triangles)
+
+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)
+
+ mesh = box(lower_bounds[0], upper_bounds[0])
+
+ for lower_bound, upper_bound in zip(lower_bounds, upper_bounds)[1:]:
+ mesh += box(lower_bound, upper_bound)
+
+ return mesh
+
+def view(viewable, name='', bits=8, load_bvh=False, camera_view=None):
+ """
+ Render `viewable` in a pygame window.
+
+ Movement:
+ - zoom: scroll the mouse wheel
+ - rotate: click and drag the mouse
+ - move: shift+click and drag the mouse
+ """
+
+ geometry = to_geometry(viewable, bits)
+
+ if load_bvh:
+ print 'loading bvh...'
+ bvhg = []
+
+ bvhg.append(geometry)
+
+ for layer in sorted(np.unique(geometry.layers)):
+ print 'building layer %i' % layer
+ bvhg.append(to_geometry(bvh_mesh(geometry, layer), bits))
lower_bound = np.array([np.min(geometry.mesh[:][:,:,0]),
np.min(geometry.mesh[:][:,:,1]),
@@ -65,27 +132,36 @@ def view(viewable, name='', bits=8):
screen = pygame.display.set_mode(size)
pygame.display.set_caption(name)
- camera = Camera(size)
+ if camera_view is None:
+ camera = Camera(size)
- diagonal = np.linalg.norm(upper_bound-lower_bound)
+ diagonal = np.linalg.norm(upper_bound-lower_bound)
- point = np.array([0, diagonal*1.75, (lower_bound[2]+upper_bound[2])/2])
- axis1 = np.array([1,0,0], dtype=np.double)
- axis2 = np.array([0,0,1], dtype=np.double)
+ point = np.array([0, diagonal*1.75, (lower_bound[2]+upper_bound[2])/2])
+ axis1 = np.array([1,0,0], dtype=np.double)
+ axis2 = np.array([0,0,1], dtype=np.double)
- camera.position(point)
+ camera.position(point)
- origins, directions = camera.get_rays()
+ origins, directions = camera.get_rays()
- origins_float3 = np.empty(origins.shape[0], dtype=gpuarray.vec.float3)
- origins_float3['x'] = origins[:,0]
- origins_float3['y'] = origins[:,1]
- origins_float3['z'] = origins[:,2]
+ origins_float3 = np.empty(origins.shape[0], dtype=gpuarray.vec.float3)
+ origins_float3['x'] = origins[:,0]
+ origins_float3['y'] = origins[:,1]
+ origins_float3['z'] = origins[:,2]
- directions_float3 = np.empty(directions.shape[0], dtype=gpuarray.vec.float3)
- directions_float3['x'] = directions[:,0]
- directions_float3['y'] = directions[:,1]
- directions_float3['z'] = directions[:,2]
+ directions_float3 = np.empty(directions.shape[0], dtype=gpuarray.vec.float3)
+ directions_float3['x'] = directions[:,0]
+ directions_float3['y'] = directions[:,1]
+ directions_float3['z'] = directions[:,2]
+ else:
+ f = open(camera_view, 'rb')
+ origins_float3 = pickle.load(f)
+ directions_float3 = pickle.load(f)
+ point = pickle.load(f)
+ axis1 = pickle.load(f)
+ axis2 = pickle.load(f)
+ f.close()
origins_gpu = cuda.to_device(origins_float3)
directions_gpu = cuda.to_device(directions_float3)
@@ -104,7 +180,7 @@ def view(viewable, name='', bits=8):
cuda.Context.synchronize()
elapsed = time.time() - t0
- print 'elapsed %f sec' % elapsed
+ #print 'elapsed %f sec' % elapsed
cuda.memcpy_dtoh(pixels, pixels_gpu)
pygame.surfarray.blit_array(screen, pixels.reshape(size))
@@ -116,6 +192,8 @@ def view(viewable, name='', bits=8):
clicked = False
shift = False
+ current_layer = 0
+
while not done:
for event in pygame.event.get():
if event.type == MOUSEBUTTONDOWN:
@@ -187,6 +265,57 @@ def view(viewable, name='', bits=8):
done = True
break
+ if event.key == K_PAGEUP:
+ try:
+ if current_layer+1 >= len(bvhg):
+ raise IndexError
+
+ geometry = bvhg[current_layer+1]
+ current_layer += 1
+
+ geometry.load(module, color=True)
+ render()
+ except IndexError:
+ print 'no further layers to view'
+
+ if event.key == K_PAGEDOWN:
+ try:
+ if current_layer-1 < 0:
+ raise IndexError
+
+ geometry = bvhg[current_layer-1]
+ current_layer -= 1
+
+ geometry.load(module, color=True)
+ render()
+ except IndexError:
+ print 'no further layers to view'
+
+ if event.key == K_F11:
+ if name == '':
+ root, ext = 'camera_view', 'pkl'
+ else:
+ root, ext = name + '_camera_view', 'pkl'
+
+ filename = '.'.join([root, ext])
+
+ i = 1
+ while os.path.exists(filename):
+ filename = '.'.join([root + str(i), ext])
+ i += 1
+
+ f = open(filename, 'wb')
+ cuda.memcpy_dtoh(origins_float3, origins_gpu)
+ cuda.memcpy_dtoh(directions_float3, directions_gpu)
+ pickle.dump(origins_float3, f)
+ pickle.dump(directions_float3, f)
+ pickle.dump(point, f)
+ pickle.dump(axis1, f)
+ pickle.dump(axis2, f)
+ f.close()
+
+ print 'camera view saved to %s' % filename
+
if event.key == K_F12:
if name == '':
root, ext = 'screenshot', 'png'
@@ -220,6 +349,10 @@ if __name__ == '__main__':
parser = optparse.OptionParser('%prog filename.stl')
parser.add_option('-b', '--bits', type='int', dest='bits',
help='bits for z-ordering space axes', default=8)
+ parser.add_option('-l', action='store_true', dest='load_bvh',
+ help='load bounding volumes', default=False)
+ parser.add_option('-v', '--camera_view', dest='camera_view',
+ help='load a camera view', default=None)
options, args = parser.parse_args()
if len(args) < 1:
@@ -229,16 +362,13 @@ if __name__ == '__main__':
root, ext = os.path.splitext(tail)
if ext.lower() == '.stl':
- geometry = Geometry()
- geometry.add_solid(Solid(mesh_from_stl(args[0])))
- geometry.build(options.bits)
- view(geometry, tail)
+ view(mesh_from_stl(args[0]), root, options.bits, options.load_bvh, options.camera_view)
else:
import inspect
members = dict(inspect.getmembers(detectors) + inspect.getmembers(solids))
if args[0] in members:
- view(members[args[0]], args[0], options.bits)
+ view(members[args[0]], args[0], options.bits, options.load_bvh, options.camera_view)
else:
sys.exit("couldn't find object %s" % args[0])