Add a solver option to not calculate the failing constraints if
we're inconsistent (singular Jacobian). That's slow, so we should provide a library interface to disable it. [git-p4: depot-paths = "//depot/solvespace/": change = 1946]solver
parent
1554402b30
commit
9efa922795
|
@ -1,3 +1,15 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Some sample code for slvs.lib. We draw some geometric entities, provide
|
||||
// initial guesses for their positions, and then constrain them. The solver
|
||||
// calculates their new positions, in order to satisfy the constraints.
|
||||
//
|
||||
// This code is provide for evaluation purposes only. To purchase a license,
|
||||
// please visit:
|
||||
//
|
||||
// http://solvespace.com/
|
||||
//
|
||||
// Copyright 2009, Jonathan Westhues
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -141,14 +153,19 @@ void Example2d(void)
|
|||
200,
|
||||
15.0,
|
||||
301, 101, 0, 0);
|
||||
|
||||
// And the distance from one endpoint to the origin is 15.0 units.
|
||||
/*
|
||||
// And same for the other endpoint; so if you add this constraint then
|
||||
// the sketch is overconstrained and will signal an error.
|
||||
sys.constraint[sys.constraints++] = Slvs_MakeConstraint(
|
||||
5, g,
|
||||
SLVS_C_PT_PT_DISTANCE,
|
||||
200,
|
||||
18.0,
|
||||
302, 101, 0, 0);
|
||||
302, 101, 0, 0); */
|
||||
|
||||
// If the solver fails, then ask it to report which constraints caused
|
||||
// the problem.
|
||||
sys.calculateFaileds = 1;
|
||||
|
||||
// And solve.
|
||||
Slvs_Solve(&sys, g);
|
||||
|
|
|
@ -187,7 +187,8 @@ default: dbp("bad constraint type %d", sc->type); return;
|
|||
ZERO(&bad);
|
||||
|
||||
// Now we're finally ready to solve!
|
||||
int how = SYS.Solve(&g, &(ssys->dof), &bad, false);
|
||||
bool andFindBad = ssys->calculateFaileds ? true : false;
|
||||
int how = SYS.Solve(&g, &(ssys->dof), &bad, andFindBad, false);
|
||||
|
||||
switch(how) {
|
||||
case System::SOLVED_OKAY:
|
||||
|
|
|
@ -128,7 +128,14 @@ typedef struct {
|
|||
// Unused members of this array should be set to zero.
|
||||
Slvs_hParam dragged[4];
|
||||
|
||||
//// OUTPUT PARAMETERS
|
||||
// If the solver fails, then it can determine which constraints are
|
||||
// causing the problem. But this is a relatively slow process (for
|
||||
// a system with n constraints, about n times as long as just solving).
|
||||
// If calculateFaileds is set, then the solver will do so, otherwise
|
||||
// not.
|
||||
int calculateFaileds;
|
||||
|
||||
//// OUTPUT VARIABLES
|
||||
//
|
||||
// If the solver fails, then it can report which constraints are causing
|
||||
// the problem. The caller should allocate the array failed[], and pass
|
||||
|
|
|
@ -410,7 +410,7 @@ void SolveSpace::SolveGroup(hGroup hg, bool andFindFree) {
|
|||
MarkDraggedParams();
|
||||
g->solved.remove.Clear();
|
||||
int how = sys.Solve(g, &(g->solved.dof),
|
||||
&(g->solved.remove), andFindFree);
|
||||
&(g->solved.remove), true, andFindFree);
|
||||
if((how != System::SOLVED_OKAY) ||
|
||||
(how == System::SOLVED_OKAY && g->solved.how != System::SOLVED_OKAY))
|
||||
{
|
||||
|
|
|
@ -271,7 +271,8 @@ public:
|
|||
static const int DIDNT_CONVERGE = 10;
|
||||
static const int SINGULAR_JACOBIAN = 11;
|
||||
static const int TOO_MANY_UNKNOWNS = 20;
|
||||
int Solve(Group *g, int *dof, List<hConstraint> *bad, bool andFindFree);
|
||||
int Solve(Group *g, int *dof, List<hConstraint> *bad,
|
||||
bool andFindBad, bool andFindFree);
|
||||
};
|
||||
|
||||
class TtfFont {
|
||||
|
|
|
@ -363,7 +363,7 @@ void System::FindWhichToRemoveToFixJacobian(Group *g, List<hConstraint> *bad) {
|
|||
}
|
||||
|
||||
int System::Solve(Group *g, int *dof, List<hConstraint> *bad,
|
||||
bool andFindFree)
|
||||
bool andFindBad, bool andFindFree)
|
||||
{
|
||||
WriteEquationsExceptFor(Constraint::NO_CONSTRAINT, g);
|
||||
|
||||
|
@ -420,7 +420,9 @@ int System::Solve(Group *g, int *dof, List<hConstraint> *bad,
|
|||
|
||||
int rank = CalculateRank();
|
||||
if(rank != mat.m) {
|
||||
FindWhichToRemoveToFixJacobian(g, bad);
|
||||
if(andFindBad) {
|
||||
FindWhichToRemoveToFixJacobian(g, bad);
|
||||
}
|
||||
return System::SINGULAR_JACOBIAN;
|
||||
}
|
||||
// This is not the full Jacobian, but any substitutions or single-eq
|
||||
|
|
Loading…
Reference in New Issue