示例#1
0
def mesh_from_rhino(mesh, layer):
    
    # get objects by layer
    rh_objs = sc.doc.Objects.FindByLayer(layer)
    
    # iterate over all objects on layer
    coords = {}
    mesh_data = None
    index = None
    index_u, index_v = None, None
    for i, rh_obj in enumerate(rh_objs):
        # check if curve object
        object_type = rh_obj.ObjectType
        if object_type == Rhino.DocObjects.ObjectType.Curve:
            
            # get start and end points of line
            curve = rh_obj.Geometry
            start = curve.PointAtStart
            end = curve.PointAtEnd
            
            # get name
            name = rh_obj.Attributes.Name
            # check if name exists and is valid
            if name:
                data = name.split('_')
                if len(data) == 3:
                    u,v  = int(data[1]), int(data[2])
                    coords[u] = start
                    coords[v] = end
                    # read in mesh data from user string
                    if mesh_data == None:
                        mesh_data = rh_obj.Attributes.GetUserString('mesh_data')
                        if mesh_data:
                            index = i
                            index_u, index_v = u, v
                            
    
    if index == None and not mesh: return None
    
    verboseprint('Index at which mesh_data UserString was found: ' + str(index))
    verboseprint('u and v where mesh_data UserString was found: ' + str((index_u, index_v)))
    
    
    if not mesh_data:
        verboseprint('No geometry found. Mesh solely constructed from sticky variable.')

    if not mesh and mesh_data:
        verboseprint('No mesh object found. Mesh constructed from unpickled data.')
        mesh_data = pickle.loads(mesh_data)
        mesh = Mesh()
        mesh.data = mesh_data
    
    for key, attr in mesh.vertices(True):
        if key in coords:
            x, y, z = coords[key]
            attr['x'] = x
            attr['y'] = y
            attr['z'] = z
            
    return mesh
示例#2
0
    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'
示例#3
0
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
示例#4
0
    def load_model(self, xdraw_function=None):
        """Load the geometry (meshes) of the robot.

        Args:
            xdraw_function (function, ): The function to draw the
                meshes in the respective CAD environment. Defaults to None.
        """
        path = self.get_model_path()

        # the links loaded as meshes
        m0 = Mesh.from_obj(os.path.join(path, 'base_and_shoulder.obj'))
        m1 = Mesh.from_obj(os.path.join(path, 'upperarm.obj'))
        m2 = Mesh.from_obj(os.path.join(path, 'forearm.obj'))
        m3 = Mesh.from_obj(os.path.join(path, 'wrist1.obj'))
        m4 = Mesh.from_obj(os.path.join(path, 'wrist2.obj'))
        m5 = Mesh.from_obj(os.path.join(path, 'wrist3.obj'))

        # draw the geometry in the respective CAD environment
        if xdraw_function:
            m0 = xdraw_function(m0)
            m1 = xdraw_function(m1)
            m2 = xdraw_function(m2)
            m3 = xdraw_function(m3)
            m4 = xdraw_function(m4)
            m5 = xdraw_function(m5)

        self.model = [m0, m1, m2, m3, m4, m5]
示例#5
0
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
示例#6
0
 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)
示例#8
0
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
示例#9
0
    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
示例#10
0
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 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
示例#12
0
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
示例#13
0
def initiate_mesh(layer):
    
    objs = rs.ObjectsByLayer(layer)
    lines = [(rs.CurveStartPoint(crv), rs.CurveEndPoint(crv)) for crv in objs]
    rs.DeleteObjects(objs)
    
    objs_dict = {}
    for i, pts in enumerate(lines):
        cent = centroid_points(pts)
        objs_dict[geometric_key(cent)] = str(objs[i]) 
        
    mesh = Mesh.from_lines(lines)
    
    for u,v, attr in mesh.edges(True):
        cent = centroid_points([mesh.vertex_coordinates(u), mesh.vertex_coordinates(v)])
        attr['master'] = False
        attr['color'] = [50, 255, 100]
        attr['passive'] = False
        attr['id'] = objs_dict[geometric_key(cent)]
        name = 'e_' + str(u) + '_' + str(v)
        
    return mesh
