How to control layers when exporting an SVG

I export an SVG from Processing, load into Inkscape, and then send to my AxiDraw. I would like to separate the image into three separate layers, RGB, or CMY in the exported SVG. This will allow me to print different layers with different pens on my axiDraw.

Is there any way to control the hierarchy of objects/layers in the processing canvas that gets sent to SVG? Right now processing seems to throw everything under level or two of ‘subdirectory’ (don’t know the right term) . Would be nice if i could maybe use "beginShape() endShape()" with some parameters to isolate tranches of curveVertex() so that they are segregated meaningfully rather than simply order-of-creation.

I thought maybe I could nest beginShape() and endShape() statements to get a nested object layers. Alas, no, it gave me a wierd subdirectory structure and a bunch of objects that were blank (highlighted in red)

add_library(“svg”)

def settings():

#size(300,300)
FN="foo.svg"
size(300,300, SVG, FN)

def setup():
noLoop()

def draw():

beginShape()
circle(20,20,10)
endShape()

beginShape()
circle(50,50,10)
endShape()

beginShape()
beginShape()
circle(80,80,10)
endShape()
beginShape()
circle(90,90,10)
endShape()
endShape()
print("done")

How about trying separate SVG files? Something like –

beginRecord(SVG, 'circles.svg')
circle(100, 100, 50)
circle(200, 100, 50)
endRecord()

beginRecord(SVG, 'squares.svg')
square(100, 300, 50)
square(200, 300, 50)
endRecord()

You can then open the SVGs in a text editor and combine them, defining your own group (<g>) tags. Or, automate this process using Python’s xml.etree module.

1 Like

To add to my previous response, here’s an xml.etree example:

add_library('svg')
# xml.etree module
from xml.etree import ElementTree

svgs = ['circles.svg', 'squares.svg']

# create a circles.svg and draw circles in it
beginRecord(SVG, svgs[0])
fill('#FF0000')
circle(10, 10, 10)
circle(50, 10, 10)
endRecord()

# create a squares.svg and draw squares in it
beginRecord(SVG, svgs[1])
fill('#0000FF')
square(10, 30, 10)
square(50, 30, 10)
endRecord()

# create an empty combined.svg file
beginRecord(SVG, 'combined.svg'); endRecord()
ElementTree.register_namespace('', 'http://www.w3.org/2000/svg')
tree = ElementTree.parse('combined.svg')
combined = tree.getroot()

# add the (circles/squares) svgs to the combined.svg file
for svg in svgs:
    file = ElementTree.parse(svg).getroot()
    group = ElementTree.SubElement(combined, 'g')
    group.set('id', svg)
    for child in file.getchildren():
        group.append(child)

# save the changes to the combined.svg file
tree.write('combined.svg')
1 Like

Wow, this is a great headstart, Thank you.

A question about the result (viewed in Inkscape). Somehow Inkscape sees the various layers as sudirectories of objects in the Objects pane. However, it sees nothing in the Layers pane. I don’t understand this behavior. Because even the icon for the ‘subdirectory’ squares.svg, I can right-click and it offers me the option to rename layer. So it quacks like Layer and looks like a Layer, but Inkscape doesn’t call it a Layer in the layers pane.

This isn’t pedantic issue – I have an inkscape plugin for my AxiDraw that allows me to print by specific layer name. Since there are no listings in the layer pane, I cannot use that Axidraw plugin plot-by-layers functionality.

Very easily could be something I fundamentally misunderstand with Inkscape…

2 Likes

Inkscape adds its own embellishments to the standard SVG format, including attributes to define layers. Add these two inkscape:-prefixed attributes to your Processing code:

    ...
    group.set('id', svg)
    group.set('inkscape:groupmode', 'layer')
    group.set('inkscape:label', svg)
    ...

BTW, I’m in the process of ordering an AxiDraw (A3) right now. Thanks to you, I’m learning how it works before I’ve even got my hands on it :smiley:

1 Like

Yeah, that fixed it perfectly. This is going to help my workflow immensely. Thanks

I found a handful of tutorials on SVG at the bottom – are there any other resources you suggest to understand the details of svg?

Yeah, I’ve coveted an AxiDraw for many years and at times was tempted to just buy a cheap aliexpress clone. They’re not cheap and I wasn’t keen to learn a new toolchain. Covid cancelled my vacation, so I used that money to buy an SE/A3. Really glad I bought the AxiDraw – the fit and finish, not only of the machine, but all the supporting documentation, is amazing. I’ve never read such refined documentation. The inkscape plugin works well, and Oskay seems to answer support queries on Discord at any moment of the day.

I would recommend:

  1. buying extra pen-lift servos. They’re cheap, easy to replace, and will fail when it’s least convenient. (they’re a slow-motion disposable part)
  2. buying the magnetic easel. These are flatter, stiffer, and hold the paper more easily, especially weird-shapes, than the particle board thing that comes stock.
  3. potentially buy the pen rotation stage and the XL pen clip if you want to print with weird markers, etc.
2 Likes