Automatically add horz/vert constraints to lines if close enough.

This commit is contained in:
whitequark 2015-03-30 01:26:07 +03:00
parent f89020ad26
commit 69c509064c
4 changed files with 73 additions and 0 deletions

View File

@ -716,6 +716,28 @@ nogrid:;
SK.constraint.elem[i].Draw();
}
// Draw the "pending" constraint, i.e. a constraint that would be
// placed on a line that is almost horizontal or vertical
if(SS.GW.pending.operation == DRAGGING_NEW_LINE_POINT) {
SuggestedConstraint suggested =
SS.GW.SuggestLineConstraint(SS.GW.pending.request);
if(suggested != GraphicsWindow::SUGGESTED_NONE) {
Constraint c;
ZERO(&c);
c.group = SS.GW.activeGroup;
c.workplane = SS.GW.ActiveWorkplane();
c.type = suggested;
c.ptA = Entity::NO_ENTITY;
c.ptB = Entity::NO_ENTITY;
c.entityA = SS.GW.pending.request.entity(0);
c.entityB = Entity::NO_ENTITY;
c.other = false;
c.other2 = false;
// Only draw.
c.Draw();
}
}
// Draw the traced path, if one exists
ssglLineWidth(Style::Width(Style::ANALYZE));
ssglColorRGB(Style::Color(Style::ANALYZE));

View File

@ -1016,3 +1016,27 @@ void GraphicsWindow::ToggleBool(bool *v) {
SS.ScheduleShowTW();
}
GraphicsWindow::SuggestedConstraint GraphicsWindow::SuggestLineConstraint(hRequest request) {
if(LockedInWorkplane()) {
Entity *ptA = SK.GetEntity(request.entity(1)),
*ptB = SK.GetEntity(request.entity(2));
Expr *au, *av, *bu, *bv;
ptA->PointGetExprsInWorkplane(ActiveWorkplane(), &au, &av);
ptB->PointGetExprsInWorkplane(ActiveWorkplane(), &bu, &bv);
Expr *du = au->Minus(bu);
Expr *dv = av->Minus(bv);
const double TOLERANCE = 10.0;
if(fabs(du->Eval()) * scale < TOLERANCE)
return SUGGESTED_VERTICAL;
else if(fabs(dv->Eval()) * scale < TOLERANCE)
return SUGGESTED_HORIZONTAL;
else
return SUGGESTED_NONE;
} else {
return SUGGESTED_NONE;
}
}

View File

@ -497,6 +497,15 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
if(context.active) return;
if(pending.operation == DRAGGING_NEW_LINE_POINT) {
SuggestedConstraint suggested =
SS.GW.SuggestLineConstraint(SS.GW.pending.request);
if(suggested != SUGGESTED_NONE) {
Constraint::Constrain(suggested,
Entity::NO_ENTITY, Entity::NO_ENTITY, pending.request.entity(0));
}
}
if(pending.operation == DRAGGING_NEW_LINE_POINT ||
pending.operation == DRAGGING_NEW_CUBIC_POINT)
{
@ -806,6 +815,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
ClearSuper();
pending.operation = DRAGGING_NEW_LINE_POINT;
pending.request = hr;
pending.point = hr.entity(2);
pending.description = "click next point of line, or press Esc";
SK.GetEntity(pending.point)->PointForceTo(v);
@ -1009,6 +1019,14 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
}
case DRAGGING_NEW_LINE_POINT: {
// Constrain the line segment horizontal or vertical if close enough
SuggestedConstraint suggested =
SS.GW.SuggestLineConstraint(SS.GW.pending.request);
if(suggested != SUGGESTED_NONE) {
Constraint::Constrain(suggested,
Entity::NO_ENTITY, Entity::NO_ENTITY, pending.request.entity(0));
}
if(hover.entity.v) {
Entity *e = SK.GetEntity(hover.entity);
if(e->IsPoint()) {
@ -1044,6 +1062,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
// And drag an endpoint of the new line segment
pending.operation = DRAGGING_NEW_LINE_POINT;
pending.request = hr;
pending.point = hr.entity(2);
pending.description = "click next point of line, or press Esc";

View File

@ -523,6 +523,7 @@ public:
struct {
int operation;
hRequest request;
hEntity point;
List<hEntity> points;
hEntity circle;
@ -535,6 +536,13 @@ public:
// The constraint that is being edited with the on-screen textbox.
hConstraint constraintBeingEdited;
enum SuggestedConstraint {
SUGGESTED_NONE = 0,
SUGGESTED_HORIZONTAL = Constraint::HORIZONTAL,
SUGGESTED_VERTICAL = Constraint::VERTICAL,
};
SuggestedConstraint SuggestLineConstraint(hRequest lineSegment);
Vector SnapToGrid(Vector p);
bool ConstrainPointByHovered(hEntity pt);
void DeleteTaggedRequests(void);