From ced42440e7babde75e5356fc9e2c2575bb37d2a5 Mon Sep 17 00:00:00 2001 From: EvilSpirit Date: Wed, 25 Jan 2017 23:39:26 +0700 Subject: [PATCH] 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. --- src/constrainteq.cpp | 23 +++++++++++++++++------ src/file.cpp | 3 ++- src/lib.cpp | 13 ++++++++++++- src/sketch.h | 3 ++- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/constrainteq.cpp b/src/constrainteq.cpp index 680f3a0..fb1106c 100644 --- a/src/constrainteq.cpp +++ b/src/constrainteq.cpp @@ -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 *l, const ExprVector &v, } } -void ConstraintBase::Generate(IdList *l) const { +void ConstraintBase::Generate(IdList *l) { switch(type) { case Type::PARALLEL: case Type::CUBIC_LINE_TANGENT: @@ -195,7 +205,8 @@ void ConstraintBase::Generate(IdList *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 *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 *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 *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 *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 diff --git a/src/file.cpp b/src/file.cpp index 45c233f..096a4ec 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -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 = {}; c.Generate(¶m); bool allParamsExist = true; diff --git a/src/lib.cpp b/src/lib.cpp index cad8058..4e5e7fd 100644 --- a/src/lib.cpp +++ b/src/lib.cpp @@ -132,7 +132,7 @@ default: dbp("bad entity type %d", se->type); return; SK.entity.Add(&e); } - + IdList 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(¶ms); + 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); } diff --git a/src/sketch.h b/src/sketch.h index c0ba682..4c85089 100644 --- a/src/sketch.h +++ b/src/sketch.h @@ -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) const; + void Generate(IdList *param); void GenerateEquations(IdList *entity, bool forReference = false) const;