Skip to content

Commit

Permalink
Merge pull request #23 from rsre/0.60
Browse files Browse the repository at this point in the history
Updates to v0.60
  • Loading branch information
rsre committed Apr 20, 2022
2 parents 33689eb + 1a64791 commit d7e5233
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 68 deletions.
9 changes: 8 additions & 1 deletion Change_Log.txt
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,6 @@ Version 0.56:
- Added code to fix driver conflict new drivers added to Linux
- Changed default file type to svg/dxf


Version 0.57:
- Fixed problem with start position (only occurred when using a custom "x scale" factor and "home in upper right")
- Added Command line option to enable debug mode
Expand All @@ -295,3 +294,11 @@ Version 0.57:
Version 0.58:
- Fixed problem with right mouse click motions that occurred when using "home in upper right"

Version 0.59:
- Now automatically removes zero length features from input files (caused unnecessary movements before)
- Removed redundant data sent to laser during raster engraving. Should reduce pauses for higher speed engraving.
- Added option for reduced memory use. This can be enabled to allow for larger designs to be loaded in K40 Whisperer or just increase speed. This option does reduce the resolution of the data coming from Inkscape 500dpi vs 1000dpi. This should not visibly affect the output in most cases.

Version 0.60:
- Fixed scaling problem when loading an SVG file with 'Reduced Memory Use' enabled.
The problem only occurred if the user was prompted for additional scaling information.
8 changes: 4 additions & 4 deletions build_macOS.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# This file executes the build command for the OS X Application bundle.
# It is here because I am lazy
# ---------------------------------------------------------------------
PYTHON_VERSION=3.9.1
PYTHON_VERSION=3.10.3

# Call getopt to validate the provided input.
VENV_DIR=build_env.$$
Expand Down Expand Up @@ -60,7 +60,7 @@ if [ "$SETUP_ENVIRONMENT" = true ]; then
check_failure "Failed to install homebrew"

# Install Dependencies
brew install --cask inkscape
brew install inkscape
brew install --build-from-source libusb
check_failure "Failed to install libusb"

Expand Down Expand Up @@ -128,7 +128,7 @@ echo "Build macOS Application Bundle..."
# Create .spec file if it doesn't exist
FILE=k40_whisperer.spec
if [ -f "$FILE" ]; then
${PYTHON} -O -m PyInstaller -y --clean k40_whisperer.spec
python3 -O -m PyInstaller -y --clean k40_whisperer.spec
else
echo "$FILE does not exist. Creating a basic one..."

Expand All @@ -147,7 +147,7 @@ else
--osx-bundle-identifier com.scorchworks.k40_whisperer \
k40_whisperer.py
mv K40\ Whisperer.spec k40_whisperer.spec
${PYTHON} -O -m PyInstaller -y --clean k40_whisperer.spec
python3 -O -m PyInstaller -y --clean k40_whisperer.spec
fi

# Get version from main source file.
Expand Down
3 changes: 2 additions & 1 deletion ecoords.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ def make_ecoords(self,coords,scale=1):
dxline= x2-x1
dyline= y2-y1
len_line=sqrt(dxline*dxline + dyline*dyline)

if len_line==0.0:
continue
dx = oldx - x1
dy = oldy - y1
dist = sqrt(dx*dx + dy*dy)
Expand Down
29 changes: 13 additions & 16 deletions egv.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -104,22 +104,6 @@ def flush(self,laser_on=None):
self.Modal_on = laser_on
self.Modal_dist = 0


# The one wire CRC algorithm is derived from the OneWire.cpp Library
# The library location: http://www.pjrc.com/teensy/td_libs_OneWire.html
def OneWireCRC(self,line):
crc=0
for i in range(len(line)):
inbyte=line[i]
for j in range(8):
mix = (crc ^ inbyte) & 0x01
crc >>= 1
if (mix):
crc ^= 0x8C
inbyte >>= 1
return crcS


