Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental SVG support #451

Open
arkypita opened this issue Sep 30, 2018 · 66 comments
Open

Experimental SVG support #451

arkypita opened this issue Sep 30, 2018 · 66 comments

Comments

@arkypita
Copy link
Owner

Write here about SVG support

@StuartB4
Copy link

StuartB4 commented Oct 1, 2018

Hi.
Just a bit of info.
Just installed v2.9.0 and made a quick test .SVG file.
This was the result:

I left the settings at the default ones, loaded the .svg file in which was made in Inkscape.
I noticed the M4 command to switch the laser on, like in the picture below.
But after generating the code and saving it, I looked at the code and saw it had generated M3 instead for the laser On.
There was also an off-set of X1 and Y2 mm's added when I loaded the file in.

untitled

I also noticed in the code there is no return to home position code generated.
So when it had finished burning, the laser stopped at the (bottom right) end of the last line.
Not sure what the M30 was supposed to do, but I removed it from the end of the code
and added G0 X0 Y0 to the end instead.
Then loaded it back in, ran the code and after it finished the laser returned Home.

untitled3

Generated code (Beginning and End) with a large section removed, it's actually 234 lines of code:

M5
G0 X31.523 Y32.336
M3 S255
G1 X38.624 Y32.336 F300
G1 X38.624 Y38.570
G1 X31.523 Y38.570
G1 X31.523 Y32.336
M5
...........
...........
...........
G0 X36.346 Y1.928
M3 S255
G1 X31.585 Y7.636 F300
G1 X31.264 Y2.268
G1 X35.063 Y8.577
G1 X29.949 Y7.295
G1 X37.058 Y5.486
G1 X34.219 Y10.062
G1 X34.813 Y2.635
G1 X38.172 Y6.745
G1 X31.431 Y3.963
G1 X36.346 Y1.928
M5
M30
M30

This is the finished test burn after 1 pass.
It burnt the shapes in this order:
1: Square.
2: Spiral from center.
3: Circle.
4: Left Star.
5: Right Star.

untitled4

@arkypita
Copy link
Owner Author

arkypita commented Oct 1, 2018

Hi @StuartB4
Thanks for your quick feedback. You are right in all of your observations.

I have used a third-party code (heavly modified) for SVG conversion, so I was expected some issues but the desire to publish a new version was stronger than to strong test it!

I noticed the M4 command to switch the laser on, like in the picture below.
But after generating the code and saving it, I looked at the code and saw it had generated M3 instead for the laser On.

I also noticed in the code there is no return to home position code generated.
So when it had finished burning, the laser stopped at the (bottom right) end of the last line.

M3 instead of M4 and missing of Go-Home at end are known. I'll fix ASAP.

There was also an off-set of X1 and Y2 mm's added when I loaded the file in.

I think the offset was not added by the code, but already existing in your original svg drawing. Check it!

It burnt the shapes in this order [...]

It is an issue or it is ok? I think that the code is generated as found inside xms-svg code, with few control on it by my side.

@StuartB4
Copy link

StuartB4 commented Oct 2, 2018

Hi Arkypita.
Not sure about the off-set.
All I did was to draw the shapes where they are and save the .svg,
I did'nt take any notice of sizes or position, just made sure they were all inside the 40 x 40 mm square.
I just had a look at the .svg file and marked the X1 Y2 position.
So although it was'nt added intentionally it was ok.

untitled4

It burnt the shapes in this order [...]
It is an issue or it is ok? I think that the code is generated as found inside xms-svg code, with few control on it by my side.

Certainly not an issue for me, just an observation.
As long as it burns correctly I don't think it matters that much.

@arkypita
Copy link
Owner Author

arkypita commented Oct 3, 2018

Did you remove Line To Line Tracing from version 2.9.0 ?
It appears to be missing.

question removed?
no changes to raster import in 2.9
configure with "pwm support" to see line2line option

@StuartB4
Copy link

StuartB4 commented Oct 3, 2018

Sorry. My mistake. I had PWM mode switched off in settings.
That's why I deleted my comment.

