2008-04-18 11:11:48 +00:00
|
|
|
|
#include "solvespace.h"
|
|
|
|
|
|
2008-04-24 06:22:16 +00:00
|
|
|
|
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));
|
2008-04-30 04:52:34 +00:00
|
|
|
|
g.visible = true;
|
2008-04-24 06:22:16 +00:00
|
|
|
|
g.name.strcpy("#references");
|
2008-04-27 09:03:01 +00:00
|
|
|
|
g.type = Group::DRAWING;
|
2008-04-24 06:22:16 +00:00
|
|
|
|
g.h = Group::HGROUP_REFERENCES;
|
|
|
|
|
group.Add(&g);
|
|
|
|
|
|
|
|
|
|
// And an empty group, for the first stuff the user draws.
|
2008-04-27 09:03:01 +00:00
|
|
|
|
g.name.strcpy("drawing");
|
2008-04-24 06:22:16 +00:00
|
|
|
|
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));
|
2008-04-27 03:26:27 +00:00
|
|
|
|
r.type = Request::WORKPLANE;
|
2008-04-24 06:22:16 +00:00
|
|
|
|
r.group = Group::HGROUP_REFERENCES;
|
2008-04-27 03:26:27 +00:00
|
|
|
|
r.workplane = Entity::FREE_IN_3D;
|
2008-04-24 06:22:16 +00:00
|
|
|
|
|
2008-04-27 03:26:27 +00:00
|
|
|
|
r.name.strcpy("#XY");
|
2008-04-24 06:22:16 +00:00
|
|
|
|
r.h = Request::HREQUEST_REFERENCE_XY;
|
|
|
|
|
request.Add(&r);
|
|
|
|
|
|
2008-04-27 03:26:27 +00:00
|
|
|
|
r.name.strcpy("#YZ");
|
2008-04-24 06:22:16 +00:00
|
|
|
|
r.h = Request::HREQUEST_REFERENCE_YZ;
|
|
|
|
|
request.Add(&r);
|
|
|
|
|
|
2008-04-27 03:26:27 +00:00
|
|
|
|
r.name.strcpy("#ZX");
|
2008-04-24 06:22:16 +00:00
|
|
|
|
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) },
|
2008-04-27 10:01:23 +00:00
|
|
|
|
{ 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) },
|
|
|
|
|
{ 'g', "Group.opB.v", 'x', &(SS.sv.g.opB.v) },
|
2008-04-24 06:22:16 +00:00
|
|
|
|
{ 'g', "Group.solveOrder", 'd', &(SS.sv.g.solveOrder) },
|
|
|
|
|
{ 'g', "Group.visible", 'b', &(SS.sv.g.visible) },
|
2008-04-27 10:01:23 +00:00
|
|
|
|
{ 'g', "Group.remap", 'M', &(SS.sv.g.remap) },
|
2008-04-24 06:22:16 +00:00
|
|
|
|
|
|
|
|
|
{ '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) },
|
2008-04-27 03:26:27 +00:00
|
|
|
|
{ 'r', "Request.workplane.v", 'x', &(SS.sv.r.workplane.v) },
|
2008-04-24 06:22:16 +00:00
|
|
|
|
{ '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) },
|
2008-04-27 10:01:23 +00:00
|
|
|
|
{ 'e', "Entity.group.v", 'x', &(SS.sv.e.group.v) },
|
2008-05-07 04:17:29 +00:00
|
|
|
|
{ 'e', "Entity.construction", 'b', &(SS.sv.e.construction) },
|
2008-04-27 03:26:27 +00:00
|
|
|
|
{ 'e', "Entity.param[0].v", 'x', &(SS.sv.e.param[0].v) },
|
|
|
|
|
{ 'e', "Entity.param[1].v", 'x', &(SS.sv.e.param[1].v) },
|
|
|
|
|
{ 'e', "Entity.param[2].v", 'x', &(SS.sv.e.param[2].v) },
|
|
|
|
|
{ 'e', "Entity.param[3].v", 'x', &(SS.sv.e.param[3].v) },
|
|
|
|
|
{ 'e', "Entity.point[0].v", 'x', &(SS.sv.e.point[0].v) },
|
|
|
|
|
{ 'e', "Entity.point[1].v", 'x', &(SS.sv.e.point[1].v) },
|
|
|
|
|
{ 'e', "Entity.point[2].v", 'x', &(SS.sv.e.point[2].v) },
|
|
|
|
|
{ 'e', "Entity.point[3].v", 'x', &(SS.sv.e.point[3].v) },
|
2008-05-05 06:18:01 +00:00
|
|
|
|
{ 'e', "Entity.normal.v", 'x', &(SS.sv.e.normal.v) },
|
2008-04-27 03:26:27 +00:00
|
|
|
|
{ 'e', "Entity.workplane.v", 'x', &(SS.sv.e.workplane.v) },
|
2008-05-05 06:18:01 +00:00
|
|
|
|
{ 'e', "Entity.numPoint.x", 'f', &(SS.sv.e.numPoint.x) },
|
|
|
|
|
{ 'e', "Entity.numPoint.y", 'f', &(SS.sv.e.numPoint.y) },
|
|
|
|
|
{ 'e', "Entity.numPoint.z", 'f', &(SS.sv.e.numPoint.z) },
|
|
|
|
|
{ 'e', "Entity.numNormal.w", 'f', &(SS.sv.e.numNormal.w) },
|
|
|
|
|
{ 'e', "Entity.numNormal.vx", 'f', &(SS.sv.e.numNormal.vx) },
|
|
|
|
|
{ 'e', "Entity.numNormal.vy", 'f', &(SS.sv.e.numNormal.vy) },
|
|
|
|
|
{ 'e', "Entity.numNormal.vz", 'f', &(SS.sv.e.numNormal.vz) },
|
2008-04-24 06:22:16 +00:00
|
|
|
|
|
|
|
|
|
{ '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) },
|
2008-04-27 05:00:12 +00:00
|
|
|
|
{ 'c', "Constraint.workplane.v", 'x', &(SS.sv.c.workplane.v) },
|
2008-04-24 06:22:16 +00:00
|
|
|
|
{ '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;
|
2008-04-27 10:01:23 +00:00
|
|
|
|
|
|
|
|
|
case 'M': {
|
|
|
|
|
int j;
|
|
|
|
|
fprintf(fh, "{\n");
|
|
|
|
|
IdList<EntityMap,EntityId> *m = (IdList<EntityMap,EntityId> *)p;
|
|
|
|
|
for(j = 0; j < m->n; j++) {
|
|
|
|
|
EntityMap *em = &(m->elem[j]);
|
|
|
|
|
fprintf(fh, " %d %08x %d\n",
|
|
|
|
|
em->h.v, em->input.v, em->copyNumber);
|
|
|
|
|
}
|
|
|
|
|
fprintf(fh, "}");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2008-04-24 06:22:16 +00:00
|
|
|
|
default: oops();
|
|
|
|
|
}
|
|
|
|
|
fprintf(fh, "\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-04-18 11:11:48 +00:00
|
|
|
|
bool SolveSpace::SaveToFile(char *filename) {
|
|
|
|
|
fh = fopen(filename, "w");
|
|
|
|
|
if(!fh) {
|
2008-04-24 06:22:16 +00:00
|
|
|
|
Error("Couldn't write to file '%s'", filename);
|
2008-04-18 11:11:48 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2008-04-24 06:22:16 +00:00
|
|
|
|
fprintf(fh, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>SolveSpaceREVa\n\n\n");
|
2008-04-18 11:11:48 +00:00
|
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
for(i = 0; i < group.n; i++) {
|
2008-04-24 06:22:16 +00:00
|
|
|
|
sv.g = group.elem[i];
|
|
|
|
|
SaveUsingTable('g');
|
2008-04-18 11:11:48 +00:00
|
|
|
|
fprintf(fh, "AddGroup\n\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < param.n; i++) {
|
2008-04-24 06:22:16 +00:00
|
|
|
|
sv.p = param.elem[i];
|
|
|
|
|
SaveUsingTable('p');
|
2008-04-18 11:11:48 +00:00
|
|
|
|
fprintf(fh, "AddParam\n\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < request.n; i++) {
|
2008-04-24 06:22:16 +00:00
|
|
|
|
sv.r = request.elem[i];
|
|
|
|
|
SaveUsingTable('r');
|
2008-04-18 11:11:48 +00:00
|
|
|
|
fprintf(fh, "AddRequest\n\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < entity.n; i++) {
|
2008-04-24 06:22:16 +00:00
|
|
|
|
sv.e = entity.elem[i];
|
|
|
|
|
SaveUsingTable('e');
|
2008-04-18 11:11:48 +00:00
|
|
|
|
fprintf(fh, "AddEntity\n\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < constraint.n; i++) {
|
2008-04-24 06:22:16 +00:00
|
|
|
|
sv.c = constraint.elem[i];
|
|
|
|
|
SaveUsingTable('c');
|
2008-04-18 11:11:48 +00:00
|
|
|
|
fprintf(fh, "AddConstraint\n\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fclose(fh);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2008-04-27 10:01:23 +00:00
|
|
|
|
void SolveSpace::LoadUsingTable(char *key, char *val) {
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
case 'M': {
|
|
|
|
|
IdList<EntityMap,EntityId> *m =
|
|
|
|
|
(IdList<EntityMap,EntityId> *)p;
|
|
|
|
|
m->Clear();
|
|
|
|
|
for(;;) {
|
|
|
|
|
EntityMap em;
|
|
|
|
|
char line2[1024];
|
|
|
|
|
fgets(line2, sizeof(line2), fh);
|
|
|
|
|
if(sscanf(line2, "%d %x %d", &(em.h.v), &(em.input.v),
|
|
|
|
|
&(em.copyNumber)) == 3)
|
|
|
|
|
{
|
|
|
|
|
m->Add(&em);
|
|
|
|
|
} else {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default: oops();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(SAVED[i].type == 0) oops();
|
|
|
|
|
}
|
|
|
|
|
|
2008-04-18 11:11:48 +00:00
|
|
|
|
bool SolveSpace::LoadFromFile(char *filename) {
|
|
|
|
|
fh = fopen(filename, "r");
|
|
|
|
|
if(!fh) {
|
2008-04-24 06:22:16 +00:00
|
|
|
|
Error("Couldn't read from file '%s'", filename);
|
2008-04-18 11:11:48 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2008-04-24 06:22:16 +00:00
|
|
|
|
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;
|
2008-04-27 10:01:23 +00:00
|
|
|
|
LoadUsingTable(key, val);
|
2008-04-24 06:22:16 +00:00
|
|
|
|
} 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, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>SolveSpaceREVa")==0) {
|
|
|
|
|
// do nothing, version string
|
|
|
|
|
} else {
|
|
|
|
|
oops();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fclose(fh);
|
|
|
|
|
|
2008-04-18 11:11:48 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|