How can I manipulate the vertices of an svg?

edited March 2014 in How To...

I'm having issues manipulating the points in an SVG loaded through PShape. getVertexCount() and getVertex() both work on a rectangle drawn within Processing, but they fail on an external SVG. The SVG in question is a simple rectangle for testing purposes.

Here's the simple test I ran:

PShape rectangle;
PShape file;

void setup() {
  size(800,600,P2D);
  rectangle = createShape(RECT,width/2-50,100,100,50);
  file = loadShape("file.svg");

  println(rectangle.getVertexCount());
  println(file.getVertexCount());
  println();
  println(rectangle.getVertex(0));
  //println(file.getVertex(0));
}

void draw() {
  background(50);
  shape(rectangle);
  shape(file);
}

The output I get is correct for the rectangle (4, and a vertex), but wrong for the SVG (0 and a null pointer exception when it's not commented out).

Is this a known issue or am I doing something incredibly stupid somewhere? I've tried with the latest version of processing, both 32 and 64 bit, as well as the previous version in 64 bit. I have the same problem with all. I'm running Windows 7 x64.

Thanks in advance. :)

Tagged:

Answers

  • edited March 2014

    First remark: playing with your code and a simple random SVG file I had at hand (generated from my P8gGraphicsSVG library from a simple rectangle shape), I noticed that a shape loaded in P2D mode is a PShapeOpenGL instead of a PShapeSVG. I don't know if it makes a practical difference, but it is interesting to know...

    So I commented out the rectangle code and I experimented a bit more.

    You have to know that most SVG files have a complex structure, grouping elements inside g tags (groups). So often you have to dig deeper. For example, for my file, I had to do:

    PShape file;
    
    void setup() 
    {
      size(800,600);
      file = loadShape("Simple.svg");
      println(file);
    
      println(file.getVertexCount());
      println(file.getChildCount());
      println();
      println(getFamilyName(file.getChild(1).getFamily()));
      println(file.getChild(1).getChildCount());
      println();
      PShape c = file.getChild(1).getChild(1).getChild(0); 
      println(c);
      println(c.getChildCount());
      println(getFamilyName(c.getFamily()));
      println(getKindName(c.getKind()));
      println(c.getParams());
    }
    
    void draw() 
    {
      background(50);
      shape(file);
    }
    
    String getFamilyName(int family) 
    {
      switch (family) 
      {
      case GROUP:
        return "GROUP";
      case PShape.PRIMITIVE:
        return "PRIMITIVE";
      case PShape.GEOMETRY:
        return "GEOMETRY";
      case PShape.PATH:
        return "PATH";
      }
      return "unknown: " + family;
    }
    
    String getKindName(int kind) 
    {
      switch (kind) 
      {
      case LINE:
        return "LINE";
      case PShape.ELLIPSE:
        return "ELLIPSE";
      case PShape.RECT:
        return "RECT";
      case 0:
        return "(PATH)";
      }
      return "unknown: " + kind;
    }
    

    For the record, the file (made by drawing a simple rect() with a big stroke width) is:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN'
              'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>;
    <svg xmlns:xlink="http://www.w3.org/1999/xlink" style="fill-opacity:1; color-rendering:auto; color-interpolation:auto; stroke:black; text-rendering:auto; stroke-linecap:square; stroke-miterlimit:10; stroke-opacity:1; shape-rendering:auto; fill:black; stroke-dasharray:none; font-weight:normal; stroke-width:1; font-family:'Dialog'; font-style:normal; stroke-linejoin:miter; font-size:12px; stroke-dashoffset:0; image-rendering:auto;" width="600" height="600" xmlns="http://www.w3.org/2000/svg"
    ><!-- Generated by Processing with the P8gGraphicsSVG library --><defs id="genericDefs"
      /><g
      ><g style="fill:white; text-rendering:geometricPrecision; stroke-linecap:round; image-rendering:optimizeQuality; stroke:white;"
        ><rect x="0" width="600" height="600" y="0" style="stroke:none;"
        /></g
        ><g style="fill:rgb(69,103,137); text-rendering:geometricPrecision; stroke-width:20; stroke-linecap:round; image-rendering:optimizeQuality; stroke:rgb(69,103,137);"
        ><rect x="200" width="300" height="300" y="200" style="stroke:none;"
        /></g
        ><g style="stroke-linecap:round; fill-opacity:0.0784; fill:rgb(0,0,0); text-rendering:geometricPrecision; image-rendering:optimizeQuality; stroke:rgb(0,0,0); stroke-width:20; stroke-opacity:0.0784;"
        ><rect x="200" width="300" height="300" y="200" style="fill:none;"
        /></g
      ></g
    ></svg
    >
    
Sign In or Register to comment.