Add the first `derived' group, that generates entities based on
other entities. This requires a new point type, for a point that's defined as a transformation of some other point. All works nicely, I think. There's ugliness because entities are no longer guaranteed to have a parent request. Also speed up display of the text window, by caching brushes instead of recreating for each character (!), and add a bit more user interface in the text window. [git-p4: depot-paths = "//depot/solvespace/": change = 1692]
This commit is contained in:
parent
bfc7109e0c
commit
49ec1346d7
|
@ -1,9 +1,15 @@
|
||||||
#include "solvespace.h"
|
#include "solvespace.h"
|
||||||
|
|
||||||
|
char *Constraint::DescriptionString(void) {
|
||||||
|
static char ret[1024];
|
||||||
|
sprintf(ret, "c%04x", h.v);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
hConstraint Constraint::AddConstraint(Constraint *c) {
|
hConstraint Constraint::AddConstraint(Constraint *c) {
|
||||||
SS.constraint.AddAndAssignId(c);
|
SS.constraint.AddAndAssignId(c);
|
||||||
|
|
||||||
if(SS.GW.solving == GraphicsWindow::SOLVE_ALWAYS) SS.Solve();
|
SS.GenerateAll(SS.GW.solving == GraphicsWindow::SOLVE_ALWAYS);
|
||||||
return c->h;
|
return c->h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +116,7 @@ void Constraint::MenuConstrain(int id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case GraphicsWindow::MNU_SOLVE_NOW:
|
case GraphicsWindow::MNU_SOLVE_NOW:
|
||||||
SS.Solve();
|
SS.GenerateAll(true);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case GraphicsWindow::MNU_SOLVE_AUTO:
|
case GraphicsWindow::MNU_SOLVE_AUTO:
|
||||||
|
|
69
entity.cpp
69
entity.cpp
|
@ -98,35 +98,22 @@ void Entity::PlaneGetExprs(ExprVector *n, Expr **dn) {
|
||||||
bool Entity::IsPoint(void) {
|
bool Entity::IsPoint(void) {
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case POINT_IN_3D:
|
case POINT_IN_3D:
|
||||||
|
// A point by (x, y, z) in our base coordinate system. These
|
||||||
|
// variables are given by param[0:2].
|
||||||
case POINT_IN_2D:
|
case POINT_IN_2D:
|
||||||
|
// A point by (u, v) in a workplane. These variables are given
|
||||||
|
// by param[0:1], and the workplane is given in workplane.
|
||||||
|
case POINT_XFRMD:
|
||||||
|
// A point by a translation of another point. The original
|
||||||
|
// point is given by point[0], and the three offsets in
|
||||||
|
// param[0:2].
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Entity::IsPointIn3d(void) {
|
|
||||||
switch(type) {
|
|
||||||
case POINT_IN_3D:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Entity::PointIsKnown(void) {
|
|
||||||
switch(type) {
|
|
||||||
case POINT_IN_3D:
|
|
||||||
return SS.GetParam(param[0])->known &&
|
|
||||||
SS.GetParam(param[1])->known &&
|
|
||||||
SS.GetParam(param[2])->known;
|
|
||||||
case POINT_IN_2D:
|
|
||||||
return SS.GetParam(param[0])->known &&
|
|
||||||
SS.GetParam(param[1])->known;
|
|
||||||
default: oops();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Entity::PointIsFromReferences(void) {
|
bool Entity::PointIsFromReferences(void) {
|
||||||
return h.request().IsFromReferences();
|
return h.request().IsFromReferences();
|
||||||
}
|
}
|
||||||
|
@ -147,6 +134,16 @@ void Entity::PointForceTo(Vector p) {
|
||||||
SS.GetParam(param[1])->val = p.Dot(v);
|
SS.GetParam(param[1])->val = p.Dot(v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case POINT_XFRMD: {
|
||||||
|
Vector orig = SS.GetEntity(point[0])->PointGetCoords();
|
||||||
|
Vector trans = p.Minus(orig);
|
||||||
|
SS.GetParam(param[0])->val = trans.x;
|
||||||
|
SS.GetParam(param[1])->val = trans.y;
|
||||||
|
SS.GetParam(param[2])->val = trans.z;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: oops();
|
default: oops();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,6 +165,14 @@ Vector Entity::PointGetCoords(void) {
|
||||||
p = p.Plus(v.ScaledBy(SS.GetParam(param[1])->val));
|
p = p.Plus(v.ScaledBy(SS.GetParam(param[1])->val));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case POINT_XFRMD: {
|
||||||
|
p = SS.GetEntity(point[0])->PointGetCoords();
|
||||||
|
p.x += SS.GetParam(param[0])->val;
|
||||||
|
p.y += SS.GetParam(param[1])->val;
|
||||||
|
p.z += SS.GetParam(param[2])->val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: oops();
|
default: oops();
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
|
@ -191,6 +196,15 @@ ExprVector Entity::PointGetExprs(void) {
|
||||||
r = r.Plus(v.ScaledBy(Expr::FromParam(param[1])));
|
r = r.Plus(v.ScaledBy(Expr::FromParam(param[1])));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case POINT_XFRMD: {
|
||||||
|
ExprVector orig = SS.GetEntity(point[0])->PointGetExprs();
|
||||||
|
ExprVector trans;
|
||||||
|
trans.x = Expr::FromParam(param[0]);
|
||||||
|
trans.y = Expr::FromParam(param[1]);
|
||||||
|
trans.z = Expr::FromParam(param[2]);
|
||||||
|
r = orig.Plus(trans);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: oops();
|
default: oops();
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
|
@ -227,6 +241,10 @@ bool Entity::PointIsLocked(void) {
|
||||||
} else if(type == POINT_IN_2D) {
|
} else if(type == POINT_IN_2D) {
|
||||||
if(SS.GetParam(param[0])->assumed) return false;
|
if(SS.GetParam(param[0])->assumed) return false;
|
||||||
if(SS.GetParam(param[1])->assumed) return false;
|
if(SS.GetParam(param[1])->assumed) return false;
|
||||||
|
} else if(type == POINT_XFRMD) {
|
||||||
|
if(SS.GetParam(param[0])->assumed) return false;
|
||||||
|
if(SS.GetParam(param[1])->assumed) return false;
|
||||||
|
if(SS.GetParam(param[2])->assumed) return false;
|
||||||
} else {
|
} else {
|
||||||
oops();
|
oops();
|
||||||
}
|
}
|
||||||
|
@ -285,13 +303,18 @@ void Entity::DrawOrGetDistance(int order) {
|
||||||
glxColor3d(1, 1, 1);
|
glxColor3d(1, 1, 1);
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
case POINT_XFRMD:
|
||||||
case POINT_IN_3D:
|
case POINT_IN_3D:
|
||||||
case POINT_IN_2D: {
|
case POINT_IN_2D: {
|
||||||
if(order >= 0 && order != 2) break;
|
if(order >= 0 && order != 2) break;
|
||||||
if(!SS.GW.showPoints) break;
|
if(!SS.GW.showPoints) break;
|
||||||
|
|
||||||
|
if(h.isFromRequest()) {
|
||||||
Entity *isfor = SS.GetEntity(h.request().entity(0));
|
Entity *isfor = SS.GetEntity(h.request().entity(0));
|
||||||
if(!SS.GW.showWorkplanes && isfor->type == Entity::WORKPLANE) break;
|
if(!SS.GW.showWorkplanes && isfor->type == Entity::WORKPLANE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Vector v = PointGetCoords();
|
Vector v = PointGetCoords();
|
||||||
|
|
||||||
|
|
10
expr.cpp
10
expr.cpp
|
@ -131,11 +131,17 @@ Expr *Expr::DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
|
||||||
Expr *n = AllocExpr();
|
Expr *n = AllocExpr();
|
||||||
if(op == PARAM) {
|
if(op == PARAM) {
|
||||||
// A param that is referenced by its hParam gets rewritten to go
|
// A param that is referenced by its hParam gets rewritten to go
|
||||||
// straight in to the parameter table with a pointer.
|
// straight in to the parameter table with a pointer, or simply
|
||||||
n->op = PARAM_PTR;
|
// into a constant if it's already known.
|
||||||
Param *p = firstTry->FindByIdNoOops(x.parh);
|
Param *p = firstTry->FindByIdNoOops(x.parh);
|
||||||
if(!p) p = thenTry->FindById(x.parh);
|
if(!p) p = thenTry->FindById(x.parh);
|
||||||
|
if(p->known) {
|
||||||
|
n->op = CONSTANT;
|
||||||
|
n->x.v = p->val;
|
||||||
|
} else {
|
||||||
|
n->op = PARAM_PTR;
|
||||||
n->x.parp = p;
|
n->x.parp = p;
|
||||||
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3
file.cpp
3
file.cpp
|
@ -12,11 +12,12 @@ void SolveSpace::NewFile(void) {
|
||||||
Group g;
|
Group g;
|
||||||
memset(&g, 0, sizeof(g));
|
memset(&g, 0, sizeof(g));
|
||||||
g.name.strcpy("#references");
|
g.name.strcpy("#references");
|
||||||
|
g.type = Group::DRAWING;
|
||||||
g.h = Group::HGROUP_REFERENCES;
|
g.h = Group::HGROUP_REFERENCES;
|
||||||
group.Add(&g);
|
group.Add(&g);
|
||||||
|
|
||||||
// And an empty group, for the first stuff the user draws.
|
// And an empty group, for the first stuff the user draws.
|
||||||
g.name.strcpy("");
|
g.name.strcpy("drawing");
|
||||||
group.AddAndAssignId(&g);
|
group.AddAndAssignId(&g);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#define mReq (&GraphicsWindow::MenuRequest)
|
#define mReq (&GraphicsWindow::MenuRequest)
|
||||||
#define mCon (&Constraint::MenuConstrain)
|
#define mCon (&Constraint::MenuConstrain)
|
||||||
#define mFile (&SolveSpace::MenuFile)
|
#define mFile (&SolveSpace::MenuFile)
|
||||||
|
#define mGrp (&Group::MenuGroup)
|
||||||
#define S 0x100
|
#define S 0x100
|
||||||
#define C 0x200
|
#define C 0x200
|
||||||
const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
||||||
|
@ -37,12 +38,12 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
||||||
{ 1, "Dimensions in &Millimeters", MNU_UNITS_MM, 0, mView },
|
{ 1, "Dimensions in &Millimeters", MNU_UNITS_MM, 0, mView },
|
||||||
|
|
||||||
{ 0, "&Group", 0, 0, NULL },
|
{ 0, "&Group", 0, 0, NULL },
|
||||||
{ 1, "New &Drawing Group", 0, 0, NULL },
|
{ 1, "New &Drawing Group\tShift+Ctrl+D", MNU_GROUP_DRAWING, 'D'|S|C,mGrp },
|
||||||
{ 1, NULL, 0, NULL },
|
{ 1, NULL, 0, NULL },
|
||||||
{ 1, "New Step and Repeat &Translating", 0, 0, NULL },
|
{ 1, "New Step and Repeat &Translating", 0, 0, NULL },
|
||||||
{ 1, "New Step and Repeat &Rotating", 0, 0, NULL },
|
{ 1, "New Step and Repeat &Rotating", 0, 0, NULL },
|
||||||
{ 1, NULL, 0, 0, NULL },
|
{ 1, NULL, 0, 0, NULL },
|
||||||
{ 1, "New Extrusion", 0, 0, NULL },
|
{ 1, "New Extrusion\tShift+Ctrl+X", MNU_GROUP_EXTRUDE, 'X'|S|C,mGrp },
|
||||||
{ 1, NULL, 0, 0, NULL },
|
{ 1, NULL, 0, 0, NULL },
|
||||||
{ 1, "New Boolean Difference", 0, 0, NULL },
|
{ 1, "New Boolean Difference", 0, 0, NULL },
|
||||||
{ 1, "New Boolean Union", 0, 0, NULL },
|
{ 1, "New Boolean Union", 0, 0, NULL },
|
||||||
|
@ -268,7 +269,7 @@ void GraphicsWindow::MenuEdit(int id) {
|
||||||
for(i = 0; i < MAX_SELECTED; i++) {
|
for(i = 0; i < MAX_SELECTED; i++) {
|
||||||
Selection *s = &(SS.GW.selection[i]);
|
Selection *s = &(SS.GW.selection[i]);
|
||||||
hRequest r; r.v = 0;
|
hRequest r; r.v = 0;
|
||||||
if(s->entity.v) {
|
if(s->entity.v && s->entity.isFromRequest()) {
|
||||||
r = s->entity.request();
|
r = s->entity.request();
|
||||||
}
|
}
|
||||||
if(r.v && !r.IsFromReferences()) {
|
if(r.v && !r.IsFromReferences()) {
|
||||||
|
@ -293,7 +294,7 @@ void GraphicsWindow::MenuEdit(int id) {
|
||||||
SS.request.RemoveTagged();
|
SS.request.RemoveTagged();
|
||||||
SS.constraint.RemoveTagged();
|
SS.constraint.RemoveTagged();
|
||||||
|
|
||||||
SS.GenerateAll();
|
SS.GenerateAll(SS.GW.solving == SOLVE_ALWAYS);
|
||||||
SS.GW.ClearSelection();
|
SS.GW.ClearSelection();
|
||||||
SS.GW.hover.Clear();
|
SS.GW.hover.Clear();
|
||||||
break;
|
break;
|
||||||
|
@ -433,9 +434,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
|
||||||
UpdateDraggedPoint(&(c->disp.offset), x, y);
|
UpdateDraggedPoint(&(c->disp.offset), x, y);
|
||||||
} else if(leftDown && pendingOperation == DRAGGING_POINT) {
|
} else if(leftDown && pendingOperation == DRAGGING_POINT) {
|
||||||
UpdateDraggedEntity(pendingPoint, x, y);
|
UpdateDraggedEntity(pendingPoint, x, y);
|
||||||
if(solving == SOLVE_ALWAYS) {
|
SS.GenerateAll(solving == SOLVE_ALWAYS);
|
||||||
SS.Solve();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No buttons pressed.
|
// No buttons pressed.
|
||||||
|
@ -562,9 +561,7 @@ hRequest GraphicsWindow::AddRequest(int type) {
|
||||||
r.workplane = activeWorkplane;
|
r.workplane = activeWorkplane;
|
||||||
r.type = type;
|
r.type = type;
|
||||||
SS.request.AddAndAssignId(&r);
|
SS.request.AddAndAssignId(&r);
|
||||||
SS.GenerateAll();
|
SS.GenerateAll(solving == SOLVE_ALWAYS);
|
||||||
|
|
||||||
if(solving == SOLVE_ALWAYS) SS.Solve();
|
|
||||||
|
|
||||||
return r.h;
|
return r.h;
|
||||||
}
|
}
|
||||||
|
@ -730,7 +727,7 @@ void GraphicsWindow::EditControlDone(char *s) {
|
||||||
Expr::FreeKeep(&(c->exprA));
|
Expr::FreeKeep(&(c->exprA));
|
||||||
c->exprA = e->DeepCopyKeep();
|
c->exprA = e->DeepCopyKeep();
|
||||||
HideGraphicsEditControl();
|
HideGraphicsEditControl();
|
||||||
if(SS.GW.solving == SOLVE_ALWAYS) SS.Solve();
|
SS.GenerateAll(solving == SOLVE_ALWAYS);
|
||||||
} else {
|
} else {
|
||||||
Error("Not a valid number or expression: '%s'", s);
|
Error("Not a valid number or expression: '%s'", s);
|
||||||
}
|
}
|
||||||
|
@ -762,7 +759,7 @@ void GraphicsWindow::ToggleBool(int link, DWORD v) {
|
||||||
bool *vb = (bool *)v;
|
bool *vb = (bool *)v;
|
||||||
*vb = !*vb;
|
*vb = !*vb;
|
||||||
|
|
||||||
SS.GenerateAll();
|
SS.GenerateAll(SS.GW.solving == SOLVE_ALWAYS);
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
SS.TW.Show();
|
SS.TW.Show();
|
||||||
}
|
}
|
||||||
|
@ -773,7 +770,7 @@ void GraphicsWindow::ToggleAnyDatumShown(int link, DWORD v) {
|
||||||
SS.GW.showAxes = t;
|
SS.GW.showAxes = t;
|
||||||
SS.GW.showPoints = t;
|
SS.GW.showPoints = t;
|
||||||
|
|
||||||
SS.GenerateAll();
|
SS.GenerateAll(SS.GW.solving == SOLVE_ALWAYS);
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
SS.TW.Show();
|
SS.TW.Show();
|
||||||
}
|
}
|
||||||
|
|
124
sketch.cpp
124
sketch.cpp
|
@ -7,6 +7,41 @@ const hRequest Request::HREQUEST_REFERENCE_XY = { 1 };
|
||||||
const hRequest Request::HREQUEST_REFERENCE_YZ = { 2 };
|
const hRequest Request::HREQUEST_REFERENCE_YZ = { 2 };
|
||||||
const hRequest Request::HREQUEST_REFERENCE_ZX = { 3 };
|
const hRequest Request::HREQUEST_REFERENCE_ZX = { 3 };
|
||||||
|
|
||||||
|
void Group::AddParam(IdList<Param,hParam> *param, hParam hp, double v) {
|
||||||
|
Param pa;
|
||||||
|
memset(&pa, 0, sizeof(pa));
|
||||||
|
pa.h = hp;
|
||||||
|
pa.val = v;
|
||||||
|
|
||||||
|
param->Add(&pa);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::MenuGroup(int id) {
|
||||||
|
Group g;
|
||||||
|
memset(&g, 0, sizeof(g));
|
||||||
|
g.visible = true;
|
||||||
|
|
||||||
|
switch(id) {
|
||||||
|
case GraphicsWindow::MNU_GROUP_DRAWING:
|
||||||
|
g.type = DRAWING;
|
||||||
|
g.name.strcpy("drawing");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GraphicsWindow::MNU_GROUP_EXTRUDE:
|
||||||
|
g.type = EXTRUDE;
|
||||||
|
g.opA.v = 2;
|
||||||
|
g.name.strcpy("extrude");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: oops();
|
||||||
|
}
|
||||||
|
|
||||||
|
SS.group.AddAndAssignId(&g);
|
||||||
|
SS.GenerateAll(SS.GW.solving == GraphicsWindow::SOLVE_ALWAYS);
|
||||||
|
SS.GW.activeGroup = g.h;
|
||||||
|
SS.TW.Show();
|
||||||
|
}
|
||||||
|
|
||||||
char *Group::DescriptionString(void) {
|
char *Group::DescriptionString(void) {
|
||||||
static char ret[100];
|
static char ret[100];
|
||||||
if(name.str[0]) {
|
if(name.str[0]) {
|
||||||
|
@ -17,13 +52,94 @@ char *Group::DescriptionString(void) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
|
IdList<Param,hParam> *param)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
switch(type) {
|
||||||
|
case DRAWING:
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EXTRUDE:
|
||||||
|
AddParam(param, h.param(0), 50);
|
||||||
|
AddParam(param, h.param(1), 50);
|
||||||
|
AddParam(param, h.param(2), 50);
|
||||||
|
for(i = 0; i < entity->n; i++) {
|
||||||
|
Entity *e = &(entity->elem[i]);
|
||||||
|
if(e->group.v != opA.v) continue;
|
||||||
|
|
||||||
|
CopyEntity(e->h, 0, h.param(0), h.param(1), h.param(2));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: oops();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hEntity Group::Remap(hEntity in, int copyNumber) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < remap.n; i++) {
|
||||||
|
EntityMap *em = &(remap.elem[i]);
|
||||||
|
if(em->input.v == in.v && em->copyNumber == copyNumber) {
|
||||||
|
// We already have a mapping for this entity.
|
||||||
|
return h.entity(em->h.v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We don't have a mapping yet, so create one.
|
||||||
|
EntityMap em;
|
||||||
|
em.input = in;
|
||||||
|
em.copyNumber = copyNumber;
|
||||||
|
remap.AddAndAssignId(&em);
|
||||||
|
return h.entity(em.h.v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz) {
|
||||||
|
Entity *ep = SS.GetEntity(in);
|
||||||
|
|
||||||
|
Entity en;
|
||||||
|
memset(&en, 0, sizeof(en));
|
||||||
|
en.type = ep->type;
|
||||||
|
en.h = Remap(ep->h, a);
|
||||||
|
en.group = h;
|
||||||
|
|
||||||
|
switch(ep->type) {
|
||||||
|
case Entity::WORKPLANE:
|
||||||
|
// Don't copy these.
|
||||||
|
return;
|
||||||
|
|
||||||
|
case Entity::LINE_SEGMENT:
|
||||||
|
en.point[0] = Remap(ep->point[0], a);
|
||||||
|
en.point[1] = Remap(ep->point[1], a);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Entity::CUBIC:
|
||||||
|
en.point[0] = Remap(ep->point[0], a);
|
||||||
|
en.point[1] = Remap(ep->point[1], a);
|
||||||
|
en.point[2] = Remap(ep->point[2], a);
|
||||||
|
en.point[3] = Remap(ep->point[3], a);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Entity::POINT_IN_3D:
|
||||||
|
case Entity::POINT_IN_2D:
|
||||||
|
en.type = Entity::POINT_XFRMD;
|
||||||
|
en.point[0] = ep->h;
|
||||||
|
en.param[0] = dx;
|
||||||
|
en.param[1] = dy;
|
||||||
|
en.param[2] = dz;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
oops();
|
||||||
|
}
|
||||||
|
SS.entity.Add(&en);
|
||||||
|
}
|
||||||
|
|
||||||
void Group::Draw(void) {
|
void Group::Draw(void) {
|
||||||
edges.l.Clear();
|
edges.l.Clear();
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < SS.entity.n; i++) {
|
for(i = 0; i < SS.entity.n; i++) {
|
||||||
Entity *e = &(SS.entity.elem[i]);
|
Entity *e = &(SS.entity.elem[i]);
|
||||||
hRequest hr = e->h.request();
|
if(e->group.v != h.v) continue;
|
||||||
if(SS.GetRequest(hr)->group.v != h.v) continue;
|
|
||||||
|
|
||||||
e->GenerateEdges(&edges);
|
e->GenerateEdges(&edges);
|
||||||
}
|
}
|
||||||
|
@ -86,6 +202,7 @@ void Request::Generate(IdList<Entity,hEntity> *entity,
|
||||||
c: {
|
c: {
|
||||||
// Generate the entity that's specific to this request.
|
// Generate the entity that's specific to this request.
|
||||||
e.type = et;
|
e.type = et;
|
||||||
|
e.group = group;
|
||||||
e.h = h.entity(0);
|
e.h = h.entity(0);
|
||||||
|
|
||||||
// And generate entities for the points
|
// And generate entities for the points
|
||||||
|
@ -95,7 +212,8 @@ c: {
|
||||||
p.workplane = workplane;
|
p.workplane = workplane;
|
||||||
// points start from entity 1, except for datum point case
|
// points start from entity 1, except for datum point case
|
||||||
p.h = h.entity(i+(et ? 1 : 0));
|
p.h = h.entity(i+(et ? 1 : 0));
|
||||||
p.symbolic = true;
|
p.group = group;
|
||||||
|
|
||||||
if(workplane.v == Entity::FREE_IN_3D.v) {
|
if(workplane.v == Entity::FREE_IN_3D.v) {
|
||||||
p.type = Entity::POINT_IN_3D;
|
p.type = Entity::POINT_IN_3D;
|
||||||
// params for x y z
|
// params for x y z
|
||||||
|
|
44
sketch.h
44
sketch.h
|
@ -19,6 +19,9 @@ class hGroup {
|
||||||
public:
|
public:
|
||||||
// bits 15: 0 -- group index
|
// bits 15: 0 -- group index
|
||||||
DWORD v;
|
DWORD v;
|
||||||
|
|
||||||
|
inline hEntity entity(int i);
|
||||||
|
inline hParam param(int i);
|
||||||
};
|
};
|
||||||
class hRequest {
|
class hRequest {
|
||||||
public:
|
public:
|
||||||
|
@ -36,6 +39,7 @@ public:
|
||||||
// 31:16 -- request index
|
// 31:16 -- request index
|
||||||
DWORD v;
|
DWORD v;
|
||||||
|
|
||||||
|
inline bool isFromRequest(void);
|
||||||
inline hRequest request(void);
|
inline hRequest request(void);
|
||||||
};
|
};
|
||||||
class hParam {
|
class hParam {
|
||||||
|
@ -49,9 +53,11 @@ public:
|
||||||
|
|
||||||
|
|
||||||
class EntityId {
|
class EntityId {
|
||||||
|
public:
|
||||||
DWORD v; // entity ID, starting from 0
|
DWORD v; // entity ID, starting from 0
|
||||||
};
|
};
|
||||||
class EntityMap {
|
class EntityMap {
|
||||||
|
public:
|
||||||
int tag;
|
int tag;
|
||||||
|
|
||||||
EntityId h;
|
EntityId h;
|
||||||
|
@ -68,14 +74,15 @@ public:
|
||||||
int tag;
|
int tag;
|
||||||
hGroup h;
|
hGroup h;
|
||||||
|
|
||||||
static const int DRAWING_GROUP = 5000;
|
static const int DRAWING = 5000;
|
||||||
static const int STEP_AND_REPEAT_TRANSLATING = 5010;
|
static const int EXTRUDE = 5010;
|
||||||
static const int STEP_AND_REPEAT_ROTATING = 5020;
|
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
int solveOrder;
|
int solveOrder;
|
||||||
bool solved;
|
bool solved;
|
||||||
|
|
||||||
|
hGroup opA;
|
||||||
|
hGroup opB;
|
||||||
bool visible;
|
bool visible;
|
||||||
|
|
||||||
SEdgeList edges;
|
SEdgeList edges;
|
||||||
|
@ -84,16 +91,21 @@ public:
|
||||||
NameStr name;
|
NameStr name;
|
||||||
char *DescriptionString(void);
|
char *DescriptionString(void);
|
||||||
|
|
||||||
|
static void AddParam(IdList<Param,hParam> *param, hParam hp, double v);
|
||||||
|
void Generate(IdList<Entity,hEntity> *entity, IdList<Param,hParam> *param);
|
||||||
// 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
|
||||||
// remap the entity ID so that it's still unique. We do this with a
|
// remap the entity ID so that it's still unique. We do this with a
|
||||||
// mapping list.
|
// mapping list.
|
||||||
IdList<EntityId,EntityMap> remap;
|
IdList<EntityMap,EntityId> remap;
|
||||||
hEntity Remap(hEntity in, int copyNumber);
|
hEntity Remap(hEntity in, int copyNumber);
|
||||||
|
void CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz);
|
||||||
|
|
||||||
void Draw(void);
|
void Draw(void);
|
||||||
|
|
||||||
SPolygon GetPolygon(void);
|
SPolygon GetPolygon(void);
|
||||||
|
|
||||||
|
static void MenuGroup(int id);
|
||||||
};
|
};
|
||||||
|
|
||||||
// A user request for some primitive or derived operation; for example a
|
// A user request for some primitive or derived operation; for example a
|
||||||
|
@ -122,7 +134,7 @@ public:
|
||||||
NameStr name;
|
NameStr name;
|
||||||
bool construction;
|
bool construction;
|
||||||
|
|
||||||
hParam AddParam(IdList<Param,hParam> *param, hParam hp);
|
static hParam AddParam(IdList<Param,hParam> *param, hParam hp);
|
||||||
void Generate(IdList<Entity,hEntity> *entity, IdList<Param,hParam> *param);
|
void Generate(IdList<Entity,hEntity> *entity, IdList<Param,hParam> *param);
|
||||||
|
|
||||||
char *DescriptionString(void);
|
char *DescriptionString(void);
|
||||||
|
@ -138,9 +150,7 @@ public:
|
||||||
static const int WORKPLANE = 1000;
|
static const int WORKPLANE = 1000;
|
||||||
static const int POINT_IN_3D = 2000;
|
static const int POINT_IN_3D = 2000;
|
||||||
static const int POINT_IN_2D = 2001;
|
static const int POINT_IN_2D = 2001;
|
||||||
static const int POINT_OFFSET = 2010;
|
static const int POINT_XFRMD = 2010;
|
||||||
static const int DIRECTION_QUATERNION = 3000;
|
|
||||||
static const int DIRECTION_OFFSET = 3010;
|
|
||||||
static const int LINE_SEGMENT = 10000;
|
static const int LINE_SEGMENT = 10000;
|
||||||
static const int CUBIC = 11000;
|
static const int CUBIC = 11000;
|
||||||
|
|
||||||
|
@ -148,16 +158,19 @@ public:
|
||||||
static const int FACE_LIST = 91000;
|
static const int FACE_LIST = 91000;
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
bool symbolic;
|
|
||||||
|
|
||||||
// When it comes time to draw an entity, we look here to get the
|
// When it comes time to draw an entity, we look here to get the
|
||||||
// defining variables.
|
// defining variables.
|
||||||
hParam param[4];
|
hParam param[4];
|
||||||
hEntity point[4];
|
hEntity point[4];
|
||||||
hEntity direction;
|
hEntity direction;
|
||||||
|
|
||||||
|
hGroup group;
|
||||||
hEntity workplane; // or Entity::FREE_IN_3D
|
hEntity workplane; // or Entity::FREE_IN_3D
|
||||||
|
|
||||||
|
// For entities that are derived by a transformation, the number of
|
||||||
|
// times to apply the transformation.
|
||||||
|
int timesApplied;
|
||||||
|
|
||||||
// Applies only for a WORKPLANE type
|
// Applies only for a WORKPLANE type
|
||||||
void WorkplaneGetBasisVectors(Vector *u, Vector *v);
|
void WorkplaneGetBasisVectors(Vector *u, Vector *v);
|
||||||
Vector WorkplaneGetNormalVector(void);
|
Vector WorkplaneGetNormalVector(void);
|
||||||
|
@ -165,7 +178,6 @@ public:
|
||||||
ExprVector WorkplaneGetOffsetExprs(void);
|
ExprVector WorkplaneGetOffsetExprs(void);
|
||||||
|
|
||||||
bool IsPoint(void);
|
bool IsPoint(void);
|
||||||
bool IsPointIn3d(void);
|
|
||||||
// Applies for any of the point types
|
// Applies for any of the point types
|
||||||
bool PointIsLocked(void);
|
bool PointIsLocked(void);
|
||||||
Vector PointGetCoords(void);
|
Vector PointGetCoords(void);
|
||||||
|
@ -173,7 +185,6 @@ public:
|
||||||
void PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v);
|
void PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v);
|
||||||
void PointForceTo(Vector v);
|
void PointForceTo(Vector v);
|
||||||
bool PointIsFromReferences(void);
|
bool PointIsFromReferences(void);
|
||||||
bool PointIsKnown(void);
|
|
||||||
|
|
||||||
// Applies for anything that comes with a plane
|
// Applies for anything that comes with a plane
|
||||||
bool HasPlane(void);
|
bool HasPlane(void);
|
||||||
|
@ -210,6 +221,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline hEntity hGroup::entity(int i)
|
||||||
|
{ hEntity r; r.v = 0x80000000 | (v << 16) | i; return r; }
|
||||||
|
inline hParam hGroup::param(int i)
|
||||||
|
{ hParam r; r.v = 0x80000000 | (v << 16) | i; return r; }
|
||||||
|
|
||||||
inline bool hRequest::IsFromReferences(void) {
|
inline bool hRequest::IsFromReferences(void) {
|
||||||
if(v == Request::HREQUEST_REFERENCE_XY.v) return true;
|
if(v == Request::HREQUEST_REFERENCE_XY.v) return true;
|
||||||
if(v == Request::HREQUEST_REFERENCE_YZ.v) return true;
|
if(v == Request::HREQUEST_REFERENCE_YZ.v) return true;
|
||||||
|
@ -221,6 +237,8 @@ inline hEntity hRequest::entity(int i)
|
||||||
inline hParam hRequest::param(int i)
|
inline hParam hRequest::param(int i)
|
||||||
{ hParam r; r.v = (v << 16) | i; return r; }
|
{ hParam r; r.v = (v << 16) | i; return r; }
|
||||||
|
|
||||||
|
inline bool hEntity::isFromRequest(void)
|
||||||
|
{ if(v & 0x80000000) return false; else return true; }
|
||||||
inline hRequest hEntity::request(void)
|
inline hRequest hEntity::request(void)
|
||||||
{ hRequest r; r.v = (v >> 16); return r; }
|
{ hRequest r; r.v = (v >> 16); return r; }
|
||||||
|
|
||||||
|
@ -269,6 +287,8 @@ public:
|
||||||
Vector offset;
|
Vector offset;
|
||||||
} disp;
|
} disp;
|
||||||
|
|
||||||
|
char *DescriptionString(void);
|
||||||
|
|
||||||
static hConstraint AddConstraint(Constraint *c);
|
static hConstraint AddConstraint(Constraint *c);
|
||||||
static void MenuConstrain(int id);
|
static void MenuConstrain(int id);
|
||||||
|
|
||||||
|
|
125
solvespace.cpp
125
solvespace.cpp
|
@ -12,34 +12,57 @@ void SolveSpace::Init(char *cmdLine) {
|
||||||
TW.Init();
|
TW.Init();
|
||||||
GW.Init();
|
GW.Init();
|
||||||
|
|
||||||
GenerateAll();
|
GenerateAll(false);
|
||||||
|
|
||||||
TW.Show();
|
TW.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpace::GenerateAll(void) {
|
void SolveSpace::GenerateAll(bool andSolve) {
|
||||||
int i;
|
int i, j;
|
||||||
|
|
||||||
// Don't lose our numerical guesses when we regenerate.
|
// Don't lose our numerical guesses when we regenerate.
|
||||||
IdList<Param,hParam> prev;
|
IdList<Param,hParam> prev;
|
||||||
param.MoveSelfInto(&prev);
|
param.MoveSelfInto(&prev);
|
||||||
|
|
||||||
entity.Clear();
|
entity.Clear();
|
||||||
for(i = 0; i < request.n; i++) {
|
|
||||||
request.elem[i].Generate(&entity, ¶m);
|
for(i = 0; i < group.n; i++) {
|
||||||
|
group.elem[i].solved = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore the numerical guesses.
|
// For now, solve the groups in given order; should discover the
|
||||||
for(i = 0; i < param.n; i++) {
|
// correct order later.
|
||||||
Param *p = prev.FindByIdNoOops(param.elem[i].h);
|
for(i = 0; i < group.n; i++) {
|
||||||
if(p) {
|
Group *g = &(group.elem[i]);
|
||||||
param.elem[i].val = p->val;
|
|
||||||
param.elem[i].assumed = p->assumed;
|
for(j = 0; j < request.n; j++) {
|
||||||
|
Request *r = &(request.elem[j]);
|
||||||
|
if(r->group.v != g->h.v) continue;
|
||||||
|
|
||||||
|
r->Generate(&entity, ¶m);
|
||||||
|
}
|
||||||
|
|
||||||
|
g->Generate(&entity, ¶m);
|
||||||
|
|
||||||
|
// Use the previous values for params that we've seen before, as
|
||||||
|
// initial guesses for the solver.
|
||||||
|
for(j = 0; j < param.n; j++) {
|
||||||
|
Param *newp = &(param.elem[j]);
|
||||||
|
if(newp->known) continue;
|
||||||
|
|
||||||
|
Param *prevp = prev.FindByIdNoOops(newp->h);
|
||||||
|
if(prevp) newp->val = prevp->val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(g->h.v == Group::HGROUP_REFERENCES.v) {
|
||||||
|
ForceReferences();
|
||||||
|
group.elem[0].solved = true;
|
||||||
|
} else {
|
||||||
|
// Solve this group.
|
||||||
|
if(andSolve) SolveGroup(g->h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prev.Clear();
|
prev.Clear();
|
||||||
ForceReferences();
|
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,27 +81,22 @@ void SolveSpace::ForceReferences(void) {
|
||||||
hRequest hr = Quat[i].hr;
|
hRequest hr = Quat[i].hr;
|
||||||
// The origin for our coordinate system, always zero
|
// The origin for our coordinate system, always zero
|
||||||
Vector v = Vector::MakeFrom(0, 0, 0);
|
Vector v = Vector::MakeFrom(0, 0, 0);
|
||||||
GetEntity(hr.entity(1))->PointForceTo(v);
|
Entity *origin = GetEntity(hr.entity(1));
|
||||||
|
origin->PointForceTo(v);
|
||||||
|
GetParam(origin->param[0])->known = true;
|
||||||
|
GetParam(origin->param[1])->known = true;
|
||||||
|
GetParam(origin->param[2])->known = true;
|
||||||
// The quaternion that defines the rotation, from the table.
|
// The quaternion that defines the rotation, from the table.
|
||||||
GetParam(hr.param(0))->val = Quat[i].a;
|
Param *p;
|
||||||
GetParam(hr.param(1))->val = Quat[i].b;
|
p = GetParam(hr.param(0)); p->val = Quat[i].a; p->known = true;
|
||||||
GetParam(hr.param(2))->val = Quat[i].c;
|
p = GetParam(hr.param(1)); p->val = Quat[i].b; p->known = true;
|
||||||
GetParam(hr.param(3))->val = Quat[i].d;
|
p = GetParam(hr.param(2)); p->val = Quat[i].c; p->known = true;
|
||||||
|
p = GetParam(hr.param(3)); p->val = Quat[i].d; p->known = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SolveSpace::SolveGroup(hGroup hg) {
|
bool SolveSpace::SolveGroup(hGroup hg) {
|
||||||
int i;
|
int i;
|
||||||
if(hg.v == Group::HGROUP_REFERENCES.v) {
|
|
||||||
// Special case; mark everything in the references known.
|
|
||||||
for(i = 0; i < param.n; i++) {
|
|
||||||
Param *p = &(param.elem[i]);
|
|
||||||
Request *r = GetRequest(p->h.request());
|
|
||||||
if(r->group.v == hg.v) p->known = true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear out the system to be solved.
|
// Clear out the system to be solved.
|
||||||
sys.entity.Clear();
|
sys.entity.Clear();
|
||||||
sys.param.Clear();
|
sys.param.Clear();
|
||||||
|
@ -90,6 +108,9 @@ bool SolveSpace::SolveGroup(hGroup hg) {
|
||||||
|
|
||||||
r->Generate(&(sys.entity), &(sys.param));
|
r->Generate(&(sys.entity), &(sys.param));
|
||||||
}
|
}
|
||||||
|
// And for the group itself
|
||||||
|
Group *g = SS.GetGroup(hg);
|
||||||
|
g->Generate(&(sys.entity), &(sys.param));
|
||||||
// Set the initial guesses for all the params
|
// Set the initial guesses for all the params
|
||||||
for(i = 0; i < sys.param.n; i++) {
|
for(i = 0; i < sys.param.n; i++) {
|
||||||
Param *p = &(sys.param.elem[i]);
|
Param *p = &(sys.param.elem[i]);
|
||||||
|
@ -109,57 +130,11 @@ bool SolveSpace::SolveGroup(hGroup hg) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SolveSpace::SolveWorker(int order) {
|
|
||||||
bool allSolved = true;
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < group.n; i++) {
|
|
||||||
Group *g = &(group.elem[i]);
|
|
||||||
if(g->solved) continue;
|
|
||||||
|
|
||||||
allSolved = false;
|
|
||||||
dbp("try solve group %s", g->DescriptionString());
|
|
||||||
|
|
||||||
// Save the parameter table; a failed solve attempt will mess that
|
|
||||||
// up a little bit.
|
|
||||||
IdList<Param,hParam> savedParam;
|
|
||||||
param.DeepCopyInto(&savedParam);
|
|
||||||
|
|
||||||
if(SolveGroup(g->h)) {
|
|
||||||
g->solved = true;
|
|
||||||
g->solveOrder = order;
|
|
||||||
// So this one worked; let's see if we can go any further.
|
|
||||||
if(SolveWorker(order+1)) {
|
|
||||||
// So everything worked; we're done.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Didn't work, so undo this choice and give up
|
|
||||||
g->solved = false;
|
|
||||||
param.Clear();
|
|
||||||
savedParam.MoveSelfInto(¶m);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we got here, then either everything failed, so we're stuck, or
|
|
||||||
// everything was already solved, so we're done.
|
|
||||||
return allSolved;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SolveSpace::Solve(void) {
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < group.n; i++) {
|
|
||||||
group.elem[i].solved = false;
|
|
||||||
}
|
|
||||||
SolveWorker(0);
|
|
||||||
|
|
||||||
InvalidateGraphics();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SolveSpace::MenuFile(int id) {
|
void SolveSpace::MenuFile(int id) {
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case GraphicsWindow::MNU_NEW:
|
case GraphicsWindow::MNU_NEW:
|
||||||
SS.NewFile();
|
SS.NewFile();
|
||||||
SS.GenerateAll();
|
SS.GenerateAll(false);
|
||||||
SS.GW.Init();
|
SS.GW.Init();
|
||||||
SS.TW.Init();
|
SS.TW.Init();
|
||||||
SS.TW.Show();
|
SS.TW.Show();
|
||||||
|
|
14
solvespace.h
14
solvespace.h
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// Debugging functions
|
// Debugging functions
|
||||||
#define oops() do { dbp("oops at line %d, file %s", __LINE__, __FILE__); \
|
#define oops() do { dbp("oops at line %d, file %s", __LINE__, __FILE__); \
|
||||||
exit(-1); } while(0)
|
if(0) *(char *)0 = 1; exit(-1); } while(0)
|
||||||
#ifndef min
|
#ifndef min
|
||||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||||
#endif
|
#endif
|
||||||
|
@ -154,15 +154,8 @@ public:
|
||||||
|
|
||||||
FILE *fh;
|
FILE *fh;
|
||||||
|
|
||||||
void GenerateAll(void);
|
|
||||||
void ForceReferences(void);
|
|
||||||
|
|
||||||
void Init(char *cmdLine);
|
void Init(char *cmdLine);
|
||||||
|
|
||||||
bool SolveGroup(hGroup hg);
|
|
||||||
bool SolveWorker(int order);
|
|
||||||
void Solve(void);
|
|
||||||
|
|
||||||
char saveFile[MAX_PATH];
|
char saveFile[MAX_PATH];
|
||||||
bool unsaved;
|
bool unsaved;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -185,6 +178,11 @@ public:
|
||||||
bool SaveToFile(char *filename);
|
bool SaveToFile(char *filename);
|
||||||
bool LoadFromFile(char *filename);
|
bool LoadFromFile(char *filename);
|
||||||
|
|
||||||
|
|
||||||
|
void GenerateAll(bool andSolve);
|
||||||
|
bool SolveGroup(hGroup hg);
|
||||||
|
void ForceReferences(void);
|
||||||
|
|
||||||
// The system to be solved.
|
// The system to be solved.
|
||||||
System sys;
|
System sys;
|
||||||
};
|
};
|
||||||
|
|
|
@ -207,10 +207,11 @@ bool System::NewtonSolve(int tag) {
|
||||||
|
|
||||||
bool System::Solve(void) {
|
bool System::Solve(void) {
|
||||||
int i, j;
|
int i, j;
|
||||||
/* dbp("%d equations", eq.n);
|
dbp("%d equations", eq.n);
|
||||||
for(i = 0; i < eq.n; i++) {
|
for(i = 0; i < eq.n; i++) {
|
||||||
dbp(" %s = 0", eq.elem[i].e->Print());
|
dbp(" %s = 0", eq.elem[i].e->Print());
|
||||||
} */
|
}
|
||||||
|
dbp("%d parameters", param.n);
|
||||||
|
|
||||||
param.ClearTags();
|
param.ClearTags();
|
||||||
eq.ClearTags();
|
eq.ClearTags();
|
||||||
|
@ -218,12 +219,11 @@ bool System::Solve(void) {
|
||||||
WriteJacobian(0, 0);
|
WriteJacobian(0, 0);
|
||||||
EvalJacobian();
|
EvalJacobian();
|
||||||
|
|
||||||
/*
|
|
||||||
for(i = 0; i < mat.m; i++) {
|
for(i = 0; i < mat.m; i++) {
|
||||||
for(j = 0; j < mat.n; j++) {
|
for(j = 0; j < mat.n; j++) {
|
||||||
dbp("A[%d][%d] = %.3f", i, j, mat.A.num[i][j]);
|
dbp("A[%d][%d] = %.3f", i, j, mat.A.num[i][j]);
|
||||||
}
|
}
|
||||||
} */
|
}
|
||||||
|
|
||||||
GaussJordan();
|
GaussJordan();
|
||||||
|
|
||||||
|
|
75
textwin.cpp
75
textwin.cpp
|
@ -159,6 +159,7 @@ void TextWindow::Show(void) {
|
||||||
case SCREEN_LIST_OF_GROUPS: ShowListOfGroups(); break;
|
case SCREEN_LIST_OF_GROUPS: ShowListOfGroups(); break;
|
||||||
case SCREEN_GROUP_INFO: ShowGroupInfo(); break;
|
case SCREEN_GROUP_INFO: ShowGroupInfo(); break;
|
||||||
case SCREEN_REQUEST_INFO: ShowRequestInfo(); break;
|
case SCREEN_REQUEST_INFO: ShowRequestInfo(); break;
|
||||||
|
case SCREEN_CONSTRAINT_INFO: ShowConstraintInfo(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InvalidateText();
|
InvalidateText();
|
||||||
|
@ -211,8 +212,8 @@ void TextWindow::ShowHeader(void) {
|
||||||
cd = SS.GetEntity(SS.GW.activeWorkplane)->DescriptionString();
|
cd = SS.GetEntity(SS.GW.activeWorkplane)->DescriptionString();
|
||||||
}
|
}
|
||||||
Printf(" %Lb%f<<%E %Lh%fhome%E %CT workplane:%CD %s",
|
Printf(" %Lb%f<<%E %Lh%fhome%E %CT workplane:%CD %s",
|
||||||
(DWORD)(&TextWindow::ScreenNavigation),
|
(&TextWindow::ScreenNavigation),
|
||||||
(DWORD)(&TextWindow::ScreenNavigation),
|
(&TextWindow::ScreenNavigation),
|
||||||
cd);
|
cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +228,7 @@ void TextWindow::ShowHeader(void) {
|
||||||
|
|
||||||
#define hs(b) ((b) ? 'S' : 'H')
|
#define hs(b) ((b) ? 'S' : 'H')
|
||||||
Printf("%CTshow: "
|
Printf("%CTshow: "
|
||||||
"%Cp%Ll%D%fworkplane%E%CT "
|
"%Cp%Ll%D%fworkplanes%E%CT "
|
||||||
"%Cp%Ll%D%faxes%E%CT "
|
"%Cp%Ll%D%faxes%E%CT "
|
||||||
"%Cp%Ll%D%fpoints%E%CT "
|
"%Cp%Ll%D%fpoints%E%CT "
|
||||||
"%Cp%Ll%fany-datum%E%CT",
|
"%Cp%Ll%fany-datum%E%CT",
|
||||||
|
@ -239,24 +240,11 @@ void TextWindow::ShowHeader(void) {
|
||||||
Printf("%CT "
|
Printf("%CT "
|
||||||
"%Cp%Ll%D%fall-groups%E%CT "
|
"%Cp%Ll%D%fall-groups%E%CT "
|
||||||
"%Cp%Ll%D%fconstraints%E%CT",
|
"%Cp%Ll%D%fconstraints%E%CT",
|
||||||
hs(SS.GW.showAllGroups), (DWORD)(&SS.GW.showAllGroups),
|
hs(SS.GW.showAllGroups), (DWORD)(&SS.GW.showAllGroups), &(SS.GW.ToggleBool),
|
||||||
&(SS.GW.ToggleBool),
|
hs(SS.GW.showConstraints), (DWORD)(&SS.GW.showConstraints), &(SS.GW.ToggleBool)
|
||||||
hs(SS.GW.showConstraints), (DWORD)(&SS.GW.showConstraints),
|
|
||||||
&(SS.GW.ToggleBool)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextWindow::ShowListOfGroups(void) {
|
|
||||||
Printf("%Cd[[all groups in sketch follow]]%E");
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < SS.group.n; i++) {
|
|
||||||
char *s;
|
|
||||||
Group *g = &(SS.group.elem[i]);
|
|
||||||
s = g->DescriptionString();
|
|
||||||
Printf(" %Cl%Ll%D%f%s%E",
|
|
||||||
g->h.v, (DWORD)(&TextWindow::ScreenSelectGroup), s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void TextWindow::ScreenSelectGroup(int link, DWORD v) {
|
void TextWindow::ScreenSelectGroup(int link, DWORD v) {
|
||||||
SS.TW.OneScreenForward();
|
SS.TW.OneScreenForward();
|
||||||
|
|
||||||
|
@ -265,7 +253,31 @@ void TextWindow::ScreenSelectGroup(int link, DWORD v) {
|
||||||
|
|
||||||
SS.TW.Show();
|
SS.TW.Show();
|
||||||
}
|
}
|
||||||
|
void TextWindow::ShowListOfGroups(void) {
|
||||||
|
Printf("%Cd[[all groups in sketch follow]]%E");
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < SS.group.n; i++) {
|
||||||
|
char *s;
|
||||||
|
Group *g = &(SS.group.elem[i]);
|
||||||
|
s = g->DescriptionString();
|
||||||
|
Printf(" %Cl%Ll%D%f%s%E",
|
||||||
|
g->h.v, (&TextWindow::ScreenSelectGroup), s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TextWindow::ScreenSelectConstraint(int link, DWORD v) {
|
||||||
|
SS.TW.OneScreenForward();
|
||||||
|
|
||||||
|
SS.TW.shown->screen = SCREEN_CONSTRAINT_INFO;
|
||||||
|
SS.TW.shown->constraint.v = v;
|
||||||
|
|
||||||
|
SS.TW.Show();
|
||||||
|
}
|
||||||
|
void TextWindow::ScreenActivateGroup(int link, DWORD v) {
|
||||||
|
SS.GW.activeGroup.v = v;
|
||||||
|
SS.TW.Show();
|
||||||
|
}
|
||||||
void TextWindow::ScreenSelectRequest(int link, DWORD v) {
|
void TextWindow::ScreenSelectRequest(int link, DWORD v) {
|
||||||
SS.TW.OneScreenForward();
|
SS.TW.OneScreenForward();
|
||||||
|
|
||||||
|
@ -276,14 +288,16 @@ void TextWindow::ScreenSelectRequest(int link, DWORD v) {
|
||||||
}
|
}
|
||||||
void TextWindow::ShowGroupInfo(void) {
|
void TextWindow::ShowGroupInfo(void) {
|
||||||
Group *g = SS.group.FindById(shown->group);
|
Group *g = SS.group.FindById(shown->group);
|
||||||
|
Printf("%Cd[[group %s]]", g->DescriptionString());
|
||||||
if(SS.GW.activeGroup.v == shown->group.v) {
|
if(SS.GW.activeGroup.v == shown->group.v) {
|
||||||
Printf("%Cd[[this is the active group]]");
|
Printf("%Cd[[this is the active group]]");
|
||||||
} else if(shown->group.v == Group::HGROUP_REFERENCES.v) {
|
} else if(shown->group.v == Group::HGROUP_REFERENCES.v) {
|
||||||
Printf("%Cd[[this group contains the references]]");
|
Printf("%Cd[[this group contains the references]]");
|
||||||
} else {
|
} else {
|
||||||
Printf("%Cd[[not active; %Cl%Llactivate this group%E%Cd]]");
|
Printf("%Cd[[not active; %Cl%Ll%D%factivate group%E%Cd]]",
|
||||||
|
g->h.v, (&TextWindow::ScreenActivateGroup));
|
||||||
}
|
}
|
||||||
Printf("%Cd[[requests in group %s]]%E", g->DescriptionString());
|
Printf("%Cd[[requests in group]]%E");
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < SS.request.n; i++) {
|
for(i = 0; i < SS.request.n; i++) {
|
||||||
|
@ -292,7 +306,20 @@ void TextWindow::ShowGroupInfo(void) {
|
||||||
if(r->group.v == shown->group.v) {
|
if(r->group.v == shown->group.v) {
|
||||||
char *s = r->DescriptionString();
|
char *s = r->DescriptionString();
|
||||||
Printf(" %Cl%Ll%D%f%s%E",
|
Printf(" %Cl%Ll%D%f%s%E",
|
||||||
r->h.v, (DWORD)(&TextWindow::ScreenSelectRequest), s);
|
r->h.v, (&TextWindow::ScreenSelectRequest), s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(SS.request.n == 0) Printf(" (none)");
|
||||||
|
|
||||||
|
Printf("");
|
||||||
|
Printf("[[constraints in group]]");
|
||||||
|
for(i = 0; i < SS.constraint.n; i++) {
|
||||||
|
Constraint *c = &(SS.constraint.elem[i]);
|
||||||
|
|
||||||
|
if(c->group.v == shown->group.v) {
|
||||||
|
char *s = c->DescriptionString();
|
||||||
|
Printf(" %Cl%Ll%D%f%s%E",
|
||||||
|
c->h.v, (&TextWindow::ScreenSelectConstraint), s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,4 +337,10 @@ void TextWindow::ShowRequestInfo(void) {
|
||||||
Printf("%Cd[[request for %s]]%E", s);
|
Printf("%Cd[[request for %s]]%E", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextWindow::ShowConstraintInfo(void) {
|
||||||
|
Constraint *c = SS.GetConstraint(shown->constraint);
|
||||||
|
|
||||||
|
Printf("[[constraint]]");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
8
ui.h
8
ui.h
|
@ -46,10 +46,12 @@ public:
|
||||||
static const int SCREEN_GROUP_INFO = 1;
|
static const int SCREEN_GROUP_INFO = 1;
|
||||||
static const int SCREEN_REQUEST_INFO = 2;
|
static const int SCREEN_REQUEST_INFO = 2;
|
||||||
static const int SCREEN_ENTIY_INFO = 3;
|
static const int SCREEN_ENTIY_INFO = 3;
|
||||||
|
static const int SCREEN_CONSTRAINT_INFO = 4;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int screen;
|
int screen;
|
||||||
hGroup group;
|
hGroup group;
|
||||||
hRequest request;
|
hRequest request;
|
||||||
|
hConstraint constraint;
|
||||||
} ShownState;
|
} ShownState;
|
||||||
static const int HISTORY_LEN = 16;
|
static const int HISTORY_LEN = 16;
|
||||||
ShownState showns[HISTORY_LEN];
|
ShownState showns[HISTORY_LEN];
|
||||||
|
@ -64,10 +66,13 @@ public:
|
||||||
void ShowGroupInfo(void);
|
void ShowGroupInfo(void);
|
||||||
void ShowRequestInfo(void);
|
void ShowRequestInfo(void);
|
||||||
void ShowEntityInfo(void);
|
void ShowEntityInfo(void);
|
||||||
|
void ShowConstraintInfo(void);
|
||||||
|
|
||||||
void OneScreenForward(void);
|
void OneScreenForward(void);
|
||||||
static void ScreenSelectGroup(int link, DWORD v);
|
static void ScreenSelectGroup(int link, DWORD v);
|
||||||
|
static void ScreenActivateGroup(int link, DWORD v);
|
||||||
static void ScreenSelectRequest(int link, DWORD v);
|
static void ScreenSelectRequest(int link, DWORD v);
|
||||||
|
static void ScreenSelectConstraint(int link, DWORD v);
|
||||||
static void ScreenNavigation(int link, DWORD v);
|
static void ScreenNavigation(int link, DWORD v);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -100,6 +105,9 @@ public:
|
||||||
MNU_LINE_SEGMENT,
|
MNU_LINE_SEGMENT,
|
||||||
MNU_RECTANGLE,
|
MNU_RECTANGLE,
|
||||||
MNU_CUBIC,
|
MNU_CUBIC,
|
||||||
|
// Group
|
||||||
|
MNU_GROUP_DRAWING,
|
||||||
|
MNU_GROUP_EXTRUDE,
|
||||||
// Constrain
|
// Constrain
|
||||||
MNU_DISTANCE_DIA,
|
MNU_DISTANCE_DIA,
|
||||||
MNU_EQUAL,
|
MNU_EQUAL,
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#define FREEZE_SUBKEY "SolveSpace"
|
#define FREEZE_SUBKEY "SolveSpace"
|
||||||
#include "freeze.h"
|
#include "freeze.h"
|
||||||
|
|
||||||
#define MIN_COLS 42
|
#define MIN_COLS 45
|
||||||
#define TEXT_HEIGHT 18
|
#define TEXT_HEIGHT 18
|
||||||
#define TEXT_WIDTH 9
|
#define TEXT_WIDTH 9
|
||||||
|
|
||||||
|
@ -26,8 +26,6 @@ HWND TextWnd;
|
||||||
HWND TextWndScrollBar;
|
HWND TextWndScrollBar;
|
||||||
int TextWndScrollPos;
|
int TextWndScrollPos;
|
||||||
int TextWndRows;
|
int TextWndRows;
|
||||||
COLORREF BgColor[256];
|
|
||||||
COLORREF FgColor[256];
|
|
||||||
|
|
||||||
HWND GraphicsWnd;
|
HWND GraphicsWnd;
|
||||||
HWND GraphicsEditControl;
|
HWND GraphicsEditControl;
|
||||||
|
@ -88,13 +86,24 @@ void MemFree(void *p) { free(p); }
|
||||||
|
|
||||||
static void PaintTextWnd(HDC hdc)
|
static void PaintTextWnd(HDC hdc)
|
||||||
{
|
{
|
||||||
// Generate the color table.
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
static BOOL MadeBrushes = FALSE;
|
||||||
|
static COLORREF BgColor[256];
|
||||||
|
static COLORREF FgColor[256];
|
||||||
|
static HBRUSH BgBrush[256];
|
||||||
|
static HBRUSH FillBrush;
|
||||||
|
if(!MadeBrushes) {
|
||||||
|
// Generate the color table.
|
||||||
for(i = 0; SS.TW.colors[i].c != 0; i++) {
|
for(i = 0; SS.TW.colors[i].c != 0; i++) {
|
||||||
int c = SS.TW.colors[i].c;
|
int c = SS.TW.colors[i].c;
|
||||||
if(c < 0 || c > 255) oops();
|
if(c < 0 || c > 255) oops();
|
||||||
BgColor[c] = SS.TW.colors[i].bg;
|
BgColor[c] = SS.TW.colors[i].bg;
|
||||||
FgColor[c] = SS.TW.colors[i].fg;
|
FgColor[c] = SS.TW.colors[i].fg;
|
||||||
|
BgBrush[c] = CreateSolidBrush(BgColor[c]);
|
||||||
|
}
|
||||||
|
FillBrush = CreateSolidBrush(SS.TW.COLOR_BG_DEFAULT);
|
||||||
|
MadeBrushes = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT rect;
|
RECT rect;
|
||||||
|
@ -107,8 +116,7 @@ static void PaintTextWnd(HDC hdc)
|
||||||
HBITMAP backBitmap = CreateCompatibleBitmap(hdc, width, height);
|
HBITMAP backBitmap = CreateCompatibleBitmap(hdc, width, height);
|
||||||
SelectObject(backDc, backBitmap);
|
SelectObject(backDc, backBitmap);
|
||||||
|
|
||||||
HBRUSH hbr = CreateSolidBrush(SS.TW.COLOR_BG_DEFAULT);
|
FillRect(backDc, &rect, FillBrush);
|
||||||
FillRect(backDc, &rect, hbr);
|
|
||||||
|
|
||||||
SelectObject(backDc, FixedFont);
|
SelectObject(backDc, FixedFont);
|
||||||
SetBkColor(backDc, SS.TW.COLOR_BG_DEFAULT);
|
SetBkColor(backDc, SS.TW.COLOR_BG_DEFAULT);
|
||||||
|
@ -135,7 +143,7 @@ static void PaintTextWnd(HDC hdc)
|
||||||
if(r < 0) continue;
|
if(r < 0) continue;
|
||||||
if(r >= SS.TW.MAX_ROWS) continue;
|
if(r >= SS.TW.MAX_ROWS) continue;
|
||||||
|
|
||||||
for(c = 0; c < SS.TW.MAX_COLS; c++) {
|
for(c = 0; c < min((width/TEXT_WIDTH)+1, SS.TW.MAX_COLS); c++) {
|
||||||
int color = SS.TW.meta[r][c].color;
|
int color = SS.TW.meta[r][c].color;
|
||||||
SetTextColor(backDc, FgColor[color]);
|
SetTextColor(backDc, FgColor[color]);
|
||||||
SetBkColor(backDc, BgColor[color]);
|
SetBkColor(backDc, BgColor[color]);
|
||||||
|
@ -150,12 +158,10 @@ static void PaintTextWnd(HDC hdc)
|
||||||
int y = (r-TextWndScrollPos)*TEXT_HEIGHT + 1 +
|
int y = (r-TextWndScrollPos)*TEXT_HEIGHT + 1 +
|
||||||
(r >= OFFSET_LINE ? OFFSET_HEIGHT : 0);
|
(r >= OFFSET_LINE ? OFFSET_HEIGHT : 0);
|
||||||
|
|
||||||
HBRUSH b = CreateSolidBrush(BgColor[color]);
|
|
||||||
RECT a;
|
RECT a;
|
||||||
a.left = x; a.right = x+TEXT_WIDTH;
|
a.left = x; a.right = x+TEXT_WIDTH;
|
||||||
a.top = y; a.bottom = y+TEXT_HEIGHT;
|
a.top = y; a.bottom = y+TEXT_HEIGHT;
|
||||||
FillRect(backDc, &a, b);
|
FillRect(backDc, &a, BgBrush[color]);
|
||||||
DeleteObject(b);
|
|
||||||
|
|
||||||
TextOut(backDc, x, y, (char *)&(SS.TW.text[r][c]), 1);
|
TextOut(backDc, x, y, (char *)&(SS.TW.text[r][c]), 1);
|
||||||
}
|
}
|
||||||
|
@ -164,7 +170,6 @@ static void PaintTextWnd(HDC hdc)
|
||||||
// And commit the back buffer
|
// And commit the back buffer
|
||||||
BitBlt(hdc, 0, 0, width, height, backDc, 0, 0, SRCCOPY);
|
BitBlt(hdc, 0, 0, width, height, backDc, 0, 0, SRCCOPY);
|
||||||
DeleteObject(backBitmap);
|
DeleteObject(backBitmap);
|
||||||
DeleteObject(hbr);
|
|
||||||
DeleteDC(backDc);
|
DeleteDC(backDc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user