diff options
author | 2012-12-10 14:50:04 +0000 | |
---|---|---|
committer | 2012-12-10 14:50:04 +0000 | |
commit | 0d3d09e5d2fd17aaed035ae23d59804b56b994ff (patch) | |
tree | 2e0497d3283bf00a25c2b359643f3912ca3d3518 /experimental/Intersection/Simplify.cpp | |
parent | 796763e0b2c06a7789185322561a1135e5484688 (diff) |
shape ops work in progress
git-svn-id: http://skia.googlecode.com/svn/trunk@6730 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'experimental/Intersection/Simplify.cpp')
-rw-r--r-- | experimental/Intersection/Simplify.cpp | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/experimental/Intersection/Simplify.cpp b/experimental/Intersection/Simplify.cpp index 9f8176b288..bf9b7cd428 100644 --- a/experimental/Intersection/Simplify.cpp +++ b/experimental/Intersection/Simplify.cpp @@ -29,7 +29,7 @@ int gDebugMaxWindValue = SK_MaxS32; #define TRY_ROTATE 1 #define DEBUG_UNUSED 0 // set to expose unused functions -#define FORCE_RELEASE 0 // set force release to 1 for multiple thread -- no debugging +#define FORCE_RELEASE 1 // set force release to 1 for multiple thread -- no debugging #if FORCE_RELEASE || defined SK_RELEASE @@ -1581,8 +1581,14 @@ public: SkTDArray<double> oOutsideTs; do { // if either span has an opposite value and the operands don't match, resolve first - index = bumpCoincidentThis(oTest, opp, index, outsideTs); - oIndex = other.bumpCoincidentOther(test, oEndT, oIndex, oOutsideTs); + SkASSERT(!test->fDone || !oTest->fDone); + if (test->fDone || oTest->fDone) { + index = advanceCoincidentThis(oTest, opp, index); + oIndex = other.advanceCoincidentOther(test, oEndT, oIndex); + } else { + index = bumpCoincidentThis(oTest, opp, index, outsideTs); + oIndex = other.bumpCoincidentOther(test, oEndT, oIndex, oOutsideTs); + } test = &fTs[index]; oTest = &other.fTs[oIndex]; } while (!approximately_negative(endT - test->fT)); @@ -1641,6 +1647,26 @@ public: } } + int advanceCoincidentThis(const Span* oTest, bool opp, int index) { + Span* const test = &fTs[index]; + Span* end = test; + do { + end = &fTs[++index]; + } while (approximately_negative(end->fT - test->fT)); + return index; + } + + int advanceCoincidentOther(const Span* test, double oEndT, int& oIndex) { + Span* const oTest = &fTs[oIndex]; + Span* oEnd = oTest; + const double oStartT = oTest->fT; + while (!approximately_negative(oEndT - oEnd->fT) + && approximately_negative(oEnd->fT - oStartT)) { + oEnd = &fTs[++oIndex]; + } + return oIndex; + } + const Bounds& bounds() const { return fBounds; } @@ -1892,6 +1918,16 @@ public: } return false; } + + // OPTIMIZE + // when the edges are initially walked, they don't automatically get the prior and next + // edges assigned to positions t=0 and t=1. Doing that would remove the need for this check, + // and would additionally remove the need for similar checks in condition edges. It would + // also allow intersection code to assume end of segment intersections (maybe?) + bool complete() const { + int count = fTs.count(); + return count > 1 && fTs[0].fT == 0 && fTs[--count].fT == 1; + } bool done() const { SkASSERT(fDoneSpans <= fTs.count()); @@ -3825,13 +3861,10 @@ public: SkASSERT(coincidence.fContours[0] == this); int thisIndex = coincidence.fSegments[0]; Segment& thisOne = fSegments[thisIndex]; - if (thisOne.done()) { - continue; - } Contour* otherContour = coincidence.fContours[1]; int otherIndex = coincidence.fSegments[1]; Segment& other = otherContour->fSegments[otherIndex]; - if (other.done()) { + if ((thisOne.done() || other.done()) && thisOne.complete() && other.complete()) { continue; } #if DEBUG_CONCIDENT @@ -3864,7 +3897,9 @@ public: || thisOne.isMissing(endT) || other.isMissing(oStartT)) { other.addTPair(oStartT, thisOne, endT, true); } - thisOne.addTCancel(startT, endT, other, oStartT, oEndT); + if (!thisOne.done() && !other.done()) { + thisOne.addTCancel(startT, endT, other, oStartT, oEndT); + } } else { if (startT > 0 || oStartT > 0 || thisOne.isMissing(startT) || other.isMissing(oStartT)) { @@ -3874,7 +3909,9 @@ public: || thisOne.isMissing(endT) || other.isMissing(oEndT)) { other.addTPair(oEndT, thisOne, endT, true); } - thisOne.addTCoincident(startT, endT, other, oStartT, oEndT); + if (!thisOne.done() && !other.done()) { + thisOne.addTCoincident(startT, endT, other, oStartT, oEndT); + } } #if DEBUG_CONCIDENT thisOne.debugShowTs(); |