From f2633e4a57ba0fef8864b62ef04a09baa66e15d6 Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 1 Aug 2016 14:00:00 +0000 Subject: [PATCH] Also consider constraints when zooming to fit. Before this commit, when working on convex sketches, zooming to fit was guaranteed to clip most or even all constraints, making it quite useless. --- CHANGELOG.md | 1 + src/graphicswin.cpp | 56 ++++++++++++++++++++++++++++++--------------- src/ui.h | 5 +++- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37fd2f0..dabd876 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Other new features: "Analyze → Measure Perimeter". * 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. 2.2 --- diff --git a/src/graphicswin.cpp b/src/graphicswin.cpp index c8eb115..f91d2ea 100644 --- a/src/graphicswin.cpp +++ b/src/graphicswin.cpp @@ -313,11 +313,11 @@ void GraphicsWindow::HandlePointForZoomToFit(Vector p, Point2d *pmax, Point2d *p *wmin = min(*wmin, w); } void GraphicsWindow::LoopOverPoints(const std::vector &entities, + const std::vector &constraints, const std::vector &faces, Point2d *pmax, Point2d *pmin, double *wmin, bool usePerspective, bool includeMesh) { - int i, j; for(Entity *e : entities) { if(e->IsPoint()) { HandlePointForZoomToFit(e->PointGetNum(), pmax, pmin, wmin, usePerspective); @@ -329,7 +329,7 @@ void GraphicsWindow::LoopOverPoints(const std::vector &entities, double r = e->CircleGetRadiusNum(); Vector c = SK.GetEntity(e->point[0])->PointGetNum(); Quaternion q = SK.GetEntity(e->normal)->NormalGetNum(); - for(j = 0; j < 4; j++) { + for(int j = 0; j < 4; j++) { Vector p = (j == 0) ? (c.Plus(q.RotationU().ScaledBy( r))) : (j == 1) ? (c.Plus(q.RotationU().ScaledBy(-r))) : (j == 2) ? (c.Plus(q.RotationV().ScaledBy( r))) : @@ -346,11 +346,19 @@ void GraphicsWindow::LoopOverPoints(const std::vector &entities, } } + for(Constraint *c : constraints) { + std::vector refs; + c->GetReferencePoints(GetCamera(), &refs); + for(Vector p : refs) { + HandlePointForZoomToFit(p, pmax, pmin, wmin, usePerspective); + } + } + if(!includeMesh && faces.empty()) return; Group *g = SK.GetGroup(activeGroup); g->GenerateDisplayItems(); - for(i = 0; i < g->displayMesh.l.n; i++) { + for(int i = 0; i < g->displayMesh.l.n; i++) { STriangle *tr = &(g->displayMesh.l.elem[i]); if(!includeMesh) { bool found = false; @@ -366,46 +374,56 @@ void GraphicsWindow::LoopOverPoints(const std::vector &entities, HandlePointForZoomToFit(tr->c, pmax, pmin, wmin, usePerspective); } if(!includeMesh) return; - for(i = 0; i < g->polyLoops.l.n; i++) { + for(int i = 0; i < g->polyLoops.l.n; i++) { SContour *sc = &(g->polyLoops.l.elem[i]); - for(j = 0; j < sc->l.n; j++) { + for(int j = 0; j < sc->l.n; j++) { HandlePointForZoomToFit(sc->l.elem[j].p, pmax, pmin, wmin, usePerspective); } } } void GraphicsWindow::ZoomToFit(bool includingInvisibles, bool useSelection) { std::vector entities; + std::vector constraints; std::vector faces; if(useSelection) { for(int i = 0; i < selection.n; i++) { Selection *s = &selection.elem[i]; - if(s->entity.v == 0) continue; - Entity *e = SK.entity.FindById(s->entity); - if(e->IsFace()) { - faces.push_back(e->h); - continue; + if(s->entity.v != 0) { + Entity *e = SK.entity.FindById(s->entity); + if(e->IsFace()) { + faces.push_back(e->h); + continue; + } + entities.push_back(e); + } + if(s->constraint.v != 0) { + Constraint *c = SK.constraint.FindById(s->constraint); + constraints.push_back(c); } - entities.push_back(e); } } - bool selectionUsed = !entities.empty() || !faces.empty(); + bool selectionUsed = !entities.empty() || !constraints.empty() || !faces.empty(); if(!selectionUsed) { - for(int i = 0; iIsPoint()) continue; - if(!includingInvisibles && !e->IsVisible()) continue; - entities.push_back(e); + if(e.IsPoint()) continue; + if(!includingInvisibles && !e.IsVisible()) continue; + entities.push_back(&e); + } + + for(Constraint &c : SK.constraint) { + if(!c.IsVisible()) continue; + constraints.push_back(&c); } } // On the first run, ignore perspective. Point2d pmax = { -1e12, -1e12 }, pmin = { 1e12, 1e12 }; double wmin = 1; - LoopOverPoints(entities, faces, &pmax, &pmin, &wmin, + LoopOverPoints(entities, constraints, faces, &pmax, &pmin, &wmin, /*usePerspective=*/false, /*includeMesh=*/!selectionUsed); double xm = (pmax.x + pmin.x)/2, ym = (pmax.y + pmin.y)/2; @@ -431,7 +449,7 @@ void GraphicsWindow::ZoomToFit(bool includingInvisibles, bool useSelection) { pmax.x = -1e12; pmax.y = -1e12; pmin.x = 1e12; pmin.y = 1e12; wmin = 1; - LoopOverPoints(entities, faces, &pmax, &pmin, &wmin, + LoopOverPoints(entities, constraints, faces, &pmax, &pmin, &wmin, /*usePerspective=*/true, /*includeMesh=*/!selectionUsed); // Adjust the scale so that no points are behind the camera diff --git a/src/ui.h b/src/ui.h index a216674..ac9cb46 100644 --- a/src/ui.h +++ b/src/ui.h @@ -559,7 +559,10 @@ public: Vector VectorFromProjs(Vector rightUpForward); void HandlePointForZoomToFit(Vector p, Point2d *pmax, Point2d *pmin, double *wmin, bool usePerspective); - void LoopOverPoints(const std::vector &entity, const std::vector &faces, Point2d *pmax, Point2d *pmin, + void LoopOverPoints(const std::vector &entities, + const std::vector &constraints, + const std::vector &faces, + Point2d *pmax, Point2d *pmin, double *wmin, bool usePerspective, bool includeMesh); void ZoomToFit(bool includingInvisibles, bool useSelection = false);