@sanyats
Copy link

sanyats commented Oct 3, 2018

Здравствуйте. Все хорошо, открывает. Возможно сделать маштабирование векторов. Спасибо

@arkypita
Copy link
Owner Author

arkypita commented Oct 3, 2018

translated: Hello. All is well, opens. It is possible to do vector scaling. Thank you

Yes, as future option I will add scaling.
For now I suggest to use inkscape to prepare the image at the required size.

@Luborson
Copy link

Luborson commented Oct 10, 2018

Hi, GOOD Job !
i have some question:

  1. do you plan for filling of vectors ? (power depend for colour ?)
  2. numbering of generated lines Gcode (ON/OFF)
  3. every new append file have first move x0 y0, can by switchable to ON/OFF
  4. same like 4, but for vectorized and filled picture, outline start again from x0 y0
  5. now not work "start from specific line over green START arrow", startet again from first line, not from specified line, but ..File/Send From Possition is work well

i do test opening .SVG file exported from Corel DRAW X7 64b= works well

thanks

@MarceloFreitas028
Copy link

I also test the corel X7 SVG exportation and works well. I think that if you can develop the vectors fill it can be very useful. i export the same file filled and unfilled an this is the difference in the files.

unfilled:
capturar5

Filled:
capturar6

@arkypita
Copy link
Owner Author

  1. do you plan for filling of vectors ? (power depend for colour ?)

I can't exclude. Maybe in the future but not for now.
For now i suggest to use filling functions from your favourite SVG editor: https://wiki.evilmadscientist.com/Creating_filled_regions

@hayttle
Copy link

hayttle commented Oct 17, 2018

I can´t import SVG file.
capturar

@hayttle
Copy link

hayttle commented Oct 17, 2018

The same with new version.
capturar

@arkypita
Copy link
Owner Author

Can you submit your svg?

@hayttle
Copy link

hayttle commented Oct 18, 2018

SVG is not supported here. :(

@arkypita
Copy link
Owner Author

Zip and upload

@hayttle
Copy link

hayttle commented Oct 18, 2018

I found the error.
The file was generated from Vectric Aspire with character coded accent and the software could not deal with this.
I edited and removed this character "ã"

Tks,

@arkypita
Copy link
Owner Author

I was sure that the problem was in the file, but if you can share it (the one with issues) i can try to make the import procedure more strong and error tollerant

@hayttle
Copy link

hayttle commented Oct 19, 2018

Of course.

Another feature that would be great is can import dxf file.

Here it is.
error_file.zip

Thanks and congratulations for the good job.

@arkypita
Copy link
Owner Author

After a little search i found that xml specification define that only some character ranges are allowed in xml (svg is a form of xml file). So your file is not a valid xml file.

I have tried to strip-out any character out of valid ranges prior to parse file content and now I was able to correctly read your error_file.svg

Future version of LaserGRBL will be more strong!

@hayttle
Copy link

hayttle commented Oct 21, 2018

I'm happy to contribute to the project.
Nice job.

Do not forget to allow direct import of the dxf file, without having to convert to svg.

;)

@StuartB4
Copy link

StuartB4 commented Nov 3, 2018

Hi Arkypita.
Just been trying SVG files again.
I noticed when it generates the GCode it writes M5 twice at the top of the code.
Not a problem, just wondered why it does it.
Start Of Code:

G90
M5
M5
G0X39.6Y19.81
M4 S255
G1X39.58Y19.86 F250
X39.52Y19.92
X39.43Y19.97

The other thing I noticed is when changing the setting from M4 to M3 just before generating the GCode
It still writes M4 in the code.
Again, not a problem as it can be changed/edited in the saved GCode file if needed.
untitled1

@kareemtawab
Copy link

kareemtawab commented Nov 29, 2018

Hi @arkypita

Just been using the awesome SVG feature. I do have some issue where after an SVG had finished engraving, the machine will go over the same paths several times with the fast speed and laser turned off before going into engraving the second path, third path and so on. I mean after every path, it does that before going to the next.

