|
Post by alexfish on Sept 17, 2023 21:59:06 GMT 1
Hi All
boating season nearly done + Been busy doing some svg to gcode + doing own gcode converter(for reacent diy cnc) afore anyone shouts best advice is to
All ready built a one , but attach a professional(motion controller etc)
so to the svg to gcode like marlin an grbl (marlin = base on grbl)
so to the short of gcode & svg
in all cases the codes have to be converted
here is a simple example arcs , look at base api's and will find all point in one direction
else how does one see the results on the canvas:
the code is presented as is :: + READ , and yes there is a hug LINE: well what else would you need in GCODE , G1,G2,G3
if want to join item together the the line will help :: + drawing a line in pixels will help one join the dots To see all results in edit can move TEXT edit to before the NEXT LOOP
Have Fun + BR Alex
'gcode arc : part of Bacon Gcoder 'alexfish@basic-converter.proboards.com INCLUDE "hug.bac" HUGOPTIONS("NOSCALING") ENUM G2, G3 END ENUM
/* SVG path A = ARC cmd.arc.type cmd.arc.rx centerX cmd.arc.ry centerY cmd.arc.x_axis_rotation cmd.arc.large_arc_flag cmd.arc.sweep_flag cmd.arc.x initialAngle cmd.arc.y finalAngle */ DECLARE lastx,lasty TYPE float SUB ARC(int gtype,int centerX, int centerY, int radiusStepX, int radiusStepY, \ float initialAngle, float finalAngle)
LOCAL i,xpos,ypos TYPE float
IF gtype = G3 THEN FOR i = initialAngle TO finalAngle STEP 0.1 xpos = radiusStepX*SIN(RAD(i)) + centerX ypos = radiusStepY*COS(RAD(i)) + centerY PIXEL("#0000FF", xpos, ypos) lastx = xpos lasty = ypos NEXT TEXT(ed,STR$((int)lastx) & " | " & STR$((int)lasty) & NL$ ) ELIF gtype = G2 THEN FOR i = finalAngle TO initialAngle STEP -0.1 xpos = radiusStepX*SIN(RAD(i)) + centerX ypos = radiusStepY*COS(RAD(i)) + centerY lastx = xpos lasty = ypos PIXEL("#FF0000", xpos, ypos) NEXT TEXT(ed,STR$((int)lastx) & " | " & STR$((int)lasty) & NL$ ) ELSE TEXT (ed,"GC TYPE Arc Type Error") END IF END SUB '============================================================================= win = WINDOW("geo",902,600) ed = EDIT(450,600) ATTACH(win,ed,0,0) can = CANVAS(450,600) ATTACH(win,can,451,0)
ARC(G3,100, 100, 80, 80,180,270) LINE("#FF00FF", lastx, lasty, lastx+100, lasty)
ARC(G2,200, 200, 200, 200,0, 360) LINE("#FFFF00", lastx, lasty, lastx+100, lasty)
ARC(G2,200, 200, 195, 195,0, 360) LINE("#FFFF00", lastx, lasty, lastx+100, lasty) ARC(G2,150, 150, 100, 100,0, 45) LINE("#FFFF00", lastx, lasty, lastx+100, lasty) ARC(G3,150, 50, 100, 200,0, 45) LINE("#FF00FF", lastx, lasty, lastx+100, lasty) ARC(G2,150, 50, 100, 200,45, 90) LINE("#FFFF00", lastx, lasty, lastx+100, lasty)
DISPLAY
|
|
|
Post by alexfish on Sept 17, 2023 22:27:41 GMT 1
and so to the svg parser that is in the hugimager thread + the Missing bits
'A' and 'a' is missing but in cases, notice that most svg to gcode or cad dfx to svg result = Capitals esp on the path = "A"
hence final update on hugimager will have the bits complete
BR Alex
here using Cairo
SUB RENDER_PATH_GCODE(long sf,STRING svg$ ,int hug_xpos, int hug_ypos,double hug_scale) svg$ = MID$(svg$,INSTR(svg$,"path"))
svg$ = REPLACE$(svg$,CHR$(34),"'") svg$ = REPLACE$(svg$,"</svg>","") svg$ = REPLACE$(svg$,"path","") svg$=REPLACE$(svg$,"M",NL$ & "M" & NL$) svg$=REPLACE$(svg$,"L",NL$ & "L" & NL$) svg$=REPLACE$(svg$,"V",NL$ & "V" & NL$) svg$=REPLACE$(svg$,"H",NL$ & "H" & NL$) svg$=REPLACE$(svg$,"C",NL$ & "C" & NL$) svg$=REPLACE$(svg$,"l",NL$ & "l" & NL$) svg$=REPLACE$(svg$,"v",NL$ & "v" & NL$) svg$=REPLACE$(svg$,"h",NL$ & "h" & NL$) svg$=REPLACE$(svg$,"c",NL$ & "c" & NL$) svg$=REPLACE$(svg$,"z",NL$ & "z" & NL$) svg$=REPLACE$(svg$,"Z",NL$ & "Z" & NL$) svg$=REPLACE$(svg$,"A",NL$ & "A" & NL$) svg$=REPLACE$(svg$,"a",NL$ & "a" & NL$)
LOCAL c , s, t , ptr LOCAL LN$, dm$ , BIT$ , FIRST$ c = cairo_create (sf) cairo_set_line_width(c,1) cairo_translate (c, hug_xpos, hug_ypos) SPLIT svg$ BY NL$ TO PATH$ SIZE dim1 LOCAL BITS[7] TYPE double FOR t = 1 TO dim1 -1 LN$ = PATH$[t] FIRST$ = MID$(LN$,INSTR(LN$,"'")+1) FIRST$ = MID$(FIRST$,1,INSTR(FIRST$,"'")-1)
FOR s = 1 TO LEN(FIRST$)
BIT$ = MID$(FIRST$,s,1) IF BIT$ != " " THEN
SELECT BIT$ /* ARC A a case 'a': cmd.arc.relative = 1; case 'A': cmd.arc.type = ELLIPTICAL_ARC; cmd.arc.rx = parse_double (&pos, &error); cmd.arc.ry = parse_double (&pos, &error); cmd.arc.x_axis_rotation = parse_double (&pos, &error); cmd.arc.large_arc_flag = parse_flag (&pos, &error); cmd.arc.sweep_flag = parse_flag (&pos, &error); cmd.arc.x = parse_double (&pos, &error); cmd.arc.y = parse_double (&pos, &error); args 1+5 cairo_arc (cairo_t *cr, double xc, double yc, double radius, double angle1, double angle2);
cairo_arc_negative (cairo_t *cr, double xc, double yc, double radius, double angle1, double angle2); parameter(cr xc = X position of the center of the arc / rx yc = Y position of the center of the arc / ry radius / angle1= the start angle, in radians / angle2= the end angle, in radians /
cmd.arc.type = ELLIPTICAL_ARC; cmd.arc.rx = parse_double (&pos, &error); cmd.arc.ry = parse_double (&pos, &error); cmd.arc.x_axis_rotation = parse_double (&pos, &error); cmd.arc.large_arc_flag = parse_flag (&pos, &error); cmd.arc.sweep_flag = parse_flag (&pos, &error); cmd.arc.x = parse_double (&pos, &error); cmd.arc.y = parse_double (&pos, &error);
*/
'====================2 CASE "A" INCR t LN$ = CHOP$(PATH$[t]) LN$ = CHOP$(MID$(LN$,1,INSTR(LN$,"'")-1)) '====================2 CASE "a" INCR t LN$ = CHOP$(PATH$[t]) LN$ = CHOP$(MID$(LN$,1,INSTR(LN$,"'")-1))
'====================2 CASE "M" INCR t LN$ = CHOP$(PATH$[t]) LN$ = CHOP$(MID$(LN$,1,INSTR(LN$,"'")-1))
dm$ = LN$ BITS[0] = VAL(MID$(dm$,1,INSTR(dm$," ")-1)) BITS[1] = VAL(MID$(dm$,INSTR(dm$," ")+1)) cairo_move_to (c,BITS[0]*hug_scale,BITS[1]*hug_scale )
'====================2 CASE "m"
INCR t LN$ = CHOP$(PATH$[t]) LN$ = CHOP$(MID$(LN$,1,INSTR(LN$,"'")-1))
dm$ = LN$ BITS[0] = VAL(MID$(dm$,1,INSTR(dm$," ")-1)) BITS[1] = VAL(MID$(dm$,INSTR(dm$," ")+1)) cairo_rel_move_to (c,BITS[0]*hug_scale,BITS[1]*hug_scale ) '====================6 CASE "c"; CASE "s"; CASE "q" INCR t LN$ = CHOP$(PATH$[t]) LN$ = CHOP$(MID$(LN$,1,INSTR(LN$,"'")-1)) IF INSTR(LN$,",") THEN SPLIT LN$ BY "," TO My$ SIZE dim IF dim = 3 THEN ptr = 0 FOR v = 0 TO dim -1 dm$ = CHOP$(My$[v])
BITS[ptr] = VAL(MID$(dm$,1,INSTR(dm$," ")-1)) INCR ptr BITS[ptr] = VAL(MID$(dm$,INSTR(dm$," ")+1)) INCR ptr NEXT
cairo_rel_curve_to (c,BITS[0]*hug_scale,BITS[1]*hug_scale,BITS[2]*hug_scale, \ BITS[3]*hug_scale,BITS[4]*hug_scale,BITS[5]*hug_scale)
END IF END IF '====================6 CASE "C"; CASE "S"; CASE "Q" '====================6 INCR t LN$ = CHOP$(PATH$[t]) LN$ = CHOP$(MID$(LN$,1,INSTR(LN$,"'")-1)) IF INSTR(LN$,",") THEN SPLIT LN$ BY "," TO My$ SIZE dim IF dim = 3 THEN ptr = 0 FOR v = 0 TO dim -1 dm$ = CHOP$(My$[v])
BITS[ptr] = VAL(MID$(dm$,1,INSTR(dm$," ")-1)) INCR ptr BITS[ptr] = VAL(MID$(dm$,INSTR(dm$," ")+1)) INCR ptr NEXT cairo_curve_to (c,BITS[0]*hug_scale,BITS[1]*hug_scale,BITS[2]*hug_scale, \ BITS[3]*hug_scale,BITS[4]*hug_scale,BITS[5]*hug_scale)
END IF END IF '====================2 CASE "l"; CASE "h"; CASE "v" INCR t LN$ = CHOP$(PATH$[t]) LN$ = CHOP$(MID$(LN$,1,INSTR(LN$,"'")-1)) dm$ = LN$ BITS[0] = VAL(MID$(dm$,1,INSTR(dm$," ")-1)) BITS[1] = VAL(MID$(dm$,INSTR(dm$," ")+1)) cairo_rel_line_to(c,BITS[0]*hug_scale,BITS[1]*hug_scale)
'====================2 CASE "L"; CASE "H"; CASE "V"
INCR t LN$ = CHOP$(PATH$[t]) LN$ = CHOP$(MID$(LN$,1,INSTR(LN$,"'")-1)) dm$ = LN$ BITS[0] = VAL(MID$(dm$,1,INSTR(dm$," ")-1)) BITS[1] = VAL(MID$(dm$,INSTR(dm$," ")+1)) cairo_line_to(c,BITS[0]*hug_scale,BITS[1]*hug_scale)
'====================1 CASE "z"; CASE "Z"
END SELECT
END IF NEXT NEXT cairo_stroke (c) cairo_destroy(c)
END SUB
|
|
|
Post by alexfish on Sept 17, 2023 23:46:32 GMT 1
ScreenShot ADDED:: With reference to ARC QUADS : if can make in the posted code IE topleft topright bottomleft bottomright TOP LEFT ARC example ARC(G2,100, 100, 80, 80,180,270) THEN Practice the quads at 90 degrees then reduce/increase the angle + radius X & Y ANTI CLOCKWISE OR CLOCK WISE G2 G3 :: think done a foo bar :: will update code at first post BUG FIXED FIRST POST test these two ARC(G2,100, 100, 80, 80,180,270) LINE("#FF00FF", lastx, lasty, lastx+100, lasty) ARC(G3,100, 100, 80, 80,180,270) LINE("#FF00FF", lastx, lasty, lastx+100, lasty) Quad added in second screenshot BR Alex Attachments:
|
|
|
Post by alexfish on Sept 18, 2023 2:27:36 GMT 1
In relation to the first post here is part of a gcode2svg , and how the coords work this has text ("TEST") and parsed to show the "T" can back port in full bCNC and all looks good however view this test.svg the original had smaller viewbox to scale the image the code <?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="210" height="297" viewBox="0 0 210 297">
<!-- G21 (All units in mm)-->
<!-- G00 Z5.000000-->
<!-- G00 X76.359066 Y274.160470--> <!-- translate to [76.359066, 274.16047] -->
<!-- M03 S1(Turn spray on)-->
<!-- G01 Z-0.125000 F100.0(Penetrate)-->
<!-- G01 X71.044302 Y274.160470 Z-0.125000 F400.000000--> <line x1="76.359066" y1="274.16047" x2="71.044302" y2="274.16047" stroke="black" stroke-width="2"/>
<!-- G01 X71.044302 Y256.630694 Z-0.125000--> <line x1="71.044302" y1="274.16047" x2="71.044302" y2="256.630694" stroke="black" stroke-width="2"/>
<!-- G01 X69.066252 Y256.630694 Z-0.125000--> <line x1="71.044302" y1="256.630694" x2="69.066252" y2="256.630694" stroke="black" stroke-width="2"/>
<!-- G01 X69.066252 Y274.160470 Z-0.125000--> <line x1="69.066252" y1="256.630694" x2="69.066252" y2="274.16047" stroke="black" stroke-width="2"/>
<!-- G01 X63.751489 Y274.160470 Z-0.125000--> <line x1="69.066252" y1="274.16047" x2="63.751489" y2="274.16047" stroke="black" stroke-width="2"/>
<!-- G01 X63.751489 Y276.510234 Z-0.125000--> <line x1="63.751489" y1="274.16047" x2="63.751489" y2="276.510234" stroke="black" stroke-width="2"/>
<!-- G01 X76.359066 Y276.510234 Z-0.125000--> <line x1="63.751489" y1="276.510234" x2="76.359066" y2="276.510234" stroke="black" stroke-width="2"/>
<!-- G01 X76.359066 Y274.160470 Z-0.125000--> <line x1="76.359066" y1="276.510234" x2="76.359066" y2="274.16047" stroke="black" stroke-width="2"/>
<!-- G01 X76.359066 Y274.160470 Z-0.125000--> <line x1="76.359066" y1="274.16047" x2="76.359066" y2="274.16047" stroke="black" stroke-width="2"/>
</svg> now back to the ARC QUADS if not correct Then the quads will be upside down test case demo with cnc , shows the pendant at top :: put there on purpose <svg x="0" y ="0" width="650" height="550" viewBox="0 0 650 550" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
<!-- Or Full viewBox="0 0 650 550" preserveAspectRatio="none" -->
<!-- ======Header========================== --> <rect id="workspace" x="0" y="0" width="650" height="550" stroke="red" stroke-width="1" fill="none" /> <circle id = "pendant" cx="5" cy="5" r="5" stroke="red" stroke-width="1" fill="none" />
<rect id="workpiece" x="95" y="145" width="110" height="110" stroke="red" stroke-width="0.1" fill="none" /> <!-- ==End Header ========================== -->
<!-- G0 X150 Y 150 F1500 --> <path id="G0" d= "M 0 0 L 150 150 " stroke="black" stroke-width="0.1" fill="none" /> <!-- G1 Z -1 f300 -->
<!-- Work Group <g>================================== -->
<g id="drawcircle"> <!-- anti wise quadrant top left x1 y1 rx ry ? ? ? x2 y2--> <path id="G3" d= "M 150 150 A 50 50 0 0 0 100 200 " stroke="red" stroke-width="1" fill="none" /> <!-- anti wise quadrant bottom left x1 y1 rx ry ? ? ? x2 y2--> <path id="G3" d= "M 100 200 A 50 50 0 0 0 150 250 " stroke="blue" stroke-width="1" fill="none" />
<!-- anti wise quadrant bottom right x1 y1 rx ry ? ? ? x2 y2--> <path id="G3" d= "M 150 250 A 50 50 0 0 0 200 200 " stroke="red" stroke-width="1" fill="none" />
<!-- anti wise quadrant top right x1 y1 rx ry ? ? ? x2 y2--> <path id="G3" d= "M 200 200 A 50 50 0 0 0 150 150 " stroke="blue" stroke-width="1" fill="none" />
<!-- END GROUP === convert to Bresenham's ================ --> </g>
<!-- LINE Markers not drawn--> <path id="marker" d="M0 200 L240 200 " stroke="yellow" stroke-width="0.3" fill="none" />
<!-- LINE --> <path id="marker" d="M150 0 L150 300 " stroke="yellow" stroke-width="0.3" fill="none" /> <!-- ======================================= -->
</svg>
BR Alex + a Picky to study so from the text coords shown in the Editor if passed to the ARC function can do as the picky shows and since know what is required , best way draw a topright quad & then the last ARC Attachments:
|
|
|
Post by alexfish on Sept 19, 2023 23:36:11 GMT 1
Just a demo of Libre cad dfx export to svg + the actual dfx with bCNC bCNC = GRBL and to clarify the above posts As Picky's note the first with librecad an bCNC with the exported svg file , note the slight dashline on the right it points to the pendant top left IE the y is in the minus 0 :: assume that quadrant bit is upside down and bCNC can not draw the rest BR Alex Attachments:
|
|
|
Post by alexfish on Sept 20, 2023 3:05:49 GMT 1
have done a mockup of simple editor for svg open file = picture to canvas + loads file to top editor can extend the code or do code at start save the code & open same file after save If Wanting see the fruits of the svg file in a GRBL gcode viewer use bCNC simple to install from a terminal sudo pip install bCNC then bCNC then open the files *.svg BR Alex the bits 'alexfish@basic-converter.proboards.com INCLUDE "hug.bac" HUGOPTIONS("NOSCALING") lib$ = HUGLIB$("gtk") Gdk$ = HUGLIB$("gdk") ' Import the GTK functions for file filters IMPORT "gtk_file_chooser_add_filter(long,long)" FROM lib$ TYPE long IMPORT "gtk_file_filter_add_pattern(long,char*)" FROM lib$ TYPE long IMPORT "gtk_file_filter_new" FROM lib$ TYPE long IMPORT "gtk_file_filter_set_name(long,char*)" FROM lib$ TYPE void IMPORT "gdk_pixbuf_get_width(int)" FROM Gdk$ TYPE int IMPORT "gdk_pixbuf_get_height(int)" FROM Gdk$ TYPE int ' Setup first filter filter1 = gtk_file_filter_new() gtk_file_filter_set_name(filter1, "SVG files (*.svg)") gtk_file_filter_add_pattern(filter1, "*.svg")
' all-files filter2 = gtk_file_filter_new() gtk_file_filter_set_name(filter2, "All files (*)") gtk_file_filter_add_pattern(filter2, "*")
' .bac files
ENUM G2, G3 END ENUM
/* SVG path A = ARC cmd.arc.type cmd.arc.rx centerX cmd.arc.ry centerY cmd.arc.x_axis_rotation cmd.arc.large_arc_flag cmd.arc.sweep_flag cmd.arc.x initialAngle cmd.arc.y finalAngle */ '@ Hide the file dialogs SUB Hide_Window(NUMBER widget) HIDE(widget) END SUB
' At a Save
FUNCTION SAVE_FILE(NUMBER dialog, int button) HIDE(SAVE_FILE_DIALOG) IF button = -4 THEN RETURN TRUE IF button != GTK_RESPONSE_CANCEL THEN
IF GRAB$(dialog) = "" THEN RETURN TRUE f_save$ = GRAB$(dialog) IF (f_save$ > "") THEN PRINT f_save$ SAVE GRAB$(svg) TO f_save$ 'Rest of code Here
END IF END IF RETURN TRUE
END FUNCTION
REM --------------------------------------
SUB SAVE_DIALOG SHOW(SAVE_FILE_DIALOG) END SUB REM -------------------------------------- SUB OPEN_DIALOG SHOW(OPEN_FILE_DIALOG) END SUB
FUNCTION OPEN_FILE(NUMBER dialog, int button) LOCAL buff HIDE(OPEN_FILE_DIALOG) IF button = -4 THEN RETURN TRUE IF FILEEXISTS(GRAB$(dialog)) = FALSE THEN RETURN FALSE END IF IF button != GTK_RESPONSE_CANCEL THEN f_open$ = GRAB$(dialog) PRINT f_open$
buff = gdk_pixbuf_new_from_file(f_open$, 0) IF buff THEN SQUARE("#FFFFFF",0,0,1200-450,600,1) PICTURE(f_open$,0,0,gdk_pixbuf_get_width(buff),gdk_pixbuf_get_height(buff) ) g_object_unref(buff) TEXT(svg,"") TEXT(svg,LOAD$(f_open$) ) END IF
END IF
RETURN TRUE
END FUNCTION
DECLARE lastx,lasty TYPE float SUB ARC(int gtype,int centerX, int centerY, int radiusStepX, int radiusStepY, \ float initialAngle, float finalAngle)
LOCAL i,xpos,ypos TYPE float
IF gtype = G3 THEN FOR i = initialAngle TO finalAngle STEP 0.1 xpos = radiusStepX*SIN(RAD(i)) + centerX ypos = radiusStepY*COS(RAD(i)) + centerY PIXEL("#0000FF", xpos, ypos) lastx = xpos lasty = ypos NEXT TEXT(results,STR$((int)lastx) & " | " & STR$((int)lasty) & NL$ ) ELIF gtype = G2 THEN FOR i = finalAngle TO initialAngle STEP -0.1 xpos = radiusStepX*SIN(RAD(i)) + centerX ypos = radiusStepY*COS(RAD(i)) + centerY lastx = xpos lasty = ypos PIXEL("#FF0000", xpos, ypos) NEXT TEXT(results,STR$((int)lastx) & " | " & STR$((int)lasty) & NL$ ) ELSE TEXT (results,"GC TYPE Arc Type Error") END IF END SUB
'============================================================================= OPEN_FILE_DIALOG = FILEDIALOG("Open-File", "Select file", 600, 400, 0) CALLBACK(OPEN_FILE_DIALOG , OPEN_FILE) gtk_file_chooser_add_filter(OPEN_FILE_DIALOG, filter1) gtk_file_chooser_add_filter(OPEN_FILE_DIALOG, filter2) g_signal_connect_data(OPEN_FILE_DIALOG, "delete-event", Hide_Window, 0, 0, 0) REM -------------------------------------- SAVE_FILE_DIALOG = FILEDIALOG("Save-File", "Save-File", 600, 400, 1) CALLBACK(SAVE_FILE_DIALOG, SAVE_FILE) gtk_file_chooser_add_filter(SAVE_FILE_DIALOG, filter1) gtk_file_chooser_add_filter(SAVE_FILE_DIALOG, filter2) g_signal_connect_data(SAVE_FILE_DIALOG, "delete-event", Hide_Window, 0, 0, 0)
win = WINDOW("geo",1200,900) svg = EDIT(450,450) ATTACH(win,svg,0,0)
results = EDIT(450,450) ATTACH(win,results,0,450) open_but = STOCK("Open",100,30) ATTACH(win,open_but,450,0) CALLBACK(open_but,OPEN_DIALOG)
save_but = STOCK("Save",100,30) ATTACH(win,save_but,550,0) CALLBACK(save_but,SAVE_DIALOG)
can = CANVAS(1200-450,600) ATTACH(win,can,450,33)
/* ARC(G3,100, 100, 80, 80,180,270) LINE("#FF00FF", lastx, lasty, lastx+100, lasty)
ARC(G2,200, 200, 200, 200,0, 360) LINE("#FFFF00", lastx, lasty, lastx+100, lasty)
ARC(G2,200, 200, 195, 195,0, 360) LINE("#FFFF00", lastx, lasty, lastx+100, lasty) ARC(G2,150, 150, 100, 100,0, 45) LINE("#FFFF00", lastx, lasty, lastx+100, lasty) ARC(G3,150, 50, 100, 200,0, 45) LINE("#FF00FF", lastx, lasty, lastx+100, lasty) ARC(G2,150, 50, 100, 200,45, 90) LINE("#FFFF00", lastx, lasty, lastx+100, lasty) */ DISPLAY
Best HUG Canvas Drawing tool everAttachments:
|
|
|
Post by alexfish on Sept 20, 2023 5:32:59 GMT 1
Here is the trick of using the viewbox as mentioned <svg version="1.1" width="300" height="200" viewBox="0 200 300 200" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="red" />
<circle cx="150" cy="100" r="80" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
</svg> final save as:: yet more to do + you will not see that drawing in the canvas hence the save as and note there is no "text" per'say but there is a way but not for this thread machine wise how ever to date A picky of that code in bCNC Attachments:
|
|
|
Post by alexfish on Sept 20, 2023 17:02:17 GMT 1
GCODE motion wise, BaCon has a High Performance Canvas, 'canvas.bac' the main drawing commands are ' PIXEL(x, y) ' => Put a pixel in the current color on position x, y ' ' LINE(xstart, ystart, xend, yend) ' => Draw a line from xstart, ystart to xend, yend ' ' SQUARE(x, y, xradius, yradius, fill) ' => Draw a square with center position at x, y and radius x radius y. ' ' OUTLINE(..., fill) ' => Draw a polygon with a variable amount of coordinates in x,y,x,y,... format. ' ' CIRCLE(x, y, xsize, ysize, fill) ' => Draw a circle with center position at x, y and radius x, y. ' ' ARC(x, y, xsize, ysize, start, end, fill) ' => Draw an arc with center position at x, y and radius x, y, start and end (degrees). ' ' TRIANGLE(x, y, base, height, fill) ' => Draw a triangle with center position at x, y and base/height. ' ' POLYGON(x, y, radius, sides, fill) ' => Draw a polygon with center position at x, y, a radius, and amount of sides. ' ' QBEZIER(xstart, ystart, bendx, bendy, xend, yend) ' => Draw a quadratic Bezier curve starting at (xstart, ystart), ending at (xend, yend) bended by (bendx, bendy) ' ' CBEZIER(xstart, ystart, bend1x, bend1y, bend2x, bend2y, xend, yend) ' => Draw a cubic Bezier curve starting at (xstart, ystart), ending at (xend, yend) bended by (bend1x, bend1y) and (bend2x, bend2y) BR Alex
|
|
|
Post by alexfish on Sept 22, 2023 3:28:17 GMT 1
How good can HUG canvas Look Last Picky to roundup the above posts Attachments:
|
|
|
Post by alexfish on Sept 22, 2023 20:21:17 GMT 1
Q: I thought this thread was about GCODE A: OH! Try this + has a scrolled canvas BR Alex 'part of Bacon Gcoder ..cnc controll(View).raspberry PI4 in development 'alexfish@basic-converter.proboards.com ' ' INCLUDE "hug.bac" HUGOPTIONS("NOSCALING") lib$ = HUGLIB$("gtk") Gdk$ = HUGLIB$("gdk") ' Import the GTK functions for file filters IMPORT "gtk_widget_modify_fg(long,int,long)" FROM lib$ TYPE void IMPORT "gtk_widget_modify_bg(long,int,long)" FROM lib$ TYPE void IMPORT "gtk_file_chooser_add_filter(long,long)" FROM lib$ TYPE long IMPORT "gtk_file_filter_add_pattern(long,char*)" FROM lib$ TYPE long IMPORT "gtk_file_filter_new" FROM lib$ TYPE long IMPORT "gtk_file_filter_set_name(long,char*)" FROM lib$ TYPE void IMPORT "gdk_pixbuf_get_width(int)" FROM Gdk$ TYPE int IMPORT "gdk_pixbuf_get_height(int)" FROM Gdk$ TYPE int IMPORT "gtk_viewport_new (void)" FROM lib$ TYPE long IMPORT "gtk_scrolled_window_add_with_viewport(long,long)" FROM lib$ TYPE void
'not sure this works with gtk ? or comment it out PRAGMA INCLUDE <sys/resource.h> USEC struct rlimit rl; getrlimit (RLIMIT_STACK, &rl); rl.rlim_cur = RLIM_INFINITY; setrlimit (RLIMIT_STACK, &rl); ENDUSEC 'File dialogfilters ' Setup first filter filter1 = gtk_file_filter_new() gtk_file_filter_set_name(filter1, "SVG files (*.svg)") gtk_file_filter_add_pattern(filter1, "*.svg") '============================================================================= filter2 = gtk_file_filter_new() gtk_file_filter_set_name(filter2, "All files (*)") gtk_file_filter_add_pattern(filter2, "*") '============================================================================= filter3 = gtk_file_filter_new() gtk_file_filter_set_name(filter3, "Gcode files (*.nc)") gtk_file_filter_add_pattern(filter3, "*.nc")
'@ Hide the file dialogs SUB Hide_Window(NUMBER widget) HIDE(widget) END SUB '============================================================================= FUNCTION SAVE_FILE(NUMBER dialog, int button) HIDE(SAVE_FILE_DIALOG) IF button = -4 THEN RETURN TRUE IF button != GTK_RESPONSE_CANCEL THEN IF GRAB$(dialog) = "" THEN RETURN TRUE f_save$ = GRAB$(dialog) IF (f_save$ > "") THEN PRINT f_save$ SAVE GRAB$(svg) TO f_save$ 'Rest of code Here END IF END IF RETURN TRUE END FUNCTION '============================================================================= SUB SAVE_DIALOG SHOW(SAVE_FILE_DIALOG) END SUB '============================================================================= SUB OPEN_DIALOG SHOW(OPEN_FILE_DIALOG) END SUB '============================================================================= SUB FILL(hugcolour$,hugxpos,hugypos,hugxsize,hugysize) SQUARE(hugcolour$,hugxpos,hugypos,hugxsize,hugysize,1)
END SUB '============================================================================= FUNCTION OPEN_FILE(NUMBER dialog, int button) LOCAL buff HIDE(OPEN_FILE_DIALOG) IF button = -4 THEN RETURN TRUE IF FILEEXISTS(GRAB$(dialog)) = FALSE THEN RETURN FALSE END IF IF button != GTK_RESPONSE_CANCEL THEN f_open$ = GRAB$(dialog) PRINT f_open$
buff = gdk_pixbuf_new_from_file(f_open$, 0) IF buff THEN FILL("#000000",0,0,2000,2000) PICTURE(f_open$,0,0,gdk_pixbuf_get_width(buff),gdk_pixbuf_get_height(buff) ) g_object_unref(buff) TEXT(svg,"") TEXT(svg,LOAD$(f_open$) ) END IF END IF RETURN TRUE
END FUNCTION '============================================================================= DECLARE lastx,lasty TYPE float '=============================================================================
SUB G02(int centerX, int centerY, int radiusStepX, int radiusStepY, \ float initialAngle, float finalAngle)
LOCAL i,xpos,ypos TYPE float FOR i = finalAngle TO initialAngle STEP -0.1 xpos = radiusStepX*SIN(RAD(i)) + centerX ypos = radiusStepY*COS(RAD(i)) + centerY lastx = xpos lasty = ypos PIXEL("#FF0000", xpos, ypos) NEXT TEXT(results,"G02 X " & STR$((int)lastx) & " Y " & STR$((int)lasty) & NL$ ) END SUB '============================================================================== SUB G03(int centerX, int centerY, int radiusStepX, int radiusStepY, \ float initialAngle, float finalAngle)
LOCAL i,xpos,ypos TYPE float FOR i = initialAngle TO finalAngle STEP 0.1 xpos = radiusStepX*SIN(RAD(i)) + centerX ypos = radiusStepY*COS(RAD(i)) + centerY PIXEL("#0000FF", xpos, ypos) lastx = xpos lasty = ypos NEXT TEXT(results,"G03 X " & STR$((int)lastx) & " Y " & STR$((int)lasty) & NL$ ) END SUB '============================================================================== SUB G01(xpos1, ypos1, xpos2, ypos2)
LINE("#00FFFF", xpos1, ypos1,xpos2, ypos2)
END SUB '============================================================================= '--- MAIN -------------------------------------------------------------------- OPEN_FILE_DIALOG = FILEDIALOG("Open-File", "Select file", 600, 400, 0) CALLBACK(OPEN_FILE_DIALOG , OPEN_FILE) gtk_file_chooser_add_filter(OPEN_FILE_DIALOG, filter1) gtk_file_chooser_add_filter(OPEN_FILE_DIALOG, filter3) gtk_file_chooser_add_filter(OPEN_FILE_DIALOG, filter2) g_signal_connect_data(OPEN_FILE_DIALOG, "delete-event", Hide_Window, 0, 0, 0) '============================================================================= SAVE_FILE_DIALOG = FILEDIALOG("Save-File", "Save-File", 600, 400, 1) CALLBACK(SAVE_FILE_DIALOG, SAVE_FILE) gtk_file_chooser_add_filter(SAVE_FILE_DIALOG, filter1) gtk_file_chooser_add_filter(SAVE_FILE_DIALOG, filter3) gtk_file_chooser_add_filter(SAVE_FILE_DIALOG, filter2) g_signal_connect_data(SAVE_FILE_DIALOG, "delete-event", Hide_Window, 0, 0, 0) '=============================================================================
win = WINDOW("geo",1200,900) 'gtk_window_set_resizable(win,1)
svg = EDIT(450,450) ATTACH(win,svg,0,0) FONT(svg,"monospace 12px")
results = EDIT(450,450) ATTACH(win,results,0,450)
open_but = STOCK("Open",100,30) ATTACH(win,open_but,450,0) CALLBACK(open_but,OPEN_DIALOG)
save_but = STOCK("Save",100,30) ATTACH(win,save_but,550,0) CALLBACK(save_but,SAVE_DIALOG)
'Scrolable Canvas ------------------------------- scrolled = gtk_scrolled_window_new(0, 0) gtk_scrolled_window_set_policy(scrolled, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC) gtk_scrolled_window_set_shadow_type(scrolled, GTK_SHADOW_ETCHED_IN) IF HUG_WIDGET_SHOW THEN gtk_widget_show_all(scrolled) hug_widget_xsize(STR$(scrolled)) = 1200-450 hug_widget_ysize(STR$(scrolled)) = 600 ATTACH(win,scrolled,450,33)
can = CANVAS(2000,2000) gtk_scrolled_window_add_with_viewport(scrolled, can) '---------------------------------------------------- 'Some drawing bits FILL("#000000",0,0,2000,2000)
G03(100, 100, 80, 80,180,270)
G01(lastx, lasty, lastx+100, lasty)
G01(lastx+100, lasty+10, lastx-40, lasty)
G01(lastx, lasty, lastx+100, lasty+20)
G02(200, 200, 200, 200,0, 360)
G01(lastx+100, lasty ,lastx, lasty)
G02(200, 200, 195, 195,0, 360)
G01(lastx, lasty, lastx+100, lasty)
G02(150, 150, 100, 100,0, 45)
G01(lastx, lasty, lastx+100, lasty)
G03(150, 50, 100, 200,0, 45)
G01(lastx, lasty, lastx+100, lasty)
G02(150, 50, 100, 200,45, 90)
G01(lastx, lasty, lastx+100, lasty)
DISPLAY
' END ALL THAT ======================= NEXT STEP ==== from the code you see Like G02(150, 50, 100, 200,45, 90) that will give you a Picture of what happens next :: here talking Machine load a gcode file parse it Draw The bits Press a Button and send the bits to the machine Hence in process ; of coding the necessary using libgpio ;; instance Raspberry PI IE a cnc machine or any device that in relation to motion controll ;; the picky show that Picture BR Alex Attachments:
|
|
|
Post by alexfish on Sept 22, 2023 22:11:58 GMT 1
Inside the machine
Stepper wise a bit of code from embryo(arduino) grbl(gcode) libgrbl has similar in the decoder
so here G02 AND G03 translated to
void Embryo::drawArc(uint8_t centerX, uint8_t centerY, uint8_t radius, float initialAngle, float finalAngle){ uint8_t _radius = radius; uint8_t _centerX = centerX; uint8_t _centerY = centerY; float _initialAngle = initialAngle; float _finalAngle = finalAngle;
uint32_t _centerStepX = map(_centerX, 0, _axisX->getLength(), 0, _axisX->getTotalSteps()); uint32_t _centerStepY = map(_centerY, 0, _axisY->getLength(), 0, _axisY->getTotalSteps()); uint32_t _radiusStepX = map(_radius, 0, _axisX->getLength(), 0, _axisX->getTotalSteps()); uint32_t _radiusStepY = map(_radius, 0, _axisY->getLength(), 0, _axisY->getTotalSteps()); uint32_t _initialStepX = map(_centerX + _radius, 0, _axisX->getLength(), 0, _axisX->getTotalSteps()); uint32_t _initialStepY = map(_centerY, 0, _axisY->getLength(), 0, _axisY->getTotalSteps()); // toStepXY(_initialStepX, _initialStepY);
for(float _i = _initialAngle; _i<= _finalAngle; _i++){ double _radians = (3.14159*_i)/180.0; uint32_t _x = _radiusStepX*cos(_radians) + _centerStepX; uint32_t _y = _radiusStepY*sin(_radians) + _centerStepY; toStepXY(_x, _y); } }
so as it draws the arc, the same is sent to the stepper motor or motors and here we are drawing exactly the ARC feature posted, same applies to G01 = a line from to
IE bacon code
SUB G02(int centerX, int centerY, int radiusStepX, int radiusStepY, \ float initialAngle, float finalAngle)
LOCAL i,xpos,ypos TYPE float FOR i = finalAngle TO initialAngle STEP -0.1 xpos = radiusStepX*SIN(RAD(i)) + centerX ypos = radiusStepY*COS(RAD(i)) + centerY lastx = xpos lasty = ypos PIXEL("#FF0000", xpos, ypos) NEXT TEXT(results,"G02 X " & STR$((int)lastx) & " Y " & STR$((int)lasty) & NL$ ) END SUB Note here, that the Drawing works first by SIN & then COS, linux wise O,0 = top of And other os may = bottom of screen + GCODE pendant wise 0.0 = bottom left
Noted by load image(flip) vertical 'linux'
BR Alex
|
|
|
Post by alexfish on Sept 23, 2023 3:17:05 GMT 1
To Summarize the above
A simple diy cnc router
Can sit with a computer..(CNC Controller)
code what you draw(design) what you want LINES and ARCS or GCODE
view the results on canvas Happy
Press The Button
No need for inkscape or possible cad, the cad(drawing tool) is what see in the picture
the and or, Simply use this interface for Drawing as in myinkspace
|
|
|
Post by alexfish on Sept 23, 2023 13:15:14 GMT 1
SVG parser?
here looking a example for circle
'Docs IF BETWEEN "Basic" AND "Pascal" THEN PRINT "This is C" /* There are 7 shape elements in SVG: <circle>, <ellipse>, <line>, <path>, <polygon>, <polyline>, and <rect>. */ txt1$ = CHOP$("<circle cx='50' cy='50' r='40' stroke='black' stroke-width='3' fill='red' />") txt1$ = REPLACE$(txt1$,CHR$(39),CHR$(34)) txt1$ = REPLACE$(txt1$,CHR$(32),"") txt1$ = INBETWEEN$(txt1$,"<circle","/>") 'PRINT txt1$ LOCAL cx,cy,r
'PRINT txt1$ IF INSTR(txt1$,"cx=") THEN cx = INSTR(txt1$,"cx=") CX$ = MID$(txt1$,cx) CX$ = INBETWEEN$(CX$,"=","=") END IF
IF INSTR(txt1$,"cy=") THEN cy = INSTR(txt1$,"cy=") CY$ = MID$(txt1$,cy) CY$ = INBETWEEN$(CY$,"=","=") END IF
IF INSTR(txt1$,"r=") THEN rd = INSTR(txt1$,"r=") RD$ = MID$(txt1$,rd) DR$ = INBETWEEN$(RD$,"=","=") END IF CX$ = INBETWEEN$(CX$,CHR$(34),CHR$(34)) CY$ = INBETWEEN$(CY$,CHR$(34),CHR$(34)) RD$ = INBETWEEN$(RD$,CHR$(34),CHR$(34)) PRINT "cx =" ,CX$ PRINT "cy =" ,CY$ PRINT "r =" ,RD$
BR Alex
|
|
|
Post by alexfish on Sept 23, 2023 17:00:35 GMT 1
Back on the hunt for fonts TEXT2GODE Stuck gold with this one HersheyFonts2Gcode HersheyFonts one of witch is hug & hpc 'canvas.bac' Source github.com/Andy1978/hf2gcodesample of demo code G1 Z-1.000 ( Pen-Down ) G1 Y18.500 G0 Z1.000 ( Pen-Up ) G0 X2.000 Y24.000 G1 Z-1.000 ( Pen-Down ) G1 X9.000 G0 Z1.000 ( Pen-Up, EOG ) ;e = LSXSXQWOVNTMQMONMPLSLUMXOZQ[T[VZXX G0 X12.500 Y22.500 G1 Z-1.000 ( Pen-Down ) G1 X18.500 G1 Y23.500 G1 X18.000 Y24.500 G1 X17.500 Y25.000 G1 X16.500 Y25.500 G1 X15.000 G1 X14.000 Y25.000 G1 X13.000 Y24.000 G1 X12.500 Y22.500 G1 Y21.500 G1 X13.000 Y20.000 G1 X14.000 Y19.000 G1 X15.000 Y18.500 G1 X16.500 G1 X17.500 Y19.000 G1 X18.500 Y20.000 G0 Z1.000 ( Pen-Up, EOG ) ;l = RFR[ G0 X22.000 Y29.000 G1 Z-1.000 ( Pen-Down ) G1 Y18.500 G0 Z1.000 ( Pen-Up, EOG ) ;l = RFR[ G0 X26.000 Y29.000 G1 Z-1.000 ( Pen-Down )
BR Alex
|
|
|
Post by alexfish on Sept 23, 2023 22:00:09 GMT 1
Anyway
can us this DIY type ; can make the extracted GCODE 0*
8bit font , not big to start with , get to practice first the can progress what ever bit size you want , normal 8,16,32, **** then also need method to font_size(*):
'example 8bit pixel font B$ = \ "my mono*-metadata" & NL$ \ "BBBBBBB -" & NL$ \ "B B-" & NL$ \ "B B-" & NL$ \ "BBBBBBB -" & NL$ \ "B B-" & NL$ \ "B B-" & NL$ \ "BBBBBBB -" & NL$ \ " " '============================= 'Normal pack into array [*][*]' ' scale wise for decent font size grow to 8*8 = 64 ' to decode < IE need the method to get [*][ASCII-CHAR] 'find in array according to ASCI CHARS ' GET ASCII(B$) '============================= ' and so on PRINT B$ rowstride = INSTR(B$, "*") PRINT rowstride LOCAL yy SPLIT B$ BY NL$ TO glyphs$ SIZE pos LOCAL nm DECR pos FOR xx = 0 TO pos
b$ = glyphs$[xx] SPLIT b$ BY "-" TO mychar$ SIZE dim2 FOR yy = 0 TO dim2 b$ = mychar$[yy] PRINT b$ PRINT "px ",MOD(xx,rowstride) , ": py ", yy, "; "; NEXT PRINT NEXT
'=== THEN MAP TO pixels to x,y
BR Alex
|
|