shape ops work in progress

git-svn-id: http://skia.googlecode.com/svn/trunk@6730 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
caryclark@google.com 2012-12-10 14:50:04 +00:00
parent 796763e0b2
commit 0d3d09e5d2
3 changed files with 50 additions and 12 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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() {