Stitch outlines before display to preserve phase of stippling.

Before this commit, the outlines are generated in an arbitrary order
from the kd-tree. This worked just fine for continuous lines, but
for stippling, especially on curves, this meant that most of
the piecewise linear edges would have the stippling phase restart
from zero, leading to a very poor appearance.
pull/97/head
whitequark 2016-10-11 10:38:21 +00:00
parent 186911a51a
commit 47288e9a4c
3 changed files with 68 additions and 2 deletions

View File

@ -401,12 +401,18 @@ void Group::GenerateDisplayItems() {
displayOutlines.Clear();
if(SS.GW.showEdges || SS.GW.showOutlines) {
SOutlineList rawOutlines = {};
if(runningMesh.l.n > 0) {
// Triangle mesh only; no shell or emphasized edges.
runningMesh.MakeOutlinesInto(&displayOutlines, EdgeKind::EMPHASIZED);
runningMesh.MakeOutlinesInto(&rawOutlines, EdgeKind::EMPHASIZED);
} else {
displayMesh.MakeOutlinesInto(&displayOutlines, EdgeKind::SHARP);
displayMesh.MakeOutlinesInto(&rawOutlines, EdgeKind::SHARP);
}
PolylineBuilder builder;
builder.MakeFromOutlines(rawOutlines);
builder.GenerateOutlines(&displayOutlines);
rawOutlines.Clear();
}
}

View File

@ -396,6 +396,11 @@ public:
std::function<void(Vertex *next, Edge *edge)> nextFunc,
std::function<void(Edge *)> aloneFunc,
std::function<void()> endFunc = [](){});
void MakeFromEdges(const SEdgeList &sel);
void MakeFromOutlines(const SOutlineList &sol);
void GenerateEdges(SEdgeList *sel);
void GenerateOutlines(SOutlineList *sol);
};
#endif

View File

@ -187,3 +187,58 @@ void PolylineBuilder::Generate(
aloneFunc(e);
}
}
void PolylineBuilder::MakeFromEdges(const SEdgeList &sel) {
for(const SEdge &se : sel.l) {
AddEdge(se.a, se.b, (uint32_t)se.auxA, reinterpret_cast<uintptr_t>(&se));
}
}
void PolylineBuilder::MakeFromOutlines(const SOutlineList &ol) {
for(const SOutline &so : ol.l) {
// Use outline tag as kind, so that emphasized and contour outlines
// would not be composed together.
AddEdge(so.a, so.b, (uint32_t)so.tag, reinterpret_cast<uintptr_t>(&so));
}
}
void PolylineBuilder::GenerateEdges(SEdgeList *sel) {
Vector prev;
auto startFunc = [&](Vertex *start, Vertex *next, Edge *e) {
sel->AddEdge(start->pos, next->pos, e->kind);
prev = next->pos;
};
auto nextFunc = [&](Vertex *next, Edge *e) {
sel->AddEdge(prev, next->pos, e->kind);
prev = next->pos;
};
auto aloneFunc = [&](Edge *e) {
sel->AddEdge(e->a->pos, e->b->pos, e->kind);
};
Generate(startFunc, nextFunc, aloneFunc);
}
void PolylineBuilder::GenerateOutlines(SOutlineList *sol) {
Vector prev;
auto startFunc = [&](Vertex *start, Vertex *next, Edge *e) {
SOutline *so = e->outline;
sol->AddEdge(start->pos, next->pos, so->nl, so->nr, so->tag);
prev = next->pos;
};
auto nextFunc = [&](Vertex *next, Edge *e) {
SOutline *so = e->outline;
sol->AddEdge(prev, next->pos, so->nl, so->nr, so->tag);
prev = next->pos;
};
auto aloneFunc = [&](Edge *e) {
SOutline *so = e->outline;
sol->AddEdge(so->a, so->b, so->nl, so->nr, so->tag);
};
Generate(startFunc, nextFunc, aloneFunc);
}