#!/usr/bin/python3
"""
K40 Whisperer CLI Mod laser photobooth
Copyright (C) <2017-2023>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
"""
version = '0.69'
title_text = "K40 Whisperer V"+version
import sys
from math import *
from egv import egv
from nano_library import K40_CLASS
from dxf import DXF_CLASS
from svg_reader import SVG_READER
from svg_reader import SVG_TEXT_EXCEPTION
from svg_reader import SVG_PXPI_EXCEPTION
from g_code_library import G_Code_Rip
from interpolate import interpolate
from ecoords import ECoord
from convex_hull import hull2D
from embedded_images import K40_Whisperer_Images
import inkex
import simplestyle
import simpletransform
import cubicsuperpath
import cspsubdiv
import traceback
import struct
DEBUG = False
if DEBUG:
import inspect
VERSION = sys.version_info[0]
LOAD_MSG = ""
if VERSION == 3:
from tkinter import *
from tkinter.filedialog import *
import tkinter.messagebox
MAXINT = sys.maxsize
else:
from Tkinter import *
from tkFileDialog import *
import tkMessageBox
MAXINT = sys.maxint
if VERSION < 3 and sys.version_info[1] < 6:
def next(item):
#return item.next()
return item.__next__()
try:
import psyco
psyco.full()
LOAD_MSG = LOAD_MSG+"\nPsyco Loaded\n"
except:
pass
import math
from time import time
import os
import re
import binascii
import getopt
import operator
import webbrowser
from PIL import Image
from PIL import ImageOps
from PIL import ImageFilter
try:
Image.warnings.simplefilter('ignore', Image.DecompressionBombWarning)
except:
pass
try:
from PIL import ImageTk
from PIL import _imaging
except:
pass #Don't worry everything will still work
try:
Image.LANCZOS
except:
Image.LANCZOS=Image.ANTIALIAS
PYCLIPPER=True
try:
import pyclipper
except:
print("Unable to load Pyclipper library (Offset trace outline will not work without it)")
PYCLIPPER = False
try:
os.chdir(os.path.dirname(__file__))
except:
pass
QUIET = False
################################################################################
class Application(Frame):
def __init__(self, master):
self.trace_window = toplevel_dummy()
Frame.__init__(self, master)
self.w = 780
self.h = 490
frame = Frame(master, width= self.w, height=self.h)
self.master = master
self.x = -1
self.y = -1
self.createWidgets()
self.micro = False
def resetPath(self):
self.RengData = ECoord()
self.VengData = ECoord()
self.VcutData = ECoord()
self.GcodeData = ECoord()
self.SCALE = 1
self.Design_bounds = (0,0,0,0)
self.UI_image = None
#if self.HomeUR.get():
self.move_head_window_temporary([0.0,0.0])
#else:
# self.move_head_window_temporary([0.0,0.0])
self.pos_offset=[0.0,0.0]
def createWidgets(self):
self.initComplete = 0
self.stop=[True]
self.k40 = None
self.run_time = 0
self.master.bind("", self.Master_Configure)
self.master.bind('', self.bindConfigure)
self.master.bind('', self.KEY_F1) #About
self.master.bind('', self.KEY_F2) #Advanced Config
self.master.bind('', self.KEY_F3) #Raster settings
self.master.bind('', self.KEY_F4) #rotary settings
self.master.bind('', self.KEY_F5)
self.master.bind('', self.KEY_F6) #advanced runtime settings
self.master.bind('', self.Home)
self.master.bind('', self.Raster_Eng)
self.master.bind('', self.Vector_Eng)
#self.master.bind('', self.Vector_Cut)
self.master.bind('', self.Gcode_Cut)
self.master.bind('' , self.Move_Left)
self.master.bind('' , self.Move_Right)
self.master.bind('' , self.Move_Up)
self.master.bind('' , self.Move_Down)
self.master.bind('' , self.Move_UL)
self.master.bind('' , self.Move_UR)
self.master.bind('' , self.Move_LR)
self.master.bind('' , self.Move_LL)
self.master.bind('' , self.Move_CC)
self.master.bind('' , self.Move_Left)
self.master.bind('' , self.Move_Right)
self.master.bind('' , self.Move_Up)
self.master.bind('' , self.Move_Down)
self.master.bind('' , self.Move_UL)
self.master.bind('' , self.Move_UR)
self.master.bind('' , self.Move_LR)
self.master.bind('' , self.Move_LL)
self.master.bind('' , self.Move_CC)
#####
self.master.bind('' , self.Move_Arb_Left)
self.master.bind('', self.Move_Arb_Right)
self.master.bind('' , self.Move_Arb_Up)
self.master.bind('' , self.Move_Arb_Down)
self.master.bind('', self.Move_Arb_Left)
self.master.bind('' , self.Move_Arb_Right)
self.master.bind('' , self.Move_Arb_Up)
self.master.bind('', self.Move_Arb_Down)
self.master.bind('' , self.Move_Arb_Left)
self.master.bind('', self.Move_Arb_Right)
self.master.bind('' , self.Move_Arb_Up)
self.master.bind('' , self.Move_Arb_Down)
self.master.bind('', self.Move_Arb_Left)
self.master.bind('' , self.Move_Arb_Right)
self.master.bind('' , self.Move_Arb_Up)
self.master.bind('', self.Move_Arb_Down)
#####
self.master.bind('' , self.Initialize_Laser)
self.master.bind('' , self.Unfreeze_Laser)
self.master.bind('' , self.menu_File_Open_Design)
self.master.bind('' , self.menu_Reload_Design)
self.master.bind('' , self.Home)
self.master.bind('' , self.Unlock)
self.master.bind('' , self.Stop)
self.master.bind('' , self.TRACE_Settings_Window)
self.include_Reng = BooleanVar()
self.include_Rpth = BooleanVar()
self.include_Veng = BooleanVar()
self.include_Vcut = BooleanVar()
self.include_Gcde = BooleanVar()
self.include_Time = BooleanVar()
self.advanced = BooleanVar()
self.halftone = BooleanVar()
self.mirror = BooleanVar()
self.rotate = BooleanVar()
self.negate = BooleanVar()
self.inputCSYS = BooleanVar()
self.HomeUR = BooleanVar()
self.engraveUP = BooleanVar()
self.init_home = BooleanVar()
self.post_home = BooleanVar()
self.post_beep = BooleanVar()
self.post_disp = BooleanVar()
self.post_exec = BooleanVar()
self.pre_pr_crc = BooleanVar()
self.inside_first = BooleanVar()
self.rotary = BooleanVar()
self.reduced_mem = BooleanVar()
self.wait = BooleanVar()
self.ht_size = StringVar()
self.Reng_feed = StringVar()
self.Veng_feed = StringVar()
self.Vcut_feed = StringVar()
self.Reng_passes = StringVar()
self.Veng_passes = StringVar()
self.Vcut_passes = StringVar()
self.Gcde_passes = StringVar()
self.board_name = StringVar()
self.units = StringVar()
self.jog_step = StringVar()
self.rast_step = StringVar()
self.funits = StringVar()
self.bezier_M1 = StringVar()
self.bezier_M2 = StringVar()
self.bezier_weight = StringVar()
## self.unsharp_flag = BooleanVar()
## self.unsharp_r = StringVar()
## self.unsharp_p = StringVar()
## self.unsharp_t = StringVar()
## self.unsharp_flag.set(False)
## self.unsharp_r.set("40")
## self.unsharp_p.set("350")
## self.unsharp_t.set("3")
self.LaserXsize = StringVar()
self.LaserYsize = StringVar()
self.LaserXscale = StringVar()
self.LaserYscale = StringVar()
self.LaserRscale = StringVar()
self.rapid_feed = StringVar()
self.gotoX = StringVar()
self.gotoY = StringVar()
self.n_egv_passes = StringVar()
self.inkscape_path = StringVar()
self.batch_path = StringVar()
self.ink_timeout = StringVar()
self.t_timeout = StringVar()
self.n_timeouts = StringVar()
self.Reng_time = StringVar()
self.Veng_time = StringVar()
self.Vcut_time = StringVar()
self.Gcde_time = StringVar()
self.comb_engrave = BooleanVar()
self.comb_vector = BooleanVar()
self.zoom2image = BooleanVar()
self.trace_w_laser = BooleanVar()
self.trace_gap = StringVar()
self.trace_speed = StringVar()
###########################################################################
# INITILIZE VARIABLES #
# if you want to change a default setting this is the place to do it #
###########################################################################
self.include_Reng.set(1)
self.include_Rpth.set(0)
self.include_Veng.set(1)
self.include_Vcut.set(1)
self.include_Gcde.set(1)
self.include_Time.set(0)
self.advanced.set(0)
self.halftone.set(1)
self.mirror.set(0)
self.rotate.set(0)
self.negate.set(0)
self.inputCSYS.set(0)
self.HomeUR.set(0)
self.engraveUP.set(0)
self.init_home.set(1)
self.post_home.set(0)
self.post_beep.set(0)
self.post_disp.set(0)
self.post_exec.set(0)
self.pre_pr_crc.set(1)
self.inside_first.set(1)
self.rotary.set(0)
self.reduced_mem.set(0)
self.wait.set(1)
self.ht_size.set(500)
self.Reng_feed.set("100")
self.Veng_feed.set("20")
self.Vcut_feed.set("10")
self.Reng_passes.set("1")
self.Veng_passes.set("1")
self.Vcut_passes.set("1")
self.Gcde_passes.set("1")
self.jog_step.set("10.0")
self.rast_step.set("0.002")
self.bezier_weight.set("3.5")
self.bezier_M1.set("2.5")
self.bezier_M2.set("0.50")
self.bezier_weight_default = float(self.bezier_weight.get())
self.bezier_M1_default = float(self.bezier_M1.get())
self.bezier_M2_default = float(self.bezier_M2.get())
self.board_name.set("LASER-M2") # Options are
# "LASER-M2",
# "LASER-M1",
# "LASER-M",
# "LASER-B2",
# "LASER-B1",
# "LASER-B",
# "LASER-A"
self.units.set("in") # Options are "in" and "mm"
self.ink_timeout.set("3")
self.t_timeout.set("200")
self.n_timeouts.set("30")
self.HOME_DIR = os.path.expanduser("~/photoBooth")
if not os.path.isdir(self.HOME_DIR):
self.HOME_DIR = ""
self.DESIGN_FILE = (self.HOME_DIR+"/None")
self.EGV_FILE = None
self.aspect_ratio = 0
self.segID = []
self.LaserXsize.set("325")
self.LaserYsize.set("220")
self.LaserXscale.set("1.000")
self.LaserYscale.set("1.000")
self.LaserRscale.set("1.000")
self.rapid_feed.set("0.0")
self.gotoX.set("0.0")
self.gotoY.set("0.0")
self.n_egv_passes.set("1")
self.comb_engrave.set(0)
self.comb_vector.set(0)
self.zoom2image.set(0)
self.trace_w_laser.set(0)
self.trace_gap.set(0)
self.trace_speed.set(50)
self.laserX = 0.0
self.laserY = 0.0
self.PlotScale = 1.0
self.GUI_Disabled = False
# PAN and ZOOM STUFF
self.panx = 0
self.panx = 0
self.lastx = 0
self.lasty = 0
self.move_start_x = 0
self.move_start_y = 0
self.RengData = ECoord()
self.VengData = ECoord()
self.VcutData = ECoord()
self.GcodeData = ECoord()
self.SCALE = 1
self.Design_bounds = (0,0,0,0)
self.UI_image = None
self.pos_offset=[0.0,0.0]
self.inkscape_warning = False
# Derived variables
if self.units.get() == 'in':
self.funits.set('in/min')
self.units_scale = 1.0
else:
self.units.set('mm')
self.funits.set('mm/s')
self.units_scale = 25.4
self.statusMessage = StringVar()
self.statusMessage.set("Welcome to K40 Whisperer")
self.Reng_time.set("0")
self.Veng_time.set("0")
self.Vcut_time.set("0")
self.Gcde_time.set("0")
self.min_vector_speed = 1.1 #in/min
self.min_raster_speed = 12 #in/min
##########################################################################
### END INITILIZING VARIABLES ###
##########################################################################
# make a Status Bar
self.statusbar = Label(self.master, textvariable=self.statusMessage, \
bd=1, relief=SUNKEN , height=1)
self.statusbar.pack(anchor=SW, fill=X, side=BOTTOM)
# Canvas
lbframe = Frame( self.master )
self.PreviewCanvas_frame = lbframe
self.PreviewCanvas = Canvas(lbframe, width=self.w-(220+20), height=self.h-200, background="grey75")
self.PreviewCanvas.pack(side=LEFT, fill=BOTH, expand=1)
self.PreviewCanvas_frame.place(x=230, y=10)
self.PreviewCanvas.tag_bind('LaserTag',"<1>" , self.mousePanStart)
self.PreviewCanvas.tag_bind('LaserTag',"" , self.mousePan)
self.PreviewCanvas.tag_bind('LaserTag',"", self.mousePanStop)
self.PreviewCanvas.tag_bind('LaserDot',"<3>" , self.right_mousePanStart)
self.PreviewCanvas.tag_bind('LaserDot',"" , self.right_mousePan)
self.PreviewCanvas.tag_bind('LaserDot',"", self.right_mousePanStop)
# Left Column #
self.separator1 = Frame(self.master, height=2, bd=1, relief=SUNKEN)
self.separator2 = Frame(self.master, height=2, bd=1, relief=SUNKEN)
self.separator3 = Frame(self.master, height=2, bd=1, relief=SUNKEN)
self.separator4 = Frame(self.master, height=2, bd=1, relief=SUNKEN)
self.Label_Reng_feed_u = Label(self.master,textvariable=self.funits, anchor=W)
self.Entry_Reng_feed = Entry(self.master,width="15")
self.Entry_Reng_feed.configure(textvariable=self.Reng_feed,justify='center',fg="black")
self.Reng_feed.trace_variable("w", self.Entry_Reng_feed_Callback)
self.NormalColor = self.Entry_Reng_feed.cget('bg')
self.Label_Veng_feed_u = Label(self.master,textvariable=self.funits, anchor=W)
self.Entry_Veng_feed = Entry(self.master,width="15")
self.Entry_Veng_feed.configure(textvariable=self.Veng_feed,justify='center',fg="blue")
self.Veng_feed.trace_variable("w", self.Entry_Veng_feed_Callback)
self.NormalColor = self.Entry_Veng_feed.cget('bg')
self.Label_Vcut_feed_u = Label(self.master,textvariable=self.funits, anchor=W)
self.Entry_Vcut_feed = Entry(self.master,width="15")
self.Entry_Vcut_feed.configure(textvariable=self.Vcut_feed,justify='center',fg="red")
self.Vcut_feed.trace_variable("w", self.Entry_Vcut_feed_Callback)
self.NormalColor = self.Entry_Vcut_feed.cget('bg')
# Buttons
self.Reng_Button = Button(self.master,text="Raster Engrave", command=self.Raster_Eng)
self.Veng_Button = Button(self.master,text="Vector Engrave", command=self.Vector_Eng)
self.Vcut_Button = Button(self.master,text="Vector Cut" , command=self.Vector_Cut)
self.Grun_Button = Button(self.master,text="Run G-Code" , command=self.Gcode_Cut)
self.Reng_Veng_Button = Button(self.master,text="Raster and\nVector Engrave", command=self.Raster_Vector_Eng)
self.Veng_Vcut_Button = Button(self.master,text="Vector Engrave\nand Cut", command=self.Vector_Eng_Cut)
self.Reng_Veng_Vcut_Button = Button(self.master,text="Raster Engrave\nVector Engrave\nand\nVector Cut", command=self.Raster_Vector_Cut)
self.Label_Position_Control = Label(self.master,text="Position Controls:", anchor=W)
self.Initialize_Button = Button(self.master,text="Initialize Laser Cutter", command=self.Initialize_Laser)
self.Open_Button = Button(self.master,text="Open\nDesign File", command=self.menu_File_Open_Design)
self.Reload_Button = Button(self.master,text="Reload\nDesign File", command=self.menu_Reload_Design)
self.Home_Button = Button(self.master,text="Home", command=self.Home)
self.UnLock_Button = Button(self.master,text="Unlock Rail", command=self.Unlock)
self.Stop_Button = Button(self.master,text="Pause/Stop", command=self.Stop)
try:
self.left_image = PhotoImage(data=K40_Whisperer_Images.left_B64, format='gif')
self.right_image = PhotoImage(data=K40_Whisperer_Images.right_B64, format='gif')
self.up_image = PhotoImage(data=K40_Whisperer_Images.up_B64, format='gif')
self.down_image = PhotoImage(data=K40_Whisperer_Images.down_B64, format='gif')
self.Right_Button = Button(self.master,image=self.right_image, command=self.Move_Right)
self.Left_Button = Button(self.master,image=self.left_image, command=self.Move_Left)
self.Up_Button = Button(self.master,image=self.up_image, command=self.Move_Up)
self.Down_Button = Button(self.master,image=self.down_image, command=self.Move_Down)
self.UL_image = PhotoImage(data=K40_Whisperer_Images.UL_B64, format='gif')
self.UR_image = PhotoImage(data=K40_Whisperer_Images.UR_B64, format='gif')
self.LR_image = PhotoImage(data=K40_Whisperer_Images.LR_B64, format='gif')
self.LL_image = PhotoImage(data=K40_Whisperer_Images.LL_B64, format='gif')
self.CC_image = PhotoImage(data=K40_Whisperer_Images.CC_B64, format='gif')
self.UL_Button = Button(self.master,image=self.UL_image, command=self.Move_UL)
self.UR_Button = Button(self.master,image=self.UR_image, command=self.Move_UR)
self.LR_Button = Button(self.master,image=self.LR_image, command=self.Move_LR)
self.LL_Button = Button(self.master,image=self.LL_image, command=self.Move_LL)
self.CC_Button = Button(self.master,image=self.CC_image, command=self.Move_CC)
except:
self.Right_Button = Button(self.master,text=">", command=self.Move_Right)
self.Left_Button = Button(self.master,text="<", command=self.Move_Left)
self.Up_Button = Button(self.master,text="^", command=self.Move_Up)
self.Down_Button = Button(self.master,text="v", command=self.Move_Down)
self.UL_Button = Button(self.master,text=" ", command=self.Move_UL)
self.UR_Button = Button(self.master,text=" ", command=self.Move_UR)
self.LR_Button = Button(self.master,text=" ", command=self.Move_LR)
self.LL_Button = Button(self.master,text=" ", command=self.Move_LL)
self.CC_Button = Button(self.master,text=" ", command=self.Move_CC)
self.Label_Step = Label(self.master,text="Jog Step", anchor=CENTER )
self.Label_Step_u = Label(self.master,textvariable=self.units, anchor=W)
self.Entry_Step = Entry(self.master,width="15")
self.Entry_Step.configure(textvariable=self.jog_step, justify='center')
self.jog_step.trace_variable("w", self.Entry_Step_Callback)
###########################################################################
self.GoTo_Button = Button(self.master,text="Move To", command=self.GoTo)
self.Entry_GoToX = Entry(self.master,width="15",justify='center')
self.Entry_GoToX.configure(textvariable=self.gotoX)
self.gotoX.trace_variable("w", self.Entry_GoToX_Callback)
self.Entry_GoToY = Entry(self.master,width="15",justify='center')
self.Entry_GoToY.configure(textvariable=self.gotoY)
self.gotoY.trace_variable("w", self.Entry_GoToY_Callback)
self.Label_GoToX = Label(self.master,text="X", anchor=CENTER )
self.Label_GoToY = Label(self.master,text="Y", anchor=CENTER )
###########################################################################
# End Left Column #
# Advanced Column #
self.separator_vert = Frame(self.master, height=2, bd=1, relief=SUNKEN)
self.Label_Advanced_column = Label(self.master,text="Advanced Settings",anchor=CENTER)
self.separator_adv = Frame(self.master, height=2, bd=1, relief=SUNKEN)
self.Label_Halftone_adv = Label(self.master,text="Halftone (Dither)")
self.Checkbutton_Halftone_adv = Checkbutton(self.master,text=" ", anchor=W)
self.Checkbutton_Halftone_adv.configure(variable=self.halftone)
self.halftone.trace_variable("w", self.View_Refresh_and_Reset_RasterPath) #self.menu_View_Refresh_Callback
self.Label_Negate_adv = Label(self.master,text="Invert Raster Color")
self.Checkbutton_Negate_adv = Checkbutton(self.master,text=" ", anchor=W)
self.Checkbutton_Negate_adv.configure(variable=self.negate)
self.negate.trace_variable("w", self.View_Refresh_and_Reset_RasterPath)
self.separator_adv2 = Frame(self.master, height=2, bd=1, relief=SUNKEN)
self.Label_Mirror_adv = Label(self.master,text="Mirror Design")
self.Checkbutton_Mirror_adv = Checkbutton(self.master,text=" ", anchor=W)
self.Checkbutton_Mirror_adv.configure(variable=self.mirror)
self.mirror.trace_variable("w", self.View_Refresh_and_Reset_RasterPath)
self.Label_Rotate_adv = Label(self.master,text="Rotate Design")
self.Checkbutton_Rotate_adv = Checkbutton(self.master,text=" ", anchor=W)
self.Checkbutton_Rotate_adv.configure(variable=self.rotate)
self.rotate.trace_variable("w", self.View_Refresh_and_Reset_RasterPath)
self.separator_adv3 = Frame(self.master, height=2, bd=1, relief=SUNKEN)
self.Label_inputCSYS_adv = Label(self.master,text="Use Input CSYS")
self.Checkbutton_inputCSYS_adv = Checkbutton(self.master,text=" ", anchor=W)
self.Checkbutton_inputCSYS_adv.configure(variable=self.inputCSYS)
self.inputCSYS.trace_variable("w", self.menu_View_inputCSYS_Refresh_Callback)
self.Label_Inside_First_adv = Label(self.master,text="Cut Inside First")
self.Checkbutton_Inside_First_adv = Checkbutton(self.master,text=" ", anchor=W)
self.Checkbutton_Inside_First_adv.configure(variable=self.inside_first)
self.inside_first.trace_variable("w", self.menu_Inside_First_Callback)
self.Label_Inside_First_adv = Label(self.master,text="Cut Inside First")
self.Checkbutton_Inside_First_adv = Checkbutton(self.master,text=" ", anchor=W)
self.Checkbutton_Inside_First_adv.configure(variable=self.inside_first)
self.Label_Rotary_Enable_adv = Label(self.master,text="Use Rotary Settings")
self.Checkbutton_Rotary_Enable_adv = Checkbutton(self.master,text="")
self.Checkbutton_Rotary_Enable_adv.configure(variable=self.rotary)
self.rotary.trace_variable("w", self.Reset_RasterPath_and_Update_Time)
#####
self.separator_comb = Frame(self.master, height=2, bd=1, relief=SUNKEN)
self.Label_Comb_Engrave_adv = Label(self.master,text="Group Engrave Tasks")
self.Checkbutton_Comb_Engrave_adv = Checkbutton(self.master,text=" ", anchor=W)
self.Checkbutton_Comb_Engrave_adv.configure(variable=self.comb_engrave)
self.comb_engrave.trace_variable("w", self.menu_View_Refresh_Callback)
self.Label_Comb_Vector_adv = Label(self.master,text="Group Vector Tasks")
self.Checkbutton_Comb_Vector_adv = Checkbutton(self.master,text=" ", anchor=W)
self.Checkbutton_Comb_Vector_adv.configure(variable=self.comb_vector)
self.comb_vector.trace_variable("w", self.menu_View_Refresh_Callback)
#####
self.Label_Reng_passes = Label(self.master,text="Raster Eng. Passes")
self.Entry_Reng_passes = Entry(self.master,width="15")
self.Entry_Reng_passes.configure(textvariable=self.Reng_passes,justify='center',fg="black")
self.Reng_passes.trace_variable("w", self.Entry_Reng_passes_Callback)
self.NormalColor = self.Entry_Reng_passes.cget('bg')
self.Label_Veng_passes = Label(self.master,text="Vector Eng. Passes")
self.Entry_Veng_passes = Entry(self.master,width="15")
self.Entry_Veng_passes.configure(textvariable=self.Veng_passes,justify='center',fg="blue")
self.Veng_passes.trace_variable("w", self.Entry_Veng_passes_Callback)
self.NormalColor = self.Entry_Veng_passes.cget('bg')
self.Label_Vcut_passes = Label(self.master,text="Vector Cut Passes")
self.Entry_Vcut_passes = Entry(self.master,width="15")
self.Entry_Vcut_passes.configure(textvariable=self.Vcut_passes,justify='center',fg="red")
self.Vcut_passes.trace_variable("w", self.Entry_Vcut_passes_Callback)
self.NormalColor = self.Entry_Vcut_passes.cget('bg')
self.Label_Gcde_passes = Label(self.master,text="G-Code Passes")
self.Entry_Gcde_passes = Entry(self.master,width="15")
self.Entry_Gcde_passes.configure(textvariable=self.Gcde_passes,justify='center',fg="black")
self.Gcde_passes.trace_variable("w", self.Entry_Gcde_passes_Callback)
self.NormalColor = self.Entry_Gcde_passes.cget('bg')
self.Hide_Adv_Button = Button(self.master,text="Hide Advanced", command=self.Hide_Advanced)
# End Right Column #
self.calc_button = Button(self.master,text="Calculate Raster Time", command=self.menu_Calc_Raster_Time)
#GEN Setting Window Entry initializations
self.Entry_Sspeed = Entry()
self.Entry_BoxGap = Entry()
self.Entry_ContAngle = Entry()
# Make Menu Bar
self.menuBar = Menu(self.master, relief = "raised", bd=2)
top_File = Menu(self.menuBar, tearoff=0)
top_File.add("command", label = "Save Settings File", command = self.menu_File_Save)
top_File.add("command", label = "Read Settings File", command = self.menu_File_Open_Settings_File)
top_File.add_separator()
top_File.add("command", label = "Open Design (SVG/DXF/G-Code)" , command = self.menu_File_Open_Design)
top_File.add("command", label = "Reload Design" , command = self.menu_Reload_Design)
top_File.add_separator()
top_File.add("command", label = "Send EGV File to Laser" , command = self.menu_File_Open_EGV)
SaveEGVmenu = Menu(self.master, relief = "raised", bd=2, tearoff=0)
top_File.add_cascade(label="Save EGV File", menu=SaveEGVmenu)
SaveEGVmenu.add("command", label = "Raster Engrave" , command = self.menu_File_Raster_Engrave)
SaveEGVmenu.add("command", label = "Vector Engrave" , command = self.menu_File_Vector_Engrave)
SaveEGVmenu.add("command", label = "Vector Cut" , command = self.menu_File_Vector_Cut)
SaveEGVmenu.add("command", label = "G-Code Operations" , command = self.menu_File_G_Code)
SaveEGVmenu.add_separator()
SaveEGVmenu.add("command", label = "Raster and Vector Engrave" , command = self.menu_File_Raster_Vector_Engrave)
SaveEGVmenu.add("command", label = "Vector Engrave and Cut" , command = self.menu_File_Vector_Engrave_Cut)
SaveEGVmenu.add("command", label = "Raster, Vector Engrave and Vector Cut" , command = self.menu_File_Raster_Vector_Cut)
top_File.add_separator()
top_File.add("command", label = "Exit" , command = self.menu_File_Quit)
self.menuBar.add("cascade", label="File", menu=top_File)
#top_Edit = Menu(self.menuBar, tearoff=0)
#self.menuBar.add("cascade", label="Edit", menu=top_Edit)
top_View = Menu(self.menuBar, tearoff=0)
top_View.add("command", label = "Refresh ", command = self.menu_View_Refresh)
top_View.add_separator()
top_View.add_checkbutton(label = "Show Raster Image" , variable=self.include_Reng ,command= self.menu_View_Refresh)
if DEBUG:
top_View.add_checkbutton(label = "Show Raster Paths" ,variable=self.include_Rpth ,command= self.menu_View_Refresh)
top_View.add_checkbutton(label = "Show Vector Engrave", variable=self.include_Veng ,command= self.menu_View_Refresh)
top_View.add_checkbutton(label = "Show Vector Cut" , variable=self.include_Vcut ,command= self.menu_View_Refresh)
top_View.add_checkbutton(label = "Show G-Code Paths" , variable=self.include_Gcde ,command= self.menu_View_Refresh)
top_View.add_separator()
top_View.add_checkbutton(label = "Show Time Estimates", variable=self.include_Time ,command= self.menu_View_Refresh)
top_View.add_checkbutton(label = "Zoom to Design Size", variable=self.zoom2image ,command= self.menu_View_Refresh)
#top_View.add_separator()
#top_View.add("command", label = "computeAccurateReng",command= self.computeAccurateReng)
#top_View.add("command", label = "computeAccurateVeng",command= self.computeAccurateVeng)
#top_View.add("command", label = "computeAccurateVcut",command= self.computeAccurateVcut)
self.menuBar.add("cascade", label="View", menu=top_View)
top_Tools = Menu(self.menuBar, tearoff=0)
self.menuBar.add("cascade", label="Tools", menu=top_Tools)
USBmenu = Menu(self.master, relief = "raised", bd=2, tearoff=0)
top_Tools.add("command", label = "Calculate Raster Time", command = self.menu_Calc_Raster_Time)
top_Tools.add("command", label = "Trace Design Boundary ", command = self.TRACE_Settings_Window)
top_Tools.add_separator()
top_Tools.add("command", label = "Initialize Laser ", command = self.Initialize_Laser)
top_Tools.add("command", label = "Unfreeze Laser " , command = self.Unfreeze_Laser)
top_Tools.add_cascade(label="USB", menu=USBmenu)
USBmenu.add("command", label = "Reset USB", command = self.Reset)
USBmenu.add("command", label = "Release USB", command = self.Release_USB)
#top_USB = Menu(self.menuBar, tearoff=0)
#top_USB.add("command", label = "Reset USB", command = self.Reset)
#top_USB.add("command", label = "Release USB", command = self.Release_USB)
#top_USB.add("command", label = "Initialize Laser", command = self.Initialize_Laser)
#self.menuBar.add("cascade", label="USB", menu=top_USB)
top_Settings = Menu(self.menuBar, tearoff=0)
top_Settings.add("command", label = "General Settings ", command = self.GEN_Settings_Window)
top_Settings.add("command", label = "Raster Settings ", command = self.RASTER_Settings_Window)
top_Settings.add("command", label = "Rotary Settings ", command = self.ROTARY_Settings_Window)
top_Settings.add_separator()
top_Settings.add_checkbutton(label = "Advanced Settings ", variable=self.advanced ,command= self.menu_View_Refresh)
self.menuBar.add("cascade", label="Settings", menu=top_Settings)
top_Help = Menu(self.menuBar, tearoff=0)
top_Help.add("command", label = "About (e-mail)", command = self.menu_Help_About)
top_Help.add("command", label = "K40 Whisperer Web Page", command = self.menu_Help_Web)
top_Help.add("command", label = "Manual (Web Page)", command = self.menu_Help_Manual)
self.menuBar.add("cascade", label="Help", menu=top_Help)
self.master.config(menu=self.menuBar)
##########################################################################
# Config File and command line options #
##########################################################################
config_file = "k40_whisperer.txt"
home_config1 = self.HOME_DIR + "/" + config_file
if ( os.path.isfile(config_file) ):
self.Open_Settings_File(config_file)
elif ( os.path.isfile(home_config1) ):
self.Open_Settings_File(home_config1)
#Lovejoy
arguments = len(sys.argv) - 1
if arguments >=1:
# read commandline arguments, first
fullCmdArguments = sys.argv
# - further arguments
argumentList = fullCmdArguments[1:]
#opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
unixOptions = "cghHio:rsnvVux:y:"
gnuOptions = ["help","go","stop","home","init","open","cut","raster", "vector", "verbose","unlock"]
try:
arguments, values = getopt.getopt(argumentList, unixOptions, gnuOptions)
except getopt.error as err:
# output error, and return with an error code
print (str(err))
sys.exit(2)
# evaluate given options
for currentArgument, currentValue in arguments:
if currentArgument in ("-i", "--init"):
print ("initializing the laser")
self.Initialize_Laser()
#sage()
#command=self.Initialize_Laser
elif currentArgument in ("-H", "--home"):
print ("move to the home position")
self.Home()
elif currentArgument in ("-h", "--help"):
print ("CLI arguments are as follows")
print ("-g --go Starts the job with whatever other arguments")
print ("-s --stop Stops the job, doesnt go home, or un initialize")
print ("-H --home Sends the cutting head to the home [0,0] position")
print ("-i --init Initializes the laser, or prints errors if it fails")
print ("-o --open Requires an SVG file to open")
print ("-h --help Prints this dialog")
print ("-c --cut Tell the laser to cut")
print ("-r --raster Raster Engrave")
print ("-v --vector Vector Engrave")
print ("-V Verbose mode lo U wish.. I guess I could set debug mode")
print ("-u --unlock Unlock the print head")
print ("-x move to X-Cordinate ")
print ("-y move to Y-Cordinate ")
print (" ")
print (" ")
print ("Example Useage: $python k40_whisperer.py -i -H -o c.svg -r ")
exit()
elif currentArgument in ("-o", "--open"):
print (("opening an svg (%s)") % (currentValue))
self.Open_SVG(currentValue)
#self.Open_SVG(filename)
self.send_data("Vector_Cut", currentValue)
elif currentArgument in ("-g", "--go"):
print ("Start cutting or moving the head")
#This option doesn't translate into a direct action like the other functions do.
elif currentArgument in ("-s", "--stop"):
print ("Stop Cutting::dont check or make a pop up, just stop")
self.CLI_Stop()
#self.Stop()
elif currentArgument in ("-u", "--unlock"):
print ("unlocked the print head")
self.Unlock()
elif currentArgument in ("-c", "cut"):
print ("cuts the open svg file")
self.Vector_Cut()
elif currentArgument in ("-r", "--raster"):
print ("raster Engraves the opened file")
self.Raster_Eng()
elif currentArgument in ("-v", "--vector"):
print ("Vector Engraves the opend file")
#self.Vector_Eng()
output_filename=currentValue
self.Vector_Cut()
self.send_data("Vector_Cut", output_filename)
elif currentArgument in ("-V"):
print ("Verbose mode lol u wish, well, there is debug mode")
print ("Version 0.19 K40_whisperer source")
print ("Version 0.0 K40 CLI source")
elif currentArgument in ("x"):
print ("Move to X Coordinate " % (currentValue))
self.gotoX.set(currentValue)
self.GoTo()
elif currentArgument in ("y"):
print("Move to Y Coordnate %s" % (currentValue))
self.gotoY.set(currentValue)
self.GoTo()
else:
print ("FOILED! put in some args if you want CLI mode")
#Lovejoy
# opts, args = None, None
# try:
# opts, args = getopt.getopt(sys.argv[1:], "ho:",["help", "other_option"])
# except:
# debug_message('Unable interpret command line options')
# sys.exit()
# for option, value in opts:
## if option in ('-h','--help'):
## fmessage(' ')
## fmessage('Usage: python .py [-g file]')
## fmessage('-o : unknown other option (also --other_option)')
## fmessage('-h : print this help (also --help)\n')
## sys.exit()
# if option in ('-m','--micro'):
# self.micro = True
##########################################################################
################################################################################
def entry_set(self, val2, calc_flag=0, new=0):
if calc_flag == 0 and new==0:
try:
self.statusbar.configure( bg = 'yellow' )
val2.configure( bg = 'yellow' )
self.statusMessage.set(" Recalculation required.")
except:
pass
elif calc_flag == 3:
try:
val2.configure( bg = 'red' )
self.statusbar.configure( bg = 'red' )
self.statusMessage.set(" Value should be a number. ")
except:
pass
elif calc_flag == 2:
try:
self.statusbar.configure( bg = 'red' )
val2.configure( bg = 'red' )
except:
pass
elif (calc_flag == 0 or calc_flag == 1) and new==1 :
try:
self.statusbar.configure( bg = 'white' )
self.statusMessage.set(" ")
val2.configure( bg = 'white' )
except:
pass
elif (calc_flag == 1) and new==0 :
try:
self.statusbar.configure( bg = 'white' )
self.statusMessage.set(" ")
val2.configure( bg = 'white' )
except:
pass
elif (calc_flag == 0 or calc_flag == 1) and new==2:
return 0
return 1
################################################################################
def Write_Config_File(self, event):
config_data = self.WriteConfig()
config_file = "k40_whisperer.txt"
configname_full = self.HOME_DIR + "/" + config_file
current_name = event.widget.winfo_parent()
win_id = event.widget.nametowidget(current_name)
if ( os.path.isfile(configname_full) ):
try:
win_id.withdraw()
except:
pass
if not message_ask_ok_cancel("Replace", "Replace Exiting Configuration File?\n"+configname_full):
try:
win_id.deiconify()
except:
pass
return
try:
fout = open(configname_full,'w')
except:
self.statusMessage.set("Unable to open file for writing: %s" %(configname_full))
self.statusbar.configure( bg = 'red' )
return
for line in config_data:
try:
fout.write(line+'\n')
except:
fout.write('(skipping line)\n')
fout.close
self.statusMessage.set("Configuration File Saved: %s" %(configname_full))
self.statusbar.configure( bg = 'white' )
try:
win_id.deiconify()
except:
pass
################################################################################
def WriteConfig(self):
global Zero
header = []
header.append('( K40 Whisperer Settings: '+version+' )')
header.append('( by Scorch - 2019 )')
header.append("(=========================================================)")
# BOOL
header.append('(k40_whisperer_set include_Reng %s )' %( int(self.include_Reng.get()) ))
header.append('(k40_whisperer_set include_Veng %s )' %( int(self.include_Veng.get()) ))
header.append('(k40_whisperer_set include_Vcut %s )' %( int(self.include_Vcut.get()) ))
header.append('(k40_whisperer_set include_Gcde %s )' %( int(self.include_Gcde.get()) ))
header.append('(k40_whisperer_set include_Time %s )' %( int(self.include_Time.get()) ))
header.append('(k40_whisperer_set halftone %s )' %( int(self.halftone.get()) ))
header.append('(k40_whisperer_set HomeUR %s )' %( int(self.HomeUR.get()) ))
header.append('(k40_whisperer_set inputCSYS %s )' %( int(self.inputCSYS.get()) ))
header.append('(k40_whisperer_set advanced %s )' %( int(self.advanced.get()) ))
header.append('(k40_whisperer_set mirror %s )' %( int(self.mirror.get()) ))
header.append('(k40_whisperer_set rotate %s )' %( int(self.rotate.get()) ))
header.append('(k40_whisperer_set negate %s )' %( int(self.negate.get()) ))
header.append('(k40_whisperer_set engraveUP %s )' %( int(self.engraveUP.get()) ))
header.append('(k40_whisperer_set init_home %s )' %( int(self.init_home.get()) ))
header.append('(k40_whisperer_set post_home %s )' %( int(self.post_home.get()) ))
header.append('(k40_whisperer_set post_beep %s )' %( int(self.post_beep.get()) ))
header.append('(k40_whisperer_set post_disp %s )' %( int(self.post_disp.get()) ))
header.append('(k40_whisperer_set post_exec %s )' %( int(self.post_exec.get()) ))
header.append('(k40_whisperer_set pre_pr_crc %s )' %( int(self.pre_pr_crc.get()) ))
header.append('(k40_whisperer_set inside_first %s )' %( int(self.inside_first.get()) ))
header.append('(k40_whisperer_set comb_engrave %s )' %( int(self.comb_engrave.get()) ))
header.append('(k40_whisperer_set comb_vector %s )' %( int(self.comb_vector.get()) ))
header.append('(k40_whisperer_set zoom2image %s )' %( int(self.zoom2image.get()) ))
header.append('(k40_whisperer_set rotary %s )' %( int(self.rotary.get()) ))
header.append('(k40_whisperer_set reduced_mem %s )' %( int(self.reduced_mem.get()) ))
header.append('(k40_whisperer_set wait %s )' %( int(self.wait.get()) ))
header.append('(k40_whisperer_set trace_w_laser %s )' %( int(self.trace_w_laser.get()) ))
# STRING.get()
header.append('(k40_whisperer_set board_name %s )' %( self.board_name.get() ))
header.append('(k40_whisperer_set units %s )' %( self.units.get() ))
header.append('(k40_whisperer_set Reng_feed %s )' %( self.Reng_feed.get() ))
header.append('(k40_whisperer_set Veng_feed %s )' %( self.Veng_feed.get() ))
header.append('(k40_whisperer_set Vcut_feed %s )' %( self.Vcut_feed.get() ))
header.append('(k40_whisperer_set jog_step %s )' %( self.jog_step.get() ))
header.append('(k40_whisperer_set Reng_passes %s )' %( self.Reng_passes.get() ))
header.append('(k40_whisperer_set Veng_passes %s )' %( self.Veng_passes.get() ))
header.append('(k40_whisperer_set Vcut_passes %s )' %( self.Vcut_passes.get() ))
header.append('(k40_whisperer_set Gcde_passes %s )' %( self.Gcde_passes.get() ))
header.append('(k40_whisperer_set rast_step %s )' %( self.rast_step.get() ))
header.append('(k40_whisperer_set ht_size %s )' %( self.ht_size.get() ))
header.append('(k40_whisperer_set LaserXsize %s )' %( self.LaserXsize.get() ))
header.append('(k40_whisperer_set LaserYsize %s )' %( self.LaserYsize.get() ))
header.append('(k40_whisperer_set LaserXscale %s )' %( self.LaserXscale.get() ))
header.append('(k40_whisperer_set LaserYscale %s )' %( self.LaserYscale.get() ))
header.append('(k40_whisperer_set LaserRscale %s )' %( self.LaserRscale.get() ))
header.append('(k40_whisperer_set rapid_feed %s )' %( self.rapid_feed.get() ))
header.append('(k40_whisperer_set gotoX %s )' %( self.gotoX.get() ))
header.append('(k40_whisperer_set gotoY %s )' %( self.gotoY.get() ))
header.append('(k40_whisperer_set bezier_M1 %s )' %( self.bezier_M1.get() ))
header.append('(k40_whisperer_set bezier_M2 %s )' %( self.bezier_M2.get() ))
header.append('(k40_whisperer_set bezier_weight %s )' %( self.bezier_weight.get() ))
header.append('(k40_whisperer_set trace_gap %s )' %( self.trace_gap.get() ))
header.append('(k40_whisperer_set trace_speed %s )' %( self.trace_speed.get() ))
## header.append('(k40_whisperer_set unsharp_flag %s )' %( int(self.unsharp_flag.get()) ))
## header.append('(k40_whisperer_set unsharp_r %s )' %( self.unsharp_r.get() ))
## header.append('(k40_whisperer_set unsharp_p %s )' %( self.unsharp_p.get() ))
## header.append('(k40_whisperer_set unsharp_t %s )' %( self.unsharp_t.get() ))
header.append('(k40_whisperer_set t_timeout %s )' %( self.t_timeout.get() ))
header.append('(k40_whisperer_set n_timeouts %s )' %( self.n_timeouts.get() ))
header.append('(k40_whisperer_set ink_timeout %s )' %( self.ink_timeout.get() ))
header.append('(k40_whisperer_set designfile \042%s\042 )' %( self.DESIGN_FILE ))
header.append('(k40_whisperer_set inkscape_path \042%s\042 )' %( self.inkscape_path.get() ))
header.append('(k40_whisperer_set batch_path \042%s\042 )' %( self.batch_path.get() ))
self.jog_step
header.append("(=========================================================)")
return header
######################################################
def Quit_Click(self, event):
self.statusMessage.set("Exiting!")
self.Release_USB
root.destroy()
def mousePanStart(self,event):
self.panx = event.x
self.pany = event.y
self.move_start_x = event.x
self.move_start_y = event.y
def mousePan(self,event):
all = self.PreviewCanvas.find_all()
dx = event.x-self.panx
dy = event.y-self.pany
self.PreviewCanvas.move('LaserTag', dx, dy)
self.lastx = self.lastx + dx
self.lasty = self.lasty + dy
self.panx = event.x
self.pany = event.y
def mousePanStop(self,event):
Xold = round(self.laserX,3)
Yold = round(self.laserY,3)
can_dx = event.x-self.move_start_x
can_dy = -(event.y-self.move_start_y)
dx = can_dx*self.PlotScale
dy = can_dy*self.PlotScale
if self.HomeUR.get():
dx = -dx
self.laserX,self.laserY = self.XY_in_bounds(dx,dy)
DXmils = round((self.laserX - Xold)*1000.0,0)
DYmils = round((self.laserY - Yold)*1000.0,0)
if self.Send_Rapid_Move(DXmils,DYmils):
self.menu_View_Refresh()
def right_mousePanStart(self,event):
self.s_panx = event.x
self.s_pany = event.y
self.s_move_start_x = event.x
self.s_move_start_y = event.y
def right_mousePan(self,event):
all = self.PreviewCanvas.find_all()
dx = event.x-self.s_panx
dy = event.y-self.s_pany
self.PreviewCanvas.move('LaserDot', dx, dy)
self.s_lastx = self.lastx + dx
self.s_lasty = self.lasty + dy
self.s_panx = event.x
self.s_pany = event.y
def right_mousePanStop(self,event):
Xold = round(self.laserX,3)
Yold = round(self.laserY,3)
can_dx = event.x-self.s_move_start_x
can_dy = -(event.y-self.s_move_start_y)
dx = can_dx*self.PlotScale
dy = can_dy*self.PlotScale
DX = round(dx*1000)
DY = round(dy*1000)
self.Move_Arbitrary(DX,DY)
self.menu_View_Refresh()
def LASER_Size(self):
MINX = 0.0
MAXY = 0.0
if self.units.get()=="in":
MAXX = float(self.LaserXsize.get())
MINY = -float(self.LaserYsize.get())
else:
MAXX = float(self.LaserXsize.get())/25.4
MINY = -float(self.LaserYsize.get())/25.4
return (MAXX-MINX,MAXY-MINY)
def XY_in_bounds(self,dx_inches,dy_inches, no_size=False):
MINX = 0.0
MAXY = 0.0
if self.units.get()=="in":
MAXX = float(self.LaserXsize.get())
MINY = -float(self.LaserYsize.get())
else:
MAXX = float(self.LaserXsize.get())/25.4
MINY = -float(self.LaserYsize.get())/25.4
if (self.inputCSYS.get() and self.RengData.image == None) or no_size:
xmin,xmax,ymin,ymax = 0.0,0.0,0.0,0.0
else:
xmin,xmax,ymin,ymax = self.Get_Design_Bounds()
X = self.laserX + dx_inches
Y = self.laserY + dy_inches
################
dx=xmax-xmin
dy=ymax-ymin
if X < MINX:
X = MINX
if X+dx > MAXX:
X = MAXX-dx
if Y-dy < MINY:
Y = MINY+dy
if Y > MAXY:
Y = MAXY
################
if not no_size:
XOFF = self.pos_offset[0]/1000.0
YOFF = self.pos_offset[1]/1000.0
if X+XOFF < MINX:
X= X +(MINX-(X+XOFF))
if X+XOFF > MAXX:
X= X -((X+XOFF)-MAXX)
if Y+YOFF < MINY:
Y= Y + (MINY-(Y+YOFF))
if Y+YOFF > MAXY:
Y= Y -((Y+YOFF)-MAXY)
################
X = round(X,3)
Y = round(Y,3)
return X,Y
## def computeAccurateVeng(self):
## self.update_gui("Optimize vector engrave.")
## self.VengData.set_ecoords(self.optimize_paths(self.VengData.ecoords),data_sorted=True)
## self.refreshTime()
##
## def computeAccurateVcut(self):
## self.update_gui("Optimize vector cut.")
## self.VcutData.set_ecoords(self.optimize_paths(self.VcutData.ecoords),data_sorted=True)
## self.refreshTime()
##
## def computeAccurateReng(self):
## self.update_gui("Calculating Raster engrave.")
## if self.RengData.image != None:
## if self.RengData.ecoords == []:
## self.make_raster_coords()
## self.RengData.sorted = True
## self.refreshTime()
def format_time(self,time_in_seconds):
# format the duration from seconds to something human readable
if time_in_seconds !=None and time_in_seconds >=0 :
s = round(time_in_seconds)
m,s=divmod(s,60)
h,m=divmod(m,60)
res = ""
if h > 0:
res = "%dh " %(h)
if m > 0:
res += "%dm " %(m)
if h == 0:
res += "%ds " %(s)
#L=len(res)
#for i in range(L,8):
# res = res+" "
return res
else :
return "?"
def refreshTime(self):
if not self.include_Time.get():
return
if self.units.get() == 'in':
factor = 60.0
else :
factor = 25.4
Raster_eng_feed = float(self.Reng_feed.get()) / factor
Vector_eng_feed = float(self.Veng_feed.get()) / factor
Vector_cut_feed = float(self.Vcut_feed.get()) / factor
Raster_eng_passes = float(self.Reng_passes.get())
Vector_eng_passes = float(self.Veng_passes.get())
Vector_cut_passes = float(self.Vcut_passes.get())
Gcode_passes = float(self.Gcde_passes.get())
rapid_feed = 100.0 / 25.4 # 100 mm/s move feed to be confirmed
if self.RengData.rpaths:
Reng_time=0
else:
Reng_time = None
Veng_time = 0
Vcut_time = 0
if self.RengData.len!=None:
# these equations are a terrible hack based on measured raster engraving times
# to be fixed someday
if Raster_eng_feed*60.0 <= 300:
accel_time=8.3264*(Raster_eng_feed*60.0)**(-0.7451)
else:
accel_time=2.5913*(Raster_eng_feed*60.0)**(-0.4795)
t_accel = self.RengData.n_scanlines * accel_time
Reng_time = ( (self.RengData.len)/Raster_eng_feed ) * Raster_eng_passes + t_accel
if self.VengData.len!=None:
Veng_time = (self.VengData.len / Vector_eng_feed + self.VengData.move / rapid_feed) * Vector_eng_passes
if self.VcutData.len!=None:
Vcut_time = (self.VcutData.len / Vector_cut_feed + self.VcutData.move / rapid_feed) * Vector_cut_passes
Gcode_time = self.GcodeData.gcode_time * Gcode_passes
self.Reng_time.set("Raster Engrave: %s" %(self.format_time(Reng_time)))
self.Veng_time.set("Vector Engrave: %s" %(self.format_time(Veng_time)))
self.Vcut_time.set(" Vector Cut: %s" %(self.format_time(Vcut_time)))
self.Gcde_time.set(" Gcode: %s" %(self.format_time(Gcode_time)))
##########################################
cszw = int(self.PreviewCanvas.cget("width"))
cszh = int(self.PreviewCanvas.cget("height"))
HUD_vspace = 15
HUD_X = cszw-5
HUD_Y = cszh-5
w = int(self.master.winfo_width())
h = int(self.master.winfo_height())
HUD_X2 = w-20
HUD_Y2 = h-75
self.PreviewCanvas.delete("HUD")
self.calc_button.place_forget()
if self.GcodeData.ecoords == []:
self.PreviewCanvas.create_text(HUD_X, HUD_Y , fill = "red" ,text =self.Vcut_time.get(), anchor="se",tags="HUD")
self.PreviewCanvas.create_text(HUD_X, HUD_Y-HUD_vspace , fill = "blue" ,text =self.Veng_time.get(), anchor="se",tags="HUD")
if (Reng_time==None):
#try:
# self.calc_button.place_forget()
#except:
# pass
#self.calc_button = Button(self.master,text="Calculate Raster Time", command=self.menu_Calc_Raster_Time)
self.calc_button.place(x=HUD_X2, y=HUD_Y2, width=120+20, height=17, anchor="se")
else:
self.calc_button.place_forget()
self.PreviewCanvas.create_text(HUD_X, HUD_Y-HUD_vspace*2, fill = "black",
text =self.Reng_time.get(), anchor="se",tags="HUD")
else:
self.PreviewCanvas.create_text(HUD_X, HUD_Y, fill = "black",text =self.Gcde_time.get(), anchor="se",tags="HUD")
##########################################
def Settings_ReLoad_Click(self, event):
win_id=self.grab_current()
def Close_Current_Window_Click(self,event=None):
current_name = event.widget.winfo_parent()
win_id = event.widget.nametowidget(current_name)
win_id.destroy()
# Left Column #
#############################
def Entry_Reng_feed_Check(self):
try:
value = float(self.Reng_feed.get())
vfactor=(25.4/60.0)/self.feed_factor()
low_limit = self.min_raster_speed*vfactor
if value < low_limit:
self.statusMessage.set(" Feed Rate should be greater than or equal to %f " %(low_limit))
return 2 # Value is invalid number
except:
return 3 # Value not a number
self.refreshTime()
return 0 # Value is a valid number
def Entry_Reng_feed_Callback(self, varName, index, mode):
self.entry_set(self.Entry_Reng_feed, self.Entry_Reng_feed_Check(), new=1)
#############################
def Entry_Veng_feed_Check(self):
try:
value = float(self.Veng_feed.get())
vfactor=(25.4/60.0)/self.feed_factor()
low_limit = self.min_vector_speed*vfactor
if value < low_limit:
self.statusMessage.set(" Feed Rate should be greater than or equal to %f " %(low_limit))
return 2 # Value is invalid number
except:
return 3 # Value not a number
self.refreshTime()
return 0 # Value is a valid number
def Entry_Veng_feed_Callback(self, varName, index, mode):
self.entry_set(self.Entry_Veng_feed, self.Entry_Veng_feed_Check(), new=1)
#############################
def Entry_Vcut_feed_Check(self):
try:
value = float(self.Vcut_feed.get())
vfactor=(25.4/60.0)/self.feed_factor()
low_limit = self.min_vector_speed*vfactor
if value < low_limit:
self.statusMessage.set(" Feed Rate should be greater than or equal to %f " %(low_limit))
return 2 # Value is invalid number
except:
return 3 # Value not a number
self.refreshTime()
return 0 # Value is a valid number
def Entry_Vcut_feed_Callback(self, varName, index, mode):
self.entry_set(self.Entry_Vcut_feed, self.Entry_Vcut_feed_Check(), new=1)
#############################
def Entry_Step_Check(self):
try:
value = float(self.jog_step.get())
if value <= 0.0:
self.statusMessage.set(" Step should be greater than 0.0 ")
return 2 # Value is invalid number
except:
return 3 # Value not a number
return 0 # Value is a valid number
def Entry_Step_Callback(self, varName, index, mode):
self.entry_set(self.Entry_Step, self.Entry_Step_Check(), new=1)
#############################
def Entry_GoToX_Check(self):
try:
value = float(self.gotoX.get())
if (value < 0.0) and (not self.HomeUR.get()):
self.statusMessage.set(" Value should be greater than 0.0 ")
return 2 # Value is invalid number
elif (value > 0.0) and self.HomeUR.get():
self.statusMessage.set(" Value should be less than 0.0 ")
return 2 # Value is invalid number
except:
return 3 # Value not a number
return 0 # Value is a valid number
def Entry_GoToX_Callback(self, varName, index, mode):
self.entry_set(self.Entry_GoToX, self.Entry_GoToX_Check(), new=1)
#############################
def Entry_GoToY_Check(self):
try:
value = float(self.gotoY.get())
if value > 0.0:
self.statusMessage.set(" Value should be less than 0.0 ")
return 2 # Value is invalid number
except:
return 3 # Value not a number
return 0 # Value is a valid number
def Entry_GoToY_Callback(self, varName, index, mode):
self.entry_set(self.Entry_GoToY, self.Entry_GoToY_Check(), new=1)
#############################
def Entry_Rstep_Check(self):
try:
value = self.get_raster_step_1000in()
if value <= 0 or value > 63:
self.statusMessage.set(" Step should be between 0.001 and 0.063 in")
return 2 # Value is invalid number
except:
return 3 # Value not a number
return 0 # Value is a valid number
def Entry_Rstep_Callback(self, varName, index, mode):
self.RengData.reset_path()
self.refreshTime()
self.entry_set(self.Entry_Rstep, self.Entry_Rstep_Check(), new=1)
## #############################
## def Entry_Unsharp_Radius_Check(self):
## try:
## value = float(self.unsharp_r.get())
## if value <= 0:
## self.statusMessage.set(" Radius should be greater than zero.")
## return 2 # Value is invalid number
## excep