def sort_pts(sets_pts):
    # sorts point sets for coons patch

    # sort point sets in a "continous chain"
    end_pt = sets_pts[0][-1]
    new_sets_pts = [sets_pts[0]]
    sets_pts.pop(0)

    while True:
        flag = True
        for i, set_pts in enumerate(sets_pts):
            if geometric_key(set_pts[0]) == geometric_key(end_pt):
                end_pt = set_pts[-1]
                new_sets_pts.append(set_pts)
                sets_pts.pop(i)
                flag = False
            elif geometric_key(set_pts[-1]) == geometric_key(end_pt):
                end_pt = set_pts[0]
                set_pts.reverse()
                new_sets_pts.append(set_pts)
                sets_pts.pop(i)
                flag = False

        if flag: break

    #coons patch sorting
    new_sets_pts[2].reverse()
    new_sets_pts[3].reverse()

    return new_sets_pts
Example #2
0
    def create_networks():
        networks = {}
        descendent_tree = {}
        for u in joints:
            global_local = {}
            lines = []
            nbrs = network_global.neighbors(u)
            start_pt = network_global.node_coordinates(u)

            for v in nbrs:
                end_pt = network_global.edge_point(u, v, t=joint_length)
                lines.append([start_pt, end_pt])

            network_local = Network.from_lines(lines)
            key_local = list(
                set(list(network_local.nodes())) -
                set(network_local.leaves()))[0]
            global_local.update({u: key_local})

            gkeys_global_network = [geometric_key(line[1]) for line in lines]
            gkeys_local_network = [
                geometric_key(network_local.node_coordinates(key))
                for key in network_local.leaves()
            ]

            for i, key_global in enumerate(nbrs):
                gkey_global = gkeys_global_network[i]
                index_local = gkeys_local_network.index(gkey_global)
                key_local = network_local.leaves()[index_local]
                global_local.update({key_global: key_local})

            descendent_tree.update({u: global_local})
            networks.update({u: network_local})

        return networks, descendent_tree
Example #3
0
    def from_polylines(cls, boundary_polylines, other_polylines):
        """Construct mesh from polylines.

        Based on construction from_lines,
        with removal of vertices that are not polyline extremities
        and of faces that represent boundaries.

        This specific method is useful to get the mesh connectivity from a set of (discretised) curves,
        that could overlap and yield a wrong connectivity if using from_lines based on the polyline extremities only.

        Parameters
        ----------
        boundary_polylines : list
            List of polylines representing boundaries as lists of vertex coordinates.
        other_polylines : list
            List of the other polylines as lists of vertex coordinates.

        Returns
        -------
        Mesh
            A mesh object.
        """
        corner_vertices = [geometric_key(xyz) for polyline in boundary_polylines + other_polylines for xyz in [polyline[0], polyline[-1]]]
        boundary_vertices = [geometric_key(xyz) for polyline in boundary_polylines for xyz in polyline]
        mesh = cls.from_lines([(u, v) for polyline in boundary_polylines + other_polylines for u, v in pairwise(polyline)])
        # remove the vertices that are not from the polyline extremities and the faces with all their vertices on the boundary
        vertex_keys = [vkey for vkey in mesh.vertices() if geometric_key(mesh.vertex_coordinates(vkey)) in corner_vertices]
        vertex_map = {vkey: i for i, vkey in enumerate(vertex_keys)}
        vertices = [mesh.vertex_coordinates(vkey) for vkey in vertex_keys]
        faces = []
        for fkey in mesh.faces():
            if sum([geometric_key(mesh.vertex_coordinates(vkey)) not in boundary_vertices for vkey in mesh.face_vertices(fkey)]):
                faces.append([vertex_map[vkey] for vkey in mesh.face_vertices(fkey) if geometric_key(mesh.vertex_coordinates(vkey)) in corner_vertices])
        mesh.cull_vertices()
        return cls.from_vertices_and_faces(vertices, faces)
