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.
This commit is contained in:
parent
8e7d2eaa84
commit
f2633e4a57
|
@ -13,6 +13,7 @@ Other new features:
|
||||||
"Analyze → Measure Perimeter".
|
"Analyze → Measure Perimeter".
|
||||||
* 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.
|
||||||
|
|
||||||
2.2
|
2.2
|
||||||
---
|
---
|
||||||
|
|
|
@ -313,11 +313,11 @@ void GraphicsWindow::HandlePointForZoomToFit(Vector p, Point2d *pmax, Point2d *p
|
||||||
*wmin = min(*wmin, w);
|
*wmin = min(*wmin, w);
|
||||||
}
|
}
|
||||||
void GraphicsWindow::LoopOverPoints(const std::vector<Entity *> &entities,
|
void GraphicsWindow::LoopOverPoints(const std::vector<Entity *> &entities,
|
||||||
|
const std::vector<Constraint *> &constraints,
|
||||||
const std::vector<hEntity> &faces,
|
const std::vector<hEntity> &faces,
|
||||||
Point2d *pmax, Point2d *pmin, double *wmin,
|
Point2d *pmax, Point2d *pmin, double *wmin,
|
||||||
bool usePerspective, bool includeMesh) {
|
bool usePerspective, bool includeMesh) {
|
||||||
|
|
||||||
int i, j;
|
|
||||||
for(Entity *e : entities) {
|
for(Entity *e : entities) {
|
||||||
if(e->IsPoint()) {
|
if(e->IsPoint()) {
|
||||||
HandlePointForZoomToFit(e->PointGetNum(), pmax, pmin, wmin, usePerspective);
|
HandlePointForZoomToFit(e->PointGetNum(), pmax, pmin, wmin, usePerspective);
|
||||||
|
@ -329,7 +329,7 @@ void GraphicsWindow::LoopOverPoints(const std::vector<Entity *> &entities,
|
||||||
double r = e->CircleGetRadiusNum();
|
double r = e->CircleGetRadiusNum();
|
||||||
Vector c = SK.GetEntity(e->point[0])->PointGetNum();
|
Vector c = SK.GetEntity(e->point[0])->PointGetNum();
|
||||||
Quaternion q = SK.GetEntity(e->normal)->NormalGetNum();
|
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))) :
|
Vector p = (j == 0) ? (c.Plus(q.RotationU().ScaledBy( r))) :
|
||||||
(j == 1) ? (c.Plus(q.RotationU().ScaledBy(-r))) :
|
(j == 1) ? (c.Plus(q.RotationU().ScaledBy(-r))) :
|
||||||
(j == 2) ? (c.Plus(q.RotationV().ScaledBy( r))) :
|
(j == 2) ? (c.Plus(q.RotationV().ScaledBy( r))) :
|
||||||
|
@ -346,11 +346,19 @@ void GraphicsWindow::LoopOverPoints(const std::vector<Entity *> &entities,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(Constraint *c : constraints) {
|
||||||
|
std::vector<Vector> refs;
|
||||||
|
c->GetReferencePoints(GetCamera(), &refs);
|
||||||
|
for(Vector p : refs) {
|
||||||
|
HandlePointForZoomToFit(p, pmax, pmin, wmin, usePerspective);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!includeMesh && faces.empty()) return;
|
if(!includeMesh && faces.empty()) return;
|
||||||
|
|
||||||
Group *g = SK.GetGroup(activeGroup);
|
Group *g = SK.GetGroup(activeGroup);
|
||||||
g->GenerateDisplayItems();
|
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]);
|
STriangle *tr = &(g->displayMesh.l.elem[i]);
|
||||||
if(!includeMesh) {
|
if(!includeMesh) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
@ -366,46 +374,56 @@ void GraphicsWindow::LoopOverPoints(const std::vector<Entity *> &entities,
|
||||||
HandlePointForZoomToFit(tr->c, pmax, pmin, wmin, usePerspective);
|
HandlePointForZoomToFit(tr->c, pmax, pmin, wmin, usePerspective);
|
||||||
}
|
}
|
||||||
if(!includeMesh) return;
|
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]);
|
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);
|
HandlePointForZoomToFit(sc->l.elem[j].p, pmax, pmin, wmin, usePerspective);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void GraphicsWindow::ZoomToFit(bool includingInvisibles, bool useSelection) {
|
void GraphicsWindow::ZoomToFit(bool includingInvisibles, bool useSelection) {
|
||||||
std::vector<Entity *> entities;
|
std::vector<Entity *> entities;
|
||||||
|
std::vector<Constraint *> constraints;
|
||||||
std::vector<hEntity> faces;
|
std::vector<hEntity> faces;
|
||||||
|
|
||||||
if(useSelection) {
|
if(useSelection) {
|
||||||
for(int i = 0; i < selection.n; i++) {
|
for(int i = 0; i < selection.n; i++) {
|
||||||
Selection *s = &selection.elem[i];
|
Selection *s = &selection.elem[i];
|
||||||
if(s->entity.v == 0) continue;
|
if(s->entity.v != 0) {
|
||||||
Entity *e = SK.entity.FindById(s->entity);
|
Entity *e = SK.entity.FindById(s->entity);
|
||||||
if(e->IsFace()) {
|
if(e->IsFace()) {
|
||||||
faces.push_back(e->h);
|
faces.push_back(e->h);
|
||||||
continue;
|
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) {
|
if(!selectionUsed) {
|
||||||
for(int i = 0; i<SK.entity.n; i++) {
|
for(Entity &e : SK.entity) {
|
||||||
Entity *e = &(SK.entity.elem[i]);
|
|
||||||
// we don't want to handle separate points, because we will iterate them inside entities.
|
// we don't want to handle separate points, because we will iterate them inside entities.
|
||||||
if(e->IsPoint()) continue;
|
if(e.IsPoint()) continue;
|
||||||
if(!includingInvisibles && !e->IsVisible()) continue;
|
if(!includingInvisibles && !e.IsVisible()) continue;
|
||||||
entities.push_back(e);
|
entities.push_back(&e);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Constraint &c : SK.constraint) {
|
||||||
|
if(!c.IsVisible()) continue;
|
||||||
|
constraints.push_back(&c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// On the first run, ignore perspective.
|
// On the first run, ignore perspective.
|
||||||
Point2d pmax = { -1e12, -1e12 }, pmin = { 1e12, 1e12 };
|
Point2d pmax = { -1e12, -1e12 }, pmin = { 1e12, 1e12 };
|
||||||
double wmin = 1;
|
double wmin = 1;
|
||||||
LoopOverPoints(entities, faces, &pmax, &pmin, &wmin,
|
LoopOverPoints(entities, constraints, faces, &pmax, &pmin, &wmin,
|
||||||
/*usePerspective=*/false, /*includeMesh=*/!selectionUsed);
|
/*usePerspective=*/false, /*includeMesh=*/!selectionUsed);
|
||||||
|
|
||||||
double xm = (pmax.x + pmin.x)/2, ym = (pmax.y + pmin.y)/2;
|
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;
|
pmax.x = -1e12; pmax.y = -1e12;
|
||||||
pmin.x = 1e12; pmin.y = 1e12;
|
pmin.x = 1e12; pmin.y = 1e12;
|
||||||
wmin = 1;
|
wmin = 1;
|
||||||
LoopOverPoints(entities, faces, &pmax, &pmin, &wmin,
|
LoopOverPoints(entities, constraints, faces, &pmax, &pmin, &wmin,
|
||||||
/*usePerspective=*/true, /*includeMesh=*/!selectionUsed);
|
/*usePerspective=*/true, /*includeMesh=*/!selectionUsed);
|
||||||
|
|
||||||
// Adjust the scale so that no points are behind the camera
|
// Adjust the scale so that no points are behind the camera
|
||||||
|
|
5
src/ui.h
5
src/ui.h
|
@ -559,7 +559,10 @@ public:
|
||||||
Vector VectorFromProjs(Vector rightUpForward);
|
Vector VectorFromProjs(Vector rightUpForward);
|
||||||
void HandlePointForZoomToFit(Vector p, Point2d *pmax, Point2d *pmin,
|
void HandlePointForZoomToFit(Vector p, Point2d *pmax, Point2d *pmin,
|
||||||
double *wmin, bool usePerspective);
|
double *wmin, bool usePerspective);
|
||||||
void LoopOverPoints(const std::vector<Entity *> &entity, const std::vector<hEntity> &faces, Point2d *pmax, Point2d *pmin,
|
void LoopOverPoints(const std::vector<Entity *> &entities,
|
||||||
|
const std::vector<Constraint *> &constraints,
|
||||||
|
const std::vector<hEntity> &faces,
|
||||||
|
Point2d *pmax, Point2d *pmin,
|
||||||
double *wmin, bool usePerspective, bool includeMesh);
|
double *wmin, bool usePerspective, bool includeMesh);
|
||||||
void ZoomToFit(bool includingInvisibles, bool useSelection = false);
|
void ZoomToFit(bool includingInvisibles, bool useSelection = false);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user