示例#14
0
    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)
示例#16
0
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
示例#17
0
 def load_model(self):
     """Load the geometry (meshes) of the robot.
     """
     path = self.get_model_path()
     # the joints loaded as meshes
     self.m0 = Mesh.from_obj(os.path.join(path, 'base_and_shoulder.obj'))
     self.m1 = Mesh.from_obj(os.path.join(path, 'upperarm.obj'))
     self.m2 = Mesh.from_obj(os.path.join(path, 'forearm.obj'))
     self.m3 = Mesh.from_obj(os.path.join(path, 'wrist1.obj'))
     self.m4 = Mesh.from_obj(os.path.join(path, 'wrist2.obj'))
     self.m5 = Mesh.from_obj(os.path.join(path, 'wrist3.obj'))
     
     # have a copy of the mesh vertices for later transformation
     self.m0_xyz = self.m0.xyz
     self.m1_xyz = self.m1.xyz
     self.m2_xyz = self.m2.xyz
     self.m3_xyz = self.m3.xyz
     self.m4_xyz = self.m4.xyz
     self.m5_xyz = self.m5.xyz
示例#18
0
# ==============================================================================
# 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())
示例#19
0
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)
示例#20
0
# 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)
示例#21
0
        A mesh object.

    Notes
    -----
    This function does not care about the directions being unified or not. It
    just reverses whatever direction it finds.

    """
    mesh.halfedge = {key: {} for key in mesh.vertices()}
    for fkey in mesh.faces():
        mesh.face[fkey][:] = mesh.face[fkey][::-1]
        for u, v in mesh.face_halfedges(fkey):
            mesh.halfedge[u][v] = fkey
            if u not in mesh.halfedge[v]:
                mesh.halfedge[v][u] = None


# ==============================================================================
# Main
# ==============================================================================

if __name__ == "__main__":

    import compas

    from compas.datastructures.mesh import Mesh

    mesh = Mesh.from_obj(compas.get_data('faces_big.obj'))

    mesh_unify_cycles(mesh)
示例#22
0
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
示例#23
0
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()
示例#24
0
def mesh_extrude(structure,
                 guid,
                 layers,
                 thickness,
                 mesh_name='',
                 links_name='',
                 blocks_name='',
                 plot_blocks=False,
                 plot_mesh=False,
                 plot_links=False):
    """ Extrudes a Rhino mesh and adds/creates elements.

    Parameters
    ----------
    structure : obj
        Structure object to update.
    guid : guid
        Rhino mesh guid.
    layers : int
        Number of layers.
    thickness : float
        Layer thickness.
    blocks_name : str
        Name of set for solid elements.
    mesh_name : str
        Name of set for mesh on final surface.
    links_name : str
        Name of set for adding links along extrusion.
    plot_blocks : bool
        Plot blocks.
    plot_mesh : bool
        Plot outer mesh.
    plot_links : bool
        Plot links.

    Returns
    -------
    None

    Notes
    -----
    - Extrusion is along the vertex normals.

    """

    mesh = mesh_from_guid(Mesh(), guid)
    extrude_mesh(structure=structure,
                 mesh=mesh,
                 layers=layers,
                 thickness=thickness,
                 mesh_name=mesh_name,
                 links_name=links_name,
                 blocks_name=blocks_name)

    block_faces = [[0, 1, 2, 3], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5],
                   [2, 3, 7, 6], [3, 0, 4, 7]]
    xyz = structure.nodes_xyz()

    rs.EnableRedraw(False)

    if plot_blocks:

        rs.CurrentLayer(rs.AddLayer(blocks_name))
        rs.DeleteObjects(rs.ObjectsByLayer(blocks_name))

        for i in structure.sets[blocks_name]['selection']:
            nodes = structure.elements[i].nodes
            xyz = structure.nodes_xyz(nodes)
            rs.AddMesh(xyz, block_faces)

    if plot_mesh:

        rs.CurrentLayer(rs.AddLayer(mesh_name))
        rs.DeleteObjects(rs.ObjectsByLayer(mesh_name))

        faces = []
        for i in structure.sets[mesh_name]['selection']:
            enodes = structure.elements[i].nodes
            if len(enodes) == 3:
                enodes.append(enodes[-1])
            faces.append(enodes)
        rs.AddMesh(xyz, faces)

    if plot_links:

        rs.CurrentLayer(rs.AddLayer(links_name))
        rs.DeleteObjects(rs.ObjectsByLayer(links_name))

        for i in structure.sets[links_name]['selection']:
            nodes = structure.elements[i].nodes
            xyz = structure.nodes_xyz(nodes)
            rs.AddLine(xyz[0], xyz[1])

    rs.EnableRedraw(True)
    rs.CurrentLayer(rs.AddLayer('Default'))
示例#25
0
        return [
            vkey for vkey in self.vertices_on_boundary()
            if self.is_boundary_vertex_kink(vkey, threshold_angle)
        ]

    def vertex_centroid(self):
        """Calculate the centroid of the mesh vertices.

		Parameters
		----------

		Returns
		-------
		list
			The coordinates of the centroid of the mesh vertices.
		"""

        return centroid_points(
            [self.vertex_coordinates(vkey) for vkey in self.vertices()])


# ==============================================================================
# Main
# ==============================================================================

if __name__ == '__main__':

    import compas

    mesh = Mesh.from_obj(compas.get('faces.obj'))
示例#26
0
# Debugging
# ==============================================================================

if __name__ == "__main__":

    import compas

    from compas.datastructures.mesh import Mesh

    from compas.visualization.viewers.viewer import Viewer

    from compas.visualization.viewers.core.drawing import draw_points
    from compas.visualization.viewers.core.drawing import draw_lines
    from compas.visualization.viewers.core.drawing import draw_circle

    mesh = Mesh.from_obj(compas.get_data('hypar.obj'))

    for key, attr in mesh.vertices(True):
        attr['is_fixed'] = mesh.vertex_degree(key) == 2

    planarize_mesh_shapeop(mesh,
                           fixed=mesh.vertices_where({'is_fixed': True}),
                           kmax=100)

    # deviations = []

    # for fkey, attr in mesh.faces(True):
    #     points = mesh.face_coordinates(fkey)
    #     base, normal = bestfit_plane_from_points(points)

    #     angles = []
示例#27
0
# ==============================================================================
# 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()
示例#28
0
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
示例#29
0
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)
示例#30
0
def delaunay_from_points(points, polygon=None, polygons=None):
    """Computes the delaunay triangulation for a list of points.

    Parameters:
        points (sequence of tuple): XYZ coordinates of the original points.
        polygon (sequence of tuples): list of ordered points describing the outer boundary (optional)
        polygons (list of sequences of tuples): list of polygons (ordered points describing internal holes (optional)

    Returns:
        list of lists: list of faces (face = list of vertex indices as integers)

    References:
        Sloan, S. W. (1987) A fast algorithm for constructing Delaunay triangulations in the plane

    Example:

        .. plot::
            :include-source:

            import compas
            from compas.datastructures.mesh import Mesh
            from compas.datastructures.mesh.algorithms import delaunay_from_points

            mesh = Mesh.from_obj(compas.get_data('faces.obj'))

            vertices = [mesh.vertex_coordinates(key) for key in mesh]
            faces = delaunay_from_points(vertices)

            delaunay = Mesh.from_vertices_and_faces(vertices, faces)

            delaunay.plot(
                vertexsize=0.1
            )

    """
    def super_triangle(coords):
        centpt = centroid_points(coords)
        bbpts = bounding_box(coords)
        dis = distance_point_point(bbpts[0], bbpts[2])
        dis = dis * 300
        v1 = (0 * dis, 2 * dis, 0)
        v2 = (1.73205 * dis, -1.0000000000001 * dis, 0
              )  # due to numerical issues
        v3 = (-1.73205 * dis, -1 * dis, 0)
        pt1 = add_vectors(centpt, v1)
        pt2 = add_vectors(centpt, v2)
        pt3 = add_vectors(centpt, v3)
        return pt1, pt2, pt3

    mesh = Mesh()

    # to avoid numerical issues for perfectly structured point sets
    tiny = 1e-8
    pts = [(point[0] + random.uniform(-tiny, tiny),
            point[1] + random.uniform(-tiny, tiny), 0.0) for point in points]

    # create super triangle
    pt1, pt2, pt3 = super_triangle(points)

    # add super triangle vertices to mesh
    n = len(points)
    super_keys = n, n + 1, n + 2

    mesh.add_vertex(super_keys[0], {'x': pt1[0], 'y': pt1[1], 'z': pt1[2]})
    mesh.add_vertex(super_keys[1], {'x': pt2[0], 'y': pt2[1], 'z': pt2[2]})
    mesh.add_vertex(super_keys[2], {'x': pt3[0], 'y': pt3[1], 'z': pt3[2]})

    mesh.add_face(super_keys)

    # iterate over points
    for i, pt in enumerate(pts):
        key = i

        # check in which triangle this point falls
        for fkey in list(mesh.faces()):
            # abc = mesh.face_coordinates(fkey) #This is slower
            # This is faster:
            keya, keyb, keyc = mesh.face_vertices(fkey)

            dicta = mesh.vertex[keya]
            dictb = mesh.vertex[keyb]
            dictc = mesh.vertex[keyc]

            a = [dicta['x'], dicta['y']]
            b = [dictb['x'], dictb['y']]
            c = [dictc['x'], dictc['y']]

            if is_point_in_triangle_2d(pt, [a, b, c]):
                # generate 3 new triangles (faces) and delete surrounding triangle
                newtris = mesh.insert_vertex(fkey, key=key, xyz=pt)
                break

        while newtris:
            fkey = newtris.pop()

            # get opposite_face
            keys = mesh.face_vertices(fkey)
            s = list(set(keys) - set([key]))
            u, v = s[0], s[1]
            fkey1 = mesh.halfedge[u][v]

            if fkey1 != fkey:
                fkey_op, u, v = fkey1, u, v
            else:
                fkey_op, u, v = mesh.halfedge[v][u], u, v

            if fkey_op:
                keya, keyb, keyc = mesh.face_vertices(fkey_op)
                dicta = mesh.vertex[keya]
                a = [dicta['x'], dicta['y']]
                dictb = mesh.vertex[keyb]
                b = [dictb['x'], dictb['y']]
                dictc = mesh.vertex[keyc]
                c = [dictc['x'], dictc['y']]

                circle = circle_from_points_2d(a, b, c)

                if is_point_in_circle_2d(pt, circle):
                    fkey, fkey_op = swap_edge_trimesh(mesh, u, v)
                    newtris.append(fkey)
                    newtris.append(fkey_op)

    # Delete faces adjacent to supertriangle
    for key in super_keys:
        mesh.remove_vertex(key)

    # Delete faces outside of boundary
    if polygon:
        for fkey in list(mesh.faces()):
            cent = mesh.face_centroid(fkey)
            if not is_point_in_polygon_2d(cent, polygon):
                mesh.delete_face(fkey)

    # Delete faces inside of inside boundaries
    if polygons:
        for polygon in polygons:
            for fkey in list(mesh.faces()):
                cent = mesh.face_centroid(fkey)
                if is_point_in_polygon_2d(cent, polygon):
                    mesh.delete_face(fkey)

    return [[int(key) for key in mesh.face_vertices(fkey, True)]
            for fkey in mesh.faces()]