Example #4
0
    def brep_to_compas(self, cls=None):
        if not self.geometry.HasBrepForm:
            return
        success, brep = self.geometry.TryConvertBrep()
        if not success:
            return

        gkey_xyz = {}
        faces = []
        for loop in brep.Loops:
            curve = loop.To3dCurve()
            segments = curve.Explode()
            face = []
            sp = segments[0].PointAtStart
            ep = segments[0].PointAtEnd
            sp_gkey = geometric_key(sp)
            ep_gkey = geometric_key(ep)
            gkey_xyz[sp_gkey] = sp
            gkey_xyz[ep_gkey] = ep
            face.append(sp_gkey)
            face.append(ep_gkey)
            for segment in segments[1:-1]:
                ep = segment.PointAtEnd
                ep_gkey = geometric_key(ep)
                face.append(ep_gkey)
                gkey_xyz[ep_gkey] = ep
            faces.append(face)

        gkey_index = {gkey: index for index, gkey in enumerate(gkey_xyz)}
        vertices = [list(xyz) for gkey, xyz in gkey_xyz.items()]
        faces = [[gkey_index[gkey] for gkey in f] for f in faces]
        cls = cls or Mesh
        return cls.from_vertices_and_faces(vertices, faces)
Example #5
0
	def quadrangulate_polygonal_faces(self):
		# WIP: problem not all faces should have the same source for propagation

		supermesh = self.mesh

		delaunay_vertex_map = tuple(geometric_key(self.vertex_coordinates(vkey)) for vkey in self.vertices())
		#newly added vertices in mesh that were not in the Delaunay are missing...

		edges_to_unweld = [edge for edge in supermesh.edges() if sum([geometric_key(supermesh.vertex_coordinates(i)) in delaunay_vertex_map for i in edge]) == 2]
		mesh_unweld_edges(supermesh, edges_to_unweld)

		meshes = mesh_explode(supermesh)

		for mesh in meshes:
			candidate_map = {geometric_key(mesh.vertex_coordinates(vkey)): [] for vkey in mesh.vertices()}
			for vkey in mesh.vertices_on_boundary():
				candidate_map[geometric_key(mesh.vertex_coordinates(vkey))].append(mesh.vertex_degree(vkey))

			source_map = tuple([geom_key for geom_key, valencies in candidate_map.items() if len(list(set(valencies))) > 1])
			self.mesh = mesh_weld(mesh)
			mesh = self.mesh

			sources = [vkey for vkey in mesh.vertices() if geometric_key(mesh.vertex_coordinates(vkey)) in source_map]

			quadrangulate_mesh(mesh, sources)
Example #6
0
def sort_pts(sets_pts):
    # sorts point sets for coons patch

    # sort point sets in a "continous chain"
    start_pt = sets_pts[0][-1]
    new_sets_pts = [sets_pts[0]]
    sets_pts.pop(0)
    
    count = 0
    while sets_pts:
        for i, set_pts in enumerate(sets_pts):
            #alternative for a more "forgiving" point comparison
            #geometric_key(set_pts[0]) == geometric_key(start_pt)
            if geometric_key(set_pts[0]) == geometric_key(start_pt):
                start_pt = set_pts[-1]
                new_sets_pts.append(set_pts)
                sets_pts.pop(i)
            elif geometric_key(set_pts[-1]) == geometric_key(start_pt):
                start_pt = set_pts[0]
                set_pts.reverse()
                new_sets_pts.append(set_pts)
                sets_pts.pop(i)
               
        if count > 100:
            break
        count += 1
                
    #coons patch sorting
    new_sets_pts[2].reverse()
    new_sets_pts[3].reverse()
                
    return new_sets_pts
    def decomposition_polysurface(self, point_features):
        """Output the remapped decomposition polysurface.

		Parameters
		----------
		point_features : list
			The point features for pole locations.

		Returns
		-------
		A Rhino surface guid.
			The remapped decomposition polysurface.

		"""

        mesh = self.decomposition_mesh()
        nurbs_curves = {(geometric_key(polyline[i]),
                         geometric_key(polyline[-i - 1])):
                        rs.AddInterpCrvOnSrfUV(self.srf_guid,
                                               [pt[:2] for pt in polyline])
                        for polyline in self.decomposition_polylines()
                        for i in [0, -1]}
        polysurface = rs.JoinSurfaces([
            rs.AddEdgeSrf([
                nurbs_curves[(geometric_key(mesh.vertex_coordinates(u)),
                              geometric_key(mesh.vertex_coordinates(v)))]
                for u, v in mesh.face_halfedges(fkey)
            ]) for fkey in mesh.faces()
        ],
                                      delete_input=True)
        rs.DeleteObjects(list(nurbs_curves.values()))
        return polysurface
