Skip to content

Commit

Permalink
clean up input polygons
Browse files Browse the repository at this point in the history
some inputs could consist of tiny line segments that are less than curveTolerance. Reduce the number of segments to the minimum necessary to satisfy tolerance constraints
  • Loading branch information
bmtm committed Jan 29, 2016
1 parent a544f70 commit 1524fbc
Showing 1 changed file with 38 additions and 6 deletions.
44 changes: 38 additions & 6 deletions svgnest.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@
}

binPolygon = SvgParser.polygonify(bin);

binPolygon = this.cleanPolygon(binPolygon);

if(!binPolygon || binPolygon.length < 3){
return false;
}
Expand Down Expand Up @@ -511,8 +512,10 @@
var numChildren = paths.length;
for(i=0; i<numChildren; i++){
var poly = SvgParser.polygonify(paths[i]);

if(poly && poly.length > 2){
poly = this.cleanPolygon(poly);

// todo: warn user if poly could not be processed and is excluded from the nest
if(poly && poly.length > 2 && Math.abs(GeometryUtil.polygonArea(poly)) > config.curveTolerance*config.curveTolerance){
poly.source = i;
polygons.push(poly);
}
Expand Down Expand Up @@ -572,7 +575,7 @@

return id;
};

return polygons;
};

Expand All @@ -585,8 +588,6 @@

var p = this.svgToClipper(polygon);



var miterLimit = 2;
var co = new ClipperLib.ClipperOffset(miterLimit, config.curveTolerance*config.clipperScale);
co.AddPath(p, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon);
Expand All @@ -602,6 +603,37 @@
return result;
};

// returns a less complex polygon that satisfies the curve tolerance
this.cleanPolygon = function(polygon){
var p = this.svgToClipper(polygon);

// remove self-intersections and find the biggest polygon that's left
var simple = ClipperLib.Clipper.SimplifyPolygon(p, ClipperLib.PolyFillType.pftNonZero);

if(!simple || simple.length == 0){
return null;
}

var biggest = simple[0];
var biggestarea = Math.abs(GeometryUtil.polygonArea(biggest));
for(var i=1; i<simple.length; i++){
var area = Math.abs(GeometryUtil.polygonArea(simple[i]));
if(area > biggestarea){
biggest = simple[i];
biggestarea = area;
}
}

// clean up singularities, coincident points and edges
var clean = ClipperLib.Clipper.CleanPolygon(biggest, config.curveTolerance*config.clipperScale);

if(!clean || clean.length == 0){
return null;
}

return this.clipperToSvg(clean);
}

// converts a polygon from normal float coordinates to integer coordinates used by clipper, as well as x/y -> X/Y
this.svgToClipper = function(polygon){
var clip = [];
Expand Down

0 comments on commit 1524fbc

Please sign in to comment.