def projection_0(self, kmax=1): """Projection of a coarse quad mesh to the closest two-colourable sub-spaces. Parameters ---------- mesh : CoarseQuadMesh A coarse quad mesh. Returns ------- results : dict The combination pointing to the its result. If the combination is valid, the result is a tuple of the the two-colourable mesh, the two-colourable network, and the network vertex colors. References ---------- .. [1] Oval et al., *Topology Finding of Two-Colourable Quad-Mesh Patterns in Structural Design*. Submitted. """ mesh = self.quad_mesh # result for input mesh vertices, edges = mesh.strip_graph() if is_adjacency_two_colorable(adjacency_from_edges(edges)) is not None: self.results = True return True results = {} # guarantee valid kmax n = mesh.number_of_strips() if kmax < 1 or kmax > n: kmax = n t0 = time.time() t1 = -float('inf') t2 = -float('inf') total_valid = 0 # start iteration k = 0 discarding_combination = [] discarding_combination_type = {} while k < kmax: k += 1 to_continue = False at_least_one_valid_k = False # test all combinations of (n k) strips for combination in itertools.combinations(mesh.strips(), k): set_combi = set(combination) # check results from potential previous sub-combinations for disc_comb in discarding_combination: if disc_comb.issubset(set_combi): #if are_items_in_list(previous_combination, combination): # if a sub-combination yielded an invalid topology do not pursue if discarding_combination_type[tuple( disc_comb)] == 'invalid shape topology': results[ combination] = 'already invalid shape topology' break elif discarding_combination_type[tuple( disc_comb)] == 'two-colourable': results[combination] = 'already two-colourable' break if len(collateral_strip_deletions(mesh, combination)) > 0: results[combination] = 'collateral deletions' if len(total_boundary_deletions(mesh, combination)) > 0: results[combination] = 'invalid shape topology' discarding_combination.append(set(combination)) discarding_combination_type[tuple( combination)] = 'invalid shape topology' if combination in results: continue # delete strips in mesh and check validity copy_mesh = mesh.copy() #copy_mesh.collect_strips() delete_strips(copy_mesh, combination, preserve_boundaries=True) topological_validity = copy_mesh.is_manifold( ) and copy_mesh.euler() == mesh.euler() if not topological_validity: results[combination] = 'invalid shape topology' discarding_combination.append(set(combination)) discarding_combination_type[tuple( combination)] = 'invalid shape topology' # delete strip vertices in network and check colourability else: #vertices, edges = copy_mesh.strip_graph() new_vertices = { vkey: xyz for vkey, xyz in vertices.items() if vkey not in combination } new_edges = [ (u, v) for u, v in edges if u not in combination and v not in combination ] two_colourability = is_adjacency_two_colorable( adjacency_from_edges(new_edges)) if not two_colourability: results[combination] = 'not two-colourable' to_continue = True else: results[combination] = (copy_mesh, (new_vertices, new_edges), two_colourability) discarding_combination.append(set(combination)) discarding_combination_type[tuple( combination)] = 'two-colourable' at_least_one_valid_k = True total_valid += 1 if t1 < 0: t1 = time.time() if t2 < 0 and total_valid > 0 and not at_least_one_valid_k: t2 = time.time() if not to_continue: break t3 = time.time() print(len(discarding_combination)) print(t3 - t0) self.results = results self.times = (t1 - t0, t2 - t0, t3 - t0)
def projection_4(self, kmax=1): """Projection of a coarse quad mesh to the closest two-colourable sub-spaces. Parameters ---------- mesh : CoarseQuadMesh A coarse quad mesh. Returns ------- results : dict The combination pointing to the its result. If the combination is valid, the result is a tuple of the the two-colourable mesh, the two-colourable network, and the network vertex colors. References ---------- .. [1] Oval et al., *Topology Finding of Two-Colourable Quad-Mesh Patterns in Structural Design*. Submitted. """ mesh = self.quad_mesh vertices, edges = mesh.strip_graph() if is_adjacency_two_colorable(adjacency_from_edges(edges)) is not None: self.results = True return True results = {} t0 = time.time() k = 0 current_pool = [[skey] for skey in mesh.strips()] while k < kmax: k += 1 next_pool = [] #print(current_pool) for combination in current_pool: if len(combination) > 1: combination = list( set([i for item in combination for i in item])) else: combination = list(set(combination)) if len(collateral_strip_deletions(mesh, combination)) > 0: continue if len(total_boundary_deletions(mesh, combination)) > 0: continue # delete strips in mesh and check validity copy_mesh = mesh.copy() delete_strips(copy_mesh, combination, preserve_boundaries=True) topological_validity = copy_mesh.is_manifold( ) and copy_mesh.euler() == mesh.euler() if not topological_validity: pass # delete strip vertices in network and check colourability else: new_vertices = { vkey: xyz for vkey, xyz in vertices.items() if vkey not in combination } new_edges = [ (u, v) for u, v in edges if u not in combination and v not in combination ] two_colourability = is_adjacency_two_colorable( adjacency_from_edges(new_edges)) if not two_colourability: next_pool.append(combination) else: results[tuple(combination)] = (copy_mesh, (new_vertices, new_edges), two_colourability) current_pool = itertools.combinations(next_pool, 2) t1 = time.time() print(t1 - t0) self.results = results
def projection(self, kmax=1): """Projection of a coarse quad mesh to the closest two-colourable sub-spaces. Parameters ---------- mesh : CoarseQuadMesh A coarse quad mesh. Returns ------- results : dict The combination pointing to the its result. If the combination is valid, the result is a tuple of the the two-colourable mesh, the two-colourable network, and the network vertex colors. References ---------- .. [1] Oval et al., *Topology Finding of Two-Colourable Quad-Mesh Patterns in Structural Design*. Submitted. """ mesh = self.quad_mesh # # result for input mesh # vertices, edges = mesh.strip_graph() # if is_adjacency_two_colorable(adjacency_from_edges(edges)) is not None: # self.results = True # return True results = {} # guarantee valid kmax n = mesh.number_of_strips() if kmax < 1 or kmax > n: kmax = n # start iteration k = 0 while k < kmax: k += 1 to_continue = False # test all combinations of (n k) strips for combination in itertools.combinations(mesh.strips(), k): # check results from potential previous sub-combinations for previous_combination in results: if are_items_in_list(previous_combination, combination): # if a sub-combination yielded an invalid topology do not pursue if results[ previous_combination] == 'invalid shape topology': results[ combination] = 'already invalid shape topology' break elif type(results[previous_combination]) == tuple: results[combination] = 'already two-colourable' break if combination in results: continue if len(collateral_strip_deletions(mesh, combination)) > 0: to_continue = True continue if len(total_boundary_deletions(mesh, combination)) > 0: results[combination] = 'invalid shape topology' continue # delete strips in mesh and check validity copy_mesh = mesh.copy() copy_mesh.collect_strips() delete_strips(copy_mesh, combination, preserve_boundaries=True) topological_validity = copy_mesh.is_manifold( ) and copy_mesh.euler() == mesh.euler() if not topological_validity: results[combination] = 'invalid shape topology' # delete strip vertices in network and check colourability else: vertices, edges = copy_mesh.strip_graph() two_colourability = is_adjacency_two_colorable( adjacency_from_edges(edges)) if not two_colourability: results[combination] = 'not two-colourable' to_continue = True else: results[combination] = (copy_mesh, (vertices, edges), two_colourability) if not to_continue: break return self.results
def projection_2(self, kmax=1): """Projection of a coarse quad mesh to the closest two-colourable sub-spaces. Parameters ---------- mesh : CoarseQuadMesh A coarse quad mesh. Returns ------- results : dict The combination pointing to the its result. If the combination is valid, the result is a tuple of the the two-colourable mesh, the two-colourable network, and the network vertex colors. References ---------- .. [1] Oval et al., *Topology Finding of Two-Colourable Quad-Mesh Patterns in Structural Design*. Submitted. """ mesh = self.quad_mesh # result for input mesh vertices, edges = mesh.strip_graph() if is_adjacency_two_colorable(adjacency_from_edges(edges)) is not None: self.results = True return True results = {} # guarantee valid kmax n = mesh.number_of_strips() if kmax < 1 or kmax > n: kmax = n t0 = time.time() # start iteration k = 0 discarding_combination = [] while k < kmax: k += 1 to_continue = False at_least_one_valid_k = False # test all combinations of (n k) strips for combination in itertools.combinations(mesh.strips(), k): set_combi = set(combination) # check results from potential previous sub-combinations for disc_comb in discarding_combination: if disc_comb.issubset(set_combi): break if len(collateral_strip_deletions(mesh, combination)) > 0: to_continue = True continue if len(total_boundary_deletions(mesh, combination)) > 0: discarding_combination.append(set(combination)) continue # delete strips in mesh and check validity copy_mesh = mesh.copy() delete_strips(copy_mesh, combination, preserve_boundaries=True) topological_validity = copy_mesh.is_manifold( ) and copy_mesh.euler() == mesh.euler() if not topological_validity: discarding_combination.append(set(combination)) # delete strip vertices in network and check colourability else: new_vertices = { vkey: xyz for vkey, xyz in vertices.items() if vkey not in combination } new_edges = [ (u, v) for u, v in edges if u not in combination and v not in combination ] two_colourability = is_adjacency_two_colorable( adjacency_from_edges(new_edges)) if not two_colourability: to_continue = True else: results[combination] = (copy_mesh, (new_vertices, new_edges), two_colourability) discarding_combination.append(set(combination)) if not to_continue: break t1 = time.time() print(t1 - t0) #print(results) self.results = results