def test_flip1_cgal(): plot = False g = unstructured_grid.UnstructuredGrid() cdt = shadow_cdt.ShadowCGALCDT(g) pnts = [[0, 0], [8, 0], [10, 5], [5, 5], [3, 0]] [g.add_node(x=pnt) for pnt in pnts]
def test_constraints_dim1_cgal(): g = unstructured_grid.UnstructuredGrid() cdt = shadow_cdt.ShadowCGALCDT(g) pnts = [[0, 0], [5, 0], [10, 0]] nodes = [g.add_node(x=pnt) for pnt in pnts] j0 = g.add_edge(nodes=[nodes[0], nodes[1]]) j1 = g.add_edge(nodes=[nodes[1], nodes[2]]) g.delete_edge(j0) g.delete_edge(j1) try: g.add_edge(nodes=[nodes[0], nodes[2]]) assert False except cdt.ConstraintCollinearNode: pass #
def test_remove_constraint_cgal(): g = unstructured_grid.UnstructuredGrid() cdt = shadow_cdt.ShadowCGALCDT(g) # inserting a constraint pnts = [[0, 0], [5, 0], [10, 0], [5, 5], [3, 0], [6, 2], [12, 4]] nodes = [g.add_node(x=pnt) for pnt in pnts] j0 = g.add_edge(nodes=[nodes[4], nodes[6]]) nodes.append(g.add_node(x=[7, 0.5])) g.delete_edge(j0) j1 = g.add_edge(nodes=[nodes[2], nodes[3]]) j2 = g.add_edge(nodes=[nodes[4], nodes[7]]) g.delete_edge(j1) g.delete_edge(j2)
def test_fuzz1_cgal(): plot = False # Fuzzing, regular x = np.arange(5) y = np.arange(5) X, Y = np.meshgrid(x, y) xys = np.array([X.ravel(), Y.ravel()]).T if plot: plt.figure(1).clf() fig, ax = plt.subplots(num=1) ax.plot(xys[:, 0], xys[:, 1], 'go', alpha=0.4) ax.axis([-1, 5, -1, 5]) idxs = np.zeros(len(xys), 'i8') - 1 g = unstructured_grid.UnstructuredGrid() cdt = shadow_cdt.ShadowCGALCDT(g) # definitely slows down as the number of nodes gets larger. # starting off with <1s per 100 operations, later more like 2s for repeat in range(1): print "Repeat: ", repeat for step in range(1000): if step % 200 == 0: print " step: ", step toggle = np.random.randint(len(idxs)) if idxs[toggle] < 0: idxs[toggle] = g.add_node(x=xys[toggle]) else: g.delete_node(idxs[toggle]) idxs[toggle] = -1 if plot: del ax.lines[1:] ax.texts = [] ax.collections = [] dt.plot_nodes(labeler=lambda n, nrec: str(n)) dt.plot_edges(alpha=0.5, lw=2) dt.plot_cells(lw=7, facecolor='#ddddff', edgecolor='w', zorder=-5) plt.draw()
def test_atomic_move_cgal(): """ Make sure that when a modify_node call tries an illegal move of a node with a constraint, the DT state is restored to the original state before raising the exception """ # inserting a constraint g = unstructured_grid.UnstructuredGrid() cdt = shadow_cdt.ShadowCGALCDT(g) pnts = [[0, 0], [5, 0], [10, 0], [5, 5], [3, 0], [6, 2], [12, 4]] nodes = [g.add_node(x=pnt) for pnt in pnts] j0 = g.add_edge(nodes=[nodes[0], nodes[5]]) j1 = g.add_edge(nodes=[nodes[3], nodes[2]]) assert np.all(g.nodes['x'][5] == [6, 2]) try: g.modify_node(nodes[5], x=[8, 3]) assert False # it should raise the exception except cdt.IntersectingConstraints: # And the nodes/constraints should be where they started. assert np.all(g.nodes['x'][5] == [6, 2])
def test_basic1_cgal(): g = unstructured_grid.UnstructuredGrid() cdt = shadow_cdt.ShadowCGALCDT(g) pnts = [[0, 0], [5, 0], [10, 0], [5, 5], [3, 0], [6, 2]] nodes = [g.add_node(x=pnt) for pnt in pnts]
def test_collinear(): g = unstructured_grid.UnstructuredGrid() cdt = shadow_cdt.ShadowCGALCDT(g) xys = [[0, 0], [1, 0], [1, 1], [0, -1], [2, 0], [2, 1]] for xy in xys: g.add_node(x=xy) g.add_edge(nodes=[0, 1]) g.add_edge(nodes=[0, 3]) g.add_edge(nodes=[1, 2]) g.add_edge(nodes=[1, 4]) # this is problematic - # in one case, it goes through a node, and the successive faces # don't share an edge. not sure if this is guaranteed behavior. # even if it is, there could be a collinear node, but without # extra adjacent faces, so we wouldn't know... # print segment_is_free(DT,vh[3], vh[5]) # Want to detect that this failed: ## fig = plt.figure(1) fig.clf() g.plot_edges(lw=7, color='0.5') g.plot_nodes(labeler=lambda n, rec: str(n)) plot_dt(cdt.DT, ax=fig.gca()) ## a = 3 b = 5 # actions in the cdt before allowing the grid to add the edge: cdt.DT.insert_constraint(g.nodes['vh'][a], g.nodes['vh'][b]) ## # traverse constrained edges from vh[3], trying to get # to vh[5]. Anonymous vertices mean we had intersecting constraints, # any other vertices mean collinear nodes. # the trick is figuring out how to traverse ## # stepping along from vh_trav def traverse_fresh_edge(self, a, b): """ invoke after adding a constraint a--b, but before it has been added to self.g. steps from node a to node b, finding out what constrained edges actually were added. returns a list of tuples, each tuple is (node, vertex_handle) """ vh_trav = self.g.nodes['vh'][a] vh_list = [(vh_trav, a)] while 1: # fetch list of constraints for traversal vertex handle constraints = [] self.DT.incident_constraints(vh_trav, constraints) n_trav = self.vh_info[vh_trav] # which neighbors are already constrained trav_nbrs_to_ignore = list(self.g.node_to_nodes(n_trav)) maybe_next = [] # potential vh for next step for edge in constraints: face = edge[0] # work around missing API idx = edge[1] v1 = face.vertex((idx + 1) % 3) v2 = face.vertex((idx + 2) % 3) if v1 == vh_trav: vh_other = v2 else: vh_other = v1 n_me = self.vh_info[vh_trav] n_other = self.vh_info[vh_other] print "Checking constrained edge %s -- %s." % (n_me, n_other) # If this is an existing neighbor in some other direction, ignore. if n_other != b and n_other in trav_nbrs_to_ignore: print " [skip]" continue if len(vh_list) > 1 and vh_other == vh_list[-2][0]: print " [backwards - skip]" continue maybe_next.append((vh_other, n_other)) assert len(maybe_next) == 1 vh_trav, n_trav = maybe_next[0] vh_list.append(maybe_next[0]) print "Stepped to node: %s" % (n_trav) if n_trav == b: print "Done with traversal" break return vh_list # This works okay.. elts = traverse_fresh_edge(cdt, a, b)
# This works okay.. elts = traverse_fresh_edge(cdt, a, b) # what are the options? # a. bring in the big guns like in live_dt.py # b. ignore this, and move on to quad algorithm # c. insert the edge, and if it doesn't come back # looking right, rewind manually # This seems best, assuming we can do that. ## # def test_intersection(): g = unstructured_grid.UnstructuredGrid() cdt = shadow_cdt.ShadowCGALCDT(g) xys = [[0, 0], [1, 0], [1, 1], [0, -1], [2, 0], [2, 2]] for xy in xys: g.add_node(x=xy) g.add_edge(nodes=[0, 1]) g.add_edge(nodes=[0, 3]) g.add_edge(nodes=[1, 2]) g.add_edge(nodes=[1, 4]) # this is problematic - # in one case, it goes through a node, and the successive faces # don't share an edge. not sure if this is guaranteed behavior. # even if it is, there could be a collinear node, but without