def project_mesh_to_cad_2d(mesh, cad): from OCC.Core.BRepAdaptor import BRepAdaptor_Curve from OCC.Core.gp import gp_Pnt from OCC.Core.GeomAPI import GeomAPI_ProjectPointOnCurve coorddata = mesh.coordinates.dat.data ids = mesh.exterior_facets.unique_markers filt = lambda arr: arr[numpy.where(arr < mesh.coordinates.dof_dset.size)[0]] boundary_nodes = {id: filt(mesh.coordinates.function_space().boundary_nodes(int(id))) for id in ids} for (id, edge) in zip(ids, cad.edges()): owned_nodes = boundary_nodes[id] for other_id in ids: if id == other_id: continue owned_nodes = numpy.setdiff1d(owned_nodes, boundary_nodes[other_id]) curve = BRepAdaptor_Curve(edge) for node in owned_nodes: pt = gp_Pnt(*coorddata[node, :], 0) proj = GeomAPI_ProjectPointOnCurve(pt, curve.Curve().Curve()) if proj.NbPoints() > 0: projpt = proj.NearestPoint() coorddata[node, :] = projpt.Coord()[0:2] else: warnings.warn("Projection of point %s onto curve failed" % coorddata[node, :])
def edge_to_svg(topods_edge, bezier_tol=0.01, bezier_degree=2): """ Returns a svgwrite.Path for the edge, and the 2d bounding box :param topods_edge: :param bezier_tol: tol of piecewise bezier approximation :param bezier_degree: degree of bezier curves :return: """ curve = BRepAdaptor_Curve(topods_edge) if curve.GetType() == 0: # line return line_to_svg(curve) else: # discretize the curve to process occlusions and transform to Bezier points_3d = discretize_edge(topods_edge, deflection=0.01) points_2d = [p[:2] for p in points_3d] try: return piecewise_bezier_to_svg( points_2d, approx_points_by_piecewise_bezier(points_3d, bezier_degree, bezier_tol), bezier_degree) except RuntimeError: print(f"Converting {CURVE_TYPES[curve.GetType()]} to polyline") return polyline_to_svg(points_2d)
def trimedge(lbound, ubound, occedge): """ This function trims the OCCedge according to the specified lower and upper bound. Parameters ---------- lbound : float The lower bound of the OCCedge. ubound : float The upper bound of the OCCedge. occedge : OCCedge The edge to be trimmed. Returns ------- trimmed edge : OCCedge The trimmed OCCedge. """ adaptor = BRepAdaptor_Curve(occedge) tr = Geom_TrimmedCurve(adaptor.Curve().Curve(), lbound, ubound) tr.SetTrim(lbound, ubound) bspline_handle = geomconvert_CurveToBSplineCurve(tr.BasisCurve()) tr_edge = BRepBuilderAPI_MakeEdge(bspline_handle) return tr_edge.Edge()
def adaptor(self): if self._adaptor is not None and not self.is_dirty: pass else: self._adaptor = BRepAdaptor_Curve(self) self._adaptor_handle = BRepAdaptor_HCurve(self._adaptor) return self._adaptor
def discretize_edge(a_topods_edge, deflection=0.5): """ Take a TopoDS_Edge and returns a list of points The more deflection is small, the more the discretization is precise, i.e. the more points you get in the returned points """ if not is_edge(a_topods_edge): raise AssertionError( "You must provide a TopoDS_Edge to the discretize_edge function.") if a_topods_edge.IsNull(): print( "Warning : TopoDS_Edge is null. discretize_edge will return an empty list of points." ) return [] curve_adaptator = BRepAdaptor_Curve(a_topods_edge) first = curve_adaptator.FirstParameter() last = curve_adaptator.LastParameter() discretizer = GCPnts_UniformAbscissa() discretizer.Initialize(curve_adaptator, deflection, first, last) if not discretizer.IsDone(): raise AssertionError("Discretizer not done.") if not discretizer.NbPoints() > 0: raise AssertionError("Discretizer nb points not > 0.") points = [] for i in range(1, discretizer.NbPoints() + 1): p = curve_adaptator.Value(discretizer.Parameter(i)) points.append(p.Coord()) return points
def is_edge_line(occedge): """ This function checks if an OCCedge contains a line. Parameters ---------- occedge : OCCedge The OCCedge to be examined. Returns ------- True or False : bool True or False if the edge contains a line. """ adaptor = BRepAdaptor_Curve(occedge) #GeomAbs_Line 0 #GeomAbs_Circle 1 #GeomAbs_Ellipse 2 #GeomAbs_Hyperbola 3 #GeomAbs_Parabola 4 #GeomAbs_BezierCurve 5 #GeomAbs_BSplineCurve 6 #GeomAbs_OtherCurve 7 ctype = adaptor.GetType() if ctype == 0: return True else: return False
def poles_from_bsplinecurve_edge(occedge): """ This function fetches the poles of a bspline OCCedge. Parameters ---------- occedge : OCCedge The OCCedge to be examined. The OCCedge needs to contain a bspline curve Returns ------- List of poles : pyptlist List of poles of the bspline curve """ adaptor = BRepAdaptor_Curve(occedge) adaptor_handle = BRepAdaptor_HCurve(adaptor) bspline = adaptor.BSpline() #handle_bspline = Handle_Geom_BSplineCurve_Create() #bspline = Geom_BSplineCurve(adaptor.Curve()) #print(bspline) #bspline = handle_bspline.DownCast(adaptor.Curve().Curve()).GetObject() npoles = bspline.NbPoles() polelist = [] for np in range(npoles): pole = bspline.Pole(np + 1) pypole = (pole.X(), pole.Y(), pole.Z()) polelist.append(pypole) if topods_Edge(occedge).Orientation() == TopAbs_REVERSED: polelist.reverse() return polelist
def generate_tool_targets(self): ba = BRepAdaptor_Curve(self.helix_edge) u_min = ba.FirstParameter() u_max = ba.LastParameter() u_step = 0.1 u_now = u_min while u_now <= u_max: v_contact = gp_Vec(ba.Value(u_now).XYZ()) if self.inside: # cut inside v_contact_to_ball_center = -gp_Vec(v_contact.X(),v_contact.Y(),0).Normalized()*self.ball_radius else: # cut outside v_contact_to_ball_center = gp_Vec(v_contact.X(),v_contact.Y(),0).Normalized()*self.ball_radius trsf = gp_Trsf() trsf.SetRotation(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1)),pi/2) v_rotation_axis = v_contact_to_ball_center.Transformed(trsf) trsf.SetRotation(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(v_rotation_axis.XYZ())),radians(self.cutting_angle)) v_ball_center_to_tool_tip = gp_Vec(0,0,-self.ball_radius) v_ball_center_to_tool_tip.Transform(trsf) v_tool_tip = v_contact+v_contact_to_ball_center+v_ball_center_to_tool_tip v_tool_orientation = - v_ball_center_to_tool_tip.Normalized() * (0.500+1e-8) if self.create_target_vis_edges: me = BRepBuilderAPI_MakeEdge(gp_Pnt(v_tool_tip.XYZ()),gp_Pnt((v_tool_tip+v_tool_orientation).XYZ())) self.target_edges.append(me.Edge()) I = v_tool_tip.X() / 1000 J = v_tool_tip.Y() / 1000 K = v_tool_tip.Z() / 1000 U = v_tool_orientation.X() V = v_tool_orientation.Y() W = v_tool_orientation.Z() x,y,z,a,b = self.ikSolver.solve((I,J,K,U,V,W),1e-6,False) x += self.output_offset[0] y += self.output_offset[1] z += self.output_offset[2] a += self.output_offset[3] b += self.output_offset[4] if self.v_previous_contact_point: cut_distance = (v_contact - self.v_previous_contact_point).Magnitude() f = self.feedrate / cut_distance self.gcode += "G01 X{:.6f} Y{:.6f} Z{:.6f} A{:.6f} B{:.6f} F{:.6f}\n".format(x,y,z,a,b,f) else: f = 0 self.gcode += "G0 X{:.6f} Y{:.6f} Z{:.6f} A{:.6f} B{:.6f}\n".format(x,y,z,a,b) self.v_previous_contact_point = v_contact print(x,y,z,a,b) if u_now == u_max: break u_next = u_now + u_step if u_next > u_max: u_next = u_max u_now = u_next
def edge_to_bezier(topods_edge): """take an edge and returns: * a bool is_bezier * the bezier curve * degrees * poles """ ad = BRepAdaptor_Curve(topods_edge) if ad.IsRational(): return True, ad.Bezier(), ad.Degree() return False, None, None
def collect_interface(edge, face): surface = BRepAdaptor_Surface(face) curve2d = BRepAdaptor_Curve2d(edge, face) curve3d = BRepAdaptor_Curve(edge) fp = curve2d.FirstParameter() lp = curve2d.LastParameter() assert fp == curve3d.FirstParameter() assert lp == curve3d.LastParameter() p_length = lp - fp return surface, curve2d, curve3d, fp, lp, p_length
def by_edge(cls, edge, face=None): """ Create by an edge. :param afem.topology.entities.Edge edge: The edge. :param afem.topology.entities.Edge face: The face the edge lies in. :return: The adaptor curve. :rtype: afem.adaptor.entities.EdgeAdaptorCurve """ if face is None: adp_crv = BRepAdaptor_Curve(edge.object) else: adp_crv = BRepAdaptor_Curve(edge.object, face.object) return cls(adp_crv)
def arc_length_t_edge(edge, t1, t2): """ This calculates the arc length between two paramters t1 and t2 """ adaptor3d_curve = BRepAdaptor_Curve(edge) arclength = GCPnts_AbscissaPoint_Length(adaptor3d_curve, t1, t2) return arclength
def curve(self): """ :return: The curve formed by concatenating all the underlying curves of the edges. :rtype: afem.geometry.entities.NurbsCurve """ geom_convert = GeomConvert_CompCurveToBSplineCurve() exp = BRepTools_WireExplorer(self.object) tol = self.tol_max while exp.More(): e = TopoDS.Edge_(exp.Current()) exp.Next() adp_crv = BRepAdaptor_Curve(e) geom_convert.Add(adp_crv.BSpline(), tol) geom_curve = geom_convert.BSplineCurve() return Curve.wrap(geom_curve)
def edge_length(edge): # result=BRep_Tool.Curve(edge)###result[0] is the handle of curve;result[1] is the umin; result[2] is umax # """ """ Calculate the lengh of an edge """ length = GCPnts_AbscissaPoint().Length(BRepAdaptor_Curve(edge)) return length
def reparameterization_arclength(edge, t1, tmin): """ This function reparameterize the curve using arc length as parameter. """ # (curve,tmin,tmax)=BRep_Tool.Curve(edge) partLength = arc_length_t_edge(edge, t1, tmin) wholeLength = GCPnts_AbscissaPoint().Length(BRepAdaptor_Curve(edge)) return partLength / wholeLength
def discretize_edge(edge, resolution=16): """Uniformly samples an edge with specified resolution (number of segments) and returns an array (segments + 1) of discrete (approximated) 3D points.""" if isinstance(edge, Edge): curve = BRepAdaptor_Curve(edge.wrapped) else: curve = BRepAdaptor_Curve(edge) try: gt = GCPnts_QuasiUniformAbscissa(curve, resolution + 1) except: return [] pts = [] for p in range(resolution + 1): pt = gt.Parameter(p + 1) curve_props = BRepLProp_CLProps(curve, 1, 1e-6) curve_props.SetParameter(pt) vpt = curve_props.Value() pts.append((vpt.X(), vpt.Y(), vpt.Z())) return pts
def divide_edge_by_nr_of_points(edg, n_pts): '''returns a nested list of parameters and points on the edge at the requested interval [(param, gp_Pnt),...] ''' curve_adapt = BRepAdaptor_Curve(edg) _lbound, _ubound = curve_adapt.FirstParameter(), curve_adapt.LastParameter( ) if n_pts <= 1: # minimally two points or a Standard_ConstructionError is raised raise AssertionError("minimally 2 points required") npts = GCPnts_UniformAbscissa(curve_adapt, n_pts, _lbound, _ubound) if npts.IsDone(): tmp = [] for i in range(1, npts.NbPoints() + 1): param = npts.Parameter(i) pnt = curve_adapt.Value(param) tmp.append((param, pnt)) return tmp
def other(): for (id, edge) in zip(ids, cad.edges()): owned_nodes = boundary_nodes[id] for other_id in ids: if id == other_id: continue owned_nodes = numpy.setdiff1d(owned_nodes, boundary_nodes[other_id]) curve = BRepAdaptor_Curve(edge) for node in owned_nodes: pt = gp_Pnt(*coorddata[node, :], 0) proj = GeomAPI_ProjectPointOnCurve(pt, curve.Curve().Curve()) if proj.NbPoints() > 0: projpt = proj.NearestPoint() coorddata[node, :] = projpt.Coord()[0:2] else: warnings.warn("Projection of point %s onto curve failed" % coorddata[node, :])
def wire_gcode(wire): print(f'Wire Orientation: {o(wire)}') if wire.Orientation() == TopAbs_REVERSED: wire.Reverse() for edge in WireExplorer(wire).ordered_edges(): print(f'Edge Orientation: {o(edge)}') tmp = BRepAdaptor_Curve(edge) # get underlying curve c, start, end = BRep_Tool.Curve(edge) # display start and endpoints of curve start_point = tmp.Value(tmp.FirstParameter()) end_point = tmp.Value(tmp.LastParameter()) if edge.Orientation() == TopAbs_FORWARD: display.DisplayColoredShape( BRepBuilderAPI_MakeVertex(start_point).Vertex(), "BLUE") display.DisplayColoredShape( BRepBuilderAPI_MakeVertex(end_point).Vertex(), "RED") else: display.DisplayColoredShape( BRepBuilderAPI_MakeVertex(start_point).Vertex(), "RED") display.DisplayColoredShape( BRepBuilderAPI_MakeVertex(end_point).Vertex(), "BLUE") # display individual curve display.DisplayShape(edge, update=True) time.sleep(1)
def edgeLen(self): """Measure length of a part edge or geometry profile line""" if self.edgeStack: edge = self.edgeStack.pop() edgelen = CPnts_AbscissaPoint_Length(BRepAdaptor_Curve(edge)) edgelen = edgelen / self.unitscale self.calculator.putx(edgelen) self.edgeLen() else: self.registerCallback(self.edgeLenC) self.canvas._display.SetSelectionModeEdge() statusText = "Pick an edge to measure." self.statusBar().showMessage(statusText)
def xyz_from_arclength_edge(edge, arclength, tmin): """ Given arclength from the endpoint with parameter tmin, return the xyz on edge """ adaptor3d_Curve = BRepAdaptor_Curve(edge) abscissaPoint = GCPnts_AbscissaPoint(adaptor3d_Curve, arclength, tmin) result = BRep_Tool.Curve( edge ) ###result[0] is the handle of curve;result[1] is the umin; result[2] is umax aPnt = result[0].GetObject().Value(abscissaPoint.Parameter()) return aPnt
def __extract_edgeType(self, an_edge): edge = BRepAdaptor_Curve(an_edge) edge_type = edge.GetType() if edge_type == GeomAbs_Line: return {'line': an_edge} elif edge_type == GeomAbs_Circle: return {'circle': an_edge} elif edge_type == GeomAbs_Ellipse: return {'ellipse': an_edge} elif edge_type == GeomAbs_Parabola: return {'parabola': an_edge} elif edge_type == GeomAbs_Hyperbola: return {'hyperbola': an_edge} elif edge_type == GeomAbs_BezierCurve: return {'bezierCurve': an_edge} elif edge_type == GeomAbs_BSplineCurve: return {'bsplineCurve': an_edge} elif edge_type == GeomAbs_OtherCurve: return {'otherCurve': an_edge} else: print('edge type is not able to be recognized !!!!!!') return {'else': an_edge}
def project_mesh_to_cad_2d(mesh, cad): from OCC.Core.BRepAdaptor import BRepAdaptor_Curve from OCC.Core.gp import gp_Pnt from OCC.Core.GeomAPI import GeomAPI_ProjectPointOnCurve coorddata = mesh.coordinates.dat.data ids = mesh.exterior_facets.unique_markers filt = lambda arr: arr[numpy.where(arr < mesh.coordinates.dof_dset.size)[0] ] boundary_nodes = { id: filt(mesh.coordinates.function_space().boundary_nodes( int(id), "topological")) for id in ids } for id_ in ids: for node in boundary_nodes[id_]: #print(node) coords = coorddata[node, :] best_coords = coords dist_old = np.inf for edge in cad.edges(): curve = BRepAdaptor_Curve(edge) pt = gp_Pnt(*coorddata[node, :], 0) proj = GeomAPI_ProjectPointOnCurve(pt, curve.Curve().Curve()) if proj.NbPoints() > 0: projpt = proj.NearestPoint() projected_coords = np.array(projpt.Coord()[0:2]) dist = np.linalg.norm(coords - projected_coords) if dist_old > dist: best_coords = projected_coords dist_old = dist #print(coords, projected_coords, np.linalg.norm(coords-projected_coords)) #print(distances) coorddata[node, :] = best_coords return
def test_curve_adaptor(self): # related to issue #1057 https://github.com/tpaviot/pythonocc-core/issues/1057 p1 = gp_Pnt(5, -5, 0) p2 = gp_Pnt(5, 5, 0) ed1 = BRepBuilderAPI_MakeEdge(p2, p1).Edge() c1 = BRepAdaptor_Curve(ed1) self.assertTrue(isinstance(c1.Curve(), GeomAdaptor_Curve)) # should pass on all platforms self.assertTrue(isinstance(c1.Curve().Curve(), Geom_Curve)) c2 = BRepAdaptor_Curve(ed1).Curve() # only works on linux if sys.platform == "linux": self.assertTrue(isinstance(c2.Curve(), Geom_Curve)) self.assertTrue( isinstance(BRepAdaptor_Curve(ed1).Curve().Curve(), Geom_Curve))
def describe_edge(self, edge): curve_adaptor = BRepAdaptor_Curve(edge) first = curve_adaptor.FirstParameter() last = curve_adaptor.LastParameter() geom_curve = curve_adaptor.Curve() if (geom_curve.GetType() == GeomAbs_Line): return "Is line" elif (geom_curve.GetType() == GeomAbs_Circle): return "Is circle" elif (geom_curve.GetType() == GeomAbs_Ellipse): return "Is ellipse" elif (geom_curve.GetType() == GeomAbs_Hyperbola): return "Is hyperbola" elif (geom_curve.GetType() == GeomAbs_Parabola): return "Is parabola" elif (geom_curve.GetType() == GeomAbs_BezierCurve): return "Is bezier" elif (geom_curve.GetType() == GeomAbs_BSplineCurve): return "Is bspline" elif (geom_curve.GetType() == GeomAbs_OffsetCurve): return "Is offset" elif (geom_curve.GetType() == GeomAbs_OtherCurve): return "Is other"
def selected_shape_info(self): if self.selectMode == 'Face': print(self.shape_selected) surf = BRepAdaptor_Surface(self.shape_selected, True) if surf.GetType() == GeomAbs_Plane: gp_pln = surf.Plane() normal = gp_pln.Axis().Direction() print('plane normal: (%.3f, %.3f, %.3f)' % (normal.X(), normal.Y(), normal.Z())) elif surf.GetType() == GeomAbs_Cylinder: gp_cyl = surf.Cylinder() axis = gp_cyl.Axis().Direction() location = gp_cyl.Location() print('cylinder axis direction: (%.3f, %.3f, %.3f)' % (axis.X(), axis.Y(), axis.Z())) print('cylinder axis location: (%.3f, %.3f, %.3f)' % (location.X(), location.Y(), location.Z())) else: typeList = ['Plane', 'Cylinder', 'Cone', 'Sphere', 'Torus', 'BezierSurface', 'BSplineSurface', 'SurfaceOfRevolution', 'SurfaceOfExtrusion', 'OffsetSurface', 'OtherSurface'] print('This surface type "%s" is not implemented !!' % typeList[surf.GetType()]) elif self.selectMode == 'Edge': print(self.shape_selected) edge = BRepAdaptor_Curve(self.shape_selected) curveType = edge.GetType() if curveType == GeomAbs_Line: gp_lin = edge.Line() direction = gp_lin.Direction() print('Line direction: (%.3f, %.3f, %.3f)' % (direction.X(), direction.Y(), direction.Z())) elif curveType == GeomAbs_Circle: gp_circ = edge.Circle() center = gp_circ.Location() print('Center of circle: (%.3f, %.3f, %.3f)' % (center.X(), center.Y(), center.Z())) print('Radius of circle:', gp_circ.Radius()) else: typeList = ['Line', 'Circle', 'Ellipse', 'Parabola', 'BezierCurve', 'BSplineCurve', 'OffsetCurve or OtherCurve?', 'OtherCurve'] print('This edge type is not implemented !!') print('This surface type "%s" is not implemented !!' % typeList[surf.GetType()])
def generate_conformal_path(nozz_dia, slices, direc): layer = [] frames = [] counter2 = 0 edge_clearance = nozz_dia / 2 for s in slices: frames.append([]) for j in range(0, len(s)): curve = BRepAdaptor_Curve(s[j]) umin = curve.FirstParameter() umax = curve.LastParameter() if direc == 'X': umin_value = curve.Value(umin).Y() umax_value = curve.Value(umax).Y() elif direc == 'Y': umin_value = curve.Value(umin).X() umax_value = curve.Value(umax).X() if umin_value > umax_value: umax = curve.FirstParameter() umin = curve.LastParameter() length = GCPnts_AbscissaPoint().Length(curve) if j == 0: kmin = umin + (umax - umin) * edge_clearance / length else: kmin = umin if j == len(s) - 1: kmax = umax - (umax - umin) * edge_clearance / length else: kmax = umax - (umax - umin) * min_point_dist / length length = GCPnts_AbscissaPoint().Length(curve, kmin, kmax) density = length / min_point_dist if density < 1: density = 1 for k in numpy.arange(kmin, kmax, (kmax - kmin) / density): if k == kmax: break frames[counter2].append( Slicing.get_point_on_curve(curve, k)) frames[counter2].append(Slicing.get_point_on_curve( curve, kmax)) if counter2 % 2 != 0: frames[counter2].reverse() layer.extend(frames[counter2]) counter2 = counter2 + 1 # Basic.display_normals(layer) return layer
def to_adaptor_3d(curveType): ''' abstract curve like type into an adaptor3d @param curveType: ''' if isinstance(curveType, TopoDS_Wire): return BRepAdaptor_CompCurve(curveType) elif isinstance(curveType, TopoDS_Edge): return BRepAdaptor_Curve(curveType) elif issubclass(curveType.__class__, Geom_Curve): return GeomAdaptor_Curve(curveType.GetHandle()) elif hasattr(curveType, 'GetObject'): _crv = curveType.GetObject() if issubclass(_crv.__class__, Geom_Curve): return GeomAdaptor_Curve(curveType) else: raise TypeError('allowed types are Wire, Edge or a subclass of Geom_Curve\nGot a %s' % (curveType.__class__))
def FindGeometry(self, object: AIS_InteractiveObject): if object.Type() == AIS_KOI_Shape: shape = self.myContext.SelectedShape() if shape.ShapeType() == TopAbs_VERTEX: pass elif shape.ShapeType() == TopAbs_EDGE: curve = BRepAdaptor_Curve(shape) curve_type = curve.GetType() if curve_type == GeomAbs_BezierCurve: return curve.Bezier() elif curve_type == GeomAbs_BSplineCurve: return curve.BSpline() elif curve_type == GeomAbs_Circle: return Geom_Circle(curve.Circle()) elif curve_type == GeomAbs_Line: return Geom_Line(curve.Line()) elif shape.ShapeType() == TopAbs_FACE: pass
def recognize_edge(self, a_edge): """ Takes a TopoDS shape and tries to identify its nature whether it is a plane a cylinder a torus etc. if a plane, returns the normal if a cylinder, returns the radius """ curve = BRepAdaptor_Curve(a_edge) curve_type = curve.GetType() if curve_type == GeomAbs_BezierCurve: print("--> Bezier") self._selectedShape = curve.Bezier() elif curve_type == GeomAbs_BSplineCurve: print("--> BSpline") self._selectedShape = curve.BSpline() elif curve_type == GeomAbs_Circle: print("--> Circle") self._selectedShape = Geom_Circle(curve.Circle()) else: # TODO there are plenty other type that can be checked # see documentation for the BRepAdaptor class # https://www.opencascade.com/doc/occt-6.9.1/refman/html/class_b_rep_adaptor___surface.html print("not implemented")