def create_cablenet_from_lines(settings): guids = compas_rhino.select_lines() if not guids: return lines = compas_rhino.get_line_coordinates(guids) cablenet = Cablenet.from_lines(lines) return cablenet
def from_rhinolines(cls, guids, delete_boundary_face=True, precision=None, **kwargs): """Construct a FormDiagram from a set of Rhino lines represented by their GUIDs. Parameters ---------- guids : list A list of GUIDs. delete_boundary_face : bool, optional Set ``True`` to delete the face on the outside of the boundary, ``False`` to keep it. Default is ``True``. precision: str, optional The precision of the geometric map that is used to connect the lines. If not specified, the global precision stored in ``compas.PRECISION`` will be used. Returns ------- FormDiagram A FormDiagram object. Examples -------- .. code-block:: python import compas_rhino from compas_tna.diagrams import FormDiagram guids = compas_rhino.select_lines() form = FormDiagram.from_rhinolines(guids) """ import compas_rhino lines = compas_rhino.get_line_coordinates(guids) mesh = FormDiagram.from_lines(lines, delete_boundary_face=delete_boundary_face, precision=precision, **kwargs) return mesh
def RunCommand(is_interactive): if 'AGS' not in sc.sticky: compas_rhino.display_message('AGS has not been initialised yet.') return scene = sc.sticky['AGS']['scene'] layer = compas_rhino.rs.CurrentLayer() layer_name = compas_rhino.rs.GetString("Layer to construct FormDiagram", layer) guids = compas_rhino.get_lines(layer=layer_name) if not guids: return compas_rhino.rs.HideObjects(guids) lines = compas_rhino.get_line_coordinates(guids) graph = FormGraph.from_lines(lines) if not graph.is_planar_embedding(): compas_rhino.display_message( 'The graph is not planar. Therefore, a form diagram cannot be created.' ) return form = FormDiagram.from_graph(graph) scene.purge() scene.add(form, name='Form', layer='AGS::FormDiagram') scene.update() scene.save()
def from_lines(root): guids = compas_rhino.select_lines() if not guids: return lines = compas_rhino.get_line_coordinates(guids) form = FormDiagram.from_lines(lines) return form
def get_initial_mesh(precision): crvs = rs.GetObjects("Select boundary curves", 4, group=True, preselect=False, select=False, objects=None, minimum_count=3, maximum_count=0) lines = get_line_coordinates(crvs) geo_lines = [(geometric_key(pt_u, precision), geometric_key(pt_v, precision)) for pt_u, pt_v in lines] network = Network.from_lines(lines, precision) if network.leaves(): return None adjacency = { key: network.vertex_neighbors(key) for key in network.vertices() } root = network.get_any_vertex() ordering, predecessors, paths = depth_first_tree(adjacency, root) if len(ordering) != network.number_of_vertices(): return None mesh = Mesh.from_lines(lines, delete_boundary_face=True, precision=precision) for u, v, attr in mesh.edges(True): pt_u, pt_v = mesh.edge_coordinates(u, v) geo_u, geo_v = geometric_key(pt_u, precision), geometric_key( pt_v, precision) for i, geo_l_uv in enumerate(geo_lines): geo_l_u, geo_l_v = geo_l_uv[0], geo_l_uv[1] if (geo_l_u == geo_u) and (geo_l_v == geo_v): attr['dir'] = True elif (geo_l_u == geo_v) and (geo_l_v == geo_u): attr['dir'] = False else: continue attr['guid'] = str(crvs[i]) attr['length'] = rs.CurveLength(crvs[i]) # initiate flag for corners for fkey, attr in mesh.faces(True): mesh.set_face_attribute(fkey, 'corner', 0) mesh.set_face_attribute(fkey, 'opening', 0) return mesh
def RunCommand(is_interactive): if 'TNA' not in sc.sticky: raise Exception("Initialise the plugin first!") TNA = sc.sticky['TNA'] settings = TNA['settings'] options = ['obj', 'json', 'lines', 'mesh'] option = rs.GetString("Initialise FormDiagram from", options[0], options) if not option: return if option == 'obj': filepath = compas_rhino.select_file(folder=compas_tna.DATA, filter='OBJ files (*.obj)|*.obj||') if not filepath: return form = FormDiagram.from_obj(filepath) elif option == 'json': filepath = compas_rhino.select_file( folder=compas_tna.DATA, filter='JSON files (*.json)|*.json||') if not filepath: return form = FormDiagram.from_json(filepath) elif option == 'lines': guids = compas_rhino.select_lines() if not guids: return lines = compas_rhino.get_line_coordinates(guids) form = FormDiagram.from_lines(lines) elif option == 'mesh': guid = compas_rhino.select_mesh() if not guid: return form = FormDiagram.from_rhinomesh(guid) else: raise NotImplementedError del TNA['form'] del TNA['force'] TNA['form'] = form TNA['force'] = None compas_rhino.clear_layer(settings['layer.force']) form.draw(layer=settings['layer.form'], clear_layer=True, settings=settings)
def update_network_from_lines(network, guids): lines = compas_rhino.get_line_coordinates(guids) names = compas_rhino.get_object_names(guids) gkey_key = {geometric_key(network.vertex_coordinates(key)): key for key in network} for i, (sp, ep) in enumerate(lines): name = names[i] try: attr = ast.literal_eval(name) except ValueError: pass else: a = geometric_key(sp) b = geometric_key(ep) if a in gkey_key and b in gkey_key: u = gkey_key[a] v = gkey_key[b] if v in network.edge[u]: network.edge[u][v].update(attr) else: network.edge[v][u].update(attr)
def RunCommand(is_interactive): scene = get_scene() if not scene: return guids = compas_rhino.select_lines() if not guids: return lines = compas_rhino.get_line_coordinates(guids) pattern = Pattern.from_lines(lines, delete_boundary_face=True) if not pattern.face: print("No faces found! Pattern object was not created.") return compas_rhino.rs.HideObjects(guids) scene.clear() scene.add(pattern, name='pattern') scene.update() print("Pattern object successfully created.")
from __future__ import print_function from __future__ import absolute_import from __future__ import division import compas_rhino from compas.utilities import geometric_key from fofin.shell import Shell from fofin.shellartist import ShellArtist # ============================================================================== # Input # ============================================================================== guids = compas_rhino.select_lines() lines = compas_rhino.get_line_coordinates(guids) # ============================================================================== # Shell # ============================================================================== shell = Shell.from_lines(lines, delete_boundary_face=True) # ============================================================================== # Vertex attributes # ============================================================================== corners = list(shell.vertices_where({'vertex_degree': 3})) high = 26 higher = 43
def get_initial_mesh(precision): crvs = rs.GetObjects("Select boundary curves", 4, group=True, preselect=False, select=False, objects=None, minimum_count=3, maximum_count=0) lines = get_line_coordinates(crvs) geo_lines = [(geometric_key(pt_u, precision), geometric_key(pt_v, precision)) for pt_u, pt_v in lines] network = Network.from_lines(lines, precision) if network.leaves(): return None adjacency = { key: network.vertex_neighbours(key) for key in network.vertices() } root = network.get_any_vertex() ordering, predecessors, paths = depth_first_tree(adjacency, root) if len(ordering) != network.number_of_vertices(): return None mesh = Mesh.from_lines(lines, delete_boundary_face=True, precision=precision) rs.EnableRedraw(False) dots = {} for fkey in mesh.faces(): cent = mesh.face_centroid(fkey) dot = rs.AddTextDot('', cent) rs.TextDotHeight(dot, 6) dots[str(dot)] = fkey rs.EnableRedraw(True) if not dots: return None dot_ids = dots.keys() data = rs.GetObjectsEx(message="Select face for openings", filter=0, preselect=False, select=False, objects=dot_ids) rs.DeleteObjects(dot_ids) if data: for datum in data: dot = datum[0] fkey = dots[str(dot)] mesh.delete_face(fkey) geo_edges = [] for u, v, attr in mesh.edges(True): pt_u, pt_v = mesh.edge_coordinates(u, v) geo_u, geo_v = geometric_key(pt_u, precision), geometric_key( pt_v, precision) for i, geo_l_uv in enumerate(geo_lines): geo_l_u, geo_l_v = geo_l_uv[0], geo_l_uv[1] if (geo_l_u == geo_u) and (geo_l_v == geo_v): attr['dir'] = True elif (geo_l_u == geo_v) and (geo_l_v == geo_u): attr['dir'] = False else: continue attr['guid'] = str(crvs[i]) attr['length'] = rs.CurveLength(crvs[i]) # initiate flag for corners for fkey, attr in mesh.faces(True): mesh.set_face_attribute(fkey, 'corner', 0) return mesh, crvs
a = vertices[i - 1] b = vertices[i - 2] # check if the starting edge is reached if (a, b) in edges or (b, a) in edges: break edges.append((a, b)) return edges if __name__ == '__main__': crvs = rs.GetObjects("Select mesh edges", 4) lines = get_line_coordinates(crvs) mesh = Mesh.from_lines(lines, delete_boundary_face=True) artist = MeshArtist(mesh, layer='new_lines') artist.draw_edges() artist.redraw() # select edge rs.HideObjects(crvs) edge = mesh_select_edge(mesh, "select a mesh edge") rs.ShowObjects(crvs) # select edge artist.clear_edges()
def RunCommand(is_interactive): scene = get_scene() if not scene: return # skeleton from single point or a set of lines guids_temp = compas_rhino.rs.GetObjects( message="Select a single point or a group of lines", filter=compas_rhino.rs.filter.point | compas_rhino.rs.filter.curve) if not guids_temp: return # detect input object type guids_points = [] guids_lines = [] for guid in guids_temp: if is_curve_line(guid): guids_lines.append(guid) if compas_rhino.rs.IsPoint(guid): guids_points.append(guid) if len(guids_points) == 1 and len(guids_lines) == 0: guids = guids_points point = compas_rhino.get_point_coordinates(guids)[0] skeleton = Skeleton.from_center_point(point) elif len(guids_points) == 0 and len(guids_lines) > 0: guids = guids_lines lines = compas_rhino.get_line_coordinates(guids) skeleton = Skeleton.from_skeleton_lines(lines) if not skeleton: return compas_rhino.rs.HideObjects(guids) skeletonobject = SkeletonObject(skeleton) skeletonobject.draw() skeletonobject.dynamic_draw_widths() # modify skeleton while True: menu = CommandMenu(config) action = menu.select_action() if not action: return if action['name'] == 'Finish': break action['action'](skeletonobject) skeletonobject.draw() # make pattern mesh = skeletonobject.skeleton.to_mesh() xyz = mesh.vertices_attributes('xyz') faces = [mesh.face_vertices(fkey) for fkey in mesh.faces()] pattern = Pattern.from_vertices_and_faces(xyz, faces) # clear skeleton layer = skeletonobject.settings['layer'] skeletonobject.clear() compas_rhino.delete_layers([layer]) scene.clear() scene.add(pattern, name='pattern') scene.update() print("Pattern object successfully created. Input lines have been hidden.")
b = vertices[i - 2] # check if the starting edge is reached if (a, b) in edges or (b, a) in edges: break edges.append((a, b)) # check for the right uv tuples. Ordered as in mesh.edges() edgeset = set(list(mesh.edges())) return [(u, v) if (u, v) in edgeset else (v, u) for u, v in edges] if __name__ == '__main__': edge_crvs = rs.GetObjects("Select edges", 4) lines = get_line_coordinates(edge_crvs) mesh = Mesh.from_lines(lines, delete_boundary_face=True) # draw edges for selection artist = MeshArtist(mesh, layer='joint_lines') artist.draw_edges() artist.redraw() # select edge rs.HideObjects(edge_crvs) edges = mesh_select_edges(mesh) rs.ShowObjects(edge_crvs) # clear edges artist.clear_edges()
class SkeletonVol(Mesh): """ SkeletonVol is typologically constructed low poly mesh. It construct a branch like volumetric mesh from input lines. """ def __init__(self): super(SkeletonVol, self).__init__() @classmethod def from_skeleton_lines(cls, lines=[]): skeleton_vol = cls() network = Network.from_lines(lines) convex_hull_mesh = get_convex_hull_mesh(points) def get_convex_hull_mesh(points): faces = convex_hull(points) vertices = list(set(flatten(faces))) i_index = {i: index for index, i in enumerate(vertices)} vertices = [points[index] for index in vertices] faces = [[i_index[i] for i in face] for face in faces] faces = unify_cycles(vertices, faces) mesh = Mesh.from_vertices_and_faces(vertices, faces) return mesh guids = compas_rhino.select_lines() lines = compas_rhino.get_line_coordinates(guids) network = Network.from_lines(lines) leafs = [] joints = [] for key in network.node: if network.is_leaf(key): leafs.append(key) else: joints.append(key) pt_center = network.node_coordinates(joints[0]) pts = [network.node_coordinates(key) for key in leafs] convex_hull_mesh = get_convex_hull_mesh(pts) mesh = Mesh() # for key in convex_hull_mesh.vertices(): # mesh.add_vertex(key) # mesh.vertex[key].update(convex_hull_mesh.vertex[key]) descdent_tree = copy.deepcopy(convex_hull_mesh.halfedge) for u, v in convex_hull_mesh.edges(): descdent_tree[u][v] = {'jp': None, 'lp': None} descdent_tree[v][u] = {'jp': None, 'lp': None} # current_key = convex_hull_mesh.number_of_vertices() current_key = 0 for fkey in convex_hull_mesh.faces(): f_centroid = convex_hull_mesh.face_centroid(fkey) vec = Vector.from_start_end(pt_center, f_centroid) # if the branches has a 'convex' corner, # flip the vec to the corresponding face. f_normal = convex_hull_mesh.face_normal(fkey) angle = angle_vectors(f_normal, vec, False) if angle > math.pi * 0.5: pln = Plane(pt_center, f_normal) pt_mirror = mirror_point_plane(f_centroid, pln) vec = Vector.from_start_end(pt_center, pt_mirror) vec.unitize() vec.scale(joint_width) pt = add_vectors(pt_center, vec) face = convex_hull_mesh.face[fkey] v_keys = face + [face[0]] for u, v in pairwise(v_keys): descdent_tree[u][v].update({'jp': current_key}) mesh.add_vertex(current_key) mesh.vertex[current_key].update({'x': pt[0], 'y': pt[1], 'z': pt[2]}) current_key += 1 for key in convex_hull_mesh.vertices(): nbrs = convex_hull_mesh.vertex_neighbors(key) for nbr in nbrs: halfedge = (key, nbr) pt_joint_descendent = mesh.vertex_coordinates( descdent_tree[key][nbr]['jp']) vec_edge = Vector.from_start_end( pt_center, convex_hull_mesh.vertex_coordinates(key)) pln_end = Plane(convex_hull_mesh.vertex_coordinates(key), vec_edge) pt = project_point_plane(pt_joint_descendent, pln_end) vec_leaf = Vector.from_start_end( convex_hull_mesh.vertex_coordinates(key), pt) vec_leaf.unitize() vec_leaf.scale(leaf_width) pt = add_vectors(convex_hull_mesh.vertex_coordinates(key), vec_leaf) descdent_tree[key][nbr].update({'lp': current_key}) mesh.add_vertex(current_key) mesh.vertex[current_key].update({ 'x': pt[0], 'y': pt[1], 'z': pt[2] }) current_key += 1 for key in convex_hull_mesh.vertices(): nbrs = convex_hull_mesh.vertex_neighbors(key, ordered=True) v_keys = nbrs + [nbrs[0]] for a, b in pairwise(v_keys): face = [ descdent_tree[key][a]['lp'], descdent_tree[key][a]['jp'], descdent_tree[key][b]['jp'], descdent_tree[key][b]['lp'] ] mesh.add_face(face) fixed = list(mesh.vertices_where({'vertex_degree': 3})) fixed = list(mesh.vertices()) mesh = mesh_subdivide_catmullclark(mesh, k=1, fixed=fixed) # mesh = mesh_subdivide_quad(mesh, k=1) mesh_smooth_centroid(mesh, fixed=fixed) artist = MeshArtist(mesh) artist.draw_mesh()