Example #8
0
def meshes_join_and_weld(meshes, precision=None, cls=None):
    """Join and and weld meshes within some precision distance.
    Parameters
    ----------
    meshes : list
        A list of meshes.
    precision: str
        Tolerance distance for welding.
    Returns
    -------
    mesh
        The joined and welded mesh.
    """

    if cls is None:
        cls = type(meshes[0])

    # create vertex map based on geometric keys in dictionary without duplicates
    vertex_map = {geometric_key(mesh.vertex_coordinates(vkey), precision): vkey for mesh in meshes for vkey in mesh.vertices()}
    # list vertices with coordinates
    vertices = [reverse_geometric_key(geom_key) for geom_key in vertex_map.keys()]
    # reorder vertex keys in vertex map
    vertex_map = {geom_key: i for i, geom_key in enumerate(vertex_map.keys())}
    # modify vertex indices in the faces
    faces = [ [vertex_map[geometric_key(mesh.vertex_coordinates(vkey), precision)] for vkey in mesh.face_vertices(fkey)] for mesh in meshes for fkey in mesh.faces()]

    return cls.from_vertices_and_faces(vertices, faces)
    def decomposition_mesh(self, poles):
        """Return a quad mesh based on the decomposition polylines.
		Some fixes are added to convert the mesh formed by the decomposition polylines into a (coarse) quad mesh.

		Returns
		-------
		mesh
			A coarse quad mesh based on the topological skeleton from a Delaunay mesh.

		"""

        polylines = self.decomposition_polylines()
        boundary_keys = set([
            geometric_key(self.vertex_coordinates(vkey))
            for vkey in self.vertices_on_boundary()
        ])
        boundary_polylines = [
            polyline for polyline in polylines
            if geometric_key(polyline[0]) in boundary_keys
            and geometric_key(polyline[1]) in boundary_keys
        ]
        other_polylines = [
            polyline for polyline in polylines
            if geometric_key(polyline[0]) not in boundary_keys
            or geometric_key(polyline[1]) not in boundary_keys
        ]
        self.mesh = CoarsePseudoQuadMesh.from_polylines(
            boundary_polylines, other_polylines)
        self.solve_triangular_faces()
        self.quadrangulate_polygonal_faces()
        self.split_quads_with_poles(poles)
        self.store_pole_data(poles)
        return self.mesh
Example #10
0
def sort_pts(sets_pts):
    # sorts point sets for coons patch

    # sort point sets in a "continous chain"
    start_pt = sets_pts[0][-1]
    new_sets_pts = [sets_pts[0]]
    sets_pts.pop(0)

    count = 0
    while sets_pts:
        for i, set_pts in enumerate(sets_pts):
            if geometric_key(set_pts[0]) == geometric_key(start_pt):
                start_pt = set_pts[-1]
                new_sets_pts.append(set_pts)
                sets_pts.pop(i)
            elif geometric_key(set_pts[-1]) == geometric_key(start_pt):
                start_pt = set_pts[0]
                set_pts.reverse()
                new_sets_pts.append(set_pts)
                sets_pts.pop(i)

        if count > 100:
            break
        count += 1
    return new_sets_pts
Example #11
0
def join_and_weld_meshes(meshes, tolerance = '3f'):
    """Join and and weld meshes within some tolerance distance.

    Parameters
    ----------
    meshes : list
        A list of meshes.

    tolerance: str
        Tolerance distance for welding.

    Returns
    -------
    vertices : list
        The vertices of the new mesh.
    faces : list
        The faces of the new mesh.

    """

    # create vertex map based on geometric keys in dictionary without duplicates
    vertex_map = {geometric_key(mesh.vertex_coordinates(vkey), tolerance): vkey for mesh in meshes for vkey in mesh.vertices()}
    # list vertices with coordinates
    vertices = [reverse_geometric_key(geom_key) for geom_key in vertex_map.keys()]
    # reorder vertex keys in vertex map
    vertex_map = {geom_key: i for i, geom_key in enumerate(vertex_map.keys())}
    # modify vertex indices in the faces
    faces = [ [vertex_map[geometric_key(mesh.vertex_coordinates(vkey), tolerance)] for vkey in mesh.face_vertices(fkey)] for mesh in meshes for fkey in mesh.faces()]

    return vertices, faces
Example #12
0
def volmesh_from_polysurfaces(cls, guids):
    """Construct a volumetric mesh from given polysurfaces.

    Essentially, this function does the following:

    * find each of the polysurfaces and check if they have a boundary representation (b-rep)
    * convert to b-rep and extract the edge loops
    * make a face of each loop by referring to vertices using their geometric keys
    * add a cell per brep
    * and add the faces of a brep to the cell
    * create a volmesh from the found vertices and cells

    Parameters:
        cls (compas.datastructures.volmesh.VolMesh):
            The class of volmesh.
        guids (sequence of str or System.Guid):
            The *globally unique identifiers* of the polysurfaces.

    Returns:
        compas.datastructures.volmesh.Volmesh: The volumetric mesh object.

    """
    gkey_xyz = {}
    cells = []

    for guid in guids:
        cell = []
        obj = sc.doc.Objects.Find(guid)

        if not obj.Geometry.HasBrepForm:
            continue

        brep = Rhino.Geometry.Brep.TryConvertBrep(obj.Geometry)

        for loop in brep.Loops:
            curve = loop.To3dCurve()
            segments = curve.Explode()
            face = []
            sp = segments[0].PointAtStart
            ep = segments[0].PointAtEnd
            sp_gkey = geometric_key(sp)
            ep_gkey = geometric_key(ep)
            gkey_xyz[sp_gkey] = sp
            gkey_xyz[ep_gkey] = ep
            face.append(sp_gkey)
            face.append(ep_gkey)
            for segment in segments[1:-1]:
                ep = segment.PointAtEnd
                ep_gkey = geometric_key(ep)
                face.append(ep_gkey)
                gkey_xyz[ep_gkey] = ep
            cell.append(face)
        cells.append(cell)

    gkey_index = dict((gkey, index) for index, gkey in enumerate(gkey_xyz))
    vertices = [list(xyz) for gkey, xyz in gkey_xyz.items()]
    cells = [[[gkey_index[gkey] for gkey in face] for face in cell]
             for cell in cells]

    return cls.from_vertices_and_cells(vertices, cells)
Example #13
0
def mesh_identify_vertices(mesh, points, precision=None):
    keys = []
    gkey_key = {geometric_key(mesh.vertex_coordinates(key), precision): key for key in mesh.vertices()}
    for xyz in points:
        gkey = geometric_key(xyz, precision)
        if gkey in gkey_key:
            key = gkey_key[gkey]
            keys.append(key)
    return keys
Example #14
0
def is_point_on_curve(curve_guid, point_xyz):
    geom_key = geometric_key(point_xyz)
    t = rs.CurveClosestPoint(curve_guid, point_xyz)
    pt_on_crv = rs.EvaluateCurve(curve_guid, t)
    geom_key_pt_on_crv = geometric_key(pt_on_crv)
    if geom_key == geom_key_pt_on_crv:
        return True
    else:
        return False
def boundary_triangulation(outer_boundary, inner_boundaries, polyline_features = [], point_features = [], src='numpy_rpc'):
	"""Generate Delaunay triangulation between a planar outer boundary and planar inner boundaries. All vertices lie the boundaries.

	Parameters
	----------
	outer_boundary : list
		Planar outer boundary as list of vertex coordinates.
	inner_boundaries : list
		List of planar inner boundaries as lists of vertex coordinates.
	polyline_features : list
		List of planar polyline_features as lists of vertex coordinates.
	point_features : list
		List of planar point_features as lists of vertex coordinates.
	src : str
		Source of Delaunay triangulation. Default is NumPy via RPC.

	Returns
	-------
	delaunay_mesh : Mesh
		The Delaunay mesh.

	"""

	# generate planar Delaunay triangulation
	vertices = [pt for boundary in [outer_boundary] + inner_boundaries + polyline_features for pt in boundary] + point_features
	if src == 'numpy_rpc':
		faces = delaunay_numpy_rpc(vertices)
	elif src == 'numpy':
		faces = delaunay_numpy(vertices)
	else:
		delaunay_compas(vertices)
	
	delaunay_mesh = Mesh.from_vertices_and_faces(vertices, faces)
	
	# delete false faces with aligned vertices
	for fkey in list(delaunay_mesh.faces()):
		a, b, c = [delaunay_mesh.vertex_coordinates(vkey) for vkey in delaunay_mesh.face_vertices(fkey)]
		ab = subtract_vectors(b, a)
		ac = subtract_vectors(c, a)
		if length_vector(cross_vectors(ab, ac)) == 0:
			delaunay_mesh.delete_face(fkey)

	# delete faces outisde the borders
	for fkey in list(delaunay_mesh.faces()):
		centre = trimesh_face_circle(delaunay_mesh, fkey)[0]
		if not is_point_in_polygon_xy(centre, outer_boundary) or any([is_point_in_polygon_xy(centre, inner_boundary) for inner_boundary in inner_boundaries]):
			delaunay_mesh.delete_face(fkey)

	# topological cut along the feature polylines through unwelding
	vertex_map = {geometric_key(delaunay_mesh.vertex_coordinates(vkey)): vkey for vkey in delaunay_mesh.vertices()}
	edges = [edge for polyline in polyline_features for edge in pairwise([vertex_map[geometric_key(point)] for point in polyline])]
	mesh_unweld_edges(delaunay_mesh, edges)

	return delaunay_mesh
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
Example #17
0
	def branches_singularity_to_singularity(self):
		"""Get the branch polylines of the topological skeleton between singularities only, not corners.

		Returns
		-------
		list
			List of polylines as list of point XYZ-coordinates.

		"""

		map_corners = [geometric_key(trimesh_face_circle(self, corner)[0]) for corner in self.corner_faces()]
		return [branch for branch in self.branches() if geometric_key(branch[0]) not in map_corners and geometric_key(branch[-1]) not in map_corners]
Example #18
0
def mesh_from_surface(cls, guid):
    """Construct a mesh from a Rhino surface.

    Parameters
    ----------
    cls : Mesh
        A mesh type.
    guid : str
        The GUID of the Rhino surface.

    Returns
    -------
    Mesh
        A mesh object.

    """
    gkey_xyz = {}
    faces = []
    obj = sc.doc.Objects.Find(guid)

    if not obj.Geometry.HasBrepForm:
        return

    brep = Rhino.Geometry.Brep.TryConvertBrep(obj.Geometry)

    for loop in brep.Loops:
        curve = loop.To3dCurve()
        segments = curve.Explode()
        face = []
        sp = segments[0].PointAtStart
        ep = segments[0].PointAtEnd
        sp_gkey = geometric_key(sp)
        ep_gkey = geometric_key(ep)
        gkey_xyz[sp_gkey] = sp
        gkey_xyz[ep_gkey] = ep
        face.append(sp_gkey)
        face.append(ep_gkey)

        for segment in segments[1:-1]:
            ep = segment.PointAtEnd
            ep_gkey = geometric_key(ep)
            face.append(ep_gkey)
            gkey_xyz[ep_gkey] = ep

        faces.append(face)

    gkey_index = {gkey: index for index, gkey in enumerate(gkey_xyz)}
    vertices = [list(xyz) for gkey, xyz in gkey_xyz.items()]
    faces = [[gkey_index[gkey] for gkey in f] for f in faces]
    mesh = cls.from_vertices_and_faces(vertices, faces)

    return mesh
    def split_quads_with_poles(self, poles):

        mesh = self.mesh
        pole_map = tuple([geometric_key(pole) for pole in poles])

        faces = list(mesh.faces())
        for fkey in faces:
            if len(mesh.face_vertices(fkey)) == 4:
                for vkey in mesh.face_vertices(fkey):
                    if geometric_key(
                            mesh.vertex_coordinates(vkey)) in pole_map:
                        split_quad_in_pseudo_quads(mesh, fkey, vkey)
                        break
Example #20
0
    def to_compas(self, cls=None):
        """Convert the surface b-rep loops to a COMPAS mesh.

        Parameters
        ----------
        cls : :class:`compas.datastructures.Mesh`, optional
            The type of COMPAS mesh.

        Returns
        -------
        :class:`compas.datastructures.Mesh`
            The resulting mesh.

        """
        if not self.geometry.HasBrepForm:
            return
        brep = Rhino.Geometry.Brep.TryConvertBrep(self.geometry)
        gkey_xyz = {}
        faces = []
        for loop in brep.Loops:
            curve = loop.To3dCurve()
            segments = curve.Explode()
            face = []
            sp = segments[0].PointAtStart
            ep = segments[0].PointAtEnd
            sp_gkey = geometric_key(sp)
            ep_gkey = geometric_key(ep)
            gkey_xyz[sp_gkey] = sp
            gkey_xyz[ep_gkey] = ep
            face.append(sp_gkey)
            face.append(ep_gkey)
            for segment in segments[1:-1]:
                ep = segment.PointAtEnd
                ep_gkey = geometric_key(ep)
                face.append(ep_gkey)
                gkey_xyz[ep_gkey] = ep
            faces.append(face)
        gkey_index = {gkey: index for index, gkey in enumerate(gkey_xyz)}
        vertices = [list(xyz) for gkey, xyz in gkey_xyz.items()]
        faces = [[gkey_index[gkey] for gkey in f] for f in faces]
        polygons = []
        for temp in faces:
            face = []
            for vertex in temp:
                if vertex not in face:
                    face.append(vertex)
            polygons.append(face)
        cls = cls or Mesh
        mesh = cls.from_vertices_and_faces(vertices, polygons)
        mesh.name = self.name
        return mesh
    def branches_splitting_flipped_faces(self):
        """Add new branches to fix the problem of polyline patches that would form flipped faces in the decomposition mesh.

		Returns
		-------
		new_branches : list
			List of polylines as list of point XYZ-coordinates.

		"""

        new_branches = []
        centre_to_fkey = {
            geometric_key(trimesh_face_circle(self, fkey)[0]): fkey
            for fkey in self.faces()
        }

        # compute total rotation of polyline
        for polyline in self.branches_singularity_to_singularity():
            angles = [
                angle_vectors_signed(subtract_vectors(v, u),
                                     subtract_vectors(w, v), [0., 0., 1.])
                for u, v, w in window(polyline, n=3)
            ]
            # subdivide once per angle limit in rotation
            if abs(sum(angles)) > self.flip_angle_limit:
                # the step between subdivision points in polylines (+ 2 for the extremities, which will be discarded)
                alone = len(self.compas_singular_faces()) == 0
                n = floor(abs(sum(angles)) / self.flip_angle_limit) + 1
                step = int(floor(len(polyline) / n))
                # add new branches from corresponding face in Delaunay mesh
                seams = polyline[::step]
                if polyline[-1] != seams[-1]:
                    if len(seams) == n + 1:
                        del seams[-1]
                    seams.append(polyline[-1])
                if alone:
                    seams = seams[0:-1]
                else:
                    seams = seams[1:-1]
                for point in seams:
                    fkey = centre_to_fkey[geometric_key(point)]
                    for edge in self.face_halfedges(fkey):
                        if not self.is_edge_on_boundary(*edge):
                            new_branches += [[
                                trimesh_face_circle(self, fkey)[0],
                                self.vertex_coordinates(vkey)
                            ] for vkey in edge]
                            break

        return new_branches
