Skip to main content

Reading SVG Path information in Processing with Geomerative

Recently I have been using the Geomerative library for Processing to read SVG files.  I'm interested in using SVG files to determine paths for CNC machines.  The Geomerative example for loading an SVG file simply has:

RShape shp = RG.loadShape("tiger.svg");

to load an SVG file.  I found this a little restrictive, since all the paths within an SVG file are stored in one shape variable.  Digging deeper in the source code, the problem is because the loadShape( filename ) command further calls a command called elemToCompositeShape(), and this has the effect of merging all the unique paths into one single path.

To get around this you need to make a series of manual calls to load an SVG file and store away the information all for unique path information.  The following example sketch encapsulates these commands, and store the shapes (paths) to a global array list.

// include the geomerative library
import geomerative.*;

// Store our shapes in an array list
ArrayList shapes;

// Processing requires setup
void setup() {

   // Geomerative requires this call first of all.
   shapes = new ArrayList();

   loadSVGFile( "path_to_your_file");

// Processing requires a draw function
void draw() {

// Loads an SVG file and parses for shapes (paths)
void loadSVGFile( String filename ) {
   RSVG svgLoader = new RSVG();
   RGroup new_group = svgLoader.toGroup( filename );
   createPaths( new_group );

// Will call recursively if more groups of shapes are found.
void createPaths( RGroup group_in ) {
  int e; 

  println(" Found " + group_in.countElements() + " elements");  

 // loop through each element in the group, store if it is a 
 // shape (path), call this same function again if it is another
 // group, or ignore otherwise.
  for ( e = 0; e < group_in.countElements (); e++ ) {
    switch( group_in.elements[0].getType() ) {
      case RGeomElem.MESH:
        println(" ignoring Mesh");
      case RGeomElem.GROUP:
        println(" Found another Group");
        RGroup new_group = (RGroup)group_in.elements[e];
        createPaths( new_group );
      case RGeomElem.POLYGON:
        println(" ignoring polygon");
      case RGeomElem.SHAPE:
        println(" Found shape, adding to list");
        RShape new_shape = group_in.elements[e].toShape();
       shapes.add( new_shape );
        println(" unknown: " + group_in.elements[e].getType() );