box2D + SVG : close poly shapes

hello,

i wonder how i can correctly grab the shapes from an SVG file and import it into a box2D world.

For now i can import it but i have problems with shapes linked together…

Is it a problem while converting the svg to polyline ? or a problem while creating the svg (i used Illustrator and Inkscape) ?

my SVG file :

Result :

void ofApp::setup() {
    
    ofSetVerticalSync(true);
    ofBackgroundHex(0x0);
    ofSetLogLevel(OF_LOG_NOTICE);
    
    box2d.init();
    box2d.setGravity(0, 10);
    box2d.createBounds();
    box2d.setFPS(60.0);
    box2d.registerGrabbing();
    
    svg.load("contour.svg");
    for (int i = 0; i < svg.getNumPath(); i++){
        ofPath p = svg.getPathAt(i);
        
        vector<ofPolyline> outline = p.getOutline();
        // convert to polyline for further processing
        for (int i = 0; i < outline.size(); i++) {
            contour.addVertices(outline[i].getVertices());
        }
        
        if (contour.isClosed()) {
            p.close();
            p.setFilled(false);
        }
     }
    
    for (int i = 0; i < 300; i++) {
        boxes.push_back(shared_ptr<ofxBox2dRect>(new ofxBox2dRect));
        boxes.back().get()->setPhysics(3.0, 0.53, 0.1);
        boxes.back().get()->setup(box2d.getWorld(), 512, 100, 6, 6);
    }
    
    obstacle.addVertexes(contour);
    obstacle.create(box2d.getWorld());
}

First of all, why aren’t the shapes closed ?

And why are the lines between the last vertex of a shape and the first of the next shape are drawn ? is it an expected behavior ? should i take care of it manually ?

thanks for help

a polyline is a unique continuous line you can’t add several shapes in one polyline like you are doing in:

        vector<ofPolyline> outline = p.getOutline();
        // convert to polyline for further processing
        for (int i = 0; i < outline.size(); i++) {
            contour.addVertices(outline[i].getVertices());
        }

you would beed to create several contours, one per outline in the path. if you draw the svg paths it should work fine because they use several polylines

Thanks @arturo, nice tip !

so here is the way i made it to work as expected :

void ofApp::setup() {
    
    ofSetVerticalSync(true);
    ofBackground(0);
    ofSetLogLevel(OF_LOG_NOTICE);
    ofSetFrameRate(60);
    
    box2d.init();
    box2d.setGravity(0, 0);
    box2d.createBounds();
    box2d.setFPS(60.0);
    box2d.registerGrabbing();
    
    svg.load("contour.svg");
    
     for (int i = 0; i < svg.getNumPath(); i++){
        
        // grab a shape from SVG file
        ofPath p = svg.getPathAt(i);
        p.setPolyWindingMode(OF_POLY_WINDING_ODD);
        
        // convert shape path to polyline
        ofPolyline  contour;
        contour.addVertices(p.getOutline().at(0).getVertices());

        // close the shape by adding a last vertex which is the first vertex of the shape
        contour.addVertex(p.getOutline().at(0).getVertices().at(0));
        
        // convert contour to box2d edge and add to the box2d World
        shared_ptr <ofxBox2dEdge> edge = shared_ptr<ofxBox2dEdge>(new ofxBox2dEdge);
        edge.get()->addVertices(contour.getVertices());
        edge.get()->create(box2d.getWorld());
        obstacles.push_back(edge);
    }
}