diff options
author | 2012-07-24 18:11:03 +0000 | |
---|---|---|
committer | 2012-07-24 18:11:03 +0000 | |
commit | afe56de6361a81eef537ddd8f6d5626c8546d4c7 (patch) | |
tree | 684112f3a939c725483eca13539b1e9380c9c369 | |
parent | 8f4fdc9968123d508d4bb17b5d15946a990613d4 (diff) |
shape ops work in progress
git-svn-id: http://skia.googlecode.com/svn/trunk@4737 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | experimental/Intersection/Simplify.cpp | 134 | ||||
-rw-r--r-- | experimental/Intersection/SimplifyFindNext_Test.cpp | 5 | ||||
-rw-r--r-- | experimental/Intersection/SimplifyNew_Test.cpp | 2 |
3 files changed, 75 insertions, 66 deletions
diff --git a/experimental/Intersection/Simplify.cpp b/experimental/Intersection/Simplify.cpp index f8f2b4b1ce..9dcd305460 100644 --- a/experimental/Intersection/Simplify.cpp +++ b/experimental/Intersection/Simplify.cpp @@ -40,13 +40,14 @@ const bool gRunTestsInOneThread = false; #define DEBUG_MARK_DONE 0 #define DEBUG_PATH_CONSTRUCTION 0 #define DEBUG_SORT 0 +#define DEBUG_WIND_BUMP 0 #define DEBUG_WINDING 0 #else const bool gRunTestsInOneThread = true; -#define DEBUG_ACTIVE_SPANS 0 +#define DEBUG_ACTIVE_SPANS 1 #define DEBUG_ADD_INTERSECTING_TS 0 #define DEBUG_ADD_T_PAIR 0 #define DEBUG_CONCIDENT 0 @@ -55,6 +56,7 @@ const bool gRunTestsInOneThread = true; #define DEBUG_MARK_DONE 1 #define DEBUG_PATH_CONSTRUCTION 1 #define DEBUG_SORT 1 +#define DEBUG_WIND_BUMP 0 #define DEBUG_WINDING 1 #endif @@ -485,6 +487,10 @@ public: return fEnd; } + bool firstBump(int contourWinding, int sumWinding) const { + return sign() * sumWinding > 0; + } + bool isHorizontal() const { return fDy == 0 && fDDy == 0 && fDDDy == 0; } @@ -1223,13 +1229,19 @@ public: // winding -1 means ccw, 1 means cw // firstFind allows coincident edges to be treated differently Segment* findNext(SkTDArray<Span*>& chase, int winding, - int contourWinding, int spanWinding, + int contourWinding, bool firstFind, bool active, const int startIndex, const int endIndex, int& nextStart, - int& nextEnd, int& flipped, bool firstFind, bool active) { + int& nextEnd, int& spanWinding) { + int flipped = 1; int sumWinding = winding + spanWinding; if (sumWinding == 0) { sumWinding = spanWinding; } + bool insideContour = contourWinding && contourWinding * sumWinding < 0; + if (insideContour) { + sumWinding = contourWinding; + } + #if DEBUG_WINDING SkDebugf("%s winding=%d contourWinding=%d spanWinding=%d sumWinding=%d\n", __FUNCTION__, winding, contourWinding, spanWinding, sumWinding); @@ -1267,25 +1279,18 @@ public: #if DEBUG_SORT debugShowSort(sorted, firstIndex, contourWinding, sumWinding); #endif + bool doBump = sorted[firstIndex]->firstBump(contourWinding, sumWinding); #if DEBUG_WINDING - SkDebugf("%s sumWinding=%d sign=%d (%srewind)\n", __FUNCTION__, - sumWinding, sorted[firstIndex]->sign(), - sorted[firstIndex]->sign() * sumWinding > 0 ? "" : "no "); + SkDebugf("%s sumWinding=%d sign=%d (%sbump)\n", __FUNCTION__, + sumWinding, sorted[firstIndex]->sign(), doBump ? "" : "no "); #endif - bool innerSwap = false; + bool innerSwap = active && (doBump || insideContour); int startWinding = sumWinding; // SkASSERT(SkSign32(sumWinding) == SkSign32(winding) || winding == 0); - if (sorted[firstIndex]->sign() * sumWinding > 0) { - int prior = rewind(sorted[firstIndex]); + if (doBump || insideContour) { + int prior = windBump(sorted[firstIndex]); SkDebugf("%s prior=%d\n", __FUNCTION__, prior); - if (0 && winding && contourWinding) { - sumWinding += prior; - } else { - sumWinding -= prior; - } - if (active) { - innerSwap = true; - } + sumWinding -= prior; } int nextIndex = firstIndex + 1; int lastIndex = firstIndex != 0 ? firstIndex : angleCount; @@ -1293,16 +1298,16 @@ public: bool foundDone = false; // iterate through the angle, and compute everyone's winding bool firstEdge = true; + bool flopped = false; + Segment* nextSegment; do { if (nextIndex == angleCount) { nextIndex = 0; } const Angle* nextAngle = sorted[nextIndex]; int maxWinding = sumWinding; - Segment* nextSegment = nextAngle->segment(); - int windValue = nextSegment->windValue(nextAngle); - SkASSERT(windValue > 0); - sumWinding -= nextAngle->sign() * windValue; + nextSegment = nextAngle->segment(); + sumWinding -= nextSegment->windBump(nextAngle); SkASSERT(abs(sumWinding) <= gDebugMaxWindSum); #if DEBUG_WINDING SkDebugf("%s maxWinding=%d sumWinding=%d sign=%d\n", __FUNCTION__, @@ -1310,6 +1315,7 @@ public: #endif if (maxWinding * sumWinding < 0) { flipped = -flipped; + flopped = true; #if DEBUG_WINDING SkDebugf("flipped sign %d %d\n", maxWinding, sumWinding); #endif @@ -1328,7 +1334,7 @@ public: if (!foundAngle || foundDone) { foundAngle = nextAngle; foundDone = nextSegment->done(*nextAngle); - if (flipped > 0 && maxWinding * startWinding < 0) { + if (!flopped && maxWinding * startWinding < 0) { flipped = -flipped; #if DEBUG_WINDING SkDebugf("flopped sign %d %d\n", maxWinding, startWinding); @@ -1369,7 +1375,13 @@ public: } nextStart = foundAngle->start(); nextEnd = foundAngle->end(); - return foundAngle->segment(); + nextSegment = foundAngle->segment(); + spanWinding = SkSign32(spanWinding) * flipped * nextSegment->windValue( + SkMin32(nextStart, nextEnd)); + #if DEBUG_WINDING + SkDebugf("%s spanWinding=%d\n", __FUNCTION__, spanWinding); + #endif + return nextSegment; } int findStartingEdge(SkTDArray<Angle*>& sorted, int start, int end) { @@ -1749,7 +1761,7 @@ public: } void markWinding(int index, int winding) { - SkASSERT(!done()); + // SkASSERT(!done()); double referenceT = fTs[index].fT; int lesser = index; while (--lesser >= 0 && referenceT - fTs[lesser].fT < FLT_EPSILON) { @@ -1825,15 +1837,6 @@ public: fTs.reset(); } - int rewind(const Angle* angle) { - SkASSERT(angle->segment() == this); - const Span& span = fTs[SkMin32(angle->start(), angle->end())]; -#if DEBUG_SORT - SkDebugf("%s offset=%d\n", __FUNCTION__, angle->sign() * span.fWindValue); -#endif - return angle->sign() * span.fWindValue; - } - // OPTIMIZATION: mark as debugging only if used solely by tests const Span& span(int tIndex) const { return fTs[tIndex]; @@ -1857,6 +1860,16 @@ public: return fVerb; } + int windBump(const Angle* angle) const { + SkASSERT(angle->segment() == this); + const Span& span = fTs[SkMin32(angle->start(), angle->end())]; + int result = angle->sign() * span.fWindValue; +#if DEBUG_WIND_BUMP + SkDebugf("%s bump=%d\n", __FUNCTION__, result); +#endif + return result; + } + int windSum(int tIndex) const { return fTs[tIndex].fWindSum; } @@ -1970,15 +1983,18 @@ public: #if DEBUG_SORT void debugShowSort(const SkTDArray<Angle*>& angles, int first, int contourWinding, int sumWinding) { - int index = first; - int windSum = sumWinding; - const Angle& fAngle = *angles[first]; - const Segment& fSegment = *fAngle.segment(); - SkASSERT(&fSegment == this); - const Span& fSpan = fSegment.fTs[SkMin32(fAngle.start(), fAngle.end())]; - if (fAngle.sign() * sumWinding < 0) { - windSum += fAngle.sign() * fSpan.fWindValue; + SkASSERT(angles[first]->segment() == this); + bool doBump = angles[first]->firstBump(contourWinding, sumWinding); + bool insideContour = contourWinding && contourWinding * sumWinding < 0; + int windSum = insideContour ? contourWinding : sumWinding; + int lastSum = windSum; + if (insideContour || doBump) { + windSum -= windBump(angles[first]); + } else { + lastSum += windBump(angles[first]); } + int index = first; + bool firstTime = true; do { const Angle& angle = *angles[index]; const Segment& segment = *angle.segment(); @@ -1987,8 +2003,12 @@ public: const Span& sSpan = segment.fTs[start]; const Span& eSpan = segment.fTs[end]; const Span& mSpan = segment.fTs[SkMin32(start, end)]; - int lastSum = windSum; - windSum -= angle.sign() * mSpan.fWindValue; + if (firstTime) { + firstTime = false; + } else { + lastSum = windSum; + windSum -= segment.windBump(&angle); + } SkDebugf("%s [%d] id=%d start=%d (%1.9g,%,1.9g) end=%d (%1.9g,%,1.9g)" " sign=%d windValue=%d winding: %d->%d (max=%d) done=%d\n", __FUNCTION__, index, segment.fID, start, segment.xAtT(&sSpan), @@ -2951,9 +2971,8 @@ static int innerContourCheck(SkTDArray<Contour*>& contourList, SkASSERT(winding != SK_MinS32); windValue = test->windValue(angle); #if 0 - int firstSign = angle->sign(); - if (firstSign * winding > 0) { - winding -= test->rewind(angle); + if (angle->firstBump(0, winding)) { + winding -= test->windBump(angle); } #endif #if DEBUG_WINDING @@ -3056,11 +3075,9 @@ static Segment* findChase(SkTDArray<Span*>& chase, int& tIndex, int& endIndex, angle->segment()->debugShowSort(sorted, firstIndex, contourWinding, spanWinding); #endif - int firstSign = angle->sign(); - if (firstSign * spanWinding > 0) { - spanWinding -= angle->segment()->rewind(angle); + if (angle->firstBump(contourWinding, spanWinding)) { + spanWinding -= angle->segment()->windBump(angle); } - // SkDebugf("%s firstSign=%d\n", __FUNCTION__, firstSign); // we care about first sign and whether wind sum indicates this // edge is inside or outside. Maybe need to pass span winding // or first winding or something into this function? @@ -3076,10 +3093,8 @@ static Segment* findChase(SkTDArray<Span*>& chase, int& tIndex, int& endIndex, } const Angle* angle = sorted[nextIndex]; segment = angle->segment(); - int windValue = segment->windValue(angle); - SkASSERT(windValue > 0); int maxWinding = spanWinding; - spanWinding -= angle->sign() * windValue; + spanWinding -= segment->windBump(angle); if (maxWinding * spanWinding < 0) { SkDebugf("%s flipped sign %d %d\n", __FUNCTION__, maxWinding, spanWinding); } @@ -3160,7 +3175,7 @@ static void bridge(SkTDArray<Contour*>& contourList, SkPath& simple) { && abs(winding) <= abs(spanWinding); #if DEBUG_WINDING if (abs(winding) > abs(spanWinding) && winding * spanWinding < 0) { - SkDebugf("%s *** unexpected active\n?", __FUNCTION__); + SkDebugf("%s *** unexpected active?\n", __FUNCTION__); } SkDebugf("%s active=%s winding=%d spanWinding=%d\n", __FUNCTION__, active ? "true" : "false", @@ -3169,10 +3184,10 @@ static void bridge(SkTDArray<Contour*>& contourList, SkPath& simple) { const SkPoint* firstPt = NULL; do { SkASSERT(!current->done()); - int nextStart, nextEnd, flipped = 1; + int nextStart, nextEnd; Segment* next = current->findNext(chaseArray, winding, - contourWinding, spanWinding, index, endIndex, - nextStart, nextEnd, flipped, firstTime, active); + contourWinding, firstTime, active, index, endIndex, + nextStart, nextEnd, spanWinding); if (!next) { break; } @@ -3183,11 +3198,6 @@ static void bridge(SkTDArray<Contour*>& contourList, SkPath& simple) { current = next; index = nextStart; endIndex = nextEnd; - spanWinding = SkSign32(spanWinding) * flipped * next->windValue( - SkMin32(nextStart, nextEnd)); - #if DEBUG_WINDING - SkDebugf("%s spanWinding=%d\n", __FUNCTION__, spanWinding); - #endif firstTime = false; } while (*firstPt != lastPt && (active || !current->done())); if (firstPt && active) { diff --git a/experimental/Intersection/SimplifyFindNext_Test.cpp b/experimental/Intersection/SimplifyFindNext_Test.cpp index 2bd69788ac..7ea716d5e3 100644 --- a/experimental/Intersection/SimplifyFindNext_Test.cpp +++ b/experimental/Intersection/SimplifyFindNext_Test.cpp @@ -32,11 +32,10 @@ static const SimplifyFindNextTest::Segment* testCommon( SimplifyFindNextTest::Segment& segment = contours[0].debugSegments()[0]; SkPoint pts[2]; pts[0] = segment.xyAtT(&segment.span(endIndex)); - int nextStart, nextEnd, flipped = 1; + int nextStart, nextEnd; SkTDArray<SimplifyFindNextTest::Span*> chaseArray; SimplifyFindNextTest::Segment* next = segment.findNext(chaseArray, winding, - winding, 0, startIndex, endIndex, nextStart, nextEnd, flipped, - true, true); + 0, true, true, startIndex, endIndex, nextStart, nextEnd, winding); pts[1] = next->xyAtT(&next->span(nextStart)); SkASSERT(pts[0] == pts[1]); return next; diff --git a/experimental/Intersection/SimplifyNew_Test.cpp b/experimental/Intersection/SimplifyNew_Test.cpp index 888f59ed1b..4557228014 100644 --- a/experimental/Intersection/SimplifyNew_Test.cpp +++ b/experimental/Intersection/SimplifyNew_Test.cpp @@ -550,7 +550,7 @@ static void testLine55() { testSimplifyx(path); } -static void (*firstTest)() = 0; +static void (*firstTest)() = testLine55; static struct { void (*fun)(); |