def collect_data_density(self): """Collect the existing density mesh in the density layer. Parameters ---------- Returns ------- """ objects = rs.ObjectsByLayer('density') if objects is not None: if len(objects) == 1: if rs.ObjectType(objects[0]) == 32: vertices, faces = RhinoGeometry.from_guid( objects[0]).get_vertices_and_faces() self.density_mesh = Mesh.from_vertices_and_faces( vertices, faces) else: print 'the object in the density layer is not a mesh' elif len(objects) > 1: print 'too many objects in the density layer'
def unjoin_mesh_parts(mesh, parts): """Explode the parts of a mesh. Parameters ---------- mesh : Mesh A mesh. parts : list List of lists of face keys. Returns ------- meshes : list The unjoined meshes. """ meshes = [] for part in parts: vertices_keys = list(set([vkey for fkey in part for vkey in mesh.face_vertices(fkey)])) vertices = [mesh.vertex_coordinates(vkey) for vkey in vertices_keys] key_to_index = {vkey: i for i, vkey in enumerate(vertices_keys)} faces = [ [key_to_index[vkey] for vkey in mesh.face_vertices(fkey)] for fkey in part] meshes.append(Mesh.from_vertices_and_faces(vertices, faces)) return meshes
def mesh_from_bmesh(bmesh): """ Create a Mesh datastructure from a Blender mesh. Parameters: bmesh (obj): Blender mesh object. Returns: obj: Mesh object. """ vertices, _, faces = bmesh_data(bmesh) mesh = Mesh.from_vertices_and_faces(vertices, faces) mesh.add_edges_from_faces() return mesh
def to_mesh_2(self): vertices = [self.vertex_coordinates(vkey) for vkey in self.vertices()] face_vertices = [] # remove consecutive duplicates in pseudo quad faces for fkey in self.faces(): non_pseudo_face = [] pseudo_face = self.face_vertices(fkey) for i, vkey in enumerate(pseudo_face): if vkey != pseudo_face[i - 1]: non_pseudo_face.append(vkey) face_vertices.append(non_pseudo_face) mesh = Mesh.from_vertices_and_faces(vertices, face_vertices) return mesh
def conway_gyro(mesh): """Generates the gyro mesh from a seed mesh. Parameters ---------- mesh : Mesh A seed mesh Returns ------- mesh The gyro mesh. References ---------- .. [1] Wikipedia. *Conway polyhedron notation*. Available at: https://en.wikipedia.org/wiki/Conway_polyhedron_notation. .. [2] Hart, George. *Conway Notation for Polyhedron*. Available at: http://www.georgehart.com/virtual-polyhedra/conway_notation.html. """ vertices = [mesh.vertex_coordinates(vkey) for vkey in mesh.vertices() ] + [mesh.face_centroid(fkey) for fkey in mesh.faces()] + [ mesh.edge_point(u, v, t=.33) for u in mesh.vertices() for v in mesh.halfedge[u] ] old_vertices_to_new_vertices = { vkey: i for i, vkey in enumerate(mesh.vertices()) } old_faces_to_new_vertices = { fkey: i + mesh.number_of_vertices() for i, fkey in enumerate(mesh.faces()) } old_halfedges_to_new_vertices = { halfedge: i + mesh.number_of_vertices() + mesh.number_of_faces() for i, halfedge in enumerate([(u, v) for u in mesh.vertices() for v in mesh.halfedge[u]]) } faces = [[ old_halfedges_to_new_vertices[(u, v)], old_halfedges_to_new_vertices[(v, u)], old_vertices_to_new_vertices[v], old_halfedges_to_new_vertices[(v, mesh.face_vertex_descendant(fkey, v))], old_faces_to_new_vertices[mesh.halfedge[u][v]] ] for fkey in mesh.faces() for u, v in mesh.face_halfedges(fkey)] return Mesh.from_vertices_and_faces(vertices, faces)
def mesh_from_guid(guid, **kwargs): """Creates an instance of a compAS mesh class from an identifier in Rhino/Grasshopper. This function is almost identical to ``mesh_from_guid`` in the core framework, but there were some import issues when used from within Grasshopper, but eventually, it should be migrated into the core. """ trimesh = ghcomp.Triangulate(rs.coercemesh(guid))[0] vertices = [map(float, vertex) for vertex in rs.MeshVertices(trimesh)] faces = map(list, rs.MeshFaceVertices(trimesh)) faces = [face[:-1] if face[-2] == face[-1] else face for face in faces] mesh = Mesh.from_vertices_and_faces(vertices, faces) mesh.attributes.update(kwargs) return mesh
def to_mesh(self): vertices = [self.vertex_coordinates(vkey) for vkey in self.vertices()] vertex_remap = list(self.vertices()) faces = [] for fkey in self.faces(): face_vertices = [] for vkey in self.face_vertices(fkey): vkey_idx = vertex_remap.index(vkey) if vkey_idx not in face_vertices: face_vertices.append(vkey_idx) faces.append(face_vertices) mesh = Mesh.from_vertices_and_faces(vertices, faces) return mesh
def delaunay_from_mesh(mesh): """Return a Delaunay triangulation from a given mesh. Parameters: mesh (compas.datastructures.mesh.Mesh) : The original mesh. Returns: mesh : ... >>> ... """ d = Delaunay(mesh.xy) return Mesh.from_vertices_and_faces(mesh.xyz, d.simplices)
def close_handle_2(mesh, edge_path_1, edge_path_2): # two closed edge paths # unweld unweld_mesh_along_edge_path(mesh, edge_path_1) unweld_mesh_along_edge_path(mesh, edge_path_2) # explode parts = mesh_disjointed_parts(mesh) meshes = unjoin_mesh_parts(mesh, parts) # find parts with the topolog of a strip: two boundary components and an EUler characteristic of 0 # if there are several, select the topologically smallest one (lowest number of faces) index = -1 size = -1 for i, submesh in enumerate(meshes): B = len(mesh_boundaries(mesh)) X = mesh_euler(submesh) if B == 2 and X == 0: n = submesh.number_of_faces() if index < 0 or n < size: index = i size = n # collect the boundaries of the strip, oriented towards the outside of the strip vertices = [] key_to_index = {} for i, vkey in enumerate(mesh.vertices()): vertices.append(mesh.vertex_coordinates(vkey)) key_to_index[vkey] = i faces = [[key_to_index[vkey] for vkey in mesh.face_vertices(fkey)] for fkey in parts[index]] strip_mesh = Mesh.from_vertices_and_faces(vertices, faces) boundaries = mesh_boundaries(strip_mesh) # remove faces of the selected band for fkey in parts[index]: mesh.delete_face(fkey) # close the two boundaries new_fkeys = [] for bdry in boundaries: new_fkeys += close_opening(mesh, list(reversed(bdry))) return new_fkeys
def conway_join(mesh): """Generates the join mesh from a seed mesh. Parameters ---------- mesh : Mesh A seed mesh Returns ------- join_mesh : mesh The join mesh. References ---------- .. [1] Wikipedia. *Conway polyhedron notation*. Available at: https://en.wikipedia.org/wiki/Conway_polyhedron_notation. .. [2] Hart, George. *Conway Notation for Polyhedron*. Available at: http://www.georgehart.com/virtual-polyhedra/conway_notation.html. """ vertices = [mesh.vertex_coordinates(vkey) for vkey in mesh.vertices() ] + [mesh.face_centroid(fkey) for fkey in mesh.faces()] old_vertices_to_new_vertices = { vkey: i for i, vkey in enumerate(mesh.vertices()) } old_faces_to_new_vertices = { fkey: i + mesh.number_of_vertices() for i, fkey in enumerate(mesh.faces()) } faces = [[ old_vertices_to_new_vertices[u], old_faces_to_new_vertices[mesh.halfedge[v][u]], old_vertices_to_new_vertices[v], old_faces_to_new_vertices[mesh.halfedge[u][v]] ] for u, v in mesh.edges() if not mesh.is_edge_on_boundary(u, v)] join_mesh = Mesh.from_vertices_and_faces(vertices, faces) join_mesh.cull_vertices() return join_mesh
def get_transformed_model(self, transformations, xtransform_function=None): """Get the transformed meshes of the robot model. Args: transformations (:obj:`list` of :class:`Transformation`): A list of transformations to apply on each of the links xtransform_function (function name, ): the name of the function used to transform the model. Defaults to None. Returns: model (:obj:`list` of :class:`Mesh`): The list of meshes in the respective class of the CAD environment """ tmodel = [] if xtransform_function: for m, T in zip(self.model, transformations): tmodel.append(xtransform_function(m, T, copy=True)) else: for m, T in zip(self.model, transformations): mtxyz = transform_points(m.xyz, T) faces = [m.face_vertices(fkey) for fkey in m.faces()] tmodel.append(Mesh.from_vertices_and_faces(mtxyz, faces)) return tmodel
def conway_dual(mesh): """Generates the dual mesh from a seed mesh. Parameters ---------- mesh : Mesh A seed mesh Returns ------- mesh The dual mesh. References ---------- .. [1] Wikipedia. *Conway polyhedron notation*. Available at: https://en.wikipedia.org/wiki/Conway_polyhedron_notation. .. [2] Hart, George. *Conway Notation for Polyhedron*. Available at: http://www.georgehart.com/virtual-polyhedra/conway_notation.html. """ vertices = [mesh.face_centroid(fkey) for fkey in mesh.faces()] old_faces_to_new_vertices = { fkey: i for i, fkey in enumerate(mesh.faces()) } faces = [[ old_faces_to_new_vertices[fkey] for fkey in reversed(mesh.vertex_faces(vkey, ordered=True)) ] for vkey in mesh.vertices() if not mesh.is_vertex_on_boundary(vkey) and len(mesh.vertex_neighbors(vkey)) != 0] return Mesh.from_vertices_and_faces(vertices, faces)
def close_handle(mesh, fkeys): # remove handle and close openings # fkeys: closed face strip if fkeys[0] == fkeys[-1]: del fkeys[-1] vertices = [] key_to_index = {} for i, vkey in enumerate(mesh.vertices()): vertices.append(mesh.vertex_coordinates(vkey)) key_to_index[vkey] = i faces = [[key_to_index[vkey] for vkey in mesh.face_vertices(fkey)] for fkey in fkeys] strip_mesh = Mesh.from_vertices_and_faces(vertices, faces) boundaries = mesh_boundaries(strip_mesh) for fkey in fkeys: mesh.delete_face(fkey) new_fkeys = [] for bdry in boundaries: new_fkeys += close_opening(mesh, list(reversed(bdry))) return new_fkeys
def voronoi_from_points(points, boundary=None, holes=None, return_delaunay=False): """Construct the Voronoi dual of the triangulation of a set of points. Parameters: points boundary holes return_delaunay Example: .. plot:: :include-source: from numpy import random from numpy import hstack from numpy import zeros from compas.datastructures.mesh import Mesh from compas.datastructures.mesh.algorithms import optimise_trimesh_topology from compas.datastructures.mesh.algorithms import delaunay_from_points from compas.datastructures.mesh.algorithms import voronoi_from_points points = hstack((10.0 * random.random_sample((20, 2)), zeros((20, 1)))).tolist() mesh = Mesh.from_vertices_and_faces(points, delaunay_from_points(points)) optimise_trimesh_topology(mesh, 1.0, allow_boundary_split=True) points = [mesh.vertex_coordinates(key) for key in mesh] voronoi, delaunay = voronoi_from_points(points, return_delaunay=True) lines = [] for u, v in voronoi.edges(): lines.append({ 'start': voronoi.vertex_coordinates(u, 'xy'), 'end' : voronoi.vertex_coordinates(v, 'xy') }) boundary = set(delaunay.vertices_on_boundary()) delaunay.plot( vertexsize=0.075, faces_on=False, edgecolor='#cccccc', vertexcolor={key: '#0092d2' for key in delaunay if key not in boundary}, lines=lines ) """ delaunay = Mesh.from_vertices_and_faces(points, delaunay_from_points(points)) voronoi = construct_dual_mesh(delaunay) for key in voronoi: a, b, c = delaunay.face_coordinates(key) center, radius, normal = circle_from_points_2d(a, b, c) voronoi.vertex[key]['x'] = center[0] voronoi.vertex[key]['y'] = center[1] voronoi.vertex[key]['z'] = center[2] if return_delaunay: return voronoi, delaunay return voronoi
def cell_mesh(self, ckey): vertices, halffaces = self.cell_vertices_and_halffaces(ckey) return Mesh.from_vertices_and_faces(vertices, halffaces)
def polyhedron_from_node(cent, points, scale=1., tolerance=1e-6): """Computes polyhedra from a spatial node. Parameters: cent (sequence of float): XYZ coordinates of the central node vertex points (sequence of sequence of float): XYZ coordinates of the neighboring vertices Returns: points (sequence of sequences of floats): the XYZ coordinates of the vertices of the polyhedra faces (sequence of sequences of integers): the faces of the polyhedra Examples: .. code-block:: python from compas.datastructures.network import Network import rhinoscriptsyntax as rs crvs = rs.GetObjects("Select Edges", 4) lines = [[rs.CurveStartPoint(crv), rs.CurveEndPoint(crv)] for crv in crvs] network = Network.from_lines(lines) keys = [] for key in network.vertices(): if not network.is_vertex_leaf(key): keys.append(key) for key in keys: nbrs = network.neighbours(key) cent = network.vertex_coordinates(key) points = [network.vertex_coordinates(nbr) for nbr in nbrs] points, faces = polyhedron_from_node(cent, points, 1) for face in faces: pts = [points[i] for i in face] poly = rs.AddPolyline(pts+[pts[0]]) rs.AddPlanarSrf(poly) """ pts_hull = [] for pt in points: vec = subtract_vectors(pt, cent) vec = scale_vector(normalize_vector(vec), scale) pt = add_vectors(cent, vec) pts_hull.append(pt) faces = convex_hull(pts_hull) mesh = Mesh.from_vertices_and_faces(pts_hull, faces) planes = {} for key in mesh.vertices(): vec = subtract_vectors(mesh.vertex_coordinates(key), cent) planes[key] = [mesh.vertex_coordinates(key), vec] faces = [] pts = [] for key in mesh.vertices(): nbrs = mesh.vertex_neighbours(key, True) face = [] for i in range(len(nbrs)): pt = intersection_plane_plane_plane(planes[nbrs[i - 1]], planes[nbrs[i]], planes[key]) if not pt: continue dup = False n = len(pts) for j in range(n): if distance_point_point(pt, pts[j]) < tolerance: face.append(j) dup = True break if not dup: face.append(n) pts.append(pt) if face: faces.append(face) return pts, faces
def mesh_from_guid(guid): vertices = rs.MeshVertices(guid) faces = [list(face) for face in rs.MeshFaceVertices(guid)] mesh = Mesh.from_vertices_and_faces(vertices, faces) return mesh
__author__ = [ 'Tom Van Mele', ] __copyright__ = 'Copyright 2017, BRG - ETH Zurich', __license__ = 'MIT' __email__ = '*****@*****.**' # clear the *SubdModeling* layer compas_rhino.clear_layer('SubdModeling') # make a control mesh cube = Polyhedron.generate(6) mesh = Mesh.from_vertices_and_faces(cube.vertices, cube.faces) # give it a name # and set default vertex attributes mesh.attributes['name'] = 'Control' mesh.update_default_vertex_attributes({'is_fixed': False}) # draw the control mesh # with showing the faces compas_rhino.draw_mesh(mesh, layer='SubdModeling::Control', clear_layer=True, show_faces=False, show_vertices=True,
from compas_pattern.algorithms.densification import densification from compas_pattern.cad.rhino.utilities import draw_mesh guids = rs.GetObjects('get meshes') poles = rs.GetObjects('pole points', filter=1) if poles is None: poles = [] poles = [rs.PointCoordinates(pole) for pole in poles] target_length = rs.GetReal('target length for densification', number=1) for guid in guids: mesh = RhinoGeometry.from_guid(guid) vertices, faces = mesh.get_vertices_and_faces() coarse_quad_mesh = Mesh.from_vertices_and_faces(vertices, faces) rs.EnableRedraw(False) vertices, face_vertices = pqm_from_mesh(coarse_quad_mesh, poles) coarse_quad_mesh = PseudoQuadMesh.from_vertices_and_faces( vertices, face_vertices) quad_mesh = densification(coarse_quad_mesh, target_length) quad_mesh_guid = draw_mesh(quad_mesh) #layer = 'quad_mesh' #rs.AddLayer(layer) #rs.ObjectLayer(quad_mesh_guid, layer = layer)
if __name__ == "__main__": # todo: distinguish between vertices of hull and internal vertices import random from compas.visualization.viewers.meshviewer import MeshViewer radius = 5 origin = (0., 0., 0.) count = 0 points = [] while count < 1000: x = (random.random() - 0.5) * radius * 2 y = (random.random() - 0.5) * radius * 2 z = (random.random() - 0.5) * radius * 2 pt = x, y, z if distance_point_point(origin, pt) <= radius: points.append(pt) count += 1 faces = convex_hull(points) mesh = Mesh.from_vertices_and_faces(points, faces) viewer = MeshViewer(mesh) viewer.setup() viewer.show()
x, y, z = centroid_points(positions[index]) vertex[0] = x vertex[1] = y vertex[2] = z if callback: callback(k, callback_args) return vertices guid = rs.GetObject('get mesh') mesh = rhino.mesh_from_guid(PseudoQuadMesh, guid) vertices = [] key_to_index = {} for i, vkey in enumerate(mesh.vertices()): vertices.append(mesh.vertex_coordinates(vkey)) key_to_index[vkey] = i faces = [[key_to_index[vkey] for vkey in mesh.face_vertices(fkey)] for fkey in fkeys] fixed_vertices = [key_to_index[vkey] for vkey in mesh.vertices_on_boundary()] new_vertices = planarize_faces(vertices, faces, fixed = fixed_vertices, kmax=100) draw_mesh(Mesh.from_vertices_and_faces(new_vertices, faces))
# Debugging # ============================================================================== if __name__ == "__main__": import os import compas from compas.datastructures.mesh import Mesh filename = os.path.join( compas.get_data('stanford/bunny/reconstruction/bun_zipper.ply')) filename = os.path.join( compas.get_data('stanford/dragon_recon/dragon_vrip.ply')) filename = os.path.join(compas.get_data('stanford/Armadillo.ply')) reader = PLYreader(filename) reader.read() for line in reader.header: print(line) vertices = [(vertex['x'], vertex['y'], vertex['z']) for vertex in reader.vertices] faces = [face['vertex_indices'] for face in reader.faces] mesh = Mesh.from_vertices_and_faces(vertices, faces) print(mesh)
def start(): from compas.geometry.algorithms.smoothing import mesh_smooth_centroid from compas.geometry.algorithms.smoothing import mesh_smooth_area from compas_pattern.algorithms.smoothing import define_constraints from compas_pattern.algorithms.smoothing import apply_constraints guid = rs.GetObject('get mesh') dense_mesh = RhinoGeometry.from_guid(guid) vertices, faces = dense_mesh.get_vertices_and_faces() dense_mesh = Mesh.from_vertices_and_faces(vertices, faces) #lines = rs.GetObjects('lines', filter = 4) #edges = [[rs.CurveStartPoint(line), rs.CurveEndPoint(line)] for line in lines] #dense_mesh = Mesh.from_lines(edges) #faces = list(dense_mesh.faces()) #for fkey in faces: # if len(dense_mesh.face_vertices(fkey)) > 10: # delete_face(dense_mesh, fkey) # print '-1 face' #dense_mesh = conway_ambo(dense_mesh) #dense_mesh = conway_dual(dense_mesh) #dense_mesh = conway_gyro(dense_mesh) #dense_mesh = conway_dual(dense_mesh) #dense_mesh = conway_gyro(dense_mesh) #dense_mesh = conway_kis(dense_mesh) #rs.EnableRedraw(False) #draw_mesh(dense_mesh) #rs.EnableRedraw(True) #return surface_guid = rs.GetSurfaceObject('surface constraint')[0] smooth_mesh = dense_mesh.copy() smoothing_iterations = rs.GetInteger('number of iterations for smoothing', number=20) damping_value = rs.GetReal('damping value for smoothing', number=.5) rs.EnableRedraw(False) #constraints, surface_boundaries = custom_constraints(smooth_mesh, surface_guid) constraints, surface_boundaries = define_constraints( smooth_mesh, surface_guid) rs.EnableRedraw(False) fixed_vertices = [ vkey for vkey, constraint in constraints.items() if constraint[0] == 'fixed' ] mesh_smooth_area(smooth_mesh, fixed=fixed_vertices, kmax=smoothing_iterations, damping=damping_value, callback=apply_constraints, callback_args=[smooth_mesh, constraints]) smooth_mesh_guid = draw_mesh(smooth_mesh) #layer = 'smooth_mesh' #rs.AddLayer(layer) #rs.ObjectLayer(smooth_mesh_guid, layer = layer) rs.EnableRedraw(True)
# ============================================================================== # Debugging # ============================================================================== if __name__ == "__main__": import time from compas.datastructures.mesh import Mesh from compas.geometry.elements import Polyhedron from compas_rhino.artists.meshartist import MeshArtist poly = Polyhedron.generate(12) mesh = Mesh.from_vertices_and_faces(poly.vertices, poly.faces) artist = MeshArtist(mesh, layer='MeshArtist') artist.clear_layer() artist.draw_vertices() artist.redraw() time.sleep(2.0) artist.draw_faces() artist.redraw() time.sleep(2.0) artist.draw_edges() artist.redraw()
# ============================================================================== # Debugging # ============================================================================== if __name__ == "__main__": from numpy import random from numpy import hstack from numpy import zeros from compas.visualization.plotters.meshplotter import MeshPlotter points = hstack((10.0 * random.random_sample((20, 2)), zeros( (20, 1)))).tolist() mesh = Mesh.from_vertices_and_faces(points, delaunay_from_points(points)) optimise_trimesh_topology(mesh, 1.0, allow_boundary_split=True) points = [mesh.vertex_coordinates(key) for key in mesh] voronoi, delaunay = voronoi_from_points(points, return_delaunay=True) lines = [] for u, v in voronoi.wireframe(): lines.append({ 'start': voronoi.vertex_coordinates(u, 'xy'), 'end': voronoi.vertex_coordinates(v, 'xy') }) boundary = set(delaunay.vertices_on_boundary())
def delaunay_from_points(points): """""" xyz = asarray(points) assert 2 <= xyz.shape[1], "At least xy xoordinates required." d = Delaunay(xyz[:, 0:2]) return Mesh.from_vertices_and_faces(points, d.simplices)
def triangulation(boundary, holes=[], polyline_features=[], point_features=[]): """Generates a trimmed Delaunay mesh on a closed outer boundary polyline with potential closed inner boundary polylines, polyline constraints and point constraints. Parameters ---------- boundary : list List of vertices of the closed outer boundary polyline. holes : list List of lists of vertices of the closed inner boundary polylines. polyline_features : list List of lists of vertices of the feature polylines for constraints to the Delaunay triangulation. point_features : list List of points for constraints to the Delaunay triangulation. Returns ------- delunay_mesh: Mesh Raises ------ - """ # get polyline points for Delaunay triangulation delaunay_points = [] delaunay_points += boundary + point_features for polyline in holes: delaunay_points += polyline for polyline in polyline_features: delaunay_points += polyline # remove duplicates based on their geometric keys delaunay_point_map = {} for point in delaunay_points: point = [float(point[0]), float(point[1]), float(point[2])] geom_key = geometric_key(point) if geom_key not in delaunay_point_map: delaunay_point_map[geom_key] = point delaunay_points = list(delaunay_point_map.values()) holes = [hole[:-1] for hole in holes] # generate Delaunay mesh delaunay_faces = delaunay_from_points_2(delaunay_points, boundary=boundary[:-1], holes=holes) delaunay_mesh = Mesh.from_vertices_and_faces(delaunay_points, delaunay_faces) # topological cut along the feature polylines through unwelding vertex_map = { geometric_key(delaunay_mesh.vertex_coordinates(vkey)): vkey for vkey in delaunay_mesh.vertices() } edge_paths = [] for polyline in polyline_features: edge_path = [] vertex_path = [ vertex_map[geometric_key([float(x), float(y), float(z)])] for x, y, z in polyline ] for i in range(len(vertex_path) - 1): if vertex_path[i + 1] in delaunay_mesh.halfedge[vertex_path[i]]: edge_path.append([vertex_path[i], vertex_path[i + 1]]) edge_paths.append(edge_path) for edge_path in edge_paths: unweld_mesh_along_edge_path(delaunay_mesh, edge_path) return delaunay_mesh