def setUp(self): b = ((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0)) points = [((sin(0.1*t), sin(0.2*t), sin(0.3*t)), t) for t in range(50)] self.o1 = Octree(b) self.o1.extend(points) self.o2 = octree_from_list(b, points)
def expand(points, distance): expanded = Octree(expand_bounds(points.bounds, distance)) points_list = list(points) d_angle = 0.2 max_angle = 0.600000001 all_norm_offsets = [(0, 0, 1)] distance_slightly_reduced = 0.9999 * distance for theta in [d_angle * (i + 1) for i in range(int(max_angle / d_angle))]: sin_theta = sin(theta) cos_theta = cos(theta) num_phis = int(round(2 * pi * sin_theta / d_angle)) for phi in [2 * pi * j / num_phis for j in range(num_phis)]: all_norm_offsets.append( (sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta))) num_points = len(points_list) hits = 0 for i, (point, normal) in enumerate(points_list): if i % 100 == 0: print "%0.2f%% complete of %i hits from %i starting points" % ( (100.0 * i) / num_points, hits, i) n = Vector(*normal) nn = n.normalise() a, b = nn.get_orthogonal_vectors() for oa, ob, on in all_norm_offsets: new_point = [ pc + on * nc * distance + oa * ac * distance + ob * bc * distance for pc, nc, ac, bc in zip(point, n, a, b) ] try: points.by_distance_from_point( new_point, distance_slightly_reduced).next() except StopIteration: expanded.insert(new_point, normal) hits += 1 return expanded
def setUp(self): self.coords1 = set((sin(0.1*t), sin(0.2*t), sin(0.3*t)) for t in xrange(50)) self.o1 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) self.o1.extend((p, None) for p in self.coords1) self.coords2 = set((sin(0.1*t), sin(0.2*t), sin(0.3*t)) for t in xrange(150, 200)) self.o2 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) self.o2.extend((p, None) for p in self.coords2)
def setUp(self): self.coords1 = set( (sin(0.1 * t), sin(0.2 * t), sin(0.3 * t)) for t in xrange(50)) self.o1 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) self.o1.extend((p, None) for p in self.coords1) self.coords2 = set((sin(0.1 * t), sin(0.2 * t), sin(0.3 * t)) for t in xrange(150, 200)) self.o2 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) self.o2.extend((p, None) for p in self.coords2)
def copy_point_cloud_excluding(points, excluding_points, distance): clean_skin = Octree(points.bounds) points_list = points.by_distance_from_point( (0, 0, 0) ) #Points do not actually need to be ordered, perhaps they can be found more efficiently for ignore, point, normal in points_list: try: excluding_points.by_distance_from_point(point, distance).next() except StopIteration: clean_skin.insert(point, normal) return clean_skin
class BuilderTests(TestCase): def setUp(self): b = ((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0)) points = [((sin(0.1*t), sin(0.2*t), sin(0.3*t)), t) for t in xrange(50)] self.o1 = Octree(b) self.o1.extend(points) self.o2 = octree_from_list(b, points) def test_equality(self): self.assertEqual(self.o1, self.o2)
class BuilderTests(TestCase): def setUp(self): b = ((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0)) points = [((sin(0.1*t), sin(0.2*t), sin(0.3*t)), t) for t in range(50)] self.o1 = Octree(b) self.o1.extend(points) self.o2 = octree_from_list(b, points) def test_equality(self): self.assertEqual(self.o1, self.o2)
def setUp(self): b = ((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0)) points = [((sin(0.1*t), sin(0.2*t), sin(0.3*t)), t) for t in xrange(50)] self.o1 = Octree(b) self.o1.extend(points) self.o2 = octree_from_list(b, points)
def test_union(self): p = (0.236, -0.532, -0.117) l = [c for (_, c, _) in self.o.by_distance_from_point(p)] o1 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) o1.extend((p, True) for p in l[:25]) self.assertEqual(len(o1), 25) o2 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) o2.extend((p, True) for p in l[25:]) self.assertEqual(len(o2), 25) self.assertEqual(o1.simple_union(o2), self.o)
def __call__(self, outerROI, triangle): #Create an Octree from inner surface minx = min([v.x for v in self.inner_mesh.vertices]) - 0.01 maxx = max([v.x for v in self.inner_mesh.vertices]) + 0.01 miny = min([v.y for v in self.inner_mesh.vertices]) - 0.01 maxy = max([v.y for v in self.inner_mesh.vertices]) + 0.01 minz = min([v.z for v in self.inner_mesh.vertices]) - 0.01 maxz = max([v.z for v in self.inner_mesh.vertices]) + 0.01 points = Octree(((minx, maxx), (miny, maxy), (minz, maxz))) for v in self.inner_mesh.vertices: points.insert((v.x, v.y, v.z), v) #Copy extend to inner surface inner_avoid_edges = [] outer_avoid_edges = [] join_strip = [] for roi in outerROI.rois: for start_outer, end_outer in zip(roi.points, roi.points[1:] + [roi.points[0]]): start_outer_vertex = outerROI.mesh.faces[start_outer[3]].nearest_vertex(*start_outer[:3]) end_outer_vertex = outerROI.mesh.faces[end_outer[3]].nearest_vertex(*end_outer[:3]) start_distance, start_coords, start_inner = points.by_distance_from_point((start_outer_vertex.x, start_outer_vertex.y, start_outer_vertex.z)).next() end_distance, end_coords, end_inner = points.by_distance_from_point((end_outer_vertex.x, end_outer_vertex.y, end_outer_vertex.z)).next() inner_strip = [x.edge for x in self.inner_mesh.get_vertex_path(start_inner, end_inner)] outer_strip = [x.edge for x in self.outer_mesh.get_vertex_path(start_outer_vertex,end_outer_vertex)] inner_avoid_edges = inner_avoid_edges + inner_strip outer_avoid_edges = outer_avoid_edges + outer_strip join_strip = join_strip + [(start_inner, inner_strip, start_outer_vertex, outer_strip)] triangle_distance, triangle_coords, triangle_vertex_inner = points.by_distance_from_point(triangle.vertices[0]).next() start_triangle = triangle_vertex_inner.faces[0] innerMesh = self.inner_mesh.cloneSubVol(start_triangle, inner_avoid_edges) print outer_avoid_edges outerMesh = self.outer_mesh.cloneSubVol(triangle, outer_avoid_edges) newMesh = mesh.Mesh() newMesh.add_mesh(outerMesh) newMesh.add_mesh(innerMesh, invert = True) for current_inner, inner_strip, current_outer, outer_strip in join_strip: inner_list = list_vertices(newMesh, current_inner, inner_strip) outer_list = list_vertices(newMesh, current_outer, outer_strip) while len(inner_list) > 1 or len(outer_list) > 1: if len(outer_list) == 1 or (len(inner_list) > 1 and (inner_list[0] - outer_list[1]).magnitude() > (inner_list[1] - outer_list[0]).magnitude()): newMesh.add_face(inner_list[0], inner_list[1], outer_list[0]) inner_list = inner_list[1:] else: newMesh.add_face(inner_list[0], outer_list[1], outer_list[0]) outer_list = outer_list[1:] for edge in newMesh.edges.values(): if edge.lface is None or edge.rface is None: print edge print newMesh.closed() stlwriter = mesh.fileio.StlWriter(mesh.fileio.STL_FORMAT_BINARY) stlwriter.write(newMesh, "Mould", self.base_file + "mould.stl")
def __call__(self, roiGUI, triangle): avoid_edges = [] for roi in roiGUI.rois: avoid = [] for paths in roi.paths: start = None previous_vertex = None for path in paths: for point in path.points(): if start != point:#if first point != last point vertex = point.splitmesh(self.mesh) if previous_vertex is not None: avoid.append(self.mesh.edges[(vertex, previous_vertex)])#Need an edge not a vertex!! previous_vertex = vertex if start is None: start = point avoid_edges.append(avoid) #avoid_edges = roiGUI.get_avoidance_edges() #Save the cut out mesh to a file roughcut = self.mesh.cloneSubVol(triangle, avoid_edges) print "Saving" mesh.fileio.write_ply(roughcut, self.base_file + "rough.ply") #Expand cut out mesh and save that to a file called external minx = min([v.x for v in roughcut.vertices]) - 0.01 maxx = max([v.x for v in roughcut.vertices]) + 0.01 miny = min([v.y for v in roughcut.vertices]) - 0.01 maxy = max([v.y for v in roughcut.vertices]) + 0.01 minz = min([v.z for v in roughcut.vertices]) - 0.01 maxz = max([v.z for v in roughcut.vertices]) + 0.01 points = Octree(((minx, maxx), (miny, maxy), (minz, maxz))) for v in roughcut.vertices: n = v.normal() points.insert((v.x, v.y, v.z), (n.x, n.y, n.z)) external = expand(points, MOULD_THICKNESS) make_ply(external, self.base_file + "external", poisson_depth = POISSON_DEPTH) make_ply(points, self.base_file + "external_base", poisson_depth = POISSON_DEPTH)
def onSelect(self, triangle, m, rois): # XXX: self.base_file = "blahblah" avoid_edges = self.get_avoidance_edges(rois) #Save the cut out mesh to a file roughcut = m.cloneSubVol(triangle, avoid_edges) self.controller.addMesh(roughcut, "Rough") self.controller.parent.meshPanel.addMesh("Rough") self.controller.parent.meshPanel.hideMesh("Skin") return print "Saving" mesh.fileio.write_ply(roughcut, self.base_file + "rough.ply") #Expand cut out mesh and save that to a file called external minx = min([v.x for v in roughcut.vertices]) - 0.01 maxx = max([v.x for v in roughcut.vertices]) + 0.01 miny = min([v.y for v in roughcut.vertices]) - 0.01 maxy = max([v.y for v in roughcut.vertices]) + 0.01 minz = min([v.z for v in roughcut.vertices]) - 0.01 maxz = max([v.z for v in roughcut.vertices]) + 0.01 points = Octree(((minx, maxx), (miny, maxy), (minz, maxz))) for v in roughcut.vertices: n = v.normal() points.insert((v.x, v.y, v.z), (n.x, n.y, n.z)) external = expand(points, MOULD_THICKNESS) make_ply(external, self.base_file + "external", poisson_depth = POISSON_DEPTH) make_ply(points, self.base_file + "external_base", poisson_depth = POISSON_DEPTH) print "Done"
class BinaryTests(TestCase): def setUp(self): self.coords1 = set( (sin(0.1 * t), sin(0.2 * t), sin(0.3 * t)) for t in xrange(50)) self.o1 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) self.o1.extend((p, None) for p in self.coords1) self.coords2 = set((sin(0.1 * t), sin(0.2 * t), sin(0.3 * t)) for t in xrange(150, 200)) self.o2 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) self.o2.extend((p, None) for p in self.coords2) def test_proximity(self): l1 = [] for c1 in self.coords1: (d, c2, _) = self.o2.nearest_to_point(c1) l1.append((d, c1, c2, None, None)) l1.sort() l2 = list(self.o1.by_proximity(self.o2)) self.assertEqual(l1, l2) l1b = list(t for t in l1 if t[0] < 0.1) l2b = list(self.o1.by_proximity(self.o2, 0.1)) self.assertEqual(l1b, l2b) def test_isolation(self): l1 = [] for c1 in self.coords1: (d, c2, _) = self.o2.nearest_to_point(c1) l1.append((d, c1, c2, None, None)) l1.sort(reverse=True) l2 = list(self.o1.by_isolation(self.o2)) self.assertEqual(l1, l2) l1b = list(t for t in l1 if t[0] > 0.3) l2b = list(self.o1.by_isolation(self.o2, 0.3)) self.assertEqual(l1b, l2b) def test_pairs_by_distance(self): l1 = [] for c1 in self.coords1: for c2 in self.coords2: d = euclidean_point_point(c1, c2) if d < 0.1: l1.append((d, c1, c2, None, None)) l1.sort() l2 = list(self.o1.pairs_by_distance(self.o2, 0.1)) self.assertEqual(l1, l2) def test_pairs_nearby(self): s1 = set() for c1 in self.coords1: for c2 in self.coords2: d = euclidean_point_point(c1, c2) if d < 0.1: s1.add((c1, c2, None, None)) s2 = set(self.o1.pairs_nearby(self.o2, 0.1)) self.assertEqual(s1, s2)
def setUp(self): self.coords = set((sin(0.1*t), sin(0.2*t), sin(0.3*t)) for t in xrange(50)) self.o = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) self.o.extend((p, True) for p in self.coords)
def makepoints(t, zpositions, posX, posY, spacingX, spacingY, level): t = t.astype(numpy.int16) mean = (t[1:, 1:, 1:] + t[1:, 1:, :-1] + t[1:, :-1, 1:] + t[1:, :-1, :-1] + t[:-1, 1:, 1:] + t[:-1, 1:, :-1] + t[:-1, :-1, 1:] + t[:-1, :-1, :-1]) / 8 gz = (t[1:, 1:, 1:] + t[1:, 1:, :-1] + t[1:, :-1, 1:] + t[1:,:-1,:-1] \ - t[:-1, 1:, 1:] - t[:-1, 1:, :-1] - t[:-1, :-1, 1:] - t[:-1,:-1,:-1]) / 4 #print "gz", gz gy = (t[1:, 1:, 1:] + t[1:, 1:, :-1] - t[1:, :-1, 1:] - t[1:,:-1,:-1] \ + t[:-1, 1:, 1:] + t[:-1, 1:, :-1] - t[:-1, :-1, 1:] - t[:-1,:-1,:-1]) / 4 gx = (t[1:, 1:, 1:] - t[1:, 1:, :-1] + t[1:, :-1, 1:] - t[1:,:-1,:-1] \ + t[:-1, 1:, 1:] - t[:-1, 1:, :-1] + t[:-1, :-1, 1:] - t[:-1,:-1,:-1]) / 4 #print t[:2, :2, :2] #print mean[:1, :1, :1] #print "gx", gx[:1, :1, :1] #print "gy", gy[:1, :1, :1] #print "gz", gz.dtype #print ((posX, posX + (t.shape[0] + 1) * spacingX),(posY, posY + (t.shape[1] + 1) * spacingY),(min(zpositions),max(zpositions))) results = Octree( ((posX, posX + (t.shape[2] + 1) * spacingX), (posY, posY + (t.shape[1] + 1) * spacingY), (min(zpositions), max(zpositions)))) #del t gn = (gx**2 + gy**2 + gz**2)**0.5 nx = gx / gn #print nx.dtype #print gx.dtype del gx ny = gy / gn del gy nz = gz / gn del gz dist = (mean - level) / gn del gn dx = dist * nx dy = dist * ny dz = dist * nz print dz.dtype del dist hit = numpy.logical_and(numpy.logical_and(abs(dx) < 0.5, abs(dy) < 0.5), abs(dz) < 0.5) for i, j, k in zip(*hit.nonzero()): rx = nx[i, j, k] / spacingX ry = ny[i, j, k] / spacingY rz = nz[i, j, k] / float(zpositions[i + 1] - zpositions[i]) rn = (rx**2 + ry**2 + rz**2)**0.5 rx = -rx / rn ry = -ry / rn rz = -rz / rn #print k, dx[i, j, k], posX, spacingX, t.shape #print posX, posX + (k + 0.5 - dx[i, j, k] / 2) * spacingX, posX + (t.shape[0] + 1) * spacingX results.insert( (posX + (k + 0.5 - dx[i, j, k]) * spacingX, posY + (j + 0.5 - dy[i, j, k]) * spacingY, float(zpositions[i]) * (0.5 + dz[i, j, k]) + float(zpositions[i + 1]) * (0.5 - dz[i, j, k])), (rx, ry, rz)) del dx del dy del dz del nx del ny del nz return results
class GeometricTests(TestCase): def setUp(self): self.coords = set((sin(0.1*t), sin(0.2*t), sin(0.3*t)) for t in xrange(50)) self.o = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) self.o.extend((p, True) for p in self.coords) def test_basic(self): self.assertEqual(len(self.o), 50) def test_get(self): for (i, p) in enumerate(self.coords): self.assertTrue(self.o.get(p, False)) self.assertFalse(self.o.get((2.3, 3.4, 4.5), False)) def test_by_distance_from_point(self): p = (0.123, 0.456, 0.789) l1 = list(self.o.by_distance_from_point(p)) l2 = list(self.o.by_distance_from_point_rev(p)) self.assertEqual(set(c for (_, c, _) in l1), self.coords, """the points in order of distance from p should be the same as the points we put in""") for (d, c, v) in l1: self.assertEqual(d, euclidean_point_point(p, c), """the points in order of distance from p should have distance computed correctly""") self.assertEqual(l1, list(reversed(l2)), """the points in order of distance reversed should be the reverse of the points in order of distance""") for ((d1, _, _), (d2, _, _)) in zip(l1, l1[1:]): self.assertTrue(d1 <= d2, """the points in order of distance from p should have increasing distance from p""") self.assertEqual(self.o.nearest_to_point(p), l1[0], """the nearest point to p should be the first in order of distance from p""") l3 = list(self.o.by_distance_from_point(p, 1.3)) self.assertEqual(l3, l1[:len(l3)], """the points near p should be an initial segment of the points in order of distance from p""") def test_embiggen(self): b = ((-1.0, 1.6), (-1.0, 1.6), (-1.0, 1.6)) o2 = self.o.rebound(b) self.assertEqual(o2.bounds, b) p = (0.653, -0.234, 0.113) l1 = list(self.o.by_distance_from_point(p)) l2 = list(o2.by_distance_from_point(p)) self.assertEqual(l1, l2, """enlarging the bounds shouldn't have changed the points""") def test_restrict(self): b = ((-1.57, 0.43), (-0.76, 0.83), (-0.37, 1.96)) o2 = self.o.rebound(b) self.assertEqual(o2.bounds, b) p = (0.653, -0.234, 0.113) l1 = [(d, c, v) for (d, c, v) in self.o.by_distance_from_point(p) if point_in_box(c, b)] l2 = list(o2.by_distance_from_point(p)) self.assertEqual(l1, l2, """playing around with the bounds should restrict the points""") def test_remove_all(self): p = (-0.432, 0.651, 0.791) l = list(self.o.by_distance_from_point(p)) n = len(l) for (i, (_, c, _)) in enumerate(l): self.o.remove(c) self.assertEqual(len(self.o), n-i-1) with self.assertRaises(KeyError): self.o.remove(c) def test_union(self): p = (0.236, -0.532, -0.117) l = [c for (_, c, _) in self.o.by_distance_from_point(p)] o1 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) o1.extend((p, True) for p in l[:25]) self.assertEqual(len(o1), 25) o2 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) o2.extend((p, True) for p in l[25:]) self.assertEqual(len(o2), 25) self.assertEqual(o1.simple_union(o2), self.o) def test_matrix(self): m = ((0.123, 0.143, -0.987), (-0.345, 0.687, -0.431), (0.361, -0.183, 0.781)) o1 = self.o.apply_matrix(m) s = set(matrix_action(m, p) for p in self.coords) self.assertEqual(len(s), len(self.coords)) g1 = o1.by_distance_from_point((0.123, 0.456, 0.789)) s1 = set(c for (_, c, _) in g1) self.assertEqual(s, s1) def test_iter_and_subset(self): l1 = set(t for (t, _) in self.o if sum(t) > 0) l2 = set(t for t in self.coords if sum(t) > 0) l3 = set(t for (t, _) in self.o.subset(lambda t: sum(t) > 0)) self.assertEqual(l1, l2) self.assertEqual(l1, l3) def test_point_within_distance(self): epsilon = 0.1 for t in xrange(150, 200): p = (sin(0.1*t), sin(0.2*t), sin(0.3*t)) try: self.o.by_distance_from_point(p, epsilon).next() f_computed = True except StopIteration: f_computed = False f_real = False for (q, _) in self.o: if euclidean_point_point(p, q) < epsilon: f_real = True break self.assertEqual(f_computed, f_real)
def setUp(self): self.o = Octree(((0.0, 1.0), (0.0, 1.0), (0.0, 1.0))) self.o.insert((0.33, 0.66, 0.99), "Point one") self.o.insert((0.12, 0.34, 0.56), "Point two") self.o.insert((0.98, 0.76, 0.54), "Point three")
class BasicTests(TestCase): def setUp(self): self.o = Octree(((0.0, 1.0), (0.0, 1.0), (0.0, 1.0))) self.o.insert((0.33, 0.66, 0.99), "Point one") self.o.insert((0.12, 0.34, 0.56), "Point two") self.o.insert((0.98, 0.76, 0.54), "Point three") def test_size(self): self.assertEqual(len(self.o), 3) def test_thinking_outside_box(self): with self.assertRaises(KeyError): self.o.insert((2.35, 0.87, 0.56), "> maxx") with self.assertRaises(KeyError): self.o.insert((-0.43, 0.87, 0.56), "< minx") with self.assertRaises(KeyError): self.o.insert((0.35, 1.94, 0.56), "> maxy") with self.assertRaises(KeyError): self.o.insert((0.35, -0.51, 0.56), "< miny") with self.assertRaises(KeyError): self.o.insert((0.35, 0.87, 1.04), "> maxz") with self.assertRaises(KeyError): self.o.insert((0.35, 0.87, -0.35), "< minz") def test_update_insert(self): with self.assertRaises(KeyError): self.o.insert((0.33, 0.66, 0.99), "Point one, renewed") self.o.update((0.33, 0.66, 0.99), "Point one, renewed") self.assertEqual(len(self.o), 3) self.o.insert((0.98, 0.23, 0.15), "Point four") self.assertEqual(len(self.o), 4)
def setUp(self): self.coords = set( (sin(0.1 * t), sin(0.2 * t), sin(0.3 * t)) for t in xrange(50)) self.o = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) self.o.extend((p, None) for p in self.coords)
class GeometricTests(TestCase): def setUp(self): self.coords = set( (sin(0.1 * t), sin(0.2 * t), sin(0.3 * t)) for t in xrange(50)) self.o = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) self.o.extend((p, True) for p in self.coords) def test_basic(self): self.assertEqual(len(self.o), 50) def test_get(self): for (i, p) in enumerate(self.coords): self.assertTrue(self.o.get(p, False)) self.assertFalse(self.o.get((2.3, 3.4, 4.5), False)) def test_by_distance_from_point(self): p = (0.123, 0.456, 0.789) l1 = list(self.o.by_distance_from_point(p)) l2 = list(self.o.by_distance_from_point_rev(p)) self.assertEqual( set(c for (_, c, _) in l1), self.coords, """the points in order of distance from p should be the same as the points we put in""") for (d, c, v) in l1: self.assertEqual( d, euclidean_point_point(p, c), """the points in order of distance from p should have distance computed correctly""") self.assertEqual( l1, list(reversed(l2)), """the points in order of distance reversed should be the reverse of the points in order of distance""") for ((d1, _, _), (d2, _, _)) in zip(l1, l1[1:]): self.assertTrue( d1 <= d2, """the points in order of distance from p should have increasing distance from p""") self.assertEqual( self.o.nearest_to_point(p), l1[0], """the nearest point to p should be the first in order of distance from p""") l3 = list(self.o.by_distance_from_point(p, 1.3)) self.assertEqual( l3, l1[:len(l3)], """the points near p should be an initial segment of the points in order of distance from p""") def test_embiggen(self): b = ((-1.0, 1.6), (-1.0, 1.6), (-1.0, 1.6)) o2 = self.o.rebound(b) self.assertEqual(o2.bounds, b) p = (0.653, -0.234, 0.113) l1 = list(self.o.by_distance_from_point(p)) l2 = list(o2.by_distance_from_point(p)) self.assertEqual( l1, l2, """enlarging the bounds shouldn't have changed the points""") def test_restrict(self): b = ((-1.57, 0.43), (-0.76, 0.83), (-0.37, 1.96)) o2 = self.o.rebound(b) self.assertEqual(o2.bounds, b) p = (0.653, -0.234, 0.113) l1 = [(d, c, v) for (d, c, v) in self.o.by_distance_from_point(p) if point_in_box(c, b)] l2 = list(o2.by_distance_from_point(p)) self.assertEqual( l1, l2, """playing around with the bounds should restrict the points""") def test_remove_all(self): p = (-0.432, 0.651, 0.791) l = list(self.o.by_distance_from_point(p)) n = len(l) for (i, (_, c, _)) in enumerate(l): self.o.remove(c) self.assertEqual(len(self.o), n - i - 1) with self.assertRaises(KeyError): self.o.remove(c) def test_union(self): p = (0.236, -0.532, -0.117) l = [c for (_, c, _) in self.o.by_distance_from_point(p)] o1 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) o1.extend((p, True) for p in l[:25]) self.assertEqual(len(o1), 25) o2 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) o2.extend((p, True) for p in l[25:]) self.assertEqual(len(o2), 25) self.assertEqual(o1.simple_union(o2), self.o) def test_matrix(self): m = ((0.123, 0.143, -0.987), (-0.345, 0.687, -0.431), (0.361, -0.183, 0.781)) o1 = self.o.apply_matrix(m) s = set(matrix_action(m, p) for p in self.coords) self.assertEqual(len(s), len(self.coords)) g1 = o1.by_distance_from_point((0.123, 0.456, 0.789)) s1 = set(c for (_, c, _) in g1) self.assertEqual(s, s1) def test_iter_and_subset(self): l1 = set(t for (t, _) in self.o if sum(t) > 0) l2 = set(t for t in self.coords if sum(t) > 0) l3 = set(t for (t, _) in self.o.subset(lambda t: sum(t) > 0)) self.assertEqual(l1, l2) self.assertEqual(l1, l3) def test_point_within_distance(self): epsilon = 0.1 for t in xrange(150, 200): p = (sin(0.1 * t), sin(0.2 * t), sin(0.3 * t)) try: self.o.by_distance_from_point(p, epsilon).next() f_computed = True except StopIteration: f_computed = False f_real = False for (q, _) in self.o: if euclidean_point_point(p, q) < epsilon: f_real = True break self.assertEqual(f_computed, f_real)
def __call__(self, outerROI, triangle): #Create an Octree from inner surface minx = min([v.x for v in self.inner_mesh.vertices]) - 0.01 maxx = max([v.x for v in self.inner_mesh.vertices]) + 0.01 miny = min([v.y for v in self.inner_mesh.vertices]) - 0.01 maxy = max([v.y for v in self.inner_mesh.vertices]) + 0.01 minz = min([v.z for v in self.inner_mesh.vertices]) - 0.01 maxz = max([v.z for v in self.inner_mesh.vertices]) + 0.01 points = Octree(((minx, maxx), (miny, maxy), (minz, maxz))) for v in self.inner_mesh.vertices: points.insert((v.x, v.y, v.z), v) #Copy extend to inner surface inner_avoid_edges = [] outer_avoid_edges = [] join_strip = [] for roi in outerROI.rois: for start_outer, end_outer in zip(roi.points, roi.points[1:] + [roi.points[0]]): start_outer_vertex = outerROI.mesh.faces[ start_outer[3]].nearest_vertex(*start_outer[:3]) end_outer_vertex = outerROI.mesh.faces[ end_outer[3]].nearest_vertex(*end_outer[:3]) start_distance, start_coords, start_inner = points.by_distance_from_point( (start_outer_vertex.x, start_outer_vertex.y, start_outer_vertex.z)).next() end_distance, end_coords, end_inner = points.by_distance_from_point( (end_outer_vertex.x, end_outer_vertex.y, end_outer_vertex.z)).next() inner_strip = [ x.edge for x in self.inner_mesh.get_vertex_path( start_inner, end_inner) ] outer_strip = [ x.edge for x in self.outer_mesh.get_vertex_path( start_outer_vertex, end_outer_vertex) ] inner_avoid_edges = inner_avoid_edges + inner_strip outer_avoid_edges = outer_avoid_edges + outer_strip join_strip = join_strip + [ (start_inner, inner_strip, start_outer_vertex, outer_strip) ] triangle_distance, triangle_coords, triangle_vertex_inner = points.by_distance_from_point( triangle.vertices[0]).next() start_triangle = triangle_vertex_inner.faces[0] innerMesh = self.inner_mesh.cloneSubVol(start_triangle, inner_avoid_edges) print outer_avoid_edges outerMesh = self.outer_mesh.cloneSubVol(triangle, outer_avoid_edges) newMesh = mesh.Mesh() newMesh.add_mesh(outerMesh) newMesh.add_mesh(innerMesh, invert=True) for current_inner, inner_strip, current_outer, outer_strip in join_strip: inner_list = list_vertices(newMesh, current_inner, inner_strip) outer_list = list_vertices(newMesh, current_outer, outer_strip) while len(inner_list) > 1 or len(outer_list) > 1: if len(outer_list) == 1 or ( len(inner_list) > 1 and (inner_list[0] - outer_list[1]).magnitude() > (inner_list[1] - outer_list[0]).magnitude()): newMesh.add_face(inner_list[0], inner_list[1], outer_list[0]) inner_list = inner_list[1:] else: newMesh.add_face(inner_list[0], outer_list[1], outer_list[0]) outer_list = outer_list[1:] for edge in newMesh.edges.values(): if edge.lface is None or edge.rface is None: print edge print newMesh.closed() stlwriter = mesh.fileio.StlWriter(mesh.fileio.STL_FORMAT_BINARY) stlwriter.write(newMesh, "Mould", self.base_file + "mould.stl")
class GeometricTests(TestCase): def setUp(self): self.coords = set( (sin(0.1 * t), sin(0.2 * t), sin(0.3 * t)) for t in xrange(50)) self.o = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) self.o.extend((p, None) for p in self.coords) def test_basic(self): self.assertEqual(len(self.o), 50) def test_by_distance_from_point(self): p = (0.123, 0.456, 0.789) l1 = list(self.o.by_distance_from_point(p)) l2 = list(self.o.by_distance_from_point_rev(p)) self.assertEqual( set(c for (_, c, _) in l1), self.coords, "the points in order of distance from p should be the same as the points we put in" ) for (d, c, v) in l1: self.assertEqual( d, euclidean_point_point(p, c), "the points in order of distance from p should have distance computed correctly" ) self.assertEqual( l1, list(reversed(l2)), "the points in order of distance reversed should be the reverse of the points in order of distance" ) for ((d1, _, _), (d2, _, _)) in zip(l1, l1[1:]): self.assertTrue( d1 <= d2, "the points in order of distance from p should have increasing distance from p" ) self.assertEqual( self.o.nearest_to_point(p), l1[0], "the nearest point to p should be the first in order of distance from p" ) l3 = list(self.o.near_point(p, 1.3)) self.assertEqual( l3, l1[:len(l3)], "the points near p should be an initial segment of the points in order of distance from p" ) def test_embiggen(self): b = ((-1.0, 1.6), (-1.0, 1.6), (-1.0, 1.6)) o2 = self.o.rebound(b) self.assertEqual(o2.bounds, b) p = (0.653, -0.234, 0.113) l1 = list(self.o.by_distance_from_point(p)) l2 = list(o2.by_distance_from_point(p)) self.assertEqual( l1, l2, "enlarging the bounds shouldn't have changed the points") def test_restrict(self): b = ((-1.57, 0.43), (-0.76, 0.83), (-0.37, 1.96)) o2 = self.o.rebound(b) self.assertEqual(o2.bounds, b) p = (0.653, -0.234, 0.113) l1 = [(d, c, v) for (d, c, v) in self.o.by_distance_from_point(p) if point_in_box(c, b)] l2 = list(o2.by_distance_from_point(p)) self.assertEqual( l1, l2, "playing around with the bounds should restrict the points") def test_remove_all(self): p = (-0.432, 0.651, 0.791) l = list(self.o.by_distance_from_point(p)) n = len(l) for (i, (_, c, _)) in enumerate(l): self.o.remove(c) self.assertEqual(len(self.o), n - i - 1) with self.assertRaises(KeyError): self.o.remove(c)
class BinaryTests(TestCase): def setUp(self): self.coords1 = set((sin(0.1*t), sin(0.2*t), sin(0.3*t)) for t in xrange(50)) self.o1 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) self.o1.extend((p, None) for p in self.coords1) self.coords2 = set((sin(0.1*t), sin(0.2*t), sin(0.3*t)) for t in xrange(150, 200)) self.o2 = Octree(((-1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0))) self.o2.extend((p, None) for p in self.coords2) def test_proximity(self): l1 = [] for c1 in self.coords1: (d, c2, _) = self.o2.nearest_to_point(c1) l1.append((d, c1, c2, None, None)) l1.sort() l2 = list(self.o1.by_proximity(self.o2)) self.assertEqual(l1, l2) l1b = list(t for t in l1 if t[0] < 0.1) l2b = list(self.o1.by_proximity(self.o2, 0.1)) self.assertEqual(l1b, l2b) def test_isolation(self): l1 = [] for c1 in self.coords1: (d, c2, _) = self.o2.nearest_to_point(c1) l1.append((d, c1, c2, None, None)) l1.sort(reverse=True) l2 = list(self.o1.by_isolation(self.o2)) self.assertEqual(l1, l2) l1b = list(t for t in l1 if t[0] > 0.3) l2b = list(self.o1.by_isolation(self.o2, 0.3)) self.assertEqual(l1b, l2b) def test_pairs_by_distance(self): l1 = [] for c1 in self.coords1: for c2 in self.coords2: d = euclidean_point_point(c1, c2) if d < 0.1: l1.append((d, c1, c2, None, None)) l1.sort() l2 = list(self.o1.pairs_by_distance(self.o2, 0.1)) self.assertEqual(l1, l2) def test_pairs_nearby(self): s1 = set() for c1 in self.coords1: for c2 in self.coords2: d = euclidean_point_point(c1, c2) if d < 0.1: s1.add((c1, c2, None, None)) s2 = set(self.o1.pairs_nearby(self.o2, 0.1)) self.assertEqual(s1, s2)
class GeometricTests(TestCase): def setUp(self): self.coords = set((sin(0.1*t), sin(0.2*t), sin(0.3*t)) for t in xrange(50)) self.o = Octree(((-1.0, 1.0),(-1.0, 1.0),(-1.0, 1.0))) self.o.extend((p,None) for p in self.coords) def test_basic(self): self.assertEqual(len(self.o), 50) def test_by_distance_from_point(self): p = (0.123, 0.456, 0.789) l1 = list(self.o.by_distance_from_point(p)) l2 = list(self.o.by_distance_from_point_rev(p)) self.assertEqual(set(c for (_,c,_) in l1), self.coords, "the points in order of distance from p should be the same as the points we put in") for (d,c,v) in l1: self.assertEqual(d, euclidean_point_point(p,c), "the points in order of distance from p should have distance computed correctly") self.assertEqual(l1,list(reversed(l2)), "the points in order of distance reversed should be the reverse of the points in order of distance") for ((d1,_,_),(d2,_,_)) in zip(l1,l1[1:]): self.assertTrue(d1 <= d2, "the points in order of distance from p should have increasing distance from p") self.assertEqual(self.o.nearest_to_point(p), l1[0], "the nearest point to p should be the first in order of distance from p") l3 = list(self.o.near_point(p, 1.3)) self.assertEqual(l3, l1[:len(l3)], "the points near p should be an initial segment of the points in order of distance from p") def test_embiggen(self): b = ((-1.0,1.6),(-1.0,1.6),(-1.0,1.6)) o2 = self.o.rebound(b) self.assertEqual(o2.bounds, b) p = (0.653, -0.234, 0.113) l1 = list(self.o.by_distance_from_point(p)) l2 = list(o2.by_distance_from_point(p)) self.assertEqual(l1, l2, "enlarging the bounds shouldn't have changed the points") def test_restrict(self): b = ((-1.57,0.43),(-0.76,0.83),(-0.37,1.96)) o2 = self.o.rebound(b) self.assertEqual(o2.bounds, b) p = (0.653, -0.234, 0.113) l1 = [(d,c,v) for (d,c,v) in self.o.by_distance_from_point(p) if point_in_box(c,b)] l2 = list(o2.by_distance_from_point(p)) self.assertEqual(l1, l2, "playing around with the bounds should restrict the points") def test_remove_all(self): p = (-0.432, 0.651, 0.791) l = list(self.o.by_distance_from_point(p)) n = len(l) for (i,(_,c,_)) in enumerate(l): self.o.remove(c) self.assertEqual(len(self.o), n-i-1) with self.assertRaises(KeyError): self.o.remove(c)