Unify displayEdges and displayOutlines.
This has the following benefits: * Less geometry to generate; we can do both in one pass; * Less geometry to draw; * Eliminate overdraw of outlines on top of emphasized edges; * In future, being able to seamlessly stitch stippled lines. The contour edges are now also drawn before emphasized edges; this makes intersections of contour and emphasized edges look better as the thinner emphasized edge doesn't clobber the depth buffer.pull/33/head
parent
e7c8c1c8f2
commit
7f411d1593
|
@ -143,7 +143,7 @@ public:
|
||||||
bool DrawBeziers(const SBezierList &bl, hStroke hcs) override {
|
bool DrawBeziers(const SBezierList &bl, hStroke hcs) override {
|
||||||
ssassert(false, "Not implemented");
|
ssassert(false, "Not implemented");
|
||||||
}
|
}
|
||||||
void DrawOutlines(const SOutlineList &ol, hStroke hcs) override {
|
void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) override {
|
||||||
ssassert(false, "Not implemented");
|
ssassert(false, "Not implemented");
|
||||||
}
|
}
|
||||||
void DrawPoint(const Vector &o, double d, hFill hcf) override {
|
void DrawPoint(const Vector &o, double d, hFill hcf) override {
|
||||||
|
@ -209,11 +209,7 @@ void SolveSpaceUI::ExportViewOrWireframeTo(const std::string &filename, bool exp
|
||||||
if(SS.GW.showEdges) {
|
if(SS.GW.showEdges) {
|
||||||
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
||||||
g->GenerateDisplayItems();
|
g->GenerateDisplayItems();
|
||||||
SEdgeList *selr = &(g->displayEdges);
|
g->displayOutlines.ListTaggedInto(&edges, Style::SOLID_EDGE);
|
||||||
SEdge *se;
|
|
||||||
for(se = selr->l.First(); se; se = selr->l.NextAfter(se)) {
|
|
||||||
edges.AddEdge(se->a, se->b, Style::SOLID_EDGE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SS.GW.showConstraints) {
|
if(SS.GW.showConstraints) {
|
||||||
|
@ -812,7 +808,7 @@ void SolveSpaceUI::ExportMeshTo(const std::string &filename) {
|
||||||
ExportMeshAsObjTo(f, m);
|
ExportMeshAsObjTo(f, m);
|
||||||
} else if(FilenameHasExtension(filename, ".js") ||
|
} else if(FilenameHasExtension(filename, ".js") ||
|
||||||
FilenameHasExtension(filename, ".html")) {
|
FilenameHasExtension(filename, ".html")) {
|
||||||
SEdgeList *e = &(SK.GetGroup(SS.GW.activeGroup)->displayEdges);
|
SOutlineList *e = &(SK.GetGroup(SS.GW.activeGroup)->displayOutlines);
|
||||||
ExportMeshAsThreeJsTo(f, filename, m, e);
|
ExportMeshAsThreeJsTo(f, filename, m, e);
|
||||||
} else {
|
} else {
|
||||||
Error("Can't identify output file type from file extension of "
|
Error("Can't identify output file type from file extension of "
|
||||||
|
@ -899,11 +895,10 @@ void SolveSpaceUI::ExportMeshAsObjTo(FILE *f, SMesh *sm) {
|
||||||
// Export the mesh as a JavaScript script, which is compatible with Three.js.
|
// Export the mesh as a JavaScript script, which is compatible with Three.js.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SolveSpaceUI::ExportMeshAsThreeJsTo(FILE *f, const std::string &filename,
|
void SolveSpaceUI::ExportMeshAsThreeJsTo(FILE *f, const std::string &filename,
|
||||||
SMesh *sm, SEdgeList *sel)
|
SMesh *sm, SOutlineList *sol)
|
||||||
{
|
{
|
||||||
SPointList spl = {};
|
SPointList spl = {};
|
||||||
STriangle *tr;
|
STriangle *tr;
|
||||||
SEdge *e;
|
|
||||||
Vector bndl, bndh;
|
Vector bndl, bndh;
|
||||||
const char htmlbegin[] = R"(
|
const char htmlbegin[] = R"(
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
@ -1055,14 +1050,15 @@ void SolveSpaceUI::ExportMeshAsThreeJsTo(FILE *f, const std::string &filename,
|
||||||
fputs(" ],\n"
|
fputs(" ],\n"
|
||||||
" edges: [\n", f);
|
" edges: [\n", f);
|
||||||
// Output edges. Assume user's model colors do not obscure white edges.
|
// Output edges. Assume user's model colors do not obscure white edges.
|
||||||
for(e = sel->l.First(); e; e = sel->l.NextAfter(e)) {
|
for(const SOutline &so : sol->l) {
|
||||||
|
if(so.tag == 0) continue;
|
||||||
fprintf(f, " [[%f, %f, %f], [%f, %f, %f]],\n",
|
fprintf(f, " [[%f, %f, %f], [%f, %f, %f]],\n",
|
||||||
e->a.x / SS.exportScale,
|
so.a.x / SS.exportScale,
|
||||||
e->a.y / SS.exportScale,
|
so.a.y / SS.exportScale,
|
||||||
e->a.z / SS.exportScale,
|
so.a.z / SS.exportScale,
|
||||||
e->b.x / SS.exportScale,
|
so.b.x / SS.exportScale,
|
||||||
e->b.y / SS.exportScale,
|
so.b.y / SS.exportScale,
|
||||||
e->b.z / SS.exportScale);
|
so.b.z / SS.exportScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
fputs(" ]\n};\n", f);
|
fputs(" ]\n};\n", f);
|
||||||
|
|
|
@ -28,7 +28,6 @@ void Group::Clear() {
|
||||||
thisShell.Clear();
|
thisShell.Clear();
|
||||||
runningShell.Clear();
|
runningShell.Clear();
|
||||||
displayMesh.Clear();
|
displayMesh.Clear();
|
||||||
displayEdges.Clear();
|
|
||||||
displayOutlines.Clear();
|
displayOutlines.Clear();
|
||||||
impMesh.Clear();
|
impMesh.Clear();
|
||||||
impShell.Clear();
|
impShell.Clear();
|
||||||
|
|
|
@ -377,14 +377,8 @@ void Group::GenerateDisplayItems() {
|
||||||
displayMesh.Clear();
|
displayMesh.Clear();
|
||||||
displayMesh.MakeFromCopyOf(&(pg->displayMesh));
|
displayMesh.MakeFromCopyOf(&(pg->displayMesh));
|
||||||
|
|
||||||
displayEdges.Clear();
|
|
||||||
displayOutlines.Clear();
|
displayOutlines.Clear();
|
||||||
if(SS.GW.showEdges) {
|
if(SS.GW.showEdges) {
|
||||||
SEdge *se;
|
|
||||||
SEdgeList *src = &(pg->displayEdges);
|
|
||||||
for(se = src->l.First(); se; se = src->l.NextAfter(se)) {
|
|
||||||
displayEdges.l.Add(se);
|
|
||||||
}
|
|
||||||
displayOutlines.MakeFromCopyOf(&pg->displayOutlines);
|
displayOutlines.MakeFromCopyOf(&pg->displayOutlines);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -402,17 +396,14 @@ void Group::GenerateDisplayItems() {
|
||||||
displayMesh.AddTriangle(&trn);
|
displayMesh.AddTriangle(&trn);
|
||||||
}
|
}
|
||||||
|
|
||||||
displayEdges.Clear();
|
|
||||||
displayOutlines.Clear();
|
displayOutlines.Clear();
|
||||||
|
|
||||||
if(SS.GW.showEdges) {
|
if(SS.GW.showEdges) {
|
||||||
if(runningMesh.l.n > 0) {
|
if(runningMesh.l.n > 0) {
|
||||||
// Triangle mesh only; no shell or emphasized edges.
|
// Triangle mesh only; no shell or emphasized edges.
|
||||||
runningMesh.MakeCertainEdgesAndOutlinesInto(
|
runningMesh.MakeOutlinesInto(&displayOutlines, EdgeKind::EMPHASIZED);
|
||||||
&displayEdges, &displayOutlines, EdgeKind::EMPHASIZED);
|
|
||||||
} else {
|
} else {
|
||||||
displayMesh.MakeCertainEdgesAndOutlinesInto(
|
displayMesh.MakeOutlinesInto(&displayOutlines, EdgeKind::SHARP);
|
||||||
&displayEdges, &displayOutlines, EdgeKind::SHARP);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -536,13 +527,27 @@ void Group::Draw(Canvas *canvas) {
|
||||||
DrawMesh(DrawMeshAs::DEFAULT, canvas);
|
DrawMesh(DrawMeshAs::DEFAULT, canvas);
|
||||||
|
|
||||||
if(SS.GW.showEdges) {
|
if(SS.GW.showEdges) {
|
||||||
|
if(SS.GW.showOutlines) {
|
||||||
|
Canvas::Stroke strokeOutline = {};
|
||||||
|
strokeOutline.zIndex = 1;
|
||||||
|
strokeOutline.color = Style::Color(Style::OUTLINE);
|
||||||
|
strokeOutline.width = Style::Width(Style::OUTLINE);
|
||||||
|
Canvas::hStroke hcsOutline = canvas->GetStroke(strokeOutline);
|
||||||
|
|
||||||
|
canvas->DrawOutlines(displayOutlines, hcsOutline,
|
||||||
|
Canvas::DrawOutlinesAs::CONTOUR_ONLY);
|
||||||
|
}
|
||||||
|
|
||||||
Canvas::Stroke strokeEdge = {};
|
Canvas::Stroke strokeEdge = {};
|
||||||
strokeEdge.zIndex = 1;
|
strokeEdge.zIndex = 1;
|
||||||
strokeEdge.color = Style::Color(Style::SOLID_EDGE);
|
strokeEdge.color = Style::Color(Style::SOLID_EDGE);
|
||||||
strokeEdge.width = Style::Width(Style::SOLID_EDGE);
|
strokeEdge.width = Style::Width(Style::SOLID_EDGE);
|
||||||
Canvas::hStroke hcsEdge = canvas->GetStroke(strokeEdge);
|
Canvas::hStroke hcsEdge = canvas->GetStroke(strokeEdge);
|
||||||
|
|
||||||
canvas->DrawEdges(displayEdges, hcsEdge);
|
canvas->DrawOutlines(displayOutlines, hcsEdge,
|
||||||
|
SS.GW.showOutlines
|
||||||
|
? Canvas::DrawOutlinesAs::EMPHASIZED_WITHOUT_CONTOUR
|
||||||
|
: Canvas::DrawOutlinesAs::EMPHASIZED_AND_CONTOUR);
|
||||||
|
|
||||||
if(SS.GW.showHdnLines) {
|
if(SS.GW.showHdnLines) {
|
||||||
Canvas::Stroke strokeHidden = strokeEdge;
|
Canvas::Stroke strokeHidden = strokeEdge;
|
||||||
|
@ -552,19 +557,8 @@ void Group::Draw(Canvas *canvas) {
|
||||||
strokeHidden.stippleScale = Style::StippleScaleMm({ Style::HIDDEN_EDGE });
|
strokeHidden.stippleScale = Style::StippleScaleMm({ Style::HIDDEN_EDGE });
|
||||||
Canvas::hStroke hcsHidden = canvas->GetStroke(strokeHidden);
|
Canvas::hStroke hcsHidden = canvas->GetStroke(strokeHidden);
|
||||||
|
|
||||||
canvas->DrawEdges(displayEdges, hcsHidden);
|
canvas->DrawOutlines(displayOutlines, hcsHidden,
|
||||||
canvas->DrawOutlines(displayOutlines, hcsHidden);
|
Canvas::DrawOutlinesAs::EMPHASIZED_AND_CONTOUR);
|
||||||
}
|
|
||||||
|
|
||||||
if(SS.GW.showOutlines) {
|
|
||||||
Canvas::Stroke strokeOutline = strokeEdge;
|
|
||||||
strokeOutline.color = Style::Color(Style::OUTLINE);
|
|
||||||
strokeOutline.width = Style::Width(Style::OUTLINE);
|
|
||||||
Canvas::hStroke hcsOutline = canvas->GetStroke(strokeOutline);
|
|
||||||
|
|
||||||
canvas->DrawOutlines(displayOutlines, hcsOutline);
|
|
||||||
} else {
|
|
||||||
canvas->DrawOutlines(displayOutlines, hcsEdge);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
45
src/mesh.cpp
45
src/mesh.cpp
|
@ -91,10 +91,9 @@ void SMesh::MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d) {
|
||||||
m.Clear();
|
m.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMesh::MakeCertainEdgesAndOutlinesInto(SEdgeList *sel, SOutlineList *sol, EdgeKind type) {
|
void SMesh::MakeOutlinesInto(SOutlineList *sol, EdgeKind edgeKind) {
|
||||||
SKdNode *root = SKdNode::From(this);
|
SKdNode *root = SKdNode::From(this);
|
||||||
root->MakeCertainEdgesInto(sel, type, /*coplanarIsInter=*/false, NULL, NULL);
|
root->MakeOutlinesInto(sol, edgeKind);
|
||||||
root->MakeOutlinesInto(sol);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1010,7 +1009,7 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, EdgeKind how, bool coplanarIs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SKdNode::MakeOutlinesInto(SOutlineList *sol) const
|
void SKdNode::MakeOutlinesInto(SOutlineList *sol, EdgeKind edgeKind) const
|
||||||
{
|
{
|
||||||
std::vector<STriangle *> tris;
|
std::vector<STriangle *> tris;
|
||||||
ClearTags();
|
ClearTags();
|
||||||
|
@ -1030,13 +1029,37 @@ void SKdNode::MakeOutlinesInto(SOutlineList *sol) const
|
||||||
if(CheckAndAddTrianglePair(&edgeTris, tr, info.tr))
|
if(CheckAndAddTrianglePair(&edgeTris, tr, info.tr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
int tag = 0;
|
||||||
|
switch(edgeKind) {
|
||||||
|
case EdgeKind::EMPHASIZED:
|
||||||
|
if(tr->meta.face != info.tr->meta.face) {
|
||||||
|
tag = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EdgeKind::SHARP: {
|
||||||
|
Vector na0 = tr->normals[j].WithMagnitude(1.0);
|
||||||
|
Vector nb0 = tr->normals[(j + 1) % 3].WithMagnitude(1.0);
|
||||||
|
Vector na1 = info.tr->normals[info.ai].WithMagnitude(1.0);
|
||||||
|
Vector nb1 = info.tr->normals[info.bi].WithMagnitude(1.0);
|
||||||
|
if(!((na0.Equals(na1) && nb0.Equals(nb1)) ||
|
||||||
|
(na0.Equals(nb1) && nb0.Equals(na1)))) {
|
||||||
|
tag = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ssassert(false, "Unexpected edge kind");
|
||||||
|
}
|
||||||
|
|
||||||
Vector nl = tr->Normal().WithMagnitude(1.0);
|
Vector nl = tr->Normal().WithMagnitude(1.0);
|
||||||
Vector nr = info.tr->Normal().WithMagnitude(1.0);
|
Vector nr = info.tr->Normal().WithMagnitude(1.0);
|
||||||
|
|
||||||
// We don't add edges with the same left and right
|
// We don't add edges with the same left and right
|
||||||
// normals because they can't produce outlines.
|
// normals because they can't produce outlines.
|
||||||
if(nl.Equals(nr)) continue;
|
if(tag == 0 && nl.Equals(nr)) continue;
|
||||||
sol->AddEdge(a, b, nl, nr);
|
sol->AddEdge(a, b, nl, nr, tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1052,15 +1075,23 @@ void SOutlineList::Clear() {
|
||||||
l.Clear();
|
l.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SOutlineList::AddEdge(Vector a, Vector b, Vector nl, Vector nr) {
|
void SOutlineList::AddEdge(Vector a, Vector b, Vector nl, Vector nr, int tag) {
|
||||||
SOutline so = {};
|
SOutline so = {};
|
||||||
so.a = a;
|
so.a = a;
|
||||||
so.b = b;
|
so.b = b;
|
||||||
so.nl = nl;
|
so.nl = nl;
|
||||||
so.nr = nr;
|
so.nr = nr;
|
||||||
|
so.tag = tag;
|
||||||
l.Add(&so);
|
l.Add(&so);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SOutlineList::ListTaggedInto(SEdgeList *el, int auxA, int auxB) {
|
||||||
|
for(const SOutline &so : l) {
|
||||||
|
if(so.tag == 0) continue;
|
||||||
|
el->AddEdge(so.a, so.b, auxA, auxB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SOutlineList::MakeFromCopyOf(SOutlineList *sol) {
|
void SOutlineList::MakeFromCopyOf(SOutlineList *sol) {
|
||||||
for(SOutline *so = sol->l.First(); so; so = sol->l.NextAfter(so)) {
|
for(SOutline *so = sol->l.First(); so; so = sol->l.NextAfter(so)) {
|
||||||
l.Add(so);
|
l.Add(so);
|
||||||
|
|
|
@ -269,7 +269,7 @@ public:
|
||||||
void MakeFromAssemblyOf(SMesh *a, SMesh *b);
|
void MakeFromAssemblyOf(SMesh *a, SMesh *b);
|
||||||
|
|
||||||
void MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d);
|
void MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d);
|
||||||
void MakeCertainEdgesAndOutlinesInto(SEdgeList *sel, SOutlineList *sol, EdgeKind type);
|
void MakeOutlinesInto(SOutlineList *sol, EdgeKind type);
|
||||||
|
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
void RemapFaces(Group *g, int remap);
|
void RemapFaces(Group *g, int remap);
|
||||||
|
@ -300,7 +300,8 @@ public:
|
||||||
List<SOutline> l;
|
List<SOutline> l;
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
void AddEdge(Vector a, Vector b, Vector nl, Vector nr);
|
void AddEdge(Vector a, Vector b, Vector nl, Vector nr, int tag = 0);
|
||||||
|
void ListTaggedInto(SEdgeList *el, int auxA = 0, int auxB = 0);
|
||||||
|
|
||||||
void MakeFromCopyOf(SOutlineList *ol);
|
void MakeFromCopyOf(SOutlineList *ol);
|
||||||
};
|
};
|
||||||
|
@ -336,7 +337,7 @@ public:
|
||||||
void FindEdgeOn(Vector a, Vector b, int cnt, bool coplanarIsInter, EdgeOnInfo *info) const;
|
void FindEdgeOn(Vector a, Vector b, int cnt, bool coplanarIsInter, EdgeOnInfo *info) const;
|
||||||
void MakeCertainEdgesInto(SEdgeList *sel, EdgeKind how, bool coplanarIsInter,
|
void MakeCertainEdgesInto(SEdgeList *sel, EdgeKind how, bool coplanarIsInter,
|
||||||
bool *inter, bool *leaky, int auxA = 0) const;
|
bool *inter, bool *leaky, int auxA = 0) const;
|
||||||
void MakeOutlinesInto(SOutlineList *sel) const;
|
void MakeOutlinesInto(SOutlineList *sel, EdgeKind tagKind) const;
|
||||||
|
|
||||||
void OcclusionTestLine(SEdge orig, SEdgeList *sel, int cnt, bool removeHidden) const;
|
void OcclusionTestLine(SEdge orig, SEdgeList *sel, int cnt, bool removeHidden) const;
|
||||||
void SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr, bool removeHidden) const;
|
void SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr, bool removeHidden) const;
|
||||||
|
|
|
@ -297,7 +297,7 @@ void ObjectPicker::DrawEdges(const SEdgeList &el, hStroke hcs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectPicker::DrawOutlines(const SOutlineList &ol, hStroke hcs) {
|
void ObjectPicker::DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) {
|
||||||
ssassert(false, "Not implemented");
|
ssassert(false, "Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,17 @@ public:
|
||||||
FRONT, // Always drawn above all other geometry
|
FRONT, // Always drawn above all other geometry
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The outlines are the collection of all edges that may be drawn.
|
||||||
|
// Outlines can be classified as emphasized or not; emphasized outlines indicate an abrupt
|
||||||
|
// change in the surface curvature. These are indicated by the SOutline tag.
|
||||||
|
// Outlines can also be classified as contour or not; contour outlines indicate the boundary
|
||||||
|
// of the filled mesh. Whether an outline is a part of contour or not depends on point of view.
|
||||||
|
enum class DrawOutlinesAs {
|
||||||
|
EMPHASIZED_AND_CONTOUR, // Both emphasized and contour outlines
|
||||||
|
EMPHASIZED_WITHOUT_CONTOUR, // Emphasized outlines except those also belonging to contour
|
||||||
|
CONTOUR_ONLY // Contour outlines only
|
||||||
|
};
|
||||||
|
|
||||||
class Stroke {
|
class Stroke {
|
||||||
public:
|
public:
|
||||||
hStroke h;
|
hStroke h;
|
||||||
|
@ -113,7 +124,7 @@ public:
|
||||||
virtual void DrawLine(const Vector &a, const Vector &b, hStroke hcs) = 0;
|
virtual void DrawLine(const Vector &a, const Vector &b, hStroke hcs) = 0;
|
||||||
virtual void DrawEdges(const SEdgeList &el, hStroke hcs) = 0;
|
virtual void DrawEdges(const SEdgeList &el, hStroke hcs) = 0;
|
||||||
virtual bool DrawBeziers(const SBezierList &bl, hStroke hcs) = 0;
|
virtual bool DrawBeziers(const SBezierList &bl, hStroke hcs) = 0;
|
||||||
virtual void DrawOutlines(const SOutlineList &ol, hStroke hcs) = 0;
|
virtual void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) = 0;
|
||||||
virtual void DrawVectorText(const std::string &text, double height,
|
virtual void DrawVectorText(const std::string &text, double height,
|
||||||
const Vector &o, const Vector &u, const Vector &v,
|
const Vector &o, const Vector &u, const Vector &v,
|
||||||
hStroke hcs) = 0;
|
hStroke hcs) = 0;
|
||||||
|
@ -169,7 +180,7 @@ public:
|
||||||
void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override;
|
void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override;
|
||||||
void DrawEdges(const SEdgeList &el, hStroke hcs) override;
|
void DrawEdges(const SEdgeList &el, hStroke hcs) override;
|
||||||
bool DrawBeziers(const SBezierList &bl, hStroke hcs) override { return false; }
|
bool DrawBeziers(const SBezierList &bl, hStroke hcs) override { return false; }
|
||||||
void DrawOutlines(const SOutlineList &ol, hStroke hcs) override;
|
void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) override;
|
||||||
void DrawVectorText(const std::string &text, double height,
|
void DrawVectorText(const std::string &text, double height,
|
||||||
const Vector &o, const Vector &u, const Vector &v,
|
const Vector &o, const Vector &u, const Vector &v,
|
||||||
hStroke hcs) override;
|
hStroke hcs) override;
|
||||||
|
@ -216,7 +227,7 @@ public:
|
||||||
void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override;
|
void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override;
|
||||||
void DrawEdges(const SEdgeList &el, hStroke hcs) override;
|
void DrawEdges(const SEdgeList &el, hStroke hcs) override;
|
||||||
bool DrawBeziers(const SBezierList &bl, hStroke hcs) override { return false; }
|
bool DrawBeziers(const SBezierList &bl, hStroke hcs) override { return false; }
|
||||||
void DrawOutlines(const SOutlineList &ol, hStroke hcs) override;
|
void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) override;
|
||||||
void DrawVectorText(const std::string &text, double height,
|
void DrawVectorText(const std::string &text, double height,
|
||||||
const Vector &o, const Vector &u, const Vector &v,
|
const Vector &o, const Vector &u, const Vector &v,
|
||||||
hStroke hcs) override;
|
hStroke hcs) override;
|
||||||
|
|
|
@ -408,11 +408,32 @@ void OpenGl1Renderer::DrawEdges(const SEdgeList &el, hStroke hcs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGl1Renderer::DrawOutlines(const SOutlineList &ol, hStroke hcs) {
|
void OpenGl1Renderer::DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) {
|
||||||
Vector projDir = camera.projRight.Cross(camera.projUp);
|
Vector projDir = camera.projRight.Cross(camera.projUp);
|
||||||
for(const SOutline *o = ol.l.First(); o; o = ol.l.NextAfter(o)) {
|
switch(drawAs) {
|
||||||
if(!o->IsVisible(projDir)) continue;
|
case DrawOutlinesAs::EMPHASIZED_AND_CONTOUR:
|
||||||
DoStippledLine(o->a, o->b, hcs);
|
for(const SOutline &o : ol.l) {
|
||||||
|
if(o.IsVisible(projDir) || o.tag != 0) {
|
||||||
|
DoStippledLine(o.a, o.b, hcs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DrawOutlinesAs::EMPHASIZED_WITHOUT_CONTOUR:
|
||||||
|
for(const SOutline &o : ol.l) {
|
||||||
|
if(!o.IsVisible(projDir) && o.tag != 0) {
|
||||||
|
DoStippledLine(o.a, o.b, hcs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DrawOutlinesAs::CONTOUR_ONLY:
|
||||||
|
for(const SOutline &o : ol.l) {
|
||||||
|
if(o.IsVisible(projDir)) {
|
||||||
|
DoStippledLine(o.a, o.b, hcs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -192,7 +192,6 @@ public:
|
||||||
|
|
||||||
bool displayDirty;
|
bool displayDirty;
|
||||||
SMesh displayMesh;
|
SMesh displayMesh;
|
||||||
SEdgeList displayEdges;
|
|
||||||
SOutlineList displayOutlines;
|
SOutlineList displayOutlines;
|
||||||
|
|
||||||
enum class CombineAs : uint32_t {
|
enum class CombineAs : uint32_t {
|
||||||
|
|
|
@ -798,7 +798,7 @@ public:
|
||||||
void ExportMeshAsStlTo(FILE *f, SMesh *sm);
|
void ExportMeshAsStlTo(FILE *f, SMesh *sm);
|
||||||
void ExportMeshAsObjTo(FILE *f, SMesh *sm);
|
void ExportMeshAsObjTo(FILE *f, SMesh *sm);
|
||||||
void ExportMeshAsThreeJsTo(FILE *f, const std::string &filename,
|
void ExportMeshAsThreeJsTo(FILE *f, const std::string &filename,
|
||||||
SMesh *sm, SEdgeList *sel);
|
SMesh *sm, SOutlineList *sol);
|
||||||
void ExportViewOrWireframeTo(const std::string &filename, bool exportWireframe);
|
void ExportViewOrWireframeTo(const std::string &filename, bool exportWireframe);
|
||||||
void ExportSectionTo(const std::string &filename);
|
void ExportSectionTo(const std::string &filename);
|
||||||
void ExportWireframeCurves(SEdgeList *sel, SBezierList *sbl,
|
void ExportWireframeCurves(SEdgeList *sel, SBezierList *sbl,
|
||||||
|
|
|
@ -63,7 +63,6 @@ void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) {
|
||||||
dest.thisShell = {};
|
dest.thisShell = {};
|
||||||
dest.runningShell = {};
|
dest.runningShell = {};
|
||||||
dest.displayMesh = {};
|
dest.displayMesh = {};
|
||||||
dest.displayEdges = {};
|
|
||||||
dest.displayOutlines = {};
|
dest.displayOutlines = {};
|
||||||
|
|
||||||
dest.remap = {};
|
dest.remap = {};
|
||||||
|
|
Loading…
Reference in New Issue