SVG file:
1.zip

@kareemtawab
Copy link

Bump. Any ideas?

@StuartB4
Copy link

StuartB4 commented Dec 4, 2018

Strange problem.
I just downloaded your file, loaded it in to Inkscape and shrunk it down to fit my machine because it's only 40 x 40 mm's, saved it and loaded it in to LaserGRBL and it burned perfectlly.

For some reason though when loading it in it also showed the original size path in the window,
shown in the image below.

After it burned ok it then started to go over the original size path but without the laser coming on.

untitled2

As good as it's can be at this size.

img_5807

@StuartB4
Copy link

StuartB4 commented Dec 4, 2018

Just tried it again by cutting the object from the original document and pasting it in to a new 40 x 40 mm document. Shrunk it again to fit the document and burned it again.
This time it did it perfectly and just once.

May be worth a try to just select the object, cut it and paste it in to a new document the same size as the original.

untitled6

img_5808

@StuartB4
Copy link

StuartB4 commented Dec 5, 2018

Hi hk89.

Had a look at the file with Notepad++.
There are 3 seperate large blocks of characters in the file.
Looks like way too much for what it's actually got to do.
I removed the last 2 blocks and re-saved the file.
Could you just try this file on a piece of scrap when you have a moment.
It worked on my machine perfectly and only did it once, as it's supposed to.

12.zip

@garthanstey
Copy link

I've just got into svg files from inkscape and tried loading them into lasergrbl . The images are great but I have the problem of getting them the exact size I need. Also I have built a jig at 100mm x and y offsets so that I can rapidly repeat burns. The option to resize and offset is not present for svg and i understand you are working on this. I'd love to know how things are going.

@RudiZc
Copy link

RudiZc commented Jan 11, 2019

Hi.
I noticed just a small issue using svg conversion: I'm using illustrator and if I use millimiters as unit, when I import my file the scale change and become bigger. I found that that scale matches with the dimensions of the image if I use "points" as unit in illustrator. So now, to have the right dimensions importing an svg file, i change my measure unit in illustrator from millimiters to points and consider that as millimiters.

@chrisgrul
Copy link

Hi.
I noticed just a small issue using svg conversion: I'm using illustrator and if I use millimiters as unit, when I import my file the scale change and become bigger.

I'm having the same problem. It seems when using Illustrator, LaserGBRL considers mm to be pt and divides by about 2.83465. I had been dividing my measurements by this value but I like Rudi's suggestion as it is easier.

@arkypita
Copy link
Owner Author

arkypita commented Apr 8, 2020

Looking at the code of the project from which I took the SVG library I see that in the comments it says:

/*  GCodeFromSVG.cs a static class to convert SVG data into G-Code 
    Not implemented: 
        Basic-shapes: Text, Image
        Transform: rotation with offset, skewX, skewY

    GCode will be written to gcodeString[gcodeStringIndex] where gcodeStringIndex corresponds with color of element to draw
*/

This is exactly the cause of the problem reported here by @Ziggy2013

Looking at the code of file GCodeFromSVG.cs line 319 we can see that the code use only the param "angle" and ignore the rotation point.

if ((transform != null) && (transform.IndexOf("rotate") >= 0))
{
	var coord = getTextBetween(transform, "rotate(", ")");
	var split = coord.Split(',');
	if (coord.IndexOf(',') < 0)
		split = coord.Split(' ');
	float angle = floatParse(split[0]) * (float)Math.PI / 180;
	tmp.M11 = Math.Cos(angle); tmp.M12 = Math.Sin(angle);
	tmp.M21 = -Math.Sin(angle); tmp.M22 = Math.Cos(angle);

	if (svgComments) gcodeString.Append(string.Format("( SVG-Rotate {0} )\r\n", angle));
}

Now I'm looking for a trigonometric solution (I'm not very good with this) to implement rotation around a point other than 0.0

@arkypita
Copy link
Owner Author

arkypita commented Apr 8, 2020

It would seem to be easy, just replace the assignment of M11, M12, M21, M22 of a transformation matrix with the call to the RotateAt function.

