From 6e860fb1480c2625c5abfef2fbf29bb9bbde8815 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sat, 13 Aug 2016 09:02:12 +0000 Subject: [PATCH] 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. --- CHANGELOG.md | 3 + res/CMakeLists.txt | 4 +- res/icons/text-window/occluded-invisible.png | Bin 0 -> 345 bytes ...hidden-lines.png => occluded-stippled.png} | Bin res/icons/text-window/occluded-visible.png | Bin 0 -> 365 bytes src/draw.cpp | 14 +++- src/drawentity.cpp | 4 + src/export.cpp | 6 +- src/graphicswin.cpp | 2 +- src/groupmesh.cpp | 7 +- src/sketch.h | 2 +- src/textwin.cpp | 75 +++++++++++++++++- src/ui.h | 4 +- 13 files changed, 105 insertions(+), 16 deletions(-) create mode 100644 res/icons/text-window/occluded-invisible.png rename res/icons/text-window/{hidden-lines.png => occluded-stippled.png} (100%) create mode 100644 res/icons/text-window/occluded-visible.png diff --git a/CHANGELOG.md b/CHANGELOG.md index f11a1c1..bb3d055 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ Other new features: * New link to match the on-screen size of the sketch with its actual size, "view → set to full scale". * 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 --- diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt index 3a2552a..dad6bf5 100644 --- a/res/CMakeLists.txt +++ b/res/CMakeLists.txt @@ -177,7 +177,9 @@ add_resources( icons/text-window/constraint.png icons/text-window/edges.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/normal.png icons/text-window/outlines.png diff --git a/res/icons/text-window/occluded-invisible.png b/res/icons/text-window/occluded-invisible.png new file mode 100644 index 0000000000000000000000000000000000000000..5ab4f82fbdf14b1145951f7597361a8157fbc840 GIT binary patch literal 345 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1rX+877Y2q^y~;*F9%q3^Bv6!F z2!t6g-L3lr6l5>)^mS!_z`@I*!e4%_eQ|$Sg3?z=mr%rK6N=ka< zwy0CDf;s_&a~Fv`qeB) zt7i>{!G3o*kNCtYJZO_tKKSpV_JIl2^CSxc48^Sy7>ng*Y*1el_lixx=%L|s`L>%^ zxE*S}oSv)k>ob2`5E3}~{;fCbvQ1OYNo*}RwAJDG#y>wc&RynNz;IRM!`kh?<)fRA zaU9^3s=ZTjkVi^t*SjgpB)Gkg`s^%eR2F-*eQtnQgT6_0+xbb)cONruNgdD{an^LB{Ts56mW#w literal 0 HcmV?d00001 diff --git a/res/icons/text-window/hidden-lines.png b/res/icons/text-window/occluded-stippled.png similarity index 100% rename from res/icons/text-window/hidden-lines.png rename to res/icons/text-window/occluded-stippled.png diff --git a/res/icons/text-window/occluded-visible.png b/res/icons/text-window/occluded-visible.png new file mode 100644 index 0000000000000000000000000000000000000000..2ccd73e6c878d72326c415f20f7bb17ca3415603 GIT binary patch literal 365 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1rX+877Y2q^y~;*F9%q3^Bv6!F z2!t6g-L3lr6l5>)^mS!_z`@I*WK{VlMGYwQ&(p;*#NzbXDTaB690XkdKkAs~F;VFh zhvt$N<0lMvT9p^vVRjYqSkmFb%I=Y^=P;X3X{p+Q#UIw$##y_HOqj9qS@pcV)}K?` z|B3Pb6|Z=@J)lg&=iVp2634>68!X4Rt^e_%$TI%MrS3-dpl1stGK^Dw_3Ix!wTt)J zv6@kA$rhuv48L+De;t!&F7b$LE#tRP;Vk(Q>{Vi5?5#3g{DdaM#+Ycu^1h?7wi{M! zm@n0OsL7+(z3j>H8Rxf0a5^nM+}3#4wDl+3F{vp&%Oo~bO_0BxfBAgr9X*3*lQ$mo z(Y^aR^1j|K<GuF{3LGg{J{GPz>r|@boFyt I=akR{0Em&1x&QzG literal 0 HcmV?d00001 diff --git a/src/draw.cpp b/src/draw.cpp index 1a8461d..b61a36b 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -565,10 +565,18 @@ void GraphicsWindow::DrawPersistent(Canvas *canvas) { // Now draw the entities. for(Entity &e : SK.entity) { - if(SS.GW.showHdnLines) { - e.Draw(Entity::DrawAs::HIDDEN, canvas); + switch(SS.GW.drawOccludedAs) { + 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 diff --git a/src/drawentity.cpp b/src/drawentity.cpp index 4576c86..92eec9b 100644 --- a/src/drawentity.cpp +++ b/src/drawentity.cpp @@ -474,6 +474,10 @@ void Entity::Draw(DrawAs how, Canvas *canvas) { stroke.layer = Canvas::Layer::NORMAL; break; + case DrawAs::OVERLAY: + stroke.layer = Canvas::Layer::FRONT; + break; + case DrawAs::HIDDEN: stroke.layer = Canvas::Layer::OCCLUDED; stroke.stipplePattern = Style::PatternType({ Style::HIDDEN_EDGE }); diff --git a/src/export.cpp b/src/export.cpp index 2ef4ee7..8990080 100644 --- a/src/export.cpp +++ b/src/export.cpp @@ -178,7 +178,7 @@ void SolveSpaceUI::ExportViewOrWireframeTo(const std::string &filename, bool exp GenerateAll(Generate::ALL); 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); g->GenerateDisplayItems(); sm = &(g->displayMesh); @@ -410,13 +410,13 @@ void SolveSpaceUI::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *s // Split the original edge against the mesh edges.AddEdge(se->a, se->b, se->auxA); root->OcclusionTestLine(*se, &edges, cnt); - if(SS.GW.showHdnLines) { + if(SS.GW.drawOccludedAs == GraphicsWindow::DrawOccludedAs::STIPPLED) { for(SEdge &se : edges.l) { if(se.tag == 1) { se.auxA = Style::HIDDEN_EDGE; } } - } else { + } else if(SS.GW.drawOccludedAs == GraphicsWindow::DrawOccludedAs::INVISIBLE) { edges.l.RemoveTagged(); } diff --git a/src/graphicswin.cpp b/src/graphicswin.cpp index c522dee..55af7bf 100644 --- a/src/graphicswin.cpp +++ b/src/graphicswin.cpp @@ -223,11 +223,11 @@ void GraphicsWindow::Init() { showNormals = true; showPoints = true; showConstraints = true; - showHdnLines = false; showShaded = true; showEdges = true; showMesh = false; showOutlines = false; + drawOccludedAs = DrawOccludedAs::INVISIBLE; showTextWindow = true; ShowTextWindow(showTextWindow); diff --git a/src/groupmesh.cpp b/src/groupmesh.cpp index da04ce1..599c5fa 100644 --- a/src/groupmesh.cpp +++ b/src/groupmesh.cpp @@ -444,7 +444,8 @@ bool Group::IsMeshGroup() { } 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) { case DrawMeshAs::DEFAULT: { @@ -452,7 +453,7 @@ void Group::DrawMesh(DrawMeshAs how, Canvas *canvas) { // the sketch. Canvas::Fill fillFront = {}; 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) { fillFront.color = Style::Color(Style::DIM_SOLID); @@ -549,7 +550,7 @@ void Group::Draw(Canvas *canvas) { ? Canvas::DrawOutlinesAs::EMPHASIZED_WITHOUT_CONTOUR : Canvas::DrawOutlinesAs::EMPHASIZED_AND_CONTOUR); - if(SS.GW.showHdnLines) { + if(SS.GW.drawOccludedAs == GraphicsWindow::DrawOccludedAs::STIPPLED) { Canvas::Stroke strokeHidden = strokeEdge; strokeHidden.layer = Canvas::Layer::OCCLUDED; strokeHidden.width = Style::Width(Style::HIDDEN_EDGE); diff --git a/src/sketch.h b/src/sketch.h index 3de3738..1ca5710 100644 --- a/src/sketch.h +++ b/src/sketch.h @@ -506,7 +506,7 @@ public: bool IsStylable() 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 GetReferencePoints(std::vector *refs); int GetPositionOfPoint(const Camera &camera, Point2d p); diff --git a/src/textwin.cpp b/src/textwin.cpp index 1f37a2b..2bdcf6e 100644 --- a/src/textwin.cpp +++ b/src/textwin.cpp @@ -83,6 +83,76 @@ public: } }; +class OccludedLinesButton : public Button { +public: + std::shared_ptr visibleIcon; + std::shared_ptr stippledIcon; + std::shared_ptr 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 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 ShowHideButton workplanesButton = @@ -102,8 +172,7 @@ static ShowHideButton outlinesButton = { &(SS.GW.showOutlines), "outlines", "outline of solid model" }; static ShowHideButton meshButton = { &(SS.GW.showMesh), "mesh", "triangle mesh of solid model" }; -static ShowHideButton hdnLinesButton = - { &(SS.GW.showHdnLines), "hidden-lines", "hidden lines" }; +static OccludedLinesButton occludedLinesButton; static Button *buttons[] = { &workplanesButton, @@ -117,7 +186,7 @@ static Button *buttons[] = { &outlinesButton, &meshButton, &spacerButton, - &hdnLinesButton, + &occludedLinesButton, }; const TextWindow::Color TextWindow::fgColors[] = { diff --git a/src/ui.h b/src/ui.h index 1e2c944..488d021 100644 --- a/src/ui.h +++ b/src/ui.h @@ -719,9 +719,11 @@ public: bool showOutlines; bool showFaces; bool showMesh; - bool showHdnLines; void ToggleBool(bool *v); + enum class DrawOccludedAs { INVISIBLE, STIPPLED, VISIBLE }; + DrawOccludedAs drawOccludedAs; + bool showSnapGrid; void DrawSnapGrid(Canvas *canvas);