From bc6bdfade8b9fcc1de75526c2fa6446380a68a77 Mon Sep 17 00:00:00 2001 From: Jonathan Westhues Date: Mon, 18 May 2009 23:26:38 -0800 Subject: [PATCH] Save the exact surfaces in the exported file, and import and transform them for assembly. [git-p4: depot-paths = "//depot/solvespace/": change = 1954] --- file.cpp | 148 ++++++++++++++++++++++++++++++++++++++++++++++++-- groupmesh.cpp | 15 ++++- sketch.h | 1 + solvespace.h | 3 +- undoredo.cpp | 2 + 5 files changed, 160 insertions(+), 9 deletions(-) diff --git a/file.cpp b/file.cpp index ee5a550..2b437ee 100644 --- a/file.cpp +++ b/file.cpp @@ -2,6 +2,10 @@ #define VERSION_STRING "±²³SolveSpaceREVa" +static int StrStartsWith(char *str, char *start) { + return memcmp(str, start, strlen(start)) == 0; +} + hGroup SolveSpace::CreateDefaultDrawingGroup(void) { Group g; ZERO(&g); @@ -199,7 +203,7 @@ bool SolveSpace::SaveToFile(char *filename) { fprintf(fh, "%s\n\n\n", VERSION_STRING); - int i; + int i, j; for(i = 0; i < SK.group.n; i++) { sv.g = SK.group.elem[i]; SaveUsingTable('g'); @@ -240,6 +244,49 @@ bool SolveSpace::SaveToFile(char *filename) { CO(tr->a), CO(tr->b), CO(tr->c)); } + SShell *s = &(SK.group.elem[SK.group.n-1].runningShell); + SSurface *srf; + for(srf = s->surface.First(); srf; srf = s->surface.NextAfter(srf)) { + fprintf(fh, "Surface %08x %08x %08x %d %d\n", + srf->h.v, srf->color, srf->face, srf->degm, srf->degn); + for(i = 0; i <= srf->degm; i++) { + for(j = 0; j <= srf->degn; j++) { + fprintf(fh, "SCtrl %d %d %.20f %.20f %.20f Weight %20.20f\n", + i, j, CO(srf->ctrl[i][j]), srf->weight[i][j]); + } + } + + STrimBy *stb; + for(stb = srf->trim.First(); stb; stb = srf->trim.NextAfter(stb)) { + fprintf(fh, "TrimBy %08x %d %.20f %.20f %.20f %.20f %.20f %.20f\n", + stb->curve.v, stb->backwards ? 1 : 0, + CO(stb->start), CO(stb->finish)); + } + + fprintf(fh, "AddSurface\n"); + } + SCurve *sc; + for(sc = s->curve.First(); sc; sc = s->curve.NextAfter(sc)) { + fprintf(fh, "Curve %08x %d %d %08x %08x\n", + sc->h.v, + sc->isExact ? 1 : 0, sc->exact.deg, + sc->surfA.v, sc->surfB.v); + + if(sc->isExact) { + for(i = 0; i <= sc->exact.deg; i++) { + fprintf(fh, "CCtrl %d %.20f %.20f %.20f Weight %.20f\n", + i, CO(sc->exact.ctrl[i]), sc->exact.weight[i]); + } + } + SCurvePt *scpt; + for(scpt = sc->pts.First(); scpt; scpt = sc->pts.NextAfter(scpt)) { + fprintf(fh, "CurvePt %d %.20f %.20f %.20f\n", + scpt->vertex ? 1 : 0, CO(scpt->p)); + } + + fprintf(fh, "AddCurve\n"); + } + fclose(fh); return true; @@ -345,8 +392,17 @@ bool SolveSpace::LoadFromFile(char *filename) { memset(&(sv.c), 0, sizeof(sv.c)); } 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 if(StrStartsWith(line, "Triangle ") || + StrStartsWith(line, "Surface ") || + StrStartsWith(line, "SCtrl ") || + StrStartsWith(line, "TrimBy ") || + StrStartsWith(line, "Curve ") || + StrStartsWith(line, "CCtrl ") || + StrStartsWith(line, "CurvePt ") || + strcmp(line, "AddSurface")==0 || + strcmp(line, "AddCurve")==0) + { + // ignore the mesh or shell, since we regenerate that } else { oops(); } @@ -357,7 +413,14 @@ bool SolveSpace::LoadFromFile(char *filename) { return true; } -bool SolveSpace::LoadEntitiesFromFile(char *file, EntityList *le, SMesh *m) { +bool SolveSpace::LoadEntitiesFromFile(char *file, EntityList *le, + SMesh *m, SShell *sh) +{ + SSurface srf; + ZERO(&srf); + SCurve crv; + ZERO(&crv); + fh = fopen(file, "rb"); if(!fh) return false; @@ -395,7 +458,7 @@ bool SolveSpace::LoadEntitiesFromFile(char *file, EntityList *le, SMesh *m) { } else if(strcmp(line, VERSION_STRING)==0) { - } else if(memcmp(line, "Triangle", 8)==0) { + } else if(StrStartsWith(line, "Triangle ")) { STriangle tr; ZERO(&tr); if(sscanf(line, "Triangle %x %x " "%lf %lf %lf %lf %lf %lf %lf %lf %lf", @@ -407,6 +470,76 @@ bool SolveSpace::LoadEntitiesFromFile(char *file, EntityList *le, SMesh *m) { oops(); } m->AddTriangle(&tr); + } else if(StrStartsWith(line, "Surface ")) { + if(sscanf(line, "Surface %x %x %x %d %d", + &(srf.h.v), &(srf.color), &(srf.face), + &(srf.degm), &(srf.degn)) != 5) + { + oops(); + } + } else if(StrStartsWith(line, "SCtrl ")) { + int i, j; + Vector c; + double w; + if(sscanf(line, "SCtrl %d %d %lf %lf %lf Weight %lf", + &i, &j, &(c.x), &(c.y), &(c.z), &w) != 6) + { + oops(); + } + srf.ctrl[i][j] = c; + srf.weight[i][j] = w; + } else if(StrStartsWith(line, "TrimBy ")) { + STrimBy stb; + ZERO(&stb); + int backwards; + if(sscanf(line, "TrimBy %x %d %lf %lf %lf %lf %lf %lf", + &(stb.curve.v), &backwards, + &(stb.start.x), &(stb.start.y), &(stb.start.z), + &(stb.finish.x), &(stb.finish.y), &(stb.finish.z)) != 8) + { + oops(); + } + stb.backwards = (backwards != 0); + srf.trim.Add(&stb); + } else if(strcmp(line, "AddSurface")==0) { + sh->surface.Add(&srf); + ZERO(&srf); + } else if(StrStartsWith(line, "Curve ")) { + int isExact; + if(sscanf(line, "Curve %x %d %d %x %x", + &(crv.h.v), + &(isExact), + &(crv.exact.deg), + &(crv.surfA.v), &(crv.surfB.v)) != 5) + { + oops(); + } + crv.isExact = (isExact != 0); + } else if(StrStartsWith(line, "CCtrl ")) { + int i; + Vector c; + double w; + if(sscanf(line, "CCtrl %d %lf %lf %lf Weight %lf", + &i, &(c.x), &(c.y), &(c.z), &w) != 5) + { + oops(); + } + crv.exact.ctrl[i] = c; + crv.exact.weight[i] = w; + } else if(StrStartsWith(line, "CurvePt ")) { + SCurvePt scpt; + int vertex; + if(sscanf(line, "CurvePt %d %lf %lf %lf", + &vertex, + &(scpt.p.x), &(scpt.p.y), &(scpt.p.z)) != 4) + { + oops(); + } + scpt.vertex = (vertex != 0); + crv.pts.Add(&scpt); + } else if(strcmp(line, "AddCurve")==0) { + sh->curve.Add(&crv); + ZERO(&crv); } else { oops(); } @@ -426,6 +559,7 @@ void SolveSpace::ReloadAllImported(void) { g->impEntity.Clear(); g->impMesh.Clear(); + g->impShell.Clear(); FILE *test = fopen(g->impFile, "rb"); if(test) { @@ -446,7 +580,9 @@ void SolveSpace::ReloadAllImported(void) { } } - if(LoadEntitiesFromFile(g->impFile, &(g->impEntity), &(g->impMesh))) { + if(LoadEntitiesFromFile(g->impFile, + &(g->impEntity), &(g->impMesh), &(g->impShell))) + { if(SS.saveFile[0]) { // Record the imported file's name relative to our filename; // if the entire tree moves, then everything will still work diff --git a/groupmesh.cpp b/groupmesh.cpp index c0140a1..1d62d94 100644 --- a/groupmesh.cpp +++ b/groupmesh.cpp @@ -191,8 +191,8 @@ void Group::GenerateShellAndMesh(void) { thisShell.MakeFromRevolutionOf(&(src->bezierLoopSet), pt, axis, color); } else if(type == IMPORTED) { - // Triangles are just copied over, with the appropriate transformation - // applied. + // The imported shell or mesh are copied over, with the appropriate + // transformation applied. We also must remap the face entities. Vector offset = { SK.GetParam(h.param(0))->val, SK.GetParam(h.param(1))->val, @@ -214,6 +214,16 @@ void Group::GenerateShellAndMesh(void) { st.b = q.Rotate(st.b).Plus(offset); st.c = q.Rotate(st.c).Plus(offset); } + + thisShell.MakeFromTransformationOf(&impShell, offset, q); + SSurface *srf; + IdList *sl = &(thisShell.surface); + for(srf = sl->First(); srf; srf = sl->NextAfter(srf)) { + if(srf->face != 0) { + hEntity he = { srf->face }; + srf->face = Remap(he, 0).v; + } + } } runningShell.Clear(); @@ -234,6 +244,7 @@ void Group::GenerateShellAndMesh(void) { } else if(meshCombine == COMBINE_AS_DIFFERENCE) { runningShell.MakeFromDifferenceOf(a, &thisShell); } else { + runningShell.MakeFromUnionOf(a, &thisShell); // TODO, assembly } diff --git a/sketch.h b/sketch.h index 780db90..55bc91e 100644 --- a/sketch.h +++ b/sketch.h @@ -163,6 +163,7 @@ public: char impFile[MAX_PATH]; char impFileRel[MAX_PATH]; SMesh impMesh; + SShell impShell; EntityList impEntity; NameStr name; diff --git a/solvespace.h b/solvespace.h index 2572ee4..e0a1fbb 100644 --- a/solvespace.h +++ b/solvespace.h @@ -543,7 +543,8 @@ public: void NewFile(void); bool SaveToFile(char *filename); bool LoadFromFile(char *filename); - bool LoadEntitiesFromFile(char *filename, EntityList *le, SMesh *m); + bool LoadEntitiesFromFile(char *filename, EntityList *le, + SMesh *m, SShell *sh); void ReloadAllImported(void); // And the various export options void ExportAsPngTo(char *file); diff --git a/undoredo.cpp b/undoredo.cpp index 3779472..d7d85c9 100644 --- a/undoredo.cpp +++ b/undoredo.cpp @@ -59,6 +59,7 @@ void SolveSpace::PushFromCurrentOnto(UndoStack *uk) { src->remap.DeepCopyInto(&(dest.remap)); ZERO(&(dest.impMesh)); + ZERO(&(dest.impShell)); ZERO(&(dest.impEntity)); ut->group.Add(&dest); } @@ -98,6 +99,7 @@ void SolveSpace::PopOntoCurrentFrom(UndoStack *uk) { g->runningEdges.Clear(); g->remap.Clear(); g->impMesh.Clear(); + g->impShell.Clear(); g->impEntity.Clear(); } SK.group.Clear();