if ((transform != null) && (transform.IndexOf("rotate") >= 0))
{
	var coord = getTextBetween(transform, "rotate(", ")");
	var split = coord.Split(',');
	if (coord.IndexOf(',') < 0)
		split = coord.Split(' ');
	float angle = floatParse(split[0]);// * (float)Math.PI / 180;
	float px = split.Length == 3 ? floatParse(split[1]) : 0.0f;
	float py = split.Length == 3 ? floatParse(split[2]) : 0.0f;

	//tmp.OffsetX = px;
	//tmp.OffsetY = py;
	//tmp.M11 = Math.Cos(angle); tmp.M12 = Math.Sin(angle);
	//tmp.M21 = -Math.Sin(angle); tmp.M22 = Math.Cos(angle);
	tmp.RotateAt(angle, px, py);
	if (svgComments) gcodeString.Append(string.Format("( SVG-Rotate {0} )\r\n", angle));
}

Tested with file pent with vines here and now is imported correctly. I am going to do more test.

@Ziggy2013
Copy link

Ziggy2013 commented Apr 8, 2020

Thanks arkypita for following up on this issue.

An explanation of how to handle rotation about a point other than the origin is here on youtube-

https://www.youtube.com/watch?v=nu2MR1RoFsA

@arkypita
Copy link
Owner Author

arkypita commented Apr 8, 2020

Release v3.1.4 (available as pre release for test) should fix the issue of rotation about point.
https://github.com/arkypita/LaserGRBL/releases/tag/v3.1.4

Let me know

@Ziggy2013
Copy link

Ziggy2013 commented Apr 8, 2020 via email

@arkypita
Copy link
Owner Author

arkypita commented Apr 8, 2020

Mail attachment does not work in github. Can you zip and load via github web page, or send them to [email protected]?

@Ziggy2013
Copy link

Ziggy2013 commented Apr 8, 2020 via email

@arkypita
Copy link
Owner Author

arkypita commented Apr 9, 2020

Thanks @Ziggy2013
In addition to the lack of "rotate at point" the problem seems to be more the ability to manage multiple transform operations (rotate translate) in the same transform attribute. In particular, the order in which these transformations are indicated because the order in which they are performed is important (while the library I used ignored this detail).

Now it should be fine with your files and, optimistically speaking, with every file.
Let me know

https://github.com/arkypita/LaserGRBL/releases/tag/v3.1.5

@Ziggy2013
Copy link

Ziggy2013 commented Apr 9, 2020 via email

@arkypita
Copy link
Owner Author

Memo: viewbox issue #1126

@lojzik
Copy link

lojzik commented Dec 6, 2020

Would it be possible to generate PWM and multiple passes count on elements from some element attribute (opacity, color, stroke-width, etc.)?

@arkypita
Copy link
Owner Author

arkypita commented Dec 8, 2020

Already in #64 development roadmap

@mtk11
Copy link

mtk11 commented Feb 14, 2021

  1. do you plan for filling of vectors ? (power depend for colour ?)

I can't exclude. Maybe in the future but not for now.
For now i suggest to use filling functions from your favourite SVG editor: https://wiki.evilmadscientist.com/Creating_filled_regions

How about when the outline and filling requires different feedrate and laser intensity ?

@ashkan4818
Copy link

ashkan4818 commented Feb 21, 2021

Draw your design using coreldraw software, then set the design scale to 10% and convert it to svg. Everything will be fine.

@maxim-kukushkin
Copy link

maxim-kukushkin commented Mar 13, 2021

I've just tried loading an SVG file with a single circle and LaserGRBL v4.2.1 seems to interpret it incorrectly (SVG and LaserGRBL-generated NC files attached in the archive)

It's shown properly in the preview, but the GCode (G3 command) is malformed. It also fails to show the frame doing the following commands (see the screenshot): it simply moves to a single point (circle center) and back
image

circle.zip

Is it a known issue or something settings are not correct?

@arkypita
Copy link
Owner Author

