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() edg = make_edge(dss.PointOnShape1(1), dss.PointOnShape2(1)) display.DisplayColoredShape([edg], color="CYAN")
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 OCCT.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
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))