diff options
Diffstat (limited to 'geometry.py')
-rw-r--r-- | geometry.py | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/geometry.py b/geometry.py index d1bec2a..fdc361c 100644 --- a/geometry.py +++ b/geometry.py @@ -2,6 +2,7 @@ import numpy as np import numpy.ma as ma import pycuda.driver as cuda from pycuda import gpuarray +from mesh import Mesh def interleave(arr, bits): """ @@ -56,16 +57,23 @@ class Geometry(object): self.solids.append(solid) def build(self, bits=8): - self.mesh = np.concatenate([solid.build() for solid in self.solids]) + vertices = [] + triangles = [] + for solid in self.solids: + triangles.extend(solid.mesh.triangles + len(vertices)) + vertices.extend(np.inner(solid.mesh.vertices, solid.rotation) + \ + solid.displacement) - zvalues_mesh = morton_order(self.mesh, bits) + self.mesh = Mesh(vertices, triangles) + + zvalues_mesh = morton_order(self.mesh[:], bits) reorder = np.argsort(zvalues_mesh) zvalues_mesh = zvalues_mesh[reorder] if (np.diff(zvalues_mesh) < 0).any(): raise Exception('zvalues_mesh out of order.') - self.mesh = self.mesh[reorder] + self.mesh.triangles = self.mesh.triangles[reorder] material1 = np.concatenate([solid.material1 for solid in self.solids]) material2 = np.concatenate([solid.material2 for solid in self.solids]) @@ -96,9 +104,8 @@ class Geometry(object): for i, surface in enumerate(surface2[reorder]): self.surface2_index[i] = self.surfaces.index(surface) - self.solid_index = \ - np.concatenate([np.tile(i, len(solid.mesh)) \ - for i in range(len(self.solids))])[reorder] + self.solid_id = np.concatenate([np.tile(solid.id, len(solid.mesh)) \ + for solid in self.solids])[reorder] unique_zvalues = np.unique(zvalues_mesh) zvalues = np.empty(unique_zvalues.size, dtype=np.uint64) @@ -112,13 +119,13 @@ class Geometry(object): i1 = np.searchsorted(zvalues_mesh, z) i2 = np.searchsorted(zvalues_mesh, z, side='right') - self.lower_bounds[i] = [np.min(self.mesh[i1:i2,:,0]), - np.min(self.mesh[i1:i2,:,1]), - np.min(self.mesh[i1:i2,:,2])] + self.lower_bounds[i] = [np.min(self.mesh[i1:i2][:,:,0]), + np.min(self.mesh[i1:i2][:,:,1]), + np.min(self.mesh[i1:i2][:,:,2])] - self.upper_bounds[i] = [np.max(self.mesh[i1:i2,:,0]), - np.max(self.mesh[i1:i2,:,1]), - np.max(self.mesh[i1:i2,:,2])] + self.upper_bounds[i] = [np.max(self.mesh[i1:i2][:,:,0]), + np.max(self.mesh[i1:i2][:,:,1]), + np.max(self.mesh[i1:i2][:,:,2])] self.node_map[i] = i1 self.node_length[i] = i2-i1 @@ -178,10 +185,16 @@ class Geometry(object): bind it to the appropriate textures, and return a list of the texture references. """ - mesh = np.empty(self.mesh.shape[0]*3, dtype=gpuarray.vec.float4) - mesh['x'] = self.mesh[:,:,0].flatten() - mesh['y'] = self.mesh[:,:,1].flatten() - mesh['z'] = self.mesh[:,:,2].flatten() + vertices = np.empty(len(self.mesh.vertices), dtype=gpuarray.vec.float4) + vertices['x'] = self.mesh.vertices[:,0] + vertices['y'] = self.mesh.vertices[:,1] + vertices['z'] = self.mesh.vertices[:,2] + + triangles = \ + np.empty(len(self.mesh.triangles), dtype=gpuarray.vec.uint4) + triangles['x'] = self.mesh.triangles[:,0] + triangles['y'] = self.mesh.triangles[:,1] + triangles['z'] = self.mesh.triangles[:,2] lower_bounds = np.empty(self.lower_bounds.shape[0], dtype=gpuarray.vec.float4) lower_bounds['x'] = self.lower_bounds[:,0] @@ -193,28 +206,32 @@ class Geometry(object): upper_bounds['y'] = self.upper_bounds[:,1] upper_bounds['z'] = self.upper_bounds[:,2] - self.mesh_gpu = cuda.to_device(mesh) + self.vertices_gpu = cuda.to_device(vertices) + self.triangles_gpu = cuda.to_device(triangles) self.lower_bounds_gpu = cuda.to_device(lower_bounds) self.upper_bounds_gpu = cuda.to_device(upper_bounds) self.node_map_gpu = cuda.to_device(self.node_map) self.node_length_gpu = cuda.to_device(self.node_length) - mesh_tex = module.get_texref('mesh') + vertices_tex = module.get_texref('vertices') + triangles_tex = module.get_texref('triangles') lower_bounds_tex = module.get_texref('lower_bounds') upper_bounds_tex = module.get_texref('upper_bounds') node_map_tex = module.get_texref('node_map') node_length_tex = module.get_texref('node_length') - mesh_tex.set_address(self.mesh_gpu, mesh.nbytes) + vertices_tex.set_address(self.vertices_gpu, vertices.nbytes) + triangles_tex.set_address(self.triangles_gpu, triangles.nbytes) lower_bounds_tex.set_address(self.lower_bounds_gpu, lower_bounds.nbytes) upper_bounds_tex.set_address(self.upper_bounds_gpu, upper_bounds.nbytes) node_map_tex.set_address(self.node_map_gpu, self.node_map.nbytes) node_length_tex.set_address(self.node_length_gpu, self.node_length.nbytes) - mesh_tex.set_format(cuda.array_format.FLOAT, 4) + vertices_tex.set_format(cuda.array_format.FLOAT, 4) + triangles_tex.set_format(cuda.array_format.UNSIGNED_INT32, 4) lower_bounds_tex.set_format(cuda.array_format.FLOAT, 4) upper_bounds_tex.set_format(cuda.array_format.FLOAT, 4) node_map_tex.set_format(cuda.array_format.UNSIGNED_INT32, 1) node_length_tex.set_format(cuda.array_format.UNSIGNED_INT32, 1) - return [mesh_tex, lower_bounds_tex, upper_bounds_tex, node_map_tex, node_length_tex] + return [vertices_tex, triangles_tex, lower_bounds_tex, upper_bounds_tex, node_map_tex, node_length_tex] |