mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-07 13:22:07 -05:00
Simplify handling of winding overlap-adjustment in isValid()
This commit is contained in:
parent
a79212b920
commit
e9c3e72f60
1 changed files with 12 additions and 14 deletions
|
@ -444,14 +444,14 @@ PathItem.inject(new function() {
|
||||||
intersect: { 2: 1 }
|
intersect: { 2: 1 }
|
||||||
}[operation];
|
}[operation];
|
||||||
|
|
||||||
function isValid(seg, unadjusted) {
|
function isValid(seg, adjusted) {
|
||||||
if (seg._visited)
|
if (seg._visited)
|
||||||
return false;
|
return false;
|
||||||
if (!operator) // For self-intersection, we're always valid!
|
if (!operator) // For self-intersection, we're always valid!
|
||||||
return true;
|
return true;
|
||||||
var winding = seg._winding,
|
var winding = seg._winding,
|
||||||
inter = seg._intersection;
|
inter = seg._intersection;
|
||||||
if (inter && !unadjusted && overlapWinding && inter.isOverlap())
|
if (inter && adjusted && overlapWinding && inter.isOverlap())
|
||||||
winding = overlapWinding[winding] || winding;
|
winding = overlapWinding[winding] || winding;
|
||||||
return operator(winding);
|
return operator(winding);
|
||||||
}
|
}
|
||||||
|
@ -486,19 +486,19 @@ PathItem.inject(new function() {
|
||||||
|| !seg._visited && !nextSeg._visited
|
|| !seg._visited && !nextSeg._visited
|
||||||
// Self-intersections (!operator) don't need isValid() calls
|
// Self-intersections (!operator) don't need isValid() calls
|
||||||
&& (!operator
|
&& (!operator
|
||||||
// We need to use the unadjusted winding here since an
|
// Do not use the overlap-adjusted winding here since an
|
||||||
// overlap crossing might have brought us here, in which
|
// overlap crossing might have brought us here, in which
|
||||||
// case isValid(seg, false) might be false.
|
// case isValid(seg) might be false.
|
||||||
|| (!strict || isValid(seg, true))
|
|| (!strict || isValid(seg))
|
||||||
// Do not consider nextSeg in strict mode if it is part
|
// Do not consider nextSeg in strict mode if it is part
|
||||||
// of an overlap, in order to give non-overlapping
|
// of an overlap, in order to give non-overlapping
|
||||||
// options that might follow the priority over overlaps.
|
// options that might follow the priority over overlaps.
|
||||||
&& (!(strict && nextInter && nextInter.isOverlap())
|
&& (!(strict && nextInter && nextInter.isOverlap())
|
||||||
&& isValid(nextSeg, true)
|
&& isValid(nextSeg)
|
||||||
// If the next segment isn't valid, its intersection
|
// If the next segment isn't valid, its intersection
|
||||||
// to which we may switch might be, so check that.
|
// to which we may switch might be, so check that.
|
||||||
|| !strict && nextInter
|
|| !strict && nextInter
|
||||||
&& isValid(nextInter._segment, true))
|
&& isValid(nextInter._segment))
|
||||||
))
|
))
|
||||||
return inter;
|
return inter;
|
||||||
// If it's no match, continue with the next linked intersection.
|
// If it's no match, continue with the next linked intersection.
|
||||||
|
@ -522,7 +522,7 @@ PathItem.inject(new function() {
|
||||||
finished = false;
|
finished = false;
|
||||||
// Do not start a chain with already visited segments, and segments
|
// Do not start a chain with already visited segments, and segments
|
||||||
// that are not going to be part of the resulting operation.
|
// that are not going to be part of the resulting operation.
|
||||||
if (!isValid(seg))
|
if (!isValid(seg, true))
|
||||||
continue;
|
continue;
|
||||||
start = otherStart = null;
|
start = otherStart = null;
|
||||||
while (!finished) {
|
while (!finished) {
|
||||||
|
@ -536,8 +536,7 @@ PathItem.inject(new function() {
|
||||||
var other = inter && inter._segment;
|
var other = inter && inter._segment;
|
||||||
// If we are at a crossing and the other segment is part of the
|
// If we are at a crossing and the other segment is part of the
|
||||||
// boolean result, switch to it.
|
// boolean result, switch to it.
|
||||||
// Do not adjust winding when checking overlaps.
|
if (other && isValid(other))
|
||||||
if (other && isValid(other, inter.isOverlap()))
|
|
||||||
seg = other;
|
seg = other;
|
||||||
// If the new segment is visited already, check if we're back
|
// If the new segment is visited already, check if we're back
|
||||||
// at the start.
|
// at the start.
|
||||||
|
@ -566,14 +565,12 @@ PathItem.inject(new function() {
|
||||||
seg = seg.getNext();
|
seg = seg.getNext();
|
||||||
finished = isStart(seg);
|
finished = isStart(seg);
|
||||||
}
|
}
|
||||||
if (!path)
|
|
||||||
continue;
|
|
||||||
// Finish with closing the paths if necessary, correctly linking up
|
// Finish with closing the paths if necessary, correctly linking up
|
||||||
// curves etc.
|
// curves etc.
|
||||||
if (finished) {
|
if (finished) {
|
||||||
path.firstSegment.setHandleIn(seg._handleIn);
|
path.firstSegment.setHandleIn(seg._handleIn);
|
||||||
path.setClosed(true);
|
path.setClosed(true);
|
||||||
} else {
|
} else if (path) {
|
||||||
// This path wasn't finished and is hence invalid.
|
// This path wasn't finished and is hence invalid.
|
||||||
// Report the error to the console for the time being.
|
// Report the error to the console for the time being.
|
||||||
console.error('Boolean operation resulted in open path',
|
console.error('Boolean operation resulted in open path',
|
||||||
|
@ -861,7 +858,8 @@ CompoundPath.inject(/** @lends CompoundPath# */{
|
||||||
* - The holes have opposite winding direction.
|
* - The holes have opposite winding direction.
|
||||||
* - Islands have to have the same winding direction as the first child.
|
* - Islands have to have the same winding direction as the first child.
|
||||||
*/
|
*/
|
||||||
// NOTE: Does NOT handle self-intersecting CompoundPaths.
|
// NOTE: Does NOT handle self-intersecting CompoundPaths on itself, but
|
||||||
|
// the boolean code above resolves these before calling reorient().
|
||||||
reorient: function() {
|
reorient: function() {
|
||||||
var children = this.removeChildren().sort(function(a, b) {
|
var children = this.removeChildren().sort(function(a, b) {
|
||||||
return b.getBounds().getArea() - a.getBounds().getArea();
|
return b.getBounds().getArea() - a.getBounds().getArea();
|
||||||
|
|
Loading…
Reference in a new issue