Пример #1
0
def _chamfer(shp, r, refs=None):
    if refs:
        refs = points(refs)

    if shp.is_solid() or shp.is_compound() or shp.is_compsolid():
        mk = BRepFilletAPI_MakeChamfer(shp.Shape())

        if refs:
            for p in refs:
                minimum = float("inf")
                vtx = p.Vtx()

                for edg in shp.edges():
                    extrema = BRepExtrema_DistShapeShape(edg.Edge(), vtx)

                    if minimum > extrema.Value():
                        ret = edg
                        minimum = extrema.Value()

                mk.Add(r, ret.Edge())
        else:
            for edg in shp.edges():
                mk.Add(r, edg.Edge())

        return Shape(mk.Shape())
    else:
        raise Exception("Fillet argument has unsuported type.")
Пример #2
0
def min_distance(pt, face):
    """
    Minimum distance between point and face
    """

    gpPnt = gp_Pnt(pt[0], pt[1], pt[2])
    vertex = BRepBuilderAPI_MakeVertex(gpPnt).Vertex()
    dis = BRepExtrema_DistShapeShape(vertex, face)

    p = dis.PointOnShape2(1)
    d = dis.Value()
    return [d, p]
Пример #3
0
def _near_part(shp, pnt, topabs):
    min = float("inf")
    ret = shape_types[topabs].construct()
    vtx = point3(pnt).Vtx()

    ex = TopExp_Explorer(shp.Shape(), topabs)
    while ex.More():
        obj = shape_types[topabs].convert(ex.Current())
        extrema = BRepExtrema_DistShapeShape(obj, vtx)

        if min > extrema.Value():
            ret = obj
            min = extrema.Value()

        ex.Next()

    return Shape(ret)
Пример #4
0
def intersect_edge_with_edge(occedge1, occedge2, tolerance=1e-06):
    """
    This function intersects two OCCedges and obtain a list of intersection points.
 
    Parameters
    ----------
    occedge1 : OCCedge
        The first edge to be intersected.
        
    occedge2 : OCCedge
        The second edge to be intersected.
        
    tolerance : float, optional
        The minimum distance between the two edges to determine if the edges are intersecting, Default = 1e-06.

    Returns
    -------
    list of intersection points : pyptlist
        The list of points where the two edges intersect.
    """
    interpyptlist = []
    dss = BRepExtrema_DistShapeShape(occedge1, occedge2)
    dss.SetDeflection(tolerance)
    dss.Perform()
    min_dist = dss.Value()
    if min_dist < tolerance:
        npts = dss.NbSolution()
        for i in range(npts):
            gppt = dss.PointOnShape1(i + 1)
            pypt = (gppt.X(), gppt.Y(), gppt.Z())
            interpyptlist.append(pypt)

    return interpyptlist
Пример #5
0
def project_shape_on_shape(occtopo_proj, occtopo_projon, tolerance=1e-06):
    """
    This function project the occtopoproj (OCCtopology) onto the occtopoprojon (OCCtopology), and returns the list of projected points.
 
    Parameters
    ----------
    occtopo_proj : OCCtopology
        The OCCtopology to to project.
        OCCtopology includes: OCCshape, OCCcompound, OCCcompsolid, OCCsolid, OCCshell, OCCface, OCCwire, OCCedge, OCCvertex 
        
    occtopo_projon : OCCtopology
        The OCCtopology to be projected on.
        OCCtopology includes: OCCshape, OCCcompound, OCCcompsolid, OCCsolid, OCCshell, OCCface, OCCwire, OCCedge, OCCvertex 
        
    tolerance : float, optional
        The precision of the projection, Default = 1e-06.
        
    Returns
    -------
    list of projected points : pyptlist
        The list of projected points.
    """

    interpyptlist = []
    dss = BRepExtrema_DistShapeShape(occtopo_proj, occtopo_projon)
    dss.SetDeflection(tolerance)
    dss.Perform()
    min_dist = dss.Value()
    npts = dss.NbSolution()
    for i in range(npts):
        gppt = dss.PointOnShape2(i + 1)
        pypt = (gppt.X(), gppt.Y(), gppt.Z())
        interpyptlist.append(pypt)

    return interpyptlist
def compute_minimal_distance_between_cubes():
    """ compute the minimal distance between 2 cubes

    the line between the 2 points is rendered in cyan

    """
    b1 = BRepPrimAPI_MakeBox(gp_Pnt(100, 0, 0), 10., 10., 10.).Shape()
    b2 = BRepPrimAPI_MakeBox(gp_Pnt(45, 45, 45), 10., 10., 10.).Shape()
    display.DisplayShape([b1, b2])

    dss = BRepExtrema_DistShapeShape()
    dss.LoadS1(b1)
    dss.LoadS2(b2)
    dss.Perform()

    assert dss.IsDone()

    print("Minimal distance between cubes: ", dss.Value())

    edg = make_edge(dss.PointOnShape1(1), dss.PointOnShape2(1))
    display.DisplayColoredShape([edg], color="CYAN")
Пример #7
0
def compute_minimal_distance_between_shapes(
        shp1, shp2) -> BRepExtrema_DistShapeShape:
    """Compute the minimal distance between 2 shapes"""

    dss = BRepExtrema_DistShapeShape()
    dss.LoadS1(shp1)
    dss.LoadS2(shp2)
    dss.Perform()

    assert dss.IsDone()

    logging.info("Minimal distance between shapes: ", dss.Value())

    return dss
