def gh_add_delete_strips(mesh, strips_to_add, strips_to_delete): index_to_key = {index: key for index, key in enumerate(mesh.vertices())} strip_index_to_key = {index: key for index, key in enumerate(mesh.strips())} mesh_2 = deepcopy(mesh) strips_to_add_lists = [[key for key in polyedge] for polyedge in strips_to_add.Branches] add_strips(mesh_2, strips_to_add_lists) delete_strips(mesh_2, [strip_index_to_key[index] for index in strips_to_delete]) return mesh_2
def find_submesh_between_n_meshes(meshes): # find common submesh to n meshes starting with the first mesh and deleting strips after comparisons wit the other ones submesh = meshes[0].copy() for mesh in meshes[1:]: distance, deletion_rules = distance_and_deletion_rules_between_2_meshes( submesh, mesh) delete_strips(submesh, deletion_rules[submesh]) return submesh
def editing_topology(coarse_pseudo_quad_mesh): """Edit the topology of a pattern, i.e. its singularities, via its strips. Parameters ---------- coarse_pseudo_quad_mesh : CoarsePseudoQuadMesh The pattern to edit. """ while True: # update drawing rs.EnableRedraw(False) artist = rhino_artist.MeshArtist(coarse_pseudo_quad_mesh) guid = artist.draw_mesh() rs.EnableRedraw(True) # choose operation operation = rs.GetString('edit strip topology?', strings=['add', 'delete', 'split', 'exit']) # stop if asked if operation is None or operation == 'exit': rs.DeleteObject(guid) break # apply operation if operation == 'add': skey = add_strip(coarse_pseudo_quad_mesh, select_mesh_polyedge(coarse_pseudo_quad_mesh))[0] coarse_pseudo_quad_mesh.set_strip_density(skey, 1) elif operation == 'delete': skeys = set(select_quad_mesh_strips(coarse_pseudo_quad_mesh)) skey_to_skeys = delete_strips(coarse_pseudo_quad_mesh, skeys) if skey_to_skeys is not None: for skey_0, skeys in skey_to_skeys.items(): d = int( ceil( float( coarse_pseudo_quad_mesh.get_strip_density( skey_0)) / 2.)) coarse_pseudo_quad_mesh.set_strips_density(d, skeys) elif operation == 'split': skey = select_quad_mesh_strip(coarse_pseudo_quad_mesh) n = rs.GetInteger('number of splits', number=2, minimum=2) skeys = split_strip(coarse_pseudo_quad_mesh, skey, n=n) # update data d = int( ceil( float(coarse_pseudo_quad_mesh.get_strip_density(skey)) / float(n))) coarse_pseudo_quad_mesh.set_strips_density(d, skeys) # delete drawing rs.DeleteObject(guid)
def distance_and_deletion_rules_between_2_meshes(mesh_i, mesh_j): # get the distance between two meshes by testing combinations for deleting an increasing number of strips # until strip graphs are isomorphic, and mesh graphs as well in a second step, due to the limited data in strip graphs # isomoprhism comparison differentiate close strips and boundary edges # exist potentially multiple common submeshes with the same number of strips but only one is yielded # check cost for checking isomorphism of graph compared to mesh # other possibility to compare: very fast heuristic ismorphism check on strip graph and classic one on mesh graph nb_graph_iso_check = 0 nb_mesh_iso_check = 0 #nb_discard = 0 results = [] ni, nj = mesh_i.number_of_strips(), mesh_j.number_of_strips() for k in range(0, max(ni, nj) - 1): for nodes_i in it.combinations(list(mesh_i.strips()), k + max(0, ni - nj)): mesh_i_copy = mesh_i.copy() delete_strips(mesh_i_copy, nodes_i) # discard if collateral strip deletions, which are at a higher distance if ni - mesh_i_copy.number_of_strips() != len(nodes_i): continue for nodes_j in it.combinations(list(mesh_j.strips()), k + max(0, nj - ni)): mesh_j_copy = mesh_j.copy() delete_strips(mesh_j_copy, nodes_j) # discard if collateral strip deletions, which are at a higher distance if nj - mesh_j_copy.number_of_strips() != len(nodes_j): continue # # test strip isomorphism # nb_graph_iso_check += 1 # if are_strips_isomorphic(mesh_i_copy, mesh_j_copy, close_strip_data=True): # # test mesh isomorphism # nb_mesh_iso_check += 1 # if are_meshes_isomorphic(mesh_i_copy, mesh_j_copy, boundary_edge_data=True): # distance = 2 * k + abs(ni - nj) # results.append((distance, {mesh_i: nodes_i, mesh_j: nodes_j})) nb_mesh_iso_check += 1 if are_meshes_isomorphic(mesh_i_copy, mesh_j_copy, boundary_edge_data=True): distance = 2 * k + abs(ni - nj) results.append((distance, { mesh_i: nodes_i, mesh_j: nodes_j })) # if are_strips_isomorphic(mesh_i_copy, mesh_j_copy, close_strip_data=True): # distance = 2 * k + abs(ni - nj) # results.append((distance, {mesh_i: nodes_i, mesh_j: nodes_j})) # potentially several combinations with different combinations of strips at the same distance if len(results) != 0: #print(nb_graph_iso_check, nb_mesh_iso_check) return results
def submesh_and_distance_and_deletion_rules_between_2_meshes(mesh_i, mesh_j): distance, deletion_rules = distance_and_deletion_rules_between_2_meshes( mesh_i, mesh_j) submesh = mesh_i.copy() delete_strips(submesh, deletion_rules[mesh_i]) return submesh, distance, deletion_rules
t0 = time.time() results = distance_and_deletion_rules_between_2_meshes(mesh_1, mesh_2) t1 = time.time() t.append(t1 - t0) n0 = n1 - len(results[0][1][mesh_1]) k = n2 - n0 d = results[0][0] nb_submeshes = len(results) dt = average(t) print(n1, n2, n0, k, d, nb_submeshes, dt) non_iso_submeshes = [] for result in results: submesh_1 = mesh_1.copy() strips_1 = result[1][mesh_1] delete_strips(submesh_1, strips_1) add = True for submesh in non_iso_submeshes: if are_meshes_isomorphic(submesh_1, submesh, boundary_edge_data=True): add = False break if add: non_iso_submeshes.append(submesh_1) print(len(non_iso_submeshes)) for i, mesh in enumerate(non_iso_submeshes): mesh.to_json( '/Users/Robin/Desktop/distance_validation/7_{}.json'.format(i))
def gh_delete_strips(mesh, strips_to_delete): index_to_key = {index: key for index, key in enumerate(mesh.vertices())} strip_index_to_key = {index: key for index, key in enumerate(mesh.strips())} mesh_2 = deepcopy(mesh) delete_strips(mesh_2, [strip_index_to_key[index] for index in strips_to_delete]) return mesh_2