Beispiel #1
0
    def face_skewness(self, fkey):
        """Face skewness as the maximum absolute angular deviation from the ideal polygon angle.

        Parameters
        ----------
        fkey : Key
            The face key.

        Returns
        -------
        float
            The skewness.

        References
        ----------
        .. [1] Wikipedia. *Types of mesh*.
               Available at: https://en.wikipedia.org/wiki/Types_of_mesh.
        """
        ideal_angle = 180 * (1 - 2 / float(len(self.face_vertices(fkey))))
        angles = []
        vertices = self.face_vertices(fkey)
        for u, v, w in window(vertices + vertices[:2], n=3):
            o = self.vertex_coordinates(v)
            a = self.vertex_coordinates(u)
            b = self.vertex_coordinates(w)
            angle = angle_points(o, a, b, deg=True)
            angles.append(angle)
        return max((max(angles) - ideal_angle) / (180 - ideal_angle),
                   (ideal_angle - min(angles)) / ideal_angle)
Beispiel #2
0
    def vertex_curvature(self, vkey):
        """Dimensionless vertex curvature.

        Parameters
        ----------
        fkey : int
            The face key.

        Returns
        -------
        float
            The dimensionless curvature.

        References
        ----------
        Based on [1]_

        .. [1] Botsch, Mario, et al. *Polygon mesh processing.* AK Peters/CRC Press, 2010.
        """
        C = 0
        for u, v in pairwise(
                self.vertex_neighbors(vkey, ordered=True) +
                self.vertex_neighbors(vkey, ordered=True)[:1]):
            C += angle_points(self.vertex_coordinates(vkey),
                              self.vertex_coordinates(u),
                              self.vertex_coordinates(v))
        return 2 * pi - C
Beispiel #3
0
    def is_boundary_vertex_kink(self, vkey, threshold_angle):
        """Return whether there is a kink at a boundary vertex according to a threshold angle.

		Parameters
		----------
		vkey : Key
			The boundary vertex key.
		threshold_angle : float
			Threshold angle in rad.

		Returns
		-------
		bool
			True if vertex is on the boundary and has an angle larger than the threshold angle. False otherwise.
		"""

        # check if vertex is on boundary
        if not self.is_vertex_on_boundary(vkey):
            return False

        # get the two adjacent boundary vertices (exactly two for manifold meshes)
        ukey, wkey = [
            nbr for nbr in self.vertex_neighbors(vkey)
            if self.is_edge_on_boundary(vkey, nbr)
        ]

        # compare boundary angle with threshold angle
        return angle_points(self.vertex_coordinates(ukey),
                            self.vertex_coordinates(vkey),
                            self.vertex_coordinates(wkey)) > threshold_angle
Beispiel #4
0
 def brace_angle(self, value):
     if value is not None:
         self._brace_angle = value
     else:
         self._brace_angle = angle_points(self.column.end_pt,
                                          self.work_point,
                                          self.brace.end_pt,
                                          deg=True)
Beispiel #5
0
def trimesh_gaussian_curvature(mesh):
    r"""Compute the gaussian curvature at the vertices of a triangle mesh using the angular deficit.

    The angular deficit at a vertex is defined as the difference between a full
    circle angle (:math:`2\pi`) and the sum of the angles in the adjacent trianlges.

    .. math::

        k_{G}(v_{i}) = 2\pi - \sum_{j \in N(i)} \teta_{ij}

    where :math:`N(i)` are the triangles incident on vertex :math:`i` and :math:`\teta_{ij}`
    is the angle at vertex :math:`i` in triangle :math:`j`.

    Parameters
    ----------
    mesh : compas.oatastructures.Mesh
        The triangle mesh data structure.

    Returns
    -------
    list of float
        Per vertex curvature values.

    Warning
    -------
    This function will not check if the provided mesh is actually a triangle mesh.
    It will just treat as such...

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

        pass

    """
    pi2 = 2 * pi
    key_xyz = {
        key: mesh.get_vertex_attributes(key, 'xyz')
        for key in mesh.vertices()
    }
    curvature = []
    for key in mesh.vertices():
        angles = []
        o = key_xyz[key]
        for u in mesh.vertex_neighbors(key):
            fkey = mesh.halfedge[key][u]
            if fkey is not None:
                vertices = mesh.face_vertices(fkey)
                v = vertices[vertices.index(key) - 1]
                a = key_xyz[u]
                b = key_xyz[v]
                print(o, a, b)
                angles.append(angle_points(o, a, b))
        curvature.append(pi2 - sum(angles))
    return curvature
Beispiel #6
0
def vertex_curvatures(mesh):
    """Curvatures of the non-boundary mesh vertices as dict vertex: vertex curvature.
	Curvature of a vertex = 2 * pi - sum angles between adajcent edges.

	Parameters
	----------
	mesh : Mesh
		A mesh.

	Returns
	-------
	vertex_curvature_dict: dict
		Dictionary of curvatures per vertex {vertex: vertex curvature}. None if vertex is on the boundary.

	Raises
	------
	-

	"""

    vertex_curvature_dict = {}
    for vkey in mesh.vertices():
        if not mesh.is_vertex_on_boundary(vkey):
            sum_angles = 0
            neighbours = mesh.vertex_neighbours(vkey)
            for i in range(len(neighbours)):
                nbr_1 = neighbours[i - 1]
                nbr_2 = neighbours[i]
                sum_angles += angle_points(mesh.vertex_coordinates(vkey),
                                           mesh.vertex_coordinates(nbr_1),
                                           mesh.vertex_coordinates(nbr_2))
            vertex_curvature_dict[vkey] = 2 * pi - sum_angles
        else:
            vertex_curvature_dict[vkey] = None

    return vertex_curvature_dict
Beispiel #7
0
world = Frame.worldXY()

for guid in guids:
    surface = RhinoSurface.from_guid(guid)
    block = surface.to_compas()

    block.name = str(guid)

    bottom = sorted(
        block.faces(),
        key=lambda face: dot_vectors(block.face_normal(face), [0, 0, -1]))[-1]

    u, v, w = sorted(block.face_corners(bottom),
                     key=lambda corner: abs(
                         angle_points(block.vertex_coordinates(corner[1]),
                                      block.vertex_coordinates(corner[2]),
                                      block.vertex_coordinates(corner[0])) -
                         0.5 * 3.14159))[0]

    if block.edge_length(u, v) > block.edge_length(v, w):
        edge = u, v
    else:
        edge = v, w

    xaxis = block.edge_direction(*edge)
    yaxis = cross_vectors([0, 0, 1], xaxis)
    xaxis = cross_vectors(yaxis, [0, 0, 1])

    frame = Frame(block.face_centroid(bottom), xaxis, yaxis)

    T = Transformation.from_frame_to_frame(frame, world)