Explicitly represent the parameter used in constraints.

Commit f5485cb and its ancestors add a parameter to some constraints.
This parameter must be materialized and assigned a non-zero value via
ModifyToSatisfy for the solver library to not make unnecessary
changes to the sketch during the initial generation. For this, we
represent it explicitly instead of using hc.param(0), such that
the materialized constraint does not conflict with any user-defined
ones.
pull/200/head
EvilSpirit 2017-01-25 23:39:26 +07:00 committed by whitequark
parent 80c7296316
commit ced42440e7
4 changed files with 33 additions and 9 deletions

View File

@ -152,6 +152,16 @@ void ConstraintBase::ModifyToSatisfy() {
} }
double c = (a.Dot(b))/(a.Magnitude() * b.Magnitude()); double c = (a.Dot(b))/(a.Magnitude() * b.Magnitude());
valA = acos(c)*180/PI; valA = acos(c)*180/PI;
} else if(type == Type::PT_ON_LINE) {
EntityBase *eln = SK.GetEntity(entityA);
EntityBase *ea = SK.GetEntity(eln->point[0]);
EntityBase *eb = SK.GetEntity(eln->point[1]);
EntityBase *ep = SK.GetEntity(ptA);
ExprVector exp = ep->PointGetExprsInWorkplane(workplane);
ExprVector exa = ea->PointGetExprsInWorkplane(workplane);
ExprVector exb = eb->PointGetExprsInWorkplane(workplane);
ExprVector exba = exb.Minus(exa);
SK.GetParam(valP)->val = exba.Dot(exp.Minus(exa))->Eval() / exba.Dot(exba)->Eval();
} else { } else {
// We'll fix these ones up by looking at their symbolic equation; // We'll fix these ones up by looking at their symbolic equation;
// that means no extra work. // that means no extra work.
@ -185,7 +195,7 @@ void ConstraintBase::AddEq(IdList<Equation,hEquation> *l, const ExprVector &v,
} }
} }
void ConstraintBase::Generate(IdList<Param,hParam> *l) const { void ConstraintBase::Generate(IdList<Param,hParam> *l) {
switch(type) { switch(type) {
case Type::PARALLEL: case Type::PARALLEL:
case Type::CUBIC_LINE_TANGENT: case Type::CUBIC_LINE_TANGENT:
@ -195,7 +205,8 @@ void ConstraintBase::Generate(IdList<Param,hParam> *l) const {
case Type::SAME_ORIENTATION: case Type::SAME_ORIENTATION:
case Type::PT_ON_LINE: { case Type::PT_ON_LINE: {
Param p = {}; Param p = {};
p.h = h.param(0); valP = h.param(0);
p.h = valP;
l->Add(&p); l->Add(&p);
break; break;
} }
@ -393,7 +404,7 @@ void ConstraintBase::GenerateEquations(IdList<Equation,hEquation> *l,
ExprVector ea = a->PointGetExprsInWorkplane(workplane); ExprVector ea = a->PointGetExprsInWorkplane(workplane);
ExprVector eb = b->PointGetExprsInWorkplane(workplane); ExprVector eb = b->PointGetExprsInWorkplane(workplane);
ExprVector ptOnLine = ea.Plus(eb.Minus(ea).ScaledBy(Expr::From(h.param(0)))); ExprVector ptOnLine = ea.Plus(eb.Minus(ea).ScaledBy(Expr::From(valP)));
ExprVector eq = ptOnLine.Minus(ep); ExprVector eq = ptOnLine.Minus(ep);
AddEq(l, eq); AddEq(l, eq);
@ -599,7 +610,7 @@ void ConstraintBase::GenerateEquations(IdList<Equation,hEquation> *l,
bv = b->NormalExprsV(), bv = b->NormalExprsV(),
bn = b->NormalExprsN(); bn = b->NormalExprsN();
ExprVector eq = VectorsParallel3d(an, bn, h.param(0)); ExprVector eq = VectorsParallel3d(an, bn, valP);
AddEq(l, eq); AddEq(l, eq);
Expr *d1 = au.Dot(bv); Expr *d1 = au.Dot(bv);
Expr *d2 = au.Dot(bu); Expr *d2 = au.Dot(bu);
@ -690,7 +701,7 @@ void ConstraintBase::GenerateEquations(IdList<Equation,hEquation> *l,
ExprVector b = line->VectorGetExprs(); ExprVector b = line->VectorGetExprs();
if(workplane.v == EntityBase::FREE_IN_3D.v) { if(workplane.v == EntityBase::FREE_IN_3D.v) {
ExprVector eq = VectorsParallel3d(a, b, h.param(0)); ExprVector eq = VectorsParallel3d(a, b, valP);
AddEq(l, eq); AddEq(l, eq);
} else { } else {
EntityBase *w = SK.GetEntity(workplane); EntityBase *w = SK.GetEntity(workplane);
@ -744,7 +755,7 @@ void ConstraintBase::GenerateEquations(IdList<Equation,hEquation> *l,
ExprVector b = eb->VectorGetExprsInWorkplane(workplane); ExprVector b = eb->VectorGetExprsInWorkplane(workplane);
if(workplane.v == EntityBase::FREE_IN_3D.v) { if(workplane.v == EntityBase::FREE_IN_3D.v) {
ExprVector eq = VectorsParallel3d(a, b, h.param(0)); ExprVector eq = VectorsParallel3d(a, b, valP);
AddEq(l, eq); AddEq(l, eq);
} else { } else {
// We use expressions written in workplane csys, so we can assume the workplane // We use expressions written in workplane csys, so we can assume the workplane

View File

@ -171,6 +171,7 @@ const SolveSpaceUI::SaveTable SolveSpaceUI::SAVED[] = {
{ 'c', "Constraint.group.v", 'x', &(SS.sv.c.group.v) }, { 'c', "Constraint.group.v", 'x', &(SS.sv.c.group.v) },
{ 'c', "Constraint.workplane.v", 'x', &(SS.sv.c.workplane.v) }, { 'c', "Constraint.workplane.v", 'x', &(SS.sv.c.workplane.v) },
{ 'c', "Constraint.valA", 'f', &(SS.sv.c.valA) }, { 'c', "Constraint.valA", 'f', &(SS.sv.c.valA) },
{ 'c', "Constraint.valP.v", 'x', &(SS.sv.c.valP.v) },
{ 'c', "Constraint.ptA.v", 'x', &(SS.sv.c.ptA.v) }, { 'c', "Constraint.ptA.v", 'x', &(SS.sv.c.ptA.v) },
{ 'c', "Constraint.ptB.v", 'x', &(SS.sv.c.ptB.v) }, { 'c', "Constraint.ptB.v", 'x', &(SS.sv.c.ptB.v) },
{ 'c', "Constraint.entityA.v", 'x', &(SS.sv.c.entityA.v) }, { 'c', "Constraint.entityA.v", 'x', &(SS.sv.c.entityA.v) },
@ -573,7 +574,7 @@ void SolveSpaceUI::UpgradeLegacyData() {
SK.param.DeepCopyInto(&oldParam); SK.param.DeepCopyInto(&oldParam);
SS.GenerateAll(SolveSpaceUI::Generate::REGEN); SS.GenerateAll(SolveSpaceUI::Generate::REGEN);
auto AllParamsExistFor = [&](const Constraint &c) { auto AllParamsExistFor = [&](Constraint &c) {
IdList<Param,hParam> param = {}; IdList<Param,hParam> param = {};
c.Generate(&param); c.Generate(&param);
bool allParamsExist = true; bool allParamsExist = true;

View File

@ -132,7 +132,7 @@ default: dbp("bad entity type %d", se->type); return;
SK.entity.Add(&e); SK.entity.Add(&e);
} }
IdList<Param, hParam> params = {};
for(i = 0; i < ssys->constraints; i++) { for(i = 0; i < ssys->constraints; i++) {
Slvs_Constraint *sc = &(ssys->constraint[i]); Slvs_Constraint *sc = &(ssys->constraint[i]);
ConstraintBase c = {}; ConstraintBase c = {};
@ -192,6 +192,17 @@ default: dbp("bad constraint type %d", sc->type); return;
c.other = (sc->other) ? true : false; c.other = (sc->other) ? true : false;
c.other2 = (sc->other2) ? true : false; c.other2 = (sc->other2) ? true : false;
c.Generate(&params);
if(params.n > 0) {
for(Param &p : params) {
p.h = SK.param.AddAndAssignId(&p);
c.valP = p.h;
SYS.param.Add(&p);
}
params.Clear();
c.ModifyToSatisfy();
}
SK.constraint.Add(&c); SK.constraint.Add(&c);
} }

View File

@ -627,6 +627,7 @@ public:
// These are the parameters for the constraint. // These are the parameters for the constraint.
double valA; double valA;
hParam valP;
hEntity ptA; hEntity ptA;
hEntity ptB; hEntity ptB;
hEntity entityA; hEntity entityA;
@ -641,7 +642,7 @@ public:
bool HasLabel() const; bool HasLabel() const;
void Generate(IdList<Param, hParam> *param) const; void Generate(IdList<Param, hParam> *param);
void GenerateEquations(IdList<Equation,hEquation> *entity, void GenerateEquations(IdList<Equation,hEquation> *entity,
bool forReference = false) const; bool forReference = false) const;