diff --git a/Graphics/Graph2D.cpp b/Graphics/Graph2D.cpp index 4fd524d51b3cf3aec64f422185697e1b9d9a7209..c4e8b2114b8bb50de83e2e5dce4c11bfd1f67d91 100644 --- a/Graphics/Graph2D.cpp +++ b/Graphics/Graph2D.cpp @@ -1,4 +1,4 @@ -// $Id: Graph2D.cpp,v 1.63 2007-09-01 09:20:00 geuzaine Exp $ +// $Id: Graph2D.cpp,v 1.64 2007-09-02 21:05:20 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -149,16 +149,16 @@ static void drawGraphAxes(PView *p, double xleft, double ytop, double width, if((opt->ShowTime == 1 && nt > 1) || opt->ShowTime == 2){ char tmp[256]; sprintf(tmp, opt->Format, data->getTime(opt->TimeStep)); - sprintf(label, "%s (%s)", p->getName().c_str(), tmp); + sprintf(label, "%s (%s)", data->getName().c_str(), tmp); } else if((opt->ShowTime == 3 && nt > 1) || opt->ShowTime == 4){ - sprintf(label, "%s (%d)", p->getName().c_str(), opt->TimeStep); + sprintf(label, "%s (%d)", data->getName().c_str(), opt->TimeStep); } else - sprintf(label, "%s", p->getName().c_str()); + sprintf(label, "%s", data->getName().c_str()); } else - sprintf(label, "%s", p->getName().c_str()); + sprintf(label, "%s", data->getName().c_str()); glRasterPos2d(xleft, ytop + font_h + tic); Draw_String_Center(label); diff --git a/Graphics/Iso.cpp b/Graphics/Iso.cpp index 55fb20b46606bbe944ff08f849063c57f8047d57..0a35036faee76fdf005fe0b2228bcc28cd43f6b4 100644 --- a/Graphics/Iso.cpp +++ b/Graphics/Iso.cpp @@ -1,4 +1,4 @@ -// $Id: Iso.cpp,v 1.40 2007-08-27 13:46:21 geuzaine Exp $ +// $Id: Iso.cpp,v 1.41 2007-09-02 21:05:20 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -36,7 +36,7 @@ static void affect(double *xi, double *yi, double *zi, int i, zi[i] = zp[j]; } -// Draw an iso-point in a line +// Compute an iso-point in a line int IsoLine(double *X, double *Y, double *Z, double *Val, double V, double *Xp, double *Yp, double *Zp) @@ -76,6 +76,8 @@ int IsoTriangle(double *X, double *Y, double *Z, double *Val, double V, return 0; } +// Compute an iso-polygon inside a tetrahedron + int IsoSimplex(double *X, double *Y, double *Z, double *Val, double V, double *Xp, double *Yp, double *Zp, double n[3]) { diff --git a/Graphics/Scale.cpp b/Graphics/Scale.cpp index 639fc06afc45432f6c596b08389ff8cf9b755d8d..23a2d1efa1d545dac3f189f4d4dfad637883fb13 100644 --- a/Graphics/Scale.cpp +++ b/Graphics/Scale.cpp @@ -1,4 +1,4 @@ -// $Id: Scale.cpp,v 1.66 2007-09-01 09:20:00 geuzaine Exp $ +// $Id: Scale.cpp,v 1.67 2007-09-02 21:05:20 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -180,13 +180,13 @@ static void drawScaleLabel(PView *p, double xmin, double ymin, double width, if((opt->ShowTime == 1 && nt > 1) || opt->ShowTime == 2){ char tmp[256]; sprintf(tmp, opt->Format, data->getTime(opt->TimeStep)); - sprintf(label, "%s (%s)", p->getName().c_str(), tmp); + sprintf(label, "%s (%s)", data->getName().c_str(), tmp); } else if((opt->ShowTime == 3 && nt > 1) || opt->ShowTime == 4){ - sprintf(label, "%s (%d)", p->getName().c_str(), opt->TimeStep); + sprintf(label, "%s (%d)", data->getName().c_str(), opt->TimeStep); } else - sprintf(label, "%s", p->getName().c_str()); + sprintf(label, "%s", data->getName().c_str()); if(horizontal){ glRasterPos2d(xmin + width / 2., ymin + height + tic + 1.4 * font_h); @@ -306,10 +306,10 @@ void Draw_Scales() if(opt->ShowTime){ char tmp[256]; sprintf(tmp, opt->Format, data->getTime(opt->TimeStep)); - sprintf(label, "%s (%s)", p->getName().c_str(), tmp); + sprintf(label, "%s (%s)", data->getName().c_str(), tmp); } else - sprintf(label, "%s", p->getName().c_str()); + sprintf(label, "%s", data->getName().c_str()); width = std::max(width, gl_width(label)); if(i % 2) width_total += std::max(bar_size + width, bar_size + width_prev); } diff --git a/Post/Makefile b/Post/Makefile index 8d5ad98739d205d933fd53271a7cd1ef1de0963d..1085213fb49a068c9ebf76779b70883d25a93448 100644 --- a/Post/Makefile +++ b/Post/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.8 2007-09-01 16:05:43 geuzaine Exp $ +# $Id: Makefile,v 1.9 2007-09-02 21:05:20 geuzaine Exp $ # # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle # @@ -73,7 +73,7 @@ PViewDataList.o: PViewDataList.cpp PViewDataList.h PViewData.h \ ../Numeric/Numeric.h ../Common/SmoothData.h ../Common/Context.h PViewDataListIO.o: PViewDataListIO.cpp PViewDataList.h PViewData.h \ ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../DataStr/List.h \ - ../Common/Message.h + ../Numeric/Numeric.h ../Common/Message.h ../Common/Context.h PViewDataGModel.o: PViewDataGModel.cpp PViewDataGModel.h PViewData.h \ ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h PViewDataList.h \ ../DataStr/List.h ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h \ diff --git a/Post/PView.h b/Post/PView.h index 663685055028a1716311ab924223b482b1d4be39..b3e8ed825ecdfbf085ccb869378ae039f3573463 100644 --- a/Post/PView.h +++ b/Post/PView.h @@ -42,8 +42,6 @@ class PView{ int _aliasOf; // reference counter mark that some other views link to this one int _links; - // name of the view - std::string _name; // eye position SPoint3 _eye; // the options @@ -62,8 +60,6 @@ class PView{ static PView *current(); PViewOptions *getOptions(){ return _options; } PViewData *getData(){ return _data; } - std::string getName(){ return _name; } - void setName(std::string val){ _name = val; } int getNum(){ return _num; } int getIndex(){ return _index; } void setIndex(int val){ _index = val; } diff --git a/Post/PViewData.h b/Post/PViewData.h index ecb692b52ef7bdd0948930ec35d94a3fc37c2455..0617aba8f954b00677a5eb71616df6cb8a326a3d 100644 --- a/Post/PViewData.h +++ b/Post/PViewData.h @@ -28,6 +28,8 @@ class PViewData { private: // flag to mark that the data is 'dirty' and should not be displayed bool _dirty; + // name of the view + std::string _name; // name of the file the data was loaded from std::string _filename; public: @@ -35,8 +37,12 @@ class PViewData { virtual ~PViewData(){} virtual bool getDirty(){ return _dirty; } virtual void setDirty(bool val){ _dirty = val; } - virtual void finalize(){} + virtual void finalize(){ _dirty = false; } virtual int getNumTimeSteps() = 0; + virtual std::string getName(){ return _name; } + virtual void setName(std::string val){ _name = val; } + virtual std::string getFileName(){ return _filename; } + virtual void setFileName(std::string val){ _filename = val; } virtual double getTime(int step){ return 0.; } virtual double getMin(int step=-1) = 0; virtual double getMax(int step=-1) = 0; @@ -66,7 +72,13 @@ class PViewData { double &x, double &y, double &style){} virtual void getString3D(int i, int step, std::string &str, double &x, double &y, double &z, double &style){} - virtual bool read(std::string filename){} + virtual bool read(std::string name){ return false; } + virtual bool writePOS(std::string name, bool binary=false, bool parsed=true, + bool append=false){ return false; } + virtual bool writeSTL(std::string name){ return false; } + virtual bool writeTXT(std::string name){ return false; } + virtual bool writeMSH(std::string name){ return false; } + }; #endif diff --git a/Post/PViewDataGModel.cpp b/Post/PViewDataGModel.cpp index 4deea8560ddc080676d21a8d7078c412e3140ee8..3fc2cf502948007773562dcf11ca876dce32ce6e 100644 --- a/Post/PViewDataGModel.cpp +++ b/Post/PViewDataGModel.cpp @@ -1,4 +1,4 @@ -// $Id: PViewDataGModel.cpp,v 1.1 2007-09-01 16:06:24 geuzaine Exp $ +// $Id: PViewDataGModel.cpp,v 1.2 2007-09-02 21:05:20 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -23,3 +23,30 @@ // #include "PViewDataGModel.h" + +bool PViewDataGModel::read(std::string name) +{ + // model->read(); +} + +bool PViewDataGModel::writePOS(std::string name, bool binary, bool parsed, + bool append) +{ + // model->writePOS() +} + +bool PViewDataGModel::writeSTL(std::string name) +{ + // model->writeSTL() +} + +bool PViewDataGModel::writeTXT(std::string name) +{ + // model->writeTXT() +} + +bool PViewDataGModel::writeMSH(std::string name) +{ + // model->writeMSH() +} + diff --git a/Post/PViewDataGModel.h b/Post/PViewDataGModel.h index f37e1da570b0a133d96933fc8c321c8ca87e08e1..f2864fc7b882adff432fb5411166fa7ac91d4b84 100644 --- a/Post/PViewDataGModel.h +++ b/Post/PViewDataGModel.h @@ -44,6 +44,12 @@ class PViewDataGModel : public PViewData { int getNumComponents(int ele){ return 1; } void getValue(int ele, int node, int comp, int step, double &val){} int getNumEdges(int ele){ return 0; } + bool read(std::string name); + bool writePOS(std::string name, bool binary=false, bool parsed=true, + bool append=false); + bool writeSTL(std::string name); + bool writeTXT(std::string name); + bool writeMSH(std::string name); }; #endif diff --git a/Post/PViewDataList.cpp b/Post/PViewDataList.cpp index a9520a4bba0c1de348698154080bec6a169d8c50..63ed65053378c866b11bcb9d1a8019e57b6bca39 100644 --- a/Post/PViewDataList.cpp +++ b/Post/PViewDataList.cpp @@ -1,4 +1,4 @@ -// $Id: PViewDataList.cpp,v 1.1 2007-09-01 16:06:24 geuzaine Exp $ +// $Id: PViewDataList.cpp,v 1.2 2007-09-02 21:05:20 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -101,9 +101,10 @@ void PViewDataList::finalize() _stat(T2D, T2C, 4); _stat(T3D, T3C, 5); // convert all "old-style" (non adaptive) 2nd order elements into - // linear elements *and* free all the data associated with the - // 2nd order elements - //FIXME: _splitCurvedElements(); + // linear elements *and* free all the data associated with the 2nd + // order elements (this is a temporary solution, until we use + // Adaptive_Views on all curved elements) + _splitCurvedElements(); // compute min/max and other statistics for all element lists _stat(SP, 1, NbSP, 1); _stat(VP, 3, NbVP, 1); _stat(TP, 9, NbTP, 1); @@ -402,6 +403,107 @@ void PViewDataList::getString3D(int i, int step, std::string &str, _getString(3, i, step, str, x, y, z, style); } +static void splitCurvedElement(List_T **in, int *nbin, List_T *out, int *nbout, + int nodin, int nodout, int nbcomp, int nbsplit, + int split[][8], int remove=1) +{ + if(*nbin){ + int nb = List_Nbr(*in) / *nbin; + int nbstep = (nb - 3 * nodin) / (nodin * nbcomp); // we don't know this yet for the view + for(int i = 0; i < List_Nbr(*in); i += nb) { + double *coord = (double *)List_Pointer_Fast(*in, i); + double *val = (double *)List_Pointer_Fast(*in, i + 3 * nodin); + for(int j = 0; j < nbsplit; j++){ + for(int k = 0; k < nodout; k++) + List_Add(out, &coord[split[j][k]]); + for(int k = 0; k < nodout; k++) + List_Add(out, &coord[nodin + split[j][k]]); + for(int k = 0; k < nodout; k++) + List_Add(out, &coord[2 * nodin + split[j][k]]); + for(int ts = 0; ts < nbstep; ts++){ + for(int k = 0; k < nodout; k++){ + for(int l = 0; l < nbcomp; l++){ + List_Add(out, &val[nodin * nbcomp * ts + nbcomp * split[j][k] + l]); + } + } + } + (*nbout)++; + } + } + } + + if(remove){ + *nbin = 0; + List_Delete(*in); + *in = NULL; + } +} + +void PViewDataList::_splitCurvedElements() +{ + int lin[2][8] = { // 2-split + {0,2}, {2,1} + }; + splitCurvedElement(&SL2, &NbSL2, SL, &NbSL, 3,2, 1, 2, lin); + splitCurvedElement(&VL2, &NbVL2, VL, &NbVL, 3,2, 3, 2, lin); + splitCurvedElement(&TL2, &NbTL2, TL, &NbTL, 3,2, 9, 2, lin); + + int tri[4][8] = { // 4-split + {0,3,5}, {1,4,3}, {2,5,4}, {3,4,5} + }; + splitCurvedElement(&ST2, &NbST2, ST, &NbST, 6,3, 1, 4, tri); + splitCurvedElement(&VT2, &NbVT2, VT, &NbVT, 6,3, 3, 4, tri); + splitCurvedElement(&TT2, &NbTT2, TT, &NbTT, 6,3, 9, 4, tri); + + int qua[4][8] = { // 4-split + {0,4,8,7}, {1,5,8,4}, {2,6,8,5}, {3,7,8,6} + }; + splitCurvedElement(&SQ2, &NbSQ2, SQ, &NbSQ, 9,4, 1, 4, qua); + splitCurvedElement(&VQ2, &NbVQ2, VQ, &NbVQ, 9,4, 3, 4, qua); + splitCurvedElement(&TQ2, &NbTQ2, TQ, &NbTQ, 9,4, 9, 4, qua); + + int tet[8][8] = { // 8-split + {0,4,6,7}, {1,5,4,9}, {2,6,5,8}, {3,9,7,8}, + {4,6,7,8}, {4,6,5,8}, {4,5,9,8}, {4,7,9,8} + }; + splitCurvedElement(&SS2, &NbSS2, SS, &NbSS, 10,4, 1, 8, tet); + splitCurvedElement(&VS2, &NbVS2, VS, &NbVS, 10,4, 3, 8, tet); + splitCurvedElement(&TS2, &NbTS2, TS, &NbTS, 10,4, 9, 8, tet); + + int hex[8][8] = { // 8-split + {0,8,20,9, 10,21,26,22}, {8,1,11,20, 21,12,23,26}, + {9,20,13,3, 22,26,24,15}, {20,11,2,13, 26,23,14,24}, + {10,21,26,22, 4,16,25,17}, {21,12,23,26, 16,5,18,25}, + {22,26,24,15, 17,25,19,7}, {26,23,14,24, 25,18,6,19} + }; + splitCurvedElement(&SH2, &NbSH2, SH, &NbSH, 27,8, 1, 8, hex); + splitCurvedElement(&VH2, &NbVH2, VH, &NbVH, 27,8, 3, 8, hex); + splitCurvedElement(&TH2, &NbTH2, TH, &NbTH, 27,8, 9, 8, hex); + + int pri[8][8] = { // 8-split + {0,6,7, 8,15,16}, {1,9,6, 10,17,15}, {2,7,9, 11,16,17}, {6,9,7, 15,17,16}, + {8,15,16, 3,12,13}, {10,17,15, 4,14,12}, {11,16,17, 5,13,14}, {15,17,16, 12,14,13} + }; + splitCurvedElement(&SI2, &NbSI2, SI, &NbSI, 18,6, 1, 8, pri); + splitCurvedElement(&VI2, &NbVI2, VI, &NbVI, 18,6, 3, 8, pri); + splitCurvedElement(&TI2, &NbTI2, TI, &NbTI, 18,6, 9, 8, pri); + + int pyr[6][8] = { // 6 pyramids + {0,5,13,6, 7}, {5,1,8,13, 9}, {6,13,10,3, 12}, {13,8,2,10, 11}, + {7,9,11,12, 4}, {7,12,11,9, 13} + }; + splitCurvedElement(&SY2, &NbSY2, SY, &NbSY, 14,5, 1, 6, pyr, 0); // don't remove yet + splitCurvedElement(&VY2, &NbVY2, VY, &NbVY, 14,5, 3, 6, pyr, 0); + splitCurvedElement(&TY2, &NbTY2, TY, &NbTY, 14,5, 9, 6, pyr, 0); + + int pyr2[4][8] = { // + 4 tets to fill the holes + {6,12,7,13}, {7,9,5,13}, {9,11,8,13}, {12,10,11,13} + }; + splitCurvedElement(&SY2, &NbSY2, SS, &NbSS, 14,4, 1, 4, pyr2); + splitCurvedElement(&VY2, &NbVY2, VS, &NbVS, 14,4, 3, 4, pyr2); + splitCurvedElement(&TY2, &NbTY2, TS, &NbTS, 14,4, 9, 4, pyr2); +} + static void generateConnectivities(List_T *list, int nbList, int nbTimeStep, int nbVert, smooth_data &data) diff --git a/Post/PViewDataList.h b/Post/PViewDataList.h index 145cadffbb54f8dd9fb30f3db340fdabecb9ce85..eab7173e098cf92eefd3b352f0e571bb18158b2f 100644 --- a/Post/PViewDataList.h +++ b/Post/PViewDataList.h @@ -72,6 +72,7 @@ class PViewDataList : public PViewData { List_T *list, int nblist); void _getString(int dim, int i, int timestep, std::string &str, double &x, double &y, double &z, double &style); + void _splitCurvedElements(); public: PViewDataList(bool allocate=true); ~PViewDataList(); @@ -111,7 +112,12 @@ class PViewDataList : public PViewData { void getString3D(int i, int step, std::string &str, double &x, double &y, double &z, double &style); void smooth(); - bool read(std::string filename); + bool read(std::string name); + bool writePOS(std::string name, bool binary=false, bool parsed=true, + bool append=false); + bool writeSTL(std::string name); + bool writeTXT(std::string name); + bool writeMSH(std::string name); }; #endif diff --git a/Post/PViewDataListIO.cpp b/Post/PViewDataListIO.cpp index 9aa8d845bca029f44ca36287da5d2198a12df181..82be6bdb9bd5d2a54fb8a45dfce067d54b6b543f 100644 --- a/Post/PViewDataListIO.cpp +++ b/Post/PViewDataListIO.cpp @@ -1,4 +1,4 @@ -// $Id: PViewDataListIO.cpp,v 1.1 2007-09-01 16:06:24 geuzaine Exp $ +// $Id: PViewDataListIO.cpp,v 1.2 2007-09-02 21:05:20 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -22,8 +22,13 @@ // Contributor(s): // +#include <set> #include "PViewDataList.h" +#include "Numeric.h" #include "Message.h" +#include "Context.h" + +extern Context_T CTX; bool PViewDataList::read(std::string filename) { @@ -297,5 +302,479 @@ bool PViewDataList::read(std::string filename) } + fclose(fp); + setFileName(filename); + return true; +} + + +static void writeTimePOS(FILE *fp, List_T *list) +{ + if(List_Nbr(list) > 1){ + fprintf(fp, "TIME{"); + for(int i = 0; i < List_Nbr(list); i ++){ + if(i) fprintf(fp, ","); + fprintf(fp, "%.16g", *(double *)List_Pointer(list, i)); + } + fprintf(fp, "};\n"); + } +} + +static void writeElementPOS(FILE *fp, const char *str, int nbnod, int nb, + List_T *list) +{ + if(nb){ + int n = List_Nbr(list) / nb; + for(int i = 0; i < List_Nbr(list); i += n) { + double *x = (double *)List_Pointer(list, i); + double *y = (double *)List_Pointer(list, i + nbnod); + double *z = (double *)List_Pointer(list, i + 2 * nbnod); + fprintf(fp, "%s(", str); + for(int j = 0; j < nbnod; j++) { + if(j) fprintf(fp, ","); + fprintf(fp, "%.16g,%.16g,%.16g", x[j], y[j], z[j]); + } + fprintf(fp, "){"); + for(int j = 3 * nbnod; j < n; j++) { + if(j - 3 * nbnod) fprintf(fp, ","); + fprintf(fp, "%.16g", *(double *)List_Pointer(list, i + j)); + } + fprintf(fp, "};\n"); + } + } +} + +static void writeTextPOS(FILE *fp, int nbc, int nb, List_T *TD, List_T *TC) +{ + if(!nb || (nbc != 4 && nbc != 5)) return; + for(int j = 0; j < List_Nbr(TD); j += nbc){ + double x, y, z, style, start, end; + List_Read(TD, j, &x); + List_Read(TD, j+1, &y); + if(nbc == 5) + List_Read(TD, j+2, &z); + List_Read(TD, j+nbc-2, &style); + if(nbc == 4) + fprintf(fp, "T2(%g,%g,%g){", x, y, style); + else + fprintf(fp, "T3(%g,%g,%g,%g){", x, y, z, style); + List_Read(TD, j+nbc-1, &start); + if(j+nbc*2-1 < List_Nbr(TD)) + List_Read(TD, j+nbc*2-1, &end); + else + end = List_Nbr(TC); + int l = 0; + while(l < end-start){ + char *str = (char*)List_Pointer(TC, (int)start + l); + if(l) fprintf(fp, ","); + fprintf(fp, "\"%s\"", str); + l += strlen(str)+1; + } + fprintf(fp, "};\n"); + } +} + +bool PViewDataList::writePOS(std::string name, bool binary, bool parsed, bool append) +{ + FILE *fp = fopen(name.c_str(), + append ? (binary ? "ab" : "a") : (binary ? "wb" : "w")); + if(!fp){ + Msg(GERROR, "Unable to open file '%s'", name.c_str()); + return false; + } + + if(!parsed && !append){ + fprintf(fp, "$PostFormat /* Gmsh 1.3, %s */\n", binary ? "binary" : "ascii"); + fprintf(fp, "1.3 %d %d\n", binary, (int)sizeof(double)); + fprintf(fp, "$EndPostFormat\n"); + } + + char str[256]; + strcpy(str, getName().c_str()); + for(int i = 0; i < (int)strlen(str); i++) + if(str[i] == ' ') str[i] = '^'; + + if(!parsed){ + fprintf(fp, "$View /* %s */\n", getName().c_str()); + fprintf(fp, "%s ", str); + fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d " + "%d %d %d %d %d %d %d %d %d %d %d %d\n", + List_Nbr(Time), + NbSP, NbVP, NbTP, NbSL, NbVL, NbTL, + NbST, NbVT, NbTT, NbSQ, NbVQ, NbTQ, + NbSS, NbVS, NbTS, NbSH, NbVH, NbTH, + NbSI, NbVI, NbTI, NbSY, NbVY, NbTY, + NbT2, List_Nbr(T2C), NbT3, List_Nbr(T3C)); + int f = binary ? LIST_FORMAT_BINARY : LIST_FORMAT_ASCII; + if(binary) { + int one = 1; + if(!fwrite(&one, sizeof(int), 1, fp)){ + Msg(GERROR, "Write error"); + return false; + } + } + List_WriteToFile(Time, fp, f); + List_WriteToFile(SP, fp, f); List_WriteToFile(VP, fp, f); + List_WriteToFile(TP, fp, f); List_WriteToFile(SL, fp, f); + List_WriteToFile(VL, fp, f); List_WriteToFile(TL, fp, f); + List_WriteToFile(ST, fp, f); List_WriteToFile(VT, fp, f); + List_WriteToFile(TT, fp, f); List_WriteToFile(SQ, fp, f); + List_WriteToFile(VQ, fp, f); List_WriteToFile(TQ, fp, f); + List_WriteToFile(SS, fp, f); List_WriteToFile(VS, fp, f); + List_WriteToFile(TS, fp, f); List_WriteToFile(SH, fp, f); + List_WriteToFile(VH, fp, f); List_WriteToFile(TH, fp, f); + List_WriteToFile(SI, fp, f); List_WriteToFile(VI, fp, f); + List_WriteToFile(TI, fp, f); List_WriteToFile(SY, fp, f); + List_WriteToFile(VY, fp, f); List_WriteToFile(TY, fp, f); + List_WriteToFile(T2D, fp, f); List_WriteToFile(T2C, fp, f); + List_WriteToFile(T3D, fp, f); List_WriteToFile(T3C, fp, f); + fprintf(fp, "\n"); + fprintf(fp, "$EndView\n"); + } + else{ + fprintf(fp, "View \"%s\" {\n", getName().c_str()); + writeTimePOS(fp, Time); + writeElementPOS(fp, "SP", 1, NbSP, SP); writeElementPOS(fp, "VP", 1, NbVP, VP); + writeElementPOS(fp, "TP", 1, NbTP, TP); writeElementPOS(fp, "SL", 2, NbSL, SL); + writeElementPOS(fp, "VL", 2, NbVL, VL); writeElementPOS(fp, "TL", 2, NbTL, TL); + writeElementPOS(fp, "ST", 3, NbST, ST); writeElementPOS(fp, "VT", 3, NbVT, VT); + writeElementPOS(fp, "TT", 3, NbTT, TT); writeElementPOS(fp, "SQ", 4, NbSQ, SQ); + writeElementPOS(fp, "VQ", 4, NbVQ, VQ); writeElementPOS(fp, "TQ", 4, NbTQ, TQ); + writeElementPOS(fp, "SS", 4, NbSS, SS); writeElementPOS(fp, "VS", 4, NbVS, VS); + writeElementPOS(fp, "TS", 4, NbTS, TS); writeElementPOS(fp, "SH", 8, NbSH, SH); + writeElementPOS(fp, "VH", 8, NbVH, VH); writeElementPOS(fp, "TH", 8, NbTH, TH); + writeElementPOS(fp, "SI", 6, NbSI, SI); writeElementPOS(fp, "VI", 6, NbVI, VI); + writeElementPOS(fp, "TI", 6, NbTI, TI); writeElementPOS(fp, "SY", 5, NbSY, SY); + writeElementPOS(fp, "VY", 5, NbVY, VY); writeElementPOS(fp, "TY", 5, NbTY, TY); + writeTextPOS(fp, 4, NbT2, T2D, T2C); writeTextPOS(fp, 5, NbT3, T3D, T3C); + fprintf(fp, "};\n"); + } + + fclose(fp); + return true; +} + +static void writeElementSTL(FILE *fp, int nbelm, List_T *list, int nbnod) +{ + if(!nbelm) return; + int nb = List_Nbr(list) / nbelm; + for(int i = 0; i < List_Nbr(list); i+=nb){ + double *x = (double*)List_Pointer(list, i); + double n[3]; + normal3points(x[0], x[3], x[6], + x[1], x[4], x[7], + x[2], x[5], x[8], n); + if(nbnod == 3){ + fprintf(fp, "facet normal %g %g %g\n", n[0], n[1], n[2]); + fprintf(fp, " outer loop\n"); + fprintf(fp, " vertex %g %g %g\n", x[0], x[3], x[6]); + fprintf(fp, " vertex %g %g %g\n", x[1], x[4], x[7]); + fprintf(fp, " vertex %g %g %g\n", x[2], x[5], x[8]); + fprintf(fp, " endloop\n"); + fprintf(fp, "endfacet\n"); + } + else{ + fprintf(fp, "facet normal %g %g %g\n", n[0], n[1], n[2]); + fprintf(fp, " outer loop\n"); + fprintf(fp, " vertex %g %g %g\n", x[0], x[4], x[8]); + fprintf(fp, " vertex %g %g %g\n", x[1], x[5], x[9]); + fprintf(fp, " vertex %g %g %g\n", x[2], x[6], x[10]); + fprintf(fp, " endloop\n"); + fprintf(fp, "endfacet\n"); + fprintf(fp, "facet normal %g %g %g\n", n[0], n[1], n[2]); + fprintf(fp, " outer loop\n"); + fprintf(fp, " vertex %g %g %g\n", x[0], x[4], x[8]); + fprintf(fp, " vertex %g %g %g\n", x[2], x[6], x[10]); + fprintf(fp, " vertex %g %g %g\n", x[3], x[7], x[11]); + fprintf(fp, " endloop\n"); + fprintf(fp, "endfacet\n"); + } + } +} + +bool PViewDataList::writeSTL(std::string name) +{ + FILE *fp = fopen(name.c_str(), "w"); + if(!fp){ + Msg(GERROR, "Unable to open file '%s'", name.c_str()); + return false; + } + + if(!NbST && !NbVT && !NbTT && !NbSQ && !NbVQ && !NbTQ){ + Msg(GERROR, "No surface elements to save"); + return false; + } + + fprintf(fp, "solid Created by Gmsh\n"); + writeElementSTL(fp, NbST, ST, 3); + writeElementSTL(fp, NbVT, VT, 3); + writeElementSTL(fp, NbTT, TT, 3); + writeElementSTL(fp, NbSQ, SQ, 4); + writeElementSTL(fp, NbVQ, VQ, 4); + writeElementSTL(fp, NbTQ, TQ, 4); + fprintf(fp, "endsolid Created by Gmsh\n"); + + fclose(fp); + return true; +} + +static void writeElementTXT(FILE *file, int nbelm, List_T *list, + int nbnod, int nbcomp, int nbtime) +{ + if(!nbelm) return; + int nb = List_Nbr(list) / nbelm; + for(int i = 0; i < List_Nbr(list); i += nb){ + double *x = (double*)List_Pointer(list, i); + for(int j = 0; j < nbnod * (3 + nbcomp * nbtime); j++) + fprintf(file, "%.16g ", x[j]); + fprintf(file, "\n"); + } + fprintf(file, "\n"); +} + +bool PViewDataList::writeTXT(std::string name) +{ + FILE *fp = fopen(name.c_str(), "w"); + if(!fp){ + Msg(GERROR, "Unable to open file '%s'", name.c_str()); + return false; + } + + writeElementTXT(fp, NbSP, SP, 1, 1, NbTimeStep); + writeElementTXT(fp, NbVP, VP, 1, 3, NbTimeStep); + writeElementTXT(fp, NbTP, TP, 1, 9, NbTimeStep); + writeElementTXT(fp, NbSL, SL, 2, 1, NbTimeStep); + writeElementTXT(fp, NbVL, VL, 2, 3, NbTimeStep); + writeElementTXT(fp, NbTL, TL, 2, 9, NbTimeStep); + writeElementTXT(fp, NbST, ST, 3, 1, NbTimeStep); + writeElementTXT(fp, NbVT, VT, 3, 3, NbTimeStep); + writeElementTXT(fp, NbTT, TT, 3, 9, NbTimeStep); + writeElementTXT(fp, NbSQ, SQ, 4, 1, NbTimeStep); + writeElementTXT(fp, NbVQ, VQ, 4, 3, NbTimeStep); + writeElementTXT(fp, NbTQ, TQ, 4, 9, NbTimeStep); + writeElementTXT(fp, NbSS, SS, 4, 1, NbTimeStep); + writeElementTXT(fp, NbVS, VS, 4, 3, NbTimeStep); + writeElementTXT(fp, NbTS, TS, 4, 9, NbTimeStep); + writeElementTXT(fp, NbSH, SH, 8, 1, NbTimeStep); + writeElementTXT(fp, NbVH, VH, 8, 3, NbTimeStep); + writeElementTXT(fp, NbTH, TH, 8, 9, NbTimeStep); + writeElementTXT(fp, NbSI, SI, 6, 1, NbTimeStep); + writeElementTXT(fp, NbVI, VI, 6, 3, NbTimeStep); + writeElementTXT(fp, NbTI, TI, 6, 9, NbTimeStep); + writeElementTXT(fp, NbSY, SY, 5, 1, NbTimeStep); + writeElementTXT(fp, NbVY, VY, 5, 3, NbTimeStep); + writeElementTXT(fp, NbTY, TY, 5, 9, NbTimeStep); + + fclose(fp); return true; } + +class pVertex{ + public: + int Num; + double X, Y, Z; + pVertex() : Num(0), X(0.), Y(0.), Z(0.) {} + pVertex(double x, double y, double z) : Num(0), X(x), Y(y), Z(z) {} +}; + +class pVertexLessThan{ + public: + bool operator()(const pVertex ent1, const pVertex ent2) const + { + double tol = CTX.lc * 1.e-10 ; + if(ent1.X - ent2.X > tol) return true; + if(ent1.X - ent2.X < -tol) return false; + if(ent1.Y - ent2.Y > tol) return true; + if(ent1.Y - ent2.Y < -tol) return false; + if(ent1.Z - ent2.Z > tol) return true; + return false; + } +}; + +static void getNodeMSH(int nbelm, List_T *list, int nbnod, int nbcomp, + std::set<pVertex, pVertexLessThan> *nodes, + int *numelm) +{ + if(!nbelm) return; + int nb = List_Nbr(list) / nbelm; + for(int i = 0; i < List_Nbr(list); i+=nb){ + double *x = (double *)List_Pointer_Fast(list, i); + double *y = (double *)List_Pointer_Fast(list, i + nbnod); + double *z = (double *)List_Pointer_Fast(list, i + 2 * nbnod); + for(int j = 0; j < nbnod; j++) { + pVertex n(x[j], y[j], z[j]); + std::set<pVertex, pVertexLessThan>::iterator it = nodes->find(n); + if(it == nodes->end()){ + n.Num = nodes->size() + 1; + nodes->insert(n); + } + } + (*numelm)++; + } +} + +static void writeElementMSH(FILE *fp, int num, int nbnod, pVertex nod[8], + int nbcomp, double *vals, int dim) +{ + // compute average value in elm + double d = 0.; + for(int k = 0; k < nbnod; k++) { + double *v = &vals[nbcomp * k]; + switch(nbcomp) { + case 1: // scalar + d += v[0]; + break; + case 3 : // vector + d += sqrt(DSQR(v[0]) + DSQR(v[1]) + DSQR(v[2])); + break; + case 9 : // tensor + d += ComputeVonMises(v); + break; + } + } + d /= (double)nbnod; + + // assign val as elementary region number + int ele = (int)fabs(d), phys = 1; + + switch(dim){ + case 0: + fprintf(fp, "%d 15 %d %d 1 %d\n", num, phys, ele, nod[0].Num); + break; + case 1: + fprintf(fp, "%d 1 %d %d 2 %d %d\n", num, phys, ele, nod[0].Num, nod[1].Num); + break; + case 2: + if(nbnod == 3) + fprintf(fp, "%d 2 %d %d 3 %d %d %d\n", num, phys, ele, + nod[0].Num, nod[1].Num, nod[2].Num); + else + fprintf(fp, "%d 3 %d %d 4 %d %d %d %d\n", num, phys, ele, + nod[0].Num, nod[1].Num, nod[2].Num, nod[3].Num); + break; + case 3: + default: + if(nbnod == 4) + fprintf(fp, "%d 4 %d %d 4 %d %d %d %d\n", num, phys, ele, + nod[0].Num, nod[1].Num, nod[2].Num, nod[3].Num); + else if(nbnod == 5) + fprintf(fp, "%d 7 %d %d 5 %d %d %d %d %d\n", num, phys, ele, + nod[0].Num, nod[1].Num, nod[2].Num, nod[3].Num, nod[4].Num); + else if(nbnod == 6) + fprintf(fp, "%d 6 %d %d 6 %d %d %d %d %d %d\n", num, phys, ele, + nod[0].Num, nod[1].Num, nod[2].Num, nod[3].Num, nod[4].Num, + nod[5].Num); + else + fprintf(fp, "%d 5 %d %d 8 %d %d %d %d %d %d %d %d\n", num, phys, ele, + nod[0].Num, nod[1].Num, nod[2].Num, nod[3].Num, nod[4].Num, + nod[5].Num, nod[6].Num, nod[7].Num); + break; + } +} + +static void writeElementsMSH(FILE *fp, int nbelm, List_T *list, + int nbnod, int nbcomp, int dim, + std::set<pVertex, pVertexLessThan> *nodes, + int *numelm) +{ + if(!nbelm) return; + pVertex nod[8]; + int nb = List_Nbr(list) / nbelm; + for(int i = 0; i < List_Nbr(list); i+=nb){ + double *x = (double *)List_Pointer_Fast(list, i); + double *y = (double *)List_Pointer_Fast(list, i + nbnod); + double *z = (double *)List_Pointer_Fast(list, i + 2 * nbnod); + double *v = (double *)List_Pointer_Fast(list, i + 3 * nbnod); + for(int j = 0; j < nbnod; j++) { + pVertex n(x[j], y[j], z[j]); + std::set<pVertex, pVertexLessThan>::iterator it = nodes->find(n); + if(it == nodes->end()){ + Msg(GERROR, "Unknown node in element"); + return; + } + else{ + nod[j] = (pVertex)(*it); + } + } + (*numelm)++; + writeElementMSH(fp, *numelm, nbnod, nod, nbcomp, v, dim); + } +} + +bool PViewDataList::writeMSH(std::string name) +{ + FILE *fp = fopen(name.c_str(), "w"); + if(!fp){ + Msg(GERROR, "Unable to open file '%s'", name.c_str()); + return false; + } + + std::set<pVertex, pVertexLessThan> nodes; + int numelm = 0; + getNodeMSH(NbSP, SP, 1, 1, &nodes, &numelm); + getNodeMSH(NbVP, VP, 1, 3, &nodes, &numelm); + getNodeMSH(NbTP, TP, 1, 9, &nodes, &numelm); + getNodeMSH(NbSL, SL, 2, 1, &nodes, &numelm); + getNodeMSH(NbVL, VL, 2, 3, &nodes, &numelm); + getNodeMSH(NbTL, TL, 2, 9, &nodes, &numelm); + getNodeMSH(NbST, ST, 3, 1, &nodes, &numelm); + getNodeMSH(NbVT, VT, 3, 3, &nodes, &numelm); + getNodeMSH(NbTT, TT, 3, 9, &nodes, &numelm); + getNodeMSH(NbSQ, SQ, 4, 1, &nodes, &numelm); + getNodeMSH(NbVQ, VQ, 4, 3, &nodes, &numelm); + getNodeMSH(NbTQ, TQ, 4, 9, &nodes, &numelm); + getNodeMSH(NbSS, SS, 4, 1, &nodes, &numelm); + getNodeMSH(NbVS, VS, 4, 3, &nodes, &numelm); + getNodeMSH(NbTS, TS, 4, 9, &nodes, &numelm); + getNodeMSH(NbSH, SH, 8, 1, &nodes, &numelm); + getNodeMSH(NbVH, VH, 8, 3, &nodes, &numelm); + getNodeMSH(NbTH, TH, 8, 9, &nodes, &numelm); + getNodeMSH(NbSI, SI, 6, 1, &nodes, &numelm); + getNodeMSH(NbVI, VI, 6, 3, &nodes, &numelm); + getNodeMSH(NbTI, TI, 6, 9, &nodes, &numelm); + getNodeMSH(NbSY, SY, 5, 1, &nodes, &numelm); + getNodeMSH(NbVY, VY, 5, 3, &nodes, &numelm); + getNodeMSH(NbTY, TY, 5, 9, &nodes, &numelm); + + fprintf(fp, "$NOD\n"); + fprintf(fp, "%d\n", (int)nodes.size()); + std::set<pVertex, pVertexLessThan>::iterator it = nodes.begin(); + for(; it != nodes.end(); ++it){ + pVertex n = (pVertex)(*it); + fprintf(fp, "%d %.16g %.16g %.16g\n", n.Num, n.X, n.Y, n.Z); + } + fprintf(fp, "$ENDNOD\n"); + + fprintf(fp, "$ELM\n"); + fprintf(fp, "%d\n", numelm); + numelm = 0; + writeElementsMSH(fp, NbSP, SP, 1, 1, 0, &nodes, &numelm); + writeElementsMSH(fp, NbVP, VP, 1, 3, 0, &nodes, &numelm); + writeElementsMSH(fp, NbTP, TP, 1, 9, 0, &nodes, &numelm); + writeElementsMSH(fp, NbSL, SL, 2, 1, 1, &nodes, &numelm); + writeElementsMSH(fp, NbVL, VL, 2, 3, 1, &nodes, &numelm); + writeElementsMSH(fp, NbTL, TL, 2, 9, 1, &nodes, &numelm); + writeElementsMSH(fp, NbST, ST, 3, 1, 2, &nodes, &numelm); + writeElementsMSH(fp, NbVT, VT, 3, 3, 2, &nodes, &numelm); + writeElementsMSH(fp, NbTT, TT, 3, 9, 2, &nodes, &numelm); + writeElementsMSH(fp, NbSQ, SQ, 4, 1, 2, &nodes, &numelm); + writeElementsMSH(fp, NbVQ, VQ, 4, 3, 2, &nodes, &numelm); + writeElementsMSH(fp, NbTQ, TQ, 4, 9, 2, &nodes, &numelm); + writeElementsMSH(fp, NbSS, SS, 4, 1, 3, &nodes, &numelm); + writeElementsMSH(fp, NbVS, VS, 4, 3, 3, &nodes, &numelm); + writeElementsMSH(fp, NbTS, TS, 4, 9, 3, &nodes, &numelm); + writeElementsMSH(fp, NbSH, SH, 8, 1, 3, &nodes, &numelm); + writeElementsMSH(fp, NbVH, VH, 8, 3, 3, &nodes, &numelm); + writeElementsMSH(fp, NbTH, TH, 8, 9, 3, &nodes, &numelm); + writeElementsMSH(fp, NbSI, SI, 6, 1, 3, &nodes, &numelm); + writeElementsMSH(fp, NbVI, VI, 6, 3, 3, &nodes, &numelm); + writeElementsMSH(fp, NbTI, TI, 6, 9, 3, &nodes, &numelm); + writeElementsMSH(fp, NbSY, SY, 5, 1, 3, &nodes, &numelm); + writeElementsMSH(fp, NbVY, VY, 5, 3, 3, &nodes, &numelm); + writeElementsMSH(fp, NbTY, TY, 5, 9, 3, &nodes, &numelm); + fprintf(fp, "$ENDELM\n"); + + fclose(fp); + return true; +} +