Example #1
0
def compas_mesh_to_occ_shell(mesh: Mesh) -> TopoDS_Shell:
    """Convert a general COMPAS mesh to an OCC shell.

    Parameters
    ----------
    mesh : :class:`~compas.datastructures.Mesh`
        A COMPAS mesh data structure.

    Returns
    -------
    TopoDS_Shell

    """
    # https://github.com/tpaviot/pythonocc-demos/blob/master/examples/core_geometry_geomplate.py

    shell = TopoDS_Shell()
    builder = BRep_Builder()
    builder.MakeShell(shell)

    for face in mesh.faces():
        points = mesh.face_coordinates(face)

        if len(points) == 3:
            builder.Add(shell, triangle_to_face(points))
        elif len(points) == 4:
            builder.Add(shell, quad_to_face(points))
        else:
            builder.Add(shell, ngon_to_face(points))

    return shell
Example #2
0
def compas_quadmesh_to_occ_shell(mesh: Mesh) -> TopoDS_Shell:
    """Convert a COMPAS quad mesh to an OCC shell.

    Parameters
    ----------
    mesh : :class:`~compas.datastructures.Mesh`
        A COMPAS mesh data structure with quad faces.

    Returns
    -------
    TopoDS_Shell

    Raises
    ------
    AssertionError
        If the input mesh is not a quad mesh.

    """
    assert mesh.is_quadmesh(), "The input mesh is not a quad mesh."

    shell = TopoDS_Shell()
    builder = BRep_Builder()
    builder.MakeShell(shell)

    for face in mesh.faces():
        points = mesh.face_coordinates(face)
        builder.Add(shell, quad_to_face(points))

    return shell
Example #3
0
 def from_mesh(cls: 'MeshModel',
               mesh: Mesh,
               name: str = 'Mesh',
               targetlength: float = 1.0) -> None:
     model = cls(name)
     model.vertex_tag = {}
     for vertex in mesh.vertices():
         point = mesh.vertex_coordinates(vertex)
         model.vertex_tag[vertex] = model.occ.add_point(
             *point, targetlength)
     for face in mesh.faces():
         loop = []
         for u, v in mesh.face_halfedges(face):
             tag = model.occ.add_line(model.vertex_tag[u],
                                      model.vertex_tag[v])
             loop.append(tag)
         tag = model.occ.add_curve_loop(loop)
         model.occ.add_surface_filling(tag)
     return model
