Scripting Inkscape

General discussions about Inkscape.
pfeuh
Posts: 13
Joined: Fri Jun 21, 2019 2:51 pm

Scripting Inkscape

Postby pfeuh » Fri Jun 21, 2019 4:09 pm

Hello,

I'm totally newbee, not native speaker and in retirement... That's done. :D

In a fablab in my neighbourhood, they have now a laser cutting machine which can be driven by an inkscape file. I would like to use this machine to cut and engrave front pannels made in a kind of wood designed for this machine.

The problem is that I am totally newbee to inkscape, so I think to script something like:

sheet = inkscapeDocument("testfile")
sheet.cutRectangle(0, 100, 200, 300)
sheet.cutCircle(120,120,10)
sheet.cutCircle(140,120,10)
sheet.cutCircle(160,120,10)
sheet.engraveText(100, 100, "hello world")
sheet.close()

I've read something about a python library called "inkex" in this wiki:

Python_modules_for_extensions

But I failed to download it... Does somebody has an experience, a link or a tutorial I can use?

Regards,

Pfeuh

Moini
Posts: 3381
Joined: Mon Oct 05, 2015 10:44 am

Re: Scripting Inkscape

Postby Moini » Fri Jun 21, 2019 9:18 pm

Hi Pfeuh,

inkex is already shipped with Inkscape, it's the base for all the extensions that are included.

There already exist various extensions for cutting and plotting with Inkscape, but you need to find the correct one for the machine.

What I would do if I were you:
- ask someone in the Fablab! They will most certainly know what type of instructions the machine will take.

Things to ask:

- What type of code / file does the machine take?
- What software / Inkscape extension would you recommend for creating that code / file?
- How is that code / file transferred to the machine?
Something doesn't work? - Keeping an eye on the status bar can save you a lot of time!

Inkscape FAQ - Learning Resources - Website with tutorials (German and English)

pfeuh
Posts: 13
Joined: Fri Jun 21, 2019 2:51 pm

Re: Scripting Inkscape

Postby pfeuh » Fri Jun 21, 2019 10:06 pm

Hello Moini,

Thanks for this information. Unfortunately, there is not yet a good knowledge in the fablab concerning the laser cut machine. I think it's feeded with gcode. A lot of people here create gcode with a lot of softwares. Whem the picture is done, they modify the gcode to make it understandable for the machine, which is binded to a PC, so all kinds of file transmission are possible. When I asked about the software to use for my cuts, they said "use inkscape". I will have more information this weekend.

Now, I'm going to have a look to the inscape embedded python code.

Regards,

Pfeuh

Moini
Posts: 3381
Joined: Mon Oct 05, 2015 10:44 am

Re: Scripting Inkscape

Postby Moini » Sun Jun 23, 2019 3:00 am

Inkscape comes with the gcodetools extension, I suppose that's what they mean.
Something doesn't work? - Keeping an eye on the status bar can save you a lot of time!

Inkscape FAQ - Learning Resources - Website with tutorials (German and English)

Moini
Posts: 3381
Joined: Mon Oct 05, 2015 10:44 am

Re: Scripting Inkscape

Postby Moini » Sun Jun 23, 2019 3:00 am

(it generates gcode)
Something doesn't work? - Keeping an eye on the status bar can save you a lot of time!

Inkscape FAQ - Learning Resources - Website with tutorials (German and English)

pfeuh
Posts: 13
Joined: Fri Jun 21, 2019 2:51 pm

Re: Scripting Inkscape

Postby pfeuh » Thu Jun 27, 2019 12:14 am

Some news. I've found the svgwrite module in the inkscape binary directory , I copied it to my usual python site-packages directory and I've started to python script. It works pretty well.

Some things are not clear for me, perhaps you can help me or drive me to a beginner tutorial? For instance:
- can I select a single unit for all the drawing?
- I have some syntax problems, sometime I can wite ("7in", "5in"), in for inches, sometime it raises an user error, than I have to write just "7", But I"m not sure it is interpreted as inches

Regards,

Pfeuh

Code: Select all

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import os
import svgwrite

def addLed(sketch, x, y, r):
    sys.stdout.write( "led %f %f %f\n"%(x, y, r))
    shape = svgwrite.shapes.Circle(center=("%1.3fin"%x, "%1.3fin"%y),
        r="%1.3fin"%r, fill="none", stroke="red")
    sketch.add(shape)

def addRoundedRectangle(sketch, x, y, w, h, corner_radius):
    x -= x / 2.0
    y -= w / 2.0
    sys.stdout.write( "rect %f %f %f %f %s\n"%(x, y, w, h, corner_radius))
    shape = svgwrite.shapes.Rect(insert=("%1.3fin"%x, "%1.3fin"%y),
        size=("%1.3fin"%w, "%1.3fin"%h), stroke="red", fill="none",
        rx="%1.3fin"%corner_radius, ry="%1.3fin"%corner_radius)
    sketch.add(shape)

