From c45ae4b51a123c2c16769556f8c2ee0045fbc13b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Fri, 9 Oct 2015 10:18:45 +0200 Subject: [PATCH] Revert "Never starting in intersections allows for further code simplifications." This reverts commit 892154e8f8bd4ee273e3c5e5b92dbced1bf939a1. --- src/path/PathItem.Boolean.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/path/PathItem.Boolean.js b/src/path/PathItem.Boolean.js index 244ee203..c86a030a 100644 --- a/src/path/PathItem.Boolean.js +++ b/src/path/PathItem.Boolean.js @@ -566,6 +566,7 @@ PathItem.inject(new function() { var paths = [], start, + otherStart, operator = operators[operation], // Adjust winding contributions for specific operations on overlaps: overlapWinding = { @@ -585,6 +586,10 @@ PathItem.inject(new function() { return operator(winding); } + function isStart(seg) { + return seg === start || seg === otherStart; + } + /** * Checks if the curve from seg1 to seg2 is part of an overlap. */ @@ -616,7 +621,7 @@ PathItem.inject(new function() { + nextSeg._index + ', seg vis:' + !!seg._visited + ', next vis:' + !!nextSeg._visited - + ', next start:' + (nextSeg === start) + + ', next start:' + isStart(nextSeg) + ', seg wi:' + seg._winding + ', next wi:' + nextSeg._winding + ', seg op:' + isValid(seg, true) @@ -643,7 +648,7 @@ PathItem.inject(new function() { // result, the non-strict mode is used, in which invalid current // segments are tolerated, and overlaps for the next segment are // allowed as long as they are valid when not adjusted. - if (nextSeg === start + if (isStart(nextSeg) || !seg._visited && !nextSeg._visited // Self-intersections (!operator) don't need isValid() calls && (!operator @@ -670,13 +675,14 @@ PathItem.inject(new function() { for (var i = 0, l = segments.length; i < l; i++) { var seg = segments[i], - path = null; + path = null, + finished = false; // Do not start a chain with segments that have intersections, // segments that are already visited, or that are invalid. if (seg._intersection || !isValid(seg)) continue; - start = null; - while (seg !== start) { + start = otherStart = null; + while (!finished) { var inter = seg._intersection; // Once we started a chain, see if there are multiple // intersections, and if so, pick the best one: @@ -735,8 +741,9 @@ PathItem.inject(new function() { drawSegment(seg, null, 'stay', i, 'blue'); } if (seg._visited) { - if (seg === start) { + if (isStart(seg)) { drawSegment(seg, null, 'done', i, 'red'); + finished = true; } else { // We didn't manage to switch, so stop right here. console.error('Visited segment encountered, aborting #' @@ -750,21 +757,23 @@ PathItem.inject(new function() { if (!path) { path = new Path(Item.NO_INSERT); start = seg; + otherStart = other; } // Add the current segment to the path, and mark the added // segment as visited. path.add(new Segment(seg._point, handleIn, seg._handleOut)); seg._visited = true; seg = seg.getNext(); - if (seg === start) { + if (isStart(seg)) { drawSegment(seg, null, 'done', i, 'red'); + finished = true; } } if (!path) continue; // Finish with closing the paths if necessary, correctly linking up // curves etc. - if (seg === start) { + if (finished) { path.firstSegment.setHandleIn(seg._handleIn); path.setClosed(true); if (window.reportSegments) {