Don't keep a dimension or group's user-entered numerical value as
an Expr *, since that complicates multiple units and also memory management. Now it's just a double. [git-p4: depot-paths = "//depot/solvespace/": change = 1791]solver
parent
1674443ab2
commit
28e3f0abab
|
@ -115,7 +115,7 @@ void Constraint::MenuConstrain(int id) {
|
||||||
c.disp.offset = Vector::From(0, 0, 0);
|
c.disp.offset = Vector::From(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
c.exprA = Expr::From("0")->DeepCopyKeep();
|
c.valA = 0;
|
||||||
c.ModifyToSatisfy();
|
c.ModifyToSatisfy();
|
||||||
AddConstraint(&c);
|
AddConstraint(&c);
|
||||||
break;
|
break;
|
||||||
|
@ -175,7 +175,7 @@ void Constraint::MenuConstrain(int id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.exprA = Expr::From("0")->DeepCopyKeep();
|
c.valA = 0;
|
||||||
c.ModifyToSatisfy();
|
c.ModifyToSatisfy();
|
||||||
AddConstraint(&c);
|
AddConstraint(&c);
|
||||||
break;
|
break;
|
||||||
|
@ -327,7 +327,7 @@ void Constraint::MenuConstrain(int id) {
|
||||||
c.type = ANGLE;
|
c.type = ANGLE;
|
||||||
c.entityA = gs.vector[0];
|
c.entityA = gs.vector[0];
|
||||||
c.entityB = gs.vector[1];
|
c.entityB = gs.vector[1];
|
||||||
c.exprA = Expr::From(0.0)->DeepCopyKeep();
|
c.valA = 0;
|
||||||
c.otherAngle = true;
|
c.otherAngle = true;
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for angle constraint.");
|
Error("Bad selection for angle constraint.");
|
||||||
|
@ -352,7 +352,7 @@ void Constraint::MenuConstrain(int id) {
|
||||||
case GraphicsWindow::MNU_COMMENT:
|
case GraphicsWindow::MNU_COMMENT:
|
||||||
c.type = COMMENT;
|
c.type = COMMENT;
|
||||||
c.comment.strcpy("NEW COMMENT -- DOUBLE-CLICK TO EDIT");
|
c.comment.strcpy("NEW COMMENT -- DOUBLE-CLICK TO EDIT");
|
||||||
c.disp.offset = SS.GW.offset;
|
c.disp.offset = SS.GW.offset.ScaledBy(-1);
|
||||||
AddConstraint(&c);
|
AddConstraint(&c);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -485,9 +485,7 @@ void Constraint::ModifyToSatisfy(void) {
|
||||||
b = b.ProjectVectorInto(workplane);
|
b = b.ProjectVectorInto(workplane);
|
||||||
}
|
}
|
||||||
double c = (a.Dot(b))/(a.Magnitude() * b.Magnitude());
|
double c = (a.Dot(b))/(a.Magnitude() * b.Magnitude());
|
||||||
double theta = acos(c)*180/PI;
|
valA = acos(c)*180/PI;
|
||||||
Expr::FreeKeep(&exprA);
|
|
||||||
exprA = Expr::From(theta)->DeepCopyKeep();
|
|
||||||
} 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.
|
||||||
|
@ -499,11 +497,8 @@ void Constraint::ModifyToSatisfy(void) {
|
||||||
if(l.n != 1) oops();
|
if(l.n != 1) oops();
|
||||||
|
|
||||||
// These equations are written in the form f(...) - d = 0, where
|
// These equations are written in the form f(...) - d = 0, where
|
||||||
// d is the value of the exprA.
|
// d is the value of the valA.
|
||||||
double v = (l.elem[0].e)->Eval();
|
valA += (l.elem[0].e)->Eval();
|
||||||
double nd = exprA->Eval() + v;
|
|
||||||
Expr::FreeKeep(&exprA);
|
|
||||||
exprA = Expr::From(nd)->DeepCopyKeep();
|
|
||||||
|
|
||||||
l.Clear();
|
l.Clear();
|
||||||
}
|
}
|
||||||
|
@ -522,8 +517,7 @@ void Constraint::Generate(IdList<Equation,hEquation> *l) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Constraint::GenerateReal(IdList<Equation,hEquation> *l) {
|
void Constraint::GenerateReal(IdList<Equation,hEquation> *l) {
|
||||||
Expr *exA = NULL;
|
Expr *exA = Expr::From(valA);
|
||||||
if(exprA) exA = exprA->DeepCopy();
|
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case PT_PT_DISTANCE:
|
case PT_PT_DISTANCE:
|
||||||
|
@ -546,7 +540,7 @@ void Constraint::GenerateReal(IdList<Equation,hEquation> *l) {
|
||||||
Entity *f = SS.GetEntity(entityA);
|
Entity *f = SS.GetEntity(entityA);
|
||||||
ExprVector p0 = f->FaceGetPointExprs();
|
ExprVector p0 = f->FaceGetPointExprs();
|
||||||
ExprVector n = f->FaceGetNormalExprs();
|
ExprVector n = f->FaceGetNormalExprs();
|
||||||
AddEq(l, (pt.Minus(p0)).Dot(n)->Minus(exprA), 0);
|
AddEq(l, (pt.Minus(p0)).Dot(n)->Minus(exA), 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
7
draw.cpp
7
draw.cpp
|
@ -556,8 +556,8 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
|
||||||
Vector p3 = c->GetLabelPos();
|
Vector p3 = c->GetLabelPos();
|
||||||
Point2d p2 = ProjectPoint(p3);
|
Point2d p2 = ProjectPoint(p3);
|
||||||
char *s = (c->type == Constraint::COMMENT) ? c->comment.str :
|
char *s = (c->type == Constraint::COMMENT) ? c->comment.str :
|
||||||
c->exprA->Print();
|
ToString(c->valA);
|
||||||
ShowGraphicsEditControl((int)p2.x, (int)p2.y, s);
|
ShowGraphicsEditControl((int)p2.x, (int)p2.y-4, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,8 +575,7 @@ void GraphicsWindow::EditControlDone(char *s) {
|
||||||
if(e) {
|
if(e) {
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
|
|
||||||
Expr::FreeKeep(&(c->exprA));
|
c->valA = e->Eval();
|
||||||
c->exprA = e->DeepCopyKeep();
|
|
||||||
|
|
||||||
SS.MarkGroupDirty(c->group);
|
SS.MarkGroupDirty(c->group);
|
||||||
SS.GenerateAll();
|
SS.GenerateAll();
|
||||||
|
|
|
@ -44,14 +44,14 @@ double Constraint::EllipticalInterpolation(double rx, double ry, double theta) {
|
||||||
char *Constraint::Label(void) {
|
char *Constraint::Label(void) {
|
||||||
static char Ret[1024];
|
static char Ret[1024];
|
||||||
if(type == ANGLE) {
|
if(type == ANGLE) {
|
||||||
sprintf(Ret, "%.2f", exprA->Eval());
|
sprintf(Ret, "%.2f", valA);
|
||||||
} else if(type == LENGTH_RATIO) {
|
} else if(type == LENGTH_RATIO) {
|
||||||
sprintf(Ret, "%.3f:1", exprA->Eval());
|
sprintf(Ret, "%.3f:1", valA);
|
||||||
} else if(type == COMMENT) {
|
} else if(type == COMMENT) {
|
||||||
strcpy(Ret, comment.str);
|
strcpy(Ret, comment.str);
|
||||||
} else {
|
} else {
|
||||||
// exprA has units of distance
|
// valA has units of distance
|
||||||
strcpy(Ret, SS.GW.ToString(exprA->Eval()));
|
strcpy(Ret, SS.GW.ToString(valA));
|
||||||
}
|
}
|
||||||
if(reference) {
|
if(reference) {
|
||||||
strcat(Ret, " REF");
|
strcat(Ret, " REF");
|
||||||
|
|
22
expr.cpp
22
expr.cpp
|
@ -268,28 +268,6 @@ Expr *Expr::DeepCopy(void) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr *Expr::DeepCopyKeep(void) {
|
|
||||||
Expr *n = (Expr *)MemAlloc(sizeof(Expr));
|
|
||||||
*n = *this;
|
|
||||||
n->marker = 0xbad2feed;
|
|
||||||
n->a = n->b = NULL;
|
|
||||||
int c = n->Children();
|
|
||||||
if(c > 0) n->a = a->DeepCopyKeep();
|
|
||||||
if(c > 1) n->b = b->DeepCopyKeep();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Expr::FreeKeep(Expr **e) {
|
|
||||||
if(!(*e)) oops();
|
|
||||||
|
|
||||||
int c = (*e)->Children();
|
|
||||||
if(c > 0) FreeKeep(&((*e)->a));
|
|
||||||
if(c > 1) FreeKeep(&((*e)->b));
|
|
||||||
if((*e)->marker != 0xbad2feed) oops();
|
|
||||||
MemFree(*e);
|
|
||||||
*e = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr *Expr::DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
|
Expr *Expr::DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
|
||||||
IdList<Param,hParam> *thenTry)
|
IdList<Param,hParam> *thenTry)
|
||||||
{
|
{
|
||||||
|
|
8
expr.h
8
expr.h
|
@ -84,17 +84,13 @@ public:
|
||||||
char *Print(void);
|
char *Print(void);
|
||||||
void PrintW(void); // worker
|
void PrintW(void); // worker
|
||||||
|
|
||||||
// Make a copy of an expression that won't get blown away when we
|
|
||||||
// do a FreeAllExprs(), or free it later.
|
|
||||||
Expr *DeepCopyKeep(void);
|
|
||||||
static void FreeKeep(Expr **f);
|
|
||||||
// or a copy that will
|
|
||||||
Expr *DeepCopy(void);
|
|
||||||
// number of child nodes: 0 (e.g. constant), 1 (sqrt), or 2 (+)
|
// number of child nodes: 0 (e.g. constant), 1 (sqrt), or 2 (+)
|
||||||
int Children(void);
|
int Children(void);
|
||||||
// total number of nodes in the tree
|
// total number of nodes in the tree
|
||||||
int Nodes(void);
|
int Nodes(void);
|
||||||
|
|
||||||
|
// Make a simple copy
|
||||||
|
Expr *DeepCopy(void);
|
||||||
// Make a copy, with the parameters (usually referenced by hParam)
|
// Make a copy, with the parameters (usually referenced by hParam)
|
||||||
// resolved to pointers to the actual value. This speeds things up
|
// resolved to pointers to the actual value. This speeds things up
|
||||||
// considerably.
|
// considerably.
|
||||||
|
|
17
file.cpp
17
file.cpp
|
@ -65,7 +65,7 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
|
||||||
{ 'g', "Group.name", 'N', &(SS.sv.g.name) },
|
{ 'g', "Group.name", 'N', &(SS.sv.g.name) },
|
||||||
{ 'g', "Group.activeWorkplane.v", 'x', &(SS.sv.g.activeWorkplane.v) },
|
{ 'g', "Group.activeWorkplane.v", 'x', &(SS.sv.g.activeWorkplane.v) },
|
||||||
{ 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) },
|
{ 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) },
|
||||||
{ 'g', "Group.exprA", 'E', &(SS.sv.g.exprA) },
|
{ 'g', "Group.valA", 'f', &(SS.sv.g.valA) },
|
||||||
{ 'g', "Group.color", 'x', &(SS.sv.g.color) },
|
{ 'g', "Group.color", 'x', &(SS.sv.g.color) },
|
||||||
{ 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) },
|
{ 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) },
|
||||||
{ 'g', "Group.skipFirst", 'b', &(SS.sv.g.skipFirst) },
|
{ 'g', "Group.skipFirst", 'b', &(SS.sv.g.skipFirst) },
|
||||||
|
@ -118,7 +118,7 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
|
||||||
{ 'c', "Constraint.type", 'd', &(SS.sv.c.type) },
|
{ 'c', "Constraint.type", 'd', &(SS.sv.c.type) },
|
||||||
{ '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.exprA", 'E', &(SS.sv.c.exprA) },
|
{ 'c', "Constraint.valA", 'f', &(SS.sv.c.valA) },
|
||||||
{ '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.ptC.v", 'x', &(SS.sv.c.ptC.v) },
|
{ 'c', "Constraint.ptC.v", 'x', &(SS.sv.c.ptC.v) },
|
||||||
|
@ -154,7 +154,6 @@ void SolveSpace::SaveUsingTable(int type) {
|
||||||
case 'f': fprintf(fh, "%.20f", *((double *)p)); break;
|
case 'f': fprintf(fh, "%.20f", *((double *)p)); break;
|
||||||
case 'N': fprintf(fh, "%s", ((NameStr *)p)->str); break;
|
case 'N': fprintf(fh, "%s", ((NameStr *)p)->str); break;
|
||||||
case 'P': fprintf(fh, "%s", (char *)p); break;
|
case 'P': fprintf(fh, "%s", (char *)p); break;
|
||||||
case 'E': fprintf(fh, "%s", (*((Expr **)p))->Print()); break;
|
|
||||||
|
|
||||||
case 'M': {
|
case 'M': {
|
||||||
int j;
|
int j;
|
||||||
|
@ -223,9 +222,6 @@ bool SolveSpace::SaveToFile(char *filename) {
|
||||||
SMesh *m = &(group.elem[group.n-1].mesh);
|
SMesh *m = &(group.elem[group.n-1].mesh);
|
||||||
for(i = 0; i < m->l.n; i++) {
|
for(i = 0; i < m->l.n; i++) {
|
||||||
STriangle *tr = &(m->l.elem[i]);
|
STriangle *tr = &(m->l.elem[i]);
|
||||||
/*
|
|
||||||
double mag = tr->Normal().Magnitude();
|
|
||||||
dbp("triangle: mag=%.5f", mag); */
|
|
||||||
fprintf(fh, "Triangle %08x %08x "
|
fprintf(fh, "Triangle %08x %08x "
|
||||||
"%.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f\n",
|
"%.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f\n",
|
||||||
tr->meta.face, tr->meta.color,
|
tr->meta.face, tr->meta.color,
|
||||||
|
@ -248,12 +244,6 @@ void SolveSpace::LoadUsingTable(char *key, char *val) {
|
||||||
case 'x': sscanf(val, "%x", (DWORD *)p); break;
|
case 'x': sscanf(val, "%x", (DWORD *)p); break;
|
||||||
case 'f': *((double *)p) = atof(val); break;
|
case 'f': *((double *)p) = atof(val); break;
|
||||||
case 'N': ((NameStr *)p)->strcpy(val); break;
|
case 'N': ((NameStr *)p)->strcpy(val); break;
|
||||||
case 'E':
|
|
||||||
Expr *e;
|
|
||||||
e = Expr::From(val);
|
|
||||||
if(!e) e = Expr::From(0.0);
|
|
||||||
*((Expr **)p) = e->DeepCopyKeep();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'P':
|
case 'P':
|
||||||
if(strlen(val)+1 < MAX_PATH) strcpy((char *)p, val);
|
if(strlen(val)+1 < MAX_PATH) strcpy((char *)p, val);
|
||||||
|
@ -371,7 +361,6 @@ bool SolveSpace::LoadEntitiesFromFile(char *file, EntityList *le, SMesh *m) {
|
||||||
} else if(strcmp(line, "AddGroup")==0) {
|
} else if(strcmp(line, "AddGroup")==0) {
|
||||||
// Don't leak memory; these get allocated whether we want them
|
// Don't leak memory; these get allocated whether we want them
|
||||||
// or not.
|
// or not.
|
||||||
if(sv.g.exprA) Expr::FreeKeep(&(sv.g.exprA));
|
|
||||||
sv.g.remap.Clear();
|
sv.g.remap.Clear();
|
||||||
} else if(strcmp(line, "AddParam")==0) {
|
} else if(strcmp(line, "AddParam")==0) {
|
||||||
|
|
||||||
|
@ -381,7 +370,7 @@ bool SolveSpace::LoadEntitiesFromFile(char *file, EntityList *le, SMesh *m) {
|
||||||
} else if(strcmp(line, "AddRequest")==0) {
|
} else if(strcmp(line, "AddRequest")==0) {
|
||||||
|
|
||||||
} else if(strcmp(line, "AddConstraint")==0) {
|
} else if(strcmp(line, "AddConstraint")==0) {
|
||||||
if(sv.c.exprA) Expr::FreeKeep(&(sv.c.exprA));
|
|
||||||
} else if(strcmp(line, VERSION_STRING)==0) {
|
} else if(strcmp(line, VERSION_STRING)==0) {
|
||||||
|
|
||||||
} else if(memcmp(line, "Triangle", 8)==0) {
|
} else if(memcmp(line, "Triangle", 8)==0) {
|
||||||
|
|
|
@ -115,7 +115,7 @@ void Group::MenuGroup(int id) {
|
||||||
}
|
}
|
||||||
g.type = ROTATE;
|
g.type = ROTATE;
|
||||||
g.opA = SS.GW.activeGroup;
|
g.opA = SS.GW.activeGroup;
|
||||||
g.exprA = Expr::From(3)->DeepCopyKeep();
|
g.valA = 3;
|
||||||
g.subtype = ONE_SIDED;
|
g.subtype = ONE_SIDED;
|
||||||
g.name.strcpy("rotate");
|
g.name.strcpy("rotate");
|
||||||
SS.GW.ClearSelection();
|
SS.GW.ClearSelection();
|
||||||
|
@ -125,7 +125,7 @@ void Group::MenuGroup(int id) {
|
||||||
case GraphicsWindow::MNU_GROUP_TRANS:
|
case GraphicsWindow::MNU_GROUP_TRANS:
|
||||||
g.type = TRANSLATE;
|
g.type = TRANSLATE;
|
||||||
g.opA = SS.GW.activeGroup;
|
g.opA = SS.GW.activeGroup;
|
||||||
g.exprA = Expr::From(3)->DeepCopyKeep();
|
g.valA = 3;
|
||||||
g.subtype = ONE_SIDED;
|
g.subtype = ONE_SIDED;
|
||||||
g.predef.entityB = SS.GW.ActiveWorkplane();
|
g.predef.entityB = SS.GW.ActiveWorkplane();
|
||||||
g.activeWorkplane = SS.GW.ActiveWorkplane();
|
g.activeWorkplane = SS.GW.ActiveWorkplane();
|
||||||
|
@ -293,7 +293,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
AddParam(param, h.param(1), gp.y);
|
AddParam(param, h.param(1), gp.y);
|
||||||
AddParam(param, h.param(2), gp.z);
|
AddParam(param, h.param(2), gp.z);
|
||||||
|
|
||||||
int n = (int)(exprA->Eval()), a0 = 0;
|
int n = (int)valA, a0 = 0;
|
||||||
if(subtype == ONE_SIDED && skipFirst) {
|
if(subtype == ONE_SIDED && skipFirst) {
|
||||||
a0++; n++;
|
a0++; n++;
|
||||||
}
|
}
|
||||||
|
@ -325,7 +325,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
AddParam(param, h.param(5), gn.y);
|
AddParam(param, h.param(5), gn.y);
|
||||||
AddParam(param, h.param(6), gn.z);
|
AddParam(param, h.param(6), gn.z);
|
||||||
|
|
||||||
int n = (int)(exprA->Eval()), a0 = 0;
|
int n = (int)valA, a0 = 0;
|
||||||
if(subtype == ONE_SIDED && skipFirst) {
|
if(subtype == ONE_SIDED && skipFirst) {
|
||||||
a0++; n++;
|
a0++; n++;
|
||||||
}
|
}
|
||||||
|
|
4
sketch.h
4
sketch.h
|
@ -91,7 +91,7 @@ public:
|
||||||
bool visible;
|
bool visible;
|
||||||
bool clean;
|
bool clean;
|
||||||
hEntity activeWorkplane;
|
hEntity activeWorkplane;
|
||||||
Expr *exprA;
|
double valA;
|
||||||
DWORD color;
|
DWORD color;
|
||||||
|
|
||||||
static const int SOLVED_OKAY = 0;
|
static const int SOLVED_OKAY = 0;
|
||||||
|
@ -442,7 +442,7 @@ public:
|
||||||
hEntity workplane;
|
hEntity workplane;
|
||||||
|
|
||||||
// These are the parameters for the constraint.
|
// These are the parameters for the constraint.
|
||||||
Expr *exprA;
|
double valA;
|
||||||
hEntity ptA;
|
hEntity ptA;
|
||||||
hEntity ptB;
|
hEntity ptB;
|
||||||
hEntity ptC;
|
hEntity ptC;
|
||||||
|
|
|
@ -640,7 +640,9 @@ void TextWindow::ScreenChangeExprA(int link, DWORD v) {
|
||||||
// There's an extra line for the skipFirst parameter in one-sided groups.
|
// There's an extra line for the skipFirst parameter in one-sided groups.
|
||||||
int r = (g->subtype == Group::ONE_SIDED) ? 15 : 13;
|
int r = (g->subtype == Group::ONE_SIDED) ? 15 : 13;
|
||||||
|
|
||||||
ShowTextEditControl(r, 9, g->exprA->Print());
|
char str[1024];
|
||||||
|
sprintf(str, "%d", (int)g->valA);
|
||||||
|
ShowTextEditControl(r, 9, str);
|
||||||
SS.TW.edit.meaning = EDIT_TIMES_REPEATED;
|
SS.TW.edit.meaning = EDIT_TIMES_REPEATED;
|
||||||
SS.TW.edit.group.v = v;
|
SS.TW.edit.group.v = v;
|
||||||
}
|
}
|
||||||
|
@ -724,7 +726,7 @@ void TextWindow::ShowGroupInfo(void) {
|
||||||
space = true;
|
space = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int times = (int)(g->exprA->Eval());
|
int times = (int)(g->valA);
|
||||||
Printf(space, "%Ft%s%E %d time%s %Fl%Ll%D%f[change]%E",
|
Printf(space, "%Ft%s%E %d time%s %Fl%Ll%D%f[change]%E",
|
||||||
s2, times, times == 1 ? "" : "s",
|
s2, times, times == 1 ? "" : "s",
|
||||||
g->h.v, &TextWindow::ScreenChangeExprA);
|
g->h.v, &TextWindow::ScreenChangeExprA);
|
||||||
|
@ -916,8 +918,7 @@ void TextWindow::EditControlDone(char *s) {
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
|
|
||||||
Group *g = SS.GetGroup(edit.group);
|
Group *g = SS.GetGroup(edit.group);
|
||||||
Expr::FreeKeep(&(g->exprA));
|
g->valA = e->Eval();
|
||||||
g->exprA = e->DeepCopyKeep();
|
|
||||||
|
|
||||||
SS.MarkGroupDirty(g->h);
|
SS.MarkGroupDirty(g->h);
|
||||||
SS.later.generateAll = true;
|
SS.later.generateAll = true;
|
||||||
|
|
12
undoredo.cpp
12
undoredo.cpp
|
@ -45,7 +45,6 @@ void SolveSpace::PushFromCurrentOnto(UndoStack *uk) {
|
||||||
// And then clean up all the stuff that needs to be a deep copy,
|
// And then clean up all the stuff that needs to be a deep copy,
|
||||||
// and zero out all the dynamic stuff that will get regenerated.
|
// and zero out all the dynamic stuff that will get regenerated.
|
||||||
dest.clean = false;
|
dest.clean = false;
|
||||||
if(src->exprA) dest.exprA = src->exprA->DeepCopyKeep();
|
|
||||||
ZERO(&(dest.solved));
|
ZERO(&(dest.solved));
|
||||||
ZERO(&(dest.poly));
|
ZERO(&(dest.poly));
|
||||||
ZERO(&(dest.polyError));
|
ZERO(&(dest.polyError));
|
||||||
|
@ -65,7 +64,6 @@ void SolveSpace::PushFromCurrentOnto(UndoStack *uk) {
|
||||||
for(i = 0; i < constraint.n; i++) {
|
for(i = 0; i < constraint.n; i++) {
|
||||||
Constraint *src = &(constraint.elem[i]);
|
Constraint *src = &(constraint.elem[i]);
|
||||||
Constraint dest = *src;
|
Constraint dest = *src;
|
||||||
if(src->exprA) dest.exprA = src->exprA->DeepCopyKeep();
|
|
||||||
ZERO(&(dest.dogd));
|
ZERO(&(dest.dogd));
|
||||||
ut->constraint.Add(&dest);
|
ut->constraint.Add(&dest);
|
||||||
}
|
}
|
||||||
|
@ -88,7 +86,6 @@ void SolveSpace::PopOntoCurrentFrom(UndoStack *uk) {
|
||||||
// Free everything in the main copy of the program before replacing it
|
// Free everything in the main copy of the program before replacing it
|
||||||
for(i = 0; i < group.n; i++) {
|
for(i = 0; i < group.n; i++) {
|
||||||
Group *g = &(group.elem[i]);
|
Group *g = &(group.elem[i]);
|
||||||
if(g->exprA) Expr::FreeKeep(&(g->exprA));
|
|
||||||
g->poly.Clear();
|
g->poly.Clear();
|
||||||
g->mesh.Clear();
|
g->mesh.Clear();
|
||||||
g->meshError.interferesAt.Clear();
|
g->meshError.interferesAt.Clear();
|
||||||
|
@ -96,10 +93,6 @@ void SolveSpace::PopOntoCurrentFrom(UndoStack *uk) {
|
||||||
g->impMesh.Clear();
|
g->impMesh.Clear();
|
||||||
g->impEntity.Clear();
|
g->impEntity.Clear();
|
||||||
}
|
}
|
||||||
for(i = 0; i < constraint.n; i++) {
|
|
||||||
Constraint *c = &(constraint.elem[i]);
|
|
||||||
if(c->exprA) Expr::FreeKeep(&(c->exprA));
|
|
||||||
}
|
|
||||||
group.Clear();
|
group.Clear();
|
||||||
request.Clear();
|
request.Clear();
|
||||||
constraint.Clear();
|
constraint.Clear();
|
||||||
|
@ -138,15 +131,10 @@ void SolveSpace::UndoClearState(UndoState *ut) {
|
||||||
for(i = 0; i < ut->group.n; i++) {
|
for(i = 0; i < ut->group.n; i++) {
|
||||||
Group *g = &(ut->group.elem[i]);
|
Group *g = &(ut->group.elem[i]);
|
||||||
|
|
||||||
if(g->exprA) Expr::FreeKeep(&(g->exprA));
|
|
||||||
g->remap.Clear();
|
g->remap.Clear();
|
||||||
}
|
}
|
||||||
ut->group.Clear();
|
ut->group.Clear();
|
||||||
ut->request.Clear();
|
ut->request.Clear();
|
||||||
for(i = 0; i < ut->constraint.n; i++) {
|
|
||||||
Constraint *c = &(ut->constraint.elem[i]);
|
|
||||||
if(c->exprA) Expr::FreeKeep(&(c->exprA));
|
|
||||||
}
|
|
||||||
ut->constraint.Clear();
|
ut->constraint.Clear();
|
||||||
ut->param.Clear();
|
ut->param.Clear();
|
||||||
ZERO(ut);
|
ZERO(ut);
|
||||||
|
|
Loading…
Reference in New Issue