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.
   RG.init(this);
   shapes = new ArrayList();

   loadSVGFile( "path_to_your_file");
 
}


// Processing requires a draw function
void draw() {
   exit();
}


// 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 );
   return;
}

// 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");
        break;
      case RGeomElem.GROUP:
        println(" Found another Group");
        RGroup new_group = (RGroup)group_in.elements[e];
        createPaths( new_group );
        break;
      case RGeomElem.POLYGON:
        println(" ignoring polygon");
        break;
      case RGeomElem.SHAPE:
        println(" Found shape, adding to list");
        RShape new_shape = group_in.elements[e].toShape();
       shapes.add( new_shape );
        break;
      default:
        println(" unknown: " + group_in.elements[e].getType() );
    }
  }

 return;
}


5 comments:

Anonymous said...

Hello
Absolute beginner in programming. A pair of months ago I'm began with processing interested in manipulate vector files. My goal is to generate some shape variations from my own vector drawings.Trying to access the objects from an SVG file independently I found geomerative library and then this awesome piece of code that seems to solve the problem. Now I'm simply trying to call this objects from the arraylist and display them in the screen, but I'm really stuck since I barely understand geomerative reference. How can I call one of this objects and display it in the screen?. I would appreciate any orientation about it.

Paul said...

Hi.

I didn't provide a type argument for the arraylist, this means that you'll need to do something like the following to retrieve objects from it:

int i;
for( i = 0; i < shapes.size(); i++ ) {
RShape shape = (RShape) shapes.get(i);
shape.draw();
}

Note that RShape is a type from the geomerative library. So within the for loop, we create a variable called shape of type RShape. Similarly, using (RShape)shapes.get(i) informs java that we expect to retrieve the same type from the array list.

Hope that helps? The documentation for RShape can be found here http://www.ricardmarxer.com/geomerative/documentation/index.html

Anonymous said...

Aye,

I'm beginning in processing because I heard a lot about geomerative. I noticed that you read SVG files to determine paths for CNC machines. Does it mean that you generate some gcode ?

I'm also interested in CNC machine. I found this code https://github.com/thibalte/Presto/blob/master/software/svg2gcode/svg2gcode.pde

But, even this code works well, I have some trouble with the result. The gcode file in output is only composed by the command G0 that is not allowed to trace some arc.

I would like to implement the command G2/G3 in this code but I don't know if there is a way to make the difference between a line and a curve.

Anonymous said...

coming back here I discovered I didn't replied this (?!). Thank you very much for the explanation. It worked, I managed to access the shapes, move them in the screen and after some other issues my little project is nearer of what I'm looking for. Thanks.

Morten Ydefeldt said...

Did you get further with this? I would like to make it possible in Processing to generate G2/G3 tool paths for CNC (GCODE)..

Post a Comment