Rough file/save for SolveSpace; that's all done from a single

table, relatively small code size. No user interface for it,
though.

[git-p4: depot-paths = "//depot/solvespace/": change = 1685]
solver
Jonathan Westhues 2008-04-23 22:22:16 -08:00
parent 80dd0fc029
commit 1331457928
7 changed files with 248 additions and 82 deletions

View File

@ -1,7 +1,7 @@
DEFINES = /D_WIN32_WINNT=0x500 /DISOLATION_AWARE_ENABLED /D_WIN32_IE=0x500 /DWIN32_LEAN_AND_MEAN /DWIN32 DEFINES = /D_WIN32_WINNT=0x500 /DISOLATION_AWARE_ENABLED /D_WIN32_IE=0x500 /DWIN32_LEAN_AND_MEAN /DWIN32
CFLAGS = /W3 /nologo -I..\common\win32 /O2 /D_DEBUG /D_CRT_SECURE_NO_WARNINGS /Zi /I. /EHs CFLAGS = /W3 /nologo -I..\common\win32 /O2 /D_DEBUG /D_CRT_SECURE_NO_WARNINGS /Zi /I. /EHs
HEADERS = ..\common\win32\freeze.h ui.h solvespace.h dsc.h sketch.h expr.h HEADERS = ..\common\win32\freeze.h ui.h solvespace.h dsc.h sketch.h expr.h polygon.h
OBJDIR = obj OBJDIR = obj
@ -27,7 +27,7 @@ LIBS = user32.lib gdi32.lib comctl32.lib advapi32.lib opengl32.lib glu32.lib
all: $(OBJDIR)/solvespace.exe all: $(OBJDIR)/solvespace.exe
@cp $(OBJDIR)/solvespace.exe . @cp $(OBJDIR)/solvespace.exe .
solvespace solvespace t.slvs
clean: clean:
rm -f obj/* rm -f obj/*

215
file.cpp
View File

@ -1,61 +1,149 @@
#include "solvespace.h" #include "solvespace.h"
void SolveSpace::NewFile(void) {
constraint.Clear();
request.Clear();
group.Clear();
entity.Clear();
param.Clear();
// Our initial group, that contains the references.
Group g;
memset(&g, 0, sizeof(g));
g.name.strcpy("#references");
g.h = Group::HGROUP_REFERENCES;
group.Add(&g);
// And an empty group, for the first stuff the user draws.
g.name.strcpy("");
group.AddAndAssignId(&g);
// Let's create three two-d coordinate systems, for the coordinate
// planes; these are our references, present in every sketch.
Request r;
memset(&r, 0, sizeof(r));
r.type = Request::CSYS_2D;
r.group = Group::HGROUP_REFERENCES;
r.csys = Entity::NO_CSYS;
r.name.strcpy("#XY-csys");
r.h = Request::HREQUEST_REFERENCE_XY;
request.Add(&r);
r.name.strcpy("#YZ-csys");
r.h = Request::HREQUEST_REFERENCE_YZ;
request.Add(&r);
r.name.strcpy("#ZX-csys");
r.h = Request::HREQUEST_REFERENCE_ZX;
request.Add(&r);
}
const SolveSpace::SaveTable SolveSpace::SAVED[] = {
{ 'g', "Group.h.v", 'x', &(SS.sv.g.h.v) },
{ 'g', "Group.type", 'd', &(SS.sv.g.type) },
{ 'g', "Group.name", 'N', &(SS.sv.g.name) },
{ 'g', "Group.solveOrder", 'd', &(SS.sv.g.solveOrder) },
{ 'g', "Group.visible", 'b', &(SS.sv.g.visible) },
{ 'p', "Param.h.v.", 'x', &(SS.sv.p.h.v) },
{ 'p', "Param.val", 'f', &(SS.sv.p.val) },
{ 'r', "Request.h.v", 'x', &(SS.sv.r.h.v) },
{ 'r', "Request.type", 'd', &(SS.sv.r.type) },
{ 'r', "Request.csys.v", 'x', &(SS.sv.r.csys.v) },
{ 'r', "Request.group.v", 'x', &(SS.sv.r.group.v) },
{ 'r', "Request.name", 'N', &(SS.sv.r.name) },
{ 'r', "Request.construction", 'b', &(SS.sv.r.construction) },
{ 'e', "Entity.h.v", 'x', &(SS.sv.e.h.v) },
{ 'e', "Entity.type", 'd', &(SS.sv.e.type) },
{ 'e', "Entity.param.h[0].v", 'x', &(SS.sv.e.param.h[0].v) },
{ 'e', "Entity.param.h[1].v", 'x', &(SS.sv.e.param.h[1].v) },
{ 'e', "Entity.param.h[2].v", 'x', &(SS.sv.e.param.h[2].v) },
{ 'e', "Entity.param.h[3].v", 'x', &(SS.sv.e.param.h[3].v) },
{ 'e', "Entity.assoc[0].v", 'x', &(SS.sv.e.assoc[0].v) },
{ 'e', "Entity.assoc[1].v", 'x', &(SS.sv.e.assoc[1].v) },
{ 'e', "Entity.assoc[2].v", 'x', &(SS.sv.e.assoc[2].v) },
{ 'e', "Entity.assoc[3].v", 'x', &(SS.sv.e.assoc[3].v) },
{ 'e', "Entity.csys.v", 'x', &(SS.sv.e.csys.v) },
{ 'c', "Constraint.h.v", 'x', &(SS.sv.c.h.v) },
{ 'c', "Constraint.type", 'd', &(SS.sv.c.type) },
{ 'c', "Constraint.group.v", 'x', &(SS.sv.c.group.v) },
{ 'c', "Constraint.exprA", 'E', &(SS.sv.c.exprA) },
{ 'c', "Constraint.exprB", 'E', &(SS.sv.c.exprB) },
{ 'c', "Constraint.ptA.v", 'x', &(SS.sv.c.ptA.v) },
{ 'c', "Constraint.ptB.v", 'x', &(SS.sv.c.ptB.v) },
{ 'c', "Constraint.ptC.v", 'x', &(SS.sv.c.ptC.v) },
{ 'c', "Constraint.entityA.v", 'x', &(SS.sv.c.entityA.v) },
{ 'c', "Constraint.entityB.v", 'x', &(SS.sv.c.entityB.v) },
{ 'c', "Constraint.disp.offset.x", 'f', &(SS.sv.c.disp.offset.x)},
{ 'c', "Constraint.disp.offset.y", 'f', &(SS.sv.c.disp.offset.y)},
{ 'c', "Constraint.disp.offset.z", 'f', &(SS.sv.c.disp.offset.z)},
{ 0, NULL, NULL, NULL },
};
void SolveSpace::SaveUsingTable(int type) {
int i;
for(i = 0; SAVED[i].type != 0; i++) {
if(SAVED[i].type != type) continue;
fprintf(fh, "%s=", SAVED[i].desc);
void *p = SAVED[i].ptr;
switch(SAVED[i].fmt) {
case 'd': fprintf(fh, "%d", *((int *)p)); break;
case 'b': fprintf(fh, "%d", *((bool *)p) ? 1 : 0); break;
case 'x': fprintf(fh, "%08x", *((DWORD *)p)); break;
case 'f': fprintf(fh, "%.20f", *((double *)p)); break;
case 'N': fprintf(fh, "%s", ((NameStr *)p)->str); break;
case 'E': fprintf(fh, "%s", (*((Expr **)p))->Print()); break;
default: oops();
}
fprintf(fh, "\n");
}
}
bool SolveSpace::SaveToFile(char *filename) { bool SolveSpace::SaveToFile(char *filename) {
fh = fopen(filename, "w"); fh = fopen(filename, "w");
if(!fh) { if(!fh) {
Error("Couldn't write to file '%s'", fh); Error("Couldn't write to file '%s'", filename);
return false; return false;
} }
fprintf(fh, "!!SolveSpaceREVa\n\n\n"); fprintf(fh, "ñ÷åò±²³´SolveSpaceREVa\n\n\n");
int i; int i;
for(i = 0; i < group.n; i++) { for(i = 0; i < group.n; i++) {
Group *g = &(group.elem[i]); sv.g = group.elem[i];
fprintf(fh, "Group.h.v=%08x\n", g->h.v); SaveUsingTable('g');
fprintf(fh, "Group.name=%s\n", g->name.str);
fprintf(fh, "AddGroup\n\n"); fprintf(fh, "AddGroup\n\n");
} }
for(i = 0; i < param.n; i++) { for(i = 0; i < param.n; i++) {
Param *p = &(param.elem[i]); sv.p = param.elem[i];
fprintf(fh, "Param.h.v=%08x\n", p->h.v); SaveUsingTable('p');
fprintf(fh, "Param.val=%.20f\n", p->val);
fprintf(fh, "AddParam\n\n"); fprintf(fh, "AddParam\n\n");
} }
for(i = 0; i < request.n; i++) { for(i = 0; i < request.n; i++) {
Request *r = &(request.elem[i]); sv.r = request.elem[i];
fprintf(fh, "Request.h.v=%08x\n", r->h.v); SaveUsingTable('r');
fprintf(fh, "Request.type=%d\n", r->type);
fprintf(fh, "Request.csys.v=%08x\n", r->csys.v);
fprintf(fh, "Request.group.v=%08x\n", r->group.v);
fprintf(fh, "Request.name=%s\n", r->name.str);
fprintf(fh, "AddRequest\n\n"); fprintf(fh, "AddRequest\n\n");
} }
for(i = 0; i < entity.n; i++) { for(i = 0; i < entity.n; i++) {
Entity *e = &(entity.elem[i]); sv.e = entity.elem[i];
fprintf(fh, "Entity.h.v=%08x\n", e->h.v); SaveUsingTable('e');
fprintf(fh, "Entity.type=%d\n", e->type);
fprintf(fh, "AddEntity\n\n"); fprintf(fh, "AddEntity\n\n");
} }
for(i = 0; i < constraint.n; i++) { for(i = 0; i < constraint.n; i++) {
Constraint *c = &(constraint.elem[i]); sv.c = constraint.elem[i];
fprintf(fh, "Constraint.h.v=%08x\n", c->h.v); SaveUsingTable('c');
fprintf(fh, "Constraint.type=%d\n", c->type);
fprintf(fh, "Constraint.group.v=%08x\n", c->group);
fprintf(fh, "Constraint.exprA=%s\n", c->exprA->Print());
fprintf(fh, "Constraint.exprB=%s\n", c->exprB->Print());
fprintf(fh, "Constraint.ptA.v=%08x\n", c->ptA.v);
fprintf(fh, "Constraint.ptB.v=%08x\n", c->ptB.v);
fprintf(fh, "Constraint.ptC.v=%08x\n", c->ptC.v);
fprintf(fh, "Constraint.entityA.v=%08x\n", c->entityA.v);
fprintf(fh, "Constraint.entityB.v=%08x\n", c->entityB.v);
fprintf(fh, "Constraint.disp.offset.x=%.20f\n", c->disp.offset.x);
fprintf(fh, "Constraint.disp.offset.y=%.20f\n", c->disp.offset.y);
fprintf(fh, "Constraint.disp.offset.z=%.20f\n", c->disp.offset.z);
fprintf(fh, "AddConstraint\n\n"); fprintf(fh, "AddConstraint\n\n");
} }
@ -67,10 +155,73 @@ bool SolveSpace::SaveToFile(char *filename) {
bool SolveSpace::LoadFromFile(char *filename) { bool SolveSpace::LoadFromFile(char *filename) {
fh = fopen(filename, "r"); fh = fopen(filename, "r");
if(!fh) { if(!fh) {
Error("Couldn't read from file '%s'", fh); Error("Couldn't read from file '%s'", filename);
return false; return false;
} }
constraint.Clear();
request.Clear();
group.Clear();
entity.Clear();
param.Clear();
char line[1024];
while(fgets(line, sizeof(line), fh)) {
char *s = strchr(line, '\n');
if(s) *s = '\0';
if(*line == '\0') continue;
char *e = strchr(line, '=');
if(e) {
*e = '\0';
char *key = line, *val = e+1;
int i;
for(i = 0; SAVED[i].type != 0; i++) {
if(strcmp(SAVED[i].desc, key)==0) {
void *p = SAVED[i].ptr;
switch(SAVED[i].fmt) {
case 'd': *((int *)p) = atoi(val); break;
case 'b': *((bool *)p) = (atoi(val) != 0); break;
case 'x': sscanf(val, "%x", (DWORD *)p); break;
case 'f': *((double *)p) = atof(val); break;
case 'N': ((NameStr *)p)->strcpy(val); break;
case 'E':
Expr *e;
e = Expr::FromString(val);
if(!e) e = Expr::FromConstant(0);
*((Expr **)p) = e->DeepCopyKeep();
break;
default: oops();
}
break;
}
}
if(SAVED[i].type == 0) oops();
} else if(strcmp(line, "AddGroup")==0) {
SS.group.Add(&(sv.g));
} else if(strcmp(line, "AddParam")==0) {
// params are regenerated, but we want to preload the values
// for initial guesses
SS.param.Add(&(sv.p));
} else if(strcmp(line, "AddEntity")==0) {
// entities are regenerated
} else if(strcmp(line, "AddRequest")==0) {
SS.request.Add(&(sv.r));
} else if(strcmp(line, "AddConstraint")==0) {
SS.constraint.Add(&(sv.c));
} else if(strcmp(line, "ñ÷åò±²³´SolveSpaceREVa")==0) {
// do nothing, version string
} else {
oops();
}
}
fclose(fh);
return true; return true;
} }

View File

@ -2,20 +2,39 @@
#ifndef __POLYGON_H #ifndef __POLYGON_H
#define __POLYGON_H #define __POLYGON_H
class SPolyhedron { template <class T>
class SList {
public: public:
T *elem;
int n;
int elemsAllocated;
}; };
class SPolygon { class SEdge {
public:
};
class SContour {
public: public:
Vector a, b;
}; };
class SEdgeList { class SEdgeList {
public:
SList<SEdge> l;
};
class SContour {
public:
SList<Vector> l;
};
class SPolygon {
public:
SList<SContour> l;
};
class SPolyhedron {
SList<SPolygon> l;
public: public:
}; };
#endif #endif

View File

@ -55,6 +55,11 @@ public:
int tag; int tag;
hGroup h; hGroup h;
static const int DRAWING_GROUP = 5000;
static const int STEP_AND_REPEAT_TRANSLATING = 5010;
static const int STEP_AND_REPEAT_ROTATING = 5020;
int type;
int solveOrder; int solveOrder;
bool solved; bool solved;

View File

@ -2,45 +2,12 @@
SolveSpace SS; SolveSpace SS;
void SolveSpace::Init(void) { void SolveSpace::Init(char *cmdLine) {
constraint.Clear(); if(strlen(cmdLine) == 0) {
request.Clear(); NewFile();
group.Clear(); } else {
LoadFromFile(cmdLine);
entity.Clear(); }
param.Clear();
// Our initial group, that contains the references.
Group g;
memset(&g, 0, sizeof(g));
g.name.strcpy("#references");
g.h = Group::HGROUP_REFERENCES;
group.Add(&g);
// And an empty group, for the first stuff the user draws.
g.name.strcpy("");
group.AddAndAssignId(&g);
// Let's create three two-d coordinate systems, for the coordinate
// planes; these are our references, present in every sketch.
Request r;
memset(&r, 0, sizeof(r));
r.type = Request::CSYS_2D;
r.group = Group::HGROUP_REFERENCES;
r.csys = Entity::NO_CSYS;
r.name.strcpy("#XY-csys");
r.h = Request::HREQUEST_REFERENCE_XY;
request.Add(&r);
r.name.strcpy("#YZ-csys");
r.h = Request::HREQUEST_REFERENCE_YZ;
request.Add(&r);
r.name.strcpy("#ZX-csys");
r.h = Request::HREQUEST_REFERENCE_ZX;
request.Add(&r);
TW.Init(); TW.Init();
GW.Init(); GW.Init();
@ -69,6 +36,7 @@ void SolveSpace::GenerateAll(void) {
prev.Clear(); prev.Clear();
ForceReferences(); ForceReferences();
InvalidateGraphics();
} }
void SolveSpace::ForceReferences(void) { void SolveSpace::ForceReferences(void) {
@ -186,10 +154,15 @@ void SolveSpace::Solve(void) {
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.GenerateAll();
break;
case GraphicsWindow::MNU_OPEN: case GraphicsWindow::MNU_OPEN:
break;
case GraphicsWindow::MNU_SAVE: case GraphicsWindow::MNU_SAVE:
SS.SaveToFile("t.slv"); SS.SaveToFile("t.slvs");
break; break;
case GraphicsWindow::MNU_SAVE_AS: case GraphicsWindow::MNU_SAVE_AS:

View File

@ -154,13 +154,31 @@ public:
void GenerateAll(void); void GenerateAll(void);
void ForceReferences(void); void ForceReferences(void);
void Init(void); void Init(char *cmdLine);
bool SolveGroup(hGroup hg); bool SolveGroup(hGroup hg);
bool SolveWorker(int order); bool SolveWorker(int order);
void Solve(void); void Solve(void);
char saveFile[MAX_PATH];
bool unsaved;
typedef struct {
char type;
char *desc;
char fmt;
void *ptr;
} SaveTable;
static const SaveTable SAVED[];
void SaveUsingTable(int type);
struct {
Group g;
Request r;
Entity e;
Param p;
Constraint c;
} sv;
static void MenuFile(int id); static void MenuFile(int id);
void NewFile(void);
bool SaveToFile(char *filename); bool SaveToFile(char *filename);
bool LoadFromFile(char *filename); bool LoadFromFile(char *filename);

View File

@ -720,7 +720,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
FreeAllExprs(); FreeAllExprs();
// Call in to the platform-independent code, and let them do their init // Call in to the platform-independent code, and let them do their init
SS.Init(); SS.Init(lpCmdLine);
ShowWindow(TextWnd, SW_SHOWNOACTIVATE); ShowWindow(TextWnd, SW_SHOWNOACTIVATE);
ShowWindow(GraphicsWnd, SW_SHOW); ShowWindow(GraphicsWnd, SW_SHOW);