Пример #8
0
def dist_point_to_edge(pnt, edge):    
    assert pnt is not None
    
    vert_maker = BRepBuilderAPI_MakeVertex(gp_Pnt(pnt[0], pnt[1], pnt[2]))
    dss = BRepExtrema_DistShapeShape(vert_maker.Vertex(), edge)
    if not dss.IsDone():
        print('BRepExtrema_ExtPC not done')
        return None, None

    if dss.NbSolution() < 1:
        print('no nearest points found')
        return None, None
    return dss.Value(), as_list(dss.PointOnShape2(1))
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))
Пример #10
0
def minimum_distance(shp1, shp2):
    '''
    compute minimum distance between 2 BREP's
    @param shp1:    any TopoDS_*
    @param shp2:    any TopoDS_*
    @return: minimum distance,
             minimum distance points on shp1
             minimum distance points on shp2
    '''
    from OCC.Core.BRepExtrema import BRepExtrema_DistShapeShape
    bdss = BRepExtrema_DistShapeShape(shp1, shp2)
    bdss.Perform()
    with assert_isdone(bdss, 'failed computing minimum distances'):
        min_dist = bdss.Value()
        min_dist_shp1, min_dist_shp2 = [], []
        for i in range(1, bdss.NbSolution() + 1):
            min_dist_shp1.append(bdss.PointOnShape1(i))
            min_dist_shp2.append(bdss.PointOnShape2(i))
    return min_dist, min_dist_shp1, min_dist_shp2
Пример #11
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)
Пример #12
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
    """
    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: OCC.Core.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: OCC.Core.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))
Пример #13
0
    def _write_blade_errors(self, upper_face, lower_face, errors):
        """
        Private method to write the errors between the generated foil points in
        3D space from the parametric transformations, and their projections on
        the generated blade faces from the OCC algorithm.

        :param string upper_face: if string is passed then the method generates
            the blade upper surface using the BRepOffsetAPI_ThruSections
            algorithm, then exports the generated CAD into .iges file holding
            the name <upper_face_string>.iges
        :param string lower_face: if string is passed then the method generates
            the blade lower surface using the BRepOffsetAPI_ThruSections
            algorithm, then exports the generated CAD into .iges file holding
            the name <lower_face_string>.iges
        :param string errors: if string is passed then the method writes out
            the distances between each discrete point used to construct the
            blade and the nearest point on the CAD that is perpendicular to
            that point
        """
        from OCC.Core.gp import gp_Pnt
        from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeVertex
        from OCC.Core.BRepExtrema import BRepExtrema_DistShapeShape

        output_string = '\n'
        with open(errors + '.txt', 'w') as f:
            if upper_face:
                output_string += '########## UPPER FACE ##########\n\n'
                output_string += 'N_section\t\tN_point\t\t\tX_crds\t\t\t\t'
                output_string += 'Y_crds\t\t\t\t\tZ_crds\t\t\t\t\tDISTANCE'
                output_string += '\n\n'
                for i in range(self.n_sections):
                    alength = len(self.blade_coordinates_up[i][0])
                    for j in range(alength):
                        vertex = BRepBuilderAPI_MakeVertex(
                            gp_Pnt(
                                1000 * self.blade_coordinates_up[i][0][j],
                                1000 * self.blade_coordinates_up[i][1][j],
                                1000 *
                                self.blade_coordinates_up[i][2][j])).Vertex()
                        projection = BRepExtrema_DistShapeShape(
                            self.generated_upper_face, vertex)
                        projection.Perform()
                        output_string += str(i) + '\t\t\t' + str(
                            j) + '\t\t\t' + str(
                                1000 *
                                self.blade_coordinates_up[i][0][j]) + '\t\t\t'
                        output_string += str(
                            1000 * self.blade_coordinates_up[i][1][j]
                        ) + '\t\t\t' + str(
                            1000 * self.blade_coordinates_up[i][2][j]
                        ) + '\t\t\t' + str(projection.Value())
                        output_string += '\n'

            if lower_face:
                output_string += '########## LOWER FACE ##########\n\n'
                output_string += 'N_section\t\tN_point\t\t\tX_crds\t\t\t\t'
                output_string += 'Y_crds\t\t\t\t\tZ_crds\t\t\t\t\tDISTANCE'
                output_string += '\n\n'
                for i in range(self.n_sections):
                    alength = len(self.blade_coordinates_down[i][0])
                    for j in range(alength):
                        vertex = BRepBuilderAPI_MakeVertex(
                            gp_Pnt(1000 * self.blade_coordinates_down[i][0][j],
                                   1000 * self.blade_coordinates_down[i][1][j],
                                   1000 * self.blade_coordinates_down[i][2][j])
                        ).Vertex()
                        projection = BRepExtrema_DistShapeShape(
                            self.generated_lower_face, vertex)
                        projection.Perform()
                        output_string += str(i) + '\t\t\t' + str(
                            j) + '\t\t\t' + str(
                                1000 * self.blade_coordinates_down[i][0][j]
                            ) + '\t\t\t'
                        output_string += str(
                            1000 * self.blade_coordinates_down[i][1][j]
                        ) + '\t\t\t' + str(
                            1000 * self.blade_coordinates_down[i][2][j]
                        ) + '\t\t\t' + str(projection.Value())
                        output_string += '\n'
            f.write(output_string)