Force DOF check every time a constraint is added.

Before this commit, it was possible to add some redundant constraints
(e.g. vertical, horizontal or midpoint) without failing the sketch,
because SolveBySubstitution() removed the redundant equations.
However, this could result in the solve failing later because
the system didn't converge, without any pointers as to the true
cause of the failure.
pull/144/head
EvilSpirit 2016-10-22 22:08:41 +07:00 committed by whitequark
parent 10251c6484
commit 9148d0cb91
6 changed files with 22 additions and 8 deletions

View File

@ -44,6 +44,8 @@ Bugs fixed:
causes the line length to collapse.
* Curve-line constraints (in 3d), parallel constraints (in 3d), and
same orientation constraints are more robust.
* Adding some constraints (vertical, midpoint, etc) twice will now error out
immediately, instead of later and in a confusing way.
2.3
---

View File

@ -85,6 +85,7 @@ hConstraint Constraint::AddConstraint(Constraint *c, bool rememberForUndo) {
SK.constraint.AddAndAssignId(c);
SS.MarkGroupDirty(c->group);
SK.GetGroup(c->group)->dofCheckOk = false;
SS.ScheduleGenerateAll();
return c->h;
}

View File

@ -528,7 +528,13 @@ void SolveSpaceUI::SolveGroup(hGroup hg, bool andFindFree) {
MarkDraggedParams();
g->solved.remove.Clear();
SolveResult how = sys.Solve(g, &(g->solved.dof),
&(g->solved.remove), /*andFindBad=*/true, andFindFree);
&(g->solved.remove),
/*andFindBad=*/true,
/*andFindFree=*/andFindFree,
/*forceDofCheck=*/!g->dofCheckOk);
if(how == SolveResult::OKAY) {
g->dofCheckOk = true;
}
g->solved.how = how;
FreeAllTemporary();
}

View File

@ -141,6 +141,7 @@ public:
double scale;
bool clean;
bool dofCheckOk;
hEntity activeWorkplane;
double valA;
double valB;

View File

@ -444,7 +444,7 @@ public:
void EvalJacobian();
void WriteEquationsExceptFor(hConstraint hc, Group *g);
void FindWhichToRemoveToFixJacobian(Group *g, List<hConstraint> *bad);
void FindWhichToRemoveToFixJacobian(Group *g, List<hConstraint> *bad, bool forceDofCheck);
void SolveBySubstitution();
bool IsDragged(hParam p);
@ -452,7 +452,7 @@ public:
bool NewtonSolve(int tag);
SolveResult Solve(Group *g, int *dof, List<hConstraint> *bad,
bool andFindBad, bool andFindFree);
bool andFindBad, bool andFindFree, bool forceDofCheck = false);
void Clear();
};

View File

@ -359,7 +359,7 @@ void System::WriteEquationsExceptFor(hConstraint hc, Group *g) {
g->GenerateEquations(&eq);
}
void System::FindWhichToRemoveToFixJacobian(Group *g, List<hConstraint> *bad) {
void System::FindWhichToRemoveToFixJacobian(Group *g, List<hConstraint> *bad, bool forceDofCheck) {
int a, i;
for(a = 0; a < 2; a++) {
@ -382,7 +382,9 @@ void System::FindWhichToRemoveToFixJacobian(Group *g, List<hConstraint> *bad) {
// It's a major speedup to solve the easy ones by substitution here,
// and that doesn't break anything.
if(!forceDofCheck) {
SolveBySubstitution();
}
WriteJacobian(0);
EvalJacobian();
@ -397,7 +399,7 @@ void System::FindWhichToRemoveToFixJacobian(Group *g, List<hConstraint> *bad) {
}
SolveResult System::Solve(Group *g, int *dof, List<hConstraint> *bad,
bool andFindBad, bool andFindFree)
bool andFindBad, bool andFindFree, bool forceDofCheck)
{
WriteEquationsExceptFor(Constraint::NO_CONSTRAINT, g);
@ -418,7 +420,9 @@ SolveResult System::Solve(Group *g, int *dof, List<hConstraint> *bad,
param.ClearTags();
eq.ClearTags();
if(!forceDofCheck) {
SolveBySubstitution();
}
// Before solving the big system, see if we can find any equations that
// are soluble alone. This can be a huge speedup. We don't know whether
@ -465,7 +469,7 @@ SolveResult System::Solve(Group *g, int *dof, List<hConstraint> *bad,
rankOk = TestRank();
if(!rankOk) {
if(!g->allowRedundant) {
if(andFindBad) FindWhichToRemoveToFixJacobian(g, bad);
if(andFindBad) FindWhichToRemoveToFixJacobian(g, bad, forceDofCheck);
}
} else {
// This is not the full Jacobian, but any substitutions or single-eq