diff options
author | caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-12-10 14:50:04 +0000 |
---|---|---|
committer | caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-12-10 14:50:04 +0000 |
commit | 0d3d09e5d2fd17aaed035ae23d59804b56b994ff (patch) | |
tree | 2e0497d3283bf00a25c2b359643f3912ca3d3518 /experimental | |
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')
-rw-r--r-- | experimental/Intersection/CubicIntersection.cpp | 3 | ||||
-rw-r--r-- | experimental/Intersection/Simplify.cpp | 55 | ||||
-rw-r--r-- | experimental/Intersection/SimplifyNew_Test.cpp | 4 |
3 files changed, 50 insertions, 12 deletions
diff --git a/experimental/Intersection/CubicIntersection.cpp b/experimental/Intersection/CubicIntersection.cpp index cc86f0cb59..fcd4119097 100644 --- a/experimental/Intersection/CubicIntersection.cpp +++ b/experimental/Intersection/CubicIntersection.cpp @@ -9,6 +9,8 @@ #include "IntersectionUtilities.h" #include "LineIntersection.h" +static const double tClipLimit = 0.8; // http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf see Multiple intersections + class CubicIntersections : public Intersections { public: @@ -145,7 +147,6 @@ bool chop(double minT1, double maxT1, double minT2, double maxT2, int split) { private: -const double tClipLimit = 0.8; // http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf see Multiple intersections const Cubic& cubic1; const Cubic& cubic2; Intersections& intersections; 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(); diff --git a/experimental/Intersection/SimplifyNew_Test.cpp b/experimental/Intersection/SimplifyNew_Test.cpp index 5be846b132..40b79fb720 100644 --- a/experimental/Intersection/SimplifyNew_Test.cpp +++ b/experimental/Intersection/SimplifyNew_Test.cpp @@ -2884,7 +2884,7 @@ path.close(); testSimplifyx(path); } -static void (*firstTest)() = testLine81; +static void (*firstTest)() = testLine79x; static struct { void (*fun)(); @@ -3333,7 +3333,7 @@ static const size_t subTestCount = sizeof(subTests) / sizeof(subTests[0]); static void (*firstBinaryTest)() = testOp2d; static bool skipAll = false; -static bool runBinaryTestsFirst = true; +static bool runBinaryTestsFirst = false; static bool runReverse = false; void SimplifyNew_Test() { |