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);