diff --git a/src/core/path_gcc.c b/src/core/path_gcc.c new file mode 100644 index 0000000..5775678 --- /dev/null +++ b/src/core/path_gcc.c @@ -0,0 +1,182 @@ +// +// path_epi.c +// convert path to Epilog lasercutter .epi +// +// Neil Gershenfeld 8/18/13 +// (c) Massachusetts Institute of Technology 2013 +// +// This work may be reproduced, modified, distributed, +// performed, and displayed for any purpose, but must +// acknowledge the fab modules project. Copyright is +// retained and must be preserved. The work is provided +// as is; no warranty is provided, and users accept all +// liability. +// + +#include "fab.h" + +void fab_write_epi(struct fab_vars *v, char *output_file_name, int power, int speed, int focus, float ox, float oy, char loc, int rate, int max_power) { + // + // write path to Epilog lasercutter file + // + FILE *output_file; + int i,x,y,z,current_z,layer_power,nsegs=0,npts=0; + float scale,xoffset,yoffset; + output_file = fopen(output_file_name,"w"); + scale = 600.0*v->dx/(25.4*(v->nx-1.0)); // 600 DPI + if (loc == 'l') { + xoffset = 600.0*(ox)/25.4; + yoffset = 600.0*(oy - v->dy)/25.4; + } + else if (loc == 'r') { + xoffset = 600.0*(ox - v->dx)/25.4; + yoffset = 600.0*(oy - v->dy)/25.4; + } + else if (loc == 'L') { + xoffset = 600.0*(ox)/25.4; + yoffset = 600.0*(oy)/25.4; + } + else if (loc == 'R') { + xoffset = 600.0*(ox - v->dx)/25.4; + yoffset = 600.0*(oy)/25.4; + } + if (focus == 0) + // + // init with autofocus off + // + fprintf(output_file,"%%-12345X@PJL JOB NAME=%s\r\nE@PJL ENTER LANGUAGE=PCL\r\n&y0A&l0U&l0Z&u600D*p0X*p0Y*t600R*r0F&y50P&z50S*r6600T*r5100S*r1A*rC%%1BIN;XR%d;YP%d;ZS%d;\n",output_file_name,rate,power,speed); + else + // + // init with autofocus on + // + fprintf(output_file,"%%-12345X@PJL JOB NAME=%s\r\nE@PJL ENTER LANGUAGE=PCL\r\n&y1A&l0U&l0Z&u600D*p0X*p0Y*t600R*r0F&y50P&z50S*r6600T*r5100S*r1A*rC%%1BIN;XR%d;YP%d;ZS%d;\n",output_file_name,rate,power,speed); + current_z = 0; + fprintf(output_file,"YP%d;\n",power); + v->path->segment = v->path->last; + while (1) { + // + // follow segments in reverse order + // + v->path->segment->point = v->path->segment->first; + x = xoffset + scale * v->path->segment->point->first->value; + y = yoffset + scale * v->path->segment->point->first->next->value; + if (v->path->dof >= 3) { + z = v->path->segment->point->first->next->next->value; + if (z != current_z) { + layer_power = power + (max_power-power) * z / (v->nz - 1.0); + fprintf(output_file,"YP%d;\n",layer_power); + current_z = z; + } + } + if (x < 0) x = 0; + if (y < 0) y = 0; + fprintf(output_file,"PU%d,%d;",x,y); + nsegs += 1; + while (1) { + // + // follow points + // + if (v->path->segment->point->next == 0) + break; + v->path->segment->point = v->path->segment->point->next; + x = xoffset + scale * v->path->segment->point->first->value; + y = yoffset + scale * v->path->segment->point->first->next->value; + if (v->path->dof >= 3) { + z = v->path->segment->point->first->next->next->value; + if (z != current_z) { + layer_power = power + (max_power-power) * z / (v->nz - 1.0); + fprintf(output_file,"YP%d;\n",layer_power); + current_z = z; + } + } + if (x < 0) x = 0; + if (y < 0) y = 0; + fprintf(output_file,"PD%d,%d;",x,y); + npts += 1; + } + fprintf(output_file,"\n"); + if (v->path->segment == v->path->first) + break; + v->path->segment = v->path->segment->previous; + } + fprintf(output_file,"%%0B%%1BPUE%%-12345X@PJL EOJ \r\n"); + // + // end-of-file padding hack from Epilog print driver + // + for (i = 0; i < 10000; ++i) + fprintf(output_file," "); + // fprintf(output_file,"%c",26); // ^z + // + // close and return + // + fclose(output_file); + printf("wrote %s\n",output_file_name); + printf(" segments: %d, points: %d\n",nsegs,npts); + } + +int main(int argc, char **argv) { + // + // local vars + // + struct fab_vars v; + init_vars(&v); + int power,max_power,speed,focus,rate; + float ox,oy; + char loc; + // + // command line args + // + if (!((argc == 3) || (argc == 4) || (argc == 5) || (argc == 6) || (argc == 8) || (argc == 9) || (argc == 10) || (argc == 11))) { + printf("command line: path_epi in.path out.epi [power [speed [focus [x y [ location [rate [max_power]]]]]]]\n"); + printf(" in.path = input path file\n"); + printf(" out.epi= output Epilog lasercutter file\n"); + printf(" power = percent power, for minimum z value (optional, 0-100, default 50)\n"); + printf(" speed = percent speed (optional, 0-100, default 50)\n"); + printf(" focus = autofocus (optional, 0=off | 1=on, default on)\n"); + printf(" x = origin x (optional, mm, default 0 = left side of bed)\n"); + printf(" y = origin y (optional, mm, default 0 = back side of bed, front positive)\n"); + printf(" location = origin location (optional, bottom left:l, bottom right:r, top left:L, top right:R, default l)\n"); + printf(" rate = pulse rate (optional, frequency, default 2500)\n"); + printf(" max_power = percent power, for maximum z value (optional, 0-100, default power)\n"); + exit(-1); + } + power = 50; + speed = 50; + focus = 1; + ox = 0; + oy = 0; + loc = 'l'; + rate = 2500; + max_power = power; + if (argc >= 4) { + sscanf(argv[3],"%d",&power); + } + if (argc >= 5) { + sscanf(argv[4],"%d",&speed); + } + if (argc >= 6) { + sscanf(argv[5],"%d",&focus); + } + if (argc >= 8) { + sscanf(argv[6],"%f",&ox); + sscanf(argv[7],"%f",&oy); + } + if (argc >= 9) { + sscanf(argv[8],"%c",&loc); + } + if (argc >= 10) { + sscanf(argv[9],"%d",&rate); + } + if (argc >= 11) { + sscanf(argv[10],"%d",&max_power); + } + // + // read path + // + fab_read_path(&v,argv[1]); + // + // write .epi + // + fab_write_epi(&v,argv[2],power,speed,focus,ox,oy,loc,rate,max_power); + } + diff --git a/src/guis/make_png_gcc b/src/guis/make_png_gcc new file mode 100755 index 0000000..44884e3 --- /dev/null +++ b/src/guis/make_png_gcc @@ -0,0 +1,55 @@ +#!/usr/bin/env python +# +# make_png_epi +# .png to .epi GUI wrapper +# +# Neil Gershenfeld +# CBA MIT 1/24/11 +# +# (c) Massachusetts Institute of Technology 2011 +# Permission granted for experimental and personal use; +# license for commercial sale available from MIT. +# +# imports +# +import wx,sys +from fab_set import fab_frame +from panel_control import control_panel +from panel_png import png_panel +from panel_png_path import png_path_panel +from panel_path_epi import path_epi_panel +# +# command line +# +print "command line: make_png_epi [input_file [size]]" +print " input_file = input .png file (optional)" +print " size = image panel size (optional)" +# +# start wx +# +app = wx.App() +# +# add panels to frame +# +frame = fab_frame("make_png_epi",sys.argv) +frame.control_panel = control_panel(frame) +frame.sizer.Add(frame.control_panel,(0,0),span=(1,3),flag=wx.ALIGN_CENTER_HORIZONTAL) +frame.epi_panel = path_epi_panel(frame) +frame.sizer.Add(frame.epi_panel,(1,2)) +frame.path_panel = png_path_panel(frame) +frame.sizer.Add(frame.path_panel,(1,1)) +frame.png_panel = png_panel(frame) +frame.sizer.Add(frame.png_panel,(1,0)) +# +# set defaults +# +frame.set_png_epi() +# +# fit and show frame +# +frame.Fit() +frame.Show() +# +# start mainloop +# +app.MainLoop() diff --git a/src/py/panel_path_gcc.py b/src/py/panel_path_gcc.py new file mode 100644 index 0000000..c277291 --- /dev/null +++ b/src/py/panel_path_gcc.py @@ -0,0 +1,248 @@ +# +# panel_path_epi.py +# make .epi from .path +# +# Neil Gershenfeld 8/19/13 +# (c) Massachusetts Institute of Technology 2013 +# +# This work may be reproduced, modified, distributed, +# performed, and displayed for any purpose, but must +# acknowledge the fab modules project. Copyright is +# retained and must be preserved. The work is provided +# as is; no warranty is provided, and users accept all +# liability. +# + +# +# imports +# +import wx,os,string +# +# panel class +# +class path_epi_panel(wx.Panel): + def __init__(self,parent): + self.parent = parent + self.parent.path_file = '' + # + # make epi + # + def make_epi(event): + if (self.parent.path_file == ''): + print 'panel_path_epi: oops -- need path file' + return + self.parent.epi_file = self.parent.tmp+self.parent.rootname+'.epi' + if (string.find(self.parent.path_type,"2D") != -1): + power = self.power_2D.GetValue() + if (self.focus_2D.GetValue()): + focus = '1' + else: + focus = '0' + ox = self.origin_x_2D.GetValue() + oy = self.origin_y_2D.GetValue() + if self.top_left_2D.GetValue(): + loc = 'L' + elif self.top_right_2D.GetValue(): + loc = 'R' + elif self.bottom_left_2D.GetValue(): + loc = 'l' + elif self.bottom_right_2D.GetValue(): + loc = 'r' + speed = self.speed_2D.GetValue() + rate = self.rate_2D.GetValue() + command = 'path_epi '+'\"'+self.parent.path_file+'\"'+' '+'\"'+self.parent.epi_file+'\"'+' '+power+' '+speed+' '+focus+' '+ox+' '+oy+' '+loc+' '+' '+rate + print command + os.system(command) + self.button.Show() + self.parent.Layout() + self.parent.Fit() + elif (string.find(self.parent.path_type,"3D") != -1): + min_power = self.min_power_3D.GetValue() + max_power = self.max_power_3D.GetValue() + if (self.focus_3D.GetValue()): + focus = '1' + else: + focus = '0' + ox = self.origin_x_3D.GetValue() + oy = self.origin_y_3D.GetValue() + if self.top_left_3D.GetValue(): + loc = 'L' + elif self.top_right_3D.GetValue(): + loc = 'R' + elif self.bottom_left_3D.GetValue(): + loc = 'l' + elif self.bottom_right_3D.GetValue(): + loc = 'r' + speed = self.speed_3D.GetValue() + rate = self.rate_3D.GetValue() + command = 'path_epi '+'\"'+self.parent.path_file+'\"'+' '+'\"'+self.parent.epi_file+'\"'+' '+min_power+' '+speed+' '+focus+' '+ox+' '+oy+' '+loc+' '+' '+rate+' '+max_power + print command + os.system(command) + self.button.Show() + self.parent.Layout() + self.parent.Fit() + else: + print "panel_path_epi: oops -- don't recognize path type" + return + # + # send + # + def fab_send(event): + command = 'fab_send '+'\"'+self.parent.epi_file+'\"' + print command + os.system(command) + # + # panel + # + wx.Panel.__init__(self,parent) + self.sizer = wx.GridBagSizer(10,10) + self.SetSizer(self.sizer) + # + # label + # + label = wx.StaticText(self,label='to: epi') + bold_font = wx.Font(10,wx.DEFAULT,wx.NORMAL,wx.BOLD) + label.SetFont(bold_font) + self.sizer.Add(label,(0,0),flag=wx.ALIGN_CENTER_HORIZONTAL) + # + # send + # + self.button = wx.Button(self,label='send it!') + self.button.Bind(wx.EVT_BUTTON,fab_send) + self.button.SetFont(bold_font) + self.sizer.Add(self.button,(1,0),flag=(wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)) + self.button.Hide() + # + # controls + # + make = wx.Button(self,label='make .epi') + make.Bind(wx.EVT_BUTTON,make_epi) + self.sizer.Add(make,(2,0),flag=wx.ALIGN_CENTER_HORIZONTAL) + # + # 2D panel + # + self.panel_2D = wx.Panel(self) + sizer_2D = wx.GridBagSizer(10,10) + self.panel_2D.SetSizer(sizer_2D) + # + self.focus_2D = wx.CheckBox(self.panel_2D,-1,'autofocus') + sizer_2D.Add(self.focus_2D,(0,0),span=(1,2),flag=(wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)) + # + sizer_2D.Add(wx.StaticText(self.panel_2D,label='power (%)'),(1,0),span=(1,2),flag=wx.ALIGN_CENTER_HORIZONTAL) + # + self.power_2D = wx.TextCtrl(self.panel_2D,-1,'25') + sizer_2D.Add(self.power_2D,(2,0),span=(1,2),flag=wx.ALIGN_CENTER_HORIZONTAL) + # + set_panel_2D = wx.Panel(self.panel_2D) + set_sizer_2D = wx.GridBagSizer(10,10) + set_panel_2D.SetSizer(set_sizer_2D) + # + set_sizer_2D.Add(wx.StaticText(set_panel_2D,label='speed (%)'),(0,0),flag=wx.ALIGN_RIGHT) + set_sizer_2D.Add(wx.StaticText(set_panel_2D,label='rate'),(0,1),flag=wx.ALIGN_LEFT) + # + self.speed_2D = wx.TextCtrl(set_panel_2D,-1,'75') + set_sizer_2D.Add(self.speed_2D,(1,0),flag=wx.ALIGN_RIGHT) + self.rate_2D = wx.TextCtrl(set_panel_2D,-1,'500') + set_sizer_2D.Add(self.rate_2D,(1,1),flag=wx.ALIGN_LEFT) + # + sizer_2D.Add(set_panel_2D,(3,0),span=(1,2),flag=(wx.ALIGN_CENTER_HORIZONTAL)) + # + origin_panel_2D = wx.Panel(self.panel_2D) + origin_sizer_2D = wx.GridBagSizer(10,10) + origin_panel_2D.SetSizer(origin_sizer_2D) + # + self.top_left_2D = wx.RadioButton(origin_panel_2D,-1,'left',(10,10),style=wx.RB_GROUP) + origin_sizer_2D.Add(self.top_left_2D,(0,0),flag=wx.ALIGN_CENTER_HORIZONTAL) + origin_sizer_2D.Add(wx.StaticText(origin_panel_2D,label='top'),(0,1),flag=(wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)) + self.top_right_2D = wx.RadioButton(origin_panel_2D,-1,'right',(10,10)) + origin_sizer_2D.Add(self.top_right_2D,(0,2),flag=wx.ALIGN_CENTER_HORIZONTAL) + # + self.origin_x_2D = wx.TextCtrl(origin_panel_2D,-1,'10') + origin_sizer_2D.Add(self.origin_x_2D,(1,0),flag=wx.ALIGN_RIGHT) + origin_sizer_2D.Add(wx.StaticText(origin_panel_2D,label='x origin (mm) y'),(1,1),flag=(wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)) + self.origin_y_2D = wx.TextCtrl(origin_panel_2D,-1,'10') + origin_sizer_2D.Add(self.origin_y_2D,(1,2),flag=wx.ALIGN_LEFT) + # + self.bottom_left_2D = wx.RadioButton(origin_panel_2D,-1,'left',(10,10)) + origin_sizer_2D.Add(self.bottom_left_2D,(2,0),flag=wx.ALIGN_CENTER_HORIZONTAL) + origin_sizer_2D.Add(wx.StaticText(origin_panel_2D,label='bottom'),(2,1),flag=(wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)) + self.bottom_right_2D = wx.RadioButton(origin_panel_2D,-1,'right',(10,10)) + # + origin_sizer_2D.Add(self.bottom_right_2D,(2,2),flag=wx.ALIGN_CENTER_HORIZONTAL) + sizer_2D.Add(origin_panel_2D,(4,0),span=(1,2),flag=(wx.ALIGN_CENTER_HORIZONTAL)) + # + self.sizer.Add(self.panel_2D,(3,0),flag=(wx.ALIGN_CENTER_HORIZONTAL)) + self.path_type = "2D" + # + # 3D panel + # + self.panel_3D = wx.Panel(self) + sizer_3D = wx.GridBagSizer(10,10) + self.panel_3D.SetSizer(sizer_3D) + # + self.focus_3D = wx.CheckBox(self.panel_3D,-1,'autofocus') + sizer_3D.Add(self.focus_3D,(0,0),span=(1,2),flag=wx.ALIGN_CENTER_HORIZONTAL) + # + set_panel_3D = wx.Panel(self.panel_3D) + set_sizer_3D = wx.GridBagSizer(10,10) + set_panel_3D.SetSizer(set_sizer_3D) + # + set_sizer_3D.Add(wx.StaticText(set_panel_3D,label='min z power (%)'),(0,0),flag=wx.ALIGN_RIGHT) + set_sizer_3D.Add(wx.StaticText(set_panel_3D,label='max z power (%)'),(0,1),flag=wx.ALIGN_LEFT) + # + self.min_power_3D = wx.TextCtrl(set_panel_3D,-1,'25') + set_sizer_3D.Add(self.min_power_3D,(1,0),flag=wx.ALIGN_RIGHT) + self.max_power_3D = wx.TextCtrl(set_panel_3D,-1,'25') + set_sizer_3D.Add(self.max_power_3D,(1,1),flag=wx.ALIGN_LEFT) + # + set_sizer_3D.Add(wx.StaticText(set_panel_3D,label='speed (%)'),(2,0),flag=wx.ALIGN_RIGHT) + set_sizer_3D.Add(wx.StaticText(set_panel_3D,label='rate'),(2,1),flag=wx.ALIGN_LEFT) + # + self.speed_3D = wx.TextCtrl(set_panel_3D,-1,'75') + set_sizer_3D.Add(self.speed_3D,(3,0),flag=wx.ALIGN_RIGHT) + self.rate_3D = wx.TextCtrl(set_panel_3D,-1,'500') + set_sizer_3D.Add(self.rate_3D,(3,1),flag=wx.ALIGN_LEFT) + # + sizer_3D.Add(set_panel_3D,(1,0),span=(1,2),flag=(wx.ALIGN_CENTER_HORIZONTAL)) + # + origin_panel_3D = wx.Panel(self.panel_3D) + origin_sizer_3D = wx.GridBagSizer(10,10) + origin_panel_3D.SetSizer(origin_sizer_3D) + # + self.top_left_3D = wx.RadioButton(origin_panel_3D,-1,'left',(10,10),style=wx.RB_GROUP) + origin_sizer_3D.Add(self.top_left_3D,(0,0),flag=wx.ALIGN_CENTER_HORIZONTAL) + origin_sizer_3D.Add(wx.StaticText(origin_panel_3D,label='top'),(0,1),flag=(wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)) + self.top_right_3D = wx.RadioButton(origin_panel_3D,-1,'right',(10,10)) + origin_sizer_3D.Add(self.top_right_3D,(0,2),flag=wx.ALIGN_CENTER_HORIZONTAL) + # + self.origin_x_3D = wx.TextCtrl(origin_panel_3D,-1,'10') + origin_sizer_3D.Add(self.origin_x_3D,(1,0),flag=wx.ALIGN_RIGHT) + origin_sizer_3D.Add(wx.StaticText(origin_panel_3D,label='x origin (mm) y'),(1,1),flag=(wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)) + self.origin_y_3D = wx.TextCtrl(origin_panel_3D,-1,'10') + origin_sizer_3D.Add(self.origin_y_3D,(1,2),flag=wx.ALIGN_LEFT) + # + self.bottom_left_3D = wx.RadioButton(origin_panel_3D,-1,'left',(10,10)) + origin_sizer_3D.Add(self.bottom_left_3D,(2,0),flag=wx.ALIGN_CENTER_HORIZONTAL) + origin_sizer_3D.Add(wx.StaticText(origin_panel_3D,label='bottom'),(2,1),flag=(wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL)) + self.bottom_right_3D = wx.RadioButton(origin_panel_3D,-1,'right',(10,10)) + origin_sizer_3D.Add(self.bottom_right_3D,(2,2),flag=wx.ALIGN_CENTER_HORIZONTAL) + # + sizer_3D.Add(origin_panel_3D,(2,0),span=(1,2),flag=(wx.ALIGN_CENTER_HORIZONTAL)) + # + self.panel_3D.Hide() + # + # parent call to update panel + # + def update_panel(self): + if (string.find(self.parent.path_type,"3D") != -1): + self.sizer.Detach(self.panel_2D) + self.panel_2D.Hide() + self.sizer.Add(self.panel_3D,(3,0),flag=(wx.ALIGN_CENTER_HORIZONTAL)) + self.panel_3D.Show() + elif (string.find(self.parent.path_type,"2D") != -1): + self.sizer.Detach(self.panel_3D) + self.panel_3D.Hide() + self.sizer.Add(self.panel_2D,(3,0),flag=(wx.ALIGN_CENTER_HORIZONTAL)) + self.panel_2D.Show() + self.Layout() + self.Fit()