Add a setting that permits a group to include redundant constraints.

This setting is generally useful, but it especially shines when
assembling, since the "same orientation" and "parallel" constraints
remove three and two rotational degrees of freedom, which makes them
impossible to use with 3d "point on line" constraint that removes
two spatial and two rotational degrees of freedom.

The setting is not enabled for all imported groups by default
because it exhibits some edge case failures. For example:
  * draw two line segments sharing a point,
  * constrain lengths of line segments,
  * constrain line segments perpendicular,
  * constrain line segments to a 90° angle.

This is a truly degenerate case and so it is not considered very
important. However, we can fix this later by using Eigen::SparseQR.
This commit is contained in:
whitequark 2016-01-21 15:01:43 +00:00
parent 27767f7a48
commit 000bf71a50
3 changed files with 11 additions and 4 deletions

View File

@ -106,6 +106,7 @@ public:
bool visible; bool visible;
bool suppress; bool suppress;
bool relaxConstraints; bool relaxConstraints;
bool allowRedundant;
bool allDimsReference; bool allDimsReference;
double scale; double scale;
@ -194,6 +195,7 @@ public:
static void AddParam(ParamList *param, hParam hp, double v); static void AddParam(ParamList *param, hParam hp, double v);
void Generate(EntityList *entity, ParamList *param); void Generate(EntityList *entity, ParamList *param);
bool IsSolvedOkay();
void TransformImportedBy(Vector t, Quaternion q); void TransformImportedBy(Vector t, Quaternion q);
// When a request generates entities from entities, and the source // When a request generates entities from entities, and the source
// entities may have come from multiple requests, it's necessary to // entities may have come from multiple requests, it's necessary to

View File

@ -460,9 +460,12 @@ int System::Solve(Group *g, int *dof, List<hConstraint> *bad,
goto didnt_converge; goto didnt_converge;
} }
if(!TestRank()) { rankOk = TestRank();
if(andFindBad) FindWhichToRemoveToFixJacobian(g, bad); if(!rankOk) {
return System::REDUNDANT_OKAY; if(!g->allowRedundant) {
if(andFindBad) FindWhichToRemoveToFixJacobian(g, bad);
return System::REDUNDANT_OKAY;
}
} }
// This is not the full Jacobian, but any substitutions or single-eq // This is not the full Jacobian, but any substitutions or single-eq
@ -506,7 +509,7 @@ int System::Solve(Group *g, int *dof, List<hConstraint> *bad,
pp->known = true; pp->known = true;
pp->free = p->free; pp->free = p->free;
} }
return System::SOLVED_OKAY; return rankOk ? System::SOLVED_OKAY : System::REDUNDANT_OKAY;
didnt_converge: didnt_converge:
SK.constraint.ClearTags(); SK.constraint.ClearTags();

View File

@ -271,6 +271,8 @@ public:
static void ScreenChangeCanvasSize(int link, uint32_t v); static void ScreenChangeCanvasSize(int link, uint32_t v);
static void ScreenChangeShadedTriangles(int link, uint32_t v); static void ScreenChangeShadedTriangles(int link, uint32_t v);
static void ScreenAllowRedundant(int link, uint32_t v);
static void ScreenStepDimSteps(int link, uint32_t v); static void ScreenStepDimSteps(int link, uint32_t v);
static void ScreenStepDimFinish(int link, uint32_t v); static void ScreenStepDimFinish(int link, uint32_t v);
static void ScreenStepDimGo(int link, uint32_t v); static void ScreenStepDimGo(int link, uint32_t v);