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());
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 {
// We'll fix these ones up by looking at their symbolic equation;
// 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) {
case Type::PARALLEL:
case Type::CUBIC_LINE_TANGENT:
@ -195,7 +205,8 @@ void ConstraintBase::Generate(IdList<Param,hParam> *l) const {
case Type::SAME_ORIENTATION:
case Type::PT_ON_LINE: {
Param p = {};
p.h = h.param(0);
valP = h.param(0);
p.h = valP;
l->Add(&p);
break;
}
@ -393,7 +404,7 @@ void ConstraintBase::GenerateEquations(IdList<Equation,hEquation> *l,
ExprVector ea = a->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);
AddEq(l, eq);
@ -599,7 +610,7 @@ void ConstraintBase::GenerateEquations(IdList<Equation,hEquation> *l,
bv = b->NormalExprsV(),
bn = b->NormalExprsN();
ExprVector eq = VectorsParallel3d(an, bn, h.param(0));
ExprVector eq = VectorsParallel3d(an, bn, valP);
AddEq(l, eq);
Expr *d1 = au.Dot(bv);
Expr *d2 = au.Dot(bu);
@ -690,7 +701,7 @@ void ConstraintBase::GenerateEquations(IdList<Equation,hEquation> *l,
ExprVector b = line->VectorGetExprs();
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);
} else {
EntityBase *w = SK.GetEntity(workplane);
@ -744,7 +755,7 @@ void ConstraintBase::GenerateEquations(IdList<Equation,hEquation> *l,
ExprVector b = eb->VectorGetExprsInWorkplane(workplane);
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);
} else {
// 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.workplane.v", 'x', &(SS.sv.c.workplane.v) },
{ '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.ptB.v", 'x', &(SS.sv.c.ptB.v) },
{ 'c', "Constraint.entityA.v", 'x', &(SS.sv.c.entityA.v) },
@ -573,7 +574,7 @@ void SolveSpaceUI::UpgradeLegacyData() {
SK.param.DeepCopyInto(&oldParam);
SS.GenerateAll(SolveSpaceUI::Generate::REGEN);
auto AllParamsExistFor = [&](const Constraint &c) {
auto AllParamsExistFor = [&](Constraint &c) {
IdList<Param,hParam> param = {};
c.Generate(&param);
bool allParamsExist = true;

View File

@ -132,7 +132,7 @@ default: dbp("bad entity type %d", se->type); return;
SK.entity.Add(&e);
}
IdList<Param, hParam> params = {};
for(i = 0; i < ssys->constraints; i++) {
Slvs_Constraint *sc = &(ssys->constraint[i]);
ConstraintBase c = {};
@ -192,6 +192,17 @@ default: dbp("bad constraint type %d", sc->type); return;
c.other = (sc->other) ? 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);
}

View File

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