Make "Show/hide hidden lines" a tri-state button instead.

The states are:
  * Draw all lines (on top of shaded mesh).
  * Draw occluded (by shaded mesh) lines as stippled.
  * Do not draw occluded (by shaded mesh) lines.

As usual, the export output follows the screen output.
This commit is contained in:
whitequark 2016-08-13 09:02:12 +00:00
parent 8ce2922902
commit 6e860fb148
13 changed files with 105 additions and 16 deletions

View File

@ -14,6 +14,9 @@ Other new features:
* New link to match the on-screen size of the sketch with its actual size, * New link to match the on-screen size of the sketch with its actual size,
"view → set to full scale". "view → set to full scale".
* When zooming to fit, constraints are also considered. * When zooming to fit, constraints are also considered.
* The "Show/hide hidden lines" button is now a tri-state button that allows
showing all lines (on top of shaded mesh), stippling occluded lines
or not drawing them at all.
2.2 2.2
--- ---

View File

@ -177,7 +177,9 @@ add_resources(
icons/text-window/constraint.png icons/text-window/constraint.png
icons/text-window/edges.png icons/text-window/edges.png
icons/text-window/faces.png icons/text-window/faces.png
icons/text-window/hidden-lines.png icons/text-window/occluded-visible.png
icons/text-window/occluded-stippled.png
icons/text-window/occluded-invisible.png
icons/text-window/mesh.png icons/text-window/mesh.png
icons/text-window/normal.png icons/text-window/normal.png
icons/text-window/outlines.png icons/text-window/outlines.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

View File

Before

Width:  |  Height:  |  Size: 539 B

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

View File

@ -565,10 +565,18 @@ void GraphicsWindow::DrawPersistent(Canvas *canvas) {
// Now draw the entities. // Now draw the entities.
for(Entity &e : SK.entity) { for(Entity &e : SK.entity) {
if(SS.GW.showHdnLines) { switch(SS.GW.drawOccludedAs) {
e.Draw(Entity::DrawAs::HIDDEN, canvas); case DrawOccludedAs::VISIBLE:
e.Draw(Entity::DrawAs::OVERLAY, canvas);
break;
case DrawOccludedAs::STIPPLED:
e.Draw(Entity::DrawAs::HIDDEN, canvas);
/* fallthrough */
case DrawOccludedAs::INVISIBLE:
e.Draw(Entity::DrawAs::DEFAULT, canvas);
break;
} }
e.Draw(Entity::DrawAs::DEFAULT, canvas);
} }
// Draw filled paths in all groups, when those filled paths were requested // Draw filled paths in all groups, when those filled paths were requested

View File

@ -474,6 +474,10 @@ void Entity::Draw(DrawAs how, Canvas *canvas) {
stroke.layer = Canvas::Layer::NORMAL; stroke.layer = Canvas::Layer::NORMAL;
break; break;
case DrawAs::OVERLAY:
stroke.layer = Canvas::Layer::FRONT;
break;
case DrawAs::HIDDEN: case DrawAs::HIDDEN:
stroke.layer = Canvas::Layer::OCCLUDED; stroke.layer = Canvas::Layer::OCCLUDED;
stroke.stipplePattern = Style::PatternType({ Style::HIDDEN_EDGE }); stroke.stipplePattern = Style::PatternType({ Style::HIDDEN_EDGE });

View File

@ -178,7 +178,7 @@ void SolveSpaceUI::ExportViewOrWireframeTo(const std::string &filename, bool exp
GenerateAll(Generate::ALL); GenerateAll(Generate::ALL);
SMesh *sm = NULL; SMesh *sm = NULL;
if(SS.GW.showShaded || SS.GW.showHdnLines) { if(SS.GW.showShaded || SS.GW.drawOccludedAs != GraphicsWindow::DrawOccludedAs::VISIBLE) {
Group *g = SK.GetGroup(SS.GW.activeGroup); Group *g = SK.GetGroup(SS.GW.activeGroup);
g->GenerateDisplayItems(); g->GenerateDisplayItems();
sm = &(g->displayMesh); sm = &(g->displayMesh);
@ -410,13 +410,13 @@ void SolveSpaceUI::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *s
// Split the original edge against the mesh // Split the original edge against the mesh
edges.AddEdge(se->a, se->b, se->auxA); edges.AddEdge(se->a, se->b, se->auxA);
root->OcclusionTestLine(*se, &edges, cnt); root->OcclusionTestLine(*se, &edges, cnt);
if(SS.GW.showHdnLines) { if(SS.GW.drawOccludedAs == GraphicsWindow::DrawOccludedAs::STIPPLED) {
for(SEdge &se : edges.l) { for(SEdge &se : edges.l) {
if(se.tag == 1) { if(se.tag == 1) {
se.auxA = Style::HIDDEN_EDGE; se.auxA = Style::HIDDEN_EDGE;
} }
} }
} else { } else if(SS.GW.drawOccludedAs == GraphicsWindow::DrawOccludedAs::INVISIBLE) {
edges.l.RemoveTagged(); edges.l.RemoveTagged();
} }

View File

@ -223,11 +223,11 @@ void GraphicsWindow::Init() {
showNormals = true; showNormals = true;
showPoints = true; showPoints = true;
showConstraints = true; showConstraints = true;
showHdnLines = false;
showShaded = true; showShaded = true;
showEdges = true; showEdges = true;
showMesh = false; showMesh = false;
showOutlines = false; showOutlines = false;
drawOccludedAs = DrawOccludedAs::INVISIBLE;
showTextWindow = true; showTextWindow = true;
ShowTextWindow(showTextWindow); ShowTextWindow(showTextWindow);

View File

@ -444,7 +444,8 @@ bool Group::IsMeshGroup() {
} }
void Group::DrawMesh(DrawMeshAs how, Canvas *canvas) { void Group::DrawMesh(DrawMeshAs how, Canvas *canvas) {
if(!(SS.GW.showShaded || SS.GW.showHdnLines)) return; if(!(SS.GW.showShaded ||
SS.GW.drawOccludedAs != GraphicsWindow::DrawOccludedAs::VISIBLE)) return;
switch(how) { switch(how) {
case DrawMeshAs::DEFAULT: { case DrawMeshAs::DEFAULT: {
@ -452,7 +453,7 @@ void Group::DrawMesh(DrawMeshAs how, Canvas *canvas) {
// the sketch. // the sketch.
Canvas::Fill fillFront = {}; Canvas::Fill fillFront = {};
if(!SS.GW.showShaded) { if(!SS.GW.showShaded) {
fillFront.layer = Canvas::Layer::DEPTH_ONLY; fillFront.layer = Canvas::Layer::DEPTH_ONLY;
} }
if(type == Type::DRAWING_3D || type == Type::DRAWING_WORKPLANE) { if(type == Type::DRAWING_3D || type == Type::DRAWING_WORKPLANE) {
fillFront.color = Style::Color(Style::DIM_SOLID); fillFront.color = Style::Color(Style::DIM_SOLID);
@ -549,7 +550,7 @@ void Group::Draw(Canvas *canvas) {
? Canvas::DrawOutlinesAs::EMPHASIZED_WITHOUT_CONTOUR ? Canvas::DrawOutlinesAs::EMPHASIZED_WITHOUT_CONTOUR
: Canvas::DrawOutlinesAs::EMPHASIZED_AND_CONTOUR); : Canvas::DrawOutlinesAs::EMPHASIZED_AND_CONTOUR);
if(SS.GW.showHdnLines) { if(SS.GW.drawOccludedAs == GraphicsWindow::DrawOccludedAs::STIPPLED) {
Canvas::Stroke strokeHidden = strokeEdge; Canvas::Stroke strokeHidden = strokeEdge;
strokeHidden.layer = Canvas::Layer::OCCLUDED; strokeHidden.layer = Canvas::Layer::OCCLUDED;
strokeHidden.width = Style::Width(Style::HIDDEN_EDGE); strokeHidden.width = Style::Width(Style::HIDDEN_EDGE);

View File

@ -506,7 +506,7 @@ public:
bool IsStylable() const; bool IsStylable() const;
bool IsVisible() const; bool IsVisible() const;
enum class DrawAs { DEFAULT, HIDDEN, HOVERED, SELECTED }; enum class DrawAs { DEFAULT, OVERLAY, HIDDEN, HOVERED, SELECTED };
void Draw(DrawAs how, Canvas *canvas); void Draw(DrawAs how, Canvas *canvas);
void GetReferencePoints(std::vector<Vector> *refs); void GetReferencePoints(std::vector<Vector> *refs);
int GetPositionOfPoint(const Camera &camera, Point2d p); int GetPositionOfPoint(const Camera &camera, Point2d p);

View File

@ -83,6 +83,76 @@ public:
} }
}; };
class OccludedLinesButton : public Button {
public:
std::shared_ptr<Pixmap> visibleIcon;
std::shared_ptr<Pixmap> stippledIcon;
std::shared_ptr<Pixmap> invisibleIcon;
std::string Tooltip() override {
switch(SS.GW.drawOccludedAs) {
case GraphicsWindow::DrawOccludedAs::INVISIBLE:
return "Stipple occluded lines";
case GraphicsWindow::DrawOccludedAs::STIPPLED:
return "Draw occluded lines";
case GraphicsWindow::DrawOccludedAs::VISIBLE:
return "Don't draw occluded lines";
default: ssassert(false, "Unexpected mode");
}
}
void Draw(UiCanvas *uiCanvas, int x, int y, bool asHovered) override {
if(visibleIcon == NULL) {
visibleIcon = LoadPng("icons/text-window/occluded-visible.png");
}
if(stippledIcon == NULL) {
stippledIcon = LoadPng("icons/text-window/occluded-stippled.png");
}
if(invisibleIcon == NULL) {
invisibleIcon = LoadPng("icons/text-window/occluded-invisible.png");
}
std::shared_ptr<Pixmap> icon;
switch(SS.GW.drawOccludedAs) {
case GraphicsWindow::DrawOccludedAs::INVISIBLE: icon = invisibleIcon; break;
case GraphicsWindow::DrawOccludedAs::STIPPLED: icon = stippledIcon; break;
case GraphicsWindow::DrawOccludedAs::VISIBLE: icon = visibleIcon; break;
}
uiCanvas->DrawPixmap(icon, x, y - 24);
if(asHovered) {
uiCanvas->DrawRect(x - 2, x + 26, y + 2, y - 26,
/*fillColor=*/{ 255, 255, 0, 75 },
/*outlineColor=*/{});
}
}
int AdvanceWidth() override { return 32; }
void Click() override {
switch(SS.GW.drawOccludedAs) {
case GraphicsWindow::DrawOccludedAs::INVISIBLE:
SS.GW.drawOccludedAs = GraphicsWindow::DrawOccludedAs::STIPPLED;
break;
case GraphicsWindow::DrawOccludedAs::STIPPLED:
SS.GW.drawOccludedAs = GraphicsWindow::DrawOccludedAs::VISIBLE;
break;
case GraphicsWindow::DrawOccludedAs::VISIBLE:
SS.GW.drawOccludedAs = GraphicsWindow::DrawOccludedAs::INVISIBLE;
break;
}
SS.GenerateAll();
InvalidateGraphics();
SS.ScheduleShowTW();
}
};
static SpacerButton spacerButton; static SpacerButton spacerButton;
static ShowHideButton workplanesButton = static ShowHideButton workplanesButton =
@ -102,8 +172,7 @@ static ShowHideButton outlinesButton =
{ &(SS.GW.showOutlines), "outlines", "outline of solid model" }; { &(SS.GW.showOutlines), "outlines", "outline of solid model" };
static ShowHideButton meshButton = static ShowHideButton meshButton =
{ &(SS.GW.showMesh), "mesh", "triangle mesh of solid model" }; { &(SS.GW.showMesh), "mesh", "triangle mesh of solid model" };
static ShowHideButton hdnLinesButton = static OccludedLinesButton occludedLinesButton;
{ &(SS.GW.showHdnLines), "hidden-lines", "hidden lines" };
static Button *buttons[] = { static Button *buttons[] = {
&workplanesButton, &workplanesButton,
@ -117,7 +186,7 @@ static Button *buttons[] = {
&outlinesButton, &outlinesButton,
&meshButton, &meshButton,
&spacerButton, &spacerButton,
&hdnLinesButton, &occludedLinesButton,
}; };
const TextWindow::Color TextWindow::fgColors[] = { const TextWindow::Color TextWindow::fgColors[] = {

View File

@ -719,9 +719,11 @@ public:
bool showOutlines; bool showOutlines;
bool showFaces; bool showFaces;
bool showMesh; bool showMesh;
bool showHdnLines;
void ToggleBool(bool *v); void ToggleBool(bool *v);
enum class DrawOccludedAs { INVISIBLE, STIPPLED, VISIBLE };
DrawOccludedAs drawOccludedAs;
bool showSnapGrid; bool showSnapGrid;
void DrawSnapGrid(Canvas *canvas); void DrawSnapGrid(Canvas *canvas);