Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Public Attributes | List of all members
GrTriangulator::Edge Struct Reference

#include <GrTriangulator.h>

Public Member Functions

 Edge (Vertex *top, Vertex *bottom, int winding, EdgeType type)
 
double dist (const SkPoint &p) const
 
bool isRightOf (const Vertex &v) const
 
bool isLeftOf (const Vertex &v) const
 
void recompute ()
 
void insertAbove (Vertex *, const Comparator &)
 
void insertBelow (Vertex *, const Comparator &)
 
void disconnect ()
 
bool intersect (const Edge &other, SkPoint *p, uint8_t *alpha=nullptr) const
 

Public Attributes

int fWinding
 
VertexfTop
 
VertexfBottom
 
EdgeType fType
 
EdgefLeft
 
EdgefRight
 
EdgefPrevEdgeAbove
 
EdgefNextEdgeAbove
 
EdgefPrevEdgeBelow
 
EdgefNextEdgeBelow
 
PolyfLeftPoly
 
PolyfRightPoly
 
EdgefLeftPolyPrev
 
EdgefLeftPolyNext
 
EdgefRightPolyPrev
 
EdgefRightPolyNext
 
bool fUsedInLeftPoly
 
bool fUsedInRightPoly
 
Line fLine
 

Detailed Description

An Edge joins a top Vertex to a bottom Vertex. Edge ordering for the list of "edges above" and "edge below" a vertex as well as for the active edge list is handled by isLeftOf()/isRightOf(). Note that an Edge will give occasionally dist() != 0 for its own endpoints (because floating point). For speed, that case is only tested by the callers that require it (e.g., rewind_if_necessary()). Edges also handle checking for intersection with other edges. Currently, this converts the edges to the parametric form, in order to avoid doing a division until an intersection has been confirmed. This is slightly slower in the "found" case, but a lot faster in the "not found" case.

The coefficients of the line equation stored in double precision to avoid catastrophic cancellation in the isLeftOf() and isRightOf() checks. Using doubles ensures that the result is correct in float, since it's a polynomial of degree 2. The intersect() function, being degree 5, is still subject to catastrophic cancellation. We deal with that by assuming its output may be incorrect, and adjusting the mesh topology to match (see comment at the top of this file).

Definition at line 406 of file GrTriangulator.h.

Constructor & Destructor Documentation

◆ Edge()

GrTriangulator::Edge::Edge ( Vertex top,
Vertex bottom,
int  winding,
EdgeType  type 
)
inline

Definition at line 407 of file GrTriangulator.h.

408 : fWinding(winding)
409 , fTop(top)
410 , fBottom(bottom)
411 , fType(type)
412 , fLeft(nullptr)
413 , fRight(nullptr)
414 , fPrevEdgeAbove(nullptr)
415 , fNextEdgeAbove(nullptr)
416 , fPrevEdgeBelow(nullptr)
417 , fNextEdgeBelow(nullptr)
418 , fLeftPoly(nullptr)
419 , fRightPoly(nullptr)
420 , fLeftPolyPrev(nullptr)
421 , fLeftPolyNext(nullptr)
422 , fRightPolyPrev(nullptr)
423 , fRightPolyNext(nullptr)
424 , fUsedInLeftPoly(false)
425 , fUsedInRightPoly(false)
426 , fLine(top, bottom) {
427 }

Member Function Documentation

◆ disconnect()

void GrTriangulator::Edge::disconnect ( )

Definition at line 740 of file GrTriangulator.cpp.

740 {
741 remove_edge_above(this);
742 remove_edge_below(this);
743}
static void remove_edge_above(Edge *edge)
static void remove_edge_below(Edge *edge)

◆ dist()

double GrTriangulator::Edge::dist ( const SkPoint p) const
inline

Definition at line 448 of file GrTriangulator.h.

448 {
449 // Coerce points coincident with the vertices to have dist = 0, since converting from
450 // a double intersection point back to float storage might construct a point that's no
451 // longer on the ideal line.
452 return (p == fTop->fPoint || p == fBottom->fPoint) ? 0.0 : fLine.dist(p);
453 }
double dist(const SkPoint &p) const

◆ insertAbove()

void GrTriangulator::Edge::insertAbove ( Vertex v,
const Comparator c 
)

Definition at line 688 of file GrTriangulator.cpp.

688 {
689 if (fTop->fPoint == fBottom->fPoint ||
691 return;
692 }
693 TESS_LOG("insert edge (%g -> %g) above vertex %g\n", fTop->fID, fBottom->fID, v->fID);
694 Edge* prev = nullptr;
695 Edge* next;
696 for (next = v->fFirstEdgeAbove; next; next = next->fNextEdgeAbove) {
697 if (next->isRightOf(*fTop)) {
698 break;
699 }
700 prev = next;
701 }
702 list_insert<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>(
703 this, prev, next, &v->fFirstEdgeAbove, &v->fLastEdgeAbove);
704}
#define TESS_LOG(...)
static float next(float f)
static float prev(float f)
bool sweep_lt(const SkPoint &a, const SkPoint &b) const

◆ insertBelow()

void GrTriangulator::Edge::insertBelow ( Vertex v,
const Comparator c 
)

Definition at line 706 of file GrTriangulator.cpp.

706 {
707 if (fTop->fPoint == fBottom->fPoint ||
709 return;
710 }
711 TESS_LOG("insert edge (%g -> %g) below vertex %g\n", fTop->fID, fBottom->fID, v->fID);
712 Edge* prev = nullptr;
713 Edge* next;
714 for (next = v->fFirstEdgeBelow; next; next = next->fNextEdgeBelow) {
715 if (next->isRightOf(*fBottom)) {
716 break;
717 }
718 prev = next;
719 }
720 list_insert<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>(
721 this, prev, next, &v->fFirstEdgeBelow, &v->fLastEdgeBelow);
722}