If I open your .svg with LaserGRBL v4.2.1 the generated gcode I have is correct.
The preview show that the boundary is computed correctly.

image

The exported output is:

G90 (use absolute coordinates)
G92 X0 Y0
M3 S0
S0 
G1X156.86Y15.47F1000
S1000 
G3X156.86Y15.47I-5.88J0F1000
S0 
M5 S0
G0 X0 Y0 (move back to origin)

@maxim-kukushkin
Copy link

Hmm... but I downloaded it from here: https://github.com/arkypita/LaserGRBL/releases and used the file that I provided. What could influence the processing of this file? Are there any runtime libraries that LaserGRBL relies on for generating paths?

@arkypita
Copy link
Owner Author

Download location is correct.

What could influence the processing of this file?

Nothing in my mind.
I don't remember it use data from configuration or grbl settings.

Are there any runtime libraries that LaserGRBL relies on for generating paths?

Maybe some issue with OS localization (internationalization, language settings, decimal point character)?

@maxim-kukushkin
Copy link

I've just tried debugging the code (though I have no experience with C#) and it seems like the root cause is somewhere in the Matrix transformations. I'm trying to run the application in Wine in Linux (yes, I know that's it's not supported, but it would be awesome to finally have an opportunity to use a GPL software to enable a laser engraver in Linux).

The .Net framework is Mono there.

Adding some prints shows that everything goes well up until Point coordij = translateIJ(i, j) (L1253 @ GCodeFromSVG.sc). j parameter has correct value of 0 (when the provided SVG is loaded). If I manually run the GCode that is supposed to be generated, everything works correctly.

However, the Point contains some small number close to 0 that Mono then serializes into -... The change that worked to me is to substitute such value with 0 if it's smaller than epsilon (gcodeRelated.cs):

        public static string frmtNum(float number)     // convert float to string using format pattern
        { return (Math.Abs(number) < 1e-7 ? 0 : number).ToString(formatNumber); }
        public static string frmtNum(double number)     // convert double to string using format pattern
        { return (Math.Abs(number) < 1e-7 ? 0 : number).ToString(formatNumber); }

Do you think it's something reasonable that could be included in the code? If so, I can create a pull request.

It makes it possible to LaserGRBL on Linux as well, which is quite important as there's currently shortage of free (and especially open source) software for lasers.

@arkypita
Copy link
Owner Author

I am sorry but I have no time now to follow the project and SVG issues.

It makes it possible to LaserGRBL on Linux as well, which is quite important as there's currently shortage of free (and especially open source) software for lasers.

FYI It was reported that LaserGRBL run good on Linux with wine 5.0 and wine mono 4.9.4 (wineprefix 32-bit) and windowsdll gdiplus.

@alastaira
Copy link

If the SVG code is rewritten at some point in the future, one really useful feature would be the option to process any interior paths contained within a shape before cutting the exterior outline of the shape itself.

Currently, I think LaserGRBL prepares the gcode by processing coordinates in the order in which they are presented in the SVG, which is normally exterior path first, followed by any interior "holes", but this is a problem for cutting interior details in a shape that might shift slightly after cutting (or, worse, fall out of the bed completely!)

My workaround for this is to separate any interior holes onto a separate layer in Inkscape, and process that first. But it would be nice if that extra step could be avoided.

@Rybec
Copy link

Rybec commented May 15, 2021

It has been a while since I've done anything with this, but I think level affects order. If you are willing to experiment, try this: Once your design is finished, select all of the elements you want to cut first, and press the "End" button on your keyboard. If you are using a Mac or a crippled laptop keyboard, you can use the menus instead: Object -> Lower to Bottom. At least in SVG 1, rendering order is based on element order, so moving to the bottom, making an object render earlier, means putting it earlier in the file.

Note that to select inner edges and manipulate them independently, you may have to convert your objects into paths before changing their render order.

(Also note that this is not about layers. Objects have an order within a layer. You can use Page Up and Page Down to move one order level at a time, or Home and End to bring them all the way to the top or the bottom. I believe that if you have multiple elements selected when you do this, they will keep their level relative to each other, but will be moved relative to everything else.)

Anyhow, if this works, it would be better than automatically doing that. I've had a few cases of my own, where I needed the outside cut to go first. I don't recall how I solved this, but I suspect I did what you did, and did it as separate cutting jobs.

If you try this, please report back here! I am also curious if this works the way I think it does, but I can't use my laser cutter to actually test it right now.

@alastaira
Copy link

alastaira commented May 16, 2021

Hi @Rybec thanks so much for your response.

Yes, your suggestion works if the interior and exterior cut lines are defined as separate paths - elements are processed first by layer, and then by order within that layer, so moving the interior cuts to the top will ensure they get processed first.

However (and I agree maybe I didn't describe this very well!), the problem I'm having is with elements that are a single path, but that have both an "interior" and "exterior". Imagine cutting a circle out from a rectangle, for example, like this: That's defined in the XML as a single path, but where the exterior coordinates are always listed first, then the interior coordinates.

image

@Rybec
Copy link

Rybec commented May 16, 2021 via email

@alastaira
Copy link

Thanks again for your attention, @Rybec, I really appreciate it.

I think we might have a terminology issue :) I'm not talking about an object containing multiple paths, but rather an object consisting of a single path that has multiple, closed sections (i.e. if you examine the SVG, there are mutiple sections within the path element, each separated by a z closepath command). I'm not certain what the correct terminology is, but I guess these might be referred to as "subpaths", or perhaps the whole thing is a "compound path".
I agree that if I were designing a file to be lasercut directly in Inkscape I would define these as separate objects, but unfortunately this is how they are defined when brought in from a CAD program I am using (OpenSCAD) .

I did try to use Object to Path as you suggested, but it didn't have any effect, I assume because the selected object already is a path. (I'm familiar in general with turning any Inkscape objects into paths before exporting)

I've attached a link to a simple file to illustrate the situation - I'd be really grateful if you could take a look just to make sure we have a common understanding of the problem :) : https://drive.google.com/file/d/1ikISmu4ZgXksLr8d1gE2cuIteIxY3I_U/view?usp=sharing

Thanks,

@alastaira
Copy link

Path -> Break Apart will promote the subpaths into their own paths. All I need to do is to make sure that the new path elements created are inserted in the SVG document structure before the "parent" path from which they were just detached. That, I think, will solve my problem.

@Rybec
Copy link

Rybec commented May 16, 2021

Yeah, exporting SVGs from other CAD software doesn't always come out intelligently. I wish those companies would put more effort into making their software play well. (Adobe is the worst offender, because it uses a non-standard scale for SVG, which will make your cuts come out the wrong size. They claim to be professional, but I hardly consider blatantly ignoring the SVG standard to be professional.)

First, compound path is probably the right terminology here, and the independent sections would be subpaths. (I apologize if I came off as patronizing. Terminology issues are a huge reason for miscommunication, so I like to try to resolve those very early, and it can come off as talking down to people. That was not my intent.)

Second, it sounds like you found the missing step! Once you've broken the compound path into its component paths, you should be able to change the order the way I described above, to get them to cut in the right order (assuming I am recalling correctly).

Ok, so I just checked, and it looks like that workflow should do what you want. Use Path -> Break Apart, then select the elements you want to cut first and press End or use Object -> Lower to Bottom.

I tested this with the image you provided. When I loaded it in LaserGRBL, the laser path went to the top right square first, and then worked counter-clockwise through the squares (though it looks like a couple were out of order with the rest). Just to verify, I then selected only the main object border (it turns out there are two lines there, so I selected both) and lowered them to the bottom. When I reloaded the file in LaserGRBL, it went straight to the outer lines first.

In theory, if you wanted to do path optimization (I wouldn't bother for highly complex objects, unless cutting time is a serious issue), you could select elements one by one, lowering them to bottom, in the reverse order you want them cut (or you could raise them to top in the order you want them cut). Inkscape doesn't provide any way of telling Z order though, aside from rendering order, which only works when things are overlapping.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests