def __init__(self, nr='None', closed=0, cut_cor=40, length=0.0, parent=None, geos=[], geos_hdls=[], plotoption=0): """ Standard method to initialize the class """ self.type = "Shape" self.nr = nr self.closed = closed self.cut_cor = 40 self.length = length self.parent = parent self.geos = geos self.geos_hdls = geos_hdls self.BB = BoundingBoxClass(Pa=None, Pe=None) self.plotoption = plotoption
class ShapeClass: def __init__(self, nr='None', closed=0, cut_cor=40, length=0.0, parent=None, geos=[], geos_hdls=[], plotoption=0): """ Standard method to initialize the class """ self.type = "Shape" self.nr = nr self.closed = closed self.cut_cor = 40 self.length = length self.parent = parent self.geos = geos self.geos_hdls = geos_hdls self.BB = BoundingBoxClass(Pa=None, Pe=None) self.plotoption = plotoption def __str__(self): """ Standard method to print the object @return: A string """ return ('\ntype: %s' % self.type) + \ ('\nnr: %i' % self.nr) + \ ('\nclosed: %i' % self.closed) + \ ('\ncut_cor: %s' % self.cut_cor) + \ ('\nlen(geos): %i' % len(self.geos)) + \ ('\ngeos: %s' % self.geos) + \ ('\ngeo_hdls: %s' % self.geos_hdls) def AnalyseAndOptimize(self, MyConfig=None): """ Standard method to print the object @return: A string """ #Optimisation for closed shapes if self.closed: #Startwert setzen f�r die erste Summe start, dummy = self.geos[0].get_start_end_points(0) summe = 0.0 for geo in self.geos: if geo.type == 'LineGeo': ende, dummy = geo.get_start_end_points(1) summe += (start.x + ende.x) * (ende.y - start.y) / 2 start = deepcopy(ende) elif geo.type == 'ArcGeo': segments = int((abs(degrees(geo.ext)) // 90) + 1) for i in range(segments): ang = geo.s_ang + (i + 1) * geo.ext / segments ende = PointClass(x=(geo.O.x + cos(ang) * abs(geo.r)), y=(geo.O.y + sin(ang) * abs(geo.r))) summe += (start.x + ende.x) * (ende.y - start.y) / 2 start = deepcopy(ende) if summe > 0.0: self.reverse() def reverse(self): """ Reverses the direction of the whole shape (switch direction). """ self.geos.reverse() for geo in self.geos: geo.reverse() def switch_cut_cor(self): """ Switches the cutter direction between 41 and 42. """ if self.cut_cor == 41: self.cut_cor = 42 elif self.cut_cor == 42: self.cut_cor = 41 def get_st_en_points(self, dir=None): """ Returns the start/end point and its direction @param direction: 0 to return start point and 1 to return end point @return: a list of point and angle """ start, start_ang = self.geos[0].get_start_end_points(0) ende, end_ang = self.geos[-1].get_start_end_points(1) if dir == None: return start, ende elif dir == 0: return start, start_ang elif dir == 1: return ende, end_ang def plot2can(self, canvas, col='black'): """ To be called if a Shape shall be printed to the canvas @param canvas: The canvas to be printed in @param pospro: The color of the shape """ for geo in self.geos: self.geos_hdls += geo.plot2can(canvas=canvas, tag=self.nr, col=col, plotoption=self.plotoption) if DEBUG: self.BB.plot2can(canvas=canvas, tag=self.nr, col='green', hdl=self.geos_hdls) def plot_cut_info(self, CanvasClass, config): hdls = [] hdls.append(self.plot_start(CanvasClass)) hdls.append(self.plot_end(CanvasClass)) if self.cut_cor > 40: hdls.append(self.plot_cut_cor(CanvasClass)) self.make_start_moves(config) #Versatz des Zeichnens durch Position P0 = PointClass(x= -CanvasClass.dx * CanvasClass.scale, y= -CanvasClass.dy * CanvasClass.scale - CanvasClass.canvas.winfo_height()) #Korrektur der Skalierung sca = [CanvasClass.scale] * 3 #BaseEntitie erstellen um auf oberster Ebene zu Fr�sen BaseEntitie = EntitieContentClass(Nr= -1, Name='BaseEntitie', parent=None, children=[], p0=P0, pb=PointClass(x=0.0, y=0.0), sca=sca, rot=0.0) hdls += self.st_move[1].plot2can(CanvasClass.canvas, BaseEntitie, tag=self.nr, col='SteelBlue3') hdls += self.st_move[2].plot2can(CanvasClass.canvas, BaseEntitie, tag=self.nr, col='SteelBlue3') return hdls def plot_start(self, Canvas=None, length=20): #st_point, st_angle=self.geos[0].get_start_end_points(0,parent) start, start_ang = self.get_st_en_points(0) x_ca, y_ca = Canvas.get_can_coordinates(start.x, start.y) dx = cos(radians(start_ang)) * length dy = sin(radians(start_ang)) * length hdl = Line(Canvas.canvas, x_ca, -y_ca, x_ca + dx, -y_ca - dy, fill='SteelBlue3', arrow='last') return hdl #Funktion zum drucken der zu fr�senden Kontur mit den Richtungspfeilen usw. def plot_cut_cor(self, Canvas=None, length=20): start, start_ang = self.get_st_en_points(0) #BaseEntitie erstellen um auf oberster Ebene zu Fr�sen BaseEntitie = EntitieContentClass(Nr= -1, Name='BaseEntitie', parent=None, children=[], p0=PointClass(x=0.0, y=0.0), pb=PointClass(x=0.0, y=0.0), sca=[1, 1, 1], rot=0.0) x_ca, y_ca = Canvas.get_can_coordinates(start.x, start.y) if self.cut_cor == 41: start_ang = start_ang + 90 else: start_ang = start_ang - 90 dx = cos(radians(start_ang)) * length dy = sin(radians(start_ang)) * length hdl = Line(Canvas.canvas, x_ca, -y_ca, x_ca + dx, -y_ca - dy, fill='SteelBlue3', arrow='last') return hdl def plot_end(self, Canvas=None, length=20): ende, en_angle = self.get_st_en_points(1) dx = cos(radians(en_angle)) * length dy = sin(radians(en_angle)) * length x_ca, y_ca = Canvas.get_can_coordinates(ende.x, ende.y) hdl = Line(Canvas.canvas, x_ca, -y_ca, x_ca + dx, -y_ca - dy, fill='PaleGreen2', arrow='first') return hdl def make_start_moves(self, config): self.st_move = [] #Einlaufradius und Versatz start_rad = config.start_rad.get() start_ver = start_rad #Werkzeugdurchmesser in Radius umrechnen tool_rad = config.tool_dia.get() / 2 #Errechnen des Startpunkts mit und ohne Werkzeug Kompensation start, start_ang = self.get_st_en_points(0) if self.cut_cor == 40: self.st_move.append(start) #Fr�sradiuskorrektur Links elif self.cut_cor == 41: #Mittelpunkts f�r Einlaufradius Oein = start.get_arc_point(start_ang + 90, start_rad + tool_rad) #Startpunkts f�r Einlaufradius Pa_ein = Oein.get_arc_point(start_ang + 180, start_rad + tool_rad) #Startwerts f�r Einlaufgerade Pg_ein = Pa_ein.get_arc_point(start_ang + 90, start_ver) #Eintauchpunkt errechnete Korrektur start_ein = Pg_ein.get_arc_point(start_ang, tool_rad) self.st_move.append(start_ein) #Einlaufgerade mit Korrektur start_line = LineGeo(Pg_ein, Pa_ein) self.st_move.append(start_line) #Einlaufradius mit Korrektur start_rad = ArcGeo(Pa=Pa_ein, Pe=start, O=Oein, r=start_rad + tool_rad, dir=1) self.st_move.append(start_rad) #Fr�sradiuskorrektur Rechts elif self.cut_cor == 42: #Mittelpunkt f�r Einlaufradius Oein = start.get_arc_point(start_ang - 90, start_rad + tool_rad) #Startpunkt f�r Einlaufradius Pa_ein = Oein.get_arc_point(start_ang + 180, start_rad + tool_rad) #IJ=Oein-Pa_ein #Startwerts f�r Einlaufgerade Pg_ein = Pa_ein.get_arc_point(start_ang - 90, start_ver) #Eintauchpunkts errechnete Korrektur start_ein = Pg_ein.get_arc_point(start_ang, tool_rad) self.st_move.append(start_ein) #Einlaufgerade mit Korrektur start_line = LineGeo(Pg_ein, Pa_ein) self.st_move.append(start_line) #Einlaufradius mit Korrektur start_rad = ArcGeo(Pa=Pa_ein, Pe=start, O=Oein, r=start_rad + tool_rad, dir=0) self.st_move.append(start_rad) def Write_GCode(self, config, postpro): #Erneutes erstellen der Einlaufgeometrien self.make_start_moves(config) #Werkzeugdurchmesser in Radius umrechnen tool_rad = config.tool_dia.get() / 2 #BaseEntitie erstellen um auf oberster Ebene zu Fr�sen BaseEntitie = EntitieContentClass(Nr= -1, Name='BaseEntitie', parent=None, children=[], p0=PointClass(x=0.0, y=0.0), pb=PointClass(x=0.0, y=0.0), sca=[1, 1, 1], rot=0.0) depth = config.axis3_mill_depth.get() max_slice = config.axis3_slice_depth.get() #Wenn Output Format DXF dann nur einmal Fr�sen if postpro.output_type == 'dxf': depth = max_slice #Scheibchendicke bei Fr�stiefe auf Fr�stiefe begrenzen if - abs(max_slice) <= depth: mom_depth = depth else: mom_depth = -abs(max_slice) #Positionieren des Werkzeugs �ber dem Anfang und Eintauchen self.st_move[0].Write_GCode(parent=BaseEntitie, postpro=postpro) postpro.rap_pos_z(config.axis3_safe_margin.get()) postpro.chg_feed_rate(config.F_G1_Depth.get()) postpro.lin_pol_z(mom_depth) postpro.chg_feed_rate(config.F_G1_Plane.get()) #Wenn G41 oder G42 an ist Fr�sradiuskorrektur if self.cut_cor != 40: #Errechnen des Startpunkts ohne Werkzeug Kompensation #und einschalten der Kompensation start, start_ang = self.get_st_en_points(0) postpro.set_cut_cor(self.cut_cor, start) self.st_move[1].Write_GCode(parent=BaseEntitie, postpro=postpro) self.st_move[2].Write_GCode(parent=BaseEntitie, postpro=postpro) #Schreiben der Geometrien f�r den ersten Schnitt for geo in self.geos: geo.Write_GCode(self.parent, postpro) #Ausschalten der Fr�sradiuskorrektur if (not(self.cut_cor == 40)) & (postpro.cancel_cc_for_depth == 1): ende, en_angle = self.get_st_en_points(1) if self.cut_cor == 41: pos_cut_out = ende.get_arc_point(en_angle - 90, tool_rad) elif self.cut_cor == 42: pos_cut_out = ende.get_arc_point(en_angle + 90, tool_rad) postpro.deactivate_cut_cor(pos_cut_out) #Z�hlen der Schleifen snr = 0 #Schleifen f�r die Anzahl der Schnitte while mom_depth > depth: snr += 1 mom_depth = mom_depth - abs(max_slice) if mom_depth < depth: mom_depth = depth #Erneutes Eintauchen postpro.chg_feed_rate(config.F_G1_Depth.get()) postpro.lin_pol_z(mom_depth) postpro.chg_feed_rate(config.F_G1_Plane.get()) #Falls es keine geschlossene Kontur ist if self.closed == 0: self.reverse() self.switch_cut_cor() #Falls cut correction eingeschaltet ist diese einschalten. if ((not(self.cut_cor == 40)) & (self.closed == 0))or(postpro.cancel_cc_for_depth == 1): #Errechnen des Startpunkts ohne Werkzeug Kompensation #und einschalten der Kompensation postpro.set_cut_cor(self.cut_cor, start) for geo_nr in range(len(self.geos)): self.geos[geo_nr].Write_GCode(self.parent, postpro) #Errechnen des Konturwerte mit Fr�sradiuskorrektur und ohne ende, en_angle = self.get_st_en_points(1) if self.cut_cor == 41: pos_cut_out = ende.get_arc_point(en_angle - 90, tool_rad) elif self.cut_cor == 42: pos_cut_out = ende.get_arc_point(en_angle + 90, tool_rad) #Ausschalten der Fr�sradiuskorrektur falls ben�tigt if (not(self.cut_cor == 40)) & (postpro.cancel_cc_for_depth == 1): postpro.deactivate_cut_cor(pos_cut_out) #Anfangswert f�r Direction wieder herstellen falls n�tig if (snr % 2) > 0: self.reverse() self.switch_cut_cor() #Fertig und Zur�ckziehen des Werkzeugs postpro.lin_pol_z(config.axis3_safe_margin.get()) postpro.rap_pos_z(config.axis3_retract.get()) #Falls Fr�sradius Korrektur noch nicht ausgeschaltet ist ausschalten. if (not(self.cut_cor == 40)) & (not(postpro.cancel_cc_for_depth)): #Errechnen des Konturwerte mit Fr�sradiuskorrektur und ohne ende, en_angle = self.get_st_en_points(1) postpro.deactivate_cut_cor(ende) return 1