◆ intersect()

bool GrTriangulator::Edge::intersect ( const Edge other,
SkPoint p,
uint8_t *  alpha = nullptr 
) const

Definition at line 265 of file GrTriangulator.cpp.

265 {
266 TESS_LOG("intersecting %g -> %g with %g -> %g\n",
267 fTop->fID, fBottom->fID, other.fTop->fID, other.fBottom->fID);
268 if (fTop == other.fTop || fBottom == other.fBottom ||
269 fTop == other.fBottom || fBottom == other.fTop) {
270 // If the two edges share a vertex by construction, they have already been split and
271 // shouldn't be considered "intersecting" anymore.
272 return false;
273 }
274
275 double s, t; // needed to interpolate vertex alpha
276 const bool intersects = recursive_edge_intersect(
278 other.fLine, other.fTop->fPoint, other.fBottom->fPoint,
279 p, &s, &t);
280 if (!intersects) {
281 return false;
282 }
283
284 if (alpha) {
285 if (fType == EdgeType::kInner || other.fType == EdgeType::kInner) {
286 // If the intersection is on any interior edge, it needs to stay fully opaque or later
287 // triangulation could leech transparency into the inner fill region.
288 *alpha = 255;
289 } else if (fType == EdgeType::kOuter && other.fType == EdgeType::kOuter) {
290 // Trivially, the intersection will be fully transparent since since it is by
291 // construction on the outer edge.
292 *alpha = 0;
293 } else {
294 // Could be two connectors crossing, or a connector crossing an outer edge.
295 // Take the max interpolated alpha
296 SkASSERT(fType == EdgeType::kConnector || other.fType == EdgeType::kConnector);
297 *alpha = std::max((1.0 - s) * fTop->fAlpha + s * fBottom->fAlpha,
298 (1.0 - t) * other.fTop->fAlpha + t * other.fBottom->fAlpha);
299 }
300 }
301 return true;
302}
static bool recursive_edge_intersect(const Line &u, SkPoint u0, SkPoint u1, const Line &v, SkPoint v0, SkPoint v1, SkPoint *p, double *s, double *t)
#define SkASSERT(cond)
Definition SkAssert.h:116
struct MyStruct s

◆ isLeftOf()

bool GrTriangulator::Edge::isLeftOf ( const Vertex v) const
inline

Definition at line 455 of file GrTriangulator.h.

455{ return this->dist(v.fPoint) > 0.0; }
double dist(const SkPoint &p) const

◆ isRightOf()

bool GrTriangulator::Edge::isRightOf ( const Vertex v) const
inline

Definition at line 454 of file GrTriangulator.h.

454{ return this->dist(v.fPoint) < 0.0; }

◆ recompute()

void GrTriangulator::Edge::recompute ( )
inline

Definition at line 456 of file GrTriangulator.h.

Member Data Documentation

◆ fBottom

Vertex* GrTriangulator::Edge::fBottom

Definition at line 430 of file GrTriangulator.h.

◆ fLeft

Edge* GrTriangulator::Edge::fLeft

Definition at line 432 of file GrTriangulator.h.

◆ fLeftPoly

Poly* GrTriangulator::Edge::fLeftPoly

Definition at line 438 of file GrTriangulator.h.

◆ fLeftPolyNext

Edge* GrTriangulator::Edge::fLeftPolyNext

Definition at line 441 of file GrTriangulator.h.

◆ fLeftPolyPrev

Edge* GrTriangulator::Edge::fLeftPolyPrev

Definition at line 440 of file GrTriangulator.h.

◆ fLine

Line GrTriangulator::Edge::fLine

Definition at line 446 of file GrTriangulator.h.

◆ fNextEdgeAbove

Edge* GrTriangulator::Edge::fNextEdgeAbove

Definition at line 435 of file GrTriangulator.h.

◆ fNextEdgeBelow

Edge* GrTriangulator::Edge::fNextEdgeBelow

Definition at line 437 of file GrTriangulator.h.

◆ fPrevEdgeAbove

Edge* GrTriangulator::Edge::fPrevEdgeAbove

Definition at line 434 of file GrTriangulator.h.

◆ fPrevEdgeBelow

Edge* GrTriangulator::Edge::fPrevEdgeBelow

Definition at line 436 of file GrTriangulator.h.

◆ fRight

Edge* GrTriangulator::Edge::fRight

Definition at line 433 of file GrTriangulator.h.

◆ fRightPoly

Poly* GrTriangulator::Edge::fRightPoly

Definition at line 439 of file GrTriangulator.h.

◆ fRightPolyNext

Edge* GrTriangulator::Edge::fRightPolyNext

Definition at line 443 of file GrTriangulator.h.

◆ fRightPolyPrev

Edge* GrTriangulator::Edge::fRightPolyPrev

Definition at line 442 of file GrTriangulator.h.

◆ fTop

Vertex* GrTriangulator::Edge::fTop

Definition at line 429 of file GrTriangulator.h.

◆ fType

EdgeType GrTriangulator::Edge::fType

Definition at line 431 of file GrTriangulator.h.

◆ fUsedInLeftPoly

bool GrTriangulator::Edge::fUsedInLeftPoly

Definition at line 444 of file GrTriangulator.h.

◆ fUsedInRightPoly

bool GrTriangulator::Edge::fUsedInRightPoly

Definition at line 445 of file GrTriangulator.h.

◆ fWinding

int GrTriangulator::Edge::fWinding

Definition at line 428 of file GrTriangulator.h.


The documentation for this struct was generated from the following files: