Ejemplo n.º 1
0
def compute_minimal_distance_between_circles():
    """ compute the minimal distance between 2 circles

    here the minimal distance overlaps the intersection of the circles
    the points are rendered to indicate the locations

    """
    # required for precise rendering of the circles
    display.Context.SetDeviationCoefficient(0.0001)
    L = gp_Pnt(4, 10, 0)
    M = gp_Pnt(10, 16, 0)

    Laxis = gp_Ax2()
    Maxis = gp_Ax2()
    Laxis.SetLocation(L)
    Maxis.SetLocation(M)

    r1 = 12.0
    r2 = 15.0
    Lcircle = gp_Circ(Laxis, r1)
    Mcircle = gp_Circ(Maxis, r2)

    l_circle, m_circle = make_edge(Lcircle), make_edge(Mcircle)
    display.DisplayShape([l_circle, m_circle])

    # compute the minimal distance between 2 circles
    # the minimal distance here matches the intersection of the circles
    dss = BRepExtrema_DistShapeShape(l_circle, m_circle)

    print("intersection parameters on l_circle:",
          [dss.ParOnEdgeS1(i) for i in range(1, dss.NbSolution() + 1)])
    print("intersection parameters on m_circle:",
          [dss.ParOnEdgeS2(i) for i in range(1, dss.NbSolution() + 1)])

    for i in range(1, dss.NbSolution() + 1):
        pnt = dss.PointOnShape1(i)
        display.DisplayShape(make_vertex(pnt))