sketch = svgwrite.Drawing(filename="front_pannel.svg", debug=True)
#~ unit = svgwrite.Unit(unit="inch")
#~ unit="inch"
pannelWidth = 7.8
pannelHeight = 5.2
xCenter = pannelWidth * 0.5
yCenter = pannelHeight * 0.5
ledRadius = 0.12

# let's compute borders
pannelWidth = 7.8
pannelHeight = 5.2
xCenter = pannelWidth * 0.5
yCenter = pannelHeight * 0.5
addRoundedRectangle(sketch, xCenter, yCenter, pannelWidth, pannelHeight, 0.2)

# let's compute step leds
x = xCenter - 2.975
y = yCenter - 0.025
r = ledRadius
for led_num in range(16):
    addLed(sketch, x, y, r)
    x += 0.35

# let's compute individual leds
x = xCenter - 2.975
y = yCenter - 1.4
r = ledRadius
# led start
addLed(sketch, x, y, r)
# led stop
x += 0.70 * 3.0
addLed(sketch, x, y, r)
# leds sequences
x += 0.70 * 1.5
for led_num in range(5):
    addLed(sketch, x, y, r)
    x += 0.70

sketch.save()

Moini
Posts: 3381
Joined: Mon Oct 05, 2015 10:44 am

Re: Scripting Inkscape

Postby Moini » Thu Jun 27, 2019 11:02 am

No idea how you get that svgwrite Python module. Is it included in the Windows package?

Looks like you're now asking for help with writing SVG code? With svgwrite? Never used that, sorry, can't say anything about it.

I'm also not sure how that is related to the gcode question you had.
Something doesn't work? - Keeping an eye on the status bar can save you a lot of time!

Inkscape FAQ - Learning Resources - Website with tutorials (German and English)

pfeuh
Posts: 13
Joined: Fri Jun 21, 2019 2:51 pm

Re: Scripting Inkscape

Postby pfeuh » Thu Jun 27, 2019 4:23 pm

Moini wrote:Is it included in the Windows package?

No, it is not. But often python developpers use their own python distribution(s). For instance I use a python 2.7 and a python 3.x. As the embedded Inkscape python library is pure python (only scripts, no dll), it's easy to copy it from Inkscape to my own distributions. That's what I"ve done. For your information there is a full embedded python in Incscape. It's a 2.6, really obsolete, enough to write some SVG stuff but that's all.

Moini wrote:Looks like you're now asking for help with writing SVG code?

No, rather to get Inkscape's basics. I understand that only a few people use Inscape python scripting.

pfeuh
Posts: 13
Joined: Fri Jun 21, 2019 2:51 pm

Re: Scripting Inkscape

Postby pfeuh » Fri Jun 28, 2019 1:28 am

I've done close to what I wanted to to. My coordinates system goes from left to right for x and from bottom to top for y. When I assign x y to a shape, it"s from the center of the shape. I give the unit I want to use once, after I use only floats, as the unit is already defined. That gives a more adapted script for an electronic designer who would like to laser cut a front pannel for the board he is designing.

I have a last problem concerning the text shape. In python/tkinter is is possible to anchor the text from the center of its area. I'ts the more logical way to draw a text, because if you change the text size, it's stay centered. I haven't found something like this in svgwriter (I suppose it's also the same in Inkscape), I can only anchor a text from the left. Am I wrong?

Regards,

Pfeuh

Code: Select all

#!/usr/bin/python
# -*- coding: utf-8 -*-

import svgwrite
import sys


VERBOSE = "-verbose" in sys.argv
DRAFT = "-draft" in sys.argv

class SKETCH():
    def __init__(self, fname, unit="mm"):
        self.__sketch = svgwrite.Drawing(fname, profile='tiny')
        self.changeUnit(unit)
       
    def cvrt(self, value):
        return float(value) * self.__coeff
       
    def changeUnit(self, unit):
        if unit ==  "mm":
            self.__coeff = 1.0
        elif unit == "cm":
            self.__coeff = 10.0
        elif unit == "in":
            self.__coeff = 25.4
        else:
            raise Exception("Not implemented unit \"%s\"\n"%self.__unit)
        self.__unit = unit

    def __setCutParameters(self, cut, **kwds):
        if cut and not DRAFT:
            kwds["stroke"] = "red"
            kwds["fill"] = "none"
            kwds["stroke_width"] = 0.01
        else:
            if not "stroke" in kwds.keys():
                kwds["stroke"] = "black"
            if not "fill" in kwds.keys():
                kwds["fill"] = "none"
            if not "stroke_width" in kwds.keys():
                kwds["stroke_width"] = 0.1
        return kwds
       
    def addRectangle(self, x, y, w, h, radius=0, cut=False, **kwds):
        x, y, w, h, radius = self.cvrt(x), self.cvrt(y), self.cvrt(w), self.cvrt(h), self.cvrt(radius)
        x = x - w / 2.0
        y = 0.0 - y - h / 2.0
        kwds = self.__setCutParameters(cut, **kwds)
        if VERBOSE:
            sys.stdout.write("rectangle cut=%s %f %f %f %f %s\n"%(cut, x, y, w, h, str(kwds)))
        shape = svgwrite.shapes.Rect(insert=(x, y),size=(w, h),rx=radius, ry=radius, **kwds)
        self.__sketch.add(shape)

    def addCircle(self, x, y, r, cut=False, **kwds):
        x, y, r = self.cvrt(x), 0.0 - self.cvrt(y), self.cvrt(r)
        kwds = self.__setCutParameters(cut, **kwds)
        if VERBOSE:
            sys.stdout.write("circle    cut=%s %f %f %f %s\n"%(cut, x, y, r, str(kwds)))
        shape = svgwrite.shapes.Circle(center=(x, y), r=r, **kwds)
        self.__sketch.add(shape)

    def addText(self, text, x, y, cut=False, **kwds):
        x, y = self.cvrt(x), self.cvrt(y)
        #~ x = x - w / 2.0
        #~ y = 0.0 - y - h / 2.0
        kwds = self.__setCutParameters(cut, **kwds)
        shape = svgwrite.text.Text(text, insert=(x, y), **kwds)
        self.__sketch.add(shape)

    def save(self):
        self.__sketch.save()

