diff --git a/CHANGELOG.md b/CHANGELOG.md index 65ea7704..de85b8e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 --- diff --git a/src/constraint.cpp b/src/constraint.cpp index 24634c0b..86073c7b 100644 --- a/src/constraint.cpp +++ b/src/constraint.cpp @@ -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; } diff --git a/src/generate.cpp b/src/generate.cpp index 5c466d8d..acf82637 100644 --- a/src/generate.cpp +++ b/src/generate.cpp @@ -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(); } diff --git a/src/sketch.h b/src/sketch.h index 74f0d3a1..c0ba6822 100644 --- a/src/sketch.h +++ b/src/sketch.h @@ -141,6 +141,7 @@ public: double scale; bool clean; + bool dofCheckOk; hEntity activeWorkplane; double valA; double valB; diff --git a/src/solvespace.h b/src/solvespace.h index 28a653a1..3fd468e0 100644 --- a/src/solvespace.h +++ b/src/solvespace.h @@ -444,7 +444,7 @@ public: void EvalJacobian(); void WriteEquationsExceptFor(hConstraint hc, Group *g); - void FindWhichToRemoveToFixJacobian(Group *g, List *bad); + void FindWhichToRemoveToFixJacobian(Group *g, List *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 *bad, - bool andFindBad, bool andFindFree); + bool andFindBad, bool andFindFree, bool forceDofCheck = false); void Clear(); }; diff --git a/src/system.cpp b/src/system.cpp index 7ff8c3d2..5e6b8070 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -359,7 +359,7 @@ void System::WriteEquationsExceptFor(hConstraint hc, Group *g) { g->GenerateEquations(&eq); } -void System::FindWhichToRemoveToFixJacobian(Group *g, List *bad) { +void System::FindWhichToRemoveToFixJacobian(Group *g, List *bad, bool forceDofCheck) { int a, i; for(a = 0; a < 2; a++) { @@ -382,7 +382,9 @@ void System::FindWhichToRemoveToFixJacobian(Group *g, List *bad) { // It's a major speedup to solve the easy ones by substitution here, // and that doesn't break anything. - SolveBySubstitution(); + if(!forceDofCheck) { + SolveBySubstitution(); + } WriteJacobian(0); EvalJacobian(); @@ -397,7 +399,7 @@ void System::FindWhichToRemoveToFixJacobian(Group *g, List *bad) { } SolveResult System::Solve(Group *g, int *dof, List *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 *bad, param.ClearTags(); eq.ClearTags(); - SolveBySubstitution(); + 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 *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