Ejemplo n.º 2
0
class DistanceShapeToShape(object):
    """
    Calculate minimum distance between two shapes. If geometry is provided
    it will be converted to a shape.

    :param shape1: The first shape or geometry.
    :type shape1: afem.topology.entities.Shape or
        afem.geometry.entities.Geometry
    :param shape2: The second or geometry.
    :type shape2: afem.topology.entities.Shape or
        afem.geometry.entities.Geometry

    Usage:

    >>> from afem.topology import *
    >>> v1 = VertexByPoint((0., 0., 0.)).vertex
    >>> v2 = VertexByPoint((10., 0., 0.)).vertex
    >>> tool = DistanceShapeToShape(v1, v2)
    >>> tool.nsol
    1
    >>> tool.dmin
    10.0
    """
    def __init__(self, shape1, shape2, deflection=1.0e-7):
        shape1 = Shape.to_shape(shape1)
        shape2 = Shape.to_shape(shape2)
        self._tool = BRepExtrema_DistShapeShape(shape1.object, shape2.object,
                                                deflection,
                                                Extrema_ExtFlag_MIN)

    @property
    def is_done(self):
        """
        :return: *True* if algorithm is done, *False* if not.
        :rtype: bool
        """
        return self._tool.IsDone()

    @property
    def nsol(self):
        """
        :return: The number of solutions satisfying the minimum distance.
        :rtype:
        """
        return self._tool.NbSolution()

    @property
    def dmin(self):
        """
        :return: The minimum distance.
        :rtype: float
        """
        return self._tool.Value()

    @property
    def inner_solution(self):
        """
        :return: *True* if one of the shapes is a solid and the other is
            completely or partially inside the solid.
        :rtype: bool
        """
        return self._tool.InnerSolution()

    def point_on_shape1(self, n=1):
        """
        The point for the *n-th* solution on the first shape.

        :param int n: The index.

        :return: The point.
        :rtype: afem.geometry.entities.Point
        """
        gp_pnt = self._tool.PointOnShape1(n)
        return Point(gp_pnt.X(), gp_pnt.Y(), gp_pnt.Z())

    def point_on_shape2(self, n=1):
        """
        The point for the *n-th* solution on the second shape.

        :param int n: The index.

        :return: The point.
        :rtype: afem.geometry.entities.Point
        """
        gp_pnt = self._tool.PointOnShape2(n)
        return Point(gp_pnt.X(), gp_pnt.Y(), gp_pnt.Z())

    def support_type_shape1(self, n=1):
        """
        The type of support for the *n-th* solution on the first shape.

        :param int n: The index.

        :return: The support type.
        :rtype: OCCT.BRepExtrema.BRepExtrema_SupportType
        """
        return self._tool.SupportTypeShape1(n)

    def is_vertex_shape1(self, n=1):
        """
        Check if support type is a vertex for the first shape.

        :param int n: The index.

        :return: *True* if a vertex, *False* otherwise.
        :rtype: bool
        """
        return self.support_type_shape1(n) == BRepExtrema_IsVertex

    def is_on_edge_shape1(self, n=1):
        """
        Check if support type is on an edge for the first shape.

        :param int n: The index.

        :return: *True* if on an edge, *False* otherwise.
        :rtype: bool
        """
        return self.support_type_shape1(n) == BRepExtrema_IsOnEdge

    def is_in_face_shape1(self, n=1):
        """
        Check if support type is in a face for the first shape.

        :param int n: The index.

        :return: *True* if in a face, *False* otherwise.
        :rtype: bool
        """
        return self.support_type_shape1(n) == BRepExtrema_IsInFace

    def support_type_shape2(self, n=1):
        """
        The type of support for the *n-th* solution on the second shape.

        :param int n: The index.

        :return: The support type.
        :rtype: OCCT.BRepExtrema.BRepExtrema_SupportType
        """
        return self._tool.SupportTypeShape2(n)

    def is_vertex_shape2(self, n=1):
        """
        Check if support type is a vertex for the second shape.

        :param int n: The index.

        :return: *True* if a vertex, *False* otherwise.
        :rtype: bool
        """
        return self.support_type_shape2(n) == BRepExtrema_IsVertex

    def is_on_edge_shape2(self, n=1):
        """
        Check if support type is on an edge for the second shape.

        :param int n: The index.

        :return: *True* if on an edge, *False* otherwise.
        :rtype: bool
        """
        return self.support_type_shape2(n) == BRepExtrema_IsOnEdge

    def is_in_face_shape2(self, n=1):
        """
        Check if support type is in a face for the second shape.

        :param int n: The index.

        :return: *True* if in a face, *False* otherwise.
        :rtype: bool
        """
        return self.support_type_shape2(n) == BRepExtrema_IsInFace

    def support_on_shape1(self, n=1):
        """
        Get the shape where the *n-th* solution is on the first shape.

        :param int n: The index.

        :return: The support shape.
        :rtype: afem.topology.entities.Shape
        """
        return Shape.wrap(self._tool.SupportOnShape1(n))

    def support_on_shape2(self, n=1):
        """
        Get the shape where the *n-th* solution is on the second shape.

        :param int n: The index.

        :return: The support shape.
        :rtype: afem.topology.entities.Shape
        """
        return Shape.wrap(self._tool.SupportOnShape2(n))

    def par_on_edge_shape1(self, n=1):
        """
        Get the parameter of the *n-th* solution if it is on an edge of the
        first shape.

        :param int n: The index.

        :return: The parameter.
        :rtype: float
        """
        return self._tool.ParOnEdgeS1(n, 0.)

    def par_on_edge_shape2(self, n=1):
        """
        Get the parameter of the *n-th* solution if it is on an edge of the
        second shape.

        :param int n: The index.

        :return: The parameter.
        :rtype: float
        """
        return self._tool.ParOnEdgeS2(n, 0.)

    def par_on_face_shape1(self, n=1):
        """
        Get the parameters of the *n-th* solution if it is in a face of the
        first shape.

        :param int n: The index.

        :return: The parameters.
        :rtype: tuple(float, float)
        """
        return self._tool.ParOnFaceS1(n, 0., 0.)

    def par_on_face_shape2(self, n=1):
        """
        Get the parameters of the *n-th* solution if it is in a face of the
        second shape.

        :param int n: The index.

        :return: The parameters.
        :rtype: tuple(float, float)
        """
        return self._tool.ParOnFaceS2(n, 0., 0.)

    def normal_on_shape1(self, n=1):
        """
        Get a unit normal on the first shape where the *n-th* solution is
        located if it is in a face.

        :param int n: The index.

        :return: The unit normal.
        :rtype: afem.geometry.entities.Direction

        :raise ValueError: If the solution is not in a face.
        """
        if not self.is_in_face_shape1(n):
            raise ValueError('The solution is not in a face.')

        face = self.support_on_shape1(n)
        u, v = self.par_on_face_shape1(n)

        adp_srf = FaceAdaptorSurface.by_face(face)
        return Direction.by_vector(adp_srf.norm(u, v))

    def normal_on_shape2(self, n=1):
        """
        Get a unit normal on the second shape where the *n-th* solution is
        located if it is in a face.

        :param int n: The index.

        :return: The unit normal.
        :rtype: afem.geometry.entities.Direction

        :raise ValueError: If the solution is not in a face.
        """
        if not self.is_in_face_shape2(n):
            raise ValueError('The solution is not in a face.')

        face = self.support_on_shape2(n)
        u, v = self.par_on_face_shape2(n)

        adp_srf = FaceAdaptorSurface.by_face(face)
        return Direction.by_vector(adp_srf.norm(u, v))