├── .gitignore ├── README.md ├── bezier-console.inx ├── bezier-console.py ├── biarc.py ├── close_curves.inx ├── close_curves.py ├── create_inx.py ├── csp.py ├── debian ├── changelog ├── compat ├── control ├── install └── rules ├── doc ├── Makefile ├── gcodetools-ru.asciidoc └── img │ ├── area-tab.png │ ├── area-tutorial-0001.png │ ├── area-tutorial-0002.png │ ├── area-tutorial-0003.png │ ├── area-tutorial-0004.png │ ├── area-tutorial-0005.png │ ├── area-tutorial-0006.png │ ├── area-tutorial-0007.png │ ├── area-tutorial-0008.png │ ├── aria-artifacts-tab.png │ ├── fill-area-tab.png │ ├── orientation-points-tab.png │ ├── parameters-tab.png │ ├── path-to-gcode-tab.png │ ├── preferences-tab.png │ └── tools-library-tab.png ├── dxf_input.inx ├── dxf_input.py ├── examples └── Gerber-kicad-dec-abs-mm.drl ├── gcodetools-dev.inx ├── gcodetools-dev.py ├── inline_test.c ├── inline_test_functions.c ├── png.py ├── points.py └── stable ├── gcodetools.inx.src ├── gcodetools.py ├── gcodetools_about.inx ├── gcodetools_area.inx ├── gcodetools_check_for_updates.inx ├── gcodetools_dxf_points.inx ├── gcodetools_engraving.inx ├── gcodetools_graffiti.inx ├── gcodetools_lathe.inx ├── gcodetools_orientation_points.inx ├── gcodetools_path_to_gcode.inx ├── gcodetools_prepare_path_for_plasma.inx └── gcodetools_tools_library.inx /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | *~ 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | gcodetools 2 | ========== 3 | 4 | CAM extension for Inkscape to export paths to Gcode 5 | 6 | More info at http://www.cnc-club.ru/forum/viewtopic.php?t=35 7 | 8 | 9 | License 10 | ========== 11 | Inkscape and Gcodetools are licensed under GNU GPL. 12 | 13 | 14 | 15 | Install 16 | ========== 17 | Windows 18 | 19 | Unpack and copy all the files to the following directory Program Files\Inkscape\share\extensions\ and restart inkscape. 20 | 21 | Execute python create_inx.py to create all inx-files. 22 | 23 | Linux 24 | 25 | Unpack and copy all the files to the following directory /usr/share/inkscape/extensions/ and restart inkscape. 26 | 27 | Execute python create_inx.py to create all inx-files. 28 | -------------------------------------------------------------------------------- /bezier-console.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | <_name>Besier console creator 4 | ru.cnc-club.filter.bezier-console 5 | bezier-console.py 6 | inkex.py 7 | 8 | 9 | 10 | False 11 | 12 | 13 | <_item value="3.543307">mm 14 | <_item value="90">in 15 | <_item value="1">px 16 | <_item value="1.25">pt 17 | <_item value="15">pc 18 | <_item value="35.43307">cm 19 | 20 | 21 | 22 | all 23 | 24 | 25 | 26 | 27 | 30 | 31 | -------------------------------------------------------------------------------- /bezier-console.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | ################################################################################ 5 | # Besier-console is a "console" comands based extension to create besier paths 6 | # with exact dimensions. 7 | # 8 | # Syntax: 9 | # command[; command] 10 | # Command: 11 | # type [parameters]; 12 | # Types: 13 | # a (arc) 14 | # l (line) 15 | # h (hline) 16 | # v (vline) 17 | # m (move) 18 | # Parameters : 19 | # l - length 20 | # a - angle 21 | # x,y - coordinates 22 | # all values are relative if the case is lover to use absolute coordinates use upper case. 23 | ################################################################################ 24 | 25 | from csp import CSP, CSPsubpath 26 | from points import P 27 | from math import * 28 | import inkex 29 | import re 30 | import sys 31 | import traceback 32 | from biarc import Arc, Line 33 | 34 | def warn(s) : 35 | if bezier_console.options.silent : return 36 | s = str(s) 37 | inkex.errormsg(s+"\n") 38 | 39 | def error(s) : 40 | if bezier_console.options.silent : return 41 | s = str(s) 42 | inkex.errormsg(s+"\n") 43 | sys.exit() 44 | 45 | class BezierConsole(inkex.Effect): 46 | def __init__(self): 47 | inkex.Effect.__init__(self) 48 | self.OptionParser.add_option("", "--string", action="store", type="string", dest="s", default="", help="Draw string") 49 | self.OptionParser.add_option("", "--silent", action="store", type="inkbool", dest="silent", default=True, help="Do not show an errors, usable for live preview") 50 | self.OptionParser.add_option("", "--units", action="store", type="float", dest="units", default="3.543307", help="Units scale") 51 | def get_line_xy(self,x,y,a,l) : 52 | x1,y1 = self.p.x,self.p.y 53 | #warn((x,y,a,l)) 54 | if x==None : 55 | if y != None : 56 | if a!=None : 57 | a = tan(a) 58 | if abs(a)>16331778728300000 : 59 | return P(x1,y) 60 | if a == 0 : 61 | error("Bad param a=0 for y defined line. Command: %s"%self.command) 62 | return x1+(y-y1)/a,y 63 | elif l!=None : 64 | try : 65 | x = sqrt(l**2 - (y-y1)**2) 66 | except : 67 | error("Bad params, l to small. Command: %s"%self.command) 68 | return P(x,y) 69 | else : 70 | return P(x1,y) 71 | 72 | else : 73 | if a!=None and l!=None : 74 | return self.p+P(cos(a),sin(a))*l 75 | else : 76 | if y!=None : 77 | return P(x,y) 78 | else : 79 | if a!=None : 80 | a = tan(a) 81 | if abs(a)>16331778728300000 : 82 | error("Bad param a=pi/2 for x defined line. Command: %s"%self.command) 83 | else: 84 | return x, a*(x-x1) + y1 85 | 86 | elif l!=None : 87 | try : 88 | y = sqrt(l**2 - (x-x1)**2) 89 | except : 90 | error("Bad params, l to small. Command: %s"%self.command) 91 | else : 92 | return P(x,y1) 93 | 94 | error("""Bad params for the line. Command: %s\n 95 | x = %s, 96 | y = %s, 97 | a = %s, 98 | l = %s 99 | """%(self.command,x,y,a,l)) 100 | 101 | def draw_line(self,x,y,a,l) : 102 | p1 = self.get_line_xy(x,y,a,l) 103 | self.path.join( CSP([[[self.p,self.p,self.p],[p1,p1,p1]]]) ) 104 | 105 | 106 | def move_to(self,x,y,a,l) : 107 | p1 = self.get_line_xy(x,y,a,l) 108 | self.path.items.append(CSPSubpath([[p1,p1,p1]])) 109 | 110 | def arc_on_two_points_and_slope(self,st,end,slope) : 111 | # find the center 112 | m = (end - st)/2 113 | n = slope.ccw() 114 | # get the intersection of lines throught st and m normal to slope and st-end line 115 | l1 = Line(st,st+n) 116 | l2 = Line(st+m,st+m+m.ccw()) 117 | p = l1.intersect(l2,True) 118 | if len(p)!=1 : 119 | warn((p,l1,l2,slope)) 120 | error("Bad parameters for arc on two points. Command: %s"%self.command) 121 | c = p[0] 122 | a = (st-c).cross(slope) 123 | return Arc(st,end,c,a) 124 | 125 | def get_arg_comb(self,s,args): 126 | s = list(s) 127 | args = {"x":x,"y":y,"a":a,"r":r,"i":i,"j":j,"l":l} 128 | for i in args: 129 | if (args[i] == None and i in s or 130 | args[i] != None and i not in s) : 131 | return False 132 | return True 133 | 134 | def get_arc_param(self,x,y,a,r,i,j,l) : 135 | st = self.p 136 | c = None 137 | # asume not enought params use slope. 138 | if x !=None or y!=None: 139 | # using two points and slope. 140 | end = P(x if x!=None else self.p.x, y if y!=None else self.p.y) 141 | return self.arc_on_two_points_and_slope(self.p,end,self.slope) 142 | 143 | if a != None : 144 | if l !=None : 145 | r = l/a/2 146 | if r != None : 147 | c = self.p+self.slope.ccw()*r 148 | if i != None or j != None : 149 | c = P(i if i!=None else self.p.x, j if j!=None else self.p.y) 150 | if c != None : 151 | end = (self.p - c).rotate(a) + c 152 | return self.arc_on_two_points_and_slope(self.p,end,self.slope) 153 | 154 | if l != None : 155 | if i != None or j != None : 156 | c = P(i if i!=None else self.p.x, j if j!=None else self.p.y) 157 | r = (self.p - c).mag() 158 | if r != None : 159 | a = l/r/2 160 | return self.get_arc_param(None, None, a, r, None, None, None) 161 | 162 | error("To few parametersfor arc. Command: %s"%self.command) 163 | 164 | 165 | def draw_arc(self,x,y,a,r,i,j,l) : 166 | st = self.p 167 | arc = self.get_arc_param(x,y,a,r,i,j,l) 168 | #warn(arc) 169 | self.path.join(arc.to_csp()) 170 | 171 | def parse_command(self, command) : 172 | if command.strip() == "" : return 173 | self.command = command 174 | r = re.match("\s*([almhvALMHV]?)\s*((\s*[alxyrijdALXYRIJD]\s*\-?[\d\.]+)*)\s*", command) 175 | if not r: 176 | error("Cannot parse command: \"%s\""% command) 177 | 178 | r = re.match("\s*([almhvALMHV])\s*([alxyrijdALXYRIJD].*)", command) 179 | if r : 180 | warn(r.groups()) 181 | t, command = r.groups() 182 | else : 183 | t = self.last_command 184 | 185 | # parse the parameters 186 | x,y,a,l,r,i,j = None, None, None, None, None, None, None 187 | try: 188 | self.slope = self.path.slope(-1,-1,1) 189 | except: 190 | self.slope = P(1.,0.) 191 | for p in re.findall("([alxyrijALXYRIJ])\s*(\-?\d*\.?\d*)", command) : 192 | #warn(p) 193 | p = list(p) 194 | if p[0] == "A" : a = -float(p[1])/180*pi 195 | elif p[0] == "a" : a = self.slope.angle() -float(p[1])/180*pi 196 | else : p[1] = float(p[1])*self.options.units 197 | if p[0] == "x" : x = self.p.x + p[1] 198 | elif p[0] == "X" : x = p[1] 199 | elif p[0] == "y" : y = self.p.y - p[1] 200 | elif p[0] == "Y" : y = - p[1] 201 | elif p[0] == "i" : i = self.p.x + p[1] 202 | elif p[0] == "I" : I = p[1] 203 | elif p[0] == "j" : j = self.p.y - p[1] 204 | elif p[0] == "J" : J = -p[1] 205 | elif p[0] in ("r","R") : r = p[1] 206 | elif p[0] in ("d","D") : r = p[1]/2 207 | elif p[0] in ("l","L") : l = p[1] 208 | 209 | # exec command 210 | if t in ("l","L") : self.draw_line(x,y,a,l) 211 | if t in ("a","A") : self.draw_arc(x,y,a,r,i,j,l) 212 | if t in ("m","M") : self.move_to(x,y,a,l) 213 | self.last_command = t 214 | 215 | def effect(self) : 216 | if self.options.silent : 217 | try : 218 | self.run() 219 | except : 220 | pass 221 | else : 222 | self.run() 223 | 224 | def run(self) : 225 | s = self.options.s.split(";") 226 | node = None 227 | 228 | if len(self.selected) > 0 : 229 | node = self.selected.itervalues().next() 230 | if node.tag == '{http://www.w3.org/2000/svg}path' : 231 | self.path = CSP(node) 232 | else : 233 | error("Select a path or select nothing to create new path!") 234 | 235 | try : 236 | self.p = self.path.items[-1].points[-1][1] 237 | except : 238 | self.path = CSP( [[[P(self.view_center),P(self.view_center),P(self.view_center)]]], clean=False) 239 | self.p = self.path.items[-1].points[-1][1] 240 | 241 | self.last_command = None 242 | for a in s : 243 | self.parse_command(a) 244 | try : 245 | self.p = self.path.items[-1].points[-1][1] 246 | except : 247 | pass 248 | 249 | if node == None : self.path.draw(group = self.current_layer) 250 | else : node.set("d",self.path.to_string()) 251 | 252 | 253 | bezier_console = BezierConsole() 254 | bezier_console.affect() 255 | 256 | -------------------------------------------------------------------------------- /close_curves.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | <_name>Close curves 4 | ru.cnc-club.filter.close_curves 5 | close_curves.py 6 | inkex.py 7 | 0.01 8 | false 9 | 10 | 11 | Select paths that you want to close, and press ok. 12 | 13 | 14 | 15 | 16 | 17 | 18 | path 19 | 20 | 23 | 24 | -------------------------------------------------------------------------------- /close_curves.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Copyright (C) 2009 Nick Drobchenko, nick@cnc-club.ru 4 | based on gcode.py (C) 2007 hugomatic... 5 | based on addnodes.py (C) 2005,2007 Aaron Spike, aaron@ekips.org 6 | based on dots.py (C) 2005 Aaron Spike, aaron@ekips.org 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program; if not, write to the Free Software 20 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 | """ 22 | 23 | # 24 | # This extension close paths by adding 'z' before each 'm' if it is not 25 | # the first 'm' and it is not prepended by 'z' already. 26 | # 27 | 28 | import inkex, re, cubicsuperpath 29 | 30 | class CloseCurves(inkex.Effect): 31 | def __init__(self): 32 | inkex.Effect.__init__(self) 33 | self.OptionParser.add_option("-s", "--subpaths", action="store", type="inkbool", dest="subpaths", default=True) 34 | self.OptionParser.add_option("-f", "--tolerance", action="store", type="float", dest="tolerance", default=".01") 35 | 36 | 37 | 38 | def effect(self): 39 | def point_d2(p1,p2): 40 | return (p1[0]-p2[0])**2+(p1[1]-p2[1])**2 41 | 42 | def close_csp(csp, tolerance): 43 | csp = [i for i in csp if i!=[]] 44 | done_smth = True 45 | while done_smth: 46 | done_smth = False 47 | i = 0 48 | while i(.*)",s)) 57 | if dev == "" : 58 | tags['header'] = re.sub("\-dev\.py", ".py",tags['header']) 59 | tags['footer'] = re.sub("\-dev\.py", ".py",tags['footer']) 60 | 61 | print (dev) 62 | for arg_ in args: 63 | print "Computing set: %s..." % arg_ 64 | r = re.match("((.*):)?(.*)",arg_) 65 | if r!=None: 66 | arg = r.group(3).split() 67 | 68 | res = '\n'+tags['header'] 69 | name = ( r.group(2) if r.group(2)!=None else r.group(3) ) + dev 70 | id = re.sub("\s|[\.,!@#$%^&*]", "_", r.group(3).lower()) + dev 71 | res = re.sub("(?ims)(.*)","%s"%name,res) 72 | res = re.sub("(?ims)(.*)","ru.cnc-club.filter.gcodetools%s"%id,res) 73 | 74 | for i in arg: 75 | if i not in tags and not re.match("no_",i): 76 | print "Can not find tag %s. Ignoring this set %s!\n" % (i,arg_) 77 | break 78 | if not re.match("no_",i): res += tags[i] 79 | if 'options' not in arg and 'no_options' not in arg: res += tags['options'] 80 | if 'preferences' not in arg and 'no_preferences' not in arg : res += tags['preferences'] 81 | if 'help' not in arg and 'no_help' not in arg : res += tags['help'] 82 | 83 | if i not in tags and not re.match("no_",i) : continue 84 | submenu =""" 85 | 86 | """%dev 87 | res += re.sub("(?ims)(.*)",submenu,tags['footer']) 88 | 89 | f = open("gcodetools_%s.inx"% ( re.sub("\s|[\.,!@#$%^&*]", "_", name.lower())) ,"w") 90 | f.write(res) 91 | f.close() 92 | print "Done\n" 93 | 94 | """ 95 | arg = arg_.split() 96 | for i in arg: 97 | if i not in tags : 98 | print "Can not find tag %s. Ignoring this set %s." % (i,arg_) 99 | break 100 | if i not in tags : continue 101 | print i 102 | f=open("./gcodetools_"+"_".join(["%s" % k for k in arg])+".inx" ,"w") 103 | inx = copy.deepcopy(root) 104 | tags = {} 105 | recursive(inx) 106 | for i in tags: 107 | if i not in ["notebook","help","options","id"] + arg: 108 | pass 109 | """ 110 | if __name__ == "__main__": 111 | main() 112 | 113 | -------------------------------------------------------------------------------- /csp.py: -------------------------------------------------------------------------------- 1 | from points import P 2 | from math import * 3 | import inkex 4 | import cubicsuperpath 5 | import simplestyle 6 | import cmath 7 | import bezmisc 8 | ################################################################################ 9 | ### CSP - cubic super path class 10 | ################################################################################ 11 | # CSP = [ [subpath0]...[subpathn] ] - items 12 | # subpath = [ [p01,p02,p03]...[pm1,pm2,pm3] ] - points 13 | # [p01,p02,p03] - control point - cp 14 | # p0k = P(x,y) - point 15 | 16 | def cubic_solver_real(a,b,c,d): 17 | # returns only real roots of a cubic equation. 18 | roots = cubic_solver(a,b,c,d) 19 | res = [] 20 | for root in roots : 21 | if type(root) is complex : 22 | if -1e-10=0 : 39 | t = m+sqrt(n) 40 | m1 = pow(t/2,1./3) if t>=0 else -pow(-t/2,1./3) 41 | t = m-sqrt(n) 42 | n1 = pow(t/2,1./3) if t>=0 else -pow(-t/2,1./3) 43 | else : 44 | m1 = complex((m+cmath.sqrt(n))/2)**(1./3) 45 | n1 = complex((m-cmath.sqrt(n))/2)**(1./3) 46 | x1 = -1./3 * (a + m1 + n1) 47 | x2 = -1./3 * (a + w1*m1 + w2*n1) 48 | x3 = -1./3 * (a + w2*m1 + w1*n1) 49 | return [x1,x2,x3] 50 | elif b!=0: 51 | det = c**2-4*b*d 52 | if det>0 : 53 | return [(-c+sqrt(det))/(2*b),(-c-sqrt(det))/(2*b)] 54 | elif d == 0 : 55 | return [-c/(b*b)] 56 | else : 57 | return [(-c+cmath.sqrt(det))/(2*b),(-c-cmath.sqrt(det))/(2*b)] 58 | elif c!=0 : 59 | return [-d/c] 60 | else : return [] 61 | 62 | 63 | class CSP() : 64 | def __init__(self, csp=[], clean = True ) : 65 | 66 | self.items = [] 67 | if type(csp) == type([]) : 68 | self.from_list(csp) 69 | else : 70 | self.from_el(csp) 71 | if clean : 72 | self.clean() 73 | 74 | def join(self, others=None, tolerance=None) : 75 | if type( others == CSP) : 76 | others = [others] 77 | if others != None : 78 | for csp in others : 79 | self.items += csp.copy().items 80 | joined_smf = True 81 | while joined_smf : 82 | joined_smf = False 83 | i=0 84 | while i=0 : return self.points[i], self.points[i+1] 446 | else : return self.points[i-1], self.points[i] 447 | 448 | def slope(self,j,t) : 449 | cp1, cp2 = self.get_segment(j) 450 | if self.zerro_segment(j) : return P(1.,0.) 451 | ax,ay,bx,by,cx,cy,dx,dy=self.parameterize_segment(j) 452 | slope = P(3*ax*t*t+2*bx*t+cx, 3*ay*t*t+2*by*t+cy) 453 | if slope.l2() > 1e-9 : #LT changed this from 1e-20, which caused problems, same further 454 | return slope.unit() 455 | # appears than slope len = 0 (can be at start/end point if control point equals endpoint) 456 | if t == 0 : # starting point 457 | slope = cp2[0]-cp1[1] 458 | if slope.l2() > 1e-9 : 459 | return slope.unit() 460 | if t == 1 : 461 | slope = cp2[1]-cp1[2] 462 | if slope.l2() > 1e-9 : 463 | return slope.unit() 464 | # probably segment straight 465 | slope = cp2[1]-cp1[1] 466 | if slope.l2() > 1e-9 : 467 | return slope.unit() 468 | # probably something went wrong 469 | return P(1.,0.) 470 | 471 | def normal(self,j,t) : 472 | return self.slope(j,t).ccw() 473 | 474 | def bounds(self,i=None): 475 | if i!=None : 476 | return self.boundsi(i) 477 | else : 478 | b = [1e100, 1e100, -1e100, -1e100] 479 | for i in range(len(self.points)-1) : 480 | b1 = self.boundsi(i) 481 | b = [min(b[0],b1[0]), min(b[1],b1[1]), max(b[2],b1[2]), max(b[3],b1[3])] 482 | if b == [1e100, 1e100, -1e100, -1e100] : return None 483 | return b 484 | 485 | def boundsi(self,i): 486 | minx, miny, maxx, maxy = 1e100, 1e100, -1e100, -1e100 487 | ax,ay,bx,by,cx,cy,x0,y0 = self.parameterize_segment(i) 488 | roots = cubic_solver(0, 3*ax, 2*bx, cx) + [0,1] 489 | for root in roots : 490 | if type(root) is complex and abs(root.imag)<1e-10: 491 | root = root.real 492 | if type(root) is not complex and 0<=root<=1: 493 | y = ay*(root**3)+by*(root**2)+cy*root+y0 494 | x = ax*(root**3)+bx*(root**2)+cx*root+x0 495 | maxx = max(x,maxx) 496 | minx = min(x,minx) 497 | 498 | roots = cubic_solver(0, 3*ay, 2*by, cy) + [0,1] 499 | for root in roots : 500 | if type(root) is complex and root.imag==0: 501 | root = root.real 502 | if type(root) is not complex and 0<=root<=1: 503 | y = ay*(root**3)+by*(root**2)+cy*root+y0 504 | x = ax*(root**3)+bx*(root**2)+cx*root+x0 505 | maxy = max(y,maxy) 506 | miny = min(y,miny) 507 | return minx,miny,maxx,maxy 508 | 509 | 510 | 511 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | gcodetools (1.7) unstable; urgency=low 2 | 3 | * Initial release. 4 | 5 | -- Pavel Shramov Mon, 20 Aug 2012 16:20:58 +0400 6 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: gcodetools 2 | Priority: extra 3 | Maintainer: Pavel Shramov 4 | Build-Depends: debhelper (>= 5.0.0) 5 | Standards-Version: 3.8.0 6 | Section: devel 7 | Homepage: http://www.cnc-club.ru/forum/viewtopic.php?t=34 8 | 9 | Package: gcodetools 10 | Section: devel 11 | Architecture: all 12 | Depends: inkscape 13 | Description: Inkscape extension to create G-code from image 14 | -------------------------------------------------------------------------------- /debian/install: -------------------------------------------------------------------------------- 1 | stable/gcodetools.py /usr/share/inkscape/extensions/ 2 | stable/*.inx /usr/share/inkscape/extensions/ 3 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | %: 3 | dh $@ 4 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | DBLATEX_OPTS := -bxetex -P doc.publisher.show=0 -P latex.output.revhistory=0 2 | all: gcodetools-ru.pdf gcodetools-ru.html gcodetools-ru.odt 3 | 4 | %.pdf: %.asciidoc 5 | a2x -f pdf -v --dblatex-opts="$(DBLATEX_OPTS)" $< 6 | 7 | %.html: %.asciidoc 8 | a2x -f xhtml -v --dblatex-opts="$(DBLATEX_OPTS)" $< 9 | 10 | %.odt: %.asciidoc 11 | a2x -f odt -v --dblatex-opts="$(DBLATEX_OPTS)" $< 12 | -------------------------------------------------------------------------------- /doc/gcodetools-ru.asciidoc: -------------------------------------------------------------------------------- 1 | Gcodetools руководство пользователя 2 | =================================== 3 | :Author: Drobchenko Nickolay (Nick at forum http://www.cnc-club.ru), _taras_ (_taras_ at forum http://www.cnc-club.ru) 4 | :Date: 11.07.2011 5 | :Revision: 0001 6 | 7 | == Благодарности 8 | 9 | === Разработчики 10 | 11 | 12 | * Николай Дробченко (Nick http://www.cnc-club.ru ) 13 | * Владимир Каляев (Dormouse http://www.cnc-club.ru ) 14 | * Henry Nicolas (Alfcnc http://www.cnc-club.ru ) 15 | * Chris Lusby Taylor (ChrisInNewbury http://www.cnc-club.ru ) 16 | 17 | === Переводчики 18 | 19 | 20 | * John Brooker (greybeard из http://www.cnczone.com ) 21 | 22 | 23 | [TIP] 24 | =============================== 25 | .Примечание 26 | +gcodetools+ - выделяет названия программных продуктов. 27 | *Жирное начертание* - клавиатурные команды 28 | _Курсив_ - название операции (функции) в меню 29 | =============================== 30 | 31 | == Описание программы Gcodetools 32 | 33 | +Gcodetools+ это расширение для графического векторного редактора +Inkscape+ для создания G-кода на основе изображения. 34 | +Gcodetools+ умеет генерировать G-код для различных видов обработки - фрезерование 2.5D, токарная обработка, раскрой материала и др. 35 | 36 | +Gcodetools+ и +Inkscape+ распространяются под лицензией GNU GPL, т.е. бесплатно, в т.ч. для коммерческого использования. Обе программы кросплатформенные, есть дистрибутивы под Windows, Linux и MacOS. 37 | 38 | == Установка Gcodetools 39 | 40 | 41 | === Windows 42 | Распакуйте архив и скопируйте все файлы в каталог _Program Files\Inkscape\share\extensions\_ 43 | 44 | === Linux 45 | Распакуйте архив и скопируйте все файлы в каталог _/home/<имя пользователя>/.config/inkscape/extensions/_ или _/usr/share/inkscape/extensions/_ и перезапустите inkscape 46 | 47 | Версию, находящуюся в разработке, можно загрузить с http://www.launchpad.net/gcodetools при помощи bazaar, для этого выполните в консоли +bzr branch lp:gcodetools+ или через веб-интерфейс http://bazaar.launchpad.net/~gcodetools.team/gcodetools/develope/files. 48 | 49 | == Возможности Gcodetools 50 | 51 | * Экспорт в Gcode 52 | ** Экспорт кривых в Gcode 53 | ** Аппроксимация с использованием круговой интерполяции (G02 и G03) 54 | ** Автоматическое разбиение кривых для достижения заданной степени точности 55 | ** Обработка со сменой инструментов 56 | ** Экспорт Gкода в параметрической или обычной формах 57 | ** Добавление собственных заголовков и окончаний 58 | ** Выбор единиц измерения 59 | ** Многопроходная обработка 60 | ** Автоматическое добавление цифрового суфикса к назваию сохраняемого файла 61 | * Обработка на токарном станке 62 | ** Создание траекторий для обработки детали на токарном станке 63 | ** Расчет чистового прохода 64 | ** Задание заглубления при чистовом проходе 65 | *g Задание количества чистовых проходов 66 | ** Два различных метода вычисления чистовых проходов 67 | ** Замена стандартных осей 68 | * Обработка площади контуров 69 | ** Создание траекторий для обработки площади контуров 70 | ** Возможность коррекции созданных траекторий 71 | * Гравировка фигурными фрезами 72 | ** Создание траекторий для обработки контуров фигурной фрезой 73 | ** Задание произвольной формы фрезы 74 | * Библиотека инструментов 75 | ** Здание различных параметров инструмента и обработки (диаметр инструмента, скорость обработки, заглубление за проход, скорость заглубления, задание произвольного кода перед/после заглубления, форма инструмента, произвольный код смены инструмента) 76 | ** Возможность копирования инструментов 77 | ** Возможность обработки со сменой инструмента 78 | * Система ориентирования 79 | ** Задание масштабирования по всем осям 80 | ** Задание поворотов в плоскости ХY 81 | ** Задание смещения по всем осям 82 | ** Ориентация по произвольным точкам 83 | * Постпроцессор 84 | ** Создание произвольной программы постпроцессора или выбор из стандартного набора 85 | ** Масштабирование и смещение Gcode 86 | ** Произвольная замена команд (в том числе одновременная замена) 87 | ** Параметризация Gcode 88 | ** Округление длинны дробной части чисел в Gкоде 89 | * Предварительная проверка рисунка 90 | ** Выделение маленьких контуров (возможных артефактов area) 91 | ** Проверка принадлежности инструментов 92 | ** Проверка порядка обработки 93 | * Плоттерная резка 94 | ** Экспорт в Gкод для плоттера с тангенциальным ножом. Четвертая ось A - угол наклона ножа. 95 | * Общие 96 | ** Проверка наличия обновлений. 97 | 98 | == Основные понятия 99 | 100 | === Контур 101 | 102 | +Gcodetools+ работает с кривыми безье - основным элеметном рисукнов в +Inkscape+. Все векторные объекты (фигуры, тексты, клоны) могут быть приведены к виду кривой Безье без потери точности. Для перевода объекта в кривую Безье (далее контур или path) нужно выполнить Контур-Оконтурить объект или нажать клавиши *Ctrl+Shift+C*. 103 | 104 | === Объект 105 | 106 | Объекты не являющиеся контурами, т.е. те объекты, которые нужно преобразовывать в контуры: 107 | 108 | * Текст 109 | * Фигуры: Окружности, эллипсы, прямоугольники, звезды, многоугольники 110 | * Динамические втяжки 111 | 112 | Чтобы определить, является ли объект контуром, нужно его выделить при этом в строке состояния должно быть написано Контур или несколько Контуров. 113 | 114 | === Размер объекта 115 | 116 | По-умолчанию, +Inkscape+ рассчитывает размер объектов исходя из его видимых размеров. Т.е. в линейные размеры объектов, помимо размеров контура, входят толщина обводки, размеры эффектов. Если вы нарисуете круг размером 10х10мм с обводкой 1мм, то +Inkscape+ будет отображать его размер как 11х11мм, но при экспорте в G-код круг будет диаметром 10мм. Это связанно с тем, что основное предназначение +Inkscape+ - векторная графика. 117 | 118 | Чтобы +Inkscape+ отображал реальные размеры контуров без учета обводк и эффектов нужно зайти в настройки +Inkscape+ нажатием клавиш *Ctrl+Shift+P*, в самом верхнем пункте (_Инструменты_) изменить _Площадка объекта_ на _Геометрическая площадка_. 119 | 120 | Единицы измерения - по умолчанию +Inkscape+ используется - px (пикселы). Соотношения между пискселами и другими единицами измерения 121 | 122 | * 1 дюйм = 90 px = 25.4 мм 123 | * 1 мм = 3.543 px ~ 0.03937 дюйма 124 | * 1 px = 0.2822 мм ~ 0.01111 дюйма 125 | 126 | 127 | Практически все внутренние вычисления проводятся в px. Единицы измерения можно изменить в настройках документа нажатием клавиш *Ctrl+Shift+D*. Можно настроить единицы отображения, единицы линеек и единицы сетки. 128 | 129 | 130 | == Интерфейс Gcodetools 131 | 132 | === Вкладки 133 | 134 | Т.к. +Gcodetools+ является стандартным расширением +Inkscape+, то возможности по созданию интерфейсов сильно ограничены. Выбор выполняемой функции определяется открытой вкладкой во время нажатия кнопки _Применить_. Например, если Вы хотите выполнить экспорт в G-код, то перед нажатием на _Применить_ нужно открыть вкладку _Path to Gcode_. Если появляется следующая ошибка: 135 | 136 | [WARNING] 137 | =============================== 138 | Select one of the action tabs - Path to Gcode, Area, Engraving, DXF points, Orientation, Offset, Lathe or Tools library. 139 | 140 | Current active tab id is "preferences" 141 | =============================== 142 | 143 | то это значит, что вы не открыли нужную вкладку перед нажатием Применить. 144 | 145 | Раньше все вкладки +Gcodetools+ были размещены на одном окне, но вкладок становилось все больше и больше и они перестали влезать на экран, поэтому пришлось разместить их на разных окнах. При этом одни и те же вкладки могут встречаться на нескольких окнах по мере надобности. 146 | 147 | === Live preview 148 | 149 | _Live preview_ - никогда не включайте Live preview. Чтобы окно +Gcodetools+ не блокировало +Inkscape+ и не закрывалось при нажатии Применить, +Gcodetools+ сделан в виде live effect. Это обусловливает появление _Live Preview_. Но с live preview могут возникать проблемы, поэтому, лучше не трогайте _live preview_! 150 | 151 | === Дополнительные настройки 152 | 153 | Некоторые настройки, такие как параметры инструментов и точки ориентации, вынесены с формы +Gcodetools+ в сам рисунок. В этом случае их можно редактировать при помощи инструмента _Текст_ (*F8*). Например, чтобы изменить подачу включите инструмент Текст и измените число напротив поля Feed в описании инструмента. Старайтесь редактировать такие параметры только при помощи инструмента _Текст_. Такие настройки, например определение инструментов можно копировать обычными методами +Inkscape+. 154 | 155 | [IMPORTANT] 156 | =============================== 157 | Ни в коем случае не разгруппировывайте группы настроек, это удалит скрытые параметры и +Gcodetools+ не сможет определить эти настройки! 158 | =============================== 159 | 160 | == Вкладка Path to Gcode 161 | 162 | image:img/path-to-gcode-tab.png[] 163 | 164 | Экспорт в G-код (_Path to Gcode_) - самая первая функция, с которой началась разработка +Gcodetools+. Она предназначена для экспорта контуров в Gcode для фрезерной обработки и раскроя материала. Режущий инструмент перемещается в плоскости XY повторяя выбранные контуры. 165 | 166 | _Path to Gcode_ использует Точки ориентации и характеристики Инструментов для определения параметров обработки (подача, скорость заглубления, заглубление за проход, дополнительный G-код перед/после контура (см. далее)). Если Точки ориентации или определение инструмента не были заданы, то +Gcodetools+ добавит стандартный инструмент и стандартные точки ориентации, о чем будет дополнительное сообщение. 167 | 168 | _Path to Gcode_ это одна из основных функций и она будет использоваться на финальной стадии создания G-code практически для любого вида обработки. 169 | 170 | По-умолчанию, _Path to Gcode_ экспортирует выделенные контуры в G-code, если ничего не выделено то _Path to Gcode_ попытается экспортировать все контуры на рисунке (это поведение можно изменить, отключив на вкладке _Options_ опцию _Select all paths if nothing selected_). 171 | 172 | === Параметры Path to Gcode 173 | 174 | _Biarc interpolation tolerance_ - допуск по точности аппроксимации контура биарками. Изначально каждый сегмент контура аппроксимируется одной биаркой, затем вычисляется максимальное расстояние от биарки до сегмента контура. Если оно превышает заданный допуск в единицах измерения (заданных точками ориентации) то сегмент разбивается на две части, и процедура повторяется для каждой части отдельно. 175 | 176 | _Maximum splitting depth_ - максимальная глубина разбиения, максимально число итераций для аппроксимации сегмента контура биарками. Необходимо отметить, что конечное число частей. на которые будет разбит контур может быть гораздо больше, чем максимальная глубина разбиения. Оно ограниченно 2n, где n это максимальная глубина разбиения. Если необходимая точность достигнута на какой-то итерации, то сегмент контура не будет разбиваться далее. Если вы все-таки хотите, чтобы сегмент был разбит на максимальное количество частей, то просто установите допуск аппроксимации равным 0. 177 | 178 | _Cutting order_ - это порядок в котором будут обрабатываться контуры. Контуры обрабатываются в порядке следования Слоев на рисунке, сначала обрабатывается самый верхний слой, за тем слои которые находятся ниже. Внутри слоя очередность обработки может быть следующей: 179 | 180 | * _Path by path_ - обработка ведется контур за контуром. Т.е. сначала обрабатывается перый контур целиком, затем второй и т.д. Все контуры обрабатываются на максимальную глубину перед переходом к следующему контуру. 181 | * _Subpath by Subpath_ - обработка субкотура за субконтуром. Тоже самое, что и _Path by path_, но на уровне субконтуров. Контуры могут состоять из нескольких субконтуров. Например, контур с отверстием это два субконтура - внешний и внутренний. Даже если в субконтуре нет отверстий и он кажется непрерывным он все рано может состоять из нескольких субконтуров. Для того, чтобы разделить субконтуры нужно нажать _Контур_ - _Разбить_ (*Ctrl+Shift+K*). Для того, чтобы объединить контуры в один контур - _Контур_ - _Объединить_ или *Ctrl+K*. 182 | * _Pass by pass_ - проход за проходом. Сначала будут обработаны все контуры на заглубление первого прохода, потом на заглубление второго прохода и т. д. 183 | 184 | _Depth function_ - при помощи этой функции можно дополнительно определить глубину обработки. При задании _Depth function_ можно пользоваться математическими и другими фцнкциями python (например math.sin(), math.sqrt()). Также могут быть определены константы: 185 | 186 | * d - глубина обработки заданная при помощи точек ориентации 187 | * s - координата поверхности заданная при помощи точек ориентации 188 | * c - коэффициент цвета. Число от 0 до 1 определяющее яркость цвета контура (0.0 - белый, 1.0 - черный). 189 | 190 | _Sort paths to reduse rapid distance_ - сортировать контуры для того, чтобы уменьшить холостой пробег. 191 | 192 | 193 | == Вкладка Параметры 194 | 195 | image:img/parameters-tab.png[] 196 | 197 | _Select all paths if nothing selected -_ если ни один контур не выбран и включена эта опция, то +Gcodetools+ будет пытаться обработать все контуры на рисунке. 198 | 199 | _Minimun arc radius_ - EMC2 может выдать ошибку если радиус дуги G02 или G03 будет меньше 0.02 мм (также возможны ошибки в других контроллерах на маленьких дугах). Поэтому все дуги с радиусом меньше _Minimun arc radius_ будут заменяться прямыми отрезками G01. 200 | 201 | _Get additional comments from objects properties_ - +gcodetools+ может извлекать дополнительные параметры объектов из их свойств. Эти параметры можно отредактировать нажав правой кнопкой мышки на объекте и выбрав _Свойства_. 202 | 203 | _Comment Gcode_ - В этом поле можно задавать дополнительные коментарии которые будут отображаться перед началом обработки контура. 204 | 205 | == Вкладка Preferences 206 | 207 | image:img/preferences-tab.png[] 208 | 209 | _File_ - название файла для сохранения готового G-кода. 210 | 211 | _Add numeric suffix to filename_ - если включена, к имени файла будет автоматически добавляться числовой суффикс для предотвращения перезаписи старых экспортов, например output.ngc -> output_0001.ngc. 212 | 213 | _Directory_ - папка в которую будет сохраняться G-код. Удостоверьтесь, что у вас есть права на запись в этой папку, в противном случае +Gcodetools+ выдаст ошибку. Если в этой директории содержаться файлы header или footer, то они будут использованы в качестве заголовка и окончания G-кода вместо стандартных заголовков. 214 | 215 | _Z safe distance for G00 move over blanc_ - безопасная дистанция над поверхностью материала на которой будут выполняться перемещения от контура к контуру. Выставляйте это расстояние больше всех элементов крепления заготовки, для того, чтобы быть уверенным в том, что вы не врежетесь в них инструментом. 216 | 217 | _Units_ - единицы измерения мм или дюймы определяет постановку кода G20 или G21 в готовый G-код. 218 | 219 | _Post processor_ - заранее заданные пост процессоры для дополнительной подготовки Gcode. 220 | 221 | _Additional post processor_ - вы можете задать произвольный пост-процессор. Подробнее о возможностях и синтаксисе пост-процессоров смотрите по ссылке: http://cnc-club.ru/forum/viewtopic.php?f=33&t=78 (пока только на английском). 222 | 223 | _Generate log file_ - генерировать файл лога. 224 | 225 | _Full path to log file_ - полный путь к лог файлу. 226 | 227 | 228 | 229 | == Вкладка Area 230 | 231 | image:img/area-tab.png[] 232 | 233 | При помощи вкладки _Area_ можно создавать контуры для обработки площадей. _Area_ использует внутренние функции +Inkscape+ для создания контуров, а именно _Dynamic offset_ (динамическая втяжка). После применения _Area_ в рисунок будет добавлено необходимое количество динамических втяжек. Функция _Area_ дает не самые лучшие результаты по качеству выборки материала. Если обработка ведется без нахлеста траекторий, то в острых углах будут оставаться необработанные участки. 234 | 235 | _Maximum area cutting curves_ - этот параметр нужен для того, чтобы избежать слишком большого количества динамических втяжек. 236 | 237 | _Area width_ - это онсновной параметр, от которого зависит количество добавленных контуров. Количество контуров равно Area width/Tool D (ширина контура/диаметр инструмента). Ширина контура это не ширна в общем смысле, это толщина в самом толстом месте. 238 | 239 | _Area tool overlap_ - параметр задающий нахлест траекторий. Это может быть необходимо для получения более чистого результата. 0.0 - означает без нахлеста, 0.9 - практически полный нахлест. 240 | 241 | 242 | == Вкладка Fill area 243 | 244 | image:img/fill-area-tab.png[] 245 | 246 | _Fill_ _area_ - функция служит для заполнения площади контура прямыми линиями. Заполнять можно по двум алгоритмам - зигзаг и спираль. Эта функция самая стабильная из всех функций по обработке площади, т.к. не требует сложных вычислений. 247 | 248 | _Area fill angle_ - угол наклона прямых. 0 - вертикальные линии. 249 | 250 | _Area fill shift_ - сдвиг "фазы" заполнения линиями (от 0 до 1). 251 | 252 | _Area fill overlap_ - нахлест траекторий. Нужен для получения более качественной обработки и более простого съема материала. (0 - без нахлеста, 0.9 - практически полный нахлест) 253 | 254 | _Filling method_ - выбор метода заполнения - зигзаг или спираль. 255 | 256 | 257 | 258 | == Вкладка Area artifacts 259 | 260 | image:img/aria-artifacts-tab.png[] 261 | 262 | _Area artefacts_ Т.к. функция отступа кривой безье очень не простая, иногда она дает артефакты. А при увеличении количества отступов вероятность появления ошибок растет. Для поиска этих ошибок разработана функция _Area artefacts_. Она ищет контуры маленького размера и в зависимости от выбранного действия выделяет их цветом или стрелкой или удаляет. 263 | 264 | _Aretefact diametr_ - максимальный размер артефакта, все контуры меньше заданного размера будут выделены\удалены. 265 | 266 | _Action_ - действие производимое с артефактами. Выделить цветом, выделить стрелкой, удалить. 267 | 268 | 269 | 270 | 271 | == Вкладка Orientation points 272 | 273 | image:img/orientation-points-tab.png[] 274 | 275 | _Orientation_ _points_ (точки ориентации) нужны для позиционирования материала детали на станке/рисунке. При помощи точек ориентации можно задать масштаб, перемещение, поворот, растяжение по осям. 276 | 277 | Если необходима только простая ориентация без не пропорциональных растяжений по осям и отражений, используйте ориентацию по двум точкам. 278 | 279 | После применения _Orientation_ _points_ на рисунок добавятся две или три точки ориентации. Точка ориентации это стрелка с координатами. Положение точки определяется исходя из положения вершины стрелки. 280 | 281 | При помощи точек ориентирования можно ориентировать деталь по конкретным точкам, для этого выберите любые две или три точки на детали, переместите в них точки ориентации и задайте для них желаемые координаты. 282 | 283 | В самом простом случае, точки ориентации просто добавляются в рисунок и задают начало координат. 284 | 285 | Точки ориентации применяются к текущему слою и все слоям ниже (до следующего слоя имеющего свои точки ориентации). 286 | 287 | IMPORTANT: Внимание! Не разгруппировывайте точки ориентации! Это приведет к их дисфункции! Для того, чтобы переместить только одну точку просто войдите в группу двойным щелчком мыши на группе. Координаты можно редактировать при помощи инструмента _Text_ (*F8*) не разгрупповывая элементы. 288 | 289 | _Orientation type_ - ориентация по двум или трем точкам. 290 | 291 | _Z surface_ - высота (координата Z) поверхности материала (начало обработки) 292 | 293 | _Z depth_ - глубина (координата Z) обработки. 294 | 295 | _Units _- единицы измерения, для удобства стандартные точки ориентации добавляются в точках (0,0), (0,100) и (100,0) для миллиметров и (0,0), (0,5) и (5,0) для дюймов. 296 | 297 | 298 | 299 | == Вкладка Tools library 300 | 301 | image:img/tools-library-tab.png[] 302 | 303 | _Tools library_ (библиотека инструментов). Библиотека инструментов создает шаблон для описания конкретного типа инструментов. 304 | 305 | В описании инструмента можно задавать различные параметры, начиная с простых, таких как диаметр, скорость реза, заглубление за проход, и оканчивая более сложными - G-код до и после контура, которые позволяют задавать, например, коды включения или выключения шпинделя или другого режущего интсрумента. 306 | 307 | 308 | == Проверка обработки 309 | 310 | Для того, чтобы увидеть, что будет реально вырезано, можно воспользоваться +Inkscape+ и не использовать внешние инструменты. Для этого: 311 | 312 | * Выберите все контуры, которые будут экспортироваться или контуры предварительного просмотра 313 | * Назначьте им толщину обводки равную толщине обрабатывающего инструмента 314 | * Выберите скругление на углах контуров и скругление обводки на концах контура, во вкладке _Стиль обводки_ на окне _Заливка_ и _Обводка_ 315 | * Таким образом обводка будет изображать профиль фрезы на всей траектории реза. 316 | 317 | 318 | 319 | == Пошаговое руководство по созданию G-кода обработки площади детали 320 | 321 | Такая обработка может понадобится, когда рисунок или деталь находится над (или под) основным массивом материала. 322 | 323 | . Создаем, или загружаем нужные контуры. 324 | + 325 | image:img/area-tutorial-0001.png[] 326 | 327 | . Разгруппировываем, если в рисунке есть группы (*Ctrl+Shift+G*). 328 | . Объединяем контуры используя булево сложение (*Ctrl+«+»*). 329 | . Создаем прямоугольник, который будет ограничивать область картинки, помещаем его на задний план (*PageDown* или *End*). 330 | . Выделяем все и применяем логическую операцию вычитания (*Ctrl+«-»*). В результате должны получить один контур, изображающий ту часть, которая должна быть обработана. 331 | . Добавляем точки ориентации (не обязательный шаг, точки ориентации для мм добавятся автоматически, если они не были созданы заранее). _Расширения – Gcodetools – Orientation points_ (см. главу "Вкладка Orientation points" данного руководства). Выставляем глубину фрезерования и другие параметры, жмем «Применить», «Закрыть». Полученные точки начала координат будут в левом нижнем углу листа, перетаскиваем их (не разгруппировывая) в необходимую позицию относительно рисунка (к примеру, в левый нижний угол). (Вместо перемещения точек ориентации можно переместить сам рисунок.) 332 | + 333 | image:img/area-tutorial-0002.png[] 334 | 335 | . Добавляем описание инструмента. _Расширения – Gcodetools – Tools library_ (см. главу "Вкладка Tools library" данного руководства), выбираем тип инструмента и жмем «Применить», «Закрыть». В изображение будет добаленно описание инструмента, основные параметры: 336 | * id — порядковый номер и название инструмента 337 | * diametr — диаметр режущей части инструмента 338 | * feed — скорость подачи 339 | * penetration angle - угол заглубления (пока не реализован!) 340 | * penetration feed - скорость заглубления (подача при заглублении фрезы) 341 | * depth step - заглубление на каждый проход обработки 342 | * tool change gcode - Gкод для смены инструмента 343 | + 344 | image:img/area-tutorial-0003.png[] 345 | 346 | . Выделяем контур, и выполняем _Расширения – Gcodetools – Area_ (см. главу "Вкладка Area" данного руководства), выставляем количество кривых и ширину обрабатываемой площади по контуру, жмем «Применить», «Закрыть». Расширение добавляет в рисунок траектории инструмента. 347 | + 348 | image:img/area-tutorial-0004.png[] 349 | 350 | . Разгруппировываем полученный объект (*Ctrl+Shift+G*). Удаляем оригинальный рисунок. 351 | + 352 | image:img/area-tutorial-0005.png[] 353 | 354 | . Преобразовываем все оставшиеся траектории в контуры (*Ctrl+Shift+C*), с помощью инструмента редактирования узлов (*F2*), устраняем артефакты и редактируем ошибочные участки. 355 | + 356 | [TIP] 357 | =============================== 358 | Для поиска и удаления артефактов можно воспользоваться инструментом Area artifacts (см. главу "Вкладка Area artifacts" этого руководства). 359 | =============================== 360 | + 361 | image:img/area-tutorial-0006.png[] 362 | 363 | . После удаления всех нежелательных участков траектории выполняем _Расширения – Gcodetools – Path to Gcode_ (см. главу "Вкладка Path to Gcode" данного руководства), на вкладке «Preferences» устанавливаем папку для выходных файлов, выбираем необходимый постпроцессор (например, «Parametrize Gcode» для возможности последующего перемещения или масштабирования (не применимо к обработки площади, без соответствующего изменения диаметра режущего инструмента) обработки). 364 | . (Не обязательный шаг) На вкладке «Параметры» устанавливаем флажок «Select all paths if nothing is selected», задаем минимальный радиус дуги траектории. 365 | . (Не обязательный шаг) На вкладке «Path to Gcode» выставляем допуск интерполяции и глубину разбиения кривых, жмем «Применить», «Закрыть». 366 | + 367 | image:img/area-tutorial-0007.png[] 368 | 369 | . В папке назначения будет создан файл с именем output_хххх.ngc, в котором будет содержаться Gкод для заданной обработки. Открываем файл в системе ЧПУ и проверяем полученную программу. 370 | + 371 | image:img/area-tutorial-0008.png[] 372 | 373 | 374 | -------------------------------------------------------------------------------- /doc/img/area-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/area-tab.png -------------------------------------------------------------------------------- /doc/img/area-tutorial-0001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/area-tutorial-0001.png -------------------------------------------------------------------------------- /doc/img/area-tutorial-0002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/area-tutorial-0002.png -------------------------------------------------------------------------------- /doc/img/area-tutorial-0003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/area-tutorial-0003.png -------------------------------------------------------------------------------- /doc/img/area-tutorial-0004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/area-tutorial-0004.png -------------------------------------------------------------------------------- /doc/img/area-tutorial-0005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/area-tutorial-0005.png -------------------------------------------------------------------------------- /doc/img/area-tutorial-0006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/area-tutorial-0006.png -------------------------------------------------------------------------------- /doc/img/area-tutorial-0007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/area-tutorial-0007.png -------------------------------------------------------------------------------- /doc/img/area-tutorial-0008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/area-tutorial-0008.png -------------------------------------------------------------------------------- /doc/img/aria-artifacts-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/aria-artifacts-tab.png -------------------------------------------------------------------------------- /doc/img/fill-area-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/fill-area-tab.png -------------------------------------------------------------------------------- /doc/img/orientation-points-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/orientation-points-tab.png -------------------------------------------------------------------------------- /doc/img/parameters-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/parameters-tab.png -------------------------------------------------------------------------------- /doc/img/path-to-gcode-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/path-to-gcode-tab.png -------------------------------------------------------------------------------- /doc/img/preferences-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/preferences-tab.png -------------------------------------------------------------------------------- /doc/img/tools-library-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/gcodetools/ce38e8f78d072ca08765fd158d1f07c06a04a459/doc/img/tools-library-tab.png -------------------------------------------------------------------------------- /dxf_input.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | <_name>DXF Input 4 | org.inkscape.input.dxf 5 | dxf_input.py 6 | inkex.py 7 | 8 | 9 | true 10 | 1.0 11 | false 12 | ------------------------------------------------------------------------- 13 | 14 | Latin 1 15 | CP 1250 16 | CP 1252 17 | UTF 8 18 | 19 | 20 | 21 | <_param name="inputhelp" type="description" xml:space="preserve">- AutoCAD Release 13 and newer. 22 | - assume dxf drawing is in mm. 23 | - assume svg drawing is in pixels, at 90 dpi. 24 | - layers are preserved only on File->Open, not Import. 25 | - limited support for BLOCKS, use AutoCAD Explode Blocks instead, if needed. 26 | 27 | 28 | 29 | .dxf 30 | image/x-svgz 31 | <_filetypename>AutoCAD DXF R13 (*.dxf) 32 | <_filetypetooltip>Import AutoCAD's Document Exchange Format 33 | 34 | 37 | 38 | -------------------------------------------------------------------------------- /dxf_input.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | dxf_input.py - input a DXF file >= (AutoCAD Release 13 == AC1012) 4 | 5 | Copyright (C) 2008, 2009 Alvin Penner, penner@vaxxine.com 6 | Copyright (C) 2009 Christian Mayer, inkscape@christianmayer.de 7 | - thanks to Aaron Spike for inkex.py and simplestyle.py 8 | - without which this would not have been possible 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; either version 2 of the License, or 13 | (at your option) any later version. 14 | 15 | This program is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | 20 | You should have received a copy of the GNU General Public License 21 | along with this program; if not, write to the Free Software 22 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | ''' 24 | 25 | import inkex, simplestyle, math 26 | from StringIO import StringIO 27 | from urllib import quote 28 | 29 | def export_MTEXT(): 30 | # mandatory group codes : (1 or 3, 10, 20) (text, x, y) 31 | if (vals[groups['1']] or vals[groups['3']]) and vals[groups['10']] and vals[groups['20']]: 32 | x = vals[groups['10']][0] 33 | y = vals[groups['20']][0] 34 | # optional group codes : (21, 40, 50) (direction, text height mm, text angle) 35 | size = 12 # default fontsize in px 36 | if vals[groups['40']]: 37 | size = scale*vals[groups['40']][0] 38 | attribs = {'x': '%f' % x, 'y': '%f' % y, 'style': 'font-size: %.1fpx; fill: %s' % (size, color)} 39 | angle = 0 # default angle in degrees 40 | if vals[groups['50']]: 41 | angle = vals[groups['50']][0] 42 | attribs.update({'transform': 'rotate (%f %f %f)' % (-angle, x, y)}) 43 | elif vals[groups['21']]: 44 | if vals[groups['21']][0] == 1.0: 45 | attribs.update({'transform': 'rotate (%f %f %f)' % (-90, x, y)}) 46 | elif vals[groups['21']][0] == -1.0: 47 | attribs.update({'transform': 'rotate (%f %f %f)' % (90, x, y)}) 48 | attribs.update({inkex.addNS('linespacing','sodipodi'): '125%'}) 49 | node = inkex.etree.SubElement(layer, 'text', attribs) 50 | text = '' 51 | if vals[groups['3']]: 52 | for i in range (0, len(vals[groups['3']])): 53 | text += vals[groups['3']][i] 54 | if vals[groups['1']]: 55 | text += vals[groups['1']][0] 56 | found = text.find('\P') # new line 57 | while found > -1: 58 | tspan = inkex.etree.SubElement(node , 'tspan', {inkex.addNS('role','sodipodi'): 'line'}) 59 | tspan.text = text[:found] 60 | text = text[(found+2):] 61 | found = text.find('\P') 62 | tspan = inkex.etree.SubElement(node , 'tspan', {inkex.addNS('role','sodipodi'): 'line'}) 63 | tspan.text = text 64 | 65 | def export_POINT(): 66 | # mandatory group codes : (10, 20) (x, y) 67 | if vals[groups['10']] and vals[groups['20']]: 68 | if options.gcodetoolspoints: 69 | generate_gcodetools_point(vals[groups['10']][0], vals[groups['20']][0]) 70 | else: 71 | generate_ellipse(vals[groups['10']][0], vals[groups['20']][0], w/2, 0.0, 1.0, 0.0, 0.0) 72 | 73 | def export_LINE(): 74 | # mandatory group codes : (10, 11, 20, 21) (x1, x2, y1, y2) 75 | if vals[groups['10']] and vals[groups['11']] and vals[groups['20']] and vals[groups['21']]: 76 | path = 'M %f,%f %f,%f' % (vals[groups['10']][0], vals[groups['20']][0], scale*(vals[groups['11']][0] - xmin), - scale*(vals[groups['21']][0] - ymax)) 77 | attribs = {'d': path, 'style': style} 78 | inkex.etree.SubElement(layer, 'path', attribs) 79 | 80 | def export_SPLINE(): 81 | # mandatory group codes : (10, 20, 70) (x, y, flags) 82 | if vals[groups['10']] and vals[groups['20']] and vals[groups['70']]: 83 | if not (vals[groups['70']][0] & 3) and len(vals[groups['10']]) == 4 and len(vals[groups['20']]) == 4: 84 | path = 'M %f,%f C %f,%f %f,%f %f,%f' % (vals[groups['10']][0], vals[groups['20']][0], vals[groups['10']][1], vals[groups['20']][1], vals[groups['10']][2], vals[groups['20']][2], vals[groups['10']][3], vals[groups['20']][3]) 85 | attribs = {'d': path, 'style': style} 86 | inkex.etree.SubElement(layer, 'path', attribs) 87 | if not (vals[groups['70']][0] & 3) and len(vals[groups['10']]) == 3 and len(vals[groups['20']]) == 3: 88 | path = 'M %f,%f Q %f,%f %f,%f' % (vals[groups['10']][0], vals[groups['20']][0], vals[groups['10']][1], vals[groups['20']][1], vals[groups['10']][2], vals[groups['20']][2]) 89 | attribs = {'d': path, 'style': style} 90 | inkex.etree.SubElement(layer, 'path', attribs) 91 | 92 | def export_CIRCLE(): 93 | # mandatory group codes : (10, 20, 40) (x, y, radius) 94 | if vals[groups['10']] and vals[groups['20']] and vals[groups['40']]: 95 | generate_ellipse(vals[groups['10']][0], vals[groups['20']][0], scale*vals[groups['40']][0], 0.0, 1.0, 0.0, 0.0) 96 | 97 | def export_ARC(): 98 | # mandatory group codes : (10, 20, 40, 50, 51) (x, y, radius, angle1, angle2) 99 | if vals[groups['10']] and vals[groups['20']] and vals[groups['40']] and vals[groups['50']] and vals[groups['51']]: 100 | generate_ellipse(vals[groups['10']][0], vals[groups['20']][0], scale*vals[groups['40']][0], 0.0, 1.0, vals[groups['50']][0]*math.pi/180.0, vals[groups['51']][0]*math.pi/180.0) 101 | 102 | def export_ELLIPSE(): 103 | # mandatory group codes : (10, 11, 20, 21, 40, 41, 42) (xc, xm, yc, ym, width ratio, angle1, angle2) 104 | if vals[groups['10']] and vals[groups['11']] and vals[groups['20']] and vals[groups['21']] and vals[groups['40']] and vals[groups['41']] and vals[groups['42']]: 105 | generate_ellipse(vals[groups['10']][0], vals[groups['20']][0], scale*vals[groups['11']][0], scale*vals[groups['21']][0], vals[groups['40']][0], vals[groups['41']][0], vals[groups['42']][0]) 106 | 107 | def export_LEADER(): 108 | # mandatory group codes : (10, 20) (x, y) 109 | if vals[groups['10']] and vals[groups['20']]: 110 | if len(vals[groups['10']]) > 1 and len(vals[groups['20']]) == len(vals[groups['10']]): 111 | path = 'M %f,%f' % (vals[groups['10']][0], vals[groups['20']][0]) 112 | for i in range (1, len(vals[groups['10']])): 113 | path += ' %f,%f' % (vals[groups['10']][i], vals[groups['20']][i]) 114 | attribs = {'d': path, 'style': style} 115 | inkex.etree.SubElement(layer, 'path', attribs) 116 | 117 | def export_LWPOLYLINE(): 118 | # mandatory group codes : (10, 20, 70) (x, y, flags) 119 | if vals[groups['10']] and vals[groups['20']] and vals[groups['70']]: 120 | if len(vals[groups['10']]) > 1 and len(vals[groups['20']]) == len(vals[groups['10']]): 121 | a=seqs 122 | if (seqs[-2]=='42' or seqs[-1]=='42') and vals[groups['70']][0]==1: 123 | if seqs[-1]=='42': 124 | a=seqs 125 | a.append("10") 126 | a.append("20") 127 | else: 128 | a=seqs[0:-1] 129 | a.append("10") 130 | a.append("20") 131 | a.append(seqs[-1]) 132 | vals[groups['10']].append(vals[groups['10']][0]) 133 | vals[groups['20']].append(vals[groups['20']][0]) 134 | # optional group codes : (42) (bulge) 135 | iseqs = 0 136 | ibulge = 0 137 | while a[iseqs] != '20': 138 | iseqs += 1 139 | path = 'M %f,%f' % (vals[groups['10']][0], vals[groups['20']][0]) 140 | xold = vals[groups['10']][0] 141 | yold = vals[groups['20']][0] 142 | for i in range (1, len(vals[groups['10']])): 143 | bulge = 0 144 | iseqs += 1 145 | while a[iseqs] != '20': 146 | if a[iseqs] == '42': 147 | bulge = vals[groups['42']][ibulge] 148 | ibulge += 1 149 | iseqs += 1 150 | if bulge: 151 | sweep = 0 # sweep CCW 152 | if bulge < 0: 153 | sweep = 1 # sweep CW 154 | bulge = -bulge 155 | large = 0 # large-arc-flag 156 | if bulge > 1: 157 | large = 1 158 | r = math.sqrt((vals[groups['10']][i] - xold)**2 + (vals[groups['20']][i] - yold)**2) 159 | r = 0.25*r*(bulge + 1.0/bulge) 160 | path += ' A %f,%f 0.0 %d %d %f,%f' % (r, r, large, sweep, vals[groups['10']][i], vals[groups['20']][i]) 161 | else: 162 | path += ' L %f,%f' % (vals[groups['10']][i], vals[groups['20']][i]) 163 | xold = vals[groups['10']][i] 164 | yold = vals[groups['20']][i] 165 | if vals[groups['70']][0] == 1: # closed path 166 | path += ' z' 167 | attribs = {'d': path, 'style': style} 168 | inkex.etree.SubElement(layer, 'path', attribs) 169 | 170 | def export_HATCH(): 171 | # mandatory group codes : (10, 20, 70, 72, 92, 93) (x, y, fill, Edge Type, Path Type, Number of edges) 172 | if vals[groups['10']] and vals[groups['20']] and vals[groups['70']] and vals[groups['72']] and vals[groups['92']] and vals[groups['93']]: 173 | if vals[groups['70']][0] and len(vals[groups['10']]) > 1 and len(vals[groups['20']]) == len(vals[groups['10']]): 174 | # optional group codes : (11, 21, 40, 50, 51, 73) (x, y, r, angle1, angle2, CCW) 175 | i10 = 1 # count start points 176 | i11 = 0 # count line end points 177 | i40 = 0 # count circles 178 | i72 = 0 # count edge type flags 179 | path = '' 180 | for i in range (0, len(vals[groups['93']])): 181 | xc = vals[groups['10']][i10] 182 | yc = vals[groups['20']][i10] 183 | if vals[groups['72']][i72] == 2: # arc 184 | rm = scale*vals[groups['40']][i40] 185 | a1 = vals[groups['50']][i40] 186 | path += 'M %f,%f ' % (xc + rm*math.cos(a1*math.pi/180.0), yc + rm*math.sin(a1*math.pi/180.0)) 187 | else: 188 | a1 = 0 189 | path += 'M %f,%f ' % (xc, yc) 190 | for j in range(0, vals[groups['93']][i]): 191 | if vals[groups['92']][i] & 2: # polyline 192 | if j > 0: 193 | path += 'L %f,%f ' % (vals[groups['10']][i10], vals[groups['20']][i10]) 194 | if j == vals[groups['93']][i] - 1: 195 | i72 += 1 196 | elif vals[groups['72']][i72] == 2: # arc 197 | xc = vals[groups['10']][i10] 198 | yc = vals[groups['20']][i10] 199 | rm = scale*vals[groups['40']][i40] 200 | a2 = vals[groups['51']][i40] 201 | diff = (a2 - a1 + 360) % (360) 202 | sweep = 1 - vals[groups['73']][i40] # sweep CCW 203 | large = 0 # large-arc-flag 204 | if diff: 205 | path += 'A %f,%f 0.0 %d %d %f,%f ' % (rm, rm, large, sweep, xc + rm*math.cos(a2*math.pi/180.0), yc + rm*math.sin(a2*math.pi/180.0)) 206 | else: 207 | path += 'A %f,%f 0.0 %d %d %f,%f ' % (rm, rm, large, sweep, xc + rm*math.cos((a1+180.0)*math.pi/180.0), yc + rm*math.sin((a1+180.0)*math.pi/180.0)) 208 | path += 'A %f,%f 0.0 %d %d %f,%f ' % (rm, rm, large, sweep, xc + rm*math.cos(a1*math.pi/180.0), yc + rm*math.sin(a1*math.pi/180.0)) 209 | i40 += 1 210 | i72 += 1 211 | elif vals[groups['72']][i72] == 1: # line 212 | path += 'L %f,%f ' % (scale*(vals[groups['11']][i11] - xmin), -scale*(vals[groups['21']][i11] - ymax)) 213 | i11 += 1 214 | i72 += 1 215 | i10 += 1 216 | path += "z " 217 | style = simplestyle.formatStyle({'fill': '%s' % color}) 218 | attribs = {'d': path, 'style': style} 219 | inkex.etree.SubElement(layer, 'path', attribs) 220 | 221 | def export_DIMENSION(): 222 | # mandatory group codes : (10, 11, 13, 14, 20, 21, 23, 24) (x1..4, y1..4) 223 | if vals[groups['10']] and vals[groups['11']] and vals[groups['13']] and vals[groups['14']] and vals[groups['20']] and vals[groups['21']] and vals[groups['23']] and vals[groups['24']]: 224 | dx = abs(vals[groups['10']][0] - vals[groups['13']][0]) 225 | dy = abs(vals[groups['20']][0] - vals[groups['23']][0]) 226 | if (vals[groups['10']][0] == vals[groups['14']][0]) and dx > 0.00001: 227 | d = dx/scale 228 | dy = 0 229 | path = 'M %f,%f %f,%f' % (vals[groups['10']][0], vals[groups['20']][0], vals[groups['13']][0], vals[groups['20']][0]) 230 | elif (vals[groups['20']][0] == vals[groups['24']][0]) and dy > 0.00001: 231 | d = dy/scale 232 | dx = 0 233 | path = 'M %f,%f %f,%f' % (vals[groups['10']][0], vals[groups['20']][0], vals[groups['10']][0], vals[groups['23']][0]) 234 | else: 235 | return 236 | attribs = {'d': path, 'style': style + '; marker-start: url(#DistanceX); marker-end: url(#DistanceX)'} 237 | inkex.etree.SubElement(layer, 'path', attribs) 238 | x = scale*(vals[groups['11']][0] - xmin) 239 | y = - scale*(vals[groups['21']][0] - ymax) 240 | size = 12 # default fontsize in px 241 | if vals[groups['3']]: 242 | if DIMTXT.has_key(vals[groups['3']][0]): 243 | size = scale*DIMTXT[vals[groups['3']][0]] 244 | if size < 2: 245 | size = 2 246 | attribs = {'x': '%f' % x, 'y': '%f' % y, 'style': 'font-size: %.1fpx; fill: %s' % (size, color)} 247 | if dx == 0: 248 | attribs.update({'transform': 'rotate (%f %f %f)' % (-90, x, y)}) 249 | node = inkex.etree.SubElement(layer, 'text', attribs) 250 | tspan = inkex.etree.SubElement(node , 'tspan', {inkex.addNS('role','sodipodi'): 'line'}) 251 | tspan.text = str(float('%.2f' % d)) 252 | 253 | def export_INSERT(): 254 | # mandatory group codes : (2, 10, 20) (block name, x, y) 255 | if vals[groups['2']] and vals[groups['10']] and vals[groups['20']]: 256 | x = vals[groups['10']][0] 257 | y = vals[groups['20']][0] - scale*ymax 258 | attribs = {'x': '%f' % x, 'y': '%f' % y, inkex.addNS('href','xlink'): '#' + quote(vals[groups['2']][0].encode("utf-8"))} 259 | inkex.etree.SubElement(layer, 'use', attribs) 260 | 261 | def export_BLOCK(): 262 | # mandatory group codes : (2) (block name) 263 | if vals[groups['2']]: 264 | global block 265 | block = inkex.etree.SubElement(defs, 'symbol', {'id': vals[groups['2']][0]}) 266 | 267 | def export_ENDBLK(): 268 | global block 269 | block = defs # initiallize with dummy 270 | 271 | def export_ATTDEF(): 272 | # mandatory group codes : (1, 2) (default, tag) 273 | if vals[groups['1']] and vals[groups['2']]: 274 | vals[groups['1']][0] = vals[groups['2']][0] 275 | export_MTEXT() 276 | 277 | def generate_ellipse(xc, yc, xm, ym, w, a1, a2): 278 | rm = math.sqrt(xm*xm + ym*ym) 279 | a = math.atan2(ym, xm) 280 | diff = (a2 - a1 + 2*math.pi) % (2*math.pi) 281 | if abs(diff) > 0.0000001 and abs(diff - 2*math.pi) > 0.0000001: # open arc 282 | large = 0 # large-arc-flag 283 | if diff > math.pi: 284 | large = 1 285 | xt = rm*math.cos(a1) 286 | yt = w*rm*math.sin(a1) 287 | x1 = xt*math.cos(a) - yt*math.sin(a) 288 | y1 = xt*math.sin(a) + yt*math.cos(a) 289 | xt = rm*math.cos(a2) 290 | yt = w*rm*math.sin(a2) 291 | x2 = xt*math.cos(a) - yt*math.sin(a) 292 | y2 = xt*math.sin(a) + yt*math.cos(a) 293 | path = 'M %f,%f A %f,%f %f %d 0 %f,%f' % (xc+x1, yc-y1, rm, w*rm, -180.0*a/math.pi, large, xc+x2, yc-y2) 294 | else: # closed arc 295 | path = 'M %f,%f A %f,%f %f 1 0 %f,%f %f,%f %f 1 0 %f,%f z' % (xc+xm, yc-ym, rm, w*rm, -180.0*a/math.pi, xc-xm, yc+ym, rm, w*rm, -180.0*a/math.pi, xc+xm, yc-ym) 296 | attribs = {'d': path, 'style': style} 297 | inkex.etree.SubElement(layer, 'path', attribs) 298 | 299 | def generate_gcodetools_point(xc, yc): 300 | path= 'm %s,%s 2.9375,-6.343750000001 0.8125,1.90625 6.843748640396,-6.84374864039 0,0 0.6875,0.6875 -6.84375,6.84375 1.90625,0.812500000001 z' % (xc,yc) 301 | attribs = {'d': path, 'dxfpoint':'1', 'style': 'stroke:#ff0000;fill:#ff0000'} 302 | inkex.etree.SubElement(layer, 'path', attribs) 303 | 304 | def get_line(): 305 | return (stream.readline().strip(), stream.readline().strip()) 306 | 307 | def get_group(group): 308 | line = get_line() 309 | if line[0] == group: 310 | return float(line[1]) 311 | else: 312 | return 0.0 313 | 314 | # define DXF Entities and specify which Group Codes to monitor 315 | 316 | entities = {'MTEXT': export_MTEXT, 'TEXT': export_MTEXT, 'POINT': export_POINT, 'LINE': export_LINE, 'SPLINE': export_SPLINE, 'CIRCLE': export_CIRCLE, 'ARC': export_ARC, 'ELLIPSE': export_ELLIPSE, 'LEADER': export_LEADER, 'LWPOLYLINE': export_LWPOLYLINE, 'HATCH': export_HATCH, 'DIMENSION': export_DIMENSION, 'INSERT': export_INSERT, 'BLOCK': export_BLOCK, 'ENDBLK': export_ENDBLK, 'ATTDEF': export_ATTDEF, 'DICTIONARY': False} 317 | groups = {'1': 0, '2': 1, '3': 2, '6': 3, '8': 4, '10': 5, '11': 6, '13': 7, '14': 8, '20': 9, '21': 10, '23': 11, '24': 12, '40': 13, '41': 14, '42': 15, '50': 16, '51': 17, '62': 18, '70': 19, '72': 20, '73': 21, '92': 22, '93': 23, '370': 24} 318 | colors = { 1: '#FF0000', 2: '#FFFF00', 3: '#00FF00', 4: '#00FFFF', 5: '#0000FF', 319 | 6: '#FF00FF', 8: '#414141', 9: '#808080', 12: '#BD0000', 30: '#FF7F00', 320 | 250: '#333333', 251: '#505050', 252: '#696969', 253: '#828282', 254: '#BEBEBE', 255: '#FFFFFF'} 321 | 322 | parser = inkex.optparse.OptionParser(usage="usage: %prog [options] SVGfile", option_class=inkex.InkOption) 323 | parser.add_option("--auto", action="store", type="inkbool", dest="auto", default=True) 324 | parser.add_option("--scale", action="store", type="string", dest="scale", default="1.0") 325 | parser.add_option("--gcodetoolspoints", action="store", type="inkbool", dest="gcodetoolspoints", default=True) 326 | parser.add_option("--encoding", action="store", type="string", dest="input_encode", default="latin_1") 327 | parser.add_option("--tab", action="store", type="string", dest="tab", default="Options") 328 | parser.add_option("--inputhelp", action="store", type="string", dest="inputhelp", default="") 329 | (options, args) = parser.parse_args(inkex.sys.argv[1:]) 330 | doc = inkex.etree.parse(StringIO('')) 331 | desc = inkex.etree.SubElement(doc.getroot(), 'desc', {}) 332 | defs = inkex.etree.SubElement(doc.getroot(), 'defs', {}) 333 | marker = inkex.etree.SubElement(defs, 'marker', {'id': 'DistanceX', 'orient': 'auto', 'refX': '0.0', 'refY': '0.0', 'style': 'overflow:visible'}) 334 | inkex.etree.SubElement(marker, 'path', {'d': 'M 3,-3 L -3,3 M 0,-5 L 0,5', 'style': 'stroke:#000000; stroke-width:0.5'}) 335 | stream = open(args[0], 'r') 336 | xmax = xmin = 0.0 337 | ymax = 297.0 # default A4 height in mm 338 | line = get_line() 339 | flag = 0 # (0, 1, 2, 3) = (none, LAYER, LTYPE, DIMTXT) 340 | layer_colors = {} # store colors by layer 341 | layer_nodes = {} # store nodes by layer 342 | linetypes = {} # store linetypes by name 343 | DIMTXT = {} # store DIMENSION text sizes 344 | 345 | while line[0] and line[1] != 'BLOCKS': 346 | line = get_line() 347 | if options.auto: 348 | if line[1] == '$EXTMIN': 349 | xmin = get_group('10') 350 | if line[1] == '$EXTMAX': 351 | xmax = get_group('10') 352 | ymax = get_group('20') 353 | if flag == 1 and line[0] == '2': 354 | layername = unicode(line[1], options.input_encode) 355 | attribs = {inkex.addNS('groupmode','inkscape'): 'layer', inkex.addNS('label','inkscape'): '%s' % layername} 356 | layer_nodes[layername] = inkex.etree.SubElement(doc.getroot(), 'g', attribs) 357 | if flag == 2 and line[0] == '2': 358 | linename = unicode(line[1], options.input_encode) 359 | linetypes[linename] = [] 360 | if flag == 3 and line[0] == '2': 361 | stylename = unicode(line[1], options.input_encode) 362 | if line[0] == '2' and line[1] == 'LAYER': 363 | flag = 1 364 | if line[0] == '2' and line[1] == 'LTYPE': 365 | flag = 2 366 | if line[0] == '2' and line[1] == 'DIMSTYLE': 367 | flag = 3 368 | if flag == 1 and line[0] == '62': 369 | layer_colors[layername] = int(line[1]) 370 | if flag == 2 and line[0] == '49': 371 | linetypes[linename].append(float(line[1])) 372 | if flag == 3 and line[0] == '140': 373 | DIMTXT[stylename] = float(line[1]) 374 | if line[0] == '0' and line[1] == 'ENDTAB': 375 | flag = 0 376 | 377 | if options.auto: 378 | scale = 1.0 379 | if xmax > xmin: 380 | scale = 210.0/(xmax - xmin) # scale to A4 width 381 | else: 382 | scale = float(options.scale) # manual scale factor 383 | desc.text = '%s - scale = %f' % (unicode(args[0], options.input_encode), scale) 384 | scale *= 90.0/25.4 # convert from mm to pixels 385 | 386 | if not layer_nodes: 387 | attribs = {inkex.addNS('groupmode','inkscape'): 'layer', inkex.addNS('label','inkscape'): '0'} 388 | layer_nodes['0'] = inkex.etree.SubElement(doc.getroot(), 'g', attribs) 389 | layer_colors['0'] = 7 390 | 391 | for linename in linetypes.keys(): # scale the dashed lines 392 | linetype = '' 393 | for length in linetypes[linename]: 394 | linetype += '%.4f,' % math.fabs(length*scale) 395 | linetypes[linename] = 'stroke-dasharray:' + linetype 396 | 397 | entity = '' 398 | block = defs # initiallize with dummy 399 | while line[0] and line[1] != 'DICTIONARY': 400 | line = get_line() 401 | if entity and groups.has_key(line[0]): 402 | seqs.append(line[0]) # list of group codes 403 | if line[0] == '1' or line[0] == '2' or line[0] == '3' or line[0] == '6' or line[0] == '8': # text value 404 | val = line[1].replace('\~', ' ') 405 | val = inkex.re.sub( '\\\\A.*;', '', val) 406 | val = inkex.re.sub( '\\\\H.*;', '', val) 407 | val = inkex.re.sub( '\\^I', '', val) 408 | val = inkex.re.sub( '{\\\\L', '', val) 409 | val = inkex.re.sub( '}', '', val) 410 | val = inkex.re.sub( '\\\\S.*;', '', val) 411 | val = inkex.re.sub( '\\\\W.*;', '', val) 412 | val = unicode(val, options.input_encode) 413 | val = val.encode('unicode_escape') 414 | val = inkex.re.sub( '\\\\\\\\U\+([0-9A-Fa-f]{4})', '\\u\\1', val) 415 | val = val.decode('unicode_escape') 416 | elif line[0] == '62' or line[0] == '70' or line[0] == '92' or line[0] == '93': 417 | val = int(line[1]) 418 | elif line[0] == '10' or line[0] == '13' or line[0] == '14': # scaled float x value 419 | val = scale*(float(line[1]) - xmin) 420 | elif line[0] == '20' or line[0] == '23' or line[0] == '24': # scaled float y value 421 | val = - scale*(float(line[1]) - ymax) 422 | else: # unscaled float value 423 | val = float(line[1]) 424 | vals[groups[line[0]]].append(val) 425 | elif entities.has_key(line[1]): 426 | if entities.has_key(entity): 427 | if block != defs: # in a BLOCK 428 | layer = block 429 | elif vals[groups['8']]: # use Common Layer Name 430 | layer = layer_nodes[vals[groups['8']][0]] 431 | color = '#000000' # default color 432 | if vals[groups['8']]: 433 | if layer_colors.has_key(vals[groups['8']][0]): 434 | if colors.has_key(layer_colors[vals[groups['8']][0]]): 435 | color = colors[layer_colors[vals[groups['8']][0]]] 436 | if vals[groups['62']]: # Common Color Number 437 | if colors.has_key(vals[groups['62']][0]): 438 | color = colors[vals[groups['62']][0]] 439 | style = simplestyle.formatStyle({'stroke': '%s' % color, 'fill': 'none'}) 440 | w = 0.5 # default lineweight for POINT 441 | if vals[groups['370']]: # Common Lineweight 442 | if vals[groups['370']][0] > 0: 443 | w = 90.0/25.4*vals[groups['370']][0]/00.0 444 | if w < 0.5: 445 | w = 0.5 446 | style = simplestyle.formatStyle({'stroke': '%s' % color, 'fill': 'none', 'stroke-width': '%.1f' % w}) 447 | if vals[groups['6']]: # Common Linetype 448 | if linetypes.has_key(vals[groups['6']][0]): 449 | style += ';' + linetypes[vals[groups['6']][0]] 450 | entities[entity]() 451 | entity = line[1] 452 | vals = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]] 453 | seqs = [] 454 | 455 | doc.write(inkex.sys.stdout) 456 | 457 | # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99 458 | -------------------------------------------------------------------------------- /examples/Gerber-kicad-dec-abs-mm.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ;DRILL file {Pcbnew (2013-07-07 BZR 4022)-stable} date 22.10.2013 19:42:18 3 | ;FORMAT={-:-/ absolute / metric / decimal} 4 | FMAT,2 5 | METRIC,TZ 6 | T1C0.600 7 | T2C0.900 8 | T3C2.400 9 | % 10 | G90 11 | G05 12 | M71 13 | T1 14 | X3.493Y59.372 15 | X3.493Y51.752 16 | X3.493Y49.212 17 | X3.493Y41.593 18 | X3.493Y39.052 19 | X3.493Y31.432 20 | X3.493Y28.892 21 | X3.493Y21.272 22 | X3.493Y18.732 23 | X3.493Y11.112 24 | X19.558Y36.068 25 | X19.558Y33.528 26 | X23.495Y38.735 27 | X23.495Y36.195 28 | X23.495Y33.655 29 | X23.495Y31.115 30 | X23.495Y28.575 31 | X23.495Y26.035 32 | X23.495Y23.495 33 | X23.495Y20.955 34 | X36.195Y38.735 35 | X36.195Y36.195 36 | X36.195Y33.655 37 | X36.195Y31.115 38 | X36.195Y28.575 39 | X36.195Y26.035 40 | X36.195Y23.495 41 | X36.195Y20.955 42 | X36.83Y65.278 43 | X37.465Y50.8 44 | X37.465Y43.18 45 | X39.37Y65.278 46 | X40.005Y28.575 47 | X40.005Y26.035 48 | X40.005Y23.495 49 | X41.91Y50.8 50 | X41.91Y43.18 51 | X42.545Y28.575 52 | X42.545Y26.035 53 | X42.545Y23.495 54 | X42.545Y13.97 55 | X42.545Y11.43 56 | X43.434Y66.802 57 | X45.085Y36.195 58 | X46.355Y50.8 59 | X46.355Y43.18 60 | X46.99Y13.97 61 | X46.99Y11.43 62 | X47.625Y36.195 63 | X50.8Y50.8 64 | X50.8Y43.18 65 | X51.054Y66.802 66 | X51.435Y38.735 67 | X51.435Y36.195 68 | X51.435Y33.655 69 | X51.435Y31.115 70 | X51.435Y28.575 71 | X51.435Y26.035 72 | X51.435Y23.495 73 | X51.435Y20.955 74 | X58.42Y66.04 75 | X58.42Y63.5 76 | X60.96Y66.04 77 | X60.96Y63.5 78 | X63.5Y66.04 79 | X63.5Y63.5 80 | X64.135Y38.735 81 | X64.135Y36.195 82 | X64.135Y33.655 83 | X64.135Y31.115 84 | X64.135Y28.575 85 | X64.135Y26.035 86 | X64.135Y23.495 87 | X64.135Y20.955 88 | X64.77Y50.8 89 | X64.77Y43.18 90 | X66.04Y66.04 91 | X66.04Y63.5 92 | X67.945Y28.575 93 | X67.945Y26.035 94 | X67.945Y23.495 95 | X68.58Y66.04 96 | X68.58Y63.5 97 | X69.215Y50.8 98 | X69.215Y43.18 99 | X70.485Y28.575 100 | X70.485Y26.035 101 | X70.485Y23.495 102 | X70.485Y13.97 103 | X70.485Y11.43 104 | X71.12Y66.04 105 | X71.12Y63.5 106 | X73.025Y36.195 107 | X73.66Y66.04 108 | X73.66Y63.5 109 | X73.66Y50.8 110 | X73.66Y43.18 111 | X74.93Y13.97 112 | X74.93Y11.43 113 | X75.565Y36.195 114 | X76.2Y66.04 115 | X76.2Y63.5 116 | X78.105Y50.8 117 | X78.105Y43.18 118 | X78.74Y66.04 119 | X78.74Y63.5 120 | X79.375Y38.735 121 | X79.375Y36.195 122 | X79.375Y33.655 123 | X79.375Y31.115 124 | X79.375Y28.575 125 | X79.375Y26.035 126 | X79.375Y23.495 127 | X79.375Y20.955 128 | X81.28Y66.04 129 | X81.28Y63.5 130 | X91.186Y66.04 131 | X91.186Y63.246 132 | X92.075Y38.735 133 | X92.075Y36.195 134 | X92.075Y33.655 135 | X92.075Y31.115 136 | X92.075Y28.575 137 | X92.075Y26.035 138 | X92.075Y23.495 139 | X92.075Y20.955 140 | X92.71Y50.8 141 | X92.71Y43.18 142 | X95.885Y28.575 143 | X95.885Y26.035 144 | X95.885Y23.495 145 | X97.155Y50.8 146 | X97.155Y43.18 147 | X98.425Y28.575 148 | X98.425Y26.035 149 | X98.425Y23.495 150 | X98.425Y13.97 151 | X98.425Y11.43 152 | X98.552Y65.278 153 | X100.965Y36.195 154 | X101.092Y65.278 155 | X101.6Y50.8 156 | X101.6Y43.18 157 | X102.87Y13.97 158 | X102.87Y11.43 159 | X103.505Y36.195 160 | X106.045Y51.435 161 | X106.045Y43.815 162 | X107.315Y38.735 163 | X107.315Y36.195 164 | X107.315Y33.655 165 | X107.315Y31.115 166 | X107.315Y28.575 167 | X107.315Y26.035 168 | X107.315Y23.495 169 | X107.315Y20.955 170 | X120.015Y38.735 171 | X120.015Y36.195 172 | X120.015Y33.655 173 | X120.015Y31.115 174 | X120.015Y28.575 175 | X120.015Y26.035 176 | X120.015Y23.495 177 | X120.015Y20.955 178 | X123.825Y28.575 179 | X123.825Y26.035 180 | X123.825Y23.495 181 | X124.206Y64.77 182 | X124.206Y59.69 183 | X124.206Y53.34 184 | X124.206Y50.8 185 | X126.365Y28.575 186 | X126.365Y26.035 187 | X126.365Y23.495 188 | X126.365Y13.97 189 | X126.365Y11.43 190 | X127.254Y46.99 191 | X127.254Y39.37 192 | X130.048Y31.496 193 | X130.048Y23.876 194 | X130.81Y13.97 195 | X130.81Y11.43 196 | X131.572Y65.532 197 | X131.572Y57.912 198 | X132.334Y42.926 199 | X133.858Y57.15 200 | X133.858Y24.13 201 | X135.636Y13.97 202 | X135.636Y11.43 203 | X144.018Y13.97 204 | X144.018Y8.89 205 | X146.812Y69.088 206 | X151.13Y16.256 207 | X152.4Y13.462 208 | X152.4Y10.922 209 | X153.67Y16.256 210 | T2 211 | X23.495Y6.35 212 | X27.305Y6.35 213 | X32.385Y6.35 214 | X36.195Y6.35 215 | X51.435Y6.35 216 | X55.245Y6.35 217 | X60.325Y6.35 218 | X64.135Y6.35 219 | X79.375Y6.35 220 | X83.185Y6.35 221 | X88.265Y6.35 222 | X92.075Y6.35 223 | X107.315Y6.35 224 | X111.125Y6.35 225 | X111.633Y62.23 226 | X115.443Y62.23 227 | X116.205Y6.35 228 | X120.015Y6.35 229 | X131.953Y6.35 230 | X135.763Y6.35 231 | X136.677Y26.67 232 | X136.703Y59.665 233 | X136.703Y43.155 234 | X138.684Y32.639 235 | X138.684Y20.701 236 | X138.709Y65.634 237 | X138.709Y53.696 238 | X138.709Y49.124 239 | X138.709Y37.186 240 | X150.876Y32.639 241 | X150.876Y20.701 242 | X150.901Y65.634 243 | X150.901Y53.696 244 | X150.901Y49.124 245 | X150.901Y37.186 246 | X158.75Y56.261 247 | X158.75Y52.451 248 | X158.75Y43.307 249 | X158.75Y39.497 250 | X158.75Y27.051 251 | X158.75Y23.241 252 | X158.75Y18.161 253 | X158.75Y14.351 254 | T3 255 | X7.62Y65.405 256 | X7.62Y5.08 257 | X29.845Y50.8 258 | X29.845Y15.24 259 | X57.785Y50.8 260 | X57.785Y15.24 261 | X85.725Y50.8 262 | X85.725Y34.925 263 | X85.725Y15.24 264 | X113.665Y50.8 265 | X113.665Y15.24 266 | X158.115Y65.405 267 | X158.115Y5.08 268 | T2 269 | X9.207Y57.467 270 | X9.207Y53.657 271 | X9.207Y47.307 272 | X9.207Y43.497 273 | X9.207Y37.148 274 | X9.207Y33.337 275 | X9.207Y26.987 276 | X9.207Y23.177 277 | X9.207Y16.828 278 | X9.207Y13.018 279 | T0 280 | M30 281 | -------------------------------------------------------------------------------- /gcodetools-dev.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Gcodetools dev 6 | 7 | 8 | ru.cnc-club.filter.gcodetools_dev 9 | 10 | gcodetools-dev.py 11 | inkex.py 12 | 13 | 14 | 15 | 16 | <_param name="fullhelp" type="description" xml:space="preserve"> 17 | Gcodetools plug-in: converts paths to Gcode (using circular interpolation), makes offset paths and engraves sharp corners using cone cutters. 18 | This plug-in calculates Gcode for paths using circular interpolation or linear motion when needed. 19 | 20 | Tutorials, manuals and support can be found at 21 | English support forum: 22 | http://www.cnc-club.ru/gcodetools 23 | 24 | and Russian support forum: 25 | http://www.cnc-club.ru/gcodetoolsru 26 | 27 | Credits: Nick Drobchenko, Vladimir Kalyaev, John Brooker, Henry Nicolas. 28 | 29 | Gcodetools ver. 1.6 30 | 31 | 32 | 33 | 34 | 35 | 36 | 1 37 | 0.0 38 | true 39 | 0.05 40 | 41 | False 42 | 0b0000000 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | output.ngc 54 | true 55 | 56 | /home 57 | 58 | 5 59 | 60 | <_item value="G21 (All units in mm)">mm 61 | <_item value="G20 (All units in inches)">in 62 | 63 | 64 | <_item value=" ">None 65 | <_item value="parameterize();">Parameterize Gcode 66 | <_item value="flip(y);parameterize();">Flip y axis and parameterize Gcode 67 | <_item value="round(4);">Round all values to 4 digits 68 | <_item value='regex("G01 Z([0-9\.\-]+).*\(Penetrate\)", lambda match: "G00 Z%f (Fast pre-penetrate)\n%s" %(float(match.group(1))+5, match.group(0)));'>Fast pre-penetrate 69 | 70 | 71 | 72 | 73 | 74 | false 75 | 76 | 77 | 78 | 79 | 80 | 81 | <_param name="help" type="description"> 82 | 83 | Imports files from other systems. 84 | 85 | 86 | 87 | <_item value="KiCAD gerber decimal,mm,absolute">kicad-dec-abs-mm 88 | 89 | 90 | 91 | 92 | 93 | <_param name="help" type="description" xml:space="preserve"> 94 | 95 | Convert selected objects to drill points (as dxf_import plugin does). Also you can save original shape. 96 | If path is not closed, the last ending node will be omitted. If path is closed, all nodes will be converted. 97 | 98 | Also you can manually select object, open XML editor (Shift+Ctrl+X) and add or remove XML tag 'dxfpoint' with any value. 99 | 100 | 101 | <_option value='save'>set as dxfpoint and save shape 102 | <_option value='replace'>set as dxfpoint and draw arrow 103 | <_option value='clear'>clear dxfpoint sign 104 | 105 | 106 | 107 | 108 | 109 | 110 | 1 111 | 4 112 | 113 | <_option value="subpath by subpath">Subpath by subpath 114 | <_option value="path by path">Path by path 115 | <_option value="pass by pass">Pass by Pass 116 | 117 | 118 | d 119 | True 120 | 121 | <_param name="help" type="description" xml:space="preserve"> 122 | Biarc interpolation tolerance is the maximum distance between path and its approximation. 123 | The segment will be split into two segments if the distance between path's segment and its approximation exceeds biarc interpolation tolerance. 124 | For depth function c=color intensity from 0.0 (white) to 1.0 (black), d is the depth defined by orientation points, s - surface defined by orientation points. 125 | 126 | 127 | 128 | 129 | 130 | 131 | 0 132 | 0 133 | 134 | <_option value="zig-zag">Zig zag 135 | <_option value="spiral">Spiral 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 100 144 | -10 145 | 0 146 | 147 | <_param name="help" type="description" xml:space="preserve"> 148 | "Create area offset": creates several Inkscape path offsets to fill original path's area up to "Area radius" value. 149 | 150 | Outlines start from "1/2 D" up to "Area width" total width with "D" steps where D is taken from the nearest tool definition ("Tool diameter" value). 151 | Only one offset will be created if the "Area width" is equal to "1/2 D". 152 | 153 | 154 | 155 | 156 | 157 | 5.0 158 | 159 | <_option value="mark with an arrow">mark with an arrow 160 | <_option value="mark with style">mark with style 161 | <_option value="delete">delete 162 | 163 | <_param name="help" type="description" xml:space="preserve"> 164 | Usage: 165 | 1. Select all Area Offsets (gray outlines) 166 | 2. Object/Ungroup (Shift+Ctrl+G) 167 | 3. Press Apply 168 | 169 | Suspected small objects will be marked out by colored arrows. 170 | 171 | 172 | 173 | 174 | 175 | 176 | 175 177 | 10 178 | 4 179 | false 180 | 181 | <_param name="help" type="description" xml:space="preserve"> 182 | This function creates path to engrave letters or any shape with sharp angles. 183 | Cutter's depth as a function of radius is defined by the tool. 184 | Depth may be any Python expression. For instance: 185 | 186 | cone....(45 degrees)......................: w 187 | cone....(height/diameter=10/3)..: 10*w/3 188 | sphere..(radius r)...........................: math.sqrt(max(0,r**2-w**2)) 189 | ellipse.(minor axis r, major 4r).....: math.sqrt(max(0,r**2-w**2))*4 190 | 191 | 192 | 193 | 194 | 195 | 196 | <_option value="2">2-points mode 197 | (move and rotate, 198 | maintained aspect ratio X/Y) 199 | <_option value="3">3-points mode 200 | (move, rotate and mirror, 201 | different X/Y scale) 202 | <_option value="graffiti">graffiti points 203 | <_option value="in-out reference point">in-out reference point 204 | 205 | 206 | 0 207 | -1 208 | 209 | <_item value="G21 (All units in mm)">mm 210 | <_item value="G20 (All units in inches)">in 211 | 212 | 213 | <_param name="help" type="description" xml:space="preserve"> 214 | Orientation points are used to calculate transformation (offset,scale,mirror,rotation in XY plane) of the path. 215 | 3-points mode only: do not put all three into one line (use 2-points mode instead). 216 | 217 | You can modify Z surface, Z depth values later using text tool (3rd coordinates). 218 | 219 | If there are no orientation points inside current layer they are taken from the upper layer. 220 | 221 | Do not ungroup orientation points! You can select them using double click to enter the group or by Ctrl+Click. 222 | 223 | Now press apply to create control points (independent set for each layer). 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | <_option value='default tool'>default 232 | <_option value='cylinder cutter'>cylinder 233 | <_option value='cone cutter'>cone 234 | <_option value='plasma cutter'>plasma 235 | <_option value='tangent knife'>tangent knife 236 | <_option value='lathe cutter'>lathe cutter 237 | <_option value='graffiti'>graffiti 238 | 239 | 240 | <_option value='check'>Just check tools 241 | 242 | 243 | 244 | <_param name="help" type="description" xml:space="preserve"> 245 | Selected tool type fills appropriate default values. You can change these values using the Text tool later on. 246 | 247 | The topmost (z order) tool in the active layer is used. If there is no tool inside the current layer it is taken from the upper layer. 248 | 249 | Press Apply to create new tool. 250 | 251 | 252 | 253 | 254 | 255 | 256 | 10 257 | 1 258 | 1 259 | 260 | <_option value="Move path">Move path 261 | <_option value="Offset path">Offset path 262 | 263 | X 264 | Z 265 | 266 | 267 | 268 | 269 | 270 | <_param name="help" type="description" xml:space="preserve"> 271 | This function modifies path so it will be possibe to cut it with a rectangular cutter. 272 | 273 | 4 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 10 282 | 10 283 | false 284 | false 285 | 286 | 287 | 288 | 289 | 290 | 500 291 | 100 292 | false 294 | 295 | 296 | 297 | 298 | 299 | 300 | True 301 | 10 302 | 10 303 | 304 | <_option value="Round">Round 305 | <_option value="Perpendicular">Perpendicular 306 | <_option value="Tangent">Tangent 307 | 308 | 10 309 | False 310 | False 311 | 312 | <_param name="help" type="description" xml:space="preserve">------------------------------------------------- 313 | True 314 | 10 315 | 170 316 | 317 | 318 | 319 | 320 | 321 | <_param name="help" type="description" xml:space="preserve">Outside corner: 322 | boxa/tan(boxb)/sin(a) - boxa/sin(boxb)/tan(boxc) 323 | boxa/tan(boxb)/sin(a) 324 | <_param name="help" type="description" xml:space="preserve"> 325 | Inside corner: 326 | -(boxa/tan(boxb)/sin(a) - boxa/sin(boxb)/tan(boxc)) 327 | -boxa/tan(boxb)/sin(a) 328 | 329 | 50*3.14159265/180 330 | 50*3.14159265/180 331 | 50*3.14159265/180 332 | 333 | 170 334 | 170 335 | <_param name="help" type="description" xml:space="preserve">This extension will cutt out or add some path in corners. 336 | Extension will eval() formulas as Python code. 337 | You can use a - for angle value, boxa, boxb, boxc - parameters. 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | <_param name="help" type="description" xml:space="preserve">Add gcodetools Ignore tag to selected objects so gcodetools will ignore them. 347 | 348 | 349 | 350 | 351 | 352 | 353 | 10 354 | 10 355 | (0.0;0.0) 356 | true 357 | true 358 | 800 359 | 1000 360 | 361 | 362 | 363 | 364 | 365 | 366 | <_param name="help" type="description" xml:space="preserve">Check for Gcodetools latest stable version and try to get the updates. 367 | 368 | 369 | 370 | 371 | 372 | <_param name="help" type="description" xml:space="preserve">Create Gcode for Bending machine. 373 | Bite my shiny metall a..! 374 | 375 | <_param name="bender-step" type="float" precision="5" min="0.1" max="1000" _gui-text="Path split step:">1 376 | <_param name="bender-max-split" type="int" min="1" max="1000" _gui-text="Segment max split:">32 377 | 378 | 379 | 380 | 381 | 382 | 383 | <_param name="help" type="description" xml:space="preserve">This page was created for testing purpouses. 384 | 10 385 | 10 386 | 10 387 | gcodetools.test_prof() 388 | false 389 | 390 | 391 | 392 | 393 | 394 | 395 | <_param name="help" type="description" xml:space="preserve">Gcodetools was developed to make simple Gcode from Inkscape's paths. Gcode is a special format which is used in most of CNC machines. So Gcodetools allows you to use Inkscape as CAM program. 396 | 397 | It can be used with a lot of machine types: 398 | Mills 399 | Lathes 400 | Laser and Plasma cutters and engravers 401 | Mill engravers 402 | Plotters 403 | etc. 404 | 405 | To get more info visit developers page at http://www.cnc-club.ru/gcodetools 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | path 417 | 418 | 421 | 422 | 423 | -------------------------------------------------------------------------------- /inline_test.c: -------------------------------------------------------------------------------- 1 | #line 1 "inline.c" 2 | const int len = l_; //points array len 3 | const int lp = lp_; //poly array len 4 | const int ls = ls_; //subpoly array len 5 | const int lpop = lt_*lp_*3/2; //population array len 6 | const int lt = lt_; //test array len 7 | 8 | 9 | Polygon* polygons = new Polygon; 10 | Polygon* surface = new Polygon; 11 | polygons->points = new double[len]; 12 | polygons->poly = new int[lp]; 13 | polygons->subpoly = new int[ls]; 14 | polygons->len = lp/2; 15 | 16 | surface->points = new double[len]; 17 | surface->subpoly = new int[ls]; 18 | surface->poly = new int[lp]; 19 | surface->len = 0; 20 | 21 | 22 | double *population = new double[lpop]; 23 | double *test = new double[lt]; 24 | 25 | 26 | int i,j,k; 27 | 28 | // fill the arrays with values; 29 | for (i=0; ipoints[i] = points_[i];} 30 | 31 | for (i=0; ipoly[i] = poly_[i];} 32 | for (i=0; isubpoly[i] = subpoly_[i];} 33 | for (i=0; isubpoly[n]; isubpoly[n+1]; i+=2) 19 | { 20 | double x = polygon->points[i]; 21 | double y = polygon->points[i+1]; 22 | polygon->points[i] = x*c-y*s; 23 | polygon->points[i+1] = x*s+y*c; 24 | } 25 | } 26 | 27 | void rotate_polygon( Polygon* polygon, int n, double a) 28 | { 29 | for (int i = polygon->poly[n*2]; ipoly[n*2+1]; i+=2) 30 | { 31 | rotate_subpolygon(polygon, i, a); 32 | } 33 | } 34 | 35 | void rotate_surface( Polygon* surface, double a) 36 | { 37 | for (int i=0;ilen;i++) 38 | { 39 | rotate_polygon(surface,i,a); 40 | } 41 | } 42 | 43 | 44 | void move_subpolygon( Polygon* polygon, int n, double x, double y) 45 | { 46 | for (int i=polygon->subpoly[n]; isubpoly[n+1]; i+=2) 47 | { 48 | polygon->points[i] += x; 49 | polygon->points[i+1] += y; 50 | } 51 | } 52 | 53 | 54 | void move_polygon( Polygon* polygon, int n, double x, double y) 55 | { 56 | for (int i = polygon->poly[n*2]; ipoly[n*2+1]; i+=2) 57 | { 58 | move_subpolygon(polygon, i, x, y); 59 | } 60 | } 61 | 62 | 63 | void move_surface( Polygon* surface, double x, double y) 64 | { 65 | for (int i=0;ilen;i++) 66 | { 67 | move_polygon(surface,i,x,y); 68 | } 69 | } 70 | 71 | 72 | 73 | void subpolygon_bounds(double* bounds, Polygon* polygon, int n) 74 | { 75 | for (int i=polygon->subpoly[n]; isubpoly[n+1]; i+=2) 76 | { 77 | if (bounds[0]>polygon->points[i]) 78 | {bounds[0]=polygon->points[i];} 79 | if (bounds[2]points[i]) 80 | {bounds[2]=polygon->points[i];} 81 | if (bounds[1]>polygon->points[i+1]) 82 | {bounds[1]=polygon->points[i+1];} 83 | if (bounds[3]points[i+1]) 84 | {bounds[3]=polygon->points[i+1];} 85 | } 86 | 87 | } 88 | 89 | 90 | double* polygon_bounds(double* bounds, Polygon* polygon, int n) 91 | { 92 | bounds[0] = 1E+37; 93 | bounds[1] = 1E+37; 94 | bounds[2] = -1E+37; 95 | bounds[3] = -1E+37; 96 | for (int i = polygon->poly[n*2]; ipoly[n*2+1]; i+=2) 97 | { 98 | subpolygon_bounds(bounds, polygon, i); 99 | } 100 | return bounds; 101 | } 102 | 103 | void surface_bounds(double* bounds, Polygon* surface) 104 | { 105 | bounds[0] = 1E+37; 106 | bounds[1] = 1E+37; 107 | bounds[2] = -1E+37; 108 | bounds[3] = -1E+37; 109 | for (int n=0; nlen;n++) 110 | { 111 | for (int i = surface->poly[n*2]; ipoly[n*2+1]; i+=2) 112 | { 113 | subpolygon_bounds(bounds, surface, i); 114 | } 115 | } 116 | } 117 | 118 | double minf(double a, double b) 119 | { 120 | return alen;k++) 138 | { 139 | std::cout<<"Surface poly: "<poly[k*2]<<"-"<poly[k*2+1]<poly[k*2];tpoly[k*2+1]; t+=2) 142 | { 143 | printf(" %d-%d\n",surface->subpoly[t],surface->subpoly[t+1]); 144 | } 145 | std::cout<cx,surface->cy,surface->ca); 148 | 149 | 150 | } 151 | 152 | 153 | void echo_subpolygon( Polygon* polygon, int n) 154 | { 155 | for (int i=polygon->subpoly[n]; isubpoly[n+1]; i+=2) 156 | { 157 | printf("(%f, %f) ",polygon->points[i], polygon->points[i+1]); 158 | } 159 | } 160 | 161 | 162 | void echo_polygon( Polygon* polygon, int n, std::string name=" ") 163 | { 164 | std::cout<<"****************"<poly[n*2]; ipoly[n*2+1]; i+=2) 170 | { 171 | echo_subpolygon(polygon, i); 172 | std::cout<poly[n*2]; ipoly[n*2+1]; i+=2) 182 | { 183 | cx=0; cy=0; a = 0; 184 | for (int j=polygon->subpoly[i];jsubpoly[i+1]-2;j+=2) 185 | { 186 | x1 = polygon->points[j]; 187 | y1 = polygon->points[j+1]; 188 | x2 = polygon->points[j+2]; 189 | y2 = polygon->points[j+3]; 190 | k = (x1*y2-x2*y1); 191 | cx += (x1+x2)*k; 192 | cy += (y1+y2)*k; 193 | a += k; 194 | } 195 | sx += cx; 196 | sy += cy; 197 | sa += a*3; 198 | } 199 | if (sa==0) 200 | {centroid[0]=0; centroid[1]=0;} 201 | else 202 | {centroid[0]=sx/sa; centroid[1]=sy/sa;} 203 | 204 | if (return_mass){centroid[2] = a;} 205 | 206 | } 207 | 208 | 209 | 210 | 211 | double vertex_to_segment_vertical_dist(double x,double y, double x1,double y1, double x2,double y2) //xy - vertex x1,y1, x2,y2 - line segment 212 | { 213 | if ((x1<=x && x<=x2) || (x2<=x && x<=x1)) 214 | { 215 | if (x1==x2) {return fabs(minf(y-y2,y-y1));} 216 | else {return fabs(y-y1-(y2-y1)*(x-x1)/(x2-x1));} 217 | } 218 | return -1; 219 | } 220 | 221 | 222 | void drop_polygon_down(Polygon* surface, int n) 223 | { 224 | // Polygon is array of subpoly which are ranges from points array 225 | // Surface is like a points array 226 | // Down means min y (0,-1) 227 | double s_bounds[4]; 228 | surface_bounds(s_bounds ,surface); 229 | double bounds[4]; 230 | polygon_bounds(bounds, surface, n); 231 | 232 | // move polygon to the top of surface + 10 233 | move_polygon(surface, n, 0, s_bounds[3] - bounds[1] + 10); 234 | /* 235 | # Now get shortest distance from surface to polygon in positive x=0 direction 236 | # Such distance = min(distance(vertex, edge)...) where edge from surface and 237 | # vertex from polygon and vice versa... 238 | */ 239 | double dist = 1e37; 240 | double d; 241 | 242 | for (int n_s=0; n_slen;n_s++) 243 | { 244 | for(int i=surface->poly[n_s*2];ipoly[n_s*2+1];i+=2) 245 | { 246 | for (int j=surface->subpoly[i];jsubpoly[i+1]-2;j+=2) 247 | { 248 | 249 | for(int i1=surface->poly[n*2];i1poly[n*2+1];i1+=2) 250 | { 251 | for (int j1=surface->subpoly[i1];j1subpoly[i1+1]-2;j1+=2) 252 | { 253 | // polygon vertex to surface 254 | d = vertex_to_segment_vertical_dist( surface->points[j1],surface->points[j1+1], surface->points[j],surface->points[j+1], surface->points[j+2],surface->points[j+3]); 255 | if (d>=0 && dist>d){dist=d;} 256 | // surface vertex to polygon 257 | d = vertex_to_segment_vertical_dist( surface->points[j],surface->points[j+1], surface->points[j1],surface->points[j1+1], surface->points[j1+2],surface->points[j1+3]); 258 | if (d>=0 && dist>d){dist=d;} 259 | } 260 | 261 | 262 | } 263 | 264 | } 265 | 266 | } 267 | 268 | } 269 | 270 | if (dist<1e37) 271 | { 272 | move_polygon(surface,n,0, -dist); 273 | } 274 | } 275 | 276 | void surface_append_polygon(Polygon* surface, Polygon* polygons, int n) 277 | { 278 | int start_point = 0; 279 | int start_subpoly = 0; 280 | int len = surface->len; 281 | 282 | //echo_surface(polygons, "polygon"); 283 | //std::cout<poly[2*n]<<"-"<poly[2*n+1]<poly[len*2-1]; 289 | start_point = surface->subpoly[start_subpoly-1]; 290 | } 291 | if (len==0) 292 | { 293 | surface->ca = 0; 294 | surface->cx = 0; 295 | surface->cy = 0; 296 | } 297 | int i1=0; 298 | int j1=0; 299 | surface->poly[len*2] = start_subpoly; 300 | surface->poly[len*2+1] = start_subpoly + (polygons->poly[2*n+1]-polygons->poly[2*n]); 301 | for(int i=polygons->poly[2*n]; ipoly[2*n+1]; i+=2) 302 | { 303 | surface->subpoly[start_subpoly+i1] = start_point+j1; 304 | surface->subpoly[start_subpoly+i1+1] = start_point+j1+ polygons->subpoly[i+1] - polygons->subpoly[i]; 305 | 306 | 307 | i1+=2; 308 | for (int j=polygons->subpoly[i]; jsubpoly[i+1]; j++) 309 | { 310 | surface->points[start_point+j1] = polygons->points[j]; 311 | j1++; 312 | } 313 | } 314 | } 315 | 316 | 317 | void surface_join_polygon(Polygon* surface) 318 | { 319 | double c[3]; 320 | polygon_centroid( c, surface, surface->len, true); 321 | if (surface->ca + c[2]!=0){ 322 | surface->cx = (surface->cx*surface->ca+c[0]*c[2])/(surface->ca+c[2]); 323 | surface->cy = (surface->cy*surface->ca+c[1]*c[2])/(surface->ca+c[2]); 324 | surface->ca = surface->ca + c[2]; 325 | } 326 | surface->len++; 327 | 328 | //echo_surface(surface, "After join"); 329 | } 330 | 331 | void test_centroid(Polygon* surface, Polygon* polygons, double* population, double* test, int lt_) 332 | { 333 | double surf_a=0; 334 | double c[3]; 335 | double b[4]; 336 | double l; 337 | double a1,a2; 338 | int n; 339 | int polylen = polygons->len; 340 | for (int test_n =0; test_nlen=0; 345 | 346 | for (int i=0; ilen==0) 352 | { 353 | 354 | surface_append_polygon(surface, polygons, n); 355 | rotate_polygon(surface,0,a1+a2); 356 | surf_a = a2; 357 | surface_join_polygon(surface); 358 | } 359 | else 360 | { 361 | move_surface(surface, -surface->cx, -surface->cy); 362 | // echo_polygon(surface, 0, "After move"); 363 | surface->cx = 0; 364 | surface->cy = 0; 365 | 366 | // echo_polygon(surface, l); 367 | 368 | l = surface->len; 369 | surface_append_polygon(surface, polygons, n); 370 | polygon_centroid(c, surface, l); 371 | move_polygon(surface, l, -c[0], -c[1]); 372 | 373 | rotate_polygon(surface, l, a1+a2); 374 | rotate_surface(surface, a2 - surf_a); 375 | surf_a = a2; 376 | 377 | drop_polygon_down(surface, l); 378 | surface_join_polygon(surface); 379 | // echo_polygon(surface, 0,"Surface"); 380 | // echo_polygon(surface, l,"Poly"); 381 | 382 | } 383 | } 384 | 385 | rotate_surface(surface, -surf_a); 386 | surface_bounds(b,surface); 387 | // printf("Test %d: %10.10f\n",test_n,(b[2]-b[0])*(b[3]-b[1])); 388 | // printf("Bonds: %f %f %f %f\n", b[0], b[1], b[2], b[3]); 389 | 390 | test[test_n] = (b[2]-b[0])*(b[3]-b[1]); 391 | } 392 | } 393 | } 394 | -------------------------------------------------------------------------------- /points.py: -------------------------------------------------------------------------------- 1 | from math import sin, cos, atan2, hypot 2 | 3 | ################################################################################ 4 | ### Point (x,y) operations 5 | ################################################################################ 6 | class P: 7 | def __init__(self, x, y=None): 8 | if not y==None: 9 | self.x, self.y = float(x), float(y) 10 | elif x.__class__ == P : 11 | self.x, self.y = float(x.x), float(x.y) 12 | else: 13 | self.x, self.y = float(x[0]), float(x[1]) 14 | def __add__(self, other): return P(self.x + other.x, self.y + other.y) 15 | def __sub__(self, other): return P(self.x - other.x, self.y - other.y) 16 | def __neg__(self): return P(-self.x, -self.y) 17 | def __mul__(self, other): 18 | if isinstance(other, P): 19 | return self.x * other.x + self.y * other.y 20 | return P(self.x * other, self.y * other) 21 | __rmul__ = __mul__ 22 | def __div__(self, other): return P(self.x / other, self.y / other) 23 | def mag(self): return hypot(self.x, self.y) 24 | def unit(self): 25 | h = self.mag() 26 | if h: return self / h 27 | else: return P(0,0) 28 | def dot(self, other): return self.x * other.x + self.y * other.y 29 | def cross(self, other): return self.x * other.y - self.y * other.x 30 | 31 | def rot(self, theta): 32 | c = cos(theta) 33 | s = sin(theta) 34 | return P(self.x * c - self.y * s, self.x * s + self.y * c) 35 | def rotate(self, theta): 36 | c = cos(theta) 37 | s = sin(theta) 38 | return P(self.x * c - self.y * s, self.x * s + self.y * c) 39 | def angle(self): return atan2(self.y, self.x) 40 | def __repr__(self): return '%.2f,%.2f' % (self.x, self.y) 41 | def pr(self): return "%.2f,%.2f" % (self.x, self.y) 42 | def to_list(self): return [self.x, self.y] 43 | def ccw(self): return P(-self.y,self.x) 44 | def cw(self): return P(self.y,-self.x) 45 | def l2(self): return self.x*self.x + self.y*self.y 46 | def transform(self, matrix) : 47 | x = self.x 48 | self.x = x*matrix[0][0] + self.y*matrix[0][1] + matrix[0][2] 49 | self.y = x*matrix[1][0] + self.y*matrix[1][1] + matrix[1][2] 50 | def near(self, b, tolerance=None ) : 51 | if tolerance==None : tolerance = 1e-7 52 | return (self-b).l2() < tolerance 53 | def copy(self) : return P(self.x,self.y) 54 | def __getitem__(self, i): 55 | return (self.x if i==0 else self.y if i==1 else None) 56 | -------------------------------------------------------------------------------- /stable/gcodetools.inx.src: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Gcodetools dev 6 | 7 | 8 | ru.cnc-club.filter.gcodetools_dev 9 | 10 | gcodetools-dev.py 11 | inkex.py 12 | 13 | 14 | 15 | 16 | <_param name="fullhelp" type="description"> 17 | Gcodetools plug-in: converts paths to Gcode (using circular interpolation), makes offset paths and engraves sharp corners using cone cutters. 18 | This plug-in calculates Gcode for paths using circular interpolation or linear motion when needed. 19 | 20 | Tutorials, manuals and support can be found at 21 | English support forum: 22 | http://www.cnc-club.ru/gcodetools 23 | 24 | and Russian support forum: 25 | http://www.cnc-club.ru/gcodetoolsru 26 | 27 | Credits: Nick Drobchenko, Vladimir Kalyaev, John Brooker, Henry Nicolas, Chris Lusby Taylor. 28 | 29 | Gcodetools ver. 1.7 30 | 31 | 32 | 33 | 34 | 35 | 36 | 1 37 | 0.0 38 | true 39 | 0.05 40 | 41 | False 42 | 43 | 44 | 45 | 46 | 47 | output.ngc 48 | true 49 | 50 | /home 51 | 52 | 5 53 | 54 | <_item value="G21 (All units in mm)">mm 55 | <_item value="G20 (All units in inches)">in 56 | 57 | 58 | <_item value=" ">None 59 | <_item value="parameterize();">Parameterize Gcode 60 | <_item value="flip(y);parameterize();">Flip y axis and parameterize Gcode 61 | <_item value="round(4);">Round all values to 4 digits 62 | <_item value='regex("G01 Z([0-9\.\-]+).*\(Penetrate\)", lambda match: "G00 Z%f (Fast pre-penetrate)\n%s" %(float(match.group(1))+5, match.group(0)));'>Fast pre-penetrate 63 | 64 | 65 | 66 | 67 | false 68 | 69 | 70 | 71 | 72 | 73 | 74 | <_param name="help" type="description"> 75 | 76 | Convert selected objects to drill points (as dxf_import plugin does). Also you can save original shape. Only the start point of each curve will be used. 77 | 78 | Also you can manually select object, open XML editor (Shift+Ctrl+X) and add or remove XML tag 'dxfpoint' with any value. 79 | 80 | 81 | <_option value='save'>set as dxfpoint and save shape 82 | <_option value='replace'>set as dxfpoint and draw arrow 83 | <_option value='clear'>clear dxfpoint sign 84 | 85 | 86 | 87 | 88 | 89 | 90 | 1 91 | 4 92 | 93 | <_option value="subpath by subpath">Subpath by subpath 94 | <_option value="path by path">Path by path 95 | <_option value="pass by pass">Pass by Pass 96 | 97 | 98 | d 99 | True 100 | 101 | <_param name="help" type="description"> 102 | Biarc interpolation tolerance is the maximum distance between path and its approximation. 103 | The segment will be split into two segments if the distance between path's segment and its approximation exceeds biarc interpolation tolerance. 104 | For depth function c=color intensity from 0.0 (white) to 1.0 (black), d is the depth defined by orientation points, s - surface defined by orientation points. 105 | 106 | 107 | 108 | 109 | 110 | 111 | 0 112 | 0 113 | 0 114 | 115 | <_option value="zig-zag">Zig zag 116 | <_option value="spiral">Spiral 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 100 125 | -10 126 | 0 127 | 128 | <_param name="help" type="description"> 129 | "Create area offset": creates several Inkscape path offsets to fill original path's area up to "Area radius" value. 130 | 131 | Outlines start from "1/2 D" up to "Area width" total width with "D" steps where D is taken from the nearest tool definition ("Tool diameter" value). 132 | Only one offset will be created if the "Area width" is equal to "1/2 D". 133 | 134 | 135 | 136 | 137 | 138 | 5.0 139 | 140 | <_option value="mark with an arrow">mark with an arrow 141 | <_option value="mark with style">mark with style 142 | <_option value="delete">delete 143 | 144 | <_param name="help" type="description"> 145 | Usage: 146 | 1. Select all Area Offsets (gray outlines) 147 | 2. Object/Ungroup (Shift+Ctrl+G) 148 | 3. Press Apply 149 | 150 | Suspected small objects will be marked out by colored arrows. 151 | 152 | 153 | 154 | 155 | 156 | 157 | 175 158 | 10 159 | 4 160 | false 161 | 162 | <_param name="help" type="description"> 163 | This function creates path to engrave letters or any shape with sharp angles. 164 | Cutter's depth as a function of radius is defined by the tool. 165 | Depth may be any Python expression. For instance: 166 | 167 | cone....(45 degrees)......................: w 168 | cone....(height/diameter=10/3)..: 10*w/3 169 | sphere..(radius r)...........................: math.sqrt(max(0,r**2-w**2)) 170 | ellipse.(minor axis r, major 4r).....: math.sqrt(max(0,r**2-w**2))*4 171 | 172 | 173 | 174 | 175 | 176 | 177 | <_option value="2">2-points mode 178 | (move and rotate, 179 | maintained aspect ratio X/Y) 180 | <_option value="3">3-points mode 181 | (move, rotate and mirror, 182 | different X/Y scale) 183 | <_option value="graffiti">graffiti points 184 | <_option value="in-out reference point">in-out reference point 185 | 186 | 187 | 0 188 | -1 189 | 190 | <_item value="G21 (All units in mm)">mm 191 | <_item value="G20 (All units in inches)">in 192 | 193 | 194 | <_param name="help" type="description"> 195 | Orientation points are used to calculate transformation (offset,scale,mirror,rotation in XY plane) of the path. 196 | 3-points mode only: do not put all three into one line (use 2-points mode instead). 197 | 198 | You can modify Z surface, Z depth values later using text tool (3rd coordinates). 199 | 200 | If there are no orientation points inside current layer they are taken from the upper layer. 201 | 202 | Do not ungroup orientation points! You can select them using double click to enter the group or by Ctrl+Click. 203 | 204 | Now press apply to create control points (independent set for each layer). 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | <_option value='default tool'>default 213 | <_option value='cylinder cutter'>cylinder 214 | <_option value='cone cutter'>cone 215 | <_option value='plasma cutter'>plasma 216 | <_option value='tangent knife'>tangent knife 217 | <_option value='lathe cutter'>lathe cutter 218 | <_option value='graffiti'>graffiti 219 | 220 | 221 | <_option value='check'>Just check tools 222 | 223 | 224 | 225 | <_param name="help" type="description"> 226 | Selected tool type fills appropriate default values. You can change these values using the Text tool later on. 227 | 228 | The topmost (z order) tool in the active layer is used. If there is no tool inside the current layer it is taken from the upper layer. 229 | 230 | Press Apply to create new tool. 231 | 232 | 233 | 234 | 235 | 236 | 237 | 10 238 | 1 239 | 1 240 | 241 | <_option value="Move path">Move path 242 | <_option value="Offset path">Offset path 243 | 244 | X 245 | Z 246 | 247 | 248 | 249 | 250 | 251 | <_param name="help" type="description"> 252 | This function modifies path so it will be able to be cut with the rectangular cutter. 253 | 254 | 4 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 10 263 | 10 264 | false 265 | false 266 | 267 | 268 | 269 | 270 | 271 | 500 272 | 100 273 | false 275 | 276 | 277 | 278 | 279 | 280 | 281 | True 282 | 10 283 | 10 284 | 285 | <_option value="Round">Round 286 | <_option value="Perpendicular">Perpendicular 287 | <_option value="Tangent">Tangent 288 | 289 | 10 290 | False 291 | False 292 | 293 | <_param name="help" type="description">------------------------------------------------- 294 | True 295 | 10 296 | 140 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 10 309 | 10 310 | (0.0;0.0) 311 | true 312 | true 313 | 800 314 | 1000 315 | 316 | 317 | 318 | 319 | 320 | 321 | <_param name="help" type="description">Check for Gcodetools latest stable version and try to get the updates. 322 | 323 | 324 | 325 | 326 | 327 | <_param name="help" type="description">This page was created for testing purpouses. 328 | 329 | 330 | 331 | 332 | 333 | 334 | <_param name="help" type="description">Gcodetools was developed to make simple Gcode from Inkscape's paths. Gcode is a special format which is used in most of CNC machines. So Gcodetools allows you to use Inkscape as CAM program. 335 | 336 | It can be use with a lot of machine types: 337 | Mills 338 | Lathes 339 | Laser and Plasma cutters and engravers 340 | Mill engravers 341 | Plotters 342 | etc. 343 | 344 | To get more info visit developers page at http://www.cnc-club.ru/gcodetools 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | path 356 | 357 | 360 | 361 | 362 | -------------------------------------------------------------------------------- /stable/gcodetools_about.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | About 5 | ru.cnc-club.filter.gcodetools_about_no_options_no_preferences 6 | gcodetools.py 7 | inkex.py 8 | 9 | 10 | 11 | <_param name="help" type="description">Gcodetools was developed to make simple Gcode from Inkscape's paths. Gcode is a special format which is used in most of CNC machines. So Gcodetools allows you to use Inkscape as CAM program. 12 | 13 | It can be use with a lot of machone types: 14 | Mills 15 | Lathes 16 | Laser and Palsma cutters and engravers 17 | Mill engravers 18 | Plotters 19 | etc. 20 | 21 | To get more info visit developers page at http://www.cnc-club.ru/gcodetools 22 | 23 | 24 | 25 | <_param name="fullhelp" type="description"> 26 | Gcodetools plug-in: converts paths to Gcode (using circular interpolation), makes offset paths and engraves sharp corners using cone cutters. 27 | This plug-in calculates Gcode for paths using circular interpolation or linear motion when needed. 28 | 29 | Tutorials, manuals and support can be found at 30 | English support forum: 31 | http://www.cnc-club.ru/gcodetools 32 | 33 | and Russian support forum: 34 | http://www.cnc-club.ru/gcodetoolsru 35 | 36 | Credits: Nick Drobchenko, Vladimir Kalyaev, John Brooker, Henry Nicolas, Chris Lusby Taylor. 37 | 38 | Gcodetools ver. 1.7 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | path 49 | 50 | 53 | 54 | -------------------------------------------------------------------------------- /stable/gcodetools_area.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Area 5 | ru.cnc-club.filter.gcodetools_area_area_fill_area_artefacts_ptg 6 | gcodetools.py 7 | inkex.py 8 | 9 | 10 | 11 | 100 12 | -10 13 | 0 14 | 15 | <_param name="help" type="description"> 16 | "Create area offset": creates several Inkscape path offsets to fill original path's area up to "Area radius" value. 17 | 18 | Outlines start from "1/2 D" up to "Area width" total width with "D" steps where D is taken from the nearest tool definition ("Tool diameter" value). 19 | Only one offset will be created if the "Area width" is equal to "1/2 D". 20 | 21 | 22 | 23 | 24 | 0 25 | 0 26 | 0 27 | 28 | <_option value="zig-zag">Zig zag 29 | <_option value="spiral">Spiral 30 | 31 | 32 | 33 | 34 | 5.0 35 | 36 | <_option value="mark with an arrow">mark with an arrow 37 | <_option value="mark with style">mark with style 38 | <_option value="delete">delete 39 | 40 | <_param name="help" type="description"> 41 | Usage: 42 | 1. Select all Area Offsets (gray outlines) 43 | 2. Object/Ungroup (Shift+Ctrl+G) 44 | 3. Press Apply 45 | 46 | Suspected small objects will be marked out by colored arrows. 47 | 48 | 49 | 50 | 51 | 1 52 | 4 53 | 54 | <_option value="subpath by subpath">Subpath by subpath 55 | <_option value="path by path">Path by path 56 | <_option value="pass by pass">Pass by Pass 57 | 58 | 59 | d 60 | True 61 | 62 | <_param name="help" type="description"> 63 | Biarc interpolation tolerance is the maximum distance between path and its approximation. 64 | The segment will be split into two segments if the distance between path's segment and its approximation exceeds biarc interpolation tolerance. 65 | For depth function c=color intensity from 0.0 (white) to 1.0 (black), d is the depth defined by orientation points, s - surface defined by orientation points. 66 | 67 | 68 | 69 | 70 | 1 71 | 0.0 72 | true 73 | 0.05 74 | 75 | False 76 | 77 | 78 | 79 | 80 | output.ngc 81 | true 82 | 83 | /home 84 | 85 | 5 86 | 87 | <_item value="G21 (All units in mm)">mm 88 | <_item value="G20 (All units in inches)">in 89 | 90 | 91 | <_item value=" ">None 92 | <_item value="parameterize();">Parameterize Gcode 93 | <_item value="flip(y);parameterize();">Flip y axis and parameterize Gcode 94 | <_item value="round(4);">Round all values to 4 digits 95 | <_item value='regex("G01 Z([0-9\.\-]+).*\(Penetrate\)", lambda match: "G00 Z%f (Fast pre-penetrate)\n%s" %(float(match.group(1))+5, match.group(0)));'>Fast pre-penetrate 96 | 97 | 98 | 99 | 100 | false 101 | 102 | 103 | 104 | 105 | 106 | <_param name="fullhelp" type="description"> 107 | Gcodetools plug-in: converts paths to Gcode (using circular interpolation), makes offset paths and engraves sharp corners using cone cutters. 108 | This plug-in calculates Gcode for paths using circular interpolation or linear motion when needed. 109 | 110 | Tutorials, manuals and support can be found at 111 | English support forum: 112 | http://www.cnc-club.ru/gcodetools 113 | 114 | and Russian support forum: 115 | http://www.cnc-club.ru/gcodetoolsru 116 | 117 | Credits: Nick Drobchenko, Vladimir Kalyaev, John Brooker, Henry Nicolas, Chris Lusby Taylor. 118 | 119 | Gcodetools ver. 1.7 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | path 130 | 131 | 134 | 135 | -------------------------------------------------------------------------------- /stable/gcodetools_check_for_updates.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Check for updates 5 | ru.cnc-club.filter.gcodetools_update_no_options_no_preferences 6 | gcodetools.py 7 | inkex.py 8 | 9 | 10 | 11 | <_param name="help" type="description">Check for Gcodetools latest stable version and try to get the updates. 12 | 13 | 14 | 15 | <_param name="fullhelp" type="description"> 16 | Gcodetools plug-in: converts paths to Gcode (using circular interpolation), makes offset paths and engraves sharp corners using cone cutters. 17 | This plug-in calculates Gcode for paths using circular interpolation or linear motion when needed. 18 | 19 | Tutorials, manuals and support can be found at 20 | English support forum: 21 | http://www.cnc-club.ru/gcodetools 22 | 23 | and Russian support forum: 24 | http://www.cnc-club.ru/gcodetoolsru 25 | 26 | Credits: Nick Drobchenko, Vladimir Kalyaev, John Brooker, Henry Nicolas, Chris Lusby Taylor. 27 | 28 | Gcodetools ver. 1.7 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | path 39 | 40 | 43 | 44 | -------------------------------------------------------------------------------- /stable/gcodetools_dxf_points.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DXF Points 5 | ru.cnc-club.filter.gcodetools_dxfpoints_no_options 6 | gcodetools.py 7 | inkex.py 8 | 9 | 10 | 11 | <_param name="help" type="description"> 12 | 13 | Convert selected objects to drill points (as dxf_import plugin does). Also you can save original shape. Only the start point of each curve will be used. 14 | 15 | Also you can manually select object, open XML editor (Shift+Ctrl+X) and add or remove XML tag 'dxfpoint' with any value. 16 | 17 | 18 | <_option value='save'>set as dxfpoint and save shape 19 | <_option value='replace'>set as dxfpoint and draw arrow 20 | <_option value='clear'>clear dxfpoint sign 21 | 22 | 23 | 24 | 25 | 26 | output.ngc 27 | true 28 | 29 | /home 30 | 31 | 5 32 | 33 | <_item value="G21 (All units in mm)">mm 34 | <_item value="G20 (All units in inches)">in 35 | 36 | 37 | <_item value=" ">None 38 | <_item value="parameterize();">Parameterize Gcode 39 | <_item value="flip(y);parameterize();">Flip y axis and parameterize Gcode 40 | <_item value="round(4);">Round all values to 4 digits 41 | <_item value='regex("G01 Z([0-9\.\-]+).*\(Penetrate\)", lambda match: "G00 Z%f (Fast pre-penetrate)\n%s" %(float(match.group(1))+5, match.group(0)));'>Fast pre-penetrate 42 | 43 | 44 | 45 | 46 | false 47 | 48 | 49 | 50 | 51 | 52 | <_param name="fullhelp" type="description"> 53 | Gcodetools plug-in: converts paths to Gcode (using circular interpolation), makes offset paths and engraves sharp corners using cone cutters. 54 | This plug-in calculates Gcode for paths using circular interpolation or linear motion when needed. 55 | 56 | Tutorials, manuals and support can be found at 57 | English support forum: 58 | http://www.cnc-club.ru/gcodetools 59 | 60 | and Russian support forum: 61 | http://www.cnc-club.ru/gcodetoolsru 62 | 63 | Credits: Nick Drobchenko, Vladimir Kalyaev, John Brooker, Henry Nicolas, Chris Lusby Taylor. 64 | 65 | Gcodetools ver. 1.7 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | path 76 | 77 | 80 | 81 | -------------------------------------------------------------------------------- /stable/gcodetools_engraving.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Engraving 5 | ru.cnc-club.filter.gcodetools_engraving 6 | gcodetools.py 7 | inkex.py 8 | 9 | 10 | 11 | 175 12 | 10 13 | 4 14 | false 15 | 16 | <_param name="help" type="description"> 17 | This function creates path to engrave letters or any shape with sharp angles. 18 | Cutter's depth as a function of radius is defined by the tool. 19 | Depth may be any Python expression. For instance: 20 | 21 | cone....(45 degrees)......................: w 22 | cone....(height/diameter=10/3)..: 10*w/3 23 | sphere..(radius r)...........................: math.sqrt(max(0,r**2-w**2)) 24 | ellipse.(minor axis r, major 4r).....: math.sqrt(max(0,r**2-w**2))*4 25 | 26 | 27 | 28 | 1 29 | 0.0 30 | true 31 | 0.05 32 | 33 | False 34 | 35 | 36 | 37 | 38 | output.ngc 39 | true 40 | 41 | /home 42 | 43 | 5 44 | 45 | <_item value="G21 (All units in mm)">mm 46 | <_item value="G20 (All units in inches)">in 47 | 48 | 49 | <_item value=" ">None 50 | <_item value="parameterize();">Parameterize Gcode 51 | <_item value="flip(y);parameterize();">Flip y axis and parameterize Gcode 52 | <_item value="round(4);">Round all values to 4 digits 53 | <_item value='regex("G01 Z([0-9\.\-]+).*\(Penetrate\)", lambda match: "G00 Z%f (Fast pre-penetrate)\n%s" %(float(match.group(1))+5, match.group(0)));'>Fast pre-penetrate 54 | 55 | 56 | 57 | 58 | false 59 | 60 | 61 | 62 | 63 | 64 | <_param name="fullhelp" type="description"> 65 | Gcodetools plug-in: converts paths to Gcode (using circular interpolation), makes offset paths and engraves sharp corners using cone cutters. 66 | This plug-in calculates Gcode for paths using circular interpolation or linear motion when needed. 67 | 68 | Tutorials, manuals and support can be found at 69 | English support forum: 70 | http://www.cnc-club.ru/gcodetools 71 | 72 | and Russian support forum: 73 | http://www.cnc-club.ru/gcodetoolsru 74 | 75 | Credits: Nick Drobchenko, Vladimir Kalyaev, John Brooker, Henry Nicolas, Chris Lusby Taylor. 76 | 77 | Gcodetools ver. 1.7 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | path 88 | 89 | 92 | 93 | -------------------------------------------------------------------------------- /stable/gcodetools_graffiti.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Graffiti 5 | ru.cnc-club.filter.gcodetools_graffiti_orientation 6 | gcodetools.py 7 | inkex.py 8 | 9 | 10 | 11 | 10 12 | 10 13 | (0.0;0.0) 14 | true 15 | true 16 | 800 17 | 1000 18 | 19 | 20 | 21 | 22 | 23 | <_option value="2">2-points mode 24 | (move and rotate, 25 | maintained aspect ratio X/Y) 26 | <_option value="3">3-points mode 27 | (move, rotate and mirror, 28 | different X/Y scale) 29 | <_option value="graffiti">graffiti points 30 | <_option value="in-out reference point">in-out reference point 31 | 32 | 33 | 0 34 | -1 35 | 36 | <_item value="G21 (All units in mm)">mm 37 | <_item value="G20 (All units in inches)">in 38 | 39 | 40 | <_param name="help" type="description"> 41 | Orientation points are used to calculate transformation (offset,scale,mirror,rotation in XY plane) of the path. 42 | 3-points mode only: do not put all three into one line (use 2-points mode instead). 43 | 44 | You can modify Z surface, Z depth values later using text tool (3rd coordinates). 45 | 46 | If there are no orientation points inside current layer they are taken from the upper layer. 47 | 48 | Do not ungroup orientation points! You can select them using double click to enter the group or by Ctrl+Click. 49 | 50 | Now press apply to create control points (independent set for each layer). 51 | 52 | 53 | 54 | 55 | 1 56 | 0.0 57 | true 58 | 0.05 59 | 60 | False 61 | 62 | 63 | 64 | 65 | output.ngc 66 | true 67 | 68 | /home 69 | 70 | 5 71 | 72 | <_item value="G21 (All units in mm)">mm 73 | <_item value="G20 (All units in inches)">in 74 | 75 | 76 | <_item value=" ">None 77 | <_item value="parameterize();">Parameterize Gcode 78 | <_item value="flip(y);parameterize();">Flip y axis and parameterize Gcode 79 | <_item value="round(4);">Round all values to 4 digits 80 | <_item value='regex("G01 Z([0-9\.\-]+).*\(Penetrate\)", lambda match: "G00 Z%f (Fast pre-penetrate)\n%s" %(float(match.group(1))+5, match.group(0)));'>Fast pre-penetrate 81 | 82 | 83 | 84 | 85 | false 86 | 87 | 88 | 89 | 90 | 91 | <_param name="fullhelp" type="description"> 92 | Gcodetools plug-in: converts paths to Gcode (using circular interpolation), makes offset paths and engraves sharp corners using cone cutters. 93 | This plug-in calculates Gcode for paths using circular interpolation or linear motion when needed. 94 | 95 | Tutorials, manuals and support can be found at 96 | English support forum: 97 | http://www.cnc-club.ru/gcodetools 98 | 99 | and Russian support forum: 100 | http://www.cnc-club.ru/gcodetoolsru 101 | 102 | Credits: Nick Drobchenko, Vladimir Kalyaev, John Brooker, Henry Nicolas, Chris Lusby Taylor. 103 | 104 | Gcodetools ver. 1.7 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | path 115 | 116 | 119 | 120 | -------------------------------------------------------------------------------- /stable/gcodetools_lathe.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Lathe 5 | ru.cnc-club.filter.gcodetools_lathe_lathe_modify_path_ptg 6 | gcodetools.py 7 | inkex.py 8 | 9 | 10 | 11 | 10 12 | 1 13 | 1 14 | 15 | <_option value="Move path">Move path 16 | <_option value="Offset path">Offset path 17 | 18 | X 19 | Z 20 | 21 | 22 | 23 | <_param name="help" type="description"> 24 | This function modifies path so it will be able to be cut with the rectangular cutter. 25 | 26 | 4 27 | 28 | 29 | 30 | 31 | 1 32 | 4 33 | 34 | <_option value="subpath by subpath">Subpath by subpath 35 | <_option value="path by path">Path by path 36 | <_option value="pass by pass">Pass by Pass 37 | 38 | 39 | d 40 | True 41 | 42 | <_param name="help" type="description"> 43 | Biarc interpolation tolerance is the maximum distance between path and its approximation. 44 | The segment will be split into two segments if the distance between path's segment and its approximation exceeds biarc interpolation tolerance. 45 | For depth function c=color intensity from 0.0 (white) to 1.0 (black), d is the depth defined by orientation points, s - surface defined by orientation points. 46 | 47 | 48 | 49 | 50 | 1 51 | 0.0 52 | true 53 | 0.05 54 | 55 | False 56 | 57 | 58 | 59 | 60 | output.ngc 61 | true 62 | 63 | /home 64 | 65 | 5 66 | 67 | <_item value="G21 (All units in mm)">mm 68 | <_item value="G20 (All units in inches)">in 69 | 70 | 71 | <_item value=" ">None 72 | <_item value="parameterize();">Parameterize Gcode 73 | <_item value="flip(y);parameterize();">Flip y axis and parameterize Gcode 74 | <_item value="round(4);">Round all values to 4 digits 75 | <_item value='regex("G01 Z([0-9\.\-]+).*\(Penetrate\)", lambda match: "G00 Z%f (Fast pre-penetrate)\n%s" %(float(match.group(1))+5, match.group(0)));'>Fast pre-penetrate 76 | 77 | 78 | 79 | 80 | false 81 | 82 | 83 | 84 | 85 | 86 | <_param name="fullhelp" type="description"> 87 | Gcodetools plug-in: converts paths to Gcode (using circular interpolation), makes offset paths and engraves sharp corners using cone cutters. 88 | This plug-in calculates Gcode for paths using circular interpolation or linear motion when needed. 89 | 90 | Tutorials, manuals and support can be found at 91 | English support forum: 92 | http://www.cnc-club.ru/gcodetools 93 | 94 | and Russian support forum: 95 | http://www.cnc-club.ru/gcodetoolsru 96 | 97 | Credits: Nick Drobchenko, Vladimir Kalyaev, John Brooker, Henry Nicolas, Chris Lusby Taylor. 98 | 99 | Gcodetools ver. 1.7 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | path 110 | 111 | 114 | 115 | -------------------------------------------------------------------------------- /stable/gcodetools_orientation_points.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Orientation points 5 | ru.cnc-club.filter.gcodetools_orientation_no_options_no_preferences 6 | gcodetools.py 7 | inkex.py 8 | 9 | 10 | 11 | 12 | 13 | <_option value="2">2-points mode 14 | (move and rotate, 15 | maintained aspect ratio X/Y) 16 | <_option value="3">3-points mode 17 | (move, rotate and mirror, 18 | different X/Y scale) 19 | <_option value="graffiti">graffiti points 20 | <_option value="in-out reference point">in-out reference point 21 | 22 | 23 | 0 24 | -1 25 | 26 | <_item value="G21 (All units in mm)">mm 27 | <_item value="G20 (All units in inches)">in 28 | 29 | 30 | <_param name="help" type="description"> 31 | Orientation points are used to calculate transformation (offset,scale,mirror,rotation in XY plane) of the path. 32 | 3-points mode only: do not put all three into one line (use 2-points mode instead). 33 | 34 | You can modify Z surface, Z depth values later using text tool (3rd coordinates). 35 | 36 | If there are no orientation points inside current layer they are taken from the upper layer. 37 | 38 | Do not ungroup orientation points! You can select them using double click to enter the group or by Ctrl+Click. 39 | 40 | Now press apply to create control points (independent set for each layer). 41 | 42 | 43 | 44 | 45 | <_param name="fullhelp" type="description"> 46 | Gcodetools plug-in: converts paths to Gcode (using circular interpolation), makes offset paths and engraves sharp corners using cone cutters. 47 | This plug-in calculates Gcode for paths using circular interpolation or linear motion when needed. 48 | 49 | Tutorials, manuals and support can be found at 50 | English support forum: 51 | http://www.cnc-club.ru/gcodetools 52 | 53 | and Russian support forum: 54 | http://www.cnc-club.ru/gcodetoolsru 55 | 56 | Credits: Nick Drobchenko, Vladimir Kalyaev, John Brooker, Henry Nicolas, Chris Lusby Taylor. 57 | 58 | Gcodetools ver. 1.7 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | path 69 | 70 | 73 | 74 | -------------------------------------------------------------------------------- /stable/gcodetools_path_to_gcode.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Path to Gcode 5 | ru.cnc-club.filter.gcodetools_ptg 6 | gcodetools.py 7 | inkex.py 8 | 9 | 10 | 11 | 1 12 | 4 13 | 14 | <_option value="subpath by subpath">Subpath by subpath 15 | <_option value="path by path">Path by path 16 | <_option value="pass by pass">Pass by Pass 17 | 18 | 19 | d 20 | True 21 | 22 | <_param name="help" type="description"> 23 | Biarc interpolation tolerance is the maximum distance between path and its approximation. 24 | The segment will be split into two segments if the distance between path's segment and its approximation exceeds biarc interpolation tolerance. 25 | For depth function c=color intensity from 0.0 (white) to 1.0 (black), d is the depth defined by orientation points, s - surface defined by orientation points. 26 | 27 | 28 | 29 | 30 | 1 31 | 0.0 32 | true 33 | 0.05 34 | 35 | False 36 | 37 | 38 | 39 | 40 | output.ngc 41 | true 42 | 43 | /home 44 | 45 | 5 46 | 47 | <_item value="G21 (All units in mm)">mm 48 | <_item value="G20 (All units in inches)">in 49 | 50 | 51 | <_item value=" ">None 52 | <_item value="parameterize();">Parameterize Gcode 53 | <_item value="flip(y);parameterize();">Flip y axis and parameterize Gcode 54 | <_item value="round(4);">Round all values to 4 digits 55 | <_item value='regex("G01 Z([0-9\.\-]+).*\(Penetrate\)", lambda match: "G00 Z%f (Fast pre-penetrate)\n%s" %(float(match.group(1))+5, match.group(0)));'>Fast pre-penetrate 56 | 57 | 58 | 59 | 60 | false 61 | 62 | 63 | 64 | 65 | 66 | <_param name="fullhelp" type="description"> 67 | Gcodetools plug-in: converts paths to Gcode (using circular interpolation), makes offset paths and engraves sharp corners using cone cutters. 68 | This plug-in calculates Gcode for paths using circular interpolation or linear motion when needed. 69 | 70 | Tutorials, manuals and support can be found at 71 | English support forum: 72 | http://www.cnc-club.ru/gcodetools 73 | 74 | and Russian support forum: 75 | http://www.cnc-club.ru/gcodetoolsru 76 | 77 | Credits: Nick Drobchenko, Vladimir Kalyaev, John Brooker, Henry Nicolas, Chris Lusby Taylor. 78 | 79 | Gcodetools ver. 1.7 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | path 90 | 91 | 94 | 95 | -------------------------------------------------------------------------------- /stable/gcodetools_prepare_path_for_plasma.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Prepare path for plasma 5 | ru.cnc-club.filter.gcodetools_plasma-prepare-path_no_options_no_preferences 6 | gcodetools.py 7 | inkex.py 8 | 9 | 10 | 11 | True 12 | 10 13 | 10 14 | 15 | <_option value="Round">Round 16 | <_option value="Perpendicular">Perpendicular 17 | <_option value="Tangent">Tangent 18 | 19 | 10 20 | False 21 | False 22 | 23 | <_param name="help" type="description">------------------------------------------------- 24 | True 25 | 10 26 | 140 27 | 28 | 29 | 30 | 31 | 32 | 33 | <_param name="fullhelp" type="description"> 34 | Gcodetools plug-in: converts paths to Gcode (using circular interpolation), makes offset paths and engraves sharp corners using cone cutters. 35 | This plug-in calculates Gcode for paths using circular interpolation or linear motion when needed. 36 | 37 | Tutorials, manuals and support can be found at 38 | English support forum: 39 | http://www.cnc-club.ru/gcodetools 40 | 41 | and Russian support forum: 42 | http://www.cnc-club.ru/gcodetoolsru 43 | 44 | Credits: Nick Drobchenko, Vladimir Kalyaev, John Brooker, Henry Nicolas, Chris Lusby Taylor. 45 | 46 | Gcodetools ver. 1.7 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | path 57 | 58 | 61 | 62 | -------------------------------------------------------------------------------- /stable/gcodetools_tools_library.inx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tools library 5 | ru.cnc-club.filter.gcodetools_tools_library_no_options_no_preferences 6 | gcodetools.py 7 | inkex.py 8 | 9 | 10 | 11 | 12 | 13 | <_option value='default tool'>default 14 | <_option value='plotter'>plotter 15 | <_option value='cylinder cutter'>cylinder 16 | <_option value='cone cutter'>cone 17 | <_option value='plasma cutter'>plasma 18 | <_option value='tangent knife'>tangent knife 19 | <_option value='lathe cutter'>lathe cutter 20 | <_option value='graffiti'>graffiti 21 | 22 | 23 | <_option value='check'>Just check tools 24 | 25 | 26 | 27 | <_param name="help" type="description"> 28 | Selected tool type fills appropriate default values. You can change these values using the Text tool later on. 29 | 30 | The topmost (z order) tool in the active layer is used. If there is no tool inside the current layer it is taken from the upper layer. 31 | 32 | Press Apply to create new tool. 33 | 34 | 35 | 36 | 37 | <_param name="fullhelp" type="description"> 38 | Gcodetools plug-in: converts paths to Gcode (using circular interpolation), makes offset paths and engraves sharp corners using cone cutters. 39 | This plug-in calculates Gcode for paths using circular interpolation or linear motion when needed. 40 | 41 | Tutorials, manuals and support can be found at 42 | English support forum: 43 | http://www.cnc-club.ru/gcodetools 44 | 45 | and Russian support forum: 46 | http://www.cnc-club.ru/gcodetoolsru 47 | 48 | Credits: Nick Drobchenko, Vladimir Kalyaev, John Brooker, Henry Nicolas, Chris Lusby Taylor. 49 | 50 | Gcodetools ver. 1.7 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | path 61 | 62 | 65 | 66 | --------------------------------------------------------------------------------