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
parent
80dd0fc029
commit
1331457928
4
Makefile
4
Makefile
|
@ -1,7 +1,7 @@
|
|||
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
|
||||
|
||||
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
|
||||
|
||||
|
@ -27,7 +27,7 @@ LIBS = user32.lib gdi32.lib comctl32.lib advapi32.lib opengl32.lib glu32.lib
|
|||
|
||||
all: $(OBJDIR)/solvespace.exe
|
||||
@cp $(OBJDIR)/solvespace.exe .
|
||||
solvespace
|
||||
solvespace t.slvs
|
||||
|
||||
clean:
|
||||
rm -f obj/*
|
||||
|
|
215
file.cpp
215
file.cpp
|
@ -1,61 +1,149 @@
|
|||
#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) {
|
||||
fh = fopen(filename, "w");
|
||||
if(!fh) {
|
||||
Error("Couldn't write to file '%s'", fh);
|
||||
Error("Couldn't write to file '%s'", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fh, "!!SolveSpaceREVa\n\n\n");
|
||||
fprintf(fh, "ñ÷åò±²³´SolveSpaceREVa\n\n\n");
|
||||
|
||||
int i;
|
||||
for(i = 0; i < group.n; i++) {
|
||||
Group *g = &(group.elem[i]);
|
||||
fprintf(fh, "Group.h.v=%08x\n", g->h.v);
|
||||
fprintf(fh, "Group.name=%s\n", g->name.str);
|
||||
sv.g = group.elem[i];
|
||||
SaveUsingTable('g');
|
||||
fprintf(fh, "AddGroup\n\n");
|
||||
}
|
||||
|
||||
for(i = 0; i < param.n; i++) {
|
||||
Param *p = &(param.elem[i]);
|
||||
fprintf(fh, "Param.h.v=%08x\n", p->h.v);
|
||||
fprintf(fh, "Param.val=%.20f\n", p->val);
|
||||
sv.p = param.elem[i];
|
||||
SaveUsingTable('p');
|
||||
fprintf(fh, "AddParam\n\n");
|
||||
}
|
||||
|
||||
for(i = 0; i < request.n; i++) {
|
||||
Request *r = &(request.elem[i]);
|
||||
fprintf(fh, "Request.h.v=%08x\n", r->h.v);
|
||||
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);
|
||||
sv.r = request.elem[i];
|
||||
SaveUsingTable('r');
|
||||
fprintf(fh, "AddRequest\n\n");
|
||||
}
|
||||
|
||||
for(i = 0; i < entity.n; i++) {
|
||||
Entity *e = &(entity.elem[i]);
|
||||
fprintf(fh, "Entity.h.v=%08x\n", e->h.v);
|
||||
fprintf(fh, "Entity.type=%d\n", e->type);
|
||||
sv.e = entity.elem[i];
|
||||
SaveUsingTable('e');
|
||||
fprintf(fh, "AddEntity\n\n");
|
||||
}
|
||||
|
||||
for(i = 0; i < constraint.n; i++) {
|
||||
Constraint *c = &(constraint.elem[i]);
|
||||
fprintf(fh, "Constraint.h.v=%08x\n", c->h.v);
|
||||
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);
|
||||
sv.c = constraint.elem[i];
|
||||
SaveUsingTable('c');
|
||||
fprintf(fh, "AddConstraint\n\n");
|
||||
}
|
||||
|
||||
|
@ -67,10 +155,73 @@ bool SolveSpace::SaveToFile(char *filename) {
|
|||
bool SolveSpace::LoadFromFile(char *filename) {
|
||||
fh = fopen(filename, "r");
|
||||
if(!fh) {
|
||||
Error("Couldn't read from file '%s'", fh);
|
||||
Error("Couldn't read from file '%s'", filename);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
31
polygon.h
31
polygon.h
|
@ -2,20 +2,39 @@
|
|||
#ifndef __POLYGON_H
|
||||
#define __POLYGON_H
|
||||
|
||||
class SPolyhedron {
|
||||
template <class T>
|
||||
class SList {
|
||||
public:
|
||||
T *elem;
|
||||
int n;
|
||||
int elemsAllocated;
|
||||
};
|
||||
|
||||
class SPolygon {
|
||||
public:
|
||||
};
|
||||
|
||||
class SContour {
|
||||
class SEdge {
|
||||
public:
|
||||
Vector a, b;
|
||||
};
|
||||
|
||||
class SEdgeList {
|
||||
public:
|
||||
SList<SEdge> l;
|
||||
|
||||
};
|
||||
|
||||
class SContour {
|
||||
public:
|
||||
SList<Vector> l;
|
||||
};
|
||||
|
||||
class SPolygon {
|
||||
public:
|
||||
SList<SContour> l;
|
||||
};
|
||||
|
||||
class SPolyhedron {
|
||||
SList<SPolygon> l;
|
||||
public:
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
5
sketch.h
5
sketch.h
|
@ -55,6 +55,11 @@ public:
|
|||
int tag;
|
||||
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;
|
||||
bool solved;
|
||||
|
||||
|
|
|
@ -2,45 +2,12 @@
|
|||
|
||||
SolveSpace SS;
|
||||
|
||||
void SolveSpace::Init(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);
|
||||
void SolveSpace::Init(char *cmdLine) {
|
||||
if(strlen(cmdLine) == 0) {
|
||||
NewFile();
|
||||
} else {
|
||||
LoadFromFile(cmdLine);
|
||||
}
|
||||
|
||||
TW.Init();
|
||||
GW.Init();
|
||||
|
@ -69,6 +36,7 @@ void SolveSpace::GenerateAll(void) {
|
|||
|
||||
prev.Clear();
|
||||
ForceReferences();
|
||||
InvalidateGraphics();
|
||||
}
|
||||
|
||||
void SolveSpace::ForceReferences(void) {
|
||||
|
@ -186,10 +154,15 @@ void SolveSpace::Solve(void) {
|
|||
void SolveSpace::MenuFile(int id) {
|
||||
switch(id) {
|
||||
case GraphicsWindow::MNU_NEW:
|
||||
SS.NewFile();
|
||||
SS.GenerateAll();
|
||||
break;
|
||||
|
||||
case GraphicsWindow::MNU_OPEN:
|
||||
break;
|
||||
|
||||
case GraphicsWindow::MNU_SAVE:
|
||||
SS.SaveToFile("t.slv");
|
||||
SS.SaveToFile("t.slvs");
|
||||
break;
|
||||
|
||||
case GraphicsWindow::MNU_SAVE_AS:
|
||||
|
|
20
solvespace.h
20
solvespace.h
|
@ -154,13 +154,31 @@ public:
|
|||
void GenerateAll(void);
|
||||
void ForceReferences(void);
|
||||
|
||||
void Init(void);
|
||||
void Init(char *cmdLine);
|
||||
|
||||
bool SolveGroup(hGroup hg);
|
||||
bool SolveWorker(int order);
|
||||
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);
|
||||
void NewFile(void);
|
||||
bool SaveToFile(char *filename);
|
||||
bool LoadFromFile(char *filename);
|
||||
|
||||
|
|
|
@ -720,7 +720,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||
FreeAllExprs();
|
||||
|
||||
// Call in to the platform-independent code, and let them do their init
|
||||
SS.Init();
|
||||
SS.Init(lpCmdLine);
|
||||
|
||||
ShowWindow(TextWnd, SW_SHOWNOACTIVATE);
|
||||
ShowWindow(GraphicsWnd, SW_SHOW);
|
||||
|
|
Loading…
Reference in New Issue