Initial work on the assembly (`import') feature. I can import a
part, including all of its entities and the triangle mesh. These are transformed by a rotation and translation, and appear in the sketch; the transformation may be set with constraints. [git-p4: depot-paths = "//depot/solvespace/": change = 1756]solver
parent
d5a8c431da
commit
4bd44bf18a
16
entity.cpp
16
entity.cpp
|
@ -240,8 +240,15 @@ void Entity::NormalForceTo(Quaternion q) {
|
|||
// There's absolutely nothing to do; these are locked.
|
||||
break;
|
||||
|
||||
case NORMAL_N_ROT:
|
||||
case NORMAL_N_ROT: {
|
||||
Quaternion qp = q.Times(numNormal.Inverse());
|
||||
|
||||
SS.GetParam(param[0])->val = qp.w;
|
||||
SS.GetParam(param[1])->val = qp.vx;
|
||||
SS.GetParam(param[2])->val = qp.vy;
|
||||
SS.GetParam(param[3])->val = qp.vz;
|
||||
break;
|
||||
}
|
||||
|
||||
default: oops();
|
||||
}
|
||||
|
@ -852,4 +859,11 @@ void Entity::GenerateEquations(IdList<Equation,hEquation> *l) {
|
|||
}
|
||||
}
|
||||
|
||||
void Entity::CalculateNumerical(void) {
|
||||
if(IsPoint()) actPoint = PointGetNum();
|
||||
if(IsNormal()) actNormal = NormalGetNum();
|
||||
if(type == DISTANCE || type == DISTANCE_N_COPY) {
|
||||
actDistance = DistanceGetNum();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
111
file.cpp
111
file.cpp
|
@ -1,5 +1,7 @@
|
|||
#include "solvespace.h"
|
||||
|
||||
#define VERSION_STRING "±²³SolveSpaceREVa"
|
||||
|
||||
void SolveSpace::NewFile(void) {
|
||||
constraint.Clear();
|
||||
request.Clear();
|
||||
|
@ -54,7 +56,6 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
|
|||
{ 'g', "Group.name", 'N', &(SS.sv.g.name) },
|
||||
{ 'g', "Group.activeWorkplane.v", 'x', &(SS.sv.g.activeWorkplane.v) },
|
||||
{ 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) },
|
||||
{ 'g', "Group.opB.v", 'x', &(SS.sv.g.opB.v) },
|
||||
{ 'g', "Group.exprA", 'E', &(SS.sv.g.exprA) },
|
||||
{ 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) },
|
||||
{ 'g', "Group.meshCombine", 'd', &(SS.sv.g.meshCombine) },
|
||||
|
@ -70,6 +71,7 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
|
|||
{ 'g', "Group.wrkpl.negateV", 'b', &(SS.sv.g.wrkpl.negateV) },
|
||||
{ 'g', "Group.visible", 'b', &(SS.sv.g.visible) },
|
||||
{ 'g', "Group.remap", 'M', &(SS.sv.g.remap) },
|
||||
{ 'g', "Group.impFile", 'P', &(SS.sv.g.impFile) },
|
||||
|
||||
{ 'p', "Param.h.v.", 'x', &(SS.sv.p.h.v) },
|
||||
{ 'p', "Param.val", 'f', &(SS.sv.p.val) },
|
||||
|
@ -107,6 +109,15 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
|
|||
{ 'e', "Entity.numNormal.vy", 'f', &(SS.sv.e.numNormal.vy) },
|
||||
{ 'e', "Entity.numNormal.vz", 'f', &(SS.sv.e.numNormal.vz) },
|
||||
{ 'e', "Entity.numDistance", 'f', &(SS.sv.e.numDistance) },
|
||||
{ 'e', "Entity.actPoint.x", 'f', &(SS.sv.e.actPoint.x) },
|
||||
{ 'e', "Entity.actPoint.y", 'f', &(SS.sv.e.actPoint.y) },
|
||||
{ 'e', "Entity.actPoint.z", 'f', &(SS.sv.e.actPoint.z) },
|
||||
{ 'e', "Entity.actNormal.w", 'f', &(SS.sv.e.actNormal.w) },
|
||||
{ 'e', "Entity.actNormal.vx", 'f', &(SS.sv.e.actNormal.vx) },
|
||||
{ 'e', "Entity.actNormal.vy", 'f', &(SS.sv.e.actNormal.vy) },
|
||||
{ 'e', "Entity.actNormal.vz", 'f', &(SS.sv.e.actNormal.vz) },
|
||||
{ 'e', "Entity.actDistance", 'f', &(SS.sv.e.actDistance) },
|
||||
|
||||
|
||||
{ 'c', "Constraint.h.v", 'x', &(SS.sv.c.h.v) },
|
||||
{ 'c', "Constraint.type", 'd', &(SS.sv.c.type) },
|
||||
|
@ -131,14 +142,22 @@ 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);
|
||||
|
||||
int fmt = SAVED[i].fmt;
|
||||
void *p = SAVED[i].ptr;
|
||||
switch(SAVED[i].fmt) {
|
||||
// Any items that aren't specified are assumed to be zero
|
||||
if(fmt == 'd' && *((int *)p) == 0) continue;
|
||||
if(fmt == 'x' && *((DWORD *)p) == 0) continue;
|
||||
if(fmt == 'f' && *((double *)p) == 0.0) continue;
|
||||
|
||||
fprintf(fh, "%s=", SAVED[i].desc);
|
||||
switch(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 'P': fprintf(fh, "%s", (char *)p); break;
|
||||
case 'E': fprintf(fh, "%s", (*((Expr **)p))->Print()); break;
|
||||
|
||||
case 'M': {
|
||||
|
@ -167,7 +186,7 @@ bool SolveSpace::SaveToFile(char *filename) {
|
|||
return false;
|
||||
}
|
||||
|
||||
fprintf(fh, "ñ÷åò±²³´SolveSpaceREVa\n\n\n");
|
||||
fprintf(fh, "%s\n\n\n", VERSION_STRING);
|
||||
|
||||
int i;
|
||||
for(i = 0; i < group.n; i++) {
|
||||
|
@ -189,6 +208,7 @@ bool SolveSpace::SaveToFile(char *filename) {
|
|||
}
|
||||
|
||||
for(i = 0; i < entity.n; i++) {
|
||||
(entity.elem[i]).CalculateNumerical();
|
||||
sv.e = entity.elem[i];
|
||||
SaveUsingTable('e');
|
||||
fprintf(fh, "AddEntity\n\n");
|
||||
|
@ -200,6 +220,14 @@ bool SolveSpace::SaveToFile(char *filename) {
|
|||
fprintf(fh, "AddConstraint\n\n");
|
||||
}
|
||||
|
||||
SMesh *m = &(group.elem[group.n-1].mesh);
|
||||
for(i = 0; i < m->l.n; i++) {
|
||||
STriangle *tr = &(m->l.elem[i]);
|
||||
fprintf(fh, "Triangle "
|
||||
"%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n",
|
||||
CO(tr->a), CO(tr->b), CO(tr->c));
|
||||
}
|
||||
|
||||
fclose(fh);
|
||||
|
||||
return true;
|
||||
|
@ -223,6 +251,10 @@ void SolveSpace::LoadUsingTable(char *key, char *val) {
|
|||
*((Expr **)p) = e->DeepCopyKeep();
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
if(strlen(val)+1 < MAX_PATH) strcpy((char *)p, val);
|
||||
break;
|
||||
|
||||
case 'M': {
|
||||
IdList<EntityMap,EntityId> *m =
|
||||
(IdList<EntityMap,EntityId> *)p;
|
||||
|
@ -264,9 +296,9 @@ bool SolveSpace::LoadFromFile(char *filename) {
|
|||
constraint.Clear();
|
||||
request.Clear();
|
||||
group.Clear();
|
||||
|
||||
entity.Clear();
|
||||
param.Clear();
|
||||
memset(&sv, 0, sizeof(sv));
|
||||
|
||||
char line[1024];
|
||||
while(fgets(line, sizeof(line), fh)) {
|
||||
|
@ -296,8 +328,10 @@ bool SolveSpace::LoadFromFile(char *filename) {
|
|||
} else if(strcmp(line, "AddConstraint")==0) {
|
||||
SS.constraint.Add(&(sv.c));
|
||||
memset(&(sv.c), 0, sizeof(sv.c));
|
||||
} else if(strcmp(line, "ñ÷åò±²³´SolveSpaceREVa")==0) {
|
||||
} else if(strcmp(line, VERSION_STRING)==0) {
|
||||
// do nothing, version string
|
||||
} else if(memcmp(line, "Triangle", 8)==0) {
|
||||
// likewise ignore the triangles; we generate those
|
||||
} else {
|
||||
oops();
|
||||
}
|
||||
|
@ -308,3 +342,68 @@ bool SolveSpace::LoadFromFile(char *filename) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SolveSpace::LoadEntitiesFromFile(char *file, EntityList *le, SMesh *m) {
|
||||
fh = fopen(file, "r");
|
||||
if(!fh) return false;
|
||||
|
||||
le->Clear();
|
||||
memset(&sv, 0, sizeof(sv));
|
||||
|
||||
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;
|
||||
LoadUsingTable(key, val);
|
||||
} else if(strcmp(line, "AddGroup")==0) {
|
||||
|
||||
} else if(strcmp(line, "AddParam")==0) {
|
||||
|
||||
} else if(strcmp(line, "AddEntity")==0) {
|
||||
le->Add(&(sv.e));
|
||||
memset(&(sv.e), 0, sizeof(sv.e));
|
||||
} else if(strcmp(line, "AddRequest")==0) {
|
||||
|
||||
} else if(strcmp(line, "AddConstraint")==0) {
|
||||
|
||||
} else if(strcmp(line, VERSION_STRING)==0) {
|
||||
|
||||
} else if(memcmp(line, "Triangle", 8)==0) {
|
||||
STriangle tr; ZERO(&tr);
|
||||
if(sscanf(line, "Triangle %lf %lf %lf %lf %lf %lf %lf %lf %lf",
|
||||
&(tr.a.x), &(tr.a.y), &(tr.a.z),
|
||||
&(tr.b.x), &(tr.b.y), &(tr.b.z),
|
||||
&(tr.c.x), &(tr.c.y), &(tr.c.z)) != 9)
|
||||
{
|
||||
oops();
|
||||
}
|
||||
m->AddTriangle(&tr);
|
||||
} else {
|
||||
oops();
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fh);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SolveSpace::ReloadAllImported(void) {
|
||||
int i;
|
||||
for(i = 0; i < group.n; i++) {
|
||||
Group *g = &(group.elem[i]);
|
||||
if(g->type != Group::IMPORTED) continue;
|
||||
|
||||
g->impEntity.Clear();
|
||||
g->impMesh.Clear();
|
||||
if(!LoadEntitiesFromFile(g->impFile, &(g->impEntity), &(g->impMesh))) {
|
||||
oops();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
84
sketch.cpp
84
sketch.cpp
|
@ -24,6 +24,11 @@ void Group::MenuGroup(int id) {
|
|||
memset(&g, 0, sizeof(g));
|
||||
g.visible = true;
|
||||
|
||||
if(id >= RECENT_IMPORT && id < (RECENT_IMPORT + MAX_RECENT)) {
|
||||
strcpy(g.impFile, RecentFile[id-RECENT_IMPORT]);
|
||||
id = GraphicsWindow::MNU_GROUP_IMPORT;
|
||||
}
|
||||
|
||||
SS.GW.GroupSelection();
|
||||
#define gs (SS.GW.gs)
|
||||
|
||||
|
@ -95,10 +100,23 @@ void Group::MenuGroup(int id) {
|
|||
g.name.strcpy("translate");
|
||||
break;
|
||||
|
||||
case GraphicsWindow::MNU_GROUP_IMPORT: {
|
||||
g.type = IMPORTED;
|
||||
g.opA = SS.GW.activeGroup;
|
||||
if(strlen(g.impFile) == 0) {
|
||||
if(!GetOpenFile(g.impFile, SLVS_EXT, SLVS_PATTERN)) return;
|
||||
}
|
||||
g.name.strcpy("import");
|
||||
break;
|
||||
}
|
||||
|
||||
default: oops();
|
||||
}
|
||||
|
||||
SS.group.AddAndAssignId(&g);
|
||||
if(g.type == IMPORTED) {
|
||||
SS.ReloadAllImported();
|
||||
}
|
||||
SS.GenerateAll(SS.GW.solving == GraphicsWindow::SOLVE_ALWAYS);
|
||||
SS.GW.activeGroup = g.h;
|
||||
if(g.type == DRAWING_WORKPLANE) {
|
||||
|
@ -191,14 +209,15 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||
Entity *e = &(entity->elem[i]);
|
||||
if(e->group.v != opA.v) continue;
|
||||
|
||||
e->CalculateNumerical();
|
||||
hEntity he = e->h; e = NULL;
|
||||
// As soon as I call CopyEntity, e may become invalid! That
|
||||
// adds entities, which may cause a realloc.
|
||||
CopyEntity(he, ai,
|
||||
CopyEntity(SS.GetEntity(he), ai,
|
||||
h.param(0), h.param(1), h.param(2),
|
||||
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
||||
true);
|
||||
CopyEntity(he, af,
|
||||
CopyEntity(SS.GetEntity(he), af,
|
||||
h.param(0), h.param(1), h.param(2),
|
||||
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
||||
true);
|
||||
|
@ -218,7 +237,8 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||
Entity *e = &(entity->elem[i]);
|
||||
if(e->group.v != opA.v) continue;
|
||||
|
||||
CopyEntity(e->h, a*2 - (subtype == ONE_SIDED ? 0 : (n-1)),
|
||||
e->CalculateNumerical();
|
||||
CopyEntity(e, a*2 - (subtype == ONE_SIDED ? 0 : (n-1)),
|
||||
h.param(0), h.param(1), h.param(2),
|
||||
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
||||
true);
|
||||
|
@ -241,7 +261,29 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||
Entity *e = &(entity->elem[i]);
|
||||
if(e->group.v != opA.v) continue;
|
||||
|
||||
CopyEntity(e->h, 0,
|
||||
e->CalculateNumerical();
|
||||
CopyEntity(e, 0,
|
||||
h.param(0), h.param(1), h.param(2),
|
||||
h.param(3), h.param(4), h.param(5), h.param(6),
|
||||
false);
|
||||
}
|
||||
break;
|
||||
|
||||
case IMPORTED:
|
||||
// The translation vector
|
||||
AddParam(param, h.param(0), gp.x);
|
||||
AddParam(param, h.param(1), gp.y);
|
||||
AddParam(param, h.param(2), gp.z);
|
||||
// The rotation quaternion
|
||||
AddParam(param, h.param(3), 1);
|
||||
AddParam(param, h.param(4), 0);
|
||||
AddParam(param, h.param(5), 0);
|
||||
AddParam(param, h.param(6), 0);
|
||||
|
||||
for(i = 0; i < impEntity.n; i++) {
|
||||
Entity *ie = &(impEntity.elem[i]);
|
||||
|
||||
CopyEntity(ie, 0,
|
||||
h.param(0), h.param(1), h.param(2),
|
||||
h.param(3), h.param(4), h.param(5), h.param(6),
|
||||
false);
|
||||
|
@ -254,7 +296,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||
|
||||
void Group::GenerateEquations(IdList<Equation,hEquation> *l) {
|
||||
Equation eq;
|
||||
if(type == ROTATE) {
|
||||
if(type == ROTATE || type == IMPORTED) {
|
||||
// Normalize the quaternion
|
||||
ExprQuaternion q = {
|
||||
Expr::FromParam(h.param(3)),
|
||||
|
@ -266,6 +308,8 @@ void Group::GenerateEquations(IdList<Equation,hEquation> *l) {
|
|||
l->Add(&eq);
|
||||
} else if(type == EXTRUDE) {
|
||||
if(wrkpl.entityB.v != Entity::FREE_IN_3D.v) {
|
||||
// The extrusion path is locked along a line, normal to the
|
||||
// specified workplane.
|
||||
Entity *w = SS.GetEntity(wrkpl.entityB);
|
||||
ExprVector u = w->Normal()->NormalExprsU();
|
||||
ExprVector v = w->Normal()->NormalExprsV();
|
||||
|
@ -315,12 +359,10 @@ void Group::MakeExtrusionLines(hEntity in, int ai, int af) {
|
|||
SS.entity.Add(&en);
|
||||
}
|
||||
|
||||
void Group::CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz,
|
||||
void Group::CopyEntity(Entity *ep, int a, hParam dx, hParam dy, hParam dz,
|
||||
hParam qw, hParam qvx, hParam qvy, hParam qvz,
|
||||
bool transOnly)
|
||||
{
|
||||
Entity *ep = SS.GetEntity(in);
|
||||
|
||||
Entity en;
|
||||
memset(&en, 0, sizeof(en));
|
||||
en.type = ep->type;
|
||||
|
@ -378,7 +420,7 @@ void Group::CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz,
|
|||
en.param[5] = qvy;
|
||||
en.param[6] = qvz;
|
||||
}
|
||||
en.numPoint = ep->PointGetNum();
|
||||
en.numPoint = ep->actPoint;
|
||||
en.timesApplied = a;
|
||||
break;
|
||||
|
||||
|
@ -395,7 +437,7 @@ void Group::CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz,
|
|||
en.param[2] = qvy;
|
||||
en.param[3] = qvz;
|
||||
}
|
||||
en.numNormal = ep->NormalGetNum();
|
||||
en.numNormal = ep->actNormal;
|
||||
en.point[0] = Remap(ep->point[0], a);
|
||||
en.timesApplied = a;
|
||||
break;
|
||||
|
@ -403,7 +445,7 @@ void Group::CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz,
|
|||
case Entity::DISTANCE_N_COPY:
|
||||
case Entity::DISTANCE:
|
||||
en.type = Entity::DISTANCE_N_COPY;
|
||||
en.numDistance = ep->DistanceGetNum();
|
||||
en.numDistance = ep->actDistance;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -512,6 +554,26 @@ void Group::MakePolygons(void) {
|
|||
outm.AddTriangle(bbot, btop, atop);
|
||||
}
|
||||
}
|
||||
} else if(type == IMPORTED) {
|
||||
// Triangles are just copied over, with the appropriate transformation
|
||||
// applied.
|
||||
Vector offset = {
|
||||
SS.GetParam(h.param(0))->val,
|
||||
SS.GetParam(h.param(1))->val,
|
||||
SS.GetParam(h.param(2))->val };
|
||||
Quaternion q = {
|
||||
SS.GetParam(h.param(3))->val,
|
||||
SS.GetParam(h.param(4))->val,
|
||||
SS.GetParam(h.param(5))->val,
|
||||
SS.GetParam(h.param(6))->val };
|
||||
|
||||
for(int i = 0; i < impMesh.l.n; i++) {
|
||||
STriangle st = impMesh.l.elem[i];
|
||||
st.a = q.Rotate(st.a).Plus(offset);
|
||||
st.b = q.Rotate(st.b).Plus(offset);
|
||||
st.c = q.Rotate(st.c).Plus(offset);
|
||||
outm.AddTriangle(&st);
|
||||
}
|
||||
}
|
||||
edges.Clear();
|
||||
|
||||
|
|
23
sketch.h
23
sketch.h
|
@ -87,7 +87,6 @@ public:
|
|||
int type;
|
||||
|
||||
hGroup opA;
|
||||
hGroup opB;
|
||||
bool visible;
|
||||
hEntity activeWorkplane;
|
||||
Expr *exprA;
|
||||
|
@ -127,7 +126,15 @@ public:
|
|||
static const int COMBINE_AS_DIFFERENCE = 1;
|
||||
int meshCombine;
|
||||
|
||||
IdList<EntityMap,EntityId> remap;
|
||||
|
||||
char impFile[MAX_PATH];
|
||||
SMesh impMesh;
|
||||
EntityList impEntity;
|
||||
|
||||
NameStr name;
|
||||
|
||||
|
||||
char *DescriptionString(void);
|
||||
|
||||
static void AddParam(IdList<Param,hParam> *param, hParam hp, double v);
|
||||
|
@ -136,10 +143,9 @@ public:
|
|||
// 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
|
||||
// mapping list.
|
||||
IdList<EntityMap,EntityId> remap;
|
||||
hEntity Remap(hEntity in, int copyNumber);
|
||||
void MakeExtrusionLines(hEntity in, int ai, int af);
|
||||
void CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz,
|
||||
void CopyEntity(Entity *ep, int a, hParam dx, hParam dy, hParam dz,
|
||||
hParam qw, hParam qvx, hParam qvy, hParam qvz,
|
||||
bool transOnly);
|
||||
|
||||
|
@ -235,11 +241,18 @@ public:
|
|||
// and directions.
|
||||
hParam param[7];
|
||||
|
||||
// Transformed points/normals/distances have their numerical value.
|
||||
// Transformed points/normals/distances have their numerical base
|
||||
Vector numPoint;
|
||||
Quaternion numNormal;
|
||||
double numDistance;
|
||||
|
||||
// All points/normals/distances have their numerical value; this is
|
||||
// a convenience, to simplify the import/assembly code, so that the
|
||||
// part is entirely described by the entities.
|
||||
Vector actPoint;
|
||||
Quaternion actNormal;
|
||||
double actDistance;
|
||||
|
||||
hGroup group;
|
||||
hEntity workplane; // or Entity::FREE_IN_3D
|
||||
|
||||
|
@ -316,6 +329,8 @@ public:
|
|||
void AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index);
|
||||
void GenerateEquations(IdList<Equation,hEquation> *l);
|
||||
|
||||
void CalculateNumerical(void);
|
||||
|
||||
char *DescriptionString(void);
|
||||
};
|
||||
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
SolveSpace SS;
|
||||
|
||||
void SolveSpace::Init(char *cmdLine) {
|
||||
if(strlen(cmdLine) == 0) {
|
||||
NewFile();
|
||||
} else {
|
||||
NewFile();
|
||||
AfterNewFile();
|
||||
|
||||
if(strlen(cmdLine) != 0) {
|
||||
if(LoadFromFile(cmdLine)) {
|
||||
strcpy(saveFile, cmdLine);
|
||||
} else {
|
||||
|
@ -17,6 +18,7 @@ void SolveSpace::Init(char *cmdLine) {
|
|||
}
|
||||
|
||||
void SolveSpace::AfterNewFile(void) {
|
||||
ReloadAllImported();
|
||||
GenerateAll(false, 0, INT_MAX);
|
||||
|
||||
TW.Init();
|
||||
|
@ -78,7 +80,6 @@ bool SolveSpace::EntityExists(hEntity he) {
|
|||
bool SolveSpace::PruneGroups(hGroup hg) {
|
||||
Group *g = GetGroup(hg);
|
||||
if(GroupsInOrder(g->opA, hg) &&
|
||||
GroupsInOrder(g->opB, hg) &&
|
||||
EntityExists(g->wrkpl.origin) &&
|
||||
EntityExists(g->wrkpl.entityB) &&
|
||||
EntityExists(g->wrkpl.entityC))
|
||||
|
@ -334,9 +335,6 @@ void SolveSpace::AddToRecentList(char *file) {
|
|||
}
|
||||
|
||||
void SolveSpace::MenuFile(int id) {
|
||||
char *slvsPattern =
|
||||
"SolveSpace Models (*.slvs)\0*.slvs\0All Files (*)\0*\0\0";
|
||||
char *slvsExt = "slvs";
|
||||
|
||||
if(id >= RECENT_OPEN && id < (RECENT_OPEN+MAX_RECENT)) {
|
||||
char newFile[MAX_PATH];
|
||||
|
@ -362,7 +360,7 @@ void SolveSpace::MenuFile(int id) {
|
|||
|
||||
case GraphicsWindow::MNU_OPEN: {
|
||||
char newFile[MAX_PATH] = "";
|
||||
if(GetOpenFile(newFile, slvsExt, slvsPattern)) {
|
||||
if(GetOpenFile(newFile, SLVS_EXT, SLVS_PATTERN)) {
|
||||
if(SS.LoadFromFile(newFile)) {
|
||||
strcpy(SS.saveFile, newFile);
|
||||
AddToRecentList(newFile);
|
||||
|
@ -380,7 +378,7 @@ void SolveSpace::MenuFile(int id) {
|
|||
char newFile[MAX_PATH];
|
||||
strcpy(newFile, SS.saveFile);
|
||||
if(id == GraphicsWindow::MNU_SAVE_AS || strlen(newFile)==0) {
|
||||
if(!GetSaveFile(newFile, slvsExt, slvsPattern)) break;
|
||||
if(!GetSaveFile(newFile, SLVS_EXT, SLVS_PATTERN)) break;
|
||||
}
|
||||
|
||||
if(SS.SaveToFile(newFile)) {
|
||||
|
|
10
solvespace.h
10
solvespace.h
|
@ -41,6 +41,7 @@ class Expr;
|
|||
class ExprVector;
|
||||
class ExprQuaternion;
|
||||
|
||||
|
||||
// From the platform-specific code.
|
||||
#define MAX_RECENT 8
|
||||
#define RECENT_OPEN (0xf000)
|
||||
|
@ -49,6 +50,8 @@ extern char RecentFile[MAX_RECENT][MAX_PATH];
|
|||
void RefreshRecentMenus(void);
|
||||
|
||||
int SaveFileYesNoCancel(void);
|
||||
#define SLVS_PATTERN "SolveSpace Models (*.slvs)\0*.slvs\0All Files (*)\0*\0\0"
|
||||
#define SLVS_EXT "slvs"
|
||||
BOOL GetSaveFile(char *file, char *defExtension, char *selPattern);
|
||||
BOOL GetOpenFile(char *file, char *defExtension, char *selPattern);
|
||||
|
||||
|
@ -81,6 +84,11 @@ void vl(void); // debug function to validate
|
|||
|
||||
#include "dsc.h"
|
||||
#include "polygon.h"
|
||||
|
||||
class Entity;
|
||||
class hEntity;
|
||||
typedef IdList<Entity,hEntity> EntityList;
|
||||
|
||||
#include "sketch.h"
|
||||
#include "ui.h"
|
||||
#include "expr.h"
|
||||
|
@ -234,6 +242,8 @@ public:
|
|||
void NewFile(void);
|
||||
bool SaveToFile(char *filename);
|
||||
bool LoadFromFile(char *filename);
|
||||
bool LoadEntitiesFromFile(char *filename, EntityList *le, SMesh *m);
|
||||
void ReloadAllImported(void);
|
||||
|
||||
struct {
|
||||
int requests;
|
||||
|
|
|
@ -407,6 +407,10 @@ void TextWindow::ShowGroupInfo(void) {
|
|||
g->DescriptionString(),
|
||||
g->h.v, &TextWindow::ScreenChangeGroupName, s);
|
||||
|
||||
if(g->type == Group::IMPORTED) {
|
||||
Printf(true, "%FtIMPORT %E '%s'", g->impFile);
|
||||
}
|
||||
|
||||
if(g->type == Group::EXTRUDE) {
|
||||
s = "EXTRUDE";
|
||||
} else if(g->type == Group::TRANSLATE) {
|
||||
|
|
Loading…
Reference in New Issue