Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(207)

Unified Diff: src/pathops/SkAddIntersections.cpp

Issue 1029993002: Revert of pathops version two (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/pathops/SkAddIntersections.h ('k') | src/pathops/SkDCubicIntersection.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pathops/SkAddIntersections.cpp
diff --git a/src/pathops/SkAddIntersections.cpp b/src/pathops/SkAddIntersections.cpp
index b507eb7560989665109fd358e7b5fc9b359c4f21..c27434f9f778cb1a4df19570b6ecfdbeb8d90e38 100644
--- a/src/pathops/SkAddIntersections.cpp
+++ b/src/pathops/SkAddIntersections.cpp
@@ -5,7 +5,6 @@
* found in the LICENSE file.
*/
#include "SkAddIntersections.h"
-#include "SkOpCoincidence.h"
#include "SkPathOpsBounds.h"
#if DEBUG_ADD_INTERSECTING_TS
@@ -131,6 +130,20 @@
SkDebugf("\n");
}
+static void debugShowCubicIntersection(int pts, const SkIntersectionHelper& wt,
+ const SkIntersections& i) {
+ SkASSERT(i.used() == pts);
+ if (!pts) {
+ SkDebugf("%s no self intersect " CUBIC_DEBUG_STR "\n", __FUNCTION__,
+ CUBIC_DEBUG_DATA(wt.pts()));
+ return;
+ }
+ SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
+ i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
+ SkDebugf(" " T_DEBUG_STR(wtTs, 1), i[1][0]);
+ SkDebugf("\n");
+}
+
#else
static void debugShowLineIntersection(int , const SkIntersectionHelper& ,
const SkIntersectionHelper& , const SkIntersections& ) {
@@ -155,10 +168,13 @@
static void debugShowCubicIntersection(int , const SkIntersectionHelper& ,
const SkIntersectionHelper& , const SkIntersections& ) {
}
+
+static void debugShowCubicIntersection(int , const SkIntersectionHelper& ,
+ const SkIntersections& ) {
+}
#endif
-bool AddIntersectTs(SkOpContour* test, SkOpContour* next, SkOpCoincidence* coincidence,
- SkChunkAlloc* allocator) {
+bool AddIntersectTs(SkOpContour* test, SkOpContour* next) {
if (test != next) {
if (AlmostLessUlps(test->bounds().fBottom, next->bounds().fTop)) {
return false;
@@ -170,11 +186,10 @@
}
SkIntersectionHelper wt;
wt.init(test);
+ bool foundCommonContour = test == next;
do {
SkIntersectionHelper wn;
wn.init(next);
- test->debugValidate();
- next->debugValidate();
if (test == next && !wn.startAfter(wt)) {
continue;
}
@@ -291,22 +306,14 @@
break;
}
case SkIntersectionHelper::kQuad_Segment: {
- SkDQuad quad1;
- quad1.set(wt.pts());
- SkDQuad quad2;
- quad2.set(wn.pts());
- pts = ts.intersect(quad1, quad2);
+ pts = ts.quadQuad(wt.pts(), wn.pts());
+ ts.alignQuadPts(wt.pts(), wn.pts());
debugShowQuadIntersection(pts, wt, wn, ts);
break;
}
case SkIntersectionHelper::kCubic_Segment: {
swap = true;
- SkDQuad quad1;
- quad1.set(wt.pts());
- SkDCubic cubic1 = quad1.toCubic();
- SkDCubic cubic2;
- cubic2.set(wn.pts());
- pts = ts.intersect(cubic2, cubic1);
+ pts = ts.cubicQuad(wn.pts(), wt.pts());
debugShowCubicQuadIntersection(pts, wn, wt, ts);
break;
}
@@ -332,21 +339,12 @@
break;
}
case SkIntersectionHelper::kQuad_Segment: {
- SkDCubic cubic1;
- cubic1.set(wt.pts());
- SkDQuad quad2;
- quad2.set(wn.pts());
- SkDCubic cubic2 = quad2.toCubic();
- pts = ts.intersect(cubic1, cubic2);
+ pts = ts.cubicQuad(wt.pts(), wn.pts());
debugShowCubicQuadIntersection(pts, wt, wn, ts);
break;
}
case SkIntersectionHelper::kCubic_Segment: {
- SkDCubic cubic1;
- cubic1.set(wt.pts());
- SkDCubic cubic2;
- cubic2.set(wn.pts());
- pts = ts.intersect(cubic1, cubic2);
+ pts = ts.cubicCubic(wt.pts(), wn.pts());
debugShowCubicIntersection(pts, wt, wn, ts);
break;
}
@@ -357,53 +355,102 @@
default:
SkASSERT(0);
}
- int coinIndex = -1;
- SkOpPtT* coinPtT[2];
+ if (!foundCommonContour && pts > 0) {
+ test->addCross(next);
+ next->addCross(test);
+ foundCommonContour = true;
+ }
+ // in addition to recording T values, record matching segment
+ if (pts == 2) {
+ if (wn.segmentType() <= SkIntersectionHelper::kLine_Segment
+ && wt.segmentType() <= SkIntersectionHelper::kLine_Segment) {
+ if (wt.addCoincident(wn, ts, swap)) {
+ continue;
+ }
+ pts = ts.cleanUpCoincidence(); // prefer (t == 0 or t == 1)
+ } else if (wn.segmentType() >= SkIntersectionHelper::kQuad_Segment
+ && wt.segmentType() >= SkIntersectionHelper::kQuad_Segment
+ && ts.isCoincident(0)) {
+ SkASSERT(ts.coincidentUsed() == 2);
+ if (wt.addCoincident(wn, ts, swap)) {
+ continue;
+ }
+ pts = ts.cleanUpCoincidence(); // prefer (t == 0 or t == 1)
+ }
+ }
+ if (pts >= 2) {
+ for (int pt = 0; pt < pts - 1; ++pt) {
+ const SkDPoint& point = ts.pt(pt);
+ const SkDPoint& next = ts.pt(pt + 1);
+ if (wt.isPartial(ts[swap][pt], ts[swap][pt + 1], point, next)
+ && wn.isPartial(ts[!swap][pt], ts[!swap][pt + 1], point, next)) {
+ if (!wt.addPartialCoincident(wn, ts, pt, swap)) {
+ // remove extra point if two map to same float values
+ pts = ts.cleanUpCoincidence(); // prefer (t == 0 or t == 1)
+ }
+ }
+ }
+ }
for (int pt = 0; pt < pts; ++pt) {
SkASSERT(ts[0][pt] >= 0 && ts[0][pt] <= 1);
SkASSERT(ts[1][pt] >= 0 && ts[1][pt] <= 1);
- wt.segment()->debugValidate();
- SkOpPtT* testTAt = wt.segment()->addT(ts[swap][pt], SkOpSegment::kAllowAlias,
- allocator);
- wn.segment()->debugValidate();
- SkOpPtT* nextTAt = wn.segment()->addT(ts[!swap][pt], SkOpSegment::kAllowAlias,
- allocator);
- testTAt->addOpp(nextTAt);
- if (testTAt->fPt != nextTAt->fPt) {
- testTAt->span()->unaligned();
- nextTAt->span()->unaligned();
- }
- wt.segment()->debugValidate();
- wn.segment()->debugValidate();
- if (!ts.isCoincident(pt)) {
- continue;
- }
- if (coinIndex < 0) {
- coinPtT[0] = testTAt;
- coinPtT[1] = nextTAt;
- coinIndex = pt;
- continue;
- }
- if (coinPtT[0]->span() == testTAt->span()) {
- coinIndex = -1;
- continue;
- }
- if (coinPtT[1]->span() == nextTAt->span()) {
- coinIndex = -1; // coincidence span collapsed
- continue;
- }
- if (swap) {
- SkTSwap(coinPtT[0], coinPtT[1]);
- SkTSwap(testTAt, nextTAt);
- }
- SkASSERT(coinPtT[0]->span()->t() < testTAt->span()->t());
- coincidence->add(coinPtT[0], testTAt, coinPtT[1], nextTAt, allocator);
- wt.segment()->debugValidate();
- wn.segment()->debugValidate();
- coinIndex = -1;
- }
- SkASSERT(coinIndex < 0); // expect coincidence to be paired
+ SkPoint point = ts.pt(pt).asSkPoint();
+ wt.alignTPt(wn, swap, pt, &ts, &point);
+ int testTAt = wt.addT(wn, point, ts[swap][pt]);
+ int nextTAt = wn.addT(wt, point, ts[!swap][pt]);
+ wt.addOtherT(testTAt, ts[!swap][pt], nextTAt);
+ wn.addOtherT(nextTAt, ts[swap][pt], testTAt);
+ }
} while (wn.advance());
} while (wt.advance());
return true;
}
+
+void AddSelfIntersectTs(SkOpContour* test) {
+ SkIntersectionHelper wt;
+ wt.init(test);
+ do {
+ if (wt.segmentType() != SkIntersectionHelper::kCubic_Segment) {
+ continue;
+ }
+ SkIntersections ts;
+ int pts = ts.cubic(wt.pts());
+ debugShowCubicIntersection(pts, wt, ts);
+ if (!pts) {
+ continue;
+ }
+ SkASSERT(pts == 1);
+ SkASSERT(ts[0][0] >= 0 && ts[0][0] <= 1);
+ SkASSERT(ts[1][0] >= 0 && ts[1][0] <= 1);
+ SkPoint point = ts.pt(0).asSkPoint();
+ int testTAt = wt.addSelfT(point, ts[0][0]);
+ int nextTAt = wt.addSelfT(point, ts[1][0]);
+ wt.addOtherT(testTAt, ts[1][0], nextTAt);
+ wt.addOtherT(nextTAt, ts[0][0], testTAt);
+ } while (wt.advance());
+}
+
+// resolve any coincident pairs found while intersecting, and
+// see if coincidence is formed by clipping non-concident segments
+bool CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total) {
+ int contourCount = (*contourList).count();
+ for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
+ SkOpContour* contour = (*contourList)[cIndex];
+ contour->resolveNearCoincidence();
+ }
+ for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
+ SkOpContour* contour = (*contourList)[cIndex];
+ contour->addCoincidentPoints();
+ }
+ for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
+ SkOpContour* contour = (*contourList)[cIndex];
+ if (!contour->calcCoincidentWinding()) {
+ return false;
+ }
+ }
+ for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
+ SkOpContour* contour = (*contourList)[cIndex];
+ contour->calcPartialCoincidentWinding();
+ }
+ return true;
+}
« no previous file with comments | « src/pathops/SkAddIntersections.h ('k') | src/pathops/SkDCubicIntersection.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698