if __name__ == "__main__":

    sketch = SKETCH('test.svg', "in")
   
    LED_X_OFFSET = -2.975
    LED_RADIUS = 0.06
    LED_WIDTH = 0.35
    LED_HEIGHT = 1.1
    BUTTON_X_OFFSET = -2.95
   
    # let's compute front pannel border
    sketch.addRectangle(0, 0, 7.8, 5.2, 0.15, True)

    # let's compute step leds
    x = LED_X_OFFSET
    y = -0.025
    r = LED_RADIUS
    for led_num in range(16):
        sketch.addCircle(x, y, r, True)
        x += LED_WIDTH

    # let's compute individual leds
    x = LED_X_OFFSET
    y = -1.4
    r = LED_RADIUS
    # led start
    sketch.addCircle(x, y, r, True)
    # led stop
    x += LED_WIDTH * 6.0
    sketch.addCircle(x, y, r, True)
    # leds sequences
    x += LED_WIDTH * 3.0
    for led_num in range(5):
        sketch.addCircle(x, y, r, True)
        x += LED_WIDTH * 2.0
    # leds sequence, global
    x -= LED_WIDTH * 2
    for led_num in range(2):
        y += LED_HEIGHT
        sketch.addCircle(x, y, r, True)
    # leds rest, tie, last step
    y += LED_HEIGHT
    x = LED_X_OFFSET
    for led_num in range(3):
        sketch.addCircle(x, y, r, True)
        x += LED_WIDTH * 2
       
    # let's compute buttons
    w = 0.5
    h = 0.35
    r = 0.1
    x = BUTTON_X_OFFSET
    y = -1.765
    # buttons start, stop, continue, record
    for button_num in range(4):
        sketch.addRectangle(x, y, w, h, r, True)
        x += LED_WIDTH * 2.0
    # buttons sequences 1...5
    x += LED_WIDTH
    for button_num in range(5):
        sketch.addRectangle(x, y, w, h, r, True)
        x += LED_WIDTH * 2
    # buttons sequence, global, return
    x -= 0.7
    for button_num in range(3):
        y += LED_HEIGHT
        sketch.addRectangle(x, y, w, h, r, True)
    # buttons rest, tie, last step
    x = BUTTON_X_OFFSET
    for button_num in range(3):
        sketch.addRectangle(x, y, w, h, r, True)
        x += LED_WIDTH * 2

    # let's compute 4x7 segments
    sketch.addRectangle(0.2, 1.52, 1.582, 0.5, 0, True)

    # let's compute encoder button
    sketch.addCircle(1.850, 1.5, 0.350, True)

    sketch.addText("TotoTitiTata", 0, 0 ,font_size=2)

    sketch.save()

Moini
Posts: 3381
Joined: Mon Oct 05, 2015 10:44 am

Re: Scripting Inkscape

Postby Moini » Fri Jun 28, 2019 4:26 am

Latest Inkscape comes with 2.7 on Windows, as far as I know. Sorry, tkinter isn't my specialty. I know how to write normal Inkscape extensions (for the 0.92.x series, it will be different for 1.0), and have only very rarely used any GUI frameworks.
Something doesn't work? - Keeping an eye on the status bar can save you a lot of time!

Inkscape FAQ - Learning Resources - Website with tutorials (German and English)

pfeuh
Posts: 13
Joined: Fri Jun 21, 2019 2:51 pm

Re: Scripting Inkscape

Postby pfeuh » Tue Sep 10, 2019 4:09 pm

Hello,

As I could't get enough help on this "confidential" python library, I've done one. No need to have inkscape or exotic python library, it generates svg files. It's really brutal, but it works fine. It's here, on github site:

https://github.com/pfeuh/yass/tree/mast ... /scriptSvg

pfeuh wrote:the laser cut machine. I think it's feeded with gcode.


I was wrong, it's feeded with dxf files.

Here is the svg file generated with the tiny library:

test.svg
(50.99 KiB) Downloaded 75 times



Regards,

Pfeuh


Return to “General Discussions”