Example #22
0
    def from_lines(cls, lines, precision=None):
        """Construct a network from a set of lines represented by their start and end point coordinates.

        Parameters
        ----------
        lines : list
            A list of pairs of point coordinates.
        precision: str, optional
            The precision of the geometric map that is used to connect the lines.

        Returns
        -------
        Network
            A network object.

        Examples
        --------
        .. code-block:: python

            import json

            import compas
            from compas.datastructures import Network

            with open(compas.get('lines.json'), 'r') as fo:
                lines = json.load(fo)

            network = Network.from_lines(lines)

        """
        network = cls()
        edges = []
        vertex = {}
        for line in lines:
            sp = line[0]
            ep = line[1]
            a = geometric_key(sp, precision)
            b = geometric_key(ep, precision)
            vertex[a] = sp
            vertex[b] = ep
            edges.append((a, b))
        key_index = dict((k, i) for i, k in enumerate(iter(vertex)))
        for key, xyz in iter(vertex.items()):
            i = key_index[key]
            network.add_vertex(i, x=xyz[0], y=xyz[1], z=xyz[2])
        for u, v in edges:
            i = key_index[u]
            j = key_index[v]
            network.add_edge(i, j)
        return network
Example #23
0
 def from_vertices_and_faces_with_poles(cls, vertices, faces, poles=[]):
     pole_map = tuple([geometric_key(pole) for pole in poles])
     mesh = cls.from_vertices_and_faces(vertices, faces)
     for fkey in mesh.faces():
         face_vertices = mesh.face_vertices(fkey)
         if len(face_vertices) == 3:
             mesh.data['attributes']['face_pole'][fkey] = face_vertices[0]
             for vkey in face_vertices:
                 if geometric_key(
                         mesh.vertex_coordinates(vkey)) in pole_map:
                     mesh.data['attributes']['face_pole'].update(
                         {fkey: vkey})
                     break
     return mesh
Example #24
0
    def from_lines(cls, lines, boundary_face=False, precision='3f'):
        """"""
        from compas.datastructures.network.algorithms.duality import _sort_neighbours
        from compas.datastructures.network.algorithms.duality import _find_first_neighbour
        from compas.datastructures.network.algorithms.duality import _find_edge_face

        mesh = cls()
        edges = []
        vertex = {}
        for line in lines:
            sp = line[0]
            ep = line[1]
            a = geometric_key(sp, precision)
            b = geometric_key(ep, precision)
            vertex[a] = sp
            vertex[b] = ep
            edges.append((a, b))
        key_index = dict((k, i) for i, k in enumerate(iter(vertex)))
        for key, xyz in iter(vertex.items()):
            i = key_index[key]
            mesh.add_vertex(i, x=xyz[0], y=xyz[1], z=xyz[2])
        edges_uv = []
        for u, v in edges:
            i = key_index[u]
            j = key_index[v]
            edges_uv.append((i, j))
        # the clear commands below are from the network equivalent. Needed?
        # network.clear_facedict()
        # network.clear_halfedgedict()
        mesh.halfedge = dict((key, {}) for key in mesh.vertex)
        for u, v in edges_uv:
            mesh.halfedge[u][v] = None
            mesh.halfedge[v][u] = None
        _sort_neighbours(mesh)

        u = sorted(mesh.vertices(True), key=lambda x:
                   (x[1]['y'], x[1]['x']))[0][0]
        v = _find_first_neighbour(u, mesh)
        key_boundary_face = _find_edge_face(u, v, mesh)
        print(key_boundary_face)
        for u, v in mesh.edges():
            if mesh.halfedge[u][v] is None:
                _find_edge_face(u, v, mesh)
            if mesh.halfedge[v][u] is None:
                _find_edge_face(v, u, mesh)

        if not boundary_face:
            mesh.delete_face(key_boundary_face)
        return mesh
Example #25
0
def update_network_from_points(network, guids):
    points = rhino.get_point_coordinates(guids)
    names = rhino.get_object_names(guids)
    gkey_key = {geometric_key(network.vertex_coordinates(key)): key for key in network}
    for i, xyz in enumerate(points):
        name = names[i]
        try:
            attr = ast.literal_eval(name)
        except ValueError:
            pass
        else:
            gkey = geometric_key(xyz)
            if gkey in gkey_key:
                key = gkey_key[gkey]
                network.vertex[key].update(attr)
