Skip creating an automatic H/V constraint if it would be redundant.
This means that automatically added H/V constraints now will never cause the sketch to become overconstrained, which currently makes that feature almost unusable.pull/434/head
parent
394c1f62d8
commit
549565958f
|
@ -37,6 +37,8 @@ New constraint features:
|
||||||
Values are edited in the configured unit regardless of label format.
|
Values are edited in the configured unit regardless of label format.
|
||||||
* It is now possible to turn off automatic creation of horizontal/vertical
|
* It is now possible to turn off automatic creation of horizontal/vertical
|
||||||
constraints on line segments.
|
constraints on line segments.
|
||||||
|
* Automatic creation of constraints no longer happens if the constraint
|
||||||
|
would have been redundant with other ones.
|
||||||
|
|
||||||
New export/import features:
|
New export/import features:
|
||||||
* Three.js: allow configuring projection for exported model, and initially
|
* Three.js: allow configuring projection for exported model, and initially
|
||||||
|
|
|
@ -75,10 +75,6 @@ void Constraint::DeleteAllConstraintsFor(Constraint::Type type, hEntity entityA,
|
||||||
SS.GW.hover.Clear();
|
SS.GW.hover.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
hConstraint Constraint::AddConstraint(Constraint *c) {
|
|
||||||
return AddConstraint(c, /*rememberForUndo=*/true);
|
|
||||||
}
|
|
||||||
|
|
||||||
hConstraint Constraint::AddConstraint(Constraint *c, bool rememberForUndo) {
|
hConstraint Constraint::AddConstraint(Constraint *c, bool rememberForUndo) {
|
||||||
if(rememberForUndo) SS.UndoRemember();
|
if(rememberForUndo) SS.UndoRemember();
|
||||||
|
|
||||||
|
@ -107,8 +103,17 @@ hConstraint Constraint::Constrain(Constraint::Type type, hEntity ptA, hEntity pt
|
||||||
return AddConstraint(&c, /*rememberForUndo=*/false);
|
return AddConstraint(&c, /*rememberForUndo=*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
hConstraint Constraint::Constrain(Constraint::Type type, hEntity ptA, hEntity ptB, hEntity entityA){
|
hConstraint Constraint::TryConstrain(Constraint::Type type, hEntity ptA, hEntity ptB,
|
||||||
return Constrain(type, ptA, ptB, entityA, Entity::NO_ENTITY, /*other=*/false, /*other2=*/false);
|
hEntity entityA, hEntity entityB,
|
||||||
|
bool other, bool other2) {
|
||||||
|
SolveResult solvedBefore = SS.TestRankForGroup(SS.GW.activeGroup);
|
||||||
|
hConstraint hc = Constrain(type, ptA, ptB, entityA, entityB, other, other2);
|
||||||
|
SolveResult solvedAfter = SS.TestRankForGroup(SS.GW.activeGroup);
|
||||||
|
if(solvedBefore == SolveResult::OKAY && solvedAfter == SolveResult::REDUNDANT_OKAY) {
|
||||||
|
SK.constraint.RemoveById(hc);
|
||||||
|
hc = {};
|
||||||
|
}
|
||||||
|
return hc;
|
||||||
}
|
}
|
||||||
|
|
||||||
hConstraint Constraint::ConstrainCoincident(hEntity ptA, hEntity ptB) {
|
hConstraint Constraint::ConstrainCoincident(hEntity ptA, hEntity ptB) {
|
||||||
|
|
|
@ -526,7 +526,7 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
||||||
if(context.active) return;
|
if(context.active) return;
|
||||||
|
|
||||||
if(pending.operation == Pending::DRAGGING_NEW_LINE_POINT && pending.hasSuggestion) {
|
if(pending.operation == Pending::DRAGGING_NEW_LINE_POINT && pending.hasSuggestion) {
|
||||||
Constraint::Constrain(SS.GW.pending.suggestion,
|
Constraint::TryConstrain(SS.GW.pending.suggestion,
|
||||||
Entity::NO_ENTITY, Entity::NO_ENTITY, pending.request.entity(0));
|
Entity::NO_ENTITY, Entity::NO_ENTITY, pending.request.entity(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -943,7 +943,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will be clobbered by MouseMoved below.
|
// This will be clobbered by MouseMoved below.
|
||||||
bool hasConstraintSuggestion = SS.GW.pending.hasSuggestion;
|
bool hasConstraintSuggestion = pending.hasSuggestion;
|
||||||
|
Constraint::Type constraintSuggestion = pending.suggestion;
|
||||||
|
|
||||||
// Make sure the hover is up to date.
|
// Make sure the hover is up to date.
|
||||||
MouseMoved(mx, my, /*leftDown=*/false, /*middleDown=*/false, /*rightDown=*/false,
|
MouseMoved(mx, my, /*leftDown=*/false, /*middleDown=*/false, /*rightDown=*/false,
|
||||||
|
@ -1223,12 +1224,6 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case Pending::DRAGGING_NEW_LINE_POINT: {
|
case Pending::DRAGGING_NEW_LINE_POINT: {
|
||||||
// Constrain the line segment horizontal or vertical if close enough
|
|
||||||
if(hasConstraintSuggestion) {
|
|
||||||
Constraint::Constrain(SS.GW.pending.suggestion,
|
|
||||||
Entity::NO_ENTITY, Entity::NO_ENTITY, pending.request.entity(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hover.entity.v) {
|
if(hover.entity.v) {
|
||||||
Entity *e = SK.GetEntity(hover.entity);
|
Entity *e = SK.GetEntity(hover.entity);
|
||||||
if(e->IsPoint()) {
|
if(e->IsPoint()) {
|
||||||
|
@ -1246,7 +1241,15 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ConstrainPointByHovered(pending.point, &mouse)) {
|
bool doneDragging = ConstrainPointByHovered(pending.point, &mouse);
|
||||||
|
|
||||||
|
// Constrain the line segment horizontal or vertical if close enough
|
||||||
|
if(hasConstraintSuggestion) {
|
||||||
|
Constraint::TryConstrain(constraintSuggestion,
|
||||||
|
Entity::NO_ENTITY, Entity::NO_ENTITY, pending.request.entity(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(doneDragging) {
|
||||||
ClearPending();
|
ClearPending();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
13
src/sketch.h
13
src/sketch.h
|
@ -727,16 +727,17 @@ public:
|
||||||
|
|
||||||
std::string DescriptionString() const;
|
std::string DescriptionString() const;
|
||||||
|
|
||||||
static hConstraint AddConstraint(Constraint *c, bool rememberForUndo);
|
static hConstraint AddConstraint(Constraint *c, bool rememberForUndo = true);
|
||||||
static hConstraint AddConstraint(Constraint *c);
|
|
||||||
static void MenuConstrain(Command id);
|
static void MenuConstrain(Command id);
|
||||||
static void DeleteAllConstraintsFor(Constraint::Type type, hEntity entityA, hEntity ptA);
|
static void DeleteAllConstraintsFor(Constraint::Type type, hEntity entityA, hEntity ptA);
|
||||||
|
|
||||||
static hConstraint ConstrainCoincident(hEntity ptA, hEntity ptB);
|
static hConstraint ConstrainCoincident(hEntity ptA, hEntity ptB);
|
||||||
static hConstraint Constrain(Constraint::Type type, hEntity ptA, hEntity ptB, hEntity entityA);
|
static hConstraint Constrain(Constraint::Type type, hEntity ptA, hEntity ptB, hEntity entityA,
|
||||||
static hConstraint Constrain(Constraint::Type type, hEntity ptA, hEntity ptB,
|
hEntity entityB = Entity::NO_ENTITY, bool other = false,
|
||||||
hEntity entityA, hEntity entityB,
|
bool other2 = false);
|
||||||
bool other, bool other2);
|
static hConstraint TryConstrain(Constraint::Type type, hEntity ptA, hEntity ptB,
|
||||||
|
hEntity entityA, hEntity entityB = Entity::NO_ENTITY,
|
||||||
|
bool other = false, bool other2 = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
class hEquation {
|
class hEquation {
|
||||||
|
|
Loading…
Reference in New Issue