def make_distance(self,dist_mils):
dist_mils=float(dist_mils)
if abs(dist_mils-round(dist_mils,0)) > 0.000001:
Expand Down Expand Up @@ -705,6 +689,19 @@ def change_speed(self,Feed,board_name,laser_on=False,Raster_step=0,pad=True):

if laser_on:
self.write(self.ON)

def strip_redundant_codes(self, EGV_data):
E = ord('E')
new_data=[]
modal_value = -1
for code in EGV_data:
if code == modal_value:
continue
elif (code == self.RIGHT) or (code == self.LEFT) or \
(code == self.UP ) or (code == self.DOWN) or (code == E):
modal_value = code
new_data.append(code)
return new_data


if __name__ == "__main__":
Expand Down
110 changes: 73 additions & 37 deletions k40_whisperer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""
K40 Whisperer
Copyright (C) <2017-2021> <Scorch>
Copyright (C) <2017-2022> <Scorch>
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
Expand All @@ -18,7 +18,7 @@
"""
app_name = "K40 Whisperer"
version = '0.58'
version = '0.60'
title_text = app_name+" V"+version

import sys
Expand Down Expand Up @@ -238,6 +238,7 @@ def createWidgets(self):
self.pre_pr_crc = BooleanVar()
self.inside_first = BooleanVar()
self.rotary = BooleanVar()
self.reduced_mem = BooleanVar()


self.ht_size = StringVar()
Expand Down Expand Up @@ -333,6 +334,7 @@ def createWidgets(self):
self.pre_pr_crc.set(1)
self.inside_first.set(1)
self.rotary.set(0)
self.reduced_mem.set(0)

self.ht_size.set(500)

Expand Down Expand Up @@ -936,6 +938,7 @@ def WriteConfig(self):
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 trace_w_laser %s )' %( int(self.trace_w_laser.get()) ))

Expand Down Expand Up @@ -1725,7 +1728,11 @@ def menu_File_Open_Settings_File(self,event=None):
if fileselect != '' and fileselect != ():
self.Open_Settings_File(fileselect)


def Reduced_Memory_Callback(self, varName, index, mode):
if self.RengData.image != None:
self.menu_Reload_Design()
#print("Reload_Design")

def menu_Reload_Design(self,event=None):
if self.GUI_Disabled:
return
Expand Down Expand Up @@ -1955,16 +1962,17 @@ def Open_EGV(self,filemname,n_passes=1):
dymils = y_end_mils - y_start_mils
self.Send_Rapid_Move(dxmils,dxmils)
self.stop[0]=True


def Open_SVG(self,filemname):
self.resetPath()

self.SVG_FILE = filemname
if self.reduced_mem.get():
self.input_dpi = 500.0
else:
self.input_dpi = 1000.0
svg_reader = SVG_READER()
svg_reader.set_inkscape_path(self.inkscape_path.get())
self.input_dpi = 1000
svg_reader.image_dpi = self.input_dpi
svg_reader.set_inkscape_path(self.inkscape_path.get())
svg_reader.timout = int(float( self.ink_timeout.get())*60.0)
dialog_pxpi = None
dialog_viewbox = None
Expand All @@ -1981,7 +1989,9 @@ def Open_SVG(self,filemname):
svg_reader.SVG_inkscape_version)

svg_reader = SVG_READER()
svg_reader.image_dpi = self.input_dpi
svg_reader.set_inkscape_path(self.inkscape_path.get())
svg_reader.timout = int(float( self.ink_timeout.get())*60.0)
if pxpi_dialog.result == None:
return

Expand All @@ -1992,7 +2002,9 @@ def Open_SVG(self,filemname):

except SVG_TEXT_EXCEPTION as e:
svg_reader = SVG_READER()
svg_reader.image_dpi = self.input_dpi
svg_reader.set_inkscape_path(self.inkscape_path.get())
svg_reader.timout = int(float( self.ink_timeout.get())*60.0)
self.statusMessage.set("Converting TEXT to PATHS.")
self.master.update()
svg_reader.parse_svg(self.SVG_FILE)
Expand Down Expand Up @@ -2094,8 +2106,7 @@ def make_raster_coords(self):


if self.halftone.get():
#start = time()
ht_size_mils = round( 1000.0 / float(self.ht_size.get()) ,1)
ht_size_mils = round( self.input_dpi / float(self.ht_size.get()) ,1)
npixels = int( round(ht_size_mils,1) )
if npixels == 0:
return
Expand All @@ -2107,11 +2118,8 @@ def make_raster_coords(self):

image_temp = self.convert_halftoning(image_temp)
image_temp = image_temp.resize((wim,him))
#print time()-start
else:
image_temp = image_temp.point(lambda x: 0 if x<128 else 255, '1')
#image_temp = image_temp.convert('1',dither=Image.NONE)


if DEBUG:
image_name = os.path.expanduser("~")+"/IMAGE.png"
Expand All @@ -2129,9 +2137,12 @@ def make_raster_coords(self):

my_hull = hull2D()
bignumber = 9999999;
Raster_step = self.get_raster_step_1000in()
Raster_step = int(self.get_raster_step_1000in())
timestamp=0
for i in range(0,him,Raster_step):
im_height_mils = int(him/self.input_dpi*1000.0)
for i_step in range(0,im_height_mils,Raster_step):
i=floor(i_step*self.input_dpi/1000.0)
#print(i_step,i)
stamp=int(3*time()) #update every 1/3 of a second
if (stamp != timestamp):
timestamp=stamp #interlock
Expand All @@ -2147,7 +2158,6 @@ def make_raster_coords(self):
if (Reng_np[j,i] == Reng_np[j-1,i]):
cnt = cnt+1
else:
#laser = "U" if Reng_np[j-1,i] > cutoff else "D"
if Reng_np[j-1,i]:
laser = "U"
else:
Expand All @@ -2157,7 +2167,6 @@ def make_raster_coords(self):

line.append((cnt,laser))
cnt=1
#laser = "U" if Reng_np[j-1,i] > cutoff else "D"
if Reng_np[j-1,i] > cutoff:
laser = "U"
else:
Expand All @@ -2167,30 +2176,28 @@ def make_raster_coords(self):

line.append((cnt,laser))
if LEFT != bignumber and RIGHT != -bignumber:
LENGTH = LENGTH + (RIGHT - LEFT)/1000.0
LENGTH = LENGTH + (RIGHT - LEFT)/self.input_dpi
n_scanlines = n_scanlines + 1

y=(him-i)/1000.0
y=(im_height_mils-i_step)/1000.0
x=0
if LEFT != bignumber:
hcoords.append([LEFT/1000.0,y])
hcoords.append([LEFT/self.input_dpi,y])
if RIGHT != -bignumber:
hcoords.append([RIGHT/1000.0,y])
hcoords.append([RIGHT/self.input_dpi,y])
if hcoords!=[]:
hcoords = my_hull.convexHullecoords(hcoords)

#rng = range(0,len(line),1)
rng = list(range(0,len(line),1))

for i in rng:
seg = line[i]
delta = seg[0]/1000.0
delta = seg[0]/self.input_dpi
if seg[1]=="D":
loop=loop+1
ecoords.append([x ,y,loop])
ecoords.append([x+delta,y,loop])
x = x + delta
#if ecoords!=[]:
self.RengData.set_ecoords(ecoords,data_sorted=True)
self.RengData.len=LENGTH
self.RengData.n_scanlines = n_scanlines
Expand Down Expand Up @@ -2230,7 +2237,7 @@ def rotate_raster(self,image_in):

def get_raster_step_1000in(self):
val_in = float(self.rast_step.get())
value = int(round(val_in*1000.0,1))
value = int(round(val_in*1000.0,1))
return value


Expand Down Expand Up @@ -2504,6 +2511,9 @@ def Open_Settings_File(self,filename):

elif "rotary" in line:
self.rotary.set(line[line.find("rotary"):].split()[1])
elif "reduced_mem" in line:
self.reduced_mem.set(line[line.find("reduced_mem"):].split()[1])

elif "trace_w_laser" in line:
self.trace_w_laser.set(line[line.find("trace_w_laser"):].split()[1])

Expand Down Expand Up @@ -3544,7 +3554,9 @@ def send_data(self,operation_type=None, output_filename=None):
Rapid_Feed_Rate = Rapid_Feed, \
use_laser=True
)
#self.RengData.reset_path()
#print(len(Raster_Eng_data))
Raster_Eng_data=Raster_Eng_egv_inst.strip_redundant_codes(Raster_Eng_data)
#print(len(Raster_Eng_data))

if (operation_type.find("Gcode_Cut") > -1) and (self.GcodeData.ecoords!=[]):
self.statusMessage.set("Generating EGV data...")
Expand Down Expand Up @@ -3706,8 +3718,12 @@ def Stop(self,event=None):
line2 = "Press \"OK\" to abort any jobs currently running."
line3 = "Press \"Cancel\" to resume."
if self.k40 != None:
self.k40.pause_un_pause()

try:
self.k40.pause_un_pause()
except:
if message_ask_ok_cancel("Stop Laser Job.", "\n%s\n%s" %(line2,line3)):
self.stop[0]=True

if message_ask_ok_cancel("Stop Laser Job.", "%s\n\n%s\n%s" %(line1,line2,line3)):
self.stop[0]=True
else:
Expand Down Expand Up @@ -4840,6 +4856,14 @@ def GEN_Settings_Window(self):
self.Checkbutton_Preprocess_CRC.place(x=xd_entry_L, y=D_Yloc, width=75, height=23)
self.Checkbutton_Preprocess_CRC.configure(variable=self.pre_pr_crc)

D_Yloc=D_Yloc+D_dY
self.Label_Reduce_Memory = Label(gen_settings,text="Reduce Memory Use")
self.Label_Reduce_Memory.place(x=xd_label_L, y=D_Yloc, width=w_label, height=21)
self.Checkbutton_Reduce_Memory = Checkbutton(gen_settings,text="(needed for large designs or low memory computers)", anchor=W)
self.Checkbutton_Reduce_Memory.place(x=xd_entry_L, y=D_Yloc, width=350, height=23)
self.Checkbutton_Reduce_Memory.configure(variable=self.reduced_mem)
self.reduced_mem.trace_variable("w", self.Reduced_Memory_Callback)

#D_Yloc=D_Yloc+D_dY
#self.Label_Timeout = Label(gen_settings,text="USB Timeout")
#self.Label_Timeout.place(x=xd_label_L, y=D_Yloc, width=w_label, height=21)
Expand Down Expand Up @@ -5026,19 +5050,31 @@ def RASTER_Settings_Window(self):
############
D_Yloc=D_Yloc+D_dY
self.Label_Halftone_DPI = Label(raster_settings,text="Halftone Resolution", anchor=CENTER )
self.Halftone_DPI_OptionMenu = OptionMenu(raster_settings, self.ht_size,
"1000",
"500",
"333",
"250",
"200",
"167",
"143",
"125")

if self.reduced_mem.get():
if self.ht_size == "1000": self.ht_size = "500"
if self.ht_size == "333": self.ht_size = "500"
if self.ht_size == "200": self.ht_size = "250"
if self.ht_size == "143": self.ht_size = "167"
self.Halftone_DPI_OptionMenu = OptionMenu(raster_settings, self.ht_size,
"500",
"250",
"167",
"125")
else:
self.Halftone_DPI_OptionMenu = OptionMenu(raster_settings, self.ht_size,
"1000",
"500",
"333",
"250",
"200",
"167",
"143",
"125")

self.Label_Halftone_DPI.place(x=xd_label_L, y=D_Yloc, width=w_label, height=21)
self.Halftone_DPI_OptionMenu.place(x=xd_entry_L, y=D_Yloc, width=w_entry+30, height=23)


self.Label_Halftone_u = Label(raster_settings,text="dpi", anchor=W)
self.Label_Halftone_u.place(x=xd_units_L+30, y=D_Yloc, width=w_units, height=21)

Expand Down
Loading

0 comments on commit d7e5233

Please sign in to comment.