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.")
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]
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)
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
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")
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
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))
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
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)
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))
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)