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 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 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 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 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 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 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 length_from_edge(edg): curve_adapt = BRepAdaptor_Curve(edg) length = GCPnts_AbscissaPoint().Length(curve_adapt, curve_adapt.FirstParameter(), curve_adapt.LastParameter(), 1e-6) return length
def on_select(shapes): if len(shapes) < 1: return s = shapes[0] if s.ShapeType() == TopAbs_EDGE: if s.Orientation() == TopAbs_FORWARD: print('FORWARD') else: print('REVERSED') tmp = BRepAdaptor_Curve(s) # display start and endpoints of curve start_point = tmp.Value(tmp.FirstParameter()) end_point = tmp.Value(tmp.LastParameter()) if s.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") if tmp.GetType() == GeomAbs_Line: t = tmp.Line() gcode = f'G01 X{end_point.X():.6f} Y{end_point.Y():.6f}' print( f'line: ({start_point.X():.6f}, {start_point.Y():.6f}) → ({end_point.X():.6f}, {end_point.Y():.6f})' ) # print(gcode) print( f'line parameters: {tmp.FirstParameter():.6f}, {tmp.LastParameter():.6f}' ) elif tmp.GetType() == GeomAbs_Circle: t = tmp.Circle() center_point = t.Location() # make two line segments, both from the centerpoint, and one to each of the endpoints # the cross product of the lines determines the direction. positive = CCW, negative = CW # assume for now the arc is in the XY plane, so only check the sign of z # assume clockwise for now # center format arc v1 = gp_Vec(center_point, start_point) v2 = gp_Vec(center_point, end_point) # angle > 0 if acute, < 0 if obtuse angle = v1.AngleWithRef(v2, gp_Vec(0, 0, 1)) # use cross product to determine direction v1.Cross(v2) v1 *= angle # TODO: verify CCW = True if v1.Z() > 0 else False gcode = "G0{0} X{1:.6f} Y{2:.6f} I{3:.6f} J{4:.6f}".format( 2 if CCW else 3, end_point.X(), end_point.Y(), center_point.X() - start_point.X(), center_point.Y() - start_point.Y()) print( "circle: start (%.6f, %.6f), end (%.6f, %.6f), center (%.6f, %.6f), radius %.6f" % (start_point.X(), start_point.Y(), end_point.X(), end_point.Y(), center_point.X(), center_point.Y(), t.Radius())) print("circle parameters: %.6f, %.6f" % (tmp.FirstParameter() / math.pi, tmp.LastParameter() / math.pi)) # print(gcode) elif tmp.GetType() == GeomAbs_Ellipse: t = tmp.Ellipse() x = t.XAxis() y = t.YAxis() print("ellipse") elif tmp.GetType() == GeomAbs_Hyperbola: t = tmp.Hyperbola() print("hyperbola") elif tmp.GetType() == GeomAbs_Parabola: t = tmp.Parabola() print("parabola") elif tmp.GetType() == GeomAbs_BezierCurve: t = tmp.Bezier() print("bezier") elif tmp.GetType() == GeomAbs_BSplineCurve: t = tmp.BSpline() print("bspline") elif tmp.GetType() == GeomAbs_OffsetCurve: t = tmp.OffsetCurve() print("offset") elif tmp.GetType() == GeomAbs_OtherCurve: print("other")
def Write(self, path): from bcad.binterpreter.scl_context import SCLProjection p = SCLProjection(None) p.hlr_project(self.shapes) shapes = [] for c in p.children: if c.shape != None: dump_topology_to_string(c.shape.get_shape()) shapes.append(c.shape.get_shape()) lines = [] for s in shapes: lines.extend(self.collect_dumpable_shapes(s)) #debug("Lines: %s"%(str(lines),)) ctr = 0 for l in lines: #debug ("l: %s"%(str(l),)) if len(l)>1: s = l[0][:2] for p in l[1:]: e = p[:2] self.msp.add_line(s, e) s = e # e = l[1][:2] # self.doc.saveas(path) return for s in shapes: exp = TopExp_Explorer() exp.Init(s, TopAbs_EDGE) while exp.More(): edge = exp.Value() if not is_edge(edge): warning("Is not an edge.") if exp.Value().IsNull(): warning("TopoDS_Edge is null") curve_adaptor = BRepAdaptor_Curve(edge) first = curve_adaptor.FirstParameter() last = curve_adaptor.LastParameter() geom_curve = curve_adaptor.Curve() #edges.append(exp.Current()) # first = topexp.FirstVertex(exp.Value()) # last = topexp.LastVertex(exp.Value()) # # Take geometrical information from vertices. # pnt_first = BRep_Tool.Pnt(first) # pnt_last = BRep_Tool.Pnt(last) # a, b = BRep_Tool.Curve(exp.Value()) exp.Next() if (geom_curve.GetType() == GeomAbs_Line): debug("Is line") elif (geom_curve.GetType() == GeomAbs_Circle): debug("Is circle") elif (geom_curve.GetType() == GeomAbs_Ellipse): debug("Is ellipse") elif (geom_curve.GetType() == GeomAbs_Hyperbola): debug("Is hyperbola") elif (geom_curve.GetType() == GeomAbs_Parabola): debug("Is parabola") elif (geom_curve.GetType() == GeomAbs_BezierCurve): debug("Is bezier") elif (geom_curve.GetType() == GeomAbs_BSplineCurve): debug("Is bspline") elif (geom_curve.GetType() == GeomAbs_OffsetCurve): debug("Is offset") elif (geom_curve.GetType() == GeomAbs_OtherCurve): #debug("Is other") continue #self.msp.add_line() pts = discretize_edge(edge) debug("Curve[%i]: %s / %s"%(ctr, str(geom_curve.GetType()),str(edge))) ctr+=1
def print_vertex(va): pt = BRep_Tool().Pnt(va) print("%.3f, %.3f, %.3f" % (pt.Coord(1), pt.Coord(2), pt.Coord(3))) return [pt.Coord(1), pt.Coord(2), pt.Coord(3)] fig = plt.figure() ax = fig.add_subplot(111, projection='3d') while topExp.More(): edge = topExp.Current() first, last = topexp_FirstVertex(edge), topexp_LastVertex(edge) curv = BRepAdaptor_Curve(edge).Curve().Curve() if curv.FirstParameter() == REALFIRST or curv.LastParameter() == REALFIRST: print("This is a line.") first = print_vertex(first) last = print_vertex(last) plt.plot([first[0]], [first[1]], [first[2]], 'g*') plt.plot([first[0]], [last[1]], [last[2]], 'b*') else: print() print(edge) first = print_vertex(first) print("%f, %f" % (curv.FirstParameter(), curv.LastParameter())) x = curv.LastParameter()
def get_edge_endpoints(edge): end_points = [] curve = BRepAdaptor_Curve(edge) end_points.append(curve.Value(curve.FirstParameter())) end_points.append(curve.Value(curve.LastParameter())) return end_points
def generate_layer_path(faces, nozz_dia, direc, sur_nozz_dia=0): slices = [] counter1 = 0 layer = [] frames = [] counter2 = 0 edge_clearance = (nozz_dia + sur_nozz_dia) / 2 xmin, ymin, zzz, xmax, ymax, zzz =\ Slicing.get_surfaces_boundingbox(faces) new_surfaces = Slicing.sort_surfaces(faces, direc) if direc == 'X': imin = xmin imax = xmax elif direc == 'Y': imin = ymin imax = ymax for i in numpy.arange(imin + edge_clearance, imax - edge_clearance, nozz_dia): if direc == 'X': plane = gp_Pln(gp_Pnt(i, 0., 0), gp_Dir(1., 0., 0.)) elif direc == 'Y': plane = gp_Pln(gp_Pnt(0., i, 0), gp_Dir(0., 1., 0.)) face = BRepBuilderAPI_MakeFace(plane).Face() slices.append([]) for surface in new_surfaces: slices[counter1].extend(Slicing.plane_shape_intersection(face,\ surface)) counter1 = counter1 + 1 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 return layer