Squirtle - an SVG mini-library for Pyglet

As some of you may know, last PyWeek, as part of our entry, Robot Underground, I wrote a fairly minimal Pyglet-based SVG parser and renderer. Since then, I've seen a number of people do similar things for their Pyglet projects.

Rather than have people continually reinvent the wheel, I've taken the parser from RU, and spruced it up a bit. I'm releasing it under a BSD license, similar to that used for Pyglet itself. You can read about it and download a copy from the Super Effective website. It's not perfect, and it's by no means complete, but as far as I'm aware, it's the best pure-Python solution out there to the problem.

I'd appreciate any comments, and particularly any bug reports or patches.

(log in to comment)

Comments

Oh this frickin' ROCKS!!!

Two questions:

  1. Is there any chance of it being converted to use pyglet.graphics? I'll look into this if you've no interest.
  2. Is there any chance of getting holes? Easy enough to work around, but would be nice :)
Oh, and the cocos2d guys have been working on vector lines with caps :)

richard: Glad you like it!

It was using pyglet.graphics, but I started getting weird artifacts. I meant to report a bug, work up a test case, etc, but various things intervened. There's some commented out code in there that might still work, or might not. I can't remember. I'll look into it again when I get some free time, or I'm happy to answer any questions anyone else has if they want to try.

As for holes, they would require rewriting the triangulation algorithm, which I probably should do anyway. It's a big job though, and I'd like to do a little research first into how best to do it, particularly as it's the most computationally intensive part of the code.

How do the vector lines with caps work? Are you turning the lines into polygons?

I'm not the guy doing the cocos2d work and I've not looked at his code.

A friend has given me his (in his view) quite optimal and optimised triangulation code. It doesn't handle holes and is written in C++ but he'd given me permission to transcode it to Python if I got a chance. Would you be interested in seeing it?

I don't think there's much point in rewriting the triangulation code if I'm not rewriting it to allow holes. At the moment, I've got a little bit done on an implementation of this algorithm, but it'll probably be a while before it's finished.

OK that's cool :)
hi, ive done some line drawing with cocos2d (http://cocos2d.org, see europython branch). im splitting the line into triangles and using textures to get nice caps and joins. ive been talking with richard and i think the line code i have could be nicely integrated with squirtle if we can collaborate on that, so we can also get a nice vector drawing api for cocos. what do you think? lucio.
I've used gluTesselator functions before to perform triangulation of some random concave polygons. It can handle holes as well.

I no longer have the code, but its relatively easy to use. google gluNewTess for more info.
Hey i would be interested in porting this to panda3d as some thing as svg2egg tool (egg is common geometry format for panda3d.) May i do that?

simonwittber: Hmm. I had a brief look at the gluTesselator functions, but thought it was likely to require more Python/C interfacing than I was comfortable with (e.g. passing Python functions as C callbacks). Perhaps I should take another look. How widely available are the gluTesselator functions?

Treeform: Port away! It's under a BSD license, so I couldn't stop you even if I wanted to. I'd just ask that I am credited appropriately, and that you keep me up to date on what you're doing (particularly any improvements you make).

Wow this library is a good enough reason to use pyglet this time around :-D I bet I'll use it for my solo. I am soooooo psyched about this :D You guys should port this to pygame too (if possible)
Hmm, after loading an SVG I drew in InkScape I get this error:
Traceback (most recent call last):
  File "run_game.py", line 12, in 
    main()
  File "run_game.py", line 9, in main
    m.main()
  File "lib/main.py", line 12, in main
    game.Game(window)
  File "lib/game.py", line 14, in __init__
    LoadSVGS()
  File "lib/images.py", line 11, in LoadSVGS
    "player": squirtle.SVG(pygutil.filepath("data/ship.svg")),
  File "lib/squirtle.py", line 177, in __init__
    self.generate_disp_list()
  File "lib/squirtle.py", line 223, in generate_disp_list
    self.parse_doc()
  File "lib/squirtle.py", line 315, in parse_doc
    self.parse_element(e)
  File "lib/squirtle.py", line 468, in parse_element
    self.parse_element(c)    
  File "lib/squirtle.py", line 464, in parse_element
    self.gradients[e.get('id')] = LinearGradient(e, self)
  File "lib/squirtle.py", line 94, in __init__
    style = parse_style(e.get('style'))
  File "lib/squirtle.py", line 32, in parse_style
    key, value = item.split(':')
ValueError: need more than 1 value to unpack
Help?
psyched just died....
lol
pymike: Can you email the problem SVG file to martin@supereffective.org? I'll have a look into it asap.
Done :-)
squirtle doesnt work with py2exe due to it not having the parse function within the xml.etree...
http://nuigroup.com/forums/viewthread/4758/ shows the error
You can work around this issue by replacing the reference to cElementTree with ElementTree, but this slows down parsing considerably. Still, it's better than straight-out crashing.