Example #4
0
def delaunay_from_points(points, boundary=None, holes=None, tiny=1e-12):
    """Computes the delaunay triangulation for a list of points.

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

    Returns
    -------
    list
        The faces of the triangulation.
        Each face is a triplet of indices referring to the list of point coordinates.

    Notes
    -----
    For more info, see [1]_.

    References
    ----------
    .. [1] Sloan, S. W., 1987 *A fast algorithm for constructing Delaunay triangulations in the plane*
           Advances in Engineering Software 9(1): 34-55, 1978.

    Example
    -------
    .. plot::
        :include-source:

        from compas.datastructures import Mesh
        from compas.geometry import pointcloud_xy
        from compas.geometry import delaunay_from_points
        from compas_plotters import MeshPlotter

        points = pointcloud_xy(20, (0, 50))
        faces = delaunay_from_points(points)

        delaunay = Mesh.from_vertices_and_faces(points, faces)

        plotter = MeshPlotter(delaunay)
        plotter.draw_vertices(radius=0.1)
        plotter.draw_faces()
        plotter.show()

    """
    from compas.datastructures import Mesh
    from compas.datastructures import trimesh_swap_edge

    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
    points = [(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(points):
        key = i

        # newtris should be intialised here

        # 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_xy(pt, [a, b, c], True):
                # generate 3 new triangles (faces) and delete surrounding triangle
                key, newtris = mesh.insert_vertex(fkey, key=key, xyz=pt, return_fkeys=True)
                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_xy(a, b, c)

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

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

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

    # Delete faces inside of inside boundaries
    if holes:
        for polygon in holes:
            for fkey in list(mesh.faces()):
                centroid = mesh.face_centroid(fkey)
                if is_point_in_polygon_xy(centroid, polygon):
                    mesh.delete_face(fkey)

    return [mesh.face_vertices(fkey) for fkey in mesh.faces()]
    # ==========================================================================

    vector_tag = 'ps_1_top'
    lines = vector_lines_on_faces(mesh, vector_tag, True, factor=0.05)
    lines = [line for line in map(line_tuple_to_dict, lines)]
    for line in lines:
        line['width'] = 0.60

    # ==========================================================================
    # Instantiate StructuralMesh()
    # ==========================================================================

    str_mesh = StructuralMesh(mesh)

    for tag in tags:
        vector_field = mesh.get_faces_attribute(keys=list(mesh.faces()),
                                                name=tag)
        str_mesh.set_face_vectors(vector_field, tag, normalize=True)
        str_mesh.set_vertex_vectors_angles(tag)

    # str_mesh.get_edge_labels(vector_tag, 0.01)
    str_mesh.get_face_labels(vector_tag, 0.0)
    umbilic_keys = list(
        str_mesh.c_mesh.faces_where_predicate(
            lambda f_key, attr: attr['label'] != 1))
    not_umbilic_keys = list(
        str_mesh.c_mesh.faces_where_predicate(
            lambda f_key, attr: attr['label'] == 1))
    umbilics = [str_mesh.c_mesh.face_centroid(fkey) for fkey in umbilic_keys]

    # ==========================================================================
Example #6
0
def delaunay_from_points(points, boundary=None, holes=None, tiny=1e-12):
    """Computes the delaunay triangulation for a list of points.

    Parameters
    ----------
    points : sequence[[float, float, float] | :class:`compas.geometry.Point`]
        XYZ coordinates of the original points.
    boundary : sequence[[float, float, float] | :class:`compas.geometry.Point`] | :class:`compas.geometry.Polygon`, optional
        List of ordered points describing the outer boundary.
    holes : sequence[sequence[[float, float, float] | :class:`compas.geometry.Point`] | :class:`compas.geometry.Polygon`], optional
        List of polygons (ordered points describing internal holes.

    Returns
    -------
    list[[int, int, int]]
        The faces of the triangulation.
        Each face is a triplet of indices referring to the list of point coordinates.

    Notes
    -----
    For more info, see [1]_.

    References
    ----------
    .. [1] Sloan, S. W., 1987 *A fast algorithm for constructing Delaunay triangulations in the plane*
           Advances in Engineering Software 9(1): 34-55, 1978.

    Examples
    --------
    >>>

    """
    from compas.datastructures import Mesh
    from compas.datastructures import trimesh_swap_edge

    def super_triangle(coords, ccw=True):
        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)
        if ccw:
            return pt1, pt3, pt2
        return pt1, pt2, pt3

    mesh = Mesh()

    # to avoid numerical issues for perfectly structured point sets
    points = [(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 key, point in enumerate(points):
        # newtris should be intialised here

        # check in which triangle this point falls
        for fkey in list(mesh.faces()):
            abc = mesh.face_coordinates(fkey)

            if is_point_in_triangle_xy(point, abc, True):
                # generate 3 new triangles (faces) and delete surrounding triangle
                key, newtris = mesh.insert_vertex(fkey,
                                                  key=key,
                                                  xyz=point,
                                                  return_fkeys=True)
                break

        while newtris:
            fkey = newtris.pop()

            face = mesh.face_vertices(fkey)
            i = face.index(key)
            u = face[i - 2]
            v = face[i - 1]

            nbr = mesh.halfedge[v][u]

            if nbr is not None:
                a, b, c = mesh.face_coordinates(nbr)
                circle = circle_from_points_xy(a, b, c)

                if is_point_in_circle_xy(point, circle):
                    fkey, nbr = trimesh_swap_edge(mesh, u, v)
                    newtris.append(fkey)
                    newtris.append(nbr)

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

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

    # Delete faces inside of inside boundaries
    if holes:
        for polygon in holes:
            for fkey in list(mesh.faces()):
                centroid = mesh.face_centroid(fkey)
                if is_point_in_polygon_xy(centroid, polygon):
                    mesh.delete_face(fkey)

    return [mesh.face_vertices(fkey) for fkey in mesh.faces()]
Example #7
0
            else:
                mesh.face_attribute(fk, 'ftype', 'panel')


mesh = Mesh()
a = mesh.add_vertex(x=0, y=0, z=0)
b = mesh.add_vertex(x=1, y=0, z=0)
c = mesh.add_vertex(x=1, y=1, z=0)
d = mesh.add_vertex(x=0, y=1, z=0)
f = mesh.add_face([a, b, c, d])

mesh = sd.mesh_subdivide_tri(mesh)

mesh = sd.mesh_subdivide_quad(mesh)

fkeys = list(mesh.faces())

for fk in fkeys:

    new_keys = msd.segment_face(mesh, fk, num=2, start_index=0)

    for key in new_keys:
        mesh.face_attribute(key, "ftype", "plot")

# artist = MeshArtist(mesh, layer="level1")
# artist.clear_layer()
# artist.draw_faces( join_faces=True)

m1 = mesh.copy()
subdivide_by_ftype(m1)
# artist2 = MeshArtist(m1, layer="level2")
# Import mesh
# ==========================================================================

mesh = Mesh()
mesh.load(HERE)
mesh_unify_cycles(mesh)

# ==========================================================================
# Create PS vector lines
# ==========================================================================

vector_tag = 'ps_1_top'  # ps_1_top

angles = {}
centroids = {}
for fkey, attr in mesh.faces(data=True):
    vector = attr.get(vector_tag)
    angle = angle_vectors([1.0, 0.0, 0.0], vector, deg=True)
    angles[fkey] = angle
    centroids[fkey] = np.array(mesh.face_centroid(fkey))

print('max angle', min(angles.values()))
print('min angle', max(angles.values()))

for idx, angle in angles.items():
    if angle <= 90.0:
        continue
    angles[idx] = 180.0 - angle

print('max angle', min(angles.values()))
print('min angle', max(angles.values()))
sigma = 2.0

# ==========================================================================
# Import mesh
# ==========================================================================

mesh = Mesh()
new_mesh = Mesh()
mesh.load(HERE)

# ==========================================================================
# rebuild mesh
# ==========================================================================

all_vertices = set()
for idx, tup in enumerate(mesh.faces(True)):
    fkey, attr = tup

    if mesh.face_centroid(fkey)[0] < 0.0:  # mesh deleter by symmetry
        continue

    attr_dict = {k: v for k, v in attr.items()}
    face = mesh.face_vertices(fkey)
    new_mesh.add_face(key=idx, vertices=face, attr_dict=attr_dict)
    all_vertices.update(face)

for vkey, attr in mesh.vertices(True):
    if vkey not in all_vertices:
        continue
    attr_dict = {k: v for k, v in attr.items()}
    new_mesh.add_vertex(vkey, attr_dict=attr_dict)
    mesh.load(HERE)

    # ==========================================================================
    # Import mesh
    # ==========================================================================

    mesh = Mesh()
    new_mesh = Mesh()
    mesh.load(HERE)

    # ==========================================================================
    # rebuild mesh
    # ==========================================================================

    all_vertices = set()
    for idx, tup in enumerate(mesh.faces(True)):
        fkey, attr = tup

        if mesh.face_centroid(fkey)[0] < 0.0:  # mesh deleter by symmetry
            continue

        attr_dict = {k: v for k, v in attr.items()}
        face = mesh.face_vertices(fkey)
        new_mesh.add_face(key=idx, vertices=face, attr_dict=attr_dict)
        all_vertices.update(face)

    for vkey, attr in mesh.vertices(True):
        if vkey not in all_vertices:
            continue
        attr_dict = {k: v for k, v in attr.items()}
        new_mesh.add_vertex(vkey, attr_dict=attr_dict)