Example #26
0
    def check_element_exists(self, nodes, xyz=None):
        """ Check if an element already exists based on the nodes it connects to or its centroid.

        Parameters
        ----------
        nodes : list
            Node numbers the element is connected to.
        xyz : list
            Direct co-ordinates of the element centroid to check.

        Returns
        -------
        int
            The element index if the element already exists, None if not.

        Notes
        -----
        - Geometric key check is made according to self.tol [m] tolerance.

        """

        if not xyz:
            xyz = centroid_points([self.node_xyz(node) for node in nodes])
        gkey = geometric_key(xyz, '{0}f'.format(self.tol))
        return self.element_index.get(gkey, None)
Example #27
0
    def from_polygons(cls, polygons, precision=None):
        """Construct a mesh from a series of polygons.

        Parameters
        ----------
        polygons : list
            A list of polygons, with each polygon defined as an ordered list of
            XYZ coordinates of its corners.
        precision: str, optional
            The precision of the geometric map that is used to connect the lines.

        Returns
        -------
        Mesh
            A mesh object.
        """
        faces = []
        gkey_xyz = {}
        for points in polygons:
            face = []
            for xyz in points:
                gkey = geometric_key(xyz, precision=precision)
                gkey_xyz[gkey] = xyz
                face.append(gkey)
            faces.append(face)
        gkey_index = {gkey: index for index, gkey in enumerate(gkey_xyz)}
        vertices = gkey_xyz.values()
        faces[:] = [[gkey_index[gkey] for gkey in face] for face in faces]
        return cls.from_vertices_and_faces(vertices, faces)
Example #28
0
    def add_element_to_element_index(self, key, nodes, virtual=False):
        """ Adds the element to the element_index dictionary.

        Parameters
        ----------
        key : int
            Prescribed element key.
        nodes : list
            Node numbers the element is connected to.
        virtual: bool
            If true, adds element to the virtual_element_index dictionary.

        Returns
        -------
        None

        """

        centroid = centroid_points([self.node_xyz(node) for node in nodes])
        gkey = geometric_key(centroid, '{0}f'.format(self.tol))

        if virtual:
            self.virtual_element_index[gkey] = key
        else:
            self.element_index[gkey] = key
Example #29
0
    def check_element_exists(self, nodes=None, xyz=None, virtual=False):
        """ Check if an element already exists based on nodes or centroid.

        Parameters
        ----------
        nodes : list
            Node numbers the element is connected to.
        xyz : list
            Direct co-ordinates of the element centroid to check.
        virtual: bool
            Is the element to be checked a virtual element.

        Returns
        -------
        int
            The element index if the element already exists, None if not.

        Notes
        -----
        - Geometric key check is made according to self.tol [m] tolerance.

        """

        if not xyz:
            xyz = centroid_points([self.node_xyz(node) for node in nodes])

        gkey = geometric_key(xyz, '{0}f'.format(self.tol))

        if virtual:
            return self.virtual_element_index.get(gkey, None)
        else:
            return self.element_index.get(gkey, None)
Example #30
0
def intersection_polyline_box_xy(polyline, box, tol=1e-6):
    """Compute the intersection between a polyline and a box in the XY plane.

    Parameters
    ----------
    polyline : list of points or :class:`compas.geometry.Polyline`
    box : list of 4 points
    tol : float, optional
        A tolerance value for point comparison.
        Default is ``1e-6``.

    Returns
    -------
    list
        A list of intersection points.
    """
    precision = compas.PRECISION
    compas.set_precision(tol)
    points = []
    for side in pairwise(box + box[:1]):
        for segment in pairwise(polyline):
            x = intersection_segment_segment_xy(side, segment, tol=tol)
            if x:
                points.append(x)
    points = {geometric_key(point): point for point in points}
    compas.PRECISION = precision
    return list(points.values())