summaryrefslogtreecommitdiff
path: root/geometry.py
diff options
context:
space:
mode:
Diffstat (limited to 'geometry.py')
-rw-r--r--geometry.py57
1 files changed, 31 insertions, 26 deletions
diff --git a/geometry.py b/geometry.py
index 111006f..3181176 100644
--- a/geometry.py
+++ b/geometry.py
@@ -1,13 +1,15 @@
import numpy as np
import pycuda.driver as cuda
from pycuda import gpuarray
+from itertools import imap
+from itertoolset import unique_everseen
# all material/surface properties are interpolated at these
# wavelengths when they are sent to the gpu
standard_wavelengths = np.arange(200, 810, 20).astype(np.float32)
class Mesh(object):
- def __init__(self, vertices, triangles):
+ def __init__(self, vertices, triangles, remove_duplicate_vertices=False):
vertices = np.asarray(vertices, dtype=np.float32)
triangles = np.asarray(triangles, dtype=np.int32)
@@ -27,8 +29,20 @@ class Mesh(object):
self.vertices = vertices
self.triangles = triangles
- def build(self):
- return self.vertices[self.triangles]
+ if remove_duplicate_vertices:
+ self.remove_duplicate_vertices()
+
+ def remove_duplicate_vertices(self):
+ unique_vertices = list(unique_everseen(map(tuple, self.vertices)))
+
+ if len(unique_vertices) == len(self.vertices):
+ return
+
+ for i in range(len(self.triangles)):
+ for j in range(3):
+ self.triangles[i,j] = unique_vertices.index(tuple(self.vertices[self.triangles[i,j]]))
+
+ self.vertices = np.array(unique_vertices)
def __getitem__(self, key):
return self.vertices[self.triangles[key]]
@@ -216,32 +230,24 @@ class Geometry(object):
self.materials = \
list(np.unique(np.concatenate([material1, material2])))
- self.material1_index = np.empty(len(self.mesh), dtype=np.int32)
- self.material2_index = np.empty(len(self.mesh), dtype=np.int32)
+ material_lookup = dict(zip(self.materials, range(len(self.materials))))
+
+ self.material1_index = \
+ np.fromiter(imap(material_lookup.get, material1[reorder]), dtype=np.int32)
- for i, material in enumerate(material1[reorder]):
- if material is not None:
- self.material1_index[i] = self.materials.index(material)
- else:
- self.material1_index[i] = -1
+ self.material2_index = \
+ np.fromiter(imap(material_lookup.get, material2[reorder]), dtype=np.int32)
- for i, material in enumerate(material2[reorder]):
- if material is not None:
- self.material2_index[i] = self.materials.index(material)
- else:
- self.material2_index[i] = -1
+ surfaces = np.concatenate([solid.surface for solid in self.solids])
- surface = np.concatenate([solid.surface for solid in self.solids])
+ self.unique_surfaces = list(np.unique(surfaces))
- self.surfaces = list(np.unique(surface))
+ surface_lookup = dict(zip(self.unique_surfaces, range(len(self.unique_surfaces))))
- self.surface_index = np.empty(len(self.mesh), dtype=np.int32)
+ self.surface_index = \
+ np.fromiter(imap(surface_lookup.get, surfaces[reorder]), dtype=np.int32)
- for i, surface in enumerate(surface[reorder]):
- if surface is not None:
- self.surface_index[i] = self.surfaces.index(surface)
- else:
- self.surface_index[i] = -1
+ self.surface_index[self.surface_index == self.unique_surfaces.index(None)] = -1
self.colors = \
np.concatenate([solid.color for solid in self.solids])[reorder]
@@ -337,8 +343,7 @@ class Geometry(object):
for i, material in enumerate(self.materials):
if material is None:
if color is False:
- print 'warning: some triangles have no associated material.'
-
+ raise Exception('one or more triangles is missing a material.')
continue
refractive_index = np.interp(standard_wavelengths, material.refractive_index[:,0], material.refractive_index[:,1]).astype(np.float32)
@@ -352,7 +357,7 @@ class Geometry(object):
set_material(np.int32(i), material.refractive_index_gpu, material.absorption_length_gpu, material.scattering_length_gpu, block=(1,1,1), grid=(1,1))
set_surface = module.get_function('set_surface')
- for i, surface in enumerate(self.surfaces):
+ for i, surface in enumerate(self.unique_surfaces):
if surface is None:
continue