diff options
Diffstat (limited to 'view.py')
-rwxr-xr-x | view.py | 194 |
1 files changed, 162 insertions, 32 deletions
@@ -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]) |